Index: /main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pm	(revision 34921)
@@ -17,4 +17,5 @@
 #                            scalar with a multi-character newline
 #               01/24/2009 - PH Protect against reading too much at once
+#               10/04/2018 - PH Added NoBuffer option
 #
 # Notes:        Calls the normal file i/o routines unless SeekTest() fails, in
@@ -25,5 +26,5 @@
 #               May also be used for string i/o (just pass a scalar reference)
 #
-# Legal:        Copyright (c) 2003-2010 Phil Harvey (phil at owl.phy.queensu.ca)
+# Legal:        Copyright (c) 2003-2021 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.
@@ -37,5 +38,5 @@
 
 use vars qw($VERSION @ISA @EXPORT_OK);
-$VERSION = '1.10';
+$VERSION = '1.11';
 @ISA = qw(Exporter);
 
@@ -44,4 +45,5 @@
 # constants
 my $CHUNK_SIZE = 8192;  # size of chunks to read from file (must be power of 2)
+my $SKIP_SIZE = 65536;  # size to skip when fast-forwarding over sequential data
 my $SLURP_CHUNKS = 16;  # read this many chunks at a time when slurping
 
@@ -61,4 +63,5 @@
         $self = {
             BUFF_PT => $filePt,
+            BASE => 0,
             POS => 0,
             LEN => length($$filePt),
@@ -72,6 +75,7 @@
             FILE_PT => $filePt, # file pointer
             BUFF_PT => \$buff,  # reference to file data
-            POS => 0,           # current position in file
-            LEN => 0,           # data length
+            BASE => 0,          # location of start of buffer in file
+            POS => 0,           # current position in buffer
+            LEN => 0,           # length of data in buffer
             TESTED => 0,        # 0=untested, 1=passed, -1=failed (requires buffering)
         };
@@ -119,5 +123,5 @@
     my $rtnVal;
     if ($self->{TESTED} < 0) {
-        $rtnVal = $self->{POS};
+        $rtnVal = $self->{POS} + $self->{BASE};
     } else {
         $rtnVal = tell($self->{FILE_PT});
@@ -142,7 +146,9 @@
         my $newPos;
         if ($whence == 0) {
-            $newPos = $num;                 # from start of file
+            $newPos = $num - $self->{BASE}; # from start of file
         } elsif ($whence == 1) {
             $newPos = $num + $self->{POS};  # relative to current position
+        } elsif ($self->{NoBuffer} and $self->{FILE_PT}) {
+            $newPos = -1;   # (can't seek relative to end if no buffering)
         } else {
             $self->Slurp();                 # read whole file into buffer
@@ -193,4 +199,6 @@
     # read through our buffer if necessary
     if ($self->{TESTED} < 0) {
+        # purge old data before reading in NoBuffer mode
+        $self->Purge() or return 0 if $self->{NoBuffer};
         my $buff;
         my $newPos = $self->{POS} + $len;
@@ -245,4 +253,5 @@
     if ($self->{TESTED} < 0) {
         my ($num, $buff);
+        $self->Purge() or return 0 if $self->{NoBuffer};
         my $pos = $self->{POS};
         if ($fp) {
@@ -312,7 +321,37 @@
 }
 
-
-#------------------------------------------------------------------------------
-# set binary mode
+#------------------------------------------------------------------------------
+# Purge internal buffer [internal use only]
+# Inputs: 0) reference to RandomAccess object
+# Returns: 1 on success, or 0 if current buffer position is negative
+# Notes: This is called only in NoBuffer mode
+sub Purge($)
+{
+    my $self = shift;
+    return 1 unless $self->{FILE_PT};
+    return 0 if $self->{POS} < 0;   # error if we can't read from here
+    if ($self->{POS} > $CHUNK_SIZE) {
+        my $purge = $self->{POS} - ($self->{POS} % $CHUNK_SIZE);
+        if ($purge >= $self->{LEN}) {
+            # read up to current position in 64k chunks, discarding as we go
+            while ($self->{POS} > $self->{LEN}) {
+                $self->{BASE} += $self->{LEN};
+                $self->{POS} -= $self->{LEN};
+                ${$self->{BUFF_PT}} = '';
+                $self->{LEN} = read($self->{FILE_PT}, ${$self->{BUFF_PT}}, $SKIP_SIZE);
+                last if $self->{LEN} < $SKIP_SIZE;
+            }
+        } elsif ($purge > 0) {
+            ${$self->{BUFF_PT}} = substr ${$self->{BUFF_PT}}, $purge;
+            $self->{BASE} += $purge;
+            $self->{POS} -= $purge;
+            $self->{LEN} -= $purge;
+        }
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Set binary mode
 # Inputs: 0) reference to RandomAccess object
 sub BinMode($)
@@ -323,5 +362,5 @@
 
 #------------------------------------------------------------------------------
-# close the file and free the buffer
+# Close the file and free the buffer
 # Inputs: 0) reference to RandomAccess object
 sub Close($)
@@ -371,4 +410,5 @@
     my $emptyBuff = '';
     $self->{BUFF_PT} = \$emptyBuff;
+    $self->{BASE} = 0;
     $self->{LEN} = 0;
     $self->{POS} = 0;
Index: /main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pod
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pod	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/File/RandomAccess.pod	(revision 34921)
@@ -4,5 +4,5 @@
 # Description:  Buffer to support random access reading of sequential file
 #
-# Legal:        Copyright (c) 2003-2010 Phil Harvey (phil at owl.phy.queensu.ca)
+# Legal:        Copyright (c) 2003-2021 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.
@@ -48,9 +48,9 @@
 =item Inputs:
 
-0) Reference to RandomAccess object.
+0) Reference to RandomAccess object or RandomAccess class name.
 
 1) File reference or scalar reference.
 
-2) flag set if file is already random access (disables automatic SeekTest).
+2) Flag set if file is already random access (disables automatic SeekTest).
 
 =item Returns:
@@ -216,7 +216,26 @@
 =back
 
+=head1 OPTIONS
+
+=over 4
+
+=item B<NoBuffer>
+
+Avoid buffering sequential files.
+
+    $raf->{NoBuffer} = 1;
+
+When this option is set, old data is purged from the internal buffer before
+a read operation on a sequential file.  In this mode, memory requirements
+may be significantly reduced when reading sequential files, but seeking
+backward is limited to within the size of the internal buffer (which will be
+at least as large as the last returned data block), and seeking relative to
+the end of file is not allowed.
+
+=back
+
 =head1 AUTHOR
 
-Copyright 2003-2011 Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021 Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pm	(revision 34921)
@@ -4,10 +4,10 @@
 # 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-2010, Phil Harvey (phil at owl.phy.queensu.ca)
+# Legal:        Copyright (c) 2003-2021, 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.
@@ -20,12 +20,14 @@
 require Exporter;
 use File::RandomAccess;
-
-use vars qw($VERSION $RELEASE @ISA %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);
-
-$VERSION = '8.57';
+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 $testLen $exePath);
+
+$VERSION = '12.19';
 $RELEASE = '';
 @ISA = qw(Exporter);
@@ -35,4 +37,5 @@
         ImageInfo GetTagName GetShortcuts GetAllTags GetWritableTags
         GetAllGroups GetDeleteGroups GetFileType CanWrite CanCreate
+        AddUserDefinedTags
     )],
     # exports not part of the public API, but used by ExifTool modules:
@@ -40,9 +43,10 @@
         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)],
+    Utils => [qw(GetTagTable TagTableKeys GetTagInfoList AddTagToTable HexDump)],
     Vars  => [qw(%allTables @tableOrder @fileTypes)],
 );
+
 # set all of our EXPORT_TAGS in EXPORT_OK
 Exporter::export_ok_tags(keys %EXPORT_TAGS);
@@ -51,26 +55,30 @@
 { 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($;$$%);
 sub SetNewValuesFromFile($$;@);
-sub GetNewValues($;$$);
+sub GetNewValue($$;$);
+sub GetNewValues($$;$);
 sub CountNewValues($);
 sub SaveNewValues($);
 sub RestoreNewValues($);
 sub WriteInfo($$;$$);
-sub SetFileModifyDate($$;$);
-sub SetFileName($$;$);
+sub SetFileModifyDate($$;$$$);
+sub SetFileName($$;$$$);
+sub SetSystemTags($$);
 sub GetAllTags(;$);
 sub GetWritableTags(;$);
-sub GetAllGroups($);
+sub GetAllGroups($;$);
 sub GetNewGroups($);
 sub GetDeleteGroups();
+sub AddUserDefinedTags($%);
 # non-public routines below
-sub InsertTagValues($$$;$);
+sub InsertTagValues($$$;$$$);
 sub IsWritable($);
+sub IsSameFile($$$);
+sub IsRawType($);
 sub GetNewFileName($$);
-sub NextTagKey($$);
 sub LoadAllTables();
 sub GetNewTagInfoList($;$);
@@ -79,12 +87,14 @@
 sub Get64s($$);
 sub Get64u($$);
+sub GetFixed64s($$);
 sub GetExtended($$);
+sub Set64u(@);
 sub DecodeBits($$;$);
 sub EncodeBits($$;$$);
+sub Filter($$$);
 sub HexDump($;$%);
 sub DumpTrailer($$);
 sub DumpUnknownTrailer($$);
 sub VerboseInfo($$$%);
-sub VerboseDir($$;$$);
 sub VerboseValue($$$;$);
 sub VPrint($$@);
@@ -101,12 +111,24 @@
 sub PackUTF8(@);
 sub UnpackUTF8($);
-sub SetPreferredByteOrder($);
+sub SetPreferredByteOrder($;$);
 sub CopyBlock($$$);
-sub CopyFileAttrs($$);
+sub CopyFileAttrs($$$);
+sub TimeNow(;$$);
+sub NewGUID();
+sub MakeTiffHeader($$$$;$$);
 
 # other subroutine definitions
+sub SplitFileName($);
+sub EncodeFileName($$;$);
+sub Open($*$;$);
+sub Exists($$);
+sub IsDirectory($$);
+sub Rename($$$);
+sub Unlink($@);
+sub SetFileTime($$;$$$$);
 sub DoEscape($$);
 sub ConvertFileSize($);
 sub ParseArguments($;@); #(defined in attempt to avoid mod_perl problem)
+sub ReadValue($$$;$$$);
 
 # list of main tag tables to load in LoadAllTables() (sub-tables are recursed
@@ -114,17 +136,22 @@
 # unless tweaked in BuildTagLookup::GetTableOrder().
 @loadAllTables = qw(
-    PhotoMechanic Exif GeoTiff CanonRaw KyoceraRaw MinoltaRaw PanasonicRaw
-    SigmaRaw JPEG GIMP Jpeg2000 GIF BMP BMP::OS2 PICT PNG MNG DjVu PGF MIFF PSP
-    PDF PostScript Photoshop::Header FujiFilm::RAF Sony::SRF2 Sony::SR2SubIFD
-    Sony::PMP ITC ID3 Vorbis FLAC APE APE::NewHeader APE::OldHeader MPC
-    MPEG::Audio MPEG::Video MPEG::Xing M2TS QuickTime QuickTime::ImageFile
-    Matroska MXF DV Flash Flash::FLV Real::Media Real::Audio Real::Metafile RIFF
-    AIFF ASF DICOM MIE HTML XMP::SVG EXE EXE::PEVersion EXE::PEString EXE::MachO
-    EXE::PEF EXE::ELF LNK Font RSRC Rawzor ZIP ZIP::GZIP ZIP::RAR RTF OOXML
-    iWork
+    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 ZISRAW 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 ID3::Lyrics3 FLAC Ogg Vorbis APE APE::NewHeader
+    APE::OldHeader Audible MPC MPEG::Audio MPEG::Video MPEG::Xing M2TS QuickTime
+    QuickTime::ImageFile QuickTime::Stream QuickTime::Tags360Fly Matroska MOI
+    MXF DV Flash Flash::FLV Real::Media 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 Text VCard::VCalendar RSRC Rawzor ZIP ZIP::GZIP
+    ZIP::RAR RTF OOXML iWork ISO FLIR::AFF FLIR::FPF MacOS MacOS::MDItem
+    FlashPix::DocTable
 );
 
 # alphabetical list of current Lang modules
-@langs = qw(cs de en en_ca en_gb es fr it ja ko nl pl ru sv tr zh_cn zh_tw);
+@langs = qw(cs de en en_ca en_gb es fi fr it ja ko nl pl ru sv tr zh_cn zh_tw);
 
 $defaultLang = 'en';    # default language
@@ -138,4 +165,5 @@
     en_gb => 'British English',
     es => 'Spanish (EspaÃ±ol)',
+    fi => 'Finnish (Suomi)',
     fr => 'French (FranÃ§ais)',
     it => 'Italian (Italiano)',
@@ -154,25 +182,36 @@
 # Notes: 1) There is no need to test for like types separately here
 # 2) Put types with weak file signatures at end of list to avoid false matches
-@fileTypes = qw(JPEG CRW TIFF GIF MRW RAF X3F JP2 PNG MIE MIFF PS PDF PSD XMP
-                BMP PPM RIFF AIFF ASF MOV MPEG Real SWF PSP FLV OGG FLAC APE MPC
-                MKV MXF DV PMP IND PGF ICC ITC HTML VRD RTF XCF QTIF FPX PICT
-                ZIP GZIP RAR BZ2 TAR RWZ EXE LNK RAW Font RSRC M2TS MP3 DICM);
+# 3) PLIST must be in this list for the binary PLIST format, although it may
+#    cause a file to be checked twice for XML
+@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 FITS XCF DSS QTIF FPX PICT ZIP GZIP PLIST RAR BZ2
+                CZI TAR  EXE EXR HDR CHM LNK WMF AVC DEX DPX RAW Font RSRC M2TS
+                MacOS 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 X3F PS PDF ICC VRD JP2 EXIF AI AIT IND);
+my @writeTypes = qw(JPEG TIFF GIF CRW MRW ORF RAF RAW PNG MIE PSD XMP PPM EPS
+                    X3F PS PDF ICC VRD DR4 JP2 EXIF AI AIT IND MOV EXV FLIF);
+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' ],
+    XMP  => [ qw(SVG INX) ],
+    JP2  => [ qw(J2C JPC) ],
+    MOV  => [ qw(INSV) ],
 );
 
 # file types that we can create from scratch
 # - must update CanCreate() documentation if this list is changed!
-my %createTypes = (XMP=>1, ICC=>1, MIE=>1, VRD=>1, EXIF=>1);
-
-# file type lookup for all recognized file extensions
-my %fileTypeLookup = (
+my %createTypes = map { $_ => 1 } qw(XMP ICC MIE VRD DR4 EXIF EXV);
+
+# file type lookup for all recognized file extensions (upper case)
+# (if extension may be more than one type, the type is a list where
+#  the writable type should come first if it exists)
+%fileTypeLookup = (
+   '360' => ['MOV',  'GoPro 360 video'],
    '3FR' => ['TIFF', 'Hasselblad RAW format'],
    '3G2' => ['MOV',  '3rd Gen. Partnership Project 2 audio/video'],
@@ -180,5 +219,9 @@
    '3GP2'=>  '3G2',
    '3GPP'=>  '3GP',
-    ACR  => ['DICM', 'American College of Radiology ACR-NEMA'],
+    A    => ['EXE',  'Static library'],
+    AA   => ['AA',   'Audible Audiobook'],
+    AAE  => ['PLIST','Apple edit information'],
+    AAX  => ['MOV',  'Audible Enhanced Audiobook'],
+    ACR  => ['DICOM','American College of Radiology ACR-NEMA'],
     ACFM => ['Font', 'Adobe Composite Font Metrics'],
     AFM  => ['Font', 'Adobe Font Metrics'],
@@ -189,24 +232,40 @@
     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'],
+    ARQ  => ['TIFF', 'Sony Alpha Pixel-Shift RAW format'],
     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'],
+    BPG  => ['BPG',  'Better Portable Graphics'],
     BTF  => ['BTF',  'Big Tagged Image File Format'], #(unofficial)
     BZ2  => ['BZ2',  'BZIP2 archive'],
+    CHM  => ['CHM',  'Microsoft Compiled HTML format'],
     CIFF => ['CRW',  'Camera Image File Format'],
     COS  => ['COS',  'Capture One Settings'],
     CR2  => ['TIFF', 'Canon RAW 2 format'],
+    CR3  => ['MOV',  'Canon RAW 3 format'],
+    CRM  => ['MOV',  'Canon RAW Movie'],
     CRW  => ['CRW',  'Canon RAW format'],
     CS1  => ['PSD',  'Sinar CaptureShop 1-Shot RAW'],
+    CSV  => ['TXT',  'Comma-Separated Values'],
+    CZI  => ['CZI',  'Zeiss Integrated Software RAW'],
     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'],
     DIC  =>  'DICM',
-    DICM => ['DICM', 'Digital Imaging and Communications in Medicine'],
+    DICM => ['DICOM','Digital Imaging and Communications in Medicine'],
+    DIR  => ['DIR',  'Directory'],
     DIVX => ['ASF',  'DivX media format'],
     DJV  =>  'DJVU',
@@ -223,6 +282,13 @@
     DOTM => [['ZIP','FPX'], 'Office Open XML Document Template Macro-enabled'],
     DOTX => [['ZIP','FPX'], 'Office Open XML Document Template'],
+    DPX  => ['DPX',  'Digital Picture Exchange' ],
+    DR4  => ['DR4',  'Canon VRD version 4 Recipe'],
+    DS2  => ['DSS',  'Digital Speech Standard 2'],
+    DSS  => ['DSS',  'Digital Speech Standard'],
     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'],
@@ -231,40 +297,73 @@
     EPS3 =>  'EPS',
     EPSF =>  'EPS',
+    EPUB => ['ZIP',  'Electronic Publication'],
     ERF  => ['TIFF', 'Epson Raw Format'],
     EXE  => ['EXE',  'Windows executable file'],
+    EXR  => ['EXR', 'Open EXR'],
     EXIF => ['EXIF', 'Exchangable Image File Metadata'],
+    EXV  => ['EXV',  'Exiv2 metadata'],
     F4A  => ['MOV',  'Adobe Flash Player 9+ Audio'],
     F4B  => ['MOV',  'Adobe Flash Player 9+ audio Book'],
     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'],
+    FLIR => ['FLIR', 'FLIR File Format'], # (not an actual extension)
     FLV  => ['FLV',  'Flash Video'],
+    FPF  => ['FPF',  'FLIR Public image Format'],
     FPX  => ['FPX',  'FlashPix'],
     GIF  => ['GIF',  'Compuserve Graphics Interchange Format'],
+    GPR  => ['TIFF', 'GoPro RAW'],
     GZ   =>  'GZIP',
     GZIP => ['GZIP', 'GNU ZIP compressed archive'],
     HDP  => ['TIFF', 'Windows HD Photo'],
+    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',
     ICC  => ['ICC',  'International Color Consortium'],
     ICM  =>  'ICC',
+    ICS  => ['VCard','iCalendar Schedule'],
+    IDML => ['ZIP',  'Adobe InDesign Markup Language'],
     IIQ  => ['TIFF', 'Phase One Intelligent Image Quality RAW'],
     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  =>  'J2C',
     JNG  => ['PNG',  'JPG Network Graphics'],
     JP2  => ['JP2',  'JPEG 2000 file'],
     # JP4? - looks like a JPEG but the image data is different
-    JPEG =>  'JPG',
-    JPG  => ['JPEG', 'Joint Photographic Experts Group'],
+    JPC  =>  'J2C',
+    JPE  =>  'JPEG',
+    JPEG => ['JPEG', 'Joint Photographic Experts Group'],
+    JPF  =>  'JP2',
+    JPG =>   'JPEG',
     JPM  => ['JP2',  'JPEG 2000 compound image'],
     JPX  => ['JP2',  'JPEG 2000 with extensions'],
+    JSON => ['JSON', 'JavaScript Object Notation'],
+    JXR  => ['TIFF', 'JPEG XR'],
     K25  => ['TIFF', 'Kodak DC25 RAW'],
     KDC  => ['TIFF', 'Kodak Digital Camera RAW'],
     KEY  => ['ZIP',  'Apple Keynote presentation'],
     KTH  => ['ZIP',  'Apple Keynote Theme'],
+    LA   => ['RIFF', 'Lossless Audio'],
+    LFP  => ['LFP',  'Lytro Light Field Picture'],
+    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'],
@@ -274,4 +373,5 @@
     M4P  => ['MOV',  'MPEG-4 Protected'],
     M4V  => ['MOV',  'MPEG-4 Video'],
+    MAX  => ['FPX',  '3D Studio MAX'],
     MEF  => ['TIFF', 'Mamiya (RAW) Electronic Format'],
     MIE  => ['MIE',  'Meta Information Encapsulation format'],
@@ -282,5 +382,7 @@
     MKV  => ['MKV',  'Matroska Video'],
     MNG  => ['PNG',  'Multiple-image Network Graphics'],
-  # MODD => ['PLIST','Sony Picture Motion Metadata'],
+    MOBI => ['PDB',  'Mobipocket electronic book'],
+    MODD => ['PLIST','Sony Picture Motion metadata'],
+    MOI  => ['MOI',  'MOD Information file'],
     MOS  => ['TIFF', 'Creo Leaf Mosaic'],
     MOV  => ['MOV',  'Apple QuickTime movie'],
@@ -293,5 +395,5 @@
     MQV  => ['MOV',  'Sony Mobile Quicktime Video'],
     MRW  => ['MRW',  'Minolta RAW format'],
-    MTS  => ['M2TS', 'MPEG-2 Transport Stream'],
+    MTS  =>  'M2TS',
     MXF  => ['MXF',  'Material Exchange Format'],
   # NDPI => ['TIFF', 'Hamamatsu NanoZoomer Digital Pathology Image'],
@@ -301,13 +403,27 @@
     NRW  => ['TIFF', 'Nikon RAW (2)'],
     NUMBERS => ['ZIP','Apple Numbers spreadsheet'],
+    O    => ['EXE',  'Relocatable Object'],
+    ODB  => ['ZIP',  'Open Document Database'],
+    ODC  => ['ZIP',  'Open Document Chart'],
+    ODF  => ['ZIP',  'Open Document Formula'],
+    ODG  => ['ZIP',  'Open Document Graphics'],
+    ODI  => ['ZIP',  'Open Document Image'],
     ODP  => ['ZIP',  'Open Document Presentation'],
     ODS  => ['ZIP',  'Open Document Spreadsheet'],
     ODT  => ['ZIP',  'Open Document Text file'],
+    OFR  => ['RIFF', 'OptimFROG audio'],
     OGG  => ['OGG',  'Ogg Vorbis audio file'],
+    OGV  => ['OGG',  'Ogg Video file'],
+    ONP  => ['JSON', 'ON1 Presets'],
+    OPUS => ['OGG',  'Ogg Opus audio file'],
     ORF  => ['ORF',  'Olympus RAW format'],
     OTF  => ['Font', 'Open Type Font'],
+    PAC  => ['RIFF', 'Lossless Predictive Audio Compression'],
     PAGES => ['ZIP', 'Apple Pages document'],
     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'],
@@ -317,6 +433,12 @@
     PGF  => ['PGF',  'Progressive Graphics File'],
     PGM  => ['PPM',  'Portable Gray Map'],
+    PHP  => ['PHP',  'PHP Hypertext Preprocessor'],
+    PHP3 =>  'PHP',
+    PHP4 =>  'PHP',
+    PHP5 =>  'PHP',
+    PHPS =>  'PHP',
+    PHTML=>  'PHP',
     PICT => ['PICT', 'Apple PICTure'],
-  # PLIST=> ['PLIST','Apple Property List'],
+    PLIST=> ['PLIST','Apple Property List'],
     PMP  => ['PMP',  'Sony DSC-F1 Cyber-Shot PMP'], # should stand for Proprietery Metadata Package ;)
     PNG  => ['PNG',  'Portable Network Graphics'],
@@ -324,4 +446,6 @@
     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'],
@@ -331,9 +455,11 @@
     PPTM => [['ZIP','FPX'], 'Office Open XML Presentation Macro-enabled'],
     PPTX => [['ZIP','FPX'], 'Office Open XML Presentation'],
+    PRC  => ['PDB',  'Palm Database'],
     PS   => ['PS',   'PostScript'],
     PS2  =>  'PS',
     PS3  =>  'PS',
     PSB  => ['PSD',  'Photoshop Large Document'],
-    PSD  => ['PSD',  'Photoshop Drawing'],
+    PSD  => ['PSD',  'Photoshop Document'],
+    PSDT => ['PSD',  'Photoshop Document Template'],
     PSP  => ['PSP',  'Paint Shop Pro'],
     PSPFRAME => 'PSP',
@@ -342,7 +468,8 @@
     PSPTUBE  => 'PSP',
     QIF  =>  'QTIF',
-    QT   => ['MOV',  'QuickTime movie'],
+    QT   =>  'MOV',
     QTI  =>  'QTIF',
     QTIF => ['QTIF', 'QuickTime Image File'],
+    R3D  => ['R3D',  'Redcode RAW Video'],
     RA   => ['Real', 'Real Audio'],
     RAF  => ['RAF',  'FujiFilm RAW Format'],
@@ -361,4 +488,6 @@
     RWL  => ['TIFF', 'Leica RAW'],
     RWZ  => ['RWZ',  'Rawzor compressed image'],
+    SEQ  => ['FLIR', 'FLIR image Sequence'],
+    SKETCH => ['ZIP', 'Sketch design file'],
     SO   => ['EXE',  'Shared Object file'],
     SR2  => ['TIFF', 'Sony RAW Format 2'],
@@ -368,12 +497,16 @@
     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'],
+    TORRENT => ['Torrent', 'BitTorrent description file'],
     TS   =>  'M2TS',
     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'],
     VRD  => ['VRD',  'Canon VRD Recipe Data'],
@@ -384,6 +517,9 @@
     WEBP => ['RIFF', 'Google Web Picture'],
     WMA  => ['ASF',  'Windows Media Audio'],
+    WMF  => ['WMF',  'Windows Metafile Format'],
     WMV  => ['ASF',  'Windows Media Video'],
+    WV   => ['RIFF', 'WavePack lossless audio'],
     X3F  => ['X3F',  'Sigma RAW format'],
+    MACOS=> ['MacOS','MacOS ._ sidecar file'],
     XCF  => ['XCF',  'GIMP native image format'],
     XHTML=> ['HTML', 'Extensible HyperText Markup Language'],
@@ -398,5 +534,22 @@
     XLTX => [['ZIP','FPX'], 'Office Open XML Spreadsheet Template'],
     XMP  => ['XMP',  'Extensible Metadata Platform'],
+    WOFF => ['Font', 'Web Open Font Format'],
+    WOFF2=> ['Font', 'Web Open Font Format2'],
+    WTV  => ['WTV',  'Windows recorded TV show'],
     ZIP  => ['ZIP',  'ZIP archive'],
+);
+
+# typical extension for each file type (if different than FileType)
+# - case is not significant
+my %fileTypeExt = (
+    'Canon 1D RAW' => 'tif',
+    DICOM   => 'dcm',
+    FLIR    => 'fff',
+    GZIP    => 'gz',
+    JPEG    => 'jpg',
+    M2TS    => 'mts',
+    MPEG    => 'mpg',
+    TIFF    => 'tif',
+    VCard   => 'vcf',
 );
 
@@ -404,31 +557,44 @@
 my %fileDescription = (
     DICOM => 'Digital Imaging and Communications in Medicine',
-    PLIST => 'Property List',
     XML   => 'Extensible Markup Language',
-    'DJVU (multi-page)' => 'DjVu multi-page image',
     'Win32 EXE' => 'Windows 32-bit Executable',
     'Win32 DLL' => 'Windows 32-bit Dynamic Link Library',
+    'Win64 EXE' => 'Windows 64-bit Executable',
+    'Win64 DLL' => 'Windows 64-bit Dynamic Link Library',
 );
 
 # MIME types for applicable file types above
-# (missing entries default to 'application/unknown', but note that
-#  other mime types may be specified by some modules, ie. QuickTime.pm)
+# (missing entries default to 'application/unknown', but note that other MIME
+#  types may be specified by some modules, eg. QuickTime.pm and RIFF.pm)
 %mimeType = (
    '3FR' => 'image/x-hasselblad-3fr',
+    AA   => 'audio/audible',
+    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',
     ARW  => 'image/x-sony-arw',
-    AVI  => 'video/x-msvideo',
     BMP  => 'image/bmp',
+    BPG  => 'image/bpg',
     BTF  => 'image/x-tiff-big', #(NC) (ref http://www.asmail.be/msg0055371937.html)
     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',
+    CZI  => 'image/x-zeiss-czi', #PH (NC)
+    DCP  => 'application/octet-stream', #PH (NC)
     DCR  => 'image/x-kodak-dcr',
+    DCX  => 'image/dcx',
+    DEX  => 'application/octet-stream',
     DFONT=> 'application/x-dfont',
-    DICM => 'application/dicom',
+    DICOM=> 'application/dicom',
     DIVX => 'video/divx',
     DJVU => 'image/vnd.djvu',
@@ -440,22 +606,43 @@
     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',
     GZIP => 'application/x-gzip',
     HDP  => 'image/vnd.ms-photo',
+    HDR  => 'image/vnd.radiance',
     HTML => 'text/html',
     ICC  => 'application/vnd.iccprofile',
+    ICS  => 'text/calendar',
+    IDML => 'application/vnd.adobe.indesign-idml-package',
     IIQ  => 'image/x-raw',
     IND  => 'application/x-indesign',
+    INX  => 'application/x-indesign-interchange', #PH (NC)
+    ISO  => 'application/x-iso9660-image',
     ITC  => 'application/itunes',
+    J2C  => 'image/x-j2c', #PH (NC)
     JNG  => 'image/jng',
     JP2  => 'image/jp2',
@@ -463,9 +650,15 @@
     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',
     M2T  => 'video/mpeg',
     M2TS => 'video/m2ts',
+    MAX  => 'application/x-3ds',
     MEF  => 'image/x-mamiya-mef',
     MIE  => 'application/x-mie',
@@ -475,4 +668,6 @@
     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',
@@ -485,21 +680,38 @@
     NEF  => 'image/x-nikon-nef',
     NRW  => 'image/x-nikon-nrw',
+    NUMBERS => 'application/x-iwork-numbers-sffnumbers',
+    ODB  => 'application/vnd.oasis.opendocument.database',
+    ODC  => 'application/vnd.oasis.opendocument.chart',
+    ODF  => 'application/vnd.oasis.opendocument.formula',
+    ODG  => 'application/vnd.oasis.opendocument.graphics',
+    ODI  => 'application/vnd.oasis.opendocument.image',
     ODP  => 'application/vnd.oasis.opendocument.presentation',
     ODS  => 'application/vnd.oasis.opendocument.spreadsheet',
     ODT  => 'application/vnd.oasis.opendocument.text',
-    OGG  => 'audio/x-ogg',
+    OGG  => 'audio/ogg',
+    OGV  => 'video/ogg',
+    ONP  => 'application/on1',
     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',
+    PFA  => 'application/x-font-type1', # (needed if handled by PostScript module)
     PGF  => 'image/pgf',
     PGM  => 'image/x-portable-graymap',
+    PHP  => 'application/x-httpd-php',
     PICT => 'image/pict',
-    PLIST=> 'application/xml',
+    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',
@@ -513,4 +725,5 @@
     PSP  => 'image/x-paintshoppro', #(NC)
     QTIF => 'image/x-quicktime',
+    R3D  => 'video/x-red-r3d', #PH (invented)
     RA   => 'audio/x-pn-realaudio',
     RAF  => 'image/x-fujifilm-raf',
@@ -527,4 +740,6 @@
     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',
@@ -535,13 +750,17 @@
     THMX => 'application/vnd.ms-officetheme',
     TIFF => 'image/tiff',
+    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',
-    WAV  => 'audio/x-wav',
     WDP  => 'image/vnd.ms-photo',
     WEBM => 'video/webm',
-    WEBP => 'image/webp',
     WMA  => 'audio/x-ms-wma',
+    WMF  => 'application/x-wmf',
     WMV  => 'video/x-ms-wmv',
+    WTV  => 'video/x-ms-wtv',
     X3F  => 'image/x-sigma-x3f',
     XCF  => 'image/x-xcf',
@@ -565,31 +784,49 @@
 # - module name '0' indicates a recognized but unsupported file
 my %moduleName = (
+    AA   => 'Audible',
+    ALIAS=> 0,
+    AVC  => 0,
     BTF  => 'BigTIFF',
     BZ2  => 0,
     CRW  => 'CanonRaw',
-    DICM => 'DICOM',
+    CHM  => 'EXE',
     COS  => 'CaptureOne',
+    CZI  => 'ZISRAW',
+    DEX  => 0,
     DOCX => 'OOXML',
+    DCX  => 0,
+    DR4  => 'CanonVRD',
+    DSS  => 'Olympus',
+    DWF  => 0,
+    DWG  => 0,
     EPS  => 'PostScript',
     EXIF => '',
+    EXR  => 'OpenEXR',
+    EXV  => '',
     ICC  => 'ICC_Profile',
     IND  => 'InDesign',
     FLV  => 'Flash',
+    FPF  => 'FLIR',
     FPX  => 'FlashPix',
     GZIP => 'ZIP',
+    HDR  => 'Radiance',
     JP2  => 'Jpeg2000',
     JPEG => '',
-  # MODD => 'XML',
+    LFP  => 'Lytro',
+    LRI  => 0,
     MOV  => 'QuickTime',
     MKV  => 'Matroska',
     MP3  => 'ID3',
     MRW  => 'MinoltaRaw',
-    OGG  => 'Vorbis',
+    OGG  => 'Ogg',
     ORF  => 'Olympus',
-  # PLIST=> 'XML',
+    PDB  => 'Palm',
+    PCD  => 'PhotoCD',
+    PHP  => 0,
     PMP  => 'Sony',
     PS   => 'PostScript',
     PSD  => 'Photoshop',
     QTIF => 'QuickTime',
+    R3D  => 'Red',
     RAF  => 'FujiFilm',
     RAR  => 'ZIP',
@@ -599,48 +836,78 @@
     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\+',
+    Torrent => 'd\d+:\w+',
     BMP  => 'BM',
+    BPG  => "BPG\xfb",
     BTF  => '(II\x2b\0|MM\0\x2b)',
     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)',
-    DICM => '(.{128}DICM|\0[\x02\x04\x06\x08]\0[\0-\x20]|[\x02\x04\x06\x08]\0[\0-\x20]\0)',
+    CZI  => 'ZISRAWFILE\0{6}',
+    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',
+    DPX  => '(SDPX|XPDS)',
+    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/|!<arch>\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',
     FLV  => 'FLV\x01',
     Font => '((\0\x01\0\0|OTTO|true|typ1)[\0\x01]|ttcf\0[\x01\x02]\0\0|\0[\x01\x02]|' .
-            '(.{6})?%!(PS-(AdobeFont-|Bitstream )|FontType1-)|Start(Comp|Master)?FontMetrics)',
+            '(.{6})?%!(PS-(AdobeFont-|Bitstream )|FontType1-)|Start(Comp|Master)?FontMetrics|wOF[F2])',
+    FPF  => 'FPF Public Image Format\0',
     FPX  => '\xd0\xcf\x11\xe0\xa1\xb1\x1a\xe1',
     GIF  => 'GIF8[79]a',
     GZIP => '\x1f\x8b\x08',
-    HTML => '(?i)<(!DOCTYPE\s+HTML|HTML|\?xml)', # (case insensitive)
+    HDR  => '#\?(RADIANCE|RGBE)\x0a',
+    HTML => '(\xef\xbb\xbf)?\s*(?i)<(!DOCTYPE\s+HTML|HTML|\?xml)', # (case insensitive)
     ICC  => '.{12}(scnr|mntr|prtr|link|spac|abst|nmcl|nkpf)(XYZ |Lab |Luv |YCbr|Yxy |RGB |GRAY|HSV |HLS |CMYK|CMY |[2-9A-F]CLR){2}',
     IND  => '\x06\x06\xed\xf5\xd8\x1d\x46\xe5\xbd\x31\xef\xe7\xfe\x74\xb7\x1d',
+  # ISO  =>  signature is at byte 32768
     ITC  => '.{4}itch',
-    JP2  => '\0\0\0\x0cjP(  |\x1a\x1a)\x0d\x0a\x87\x0a',
+    JP2  => '(\0\0\0\x0cjP(  |\x1a\x1a)\x0d\x0a\x87\x0a|\xff\x4f\xff\x51\0)',
     JPEG => '\xff\xd8\xff',
+    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',
     M2TS => '(....)?\x47',
     MIE  => '~[\x10\x18]\x04.0MIE',
     MIFF => 'id=ImageMagick',
     MKV  => '\x1a\x45\xdf\xa3',
-    MOV  => '.{4}(free|skip|wide|ftyp|pnot|PICT|pict|moov|mdat|junk|uuid)',
+    MOV  => '.{4}(free|skip|wide|ftyp|pnot|PICT|pict|moov|mdat|junk|uuid)', # (duplicated in WriteQuickTime.pl !!)
   # MP3  =>  difficult to rule out
     MPC  => '(MP\+|ID3)',
+    MOI  => 'V6',
     MPEG => '\0\0\x01[\xb0-\xbf]',
     MRW  => '\0MR[MI]',
@@ -648,7 +915,12 @@
     OGG  => '(OggS|ID3)',
     ORF  => '(II|MM)',
-    PDF  => '%PDF-\d+\.\d+',
+    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',
     PICT => '(.{10}|.{522})(\x11\x01|\x00\x11)',
+    PLIST=> '(bplist0|\s*<|\xfe\xff\x00)',
     PMP  => '.{8}\0{3}\x7c.{112}\xff\xd8\xff\xdb',
     PNG  => '(\x89P|\x8aM|\x8bJ)NG\r\n\x1a\n',
@@ -658,24 +930,53 @@
     PSP  => 'Paint Shop Pro Image File\x0a\x1a\0{5}',
     QTIF => '.{4}(idsc|idat|iicc)',
+    R3D  => '\0\0..RED(1|2)',
     RAF  => 'FUJIFILM',
     RAR  => 'Rar!\x1a\x07\0',
     RAW  => '(.{25}ARECOYK|II|MM)',
     Real => '(\.RMF|\.ra\xfd|pnm://|rtsp://|http://)',
-    RIFF => 'RIFF',
+    RIFF => '(RIFF|LA0[234]|OFR |LPAC|wvpk|RF64)', # RIFF plus other variants
     RSRC => '(....)?\0\0\x01\0',
     RTF  => '[\n\r]*\\{[\n\r]*\\\\rtf',
-    # (don't be too restrictive for RW2/RWL -- how does magic number change for big-endian?)
-    RW2  => '(II|MM)', #(\x55\0\x18\0\0\0\x88\xe7\x74\xd8\xf8\x25\x1d\x4d\x94\x7a\x6e\x77\x82\x2b\x5d\x6a)
-    RWL  => '(II|MM)', #(ditto)
     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',
+    WMF  => '(\xd7\xcd\xc6\x9a\0\0|\x01\0\x09\0\0\x03)',
+    WTV  => '\xb7\xd8\x00\x20\x37\x49\xda\x11\xa6\x4e\x00\x07\xe9\x5e\xad\x8d',
     X3F  => 'FOVb',
+    MacOS=> '\0\x05\x16\x07\0.\0\0Mac OS X        ',
     XCF  => 'gimp xcf ',
     XMP  => '\0{0,3}(\xfe\xff|\xff\xfe|\xef\xbb\xbf)?\0{0,3}\s*<',
     ZIP  => 'PK\x03\x04',
 );
+
+# file types with weak magic number recognition
+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 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)
@@ -694,4 +995,7 @@
     vietnam     => 'Vietnam',     cp1258  => 'Vietnam',
     thai        => 'Thai',        cp874   => 'Thai',
+    doslatinus  => 'DOSLatinUS',  cp437   => 'DOSLatinUS',
+    doslatin1   => 'DOSLatin1',   cp850   => 'DOSLatin1',
+    doscyrillic => 'DOSCyrillic', cp866   => 'DOSCyrillic',
     macroman    => 'MacRoman',    cp10000 => 'MacRoman', mac => 'MacRoman', roman => 'MacRoman',
     maclatin2   => 'MacLatin2',   cp10029 => 'MacLatin2',
@@ -704,6 +1008,10 @@
 );
 
-# default group priority for writing
-my @defaultWriteGroups = qw(EXIF IPTC XMP MakerNotes Photoshop ICC_Profile CanonVRD);
+# 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 QuickTime Photoshop ICC_Profile CanonVRD Adobe
+);
 
 # group hash for ExifTool-generated tags
@@ -711,10 +1019,11 @@
 
 # special tag names (not used for tag info)
-my %specialTags = (
-    TABLE_NAME=>1, SHORT_NAME=>1, PROCESS_PROC=>1, WRITE_PROC=>1, CHECK_PROC=>1,
-    GROUPS=>1, FORMAT=>1, FIRST_ENTRY=>1, TAG_PREFIX=>1, PRINT_CONV=>1,
-    WRITABLE=>1, TABLE_DESC=>1, NOTES=>1, IS_OFFSET=>1, EXTRACT_UNKNOWN=>1,
-    NAMESPACE=>1, PREFERRED=>1, SRC_TABLE=>1, PRIORITY=>1, WRITE_GROUP=>1,
-    LANG_INFO=>1, VARS=>1, DATAMEMBER=>1, IS_SUBDIR=>1, SET_GROUP1=>1,
+%specialTags = map { $_ => 1 } qw(
+    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
+    SET_GROUP1       PERMANENT   INIT_TABLE
 );
 
@@ -734,4 +1043,11 @@
 @Image::ExifTool::pluginTags = ( );
 %Image::ExifTool::pluginTags = ( );
+
+my %systemTagsNotes = (
+    Notes => q{
+        extracted only if specifically requested or the L<SystemTags|../ExifTool.html#SystemTags> or L<RequestAll|../ExifTool.html#RequestAll> API
+        option is set
+    },
+);
 
 # tag information for preview image -- this should be used for all
@@ -746,5 +1062,5 @@
     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',
@@ -758,6 +1074,24 @@
     VARS => { NO_ID => 1 }, # tag ID's aren't meaningful for these tags
     WRITE_PROC => \&DummyWriteProc,
-    Error   => { Priority => 0, Groups => \%allGroupsExifTool },
-    Warning => { Priority => 0, Groups => \%allGroupsExifTool },
+    Error   => {
+        Priority => 0,
+        Groups => \%allGroupsExifTool,
+        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 L<IgnoreMinorErrors|../ExifTool.html#IgnoreMinorErrors> option
+        },
+    },
+    Warning => {
+        Priority => 0,
+        Groups => \%allGroupsExifTool,
+        Notes => q{
+            returns warnings that may have occurred while reading or writing a file.
+            Use the -a or L<Duplicates|../ExifTool.html#Duplicates> option to see all warnings if more than one
+            occurred. Minor warnings may be ignored with the -m or L<IgnoreMinorErrors|../ExifTool.html#IgnoreMinorErrors>
+            option.  Minor warnings with a capital "M" in the "[Minor]" designation
+            indicate that the processing is affected by ignoring the warning
+        },
+    },
     Comment => {
         Notes => 'comment embedded in JPEG, GIF89a or PPM/PGM/PBM image',
@@ -767,41 +1101,110 @@
     },
     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
+            directory that will be created if doesn't already exist
+        },
         Writable => 1,
+        WritePseudo => 1,
+        DelCheck => q{"Can't delete"},
         Protected => 1,
+        RawConv => '$self->ConvertFileName($val)',
         # translate backslashes in directory names and add trailing '/'
-        ValueConvInv => '$_=$val; tr/\\\\/\//; m{[^/]$} and $_ .= "/"; $_',
+        ValueConvInv => '$_ = $self->InverseFileName($val); m{[^/]$} and $_ .= "/"; $_',
     },
     FileName => {
-        Groups => { 1 => 'System' },
+        Groups => { 1 => 'System', 2 => 'Other' },
         Writable => 1,
+        WritePseudo => 1,
+        DelCheck => q{"Can't delete"},
         Protected => 1,
         Notes => q{
             may be written with a full path name to set FileName and Directory in one
-            operation.  See L<filename.html|../filename.html> for more information on
-            writing the FileName and Directory tags
+            operation.  This is such a powerful feature that a TestName tag is provided
+            to allow dry-run tests before actually writing the file name.  See
+            L<filename.html|../filename.html> for more information on writing the
+            FileName, Directory and TestName tags
         },
-        ValueConvInv => '$val=~tr/\\\\/\//; $val',
+        RawConv => '$self->ConvertFileName($val)',
+        ValueConvInv => '$self->InverseFileName($val)',
+    },
+    FilePath => {
+        Groups => { 1 => 'System', 2 => 'Other' },
+        Notes => q{
+            absolute path of source file. Not generated unless specifically requested or
+            the L<RequestAll|../ExifTool.html#RequestAll> API option is set.  Does not support Windows Unicode file
+            names
+        },
+    },
+    TestName => {
+        Writable => 1,
+        WritePseudo => 1,
+        DelCheck => q{"Can't delete"},
+        Protected => 1,
+        WriteOnly => 1,
+        Notes => q{
+            this write-only tag may be used instead of FileName for dry-run tests of the
+            file renaming feature.  Writing this tag prints the old and new file names
+            to the console, but does not affect the file itself
+        },
+        ValueConvInv => '$self->InverseFileName($val)',
+    },
+    FileSequence => {
+        Groups => { 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'Other' },
+        Notes => q{
+            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 L<RequestAll|../ExifTool.html#RequestAll> 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.
+        },
         PrintConv => \&ConvertFileSize,
     },
     ResourceForkSize => {
-        Groups => { 1 => 'System' },
+        Groups => { 1 => 'System', 2 => 'Other' },
         Notes => q{
-            [Mac OS only] size of the file's resource fork if it contains data.  If this
-            tag is generated the ExtractEmbedded option may be used to extract
-            resource-fork information as a sub-document
+            size of the file's resource fork if it contains data.  Mac OS only.  If this
+            tag is generated the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> 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
         },
         PrintConv => \&ConvertFileSize,
     },
-    FileType    => { },
+    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
+        },
+        PrintConv => 'lc $val',
+    },
     FileModifyDate => {
         Description => 'File Modification Date/Time',
-        Notes => 'the filesystem modification time',
+        Notes => q{
+            the filesystem modification date/time.  Note that ExifTool may not be able
+            to handle filesystem dates before 1970 depending on the limitations of the
+            system's standard libraries
+        },
         Groups => { 1 => 'System', 2 => 'Time' },
         Writable => 1,
-        # all pseudo-tags must be protected so -tagsfromfile fails with
+        WritePseudo => 1,
+        DelCheck => q{"Can't delete"},
+        # all writable pseudo-tags must be protected so -tagsfromfile fails with
         # unrecognized files unless a pseudo tag is specified explicitly
         Protected => 1,
@@ -812,14 +1215,74 @@
         PrintConvInv => '$self->InverseDateTime($val)',
     },
+    FileAccessDate => {
+        Description => 'File Access Date/Time',
+        Notes => q{
+            the date/time of last access of the file.  Note that this access time is
+            updated whenever any software, including ExifTool, reads the file
+        },
+        Groups => { 1 => 'System', 2 => 'Time' },
+        ValueConv => 'ConvertUnixTime($val,1)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    FileCreateDate => {
+        Description => 'File Creation Date/Time',
+        Notes => q{
+            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 L<RequestAll|../ExifTool.html#RequestAll> API option is
+            set to 2 or higher.  Requires "setfile" for writing on Mac, which may be
+            installed by typing C<xcode-select --install> in the Terminal
+        },
+        Groups => { 1 => 'System', 2 => 'Time' },
+        Writable => 1,
+        WritePseudo => 1,
+        DelCheck => q{"Can't delete"},
+        Protected => 1, # all writable pseudo-tags must be protected!
+        Shift => 'Time',
+        ValueConv => '$^O eq "darwin" ? $val : ConvertUnixTime($val,1)',
+        ValueConvInv => q{
+            return GetUnixTime($val,1) if $^O eq 'MSWin32';
+            return $val if $^O eq 'darwin';
+            warn "This tag is Windows/Mac only\n";
+            return undef;
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
+    },
+    FileInodeChangeDate => {
+        Description => 'File Inode Change Date/Time',
+        Notes => q{
+            the date/time when the file's directory information was last changed.
+            Non-Windows systems only
+        },
+        Groups => { 1 => 'System', 2 => 'Time' },
+        ValueConv => 'ConvertUnixTime($val,1)',
+        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
-            this value should be done in octal, ie. "oct($filePermissions) & 0200"
+            this value should be done in octal, eg. 'oct($filePermissions#) & 0200'
         },
-        ValueConv => 'sprintf("%.3o", $val & 0777)',
+        Writable => 1,
+        WritePseudo => 1,
+        DelCheck => q{"Can't delete"},
+        Protected => 1, # all writable pseudo-tags must be protected!
+        ValueConv => 'sprintf("%.3o", $val)',
+        ValueConvInv => 'oct($val & 07777)',
         PrintConv => sub {
-            my ($mask, $str, $val) = (0400, '', oct(shift));
+            my ($mask, $val) = (0400, oct(shift));
+            my %types = (
+                0010000 => 'p',
+                0020000 => 'c',
+                0040000 => 'd',
+                0060000 => 'b',
+                0120000 => 'l',
+                0140000 => 's',
+            );
+            my $str = $types{$val & 0170000} || '-';
             while ($mask) {
                 foreach (qw(r w x)) {
@@ -830,15 +1293,149 @@
             return $str;
         },
+        PrintConvInv => sub {
+            my ($bit, $val, $str) = (8, 0, shift);
+            $str = substr($str, 1) if length($str) == 10;
+            return undef if length($str) != 9;
+            while ($bit >= 0) {
+                foreach (qw(r w x)) {
+                    $val |= (1 << $bit) if substr($str, 8-$bit, 1) eq $_;
+                    --$bit;
+                }
+            }
+            return sprintf('%.3o', $val);
+        },
     },
-    MIMEType    => { },
-    ImageWidth  => { },
-    ImageHeight => { },
-    XResolution => { },
-    YResolution => { },
-    MaxVal      => { }, # max pixel value in PPM or PGM image
+    FileAttributes => {
+        Groups => { 1 => 'System', 2 => 'Other' },
+        Notes => q{
+            extracted only if specifically requested or the L<SystemTags|../ExifTool.html#SystemTags> or L<RequestAll|../ExifTool.html#RequestAll> API
+            option is set.  2 or 3 values: 0. File type, 1. Attribute bits, 2. Windows
+            attribute bits if Win32API::File is available
+        },
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => [{ # stat device types (bitmask 0xf000)
+            0x0000 => 'Unknown',
+            0x1000 => 'FIFO',
+            0x2000 => 'Character',
+            0x3000 => 'Mux Character',
+            0x4000 => 'Directory',
+            0x5000 => 'XENIX Named',
+            0x6000 => 'Block',
+            0x7000 => 'Mux Block',
+            0x8000 => 'Regular',
+            0x9000 => 'VxFS Compressed',
+            0xa000 => 'Symbolic Link',
+            0xb000 => 'Solaris Shadow Inode',
+            0xc000 => 'Socket',
+            0xd000 => 'Solaris Door',
+            0xe000 => 'BSD Whiteout',
+        },{ BITMASK => { # stat attribute bits (bitmask 0x0e00)
+            9 => 'Sticky',
+            10 => 'Set Group ID',
+            11 => 'Set User ID',
+        }},{ BITMASK => { # Windows attribute bits
+            0 => 'Read Only',
+            1 => 'Hidden',
+            2 => 'System',
+            3 => 'Volume Label',
+            4 => 'Directory',
+            5 => 'Archive',
+            6 => 'Device',
+            7 => 'Normal',
+            8 => 'Temporary',
+            9 => 'Sparse File',
+            10 => 'Reparse Point',
+            11 => 'Compressed',
+            12 => 'Offline',
+            13 => 'Not Content Indexed',
+            14 => 'Encrypted',
+        }}],
+    },
+    FileDeviceID => {
+        Groups => { 1 => 'System', 2 => 'Other' },
+        %systemTagsNotes,
+        PrintConv => '(($val >> 24) & 0xff) . "." . ($val & 0xffffff)', # (major.minor)
+    },
+    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', 2 => 'Other' },
+        Notes => q{
+            extracted only if specifically requested or the L<SystemTags|../ExifTool.html#SystemTags> or L<RequestAll|../ExifTool.html#RequestAll> API
+            option is set.  Returns user ID number with the -n option, or name
+            otherwise.  May be written with either user name or number
+        },
+        Writable => 1,
+        WritePseudo => 1,
+        DelCheck => q{"Can't delete"},
+        Protected => 1, # all writable pseudo-tags must be protected!
+        PrintConv => 'eval { getpwuid($val) } || $val',
+        PrintConvInv => 'eval { getpwnam($val) } || ($val=~/[^0-9]/ ? undef : $val)',
+    },
+    FileGroupID => {
+        Groups => { 1 => 'System', 2 => 'Other' },
+        Notes => q{
+            extracted only if specifically requested or the L<SystemTags|../ExifTool.html#SystemTags> or L<RequestAll|../ExifTool.html#RequestAll> API
+            option is set.  Returns group ID number with the -n option, or name
+            otherwise.  May be written with either group name or number
+        },
+        Writable => 1,
+        WritePseudo => 1,
+        DelCheck => q{"Can't delete"},
+        Protected => 1, # all writable pseudo-tags must be protected!
+        PrintConv => 'eval { getgrgid($val) } || $val',
+        PrintConvInv => 'eval { getgrnam($val) } || ($val=~/[^0-9]/ ? undef : $val)',
+    },
+    FileBlockSize    => { Groups => { 1 => 'System', 2 => 'Other' }, %systemTagsNotes },
+    FileBlockCount   => { Groups => { 1 => 'System', 2 => 'Other' }, %systemTagsNotes },
+    HardLink => {
+        Writable => 1,
+        DelCheck => q{"Can't delete"},
+        WriteOnly => 1,
+        WritePseudo => 1,
+        Protected => 1,
+        Notes => q{
+            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',
+    },
+    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' },
+    YResolution => { Notes => 'the vertical pixel resolution' },
+    MaxVal      => { Notes => 'maximum pixel value in PPM or PGM image' },
     EXIF => {
-        Notes => 'the full EXIF data block from JPEG, PNG, JP2, MIE and MIFF images',
+        Notes => q{
+            the full EXIF data block from JPEG, PNG, JP2, MIE and MIFF images. This tag
+            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)/;
@@ -846,17 +1443,24 @@
         },
     },
-    ICC_Profile => {
-        Notes => 'the full ICC_Profile data block',
-        Groups => { 0 => 'ICC_Profile', 1 => 'ICC_Profile' },
-        Flags => ['Writable' ,'Protected', 'Binary'],
+    IPTC => {
+        Notes => q{
+            the full IPTC data block.  This tag is generated only if specifically
+            requested
+        },
+        Groups => { 0 => 'IPTC', 1 => 'IPTC' },
+        Flags => ['Writable', 'Protected', 'Binary', 'DelGroup'],
+        Priority => 0,  # so main IPTC (which hopefully comes first) takes priority
         WriteCheck => q{
-            require Image::ExifTool::ICC_Profile;
-            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
+            return undef if $val =~ /^(\x1c|\0+$)/;
+            return 'Invalid IPTC data';
         },
     },
     XMP => {
-        Notes => 'the full XMP data block',
+        Notes => q{
+            the XMP data block, but note that extended XMP in JPEG images may be split
+            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{
@@ -865,8 +1469,28 @@
         },
     },
+    XML => {
+        Notes => 'the XML data block, extracted for some file types',
+        Groups => { 0 => 'XML', 1 => 'XML' },
+        Binary => 1,
+    },
+    ICC_Profile => {
+        Notes => q{
+            the full ICC_Profile data block.  This tag is generated only if specifically
+            requested
+        },
+        Groups => { 0 => 'ICC_Profile', 1 => 'ICC_Profile' },
+        Flags => ['Writable' ,'Protected', 'Binary', 'DelGroup'],
+        WriteCheck => q{
+            require Image::ExifTool::ICC_Profile;
+            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
+        },
+    },
     CanonVRD => {
-        Notes => 'the full Canon DPP VRD trailer block',
+        Notes => q{
+            the full Canon DPP VRD trailer block.  This tag is generated only if
+            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{
@@ -874,4 +1498,26 @@
             return 'Invalid CanonVRD data';
         },
+    },
+    CanonDR4 => {
+        Notes => q{
+            the full Canon DPP version 4 DR4 block.  This tag is generated only if
+            specifically requested
+        },
+        Groups => { 0 => 'CanonVRD', 1 => 'CanonVRD' },
+        Flags => ['Writable' ,'Protected', 'Binary'],
+        Permanent => 0, # (this is 1 by default for MakerNotes tags)
+        WriteCheck => q{
+            return undef if $val =~ /^IIII\x04\0\x04\0/;
+            return 'Invalid CanonDR4 data';
+        },
+    },
+    Adobe => {
+        Notes => q{
+            the JPEG APP14 Adobe segment.  Extracted only if specified. See the
+            L<JPEG Adobe Tags|JPEG.html#Adobe> for more information
+        },
+        Groups => { 0 => 'APP14', 1 => 'Adobe' },
+        WriteGroup => 'Adobe',
+        Flags => ['Writable' ,'Protected', 'Binary'],
     },
     CurrentIPTCDigest => {
@@ -881,11 +1527,14 @@
             specified by the L<MWG|http://www.metadataworkinggroup.org/>.  ExifTool
             automates the handling of this tag in the MWG module -- see the
-            L<MWG Tag Name documentation|MWG.html> for details
+            L<MWG Composite Tags|MWG.html> for details
         },
         ValueConv => 'unpack("H*", $val)',
     },
     PreviewImage => {
+        Notes => 'JPEG-format embedded preview image',
+        Groups => { 2 => 'Preview' },
         Writable => 1,
         WriteCheck => '$self->CheckImage(\$val)',
+        WriteGroup => 'All',
         # can't delete, so set to empty string and return no error
         DelCheck => '$val = ""; return undef',
@@ -893,8 +1542,41 @@
         RawConv => '$self->ValidateImage(ref $val ? $val : \$val, $tag)',
     },
-    PreviewPNG  => { Binary => 1 },
+    ThumbnailImage => {
+        Groups => { 2 => 'Preview' },
+        Notes => 'JPEG-format embedded thumbnail image',
+        RawConv => '$self->ValidateImage(ref $val ? $val : \$val, $tag)',
+    },
+    OtherImage => {
+        Groups => { 2 => 'Preview' },
+        Notes => 'other JPEG-format embedded image',
+        RawConv => '$self->ValidateImage(ref $val ? $val : \$val, $tag)',
+    },
+    PreviewPNG => {
+        Groups => { 2 => 'Preview' },
+        Notes => 'PNG-format embedded preview image',
+        Binary => 1,
+    },
+    PreviewWMF => {
+        Groups => { 2 => 'Preview' },
+        Notes => 'WMF-format embedded preview image',
+        Binary => 1,
+    },
+    PreviewTIFF => {
+        Groups => { 2 => 'Preview' },
+        Notes => 'TIFF-format embedded preview image',
+        Binary => 1,
+    },
+    PreviewPDF => {
+        Groups => { 2 => 'Preview' },
+        Notes => 'PDF-format embedded preview image',
+        Binary => 1,
+    },
     ExifByteOrder => {
         Writable => 1,
-        Notes => 'only writable for newly created EXIF segments',
+        DelCheck => q{"Can't delete"},
+        Notes => q{
+            represents the byte order of EXIF information.  May be written to set the
+            byte order only for newly created EXIF segments
+        },
         PrintConv => {
             II => 'Little-endian (Intel, II)',
@@ -904,9 +1586,13 @@
     ExifUnicodeByteOrder => {
         Writable => 1,
+        WriteOnly => 1,
+        DelCheck => q{"Can't delete"},
         Notes => q{
-            the EXIF specification is particularly vague about the byte ordering for
-            Unicode text, and different applications use different conventions.  By
-            default ExifTool writes Unicode text in EXIF byte order, but this write-only
-            tag may be used to force a specific byte order
+            specifies the byte order to use when writing EXIF Unicode text.  The EXIF
+            specification is particularly vague about this byte ordering, and different
+            applications use different conventions.  By default ExifTool writes Unicode
+            text in EXIF byte order, but this write-only tag may be used to force a
+            specific order.  Applies to the EXIF UserComment tag when writing special
+            characters
         },
         PrintConv => {
@@ -918,6 +1604,16 @@
         Description => 'ExifTool Version Number',
         Groups => \%allGroupsExifTool,
+        Notes => 'the version of ExifTool currently running',
     },
-    RAFVersion => { },
+    ProcessingTime => {
+        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 L<RequestAll|../ExifTool.html#RequestAll> API
+            option is set.  Requires Time::HiRes
+        },
+        PrintConv => 'sprintf("%.3g s", $val)',
+    },
+    RAFVersion => { Notes => 'RAF file version number' },
     JPEGDigest => {
         Notes => q{
@@ -926,31 +1622,57 @@
             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
+            generated only if specifically requested or the L<RequestAll|../ExifTool.html#RequestAll> API option is set
+            to 3 or higher
         },
     },
+    JPEGQualityEstimate => {
+        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 L<RequestAll|../ExifTool.html#RequestAll> 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<RequestAll|../ExifTool.html#RequestAll> 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, ie.
-            C<"-modifydate<now">.  Not generated unless specifically requested
-        },
-        ValueConv => sub {
-            my $time = shift;
-            my @tm = localtime $time;
-            my $tz = Image::ExifTool::TimeZoneString(\@tm, $time);
-            sprintf("%4d:%.2d:%.2d %.2d:%.2d:%.2d%s", $tm[5]+1900, $tm[4]+1, $tm[3],
-                    $tm[2], $tm[1], $tm[0], $tz);
+            the current date/time.  Useful when setting the tag values, eg.
+            C<"-modifydate<now">.  Not generated unless specifically requested or the
+            L<RequestAll|../ExifTool.html#RequestAll> API option is set
         },
         PrintConv => '$self->ConvertDateTime($val)',
     },
-    ID3Size     => { },
+    NewGUID => {
+        Groups => { 0 => 'ExifTool', 1 => 'ExifTool', 2 => 'Other' },
+        Notes => q{
+            generates a new, random GUID with format
+            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 L<RequestAll|../ExifTool.html#RequestAll> API option is set
+        },
+        PrintConv => '$val =~ s/(.{8})(.{4})(.{4})(.{4})/$1-$2-$3-$4-/; $val',
+    },
+    ID3Size     => { Notes => 'size of the ID3 data block' },
     Geotag => {
         Writable => 1,
+        WriteOnly => 1,
+        WriteNothing => 1,
         AllowGroup => '(exif|gps|xmp|xmp-exif)',
         Notes => q{
             this write-only tag is used to define the GPS track log data or track log
             file name.  Currently supported track log formats are GPX, NMEA RMC/GGA/GLL,
-            KML, IGC, Garmin XML and TCX, and Magellan PMGNTRK.  See
-            L<geotag.html|../geotag.html> for details
+            KML, IGC, Garmin XML and TCX, Magellan PMGNTRK, Honeywell PTNTHPR, Winplus
+            Beacon text, and Bramor gEO log files.  May be set to the special value of
+            "DATETIMEONLY" (all caps) to set GPS date/time tags if no input track points
+            are available.  See L<geotag.html|../geotag.html> for details
         },
         DelCheck => q{
@@ -970,14 +1692,14 @@
     Geotime => {
         Writable => 1,
+        WriteOnly => 1,
         AllowGroup => '(exif|gps|xmp|xmp-exif)',
         Notes => q{
             this write-only tag is used to define a date/time for interpolating a
             position in the GPS track specified by the Geotag tag.  Writing this tag
-            causes the following 8 tags to be written:  GPSLatitude, GPSLatitudeRef,
-            GPSLongitude, GPSLongitudeRef, GPSAltitude, GPSAltitudeRef, GPSDateStamp and
-            GPSTimeStamp.  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 GPS tags.  The value of Geotag must be assigned before this tag
+            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
+            GPS tags
         },
         DelCheck => q{
@@ -994,4 +1716,6 @@
     Geosync => {
         Writable => 1,
+        WriteOnly => 1,
+        WriteNothing => 1,
         AllowGroup => '(exif|gps|xmp|xmp-exif)',
         Shift => 'Time', # enables "+=" syntax as well as "=+"
@@ -1000,8 +1724,7 @@
             synchronization with the GPS clock.  For example, set this to "-12" if the
             camera clock is 12 seconds faster than GPS time.  Input format is
-            "[+-][[[DD ]HH:]MM:]SS[.ss]".  Must be set before Geotime to be effective.
-            Additional features allow calculation of time differences and time drifts,
-            and extraction of synchronization times from image files. See the
-            L<geotagging documentation|../geotag.html> for details
+            "[+-][[[DD ]HH:]MM:]SS[.ss]".  Additional features allow calculation of time
+            differences and time drifts, and extraction of synchronization times from
+            image files.  See the L<geotagging documentation|../geotag.html> for details
         },
         ValueConvInv => q{
@@ -1010,4 +1733,30 @@
         },
     },
+    ForceWrite => {
+        Groups => { 0 => '*', 1 => '*', 2 => '*' },
+        Writable => 1,
+        WriteOnly => 1,
+        Notes => q{
+            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,
+    },
+);
+
+# tags defined by UserParam option (added at runtime)
+%Image::ExifTool::UserParam = (
+    GROUPS => { 0 => 'UserParam', 1 => 'UserParam', 2 => 'Other' },
+    PRIORITY => 0,
 );
 
@@ -1071,4 +1820,5 @@
         Format => 'int8u[2]',
         PrintConv => 'sprintf("%d.%.2d", split(" ",$val))',
+        Mandatory => 1,
     },
     2 => {
@@ -1082,4 +1832,5 @@
         },
         Priority => -1,
+        Mandatory => 1,
     },
     3 => {
@@ -1089,4 +1840,5 @@
         Priority => -1,
         RawConv => '$$self{JFIFXResolution} = $val',
+        Mandatory => 1,
     },
     5 => {
@@ -1096,11 +1848,65 @@
         Priority => -1,
         RawConv => '$$self{JFIFYResolution} = $val',
+        Mandatory => 1,
+    },
+    7 => {
+        Name => 'ThumbnailWidth',
+        RawConv => '$val ? $$self{JFIFThumbnailWidth} = $val : undef',
+    },
+    8 => {
+        Name => 'ThumbnailHeight',
+        RawConv => '$val ? $$self{JFIFThumbnailHeight} = $val : undef',
+    },
+    9 => {
+        Name => 'ThumbnailTIFF',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[3*($val{7}||0)*($val{8}||0)]',
+        Notes => 'raw RGB thumbnail data, extracted as a TIFF image',
+        RawConv => 'length($val) ? $val : undef',
+        ValueConv => sub {
+            my ($val, $et) = @_;
+            my $len = length $val;
+            return \ "Binary data $len bytes" unless $et->Options('Binary');
+            my $img = MakeTiffHeader($$et{JFIFThumbnailWidth},$$et{JFIFThumbnailHeight},3,8) . $val;
+            return \$img;
+        },
     },
 );
 %Image::ExifTool::JFIF::Extension = (
-    GROUPS => { 0 => 'JFIF', 1 => 'JFIF', 2 => 'Image' },
+    GROUPS => { 0 => 'JFIF', 1 => 'JFXX', 2 => 'Image' },
+    NOTES => 'Thumbnail images extracted from the JFXX segment.',
     0x10 => {
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        Notes => 'JPEG-format thumbnail image',
         RawConv => '$self->ValidateImage(\$val,$tag)',
+    },
+    0x11 => { # (untested)
+        Name => 'ThumbnailTIFF',
+        Groups => { 2 => 'Preview' },
+        Notes => 'raw palette-color thumbnail data, extracted as a TIFF image',
+        RawConv => '(length $val > 770 and $val !~ /^\0\0/) ? $val : undef',
+        ValueConv => sub {
+            my ($val, $et) = @_;
+            my $len = length $val;
+            return \ "Binary data $len bytes" unless $et->Options('Binary');
+            my ($w, $h) = unpack('CC', $val);
+            my $img = MakeTiffHeader($w,$h,1,8,undef,substr($val,2,768)) . substr($val,770);
+            return \$img;
+        },
+    },
+    0x13 => {
+        Name => 'ThumbnailTIFF',
+        Groups => { 2 => 'Preview' },
+        Notes => 'raw RGB thumbnail data, extracted as a TIFF image',
+        RawConv => '(length $val > 2 and $val !~ /^\0\0/) ? $val : undef',
+        ValueConv => sub {
+            my ($val, $et) = @_;
+            my $len = length $val;
+            return \ "Binary data $len bytes" unless $et->Options('Binary');
+            my ($w, $h) = unpack('CC', $val);
+            my $img = MakeTiffHeader($w,$h,3,8) . substr($val,2);
+            return \$img;
+        },
     },
 );
@@ -1115,4 +1921,6 @@
 );
 
+my %compositeID;    # lookup for new ID's of Composite tags based on original ID
+
 # static private ExifTool variables
 
@@ -1131,5 +1939,5 @@
 
 # Clean unnecessary information (line number, LF) from warning
-# Inputs: 0) warning string or undef to use current warning
+# Inputs: 0) warning string or undef to use $evalWarning
 # Returns: cleaned warning
 sub CleanWarning(;$)
@@ -1160,6 +1968,9 @@
 
     $self->ClearOptions();      # create default options hash
-    $self->{VALUE} = { };       # must initialize this for warning messages
-    $self->{DEL_GROUP} = { };   # lookup for groups to delete when writing
+    $$self{VALUE} = { };        # must initialize this for warning messages
+    $$self{PATH} = [ ];         # (this too)
+    $$self{DEL_GROUP} = { };    # lookup for groups to delete when writing
+    $$self{SAVE_COUNT} = 0;     # count calls to SaveNewValues()
+    $$self{FILE_SEQUENCE} = 0;  # sequence number for files when reading
 
     # initialize our new groups for writing
@@ -1187,6 +1998,6 @@
 #   my $info = ImageInfo($file, 'DateTimeOriginal', 'ImageSize');
 #    - or -
-#   my $exifTool = new Image::ExifTool;
-#   my $info = $exifTool->ImageInfo($file, \@tagList, {Sort=>'Group0'} );
+#   my $et = new Image::ExifTool;
+#   my $info = $et->ImageInfo($file, \@tagList, {Sort=>'Group0'} );
 sub ImageInfo($;@)
 {
@@ -1199,8 +2010,8 @@
         $self = new Image::ExifTool;
     }
-    my %saveOptions = %{$self->{OPTIONS}};  # save original options
+    my %saveOptions = %{$$self{OPTIONS}};   # save original options
 
     # initialize file information
-    $self->{FILENAME} = $self->{RAF} = undef;
+    $$self{FILENAME} = $$self{RAF} = undef;
 
     $self->ParseArguments(@_);              # parse our function arguments
@@ -1208,5 +2019,5 @@
     my $info = $self->GetInfo(undef);       # get requested information
 
-    $self->{OPTIONS} = \%saveOptions;       # restore original options
+    $$self{OPTIONS} = \%saveOptions;        # restore original options
 
     return $info;   # return requested information
@@ -1216,5 +2027,5 @@
 # Get/set ExifTool options
 # Inputs: 0) ExifTool object reference,
-#         1) Parameter name, 2) Value to set the option
+#         1) Parameter name (case insensitive), 2) Value to set the option
 #         3-N) More parameter/value pairs
 # Returns: original value of last option specified
@@ -1228,5 +2039,18 @@
     while (@_) {
         my $param = shift;
+        # fix parameter case if necessary
+        unless (exists $$options{$param}) {
+            my ($fixed) = grep /^$param$/i, keys %$options;
+            if ($fixed) {
+                $param = $fixed;
+            } else {
+                $param =~ s/^Group(\d*)$/Group$1/i;
+            }
+        }
         $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;
@@ -1267,5 +2091,101 @@
                     warn "Invalid Charset $newVal\n";
                 }
-            }
+            } elsif ($param eq 'CharsetEXIF' or $param eq 'CharsetFileName' or $param eq 'CharsetRIFF') {
+                $$options{$param} = $newVal;    # only these may be set to a false value
+            } elsif ($param eq 'CharsetQuickTime') {
+                $$options{$param} = 'MacRoman'; # QuickTime defaults to MacRoman
+            } else {
+                $$options{$param} = 'Latin';    # all others default to Latin
+            }
+        } elsif ($param eq 'UserParam') {
+            # clear options if $newVal is undef
+            defined $newVal or $$options{$param} = {}, next;
+            my $table = GetTagTable('Image::ExifTool::UserParam');
+            # allow initialization of entire UserParam hash
+            if (ref $newVal eq 'HASH') {
+                my %newParams;
+                foreach (sort keys %$newVal) {
+                    my $lcTag = lc $_;
+                    $newParams{$lcTag} = $$newVal{$_};
+                    delete $$table{$lcTag};
+                    AddTagToTable($table, $lcTag, $_);
+                }
+                $$options{$param} = \%newParams;
+                next;
+            }
+            my ($force, $paramName);
+            # set/reset single UserParam parameter
+            if ($newVal =~ /(.*?)=(.*)/s) {
+                $paramName = $1;
+                $newVal = $2;
+                $force = 1 if $paramName =~ s/\^$//;
+                $paramName =~ tr/-_a-zA-Z0-9#//dc;
+                $param = lc $paramName;
+            } else {
+                ($param = lc $newVal) =~ tr/-_a-zA-Z0-9#//dc;
+                undef $newVal;
+            }
+            delete $$table{$param};
+            $oldVal = $$options{UserParam}{$param};
+            if (defined $newVal) {
+                if (length $newVal or $force) {
+                    $$options{UserParam}{$param} = $newVal;
+                    AddTagToTable($table, $param, $paramName);
+                } else {
+                    delete $$options{UserParam}{$param};
+                }
+            }
+            # remove alternate version of tag
+            $param .= '#' unless $param =~ s/#$//;
+            delete $$table{$param};
+            delete $$options{UserParam}{$param};
+        } elsif ($param eq 'RequestTags') {
+            if (defined $newVal) {
+                # parse list from delimited string if necessary
+                my @reqList = (ref $newVal eq 'ARRAY') ? @$newVal : ($newVal =~ /[-\w?*:]+/g);
+                ExpandShortcuts(\@reqList);
+                # add to existing list
+                $$options{$param} or $$options{$param} = [ ];
+                foreach (@reqList) {
+                    /^(.*:)?([-\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 {
+                $$options{$param} = undef;  # clear the list
+            }
+        } elsif ($param eq 'ListJoin') {
+            $$options{$param} = $newVal;
+            # set the old List and ListSep options for backward compatibility
+            if (defined $newVal) {
+                $$options{List} = 0;
+                $$options{ListSep} = $newVal;
+            } else {
+                $$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') {
@@ -1281,5 +2201,13 @@
                 }
                 # must forget saved values since they depend on Escape method
-                $self->{BOTH} = { };
+                $$self{BOTH} = { };
+            } elsif ($param eq 'GlobalTimeShift') {
+                delete $$self{GLOBAL_TIME_OFFSET};  # reset our calculated offset
+            } elsif ($param eq 'TimeZone' and defined $newVal and length $newVal) {
+                $ENV{TZ} = $newVal;
+                eval { require POSIX; POSIX::tzset() };
+            } elsif ($param eq 'Validate') {
+                # load Validate module if Validate option enabled
+                $newVal and require Image::ExifTool::Validate;
             }
             $$options{$param} = $newVal;
@@ -1298,52 +2226,83 @@
 
     # create options hash with default values
-    # (commented out options don't need initializing)
     # +-----------------------------------------------------+
     # ! DON'T FORGET!!  When adding any new option, must    !
     # ! decide how it is handled in SetNewValuesFromFile()  !
     # +-----------------------------------------------------+
-    $self->{OPTIONS} = {
-    #   Binary      => undef,   # flag to extract binary values even if tag not specified
-    #   ByteOrder   => undef,   # default byte order when creating EXIF information
+    # (Note: All options must exist in this lookup, even if undefined,
+    # to facilitate case-insensitive options. 'Group#' is handled specially)
+    $$self{OPTIONS} = {
+        Binary      => undef,   # flag to extract binary values even if tag not specified
+        ByteOrder   => undef,   # default byte order when creating EXIF information
         Charset     => 'UTF8',  # character set for converting Unicode characters
+        CharsetEXIF => undef,   # internal EXIF "ASCII" string encoding
+        CharsetFileName => undef,   # external encoding for file names
         CharsetID3  => 'Latin', # internal ID3v1 character set
         CharsetIPTC => 'Latin', # fallback IPTC character set if no CodedCharacterSet
-    #   Compact     => undef,   # compact XMP and IPTC data
+        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     => { },     # 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
-    #   DateFormat  => undef,   # format for date/time
+        Compress    => undef,   # flag to write new values as compressed if possible
+        CoordFormat => undef,   # GPS lat/long coordinate format
+        DateFormat  => undef,   # format for date/time
         Duplicates  => 1,       # flag to save duplicate tag values
-    #   Escape      => undef,   # escape special characters
-    #   Exclude     => undef,   # tags to exclude
-    #   ExtractEmbedded =>undef,# flag to extract information from embedded documents
-    #   FastScan    => undef,   # flag to avoid scanning for trailer
-    #   FixBase     => undef,   # fix maker notes base offsets
-    #   GeoMaxIntSecs => undef, # geotag maximum interpolation time (secs)
-    #   GeoMaxExtSecs => undef, # geotag maximum extrapolation time (secs)
-    #   GeoMaxHDOP  => undef,   # geotag maximum HDOP
-    #   GeoMaxPDOP  => undef,   # geotag maximum PDOP
-    #   GeoMinSats  => undef,   # geotag minimum satellites
+        Escape      => undef,   # escape special characters
+        Exclude     => undef,   # tags to exclude
+        ExtendedXMP => 1,       # strategy for reading extended XMP
+        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)
+        GeoMaxHDOP  => undef,   # geotag maximum HDOP
+        GeoMaxPDOP  => undef,   # geotag maximum PDOP
+        GeoMinSats  => undef,   # geotag minimum satellites
+        GeoSpeedRef => undef,   # geotag GPSSpeedRef
+        GlobalTimeShift => undef,   # apply time shift to all extracted date/time values
     #   Group#      => undef,   # return tags for specified groups in family #
+        HexTagIDs   => 0,       # use hex tag ID's in family 7 group names
         HtmlDump    => 0,       # HTML dump (0-3, higher # = bigger limit)
-    #   HtmlDumpBase => undef,  # base address for HTML dump
-    #   IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
+        HtmlDumpBase => undef,  # base address for HTML dump
+        IgnoreMinorErrors => undef, # ignore minor errors when reading/writing
         Lang        => $defaultLang,# localized language for descriptions etc
-    #   LargeFileSupport => undef,  # flag indicating support of 64-bit file offsets
-    #   List        => undef,   # extract lists of PrintConv values into arrays
-        ListSep     => ', ',    # list item separator
-    #   ListSplit   => undef,   # regex for splitting list-type tag values when writing
-    #   MakerNotes  => undef,   # extract maker notes as a block
-    #   MissingTagValue =>undef,# value for missing tags when expanded in expressions
-    #   Password    => undef,   # password for password-protected PDF documents
+        LargeFileSupport => undef,  # flag indicating support of 64-bit file offsets
+        List        => undef,   # extract lists of PrintConv values into arrays [no longer documented]
+        ListItem    => undef,   # used to return a specific item from lists
+        ListJoin    => ', ',    # join lists together with this separator
+        ListSep     => ', ',    # list item separator [no longer documented]
+        ListSplit   => undef,   # regex for splitting list-type tag values when writing
+        MakerNotes  => undef,   # extract maker notes as a block
+        MDItemTags  => undef,   # extract MacOS metadata item tags
+        MissingTagValue =>undef,# value for missing tags when expanded in expressions
+        NoMultiExif => undef,   # raise error when writing multi-segment EXIF
+        NoPDFList   => undef,   # flag to avoid splitting PDF List-type tag values
+        Password    => undef,   # password for password-protected PDF documents
         PrintConv   => 1,       # flag to enable print conversion
-    #   SavePath    => undef,   # (undocumented) 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, Alpha, Group#)
-    #   StrictDate  => undef,   # flag to return undef for invalid date conversions
-    #   Struct      => undef,   # return structures as hash references
+        QuickTimeHandler => 1,  # 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)
+        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)
+        StrictDate  => undef,   # flag to return undef for invalid date conversions
+        Struct      => undef,   # return structures as hash references
+        SystemTags  => undef,   # extract additional File System tags
         TextOut     => \*STDOUT,# file for Verbose/HtmlDump output
+        TimeZone    => undef,   # local time zone
         Unknown     => 0,       # flag to get values of unknown tags (0-2)
+        UserParam   => { },     # user parameters for additional user-defined tag values
+        Validate    => undef,   # perform additional validation
         Verbose     => 0,       # print verbose messages (0-5, higher # = more verbose)
+        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
@@ -1370,6 +2329,9 @@
     local $_;
     my $self = shift;
-    my $options = $self->{OPTIONS};     # pointer to current options
-    my (%saveOptions, $reEntry, $rsize);
+    my $options = $$self{OPTIONS};      # pointer to current options
+    my $fast = $$options{FastScan} || 0;
+    my $req = $$self{REQ_TAG_LOOKUP};
+    my $reqAll = $$options{RequestAll} || 0;
+    my (%saveOptions, $reEntry, $rsize, $type, @startTime, $saveOrder, $isDir);
 
     # check for internal ReEntry option to allow recursive calls to ExtractInfo
@@ -1385,20 +2347,23 @@
             FILE_TYPE => $$self{FILE_TYPE},
         };
-        $self->{RAF} = new File::RandomAccess($_[0]);
+        $saveOrder = GetByteOrder(),
+        $$self{RAF} = new File::RandomAccess($_[0]);
         $$self{PROCESSED} = { };
         delete $$self{EXIF_DATA};
         delete $$self{EXIF_POS};
     } else {
-        if (defined $_[0] or $options->{HtmlDump}) {
+        if (defined $_[0] or $$options{HtmlDump} or $$req{validate}) {
             %saveOptions = %$options;       # save original options
-    
+
             # require duplicates for html dump
-            $self->Options(Duplicates => 1) if $options->{HtmlDump};
-    
+            $self->Options(Duplicates => 1) if $$options{HtmlDump};
+            # enable Validate option if Validate tag is requested
+            $self->Options(Validate => 1) if $$req{validate};
+
             if (defined $_[0]) {
                 # only initialize filename if called with arguments
-                $self->{FILENAME} = undef;  # name of file (or '' if we didn't open it)
-                $self->{RAF} = undef;       # RandomAccess object reference
-    
+                $$self{FILENAME} = undef;   # name of file (or '' if we didn't open it)
+                $$self{RAF} = undef;        # RandomAccess object reference
+
                 $self->ParseArguments(@_);  # initialize from our arguments
             }
@@ -1407,13 +2372,26 @@
         $self->Init();
 
-        delete $self->{MAKER_NOTE_FIXUP};   # fixup information for extracted maker notes
-        delete $self->{MAKER_NOTE_BYTE_ORDER};
+        delete $$self{MAKER_NOTE_FIXUP};    # fixup information for extracted maker notes
+        delete $$self{MAKER_NOTE_BYTE_ORDER};
 
         # return our version number
         $self->FoundTag('ExifToolVersion', "$VERSION$RELEASE");
-        $self->FoundTag('Now', time()) if $self->{REQ_TAG_LOOKUP}{now} or $self->{TAGS_FROM_FILE};
-    }
-    my $filename = $self->{FILENAME};   # image file name ('' if already open)
-    my $raf = $self->{RAF};             # RandomAccess object
+        $self->FoundTag('Now', $self->TimeNow()) if $$req{now} or $reqAll;
+        $self->FoundTag('NewGUID', NewGUID()) if $$req{newguid} or $reqAll;
+        # generate sequence number if necessary
+        $self->FoundTag('FileSequence', $$self{FILE_SEQUENCE}) if $$req{filesequence} or $reqAll;
+
+        if ($$req{processingtime} or $reqAll) {
+            eval { require Time::HiRes; @startTime = Time::HiRes::gettimeofday() };
+            if (not @startTime and $$req{processingtime}) {
+                $self->WarnOnce('Install Time::HiRes to generate ProcessingTime');
+            }
+        }
+
+        ++$$self{FILE_SEQUENCE};        # count files read
+    }
+
+    my $filename = $$self{FILENAME};    # image file name ('' if already open)
+    my $raf = $$self{RAF};              # RandomAccess object
 
     local *EXIFTOOL_FILE;   # avoid clashes with global namespace
@@ -1425,27 +2403,32 @@
             unless ($filename eq '-') {
                 # extract file name from pipe if necessary
-                $realname =~ /\|$/ and $realname =~ s/.*?"(.*?)".*/$1/;
-                my ($dir, $name);
-                if (eval 'require File::Basename') {
-                    $dir = File::Basename::dirname($realname);
-                    $name = File::Basename::basename($realname);
-                } else {
-                    ($name = $realname) =~ tr/\\/\//;
-                    # remove path
-                    $dir = length($1) ? $1 : '/' if $name =~ s/(.*)\///;
-                }
+                $realname =~ /\|$/ and $realname =~ s/^.*?"(.*?)".*/$1/s;
+                my ($dir, $name) = SplitFileName($realname);
                 $self->FoundTag('FileName', $name);
                 $self->FoundTag('Directory', $dir) if defined $dir and length $dir;
+                if ($$req{filepath} or
+                   ($reqAll and not $$self{EXCL_TAG_LOOKUP}{filepath}))
+                {
+                    local $SIG{'__WARN__'} = \&SetWarning;
+                    if (eval { require Cwd }) {
+                        my $path = eval { Cwd::abs_path($filename) };
+                        $self->FoundTag('FilePath', $path) if defined $path;
+                    } elsif ($$req{filepath}) {
+                        $self->WarnOnce('The Perl Cwd module must be installed to use FilePath');
+                    }
+                }
                 # get size of resource fork on Mac OS
-                $rsize = -s "$filename/rsrc" if $^O eq 'darwin' and not $$self{IN_RESOURCE};
+                $rsize = -s "$filename/..namedfork/rsrc" if $^O eq 'darwin' and not $$self{IN_RESOURCE};
             }
             # open the file
-            if (open(EXIFTOOL_FILE, $filename)) {
+            if ($self->Open(\*EXIFTOOL_FILE, $filename)) {
                 # create random access file object
                 $raf = new File::RandomAccess(\*EXIFTOOL_FILE);
                 # patch to force pipe to be buffered because seek returns success
                 # in Windows cmd shell pipe even though it really failed
-                $raf->{TESTED} = -1 if $filename eq '-' or $filename =~ /\|$/;
-                $self->{RAF} = $raf;
+                $$raf{TESTED} = -1 if $filename eq '-' or $filename =~ /\|$/;
+                $$self{RAF} = $raf;
+            } elsif ($self->IsDirectory($filename)) {
+                $isDir = 1;
             } else {
                 $self->Error('Error opening file');
@@ -1456,32 +2439,105 @@
     }
 
-    if ($raf) {
+    while ($raf or $isDir) {
+        my (@stat, $plainFile);
         if ($reEntry) {
             # we already set these tags
-        } elsif (not $raf->{FILE_PT}) {
+        } elsif (not $raf) {
+            @stat = stat $filename;
+        } elsif (not $$raf{FILE_PT}) {
             # get file size from image in memory
-            $self->FoundTag('FileSize', length ${$raf->{BUFF_PT}});
-        } elsif (-f $raf->{FILE_PT}) {
-            # get file size and last modified time if this is a plain file
-            my $fileSize = -s _;
-            my $fileTime = -M _;
-            my @stat = stat _;
-            $self->FoundTag('FileSize', $fileSize) if defined $fileSize;
-            $self->FoundTag('ResourceForkSize', $rsize) if $rsize;
-            $self->FoundTag('FileModifyDate', $^T - $fileTime*(24*3600)) if defined $fileTime;
-            $self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2];
-        }
-
+            $self->FoundTag('FileSize', length ${$$raf{BUFF_PT}});
+        } elsif (-f $$raf{FILE_PT}) {
+            # get file tags if this is a plain file
+            @stat = stat _;
+            $plainFile = 1;
+        } else {
+            @stat = stat $$raf{FILE_PT};
+        }
+        my $fileSize = $stat[7];
+        $self->FoundTag('FileSize', $stat[7]) if defined $stat[7];
+        $self->FoundTag('ResourceForkSize', $rsize) if $rsize;
+        $self->FoundTag('FileModifyDate', $stat[9]) if defined $stat[9];
+        $self->FoundTag('FileAccessDate', $stat[8]) if defined $stat[8];
+        my $cTag = $^O eq 'MSWin32' ? 'FileCreateDate' : 'FileInodeChangeDate';
+        $self->FoundTag($cTag, $stat[10]) if defined $stat[10];
+        $self->FoundTag('FilePermissions', $stat[2]) if defined $stat[2];
+        # extract more system info if SystemTags option is set
+        if (@stat) {
+            my $sys = $$options{SystemTags} || ($reqAll and not defined $$options{SystemTags});
+            if ($sys or $$req{fileattributes}) {
+                my @attr = ($stat[2] & 0xf000, $stat[2] & 0x0e00);
+                # add Windows file attributes if available
+                if ($^O eq 'MSWin32' and defined $filename and $filename ne '' and $filename ne '-') {
+                    local $SIG{'__WARN__'} = \&SetWarning;
+                    if (eval { require Win32API::File }) {
+                        my $wattr;
+                        my $file = $filename;
+                        if ($self->EncodeFileName($file)) {
+                            $wattr = eval { Win32API::File::GetFileAttributesW($file) };
+                        } else {
+                            $wattr = eval { Win32API::File::GetFileAttributes($file) };
+                        }
+                        push @attr, $wattr if defined $wattr and $wattr != 0xffffffff;
+                    }
+                }
+                $self->FoundTag('FileAttributes', "@attr");
+            }
+            $self->FoundTag('FileDeviceNumber', $stat[0]) if $sys or $$req{filedevicenumber};
+            $self->FoundTag('FileInodeNumber', $stat[1])  if $sys or $$req{fileinodenumber};
+            $self->FoundTag('FileHardLinks', $stat[3])    if $sys or $$req{filehardlinks};
+            $self->FoundTag('FileUserID', $stat[4])       if $sys or $$req{fileuserid};
+            $self->FoundTag('FileGroupID', $stat[5])      if $sys or $$req{filegroupid};
+            $self->FoundTag('FileDeviceID', $stat[6])     if $sys or $$req{filedeviceid};
+            $self->FoundTag('FileBlockSize', $stat[11])   if $sys or $$req{fileblocksize};
+            $self->FoundTag('FileBlockCount', $stat[12])  if $sys or $$req{fileblockcount};
+        }
+        # extract MDItem tags if requested (only on plain files)
+        if ($^O eq 'darwin' and defined $filename and $filename ne '' and defined $fileSize) {
+            my $reqMacOS = ($reqAll > 1 or $$req{'macos:'});
+            my $crDate = ($reqMacOS || $$req{filecreatedate});
+            my $mdItem = ($reqMacOS || $$options{MDItemTags} || grep /^mditem/, keys %$req);
+            my $xattr  = ($reqMacOS || $$options{XAttrTags}  || grep /^xattr/,  keys %$req);
+            if ($crDate or $mdItem or $xattr) {
+                require Image::ExifTool::MacOS;
+                Image::ExifTool::MacOS::GetFileCreateDate($self, $filename) if $crDate;
+                Image::ExifTool::MacOS::ExtractMDItemTags($self, $filename) if $mdItem and $plainFile;
+                Image::ExifTool::MacOS::ExtractXAttrTags($self, $filename) if $xattr;
+            }
+        }
+        # do whatever else we can with directories, then return
+        if ($isDir or (defined $stat[2] and ($stat[2] & 0170000) == 0040000)) {
+            $self->FoundTag('FileType', 'DIR');
+            $self->FoundTag('FileTypeExtension', '');
+            $self->BuildCompositeTags() if $$options{Composite};
+            $raf->Close() if $raf;
+            return 1;
+        }
         # get list of file types to check
-        my ($tiffType, %noMagic);
-        $self->{FILE_EXT} = GetFileExtension($realname);
+        my ($tiffType, %noMagic, $recognizedExt);
+        my $ext = $$self{FILE_EXT} = GetFileExtension($realname);
+        # set $recognizedExt if this file type is recognized by extension only
+        $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');
+            }
+            $self->BuildCompositeTags() if $fast == 4 and $$options{Composite};
+            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};
-            $noMagic{MXF} = 1;  # don't do magic number test on MXF or DV files
-            $noMagic{DV} = 1;
+            $tiffType = $$self{FILE_EXT};
+            unless ($fast == 3) {
+                $noMagic{MXF} = 1;  # don't do magic number test on MXF or DV files
+                $noMagic{DV} = 1;
+            }
         } else {
             # scan through all recognized file types
@@ -1493,18 +2549,28 @@
         $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 ($type, $buff, $seekErr);
-        # read first 1024 bytes of file for testing
-        $raf->Read($buff, 1024) or $buff = '';
+        my ($buff, $seekErr);
+        my %dirInfo = ( RAF => $raf, Base => $pos, TestBuff => \$buff );
+        # read start of file for testing
+        $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;
+            } elsif ($recognizedExt) {
+                $type = $recognizedExt; # set type from recognized file extension only
             } else {
-                last unless defined $type;
                 # last ditch effort to scan past unknown header for JPEG/TIFF
                 next unless $buff =~ /(\xff\xd8\xff|MM\0\x2a|II\x2a\0)/g;
@@ -1513,9 +2579,17 @@
                 $dirInfo{Base} = $pos + $skip;
                 $raf->Seek($pos + $skip, 0) or $seekErr = 1, last;
-                $self->Warn("Skipped unknown $skip byte header");
+                $self->Warn("Processing $type-like data after unknown $skip-byte header");
+                $unkHeader = 1 unless $$self{DOC_NUM};
             }
             # save file type in member variable
-            $self->{FILE_TYPE} = $self->{PATH}[0] = $type;
+            $$self{FILE_TYPE} = $type;
             $dirInfo{Parent} = ($type eq 'TIFF') ? $tiffType : $type;
+            # don't process the file when FastScan == 3
+            if ($fast == 3 and not $processType{$type}) {
+                unless ($weakMagic{$type} and (not $ext or $ext ne $type)) {
+                    $self->SetFileType($dirInfo{Parent});
+                }
+                last;
+            }
             my $module = $moduleName{$type};
             $module = $type unless defined $module;
@@ -1531,16 +2605,77 @@
                 last;
             }
+            push @{$$self{PATH}}, $type;    # save file type in metadata PATH
+
             # process the file
             no strict 'refs';
-            &$func($self, \%dirInfo) and last;
+            my $result = &$func($self, \%dirInfo);
             use strict 'refs';
 
+            pop @{$$self{PATH}};
+
+            if ($result) {  # all done if successful
+                if ($unkHeader) {
+                    $self->DeleteTag('FileType');
+                    $self->DeleteTag('FileTypeExtension');
+                    $self->DeleteTag('MIMEType');
+                    $self->VPrint(0,"Reset file type due to unknown header\n");
+                }
+                last;
+            }
             # seek back to try again from the same position in the file
             $raf->Seek($pos, 0) or $seekErr = 1, last;
+        }
+        if (not defined $type and not $$self{DOC_NUM}) {
+            # if we were given a single image with a known type there
+            # must be a format error since we couldn't read it, otherwise
+            # it is likely we don't support images of this type
+            my $fileType = GetFileType($realname) || '';
+            my $err;
+            if (not length $buff) {
+                $err = 'File is empty';
+            } else {
+                my $ch = substr($buff, 0, 1);
+                if (length $buff < 16 or $buff =~ /[^\Q$ch\E]/) {
+                    if ($fileType eq 'RAW') {
+                        $err = 'Unsupported RAW file type';
+                    } elsif ($fileType) {
+                        $err = 'File format error';
+                    } else {
+                        $err = 'Unknown file type';
+                    }
+                } else {
+                    # provide some insight into the content of some corrupted files
+                    if ($$self{OPTIONS}{FastScan}) {
+                        $err = 'File header is all';
+                    } else {
+                        my $num = 0;
+                        for (;;) {
+                            $raf->Read($buff, 65536) or undef($num), last;
+                            $buff =~ /[^\Q$ch\E]/g and $num += pos($buff) - 1, last;
+                            $num += length($buff);
+                        }
+                        if ($num) {
+                            $err = 'First ' . ConvertFileSize($num) . ' of file is';
+                        } else {
+                            $err = 'Entire file is';
+                        }
+                    }
+                    if ($ch eq "\0") {
+                        $err .= ' binary zeros';
+                    } elsif ($ch eq ' ') {
+                        $err .= ' ASCII spaces';
+                    } elsif ($ch =~ /[a-zA-Z0-9]/) {
+                        $err .= " ASCII '${ch}' characters";
+                    } else {
+                        $err .= sprintf(" binary 0x%.2x's", ord $ch);
+                    }
+                }
+            }
+            $self->Error($err);
         }
         if ($seekErr) {
             $self->Error('Error seeking in file');
         } elsif ($self->Options('ScanForXMP') and (not defined $type or
-            (not $self->Options('FastScan') and not $$self{FoundXMP})))
+            (not $fast and not $$self{FoundXMP})))
         {
             # scan for XMP
@@ -1549,41 +2684,29 @@
             Image::ExifTool::XMP::ScanForXMP($self, $raf) and $type = '';
         }
-        unless (defined $type) {
-            # if we were given a single image with a known type there
-            # must be a format error since we couldn't read it, otherwise
-            # it is likely we don't support images of this type
-            my $fileType = GetFileType($realname);
-            my $err;
-            if (not $fileType) {
-                $err = 'Unknown file type';
-            } elsif ($fileType eq 'RAW') {
-                $err = 'Unsupported RAW file type';
-            } else {
-                $err = 'File format error';
-            }
-            $self->Error($err);
-        }
         # extract binary EXIF data block only if requested
-        if (defined $self->{EXIF_DATA} and length $$self{EXIF_DATA} > 16 and
-            ($self->{REQ_TAG_LOOKUP}{exif} or $self->{OPTIONS}{Binary}))
+        if (defined $$self{EXIF_DATA} and length $$self{EXIF_DATA} > 16 and
+            ($$req{exif} or
+            # (not extracted normally, so check TAGS_FROM_FILE)
+            ($$self{TAGS_FROM_FILE} and not $$self{EXCL_TAG_LOOKUP}{exif})))
         {
-            $self->FoundTag('EXIF', $self->{EXIF_DATA});
+            $self->FoundTag('EXIF', $$self{EXIF_DATA});
         }
         unless ($reEntry) {
-            $self->{PATH} = [ ];    # reset PATH
+            $$self{PATH} = [ ];     # reset PATH
             # calculate Composite tags
-            $self->BuildCompositeTags() if $options->{Composite};
+            $self->BuildCompositeTags() if $$options{Composite};
             # do our HTML dump if requested
-            if ($self->{HTML_DUMP}) {
+            if ($$self{HTML_DUMP}) {
                 $raf->Seek(0, 2);   # seek to end of file
-                $self->{HTML_DUMP}->FinishTiffDump($self, $raf->Tell());
-                my $pos = $options->{HtmlDumpBase};
-                $pos = ($self->{FIRST_EXIF_POS} || 0) unless defined $pos;
-                my $dataPt = defined $self->{EXIF_DATA} ? \$self->{EXIF_DATA} : undef;
-                undef $dataPt if defined $self->{EXIF_POS} and $pos != $self->{EXIF_POS};
-                my $success = $self->{HTML_DUMP}->Print($raf, $dataPt, $pos,
-                    $options->{TextOut}, $options->{HtmlDump},
-                    $self->{FILENAME} ? "HTML Dump ($self->{FILENAME})" : 'HTML Dump');
-                $self->Warn("Error reading $self->{HTML_DUMP}{ERROR}") if $success < 0;
+                $$self{HTML_DUMP}->FinishTiffDump($self, $raf->Tell());
+                my $pos = $$options{HtmlDumpBase};
+                $pos = ($$self{FIRST_EXIF_POS} || 0) unless defined $pos;
+                my $dataPt = defined $$self{EXIF_DATA} ? \$$self{EXIF_DATA} : undef;
+                undef $dataPt if defined $$self{EXIF_POS} and $pos != $$self{EXIF_POS};
+                undef $dataPt if $$self{ExtendedEXIF}; # can't use EXIF block if not contiguous
+                my $success = $$self{HTML_DUMP}->Print($raf, $dataPt, $pos,
+                    $$options{TextOut}, $$options{HtmlDump},
+                    $$self{FILENAME} ? "HTML Dump ($$self{FILENAME})" : 'HTML Dump');
+                $self->Warn("Error reading $$self{HTML_DUMP}{ERROR}") if $success < 0;
             }
         }
@@ -1591,7 +2714,7 @@
             $raf->Close();  # close the file if we opened it
             # process the resource fork as an embedded file on Mac filesystems
-            if ($rsize and $options->{ExtractEmbedded}) {
+            if ($rsize and $$options{ExtractEmbedded}) {
                 local *RESOURCE_FILE;
-                if (open(RESOURCE_FILE, "$filename/rsrc")) {
+                if ($self->Open(\*RESOURCE_FILE, "$filename/..namedfork/rsrc")) {
                     $$self{DOC_NUM} = $$self{DOC_COUNT} + 1;
                     $$self{IN_RESOURCE} = 1;
@@ -1604,15 +2727,40 @@
             }
         }
+        last;   # (loop was a cheap "goto")
+    }
+
+    # generate Validate tag if requested
+    if ($$options{Validate} and not $reEntry) {
+        Image::ExifTool::Validate::FinishValidate($self, $$req{validate});
+    }
+
+    @startTime and $self->FoundTag('ProcessingTime', Time::HiRes::tv_interval(\@startTime));
+
+    # add user-defined parameters that ended with '!'
+    if (%{$$options{UserParam}}) {
+        my $doMsg = $$options{Verbose};
+        my $table = GetTagTable('Image::ExifTool::UserParam');
+        foreach (sort keys %{$$options{UserParam}}) {
+            next unless /#$/;
+            if ($doMsg) {
+                $self->VPrint(0, "UserParam tags:\n");
+                undef $doMsg;
+            }
+            $self->HandleTag($table, $_, $$options{UserParam}{$_});
+        }
     }
 
     # restore original options
-    %saveOptions and $self->{OPTIONS} = \%saveOptions;
+    %saveOptions and $$self{OPTIONS} = \%saveOptions;
 
     if ($reEntry) {
         # restore necessary members when exiting re-entrant code
         $$self{$_} = $$reEntry{$_} foreach keys %$reEntry;
-    }
-
-    return exists $self->{VALUE}{Error} ? 0 : 1;
+        SetByteOrder($saveOrder);
+    }
+
+    # ($type may be undef without an Error when processing sub-documents)
+    return 0 if not defined $type or exists $$self{VALUE}{Error};
+    return 1;
 }
 
@@ -1633,16 +2781,16 @@
 
     unless (@_ and not defined $_[0]) {
-        %saveOptions = %{$self->{OPTIONS}}; # save original options
+        %saveOptions = %{$$self{OPTIONS}}; # save original options
         # must set FILENAME so it isn't parsed from the arguments
-        $self->{FILENAME} = '' unless defined $self->{FILENAME};
+        $$self{FILENAME} = '' unless defined $$self{FILENAME};
         $self->ParseArguments(@_);
     }
 
     # get reference to list of tags for which we will return info
-    my ($rtnTags, $byValue) = $self->SetFoundTags();
+    my ($rtnTags, $byValue, $wildTags) = $self->SetFoundTags();
 
     # build hash of tag information
     my (%info, %ignored);
-    my $conv = $self->{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv';
+    my $conv = $$self{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv';
     foreach (@$rtnTags) {
         my $val = $self->GetValue($_, $conv);
@@ -1652,5 +2800,5 @@
 
     # override specified tags with ValueConv value if necessary
-    if (@$byValue and $conv ne 'ValueConv') {
+    if (@$byValue) {
         # first determine the number of times each non-ValueConv value is used
         my %nonVal;
@@ -1665,9 +2813,9 @@
             # generate a new tag key like "Tag #" or "Tag #(1)"
             $vtag =~ s/( |$)/ #/;
-            unless (defined $self->{VALUE}->{$vtag}) {
-                $self->{VALUE}{$vtag} = $self->{VALUE}{$tag};
-                $self->{TAG_INFO}{$vtag} = $self->{TAG_INFO}{$tag};
-                $self->{TAG_EXTRA}{$vtag} = $self->{TAG_EXTRA}{$tag};
-                $self->{FILE_ORDER}{$vtag} = $self->{FILE_ORDER}{$tag};
+            unless (defined $$self{VALUE}{$vtag}) {
+                $$self{VALUE}{$vtag} = $$self{VALUE}{$tag};
+                $$self{TAG_INFO}{$vtag} = $$self{TAG_INFO}{$tag};
+                $$self{TAG_EXTRA}{$vtag} = $$self{TAG_EXTRA}{$tag};
+                $$self{FILE_ORDER}{$vtag} = $$self{FILE_ORDER}{$tag};
                 # remove existing PrintConv entry unless we are using it too
                 delete $info{$tag} unless $nonVal{$tag};
@@ -1679,59 +2827,43 @@
 
     # remove ignored tags from the list
-    my $reqTags = $self->{REQUESTED_TAGS} || [ ];
-    if (%ignored and not @$reqTags) {
-        my @goodTags;
-        foreach (@$rtnTags) {
-            push @goodTags, $_ unless $ignored{$_};
-        }
-        $rtnTags = $self->{FOUND_TAGS} = \@goodTags;
+    my $reqTags = $$self{REQUESTED_TAGS} || [ ];
+    if (%ignored) {
+        if (not @$reqTags) {
+            my @goodTags;
+            foreach (@$rtnTags) {
+                push @goodTags, $_ unless $ignored{$_};
+            }
+            $rtnTags = $$self{FOUND_TAGS} = \@goodTags;
+        } elsif (@$wildTags) {
+            # only remove tags specified by wildcard
+            my @goodTags;
+            my $i = 0;
+            foreach (@$rtnTags) {
+                if (@$wildTags and $i == $$wildTags[0]) {
+                    shift @$wildTags;
+                    push @goodTags, $_ unless $ignored{$_};
+                } else {
+                    push @goodTags, $_;
+                }
+                ++$i;
+            }
+            $rtnTags = $$self{FOUND_TAGS} = \@goodTags;
+        }
     }
 
     # return sorted tag list if provided with a list reference
-    if ($self->{IO_TAG_LIST}) {
+    if ($$self{IO_TAG_LIST}) {
         # use file order by default if no tags specified
         # (no such thing as 'Input' order in this case)
-        my $sortOrder = $self->{OPTIONS}{Sort};
-        unless (@$reqTags or ($sortOrder and $sortOrder ne 'Input')) {
-            $sortOrder = 'File';
-        }
+        my $sort = $$self{OPTIONS}{Sort};
+        $sort = 'File' unless @$reqTags or ($sort and $sort ne 'Input');
         # return tags in specified sort order
-        @{$self->{IO_TAG_LIST}} = $self->GetTagList($rtnTags, $sortOrder);
+        @{$$self{IO_TAG_LIST}} = $self->GetTagList($rtnTags, $sort, $$self{OPTIONS}{Sort2});
     }
 
     # restore original options
-    %saveOptions and $self->{OPTIONS} = \%saveOptions;
+    %saveOptions and $$self{OPTIONS} = \%saveOptions;
 
     return \%info;
-}
-
-#------------------------------------------------------------------------------
-# Combine information from a list of info hashes
-# Unless Duplicates is enabled, first entry found takes priority
-# Inputs: 0) ExifTool object reference, 1-N) list of info hash references
-# Returns: Combined information hash reference
-sub CombineInfo($;@)
-{
-    local $_;
-    my $self = shift;
-    my (%combinedInfo, $info, $tag, %haveInfo);
-
-    if ($self->{OPTIONS}{Duplicates}) {
-        while ($info = shift) {
-            foreach $tag (keys %$info) {
-                $combinedInfo{$tag} = $$info{$tag};
-            }
-        }
-    } else {
-        while ($info = shift) {
-            foreach $tag (keys %$info) {
-                my $tagName = GetTagName($tag);
-                next if $haveInfo{$tagName};
-                $haveInfo{$tagName} = 1;
-                $combinedInfo{$tag} = $$info{$tag};
-            }
-        }
-    }
-    return \%combinedInfo;
 }
 
@@ -1740,9 +2872,10 @@
 #         1) [optional] reference to info hash or tag list ref (default is found tags)
 #         2) [optional] sort order ('File', 'Input', ...)
+#         3) [optional] secondary sort order
 # Returns: List of tags in specified order
-sub GetTagList($;$$)
+sub GetTagList($;$$$)
 {
     local $_;
-    my ($self, $info, $sortOrder) = @_;
+    my ($self, $info, $sort, $sort2) = @_;
 
     my $foundTags;
@@ -1753,5 +2886,5 @@
         $foundTags = $info;
     }
-    my $fileOrder = $self->{FILE_ORDER};
+    my $fileOrder = $$self{FILE_ORDER};
 
     if ($foundTags) {
@@ -1763,15 +2896,15 @@
         }
     } else {
-        $sortOrder = $info if $info and not $sortOrder;
-        $foundTags = $self->{FOUND_TAGS} || $self->SetFoundTags() or return undef;
-    }
-    $sortOrder or $sortOrder = $self->{OPTIONS}{Sort};
+        $sort = $info if $info and not $sort;
+        $foundTags = $$self{FOUND_TAGS} || $self->SetFoundTags() or return undef;
+    }
+    $sort or $sort = $$self{OPTIONS}{Sort};
 
     # return original list if no sort order specified
-    return @$foundTags unless $sortOrder and $sortOrder ne 'Input';
-
-    if ($sortOrder eq 'Alpha') {
+    return @$foundTags unless $sort and $sort ne 'Input';
+
+    if ($sort eq 'Tag' or $sort eq 'Alpha') {
         return sort @$foundTags;
-    } elsif ($sortOrder =~ /^Group(\d*(:\d+)*)/) {
+    } elsif ($sort =~ /^Group(\d*(:\d+)*)/) {
         my $family = $1 || 0;
         # want to maintain a basic file order with the groups
@@ -1786,6 +2919,19 @@
             $groupOrder{$tag} = $num;
         }
+        $sort2 or $sort2 = $$self{OPTIONS}{Sort2};
+        if ($sort2) {
+            if ($sort2 eq 'Tag' or $sort2 eq 'Alpha') {
+                return sort { $groupOrder{$a} <=> $groupOrder{$b} or $a cmp $b } @$foundTags;
+            } elsif ($sort2 eq 'Descr') {
+                my $desc = $self->GetDescriptions($foundTags);
+                return sort { $groupOrder{$a} <=> $groupOrder{$b} or
+                              $$desc{$a} cmp $$desc{$b} } @$foundTags;
+            }
+        }
         return sort { $groupOrder{$a} <=> $groupOrder{$b} or
                       $$fileOrder{$a} <=> $$fileOrder{$b} } @$foundTags;
+    } elsif ($sort eq 'Descr') {
+        my $desc = $self->GetDescriptions($foundTags);
+        return sort { $$desc{$a} cmp $$desc{$b} } @$foundTags;
     } else {
         return sort { $$fileOrder{$a} <=> $$fileOrder{$b} } @$foundTags;
@@ -1796,12 +2942,13 @@
 # Get list of found tags in specified sort order
 # Inputs: 0) ExifTool object reference, 1) sort order ('File', 'Input', ...)
+#         2) secondary sort order
 # Returns: List of tag keys in specified order
 # Notes: If not specified, sort order is taken from OPTIONS
-sub GetFoundTags($;$)
+sub GetFoundTags($;$$)
 {
     local $_;
-    my ($self, $sortOrder) = @_;
-    my $foundTags = $self->{FOUND_TAGS} || $self->SetFoundTags() or return undef;
-    return $self->GetTagList($foundTags, $sortOrder);
+    my ($self, $sort, $sort2) = @_;
+    my $foundTags = $$self{FOUND_TAGS} || $self->SetFoundTags() or return undef;
+    return $self->GetTagList($foundTags, $sort, $sort2);
 }
 
@@ -1819,6 +2966,7 @@
 # Get tag value
 # Inputs: 0) ExifTool object reference
-#         1) tag key (or flattened tagInfo for getting field values, not part of public API)
-#         2) [optional] Value type: PrintConv, ValueConv, Both or Raw, the default
+#         1) tag key or tag name with optional group names (case sensitive)
+#            (or flattened tagInfo for getting field values, not part of public API)
+#         2) [optional] Value type: PrintConv, ValueConv, Both, Raw or Rational, the default
 #            is PrintConv or ValueConv, depending on the PrintConv option setting
 #         3) raw field value (not part of public API)
@@ -1830,12 +2978,33 @@
     my ($self, $tag, $type) = @_; # plus: ($fieldValue)
     my (@convTypes, $tagInfo, $valueConv, $both);
-
+    my $rawValue = $$self{VALUE};
+
+    # get specific tag key if tag has a group name
+    if ($tag =~ /^(.*):(.+)/) {
+        my ($gp, $tg) = ($1, $2);
+        my ($i, $key, @keys);
+        # build list of tag keys in the order of priority (no index
+        # is top priority, otherwise higher index is higher priority)
+        for ($key=$tg, $i=$$self{DUPL_TAG}{$tg} || 0; ; --$i) {
+            push @keys, $key if defined $$rawValue{$key};
+            last if $i <= 0;
+            $key = "$tg ($i)";
+        }
+        if (@keys) {
+            $key = $self->GroupMatches($gp, \@keys);
+            $tag = $key if $key;
+        }
+    }
     # figure out what conversions to do
-    $type or $type = $self->{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv';
+    if ($type) {
+        return $$self{RATIONAL}{$tag} if $type eq 'Rational';
+    } else {
+        $type = $$self{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv';
+    }
 
     # start with the raw value
-    my $value = $self->{VALUE}{$tag};
+    my $value = $$rawValue{$tag};
     if (not defined $value) {
-        return wantarray ? () : undef unless ref $tag;
+        return () unless ref $tag;
         # get the value of a structure field
         $tagInfo = $tag;
@@ -1848,5 +3017,5 @@
         }
     } else {
-        $tagInfo = $self->{TAG_INFO}{$tag};
+        $tagInfo = $$self{TAG_INFO}{$tag};
         if ($$tagInfo{Struct} and ref $value) {
             # must load XMPStruct.pl just in case (should already be loaded if
@@ -1856,5 +3025,5 @@
             # convert strucure field values
             unless ($type eq 'Both') {
-                # (note: ConvertStruct handles the escape too if necessary)
+                # (note: ConvertStruct handles the filtering and escaping too if necessary)
                 return Image::ExifTool::XMP::ConvertStruct($self,$tagInfo,$value,$type);
             }
@@ -1866,5 +3035,5 @@
         if ($type ne 'Raw') {
             # use values we calculated already if we stored them
-            $both = $self->{BOTH}{$tag};
+            $both = $$self{BOTH}{$tag};
             if ($both) {
                 if ($type eq 'PrintConv') {
@@ -1887,5 +3056,5 @@
     foreach $convType (@convTypes) {
         # don't convert a scalar reference or structure
-        last if ref $value eq 'SCALAR';
+        last if ref $value eq 'SCALAR' and not $$tagInfo{ConvertBinary};
         my $conv = $$tagInfo{$convType};
         unless (defined $conv) {
@@ -1895,5 +3064,5 @@
             } else {
                 # use PRINT_CONV from tag table if PrintConv doesn't exist
-                next unless defined($conv = $tagInfo->{Table}{PRINT_CONV});
+                next unless defined($conv = $$tagInfo{Table}{PRINT_CONV});
                 next if exists $$tagInfo{$convType};
             }
@@ -1906,5 +3075,5 @@
             $convList = $conv;
             $conv = $$convList[0];
-            my @valList = split ' ', $value;
+            my @valList = (ref $value eq 'ARRAY') ? @$value : split ' ', $value;
             # reorganize list if specified (Note: The writer currently doesn't
             # relist values, so they may be grouped but the order must not change)
@@ -1928,10 +3097,15 @@
                 $value = \@valList;
             }
+            return () unless @$value;
         }
         # initialize array so we can iterate over values in list
         if (ref $value eq 'ARRAY') {
-            $i = 0;
-            $vals = $value;
-            $val = $$vals[0];
+            if (defined $$tagInfo{RawJoin}) {
+                $val = join ' ', @$value;
+            } else {
+                $i = 0;
+                $vals = $value;
+                $val = $$vals[0];
+            }
         } else {
             $val = $value;
@@ -1945,11 +3119,17 @@
                     my $oldEscape = $$self{ESCAPE_PROC};
                     delete $$self{ESCAPE_PROC};
+                    # temporarily delete filter so it isn't applied to the Require'd values
+                    my $oldFilter = $$self{OPTIONS}{Filter};
+                    delete $$self{OPTIONS}{Filter};
                     foreach (keys %$val) {
-                        $raw[$_] = $self->{VALUE}{$$val{$_}};
+                        next unless defined $$val{$_};
+                        $raw[$_] = $$rawValue{$$val{$_}};
                         ($val[$_], $prt[$_]) = $self->GetValue($$val{$_}, 'Both');
-                        next if defined $val[$_] or not $tagInfo->{Require}{$_};
+                        next if defined $val[$_] or not $$tagInfo{Require}{$_};
+                        $$self{OPTIONS}{Filter} = $oldFilter if defined $oldFilter;
                         $$self{ESCAPE_PROC} = $oldEscape;
-                        return wantarray ? () : undef;
+                        return ();
                     }
+                    $$self{OPTIONS}{Filter} = $oldFilter if defined $oldFilter;
                     $$self{ESCAPE_PROC} = $oldEscape;
                     # set $val to $val[0], or \@val for a CODE ref conversion
@@ -1958,39 +3138,41 @@
                 if (ref $conv eq 'HASH') {
                     # look up converted value in hash
-                    my $lc;
-                    if (defined($value = $$conv{$val})) {
-                        # override with our localized language PrintConv if available
-                        if ($$self{CUR_LANG} and $convType eq 'PrintConv' and
-                            # (no need to check for lang-alt tag names -- they won't have a PrintConv)
-                            ref($lc = $self->{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
-                            ($lc = $$lc{PrintConv}) and ($lc = $$lc{$value}))
-                        {
-                            $value = $self->Decode($lc, 'UTF8');
+                    if (not defined($value = $$conv{$val})) {
+                        if ($$conv{BITMASK}) {
+                            $value = DecodeBits($val, $$conv{BITMASK}, $$tagInfo{BitsPerWord});
+                        } else {
+                             # use alternate conversion routine if available
+                            if ($$conv{OTHER}) {
+                                local $SIG{'__WARN__'} = \&SetWarning;
+                                undef $evalWarning;
+                                $value = &{$$conv{OTHER}}($val, undef, $conv);
+                                $self->Warn("$convType $tag: " . CleanWarning()) if $evalWarning;
+                            }
+                            if (not defined $value) {
+                                if ($$tagInfo{PrintHex} and $val and IsInt($val) and
+                                    $convType eq 'PrintConv')
+                                {
+                                    $value = sprintf('Unknown (0x%x)',$val);
+                                } else {
+                                    $value = "Unknown ($val)";
+                                }
+                            }
                         }
-                    } else {
-                        if ($$conv{BITMASK}) {
-                            $value = DecodeBits($val, $$conv{BITMASK});
-                            # override with localized language strings
-                            if (defined $value and $$self{CUR_LANG} and $convType eq 'PrintConv' and
-                                ref($lc = $self->{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
-                                ($lc = $$lc{PrintConv}))
-                            {
-                                my @vals = split ', ', $value;
-                                foreach (@vals) {
-                                    $_ = $$lc{$_} if defined $$lc{$_};
-                                }
-                                $value = join ', ', @vals;
+                    }
+                    # override with our localized language PrintConv if available
+                    my $tmp;
+                    if ($$self{CUR_LANG} and $convType eq 'PrintConv' and
+                        # (no need to check for lang-alt tag names -- they won't have a PrintConv)
+                        ref($tmp = $$self{CUR_LANG}{$$tagInfo{Name}}) eq 'HASH' and
+                        ($tmp = $$tmp{PrintConv}))
+                    {
+                        if ($$conv{BITMASK} and not defined $$conv{$val}) {
+                            my @vals = split ', ', $value;
+                            foreach (@vals) {
+                                $_ = $$tmp{$_} if defined $$tmp{$_};
                             }
-                        } elsif (not $$conv{OTHER} or
-                                 # use alternate conversion routine if available
-                                 not defined($value = &{$$conv{OTHER}}($val, undef, $conv)))
-                        {
-                            if (($$tagInfo{PrintHex} or
-                                ($$tagInfo{Mask} and not defined $$tagInfo{PrintHex}))
-                                and $val and IsInt($val) and $convType eq 'PrintConv')
-                            {
-                                $val = sprintf('0x%x',$val);
-                            }
-                            $value = "Unknown ($val)";
+                            $value = join ', ', @vals;
+                        } elsif (defined($tmp = $$tmp{$value})) {
+                            $value = $self->Decode($tmp, 'UTF8');
                         }
                     }
@@ -2012,4 +3194,9 @@
             }
             last unless $vals;
+            # must store a separate copy of each binary data value in the list
+            if (ref $value eq 'SCALAR') {
+                my $tval = $$value;
+                $value = \$tval;
+            }
             # save this converted value and step to next value in list
             push @values, $value if defined $value;
@@ -2019,8 +3206,15 @@
             }
             $val = $$vals[$i];
-            $conv = $$convList[$i] if $convList;
+            if ($convList) {
+                my $nextConv = $$convList[$i];
+                if ($nextConv and $nextConv eq 'REPEAT') {
+                    undef $convList;
+                } else {
+                    $conv = $nextConv;
+                }
+            }
         }
         # return undefined now if no value
-        return wantarray ? () : undef unless defined $value;
+        return () unless defined $value;
         # join back into single value if split for conversion list
         if ($convList and ref $value eq 'ARRAY') {
@@ -2031,5 +3225,5 @@
         # save both (unescaped) values because we often need them again
         # (Composite tags need "Both" and often Require one tag for various Composite tags)
-        $self->{BOTH}{$tag} = [ $valueConv, $value ] unless $both;
+        $$self{BOTH}{$tag} = [ $valueConv, $value ] unless $both;
         # escape values if necessary
         if ($$self{ESCAPE_PROC}) {
@@ -2044,4 +3238,5 @@
             $valueConv = $value;
         }
+        $self->Filter($$self{OPTIONS}{Filter}, \$value);
         # return Both values as a list (ValueConv, PrintConv)
         return ($valueConv, $value);
@@ -2050,11 +3245,18 @@
     DoEscape($value, $$self{ESCAPE_PROC}) if $$self{ESCAPE_PROC};
 
+    # filter if necessary
+    $self->Filter($$self{OPTIONS}{Filter}, \$value) if $$self{OPTIONS}{Filter} and $type eq 'PrintConv';
+
     if (ref $value eq 'ARRAY') {
-        # return array if requested
-        return @$value if wantarray;
-        # return list reference for Raw, ValueConv or if List or not a list of scalars
-        return $value if $type ne 'PrintConv' or $self->{OPTIONS}{List} or ref $$value[0];
-        # otherwise join in comma-separated string
-        $value = join $self->{OPTIONS}{ListSep}, @$value;
+        if (defined $$self{OPTIONS}{ListItem}) {
+            $value = $$value[$$self{OPTIONS}{ListItem}];
+        } elsif (wantarray) {
+            # return array if requested
+            return @$value;
+        } elsif ($type eq 'PrintConv' and not $$self{OPTIONS}{List} and not ref $$value[0]) {
+            # join PrintConv values in comma-separated string if List option not used
+            # and list contains simple scalars (otherwise return ARRAY ref)
+            $value = join $$self{OPTIONS}{ListSep}, @$value;
+        }
     }
     return $value;
@@ -2064,35 +3266,13 @@
 # Get tag identification number
 # Inputs: 0) ExifTool object reference, 1) tag key
-# Returns: Scalar context: Tag ID if available, otherwise ''
-#          List context: 0) Tag ID (or ''), 1) language code (or undef)
+# Returns: Scalar context: tag ID if available, otherwise ''
+#          List context: 0) tag ID (or ''), 1) language code (or undef)
 sub GetTagID($$)
 {
     my ($self, $tag) = @_;
-    my $tagInfo = $self->{TAG_INFO}{$tag};
+    my $tagInfo = $$self{TAG_INFO}{$tag};
     return '' unless $tagInfo and defined $$tagInfo{TagID};
     return ($$tagInfo{TagID}, $$tagInfo{LangCode}) if wantarray;
     return $$tagInfo{TagID};
-}
-
-#------------------------------------------------------------------------------
-# Get tag table name
-# Inputs: 0) ExifTool object reference, 1) tag key
-# Returns: Table name if available, otherwise ''
-sub GetTableName($$)
-{
-    my ($self, $tag) = @_;
-    my $tagInfo = $self->{TAG_INFO}{$tag} or return '';
-    return $tagInfo->{Table}{SHORT_NAME};
-}
-
-#------------------------------------------------------------------------------
-# Get tag index number
-# Inputs: 0) ExifTool object reference, 1) tag key
-# Returns: Table index number, or undefined if this tag isn't indexed
-sub GetTagIndex($$)
-{
-    my ($self, $tag) = @_;
-    my $tagInfo = $self->{TAG_INFO}{$tag} or return undef;
-    return $$tagInfo{Index};
 }
 
@@ -2107,10 +3287,10 @@
     my ($self, $tag) = @_;
     my ($desc, $name);
-    my $tagInfo = $self->{TAG_INFO}{$tag};
+    my $tagInfo = $$self{TAG_INFO}{$tag};
     # ($tagInfo won't be defined for missing tags extracted with -f)
     if ($tagInfo) {
         # use alternate language description if available
         while ($$self{CUR_LANG}) {
-            $desc = $self->{CUR_LANG}{$$tagInfo{Name}};
+            $desc = $$self{CUR_LANG}{$$tagInfo{Name}};
             if ($desc) {
                 # must look up Description if this tag also has a PrintConv
@@ -2120,5 +3300,5 @@
                 last unless $$tagInfo{LangCode} and
                     ($name = $$tagInfo{Name}) =~ s/-$$tagInfo{LangCode}$// and
-                    $desc = $self->{CUR_LANG}{$name};
+                    $desc = $$self{CUR_LANG}{$name};
                 $desc = $$desc{Description} or last if ref $desc;
                 $desc .= " ($$tagInfo{LangCode})";
@@ -2144,14 +3324,15 @@
 # Inputs: 0) ExifTool object reference
 #         1) tag key (or reference to tagInfo hash, not part of the public API)
-#         2) [optional] group family (-1 to get extended group list)
-# Returns: Scalar context: Group name (for family 0 if not otherwise specified)
-#          Array context: Group name if family specified, otherwise list of
+#         2) [optional] group family (-1 to get extended group list, or multiple
+#            families separated by colons to return multiple groups as a string)
+# 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 (ie. '1:2')
+# Notes: Multiple families may be specified with ':' in family argument (eg. '1:2')
 sub GetGroup($$;$)
 {
     local $_;
     my ($self, $tag, $family) = @_;
-    my ($tagInfo, @groups, @families, $simplify, $byTagInfo);
+    my ($tagInfo, @groups, @families, $simplify, $byTagInfo, $ex, $noID);
     if (ref $tag eq 'HASH') {
         $tagInfo = $tag;
@@ -2160,5 +3341,6 @@
         $byTagInfo = 1;
     } else {
-        $tagInfo = $self->{TAG_INFO}{$tag} or return '';
+        $tagInfo = $$self{TAG_INFO}{$tag} || { };
+        $ex = $$self{TAG_EXTRA}{$tag};
     }
     my $groups = $$tagInfo{Groups};
@@ -2166,12 +3348,10 @@
     # (after this, Groups 0-2 in tagInfo are guaranteed to be defined)
     unless ($$tagInfo{GotGroups}) {
-        my $tagTablePtr = $$tagInfo{Table};
-        if ($tagTablePtr) {
-            # construct our group list
-            $groups or $groups = $$tagInfo{Groups} = { };
-            # fill in default groups
-            foreach (keys %{$$tagTablePtr{GROUPS}}) {
-                $$groups{$_} or $$groups{$_} = $tagTablePtr->{GROUPS}{$_};
-            }
+        my $tagTablePtr = $$tagInfo{Table} || { GROUPS => { } };
+        # construct our group list
+        $groups or $groups = $$tagInfo{Groups} = { };
+        # fill in default groups
+        foreach (0..2) {
+            $$groups{$_} = $$tagTablePtr{GROUPS}{$_} || '' unless $$groups{$_};
         }
         # set flag indicating group list was built
@@ -2181,14 +3361,15 @@
         if ($family =~ /[^\d]/) {
             @families = ($family =~ /\d+/g);
-            return $$groups{0} unless @families;
+            return(($ex && $$ex{G0}) || $$groups{0}) unless @families;
             $simplify = 1 unless $family =~ /^:/;
             undef $family;
             foreach (0..2) { $groups[$_] = $$groups{$_}; }
+            $noID = 1 if @families == 1 and $families[0] != 7;
         } else {
-            return $$groups{$family} if $family == 0 or $family == 2;
+            return(($ex && $$ex{"G$family"}) || $$groups{$family}) if $family == 0 or $family == 2;
             $groups[1] = $$groups{1};
         }
     } else {
-        return $$groups{0} unless wantarray;
+        return(($ex && $$ex{G0}) || $$groups{0}) unless wantarray;
         foreach (0..2) { $groups[$_] = $$groups{$_}; }
     }
@@ -2196,15 +3377,33 @@
     $groups[4] = ($tag =~ /\((\d+)\)$/) ? "Copy$1" : '';
     # handle dynamic group names if necessary
-    my $ex = $self->{TAG_EXTRA}{$tag};
-    if ($ex and not $byTagInfo) {
-        $groups[0] = $$ex{G0} if $$ex{G0};
-        $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};
+    unless ($byTagInfo) {
+        if ($ex) {
+            $groups[0] = $$ex{G0} if $$ex{G0};
+            $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};
+            }
+        }
+        # generate tag ID group names unless obviously not needed
+        unless ($noID) {
+            my $id = $$tagInfo{TagID};
+            if (not defined $id) {
+                $id = '';   # (just to be safe)
+            } elsif ($id =~ /^\d+$/) {
+                $id = sprintf('0x%x', $id) if $$self{OPTIONS}{HexTagIDs};
+            } else {
+                $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge;
+            }
+            $groups[7] = 'ID-' . $id;
+            defined $groups[$_] or $groups[$_] = '' foreach (5,6);
+        }
     }
     if ($family) {
         return $groups[$family] || '' if $family > 0;
         # add additional matching group names to list
-        # ie) for MIE-Doc, also add MIE1, MIE1-Doc, MIE-Doc1 and MIE1-Doc1
+        # eg) for MIE-Doc, also add MIE1, MIE1-Doc, MIE-Doc1 and MIE1-Doc1
         # and for MIE2-Doc3, also add MIE2, MIE-Doc3, MIE2-Doc and MIE-Doc
         if ($groups[1] =~ /^MIE(\d*)-(.+?)(\d*)$/) {
@@ -2219,5 +3418,9 @@
         # create list of group names (without identical adjacent groups if simplifying)
         foreach (@families) {
-            my $grp = $groups[$_] or next;
+            my $grp = $groups[$_];
+            unless ($grp) {
+                next if $simplify;
+                $grp = '';
+            }
             push @grps, $grp unless $simplify and @grps and $grp eq $grps[-1];
         }
@@ -2246,5 +3449,5 @@
     if (ref $info ne 'HASH') {
         $family = $info;
-        $info = $self->{VALUE};
+        $info = $$self{VALUE};
     } else {
         $family = shift;
@@ -2264,4 +3467,5 @@
 # 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($;@)
 {
@@ -2269,14 +3473,15 @@
     my ($self, @groups) = @_;
     @groups or @groups = @defaultWriteGroups;
-    my $count = @groups;
+    my $count = @groups * 10;
     my %priority;
     foreach (@groups) {
-        $priority{lc($_)} = $count--;
-    }
-    $priority{file} = 10;       # 'File' group is always written (Comment)
-    $priority{composite} = 10;  # 'Composite' group is always written
+        $priority{lc($_)} = $count;
+        $count -= 10;
+    }
+    $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;
+    $$self{WRITE_PRIORITY} = \%priority;
+    $$self{WRITE_GROUPS} = \@groups;
 }
 
@@ -2293,57 +3498,90 @@
 
     $$self{BuildingComposite} = 1;
-    # first, add user-defined Composite tags if necessary
-    if (%UserDefined and $UserDefined{'Image::ExifTool::Composite'}) {
-        AddCompositeTags($UserDefined{'Image::ExifTool::Composite'}, 1);
-        delete $UserDefined{'Image::ExifTool::Composite'};
-    }
-    my @tagList = sort keys %Image::ExifTool::Composite;
-    my %tagsUsed;
-
-    my $rawValue = $self->{VALUE};
+
+    my $compTable = GetTagTable('Image::ExifTool::Composite');
+    my @tagList = sort keys %$compTable;
+    my $rawValue = $$self{VALUE};
+    my $compKeys = $$self{COMP_KEYS};
+    my (%cache, $allBuilt);
+
     for (;;) {
-        my %notBuilt;
-        $notBuilt{$_} = 1 foreach @tagList;
-        my @deferredTags;
-        my $tag;
+        my (%notBuilt, $tag, @deferredTags);
+        foreach (@tagList) {
+            $notBuilt{$$compTable{$_}{Name}} = 1 unless $specialTags{$_};
+        }
 COMPOSITE_TAG:
         foreach $tag (@tagList) {
             next if $specialTags{$tag};
-            my $tagInfo = $self->GetTagInfo(\%Image::ExifTool::Composite, $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} || { };
-            my $desire = $$tagInfo{Desire} || { };
+            my $desire  = $$tagInfo{Desire}  || { };
+            my $inhibit = $$tagInfo{Inhibit} || { };
             # loop through sub-documents if necessary
-            my $doc;
+            my $docNum = 0;
             for (;;) {
                 my (%tagKey, $found, $index);
                 # save Require'd and Desire'd tag values in list
                 for ($index=0; ; ++$index) {
-                    my $reqTag = $$require{$index} || $$desire{$index} or last;
-                    # add family 3 group if generating Composite tags for sub-documents
-                    # (unless tag already begins with family 3 group name)
-                    if ($subDoc and $reqTag !~ /^(Main|Doc\d+):/) {
-                        $reqTag = ($doc ? "Doc$doc:" : 'Main:') . $reqTag;
+                    my $reqTag = $$require{$index} || $$desire{$index} || $$inhibit{$index};
+                    unless ($reqTag) {
+                        # allow Composite with no Require'd or Desire'd tags
+                        $found = 1 if $index == 0;
+                        last;
                     }
-                    # allow tag group to be specified
-                    if ($reqTag =~ /^(.*):(.+)/) {
+                    if ($subDoc) {
+                        # handle SubDoc tags specially to cache tag keys for faster
+                        # processing when there are a large number of sub-documents
+                        # - get document number from the tag groups if specified,
+                        #   otherwise we are looping through all documents for this tag
+                        my $doc = $reqTag =~ s/\b(Main|Doc(\d+)):// ? ($2 || 0) : $docNum;
+                        # make fast lookup for keys of this tag with specified groups other than doc group
+                        # (similar to code in InsertTagValues(), but this is case-sensitive)
+                        my $cacheTag = $cache{$reqTag};
+                        unless ($cacheTag) {
+                            $cacheTag = $cache{$reqTag} = [ ];
+                            my $reqGroup;
+                            $reqTag =~ s/^(.*):// and $reqGroup = $1;
+                            my ($i, $key, @keys);
+                            # build list of tag keys in order of precedence
+                            for ($key=$reqTag, $i=$$self{DUPL_TAG}{$reqTag} || 0; ; --$i) {
+                                push @keys, $key if defined $$rawValue{$key};
+                                last if $i <= 0;
+                                $key = "$reqTag ($i)";
+                            }
+                            @keys = $self->GroupMatches($reqGroup, \@keys) if defined $reqGroup;
+                            if (@keys) {
+                                my $ex = $$self{TAG_EXTRA};
+                                # loop through tags in reverse order of precedence so the higher
+                                # priority tag will win in the case of duplicates within a doc
+                                $$cacheTag[$$ex{$_} ? $$ex{$_}{G3} || 0 : 0] = $_ foreach reverse @keys;
+                            }
+                        }
+                        # (set $reqTag to a bogus key if not found)
+                        $reqTag = $$cacheTag[$doc] || "$reqTag (0)";
+                    } 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);
-                        for ($i=0; ; ++$i) {
-                            $key = $name;
-                            $key .= " ($i)" if $i;
-                            last unless defined $$rawValue{$key};
-                            push @keys, $key;
+                        for ($key=$name, $i=$$self{DUPL_TAG}{$name} || 0; ; --$i) {
+                            push @keys, $key if defined $$rawValue{$key};
+                            last if $i <= 0;
+                            $key = "$name ($i)";
                         }
                         # find first matching tag
                         $key = $self->GroupMatches($reqGroup, \@keys);
-                        $reqTag = $key if $key;
-                    } elsif ($notBuilt{$reqTag}) {
+                        $reqTag = $key || "$name (0)";
+                    } elsif ($notBuilt{$reqTag} and not $$inhibit{$index}) {
                         # calculate this tag later if it relies on another
                         # Composite tag which hasn't been calculated yet
@@ -2352,5 +3590,10 @@
                     }
                     if (defined $$rawValue{$reqTag}) {
-                        $found = 1;
+                        if ($$inhibit{$index}) {
+                            $found = 0;
+                            last;
+                        } else {
+                            $found = 1;
+                        }
                     } elsif ($$require{$index}) {
                         $found = 0;
@@ -2359,14 +3602,19 @@
                     $tagKey{$index} = $reqTag;
                 }
-                if ($doc) {
+                if ($docNum) {
                     if ($found) {
-                        $self->{DOC_NUM} = $doc;
+                        $$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};
+                        delete $$self{DOC_NUM};
                     }
-                    next if ++$doc <= $self->{DOC_COUNT};
+                    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) {
@@ -2374,35 +3622,62 @@
                         # can be replaced (also eliminates keys with
                         # instance numbers which can't be replaced either)
-                        next unless $Image::ExifTool::Composite{$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{$tagName}; # tag can't be built anyway
+                }
+                last unless $subDoc;
+                # don't process sub-documents if there is no chance to build this tag
+                # (can be very time-consuming if there are many docs)
+                if (%$require) {
+                    foreach (keys %$require) {
+                        my $reqTag = $$require{$_};
+                        $reqTag =~ s/.*://;
+                        next COMPOSITE_TAG unless defined $$rawValue{$reqTag};
                     }
-                } elsif (not defined $found) {
-                    delete $notBuilt{$tag}; # tag can't be built anyway
-                }
-                last unless $subDoc;
-                $doc = 1;   # continue to process the 1st sub-document
+                    $docNum = 1;   # go ahead and process the 1st sub-document
+                } else {
+                    my @try = ref $$tagInfo{SubDoc} ? @{$$tagInfo{SubDoc}} : keys %$desire;
+                    # at least one of the specified desire tags must exist
+                    foreach (@try) {
+                        my $desTag = $$desire{$_} or next;
+                        $desTag =~ s/.*://;
+                        defined $$rawValue{$desTag} and $docNum = 1, last;
+                    }
+                    last unless $docNum;
+                }
             }
         }
         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]};
 }
 
@@ -2434,8 +3709,7 @@
 #         1) flag to return long description instead of type ('0' to return any recognized type)
 # Returns: File type (or desc) or undef if extension not supported or if
-#          description is the same as the input FileType.  In array
-#          context, may return more than one file type if the file may be
-#          different formats.  Returns list of all supported extensions if no
-#          file specified
+#          description is the same as the input FileType.  In list context,
+#          may return more than one file type if the file may be different formats.
+#          Returns list of all supported extensions if no file specified
 sub GetFileType(;$$)
 {
@@ -2450,18 +3724,28 @@
             # return all supported types
             foreach (sort keys %fileTypeLookup) {
-                push @types, $_ unless defined $moduleName{$_} and $moduleName{$_} eq '0';
+                my $module = $moduleName{$_};
+                $module = $moduleName{$fileTypeLookup{$_}} unless defined $module;
+                push @types, $_ unless defined $module and $module eq '0';
             }
         }
         return @types;
     }
-    my $fileType;
+    my ($fileType, $subType);
     my $fileExt = GetFileExtension($file);
-    $fileExt = uc($file) unless $fileExt;
+    unless ($fileExt) {
+        if ($file =~ s/ \((.*)\)$//) {
+            $subType = $1;
+            $fileExt = GetFileExtension($file);
+        }
+        $fileExt = uc($file) unless $fileExt;
+    }
     $fileExt and $fileType = $fileTypeLookup{$fileExt}; # look up the file type
-    $fileType = $fileTypeLookup{$fileType} unless ref $fileType or not $fileType;
+    $fileType = $fileTypeLookup{$fileType} while $fileType and not ref $fileType;
     # return description if specified
     # (allow input $file to be a FileType for this purpose)
     if ($desc) {
-        return $fileType ? $$fileType[1] : $fileDescription{$file};
+        $desc = $fileType ? $$fileType[1] : $fileDescription{$file};
+        $desc .= ", $subType" if $subType;
+        return $desc;
     } elsif ($fileType and (not defined $desc or $desc ne '0')) {
         # return only supported file types
@@ -2469,5 +3753,5 @@
         undef $fileType if defined $mod and $mod eq '0';
     }
-    $fileType or return wantarray ? () : undef;
+    $fileType or return ();
     $fileType = $$fileType[0];      # get file type (or list of types)
     if (wantarray) {
@@ -2487,5 +3771,5 @@
     local $_;
     my $file = shift or return undef;
-    my $type = GetFileType($file) or return undef;
+    my ($type) = GetFileType($file) or return undef;
     if ($noWriteFile{$type}) {
         # can't write TIFF files with certain extensions (various RAW formats)
@@ -2493,5 +3777,8 @@
         return grep(/^$ext$/, @{$noWriteFile{$type}}) ? 0 : 1 if $ext;
     }
-    return scalar(grep /^$type$/, @writeTypes);
+    unless (%writeTypes) {
+        $writeTypes{$_} = 1 foreach @writeTypes;
+    }
+    return $writeTypes{$type};
 }
 
@@ -2513,5 +3800,5 @@
 # Functions below this are not part of the public API
 
-# Initialize member variables
+# Initialize member variables for reading or writing a new file
 # Inputs: 0) ExifTool object reference
 sub Init($)
@@ -2521,42 +3808,349 @@
     # delete all DataMember variables (lower-case names)
     foreach (keys %$self) {
-        /[a-z]/ and delete $self->{$_};
-    }
-    delete $self->{FOUND_TAGS};     # list of found tags
-    delete $self->{EXIF_DATA};      # the EXIF data block
-    delete $self->{EXIF_POS};       # EXIF position in file
-    delete $self->{FIRST_EXIF_POS}; # position of first EXIF in file
-    delete $self->{HTML_DUMP};      # html dump information
-    delete $self->{SET_GROUP1};     # group1 name override
-    delete $self->{DOC_NUM};        # current embedded document number
-    $self->{DOC_COUNT}  = 0;        # count of embedded documents processed
-    $self->{BASE}       = 0;        # base for offsets from start of file
-    $self->{FILE_ORDER} = { };      # * hash of tag order in file
-    $self->{VALUE}      = { };      # * hash of raw tag values
-    $self->{BOTH}       = { };      # * hash for Value/PrintConv values of Require'd tags
-    $self->{TAG_INFO}   = { };      # * hash of tag information
-    $self->{TAG_EXTRA}  = { };      # * hash of extra tag information (dynamic group names)
-    $self->{PRIORITY}   = { };      # * priority of current tags
-    $self->{LIST_TAGS}  = { };      # hash of tagInfo refs for active List-type tags
-    $self->{PROCESSED}  = { };      # hash of processed directory start positions
-    $self->{DIR_COUNT}  = { };      # count various types of directories
-    $self->{DUPL_TAG}   = { };      # last-used index for duplicate-tag keys
-    $self->{WARNED_ONCE}= { };      # WarnOnce() warnings already issued
-    $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)
-    $self->{INDENT}     = '  ';     # initial indent for verbose messages
-    $self->{PRIORITY_DIR} = '';     # the priority directory name
-    $self->{LOW_PRIORITY_DIR} = { PreviewIFD => 1 }; # names of priority 0 directories
-    $self->{TIFF_TYPE}  = '';       # type of TIFF data (APP1, TIFF, NEF, etc...)
-    $self->{Make}       = '';       # camera make
-    $self->{Model}      = '';       # camera model
-    $self->{CameraType} = '';       # Olympus camera type
+        /[a-z]/ and delete $$self{$_};
+    }
+    delete $$self{FOUND_TAGS};      # list of found tags
+    delete $$self{EXIF_DATA};       # the EXIF data block
+    delete $$self{EXIF_POS};        # EXIF position in file
+    delete $$self{FIRST_EXIF_POS};  # position of first EXIF in file
+    delete $$self{HTML_DUMP};       # html dump information
+    delete $$self{SET_GROUP0};      # group0 name override
+    delete $$self{SET_GROUP1};      # group1 name override
+    delete $$self{DOC_NUM};         # current embedded document number
+    $$self{DOC_COUNT}  = 0;         # count of embedded documents processed
+    $$self{BASE}       = 0;         # base for offsets from start of file
+    $$self{FILE_ORDER} = { };       # * hash of tag order in file ('*' = based on tag key)
+    $$self{VALUE}      = { };       # * hash of raw tag values
+    $$self{BOTH}       = { };       # * hash for Value/PrintConv values of Require'd tags
+    $$self{RATIONAL}   = { };       # * hash of original rational components
+    $$self{TAG_INFO}   = { };       # * hash of tag information
+    $$self{TAG_EXTRA}  = { };       # * hash of extra tag information (dynamic group names)
+    $$self{PRIORITY}   = { };       # * priority of current tags
+    $$self{LIST_TAGS}  = { };       # hash of tagInfo refs for active List-type tags
+    $$self{PROCESSED}  = { };       # hash of processed directory start positions
+    $$self{DIR_COUNT}  = { };       # count various types of directories
+    $$self{DUPL_TAG}   = { };       # last-used index for duplicate-tag keys
+    $$self{WARNED_ONCE}= { };       # WarnOnce() warnings already issued
+    $$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)
+    $$self{INDENT}     = '  ';      # initial indent for verbose messages
+    $$self{PRIORITY_DIR} = '';      # the priority directory name
+    $$self{LOW_PRIORITY_DIR} = { PreviewIFD => 1 }; # names of priority 0 directories
+    $$self{TIFF_TYPE}  = '';        # type of TIFF data (APP1, TIFF, NEF, etc...)
+    $$self{FMT_EXPR}   = undef;     # current advanced formatting expression
+    $$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;
+        $$self{HTML_DUMP} = new Image::ExifTool::HtmlDump;
     }
     # make sure our TextOut is a file reference
-    $self->{OPTIONS}{TextOut} = \*STDOUT unless ref $self->{OPTIONS}{TextOut};
+    $$self{OPTIONS}{TextOut} = \*STDOUT unless ref $$self{OPTIONS}{TextOut};
+}
+
+#------------------------------------------------------------------------------
+# Combine information from a list of info hashes
+# Unless Duplicates is enabled, first entry found takes priority
+# Inputs: 0) ExifTool object reference, 1-N) list of info hash references
+# Returns: Combined information hash reference
+sub CombineInfo($;@)
+{
+    local $_;
+    my $self = shift;
+    my (%combinedInfo, $info, $tag, %haveInfo);
+
+    if ($$self{OPTIONS}{Duplicates}) {
+        while ($info = shift) {
+            foreach $tag (keys %$info) {
+                $combinedInfo{$tag} = $$info{$tag};
+            }
+        }
+    } else {
+        while ($info = shift) {
+            foreach $tag (keys %$info) {
+                my $tagName = GetTagName($tag);
+                next if $haveInfo{$tagName};
+                $haveInfo{$tagName} = 1;
+                $combinedInfo{$tag} = $$info{$tag};
+            }
+        }
+    }
+    return \%combinedInfo;
+}
+
+#------------------------------------------------------------------------------
+# Get tag table name
+# Inputs: 0) ExifTool object reference, 1) tag key
+# Returns: Table name if available, otherwise ''
+sub GetTableName($$)
+{
+    my ($self, $tag) = @_;
+    my $tagInfo = $$self{TAG_INFO}{$tag} or return '';
+    return $$tagInfo{Table}{SHORT_NAME};
+}
+
+#------------------------------------------------------------------------------
+# Get tag index number
+# Inputs: 0) ExifTool object reference, 1) tag key
+# Returns: Table index number, or undefined if this tag isn't indexed
+sub GetTagIndex($$)
+{
+    my ($self, $tag) = @_;
+    my $tagInfo = $$self{TAG_INFO}{$tag} or return undef;
+    return $$tagInfo{Index};
+}
+
+#------------------------------------------------------------------------------
+# Find value for specified tag
+# Inputs: 0) ExifTool ref, 1) tag name, 2) tag group (family 1)
+# Returns: value or undef
+sub FindValue($$$)
+{
+    my ($et, $tag, $grp) = @_;
+    my ($i, $val);
+    my $value = $$et{VALUE};
+    for ($i=0; ; ++$i) {
+        my $key = $tag . ($i ? " ($i)" : '');
+        last unless defined $$value{$key};
+        if ($et->GetGroup($key, 1) eq $grp) {
+            $val = $$value{$key};
+            last;
+        }
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Get tag key for next existing tag
+# Inputs: 0) ExifTool ref, 1) tag key or case-sensitive tag name
+# Returns: Key of next existing tag, or undef if no more
+# Notes: This routine is provided for iterating through duplicate tags in the
+#        ValueConv of Composite tags.
+sub NextTagKey($$)
+{
+    my ($self, $tag) = @_;
+    my $i = ($tag =~ s/ \((\d+)\)$//) ? $1 + 1 : 1;
+    $tag = "$tag ($i)";
+    return $tag if defined $$self{VALUE}{$tag};
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Split file name into directory and name parts
+# Inptus: 0) file name
+# Returns: 0) directory, 1) filename
+sub SplitFileName($)
+{
+    my $file = shift;
+    my ($dir, $name);
+    if (eval { require File::Basename }) {
+        $dir = File::Basename::dirname($file);
+        $name = File::Basename::basename($file);
+    } else {
+        ($name = $file) =~ tr/\\/\//;
+        # remove path
+        $dir = length($1) ? $1 : '/' if $name =~ s/(.*)\///;
+    }
+    return ($dir, $name);
+}
+
+#------------------------------------------------------------------------------
+# Encode file name for calls to system i/o routines
+# Inputs: 0) ExifTool ref, 1) file name in CharSetFileName, 2) flag to force conversion
+# Returns: true if Windows Unicode routines should be used (in which case
+#          the file name will be encoded as a null-terminated UTF-16LE string)
+sub EncodeFileName($$;$)
+{
+    my ($self, $file, $force) = @_;
+    my $enc = $$self{OPTIONS}{CharsetFileName};
+    if ($enc) {
+        if ($file =~ /[\x80-\xff]/ or $force) {
+            # encode for use in Windows Unicode functions if necessary
+            if ($^O eq 'MSWin32') {
+                local $SIG{'__WARN__'} = \&SetWarning;
+                if (eval { require Win32API::File }) {
+                    # recode as UTF-16LE and add null terminator
+                    $_[1] = $self->Decode($file, $enc, undef, 'UTF16', 'II') . "\0\0";
+                    return 1;
+                }
+                $self->WarnOnce('Install Win32API::File for Windows Unicode file support');
+            } else {
+                # recode as UTF-8 for other platforms if necessary
+                $_[1] = $self->Decode($file, $enc, undef, 'UTF8') unless $enc eq 'UTF8';
+            }
+        }
+    } elsif ($^O eq 'MSWin32' and $file =~ /[\x80-\xff]/ and not defined $enc) {
+        require Image::ExifTool::XMP;
+        if (Image::ExifTool::XMP::IsUTF8(\$file) < 0) {
+            $self->WarnOnce('FileName encoding not specified');
+        }
+    }
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Modified perl open() routine to properly handle special characters in file names
+# Inputs: 0) ExifTool ref, 1) filehandle, 2) filename,
+#         3) mode: '<' or undef = read, '>' = write, '+<' = update
+# Returns: true on success
+# Note: Must call like "$et->Open(\*FH,$file)", not "$et->Open(FH,$file)" to avoid
+#       "unopened filehandle" errors due to a change in scope of the filehandle
+sub Open($*$;$)
+{
+    my ($self, $fh, $file, $mode) = @_;
+
+    $file =~ s/^([\s&])/.\/$1/; # protect leading whitespace or ampersand
+    # default to read mode ('<') unless input is a pipe
+    $mode = ($file =~ /\|$/ ? '' : '<') unless $mode;
+    if ($mode) {
+        if ($self->EncodeFileName($file)) {
+            # handle Windows Unicode file name
+            local $SIG{'__WARN__'} = \&SetWarning;
+            my ($access, $create);
+            if ($mode eq '>') {
+                eval {
+                    $access  = Win32API::File::GENERIC_WRITE();
+                    $create  = Win32API::File::CREATE_ALWAYS();
+                }
+            } else {
+                eval {
+                    $access  = Win32API::File::GENERIC_READ();
+                    $access |= Win32API::File::GENERIC_WRITE() if $mode eq '+<'; # update
+                    $create  = Win32API::File::OPEN_EXISTING();
+                }
+            }
+            my $share = 0;
+            eval {
+                unless ($access & Win32API::File::GENERIC_WRITE()) {
+                    $share = Win32API::File::FILE_SHARE_READ() | Win32API::File::FILE_SHARE_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) {
+                eval { Win32API::File::CloseHandle($wh) };
+                return undef;
+            }
+            $file = "&=$fd";    # specify file by descriptor
+        } else {
+            # add leading space to protect against leading characters like '>'
+            # in file name, and trailing "\0" to protect trailing spaces
+            $file = " $file\0";
+        }
+    }
+    return open $fh, "$mode$file";
+}
+
+#------------------------------------------------------------------------------
+# Check to see if a file exists (with Windows Unicode support)
+# Inputs: 0) ExifTool ref, 1) file name
+# Returns: true if file exists
+sub Exists($$)
+{
+    my ($self, $file) = @_;
+
+    if ($self->EncodeFileName($file)) {
+        local $SIG{'__WARN__'} = \&SetWarning;
+        my $wh = eval { Win32API::File::CreateFileW($file,
+                        Win32API::File::GENERIC_READ(),
+                        Win32API::File::FILE_SHARE_READ(), [],
+                        Win32API::File::OPEN_EXISTING(), 0, []) };
+        return 0 unless $wh;
+        eval { Win32API::File::CloseHandle($wh) };
+    } else {
+        return -e $file;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Return true if file is a directory (with Windows Unicode support)
+# Inputs: 0) ExifTool ref, 1) file name
+# Returns: true if file is a directory (false if file isn't, or doesn't exist)
+sub IsDirectory($$)
+{
+    my ($et, $file) = @_;
+    if ($et->EncodeFileName($file)) {
+        local $SIG{'__WARN__'} = \&SetWarning;
+        my $attrs = eval { Win32API::File::GetFileAttributesW($file) };
+        my $dirBit = eval { Win32API::File::FILE_ATTRIBUTE_DIRECTORY() } || 0;
+        return 1 if $attrs and $attrs != 0xffffffff and $attrs & $dirBit;
+    } else {
+        return -d $file;
+    }
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Get file times (Unix seconds since the epoch)
+# Inputs: 0) ExifTool ref, 1) file name or ref
+# Returns: 0) access time, 1) modification time, 2) creation time (or undefs on error)
+my $k32GetFileTime;
+sub GetFileTime($$)
+{
+    my ($self, $file) = @_;
+
+    # open file by name if necessary
+    unless (ref $file) {
+        local *FH;
+        unless ($self->Open(\*FH, $file)) {
+            if ($self->IsDirectory($file)) {
+                my @rtn = (stat $file)[8, 9, 10];
+                return @rtn if defined $rtn[0];
+            }
+            $self->Warn("GetFileTime error for '${file}'");
+            return ();
+        }
+        $file = *FH;  # (not \*FH, so *FH will be kept open until $file goes out of scope)
+    }
+    # on Windows, try to work around incorrect file times when daylight saving time is in effect
+    if ($^O eq 'MSWin32') {
+        if (not eval { require Win32::API }) {
+            $self->WarnOnce('Install Win32::API for proper handling of Windows file times');
+        } elsif (not eval { require Win32API::File }) {
+            $self->WarnOnce('Install Win32API::File for proper handling of Windows file times');
+        } else {
+            # get Win32 handle, needed for GetFileTime
+            my $win32Handle = eval { Win32API::File::GetOsFHandle($file) };
+            unless ($win32Handle) {
+                $self->Warn("Win32API::File::GetOsFHandle returned invalid handle");
+                return ();
+            }
+            # get FILETIME structs
+            my ($atime, $mtime, $ctime, $time);
+            $atime = $mtime = $ctime = pack 'LL', 0, 0;
+            unless ($k32GetFileTime) {
+                return () if defined $k32GetFileTime;
+                $k32GetFileTime = new Win32::API('KERNEL32', 'GetFileTime', 'NPPP', 'I');
+                unless ($k32GetFileTime) {
+                    $self->Warn('Error calling Win32::API::GetFileTime');
+                    $k32GetFileTime = 0;
+                    return ();
+                }
+            }
+            unless ($k32GetFileTime->Call($win32Handle, $ctime, $atime, $mtime)) {
+                $self->Warn("Win32::API::GetFileTime returned " . Win32::GetLastError());
+                return ();
+            }
+            # convert FILETIME structs to Unix seconds
+            foreach $time ($atime, $mtime, $ctime) {
+                my ($lo, $hi) = unpack 'LL', $time; # unpack FILETIME struct
+                # FILETIME is in 100 ns intervals since 0:00 UTC Jan 1, 1601
+                # (89 leap years between 1601 and 1970)
+                $time = ($hi * 4294967296 + $lo) * 1e-7 - (((1970-1601)*365+89)*24*3600);
+            }
+            return ($atime, $mtime, $ctime);
+        }
+    }
+    # other os (or Windows fallback)
+    return (stat $file)[8, 9, 10];
 }
 
@@ -2568,24 +4162,24 @@
 {
     my $self = shift;
-    my $options = $self->{OPTIONS};
-    my @exclude;
-    my @oldGroupOpts = grep /^Group/, keys %{$self->{OPTIONS}};
-    my $wasExcludeOpt;
-
-    $self->{REQUESTED_TAGS} = [ ];
-    $self->{REQ_TAG_LOOKUP} = { };
-    $self->{IO_TAG_LIST} = undef;
+    my $options = $$self{OPTIONS};
+    my @oldGroupOpts = grep /^Group/, keys %{$$self{OPTIONS}};
+    my (@exclude, $wasExcludeOpt);
+
+    $$self{REQUESTED_TAGS}  = [ ];
+    $$self{REQ_TAG_LOOKUP}  = { };
+    $$self{EXCL_TAG_LOOKUP} = { };
+    $$self{IO_TAG_LIST} = undef;
 
     # 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;
+                $$self{IO_TAG_LIST} = $arg;
                 foreach (@$arg) {
                     if (/^-(.*)/) {
                         push @exclude, $1;
                     } else {
-                        push @{$self->{REQUESTED_TAGS}}, $_;
+                        push @{$$self{REQUESTED_TAGS}}, $_;
                     }
                 }
@@ -2596,5 +4190,5 @@
                     if (@oldGroupOpts and $opt =~ /^Group/) {
                         foreach (@oldGroupOpts) {
-                            delete $options->{$_};
+                            delete $$options{$_};
                         }
                         undef @oldGroupOpts;
@@ -2604,56 +4198,80 @@
                 }
             } elsif (ref $arg eq 'SCALAR' or UNIVERSAL::isa($arg,'GLOB')) {
-                next if defined $self->{RAF};
+                next if defined $$self{RAF};
                 # convert image data from UTF-8 to character stream if necessary
                 # (patches RHEL 3 UTF8 LANG problem)
                 if (ref $arg eq 'SCALAR' and $] >= 5.006 and
-                    (eval 'require Encode; Encode::is_utf8($$arg)' or $@))
+                    (eval { require Encode; Encode::is_utf8($$arg) } or $@))
                 {
                     # repack by hand if Encode isn't available
-                    my $buff = $@ ? pack('C*',unpack('U0C*',$$arg)) : Encode::encode('utf8',$$arg);
+                    my $buff = $@ ? pack('C*',unpack($] < 5.010000 ? 'U0C*' : 'C0C*',$$arg)) : Encode::encode('utf8',$$arg);
                     $arg = \$buff;
                 }
-                $self->{RAF} = new File::RandomAccess($arg);
+                $$self{RAF} = new File::RandomAccess($arg);
                 # set filename to empty string to indicate that
                 # we have a file but we didn't open it
-                $self->{FILENAME} = '';
+                $$self{FILENAME} = '';
             } elsif (UNIVERSAL::isa($arg, 'File::RandomAccess')) {
-                $self->{RAF} = $arg;
-                $self->{FILENAME} = '';
+                $$self{RAF} = $arg;
+                $$self{FILENAME} = '';
             } else {
                 warn "Don't understand ImageInfo argument $arg\n";
             }
-        } elsif (defined $self->{FILENAME}) {
+        } elsif (defined $$self{FILENAME}) {
             if ($arg =~ /^-(.*)/) {
                 push @exclude, $1;
             } else {
-                push @{$self->{REQUESTED_TAGS}}, $arg;
+                push @{$$self{REQUESTED_TAGS}}, $arg;
             }
         } else {
-            $self->{FILENAME} = $arg;
-        }
+            $$self{FILENAME} = $arg;
+        }
+    }
+    # add additional requested tags to lookup
+    if ($$options{RequestTags}) {
+        $$self{REQ_TAG_LOOKUP}{$_} = 1 foreach @{$$options{RequestTags}};
     }
     # expand shortcuts in tag arguments if provided
-    if (@{$self->{REQUESTED_TAGS}}) {
-        ExpandShortcuts($self->{REQUESTED_TAGS});
+    if (@{$$self{REQUESTED_TAGS}}) {
+        ExpandShortcuts($$self{REQUESTED_TAGS});
         # initialize lookup for requested tags
-        foreach (@{$self->{REQUESTED_TAGS}}) {
-            $self->{REQ_TAG_LOOKUP}{lc(/.+:(.+)/ ? $1 : $_)} = 1;
-        }
-    }
-
+        foreach (@{$$self{REQUESTED_TAGS}}) {
+            /^(.*:)?([-\w?*]*)#?$/ or next;
+            $$self{REQ_TAG_LOOKUP}{lc($2)} = 1 if $2;
+            next unless $1;
+            $$self{REQ_TAG_LOOKUP}{lc($_).':'} = 1 foreach split /:/, $1;
+        }
+    }
     if (@exclude or $wasExcludeOpt) {
         # must add existing excluded tags
-        if ($options->{Exclude}) {
-            if (ref $options->{Exclude} eq 'ARRAY') {
-                push @exclude, @{$options->{Exclude}};
-            } else {
-                push @exclude, $options->{Exclude};
-            }
-        }
-        $options->{Exclude} = \@exclude;
+        push @exclude, @{$$options{Exclude}} if $$options{Exclude};
+        $$options{Exclude} = \@exclude;
         # expand shortcuts in new exclude list
-        ExpandShortcuts($options->{Exclude}, 1); # (also remove '#' suffix)
-    }
+        ExpandShortcuts($$options{Exclude}, 1); # (also remove '#' suffix)
+    }
+    # generate lookup for excluded tags
+    if ($$options{Exclude}) {
+        foreach (@{$$options{Exclude}}) {
+            /([-\w]+)#?$/ and $$self{EXCL_TAG_LOOKUP}{lc($1)} = 1;
+        }
+        # exclude list is used only for EXCL_TAG_LOOKUP when TAGS_FROM_FILE is set
+        undef $$options{Exclude} if $$self{TAGS_FROM_FILE};
+    }
+}
+
+#------------------------------------------------------------------------------
+# Does group name match the tag ID?
+# Inputs: 0) tag ID, 1) group name (with "ID-" removed)
+# Returns: true on success
+sub IsSameID($$)
+{
+    my ($id, $grp) = @_;
+    return 1 if $grp eq $id;    # decimal ID's or raw ID's
+    if ($id =~ /^\d+$/) {       # numerical numerical ID's may be in hex
+        return 1 if $grp =~ s/^0x0*// and $grp eq sprintf('%x', $id);
+    } else {                    # other ID's may conform to ExifTool group name conventions
+        return 1 if $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge and $grp eq $id;
+    }
+    return 0;
 }
 
@@ -2669,33 +4287,73 @@
     $tagList = [ $tagList ] unless ref $tagList;
     my ($tag, @matches);
-    if ($group =~ /:/) {
-        # check each group name individually (ie. "Author:1IPTC")
-        my @grps = split ':', lc $group;
-        my (@fmys, $g);
+    # check each group name individually (eg. "Author:1IPTC")
+    my @grps = split ':', $group;
+    my (@fmys, $g);
+    for ($g=0; $g<@grps; ++$g) {
+        if ($grps[$g] =~ s/^(\d*)(id-)?//i) {
+            $fmys[$g] = $1 if length $1;
+            if ($2) {
+                $fmys[$g] = 7;
+                next;   # (don't convert tag ID's to lower case)
+            }
+        }
+        $grps[$g] = lc $grps[$g];
+        $grps[$g] = '' if $grps[$g] eq 'copy0'; # accept 'Copy0' for primary tag
+    }
+    foreach $tag (@$tagList) {
+        my @groups = $self->GetGroup($tag, -1);
         for ($g=0; $g<@grps; ++$g) {
-            $fmys[$g] = $1 if $grps[$g] =~ s/^(\d+)//;
-        }
-        foreach $tag (@$tagList) {
-            my @groups = $self->GetGroup($tag, -1);
-            for ($g=0; $g<@grps; ++$g) {
-                my $grp = $grps[$g];
-                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];
+            my $grp = $grps[$g];
+            next if $grp eq '*' or $grp eq 'all';
+            my $f;
+            if (defined($f = $fmys[$g])) {
+                last unless defined $groups[$f];
+                if ($f == 7) {
+                    next if IsSameID($self->GetTagID($tag), $grp);
                 } else {
-                    last unless grep /^$grps[$g]$/i, @groups;
-                }
-            }
-            push @matches, $tag if $g == @grps;
+                    next if $grp eq lc $groups[$f];
+                }
+                last;
+            } else {
+                last unless grep /^$grp$/i, @groups;
+            }
+        }
+        if ($g == @grps) {
+            return $tag unless wantarray;
+            push @matches, $tag;
+        }
+    }
+    return wantarray ? @matches : $matches[0];
+}
+
+#------------------------------------------------------------------------------
+# Remove specified tags from returned tag list, updating indices in other lists
+# Inputs: 0) tag list ref, 1) index list ref, 2) index list ref, 3) hash ref,
+#         4) true to include tags from hash instead of excluding
+# Returns: nothing, but updates input lists
+sub RemoveTagsFromList($$$$;$)
+{
+    local $_;
+    my ($tags, $list1, $list2, $exclude, $inv) = @_;
+    my @filteredTags;
+
+    if (@$list1 or @$list2) {
+        while (@$tags) {
+            my $tag = pop @$tags;
+            my $i = @$tags;
+            if ($$exclude{$tag} xor $inv) {
+                # remove index of excluded tag from each list
+                @$list1 = map { $_ < $i ? $_ : $_ == $i ? () : $_ - 1 } @$list1;
+                @$list2 = map { $_ < $i ? $_ : $_ == $i ? () : $_ - 1 } @$list2;
+            } else {
+                unshift @filteredTags, $tag;
+            }
         }
     } else {
-        my $family = ($group =~ s/^(\d+)//) ? $1 : -1;
-        foreach $tag (@$tagList) {
-            my @groups = $self->GetGroup($tag, $family);
-            push @matches, $tag if grep(/^$group$/i, @groups);
-        }
-    }
-    return wantarray ? @matches : $matches[0];
+        foreach (@$tags) {
+            push @filteredTags, $_ unless $$exclude{$_} xor $inv;
+        }
+    }
+    $_[0] = \@filteredTags;     # update tag list
 }
 
@@ -2705,15 +4363,17 @@
 # Returns: 0) Reference to list of found tag keys (in order of requested tags)
 #          1) Reference to list of indices for tags requested by value
+#          2) Reference to list of indices for tags specified by wildcard or "all"
+# Notes: index lists are returned in increasing order
 sub SetFoundTags($)
 {
     my $self = shift;
-    my $options = $self->{OPTIONS};
-    my $reqTags = $self->{REQUESTED_TAGS} || [ ];
-    my $duplicates = $options->{Duplicates};
-    my $exclude = $options->{Exclude};
-    my $fileOrder = $self->{FILE_ORDER};
+    my $options = $$self{OPTIONS};
+    my $reqTags = $$self{REQUESTED_TAGS} || [ ];
+    my $duplicates = $$options{Duplicates};
+    my $exclude = $$options{Exclude};
+    my $fileOrder = $$self{FILE_ORDER};
     my @groupOptions = sort grep /^Group/, keys %$options;
     my $doDups = $duplicates || $exclude || @groupOptions;
-    my ($tag, $rtnTags, @byValue);
+    my ($tag, $rtnTags, @byValue, @wildTags);
 
     # only return requested tags if specified
@@ -2721,5 +4381,5 @@
         $rtnTags or $rtnTags = [ ];
         # scan through the requested tags and generate a list of tags we found
-        my $tagHash = $self->{VALUE};
+        my $tagHash = $$self{VALUE};
         my $reqTag;
         foreach $reqTag (@$reqTags) {
@@ -2730,5 +4390,5 @@
                     $allGrp = 1;
                 } elsif ($group !~ /^[-\w:]*$/) {
-                    $self->Warn("Invalid group name '$group'");
+                    $self->Warn("Invalid group name '${group}'");
                     $group = 'invalid';
                 }
@@ -2736,11 +4396,11 @@
                 $tag = $reqTag;
             }
-            $byValue = 1 if $tag =~ s/#$//;
-            if (defined $tagHash->{$reqTag} and not $doDups) {
+            $byValue = 1 if $tag =~ s/#$// and $$options{PrintConv};
+            if (defined $$tagHash{$reqTag} and not $doDups) {
                 $matches[0] = $tag;
             } elsif ($tag =~ /^(\*|all)$/i) {
                 # tag name of '*' or 'all' matches all tags
                 if ($doDups or $allGrp) {
-                    @matches = keys %$tagHash;
+                    @matches = grep(!/#/, keys %$tagHash);
                 } else {
                     @matches = grep(!/ /, keys %$tagHash);
@@ -2752,5 +4412,5 @@
                 $tag =~ s/\*/[-\\w]*/g;
                 $tag =~ s/\?/[-\\w]/g;
-                $tag .= '( .*)?' if $doDups or $allGrp;
+                $tag .= '( \\(.*)?' if $doDups or $allGrp;
                 @matches = grep(/^$tag$/i, keys %$tagHash);
                 next unless @matches;   # don't want entry in list for wildcard tags
@@ -2758,5 +4418,6 @@
             } elsif ($doDups or defined $group) {
                 # must also look for tags like "Tag (1)"
-                @matches = grep(/^$tag( |$)/i, keys %$tagHash);
+                # (but be sure not to match temporary ValueConv entries like "Tag #")
+                @matches = grep(/^$tag( \(|$)/i, keys %$tagHash);
             } elsif ($tag =~ /^[-\w]+$/) {
                 # find first matching value
@@ -2765,5 +4426,5 @@
                 defined $matches[0] or undef @matches;
             } else {
-                $self->Warn("Invalid tag name '$tag'");
+                $self->Warn("Invalid tag name '${tag}'");
             }
             if (defined $group and not $allGrp) {
@@ -2778,7 +4439,7 @@
                 unless ($doDups or $allTag or $allGrp) {
                     $tag = shift @matches;
-                    my $oldPriority = $self->{PRIORITY}{$tag} || 1;
+                    my $oldPriority = $$self{PRIORITY}{$tag} || 1;
                     foreach (@matches) {
-                        my $priority = $self->{PRIORITY}{$_};
+                        my $priority = $$self{PRIORITY}{$_};
                         $priority = 1 unless defined $priority;
                         next unless $priority >= $oldPriority;
@@ -2790,10 +4451,12 @@
             } elsif (not @matches) {
                 # put entry in return list even without value (value is undef)
-                $matches[0] = "$tag (0)";
+                $matches[0] = $byValue ? "$tag #(0)" : "$tag (0)";
                 # bogus file order entry to avoid warning if sorting in file order
-                $self->{FILE_ORDER}{$matches[0]} = 999;
+                $$self{FILE_ORDER}{$matches[0]} = 9999;
             }
             # save indices of tags extracted by value
             push @byValue, scalar(@$rtnTags) .. (scalar(@$rtnTags)+scalar(@matches)-1) if $byValue;
+            # save indices of wildcard tags
+            push @wildTags, scalar(@$rtnTags) .. (scalar(@$rtnTags)+scalar(@matches)-1) if $allTag;
             push @$rtnTags, @matches;
         }
@@ -2802,10 +4465,8 @@
         my @allTags;
         if ($doDups) {
-            @allTags = keys %{$self->{VALUE}};
+            @allTags = keys %{$$self{VALUE}};
         } else {
-            foreach (keys %{$self->{VALUE}}) {
-                # only include tag if it doesn't end in a copy number
-                push @allTags, $_ unless / /;
-            }
+            # only include tag if it doesn't end in a copy number
+            @allTags = grep(!/ /, keys %{$$self{VALUE}});
         }
         $rtnTags = \@allTags;
@@ -2823,5 +4484,5 @@
                         undef $group;
                     } elsif ($group !~ /^[-\w:]*$/) {
-                        $self->Warn("Invalid group name '$group'");
+                        $self->Warn("Invalid group name '${group}'");
                         $group = 'invalid';
                     }
@@ -2842,8 +4503,7 @@
             }
             if (%exclude) {
-                my @filteredTags;
-                $exclude{$_} or push @filteredTags, $_ foreach @$rtnTags;
-                $rtnTags = \@filteredTags;      # use new filtered tag list
-                last unless @filteredTags;      # all done if nothing left
+                # remove excluded tags from return list(s)
+                RemoveTagsFromList($rtnTags, \@byValue, \@wildTags, \%exclude);
+                last unless @$rtnTags;      # all done if nothing left
             }
             last if $duplicates and not @groupOptions;
@@ -2859,8 +4519,8 @@
             $wantGroup{$family} or $wantGroup{$family} = { };
             my $groupList;
-            if (ref $options->{$groupOpt} eq 'ARRAY') {
-                $groupList = $options->{$groupOpt};
+            if (ref $$options{$groupOpt} eq 'ARRAY') {
+                $groupList = $$options{$groupOpt};
             } else {
-                $groupList = [ $options->{$groupOpt} ];
+                $groupList = [ $$options{$groupOpt} ];
             }
             foreach (@$groupList) {
@@ -2894,38 +4554,31 @@
             }
             next unless $wantTag;
-            if ($duplicates) {
-                push @tags, $tag;
-            } else {
-                my $tagName = GetTagName($tag);
-                my $bestTag = $bestTag{$tagName};
-                if (defined $bestTag) {
-                    next if $wantTag > $keepTags{$bestTag};
-                    if ($wantTag == $keepTags{$bestTag}) {
-                        # want two tags with the same name -- keep the latest one
-                        if ($tag =~ / \((\d+)\)$/) {
-                            my $tagNum = $1;
-                            next if $bestTag !~ / \((\d+)\)$/ or $1 > $tagNum;
-                        }
+            $duplicates and $keepTags{$tag} = 1, next;
+            # determine which tag we want to keep
+            my $tagName = GetTagName($tag);
+            my $bestTag = $bestTag{$tagName};
+            if (defined $bestTag) {
+                next if $wantTag > $keepTags{$bestTag};
+                if ($wantTag == $keepTags{$bestTag}) {
+                    # want two tags with the same name -- keep the latest one
+                    if ($tag =~ / \((\d+)\)$/) {
+                        my $tagNum = $1;
+                        next if $bestTag !~ / \((\d+)\)$/ or $1 > $tagNum;
                     }
-                    # this tag is better, so delete old best tag
-                    delete $keepTags{$bestTag};
-                }
-                $keepTags{$tag} = $wantTag;    # keep this tag (for now...)
-                $bestTag{$tagName} = $tag;      # this is our current best tag
-            }
-        }
-        unless ($duplicates) {
-            # construct new tag list with no duplicates, preserving order
-            foreach $tag (@$rtnTags) {
-                push @tags, $tag if $keepTags{$tag};
-            }
-        }
-        $rtnTags = \@tags;
+                }
+                # this tag is better, so delete old best tag
+                delete $keepTags{$bestTag};
+            }
+            $keepTags{$tag} = $wantTag;     # keep this tag (for now...)
+            $bestTag{$tagName} = $tag;      # this is our current best tag
+        }
+        # include only tags we want to keep in return lists
+        RemoveTagsFromList($rtnTags, \@byValue, \@wildTags, \%keepTags, 1);
         last;
     }
-    $self->{FOUND_TAGS} = $rtnTags;     # save found tags 
+    $$self{FOUND_TAGS} = $rtnTags;      # save found tags
 
     # return reference to found tag keys (and list of indices of tags to extract by value)
-    return wantarray ? ($rtnTags, \@byValue) : $rtnTags;
+    return wantarray ? ($rtnTags, \@byValue, \@wildTags) : $rtnTags;
 }
 
@@ -2934,6 +4587,4 @@
 # Inputs: 0) autoload function, 1-N) function arguments
 # Returns: result of function or dies if function not available
-# To Do: Generalize this routine so it works on systems that don't use '/'
-#        as a path name separator.
 sub DoAutoLoad(@)
 {
@@ -2946,4 +4597,6 @@
         # load Image/ExifTool/WriteMODULE.pl
         $file .= "$callInfo[2].pl";
+    } elsif ($callInfo[-1] eq 'ShiftTime') {
+        $file = 'Image/ExifTool/Shift.pl';  # load Shift.pl
     } else {
         # load Image/ExifTool/Writer.pl
@@ -2951,5 +4604,5 @@
     }
     # attempt to load the package
-    eval "require '$file'" or die "Error while attempting to call $autoload\n$@\n";
+    eval { require $file } or die "Error while attempting to call $autoload\n$@\n";
     unless (defined &$autoload) {
         my @caller = caller(0);
@@ -2971,5 +4624,7 @@
 #------------------------------------------------------------------------------
 # Add warning tag
-# Inputs: 0) ExifTool object reference, 1) warning message, 2) true if minor
+# Inputs: 0) ExifTool object reference, 1) warning message
+#         2) true if minor (2 if behaviour changes when warning is ignored,
+#            or 3 if warning shouldn't be issued when Validate option is used)
 # Returns: true if warning tag was added
 sub Warn($$;$)
@@ -2977,6 +4632,7 @@
     my ($self, $str, $ignorable) = @_;
     if ($ignorable) {
-        return 0 if $self->{OPTIONS}{IgnoreMinorErrors};
-        $str = "[minor] $str";
+        return 0 if $$self{OPTIONS}{IgnoreMinorErrors};
+        return 0 if $ignorable eq '3' and $$self{OPTIONS}{Validate};
+        $str = $ignorable eq '2' ? "[Minor] $str" : "[minor] $str";
     }
     $self->FoundTag('Warning', $str);
@@ -2991,5 +4647,5 @@
 {
     my ($self, $str, $ignorable) = @_;
-    return 0 if $ignorable and $self->{OPTIONS}{IgnoreMinorErrors};
+    return 0 if $ignorable and $$self{OPTIONS}{IgnoreMinorErrors};
     unless ($$self{WARNED_ONCE}{$str}) {
         $self->Warn($str, $ignorable);
@@ -3006,9 +4662,9 @@
 {
     my ($self, $str, $ignorable) = @_;
-    if ($ignorable) {
-        if ($self->{OPTIONS}{IgnoreMinorErrors}) {
-            $self->Warn($str);
-            return 0;
-        }
+    if ($$self{DemoteErrors}) {
+        $self->Warn($str) and ++$$self{DemoteErrors};
+        return 1;
+    } elsif ($ignorable) {
+        $$self{OPTIONS}{IgnoreMinorErrors} and $self->Warn($str), return 0;
         $str = "[minor] $str";
     }
@@ -3116,52 +4772,88 @@
 # Add hash of Composite tags to our composites
 # Inputs: 0) hash reference to table of Composite tags to add or module name,
-#         1) overwrite existing tag
+#         1) override existing tag definition
 sub AddCompositeTags($;$)
 {
     local $_;
-    my ($add, $overwrite) = @_;
-    my $module;
+    my ($add, $override) = @_;
+    my ($module, $prefix, $tagID);
     unless (ref $add) {
+        ($prefix = $add) =~ s/.*:://;
         $module = $add;
         $add .= '::Composite';
         no strict 'refs';
         $add = \%$add;
+        $prefix .= '-';
+    } else {
+        $prefix = 'UserDefined-';
     }
     my $defaultGroups = $$add{GROUPS};
+    my $compTable = GetTagTable('Image::ExifTool::Composite');
 
     # make sure default groups are defined in families 0 and 1
     if ($defaultGroups) {
-        $defaultGroups->{0} or $defaultGroups->{0} = 'Composite';
-        $defaultGroups->{1} or $defaultGroups->{1} = 'Composite';
-        $defaultGroups->{2} or $defaultGroups->{2} = 'Other';
+        $$defaultGroups{0} or $$defaultGroups{0} = 'Composite';
+        $$defaultGroups{1} or $$defaultGroups{1} = 'Composite';
+        $$defaultGroups{2} or $$defaultGroups{2} = 'Other';
     } else {
         $defaultGroups = $$add{GROUPS} = { 0 => 'Composite', 1 => 'Composite', 2 => 'Other' };
     }
-    SetupTagTable($add);    # generate tag Name, etc
-    my $tagID;
+    SetupTagTable($add);    # generate Name, TagID, etc
     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};
-        # allow Composite tags with the same name
-        my ($t, $n, $type);
-        while ($Image::ExifTool::Composite{$tag} and not $overwrite) {
-            $n ? $n += 1 : ($n = 2, $t = $tag);
-            $tag = "${t}_$n";
-            $$tagInfo{NewTagID} = $tag; # save new ID so we can use it in TagLookup
-        }
-        # convert scalar Require/Desire entries
-        foreach $type ('Require','Desire') {
+        $$tagInfo{Override} = 1 if $override and not defined $$tagInfo{Override};
+        $$tagInfo{IsComposite} = 1;
+        # 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{$compositeID{$tagID}[0]}{Override} || 0);
+            next if $over < 0;
+            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} = \%Image::ExifTool::Composite;
-        # (use the original TagID, even if we changed it)
-        # $$tagInfo{TagID} = $tag;
-        # save new tag ID so we can find entry in Composite table
-        $Image::ExifTool::Composite{$tag} = $tagInfo;
+        $$tagInfo{Table} = $compTable;
+        # (use the original TagID, even if we changed it, so don't do this:)
+        $$tagInfo{TagID} = $new;
+        # save tag under new ID in Composite table
+        $$compTable{$new} = $tagInfo;
         # set all default groups in tag
         my $groups = $$tagInfo{Groups};
@@ -3223,4 +4915,5 @@
 {
     my $tagTablePtr = shift;
+    my $avoid = $$tagTablePtr{AVOID};
     my ($tagID, $tagInfo);
     foreach $tagID (TagTableKeys($tagTablePtr)) {
@@ -3230,11 +4923,13 @@
             $$tagInfo{Table} = $tagTablePtr;
             $$tagInfo{TagID} = $tagID;
-            my $tag = $$tagInfo{Name};
-            unless (defined $tag) {
-                # generate name equal to tag ID if 'Name' doesn't exist
-                $tag = $tagID;
-                $$tagInfo{Name} = ucfirst($tag); # make first char uppercase
-            }
+            $$tagInfo{Name} or $$tagInfo{Name} = MakeTagName($tagID);
             $$tagInfo{Flags} and ExpandFlags($tagInfo);
+            $$tagInfo{Avoid} = $avoid if defined $avoid;
+            # calculate BitShift from Mask if necessary
+            if ($$tagInfo{Mask} and not defined $$tagInfo{BitShift}) {
+                my ($mask, $bitShift) = ($$tagInfo{Mask}, 0);
+                ++$bitShift until $mask & (1 << $bitShift);
+                $$tagInfo{BitShift} = $bitShift;
+            }
         }
         next unless @infoArray > 1;
@@ -3267,9 +4962,5 @@
 {
     my ($val, $sig) = @_;
-    $val == 0 and return 0;
-    my $sign = $val < 0 ? ($val=-$val, -1) : 1;
-    my $log = log($val) / log(10);
-    my $exp = int($log) - $sig + ($log > 0 ? 1 : 0);
-    return $sign * int(10 ** ($log - $exp) + 0.5) * 10 ** $exp;
+    return sprintf("%.${sig}g", $val);
 }
 
@@ -3396,34 +5087,36 @@
 sub GetDouble($$) { return DoUnpackDbl('d', @_); }
 sub Get16uRev($$) { return DoUnpackRev('S', @_); }
+sub Get32uRev($$) { return DoUnpackRev('L', @_); }
 
 # rationals may be a floating point number, 'inf' or 'undef'
+my ($ratNumer, $ratDenom);
 sub GetRational32s($$)
 {
     my ($dataPt, $pos) = @_;
-    my $numer = Get16s($dataPt,$pos);
-    my $denom = Get16s($dataPt, $pos + 2) or return $numer ? 'inf' : 'undef';
+    $ratNumer = Get16s($dataPt,$pos);
+    $ratDenom = Get16s($dataPt, $pos + 2) or return $ratNumer ? 'inf' : 'undef';
     # round off to a reasonable number of significant figures
-    return RoundFloat($numer / $denom, 7);
+    return RoundFloat($ratNumer / $ratDenom, 7);
 }
 sub GetRational32u($$)
 {
     my ($dataPt, $pos) = @_;
-    my $numer = Get16u($dataPt,$pos);
-    my $denom = Get16u($dataPt, $pos + 2) or return $numer ? 'inf' : 'undef';
-    return RoundFloat($numer / $denom, 7);
+    $ratNumer = Get16u($dataPt,$pos);
+    $ratDenom = Get16u($dataPt, $pos + 2) or return $ratNumer ? 'inf' : 'undef';
+    return RoundFloat($ratNumer / $ratDenom, 7);
 }
 sub GetRational64s($$)
 {
     my ($dataPt, $pos) = @_;
-    my $numer = Get32s($dataPt,$pos);
-    my $denom = Get32s($dataPt, $pos + 4) or return $numer ? 'inf' : 'undef';
-    return RoundFloat($numer / $denom, 10);
+    $ratNumer = Get32s($dataPt,$pos);
+    $ratDenom = Get32s($dataPt, $pos + 4) or return $ratNumer ? 'inf' : 'undef';
+    return RoundFloat($ratNumer / $ratDenom, 10);
 }
 sub GetRational64u($$)
 {
     my ($dataPt, $pos) = @_;
-    my $numer = Get32u($dataPt,$pos);
-    my $denom = Get32u($dataPt, $pos + 4) or return $numer ? 'inf' : 'undef';
-    return RoundFloat($numer / $denom, 10);
+    $ratNumer = Get32u($dataPt,$pos);
+    $ratDenom = Get32u($dataPt, $pos + 4) or return $ratNumer ? 'inf' : 'undef';
+    return RoundFloat($ratNumer / $ratDenom, 10);
 }
 sub GetFixed16s($$)
@@ -3524,4 +5217,5 @@
     int32s => 4,
     int32u => 4,
+    int32uRev => 4,
     int64s => 8,
     int64u => 8,
@@ -3534,4 +5228,5 @@
     fixed32s => 4,
     fixed32u => 4,
+    fixed64s => 8,
     float => 4,
     double => 8,
@@ -3544,4 +5239,5 @@
     ifd => 4,
     ifd64 => 8,
+    ue7 => 1,
 );
 my %readValueProc = (
@@ -3553,4 +5249,5 @@
     int32s => \&Get32s,
     int32u => \&Get32u,
+    int32uRev => \&Get32uRev,
     int64s => \&Get64s,
     int64u => \&Get64u,
@@ -3563,4 +5260,5 @@
     fixed32s => \&GetFixed32s,
     fixed32u => \&GetFixed32u,
+    fixed64s => \&GetFixed64s,
     float => \&GetFloat,
     double => \&GetDouble,
@@ -3569,4 +5267,11 @@
     ifd64 => \&Get64u,
 );
+# lookup for all rational types
+my %isRational = (
+    rational32u => 1,
+    rational32s => 1,
+    rational64u => 1,
+    rational64s => 1,
+);
 sub FormatSize($) { return $formatSize{$_[0]}; }
 
@@ -3574,11 +5279,12 @@
 # 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
+#         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($$$$$)
-{
-    my ($dataPt, $offset, $format, $count, $size) = @_;
+sub ReadValue($$$;$$$)
+{
+    my ($dataPt, $offset, $format, $count, $size, $ratPt) = @_;
 
     my $len = $formatSize{$format};
@@ -3587,4 +5293,5 @@
         $len = 1;
     }
+    $size = length($$dataPt) - $offset unless defined $size;
     unless ($count) {
         return '' if defined $count or $size < $len;
@@ -3598,5 +5305,20 @@
     my @vals;
     my $proc = $readValueProc{$format};
-    if ($proc) {
+    if (not $proc) {
+        # handle undef/binary/string (also unsupported unicode/complex)
+        $vals[0] = substr($$dataPt, $offset, $count * $len);
+        # truncate string at null terminator if necessary
+        $vals[0] =~ s/\0.*//s if $format eq 'string';
+    } elsif ($isRational{$format} and $ratPt) {
+        # store rationals separately as string fractions
+        my @rat;
+        for (;;) {
+            push @vals, &$proc($dataPt, $offset);
+            push @rat, "$ratNumer/$ratDenom";
+            last if --$count <= 0;
+            $offset += $len;
+        }
+        $$ratPt = join(' ',@rat);
+    } else {
         for (;;) {
             push @vals, &$proc($dataPt, $offset);
@@ -3604,9 +5326,4 @@
             $offset += $len;
         }
-    } else {
-        # handle undef/binary/string (also unsupported unicode/complex)
-        $vals[0] = substr($$dataPt, $offset, $count * $len);
-        # truncate string at null terminator if necessary
-        $vals[0] =~ s/\0.*//s if $format eq 'string';
     }
     return @vals if wantarray;
@@ -3706,5 +5423,5 @@
     {
         # issue warning only if the tag was specifically requested
-        if ($self->{REQ_TAG_LOOKUP}{lc GetTagName($tag)}) {
+        if ($$self{REQ_TAG_LOOKUP}{lc GetTagName($tag)}) {
             $self->Warn("$tag is not a valid JPEG image",1);
             return undef;
@@ -3712,4 +5429,31 @@
     }
     return $imagePt;
+}
+
+#------------------------------------------------------------------------------
+# Validate a tag name argument (including group name and wildcards, etc)
+# Inputs: 0) tag name
+# Returns: true if tag name is valid
+# - a tag name may contain [-_A-Za-z0-9], but may not start with [-0-9]
+# - tag names may contain wildcards [?*], and end with a hash [#]
+# - may have group name prefixes (which may have family number prefix), separated by colons
+# - a group name may be zero or more characters
+sub ValidTagName($)
+{
+    my $tag = shift;
+    return $tag =~ /^(([-\w]*|\d*\*):)*[_a-zA-Z?*][-\w?*]*#?$/;
+}
+
+#------------------------------------------------------------------------------
+# Generate a valid tag name based on the tag ID or name
+# Inputs: 0) tag ID or name
+# Returns: valid tag name
+sub MakeTagName($)
+{
+    my $name = shift;
+    $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
+    $name = ucfirst $name;          # capitalize first letter
+    $name = "Tag$name" if length($name) < 2; # must at least 2 characters long
+    return $name;
 }
 
@@ -3731,5 +5475,5 @@
     # put a space between acronyms and words
     $desc =~ s/([A-Z])([A-Z][a-z])/$1 $2/g;
-    # put spaces after numbers (if more than one character following number)
+    # put spaces after numbers (if more than one character follows the number)
     $desc =~ s/(\d)([A-Z]\S)/$1 $2/g;
     # add TagID to description
@@ -3739,4 +5483,57 @@
 
 #------------------------------------------------------------------------------
+# Get descriptions for all tags in an array
+# Inputs: 0) ExifTool ref, 1) reference to list of tag keys
+# Returns: reference to hash lookup for descriptions
+# Note: Returned descriptions are NOT escaped by ESCAPE_PROC
+sub GetDescriptions($$)
+{
+    local $_;
+    my ($self, $tags) = @_;
+    my %desc;
+    my $oldEscape = $$self{ESCAPE_PROC};
+    delete $$self{ESCAPE_PROC};
+    $desc{$_} = $self->GetDescription($_) foreach @$tags;
+    $$self{ESCAPE_PROC} = $oldEscape;
+    return \%desc;
+}
+
+#------------------------------------------------------------------------------
+# Apply filter to value(s) if necessary
+# Inputs: 0) ExifTool ref, 1) filter expression, 2) reference to value to filter
+# Returns: true unless a filter returned undef; changes value if necessary
+sub Filter($$$)
+{
+    local $_;
+    my ($self, $filter, $valPt) = @_;
+    return 1 unless defined $filter and defined $$valPt;
+    my $rtnVal;
+    if (not ref $$valPt) {
+        $_ = $$valPt;
+        #### eval Filter ($_, $self)
+        eval $filter;
+        if (defined $_) {
+            $$valPt = $_;
+            $rtnVal = 1;
+        }
+    } elsif (ref $$valPt eq 'SCALAR') {
+        my $val = $$$valPt; # make a copy to avoid filtering twice
+        $rtnVal = $self->Filter($filter, \$val);
+        $$valPt = \$val;
+    } elsif (ref $$valPt eq 'ARRAY') {
+        my @val = @{$$valPt}; # make a copy to avoid filtering twice
+        $self->Filter($filter, \$_) and $rtnVal = 1 foreach @val;
+        $$valPt = \@val;
+    } elsif (ref $$valPt eq 'HASH') {
+        my %val = %{$$valPt}; # make a copy to avoid filtering twice
+        $self->Filter($filter, \$val{$_}) and $rtnVal = 1 foreach keys %val;
+        $$valPt = \%val;
+    } else {
+        $rtnVal = 1;
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
 # Return printable value
 # Inputs: 0) ExifTool object reference
@@ -3748,14 +5545,21 @@
     $outStr =~ tr/\x01-\x1f\x7f-\xff/./;
     $outStr =~ s/\x00//g;
-    if (defined $maxLen) {
-        # minimum length is 20 (0 is unlimited)
-        $maxLen = 20 if $maxLen and $maxLen < 20;
+    my $verbose = $$self{OPTIONS}{Verbose};
+    if ($verbose < 4) {
+        if ($maxLen) {
+            $maxLen = 20 if $maxLen < 20;   # minimum length is 20
+        } elsif (defined $maxLen) {
+            $maxLen = length $outStr;       # 0 is unlimited
+        } else {
+            $maxLen = 60;                   # default maximum is 60
+        }
     } else {
-        $maxLen = 60;                   # default length is 60
-    }
-    # limit length only if verbose < 4
-    if ($maxLen and length($outStr) > $maxLen and $self->{OPTIONS}{Verbose} < 4) {
-        $outStr = substr($outStr,0,$maxLen-6) . '[snip]';
-    }
+        $maxLen = length $outStr;
+        # limit to 2048 characters if verbose < 5
+        $maxLen = 2048 if $maxLen > 2048 and $verbose < 5;
+    }
+
+    # limit length if necessary
+    $outStr = substr($outStr,0,$maxLen-6) . '[snip]' if length($outStr) > $maxLen;
     return $outStr;
 }
@@ -3768,17 +5572,43 @@
 {
     my ($self, $date) = @_;
-    my $dateFormat = $self->{OPTIONS}{DateFormat};
+    my $fmt = $$self{OPTIONS}{DateFormat};
+    my $shift = $$self{OPTIONS}{GlobalTimeShift};
+    if ($shift) {
+        my $dir = ($shift =~ s/^([-+])// and $1 eq '-') ? -1 : 1;
+        my $offset = $$self{GLOBAL_TIME_OFFSET};
+        $offset or $offset = $$self{GLOBAL_TIME_OFFSET} = { };
+        ShiftTime($date, $shift, $dir, $offset);
+    }
     # only convert date if a format was specified and the date is recognizable
-    if ($dateFormat) {
+    if ($fmt) {
+        # separate time zone if it exists
+        my $tz;
+        $date =~ s/([-+]\d{2}:\d{2}|Z)$// and $tz = $1;
         # a few cameras use incorrect date/time formatting:
         # - slashes instead of colons in date (RolleiD330, ImpressCam)
         # - date/time values separated by colon instead of space (Polariod, Sanyo, Sharp, Vivitar)
         # - single-digit seconds with leading space (HP scanners)
-        $date =~ s/[-+]\d{2}:\d{2}$//;  # remove timezone if it exists
-        my @a = ($date =~ /\d+/g);      # be very flexible about date/time format
-        if (@a and $a[0] > 1900 and $a[0] < 3000 and eval 'require POSIX') {
-            $date = POSIX::strftime($dateFormat, $a[5]||0, $a[4]||0, $a[3]||0,
-                                                 $a[2]||1, ($a[1]||1)-1, $a[0]-1900);
-        } elsif ($self->{OPTIONS}{StrictDate}) {
+        my @a = reverse ($date =~ /\d+/g);  # be very flexible about date/time format
+        if (@a and $a[-1] >= 1000 and $a[-1] < 3000 and eval { require POSIX }) {
+            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[4] -= 1;                 # base month is 1
+            # parse %z and %s ourself (to handle time zones properly)
+            if ($fmt =~ /%[sz]/) {
+                # use system time zone unless otherwise specified
+                $tz = TimeZoneString(\@a, TimeLocal(@a)) if not $tz and eval { require Time::Local };
+                # remove colon, setting to UTC if time zone is not numeric
+                $tz = ($tz and $tz=~/^([-+]\d{2}):(\d{2})$/) ? "$1$2" : '+0000';
+                $fmt =~ s/(^|[^%])((%%)*)%z/$1$2$tz/g;      # convert '%z' format codes
+                if ($fmt =~ /%s/ and eval { require Time::Local }) {
+                    # calculate seconds since the Epoch, UTC
+                    my $s = Time::Local::timegm(@a) - 60 * ($tz - int($tz/100) * 40);
+                    $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;
         }
@@ -3832,5 +5662,5 @@
 # Inputs: 0) localtime array ref, 1) gmtime array ref
 # Returns: time zone offset in minutes
-sub GetTimeZone(;$$)
+sub GetTimeZone($$)
 {
     my ($tm, $gm) = @_;
@@ -3843,4 +5673,7 @@
         $min += ($$tm[3] - $$gm[3]) * 24 * 60;
     }
+    # MirBSD patch to round to the nearest 30 minutes because
+    # it includes leap seconds in localtime but not gmtime
+    $min = int($min / 30 + ($min > 0 ? 0.5 : -0.5)) * 30 if $^O eq 'mirbsd';
     return $min;
 }
@@ -3860,4 +5693,5 @@
     my $sign = '+';
     $min < 0 and $sign = '-', $min = -$min;
+    $min = int($min + 0.5); # round off to nearest minute
     my $h = int($min / 60);
     return sprintf('%s%.2d:%.2d', $sign, $h, $min - $h * 60);
@@ -3866,12 +5700,23 @@
 #------------------------------------------------------------------------------
 # 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($;$)
-{
-    my ($time, $toLocal) = @_;
+sub ConvertUnixTime($;$$)
+{
+    my ($time, $toLocal, $dec) = @_;
     return '0000:00:00 00:00:00' if $time == 0;
     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);
@@ -3881,5 +5726,5 @@
         $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;
@@ -3888,5 +5733,5 @@
 #------------------------------------------------------------------------------
 # Get Unix time from EXIF-formatted date/time string with optional timezone
-# Inputs: 0) EXIF date/time string, 1) non-zero if time is local
+# Inputs: 0) EXIF date/time string, 1) non-zero if time is local, or 2 to assume UTC
 # Returns: Unix time (seconds since 0:00 GMT Jan 1, 1970) or undefined on error
 sub GetUnixTime($;$)
@@ -3894,18 +5739,24 @@
     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) {
-        # use specified timezone if one exists
-        $tzsec = ($2 * 60 + $3) * ($1 eq '-' ? -60 : 60) if $1;
-        undef $isLocal; # convert using GMT corrected for specified timezone
-    }
-    $tm[0] -= 1900;     # convert year
+    if ($isLocal) {
+        if ($tzStr =~ /(?:Z|([-+])(\d+):(\d+))/i) {
+            # use specified timezone if one exists
+            $tzSec = ($2 * 60 + $3) * ($1 eq '-' ? -60 : 60) if $1;
+            undef $isLocal; # convert using GMT corrected for specified timezone
+        } elsif ($isLocal eq '2') {
+            undef $isLocal;
+        }
+    }
     $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;
 }
 
@@ -3918,8 +5769,10 @@
     my $val = shift;
     $val < 2048 and return "$val bytes";
-    $val < 10240 and return sprintf('%.1f kB', $val / 1024);
-    $val < 2097152 and return sprintf('%.0f kB', $val / 1024);
-    $val < 10485760 and return sprintf('%.1f MB', $val / 1048576);
-    return sprintf('%.0f MB', $val / 1048576);
+    $val < 10240 and return sprintf('%.1f KiB', $val / 1024);
+    $val < 2097152 and return sprintf('%.0f KiB', $val / 1024);
+    $val < 10485760 and return sprintf('%.1f MiB', $val / 1048576);
+    $val < 2147483648 and return sprintf('%.0f MiB', $val / 1048576);
+    $val < 10737418240 and return sprintf('%.1f GiB', $val / 1073741824);
+    return sprintf('%.0f GiB', $val / 1073741824);
 }
 
@@ -3927,5 +5780,5 @@
 # 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($)
 {
@@ -3935,8 +5788,14 @@
     my $sign = ($time > 0 ? '' : (($time = -$time), '-'));
     return sprintf("$sign%.2f s", $time) if $time < 30;
+    $time += 0.5;   # to round off to nearest second
     my $h = int($time / 3600);
     $time -= $h * 3600;
     my $m = int($time / 60);
     $time -= $m * 60;
+    if ($h > 24) {
+        my $d = int($h / 24);
+        $h -= $d * 24;
+        $sign = "$sign$d days ";
+    }
     return sprintf("$sign%d:%.2d:%.2d", $h, $m, int($time));
 }
@@ -3961,54 +5820,55 @@
 
 #------------------------------------------------------------------------------
+# Convert file name for printing
+# Inputs: 0) ExifTool ref, 1) file name in CharsetFileName character set
+# Returns: converted file name in external character set
+sub ConvertFileName($$)
+{
+    my ($self, $val) = @_;
+    my $enc = $$self{OPTIONS}{CharsetFileName};
+    $val = $self->Decode($val, $enc) if $enc;
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Inverse conversion for file name (encode in CharsetFileName)
+# Inputs: 0) ExifTool ref, 1) file name in external character set
+# Returns: file name in CharsetFileName character set
+sub InverseFileName($$)
+{
+    my ($self, $val) = @_;
+    my $enc = $$self{OPTIONS}{CharsetFileName};
+    $val = $self->Encode($val, $enc) if $enc;
+    $val =~ tr/\\/\//;  # make sure we are using forward slashes
+    return $val;
+}
+
+#------------------------------------------------------------------------------
 # 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;
-    my $pos = shift;
+    $$self{HTML_DUMP} or return;
+    my ($pos, $len, $com, $tip, $flg, $ifd) = @_;
     $pos += $$self{BASE} if $$self{BASE};
-    $$self{HTML_DUMP} and $self->{HTML_DUMP}->Add($pos, @_);
-}
-
-#------------------------------------------------------------------------------
-# JPEG constants
-my %jpegMarker = (
-    0x01 => 'TEM',
-    0xc0 => 'SOF0', # to SOF15, with a few exceptions below
-    0xc4 => 'DHT',
-    0xc8 => 'JPGA',
-    0xcc => 'DAC',
-    0xd0 => 'RST0',
-    0xd8 => 'SOI',
-    0xd9 => 'EOI',
-    0xda => 'SOS',
-    0xdb => 'DQT',
-    0xdc => 'DNL',
-    0xdd => 'DRI',
-    0xde => 'DHP',
-    0xdf => 'EXP',
-    0xe0 => 'APP0', # to APP15
-    0xf0 => 'JPG0',
-    0xfe => 'COM',
-);
-
-#------------------------------------------------------------------------------
-# Get JPEG marker name
-# Inputs: 0) Jpeg number
-# Returns: marker name
-sub JpegMarkerName($)
-{
-    my $marker = shift;
-    my $markerName = $jpegMarker{$marker};
-    unless ($markerName) {
-        $markerName = $jpegMarker{$marker & 0xf0};
-        if ($markerName and $markerName =~ /^([A-Z]+)\d+$/) {
-            $markerName = $1 . ($marker & 0x0f);
-        } else {
-            $markerName = sprintf("marker 0x%.2x", $marker);
-        }
-    }
-    return $markerName;
+    # skip structural data blocks which have been removed from the middle of this dump
+    # (SkipData list contains ordered [start,end+1] offsets to skip)
+    if ($$self{SkipData}) {
+        my $end = $pos + $len;
+        my $skip;
+        foreach $skip (@{$$self{SkipData}}) {
+            $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, $ifd);
+                $len -= $$skip[0] - $pos;
+                $tip = 'SAME';
+            }
+            $pos = $$skip[1];
+        }
+    }
+    $$self{HTML_DUMP}->Add($pos, $len, $com, $tip, $flg, $ifd);
 }
 
@@ -4041,4 +5901,8 @@
         {
             $type = 'MIE';
+        } elsif ($buff =~ /\0\0(QDIOBS|SEFT)$/) {
+            $type = 'Samsung';
+        } elsif ($buff =~ /8db42d694ccc418790edff439fe026bf$/s) {
+            $type = 'Insta360';
         }
         last;
@@ -4072,7 +5936,12 @@
 
     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
@@ -4089,13 +5958,14 @@
 
         # 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';
 
-        # restore PATH
-        pop @$path;
-        pop @$path;
+        # restore PATH (pop last 2 items)
+        splice @$path, -2;
+
         # check result
         if ($outfile) {
@@ -4108,12 +5978,16 @@
                     $outBuff = '';      # free memory
                 }
-                if ($fixup) {
-                    # add new fixup information if any
-                    $fixup->AddFixup($$dirInfo{Fixup}) if $$dirInfo{Fixup};
-                } else {
+                if ($$dirInfo{Fixup}) {
+                    if ($fixup) {
+                        # add fixup for subsequent trailers to the fixup for this trailer
+                        # (but first we must adjust for the new start position)
+                        $$fixup{Shift} += $$dirInfo{Fixup}{Start};
+                        $$fixup{Start} -= $$dirInfo{Fixup}{Start};
+                        $$dirInfo{Fixup}->AddFixup($fixup);
+                    }
                     $fixup = $$dirInfo{Fixup};  # save fixup
                 }
             } else {
-                $success = 0 if $self->Error("Error rewriting $dirName trailer", 1);
+                $success = 0 if $self->Error("Error rewriting $dirName trailer", 2);
                 last;
             }
@@ -4139,5 +6013,79 @@
 
 #------------------------------------------------------------------------------
-# Extract EXIF information from a jpg image
+# JPEG constants
+
+# JPEG marker names
+%jpegMarker = (
+    0x00 => 'NULL',
+    0x01 => 'TEM',
+    0xc0 => 'SOF0', # to SOF15, with a few exceptions below
+    0xc4 => 'DHT',
+    0xc8 => 'JPGA',
+    0xcc => 'DAC',
+    0xd0 => 'RST0', # to RST7
+    0xd8 => 'SOI',
+    0xd9 => 'EOI',
+    0xda => 'SOS',
+    0xdb => 'DQT',
+    0xdc => 'DNL',
+    0xdd => 'DRI',
+    0xde => 'DHP',
+    0xdf => 'EXP',
+    0xe0 => 'APP0', # to APP15
+    0xf0 => 'JPG0',
+    0xfe => 'COM',
+);
+
+# lookup for size of JPEG marker length word
+# (2 bytes assumed unless specified here)
+my %markerLenBytes = (
+    0x00 => 0,  0x01 => 0,
+    0xd0 => 0,  0xd1 => 0,  0xd2 => 0,  0xd3 => 0,  0xd4 => 0,  0xd5 => 0,  0xd6 => 0,  0xd7 => 0,
+    0xd8 => 0,  0xd9 => 0,  0xda => 0,
+    # J2C
+    0x30 => 0,  0x31 => 0,  0x32 => 0,  0x33 => 0,  0x34 => 0,  0x35 => 0,  0x36 => 0,  0x37 => 0,
+    0x38 => 0,  0x39 => 0,  0x3a => 0,  0x3b => 0,  0x3c => 0,  0x3d => 0,  0x3e => 0,  0x3f => 0,
+    0x4f => 0,
+    0x92 => 0,  0x93 => 0,
+    # J2C extensions
+    0x74 => 4, 0x75 => 4, 0x77 => 4,
+);
+
+#------------------------------------------------------------------------------
+# Get JPEG marker name
+# Inputs: 0) Jpeg number
+# Returns: marker name
+sub JpegMarkerName($)
+{
+    my $marker = shift;
+    my $markerName = $jpegMarker{$marker};
+    unless ($markerName) {
+        $markerName = $jpegMarker{$marker & 0xf0};
+        if ($markerName and $markerName =~ /^([A-Z]+)\d+$/) {
+            $markerName = $1 . ($marker & 0x0f);
+        } else {
+            $markerName = sprintf("marker 0x%.2x", $marker);
+        }
+    }
+    return $markerName;
+}
+
+#------------------------------------------------------------------------------
+# Adjust directory start position
+# Inputs: 0) dirInfo ref, 1) start offset
+#         2) Base for offsets (relative to DataPos, defaults to absolute Base of 0)
+sub DirStart($$;$)
+{
+    my ($dirInfo, $start, $base) = @_;
+    $$dirInfo{DirStart} = $start;
+    $$dirInfo{DirLen} -= $start;
+    if (defined $base) {
+        $$dirInfo{Base} = $$dirInfo{DataPos} + $base;
+        $$dirInfo{DataPos} = -$base;    # (relative to Base!)
+    }
+}
+
+#------------------------------------------------------------------------------
+# Extract metadata from a jpg image
 # Inputs: 0) ExifTool object reference, 1) dirInfo ref with RAF set
 # Returns: 1 on success, 0 if this wasn't a valid JPEG file
@@ -4147,25 +6095,40 @@
     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 $htmlDump = $$self{HTML_DUMP};
     my %dumpParms = ( Out => $out );
-    my ($success, $icc_profile, $wantTrailer, $trailInfo, %extendedXMP);
-    my ($preview, $scalado, @dqt, $subSampling, $dumpEnd);
-
-    # check to be sure this is a valid JPG file
-    return 0 unless $raf->Read($s, 2) == 2 and $s eq "\xff\xd8";
+    my ($success, $wantTrailer, $trailInfo, $foundSOS);
+    my (@iccChunk, $iccChunkCount, $iccChunksTotal, @flirChunk, $flirCount, $flirTotal);
+    my ($preview, $scalado, @dqt, $subSampling, $dumpEnd, %extendedXMP);
+
+    # check to be sure this is a valid JPG (or J2C, or EXV) file
+    return 0 unless $raf->Read($s, 2) == 2 and $s =~ /^\xff[\xd8\x4f\x01]/;
+    if ($s eq "\xff\x01") {
+        return 0 unless $raf->Read($s, 5) == 5 and $s eq 'Exiv2';
+        $$self{FILE_TYPE} = 'EXV';
+    }
+    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 == 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
+
     $dumpParms{MaxLen} = 128 if $verbose < 4;
-    unless ($self->{VALUE}{FileType}) {
-        $self->SetFileType();               # set FileType tag
-        $$self{LOW_PRIORITY_DIR}{IFD1} = 1; # lower priority of IFD1 tags
-    }
     if ($htmlDump) {
         $dumpEnd = $raf->Tell();
-        my $pos = $dumpEnd - 2;
+        my ($n, $t, $m) = $s eq 'Exiv2' ? (7,'EXV','TEM') : (2,'JPEG','SOI');
+        my $pos = $dumpEnd - $n;
         $self->HDump(0, $pos, '[unknown header]') if $pos;
-        $self->HDump($pos, 2, 'JPEG header', 'SOI Marker');
+        $self->HDump($pos, $n, "$t header", "$m Marker");
     }
     my $path = $$self{PATH};
@@ -4175,5 +6138,5 @@
     local $/ = "\xff";
 
-    my ($nextMarker, $nextSegDataPt, $nextSegPos, $combinedSegData);
+    my ($nextMarker, $nextSegDataPt, $nextSegPos, $combinedSegData, $firstSegPos, @skipData);
 
     # read file until we reach an end of image (EOI) or start of scan (SOS)
@@ -4186,7 +6149,7 @@
         undef $nextSegDataPt;
 #
-# read ahead to the next segment unless we have reached EOI or SOS
+# read ahead to the next segment unless we have reached EOI, SOS or SOD
 #
-        unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer))) {
+        unless ($marker and ($marker==0xd9 or ($marker==0xda and not $wantTrailer) or $marker==0x93)) {
             # read up to next marker (JPEG markers begin with 0xff)
             my $buff;
@@ -4198,9 +6161,6 @@
                 last unless $nextMarker == 0xff;
             }
-            # read data for all markers except 0xd9 (EOI) and stand-alone
-            # markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, RST0-RST7)
-            if ($nextMarker!=0xd9 and $nextMarker!=0x00 and $nextMarker!=0x01 and
-                ($nextMarker<0xd0 or $nextMarker>0xd7))
-            {
+            # read segment data if it exists
+            if (not defined $markerLenBytes{$nextMarker}) {
                 # read record length word
                 last unless $raf->Read($s, 2) == 2;
@@ -4211,4 +6171,12 @@
                 last unless $raf->Read($buff, $len) == $len;
                 $nextSegDataPt = \$buff;    # set pointer to our next data
+            } elsif ($markerLenBytes{$nextMarker} == 4) {
+                # handle J2C extensions with 4-byte length word
+                last unless $raf->Read($s, 4) == 4;
+                my $len = unpack('N',$s);   # get data length
+                last unless defined($len) and $len >= 4;
+                $nextSegPos = $raf->Tell();
+                $len -= 4;  # subtract size of length word
+                last unless $raf->Seek($len, 1);
             }
             # read second segment too if this was the first
@@ -4227,4 +6195,7 @@
                 print $out "JPEG $markerName ($length bytes):\n";
                 HexDump($segDataPt, undef, %dumpParms, Addr=>$segPos) if $verbose>2;
+            } elsif ($htmlDump) {
+                $self->HDump($segPos-4, $length+4, "[JPEG $markerName]", undef, 0x08);
+                $dumpEnd = $segPos + $length;
             }
             next unless $length >= 6;
@@ -4232,9 +6203,9 @@
             my ($p, $h, $w, $n) = unpack('Cn2C', $$segDataPt);
             my $sof = GetTagTable('Image::ExifTool::JPEG::SOF');
-            $self->FoundTag($$sof{ImageWidth}, $w);
-            $self->FoundTag($$sof{ImageHeight}, $h);
-            $self->FoundTag($$sof{EncodingProcess}, $marker - 0xc0);
-            $self->FoundTag($$sof{BitsPerSample}, $p);
-            $self->FoundTag($$sof{ColorComponents}, $n);
+            $self->HandleTag($sof, 'ImageWidth', $w);
+            $self->HandleTag($sof, 'ImageHeight', $h);
+            $self->HandleTag($sof, 'EncodingProcess', $marker - 0xc0);
+            $self->HandleTag($sof, 'BitsPerSample', $p);
+            $self->HandleTag($sof, 'ColorComponents', $n);
             next unless $n == 3 and $length >= 15;
             my ($i, $hmin, $hmax, $vmin, $vmax);
@@ -4259,5 +6230,5 @@
             if ($hmin and $vmin) {
                 my ($hs, $vs) = ($hmax / $hmin, $vmax / $vmin);
-                $self->FoundTag($$sof{YCbCrSubSampling}, "$hs $vs");
+                $self->HandleTag($sof, 'YCbCrSubSampling', "$hs $vs");
             }
             next;
@@ -4271,9 +6242,27 @@
                 $dumpEnd = 0;
             }
-            $success = 1;
+            if ($foundSOS or $$self{FILE_TYPE} eq 'EXV') {
+                $success = 1;
+            } 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
@@ -4282,20 +6271,41 @@
                     # (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};
+                                }
                             }
                         }
@@ -4333,7 +6343,9 @@
                 }) if $endPos > $pos;
             }
+            $self->FoundTag('JPEGImageLength', $pos - $appBytes) if $calcImageLen;
             last;       # all done parsing file
         } elsif ($marker == 0xda) {         # SOS
             pop @$path;
+            $foundSOS = 1;
             # all done with meta information unless we have a trailer
             $verbose and print $out "JPEG SOS\n";
@@ -4346,5 +6358,5 @@
                     $self->ProcessTrailers($trailInfo) and undef $trailInfo;
                 }
-                if ($wantTrailer) {
+                if ($wantTrailer and $$self{PreviewImageStart}) {
                     # seek ahead and validate preview image
                     my $buff;
@@ -4363,17 +6375,32 @@
                     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;
             }
+            # 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
-        } elsif ($marker==0x00 or $marker==0x01 or ($marker>=0xd0 and $marker<=0xd7)) {
-            # handle stand-alone markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, RST0-RST7)
-            $verbose and $marker and print $out "JPEG $markerName:\n";
+        } elsif ($marker == 0x93) {
+            pop @$path;
+            $verbose and print $out "JPEG SOD\n";
+            $success = 1;
+            next if $verbose > 2 or $htmlDump;
+            last;   # all done parsing file
+        } elsif (defined $markerLenBytes{$marker}) {
+            # handle other stand-alone markers and segments we skipped over
+            $verbose and $marker and print $out "JPEG $markerName\n";
             next;
         } elsif ($marker == 0xdb and length($$segDataPt) and    # DQT
             # save the DQT data only if JPEGDigest has been requested
-            $self->{REQ_TAG_LOOKUP}->{jpegdigest})
+            # (Note: since we aren't checking the RequestAll API option here, the application
+            #  must use the RequestTags option to generate these tags if they have not been
+            #  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 ($$options{RequestAll} and $$options{RequestAll} > 2)))
         {
             my $num = unpack('C',$$segDataPt) & 0x0f;   # get table index
@@ -4382,5 +6409,7 @@
         # handle all other markers
         my $dumpType = '';
+        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";
@@ -4391,56 +6420,58 @@
             }
         }
+        # prepare dirInfo hash for processing this information
+        my %dirInfo = (
+            Parent   => $markerName,
+            DataPt   => $segDataPt,
+            DataPos  => $segPos,
+            DataLen  => $length,
+            DirStart => 0,
+            DirLen   => $length,
+            Base     => 0,
+        );
         if ($marker == 0xe0) {              # APP0 (JFIF, JFXX, CIFF, AVI1, Ocad)
             if ($$segDataPt =~ /^JFIF\0/) {
                 $dumpType = 'JFIF';
-                my %dirInfo = (
-                    DataPt => $segDataPt,
-                    DataPos  => $segPos,
-                    DirStart => 5,
-                    DirLen => $length - 5,
-                );
+                DirStart(\%dirInfo, 5); # start at byte 5
                 SetByteOrder('MM');
                 my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Main');
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
-            } elsif ($$segDataPt =~ /^JFXX\0\x10/) {
+            } elsif ($$segDataPt =~ /^JFXX\0(\x10|\x11|\x13)/) {
+                my $tag = ord $1;
                 $dumpType = 'JFXX';
                 my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Extension');
-                my $tagInfo = $self->GetTagInfo($tagTablePtr, 0x10);
+                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';
+                my %dirInfo = ( RAF => new File::RandomAccess($segDataPt) );
+                $$self{SET_GROUP1} = 'CIFF';
+                push @{$$self{PATH}}, 'CIFF';
                 require Image::ExifTool::CanonRaw;
                 Image::ExifTool::CanonRaw::ProcessCRW($self, \%dirInfo);
-                delete $self->{SET_GROUP1};
+                pop @{$$self{PATH}};
+                delete $$self{SET_GROUP1};
             } elsif ($$segDataPt =~ /^(AVI1|Ocad)/) {
                 $dumpType = $1;
                 SetByteOrder('MM');
                 my $tagTablePtr = GetTagTable("Image::ExifTool::JPEG::$dumpType");
-                my %dirInfo = (
-                    DataPt   => $segDataPt,
-                    DataPos  => $segPos,
-                    DirStart => 4,
-                    DirLen   => $length - 4,
-                );
+                DirStart(\%dirInfo, 4);
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
             }
-        } elsif ($marker == 0xe1) {         # APP1 (EXIF, XMP, QVCI)
-            if ($$segDataPt =~ /^Exif\0/) { # (some Kodak cameras don't put a second \0)
+        } 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) {
                 undef $dumpType;    # (will be dumped here)
                 # this is EXIF data --
                 # get the data block (into a common variable)
                 my $hdrLen = length($exifAPP1hdr);
-                my %dirInfo = (
-                    Parent => $markerName,
-                    DataPt => $segDataPt,
-                    DataPos => $segPos,
-                    DirStart => $hdrLen,
-                    Base => $segPos + $hdrLen,
-                );
+                if (length $1) {
+                    $hdrLen += length $1;
+                    $self->Warn('Unknown garbage at start of EXIF segment',1);
+                } elsif ($$segDataPt !~ /^Exif\0/) {
+                    $self->Warn('Incorrect EXIF segment identifier',1);
+                }
                 if ($htmlDump) {
                     $self->HDump($segPos-4, 4, 'APP1 header', "Data size: $length bytes");
@@ -4448,23 +6479,58 @@
                     $dumpEnd = $segPos + $length;
                 }
+                my $dataPt = $segDataPt;
+                if (defined $combinedSegData) {
+                    push @skipData, [ $segPos-4, $segPos+$hdrLen ];
+                    $combinedSegData .= substr($$segDataPt,$hdrLen);
+                    undef $$segDataPt;
+                    $dataPt = \$combinedSegData;
+                    $segPos = $firstSegPos;
+                }
+                # peek ahead to see if the next segment is extended EXIF
+                if ($nextMarker == $marker and
+                    $$nextSegDataPt =~ /^$exifAPP1hdr(?!(MM\0\x2a|II\x2a\0))/)
+                {
+                    # initialize combined data if necessary
+                    unless (defined $combinedSegData) {
+                        $combinedSegData = $$segDataPt;
+                        undef $$segDataPt;
+                        $firstSegPos = $segPos;
+                        $self->Warn('File contains multi-segment EXIF',1);
+                        $$self{ExtendedEXIF} = 1;
+                    }
+                    next;
+                }
+                $dirInfo{DataPt} = $dataPt;
+                $dirInfo{DataPos} = $segPos;
+                $dirInfo{DataLen} = $dirInfo{DirLen} = length $$dataPt;
+                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
-                my $start = $self->GetValue('PreviewImageStart');
-                my $length = $self->GetValue('PreviewImageLength');
-                if (not $start or not $length and $$self{PreviewError}) {
+                my $start = $self->GetValue('PreviewImageStart', 'ValueConv');
+                my $plen = $self->GetValue('PreviewImageLength', 'ValueConv');
+                if (not $start or not $plen and $$self{PreviewError}) {
                     $start = $$self{PreviewImageStart};
-                    $length = $$self{PreviewImageLength};
-                }
-                if ($start and $length and
-                    $start + $length > $self->{EXIF_POS} + length($self->{EXIF_DATA}) and
-                    $self->{REQ_TAG_LOOKUP}{previewimage})
+                    $plen = $$self{PreviewImageLength};
+                }
+                if ($start and $plen and IsInt($start) and IsInt($plen) and
+                    $start + $plen > $$self{EXIF_POS} + length($$self{EXIF_DATA}) and
+                    ($$self{REQ_TAG_LOOKUP}{previewimage} or
+                    # (extracted normally, so check Binary option)
+                    ($$options{Binary} and not $$self{EXCL_TAG_LOOKUP}{previewimage})))
                 {
                     $$self{PreviewImageStart} = $start;
-                    $$self{PreviewImageLength} = $length;
+                    $$self{PreviewImageLength} = $plen;
                     $wantTrailer = 1;
                 }
+                if (@skipData) {
+                    undef @skipData;
+                    delete $$self{SkipData};
+                }
+                undef $$dataPt;
+                next;
             } elsif ($$segDataPt =~ /^$xmpExtAPP1hdr/) {
                 # off len -- extended XMP header (75 bytes total):
@@ -4474,51 +6540,77 @@
                 #  71   4 bytes - offset for this XMP data portion
                 $dumpType = 'Extended XMP';
-                if (length $$segDataPt > 75) {
+                if ($length > 75) {
                     my ($size, $off) = unpack('x67N2', $$segDataPt);
                     my $guid = substr($$segDataPt, 35, 32);
-                    my $extXMP = $extendedXMP{$guid};
-                    $extXMP or $extXMP = $extendedXMP{$guid} = { };
-                    $$extXMP{Size} = $size;
-                    $$extXMP{$off} = substr($$segDataPt, 75);
-                    # process extended XMP if complete
-                    my @offsets;
-                    for ($off=0; $off<$size; ) {
-                        last unless defined $$extXMP{$off};
-                        push @offsets, $off;
-                        $off += length $$extXMP{$off};
-                    }
-                    if ($off == $size) {
-                        my $buff = '';
-                        # assemble XMP all together
-                        $buff .= $$extXMP{$_} foreach @offsets;
-                        $dumpType = 'Extended XMP';
-                        my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
-                        my %dirInfo = (
-                            DataPt   => \$buff,
-                            Parent   => $markerName,
-                        );
-                        $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
-                        delete $extendedXMP{$guid};
+                    if ($guid =~ /[^A-Za-z0-9]/) { # (technically, should be uppercase)
+                        $self->WarnOnce($tip = 'Invalid extended XMP GUID');
+                    } else {
+                        my $extXMP = $extendedXMP{$guid};
+                        if (not $extXMP) {
+                            $extXMP = $extendedXMP{$guid} = { };
+                        } elsif ($size != $$extXMP{Size}) {
+                            $self->WarnOnce('Inconsistent extended XMP size');
+                        }
+                        $$extXMP{Size} = $size;
+                        $$extXMP{$off} = substr($$segDataPt, 75);
+                        $tip = "Full length: $size\nChunk offset: $off\nChunk length: " .
+                            ($length - 75) . "\nGUID: $guid";
+                        # (delay processing extended XMP until after reading all segments)
                     }
                 } else {
-                    $self->Warn('Invalid extended XMP segment');
+                    $self->WarnOnce($tip = 'Invalid extended XMP segment');
                 }
             } elsif ($$segDataPt =~ /^QVCI\0/) {
                 $dumpType = 'QVCI';
                 my $tagTablePtr = GetTagTable('Image::ExifTool::Casio::QVCI');
-                my %dirInfo = (
-                    Base     => 0,
-                    DataPt   => $segDataPt,
-                    DataPos  => $segPos,
-                    DataLen  => $length,
-                    DirStart => 0,
-                    DirLen   => $length,
-                    Parent   => $markerName,
-                );
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            } elsif ($$segDataPt =~ /^FLIR\0/ and $length >= 8) {
+                $dumpType = 'FLIR';
+                # must concatenate FLIR chunks (note: handle the case where
+                # some software erroneously writes zeros for the chunk counts)
+                my $chunkNum = Get8u($segDataPt, 6);
+                my $chunksTot = Get8u($segDataPt, 7) + 1; # (note the "+ 1"!)
+                $verbose and printf $out "$$self{INDENT}FLIR chunk %d of %d\n",
+                                    $chunkNum + 1, $chunksTot;
+                if (defined $flirTotal) {
+                    # abort parsing FLIR if the total chunk count is inconsistent
+                    undef $flirCount if $chunksTot != $flirTotal;
+                } else {
+                    $flirCount = 0;
+                    $flirTotal = $chunksTot;
+                }
+                if (defined $flirCount) {
+                    if (defined $flirChunk[$chunkNum]) {
+                        $self->WarnOnce('Duplicate FLIR chunk number(s)');
+                        $flirChunk[$chunkNum] .= substr($$segDataPt, 8);
+                    } else {
+                        $flirChunk[$chunkNum] = substr($$segDataPt, 8);
+                    }
+                    # process the FLIR information if we have all of the chunks
+                    if (++$flirCount >= $flirTotal) {
+                        my $flir = '';
+                        defined $_ and $flir .= $_ foreach @flirChunk;
+                        undef @flirChunk;   # free memory
+                        my $tagTablePtr = GetTagTable('Image::ExifTool::FLIR::FFF');
+                        my %dirInfo = (
+                            DataPt   => \$flir,
+                            Parent   => $markerName,
+                            DirName  => 'FLIR',
+                        );
+                        $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                        undef $flirCount;   # prevent reprocessing
+                    }
+                } 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;
-                if ($$segDataPt =~ /^http/ or $$segDataPt =~ /<exif:/) {
+                if ($$segDataPt =~ /^(http|XMP\0)/ or $$segDataPt =~ /<(exif:|\?xpacket)/) {
                     $dumpType = 'XMP';
                     # also try to parse XMP with a non-standard header
@@ -4526,13 +6618,6 @@
                     my $start = ($$segDataPt =~ /^$xmpAPP1hdr/) ? length($xmpAPP1hdr) : 0;
                     my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
-                    my %dirInfo = (
-                        Base     => 0,
-                        DataPt   => $segDataPt,
-                        DataPos  => $segPos,
-                        DataLen  => $length,
-                        DirStart => $start,
-                        DirLen   => $length - $start,
-                        Parent   => $markerName,
-                    );
+                    DirStart(\%dirInfo, $start);
+                    $dirInfo{DirName} = $start ? 'XMP' : 'XML',
                     $processed = $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
                     if ($processed and not $start) {
@@ -4541,17 +6626,35 @@
                 }
                 if ($verbose and not $processed) {
-                    $self->Warn("Ignored EXIF block length $length (bad header)");
+                    $self->Warn("Ignored APP1 segment length $length (unknown header)");
                 }
             }
         } elsif ($marker == 0xe2) {         # APP2 (ICC Profile, FPXR, MPF, PreviewImage)
-            if ($$segDataPt =~ /^ICC_PROFILE\0/) {
+            if ($$segDataPt =~ /^ICC_PROFILE\0/ and $length >= 14) {
                 $dumpType = 'ICC_Profile';
-                # must concatenate blocks of profile
-                my $block_num = Get8u($segDataPt, 12);
-                my $blocks_tot = Get8u($segDataPt, 13);
-                $icc_profile = '' if $block_num == 1;
-                if (defined $icc_profile) {
-                    $icc_profile .= substr($$segDataPt, 14);
-                    if ($block_num == $blocks_tot) {
+                # must concatenate profile chunks (note: handle the case where
+                # some software erroneously writes zeros for the chunk counts)
+                my $chunkNum = Get8u($segDataPt, 12);
+                my $chunksTot = Get8u($segDataPt, 13);
+                $verbose and print $out "$$self{INDENT}ICC_Profile chunk $chunkNum of $chunksTot\n";
+                if (defined $iccChunksTotal) {
+                    # abort parsing ICC_Profile if the total chunk count is inconsistent
+                    undef $iccChunkCount if $chunksTot != $iccChunksTotal;
+                } else {
+                    $iccChunkCount = 0;
+                    $iccChunksTotal = $chunksTot;
+                    $self->Warn('ICC_Profile chunk count is zero') if !$chunksTot;
+                }
+                if (defined $iccChunkCount) {
+                    if (defined $iccChunk[$chunkNum]) {
+                        $self->WarnOnce('Duplicate ICC_Profile chunk number(s)');
+                        $iccChunk[$chunkNum] .= substr($$segDataPt, 14);
+                    } else {
+                        $iccChunk[$chunkNum] = substr($$segDataPt, 14);
+                    }
+                    # process profile if we have all of the chunks
+                    if (++$iccChunkCount >= $iccChunksTotal) {
+                        my $icc_profile = '';
+                        defined $_ and $icc_profile .= $_ foreach @iccChunk;
+                        undef @iccChunk;   # free memory
                         my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
                         my %dirInfo = (
@@ -4564,32 +6667,20 @@
                         );
                         $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
-                        undef $icc_profile;
+                        undef $iccChunkCount;     # prevent reprocessing
                     }
+                } else {
+                    $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');
-                my %dirInfo = (
-                    DataPt   => $segDataPt,
-                    DataPos  => $segPos,
-                    DataLen  => $length,
-                    DirStart => 0,
-                    DirLen   => $length,
-                    Parent   => $markerName,
-                    # set flag if this is the last FPXR segment
-                    LastFPXR => not ($nextMarker==$marker and $$nextSegDataPt=~/^FPXR\0/),
-                );
+                # set flag if this is the last FPXR segment
+                $dirInfo{LastFPXR} = not ($nextMarker==$marker and $$nextSegDataPt=~/^FPXR\0/),
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
             } elsif ($$segDataPt =~ /^MPF\0/) {
                 undef $dumpType;    # (will be dumped here)
-                my %dirInfo = (
-                    Parent => $markerName,
-                    DataPt => $segDataPt,
-                    DataPos => $segPos,
-                    DirStart => 4,
-                    Base => $segPos + 4,
-                    Multi => 1, # the MP Attribute IFD will be MPF1
-                );
+                DirStart(\%dirInfo, 4, 4);
+                $dirInfo{Multi} = 1;    # the MP Attribute IFD will be MPF1
                 if ($htmlDump) {
                     $self->HDump($segPos-4, 4, 'APP2 header', "Data size: $length bytes");
@@ -4600,10 +6691,12 @@
                 my $tagTablePtr = GetTagTable('Image::ExifTool::MPF::Main');
                 $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
-            } elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) {
-                $preview = $$segDataPt;
-                $dumpType = 'Samsung Preview';
+            } elsif ($$segDataPt =~ /^(|QVGA\0|BGTH)\xff\xd8\xff[\xdb\xe0\xe1]/) {
+                # Samsung/GE/GoPro="", BenQ DC C1220/Pentacon/Polaroid="QVGA\0",
+                # Digilife DDC-690/Rollei="BGTH"
+                $dumpType = 'Preview Image';
+                $preview = substr($$segDataPt, length($1));
             } elsif ($preview) {
+                $dumpType = 'Preview Image';
                 $preview .= $$segDataPt;
-                $dumpType = 'Samsung Preview';
             }
             if ($preview and $nextMarker ne $marker) {
@@ -4614,11 +6707,5 @@
             if ($$segDataPt =~ /^(Meta|META|Exif)\0\0/) {
                 undef $dumpType;    # (will be dumped here)
-                my %dirInfo = (
-                    Parent => $markerName,
-                    DataPt => $segDataPt,
-                    DataPos => $segPos,
-                    DirStart => 6,
-                    Base => $segPos + 6,
-                );
+                DirStart(\%dirInfo, 6, 6);
                 if ($htmlDump) {
                     $self->HDump($segPos-4, 10, 'APP3 Meta header');
@@ -4629,11 +6716,5 @@
             } elsif ($$segDataPt =~ /^Stim\0/) {
                 undef $dumpType;    # (will be dumped here)
-                my %dirInfo = (
-                    Parent => $markerName,
-                    DataPt => $segDataPt,
-                    DataPos => $segPos,
-                    DirStart => 6,
-                    Base => $segPos + 6,
-                );
+                DirStart(\%dirInfo, 6, 6);
                 if ($htmlDump) {
                     $self->HDump($segPos-4, 4, 'APP3 header', "Data size: $length bytes");
@@ -4644,10 +6725,25 @@
                 my $tagTablePtr = GetTagTable('Image::ExifTool::Stim::Main');
                 $self->ProcessTIFF(\%dirInfo, $tagTablePtr);
+            } elsif ($$self{Make} eq 'DJI') {
+                $dumpType = 'DJI ThermalData';
+                # add this data to the combined data if it exists
+                my $dataPt = $segDataPt;
+                if (defined $combinedSegData) {
+                    $combinedSegData .= $$segDataPt;
+                    $dataPt = \$combinedSegData;
+                }
+                if ($nextMarker == $marker) {
+                    $combinedSegData = $$segDataPt unless defined $combinedSegData;
+                } else {
+                    # process DJI FLIR thermal data
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::Main');
+                    $self->HandleTag($tagTablePtr, 'APP3', $$dataPt);
+                    undef $combinedSegData;
+                }
             } elsif ($$segDataPt =~ /^\xff\xd8\xff\xdb/) {
+                $dumpType = 'PreviewImage'; # (Samsung, HP, BenQ)
                 $preview = $$segDataPt;
-                $dumpType = 'Samsung/HP Preview';
-            }
-            # Samsung continues the preview in APP4
-            if ($preview and $nextMarker ne 0xe4) {
+            }
+            if ($preview and $nextMarker ne 0xe4) { # this preview continues in APP4
                 $self->FoundTag('PreviewImage', $preview);
                 undef $preview;
@@ -4668,55 +6764,56 @@
                         DataPt => \$scalado,
                     );
-                    my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::Scalado');
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::Scalado::Main');
                     $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
                     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');
-                my %dirInfo = (
-                    DataPt   => $segDataPt,
-                    DataPos  => $segPos,
-                    DataLen  => $length,
-                    DirStart => 0,
-                    DirLen   => $length,
-                    Parent   => $markerName,
-                    # set flag if this is the last FPXR segment
-                    LastFPXR => not ($nextMarker==$marker and $$nextSegDataPt=~/^FPXR\0/),
-                );
+                # set flag if this is the last FPXR segment
+                $dirInfo{LastFPXR} = not ($nextMarker==$marker and $$nextSegDataPt=~/^FPXR\0/),
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            } elsif ($$self{Make} eq 'DJI' and $$segDataPt =~ /^\xaa\x55\x12\x06/) {
+                $dumpType = 'DJI ThermalParams';
+                DirStart(\%dirInfo, 0, 0);
+                my $tagTablePtr = GetTagTable('Image::ExifTool::DJI::ThermalParams');
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
             } elsif ($preview) {
                 # continued Samsung S1060 preview from APP3
+                $dumpType = 'PreviewImage';
                 $preview .= $$segDataPt;
-                # (not sure if next part would be APP5 or APP4 again, but assume APP4)
-                if ($nextMarker ne $marker) {
-                    $self->FoundTag('PreviewImage', $preview);
-                    undef $preview;
-                }
+            }
+            # (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);
+                undef $preview;
             }
         } elsif ($marker == 0xe5) {         # APP5 (Ricoh "RMETA")
             if ($$segDataPt =~ /^RMETA\0/) {
+                # (NOTE: apparently these may span multiple segments, but I haven't seen
+                # a sample like this, so multi-segment support hasn't yet been implemented)
                 $dumpType = 'Ricoh RMETA';
-                my %dirInfo = (
-                    Parent => $markerName,
-                    DataPt => $segDataPt,
-                    DataPos => $segPos,
-                    DirStart => 6,
-                    Base => $segPos + 6,
-                );
+                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 ($$self{Make} eq 'DJI') {
+                $dumpType = 'DJI ThermalCal';
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::Main');
+                $self->HandleTag($tagTablePtr, 'APP5', $$segDataPt);
+            } elsif ($preview) {
+                $dumpType = 'PreviewImage';
+                $preview .= $$segDataPt;
+                $self->FoundTag('PreviewImage', $preview);
+                undef $preview;
             }
         } elsif ($marker == 0xe6) {         # APP6 (Toshiba EPPIM, NITF, HP_TDHD)
             if ($$segDataPt =~ /^EPPIM\0/) {
                 undef $dumpType;    # (will be dumped here)
-                my %dirInfo = (
-                    Parent => $markerName,
-                    DataPt => $segDataPt,
-                    DataPos => $segPos,
-                    DirStart => 6,
-                    Base => $segPos + 6,
-                );
+                DirStart(\%dirInfo, 6, 6);
                 if ($htmlDump) {
                     $self->HDump($segPos-4, 10, 'APP6 EPPIM header');
@@ -4729,10 +6826,5 @@
                 SetByteOrder('MM');
                 my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::NITF');
-                my %dirInfo = (
-                    DataPt   => $segDataPt,
-                    DataPos  => $segPos,
-                    DirStart => 5,
-                    DirLen   => $length - 5,
-                );
+                DirStart(\%dirInfo, 5);
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
             } elsif ($$segDataPt =~ /^TDHD\x01\0\0\0/ and $length > 12) {
@@ -4740,10 +6832,56 @@
                 $dumpType = 'TDHD';
                 my $tagTablePtr = GetTagTable('Image::ExifTool::HP::TDHD');
-                my %dirInfo = (
-                    DataPt   => $segDataPt,
-                    DataPos  => $segPos,
-                    DirStart => 12, # (ignore first TDHD element because size includes 12-byte tag header)
-                    DirLen   => $length - 12,
-                );
+                # (ignore first TDHD element because size includes 12-byte tag header)
+                DirStart(\%dirInfo, 12);
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            } elsif ($$segDataPt =~ /^GoPro\0/) {
+                # GoPro segment
+                $dumpType = 'GoPro';
+                my $tagTablePtr = GetTagTable('Image::ExifTool::GoPro::GPMF');
+                DirStart(\%dirInfo, 6);
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            } elsif ($$segDataPt =~ /^DTAT\0\0.\{/s) {
+                $dumpType = 'DJI_DTAT';
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::Main');
+                $self->HandleTag($tagTablePtr, 'APP6', $$segDataPt);
+            }
+        } elsif ($marker == 0xe7) {         # APP7 (Pentax, Huawei, Qualcomm)
+            if ($$segDataPt =~ /^PENTAX \0(II|MM)/) {
+                # found in K-3 images (is this multi-segment??)
+                SetByteOrder($1);
+                undef $dumpType; # (dump this ourself)
+                my $hdrLen = 10;
+                my $tagTablePtr = GetTagTable('Image::ExifTool::Pentax::Main');
+                DirStart(\%dirInfo, $hdrLen, 0);
+                $dirInfo{DirName} = 'Pentax APP7';
+                if ($htmlDump) {
+                    $self->HDump($segPos-4, 4, 'APP7 header', "Data size: $length bytes");
+                    $self->HDump($segPos, $hdrLen, 'Pentax header', 'APP7 data type: Pentax');
+                    $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';
+                my $tagTablePtr = GetTagTable('Image::ExifTool::Qualcomm::Main');
+                DirStart(\%dirInfo, 27);
+                $dirInfo{DirName} = 'Qualcomm';
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
             }
@@ -4752,12 +6890,17 @@
             if ($$segDataPt =~ /^SPIFF\0/ and $length == 32) {
                 $dumpType = 'SPIFF';
-                my %dirInfo = (
-                    DataPt => $segDataPt,
-                    DataPos  => $segPos,
-                    DirStart => 6,
-                    DirLen => $length - 6,
-                );
+                DirStart(\%dirInfo, 6);
                 my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::SPIFF');
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+        } elsif ($marker == 0xe9) {         # APP9 (Media Jukebox)
+            if ($$segDataPt =~ /^Media Jukebox\0/ and $length > 22) {
+                $dumpType = 'MediaJukebox';
+                # (start parsing after the "<MJMD>")
+                DirStart(\%dirInfo, 22);
+                $dirInfo{DirName} = 'MediaJukebox';
+                require Image::ExifTool::XMP;
+                my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::MediaJukebox');
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr, \&Image::ExifTool::XMP::ProcessXMP);
             }
         } elsif ($marker == 0xea) {         # APP10 (PhotoStudio Unicode comments)
@@ -4766,18 +6909,37 @@
                 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 /) {
+                $dumpType = 'JPEG-HDR';
+                my $dataPt = $segDataPt;
+                if (defined $combinedSegData) {
+                    if ($$segDataPt =~ /~\0/g) {
+                        $combinedSegData .= substr($$segDataPt,pos($$segDataPt));
+                    } else {
+                        $self->Warn('Invalid format for JPEG-HDR extended segment');
+                    }
+                    $dataPt = \$combinedSegData;
+                }
+                if ($nextMarker == $marker and $$nextSegDataPt =~ /^HDR_RI /) {
+                    $combinedSegData = $$segDataPt unless defined $combinedSegData;
+                } else {
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::HDR');
+                    my %dirInfo = ( DataPt => $dataPt );
+                    $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                    undef $combinedSegData;
+                }
             }
         } elsif ($marker == 0xec) {         # APP12 (Ducky, Picture Info)
             if ($$segDataPt =~ /^Ducky/) {
                 $dumpType = 'Ducky';
-                my %dirInfo = (
-                    DataPt => $segDataPt,
-                    DataPos => $segPos,
-                    DirStart => 5,
-                    DirLen => $length - 5,
-                );
+                DirStart(\%dirInfo, 5);
                 my $tagTablePtr = GetTagTable('Image::ExifTool::APP12::Ducky');
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
             } else {
-                my %dirInfo = ( DataPt => $segDataPt );
                 my $tagTablePtr = GetTagTable('Image::ExifTool::APP12::PictureInfo');
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr) and $dumpType = 'Picture Info';
@@ -4799,5 +6961,5 @@
                     # (will handle the Photoshop data the next time around)
                 } else {
-                    my $hdrlen = $isOld ? 27 : 14;
+                    my $hdrLen = $isOld ? 27 : 14;
                     # process APP13 Photoshop record
                     my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
@@ -4806,6 +6968,6 @@
                         DataPos  => $segPos,
                         DataLen  => length $$dataPt,
-                        DirStart => $hdrlen,    # directory starts after identifier
-                        DirLen   => length($$dataPt) - $hdrlen,
+                        DirStart => $hdrLen,    # directory starts after identifier
+                        DirLen   => length($$dataPt) - $hdrLen,
                         Parent   => $markerName,
                     );
@@ -4817,23 +6979,20 @@
                 SetByteOrder('MM');
                 my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::AdobeCM');
-                my %dirInfo = (
-                    DataPt   => $segDataPt,
-                    DataPos  => $segPos,
-                    DirStart => 8,
-                    DirLen   => $length - 8,
-                );
+                DirStart(\%dirInfo, 8);
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
             }
         } elsif ($marker == 0xee) {         # APP14 (Adobe)
             if ($$segDataPt =~ /^Adobe/) {
+                # extract as a block if requested, or if copying tags from file
+                if ($$self{REQ_TAG_LOOKUP}{adobe} or
+                    # (not extracted normally, so check TAGS_FROM_FILE)
+                    ($$self{TAGS_FROM_FILE} and not $$self{EXCL_TAG_LOOKUP}{adobe}))
+                {
+                    $self->FoundTag('Adobe', $$segDataPt);
+                }
                 $dumpType = 'Adobe';
                 SetByteOrder('MM');
                 my $tagTablePtr = GetTagTable('Image::ExifTool::JPEG::Adobe');
-                my %dirInfo = (
-                    DataPt   => $segDataPt,
-                    DataPos  => $segPos,
-                    DirStart => 5,
-                    DirLen   => $length - 5,
-                );
+                DirStart(\%dirInfo, 5);
                 $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
             }
@@ -4848,14 +7007,30 @@
             $$segDataPt =~ s/\0+$//;    # some dumb softwares add null terminators
             $self->FoundTag('Comment', $$segDataPt);
+        } elsif ($marker == 0x64) {         # CME (J2C comment and extension)
+            $dumpType = 'Comment';
+            if ($length > 2) {
+                my $reg = unpack('n', $$segDataPt); # get registration value
+                my $val = substr($$segDataPt, 2);
+                $val = $self->Decode($val, 'Latin') if $reg == 1;
+                # (actually an extension for $reg==65535, but store as binary comment)
+                $self->FoundTag('Comment', ($reg==0 or $reg==65535) ? \$val : $val);
+            }
+        } elsif ($marker == 0x51) {         # SIZ (J2C)
+            my ($w, $h) = unpack('x2N2', $$segDataPt);
+            $self->FoundTag('ImageWidth', $w);
+            $self->FoundTag('ImageHeight', $h);
         } elsif (($marker & 0xf0) != 0xe0) {
-            undef $dumpType;    # only dump unknown APP segments
+            $dumpType = "$markerName segment";
+            $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) {
-                my $desc = $markerName . ($dumpType ? " $dumpType" : '') . ' segment';
-                $self->HDump($segPos-4, $length+4, $desc, undef, 0x08);
+                $desc or $desc = $markerName . ($dumpType ? " $dumpType" : '') . ' segment';
+                $self->HDump($segPos-4, $length+4, $desc, $tip, 0x08);
                 $dumpEnd = $segPos + $length;
             }
@@ -4863,14 +7038,70 @@
         undef $$segDataPt;
     }
+    # process extended XMP now if it existed
+    if (%extendedXMP) {
+        my $guid;
+        # 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 = $$options{ExtendedXMP} || 0;
+        $readGuid = $goodGuid if $readGuid eq '1';
+        foreach $guid (sort keys %extendedXMP) {
+            next unless length $guid == 32;     # ignore other (internal) keys
+            my $extXMP = $extendedXMP{$guid};
+            my ($off, @offsets, $warn);
+            # make sure we have all chunks, and create a list of sorted offsets
+            for ($off=0; $off<$$extXMP{Size}; ) {
+                last unless defined $$extXMP{$off};
+                push @offsets, $off;
+                $off += length $$extXMP{$off};
+            }
+            unless ($off == $$extXMP{Size}) {
+                $self->Warn("Incomplete extended XMP (GUID $guid)");
+                next;
+            }
+            if ($guid eq $readGuid or $readGuid eq '2') {
+                $warn = 'Reading non-' if $guid ne $goodGuid;
+                my $buff = '';
+                # assemble XMP all together
+                $buff .= $$extXMP{$_} foreach @offsets;
+                my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+                my %dirInfo = (
+                    DataPt      => \$buff,
+                    Parent      => 'APP1',
+                    IsExtended  => 1,
+                );
+                $$path[$pn] = 'APP1';
+                $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                pop @$path;
+            } else {
+                $warn = 'Ignored ';
+                $warn .= 'non-' if $guid ne $goodGuid;
+            }
+            $self->Warn("${warn}standard extended XMP (GUID $guid)") if $warn;
+            delete $extendedXMP{$guid};
+        }
+    }
     # calculate JPEGDigest if requested
-    if (@dqt and $subSampling) {
+    if (@dqt) {
         require Image::ExifTool::JPEGDigest;
         Image::ExifTool::JPEGDigest::Calculate($self, \@dqt, $subSampling);
     }
+    # issue necessary warnings
+    $self->Warn('Incomplete ICC_Profile record', 1) if defined $iccChunkCount;
+    $self->Warn('Incomplete FLIR record', 1) if defined $flirCount;
     $self->Warn('Error reading PreviewImage', 1) if $$self{PreviewError};
-    $self->Warn('Invalid extended XMP') if %extendedXMP;
     $success or $self->Warn('JPEG format error');
     pop @$path if @$path > $pn;
     return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract metadata from an Exiv2 EXV file
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref with RAF set
+# Returns: 1 on success, 0 if this wasn't a valid JPEG file
+sub ProcessEXV($$)
+{
+    my ($self, $dirInfo) = @_;
+    return $self->ProcessJPEG($dirInfo);
 }
 
@@ -4914,8 +7145,8 @@
     my $base = $$dirInfo{Base} || 0;
     my $outfile = $$dirInfo{OutFile};
-    my ($err, $canonSig, $otherSig);
+    my ($err, $sig, $canonSig, $otherSig);
 
     # attempt to read TIFF header
-    $self->{EXIF_DATA} = '';
+    $$self{EXIF_DATA} = '';
     if ($raf) {
         if ($outfile) {
@@ -4930,9 +7161,9 @@
         # extract full EXIF block (for block copy) from EXIF file
         my $amount = $fileType eq 'EXIF' ? 65536 * 8 : 8;
-        my $n = $raf->Read($self->{EXIF_DATA}, $amount);
+        my $n = $raf->Read($$self{EXIF_DATA}, $amount);
         if ($n < 8) {
             return 0 if $n or not $outfile or $fileType ne 'EXIF';
             # create EXIF file from scratch
-            delete $self->{EXIF_DATA};
+            delete $$self{EXIF_DATA};
             undef $raf;
         }
@@ -4940,5 +7171,5 @@
             $raf->Seek(8, 0);
             if ($n == $amount) {
-                $self->{EXIF_DATA} = substr($self->{EXIF_DATA}, 0, 8);
+                $$self{EXIF_DATA} = substr($$self{EXIF_DATA}, 0, 8);
                 $self->Warn('EXIF too large to extract as a block'); #(shouldn't happen)
             }
@@ -4948,22 +7179,27 @@
         my $dirStart = $$dirInfo{DirStart} || 0;
         my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
-        $self->{EXIF_DATA} = substr($$dataPt, $dirStart, $dirLen);
-        $self->VerboseDir('TIFF') if $self->{OPTIONS}{Verbose} and length($$self{INDENT}) > 2;
+        $$self{EXIF_DATA} = substr($$dataPt, $dirStart, $dirLen);
+        $self->VerboseDir('TIFF') if $$self{OPTIONS}{Verbose} and length($$self{INDENT}) > 2;
     } elsif ($outfile) {
-        delete $self->{EXIF_DATA};  # create from scratch
+        delete $$self{EXIF_DATA};  # create from scratch
     } else {
-        $self->{EXIF_DATA} = '';
-    }
-    unless (defined $self->{EXIF_DATA}) {
+        $$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') {
-            $self->{EXIF_DATA} = "MM\0\x2a\0\0\0\x08";
+        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_DATA} = "II\x2a\0\x08\0\0\0";
+        }
+    }
     $$self{EXIF_POS} = $base + $$self{BASE};
-    $dataPt = \$self->{EXIF_DATA};
+    $$self{FIRST_EXIF_POS} = $$self{EXIF_POS} unless defined $$self{FIRST_EXIF_POS};
+    $dataPt = \$$self{EXIF_DATA};
 
     # set byte ordering
@@ -4977,20 +7213,27 @@
   # (TIFF=0x2a, RW2/RWL=0x55, HDP=0xbc, BTF=0x2b, ORF=0x4f52/0x5352/0x????)
   #  return 0 unless $identifier == 0x2a;
+    $self->Warn('Invalid magic number in EXIF TIFF header') if $fileType eq 'APP1' and $identifier != 0x2a;
 
     # get offset to IFD0
+    return 0 if length $$dataPt < 8;
     my $offset = Get32u($dataPt, 4);
     $offset >= 8 or return 0;
 
     if ($raf) {
-        # Canon CR2 images usually have an offset of 16, but it may be
-        # greater if edited by PhotoMechanic, so check the 4-byte signature
+        # check for canon or EXIF signature
+        # (Canon CR2 images should have an offset of 16, but it may be
+        #  greater if edited by PhotoMechanic)
         if ($identifier == 0x2a and $offset >= 16) {
-            $raf->Read($canonSig, 8) == 8 or return 0;
-            $$dataPt .= $canonSig;
-            if ($canonSig =~ /^(CR\x02\0|\xba\xb0\xac\xbb)/) {
-                $fileType = $canonSig =~ /^CR/ ? 'CR2' : 'Canon 1D RAW';
-                $self->HDump($base+8, 8, "[$fileType header]") if $self->{HTML_DUMP};
-            } else {
-                undef $canonSig;
+            $raf->Read($sig, 8) == 8 or return 0;
+            $$dataPt .= $sig;
+            if ($sig =~ /^(CR\x02\0|\xba\xb0\xac\xbb|ExifMeta)/) {
+                if ($sig eq 'ExifMeta') {
+                    $self->SetFileType($fileType = 'EXIF');
+                    $otherSig = $sig;
+                } else {
+                    $fileType = $sig =~ /^CR/ ? 'CR2' : 'Canon 1D RAW';
+                    $canonSig = $sig;
+                }
+                $self->HDump($base+8, 8, "[$fileType header]") if $$self{HTML_DUMP};
             }
         } elsif ($identifier == 0x55 and $fileType =~ /^(RAW|RW2|RWL|TIFF)$/) {
@@ -5008,36 +7251,47 @@
             }
             $tagTablePtr = GetTagTable('Image::ExifTool::PanasonicRaw::Main');
-        } elsif ($identifier == 0x2b and $fileType eq 'TIFF') {
-            # this looks like a BigTIFF image
-            $raf->Seek(0);
-            require Image::ExifTool::BigTIFF;
-            return 1 if Image::ExifTool::BigTIFF::ProcessBTF($self, $dirInfo);
-        } elsif (Get8u($dataPt, 2) == 0xbc and $byteOrder eq 'II' and $fileType eq 'TIFF') {
-            $fileType = 'HDP';  # Windows HD Photo file
-            # check version number
-            my $ver = Get8u($dataPt, 3);
-            if ($ver > 1) {
-                $self->Error("Windows HD Photo version $ver files not yet supported");
-                return 1;
-            }
-        } elsif ($identifier == 0x4352 and $fileType eq 'TIFF') {
-            $fileType = 'DCP';
+        } elsif ($fileType eq 'TIFF') {
+            if ($identifier == 0x2b) {
+                # this looks like a BigTIFF image
+                $raf->Seek(0);
+                require Image::ExifTool::BigTIFF;
+                return 1 if Image::ExifTool::BigTIFF::ProcessBTF($self, $dirInfo);
+            } elsif ($identifier == 0x4f52 or $identifier == 0x5352) {
+                # Olympus ORF image (set FileType now because base type is 'ORF')
+                $self->SetFileType($fileType = 'ORF');
+            } elsif ($identifier == 0x4352) {
+                $fileType = 'DCP';
+            } elsif ($byteOrder eq 'II' and ($identifier & 0xff) == 0xbc) {
+                $fileType = 'HDP';  # Windows HD Photo file
+                # check version number
+                my $ver = Get8u($dataPt, 3);
+                if ($ver > 1) {
+                    $self->Error("Windows HD Photo version $ver files not yet supported");
+                    return 1;
+                }
+            }
         }
         # we have a valid TIFF (or whatever) file
-        if ($fileType and not $self->{VALUE}{FileType}) {
+        if ($fileType and not $$self{VALUE}{FileType}) {
             my $lookup = $fileTypeLookup{$fileType};
             $lookup = $fileTypeLookup{$lookup} unless ref $lookup or not $lookup;
             # use file extension to pre-determine type if extension is TIFF-based or type is RAW
-            my $t = (($lookup and $$lookup[0] eq 'TIFF') or $fileType =~ /RAW/) ? $fileType : undef;
+            my $baseType = $lookup ? (ref $$lookup[0] ? $$lookup[0][0] : $$lookup[0]) : '';
+            my $t = ($baseType eq 'TIFF' or $fileType =~ /RAW/) ? $fileType : undef;
             $self->SetFileType($t);
         }
-    }
-    my $ifdName = 'IFD0';
+        # don't process file if FastScan == 3
+        return 1 if not $outfile and $$self{OPTIONS}{FastScan} and $$self{OPTIONS}{FastScan} == 3;
+    }
+    # (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);
+        $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};
     }
-    if ($self->{HTML_DUMP}) {
+    if ($$self{HTML_DUMP}) {
         my $tip = sprintf("Byte order: %s endian\nIdentifier: 0x%.4x\n$ifdName offset: 0x%.4x",
                           ($byteOrder eq 'II') ? 'Little' : 'Big', $identifier, $offset);
@@ -5045,5 +7299,5 @@
     }
     # remember where we found the TIFF data (APP1, APP3, TIFF, NEF, etc...)
-    $self->{TIFF_TYPE} = $fileType;
+    $$self{TIFF_TYPE} = $fileType;
 
     # get reference to the main EXIF table
@@ -5070,5 +7324,5 @@
         $self->ProcessDirectory(\%dirInfo, $tagTablePtr);
         # process GeoTiff information if available
-        if ($self->{VALUE}{GeoTiffDirectory}) {
+        if ($$self{VALUE}{GeoTiffDirectory}) {
             require Image::ExifTool::GeoTiff;
             Image::ExifTool::GeoTiff::ProcessGeoTiff($self);
@@ -5081,5 +7335,5 @@
                 $self->ProcessTrailers($trailInfo);
             }
-            # dump any other known trailer (ie. A100 RAW Data)
+            # dump any other known trailer (eg. A100 RAW Data)
             if ($$self{HTML_DUMP} and $$self{KnownTrailer}) {
                 my $known = $$self{KnownTrailer};
@@ -5091,7 +7345,7 @@
         }
         # update FileType if necessary now that we know more about the file
-        if ($$self{DNGVersion} and $self->{VALUE}{FileType} ne 'DNG') {
+        if ($$self{DNGVersion} and $$self{VALUE}{FileType} !~ /^(DNG|GPR)$/) {
             # override whatever FileType we set since we now know it is DNG
-            $self->OverrideFileType('DNG');
+            $self->OverrideFileType($$self{TIFF_TYPE} = 'DNG');
         }
         return 1;
@@ -5101,8 +7355,8 @@
 #
     if ($$dirInfo{NoTiffEnd}) {
-        delete $self->{TIFF_END};
+        delete $$self{TIFF_END};
     } else {
         # initialize TIFF_END so it will be updated by WriteExif()
-        $self->{TIFF_END} = 0;
+        $$self{TIFF_END} = 0;
     }
     if ($canonSig) {
@@ -5114,5 +7368,9 @@
     } else {
         # write TIFF header (8 bytes [plus optional signature] followed by IFD)
-        $otherSig = '' unless defined $otherSig;
+        if ($fileType eq 'EXIF') {
+            $otherSig = 'ExifMeta'; # force this signature for all EXIF files
+        } elsif (not defined $otherSig) {
+            $otherSig = '';
+        }
         my $offset = 8 + length($otherSig);
         # construct tiff header
@@ -5138,5 +7396,5 @@
                 # write any required ARW trailer and patch other ARW quirks
                 require Image::ExifTool::Sony;
-                my $errStr = Image::ExifTool::Sony::FinishARW($self, $dirInfo, \$newData, 
+                my $errStr = Image::ExifTool::Sony::FinishARW($self, $dirInfo, \$newData,
                                                               $dirInfo{ImageData});
                 $errStr and $self->Error($errStr);
@@ -5154,6 +7412,6 @@
     }
     # make local copy of TIFF_END now (it may be reset when processing trailers)
-    my $tiffEnd = $self->{TIFF_END};
-    delete $self->{TIFF_END};
+    my $tiffEnd = $$self{TIFF_END};
+    delete $$self{TIFF_END};
 
     # rewrite trailers if they exist
@@ -5189,7 +7447,7 @@
         if ($extra > 0) {
             my $known = $$self{KnownTrailer};
-            if ($self->{DEL_GROUP}{Trailer} and not $known) {
+            if ($$self{DEL_GROUP}{Trailer} and not $known) {
                 $self->VPrint(0, "  Deleting unknown trailer ($extra bytes)\n");
-                ++$self->{CHANGED};
+                ++$$self{CHANGED};
             } elsif ($known) {
                 $self->VPrint(0, "  Copying $$known{Name} ($extra bytes)\n");
@@ -5228,8 +7486,8 @@
     if ($$self{DNGVersion}) {
         my $ver = $$self{DNGVersion};
-        # currently support up to DNG version 1.2
-        unless ($ver =~ /^(\d+) (\d+)/ and "$1.$2" <= 1.3) {
+        # 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 supported", 1);
+            $self->Error("DNG Version $ver not yet tested", 1);
         }
     }
@@ -5276,7 +7534,11 @@
                 my $module = $1;
                 if (eval "require $module") {
-                    # load additional XMP modules if required
-                    if (not %$tableName and $module eq 'Image::ExifTool::XMP') {
-                        require 'Image/ExifTool/XMP2.pl';
+                    # load additional modules if required
+                    if (not %$tableName) {
+                        if ($module eq 'Image::ExifTool::XMP') {
+                            require 'Image/ExifTool/XMP2.pl';
+                        } elsif ($tableName eq 'Image::ExifTool::QuickTime::Stream') {
+                            require 'Image/ExifTool/QuickTimeStream.pl';
+                        }
                     }
                 } else {
@@ -5292,4 +7554,5 @@
         $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:://;
@@ -5317,5 +7580,5 @@
         }
         # generate a tag prefix for unknown tags if necessary
-        unless ($$table{TAG_PREFIX}) {
+        unless (defined $$table{TAG_PREFIX}) {
             my $tagPrefix;
             if ($tableName =~ /Image::.*?::(.*)::Main/ || $tableName =~ /Image::.*?::(.*)/) {
@@ -5328,21 +7591,11 @@
         # set up the new table
         SetupTagTable($table);
-        # add any user-defined tags
-        if (%UserDefined and $UserDefined{$tableName}) {
+        # add any user-defined tags (except Composite tags, which are handled specially)
+        if (%UserDefined and $UserDefined{$tableName} and $table ne \%Image::ExifTool::Composite) {
             my $tagID;
             foreach $tagID (TagTableKeys($UserDefined{$tableName})) {
-                my $tagInfo = $UserDefined{$tableName}{$tagID};
-                if (ref $tagInfo eq 'HASH') {
-                    $$tagInfo{Name} or $$tagInfo{Name} = ucfirst($tagID);
-                } else {
-                    $tagInfo = { Name => $tagInfo };
-                }
-                if ($$table{WRITABLE} and not defined $$tagInfo{Writable} and
-                    not $$tagInfo{SubDirectory})
-                {
-                    $$tagInfo{Writable} = $$table{WRITABLE};
-                }
+                next if $specialTags{$tagID};
                 delete $$table{$tagID}; # replace any existing entry
-                AddTagToTable($table, $tagID, $tagInfo);
+                AddTagToTable($table, $tagID, $UserDefined{$tableName}{$tagID}, 1);
             }
         }
@@ -5351,4 +7604,15 @@
         # insert newly loaded table into list
         $allTables{$tableName} = $table;
+    }
+    # must check each time to add UserDefined Composite tags because the Composite table
+    # may be loaded before the UserDefined tags are available
+    if ($table eq \%Image::ExifTool::Composite and not $$table{VARS}{LOADED_USERDEFINED} and
+        %UserDefined and $UserDefined{$tableName})
+    {
+        my $userComp = $UserDefined{$tableName};
+        delete $UserDefined{$tableName};        # (must delete first to avoid infinite recursion)
+        AddCompositeTags($userComp, 1);
+        $UserDefined{$tableName} = $userComp;   # (add back again for adding writable tags later)
+        $$table{VARS}{LOADED_USERDEFINED} = 1;  # set flag to avoid doing this again
     }
     return $table;
@@ -5368,28 +7632,39 @@
     $proc or $proc = $$tagTablePtr{PROCESS_PROC} || \&Image::ExifTool::Exif::ProcessExif;
     # set directory name from default group0 name if not done already
-    $$dirInfo{DirName} or $$dirInfo{DirName} = $tagTablePtr->{GROUPS}{0};
+    my $dirName = $$dirInfo{DirName};
+    unless ($dirName) {
+        $dirName = $$tagTablePtr{GROUPS}{0};
+        $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}) {
-        my $addr = $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base}||0);
-        if ($self->{PROCESSED}{$addr}) {
-            $self->Warn("$$dirInfo{DirName} pointer references previous $self->{PROCESSED}{$addr} directory");
-            return 0;
-        }
-        $self->{PROCESSED}{$addr} = $$dirInfo{DirName};
+    if (defined $$dirInfo{DirStart} and defined $$dirInfo{DataPos} and
+        # directories don't overlap if the length is zero
+        ($$dirInfo{DirLen} or not defined $$dirInfo{DirLen}))
+    {
+        my $addr = $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base}||0) + $$self{BASE};
+        if ($$self{PROCESSED}{$addr}) {
+            $self->Warn("$dirName pointer references previous $$self{PROCESSED}{$addr} directory");
+            # patch for bug in Windows phone 7.5 O/S that writes incorrect InteropIFD pointer
+            return 0 unless $dirName eq 'GPS' and $$self{PROCESSED}{$addr} eq 'InteropIFD';
+        }
+        $$self{PROCESSED}{$addr} = $dirName;
     }
     my $oldOrder = GetByteOrder();
-    my $oldIndent = $self->{INDENT};
-    my $oldDir = $self->{DIR_NAME};
-    $self->{LIST_TAGS} = { };  # don't build lists across different directories
-    $self->{INDENT} .= '| ';
-    $self->{DIR_NAME} = $$dirInfo{DirName};
-    push @{$self->{PATH}}, $$dirInfo{DirName};
+    my @save = @$self{'INDENT','DIR_NAME','Compression','SubfileType'};
+    $$self{LIST_TAGS} = { };    # don't build lists across different directories
+    $$self{INDENT} .= '| ';
+    $$self{DIR_NAME} = $dirName;
+    push @{$$self{PATH}}, $dirName;
+    $$self{FOUND_DIR}{$dirName} = 1;
 
     # process the directory
+    no strict 'refs';
     my $rtnVal = &$proc($self, $dirInfo, $tagTablePtr);
-
-    pop @{$self->{PATH}};
-    $self->{INDENT} = $oldIndent;
-    $self->{DIR_NAME} = $oldDir;
+    use strict 'refs';
+
+    pop @{$$self{PATH}};
+    @$self{'INDENT','DIR_NAME','Compression','SubfileType'} = @save;
     SetByteOrder($oldOrder);
     return $rtnVal;
@@ -5398,5 +7673,5 @@
 #------------------------------------------------------------------------------
 # Get Metadata path
-# Inputs: 0) Exiftool object ref
+# Inputs: 0) ExifTool object ref
 # Return: Metadata path string
 sub MetadataPath($)
@@ -5414,5 +7689,5 @@
     my $filename = shift;
     my $fileExt;
-    if ($filename and $filename =~ /.*\.(.+)$/) {
+    if ($filename and $filename =~ /^.*\.([^.]+)$/s) {
         $fileExt = uc($1);   # change extension to upper case
         # convert TIF extension to TIFF because we use the
@@ -5433,5 +7708,8 @@
     my $tagInfo = $$tagTablePtr{$tagID};
 
-    if (ref $tagInfo eq 'HASH') {
+    if ($specialTags{$tagID}) {
+        # (hopefully this won't happen)
+        warn "Tag $tagID conflicts with internal ExifTool variable in $$tagTablePtr{TABLE_NAME}\n";
+    } elsif (ref $tagInfo eq 'HASH') {
         return ($tagInfo);
     } elsif (ref $tagInfo eq 'ARRAY') {
@@ -5477,5 +7755,7 @@
             }
         }
-        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;
@@ -5515,11 +7795,16 @@
 # Add new tag to table (must use this routine to add new tags to a table)
 # Inputs: 0) reference to tag table, 1) tag ID
-#         2) [optional] reference to tag information hash
-# Notes: - will not overwrite existing entry in table
+#         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
-sub AddTagToTable($$;$)
-{
-    my ($tagTablePtr, $tagID, $tagInfo) = @_;
-    $tagInfo or $tagInfo = { };
+# - tag name is cleaned if necessary
+sub AddTagToTable($$;$$)
+{
+    my ($tagTablePtr, $tagID, $tagInfo, $noPrefix) = @_;
+
+    # generate tag info hash if necessary
+    $tagInfo = $tagInfo ? { Name => $tagInfo } : { } unless ref $tagInfo eq 'HASH';
 
     # define necessary entries in information hash
@@ -5527,6 +7812,6 @@
         # fill in default groups from table GROUPS
         foreach (keys %{$$tagTablePtr{GROUPS}}) {
-            next if $tagInfo->{Groups}{$_};
-            $tagInfo->{Groups}{$_} = $tagTablePtr->{GROUPS}{$_};
+            next if $$tagInfo{Groups}{$_};
+            $$tagInfo{Groups}{$_} = $$tagTablePtr{GROUPS}{$_};
         }
     } else {
@@ -5537,27 +7822,27 @@
     $$tagInfo{Table} = $tagTablePtr;
     $$tagInfo{TagID} = $tagID;
+    if (defined $$tagTablePtr{AVOID} and not defined $$tagInfo{Avoid}) {
+        $$tagInfo{Avoid} = $$tagTablePtr{AVOID};
+    }
 
     my $name = $$tagInfo{Name};
-    if (defined $name) {
-        $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
-    } else {
-        # construct a name from the tag ID
-        $name = $tagID;
-        $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
-        $name = ucfirst $name;          # start with uppercase
-        # make sure name is a reasonable length
-        my $prefix = $$tagTablePtr{TAG_PREFIX};
-        if ($prefix) {
-            # make description to prevent tagID from getting mangled by MakeDescription()
-            $$tagInfo{Description} = MakeDescription($prefix, $name);
-            $name = "${prefix}_$name";
-        }
-    }
-    # tag names must be at least 2 characters long and begin with a letter
-    $name = "Tag$name" if length($name) <= 1 or $name !~ /^[A-Z]/i;
+    $name = $tagID unless defined $name;
+    $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
+    $name = ucfirst $name;          # capitalize first letter
+    # add tag-name prefix if specified and tag name not provided
+    unless (defined $$tagInfo{Name} or $noPrefix or not $$tagTablePtr{TAG_PREFIX}) {
+        # make description to prevent tagID from getting mangled by MakeDescription()
+        $$tagInfo{Description} = MakeDescription($$tagTablePtr{TAG_PREFIX}, $name);
+        $name = "$$tagTablePtr{TAG_PREFIX}_$name";
+    }
+    # tag names must be at least 2 characters long and prefer them to start with a letter
+    $name = "Tag$name" if length($name) < 2 or $name !~ /^[A-Z]/i;
     $$tagInfo{Name} = $name;
-    # add tag to table, but never overwrite existing entries (could potentially happen
+    # add tag to table, but never override existing entries (could potentially happen
     # if someone thinks there isn't any tagInfo because a condition wasn't satisfied)
-    $$tagTablePtr{$tagID} = $tagInfo unless defined $$tagTablePtr{$tagID};
+    unless (defined $$tagTablePtr{$tagID} or $specialTags{$tagID}) {
+        $$tagTablePtr{$tagID} = $tagInfo;
+    }
+    return $tagInfo;
 }
 
@@ -5565,6 +7850,6 @@
 # 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, Start, Size, Parent,
-#              TagInfo, ProcessProc, RAF
+#         4-N) parameters hash: Index, DataPt, DataPos, Base, Start, Size, Parent,
+#              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
@@ -5573,11 +7858,12 @@
 {
     my ($self, $tagTablePtr, $tag, $val, %parms) = @_;
-    my $verbose = $self->{OPTIONS}{Verbose};
-    my $tagInfo = $parms{TagInfo} || $self->GetTagInfo($tagTablePtr, $tag, \$val);
+    my $verbose = $$self{OPTIONS}{Verbose};
+    my $pfmt = $parms{Format};
+    my $tagInfo = $parms{TagInfo} || $self->GetTagInfo($tagTablePtr, $tag, \$val, $pfmt, $parms{Count});
     my $dataPt = $parms{DataPt};
-    my ($subdir, $format, $count, $size, $noTagInfo);
+    my ($subdir, $format, $noTagInfo, $rational);
 
     if ($tagInfo) {
-        $subdir = $$tagInfo{SubDirectory}
+        $subdir = $$tagInfo{SubDirectory};
     } else {
         return undef unless $verbose;
@@ -5586,12 +7872,15 @@
     }
     # read value if not done already (not necessary for subdir)
-    unless (defined $val or ($subdir and not $$tagInfo{Writable})) {
+    unless (defined $val or ($subdir and not $$tagInfo{Writable} and not $$tagInfo{RawConv})) {
         my $start = $parms{Start} || 0;
-        my $size = $parms{Size} || 0;
+        my $dLen = $dataPt ? length($$dataPt) : -1;
+        my $size = $parms{Size};
+        $size = $dLen unless defined $size;
         # read from data in memory if possible
-        if ($dataPt and $start >= 0 and $start + $size <= length($$dataPt)) {
+        if ($start >= 0 and $start + $size <= $dLen) {
             $format = $$tagInfo{Format} || $$tagTablePtr{FORMAT};
+            $format = $pfmt if not $format and $pfmt and $formatSize{$pfmt};
             if ($format) {
-                $val = ReadValue($dataPt, $start, $format, $$tagInfo{Count}, $size);
+                $val = ReadValue($dataPt, $start, $format, $$tagInfo{Count}, $size, \$rational);
             } else {
                 $val = substr($$dataPt, $start, $size);
@@ -5606,7 +7895,8 @@
         undef $tagInfo if $noTagInfo;
         $parms{Value} = $val;
+        $parms{Value} .= " ($rational)" if defined $rational;
         $parms{Table} = $tagTablePtr;
         if ($format) {
-            $count or $count = int(($parms{Size} || 0) / ($formatSize{$format} || 1));
+            my $count = int(($parms{Size} || 0) / ($formatSize{$format} || 1));
             $parms{Format} = $format . "[$count]";
         }
@@ -5617,8 +7907,28 @@
             my $subdirStart = $parms{Start};
             my $subdirLen = $parms{Size};
+            if ($$tagInfo{RawConv} and not $$tagInfo{Writable}) {
+                my $conv = $$tagInfo{RawConv};
+                local $SIG{'__WARN__'} = \&SetWarning;
+                undef $evalWarning;
+                if (ref $conv eq 'CODE') {
+                    $val = &$conv($val, $self);
+                } else {
+                    my ($priority, @grps);
+                    # NOTE: RawConv is evaluated in Writer.pl and twice in ExifTool.pm
+                    #### eval RawConv ($self, $val, $tag, $tagInfo, $priority, @grps)
+                    $val = eval $conv;
+                    $@ and $evalWarning = $@;
+                }
+                $self->Warn("RawConv $tag: " . CleanWarning()) if $evalWarning;
+                return undef unless defined $val;
+                $val = $$val if ref $val eq 'SCALAR';
+                $dataPt = \$val;
+                $subdirStart = 0;
+                $subdirLen = length $val;
+            }
             if ($$subdir{Start}) {
                 my $valuePtr = 0;
                 #### eval Start ($valuePtr)
-                my $off = eval $$subdir{Start};                
+                my $off = eval $$subdir{Start};
                 $subdirStart += $off;
                 $subdirLen -= $off;
@@ -5640,5 +7950,15 @@
             );
             my $oldOrder = GetByteOrder();
-            SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
+            if ($$subdir{ByteOrder}) {
+                if ($$subdir{ByteOrder} eq 'Unknown') {
+                    if ($subdirStart + 2 <= $subdirLen) {
+                        # attempt to determine the byte ordering of an IFD-style subdirectory
+                        my $num = Get16u($dataPt, $subdirStart);
+                        ToggleByteOrder if $num & 0xff00 and ($num>>8) > ($num&0xff);
+                    }
+                } else {
+                    SetByteOrder($$subdir{ByteOrder});
+                }
+            }
             my $subTablePtr = GetTagTable($$subdir{TagTable}) || $tagTablePtr;
             $self->ProcessDirectory(\%dirInfo, $subTablePtr, $$subdir{ProcessProc} || $parms{ProcessProc});
@@ -5647,5 +7967,8 @@
             return undef unless $$tagInfo{Writable};
         }
-        return $self->FoundTag($tagInfo, $val);
+        my $key = $self->FoundTag($tagInfo, $val);
+        # save original components of rational numbers
+        $$self{RATIONAL}{$key} = $rational if defined $rational and defined $key;
+        return $key;
     }
     return undef;
@@ -5657,10 +7980,12 @@
 #         1) reference to tagInfo hash or tag name
 #         2) data value (or reference to require hash if Composite)
+#         3) optional family 0 group, 4) optional family 1 group
 # Returns: tag key or undef if no value
-sub FoundTag($$$)
+sub FoundTag($$$;@)
 {
     local $_;
-    my ($self, $tagInfo, $value) = @_;
-    my $tag;
+    my ($self, $tagInfo, $value, @grps) = @_;
+    my ($tag, $noListDel);
+    my $options = $$self{OPTIONS};
 
     if (ref $tagInfo eq 'HASH') {
@@ -5673,12 +7998,21 @@
         # (not advised to do this since the tag won't show in list)
         $tagInfo or $tagInfo = { Name => $tag, Groups => \%allGroupsExifTool };
-        $self->{OPTIONS}{Verbose} and $self->VerboseInfo(undef, $tagInfo, Value => $value);
-    }
-    my $rawValueHash = $self->{VALUE};
+        $$options{Verbose} and $self->VerboseInfo(undef, $tagInfo, Value => $value);
+    }
+    # get tag priority
+    my $priority = $$tagInfo{Priority};
+    unless (defined $priority) {
+        $priority = $$tagInfo{Table}{PRIORITY};
+        $priority = 0 if not defined $priority and $$tagInfo{Avoid};
+    }
+    $grps[0] or $grps[0] = $$self{SET_GROUP0};
+    $grps[1] or $grps[1] = $$self{SET_GROUP1};
+    my $valueHash = $$self{VALUE};
+
     if ($$tagInfo{RawConv}) {
         # initialize @val for use in Composite RawConv expressions
         my @val;
-        if (ref $value eq 'HASH') {
-            foreach (keys %$value) { $val[$_] = $$rawValueHash{$$value{$_}}; }
+        if (ref $value eq 'HASH' and $$tagInfo{IsComposite}) {
+            foreach (keys %$value) { $val[$_] = $$valueHash{$$value{$_}}; }
         }
         my $conv = $$tagInfo{RawConv};
@@ -5687,8 +8021,9 @@
         if (ref $conv eq 'CODE') {
             $value = &$conv($value, $self);
+            $$self{grps} and @grps = @{$$self{grps}}, delete $$self{grps};
         } else {
-            my $val = $value;   # must do this in case eval references $val
+            my $val = $value;   # do this so eval can use $val
             # NOTE: RawConv is also evaluated in Writer.pl
-            #### eval RawConv ($self, $val, $tag, $tagInfo)
+            #### eval RawConv ($self, $val, $tag, $tagInfo, $priority, @grps)
             $value = eval $conv;
             $@ and $evalWarning = $@;
@@ -5697,20 +8032,27 @@
         return undef unless defined $value;
     }
-    # get tag priority
-    my $priority = $$tagInfo{Priority};
-    defined $priority or $priority = $tagInfo->{Table}{PRIORITY};
     # handle duplicate tag names
-    if (defined $$rawValueHash{$tag}) {
+    if (defined $$valueHash{$tag}) {
         # add to list if there is an active list for this tag
-        if ($self->{LIST_TAGS}{$tagInfo}) {
-            $tag = $self->{LIST_TAGS}{$tagInfo};  # use key from previous list tag
-            if (ref $$rawValueHash{$tag} ne 'ARRAY') {
-                $$rawValueHash{$tag} = [ $$rawValueHash{$tag} ];
-            }
-            push @{$$rawValueHash{$tag}}, $value;
-            return $tag;    # return without creating a new entry
+        if ($$self{LIST_TAGS}{$tagInfo}) {
+            $tag = $$self{LIST_TAGS}{$tagInfo}; # use key from previous list tag
+            if (defined $$self{NO_LIST}) {
+                # accumulate list in TAG_EXTRA "NoList" element
+                if (defined $$self{TAG_EXTRA}{$tag}{NoList}) {
+                    push @{$$self{TAG_EXTRA}{$tag}{NoList}}, $value;
+                } else {
+                    $$self{TAG_EXTRA}{$tag}{NoList} = [ $$valueHash{$tag}, $value ];
+                }
+                $noListDel = 1; # set flag to delete this tag if re-listed
+            } else {
+                if (ref $$valueHash{$tag} ne 'ARRAY') {
+                    $$valueHash{$tag} = [ $$valueHash{$tag} ];
+                }
+                push @{$$valueHash{$tag}}, $value;
+                return $tag;    # return without creating a new entry
+            }
         }
         # get next available tag key
-        my $nextInd = $self->{DUPL_TAG}{$tag} = ($self->{DUPL_TAG}{$tag} || 0) + 1;
+        my $nextInd = $$self{DUPL_TAG}{$tag} = ($$self{DUPL_TAG}{$tag} || 0) + 1;
         my $nextTag = "$tag ($nextInd)";
 #
@@ -5718,9 +8060,10 @@
 #
         # promote existing 0-priority tag so it takes precedence over a new 0-tag
-        # (unless old tag was a sub-document and new tag isn't)
-        my $oldPriority = $self->{PRIORITY}{$tag};
+        # (unless old tag was a sub-document and new tag isn't.  Also, never override
+        #  a Warning tag because they may be added by ValueConv, which could be confusing)
+        my $oldPriority = $$self{PRIORITY}{$tag};
         unless ($oldPriority) {
-            if ($self->{DOC_NUM} or not $self->{TAG_EXTRA}{$tag} or
-                                    not $self->{TAG_EXTRA}{$tag}{G3})
+            if ($$self{DOC_NUM} or not $$self{TAG_EXTRA}{$tag} or $tag eq 'Warning' or
+                                   not $$self{TAG_EXTRA}{$tag}{G3})
             {
                 $oldPriority = 1;
@@ -5734,50 +8077,76 @@
             $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}) {
+        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
-            $self->{MOVED_KEY} = $nextTag;  # used in BuildCompositeTags()
-            $self->{PRIORITY}{$nextTag} = $self->{PRIORITY}{$tag};
-            $$rawValueHash{$nextTag} = $$rawValueHash{$tag};
-            $self->{FILE_ORDER}{$nextTag} = $self->{FILE_ORDER}{$tag};
-            my $oldInfo = $self->{TAG_INFO}{$nextTag} = $self->{TAG_INFO}{$tag};
-            if ($self->{TAG_EXTRA}{$tag}) {
-                $self->{TAG_EXTRA}{$nextTag} = $self->{TAG_EXTRA}{$tag};
-                delete $self->{TAG_EXTRA}{$tag};
-            }
+            # (NOTE: any new members added here must also be added to DeleteTag())
+            $$self{PRIORITY}{$nextTag} = $$self{PRIORITY}{$tag};
+            $$valueHash{$nextTag} = $$valueHash{$tag};
+            $$self{FILE_ORDER}{$nextTag} = $$self{FILE_ORDER}{$tag};
+            my $oldInfo = $$self{TAG_INFO}{$nextTag} = $$self{TAG_INFO}{$tag};
+            foreach ('TAG_EXTRA','RATIONAL') {
+                if ($$self{$_}{$tag}) {
+                    $$self{$_}{$nextTag} = $$self{$_}{$tag};
+                    delete $$self{$_}{$tag};
+                }
+            }
+            delete $$self{BOTH}{$tag};
             # update tag key for list if necessary
-            $self->{LIST_TAGS}{$oldInfo} = $nextTag if $self->{LIST_TAGS}{$oldInfo};
+            $$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
         }
-        $self->{PRIORITY}{$tag} = $priority;
+        $$self{PRIORITY}{$tag} = $priority;
+        $$self{TAG_EXTRA}{$tag}{NoListDel} = 1 if $noListDel;
     } elsif ($priority) {
-        # set tag priority (only if exists and non-zero)
-        $self->{PRIORITY}{$tag} = $priority;
+        # set tag priority (only if exists and is non-zero)
+        $$self{PRIORITY}{$tag} = $priority;
     }
 
     # save the raw value, file order, tagInfo ref, group1 name,
     # and tag key for lists if necessary
-    $$rawValueHash{$tag} = $value;
-    $self->{FILE_ORDER}{$tag} = ++$self->{NUM_FOUND};
-    $self->{TAG_INFO}{$tag} = $tagInfo;
-    # set dynamic groups 1 and 3 if necessary
-    $self->{TAG_EXTRA}{$tag}{G1} = $self->{SET_GROUP1} if $self->{SET_GROUP1};
-    if ($self->{DOC_NUM}) {
-        $self->{TAG_EXTRA}{$tag}{G3} = $self->{DOC_NUM};
-        if ($self->{DOC_NUM} =~ /^(\d+)/) {
+    $$valueHash{$tag} = $value;
+    $$self{FILE_ORDER}{$tag} = ++$$self{NUM_FOUND};
+    $$self{TAG_INFO}{$tag} = $tagInfo;
+    # set dynamic groups 0, 1 and 3 if necessary
+    $$self{TAG_EXTRA}{$tag}{G0} = $grps[0] if $grps[0];
+    $$self{TAG_EXTRA}{$tag}{G1} = $grps[1] if $grps[1];
+    if ($$self{DOC_NUM}) {
+        $$self{TAG_EXTRA}{$tag}{G3} = $$self{DOC_NUM};
+        if ($$self{DOC_NUM} =~ /^(\d+)/) {
             # keep track of maximum 1st-level sub-document number
-            $self->{DOC_COUNT} = $1 unless $self->{DOC_COUNT} >= $1;
+            $$self{DOC_COUNT} = $1 unless $$self{DOC_COUNT} >= $1;
         }
     }
     # save path if requested
-    $self->{TAG_EXTRA}{$tag}{G5} = $self->MetadataPath() if $self->{OPTIONS}{SavePath};
+    $$self{TAG_EXTRA}{$tag}{G5} = $self->MetadataPath() if $$options{SavePath};
 
     # remember this tagInfo if we will be accumulating values in a list
-    $self->{LIST_TAGS}{$tagInfo} = $tag if $$tagInfo{List} and not $$self{NO_LIST};
+    # (but don't override earlier list if this may be deleted by NoListDel flag)
+    if ($$tagInfo{List} and not $$self{NO_LIST} and not $noListDel) {
+        $$self{LIST_TAGS}{$tagInfo} = $tag;
+    }
+
+    # validate tag if requested (but only for simple values -- could result
+    # in infinite recursion if called for a Composite tag (HASH ref value)
+    # because FoundTag is called in the middle of building Composite tags
+    if ($$options{Validate} and not ref $value) {
+        Image::ExifTool::Validate::ValidateRaw($self, $tag, $value);
+    }
 
     return $tag;
@@ -5790,5 +8159,5 @@
 {
     my $self = shift;
-    $self->{PRIORITY_DIR} = $self->{DIR_NAME} unless $self->{PRIORITY_DIR};
+    $$self{PRIORITY_DIR} = $$self{DIR_NAME} unless $$self{PRIORITY_DIR};
 }
 
@@ -5799,5 +8168,5 @@
 {
     my ($self, $tagKey, $extra, $fam) = @_;
-    $self->{TAG_EXTRA}{$tagKey}{defined $fam ? "G$fam" : 'G1'} = $extra;
+    $$self{TAG_EXTRA}{$tagKey}{defined $fam ? "G$fam" : 'G1'} = $extra;
 }
 
@@ -5808,8 +8177,11 @@
 {
     my ($self, $tag) = @_;
-    delete $self->{VALUE}{$tag};
-    delete $self->{FILE_ORDER}{$tag};
-    delete $self->{TAG_INFO}{$tag};
-    delete $self->{TAG_EXTRA}{$tag};
+    delete $$self{VALUE}{$tag};
+    delete $$self{FILE_ORDER}{$tag};
+    delete $$self{TAG_INFO}{$tag};
+    delete $$self{TAG_EXTRA}{$tag};
+    delete $$self{PRIORITY}{$tag};
+    delete $$self{RATIONAL}{$tag};
+    delete $$self{BOTH}{$tag};
 }
 
@@ -5838,15 +8210,31 @@
 #         1) Optional file type (uses FILE_TYPE if not specified)
 #         2) Optional MIME type (uses our lookup if not specified)
+#         3) Optional recommended extension (converted to lower case; uses FileType if undef)
 # Notes:  Will NOT set file type twice (subsequent calls ignored)
-sub SetFileType($;$$)
-{
-    my ($self, $fileType, $mimeType) = @_;
-    unless ($self->{VALUE}{FileType}) {
-        my $baseType = $self->{FILE_TYPE};
+sub SetFileType($;$$$)
+{
+    my ($self, $fileType, $mimeType, $normExt) = @_;
+    unless ($$self{VALUE}{FileType} and not $$self{DOC_NUM}) {
+        my $baseType = $$self{FILE_TYPE};
+        my $ext = $$self{FILE_EXT};
         $fileType or $fileType = $baseType;
+        # handle sub-types which are identified by extension
+        if (defined $ext and $ext ne $fileType and not $$self{DOC_NUM}) {
+            my ($f,$e) = @fileTypeLookup{$fileType,$ext};
+            if (ref $f eq 'ARRAY' and ref $e eq 'ARRAY' and $$f[0] eq $$e[0]) {
+                # make sure $fileType was a root type and not another sub-type
+                $fileType = $ext if $$f[0] eq $fileType or not $fileTypeLookup{$$f[0]};
+            }
+        }
         $mimeType or $mimeType = $mimeType{$fileType};
         # use base file type if necessary (except if 'TIFF', which is a special case)
         $mimeType = $mimeType{$baseType} unless $mimeType or $baseType eq 'TIFF';
+        unless (defined $normExt) {
+            $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');
     }
@@ -5855,15 +8243,23 @@
 #------------------------------------------------------------------------------
 # Override the FileType and MIMEType tags
-# Inputs: 0) ExifTool object ref, 1) file type
+# Inputs: 0) ExifTool object ref, 1) file type, 2) MIME type, 3) normal extension
 # Notes:  does nothing if FileType was not previously defined (ie. when writing)
-sub OverrideFileType($$)
-{
-    my ($self, $fileType) = @_;
+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;
-        $$self{VALUE}{MIMEType} = $mimeType{$fileType} || 'application/unknown';
+        unless (defined $normExt) {
+            $normExt = $fileTypeExt{$fileType};
+            $normExt = $fileType unless defined $normExt;
+        }
+        $$self{VALUE}{FileTypeExtension} = uc $normExt;
+        $mimeType or $mimeType = $mimeType{$fileType};
+        $$self{VALUE}{MIMEType} = $mimeType if $mimeType;
         if ($$self{OPTIONS}{Verbose}) {
             $self->VPrint(0,"$$self{INDENT}FileType [override] = $fileType\n");
-            $self->VPrint(0,"$$self{INDENT}MIMEType [override] = $$self{VALUE}{MIMEType}\n");
+            $self->VPrint(0,"$$self{INDENT}FileTypeExtension [override] = $$self{VALUE}{FileTypeExtension}\n");
+            $self->VPrint(0,"$$self{INDENT}MIMEType [override] = $mimeType\n") if $mimeType;
         }
     }
@@ -5878,10 +8274,10 @@
     my ($self, $mime) = @_;
     $mime =~ m{/} or $mime = $mimeType{$mime} or return;
-    my $old = $self->{VALUE}{MIMEType};
+    my $old = $$self{VALUE}{MIMEType};
     if (defined $old) {
         my ($a, $b) = split '/', $old;
         my ($c, $d) = split '/', $mime;
         $d =~ s/^x-//;
-        $self->{VALUE}{MIMEType} = "$c/$b-$d";
+        $$self{VALUE}{MIMEType} = "$c/$b-$d";
         $self->VPrint(0, "  Modified MIMEType = $c/$b-$d\n");
     } else {
@@ -5897,8 +8293,29 @@
     my $self = shift;
     my $level = shift;
-    if ($self->{OPTIONS}{Verbose} and $self->{OPTIONS}{Verbose} > $level) {
-        my $out = $self->{OPTIONS}{TextOut};
+    if ($$self{OPTIONS}{Verbose} and $$self{OPTIONS}{Verbose} > $level) {
+        my $out = $$self{OPTIONS}{TextOut};
         print $out @_;
-    }
+        print $out "\n" unless $_[-1] =~ /\n$/;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Print verbose directory information
+# Inputs: 0) ExifTool object reference, 1) directory name or dirInfo ref
+#         2) number of entries in directory (or 0 if unknown)
+#         3) optional size of directory in bytes
+sub VerboseDir($$;$$)
+{
+    my ($self, $name, $entries, $size) = @_;
+    return unless $$self{OPTIONS}{Verbose};
+    if (ref $name eq 'HASH') {
+        $size = $$name{DirLen} unless $size;
+        $name = $$name{Name} || $$name{DirName};
+    }
+    my $indent = substr($$self{INDENT}, 0, -2);
+    my $out = $$self{OPTIONS}{TextOut};
+    my $str = ($entries or defined $entries and not $size) ? " with $entries entries" : '';
+    $str .= ", $size bytes" if $size;
+    print $out "$indent+ [$name directory$str]\n";
 }
 
@@ -5910,12 +8327,24 @@
     my $self = shift;
     my $dataPt = shift;
-    if ($self->{OPTIONS}{Verbose} and $self->{OPTIONS}{Verbose} > 2) {
+    my $verbose = $$self{OPTIONS}{Verbose};
+    if ($verbose and $verbose > 2) {
         my %parms = (
-            Prefix => $self->{INDENT},
-            Out    => $self->{OPTIONS}{TextOut},
-            MaxLen => $self->{OPTIONS}{Verbose} < 4 ? 96 : undef,
+            Prefix => $$self{INDENT},
+            Out    => $$self{OPTIONS}{TextOut},
+            MaxLen => $verbose < 4 ? 96 : $verbose < 5 ? 2048 : undef,
         );
         HexDump($dataPt, undef, %parms, @_);
     }
+}
+
+#------------------------------------------------------------------------------
+# Print data in hex
+# Inputs: 0) data
+# Returns: hex string
+# (this is a convenience function for use in debugging PrintConv statements)
+sub PrintHex($)
+{
+    my $val = shift;
+    return join(' ', unpack('H2' x length($val), $val));
 }
 
@@ -5931,17 +8360,20 @@
     my ($isPreview, $buff);
 
-    if ($tag and $tag eq 'PreviewImage') {
-        # save PreviewImage start/length in case we want to dump trailer
-        $$self{PreviewImageStart} = $offset;
-        $$self{PreviewImageLength} = $length;
-        $isPreview = 1;
-    }
-    if ($tag and not $self->{OPTIONS}{Binary} and not $self->{OPTIONS}{Verbose} and
-        not $self->{REQ_TAG_LOOKUP}{lc($tag)})
-    {
-        return "Binary data $length bytes";
-    }
-    unless ($self->{RAF}->Seek($offset,0)
-        and $self->{RAF}->Read($buff, $length) == $length)
+    if ($tag) {
+        if ($tag eq 'PreviewImage') {
+            # save PreviewImage start/length in case we want to dump trailer
+            $$self{PreviewImageStart} = $offset;
+            $$self{PreviewImageLength} = $length;
+            $isPreview = 1;
+        }
+        my $lcTag = lc $tag;
+        if ((not $$self{OPTIONS}{Binary} or $$self{EXCL_TAG_LOOKUP}{$lcTag}) and
+             not $$self{OPTIONS}{Verbose} and not $$self{REQ_TAG_LOOKUP}{$lcTag})
+        {
+            return "Binary data $length bytes";
+        }
+    }
+    unless ($$self{RAF}->Seek($offset,0)
+        and $$self{RAF}->Read($buff, $length) == $length)
     {
         $tag or $tag = 'binary data';
@@ -5969,6 +8401,6 @@
     my $size = $$dirInfo{DirLen} || (length($$dataPt) - $offset);
     my $base = $$dirInfo{Base} || 0;
-    my $verbose = $self->{OPTIONS}{Verbose};
-    my $unknown = $self->{OPTIONS}{Unknown};
+    my $verbose = $$self{OPTIONS}{Verbose};
+    my $unknown = $$self{OPTIONS}{Unknown};
     my $dataPos = $$dirInfo{DataPos} || 0;
 
@@ -5982,8 +8414,11 @@
     }
     # prepare list of tag numbers to extract
-    my @tags;
+    my (@tags, $topIndex);
     if ($unknown > 1 and defined $$tagTablePtr{FIRST_ENTRY}) {
+        # don't create a stupid number of tags if data is huge
+        my $sizeLimit = $size < 65536 ? $size : 65536;
         # scan through entire binary table
-        @tags = ($$tagTablePtr{FIRST_ENTRY}..(int($size/$increment) - 1));
+        $topIndex = int($sizeLimit/$increment);
+        @tags = ($$tagTablePtr{FIRST_ENTRY}..($topIndex - 1));
         # add in floating point tag ID's if they exist
         my @ftags = grep /\./, TagTableKeys($tagTablePtr);
@@ -5992,7 +8427,10 @@
         @tags = @{$$dirInfo{DataMember}};
         $verbose = 0;   # no verbose output of extracted values when writing
+    } elsif ($$dirInfo{MixedTags}) {
+        # process sorted integer-ID tags only
+        @tags = sort { $a <=> $b } grep /^\d+$/, TagTableKeys($tagTablePtr);
     } else {
         # extract known tags in numerical order
-        @tags = sort { $a <=> $b } TagTableKeys($tagTablePtr);
+        @tags = sort { ($a < 0 ? $a + 1e9 : $a) <=> ($b < 0 ? $b + 1e9 : $b) } TagTableKeys($tagTablePtr);
     }
     $self->VerboseDir('BinaryData', undef, $size) if $verbose;
@@ -6003,5 +8441,5 @@
     my $varSize = 0;
     foreach $index (@tags) {
-        my ($tagInfo, $val, $saveNextIndex, $len, $mask, $wasVar);
+        my ($tagInfo, $val, $saveNextIndex, $len, $mask, $wasVar, $rational);
         if ($$tagTablePtr{$index}) {
             $tagInfo = $self->GetTagInfo($tagTablePtr, $index);
@@ -6009,4 +8447,8 @@
                 next unless defined $tagInfo;
                 my $entry = int($index) * $increment + $varSize;
+                if ($entry < 0) {
+                    $entry += $size;
+                    next if $entry < 0;
+                }
                 next if $entry >= $size;
                 my $more = $size - $entry;
@@ -6018,4 +8460,6 @@
             next if $$tagInfo{Unknown} and
                    ($$tagInfo{Unknown} > $unknown or $index < $nextIndex);
+        } elsif ($topIndex and $$tagTablePtr{$index - $topIndex}) {
+            $tagInfo = $self->GetTagInfo($tagTablePtr, $index - $topIndex) or next;
         } else {
             # don't generate unknown tags in binary tables unless Unknown > 1
@@ -6027,4 +8471,9 @@
         # get relative offset of this entry
         my $entry = int($index) * $increment + $varSize;
+        # allow negative indices to represent bytes from end
+        if ($entry < 0) {
+            $entry += $size;
+            next if $entry < 0;
+        }
         my $more = $size - $entry;
         last if $more <= 0;     # all done if we have reached the end of data
@@ -6050,11 +8499,17 @@
                 $@ and warn("Format $$tagInfo{Name}: $@"), next;
                 next if $count < 0;
-                # allow a variable-length of any format type (with base $count = 1)
+                # allow a variable-length value of any format
+                # (note: the next incremental index points to data immediately after
+                #  this value, regardless of the size of this value, even if it is zero)
                 if ($format =~ s/^var_//) {
-                    $varSize += ($count - 1) * ($formatSize{$format} || 1);
+                    $varSize += $count * ($formatSize{$format} || 1) - $increment;
+                    $wasVar = 1;
                     # save variable size data if required for writing
                     if ($$dirInfo{VarFormatData}) {
-                        push @{$$dirInfo{VarFormatData}}, $index, $varSize;
+                        push @{$$dirInfo{VarFormatData}}, [ $index, $varSize, $format ];
                     }
+                    # don't extract value if large and we wanted it just to get
+                    # the variable-format information when writing
+                    next if $$tagInfo{LargeTag} and $$dirInfo{VarFormatData};
                 }
             } elsif ($format =~ /^var_/) {
@@ -6069,9 +8524,11 @@
                     $count = Get8u($dataPt, ($entry++)+$offset);
                     --$more;
-                } elsif ($format eq 'pstr32') {
+                } elsif ($format eq 'pstr32' or $format eq 'ustr32') {
                     last if $more < 4;
                     $count = Get32u($dataPt, $entry + $offset);
+                    $count *= 2 if $format eq 'ustr32';
                     $entry += 4;
                     $more -= 4;
+                    $nextIndex += 4 / $increment;   # (increment next index for int32u)
                 } elsif ($format eq 'int16u') {
                     # int16u size of binary data to follow
@@ -6080,4 +8537,9 @@
                     $varSize -= 2;  # ($count includes size word)
                     $format = 'undef';
+                } elsif ($format eq 'ue7') {
+                    require Image::ExifTool::BPG;
+                    ($val, $count) = Image::ExifTool::BPG::Get_ue7($dataPt, $entry + $offset);
+                    last unless defined $val;
+                    --$varSize;     # ($count includes base size of 1 byte)
                 } elsif ($$dataPt =~ /\0/g) {
                     $count = pos($$dataPt) - ($entry+$offset);
@@ -6086,11 +8548,13 @@
                 $count = $more if not defined $count or $count > $more;
                 $varSize += $count; # shift subsequent indices
-                $val = substr($$dataPt, $entry+$offset, $count);
-                $val = $self->Decode($val, 'UCS2') if $format eq 'ustring';
-                $val =~ s/\0.*//s unless $format eq 'undef';  # truncate at null
+                unless (defined $val) {
+                    $val = substr($$dataPt, $entry+$offset, $count);
+                    $val = $self->Decode($val, 'UCS2') if $format eq 'ustring' or $format eq 'ustr32';
+                    $val =~ s/\0.*//s unless $format eq 'undef';  # truncate at null
+                }
                 $wasVar = 1;
                 # save variable size data if required for writing
                 if ($$dirInfo{VarFormatData}) {
-                    push @{$$dirInfo{VarFormatData}}, $index, $varSize;
+                    push @{$$dirInfo{VarFormatData}}, [ $index, $varSize, $format ];
                 }
             }
@@ -6098,10 +8562,16 @@
         # hook to allow format, etc to be set dynamically
         if (defined $$tagInfo{Hook}) {
-            #### eval Hook ($format, $varSize)
+            my $oldVarSize = $varSize;
+            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}) {
-                $#{$$dirInfo{VarFormatData}} -= 2 if $wasVar; # remove previous entries for this tag
-                push @{$$dirInfo{VarFormatData}}, $index, $varSize;
+                $#{$$dirInfo{VarFormatData}} -= 1 if $wasVar; # remove previous entry for this tag
+                push @{$$dirInfo{VarFormatData}}, [ $index, $varSize, $format ];
+            } elsif ($varSize != $oldVarSize and $verbose > 2) {
+                my ($tmp, $sign) = ($varSize, '+');
+                $tmp < 0 and $tmp = -$tmp, $sign = '-';
+                $self->VPrint(2, sprintf("$$self{INDENT}\[offsets adjusted by ${sign}0x%.4x after 0x%.4x $$tagInfo{Name}]\n", $tmp, $index));
             }
         }
@@ -6113,9 +8583,12 @@
             $nextIndex = $ni unless $nextIndex > $ni;
         }
+        # allow large tags to be excluded from extraction
+        # (provides a work-around for some tight memory situations)
+        next if $$tagInfo{LargeTag} and $$self{EXCL_TAG_LOOKUP}{lc $$tagInfo{Name}};
         # read value now if necessary
         unless (defined $val and not $$tagInfo{SubDirectory}) {
-            $val = ReadValue($dataPt, $entry+$offset, $format, $count, $more);
+            $val = ReadValue($dataPt, $entry+$offset, $format, $count, $more, \$rational);
             $mask = $$tagInfo{Mask};
-            $val &= $mask if $mask;
+            $val = ($val & $mask) >> $$tagInfo{BitShift} if $mask;
         }
         if ($verbose and not $$tagInfo{Hidden}) {
@@ -6140,5 +8613,6 @@
         # parse nested BinaryData directories
         if ($$tagInfo{SubDirectory}) {
-            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}{TagTable});
+            my $subdir = $$tagInfo{SubDirectory};
+            my $subTablePtr = GetTagTable($$subdir{TagTable});
             # use specified subdirectory length if given
             if ($$tagInfo{Format} and $formatSize{$format}) {
@@ -6146,5 +8620,5 @@
                 $len = $more if $len > $more;
             } else {
-                $len = $more;
+                $len = $more;   # directory size is all of remaining data
                 if ($$subTablePtr{PROCESS_PROC} and
                     $$subTablePtr{PROCESS_PROC} eq \&ProcessBinaryData)
@@ -6154,21 +8628,40 @@
                 }
             }
+            my $subdirBase = $base;
+            if (defined $$subdir{Base}) {
+                #### eval Base ($start,$base)
+                my $start = $entry + $offset + $dataPos;
+                $subdirBase = eval($$subdir{Base}) + $base;
+            }
+            my $start = $$subdir{Start} || 0;
             my %subdirInfo = (
                 DataPt   => $dataPt,
                 DataPos  => $dataPos,
-                DirStart => $entry + $offset,
-                DirLen   => $len,
-                Base     => $base,
+                DataLen  => length $$dataPt,
+                DirStart => $entry + $offset + $start,
+                DirLen   => $len - $start,
+                Base     => $subdirBase,
             );
-            $self->ProcessDirectory(\%subdirInfo, $subTablePtr);
+            delete $$self{NO_UNKNOWN};
+            $self->ProcessDirectory(\%subdirInfo, $subTablePtr, $$subdir{ProcessProc});
+            $$self{NO_UNKNOWN} = 1 if $unknown < 2;
             next;
         }
         if ($$tagInfo{IsOffset} and $$tagInfo{IsOffset} ne '3') {
-            my $exifTool = $self;
-            #### eval IsOffset ($val, $exifTool)
+            my $et = $self;
+            #### eval IsOffset ($val, $et)
             $val += $base + $$self{BASE} if eval $$tagInfo{IsOffset};
         }
         $val{$index} = $val;
-        unless ($self->FoundTag($tagInfo,$val)) {
+        my $oldBase;
+        if ($$tagInfo{SetBase}) {
+            $oldBase = $$self{BASE};
+            $$self{BASE} += $base;
+        }
+        my $key = $self->FoundTag($tagInfo,$val);
+        $$self{BASE} = $oldBase if defined $oldBase;
+        if ($key) {
+            $$self{RATIONAL}{$key} = $rational if defined $rational;
+        } else {
             # don't increment nextIndex if we didn't extract a tag
             $nextIndex = $saveNextIndex if defined $saveNextIndex;
@@ -6183,7 +8676,8 @@
 # (use of noConfig is now deprecated, use configFile = '' instead)
 until ($Image::ExifTool::noConfig) {
-    my $file = $Image::ExifTool::configFile;
-    if (not defined $file) {
-        my $config = '.ExifTool_config';
+    my $config = $Image::ExifTool::configFile;
+    my $file;
+    if (not defined $config) {
+        $config = '.ExifTool_config';
         # get our home directory (HOMEDRIVE and HOMEPATH are used in Windows cmd shell)
         my $home = $ENV{EXIFTOOL_HOME} || $ENV{HOME} ||
@@ -6191,20 +8685,59 @@
         # look for the config file in 1) the home directory, 2) the program dir
         $file = "$home/$config";
-        -r $file or $file = ($0 =~ /(.*[\\\/])/ ? $1 : './') . $config;
-        -r $file or last;
     } else {
-        length $file or last;   # filename of "" disables configuration
-        -r $file or warn("Config file not found\n"), last;
-    }
-    eval "require '$file'"; # load the config file
+        length $config or last; # filename of "" disables configuration
+        $file = $config;
+    }
+    # also check executable directory unless path is absolute
+    $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;
+    }
+    unshift @INC, '.';      # look in current directory first
+    eval { require $file }; # load the config file
+    shift @INC;
     # print warning (minus "Compilation failed" part)
     $@ and $_=$@, s/Compilation failed.*//s, warn $_;
-    if (@Image::ExifTool::UserDefined::Lenses) {
-        foreach (@Image::ExifTool::UserDefined::Lenses) {
-            $Image::ExifTool::userLens{$_} = 1;
-        }
-    }
     last;
 }
+# read user-defined lenses (may have been defined by script instead of config file)
+if (@Image::ExifTool::UserDefined::Lenses) {
+    foreach (@Image::ExifTool::UserDefined::Lenses) {
+        $Image::ExifTool::userLens{$_} = 1;
+    }
+}
+# add user-defined file types
+if (%Image::ExifTool::UserDefined::FileTypes) {
+    foreach (sort keys %Image::ExifTool::UserDefined::FileTypes) {
+        my $fileInfo = $Image::ExifTool::UserDefined::FileTypes{$_};
+        my $type = uc $_;
+        ref $fileInfo eq 'HASH' or $fileTypeLookup{$type} = $fileInfo, next;
+        my $baseType = $$fileInfo{BaseType};
+        if ($baseType) {
+            if ($$fileInfo{Description}) {
+                $fileTypeLookup{$type} = [ $baseType, $$fileInfo{Description} ];
+            } else {
+                $fileTypeLookup{$type} = $baseType;
+            }
+            if (defined $$fileInfo{Writable} and not $$fileInfo{Writable}) {
+                # first make sure we are using an actual base type and not a derived type
+                $baseType = $fileTypeLookup{$baseType} while $baseType and not ref $fileTypeLookup{$baseType};
+                # mark this type as not writable
+                $noWriteFile{$baseType} or $noWriteFile{$baseType} = [ ];
+                push @{$noWriteFile{$baseType}}, $type;
+            }
+        } else {
+            $fileTypeLookup{$type} = [ $type, $$fileInfo{Description} || $type ];
+            $moduleName{$type} = 0; # not supported
+            if ($$fileInfo{Magic}) {
+                $magicNumber{$type} = $$fileInfo{Magic};
+                push @fileTypes, $type unless grep /^$type$/, @fileTypes;
+            }
+        }
+        $mimeType{$type} = $$fileInfo{MIMEType} if defined $$fileInfo{MIMEType};
+    }
+}
 
 #------------------------------------------------------------------------------
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pod
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pod	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool.pod	(revision 34921)
@@ -4,7 +4,7 @@
 # Description:  Read and write meta information
 #
-# URL:          http://owl.phy.queensu.ca/~phil/exiftool/
+# URL:          https://exiftool.org/
 #
-# Legal:        Copyright (c) 2003-2010, Phil Harvey (phil at owl.phy.queensu.ca)
+# Legal:        Copyright (c) 2003-2021, 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.
@@ -54,10 +54,10 @@
 =head1 DESCRIPTION
 
-ExifTool provides an extensible set of perl modules to read and write meta
-information in a wide variety of files, including the maker note information
-of many digital cameras by various manufacturers such as Canon, Casio,
-FujiFilm, GE, HP, JVC/Victor, Kodak, Leaf, Minolta/Konica-Minolta, Nikon,
-Olympus/Epson, Panasonic/Leica, Pentax/Asahi, Reconyx, Ricoh, Samsung,
-Sanyo, Sigma/Foveon and Sony.
+Reads and writes meta information in a wide variety of files, including the
+maker notes of many digital cameras by various manufacturers such as Canon,
+Casio, DJI, FLIR, FujiFilm, GE, GoPro, HP, JVC/Victor, Kodak, Leaf,
+Minolta/Konica-Minolta, Nikon, Nintendo, Olympus/Epson, Panasonic/Leica,
+Pentax/Asahi, Phase One, Reconyx, Ricoh, Samsung, Sanyo, Sigma/Foveon and
+Sony.
 
 Below is a list of file types and meta information formats currently
@@ -66,32 +66,45 @@
   File Types
   ------------+-------------+-------------+-------------+------------
-  3FR   r     | DVB   r     | M4A/V r     | PBM   r/w   | RWL   r/w
-  3G2   r     | DYLIB r     | MEF   r/w   | PDF   r/w   | RWZ   r
-  3GP   r     | EIP   r     | MIE   r/w/c | PEF   r/w   | RM    r
-  ACR   r     | EPS   r/w   | MIFF  r     | PFA   r     | SO    r
-  AFM   r     | ERF   r/w   | MKA   r     | PFB   r     | SR2   r/w
-  AI    r/w   | EXE   r     | MKS   r     | PFM   r     | SRF   r
-  AIFF  r     | EXIF  r/w/c | MKV   r     | PGF   r     | SRW   r/w
-  APE   r     | F4A/V r     | MNG   r/w   | PGM   r/w   | SVG   r
-  ARW   r/w   | FLA   r     | MOS   r/w   | PICT  r     | SWF   r
-  ASF   r     | FLAC  r     | MOV   r     | PMP   r     | THM   r/w
-  AVI   r     | FLV   r     | MP3   r     | PNG   r/w   | TIFF  r/w
-  BMP   r     | FPX   r     | MP4   r     | PPM   r/w   | TTC   r
-  BTF   r     | GIF   r/w   | MPC   r     | PPT   r     | TTF   r
-  COS   r     | GZ    r     | MPG   r     | PPTX  r     | VRD   r/w/c
-  CR2   r/w   | HDP   r/w   | MPO   r/w   | PS    r/w   | VSD   r
-  CRW   r/w   | HTML  r     | MQV   r     | PSB   r/w   | WAV   r
-  CS1   r/w   | ICC   r/w/c | MRW   r/w   | PSD   r/w   | WDP   r/w
-  DCM   r     | IIQ   r/w   | MXF   r     | PSP   r     | WEBP  r
-  DCP   r/w   | IND   r/w   | NEF   r/w   | QTIF  r     | WEBM  r
-  DCR   r     | ITC   r     | NRW   r/w   | RA    r     | WMA   r
-  DFONT r     | JNG   r/w   | NUMBERS r   | RAF   r/w   | WMV   r
-  DIVX  r     | JP2   r/w   | ODP   r     | RAM   r     | X3F   r/w
-  DJVU  r     | JPEG  r/w   | ODS   r     | RAR   r     | XCF   r
-  DLL   r     | K25   r     | ODT   r     | RAW   r/w   | XLS   r
-  DNG   r/w   | KDC   r     | OGG   r     | RIFF  r     | XLSX  r
-  DOC   r     | KEY   r     | ORF   r/w   | RSRC  r     | XMP   r/w/c
-  DOCX  r     | LNK   r     | OTF   r     | RTF   r     | ZIP   r
-  DV    r     | M2TS  r     | PAGES r     | RW2   r/w   |
+  360   r/w   | DPX   r     | ITC   r     | ODP   r     | RIFF  r
+  3FR   r     | DR4   r/w/c | J2C   r     | ODS   r     | RSRC  r
+  3G2   r/w   | DSS   r     | JNG   r/w   | ODT   r     | RTF   r
+  3GP   r/w   | DV    r     | JP2   r/w   | OFR   r     | RW2   r/w
+  A     r     | DVB   r/w   | JPEG  r/w   | OGG   r     | RWL   r/w
+  AA    r     | DVR-MS r    | JSON  r     | OGV   r     | RWZ   r
+  AAE   r     | DYLIB r     | K25   r     | ONP   r     | RM    r
+  AAX   r/w   | EIP   r     | KDC   r     | OPUS  r     | SEQ   r
+  ACR   r     | EPS   r/w   | KEY   r     | ORF   r/w   | SKETCH r
+  AFM   r     | EPUB  r     | LA    r     | OTF   r     | SO    r
+  AI    r/w   | ERF   r/w   | LFP   r     | PAC   r     | SR2   r/w
+  AIFF  r     | EXE   r     | LNK   r     | PAGES r     | SRF   r
+  APE   r     | EXIF  r/w/c | LRV   r/w   | PBM   r/w   | SRW   r/w
+  ARQ   r/w   | EXR   r     | M2TS  r     | PCD   r     | SVG   r
+  ARW   r/w   | EXV   r/w/c | M4A/V r/w   | PCX   r     | SWF   r
+  ASF   r     | F4A/V r/w   | MACOS r     | PDB   r     | THM   r/w
+  AVI   r     | FFF   r/w   | MAX   r     | PDF   r/w   | TIFF  r/w
+  AVIF  r/w   | FITS  r     | MEF   r/w   | PEF   r/w   | TORRENT r
+  AZW   r     | FLA   r     | MIE   r/w/c | PFA   r     | TTC   r
+  BMP   r     | FLAC  r     | MIFF  r     | PFB   r     | TTF   r
+  BPG   r     | FLIF  r/w   | MKA   r     | PFM   r     | TXT   r
+  BTF   r     | FLV   r     | MKS   r     | PGF   r     | VCF   r
+  CHM   r     | FPF   r     | MKV   r     | PGM   r/w   | VRD   r/w/c
+  COS   r     | FPX   r     | MNG   r/w   | PLIST r     | VSD   r
+  CR2   r/w   | GIF   r/w   | MOBI  r     | PICT  r     | WAV   r
+  CR3   r/w   | GPR   r/w   | MODD  r     | PMP   r     | WDP   r/w
+  CRM   r/w   | GZ    r     | MOI   r     | PNG   r/w   | WEBP  r
+  CRW   r/w   | HDP   r/w   | MOS   r/w   | PPM   r/w   | WEBM  r
+  CS1   r/w   | HDR   r     | MOV   r/w   | PPT   r     | WMA   r
+  CSV   r     | HEIC  r/w   | MP3   r     | PPTX  r     | WMV   r
+  CZI   r     | HEIF  r/w   | MP4   r/w   | PS    r/w   | WTV   r
+  DCM   r     | HTML  r     | MPC   r     | PSB   r/w   | WV    r
+  DCP   r/w   | ICC   r/w/c | MPG   r     | PSD   r/w   | X3F   r/w
+  DCR   r     | ICS   r     | MPO   r/w   | PSP   r     | XCF   r
+  DFONT r     | IDML  r     | MQV   r/w   | QTIF  r/w   | XLS   r
+  DIVX  r     | IIQ   r/w   | MRW   r/w   | R3D   r     | XLSX  r
+  DJVU  r     | IND   r/w   | MXF   r     | RA    r     | XMP   r/w/c
+  DLL   r     | INSP  r/w   | NEF   r/w   | RAF   r/w   | ZIP   r
+  DNG   r/w   | INSV  r     | NRW   r/w   | RAM   r     |
+  DOC   r     | INX   r     | NUMBERS r   | RAR   r     |
+  DOCX  r     | ISO   r     | O     r     | RAW   r/w   |
 
   Meta Information
@@ -102,13 +115,14 @@
   XMP            r/w/c  |  FotoStation    r/w  |  MPF            r
   MakerNotes     r/w/c  |  PhotoMechanic  r/w  |  Stim           r
-  Photoshop IRB  r/w/c  |  JPEG 2000      r    |  APE            r
-  ICC Profile    r/w/c  |  DICOM          r    |  Vorbis         r
-  MIE            r/w/c  |  Flash          r    |  SPIFF          r
-  JFIF           r/w/c  |  FlashPix       r    |  DjVu           r
-  Ducky APP12    r/w/c  |  QuickTime      r    |  M2TS           r
-  PDF            r/w/c  |  Matroska       r    |  PE/COFF        r
-  PNG            r/w/c  |  GeoTIFF        r    |  AVCHD          r
-  Canon VRD      r/w/c  |  PrintIM        r    |  ZIP            r
-  Nikon Capture  r/w/c  |  ID3            r    |  (and more)
+  Photoshop IRB  r/w/c  |  JPEG 2000      r    |  DPX            r
+  ICC Profile    r/w/c  |  DICOM          r    |  APE            r
+  MIE            r/w/c  |  Flash          r    |  Vorbis         r
+  JFIF           r/w/c  |  FlashPix       r    |  SPIFF          r
+  Ducky APP12    r/w/c  |  QuickTime      r    |  DjVu           r
+  PDF            r/w/c  |  Matroska       r    |  M2TS           r
+  PNG            r/w/c  |  MXF            r    |  PE/COFF        r
+  Canon VRD      r/w/c  |  PrintIM        r    |  AVCHD          r
+  Nikon Capture  r/w/c  |  FLAC           r    |  ZIP            r
+  GeoTIFF        r/w/c  |  ID3            r    |  (and more)
 
 =head1 CONFIGURATION
@@ -121,12 +135,14 @@
 By default ExifTool looks for a configuration file named ".ExifTool_config"
 first in your home directory, then in the directory of the application
-script, but a different file may be specified by setting the ExifTool
-C<configFile> variable before using Image::ExifTool.  For example:
+script, but a different directory may be specified by setting the
+EXIFTOOL_HOME environment variable, or a different file may be specified by
+setting the ExifTool C<configFile> variable before using Image::ExifTool. 
+For example:
 
     BEGIN { $Image::ExifTool::configFile = '/Users/phil/myconfig.cfg' }
     use Image::ExifTool;
 
-or the configuration feature may be disabled by setting C<configFile> to an
-empty string:
+The configuration feature may also be disabled by setting C<configFile> to
+an empty string:
 
     BEGIN { $Image::ExifTool::configFile = '' }
@@ -146,9 +162,12 @@
 
 None of these methods should ever die or issue warnings to STDERR if called
-with the proper arguments (with the exception of L</SetNewValue> which
-returns an error string when called in list context, or sends the error to
-STDERR otherwise).  Error and warning messages that occur during processing
-are stored in the values of the Error and Warning tags, and are accessible
-via the L</GetValue> method.
+with the proper arguments (with the exception of L</SetNewValue> which may
+send an error message to STDERR, but only when called in scalar context).
+Error and warning messages that occur during processing are stored in the
+values of the Error and Warning tags, and are accessible via the
+L</GetValue> method to retrieve a single Error or Warning message, or
+L</GetInfo> to retrieve any number of them.
+
+The ExifTool methods are not thread safe.
 
 =head2 new
@@ -160,5 +179,5 @@
 Note that ExifTool uses AUTOLOAD to load non-member methods, so any class
 using Image::ExifTool as a base class must define an AUTOLOAD which calls
-Image::ExifTool::DoAutoLoad().  ie)
+Image::ExifTool::DoAutoLoad().  eg)
 
     sub AUTOLOAD
@@ -209,8 +228,8 @@
 =item ExifTool ref
 
-L</ImageInfo> may be called with an ExifTool object if desired.  The
-advantage of using the object-oriented form is that the options may be set
-before calling L</ImageInfo>, and the object may be used afterward to access
-member functions.  Must be the first argument if used.
+L</ImageInfo> may be called with an ExifTool object if desired.  Advantages
+of using the object-oriented form are that options may be set before calling
+L</ImageInfo>, and the object may be used afterward to access member
+functions.  Must be the first argument if used.
 
 =item SCALAR
@@ -222,5 +241,5 @@
 
 Tag names are case-insensitive and may be prefixed by optional group names
-separated by colons.  A group name may begin with a family number (ie.
+separated by colons.  A group name may begin with a family number (eg.
 '1IPTC:Keywords'), to restrict matches to a specific family.  In the tag
 name, a '?' matches any single character and a '*' matches zero or more
@@ -228,7 +247,7 @@
 Wildcards may not be used in group names, with the exception that a group
 name of '*' may be used to extract all available instances of a tag
-regardless of the L</Duplicates> setting (ie. '*:WhiteBalance').  Multiple
-groups may be specified (ie. 'EXIF:Time:*' extracts all EXIF Time tags). And
-finally, a leading '-' indicates a tag to be excluded (ie. '-IFD1:*'), or a
+regardless of the L</Duplicates> setting (eg. '*:WhiteBalance').  Multiple
+groups may be specified (eg. 'EXIF:Time:*' extracts all EXIF Time tags). And
+finally, a leading '-' indicates a tag to be excluded (eg. '-IFD1:*'), or a
 trailing '#' causes the ValueConv value to be returned for this tag.
 
@@ -237,5 +256,5 @@
 are removed, the case may be changed, and an instance number may be added. 
 For this reason it is best to use either the keys of the returned hash or
-the elements of the tag array when accessing the tag values.
+the elements of the returned tag list when accessing the tag values.
 
 See L<Image::ExifTool::TagNames|Image::ExifTool::TagNames> for a complete
@@ -246,13 +265,12 @@
 A reference to an open image file.  If you use this method (or a SCALAR
 reference) to access information in an image, the FileName and Directory
-tags will not be returned.  (Also, the FileSize, FileModifyDate and
-FilePermissions tags will not be returned unless it is a plain file.)  Image
-processing begins at the current file position, and on return the file
-position is unspecified.  May be either a standard filehandle, or a
-reference to a L<File::RandomAccess|File::RandomAccess> object.  Note that
-the file remains open and must be closed by the caller after L</ImageInfo>
-returns.
-
-[Advanced:  To allow a non-rewindable stream (ie. a network socket) to be
+tags will not be returned.  (Also, a number of the File System tags will not
+be returned unless it is a plain file.)  Image processing begins at the
+current file position, and on return the file position is unspecified.  May
+be either a standard filehandle, or a reference to a
+L<File::RandomAccess|File::RandomAccess> object.  Note that the file remains
+open and must be closed by the caller after L</ImageInfo> returns.
+
+[Advanced:  To allow a non-rewindable stream (eg. a network socket) to be
 re-read after processing with ExifTool, first wrap the file reference in a
 L<File::RandomAccess|File::RandomAccess> object, then pass this object to
@@ -276,11 +294,13 @@
 (With L</Duplicates> enabled, there may be more entries in the returned list
 of tag keys, and with other L</Sort> settings the entries may not be in the
-same order as requested.)
+same order as requested.)  If a requested tag doesn't exist, a tag key is
+still generated, but the tag value is undefined.
 
 =item HASH ref
 
-Reference to a hash containing the options settings.  See L</Options>
-documentation below for a list of available options.  Options specified
-as arguments to L</ImageInfo> take precedence over L</Options> settings.
+Reference to a hash containing the options settings valid for this call
+only.  See L</Options> documentation below for a list of available options. 
+Options specified as arguments to L</ImageInfo> take precedence over
+L</Options> settings.
 
 =back
@@ -288,9 +308,9 @@
 =item Return Values:
 
-L</ImageInfo> returns a reference to a hash of tag key/value pairs.  The tag
-keys are identifiers, which are similar to the tag names but may have an
-embedded instance number if multiple tags with the same name were extracted
+L</ImageInfo> returns a reference to a hash of tag-key/value pairs.  The tag
+keys are identifiers -- essentially case-sensitive tag names with an
+appended instance number if multiple tags with the same name were extracted
 from the image.  Many of the ExifTool functions require a tag key as an
-argument. Use L</GetTagName [static]> to get the tag name for a given tag
+argument.  Use L</GetTagName [static]> to get the tag name for a given tag
 key.  Note that the case of the tag names may not be the same as requested.
 Here is a simple example to print out the information returned by
@@ -305,9 +325,9 @@
 to indicate a list.  Also, a hash reference may be returned if the L</Struct>
 option is used.  Lists of values are joined by commas into a single
-string only if the PrintConv option is enabled and the List option is
-disabled (which are the defaults).  Note that binary values are not
-necessarily extracted unless specifically requested or the Binary option is
-set.  If not extracted the value is a reference to a string of the form
-"Binary data ##### bytes".
+string only if the PrintConv option is enabled and the ListJoin option is
+enabled (which are the defaults).  Note that binary values are not
+necessarily extracted unless specifically requested, or the Binary option is
+enabled and the tag is not specifically excluded.  If not extracted the
+value is a reference to a string of the form "Binary data ##### bytes".
 
 The code below gives an example of how to handle these return values, as
@@ -341,8 +361,11 @@
 ExifTool returns all values as byte strings of encoded characters.  Perl
 wide characters are not used.  See L</CHARACTER ENCODINGS> for details about
-the encodings.
-
-As well as tags representing information extracted from the image,
-the following tags generated by ExifTool may be returned:
+the encodings.  By default, most returned values are encoded in UTF-8.  For
+these, Encode::decode_utf8() may be used to convert to a sequence of logical
+Perl characters.
+
+As well as tags representing information extracted from the image, the
+following L<Extra tags|Image::ExifTool::TagNames/Extra Tags> generated by
+ExifTool may be returned:
 
     ExifToolVersion - The ExifTool version number.
@@ -360,9 +383,9 @@
 options for an ExifTool object.  Options set this way are in effect for
 all function calls but may be overridden by options passed as arguments
-to some functions.
-
-The initial default options are obtained from values in the
-%Image::ExifTool::UserDefined::Options hash if it exists.  See the
-.ExifTool_config file in the full ExifTool distribution for details.
+to some functions.  Option names are not case sensitive.
+
+The default option values may be changed by defining a
+%Image::ExifTool::UserDefined::Options hash.  See the ExifTool_config file
+in the full ExifTool distribution for examples.
 
     # exclude the 'OwnerName' tag from returned information
@@ -387,18 +410,24 @@
     $isVerbose = $exifTool->Options('Verbose');
 
-=over 4
-
-=item Inputs:
-
-0) ExifTool object reference.
-
-1) Option parameter name.
-
-2) [optional] Option parameter value (may be undef to clear option).
-
-3-N) [optional] Additional parameter/value pairs.
+    # set a user parameter
+    $exifTool->Options(UserParam => 'MyParam=some value');
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Option parameter name (case-insensitive)
+
+2) [optional] Option parameter value (may be undef to clear option)
+
+3-N) [optional] Additional parameter/value pairs
 
 =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
 
@@ -406,7 +435,7 @@
 
 Flag to extract the value data for all binary tags.  Tag values representing
-large binary data blocks (ie. ThumbnailImage) are not necessarily extracted
+large binary data blocks (eg. ThumbnailImage) are not necessarily extracted
 unless this option is set or the tag is specifically requested by name.
-Default is 0.
+Default is undef.
 
 =item ByteOrder
@@ -417,12 +446,12 @@
 then the maker note byte order is used (if they are being copied), otherwise
 big-endian ('MM') order is assumed.  This can also be set via the
-ExifByteOrder tag, but the ByteOrder option takes precedence if both are
-set.
+L<ExifByteOrder tag|Image::ExifTool::TagNames/Extra Tags>, but the ByteOrder
+option takes precedence if both are set.
 
 =item Charset
 
-Character set for encoding character strings passed to/from ExifTool with
-code points above U+007F.  Default is UTF8.  Valid values are listed below,
-case is not significant:
+Character set for encoding character tag values passed to/from ExifTool with
+code points above U+007F.  Default is 'UTF8'.  Valid values are listed
+below, case is not significant:
 
   Value        Alias(es)        Description
@@ -439,4 +468,7 @@
   Vietnam      cp1258           Windows Vietnamese
   Thai         cp874            Windows Thai
+  DOSLatinUS   cp437            DOS Latin US
+  DOSLatin1    cp850            DOS Latin1
+  DOSCyrillic  cp866            DOS Cyrillic
   MacRoman     cp10000, Roman   Macintosh Roman
   MacLatin2    cp10029          Macintosh Latin2 (Central Europe)
@@ -450,17 +482,31 @@
 Note that this option affects some types of information when reading/writing
 the file and other types when getting/setting tag values, so it must be
-defined for both types of access.
+defined for both types of access.  See the L</CHARACTER ENCODINGS> section
+for more information about the handling of special characters.
+
+=item CharsetEXIF
+
+Internal encoding to use for stored EXIF "ASCII" string values.  May also be
+set to undef to pass through EXIF "ASCII" values without recoding.  Set to
+"UTF8" to conform with the MWG recommendation.  Default is undef.
+
+=item CharsetFileName
+
+External character set used for file names passed to ExifTool functions. 
+When set in Windows, this triggers use of Windows wide-character i/o library
+routines (requires Win32API::File).  Default is undef.  May also be set to
+an empty string to avoid "encoding not specified" warnings on Windows.
 
 =item CharsetID3
 
-Character encoding to assume for ID3v1 strings.  By the specification ID3v1
+Internal encoding to assume for ID3v1 strings.  By the specification ID3v1
 strings should be encoded in ISO 8859-1 (essentially Latin), but some
-applications may use local encoding instead.  Default is Latin.
+applications may use local encoding instead.  Default is 'Latin'.
 
 =item CharsetIPTC
 
-Fallback IPTC character set to assume if IPTC information contains no
-CodedCharacterSet tag.  Possible values are the same as the L</Charset>
-option.  Default is Latin.
+Fallback internal IPTC character set to assume if IPTC information contains
+no CodedCharacterSet tag.  Possible values are the same as the L</Charset>
+option.  Default is 'Latin'.
 
 Note that this option affects some types of information when reading/writing
@@ -470,22 +516,46 @@
 =item CharsetPhotoshop
 
-Character encoding to assume for Photoshop IRB resource names.  Default is
-Latin.
+Internal encoding to assume for Photoshop IRB resource names.  Default is
+'Latin'.
+
+=item CharsetQuickTime
+
+Internal encoding to assume for QuickTime strings stored with an unspecified
+encoding.  Default is 'MacRoman'.
+
+=item CharsetRIFF
+
+Internal encoding to assume for strings in RIFF metadata (eg. AVI and WAV
+files).  The default value of 0 assumes "Latin" encoding unless otherwise
+specified by the RIFF CSET chunk.  Set to undef to pass through strings
+without recoding.  Default is 0.
 
 =item Compact
 
-Flag to write compact output.  Default is 0.  The XMP specification suggests
-that the data be padded with blanks to allow in-place editing.  With this
-flag set the 2kB of padding is not written.  Note that this only effects
-embedded XMP since padding is never written for stand-alone XMP files.
+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
 
-Flag to calculate Composite tags automatically.  Default is 1.
+Flag to generate Composite tags when extracting information.  Default is 1.
 
 =item Compress
 
 Flag to write new values in compressed format if possible.  Has no effect
-unless Compress::Zlib is installed.  Default is 0.
+unless Compress::Zlib is installed.  Default is undef.
 
 =item CoordFormat
@@ -493,6 +563,9 @@
 Format for printing GPS coordinates.  This is a printf format string with
 specifiers for degrees, minutes and seconds in that order, however minutes
-and seconds may be omitted.  For example, the following table gives the
-output for the same coordinate using various formats:
+and seconds may be omitted.  If the hemisphere is known, a reference
+direction (N, S, E or W) is appended to each printed coordinate, but adding
+a C<+> to the first format specifier (eg. C<%+.6f>) prints a signed
+coordinate instead.  For example, the following table gives the output for
+the same coordinate using various formats:
 
       CoordFormat        Example Output
@@ -509,7 +582,10 @@
 
 Format for printing date/time values.  See C<strftime> in the L<POSIX>
-package for details about the format string.  The default is similar to a
-format of "%Y:%m:%d %H:%M:%S".  If date can not be converted, value is left
-unchanged unless the StrictDate option is set.  Timezones are ignored.
+package for details about the format string.  If date can not be converted,
+value is left unchanged unless the StrictDate option is set.  Timezones are
+ignored.  The inverse conversion (ie. when calling L</SetNewValue>) is
+performed only if POSIX::strptime or Time::Piece is installed.  The default
+setting of undef causes date/time values to remain in standard EXIF format
+(similar to a DateFormat of "%Y:%m:%d %H:%M:%S").
 
 =item Duplicates
@@ -530,24 +606,66 @@
 is either a tag name or reference to a list of tag names to exclude.  The
 case of tag names is not significant.  This option is ignored for
-specifically requested tags.  Tags may also be excluded by preceeding their
+specifically requested tags.  Tags may also be excluded by preceding their
 name with a '-' in the arguments to L</ImageInfo>.
 
+=item ExtendedXMP
+
+This setting affects the reading and editing of extended XMP in JPEG images.
+According to the XMP specification, extended XMP is only valid if it has the
+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
+  <guid> - Read extended XMP with a specific GUID
+
 =item ExtractEmbedded
 
-Flag to extract information from embedded documents in EPS and 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 0.
+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, timed metadata in videos, and the resource
+fork of Mac OS files.  A setting of 2 also causes the H264 video stream in
+MP4 files to be parsed until the first SEI message is decoded, or 3 to
+parse the entire stream.  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 (ie. XMP written by some utilities) may be missed.  When
+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.  Default is 0.
+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 higher, 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.  For 5, generation of Composite tags is also
+disabled (like setting L</Composite> to 0).  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 current ExifTool object may be accessed through
+$self.  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 current ExifTool object may be
+accessed through $self.  The tag is not written if $_ is set to undef.
 
 =item FixBase
@@ -563,7 +681,11 @@
 =item GeoMaxIntSecs
 
-Maximum interpolation time in seconds for geotagging.  Geotagging fails if
-the Geotime value lies between two fixes in the same track which are
-separated by a number of seconds greater than this.  Default is 1800.
+Maximum interpolation time in seconds for geotagging.  Geotagging is treated
+as an extrapolation if the Geotime value lies between two fixes in the same
+track which are separated by a number of seconds greater than this. 
+Otherwise, the coordinates are calculated as a linear interpolation between
+the nearest fixes on either side of the Geotime value.  Set to 0 to disable
+interpolation and use the coordinates of the nearest fix instead (provided
+it is within GeoMaxExtSecs, otherwise geotagging fails).  Default is 1800.
 
 =item GeoMaxExtSecs
@@ -571,5 +693,7 @@
 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.  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
@@ -587,4 +711,19 @@
 Minimum number of satellites for geotagging.  GPS fixes are ignored if the
 number of acquired satellites is less than this.  Default is undef.
+
+=item GeoSpeedRef
+
+Reference units for writing GPSSpeed when geotagging:
+
+    'K', 'k' or 'km/h'  - km/h
+    'M', 'm' or 'mph'   - mph
+    <anything else>     - knots (default undef)
+
+=item GlobalTimeShift
+
+Time shift to apply to all extracted date/time PrintConv values.  Does not
+affect ValueConv values.  Value is a date/time shift string (see
+L<Image::ExifTool::Shift(3pm)|Image::ExifTool::Shift.pl>), with a leading
+'-' for negative shifts.  Default is undef.
 
 =item Group#
@@ -597,4 +736,9 @@
 group names.
 
+=item HexTagIDs
+
+Return hexadecimal instead of decimal for the family 7 group names of tags
+with numerical ID's.
+
 =item HtmlDump
 
@@ -605,6 +749,6 @@
 =item HtmlDumpBase
 
-Specifies base for HTML dump offsets.  If not defined, the EXIF/TIFF base
-offset is used.  Set to 0 for absolute offsets.  Default is undef.
+Base for HTML dump offsets.  If not defined, the EXIF/TIFF base offset is
+used.  Set to 0 for absolute offsets.  Default is undef.
 
 =item IgnoreMinorErrors
@@ -615,35 +759,39 @@
 minor warnings the behaviour of ExifTool may be changed to allow some
 questionable operations to proceed (such as extracting thumbnail and preview
-images even if they don't have a recognizable header).  Minor
-errors/warnings are denoted by '[minor]' at the start of the message.
+images even if they don't have a recognizable header).  Minor errors and
+warnings are denoted by "[minor]" at the start of the message, or "[Minor]"
+(with a capital "M") for warnings that affect processing when ignored.
 
 =item Lang
 
 Localized language for exiftool tag descriptions, etc.  Available languages
-are given by the Image::ExifTool::Lang module names (ie. 'fr').  If the
-specified language isn't available, the option is not changed.  May be set
-to undef to select the built-in default language.  Default is 'en'.
+are given by the Image::ExifTool::Lang module names (eg. 'fr', 'zh_cn').  If
+the specified language isn't available, the option is not changed.  May be
+set to undef to select the built-in default language.  Default is 'en'.
 
 =item LargeFileSupport
 
 Flag to indicate that 64-bit file offsets are supported on this system.
-Default is 0.
-
-=item List
-
-Flag to extract lists of PrintConv values into arrays instead of joining
-them into a string of values.  The L</ListSep> option specifies the
-separator used when combining values.  Default is 0.
-
-=item ListSep
-
-Separator string used to join lists of PrintConv values when L</List> option
-is not set.  Default is ', '.
+Default is undef.
+
+=item ListItem
+
+Return only a specific item from list-type values.  A value of 0 returns the
+first item in the list, 1 return the second item, etc.  Negative indices may
+also be used, with -1 representing the last item in the list.  Applies only
+to the top-level list of nested lists.  Default is undef to return all items
+in the list.
+
+=item ListJoin
+
+Separator used to join the PrintConv value of multi-item List-type tags into
+a single string.  If not defined, multi-item lists are returned as a list
+reference.  Does not affect ValueConv values.  Default is ', '.
 
 =item ListSplit
 
 Regular expression used to split values of list-type tags into individual
-items when writing.  (ie. use ',\\s*' to split a comma-separated list.) 
-Default is undef.
+items when writing.  (eg. use ',\\s*' to split a comma-separated list.)
+Split when writing either PrintConv or ValueConv values.  Default is undef.
 
 =item MakerNotes
@@ -655,17 +803,33 @@
 are:
 
-  0 - Do not extract writable subdirectories (default)
+  0 - Do not extract writable subdirectories (same as default of undef)
   1 - Extract and rebuild maker notes into self-contained block
   2 - Extract without rebuilding maker notes
 
+=item MDItemTags
+
+Flag to extract the OS X metadata item tags (see the "mdls" man page and
+L<Image::ExifTool::TagNames/MacOS MDItem Tags> for more information).
+
 =item MissingTagValue
 
-Value for missing tags in expressions evaluated by L</SetNewValuesFromFile>.
-If not set, a minor error is issued for missing values, or the value is set
-to '' if L</IgnoreMinorErrors> 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</IgnoreMinorErrors> is
+set.  Default is undef.
+
+=item NoMultiExif
+
+Raise error when attempting to write multi-segment EXIF in a JPEG image. 
+Default is undef.
+
+=item NoPDFList
+
+Flag to avoid splitting PDF list-type tag values into separate items.
+Default is undef.
 
 =item Password
 
-Password for processing password-protected PDF documents.  Ignored if a
+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.
@@ -676,9 +840,60 @@
 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, and it has been reported that
+Apple QuickTime Player and Photos.apps will ignore ItemList tags if this is
+missing.  Default is 1.
+
+=item QuickTimeUTC
+
+Flag set to assume that QuickTime date/time values are stored as UTC,
+causing conversion to local time when they are extracted and from local time
+when written.  According to the QuickTime specification date/time values
+should be UTC, but many digital cameras store local time instead (presumably
+because they don't know the time zone), so the default is to not convert
+these times (except for Canon CR3 files, which always use UTC times).  This
+option also disables the autodetection of incorrect time-zero offsets in
+QuickTime date/time values, and enforces a time zero of 1904 as per the
+QuickTime specification.
+
+=item RequestAll
+
+Flag to request all tags to be extracted.  This causes some tags to be
+generated which normally would not be unless specifically requested (by
+passing the tag name to L</ImageInfo> or L</ExtractInfo>).  May be set to 2
+or 3 to enable generation of some additional tags as mentioned in the tag
+name documentation.  Default is undef.
+
+=item RequestTags
+
+List of additional tag and/or group names to request in the next call to
+L</ExtractInfo>.  This option is useful only for tags/groups which aren't
+extracted unless specifically requested.  Value may be a list reference, a
+delimited string of names (any delimiter is allowed), or undef to clear the
+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</GetGroup> 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</GetGroup> option for more details.
+
 =item ScanForXMP
 
-Flag for scan all files (even unrecognized formats) for XMP information
+Flag to scan all files (even unrecognized formats) for XMP information
 unless XMP was already found in the file.  When combined with the FastScan
-option, only unrecognized file types are scanned for XMP.  Default is 0.
+option, only unrecognized file types are scanned for XMP.  Default is undef.
 
 =item Sort
@@ -687,6 +902,7 @@
 
   Input  - Sort in same order as input tag arguments (default)
-  Alpha  - Sort alphabetically
   File   - Sort in order that tags were found in the file
+  Tag    - Sort alphabetically by tag name
+  Descr  - Sort by tag description (for current Lang setting)
   Group# - Sort by tag group, where # is zero or more family
            numbers separated by colons. If # is not specified,
@@ -694,4 +910,12 @@
            of group families.
 
+=item Sort2
+
+Secondary sort order used for tags within each group when Sort is 'Group':
+
+  File   - Sort in order tags were found in the file (default)
+  Tag    - Sort alphabetically by tag name
+  Descr  - Sort by tag description (for current Lang setting)
+
 =item StrictDate
 
@@ -699,15 +923,35 @@
 the DateFormat option is used.  Default is undef.
 
+  undef - Same as 0 for reading/writing, or 1 for copying
+    0   - Return date/time value unchanged if it can't be converted
+    1   - Return undef if date/time value can't be converted
+
+When set to 1 while writing a PrintConv date/time value with the DateFormat
+option set, the value is written only if POSIX::strptime or Time::Piece is
+available and can successfully convert the value.
+
+For PNG CreationTime, a setting of 1 has the additional effect of causing
+the date/time to be reformatted according to PNG 1.2 recommendation
+(RFC-1123) when writing, and a warning to be issued for any non-standard
+value when reading (but note that Windows may not recognize PNG date/time
+values in standard format).
+
 =item Struct
 
 Flag to return XMP structures as hash references instead of flattening into
-individual tags.  If not defined (the default), tags are flattened when
-reading (with L<ExtractInfo>), and structured when copying (with
-L</SetNewValuesFromFile>).  Has no effect when writing since both flattened
-and structured tags may always be written.  Possible values are:
-
-  undef - Read flattened tags, copy structured tags (default)
-    0   - Read and copy flattened tags
-    1   - Read and copy structured tags
+individual tags.  Has no effect when writing since both flattened and
+structured tags may always be written.  Possible values are:
+
+  undef - (default) Same as 0 for reading, 2 for copying
+    0   - Read/copy flattened tags
+    1   - Read/copy structured tags
+    2   - Read/copy both flattened and structured tags, but flag
+          flattened tags as 'unsafe' for copying
+
+=item SystemTags
+
+Flag to extract the following additional File System tags:  FileAttributes,
+FileDeviceNumber, FileInodeNumber, FileHardLinks, FileUserID, FileGroupID,
+FileDeviceID, FileBlockSize and FileBlockCount.
 
 =item TextOut
@@ -715,4 +959,11 @@
 Output file reference for Verbose and HtmlDump options.  Default is
 \*STDOUT.
+
+=item TimeZone
+
+Time zone for local date/time values.  May be set to any valid TZ string.
+Uses the system time zone if not specified.  Default is undef.  (Requires
+POSIX::tzset, which may not be available in Windows.  A work-around in
+Windows is to C<set TZ=E<lt>zoneE<gt>> before running ExifTool.)
 
 =item Unknown
@@ -721,4 +972,32 @@
 extracted from EXIF (or other tagged-format) directories.  If set to 2,
 unknown tags are also extracted from binary data blocks.  Default is 0.
+
+=item UserParam
+
+Special option to set/get user-defined parameters.  Useful to allow external
+input into tag name expressions and ValueConv logic.  Valid UserParam values
+are:
+
+  PARAM         - Get parameter
+  PARAM=        - Clear parameter
+  PARAM^=       - Set parameter to empty string
+  PARAM=VALUE   - Set parameter
+  <hash ref>    - Set entire UserParam hash lookup
+  undef         - Clear all user parameters
+
+Where I<PARAM> is the user-defined parameter name (case insensitive).
+
+User-defined parameters may be accessed in tag name expressions by prefixing
+the parameter name with a dollar sign just like normal tags, or via the API
+by calling C<Options('UserParam','PARAM')>.  Appending a hash tag (C<#>) to
+the parameter name also causes the parameter to be extracted as a normal tag
+(in the UserParam group).  If called without additional arguments,
+C<Options('UserParam')> returns a reference to the hash of all user
+parameters (with lower-case names).
+
+=item Validate
+
+Flag to perform extra validation metadata checks when reading, causing extra
+warnings to be generated if problems are found.  Default is undef.
 
 =item Verbose
@@ -732,4 +1011,29 @@
 on tag values and JPEG segment data respectively.
 
+=item WriteMode
+
+Set tag write/create mode.  Value is a string of one or more characters from
+list below.  Default is 'wcg'.
+
+    w - Write existing tags
+    c - Create new tags
+    g - create new Groups as necessary
+
+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).  The 'w' and 'c' modes are
+tested only when L</SetNewValue> is called, but the 'g' mode is also tested
+in L</WriteInfo>.
+
+=item XAttrTags
+
+Flag to extract the OS X extended attribute tags (see the "xattr" man page
+and L<Image::ExifTool::TagNames/MacOS XAttr Tags> for more information).
+
+=item XMPAutoConv
+
+Flag to enable automatic conversion for unknown XMP tags with values that
+look like rational numbers or dates.  Default is 1.
+
 =back
 
@@ -775,8 +1079,11 @@
 L</ExtractInfo>:
 
-Binary, Charset, CharsetID3, CharsetIPTC, Composite, ExtractEmbedded,
-FastScan, FixBase, HtmlDump, HtmlDumpBase, IgnoreMinorErrors, Lang,
-LargeFileSupport, MakerNotes, ScanForXMP, Struct, TextOut, Unknown and
-Verbose.
+Binary, Charset, CharsetEXIF, CharsetFileName, CharsetID3, CharsetIPTC,
+CharsetPhotoshop, CharsetQuickTime, CharsetRIFF, Composite, ExtendedXMP,
+ExtractEmbedded, FastScan, FixBase, HtmlDump, HtmlDumpBase,
+IgnoreMinorErrors, Lang, LargeFileSupport, MakerNotes, MDItemTags,
+NoPDFList, Password, QuickTimeUTC (enforced 1904 time zero), RequestAll,
+RequestTags, SaveFormat, SavePath, ScanForXMP, Struct, TextOut, Unknown,
+Verbose, XAttrTags and XMPAutoConv.
 
 =item Return Value:
@@ -793,6 +1100,9 @@
 L</ImageInfo>.
 
-    # get image width and hieght only
+    # get image width and height only
     $info = $exifTool->GetInfo('ImageWidth', 'ImageHeight');
+
+    # get all Error and Warning messages
+    $info = $exifTool->GetInfo('Error', 'Warning');
 
     # get information for all tags in list (list updated with tags found)
@@ -809,13 +1119,20 @@
 image can not be specified.  Options in effect are:
 
-Charset, CoordFormat, DateFormat, Duplicates, Escape, Exclude, Group#, Lang,
-List, ListSep, PrintConv, Sort (if a tag list reference is given) and
+Charset, CoordFormat, DateFormat, Duplicates, Escape, Exclude, Filter,
+Group#, GlobalTimeShift, Lang, ListItem, ListJoin, PrintConv, Sort (if a tag
+list reference is given) and StrictDate.
+
+=item Return Value:
+
+Reference to information hash, the same as with L</ImageInfo>.
+
+=back
+
+The following options are effective in the call to L</GetInfo>:
+
+Charset, CoordFormat, DateFormat, Duplicates, Escape, Exclude, Filter,
+Group#, GlobalTimeShift, Lang, ListItem, ListJoin, PrintConv, QuickTimeUTC
+(conversion to local time), Sort (if a tag list reference is given) and
 StrictDate.
-
-=item Return Value:
-
-Reference to information hash, the same as with L</ImageInfo>.
-
-=back
 
 =head2 WriteInfo
@@ -828,4 +1145,15 @@
 additional files without the need to call L</SetNewValue> again.
 
+ExifTool queues all new values that are assigned via calls to
+L</SetNewValue>, then applies them to any number of files through one or
+more calls to L</WriteInfo>. These queued values may be accessed through
+L</GetNewValue>, and are completely separate from metadata extracted from
+files via L</ExtractInfo> or L</ImageInfo> and accessed through L</GetInfo>
+or L</GetValue>.
+
+To be clear, it is NOT necessary to call L</ExtractInfo> or L</ImageInfo>
+before L</WriteInfo>.  L</WriteInfo> changes only metadata specified by
+previous calls to L</SetNewValue>.
+
     # add information to a source file, writing output to new file
     $exifTool->WriteInfo($srcfile, $dstfile);
@@ -844,10 +1172,12 @@
 
 1) Source file name, file reference, scalar reference, or undef to create a
-file from scratch
+file from scratch.  A reference to a
+L<File::RandomAccess|File::RandomAccess> object is also allowed as a source,
+but in this case the destination is not optional.
 
 2) [optional] Destination file name, file reference, scalar reference, or
-undef to overwrite the original file
-
-3) [optional] Destination file type
+undef to overwrite the original file.  May be '-' to write to stdout.
+
+3) [optional] Destination file type.  Ignored if a source is defined.
 
 =item Return Value:
@@ -867,19 +1197,20 @@
 
 The source file name may be undefined to create a file from scratch
-(currently only XMP, MIE, ICC, VRD and EXIF files can be created in this way
--- see L</CanCreate> for details).  If undefined, the destination file type
-is required unless the type can be determined from the destination file
-name.
+(currently only XMP, MIE, ICC, VRD, DR4, EXV and EXIF files can be created
+in this way -- see L</CanCreate> for details).  If undefined, the
+destination file type is required unless the type can be determined from the
+extension of the destination file name.
 
 If a destination file name is given, the specified file must not exist
-because an existing destination file will not be overwritten.  The
-destination file name may be undefined to overwrite the original file (make
-sure you have backups!).  In this case, if a source file name is provided, a
-temporary file is created and renamed to replace the source file if no
-errors occurred while writing.  Otherwise, if a source file reference or
-scalar reference is used, the image is first written to memory then copied
-back to replace the original if there were no errors.
-
-The destination file type is only used if the source file is undefined.
+because an existing destination file will not be overwritten.  Any new
+values for FileName, Directory or HardLink are ignored when a destination
+file name is specified.
+
+The destination file name may be undefined to overwrite the original file
+(make sure you have backups!).  In this case, if a source file name is
+provided, a temporary file is created and renamed to replace the source file
+if no errors occurred while writing.  Otherwise, if a source file reference
+or scalar reference is used, the image is first written to memory then
+copied back to replace the original if there were no errors.
 
 On Mac OS systems, the file resource fork is preserved if this routine is
@@ -890,12 +1221,13 @@
 The following ExifTool options are effective in the call to L</WriteInfo>:
 
-ByteOrder, Charset, CharsetID3, CharsetIPTC, Compact, Compress, FixBase,
-IgnoreMinorErrors and Verbose.
-
-=head2 CombineInfo
-
-Combine information from more than one information hash into a single hash.
-
-    $info = $exifTool->CombineInfo($info1, $info2, $info3);
+ByteOrder, Charset, CharsetEXIF, CharsetFileName, CharsetIPTC, Compact,
+Compress, FixBase, IgnoreMinorErrors, Password, QuickTimeHandler, Verbose
+and WriteMode.
+
+=head2 GetTagList
+
+Get a sorted list of tags from the specified information hash or tag list.
+
+    @tags = $exifTool->GetTagList($info, 'Group0');
 
 =over 4
@@ -905,28 +1237,9 @@
 0) ExifTool object reference
 
-1-N) Information hash references
-
-=back
-
-If the Duplicates option is disabled and duplicate tags exist, the order of
-the hashes is significant.  In this case, the value used is the first value
-found as the hashes are scanned in order of input.  The Duplicates option
-is the only option that is in effect for this function.
-
-=head2 GetTagList
-
-Get a sorted list of tags from the specified information hash or tag list.
-
-    @tags = $exifTool->GetTagList($info, 'Group0');
-
-=over 4
-
-=item Inputs:
-
-0) ExifTool object reference,
-
-1) [optional] Information hash reference or tag list reference,
-
-2) [optional] Sort order ('File', 'Input', 'Alpha' or 'Group#').
+1) [optional] Information hash reference or tag list reference
+
+2) [optional] Sort order ('Input', 'File', 'Tag', 'Descr' or 'Group#')
+
+3) [optional] Secondary sort order ('File', 'Tag' or 'Descr')
 
 If the information hash or tag list reference is not provided, then the list
@@ -956,5 +1269,7 @@
 0) ExifTool object reference
 
-1) [optional] Sort order ('File', 'Input', 'Alpha' or 'Group#')
+1) [optional] Sort order ('Input', 'File', 'Tag', 'Descr' or 'Group#')
+
+2) [optional] Secondary sort order ('File', 'Tag' or 'Descr')
 
 If sort order is not specified, the sort order from the ExifTool options is
@@ -994,16 +1309,17 @@
 Get the value of a specified tag.  The returned value is either the
 human-readable (PrintConv) value, the converted machine-readable (ValueConv)
-value, or the original raw (Raw) value.  If the value type is not specified,
-the PrintConv value is returned if the PrintConv option is set, otherwise
-the ValueConv value is returned.  The PrintConv values are same as the
-values returned by L</ImageInfo> and L</GetInfo> in the tag/value hash
-unless the PrintConv option is disabled.
+value, the original raw (Raw) value, or the original rational (Rational)
+value for rational formats.  If the value type is not specified, the
+PrintConv value is returned if the PrintConv option is set, otherwise the
+ValueConv value is returned.  The PrintConv values are same as the values
+returned by L</ImageInfo> and L</GetInfo> in the tag/value hash unless the
+PrintConv option is disabled.
 
 Tags which represent lists of multiple values (as may happen with 'Keywords'
 for example) are handled specially.  In scalar context, the returned
 PrintConv value for these tags is either a string of values or a list
-reference (depending on the List option setting), and the ValueConv value is
-always a list reference.  But in list context, L</GetValue> always returns
-the list itself.
+reference (depending on the ListJoin option setting), and the ValueConv
+value is always a list reference.  But in list context, L</GetValue> always
+returns the list itself.
 
 Note that L</GetValue> requires a case-sensitive tag key as an argument.  To
@@ -1031,8 +1347,9 @@
     my @keywords = $exifTool->GetValue('Keywords', 'ValueConv');
 
-The following options are in effect when <L/GetValue> is called:
-
-Charset, CoordFormat, DateFormat, Escape, Lang, List, ListSep, PrintConv and
-StrictDate.
+The following options are in effect when L</GetValue> is called:
+
+Charset, CoordFormat, DateFormat, Escape, Filter, GlobalTimeShift, Lang,
+ListItem, ListJoin, PrintConv, QuickTimeUTC (conversion to local time),
+StrictDate and TimeZone.
 
 =over 4
@@ -1042,23 +1359,30 @@
 0) ExifTool object reference
 
-1) Tag key
-
-2) [optional] Value type, 'PrintConv', 'ValueConv', 'Both' or 'Raw'
+1) Tag key, or case-sensitive tag name with optional group prefix(es)
+
+2) [optional] Value type: 'PrintConv', 'ValueConv', 'Both', 'Raw' or
+'Rational'
 
 The default value type is 'PrintConv' if the PrintConv option is set,
 otherwise the default is 'ValueConv'.  A value type of 'Both' returns both
-ValueConv and PrintConv values as a list.
+ValueConv and PrintConv values as a list.  'Rational' returns the raw
+rational value as a string fraction for rational types, or undef for other
+types.
 
 =item Return Values:
 
-The value of the specified tag.  If the tag represents a list of values and
-the List option is disabled then PrintConv returns a string of values,
-otherwise a reference to the list is returned in scalar context.  The list
-itself is returned in list context.  Values may also be scalar references to
-binary data, or hash references if the Struct option is set.
+The value of the specified tag.  If the tag represents a list of multiple
+values and the ListJoin option is enabled then PrintConv returns a string of
+values, otherwise a reference to the list is returned in scalar context. The
+list itself is returned in list context.  (Unless 'Both' values are
+requested, in which case two list references are returned, regardless of
+context.)  Values may also be scalar references to binary data, or hash
+references if the L</Struct> option is set.
 
 Note: It is possible for L</GetValue> to return an undefined ValueConv or
 PrintConv value (or an empty list in list context) even if the tag exists,
-since it is possible for these conversions to yield undefined values.
+since it is possible for these conversions to yield undefined values.  And
+the Rational value will be undefined for any non-rational tag.  The Raw
+value should always exist if the tag exists.
 
 =back
@@ -1089,5 +1413,5 @@
     $exifTool->SetNewValue('Keywords', $word, DelValue => 1);
 
-    # set keywords (a List-type tag) with two new values
+    # set keywords (a list-type tag) with two new values
     $exifTool->SetNewValue(Keywords => 'word1');
     $exifTool->SetNewValue(Keywords => 'word2');
@@ -1098,10 +1422,16 @@
     $exifTool->SetNewValue(Keywords => $word, AddValue => 1);
 
+    # conditionally add a tag if it didn't exist before,
+    # or replace it if it had a specified value ("old value")
+    $exifTool->SetNewValue(Description => '', DelValue => 1);
+    $exifTool->SetNewValue(Description => 'old value', DelValue => 1);
+    $exifTool->SetNewValue(Description => 'new value');
+
     # set a tag in a specific group
     $exifTool->SetNewValue(Headline => $val, Group => 'XMP');
     $exifTool->SetNewValue('XMP:Headline' => $val);  # (equivalent)
 
-    # shift original date/time back by 1 hour
-    $exifTool->SetNewValue(DateTimeOriginal => '1:00', Shift => -1);
+    # shift original date/time back by 2.5 hours
+    $exifTool->SetNewValue(DateTimeOriginal => '2:30', Shift => -1);
 
     # write a tag only if it had a specific value
@@ -1128,6 +1458,6 @@
     $exifTool->SetNewValue('XMP:Flash'=>'{mode=on,fired=true,return=not}');
 
-(See L<http://owl.phy.queensu.ca/~phil/exiftool/struct.html#Serialize> for
-a description of the structure serialization technique.)
+(See L<https://exiftool.org/struct.html#Serialize> for a description of the
+structure serialization technique.)
 
 =over 4
@@ -1137,10 +1467,17 @@
 0) ExifTool object reference
 
-1) [optional] Tag key or tag name, or undef to clear all new values.  A tag
-name of '*' can be used when deleting tags to delete all tags, or all tags
-in a specified group.  The tag name may be prefixed by group name, separated
-by a colon (ie. 'EXIF:Artist'), which is equivalent to using a Group option
-argument.  Also, a '#' may be appended to the tag name (ie.
-'EXIF:Orientation#'), with the same effect as setting Type to 'ValueConv'.
+1) [optional] Tag key or tag name, or undef to clear all new values.  The
+tag name may be prefixed by one or more family 0, 1 or 2 group names with
+optional leading family numbers, separated by colons (eg. 'EXIF:Artist',
+'XMP:Time:*'), which is equivalent to using a Group option argument.  Also,
+a '#' may be appended to the tag name (eg. 'EXIF:Orientation#'), with the
+same effect as setting Type to 'ValueConv'.  Wildcards ('*' and '?') may be
+used in the tag name to assign multiple tags simultaneously.  A tag name of
+'*' is special when deleting information, and will delete an entire group
+even if some individual tags in the group are not writable, but only if a
+single family 0 or 1 group is specified (otherwise the tags are deleted
+individually).  Use L</GetDeleteGroups> to get a list of deletable group
+names, and see L<Image::ExifTool::TagNames|Image::ExifTool::TagNames> for a
+complete list of tag names.
 
 2) [optional] New value for tag.  Undefined to delete tag from file.  May be
@@ -1148,5 +1485,5 @@
 reference for a structure.  Integer values may be specified as a hexadecimal
 string (with a leading '0x'), and simple rational values may be specified in
-fractional form (ie. '4/10').  Structure tags may be specified either as a
+fractional form (eg. '4/10').  Structure tags may be specified either as a
 hash reference or a serialized string (see the last two examples above).
 
@@ -1159,27 +1496,42 @@
 =item AddValue
 
-Specifies that the value be added to an existing list rather than replacing
-the list.  Valid values are 0 or 1.  Default is 0.
+Specifies that the value be added to an existing list in a file rather than
+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
 
-Delete the existing tag if it has the specified value.  Valid values are
-0 or 1.  Default is 0.
+Delete existing tag from a file if it has the specified value.  For
+list-type tags this deletes a specified item from the list.  For non-list
+tags this may be used to conditionally replace a tag by providing a new
+value in a separate call to L<SetNewValue> (see examples above).  For
+structured tags, the entire structure is deleted/replaced only if all of the
+specified fields match the existing structure.  Option values are 0 or 1. 
+Default is 0.
 
 =item EditGroup
 
 Create tags in existing groups only.  Don't create new group.  Valid values
-are 0 and 1.  Default is 0.
+are 0 and 1.  Effectively removes the 'g' from the ExifTool WriteMode option
+for this tag only.  Default is 0.
 
 =item EditOnly
 
 Edit tag only if it already exists.  Don't create new tag.  Valid values are
-0 and 1.  Default is 0.
+0 and 1.  Effectively removes the 'c' from the ExifTool WriteMode option for
+this tag only.  Default is 0.
 
 =item Group
 
-Specifies group name where tag should be written.  If not specified, tag is
-written to highest priority group as specified by L</SetNewGroups>.  Any
-family 0 or 1 group name may be used.  Case is not significant.
+Specifies group name where tag should be written.  This option is superseded
+by any group specified in the tag name.  If not specified, tag is written to
+highest priority group as specified by L</SetNewGroups>.  May be one or more
+family 0, 1 or 2 groups with optional leading family number, separated by
+colons.  Case is not significant.
+
+=item NoFlat
+
+Treat flattened tags as 'unsafe'.
 
 =item NoShortcut
@@ -1197,21 +1549,28 @@
 names indicating 'unsafe' and 'protected' tags.  Default is 0.
 
+=item ProtectSaved
+
+Avoid setting new values which were saved after the Nth call to
+L</SaveNewValues>.  Has no effect on unsaved values, or values saved before
+Nth call.  Option value is N.  Default is undef.
+
 =item Replace
 
 Flag to replace the previous new values for this tag (ie. replace the values
 set in previous calls to L</SetNewValue>).  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).
+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 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
 
-Shift the tag by the specified value.  Currently only date/time tags can be
-shifted.  Undefined for no shift, 1 for a positive shift, or -1 for a
-negative shift.  If 0, the shift is applied only if the tag is shiftable,
-and the shift is positive if AddValue is set, or negative if DelValue is
-set.  Default is undef.  See
-L<Image::ExifTool::Shift.pl|Image::ExifTool::Shift.pl> for more information.
+Shift the tag by the specified value.  Currently only date/time tags and
+tags with numerical values may be shifted.  Undefined for no shift, 1 for a
+positive shift, or -1 for a negative shift.  A value of 0 causes a positive
+shift to be applied if the tag is shiftable and AddValue is set, or a
+negative shift for date/time tags only if DelValue is set. Default is undef.
+See L<Image::ExifTool::Shift(3pm)|Image::ExifTool::Shift.pl> for more
+information.
 
 =item Type
@@ -1226,14 +1585,19 @@
 
 In scalar context, returns the number of tags set and error messages are
-printed to STDERR.  In list context, returns the number of tags set and the
-error string.
+printed to STDERR.  In list context, returns the number of tags set, and the
+error string (which is undefined if there was no error).
 
 =item Notes:
 
-When deleting groups of tags, the Replace option may be used as in the last
-example above to exclude specific groups from a mass delete.  However, this
-technique may not be used to exclude individual tags.  Instead, use
-L</SetNewValuesFromFile> to recover the values of individual tags after
-deleting a group.
+When deleting groups of tags, the Replace option may be used to exclude
+specific groups from a mass delete.  However, this technique may not be used
+to exclude individual tags from a group delete (unless a family 2 group was
+specified in the delete).  Instead, use L</SetNewValuesFromFile> to recover
+the values of individual tags after deleting a group.
+
+When deleting all tags from a JPEG image, the APP14 "Adobe" information is
+not deleted by default because doing so may affect the appearance of the
+image.  However, this information may be deleted by specifying it
+explicitly, either by group (with 'Adobe:*') or as a block (with 'Adobe').
 
 =back
@@ -1241,6 +1605,33 @@
 The following ExifTool options are effective in the call to L</SetNewValue>:
 
-Charset, Escape, IgnoreMinorErrors, Lang, ListSep, ListSplit, PrintConv and
-Verbose.
+Charset, DateFormat, Escape, IgnoreMinorErrors, Lang, ListJoin, ListSplit,
+PrintConv, QuickTimeUTC, StrictDate, TimeZone, Verbose and WriteMode.
+
+=head2 GetNewValue
+
+Get the new Raw value for a tag.  This is the value set by L</SetNewValue>
+this is queued to be written to file.  List-type tags may return multiple
+values in list context.
+
+    $rawVal = $exifTool->GetNewValue($tag);
+
+    @rawVals = $exifTool->GetNewValue($tag);
+
+=over 4
+
+=item Inputs:
+
+0) ExifTool object reference
+
+1) Tag name (case sensitive, may be prefixed by family 0, 1 or 7 group
+names, separated by colons)
+
+=item Return Values:
+
+List of new Raw tag values, or first value in list when called in scalar
+context.  The list may be empty either if the tag isn't being written, or if
+it is being deleted (ie. if L</SetNewValue> was called without a value).
+
+=back
 
 =head2 SetNewValuesFromFile
@@ -1261,8 +1652,8 @@
 
     # set new value from a different tag in specific group
-    $exifTool->SetNewValuesFromFile($fp, 'IPTC:Keywords>XMP-dc:Subject');
+    $exifTool->SetNewValuesFromFile($fp, 'XMP-dc:Subject<IPTC:Keywords');
 
     # add all IPTC keywords to XMP subject list
-    $exifTool->SetNewValuesFromFile($fp, 'IPTC:Keywords+>XMP-dc:Subject');
+    $exifTool->SetNewValuesFromFile($fp, 'XMP-dc:Subject+<IPTC:Keywords');
 
     # set new value from an expression involving other tags
@@ -1275,6 +1666,14 @@
 
     # copy all EXIF information, preserving the original IFD
-    # (without '>*.*' tags would be copied to the preferred EXIF IFD)
-    $exifTool->SetNewValuesFromFile($file, 'EXIF:*>*:*');
+    # (without '*.*<' tags would be copied to the preferred EXIF IFD)
+    $exifTool->SetNewValuesFromFile($file, '*:*<EXIF:*');
+
+    # copy all tags with names starting with "gps" (note: this is
+    # different than "gps:*" because it will also copy XMP GPS tags)
+    $exifTool->SetNewValuesFromFile($file, 'gps*');
+
+    # set FileName from Model, translating questionable characters
+    $exifTool->SetNewValuesFromFile($file,
+        'filename<${model; tr(/\\\\?*:|"><)(_) }.jpg');
 
 =over 4
@@ -1288,25 +1687,33 @@
 2-N) [optional] List of tag names to set or options hash references.  All
 writable tags are set if none are specified.  The tag names are not case
-sensitive, and may be prefixed by an optional family 0 or 1 group name,
-separated by a colon (ie. 'exif:iso').  A leading '-' indicates tags to be
-excluded (ie. '-comment'), or a trailing '#' causes the ValueConv value to
-be copied (same as setting the Type option to 'ValueConv' for this tag
-only).  An asterisk ('*') may be used for the tag name, and is useful when a
-group is specified to set all tags from a group (ie. 'XMP:*').  A special
-feature allows tag names of the form 'SRCTAG>DSTTAG' (or
-'DSTTAGE<lt>SRCTAG') to be specified to copy information to a tag with a
-different name or a specified group. Both 'SRCTAG' and 'DSTTAG' may use '*'
-and/or be prefixed by a group name (ie. 'modifyDate>fileModifyDate' or
-'*>xmp:*').  Copied tags may also be added or deleted from a list with
-arguments of the form 'SRCTAG+>DSTTAG' or 'SRCTAG->DSTTAG'.  Tags are
-evaluated in order, so exclusions apply only to tags included earlier in the
-list.  An extension of this feature allows the tag value to be set from an
-expression containing tag names with leading '$' symbols (ie.
-'CommentE<lt>the file is $filename').  Braces '{}' may be used around the tag
-name to separate it from subsequent text, and a '$$' is used to to represent
-a '$' symbol.  (The behaviour for missing tags in expressions is defined by
-the L</MissingTagValue> option.)  Multiple options hash references may be
-passed to set different options for different tags. Options apply to
-subsequent tags in the argument list.
+sensitive, and may be prefixed by one or more family 0, 1, 2 or 7 group
+names with optional leading family numbers, separated by colons (eg.
+'exif:iso'). A leading '-' indicates tags to be excluded (eg. '-comment'),
+or a trailing '#' causes the ValueConv value to be copied (same as setting
+the Type option to 'ValueConv' for this tag only).  Wildcards ('*' and '?')
+may be used in the tag name.  A tag name of '*' is commonly used when a
+group is specified to copy all tags in the group (eg. 'XMP:*').  A special
+feature allows tag names of the form 'DSTTAGE<lt>SRCTAG' (or
+'SRCTAGE<gt>DSTTAG') to be specified to copy information to a tag with a
+different name or a specified group.  Both 'SRCTAG' and 'DSTTAG' may contain
+wildcards and/or be prefixed by a group name (eg.
+'fileModifyDateE<lt>modifyDate' or 'xmp:*E<lt>*'), and/or suffixed by a '#'
+to disable print conversion.  Copied tags may also be added or deleted from
+a list with arguments of the form 'DSTTAG+E<lt>SRCTAG' or
+'DSTTAG-E<lt>SRCTAG'.  Tags are evaluated in order, so exclusions apply only
+to tags included earlier in the list.  An extension of this feature allows
+the tag value to be set from a string containing tag names with leading '$'
+symbols (eg. 'CommentE<lt>the file is $filename'). Braces '{}' may be used
+around the tag name to separate it from subsequent text, and a '$$' is used
+to to represent a '$' symbol.  The behaviour for missing tags in expressions
+is defined by the L</MissingTagValue> option. The tag value may be modified
+via changes to the default input variable ($_) in a Perl expression placed
+inside the braces and after a semicolon following the tag name (see the last
+example above).  A '@' may be added after the tag name (before the
+semicolon) to make the expression act on individual list items instead of
+the concatenated string for list-type tags. Braces within the expression
+must be balanced. Multiple options hash references may be passed to set
+different options for different tags. Options apply to subsequent tags in
+the argument list.
 
 By default, this routine will commute information between same-named tags in
@@ -1315,7 +1722,9 @@
 name for extracted tags (even if '*' is used as a group name), in which case
 the information is written to the original group, unless redirected to a
-different group.  When '*' is used for a group name, the family 1 group of
-the original tag is preserved.  (For example, specifying '*:*' copies all
-information while preserving the original family 1 groups.)
+different group.  When '*' is used for a group name, by default the family 1
+group of the original tag is preserved, but a different family may be
+specified with a leading family number.  (For example, specifying '*:*'
+copies all information while preserving the original family 1 groups, while
+'0*:*' preserves the family 0 group.)
 
 =item SetNewValuesFromFile Options:
@@ -1359,30 +1768,4 @@
 when copying, but the Struct option may be set to 0 to override this
 behaviour and copy as flattened tags instead.
-
-=back
-
-=head2 GetNewValues
-
-Get list of new Raw values for the specified tag.  These are the values
-that will be written to file.  Only tags which support a 'List' may return
-more than one value.
-
-    $rawVal = $exifTool->GetNewValues($tag);
-
-    @rawVals = $exifTool->GetNewValues($tag);
-
-=over 4
-
-=item Inputs:
-
-0) ExifTool object reference
-
-1) Tag name (case sensitive, may be prefixed by family 0 or 1 group name)
-
-=item Return Values:
-
-List of new Raw tag values, or first value in list when called in scalar
-context.  The list may be empty either if the tag isn't being written, or if
-it is being deleted (ie. if L</SetNewValue> was called without a value).
 
 =back
@@ -1428,5 +1811,6 @@
 =item Return Value:
 
-None.
+Count of the number of times this routine has been called (N) since the last
+time the new values were reset.
 
 =back
@@ -1452,5 +1836,6 @@
 =head2 SetFileModifyDate
 
-Set the file modification time from the new value of the FileModifyDate tag.
+Write the filesystem modification or creation time from the new value of the
+FileModifyDate or FileCreateDate tag.
 
     $exifTool->SetNewValue(FileModifyDate => '2000:01:02 03:04:05-05:00',
@@ -1468,4 +1853,6 @@
 2) [optional] Base time if applying shift (days before $^T)
 
+3) [optional] Tag to write: 'FileModifyDate' (default), or 'FileCreateDate'
+
 =item Return Value:
 
@@ -1476,8 +1863,10 @@
 
 Equivalent to, but more efficient than calling L</WriteInfo> when only the
-FileModifyDate tag has been set.  If a timezone is not specified in the
-FileModifyDate value, local time is assumed.  When shifting FileModifyDate,
-the time of the original file is used unless an optional base time is
-specified.
+FileModifyDate or FileCreateDate tag has been set.  If a timezone is not
+specified, local time is assumed.  When shifting, the time of the original
+file is used unless the optional base time is specified.
+
+The ability to write FileCreateDate is currently restricted to Windows
+systems only.
 
 =back
@@ -1485,10 +1874,11 @@
 =head2 SetFileName
 
-Set the file name and directory.  If not specified, the new file name is
-derived from the new values of the FileName and Directory tags.  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.
+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 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);
@@ -1505,12 +1895,18 @@
 2) [optional] New file name
 
+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:
 
-Will not overwrite existing files. New directories are created as necessary.
+Will not overwrite existing files. New directories are created as necessary. 
+If the file is successfully renamed, the new file name may be accessed via
+C<$$exifTool{NewName}>.
 
 =back
@@ -1522,6 +1918,7 @@
 first valid group of this list.  This has an impact only if the group is not
 specified when calling L</SetNewValue> 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');
@@ -1566,5 +1963,5 @@
 binary data block.  For some tags, such as Composite tags where there is no
 ID, an empty string is returned.  In list context, also returns a language
-code for the tag if available and different from the default language (ie.
+code for the tag if available and different from the default language (eg.
 with alternate language entries for XMP "lang-alt" tags).
 
@@ -1612,14 +2009,14 @@
 Get group name(s) for a specified tag.
 
-    # return family 0 group name (ie. 'EXIF');
+    # return family 0 group name (eg. 'EXIF');
     $group = $exifTool->GetGroup($tag, 0);
 
-    # return all groups (ie. qw{EXIF IFD0 Author Main})
+    # return all groups (eg. qw{EXIF IFD0 Author Main})
     @groups = $exifTool->GetGroup($tag);
 
-    # return groups as a string (ie. 'Main:IFD0:Author')
+    # return groups as a string (eg. 'Main:IFD0:Author')
     $group = $exifTool->GetGroup($tag, ':3:1:2');
 
-    # return groups as a simplified string (ie. 'IFD0:Author')
+    # return groups as a simplified string (eg. 'IFD0:Author')
     $group = $exifTool->GetGroup($tag, '3:1:2');
 
@@ -1647,9 +2044,12 @@
 The group family numbers are currently available:
 
-    0) Information Type             (ie. EXIF, XMP, IPTC)
-    1) Specific Location            (ie. IFD0, XMP-dc)
-    2) Category                     (ie. Author, Time)
-    3) Document Number              (ie. Main, Doc1, Doc3-2)
-    4) Instance Number              (ie. Copy1, Copy2, Copy3...)
+    0) Information Type         (eg. EXIF, XMP, IPTC)
+    1) Specific Location        (eg. IFD0, XMP-dc)
+    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)
+    7) Tag ID                   (eg. ID-271, ID-rights, ID-a9aut)
 
 Families 0 and 1 are based on the file structure, and are similar except
@@ -1675,13 +2075,32 @@
 L</ExtractEmbedded> 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. (ie. 'Doc2-3-1' is the 1st
+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</SavePath> 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</SaveFormat> option is
+used when extracting.
+
+Family 7 is used for tag ID's.  The group names are the actual tag ID's,
+with a leading "ID-" string.  Non-numerical ID's have characters other than
+[-_A-Za-z0-9] converted to hex.  Numerical tag ID's are returned in hex if
+the L</HexTagIDs> option is set, otherwise decimal is used.  When specifying
+a family 7 group name, numerical ID's may be in hex or decimal, and
+non-numerical ID's may or may not have characters other than [-_A-Za-z0-9]
+converted to hex.  Note that unlike other group names, the tag ID's of
+family 7 group names are case sensitive (but the leading "ID-" is not).
 
 See L</GetAllGroups [static]> for complete lists of group names.
@@ -1735,12 +2154,13 @@
 Tag values are calculated in alphabetical order unless a tag Require's or
 Desire's another composite tag, in which case the calculation is deferred
-until after the other tag is calculated. Composite tags may need to read
-data from the image for their value to be determined, so for these
-L</BuildCompositeTags> must be called while the image is available.  This is
-only a problem if L</ImageInfo> is called with a filename (as opposed to a
-file reference or scalar reference) since in this case the file is closed
-before L</ImageInfo> returns.  However if you enable the Composite option,
-L</BuildCompositeTags> is called from within L</ImageInfo> before the file
-is closed.
+until after the other tag is calculated.
+
+Composite tags may need to read data from the image for their value to be
+determined, and for these L</BuildCompositeTags> must be called while the
+image is available.  This is only a problem if L</ImageInfo> is called with
+a filename (as opposed to a file reference or scalar reference) since in
+this case the file is closed before L</ImageInfo> returns.  Here the
+Composite option may be used so that L</BuildCompositeTags> is called from
+within L</ImageInfo>, before the file is closed.
 
 =back
@@ -1839,5 +2259,5 @@
 =item Inputs:
 
-0) Group family number (0-4)
+0) Group family number (0-7)
 
 =item Return Values:
@@ -1853,40 +2273,52 @@
 =item Family 0 (Information Type):
 
-AFCP, AIFF, APE, APP0, APP12, APP13, APP14, APP15, APP4, APP5, APP6, APP8,
-ASF, CanonVRD, Composite, DICOM, DNG, DV, DjVu, Ducky, EXE, EXIF, ExifTool,
-FLAC, File, Flash, FlashPix, Font, FotoStation, GIF, GIMP, GeoTiff, H264,
-HTML, ICC_Profile, ID3, IPTC, ITC, JFIF, JPEG, Jpeg2000, LNK, Leaf, M2TS,
-MIE, MIFF, MNG, MPC, MPEG, MPF, MXF, MakerNotes, Matroska, Meta, PDF, PICT,
-PNG, PSP, PhotoMechanic, Photoshop, PostScript, PrintIM, QuickTime, RAF,
-RIFF, RSRC, RTF, Rawzor, Real, SVG, SigmaRaw, Stim, Vorbis, XML, XMP, ZIP
+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, 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, UserParam, VCard, Vorbis, WTV, XML, XMP, ZIP
 
 =item Family 1 (Specific Location):
 
-AC3, AFCP, AIFF, APE, ASF, AVI1, Adobe, AdobeCM, CIFF, Canon, CanonCustom,
-CanonRaw, CanonVRD, Casio, Chapter#, Composite, DICOM, DNG, DV, DjVu,
-DjVu-Meta, Ducky, EPPIM, EXE, EXIF, ExifIFD, ExifTool, FLAC, File, Flash,
-FlashPix, Font, FotoStation, FujiFilm, GE, GIF, GIMP, GPS, GeoTiff,
-GlobParamIFD, GraphConv, H264, HP, HTML, HTML-dc, HTML-ncc, HTML-office,
+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, 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#, ITC, InteropIFD, JFIF,
-JPEG, JVC, Jpeg2000, KDC_IFD, Kodak, KodakBordersIFD, KodakEffectsIFD,
-KodakIFD, KyoceraRaw, LNK, Leaf, LeafSubIFD, Leica, 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, MPC,
-MPEG, MPF0, MPImage, MXF, MakerNotes, MakerUnknown, Matroska, MetaIFD,
-Microsoft, Minolta, MinoltaRaw, NITF, Nikon, NikonCapture, NikonCustom,
-NikonScan, Olympus, PDF, PICT, PNG, PSP, Panasonic, Pentax, PhotoMechanic,
-Photoshop, PictureInfo, PostScript, PreviewIFD, PrintIM, ProfileIFD,
-QuickTime, RAF, RAF2, RIFF, RMETA, RSRC, RTF, Rawzor, Real, Real-CONT,
-Real-MDPR, Real-PROP, Real-RA3, Real-RA4, Real-RA5, Real-RJMD, Reconyx,
-Ricoh, SPIFF, SR2, SR2DataIFD, SR2SubIFD, SRF#, SVG, Samsung, Sanyo,
-Scalado, Sigma, SigmaRaw, Sony, SonyIDC, Stim, SubIFD, System, Track#,
-Version0, Vorbis, XML, XMP, XMP-DICOM, XMP-MP, XMP-MP1, XMP-PixelLive,
-XMP-acdsee, XMP-album, XMP-aux, XMP-cc, XMP-cell, XMP-crs, XMP-dc, XMP-dex,
-XMP-digiKam, XMP-exif, 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, XMP-photoshop, XMP-plus, XMP-prism, XMP-prl, XMP-pur,
+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, Lyrics3, 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, NikonSettings, 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, UserParam, 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,
+XMP-photoshop, XMP-plus, XMP-pmi, XMP-prism, XMP-prl, XMP-prm, XMP-pur,
 XMP-rdf, XMP-swf, XMP-tiff, XMP-x, XMP-xmp, XMP-xmpBJ, XMP-xmpDM, XMP-xmpMM,
 XMP-xmpNote, XMP-xmpPLUS, XMP-xmpRights, XMP-xmpTPg, ZIP
@@ -1894,6 +2326,6 @@
 =item Family 2 (Category):
 
-Audio, Author, Camera, Document, ExifTool, Image, Location, Other, Printing,
-Time, Unknown, Video
+Audio, Author, Camera, Device, Document, ExifTool, Image, Location, Other,
+Preview, Printing, Time, Unknown, Video
 
 =item Family 3 (Document Number):
@@ -1905,5 +2337,24 @@
 Copy#
 
-=back
+=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
+
+=item Family 7 (Tag ID):
+
+ID-xxx (Where xxx is the tag ID.  Numerical ID's are returned in hex with a
+leading "0x" if the HexTagIDs option is set, or decimal otherwise. 
+Characters in non-numerical ID's which are not valid in a group name are
+returned as 2 hex digits.)
+
+=back
+
+Note:  This function may also be called as an ExifTool member function to
+allow the HexTagIDs option to be set when retrieving family 7 group names.
 
 =head2 GetDeleteGroups [static]
@@ -1924,14 +2375,26 @@
 deletable group names is:
 
-AFCP, CIFF, CanonVRD, EXIF, ExifIFD, Ducky, File, FlashPix, FotoStation,
-GlobParamIFD, GPS, IFD0, IFD1, InteropIFD, ICC_Profile, IPTC, JFIF,
-MakerNotes, Meta, MetaIFD, MIE, PhotoMechanic, Photoshop, PNG, PrintIM,
-RMETA, SubIFD, Trailer, XMP
-
-All names in this list are either family 0 or family 1 group names, with the
-exception of 'Trailer' which allows all trailers in JPEG and TIFF-format
-images to be deleted at once, including unknown trailers.  To schedule a
-group for deletion, call L</SetNewValue> with an undefined value and a tag
-name like 'Trailer:*'.
+AFCP, APP0, APP1, APP10, APP11, APP12, APP13, APP14, APP15, APP2, APP3,
+APP4, APP5, APP6, APP7, APP8, APP9, Adobe, Audio, Author, CIFF, Camera,
+CanonVRD, Document, Ducky, EXIF, ExifIFD, ExifTool, File, FlashPix,
+FotoStation, GPS, GlobParamIFD, ICC_Profile, IFD0, IFD1, IPTC, Image,
+InteropIFD, JFIF, Jpeg2000, Location, MIE, MPF, MakerNotes, Meta, MetaIFD,
+NikonCapture, Other, PDF, PDF-update, PNG, PNG-pHYs, PhotoMechanic,
+Photoshop, Preview, PrintIM, Printing, RMETA, RSRC, SubIFD, Time, Trailer,
+Video, XML, XML-*, XMP, XMP-*
+
+To schedule a group for deletion, call L</SetNewValue> with a tag name like
+'EXIF:*' and an undefined tag value.
+
+Deleting a family 0 or 1 group will delete the entire corresponding block of
+metadata, but deleting a family 2 group (eg. Audio, Author, Camera, etc.)
+deletes the individual tags belonging to that category.
+
+The 'Trailer' group allows all trailers in JPEG and TIFF-format images to be
+deleted at once, including unknown trailers.  Note that the JPEG "APP"
+groups are special, and are used only to delete application segments which
+are not associated with another deletable group. For example, deleting
+'APP14:*' will delete other APP14 segments, but not the APP14 "Adobe"
+segment.
 
 =back
@@ -1950,7 +2413,8 @@
 0) [optional] File name (or just an extension)
 
-1) [optional] Flag to return a description instead of a type.  Set to 0 to
-return type for recognized but unsupported files (otherwise the return value
-for unsupported files is undef).
+1) [optional] Flag to return a description instead of a type.  Default is
+undef.  Set to 0 to also return types of recognized but unsupported files
+(otherwise the return value for unsupported files is undef), or 1 to return
+descriptions.
 
 =item Return Value:
@@ -1958,10 +2422,10 @@
 A string, based on the file extension, which indicates the basic format of
 the file.  Note that some files may be based on other formats (like many RAW
-image formats are based on TIFF).  In array context, may return more than
-one file type if the file may be based on different formats.  Returns undef
-if files with this extension are not yet supported by ExifTool.  Returns a
-list of extensions for all supported file types if no input extension is
-specified (or all recognized file types if the description flag is set to 0). 
-Returns a more detailed description of the specific file format when the
+image formats are based on TIFF).  In list context, may return more than one
+file type if the file may be based on different formats.  Returns undef if
+files with this extension are not yet supported by ExifTool.  Returns a list
+of extensions for all supported file types if no input extension is
+specified (or all recognized file types if the description flag is set to
+0). Returns a more detailed description of the specific file format when the
 description flag is set.
 
@@ -2001,6 +2465,42 @@
 =item Return Value:
 
-True if ExifTool can create files with this extension from scratch. 
-Currently, this can only be done with XMP, MIE, ICC, VRD and EXIF files.
+True if ExifTool can create files with this extension from scratch.
+Currently, this can only be done with XMP, MIE, ICC, VRD, DR4, EXV and EXIF
+files.
+
+=back
+
+=head2 AddUserDefinedTags [static]
+
+Add user-defined tags to an existing tag table at run time.  This differs
+from the usual technique of creating user-defined tags via the
+%Image::ExifTool::UserDefined hash (see the ExifTool_config file in the
+Image::ExifTool distribution) because it allows tags to be added after a tag
+table has been initialized.
+
+    use Image::ExifTool ':Public';
+    my %tags = (
+        TestTagID1 => { Name => 'TestTagName1' },
+        TestTagID2 => { Name => 'TestTagName2' },
+    );
+    my $num = AddUserDefinedTags('Image::ExifTool::PDF::Info', %tags);
+
+=over 4
+
+=item Inputs:
+
+0) Destination tag table name
+
+1-N) Pairs of tag ID / tag information hash references for the new tags
+
+=item Return Value:
+
+The number of tags added.
+
+=item Notes
+
+Pre-existing tags with the same ID will be replaced in the destination
+table. See lib/Image/ExifTool/README in the full distribution for full
+details on the elements of the tag information hash.
 
 =back
@@ -2009,29 +2509,83 @@
 
 Certain meta information formats allow coded character sets other than plain
-ASCII.  When reading, 8-bit encodings are passed straight through ExifTool
-without re-coding unless specified otherwise below, and multi-byte encodings
-are converted according to the L</Charset> option ('UTF8' by default).  When
-writing, the inverse conversions are performed.  See the L</Charset> option
-for a list of valid character sets.
+ASCII.  When reading, most known encodings are converted to the external
+character set according to the L</Charset> option, or to UTF-8 by default.
+When writing, the inverse conversions are performed.  Alternatively, special
+characters may be converted to/from HTML character entities with the
+L</Escape> HTML option.
+
+A distinction is made between the external character set visible via the
+ExifTool API, and the internal character used to store text in the metadata
+of a file.  These character sets may be specified separately as follows:
+
+=over 4
+
+=item External Character Sets:
+
+The encoding for tag values passed to/from ExifTool API functions is set via
+the L</Charset> option, which is 'UTF8' by default.
+
+The encoding of file names is specified via the L</CharsetFileName> option.
+By default, L</CharsetFileName> is not defined, and file names passed to
+ExifTool are used directly in calls to the system i/o routines (which expect
+UTF-8 strings on Mac/Linux, but default to the system code page on Windows).
+In this mode on Windows a warning is issued if a file name contains special
+characters, but this warning may be avoided by setting L</CharsetFileName>
+to an empty string.  Setting L</CharsetFileName> to any other value causes
+file names to be converted from the specified encoding to one appropriate
+for the system.  In Windows this also has the effect of activating Unicode
+filename support via the special Windows wide-character i/o routines if
+Win32API::File is available.
+
+=item Internal Character Sets:
+
+The encodings used to store strings in the various metadata formats.  These
+encodings may be changed for certain types of metadata via the
+L</CharsetEXIF>, L</CharsetID3>, L</CharsetIPTC>, L</CharsetPhotoshop>,
+L</CharsetQuickTime> and L</CharsetRIFF> options.
+
+=back
+
+Values are returned as byte strings of encoded characters.  Perl wide
+characters are not used.  By default, most returned strings are encoded in
+UTF-8.  For these, Encode::decode_utf8() may be used to convert to a
+sequence of logical Perl characters.  Note that some settings of the
+PERL_UNICODE environment variable may be incompatible with ExifTool's
+character handling.
 
 More specific details are given below about how character coding is handled
-for EXIF, IPTC, XMP, PNG, ID3, PDF and MIE information:
+for EXIF, IPTC, XMP, PNG, ID3, PDF, Photoshop, QuickTime, AIFF, MIE and
+Vorbis information:
 
 =head2 EXIF
 
-Most textual information in EXIF is stored in ASCII format, and ExifTool
-does not convert these tags.  However it is not uncommon for applications to
-write UTF-8 or other encodings where ASCII is expected, and ExifTool will
-quite happily read/write any encoding without conversion.  For a few EXIF
-tags (UserComment, GPSProcessingMethod and GPSAreaInformation) the stored
-text may be encoded either in ASCII, Unicode (UCS-2) or JIS.  When reading
-these tags, Unicode and JIS are converted to the character set specified by
-the L</Charset> option.  Other encodings are not converted.  When writing,
+Most textual information in EXIF is stored in ASCII format (called "string"
+in the L<ExifTool tag name documentation|Image::ExifTool::TagNames>). By
+default ExifTool does not convert these strings.  However, it is not
+uncommon for applications to write UTF-8 or other encodings where ASCII is
+expected.  To deal with these, ExifTool allows the internal EXIF string
+encoding to be specified with L</CharsetEXIF>, which causes EXIF string
+values to be converted from the specified character set when reading, and
+stored with this character set when writing.  (The MWG recommends using
+UTF-8 encoding for EXIF strings, and in keeping with this the
+L<MWG|Image::ExifTool::MWG> module sets the default internal EXIF string
+encoding to UTF-8, but note that this will have no effect unless the
+external encoding is also set to something other than the default of UTF-8.)
+
+A few EXIF tags (UserComment, GPSProcessingMethod and GPSAreaInformation)
+support a designated internal text encoding, with values stored as ASCII,
+Unicode (UCS-2) or JIS.  When reading these tags, ExifTool converts Unicode
+and JIS to the external character set specified by the L</Charset>
+option, or to UTF-8 by default.  ASCII text is not converted. When writing,
 text is stored as ASCII unless the string contains special characters, in
-which case it is converted from the specified character set and stored as
-Unicode.  ExifTool writes Unicode in native EXIF byte ordering by default,
-but this may be changed by setting the ExifUnicodeByteOrder tag.  The EXIF
-"XP" tags (XPTitle, XPComment, etc) are always stored as little-endian
-Unicode, and are read and written using the specified character set.
+which case it is converted from the external character set (UTF-8 by
+default), and stored as Unicode. ExifTool writes Unicode in native EXIF byte
+ordering by default, but the byte order may be specified by setting the
+ExifUnicodeByteOrder tag (see the
+L<Extra Tags documentation|Image::ExifTool::TagNames/Extra Tags>).
+
+The EXIF "XP" tags (XPTitle, XPComment, etc) are always stored as
+little-endian Unicode (UCS-2), and are read and written using the specified
+character set.
 
 =head2 IPTC
@@ -2047,10 +2601,39 @@
 character sets are the same.  Note that ISO 2022 character set shifting is
 not supported.  Instead, a warning is issued and the string is not converted
-if an ISO 2022 shift code is found.  See L<http://www.iptc.org/IIM/> for the
-official IPTC specification.
+if an ISO 2022 shift code is encountered.  See L<http://www.iptc.org/IIM/>
+for the official IPTC specification.
+
+ExifTool may be used to convert IPTC values to a different internal
+encoding.  To do this, all IPTC tags must be rewritten along with the
+desired value of CodedCharacterSet.  For example, the following command
+changes the internal IPTC encoding to UTF-8 (from Windows Latin1 unless
+CodedCharacterSet was already 'UTF8'):
+
+  exiftool -tagsfromfile @ -iptc:all -codedcharacterset=utf8 a.jpg
+
+or from Windows Latin2 (cp1250) to UTF-8:
+
+  exiftool -tagsfromfile @ -iptc:all -codedcharacterset=utf8 \
+  -charset iptc=latin2 a.jpg
+
+and this command changes it back from UTF-8 to Windows Latin1 (cp1252):
+
+  exiftool -tagsfromfile @ -iptc:all -codedcharacterset= a.jpg
+
+or to Windows Latin2:
+
+  exiftool -tagsfromfile @ -iptc:all -codedcharacterset= \
+  -charset iptc=latin2 a.jpg
+
+Unless CodedCharacterSet is 'UTF8', applications have no reliable way to
+determine the IPTC character encoding.  For this reason, it is recommended
+that CodedCharacterSet be set to 'UTF8' when creating new IPTC.
+
+(Note: Here, "IPTC" Refers to the older IPTC IIM format.  The more recent
+IPTC Core and Extension specifications actually use the XMP format.)
 
 =head2 XMP
 
-Exiftool reads XMP encoded as UTF-8, UTF-16 or UTF-32, and converts them all
+ExifTool reads XMP encoded as UTF-8, UTF-16 or UTF-32, and converts them all
 to UTF-8 internally.  Also, all XML character entity references and numeric
 character references are converted.  When writing, ExifTool always encodes
@@ -2058,5 +2641,5 @@
 references: E<amp> E<lt> E<gt> E<39> E<quot>.  By default no further
 conversion is performed, however if the L</Charset> option is other than
-'UTF8' then text is converted to/from a specified character set when
+'UTF8' then text is converted to/from the specified character set when
 reading/writing.
 
@@ -2072,4 +2655,9 @@
 text is converted from the specified character set and stored as UTF-8.
 
+=head2 JPEG Comment
+
+The encoding for the JPEG Comment (COM segment) is not specified, so
+ExifTool reads/writes this text without conversion.
+
 =head2 ID3
 
@@ -2077,9 +2665,9 @@
 subset of Windows Latin1), although some applications may incorrectly use
 other character sets.  By default ExifTool converts ID3v1 text from Latin to
-the character set specified by the </Charset> option.  However, the internal
-ID3v1 charset may be specified with the L</CharsetID3> option.  The encoding
-for ID3v2 information is stored in the file, so ExifTool converts ID3v2 text
-from this encoding to the character set specified by the L</Charset> option.
-ExifTool does not currently write ID3 information.
+the character set specified by the L</Charset> option.  However, the
+internal ID3v1 charset may be specified with the L</CharsetID3> option.  The
+encoding for ID3v2 information is stored in the file, so ExifTool converts
+ID3v2 text from this encoding to the character set specified by the
+L</Charset> option. ExifTool does not currently write ID3 information.
 
 =head2 PDF
@@ -2090,4 +2678,30 @@
 encodes input text from the specified character set as Unicode only if the
 string contains special characters, otherwise PDFDocEncoding is used.
+
+=head2 Photoshop
+
+Some Photoshop resource names are stored as Pascal strings with unknown
+encoding.  By default, ExifTool assumes MacRoman encoding and converts this
+to UTF-8, but the internal and external character sets may be specified with
+the L</CharsetPhotoshop> and L</Charset> options respectively.
+
+=head2 QuickTime
+
+QuickTime text strings may be stored in a variety of poorly document
+formats. ExifTool does its best to decode these according to the L</Charset>
+option setting.  For some QuickTime strings, ExifTool assumes a default
+encoding of MacRoman, but this may be changed with the L</CharsetQuickTime>
+option.
+
+=head2 AIFF
+
+AIFF strings are assumed to be stored in MacRoman, and are converted
+according to the L</Charset> option when reading.
+
+=head2 RIFF
+
+The internal encoding of RIFF strings (eg. in AVI and WAV files) is assumed
+to be Latin unless otherwise specified by the RIFF CSET chunk or the
+L</CharsetRIFF> option.
 
 =head2 MIE
@@ -2100,7 +2714,12 @@
 are stored as ISO 8859-1.
 
+=head2 Vorbis
+
+Vorbis comments are stored as UTF-8, and are converted to the character set
+specified by the L</Charset> option.
+
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey
+Copyright 2003-2021, Phil Harvey
 
 This library is free software; you can redistribute it and/or modify it
@@ -2120,5 +2739,5 @@
 L<Image::ExifTool::TagNames(3pm)|Image::ExifTool::TagNames>,
 L<Image::ExifTool::Shortcuts(3pm)|Image::ExifTool::Shortcuts>,
-L<Image::ExifTool::Shift.pl|Image::ExifTool::Shift.pl>,
+L<Image::ExifTool::Shift(3pm)|Image::ExifTool::Shift.pl>,
 L<Image::Info(3pm)|Image::Info>,
 L<Image::MetaData::JPEG(3pm)|Image::MetaData::JPEG>
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AES.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AES.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AES.pm	(revision 34921)
@@ -103,5 +103,5 @@
     # temporary variables (all unsigned characters)
     my ($i,@temp);
-    
+
     # The first round key is the key itself.
     for ($i=0; $i<$nk; ++$i) {
@@ -336,5 +336,5 @@
 #         3) flag to disable padding
 # Returns: error string, or undef on success
-# Notes: encrypts/decrypts data in place
+# Notes: encrypts/decrypts data in place (encrypted data returned with leading IV)
 sub Crypt($$;$$)
 {
@@ -478,5 +478,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AFCP.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AFCP.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AFCP.pm	(revision 34921)
@@ -6,5 +6,5 @@
 # Revisions:    12/26/2005 - P. Harvey Created
 #
-# References:   1) http://www.tocarte.com/media/axs_afcp_spec.pdf
+# References:   1) http://web.archive.org/web/20080828211305/http://www.tocarte.com/media/axs_afcp_spec.pdf
 #------------------------------------------------------------------------------
 
@@ -15,5 +15,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.04';
+$VERSION = '1.08';
 
 sub ProcessAFCP($$);
@@ -29,4 +29,8 @@
 ExifTool will read and write (but not create) AFCP IPTC information in JPEG
 and TIFF images.
+
+See
+L<http://web.archive.org/web/20080828211305/http://www.tocarte.com/media/axs_afcp_spec.pdf>
+for the AFCP specification.
     },
     IPTC => { SubDirectory => { TagTable => 'Image::ExifTool::IPTC::Main' } },
@@ -34,4 +38,5 @@
     Nail => {
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
         # (the specification allows for a variable amount of padding before
         #  the image after a 10-byte header, so look for the JPEG SOI marker,
@@ -46,4 +51,5 @@
     PrVw => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         RawConv => q{
             pos($val) = 10;
@@ -66,5 +72,5 @@
 sub ProcessAFCP($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $curPos = $raf->Tell();
@@ -116,12 +122,12 @@
 
         $rtnVal = 1;
-        my $verbose = $exifTool->Options('Verbose');
-        my $out = $exifTool->Options('TextOut');
+        my $verbose = $et->Options('Verbose');
+        my $out = $et->Options('TextOut');
         my $outfile = $$dirInfo{OutFile};
         if ($outfile) {
             # allow all AFCP information to be deleted
-            if ($exifTool->{DEL_GROUP}->{AFCP}) {
+            if ($$et{DEL_GROUP}{AFCP}) {
                 $verbose and print $out "  Deleting AFCP\n";
-                ++$exifTool->{CHANGED};
+                ++$$et{CHANGED};
                 last;
             }
@@ -132,5 +138,5 @@
             $vers = substr($buff, 4, 2); # get version number
         } else {
-            $exifTool->DumpTrailer($dirInfo) if $verbose or $exifTool->{HTML_DUMP};
+            $et->DumpTrailer($dirInfo) if $verbose or $$et{HTML_DUMP};
         }
         # read AFCP directory data
@@ -138,5 +144,5 @@
         my $dir;
         unless ($raf->Read($dir, 12 * $numEntries) == 12 * $numEntries) {
-            $exifTool->Error('Error reading AFCP directory', 1);
+            $et->Error('Error reading AFCP directory', 1);
             last;
         }
@@ -144,12 +150,7 @@
             my $dat = $buff . $dir;
             print $out "  AFCP Directory:\n";
-            Image::ExifTool::HexDump(\$dat, undef,
-                Addr   => $$dirInfo{DataPos},
-                Width  => 12,
-                Prefix => $exifTool->{INDENT},
-                Out => $out,
-            );
-        }
-        $fix and $exifTool->Warn("Adjusted AFCP offsets by $fix", 1);
+            $et->VerboseDump(\$dat, Addr => $$dirInfo{DataPos}, Width  => 12);
+        }
+        $fix and $et->Warn("Adjusted AFCP offsets by $fix", 1);
 #
 # process AFCP directory
@@ -168,5 +169,5 @@
                 if ($outfile) {
                     # rewrite this information
-                    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+                    my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
                     if ($tagInfo and $$tagInfo{SubDirectory}) {
                         my %subdirInfo = (
@@ -178,5 +179,5 @@
                         );
                         my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
-                        my $newDir = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                        my $newDir = $et->WriteDirectory(\%subdirInfo, $subTable);
                         if (defined $newDir) {
                             $size = length $newDir;
@@ -189,5 +190,5 @@
                 } else {
                     # extract information
-                    $exifTool->HandleTag($tagTablePtr, $tag, $buff,
+                    $et->HandleTag($tagTablePtr, $tag, $buff,
                         DataPt => \$buff,
                         Size => $size,
@@ -197,5 +198,5 @@
                 }
             } else {
-                $exifTool->Warn("Bad AFCP directory");
+                $et->Warn("Bad AFCP directory");
                 $rtnVal = -1 if $outfile;
                 last;
@@ -259,5 +260,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AIFF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AIFF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/AIFF.pm	(revision 34921)
@@ -19,5 +19,5 @@
 use Image::ExifTool::ID3;
 
-$VERSION = '1.03';
+$VERSION = '1.11';
 
 # information for time/date-based tags (time zero is Jan 1, 1904)
@@ -31,5 +31,9 @@
 %Image::ExifTool::AIFF::Main = (
     GROUPS => { 2 => 'Audio' },
-    NOTES => 'Only the tags decoded by ExifTool are listed in this table.',
+    NOTES => q{
+        Tags extracted from Audio Interchange File Format (AIFF) files.  See
+        L<http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html> for
+        the AIFF specification.
+    },
 #    FORM => 'Format',
     FVER => {
@@ -45,8 +49,22 @@
         SubDirectory => { TagTable => 'Image::ExifTool::AIFF::Comment' },
     },
-    NAME => 'Name',
-    AUTH => { Name => 'Author', Groups => { 2 => 'Author' } },
-   '(c) ' => { Name => 'Copyright', Groups => { 2 => 'Author' } },
-    ANNO => 'Annotation',
+    NAME => {
+        Name => 'Name',
+        ValueConv => '$self->Decode($val, "MacRoman")',
+    },
+    AUTH => {
+        Name => 'Author',
+        Groups => { 2 => 'Author' },
+        ValueConv => '$self->Decode($val, "MacRoman")',
+    },
+   '(c) ' => {
+        Name => 'Copyright',
+        Groups => { 2 => 'Author' },
+        ValueConv => '$self->Decode($val, "MacRoman")',
+    },
+    ANNO => {
+        Name => 'Annotation',
+        ValueConv => '$self->Decode($val, "MacRoman")',
+    },
    'ID3 ' => {
         Name => 'ID3',
@@ -56,4 +74,5 @@
         },
     },
+    APPL => 'ApplicationData', # (first 4 bytes are the application signature)
 #    SSND => 'SoundData',
 #    MARK => 'Marker',
@@ -61,5 +80,4 @@
 #    MIDI => 'MidiData',
 #    AESD => 'AudioRecording',
-#    APPL => 'ApplicationSpecific',
 );
 
@@ -82,5 +100,18 @@
             MAC6 => 'MAC 6-to-1',
             sowt => 'Little-endian, no compression',
+            alaw => 'a-law',
+            ALAW => 'A-law',
+            ulaw => 'mu-law',
+            ULAW => 'Mu-law',
+           'GSM '=> 'GSM',
+            G722 => 'G722',
+            G726 => 'G726',
+            G728 => 'G728',
         },
+    },
+    11 => { #PH
+        Name => 'CompressorName',
+        Format => 'pstring',
+        ValueConv => '$self->Decode($val, "MacRoman")',
     },
 );
@@ -97,6 +128,24 @@
     0 => { Name => 'CommentTime', %timeInfo },
     1 => 'MarkerID',
-    2 => 'Comment',
-);
+    2 => {
+        Name => 'Comment',
+        ValueConv => '$self->Decode($val, "MacRoman")',
+    },
+);
+
+%Image::ExifTool::AIFF::Composite = (
+    Duration => {
+        Require => {
+            0 => 'AIFF:SampleRate',
+            1 => 'AIFF:NumSampleFrames',
+        },
+        RawConv => '($val[0] and $val[1]) ? $val[1] / $val[0] : undef',
+        PrintConv => 'ConvertDuration($val)',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::AIFF');
+
 
 #------------------------------------------------------------------------------
@@ -106,22 +155,22 @@
 sub ProcessComment($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     return 0 unless $dirLen > 2;
     my $numComments = unpack('n',$$dataPt);
     my $pos = 2;
     my $i;
-    $verbose and $exifTool->VerboseDir('Comment', $numComments);
+    $verbose and $et->VerboseDir('Comment', $numComments);
     for ($i=0; $i<$numComments; ++$i) {
         last if $pos + 8 > $dirLen;
         my ($time, $markerID, $size) = unpack("x${pos}Nnn", $$dataPt);
-        $exifTool->HandleTag($tagTablePtr, 0, $time);
-        $exifTool->HandleTag($tagTablePtr, 1, $markerID) if $markerID;
+        $et->HandleTag($tagTablePtr, 0, $time);
+        $et->HandleTag($tagTablePtr, 1, $markerID) if $markerID;
         $pos += 8;
         last if $pos + $size > $dirLen;
         my $val = substr($$dataPt, $pos, $size);
-        $exifTool->HandleTag($tagTablePtr, 2, $val);
+        $et->HandleTag($tagTablePtr, 2, $val);
         ++$size if $size & 0x01;    # account for padding byte if necessary
         $pos += $size;
@@ -135,10 +184,11 @@
 sub ProcessAIFF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    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;
+    my $fast3 = $$et{OPTIONS}{FastScan} && $$et{OPTIONS}{FastScan} == 3;
     my $pos = 12;
     # check for DjVu image
@@ -150,32 +200,45 @@
         $pos += 4;
         $buff = substr($buff, 4) . $buf2;
+        $et->SetFileType('DJVU');
+        return 1 if $fast3;
         $tagTablePtr = GetTagTable('Image::ExifTool::DjVu::Main');
-        $exifTool->SetFileType('DJVU');
-        # modifiy FileType to indicate a multi-page document
-        $exifTool->{VALUE}->{FileType} .= " (multi-page)" if $buf2 eq 'DJVM';
+        # modify FileType to indicate a multi-page document
+        $$et{VALUE}{FileType} .= " (multi-page)" if $buf2 eq 'DJVM';
         $type = 'DjVu';
     } else {
         return 0 unless $buff =~ /^FORM....(AIF(F|C))/s;
-        $exifTool->SetFileType($1);
+        $et->SetFileType($1);
+        return 1 if $fast3;
         $tagTablePtr = GetTagTable('Image::ExifTool::AIFF::Main');
         $type = 'AIFF';
     }
     SetByteOrder('MM');
+    my $verbose = $et->Options('Verbose');
 #
 # 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 = $exifTool->GetTagInfo($tagTablePtr, $tag);
-        $exifTool->VPrint(0, "AIFF '$tag' chunk ($len bytes of data):\n");
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        $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;
                 $page = ($page || 0) + 1;
-                $exifTool->VPrint(0, $exifTool->{INDENT} . "Page $page:\n");
+                $et->VPrint(0, $$et{INDENT} . "Page $page:\n");
             }
             $raf->Read($buff, $len2) >= $len or $err=1, last;
@@ -183,5 +246,5 @@
                 $buff =~ s/\0+$//;  # remove trailing nulls
             }
-            $exifTool->HandleTag($tagTablePtr, $tag, $buff,
+            $et->HandleTag($tagTablePtr, $tag, $buff,
                 DataPt => \$buff,
                 DataPos => $pos,
@@ -189,10 +252,18 @@
                 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);
         } else {
             $raf->Seek($len2, 1) or $err=1, last;
         }
         $pos += $len2;
+        $n = 0;
     }
-    $err and $exifTool->Warn("Error reading $type file (corrupted?)");
+    $err and $et->Warn("Error reading $type file (corrupted?)");
     return 1;
 }
@@ -217,5 +288,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APE.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APE.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APE.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.01';
+$VERSION = '1.06';
 
 # APE metadata blocks
@@ -24,5 +24,6 @@
         Tags found in Monkey's Audio (APE) information.  Only a few common tags are
         listed below, but ExifTool will extract any tag found.  ExifTool supports
-        APEv1 and APEv2 tags, as well as ID3 information in APE files.
+        APEv1 and APEv2 tags, as well as ID3 information in APE files, and will also
+        read APE metadata from MP3 and MPC files.
     },
     Album   => { },
@@ -32,4 +33,9 @@
     Track   => { },
     Year    => { },
+    DURATION => {
+        Name => 'Duration',
+        ValueConv => '$val += 4294967296 if $val < 0 and $val >= -2147483648; $val * 1e-7',
+        PrintConv => 'ConvertDuration($val)',
+    },
     'Tool Version' => { Name => 'ToolVersion' },
     'Tool Name'    => { Name => 'ToolName' },
@@ -72,4 +78,22 @@
 );
 
+# APE Composite tags
+%Image::ExifTool::APE::Composite = (
+    GROUPS => { 2 => 'Audio' },
+    Duration => {
+        Require => {
+            0 => 'APE:SampleRate',
+            1 => 'APE:TotalFrames',
+            2 => 'APE:BlocksPerFrame',
+            3 => 'APE:FinalFrameBlocks',
+        },
+        RawConv => '($val[0] && $val[1]) ? (($val[1] - 1) * $val[2] + $val[3]) / $val[0]: undef',
+        PrintConv => 'ConvertDuration($val)',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::APE');
+
 #------------------------------------------------------------------------------
 # Make tag info hash for specified tag
@@ -83,5 +107,7 @@
     $name =~ s/[^\w-]+(.?)/\U$1/sg;
     $name =~ s/([a-z0-9])_([a-z])/$1\U$2/g;
-    Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
+    my %tagInfo = ( Name => $name );
+    $tagInfo{Groups} = { 2 => 'Preview' } if $tag =~ /^Cover Art/ and $tag !~ /Desc$/;
+    AddTagToTable($tagTablePtr, $tag, \%tagInfo);
 }
 
@@ -93,21 +119,23 @@
 sub ProcessAPE($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
 
     # must first check for leading/trailing ID3 information
-    unless ($exifTool->{DoneID3}) {
+    unless ($$et{DoneID3}) {
         require Image::ExifTool::ID3;
-        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
+        Image::ExifTool::ID3::ProcessID3($et, $dirInfo) and return 1;
     }
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
-    my ($buff, $i, $header, $tagTablePtr, $dataPos);
+    my $verbose = $et->Options('Verbose');
+    my ($buff, $i, $header, $tagTablePtr, $dataPos, $oldIndent);
+
+    $$et{DoneAPE} = 1;
 
     # check APE signature and process audio information
     # unless this is some other type of file
-    unless ($exifTool->{VALUE}->{FileType}) {
+    unless ($$et{VALUE}{FileType}) {
         $raf->Read($buff, 32) == 32 or return 0;
         $buff =~ /^(MAC |APETAGEX)/ or return 0;
-        $exifTool->SetFileType();
+        $et->SetFileType();
         SetByteOrder('II');
 
@@ -131,5 +159,5 @@
                 }
             }
-            $exifTool->ProcessDirectory( { DataPt => \$buff }, $table) if $table;
+            $et->ProcessDirectory( { DataPt => \$buff }, $table) if $table;
         }
     }
@@ -139,5 +167,5 @@
         my $footPos = -32;
         # (...but before the ID3v1 trailer if it exists)
-        $footPos -= 128 if $exifTool->{DoneID3} == 2;
+        $footPos -= $$et{DoneID3} if $$et{DoneID3} > 1;
         $raf->Seek($footPos, 2)     or return 1;
         $raf->Read($buff, 32) == 32 or return 1;
@@ -156,6 +184,8 @@
     {
         if ($verbose) {
-            $exifTool->VerboseDir("APEv$version", $count, $size);
-            $exifTool->VerboseDump(\$buff, DataPos => $raf->Tell() - $size);
+            $oldIndent = $$et{INDENT};
+            $$et{INDENT} .= '| ';
+            $et->VerboseDir("APEv$version", $count, $size);
+            $et->VerboseDump(\$buff, DataPos => $raf->Tell() - $size);
         }
         $tagTablePtr = GetTagTable('Image::ExifTool::APE::Main');
@@ -176,4 +206,6 @@
         last unless $buff =~ /\G(.*?)\0/sg;
         my $tag = $1;
+        # avoid conflicts with our special table entries
+        $tag .= '.' if $Image::ExifTool::specialTags{$tag};
         $pos = pos($buff);
         last if $pos + $len > $size;
@@ -191,9 +223,9 @@
                     my $v = $1;
                     MakeTag($t, $tagTablePtr) unless $$tagTablePtr{$t};
-                    $exifTool->HandleTag($tagTablePtr, $t, $v);
+                    $et->HandleTag($tagTablePtr, $t, $v);
                 }
             }
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $et->HandleTag($tagTablePtr, $tag, $val,
             Index => $i,
             DataPt => \$buff,
@@ -204,5 +236,6 @@
         $pos += $len;
     }
-    $i == $count or $exifTool->Warn('Bad APE trailer');
+    $i == $count or $et->Warn('Bad APE trailer');
+    $$et{INDENT} = $oldIndent if defined $oldIndent;
     return 1;
 }
@@ -231,5 +264,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APP12.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APP12.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/APP12.pm	(revision 34921)
@@ -13,7 +13,7 @@
 use strict;
 use vars qw($VERSION);
-use Image::ExifTool qw(:DataAccess);
-
-$VERSION = '1.08';
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.13';
 
 sub ProcessAPP12($$$);
@@ -25,4 +25,5 @@
     PROCESS_PROC => \&ProcessAPP12,
     GROUPS => { 0 => 'APP12', 1 => 'PictureInfo', 2 => 'Image' },
+    PRIORITY => 0,
     NOTES => q{
         The JPEG APP12 "Picture Info" segment was used by some older cameras, and
@@ -134,9 +135,9 @@
 sub WriteDucky($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart};
-    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+    my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
     my @addTags = sort { $a <=> $b } keys(%$newTags);
     my ($dirEnd, %doneTags);
@@ -158,5 +159,5 @@
             $pos += 4;
             if ($pos + $len > $dirEnd) {
-                $exifTool->Warn('Invalid Ducky block length');
+                $et->Warn('Invalid Ducky block length');
                 return undef;
             }
@@ -171,20 +172,20 @@
         my $tagInfo = $$newTags{$tag};
         if ($tagInfo) {
-            my $nvHash = $exifTool->GetNewValueHash($tagInfo);
+            my $nvHash = $et->GetNewValueHash($tagInfo);
             my $isNew;
             if (defined $val) {
-                if (Image::ExifTool::IsOverwriting($nvHash, $val)) {
-                    $exifTool->VerboseValue("- Ducky:$$tagInfo{Name}", $val);
+                if ($et->IsOverwriting($nvHash, $val)) {
+                    $et->VerboseValue("- Ducky:$$tagInfo{Name}", $val);
                     $isNew = 1;
                 }
             } else {
-                next unless Image::ExifTool::IsCreating($nvHash);
+                next unless $$nvHash{IsCreating};
                 $isNew = 1;
             }
             if ($isNew) {
-                $val = Image::ExifTool::GetNewValues($nvHash);
-                ++$exifTool->{CHANGED};
+                $val = $et->GetNewValue($nvHash);
+                ++$$et{CHANGED};
                 next unless defined $val;   # next if tag is being deleted
-                $exifTool->VerboseValue("+ Ducky:$$tagInfo{Name}", $val);
+                $et->VerboseValue("+ Ducky:$$tagInfo{Name}", $val);
             }
         }
@@ -207,5 +208,5 @@
 sub ProcessDucky($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart};
@@ -219,9 +220,9 @@
         $pos += 4;
         if ($pos + $len > $dirEnd) {
-            $exifTool->Warn('Invalid Ducky block length');
+            $et->Warn('Invalid Ducky block length');
             last;
         }
         my $val = substr($$dataPt, $pos, $len);
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $et->HandleTag($tagTablePtr, $tag, $val,
             DataPt => $dataPt,
             DataPos => $$dirInfo{DataPos},
@@ -240,5 +241,5 @@
 sub ProcessAPP12($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart} || 0;
@@ -250,5 +251,5 @@
         pos($$dataPt) = $$dirInfo{DirStart};
     }
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $success = 0;
     my $section = '';
@@ -256,5 +257,5 @@
 
     # this regular expression is a bit complex, but basically we are looking for
-    # section headers (ie. "[Camera Info]") and tag/value pairs (ie. "tag=value",
+    # section headers (eg. "[Camera Info]") and tag/value pairs (eg. "tag=value",
     # where "value" may contain white space), separated by spaces or CR/LF.
     # (APP12 uses CR/LF, but Olympus TextualInfo is similar and uses spaces)
@@ -263,14 +264,14 @@
         # was this a section name?
         if ($token =~ /^\[(.*)\]/) {
-            $exifTool->VerboseDir($1) if $verbose;
+            $et->VerboseDir($1) if $verbose;
             $section = ($token =~ /\[(\S+) ?Info\]/i) ? $1 : '';
             $success = 1;
             next;
         }
-        $exifTool->VerboseDir($$dirInfo{DirName}) if $verbose and not $success;
+        $et->VerboseDir($$dirInfo{DirName}) if $verbose and not $success;
         $success = 1;
         my ($tag, $val) = ($token =~ /(\S+)=(.+)/);
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
-        $verbose and $exifTool->VerboseInfo($tag, $tagInfo, Value => $val);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        $verbose and $et->VerboseInfo($tag, $tagInfo, Value => $val);
         unless ($tagInfo) {
             # add new tag to table
@@ -278,7 +279,7 @@
             # put in Camera group if information in "Camera" section
             $$tagInfo{Groups} = { 2 => 'Camera' } if $section =~ /camera/i;
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
-        }
-        $exifTool->FoundTag($tagInfo, $val);
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        $et->FoundTag($tagInfo, $val);
     }
     return $success;
@@ -305,5 +306,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ASF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ASF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ASF.pm	(revision 34921)
@@ -18,8 +18,10 @@
 use Image::ExifTool::RIFF;
 
-$VERSION = '1.17';
-
+$VERSION = '1.25';
+
+sub ProcessASF($$;$);
+sub ProcessContentDescription($$$);
+sub ProcessExtendedContentDescription($$$);
 sub ProcessMetadata($$$);
-sub ProcessContentDescription($$$);
 sub ProcessPicture($$$);
 sub ProcessCodecList($$$);
@@ -63,5 +65,5 @@
 # ASF top level objects
 %Image::ExifTool::ASF::Main = (
-    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessASF,
+    PROCESS_PROC => \&ProcessASF,
     NOTES => q{
         The ASF format is used by Windows WMA and WMV files, and DIVX videos.  Tag
@@ -86,5 +88,5 @@
 # ASF header objects
 %Image::ExifTool::ASF::Header = (
-    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessASF,
+    PROCESS_PROC => \&ProcessASF,
     '8CABDCA1-A947-11CF-8EE4-00C00C205365' => {
         Name => 'FileProperties',
@@ -130,5 +132,5 @@
     GROUPS => { 2 => 'Video' },
     0 => 'Title',
-    1 => { Name => 'Author', Groups => { 2 => 'Author' } },
+    1 => { Name => 'Author',    Groups => { 2 => 'Author' } },
     2 => { Name => 'Copyright', Groups => { 2 => 'Author' } },
     3 => 'Description',
@@ -148,9 +150,12 @@
         },
     },
-    1 => { Name => 'BannerImage', Binary => 1 },
+    1 => { Name => 'BannerImage', Groups => { 2 => 'Preview' }, Binary => 1 },
     2 => 'BannerImageURL',
     3 => 'CopyrightURL',
 );
 
+# Note: Many of these tags are similar to those in Image::ExifTool::Microsoft::Xtra
+#       and Image::ExifTool::WTV::Metadata
+# (tags in this table may have a leading "WM/" removed)
 %Image::ExifTool::ASF::ExtendedDescr = (
     PROCESS_PROC => \&ProcessExtendedContentDescription,
@@ -237,5 +242,5 @@
     EncodedBy => {},
     EncodingSettings => {},
-    EncodingTime => { Groups => { 2 => 'Time' } },
+    EncodingTime => { Groups => { 2 => 'Time' }, PrintConv => '$self->ConvertDateTime($val)' },
     Genre => {},
     GenreID => {},
@@ -246,6 +251,6 @@
     Lyrics_Synchronised => {},
     MCDI => {},
-    MediaClassPrimaryID => {},
-    MediaClassSecondaryID => {},
+    MediaClassPrimaryID => { ValueConv => 'Image::ExifTool::ASF::GetGUID($val)' },
+    MediaClassSecondaryID => { ValueConv => 'Image::ExifTool::ASF::GetGUID($val)' },
     MediaCredits => {},
     MediaIsDelay => {},
@@ -259,5 +264,9 @@
     MediaIsTape => {},
     MediaNetworkAffiliation => {},
-    MediaOriginalBroadcastDateTime => { Groups => { 2 => 'Time' } },
+    MediaOriginalBroadcastDateTime => {
+        Groups => { 2 => 'Time' },
+        ValueConv => '$val=~tr/-T/: /; $val',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
     MediaOriginalChannel => {},
     MediaStationCallSign => {},
@@ -267,7 +276,11 @@
     OriginalAlbumTitle => {},
     OriginalArtist => {},
-    OriginalFilename => {},
+    OriginalFilename => 'OriginalFileName',
     OriginalLyricist => {},
-    OriginalReleaseTime => { Groups => { 2 => 'Time' } },
+    OriginalReleaseTime => {
+        Groups => { 2 => 'Time' },
+        ValueConv => '$val=~tr/-T/: /; $val',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
     OriginalReleaseYear => { Groups => { 2 => 'Time' } },
     ParentalRating => {},
@@ -295,6 +308,6 @@
     StreamTypeInfo => {},
     SubscriptionContentID => {},
-    SubTitle => {},
-    SubTitleDescription => {},
+    SubTitle            => 'Subtitle',
+    SubTitleDescription => 'SubtitleDescription',
     Text => {},
     ToolName => {},
@@ -316,5 +329,5 @@
     WMContentID => {},
     Writer => { Groups => { 2 => 'Author' } },
-    Year => { Groups => { 2 => 'Time' } },
+    Year   => { Groups => { 2 => 'Time' } },
 );
 
@@ -348,8 +361,9 @@
         },
     },
-    1 => 'PictureMimeType',
+    1 => 'PictureMIMEType',
     2 => 'PictureDescription',
     3 => {
         Name => 'Picture',
+        Groups => { 2 => 'Preview' },
         Binary => 1,
     },
@@ -373,10 +387,13 @@
             my $t = $val / 1e7 - (((1970-1601)*365+89)*24*3600);
             return Image::ExifTool::ConvertUnixTime($t) . 'Z';
-        }
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
     },
     32 => { Name => 'DataPackets',  Format => 'int64u' },
     40 => {
-        Name => 'PlayDuration',
+        Name => 'Duration',
         Format => 'int64u',
+        Notes => 'called PlayDuration by the ASF spec',
+        Priority => 0,
         ValueConv => '$val / 1e7',
         PrintConv => 'ConvertDuration($val)',
@@ -403,6 +420,6 @@
         Format => 'binary[16]',
         RawConv => sub { # set ASF_STREAM_TYPE for use in conditional tags
-            my ($val, $exifTool) = @_;
-            $exifTool->{ASF_STREAM_TYPE} = $streamType{GetGUID($val)} || '';
+            my ($val, $et) = @_;
+            $$et{ASF_STREAM_TYPE} = $streamType{GetGUID($val)} || '';
             return $val;
         },
@@ -462,5 +479,5 @@
 
 %Image::ExifTool::ASF::HeaderExtension = (
-    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessASF,
+    PROCESS_PROC => \&ProcessASF,
     '14E6A5CB-C672-4332-8399-A96952065B5A' => 'ExtendedStreamProps',
     'A08649CF-4775-4670-8A16-6E35357566CD' => 'AdvancedMutualExcl',
@@ -471,9 +488,17 @@
     'C5F8CBEA-5BAF-4877-8467-AA8C44FA4CCA' => {
         Name => 'Metadata',
-        SubDirectory => { TagTable => 'Image::ExifTool::ASF::Metadata' },
+        SubDirectory => {
+            # have seen some tags same as ExtendedDescr, so use this table - PH
+            TagTable => 'Image::ExifTool::ASF::ExtendedDescr',
+            ProcessProc => \&ProcessMetadata,
+        },
     },
     '44231C94-9498-49D1-A141-1D134E457054' => {
         Name => 'MetadataLibrary',
-        SubDirectory => { TagTable => 'Image::ExifTool::ASF::Metadata' },
+        SubDirectory => {
+            # have seen some tags same as ExtendedDescr, so use this table - PH
+            TagTable => 'Image::ExifTool::ASF::ExtendedDescr',
+            ProcessProc => \&ProcessMetadata,
+        },
     },
     'D6E229DF-35DA-11D1-9034-00A0C90349BE' => 'IndexParameters',
@@ -482,8 +507,4 @@
     '43058533-6981-49E6-9B74-AD12CB86D58C' => 'AdvancedContentEncryption',
     'ABD3D211-A9BA-11cf-8EE6-00C00C205365' => 'Reserved1',
-);
-
-%Image::ExifTool::ASF::Metadata = (
-    PROCESS_PROC => \&Image::ExifTool::ASF::ProcessMetadata,
 );
 
@@ -505,5 +526,7 @@
 {
     # must do some byte swapping
-    my $buff = unpack('H*',pack('NnnNN',unpack('VvvNN',$_[0])));
+    my $val = shift;
+    return $val unless length($val) == 16;
+    my $buff = unpack('H*',pack('NnnNN',unpack('VvvNN',$val)));
     $buff =~ s/(.{8})(.{4})(.{4})(.{4})/$1-$2-$3-$4-/;
     return uc($buff);
@@ -516,5 +539,5 @@
 sub ProcessContentDescription($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = $$dirInfo{DirLen};
@@ -527,6 +550,6 @@
         next unless $len;
         return 0 if $pos + $len > $dirLen;
-        my $val = $exifTool->Decode(substr($$dataPt,$pos,$len),'UCS2','II');
-        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+        my $val = $et->Decode(substr($$dataPt,$pos,$len),'UCS2','II');
+        $et->HandleTag($tagTablePtr, $tag, $val);
         $pos += $len;
     }
@@ -540,10 +563,10 @@
 sub ProcessContentBranding($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = $$dirInfo{DirLen};
     return 0 if $dirLen < 40;
     # decode banner image type
-    $exifTool->HandleTag($tagTablePtr, 0, unpack('V', $$dataPt));
+    $et->HandleTag($tagTablePtr, 0, unpack('V', $$dataPt));
     # decode banner image, banner URL and copyright URL
     my $pos = 4;
@@ -556,5 +579,5 @@
         return 0 if $pos + $size > $dirLen;
         my $val = substr($$dataPt, $pos, $size);
-        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+        $et->HandleTag($tagTablePtr, $tag, $val);
         $pos += $size;
     }
@@ -569,8 +592,8 @@
 sub ReadASF($$$$$)
 {
-    my ($exifTool, $dataPt, $pos, $format, $size) = @_;
+    my ($et, $dataPt, $pos, $format, $size) = @_;
     my @vals;
     if ($format == 0) { # unicode string
-        $vals[0] = $exifTool->Decode(substr($$dataPt,$pos,$size),'UCS2','II');
+        $vals[0] = $et->Decode(substr($$dataPt,$pos,$size),'UCS2','II');
     } elsif ($format == 2) { # 4-byte boolean
         @vals = ReadValue($dataPt, $pos, 'int32u', undef, $size);
@@ -596,10 +619,10 @@
 sub ProcessExtendedContentDescription($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = $$dirInfo{DirLen};
     return 0 if $dirLen < 2;
     my $count = Get16u($dataPt, 0);
-    $exifTool->VerboseDir($dirInfo, $count);
+    $et->VerboseDir($dirInfo, $count);
     my $pos = 2;
     my $i;
@@ -613,11 +636,46 @@
         $pos += $nameLen;
         my ($dType, $dLen) = unpack("x${pos}v2", $$dataPt);
-        my $val = ReadASF($exifTool,$dataPt,$pos+4,$dType,$dLen);
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $pos += 4;
+        return 0 if $pos + $dLen > $dirLen;
+        my $val = ReadASF($et,$dataPt,$pos,$dType,$dLen);
+        $et->HandleTag($tagTablePtr, $tag, $val,
             DataPt => $dataPt,
-            Start  => $pos + 4,
+            Start  => $pos,
             Size   => $dLen,
         );
-        $pos += 4 + $dLen;
+        $pos += $dLen;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process ASF metadata library (similar to ProcessExtendedContentDescription above)
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
+# Returns: 1 on success
+sub ProcessMetadata($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = $$dirInfo{DirLen};
+    return 0 if $dirLen < 2;
+    my $count = Get16u($dataPt, 0);
+    $et->VerboseDir($dirInfo, $count);
+    my $pos = 2;
+    my $i;
+    for ($i=0; $i<$count; ++$i) {
+        return 0 if $pos + 12 > $dirLen;
+        my ($index, $stream, $nameLen, $dType, $dLen) = unpack("x${pos}v4V", $$dataPt);
+        $pos += 12;
+        return 0 if $pos + $nameLen + $dLen > $dirLen;
+        my $tag = Image::ExifTool::Decode(undef,substr($$dataPt,$pos,$nameLen),'UCS2','II','Latin');
+        $tag =~ s/^WM\///; # remove leading "WM/"
+        $pos += $nameLen;
+        my $val = ReadASF($et,$dataPt,$pos,$dType,$dLen);
+        $et->HandleTag($tagTablePtr, $tag, $val,
+            DataPt => $dataPt,
+            Start  => $pos,
+            Size   => $dLen,
+        );
+        $pos += $dLen;
     }
     return 1;
@@ -630,5 +688,5 @@
 sub ProcessPicture($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
@@ -637,15 +695,16 @@
     # extract picture type and length
     my ($type, $picLen) = unpack("x${dirStart}CV", $$dataPt);
-    $exifTool->HandleTag($tagTablePtr, 0, $type);
+    $et->VerboseDir('Picture');
+    $et->HandleTag($tagTablePtr, 0, $type);
     # extract mime type and description strings (null-terminated unicode strings)
     my $n = $dirLen - 5 - $picLen;
     return 0 if $n & 0x01 or $n < 4;
     my $str = substr($$dataPt, $dirStart+5, $n);
-    if ($str =~ /^((?:..)*?)\0\0((?:..)*?)\0\0/) {
+    if ($str =~ /^((?:..)*?)\0\0((?:..)*?)\0\0/s) {
         my ($mime, $desc) = ($1, $2);
-        $exifTool->HandleTag($tagTablePtr, 1, $exifTool->Decode($mime,'UCS2','II'));
-        $exifTool->HandleTag($tagTablePtr, 2, $exifTool->Decode($desc,'UCS2','II')) if length $desc;
+        $et->HandleTag($tagTablePtr, 1, $et->Decode($mime,'UCS2','II'));
+        $et->HandleTag($tagTablePtr, 2, $et->Decode($desc,'UCS2','II')) if length $desc;
     }
-    $exifTool->HandleTag($tagTablePtr, 3, substr($$dataPt, $dirStart+5+$n, $picLen));
+    $et->HandleTag($tagTablePtr, 3, substr($$dataPt, $dirStart+5+$n, $picLen));
     return 1;
 }
@@ -657,10 +716,10 @@
 sub ProcessCodecList($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = $$dirInfo{DirLen};
     return 0 if $dirLen < 20;
     my $count = Get32u($dataPt, 16);
-    $exifTool->VerboseDir($dirInfo, $count);
+    $et->VerboseDir($dirInfo, $count);
     my $pos = 20;
     my $i;
@@ -673,11 +732,11 @@
         $pos += 4;
         return 0 if $pos + $nameLen + 2 > $dirLen;
-        my $name = $exifTool->Decode(substr($$dataPt,$pos,$nameLen),'UCS2','II');
-        $exifTool->HandleTag($tagTablePtr, "${type}Name", $name);
+        my $name = $et->Decode(substr($$dataPt,$pos,$nameLen),'UCS2','II');
+        $et->HandleTag($tagTablePtr, "${type}Name", $name);
         my $descLen = Get16u($dataPt, $pos + $nameLen) * 2;
         $pos += $nameLen + 2;
         return 0 if $pos + $descLen + 2 > $dirLen;
-        my $desc = $exifTool->Decode(substr($$dataPt,$pos,$descLen),'UCS2','II');
-        $exifTool->HandleTag($tagTablePtr, "${type}Description", $desc);
+        my $desc = $et->Decode(substr($$dataPt,$pos,$descLen),'UCS2','II');
+        $et->HandleTag($tagTablePtr, "${type}Description", $desc);
         my $infoLen = Get16u($dataPt, $pos + $descLen);
         $pos += $descLen + 2 + $infoLen;
@@ -687,35 +746,4 @@
 
 #------------------------------------------------------------------------------
-# Process ASF metadata library
-# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table reference
-# Returns: 1 on success
-sub ProcessMetadata($$$)
-{
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    my $dataPt = $$dirInfo{DataPt};
-    my $dirLen = $$dirInfo{DirLen};
-    return 0 if $dirLen < 2;
-    my $count = Get16u($dataPt, 0);
-    $exifTool->VerboseDir($dirInfo, $count);
-    my $pos = 2;
-    my $i;
-    for ($i=0; $i<$count; ++$i) {
-        return 0 if $pos + 12 > $dirLen;
-        my ($index, $stream, $nameLen, $dType, $dLen) = unpack("x${pos}v4V", $$dataPt);
-        $pos += 12;
-        return 0 if $pos + $nameLen + $dLen > $dirLen;
-        my $tag = Image::ExifTool::Decode(undef,substr($$dataPt,$pos,$nameLen),'UCS2','II','Latin');
-        my $val = ReadASF($exifTool,$dataPt,$pos+$nameLen,$dType,$dLen);
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
-            DataPt => $dataPt,
-            Start  => $pos,
-            Size   => $dLen,
-        );
-        $pos += $nameLen + $dLen;
-    }
-    return 1;
-}
-
-#------------------------------------------------------------------------------
 # Extract information from a ASF file
 # Inputs: 0) ExifTool object reference, 1) dirInfo reference, 2) tag table ref
@@ -723,7 +751,7 @@
 sub ProcessASF($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $rtnVal = 0;
     my $pos = 0;
@@ -733,11 +761,11 @@
         last unless $raf->Read($buff, 24) == 24;
         $pos += 24;
-        my $tag = GetGUID($buff);
+        my $tag = GetGUID(substr($buff,0,16));
         unless ($tagTablePtr) {
             # verify this is a valid ASF file
             last unless $tag eq '75B22630-668E-11CF-A6D9-00AA0062CE6C';
-            my $fileType = $exifTool->{FILE_EXT};
+            my $fileType = $$et{FILE_EXT};
             $fileType = 'ASF' unless $fileType and $fileType =~ /^(ASF|WMV|WMA|DIVX)$/;
-            $exifTool->SetFileType($fileType);
+            $et->SetFileType($fileType);
             SetByteOrder('II');
             $tagTablePtr = GetTagTable('Image::ExifTool::ASF::Main');
@@ -752,7 +780,7 @@
             if ($size > 0x7fffffff * 4294967296) {
                 $err = 'Invalid ASF object size';
-            } elsif ($exifTool->Options('LargeFileSupport')) {
+            } elsif ($et->Options('LargeFileSupport')) {
                 if ($raf->Seek($size, 1)) {
-                    $exifTool->VPrint(0, "  Skipped large ASF object ($size bytes)\n");
+                    $et->VPrint(0, "  Skipped large ASF object ($size bytes)\n");
                     $pos += $size;
                     next;
@@ -768,8 +796,8 @@
             pop @childEnd;
             $tagTablePtr = pop @parentTable;
-            $exifTool->{INDENT} = substr($exifTool->{INDENT},0,-2);
+            $$et{INDENT} = substr($$et{INDENT},0,-2);
         }
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
-        $verbose and $exifTool->VerboseInfo($tag, $tagInfo);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        $verbose and $et->VerboseInfo($tag, $tagInfo);
         if ($tagInfo) {
             my $subdir = $$tagInfo{SubDirectory};
@@ -781,5 +809,5 @@
                         if ($verbose > 2) {
                             $raf->Read($buff, $s) == $s or $err = 'Truncated file', last;
-                            $exifTool->VerboseDump(\$buff);
+                            $et->VerboseDump(\$buff);
                         } elsif (not $raf->Seek($s, 1)) {
                             $err = 'Seek error';
@@ -792,6 +820,6 @@
                         $pos += $$subdir{Size};
                         if ($verbose) {
-                            $exifTool->{INDENT} .= '| ';
-                            $exifTool->VerboseDir($$tagInfo{Name});
+                            $$et{INDENT} .= '| ';
+                            $et->VerboseDir($$tagInfo{Name});
                         }
                         next;
@@ -804,7 +832,7 @@
                         DirName => $$tagInfo{Name},
                     );
-                    $exifTool->VerboseDump(\$buff) if $verbose > 2;
-                    unless ($exifTool->ProcessDirectory(\%subdirInfo, $subTable)) {
-                        $exifTool->Warn("Error processing $$tagInfo{Name} directory");
+                    $et->VerboseDump(\$buff) if $verbose > 2;
+                    unless ($et->ProcessDirectory(\%subdirInfo, $subTable, $$subdir{ProcessProc})) {
+                        $et->Warn("Error processing $$tagInfo{Name} directory");
                     }
                     $pos += $size;
@@ -818,5 +846,5 @@
         if ($verbose > 2) {
             $raf->Read($buff, $size) == $size or $err = 'Truncated file', last;
-            $exifTool->VerboseDump(\$buff);
+            $et->VerboseDump(\$buff);
         } elsif (not $raf->Seek($size, 1)) { # skip the block
             $err = 'Seek error';
@@ -825,5 +853,5 @@
         $pos += $size;
     }
-    $err and $exifTool->Warn($err);
+    $err and $et->Warn($err);
     return $rtnVal;
 }
@@ -849,5 +877,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Apple.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Apple.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Apple.pm	(revision 34921)
@@ -0,0 +1,162 @@
+#------------------------------------------------------------------------------
+# File:         Apple.pm
+#
+# Description:  Apple EXIF maker notes tags
+#
+# Revisions:    2013-09-13 - P. Harvey Created
+#
+# References:   1) http://www.photoinvestigator.co/blog/the-mystery-of-maker-apple-metadata/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Apple;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+use Image::ExifTool::PLIST;
+
+$VERSION = '1.05';
+
+# Apple iPhone metadata (ref PH)
+%Image::ExifTool::Apple::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    NOTES => 'Tags extracted from the maker notes of iPhone images.',
+    # 0x0001 - int32s: seen 0,1,2,3,4,9
+    # 0x0002 - binary plist with a single data object of size 512 bytes (iPhone5s)
+    0x0003 => {
+        Name => 'RunTime', # (includes time plugged in, but not when suspended, ref 1)
+        SubDirectory => { TagTable => 'Image::ExifTool::Apple::RunTime' },
+    },
+    # 0x0004 - int32s: normally 1, but 0 for low-light images
+    # 0x0005 - int32s: seen values 113-247, and 100 for blank images
+    # 0x0006 - int32s: seen values 27-258, and 20 for blank images
+    # 0x0007 - int32s: seen 1
+    0x0008 => { #1
+        Name => 'AccelerationVector',
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational64s',
+        Count => 3,
+        # Note: the directions are contrary to the Apple documentation (which have the
+        # signs of all axes reversed -- apparently the Apple geeks aren't very good
+        # with basic physics, and don't understand the concept of acceleration.  See
+        # http://nscookbook.com/2013/03/ios-programming-recipe-19-using-core-motion-to-access-gyro-and-accelerometer/
+        # for one of the few correct descriptions of this).  Note that this leads to
+        # a left-handed coordinate system for acceleration.
+        Notes => q{
+            XYZ coordinates of the acceleration vector in units of g.  As viewed from
+            the front of the phone, positive X is toward the left side, positive Y is
+            toward the bottom, and positive Z points into the face of the phone
+        },
+    },
+    # 0x0009 - int32s: seen 19,275,531,4371
+    0x000a => {
+        Name => 'HDRImageType',
+        Writable => 'int32s',
+        PrintConv => {
+            # 2 => ? (iPad mini 2)
+            3 => 'HDR Image',
+            4 => 'Original Image',
+        },
+    },
+    0x000b => {
+        Name => 'BurstUUID',
+        Writable => 'string',
+        Notes => 'unique ID for all images in a burst',
+    },
+    # 0x000c - rational64s[2]: eg) "0.1640625 0.19921875"
+    # 0x000d - int32s: 0,1,6,20,24,32,40
+    # 0x000e - int32s: 0,1,4,12 (Orientation? 0=landscape? 4=portrait? ref 1)
+    # 0x000f - int32s: 2,3
+    # 0x0010 - int32s: 1
+    0x0011 => {
+        Name => 'MediaGroupUUID', #NealKrawetz private communication
+        # (changed in 12.19 from Name => 'ContentIdentifier', #forum8750)
+        Writable => 'string',
+    },
+    # 0x0014 - int32s: 1,2,3,4,5 (iPhone 6s, iOS 6.1)
+    0x0015 => {
+        Name => 'ImageUniqueID',
+        Writable => 'string',
+    },
+    # 0x0016 - string[29]: "AXZ6pMTOh2L+acSh4Kg630XCScoO\0"
+    # 0x0017 - int32s: 0,8192
+    # 0x0019 - int32s: 0,2,128
+    # 0x001a - string[6]: "q825s\0"
+    # 0x001f - int32s: 0
+);
+
+# PLIST-format CMTime structure (ref PH)
+# (CMTime ref https://developer.apple.com/library/ios/documentation/CoreMedia/Reference/CMTime/Reference/reference.html)
+%Image::ExifTool::Apple::RunTime = (
+    PROCESS_PROC => \&Image::ExifTool::PLIST::ProcessBinaryPLIST,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    NOTES => q{
+        This PLIST-format information contains the elements of a CMTime structure
+        representing the amount of time the phone has been running since the last
+        boot, not including standby time.
+    },
+    timescale => { Name => 'RunTimeScale' }, # (seen 1000000000 --> ns)
+    epoch     => { Name => 'RunTimeEpoch' }, # (seen 0)
+    value     => { Name => 'RunTimeValue' }, # (should divide by RunTimeScale to get seconds)
+    flags => {
+        Name => 'RunTimeFlags',
+        PrintConv => { BITMASK => {
+            0 => 'Valid',
+            1 => 'Has been rounded',
+            2 => 'Positive infinity',
+            3 => 'Negative infinity',
+            4 => 'Indefinite',
+        }},
+    },
+);
+
+# Apple composite tags
+%Image::ExifTool::Apple::Composite = (
+    GROUPS => { 2 => 'Camera' },
+    RunTimeSincePowerUp => {
+        Require => {
+            0 => 'Apple:RunTimeValue',
+            1 => 'Apple:RunTimeScale',
+        },
+        ValueConv => '$val[1] ? $val[0] / $val[1] : undef',
+        PrintConv => 'ConvertDuration($val)',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Apple');
+
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Apple - Apple EXIF 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
+Apple maker notes in EXIF information.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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/Apple Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Audible.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Audible.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Audible.pm	(revision 34921)
@@ -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-2021, 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/jteeuwen/audible>
+
+=item L<https://code.google.com/p/pyaudibletags/>
+
+=item L<http://wiki.multimedia.cx/index.php?title=Audible_Audio>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Audible Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BMP.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BMP.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BMP.pm	(revision 34921)
@@ -8,4 +8,5 @@
 # References:   1) http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html
 #               2) http://www.fourcc.org/rgb.php
+#               3) https://msdn.microsoft.com/en-us/library/dd183381(v=vs.85).aspx
 #------------------------------------------------------------------------------
 
@@ -16,5 +17,19 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.07';
+$VERSION = '1.09';
+
+# conversions for fixed-point 2.30 format values
+my %fixed2_30 = (
+    ValueConv => q{
+        my @a = split ' ', $val;
+        $_ /= 0x40000000 foreach @a;
+        "@a";
+    },
+    PrintConv => q{
+        my @a = split ' ', $val;
+        $_ = sprintf('%.6f', $_) foreach @a;
+        "@a";
+    },
+);
 
 # BMP chunks
@@ -26,11 +41,19 @@
         of image related information.
     },
-    # 0 => size of bitmap structure:
-    #        12  bytes => 'OS/2 V1',
-    #        40  bytes => 'Windows V3',
-    #        64  bytes => 'OS/2 V2',
-    #        68  bytes => some bitmap structure in AVI videos
-    #        108 bytes => 'Windows V4',
-    #        124 bytes => 'Windows V5',
+    0 => {
+        Name => 'BMPVersion',
+        Format => 'int32u',
+        Notes => q{
+            this is actually the size of the BMP header, but used to determine the BMP
+            version
+        },
+        RawConv => '$$self{BMPVersion} = $val',
+        PrintConv => {
+            40  => 'Windows V3',
+            68  => 'AVI BMP structure?', #PH (seen in AVI movies from some Casio and Nikon cameras)
+            108 => 'Windows V4',
+            124 => 'Windows V5',
+        },
+    },
     4 => {
         Name => 'ImageWidth',
@@ -45,4 +68,5 @@
         Name => 'Planes',
         Format => 'int16u',
+        # values: 0,1,4,8,16,24,32
     },
     14 => {
@@ -53,4 +77,5 @@
         Name => 'Compression',
         Format => 'int32u',
+        RawConv => '$$self{BMPCompression} = $val',
         # (formatted as string[4] for some values in AVI images)
         ValueConv => '$val > 256 ? unpack("A4",pack("V",$val)) : $val',
@@ -74,4 +99,5 @@
         Name => 'ImageLength',
         Format => 'int32u',
+        RawConv => '$$self{BMPImageLength} = $val',
     },
     24 => {
@@ -91,6 +117,97 @@
         Name => 'NumImportantColors',
         Format => 'int32u',
+        Hook => '$varSize += $size if $$self{BMPVersion} == 68', # (the rest is invalid for AVI BMP's)
         PrintConv => '$val ? $val : "All"',
     },
+    40 => {
+        Name => 'RedMask',
+        Format => 'int32u',
+        PrintConv => 'sprintf("0x%.8x",$val)',
+    },
+    44 => {
+        Name => 'GreenMask',
+        Format => 'int32u',
+        PrintConv => 'sprintf("0x%.8x",$val)',
+    },
+    48 => {
+        Name => 'BlueMask',
+        Format => 'int32u',
+        PrintConv => 'sprintf("0x%.8x",$val)',
+    },
+    52 => {
+        Name => 'AlphaMask',
+        Format => 'int32u',
+        PrintConv => 'sprintf("0x%.8x",$val)',
+    },
+    56 => {
+        Name => 'ColorSpace',
+        Format => 'undef[4]',
+        RawConv => '$$self{BMPColorSpace} = $val =~ /\0/ ? Get32u(\$val, 0) : pack("N",unpack("V",$val))',
+        PrintConv => {
+            0 => 'Calibrated RGB',
+            1 => 'Device RGB',
+            2 => 'Device CMYK',
+            LINK => 'Linked Color Profile',
+            MBED => 'Embedded Color Profile',
+            sRGB => 'sRGB',
+            'Win ' => 'Windows Color Space',
+        },
+    },
+    60 => {
+        Name => 'RedEndpoint',
+        Condition => '$$self{BMPColorSpace} eq "0"',
+        Format => 'int32u[3]',
+        %fixed2_30,
+    },
+    72 => {
+        Name => 'GreenEndpoint',
+        Condition => '$$self{BMPColorSpace} eq "0"',
+        Format => 'int32u[3]',
+        %fixed2_30,
+    },
+    84 => {
+        Name => 'BlueEndpoint',
+        Condition => '$$self{BMPColorSpace} eq "0"',
+        Format => 'int32u[3]',
+        %fixed2_30,
+    },
+    96 => {
+        Name => 'GammaRed',
+        Condition => '$$self{BMPColorSpace} eq "0"',
+        Format => 'fixed32u',
+    },
+    100 => {
+        Name => 'GammaGreen',
+        Condition => '$$self{BMPColorSpace} eq "0"',
+        Format => 'fixed32u',
+    },
+    104 => {
+        Name => 'GammaBlue',
+        Condition => '$$self{BMPColorSpace} eq "0"',
+        Format => 'fixed32u',
+    },
+    108 => {
+        Name => 'RenderingIntent',
+        Format => 'int32u',
+        PrintConv => {
+            1 => 'Graphic (LCS_GM_BUSINESS)',
+            2 => 'Proof (LCS_GM_GRAPHICS)',
+            4 => 'Picture (LCS_GM_IMAGES)',
+            8 => 'Absolute Colorimetric (LCS_GM_ABS_COLORIMETRIC)',
+        },
+    },
+    112 => {
+        Name => 'ProfileDataOffset',
+        Condition => '$$self{BMPColorSpace} eq "LINK" or $$self{BMPColorSpace} eq "MBED"',
+        Format => 'int32u',
+        RawConv => '$$self{BMPProfileOffset} = $val',
+    },
+    116 => {
+        Name => 'ProfileSize',
+        Condition => '$$self{BMPColorSpace} eq "LINK" or $$self{BMPColorSpace} eq "MBED"',
+        Format => 'int32u',
+        RawConv => '$$self{BMPProfileSize} = $val',
+    },
+    # 120 - reserved
 );
 
@@ -100,9 +217,33 @@
     GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
     NOTES => 'Information extracted from OS/2-format BMP images.',
-    # 0 => size of bitmap structure (12)
+    0 => {
+        Name => 'BMPVersion',
+        Format => 'int32u',
+        Notes => 'again, the header size is used to determine the BMP version',
+        PrintConv => {
+            12  => 'OS/2 V1',
+            64  => 'OS/2 V2',
+        },
+    },
     4  => { Name => 'ImageWidth',  Format => 'int16u' },
     6  => { Name => 'ImageHeight', Format => 'int16u' },
     8  => { Name => 'Planes',      Format => 'int16u' },
     10 => { Name => 'BitDepth',    Format => 'int16u' },
+);
+
+%Image::ExifTool::BMP::Extra = (
+    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
+    NOTES => 'Extra information extracted from some BMP images.',
+    VARS => { NO_ID => 1 },
+    LinkedProfileName => { },
+    ICC_Profile => { SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' } },
+    EmbeddedJPG => {
+        Groups => { 2 => 'Preview' },
+        Binary => 1,
+    },
+    EmbeddedPNG => {
+        Groups => { 2 => 'Preview' },
+        Binary => 1,
+    },
 );
 
@@ -113,5 +254,5 @@
 sub ProcessBMP($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $tagTablePtr);
@@ -122,7 +263,11 @@
     SetByteOrder('II');
     my $len = Get32u(\$buff, 14);
-    return 0 unless $len == 12 or $len >= 40;
+    # len = v1:12, v4:108, v5:124
+    return 0 unless $len == 12 or $len == 16 or ($len >= 40 and $len < 1000000);
     return 0 unless $raf->Seek(-4, 1) and $raf->Read($buff, $len) == $len;
-    $exifTool->SetFileType();   # set the FileType tag
+    $et->SetFileType();   # set the FileType tag
+#
+# process the BMP header
+#
     my %dirInfo = (
         DataPt => \$buff,
@@ -130,10 +275,43 @@
         DirLen => length($buff),
     );
-    if ($len == 12) {   # old OS/2 format BMP
+    if ($len == 12 or $len == 16 or $len == 64) {   # old OS/2 format BMP
         $tagTablePtr = GetTagTable('Image::ExifTool::BMP::OS2');
     } else {
         $tagTablePtr = GetTagTable('Image::ExifTool::BMP::Main');
     }
-    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+#
+# extract any embedded images
+#
+    my $extraTable = GetTagTable('Image::ExifTool::BMP::Extra');
+    if ($$et{BMPCompression} and $$et{BMPImageLength} and
+        ($$et{BMPCompression} == 4 or $$et{BMPCompression} == 5))
+    {
+        my $tag = $$et{BMPCompression} == 4 ? 'EmbeddedJPG' : 'EmbeddedPNG';
+        my $val = $et->ExtractBinary($raf->Tell(), $$et{BMPImageLength}, $tag);
+        if ($val) {
+            $et->HandleTag($extraTable, $tag, $val);
+        }
+    }
+#
+# process profile data if it exists (v5 header only)
+#
+    if ($len == 124 and $$et{BMPProfileOffset}) {
+        my $pos = $$et{BMPProfileOffset} + 14;  # (note the 14-byte shift!)
+        my $size = $$et{BMPProfileSize};
+        if ($raf->Seek($pos, 0) and $raf->Read($buff, $size) == $size) {
+            my $tag;
+            if ($$et{BMPColorSpace} eq 'LINK') {
+                $buff =~ s/\0+$//;  # remove null terminator(s)
+                $buff = $et->Decode($buff, 'Latin'); # convert from Latin
+                $tag = 'LinkedProfileName';
+            } else {
+                $tag = 'ICC_Profile';
+            }
+            $et->HandleTag($extraTable, $tag => $buff, Size => $size, DataPos => $pos);
+        } else {
+            $et->Warn('Error loading profile data', 1);
+        }
+    }
     return 1;
 }
@@ -158,5 +336,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -169,4 +347,8 @@
 =item L<http://www.fortunecity.com/skyscraper/windows/364/bmpffrmt.html>
 
+=item L<http://www.fourcc.org/rgb.php>
+
+=item L<https://msdn.microsoft.com/en-us/library/dd183381(v=vs.85).aspx>
+
 =back
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BPG.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BPG.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BPG.pm	(revision 34921)
@@ -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<http://bellard.org/bpg/> 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-2021, 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://bellard.org/bpg/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/BPG Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BZZ.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BZZ.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BZZ.pm	(revision 34921)
@@ -446,5 +446,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 Copyright 2002, Leon Bottou and Yann Le Cun
 Copyright 2001, AT&T
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BigTIFF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BigTIFF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BigTIFF.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.05';
+$VERSION = '1.07';
 
 my $maxOffset = 0x7fffffff; # currently supported maximum data offset/size
@@ -26,38 +26,42 @@
 sub ProcessBigIFD($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->{OPTIONS}->{Verbose};
-    my $htmlDump = $exifTool->{HTML_DUMP};
+    my $verbose = $$et{OPTIONS}{Verbose};
+    my $htmlDump = $$et{HTML_DUMP};
     my $dirName = $$dirInfo{DirName};
     my $dirStart = $$dirInfo{DirStart};
-
-    $verbose = -1 if $htmlDump; # mix htmlDump into verbose so we can test for both at once
+    my ($offName, $nextOffName);
+
+    if ($htmlDump) {
+        $verbose = -1;  # mix htmlDump into verbose so we can test for both at once
+        $offName = $$dirInfo{OffsetName};
+    }
 
     # loop through IFD chain
     for (;;) {
-        if ($dirStart > $maxOffset and not $exifTool->Options('LargeFileSupport')) {
-            $exifTool->Warn('Huge offsets not supported (LargeFileSupport not set)');
+        if ($dirStart > $maxOffset and not $et->Options('LargeFileSupport')) {
+            $et->Warn('Huge offsets not supported (LargeFileSupport not set)');
             last;
         }
         unless ($raf->Seek($dirStart, 0)) {
-            $exifTool->Warn("Bad $dirName offset");
+            $et->Warn("Bad $dirName offset");
             return 0;
         }
         my ($dirBuff, $index);
         unless ($raf->Read($dirBuff, 8) == 8) {
-            $exifTool->Warn("Truncated $dirName count");
+            $et->Warn("Truncated $dirName count");
             return 0;
         }
         my $numEntries = Image::ExifTool::Get64u(\$dirBuff, 0);
-        $verbose > 0 and $exifTool->VerboseDir($dirName, $numEntries);
+        $verbose > 0 and $et->VerboseDir($dirName, $numEntries);
         my $bsize = $numEntries * 20;
         if ($bsize > $maxOffset) {
-            $exifTool->Warn('Huge directory counts not yet supported');
+            $et->Warn('Huge directory counts not yet supported');
             last;
         }
         my $bufPos = $raf->Tell();
         unless ($raf->Read($dirBuff, $bsize) == $bsize) {
-            $exifTool->Warn("Truncated $dirName directory");
+            $et->Warn("Truncated $dirName directory");
             return 0;
         }
@@ -65,8 +69,11 @@
         $raf->Read($nextIFD, 8) == 8 or undef $nextIFD; # try to read next IFD pointer
         if ($htmlDump) {
-            $exifTool->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));
-                $exifTool->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);
             }
         }
@@ -79,28 +86,28 @@
             my $formatSize = $Image::ExifTool::Exif::formatSize[$format];
             unless (defined $formatSize) {
-                $exifTool->HDump($bufPos+$entry,20,"[invalid IFD entry]",
-                         "Bad format value: $format", 1);
+                $et->HDump($bufPos+$entry,20,"[invalid IFD entry]",
+                           "Bad format value: $format", 1, $offName);
                 # warn unless the IFD was just padded with zeros
-                $exifTool->Warn(sprintf("Unknown format ($format) for $dirName tag 0x%x",$tagID));
+                $et->Warn(sprintf("Unknown format ($format) for $dirName tag 0x%x",$tagID));
                 return 0; # assume corrupted IFD
             }
             my $formatStr = $Image::ExifTool::Exif::formatName[$format];
             my $size = $count * $formatSize;
-            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+            my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
             next unless defined $tagInfo or $verbose;
             my $valuePtr = $entry + 12;
-            my ($valBuff, $valBase);
+            my ($valBuff, $valBase, $rational, $subOffName);
             if ($size > 8) {
                 if ($size > $maxOffset) {
-                    $exifTool->Warn("Can't handle $dirName entry $index (huge size)");
+                    $et->Warn("Can't handle $dirName entry $index (huge size)");
                     next;
                 }
                 $valuePtr = Image::ExifTool::Get64u(\$dirBuff, $valuePtr);
-                if ($valuePtr > $maxOffset and not $exifTool->Options('LargeFileSupport')) {
-                    $exifTool->Warn("Can't handle $dirName entry $index (LargeFileSupport not set)");
+                if ($valuePtr > $maxOffset and not $et->Options('LargeFileSupport')) {
+                    $et->Warn("Can't handle $dirName entry $index (LargeFileSupport not set)");
                     next;
                 }
                 unless ($raf->Seek($valuePtr, 0) and $raf->Read($valBuff, $size) == $size) {
-                    $exifTool->Warn("Error reading $dirName entry $index");
+                    $et->Warn("Error reading $dirName entry $index");
                     next;
                 }
@@ -112,15 +119,11 @@
             if (defined $tagInfo and not $tagInfo) {
                 # GetTagInfo() required the value for a Condition
-                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$valBuff);
-            }
-            my $val = ReadValue(\$valBuff, 0, $formatStr, $count, $size);
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID, \$valBuff);
+            }
+            my $val = ReadValue(\$valBuff, 0, $formatStr, $count, $size, \$rational);
             if ($htmlDump) {
                 my $tval = $val;
-                if ($formatStr =~ /^rational64([su])$/) {
-                    # show numerator/denominator separately
-                    my $f = ReadValue(\$valBuff, 0, "int32$1", $count*2, $size);
-                    $f =~ s/(-?\d+) (-?\d+)/$1\/$2/g;
-                    $tval .= " ($f)";
-                }
+                # show numerator/denominator separately for rational numbers
+                $tval .= " ($rational)" if defined $rational;
                 my ($tagName, $colName);
                 if ($tagID == 0x927c and $dirName eq 'ExifIFD') {
@@ -153,14 +156,20 @@
                 }
                 $tip .= "Value: $tval";
-                $exifTool->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;
-                    $exifTool->HDump($valuePtr,$size,"$tagName value",'SAME', $flg);
+                    $et->HDump($valuePtr,$size,"$tagName value",'SAME', $flg, $sid);
                 }
             }
             if ($tagInfo and $$tagInfo{SubIFD}) {
                 # process all SubIFD's as BigTIFF
-                $verbose > 0 and $exifTool->VerboseInfo($tagID, $tagInfo,
+                $verbose > 0 and $et->VerboseInfo($tagID, $tagInfo,
                     Table   => $tagTablePtr,
                     Index   => $index,
@@ -179,14 +188,15 @@
                     $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,
                     );
-                    $exifTool->ProcessDirectory(\%subdirInfo, $tagTablePtr, \&ProcessBigIFD);
+                    $et->ProcessDirectory(\%subdirInfo, $tagTablePtr, \&ProcessBigIFD);
                 }
             } else {
-                my $tagKey = $exifTool->HandleTag($tagTablePtr, $tagID, $val,
+                my $tagKey = $et->HandleTag($tagTablePtr, $tagID, $val,
                     Index   => $index,
                     DataPt  => \$valBuff,
@@ -198,12 +208,13 @@
                     RAF     => $raf,
                 );
-                $tagKey and $exifTool->SetGroup($tagKey, $dirName);
+                $tagKey and $et->SetGroup($tagKey, $dirName);
             }
         }
         last unless $dirName =~ /^(IFD|SubIFD)(\d*)$/;
         $dirName = $1 . (($2 || 0) + 1);
-        defined $nextIFD or $exifTool->Warn("Bad $dirName pointer"), return 0;
+        defined $nextIFD or $et->Warn("Bad $dirName pointer"), return 0;
         $dirStart = Image::ExifTool::Get64u(\$nextIFD, 0);
         $dirStart or last;
+        $offName = $nextOffName;
     }
     return 1;
@@ -216,5 +227,5 @@
 sub ProcessBTF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -223,14 +234,14 @@
     return 0 unless $buff =~ /^(MM\0\x2b\0\x08\0\0|II\x2b\0\x08\0\0\0)/;
     if ($$dirInfo{OutFile}) {
-        $exifTool->Error('ExifTool does not support writing of BigTIFF images');
+        $et->Error('ExifTool does not support writing of BigTIFF images');
         return 1;
     }
-    $exifTool->SetFileType('BTF'); # set the FileType tag
+    $et->SetFileType('BTF'); # set the FileType tag
     SetByteOrder(substr($buff, 0, 2));
     my $offset = Image::ExifTool::Get64u(\$buff, 8);
-    if ($exifTool->{HTML_DUMP}) {
+    if ($$et{HTML_DUMP}) {
         my $o = (GetByteOrder() eq 'II') ? 'Little' : 'Big';
-        $exifTool->HDump(0, 8, "BigTIFF header", "Byte order: $o endian", 0);
-        $exifTool->HDump(8, 8, "IFD0 pointer", sprintf("Offset: 0x%.8x",$offset), 0);
+        $et->HDump(0, 8, "BigTIFF header", "Byte order: $o endian", 0);
+        $et->HDump(8, 8, "IFD0 pointer", sprintf("Offset: 0x%.8x",$offset), 0);
     }
     my %dirInfo = (
@@ -242,5 +253,5 @@
     );
     my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
-    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr, \&ProcessBigIFD);
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr, \&ProcessBigIFD);
     return 1;
 }
@@ -265,5 +276,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BuildTagLookup.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BuildTagLookup.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/BuildTagLookup.pm	(revision 34921)
@@ -32,11 +32,19 @@
 use Image::ExifTool::Canon;
 use Image::ExifTool::Nikon;
-
-$VERSION = '2.28';
+use Image::ExifTool::Sony;
+use Image::ExifTool::Validate;
+use Image::ExifTool::MacOS;
+
+$VERSION = '3.42';
 @ISA = qw(Exporter);
 
-sub NumbersFirst;
-
-my $numbersFirst = 1;   # set to -1 to sort numbers last
+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
 
 # list of all tables in plug-in modules
@@ -51,13 +59,60 @@
 };
 
-my $homePage = 'http://owl.phy.queensu.ca/~phil/exiftool';
+my $homePage = 'https://exiftool.org';
+
+# tweak the ordering of tables in the documentation
+my %tweakOrder = (
+  # this    => comes after this
+  # -------    -----------------
+    JPEG    => '-',     # JPEG comes first
+    IPTC    => 'Exif',  # put IPTC after EXIF,
+    GPS     => 'XMP',   # etc...
+    Composite => 'Extra',
+    GeoTiff => 'GPS',
+    CanonVRD=> 'CanonCustom',
+    DJI     => 'Casio',
+    FLIR    => 'DJI',
+    FujiFilm => 'FLIR',
+    Kodak   => 'JVC',
+    Leaf    => 'Kodak',
+    Minolta => 'Leaf',
+    Motorola => 'Minolta',
+    Nikon   => 'Motorola',
+    NikonCustom => 'Nikon',
+    NikonCapture => 'NikonCustom',
+    Nintendo => 'NikonCapture',
+    Pentax  => 'Panasonic',
+    SonyIDC => 'Sony',
+    Unknown => 'SonyIDC',
+    DNG     => 'Unknown',
+    PrintIM => 'ICC_Profile',
+    Vorbis  => 'Ogg',
+    ID3     => 'PostScript',
+    MinoltaRaw => 'KyoceraRaw',
+    KyoceraRaw => 'CanonRaw',
+    SigmaRaw => 'PanasonicRaw',
+    Lytro   => 'SigmaRaw',
+    PhotoMechanic => 'FotoStation',
+    Microsoft     => 'PhotoMechanic',
+   'Microsoft::MP'=> 'Microsoft::MP1',
+    GIMP    => 'Microsoft',
+   'Nikon::CameraSettingsD300' => 'Nikon::ShotInfoD300b',
+   'Pentax::LensData' => 'Pentax::LensInfo2',
+   'Sony::SRF2' => 'Sony::SRF',
+    DarwinCore => 'AFCP',
+   'MWG::Regions' => 'MWG::Composite',
+   'MWG::Keywords' => 'MWG::Regions',
+   'MWG::Collections' => 'MWG::Keywords',
+   'GoPro::fdsc' => 'GoPro::KBAT',
+);
 
 # list of all recognized Format strings
 # (not a complete list, but this is all we use so far)
-# (also, formats like "var_X[Y]" are allowed for any valid X)
+# (also, formats like "var_X[num]" are allowed for any valid X)
 my %formatOK = (
     %Image::ExifTool::Exif::formatNumber,
     0 => 1,
     1 => 1,
+    2 => 1, # (writable for docs only)
     real    => 1,
     integer => 1,
@@ -74,9 +129,13 @@
     digits   => 1,
     int16uRev => 1,
+    int32uRev => 1,
     rational32u => 1,
     rational32s => 1,
+    pstring     => 1,
     var_string  => 1,
     var_int16u  => 1,
     var_pstr32  => 1,
+    var_ustr32  => 1,
+    var_ue7     => 1, # (BPG)
     # Matroska
     signed      => 1,
@@ -84,6 +143,4 @@
     utf8        => 1,
 );
-
-my $caseInsensitive;    # flag to ignore case when sorting tag names
 
 # Descriptions for the TagNames documentation
@@ -107,11 +164,17 @@
     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<Tag ID>, B<Index> or B<Sequence> is given in the first column of each
+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
-is the identifier that is actually stored in the file.  An B<Index> refers
-to the location of a value when found at a fixed position within a data
-block, and B<Sequence> gives the order of values for a serial data stream.
+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 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
@@ -121,5 +184,5 @@
 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<Unknown|../ExifTool.html#Unknown> (-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
@@ -127,38 +190,41 @@
 
 The B<Writable> column indicates whether the tag is writable by ExifTool.
-Anything but an C<N> in this column means the tag is writable.  A C<Y>
+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
-"list" tag which supports multiple values and allows individual values to be
-added and deleted.  A slash (C</>) indicates an "avoided" tag that is not
-created when writing if another same-named tag may be created instead.  To
-write 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 point (C<!>) indicates a tag that is considered
-unsafe to write under normal circumstances.  These "unsafe" tags are not set
-when calling SetNewValuesFromFile() or copied with the exiftool
--tagsFromFile option unless specified explicitly, and care should be taken
-when editing them manually since they may affect the way an image is
-rendered.  An asterisk (C<*>) indicates a "protected" tag which is not
+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 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 L<PrintConv|../ExifTool.html#PrintConv> 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<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
+taken when editing them manually since they may affect the way an image is
+rendered.  An asterisk (C<*>) indicates a I<Protected> tag which is not
 writable directly, but is written automatically by ExifTool (often when a
-corresponding Composite or Extra tag is written).  A colon (C<:>) indicates
-a mandatory tag which may be added automatically when writing.
+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.  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
-in the API, or or on a per-tag basis by appending a number symbol (C<#>) to
-the tag name.
+with the -n option on the command line, by setting the L<PrintConv|../ExifTool.html#PrintConv> option to 0
+in the API, or or on a per-tag basis by adding a hash (C<#>) after the tag
+name.
 
 B<Note>: If you are familiar with common meta-information tag names, you may
@@ -168,10 +234,19 @@
 documentation or run C<exiftool -s> on a file containing the information in
 question.
+
+I<(This documentation is the result of years of research, testing and
+reverse engineering, and is the most complete metadata tag list available
+anywhere on the internet.  It is provided not only for ExifTool users, but
+more importantly as a public service to help augment the collective
+knowledge, and is often used as a primary source of information in the
+development of other metadata software.  Please help keep this documentation
+as accurate and complete as possible, and feed any new discoveries back to
+ExifTool.  A big thanks to everyone who has helped with this so far!)>
 },
     EXIF => q{
 EXIF stands for "Exchangeable Image File Format".  This type of information
 is formatted according to the TIFF specification, and may be found in JPG,
-TIFF, PNG, PGF, MIFF, HDP, PSP and XCF images, as well as many TIFF-based
-RAW images, and even some AVI and MOV videos.
+TIFF, PNG, JP2, PGF, MIFF, HDP, PSP and XCF images, as well as many
+TIFF-based RAW images, and even some AVI and MOV videos.
 
 The EXIF meta information is organized into different Image File Directories
@@ -180,11 +255,16 @@
 B<Group> listed below is used unless another group is specified.
 
+Mandatory tags (indicated by a colon after the B<Writable> type) may be
+added automatically with default values when creating a new IFD, and the IFD
+is removed automatically when deleting tags if only default-valued mandatory
+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.3
+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/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf> for the
-official EXIF 2.3 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.
 },
     GPS => q{
@@ -201,12 +281,13 @@
 indicated string lengths include a null terminator which is added
 automatically by ExifTool.  Remember that the descriptive values are used
-when writing (ie. 'Above Sea Level', not '0') unless the print conversion is
-disabled (with '-n' on the command line or the PrintConv option in the API,
+when writing (eg. 'Above Sea Level', not '0') unless the print conversion is
+disabled (with '-n' on the command line or the L<PrintConv|../ExifTool.html#PrintConv> 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
 following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,
-GPSAltitude and GPSAltitudeRef.  ExifTool will write the required
-GPSVersionID tag automatically if new a GPS IFD is added to an image.
+and GPSAltitude and GPSAltitudeRef if the altitude is known.  ExifTool will
+write the required GPSVersionID tag automatically if new a GPS IFD is added
+to an image.
 },
     XMP => q{
@@ -214,7 +295,8 @@
 format which is being pushed by Adobe.  Information in this format can be
 embedded in many different image file types including JPG, JP2, TIFF, GIF,
-EPS, PDF, PSD, IND, PNG, DJVU, SVG, PGF, MIFF, XCF, CRW, DNG and a variety
-of proprietary TIFF-based RAW images, as well as MOV, AVI, ASF, WMV, FLV,
-SWF and MP4 videos, and WMA and audio formats supporting ID3v2 information.
+EPS, PDF, PSD, IND, INX, PNG, DJVU, SVG, PGF, MIFF, XCF, CRW, DNG and a
+variety of proprietary TIFF-based RAW images, as well as MOV, AVI, ASF, WMV,
+FLV, SWF and MP4 videos, and WMA and audio formats supporting ID3v2
+information.
 
 The XMP B<Tag ID>'s aren't listed because in most cases they are identical
@@ -229,32 +311,45 @@
 point number but stored as two C<integer> strings separated by a '/'
 character, C<date> is a date/time string entered in the format "YYYY:mm:dd
-HH:MM:SS[.ss][+/-HH:MM]", C<boolean> is either "True" or "False",
-C<lang-alt> indicates that the tag supports alternate languages (see below),
-and C<struct> is an XMP structure.  When reading, structures are extracted
-only if the Struct (-struct) option is used.  Otherwise the corresponding
-"flattened" tags, indicated by an underline (C<_>) after the B<Writable>
-type, are extracted.  When copying information, the Struct option is in
-effect by default.  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.
+HH:MM:SS[.ss][+/-HH:MM]", C<boolean> is either "True" or "False" (but "true"
+and "false" may be written as a ValueConv value for compatibility with
+non-conforming applications), C<struct> indicates a structured tag, and
+C<lang-alt> is a tag that supports alternate languages.
+
+When reading, C<struct> tags are extracted only if the L<Struct|../ExifTool.html#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 aren't copied unless
+specified explicitly.  The L<Struct|../ExifTool.html#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 L<Struct|../ExifTool.html#Struct> option
+has no effect, and both structured and flattened tags may be written.  See
+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 (ie. "XMP:Title-fr",
+name with a '-', followed by an RFC 3066 language code (eg. "XMP:Title-fr",
 or "Rights-en-US").  (See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC
 3066 specification.)  A C<lang-alt> tag with no language code accesses the
 "x-default" language, but causes other languages for this tag to be deleted
 when writing.  The "x-default" language code may be specified when writing
-to preserve other existing languages (ie. "XMP-dc:Description-x-default"). 
+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.  Note that a few of the longer namespace prefixes given below have
-been shortened for convenience (since the family 1 group names are derived
-from these by adding a leading "XMP-").  In cases where a tag name exists in
-more than one namespace, less common namespaces are avoided when writing.
-However, any namespace may be written by specifying a family 1 group name
-for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast.  When deciding on
-which tags to add to an image, using standard schemas such as
-L<dc|/XMP dc Tags>, L<xmp|/XMP xmp Tags> or L<iptc|/XMP iptcCore Tags> is
+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
+written by providing a family 1 group name for the tag (eg. XMP-crs:Contrast
+or XMP-exif:Contrast).  When deciding on which tags to add to an image,
+using standard schemas such as L<dc|/XMP dc Tags>, L<xmp|/XMP xmp Tags>,
+L<iptcCore|/XMP iptcCore Tags> and L<iptcExt|/XMP iptcExt Tags> is
 recommended if possible.
 
@@ -262,13 +357,18 @@
 names are very similar to tag names, except they are used to identify fields
 inside structures instead of stand-alone tags.  See
-L<the Field Name section of the Structured Information documentation|http://owl.phy.queensu.ca/~phil/exiftool/struct.html#Fields> for more
+L<the Field Name section of the Structured Information documentation|https://exiftool.org/struct.html#Fields> for more
 details.
 
 ExifTool will extract XMP information even if it is not listed in these
-tables.  For example, the C<pdfx> namespace doesn't have a predefined set of
-tag names because it is used to store application-defined PDF information,
-but this information is extracted by ExifTool.
-
-See L<http://www.adobe.com/devnet/xmp/> for the official XMP specification.
+tables, but other tags are not writable unless added as user-defined tags in
+the L<ExifTool config file|../config.html>.  For example, the C<pdfx> namespace doesn't have a
+predefined set of tag names because it is used to store application-defined
+PDF information, so although this information will be extracted, it is only
+writable if the corresponding user-defined tags have been created.
+
+The tables below list tags from the official XMP specification (with an
+underlined B<Namespace> in the HTML version of this documentation), as well
+as extensions from various other sources.  See
+L<http://www.adobe.com/devnet/xmp/> for the official XMP specification.
 },
     IPTC => q{
@@ -276,12 +376,12 @@
 Council (IPTC) and the Newspaper Association of America (NAA) Information
 Interchange Model (IIM).  This is an older meta information format, slowly
-being phased out in favor of XMP.  (In fact, the newer IPTCCore
-specification actually uses XMP format!)  IPTC information may be embedded
-in JPG, TIFF, PNG, MIFF, PS, PDF, PSD, XCF and DNG images.
+being phased out in favor of XMP -- the newer IPTCCore specification uses
+XMP format.  IPTC information may be found in JPG, TIFF, PNG, MIFF, PS, PDF,
+PSD, XCF and DNG images.
 
 IPTC information is separated into different records, each of which has its
 own set of tags.  See
 L<http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf> for the
-official specification.
+official IPTC IIM specification.
 
 This specification dictates a length for ASCII (C<string> or C<digits>) and
@@ -289,9 +389,10 @@
 the B<Writable> format name.  For tags where a range of lengths is allowed,
 the minimum and maximum lengths are separated by a comma within the
-brackets.  IPTC strings are not null terminated.  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 values to be written, but
-beware that values like this may cause problems for some other IPTC readers.
+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 L<IgnoreMinorErrors|../ExifTool.html#IgnoreMinorErrors> (-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.
 
 Separate IPTC date and time tags may be written with a combined date/time
@@ -306,4 +407,66 @@
 offset at the specified date/time is used, which may be different due to
 changes in daylight savings time).
+
+Note that it is not uncommon for IPTC to be found in non-standard locations
+in JPEG and TIFF-based images.  When reading, the family 1 group name has a
+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<Unknown|../ExifTool.html#Unknown> 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<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
+L<example.config|../config.html#PREF> in the full distribution for an
+example).  Note that some tags with the same name but different ID's may
+exist in the same location, but the family 7 group names may be used to
+differentiate these.  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, the default language is written and 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<QuickTimeUTC|../ExifTool.html#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 string-based date/time tags, the system time zone is added if
+the PrintConv option is enabled and no time zone is specified.  This is
+because Apple software may display crazy values if the time zone is missing
+for some tags.
+
+See
+L<https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/>
+for the official specification.
 },
     Photoshop => q{
@@ -314,21 +477,30 @@
 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 I<[and because Adobe denied my application for
-their file format documentation -- apparently open source software is too
-big a concept for them]>.  These unknown tags are not extracted unless the
-Unknown (-u) option is used.
+under normal circumstances.  These unknown tags are not extracted unless the
+L<Unknown|../ExifTool.html#Unknown> (-u) option is used.  See
+L<http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/> for the
+official specification
+
+Photoshop path tags (Tag ID's 0x7d0 to 0xbb5) are not defined by default,
+but a config file included in the full ExifTool distribution
+(config_files/photoshop_paths.config) contains the tag definitions to allow
+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<Unknown|../ExifTool.html#Unknown> (-u) option to extract PrintIM information.
 },
     GeoTiff => q{
 ExifTool extracts the following tags from GeoTIFF images.  See
 L<http://www.remotesensing.org/geotiff/spec/geotiffhome.html> for the
-complete GeoTIFF specification.
+complete GeoTIFF specification.  Also included in the table below are
+ChartTIFF tags (see L<http://www.charttiff.com/whitepapers.shtml>). GeoTIFF
+tags are not writable individually, but they may be copied en mass via the
+block tags GeoTiffDirectory, GeoTiffDoubleParams and GeoTiffAsciiParams.
 },
     JFIF => q{
 The following information is extracted from the JPEG JFIF header.  See
-L<http://www.jpeg.org/public/jfif.pdf> for the JFIF 1.02 specification.
+L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JFIF 1.02
+specification.
 },
     Kodak => q{
@@ -350,6 +522,7 @@
     Olympus => q{
 Tags 0x0000 through 0x0103 are used by some older Olympus cameras, and are
-the same as Konica/Minolta tags.  The Olympus tags are also used for Epson
-and Agfa cameras.
+the same as Konica/Minolta tags.  These tags are also used for some models
+from other brands such as Acer, BenQ, Epson, Hitachi, HP, Maginon, Minolta,
+Pentax, Ricoh, Samsung, Sanyo, SeaLife, Sony, Supra and Vivitar.
 },
     Panasonic => q{
@@ -358,14 +531,4 @@
     Pentax => q{
 These tags are used in Pentax/Asahi cameras.
-},
-    Sigma => q{
-These tags are used in Sigma/Foveon cameras.
-},
-    Sony => q{
-The maker notes in images from most recent Sony camera models contain a
-wealth of information, but for some models very little has been decoded. 
-Use the ExifTool Unknown (-u) or Verbose (-v) options to see information
-about the unknown tags.  Also see the Minolta tags which are used by some
-Sony models.
 },
     CanonRaw => q{
@@ -374,5 +537,7 @@
 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
@@ -380,6 +545,14 @@
 ExifTool is used to write XMP to a CRW image.
 },
+    NikonCustom => q{
+Unfortunately, the NikonCustom settings are stored in a binary data block
+which changes from model to model.  This means that significant effort must
+be spent in decoding these for each model, usually requiring hundreds of
+test images from a dedicated Nikon owner.  For this reason, the NikonCustom
+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<Unknown|../ExifTool.html#Unknown>
 (-u) option to display other unknown tags.
 },
@@ -393,11 +566,12 @@
 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<Password|../ExifTool.html#Password> option is provided to allow processing of
 password-protected PDF files.
 
-When writing PDF files, ExifTool uses an incremental update.  This has the
-advantages of being fast and reversible.  The original PDF can be easily
-recovered by deleting the C<PDF-update> pseudo-group (with
-C<-PDF-update:all=> on the command line).  But there are two main
+ExifTool may be used to write native PDF and XMP metadata to PDF files. It
+uses an incremental update technique that has the advantages of being both
+fast and reversible.  If ExifTool was used to modify a PDF file, the
+original may be recovered by deleting the C<PDF-update> pseudo-group (with
+C<-PDF-update:all=> on the command line).  However, there are two main
 disadvantages to this technique:
 
@@ -407,5 +581,7 @@
 2) All metadata edits are reversible.  While this would normally be
 considered an advantage, it is a potential security problem because old
-information is never actually deleted from the file.
+information is never actually deleted from the file.  (However, after
+running ExifTool the old information may be removed permanently using the
+"qpdf" utility with this command: "qpdf --linearize in.pdf out.pdf".)
 },
     DNG => q{
@@ -425,15 +601,23 @@
 },
     Extra => q{
-The extra tags represent extra information extracted or generated by
-ExifTool that is not directly associated with another tag group.  The three
-writable "pseudo" tags (FileName, Directory and FileModifyDate) may be
-written without the need to rewrite the file since their values are not
-contained within the file data.  These "pseudo" tags belong to the family 1
-"System" group.
+The extra tags provide extra features or extra information extracted or
+generated by ExifTool that is not directly associated with another tag
+group.  The B<Group> column lists the family 1 group name when reading. 
+Tags with a "-" in this column are write-only.
+
+Tags in the family 1 "System" group are referred to as "pseudo" tags because
+they don't represent real metadata in the file.  Instead, this information
+is stored in the directory structure of the filesystem.  The B<Writable>
+System "pseudo" tags in this table may be written without modifying the file
+itself.  The TestName tag is used for dry-run testing before writing
+FileName.
 },
     Composite => q{
 The values of the composite tags are B<Derived From> the values of other
 tags.  These are convenience tags which are calculated after all other
-information is extracted.
+information is extracted.  Only a few of these tags are writable directly,
+the others are changed by writing the corresponding B<Derived From> tags.
+User-defined Composite tags, also useful for custom-formatting of tag
+values, may created via the L<ExifTool configuration file|../config.html>.
 },
     Shortcuts => q{
@@ -447,4 +631,26 @@
 for more details.
 },
+    MWG => q{
+The Metadata Working Group (MWG) recommends techniques to allow certain
+overlapping EXIF, IPTC and XMP tags to be reconciled when reading, and
+synchronized when writing.  The MWG Composite tags below are designed to aid
+in the implementation of these recommendations.  As well, the MWG defines
+new XMP tags which are listed in the subsequent tables below.  See
+L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/>
+for the official MWG specification.
+},
+    MacOS => q{
+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.  (Except when reading
+MacOS "._" files directly, see below.)
+
+The tables below list some of the tags that may be extracted, but ExifTool
+will extract all available information even for tags not listed.
+
+Tags in these tables are referred to as "pseudo" tags because their
+information is not stored in the file itself.  As such, B<Writable> tags in
+these tables may be changed without having to rewrite the file.
+},
     PodTrailer => q{
 ~head1 NOTES
@@ -455,5 +661,5 @@
 ~head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -470,50 +676,38 @@
 # notes for Shortcuts tags
 my %shortcutNotes = (
+    AllDates => q{
+        contrary to the shortcut name, this represents only the common EXIF
+        date/time tags.  To access all date/time tags, use Time:All instead
+    },
     MakerNotes => q{
         useful when copying tags between files to either copy the maker notes as a
         block or prevent it from being copied
     },
+    ColorSpaceTags => q{
+        standard tags which carry color space information.  Useful for preserving
+        color space when deleting all other metadata
+    },
     CommonIFD0 => q{
         common metadata tags found in IFD0 of TIFF-format images.  Used to simpify
-        deletion of all metadata from these images.  See FAQ number 7 for details
+        deletion of all metadata from these images.  See
+        L<FAQ number 7|../faq.html#Q7> for details
     },
     Unsafe => q{
-        "unsafe" tags in JPEG images which are normally not copied.  Defined here
-        as a shortcut to use when rebuilding JPEG EXIF from scratch
+        I<Unsafe> tags in JPEG images which are normally not copied.  Defined here
+        as a shortcut to use when rebuilding JPEG EXIF from scratch. See
+        L<FAQ number 20|../faq.html#Q20> for more information
+    },
+    LargeTags => q{
+        large binary data tags which may be excluded to reduce memory usage if
+        memory limitations are a problem
+    },
+   'ls-l' => q{
+        mimics columns shown by Unix "ls -l" command.  Includes some tags which are
+        extracted only if the API L<SystemTags|../ExifTool.html#SystemTags> option
+        is enabled
     },
 );
 
 
-
-# EXIF table tag ID's which are part of the EXIF 2.3 specification
-# (used only to add underlines in HTML version of EXIF Tag Table)
-my %exifSpec = (
-    0x100 => 1,  0x212 => 1,   0x9204 => 1,  0xa217 => 1,
-    0x101 => 1,  0x213 => 1,   0x9205 => 1,  0xa300 => 1,
-    0x102 => 1,  0x214 => 1,   0x9206 => 1,  0xa301 => 1,
-    0x103 => 1,  0x8298 => 1,  0x9207 => 1,  0xa302 => 1,
-    0x106 => 1,  0x829a => 1,  0x9208 => 1,  0xa401 => 1,
-    0x10e => 1,  0x829d => 1,  0x9209 => 1,  0xa402 => 1,
-    0x10f => 1,  0x8769 => 1,  0x920a => 1,  0xa403 => 1,
-    0x110 => 1,  0x8822 => 1,  0x9214 => 1,  0xa404 => 1,
-    0x111 => 1,  0x8824 => 1,  0x927c => 1,  0xa405 => 1,
-    0x112 => 1,  0x8825 => 1,  0x9286 => 1,  0xa406 => 1,
-    0x115 => 1,  0x8827 => 1,  0x9290 => 1,  0xa407 => 1,
-    0x116 => 1,  0x8828 => 1,  0x9291 => 1,  0xa408 => 1,
-    0x117 => 1,  0x8830 => 1,  0x9292 => 1,  0xa409 => 1,
-    0x11a => 1,  0x8831 => 1,  0xa000 => 1,  0xa40a => 1,
-    0x11b => 1,  0x8832 => 1,  0xa001 => 1,  0xa40b => 1,
-    0x11c => 1,  0x8833 => 1,  0xa002 => 1,  0xa40c => 1,
-    0x128 => 1,  0x8834 => 1,  0xa003 => 1,  0xa420 => 1,
-    0x12d => 1,  0x8835 => 1,  0xa004 => 1,  0xa430 => 1,
-    0x131 => 1,  0x9000 => 1,  0xa005 => 1,  0xa431 => 1,
-    0x132 => 1,  0x9003 => 1,  0xa20b => 1,  0xa432 => 1,
-    0x13b => 1,  0x9004 => 1,  0xa20c => 1,  0xa433 => 1,
-    0x13e => 1,  0x9101 => 1,  0xa20e => 1,  0xa434 => 1,
-    0x13f => 1,  0x9102 => 1,  0xa20f => 1,  0xa435 => 1,
-    0x201 => 1,  0x9201 => 1,  0xa210 => 1,
-    0x202 => 1,  0x9202 => 1,  0xa214 => 1,
-    0x211 => 1,  0x9203 => 1,  0xa215 => 1,
-);
 # same thing for RIFF INFO tags found in the EXIF spec
 my %riffSpec = (
@@ -523,4 +717,15 @@
     ICMT => 1,  IDPI => 1,  IMED => 1,  ISFT => 1,
     ICOP => 1,  IENG => 1,  INAM => 1,  ISHP => 1,
+);
+# same thing for XMP namespaces
+my %xmpSpec = (
+    aux       => 1,   'x'        => 1,
+    crs       => 1,    xmp       => 1,
+    dc        => 1,    xmpBJ     => 1,
+    exif      => 1,    xmpDM     => 1,
+    pdf       => 1,    xmpMM     => 1,
+    pdfx      => 1,    xmpNote   => 1,
+    photoshop => 1,    xmpRights => 1,
+    tiff      => 1,    xmpTPg    => 1,
 );
 
@@ -534,5 +739,5 @@
     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,
@@ -543,6 +748,7 @@
 #
     my (%tagNameInfo, %id, %longID, %longName, %shortName, %tableNum,
-        %tagLookup, %tagExists, %tableWritable, %sepTable, %structs,
-        %compositeModules, %isPlugin, %flattened, %structLookup);
+        %tagLookup, %tagExists, %noLookup, %tableWritable, %sepTable, %case,
+        %structs, %compositeModules, %isPlugin, %flattened, %structLookup,
+        @writePseudo);
     $self->{TAG_NAME_INFO} = \%tagNameInfo;
     $self->{ID_LOOKUP} = \%id;
@@ -560,4 +766,5 @@
     $self->{COMPOSITE_MODULES} = \%compositeModules;
     $self->{COUNT} = \%count;
+    $self->{WRITE_PSEUDO} = \@writePseudo;
 
     Image::ExifTool::LoadAllTables();
@@ -566,5 +773,4 @@
     push @tableNames, 'Image::ExifTool::Shortcuts::Main';
     # add plug-in modules last
-    $Image::ExifTool::documentOnly = 1; # (don't really load them)
     foreach (@pluginTables) {
         push @tableNames, $_;
@@ -573,5 +779,5 @@
 
     my $tableNum = 0;
-    my $exifTool = new Image::ExifTool;
+    my $et = new Image::ExifTool;
     my ($tableName, $tag);
     # create lookup for short table names
@@ -583,4 +789,7 @@
         $short =~ s/^(.+)Tags$/\u$1/ unless $short eq 'Nikon AVITags';
         $short =~ s/^Exif\b/EXIF/;
+        # change underlines to dashes in XMP-mwg group names
+        # (we used underlines just because Perl variables can't contain dashes)
+        $short =~ s/^XMP mwg_/XMP mwg-/;
         $shortName{$tableName} = $short;    # remember short name
         $tableNum{$tableName} = $tableNum++;
@@ -622,22 +831,21 @@
         $longName{$tableName} = 0;
         # save all tag names
-        my ($tagID, $binaryTable, $noID, $isIPTC, $isXMP);
+        my ($tagID, $binaryTable, $noID, $hexID, $isIPTC, $isXMP);
         $isIPTC = 1 if $writeProc and $writeProc eq \&Image::ExifTool::IPTC::WriteIPTC;
         # generate flattened tag names for structure fields if this is an XMP table
         if ($$table{GROUPS} and $$table{GROUPS}{0} eq 'XMP') {
+            Image::ExifTool::XMP::AddFlattenedTags($table);
             $isXMP = 1;
-            foreach $tagID (TagTableKeys($table)) {
-                my $tagInfo = $$table{$tagID};
-                next unless ref $tagInfo eq 'HASH' and $$tagInfo{Struct};
-                Image::ExifTool::XMP::AddFlattenedTags($table, $tagID);
-            }
         }
         $noID = 1 if $isXMP or $short =~ /^(Shortcuts|ASF.*)$/ or $$vars{NO_ID};
+        $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;
-            $id{$tableName} = $$vars{ID_LABEL} || 'Index';
+            $id{$tableName} = $$vars{ID_LABEL} || "Index$s";
         } elsif ($isIPTC and $$table{PROCESS_PROC}) { #only the main IPTC table has a PROCESS_PROC
             $id{$tableName} = 'Record';
@@ -646,6 +854,7 @@
         }
         $caseInsensitive = $isXMP;
+        $numbersFirst = 2;
         $numbersFirst = -1 if $$table{VARS} and $$table{VARS}{ALPHA_FIRST};
-        my @keys = sort NumbersFirst TagTableKeys($table);
+        my @keys = SortedTagTableKeys($table);
         $numbersFirst = 1;
         my $defFormat = $table->{FORMAT};
@@ -654,5 +863,5 @@
 
 TagID:  foreach $tagID (@keys) {
-            my ($tagInfo, @tagNames, $subdir, $format, @values);
+            my ($tagInfo, @tagNames, $subdir, @values);
             my (@infoArray, @require, @writeGroup, @writable);
             if ($shortcut) {
@@ -672,18 +881,58 @@
                 @infoArray = GetTagInfoList($table,$tagID);
             }
-            $format = $defFormat;
             foreach $tagInfo (@infoArray) {
                 my $name = $$tagInfo{Name};
-                # validate Name
-                warn "Warning: Invalid tag name $short '$name'\n" if $name !~ /^[-\w]+$/;
+                if ($$tagInfo{WritePseudo}) {
+                    push @writePseudo, $name;
+                    warn "Writable pseudo tag $name is not protected!\n" unless $$tagInfo{Protected};
+                }
+                unless ($$tagInfo{SubDirectory} or $$tagInfo{Struct}) {
+                    my $lc = lc $name;
+                    warn "Different case for $tableName $name $case{$lc}\n" if $case{$lc} and $case{$lc} ne $name;
+                    $case{$lc} = $name;
+                }
+                my $format = $$tagInfo{Format};
+                # check TagID's to make sure they don't start with 'ID-'
+                my @grps = $et->GetGroup($tagInfo);
+                foreach (@grps) {
+                    warn "Group name starts with 'ID-' for $short $name\n" if /^ID-/i;
+                }
+                # validate Name (must not start with a digit or else XML output will not be valid;
+                # must not start with a dash or exiftool command line may get confused)
+                if ($name !~ /^[_A-Za-z][-\w]+$/ and
+                    # single-character subdirectory names are allowed
+                    (not $$tagInfo{SubDirectory} or $name !~ /^[_A-Za-z]$/))
+                {
+                    warn "Warning: Invalid tag name $short '${name}'\n";
+                }
+                # validate list type
+                if ($$tagInfo{List} and $$tagInfo{List} !~ /^(1|Alt|Bag|Seq|array|string)$/) {
+                    warn "Warning: Unknown List type ($$tagInfo{List}) for $name in $tableName\n";
+                }
                 # accumulate information for consistency check of BinaryData tables
                 if ($processBinaryData and $$table{WRITABLE}) {
+                    # can't currently write tag if Condition accesses $valPt
+                    if ($$tagInfo{Condition} and not $$tagInfo{SubDirectory} and
+                        $$tagInfo{Condition} =~ /\$valPt/ and
+                        ($$tagInfo{Writable} or not defined $$tagInfo{Writable}))
+                    {
+                        warn "Warning: Tag not writable due to Condition - $short $name\n";
+                    }
                     $isOffset{$tagID} = $name if $$tagInfo{IsOffset};
                     $hasSubdir{$tagID} = $name if $$tagInfo{SubDirectory};
                     # require DATAMEMBER for writable var-format tags, Hook and DataMember tags
-                    if ($$tagInfo{Format} and $$tagInfo{Format} =~ /^var_/) {
+                    if ($format and $format =~ /^var_/) {
                         $datamember{$tagID} = $name;
                         unless (defined $$tagInfo{Writable} and not $$tagInfo{Writable}) {
                             warn "Warning: Var-format tag is writable - $short $name\n"
+                        }
+                        # also need DATAMEMBER for tags used in length of var-sized value
+                        while ($format =~ /\$val\{(.*?)\}/g) {
+                            my $id = $1;
+                            $id = hex($id) if $id =~ /^0x/; # convert from hex if necessary
+                            $datamember{$id} = $$table{$id}{Name} if ref $$table{$id} eq 'HASH';
+                            unless ($datamember{$id}) {
+                                warn "Warning: Unknown ID ($id) used in Format - $short $name\n";
+                            }
                         }
                     } elsif ($$tagInfo{Hook} or ($$tagInfo{RawConv} and
@@ -692,8 +941,16 @@
                         $datamember{$tagID} = $name;
                     }
+                    if ($format and $format =~ /\$val\{/ and
+                        ($$tagInfo{Writable} or not defined $$tagInfo{Writable}))
+                    {
+                        warn "Warning: \$var{} used in Format of writable tag - $short $name\n"
+                    }
                 }
                 if ($$tagInfo{Hidden}) {
-                    warn "Warning: Hidden tag in list - $short $name\n" if @infoArray > 1;
-                    next TagID;
+                    if ($tagInfo == $infoArray[0]) {
+                        next TagID; # hide all tags with this ID if first tag in list is hidden
+                    } else {
+                        next;       # only hide this tag
+                    }
                 }
                 my $writable;
@@ -702,21 +959,39 @@
                     # validate Writable
                     unless ($formatOK{$writable} or  ($writable =~ /(.*)\[/ and $formatOK{$1})) {
-                        warn "Warning: Unknown Writable ($writable) for $short $name\n",
+                        warn "Warning: Unknown Writable ($writable) - $short $name\n",
                     }
                 } 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
+                    not $$tagInfo{PrintConvInv})
+                {
+                    # (this is a problem because shifting Time:All would create a new list entry)
+                    warn "Writable List-type Time tag $g[1]:$name has no PrintConvInv and is not Protected!\n";
+                }
                 if ($$tagInfo{PrintConv} and $$tagInfo{PrintConv} eq '$self->ConvertDateTime($val)') {
-                    my @g = $exifTool->GetGroup($tagInfo);
                     warn "$short $name should be in 'Time' group!\n" unless $g[2] eq 'Time';
-                    if ($writable and not $$tagInfo{Shift} and $g[0] ne 'Composite' and
-                        $short ne 'PostScript')
+                    if ($writable and not defined $$tagInfo{Shift} and $short ne 'PostScript') {
+                        warn "$short $name is not shiftable!\n";
+                    }
+                    if ($writable and (not $$tagInfo{PrintConvInv} or
+                        $$tagInfo{PrintConvInv} !~ /InverseDateTime/))
                     {
-                        warn "$short $name is not shiftable!\n";
+                        warn "$short $name missing InverseDateTime PrintConvInv\n";
                     }
                 } elsif ($name =~ /DateTime(?!Stamp)/ and (not $$tagInfo{Groups}{2} or
                     $$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)
@@ -728,6 +1003,5 @@
                     warn "$name description contains special characters!\n";
                 }
-                # validate SubIFD flag
-                my $subdir = $$tagInfo{SubDirectory};
+                # generate structure lookup
                 my $struct = $$tagInfo{Struct};
                 my $strTable;
@@ -749,9 +1023,12 @@
                     $strTable = $structLookup{$struct};
                     unless ($strTable) {
-                        warn "Missing XMP $struct structure!\n";
+                        $struct = "XMP $struct" unless $struct =~ / /;
+                        warn "Missing $struct structure!\n";
                         undef $struct;
                     }
                 }
-                my $isSub = ($subdir and $$subdir{Start} and $$subdir{Start} eq '$val');
+                # validate SubIFD flag
+                my $subdir = $$tagInfo{SubDirectory};
+                my $isSub = ($subdir and $$subdir{Start} and $$subdir{Start} =~ /\$val\b/);
                 if ($$tagInfo{SubIFD}) {
                     warn "Warning: Wrong SubDirectory Start for SubIFD tag - $short $name\n" unless $isSub;
@@ -762,24 +1039,34 @@
                     my $note = $$tagInfo{Notes};
                     # remove leading/trailing blank lines
-                    $note =~ s/(^\s+|\s+$)//g;
+                    $note =~ s/^\s+//; $note =~ s/\s+$//;
                     # remove leading/trailing spaces on each line
                     $note =~ s/(^[ \t]+|[ \t]+$)//mg;
                     push @values, "($note)";
-                } elsif ($isXMP and lc $tagID ne lc $name) {
-                    # add note about different XMP Tag ID
-                    if ($$tagInfo{RootTagInfo}) {
-                        push @values, "($tagID)";
+                }
+                if ($isXMP and (lc $tagID ne lc $name or $$tagInfo{NotFlat})) {
+                    my $note;
+                    if ($$tagInfo{NotFlat}) {
+                        $note = 'NOT a flattened tag!';
                     } else {
-                        push @values,"(called $tagID by the spec)";
+                        # add note about different XMP Tag ID
+                        $note = $$tagInfo{RootTagInfo} ? $tagID : "called $tagID by the spec";
+                    }
+                    if ($$tagInfo{Notes}) {
+                        $values[-1] =~ s/^\(/($note; /;
+                    } else {
+                        push @values, "($note)";
                     }
                 }
                 my $writeGroup;
-                $writeGroup = $$tagInfo{WriteGroup};
+                if ($short eq 'Extra') {
+                    $writeGroup = $$tagInfo{WriteOnly} ? '-' : $g[1];
+                } else {
+                    $writeGroup = $$tagInfo{WriteGroup};
+                }
                 unless ($writeGroup) {
                     $writeGroup = $$table{WRITE_GROUP} if $writable;
                     $writeGroup = '-' unless $writeGroup;
                 }
-                if (defined $$tagInfo{Format}) {
-                    $format = $$tagInfo{Format};
+                if (defined $format) {
                     # validate Format
                     unless ($formatOK{$format} or $short eq 'PICT' or
@@ -788,4 +1075,6 @@
                         warn "Warning: Unknown Format ($format) for $short $name\n";
                     }
+                } else {
+                    $format = $defFormat;
                 }
                 if ($subdir) {
@@ -810,13 +1099,13 @@
                 if ($$tagInfo{Mask}) {
                     my $val = $$tagInfo{Mask};
-                    push @values, sprintf('[Mask 0x%.2x]',$val);
-                    $$tagInfo{PrintHex} = 1 unless defined $$tagInfo{PrintHex};
+                    my $bsh = $$tagInfo{BitShift};
+                    if ($bsh) {
+                        push @values, sprintf('[val >> %d & 0x%x]',$bsh,$val>>$bsh);
+                    } else {
+                        push @values, sprintf('[val & 0x%x]',$val);
+                    }
                     # verify that all values are within the mask
                     if (ref $printConv eq 'HASH') {
-                        # convert mask if necessary
-                        if ($$tagInfo{ValueConv}) {
-                            my $v = eval $$tagInfo{ValueConv};
-                            $val = $v if defined $v;
-                        }
+                        $val >>= $$tagInfo{BitShift};
                         foreach (keys %$printConv) {
                             next if $_ !~ /^\d+$/ or ($_ & $val) == $_;
@@ -827,11 +1116,17 @@
                 }
                 if (ref($printConv) =~ /^(HASH|ARRAY)$/) {
-                    my (@printConvList, @indexList, $index);
+                    my (@printConvList, @indexList, $index, $valueConvHash);
                     if (ref $printConv eq 'ARRAY') {
                         for ($index=0; $index<@$printConv; ++$index) {
-                            next if ref $$printConv[$index] ne 'HASH';
-                            next unless %{$$printConv[$index]};
-                            push @printConvList, $$printConv[$index];
-                            push @indexList, $index;
+                            if (ref $$printConv[$index] eq 'HASH') {
+                                next unless %{$$printConv[$index]};
+                                push @printConvList, $$printConv[$index];
+                                push @indexList, $index;
+                            } elsif ($$printConv[$index] and $$printConv[$index] eq 'REPEAT' and $index) {
+                                push @printConvList, $$printConv[$index-1];
+                                push @indexList, 'N';
+                            } else {
+                                next;
+                            }
                             # collapse values with identical PrintConv's
                             if (@printConvList >= 2 and $printConvList[-1] eq $printConvList[-2]) {
@@ -847,4 +1142,6 @@
                         $printConv = shift @printConvList;
                         $index = shift @indexList;
+                    } else {
+                        $valueConvHash = $$tagInfo{ValueConv} if ref $$tagInfo{ValueConv} eq 'HASH';
                     }
                     while (defined $printConv) {
@@ -858,9 +1155,9 @@
                                 my ($i, @i, $rngStart);
                                 for ($i=0; $i<@$idx; ++$i) {
-                                    if ($i < @$idx - 1 and $$idx[$i+1] == $$idx[$i] + 1) {
-                                        $rngStart = $i unless defined $rngStart;
+                                    if ($i < @$idx - 1 and ($$idx[$i+1] eq 'N' or $$idx[$i+1] == $$idx[$i] + 1)) {
+                                        $rngStart = $$idx[$i] unless defined $rngStart;
                                         next;
                                     }
-                                    push @i, defined($rngStart) ? "$rngStart-$i" : $i;
+                                    push @i, (defined($rngStart) ? "$rngStart-" : '') . $$idx[$i];
                                 }
                                 ($idx = join ', ', @i) =~ s/(.*),/$1 and/;
@@ -890,14 +1187,28 @@
                         } else {
                             $caseInsensitive = 0;
-                            my @pk = sort NumbersFirst keys %$printConv;
+                            my @pk;
+                            if ($$tagInfo{PrintSort}) {
+                                @pk = sort { NumbersFirst($$printConv{$a},$$printConv{$b}) } keys %$printConv;
+                            } else {
+                                @pk = sort { NumbersFirst($a,$b) } keys %$printConv;
+                            }
                             my $n = scalar @values;
-                            my ($bits, $cols, $i);
+                            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;
-                                if (($$tagInfo{PrintHex} or $$printConv{BITMASK}) and /^\d+$/) {
-                                    $index = sprintf('0x%x',$_);
+                                if (($$tagInfo{PrintHex} or $$printConv{BITMASK}) and /^-?\d+$/) {
+                                    my $dig = $$tagInfo{PrintHex} || 1;
+                                    if ($_ >= 0) {
+                                        $index = sprintf('0x%.*x', $dig, $_);
+                                    } elsif ($format and $format =~ /int(16|32)/) {
+                                        # mask off unused bits of signed integer hex value
+                                        my $mask = { 16 => 0xffff, 32 => 0xffffffff }->{$1};
+                                        $index = sprintf('0x%.*x', $dig, $_ & $mask);
+                                    } else {
+                                        $index = $_;
+                                    }
                                 } elsif (/^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/ and not $$tagInfo{PrintString}) {
                                     $index = $_;
@@ -908,8 +1219,15 @@
                                         $index = qq{"$index"};
                                     } else {
-                                        $index = qq{'$index'};
+                                        $index = qq{'${index}'};
                                     }
                                 }
                                 push @values, "$index = " . $$printConv{$_};
+                                if ($valueConvHash) {
+                                    foreach $v (keys %$valueConvHash) {
+                                        next unless $$valueConvHash{$v} eq $_;
+                                        $values[-1] = "$v => " . $values[-1];
+                                        last;
+                                    }
+                                }
                                 # validate all PrintConv values
                                 if ($$printConv{$_} =~ /[\0-\x1f\x7f-\xff]/) {
@@ -918,5 +1236,5 @@
                             }
                             if ($bits) {
-                                my @pk = sort NumbersFirst keys %$bits;
+                                my @pk = sort { NumbersFirst($a,$b) } keys %$bits;
                                 foreach (@pk) {
                                     push @values, "Bit $_ = " . $$bits{$_};
@@ -924,9 +1242,22 @@
                             }
                             # organize values into columns if specified
-                            if (defined($cols = $$tagInfo{PrintConvColumns})) {
+                            my $cols = $$tagInfo{PrintConvColumns};
+                            if (not $cols and scalar(@values) - $n >= 6) {
+                                # do columns if more than 6 short entries
+                                my $maxLen = 0;
+                                for ($i=$n; $i<@values; ++$i) {
+                                    next unless $maxLen < length $values[$i];
+                                    $maxLen = length $values[$i];
+                                }
+                                my $num = scalar(@values) - $n;
+                                $cols = int(50 / ($maxLen + 2)); # (50 chars max width)
+                                # have 3 rows minimum
+                                --$cols while $cols and $num / $cols < 3;
+                            }
+                            if ($cols) {
                                 my @new = splice @values, $n;
                                 my $v = '[!HTML]<table class=cols><tr>';
                                 my $rows = int((scalar(@new) + $cols - 1) / $cols);
-                                for ($n=0; $n<@new; $n+=$rows) {
+                                for ($n=0; ;) {
                                     $v .= "\n  <td>";
                                     for ($i=0; $i<$rows and $n+$i<@new; ++$i) {
@@ -934,5 +1265,7 @@
                                         $v .= EscapeHTML($new[$n+$i]);
                                     }
-                                    $v .= '</td><td>&nbsp;&nbsp;</td>';
+                                    $v .= '</td>';
+                                    last if ($n += $rows) >= @new;
+                                    $v .= '<td>&nbsp;&nbsp;</td>'; # add spaces between columns
                                 }
                                 push @values, $v . "</tr></table>\n";
@@ -950,5 +1283,5 @@
                         warn $@;
                     } else {
-                        my @pk = sort NumbersFirst keys %$bits;
+                        my @pk = sort { NumbersFirst($a,$b) } keys %$bits;
                         foreach (@pk) {
                             push @values, "Bit $_ = " . $$bits{$_};
@@ -957,8 +1290,19 @@
                 }
                 if ($subdir and not $$tagInfo{SeparateTable}) {
-                    # subdirectories are only writable if specified explicitly
-                    my $tw = $$tagInfo{Writable};
-                    $writable = '-' . ($tw ? $writable : '');
-                    $writable .= '!' if $tw and ($$tagInfo{Protected} || 0) & 0x01;
+                    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
@@ -978,7 +1322,7 @@
                     }
                     if (not $writable) {
-                        $writable = 'N';
+                        $writable = 'no';
                     } else {
-                        $writable eq '1' and $writable = $format ? $format : 'Y';
+                        $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
@@ -1008,4 +1352,9 @@
                     $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;
@@ -1028,17 +1377,21 @@
                 }
 #
-# add this tag to the tag lookup unless PROCESS_PROC is 0 or shortcut or plug-in tag
+# add this tag to the tag lookup unless NO_LOOKUP is set or shortcut or plug-in tag
 #
                 next if $shortcut or $isPlugin;
-                next if defined $$table{PROCESS_PROC} and not $$table{PROCESS_PROC};
-                # count our tags
+                # count tags
                 if ($$tagInfo{SubDirectory}) {
+                    next if $$vars{NO_LOOKUP};
                     $subdirs{$lcName} or $subdirs{$lcName} = 0;
                     ++$subdirs{$lcName};
                 } else {
                     ++$count{'total tags'};
-                    unless ($tagExists{$lcName} and (not $subdirs{$lcName} or $subdirs{$lcName} == $tagExists{$lcName})) {
-                        ++$count{'unique tag names'};
-                    }
+                    unless ($tagExists{$lcName} and
+                        (not $subdirs{$lcName} or $subdirs{$lcName} == $tagExists{$lcName}))
+                    {
+                        ++$count{'unique tag names'} unless $noLookup{$lcName};
+                    }
+                    # don't add to tag lookup if specified
+                    $$vars{NO_LOOKUP} and $noLookup{$lcName} = 1, next;
                 }
                 $tagExists{$lcName} or $tagExists{$lcName} = 0;
@@ -1071,7 +1424,6 @@
                 $tableWritable{$tableName} = 1;
                 $tagLookup{$lcName}->{$tableNum} = $tagIDs;
-                if ($short eq 'Composite' and $$tagInfo{Module}) {
-                    $compositeModules{$lcName} = $$tagInfo{Module};
-                }
+                # keep track of extra modules needed for Composite tags
+                $compositeModules{$lcName} = $$tagInfo{Module} if $$tagInfo{Module};
             }
 #
@@ -1079,16 +1431,22 @@
 #
             my $tagIDstr;
-            if ($tagID =~ /^\d+(\.\d+)?$/) {
-                if ($1 or $binaryTable or $isIPTC or ($short =~ /^CanonCustom/ and $tagID < 256)) {
-                    if ($tagID < 0x10000) {
-                        $tagIDstr = $tagID;
-                    } else {
-                        $tagIDstr = sprintf('0x%.8x',$tagID);
-                    }
+            if ($tagID =~ /^(-)?\d+(\.\d+)?$/) {
+                if ($1) {
+                    $tagIDstr = $tagID;
+                } elsif (defined $hexID) {
+                    $tagIDstr = $hexID ? sprintf('0x%.4x',$tagID) : $tagID;
+                } elsif (not $2 and not $binaryTable and not $isIPTC and
+                         not ($short =~ /^CanonCustom/ and $tagID < 256))
+                {
+                    $tagIDstr = sprintf('0x%.4x',$tagID);
+                } elsif ($tagID < 0x10000) {
+                    $tagIDstr = $tagID;
                 } else {
-                    $tagIDstr = sprintf('0x%.4x',$tagID);
+                    $tagIDstr = sprintf('0x%.8x',$tagID);
                 }
             } elsif ($short eq 'DICOM') {
                 ($tagIDstr = $tagID) =~ s/_/,/;
+            } elsif ($tagID =~ /^0x([0-9a-f]+)\.(\d+)$/) {  # DR4 tags like '0x20500.0'
+                $tagIDstr = $tagID;
             } else {
                 # convert non-printable characters to hex escape sequences
@@ -1098,5 +1456,5 @@
                     $tagIDstr = qq{"$tagID"};
                 } else {
-                    $tagIDstr = "'$tagID'";
+                    $tagIDstr = "'${tagID}'";
                 }
             }
@@ -1122,9 +1480,11 @@
                     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);
                 }
             }
@@ -1135,9 +1495,11 @@
     foreach $strName (keys %structs) {
         my $struct = $structLookup{$strName};
-        my $info = $tagNameInfo{"XMP $strName Struct"} = [ ];
+        my $fullName = ($strName =~ / / ? '' : 'XMP ') . "$strName Struct";
+        my $info = $tagNameInfo{$fullName} = [ ];
         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' and $tag ne 'GROUPS';
+            warn "WARNING: $strName Struct containes $tag\n" if $Image::ExifTool::specialTags{$tag};
             my $writable = $$tagInfo{Writable};
             my @vals;
@@ -1154,4 +1516,13 @@
             }
             $writable .= '+' if $$tagInfo{List};
+            push @vals, "($$tagInfo{Notes})" if $$tagInfo{Notes};
+            # handle PrintConv lookups in Structure elements
+            my $printConv = $$tagInfo{PrintConv};
+            if (ref $printConv eq 'HASH') {
+                foreach (sort keys %$printConv) {
+                    next if /^(OTHER|BITMASK)$/;
+                    push @vals, "$_ = $$printConv{$_}";
+                }
+            }
             push @$info, [
                 $tag,
@@ -1169,5 +1540,5 @@
 # Rewrite this file to build the lookup tables
 # Inputs: 0) BuildTagLookup object reference
-#         1) output tag lookup module name (ie. 'lib/Image/ExifTool/TagLookup.pm')
+#         1) output tag lookup module name (eg. 'lib/Image/ExifTool/TagLookup.pm')
 # Returns: true on success
 sub WriteTagLookup($$)
@@ -1210,5 +1581,5 @@
     foreach $tableName (@tableNames) {
         if ($$tableWritable{$tableName}) {
-            print OUTFILE "\t'$tableName',\n";
+            print OUTFILE "\t'${tableName}',\n";
             $wrNum{$count} = $num++;
         }
@@ -1223,9 +1594,9 @@
         next unless $$tagLookup{$tag};
         my $n = scalar keys %{$$tagLookup{$tag}};
-        warn "Warning: $n writable '$tag' tags!\n" if $n > 1;
+        warn "Warning: $n writable '${tag}' tags!\n" if $n > 1;
     }
     print OUTFILE ");\n\n# lookup for all writable tags\nmy \%tagLookup = (\n";
     foreach $tag (sort keys %$tagLookup) {
-        print OUTFILE "\t'$tag' => { ";
+        print OUTFILE "\t'${tag}' => { ";
         my @tableNums = sort { $a <=> $b } keys %{$$tagLookup{$tag}};
         my (@entries, $tableNum);
@@ -1249,10 +1620,13 @@
                 # reference to root structure ID must come first in lookup
                 # (so we can generate the flattened tags just before we need them)
-                unshift @tagIDs, "\\'$rootID'" if $rootID;
+                unshift @tagIDs, "\\'${rootID}'" if $rootID;
                 $entry = '[' . join(',', @tagIDs) . ']';
             } 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};
@@ -1269,5 +1643,5 @@
     foreach $tag (sort keys %$tagExists) {
         next if $$tagLookup{$tag};
-        print OUTFILE "\t'$tag' => 1,\n";
+        print OUTFILE "\t'${tag}' => 1,\n";
     }
 #
@@ -1278,5 +1652,5 @@
     print OUTFILE "my \%compositeModules = (\n";
     foreach (sort keys %$compositeModules) {
-        print OUTFILE "\t'$_' => '$$compositeModules{$_}',\n";
+        print OUTFILE "\t'${_}' => '$$compositeModules{$_}',\n";
     }
     print OUTFILE ");\n\n";
@@ -1325,18 +1699,40 @@
 
 #------------------------------------------------------------------------------
-# sort numbers first numerically, then strings alphabetically (case insensitive)
-sub NumbersFirst
+# Sort numbers first numerically, then strings alphabetically (case insensitive)
+# - two global variables are used to change the sort algorithm:
+#   $numbersFirst: -1 = put numbers after other strings
+#                   1 = put numbers before other strings
+#                   2 = put numbers first, but negative numbers last
+#   $caseInsensitive: flag set for case-insensitive sorting
+sub NumbersFirst($$)
 {
+    my ($a, $b) = @_;
     my $rtnVal;
-    my $bNum = ($b =~ /^-?[0-9]+(\.\d*)?$/);
-    if ($a =~ /^-?[0-9]+(\.\d*)?$/) {
-        $rtnVal = ($bNum ? $a <=> $b : -$numbersFirst);
-    } elsif ($bNum) {
+    my ($bNum, $bDec);
+    ($bNum, $bDec) = ($1, $3) if $b =~ /^(-?[0-9]+)(\.(\d*))?$/;
+    if ($a =~ /^(-?[0-9]+)(\.(\d*))?$/) {
+        if (defined $bNum) {
+            $bNum += 1e9 if $numbersFirst == 2 and $bNum < 0;
+            my $aInt = $1;
+            $aInt += 1e9 if $numbersFirst == 2 and $aInt < 0;
+            # compare integer part as a number
+            $rtnVal = $aInt <=> $bNum;
+            unless ($rtnVal) {
+                my $aDec = $3 || 0;
+                $bDec or $bDec = 0;
+                # compare decimal part as an integer too
+                # (so that "1.10" comes after "1.9")
+                $rtnVal = $aDec <=> $bDec;
+            }
+        } else {
+            $rtnVal = -$numbersFirst;
+        }
+    } elsif (defined $bNum) {
         $rtnVal = $numbersFirst;
     } else {
         my ($a2, $b2) = ($a, $b);
         # expand numbers to 3 digits (with restrictions to avoid messing up ascii-hex tags)
-        $a2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $a2 =~ /^(APP)?[.0-9 ]*$/ and length($a2)<16;
-        $b2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $b2 =~ /^(APP)?[.0-9 ]*$/ and length($b2)<16;
+        $a2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $a2 =~ /^(APP|DMC-\w+ )?[.0-9 ]*$/ and length($a2)<16;
+        $b2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $b2 =~ /^(APP|DMC-\w+ )?[.0-9 ]*$/ and length($b2)<16;
         $caseInsensitive and $rtnVal = (lc($a2) cmp lc($b2));
         $rtnVal or $rtnVal = ($a2 cmp $b2);
@@ -1346,5 +1742,5 @@
 
 #------------------------------------------------------------------------------
-# Convert pod documentation to pod
+# Convert our pod-like documentation to pod
 # (funny, I know, but the pod headings must be hidden to prevent confusing
 #  the pod parser)
@@ -1357,9 +1753,10 @@
     $doc =~ s/\n~/\n=/g;
     $doc =~ s/L<[^>]+?\|(http[^>]+)>/L<$1>/g; # POD doesn't support text for http links
+    $doc =~ s/L<([^>]+?)\|[^>]+\.html(#\w+)?>/$1/g;  # remove relative HTML links
     return $doc;
 }
 
 #------------------------------------------------------------------------------
-# Convert pod documentation to html
+# Convert our pod-like documentation to html
 # Inputs: 0) string
 sub Doc2Html($)
@@ -1370,18 +1767,97 @@
     $doc =~ s/C&lt;(.*?)&gt;/<code>$1<\/code>/sg;
     $doc =~ s/I&lt;(.*?)&gt;/<i>$1<\/i>/sg;
-    $doc =~ s{L&lt;([^&]+?)\|\Q$homePage\E/TagNames/(.*?)&gt;}{<a href="$2">$1<\/a>}sg;
+    # L<some text|https://exiftool.org/struct.html#Fields> --> <a href="../struct.html#Fields">some text</a>
     $doc =~ s{L&lt;([^&]+?)\|\Q$homePage\E/(.*?)&gt;}{<a href="../$2">$1<\/a>}sg;
-    $doc =~ s{L&lt;\Q$homePage\E/TagNames/(.*?)&gt;}{<a href="$1">$1<\/a>}sg;
+    # L<https://exiftool.org/struct.html> --> <a href="https://exiftool.org/struct.html">https://exiftool.org/struct.html</a>
     $doc =~ s{L&lt;\Q$homePage\E/(.*?)&gt;}{<a href="../$1">$1<\/a>}sg;
+    # L<XMP DICOM Tags|Image::ExifTool::TagNames/XMP DICOM Tags> --> <a href="XMP.html#DICOM">XMP DICOM Tags</a>
+    # (specify "Image::ExifTool::TagNames" to link to another html file)
+    $doc =~ s{L&lt;([^&]+?)\|Image::ExifTool::TagNames/(\w+) ([^/&|]+) Tags&gt;}{<a href="$2.html#$3">$1</a>}sg;
+    # L<DICOM Tags|Image::ExifTool::TagNames/DICOM Tags> --> <a href="DICOM.html">DICOM Tags</a>
+    $doc =~ s{L&lt;([^&]+?)\|Image::ExifTool::TagNames/(\w+) Tags&gt;}{<a href="$2.html">$1</a>}sg;
+    # L<dc|/XMP dc Tags> --> <a href="#dc">dc</a>
+    # (a relative POD link turns into a relative HTML link)
     $doc =~ s{L&lt;([^&]+?)\|/\w+ ([^/&|]+) Tags&gt;}{<a href="#$2">$1</a>}sg;
+    # L<sample config file|../config.html> --> <a href="../config.html">sample config file</a>
     $doc =~ s/L&lt;([^&]+?)\|(.+?)&gt;/<a href="$2">$1<\/a>/sg;
-    $doc =~ s/L&lt;(.*?)&gt;/<a href="$1">$1<\/a>/sg;
+    # L<http://some.web.site/> --> <a href="http://some.web.site">http://some.web.site</a>
+    $doc =~ s/L&lt;(http.*?)&gt;/<a href="$1">$1<\/a>/sg;
     return $doc;
 }
 
 #------------------------------------------------------------------------------
+# Tweak order of tables
+# Inputs: 0) table list ref, 1) reference to tweak hash
+sub TweakOrder($$)
+{
+    local $_;
+    my ($sortedTables, $tweakOrder) = @_;
+    my @tweak = sort keys %$tweakOrder;
+    my (%addedMain, @sorted);
+    # flag files which have a "Main" table
+    foreach (@$sortedTables) {
+        $addedMain{$1} = 0 if /^Image::ExifTool::(\w+)::(\w+)/ and $2 eq 'Main';
+    }
+    # make sure that the main table always comes first in each file
+    foreach (@$sortedTables) {
+        if (/^Image::ExifTool::(\w+)::(\w+)/) {
+            if ($addedMain{$1}) {
+                next if $2 eq 'Main';   # don't add again
+            } elsif (defined $addedMain{$1}) {
+                push @sorted, "Image::ExifTool::${1}::Main" if $2 ne 'Main';
+                $addedMain{$1} = 1;
+            }
+        }
+        push @sorted, $_;
+    }
+    @$sortedTables = @sorted;
+    # apply manual tweaks
+    while (@tweak) {
+        my $table = shift @tweak;
+        my $first = $$tweakOrder{$table};
+        if ($$tweakOrder{$first}) {
+            push @tweak, $table;    # must defer this till later
+            next;
+        }
+        delete $$tweakOrder{$table}; # because the table won't move again
+        my @moving = grep /^Image::ExifTool::$table\b/, @$sortedTables;
+        my @notMoving = grep !/^Image::ExifTool::$table\b/, @$sortedTables;
+        my @after;
+        while (@notMoving) {
+            last if $notMoving[-1] =~ /^Image::ExifTool::$first\b/;
+            unshift @after, pop @notMoving;
+        }
+        @$sortedTables = (@notMoving, @moving, @after);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get a list of sorted tag ID's from a table
+# Inputs: 0) tag table ref
+# Returns: list of sorted keys
+sub SortedTagTableKeys($)
+{
+    my $table = shift;
+    my $vars = $$table{VARS} || { };
+    my @keys = TagTableKeys($table);
+    if ($$vars{NO_ID}) {
+        # sort by tag name if ID not shown
+        my ($key, %name);
+        foreach $key (@keys) {
+            my ($tagInfo) = GetTagInfoList($table, $key);
+            $name{$key} = $$tagInfo{Name};
+        }
+        return sort { $name{$a} cmp $name{$b} or $a cmp $b } @keys;
+    } else {
+        my $sortProc = $$vars{SORT_PROC} || \&NumbersFirst;
+        return sort { &$sortProc($a,$b) } @keys;
+    }
+}
+
+#------------------------------------------------------------------------------
 # Get the order that we want to print the tables in the documentation
+# Inputs: 0-N) Extra tables to add at end
 # Returns: tables in the order we want
-sub GetTableOrder()
+sub GetTableOrder(@)
 {
     my %gotTable;
@@ -1406,5 +1882,5 @@
         $caseInsensitive = ($$table{GROUPS} and $$table{GROUPS}{0} eq 'XMP');
         $numbersFirst = -1 if $$table{VARS} and $$table{VARS}{ALPHA_FIRST};
-        my @keys = sort NumbersFirst TagTableKeys($table);
+        my @keys = SortedTagTableKeys($table);
         $numbersFirst = 1;
         foreach (@keys) {
@@ -1450,55 +1926,10 @@
         }
     }
+    # add the extra tables
+    push @sortedTables, @_;
     # tweak the table order
-    my %tweakOrder = (
-        JPEG    => '-',     # JPEG comes first
-        IPTC    => 'Exif',  # put IPTC after EXIF,
-        GPS     => 'XMP',   # etc...
-        GeoTiff => 'GPS',
-        CanonVRD=> 'CanonCustom',
-        Kodak   => 'JVC',
-       'Kodak::IFD' => 'Kodak::Unknown',
-       'Kodak::TextualInfo' => 'Kodak::IFD',
-       'Kodak::Processing' => 'Kodak::TextualInfo',
-        Leaf    => 'Kodak',
-        Minolta => 'Leaf',
-        SonyIDC => 'Sony',
-        Unknown => 'SonyIDC',
-        DNG     => 'Unknown',
-        PrintIM => 'ICC_Profile',
-        ID3     => 'PostScript',
-        MinoltaRaw => 'KyoceraRaw',
-        KyoceraRaw => 'CanonRaw',
-        SigmaRaw => 'PanasonicRaw',
-        Olympus => 'NikonCapture',
-        PhotoMechanic => 'FotoStation',
-        Microsoft     => 'PhotoMechanic',
-       'Microsoft::MP'=> 'Microsoft::MP1',
-        GIMP    => 'Microsoft',
-       'Nikon::CameraSettingsD300' => 'Nikon::ShotInfoD300b',
-       'Pentax::LensData' => 'Pentax::LensInfo2',
-       'Sony::SRF2' => 'Sony::SRF',
-       'Samsung::INFO' => 'Samsung::Type2', # (necessary because Samsung doesn't have a main table)
-       'Samsung::MP4' => 'Samsung::INFO', # (necessary because Samsung doesn't have a main table)
-    );
-    my @tweak = sort keys %tweakOrder;
-    while (@tweak) {
-        my $table = shift @tweak;
-        my $first = $tweakOrder{$table};
-        if ($tweakOrder{$first}) {
-            push @tweak, $table;    # must defer this till later
-            next;
-        }
-        delete $tweakOrder{$table}; # because the table won't move again
-        my @moving = grep /^Image::ExifTool::$table\b/, @sortedTables;
-        my @notMoving = grep !/^Image::ExifTool::$table\b/, @sortedTables;
-        my @after;
-        while (@notMoving) {
-            last if $notMoving[-1] =~ /^Image::ExifTool::$first\b/;
-            unshift @after, pop @notMoving;
-        }
-        @sortedTables = (@notMoving, @moving, @after);
-    }
-    return @sortedTables
+    TweakOrder(\@sortedTables, \%tweakOrder);
+
+    return @sortedTables;
 }
 
@@ -1519,5 +1950,5 @@
         $htmlFile = "$htmldir/TagNames/$class.html";
         $head = $category;
-        if ($head =~ /^XMP .+ Struct$/) {
+        if ($head =~ /^\S+ .+ Struct$/) {
             pop @names;
         } else {
@@ -1535,5 +1966,7 @@
     } 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";
@@ -1545,5 +1978,5 @@
         }
     }
-    $head = "<a name='$url'>$head</a>" if $url;
+    $head = "<a name='${url}'>$head</a>" if $url;
     print HTMLFILE "<h2$top>$head</h2>\n" or return 0;
     print HTMLFILE '<p>',Doc2Html($docs{$category}),"</p>\n" if $docs{$category};
@@ -1580,4 +2013,5 @@
         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=";
@@ -1628,8 +2062,19 @@
 
 #------------------------------------------------------------------------------
+# Get bitmask for POD documentation
+# Inputs: mask string from HTML docs
+# Returns: mask string for POD, or ''
+sub PodMask($)
+{
+    my $mask = shift;
+    return '' unless $mask =~ /^\[val( >> (\d+))? \& (0x[\da-f]+)\]/;
+    return sprintf(' & 0x%.2x', hex($3) << ($2 || 0));
+}
+
+#------------------------------------------------------------------------------
 # Write the TagName HTML and POD documentation
 # Inputs: 0) BuildTagLookup object reference
-#         1) output pod file (ie. 'lib/Image/ExifTool/TagNames.pod')
-#         2) output html directory (ie. 'html')
+#         1) output pod file (eg. 'lib/Image/ExifTool/TagNames.pod')
+#         2) output html directory (eg. 'html')
 # Returns: true on success
 # Notes: My apologies for the patchwork code, but this is only used to generate the docs.
@@ -1650,6 +2095,7 @@
     # 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";
+    mkdir "$htmldir/TagNames", 0777;
     OpenHtmlFile($htmldir) or return 0;
     print HTMLFILE "<blockquote>\n";
@@ -1658,9 +2104,8 @@
     print HTMLFILE "<th colspan=$columns><span class=l>Tag Table Index</span></th></tr>\n";
     print HTMLFILE "<tr class=b><td width='$percent%'>\n";
-    # write the index
-    my @tableNames = GetTableOrder();
-    # add shortcuts last
-    push @tableNames, 'Image::ExifTool::Shortcuts::Main';
-    push @tableNames, @pluginTables;
+
+    # get the full table list, adding shortcuts and plug-in tables to the end
+    my @tableNames = GetTableOrder('Image::ExifTool::Shortcuts::Main', @pluginTables);
+
     # get list of headings and add any missing ones
     my $heading = 'xxx';
@@ -1698,9 +2143,10 @@
         $short = $tableName unless $short;
         $url = "$short.html";
-        print HTMLFILE "<a href='$url'>$short</a>";
+        print HTMLFILE "<a href='${url}'>$short</a>";
         ++$count;
     }
     print HTMLFILE "\n</td></tr></table></td></tr></table></blockquote>\n";
     print HTMLFILE '<p>',Doc2Html($docs{ExifTool2}),"</p>\n";
+
     # write all the tag tables
     while (@tableNames or @sepTables or @structs) {
@@ -1713,9 +2159,9 @@
             if ($notes) {
                 # remove unnecessary whitespace
-                $notes =~ s/(^\s+|\s+$)//g;
+                $notes =~ s/^\s+//; $notes =~ s/\s+$//;
                 $notes =~ s/(^[ \t]+|[ \t]+$)//mg;
             }
             my $head = $tableName;
-            $head =~ s/.* //;
+            $head =~ s/^.* //s;
             close HTMLFILE;
             if (OpenHtmlFile($htmldir, $tableName, 1)) {
@@ -1727,5 +2173,5 @@
                 my $wid = 0;
                 my @keys;
-                foreach (sort NumbersFirst keys %$printConv) {
+                foreach (sort { NumbersFirst($a,$b) } keys %$printConv) {
                     next if /^(Notes|PrintHex|PrintString|OTHER)$/;
                     $align = '' if $align and /[^\d]/;
@@ -1733,8 +2179,11 @@
                     $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
-                my $cols = int(80 / ($wid + 4));
+                my $cols = int(110 / ($wid + 4));
                 $cols = 1 if $cols < 1 or $cols > @keys or @keys < 4;
                 my $rows = int((scalar(@keys) + $cols - 1) / $cols);
@@ -1754,5 +2203,7 @@
                             $prt = '= ' . EscapeHTML($$printConv{$key});
                             if ($$printConv{PrintHex}) {
+                                $index =~ s/(\.\d+)$//; # remove decimal
                                 $index = sprintf('0x%x',$index);
+                                $index .= $1 if $1; # add back decimal
                             } elsif ($$printConv{PrintString} or
                                 $index !~ /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/)
@@ -1786,5 +2237,6 @@
             $isStruct = $$structLookup{$tableName};
             $isStruct or warn("Missing structure $tableName\n"), next;
-            $short = $tableName = "XMP $tableName Struct";
+            $tableName = "XMP $tableName" unless $tableName =~ / /;
+            $short = $tableName = "$tableName Struct";
             my $maxLen = 0;
             $maxLen < length and $maxLen = length foreach keys %$isStruct;
@@ -1800,6 +2252,7 @@
             }
         }
-        my $isExif = $tableName eq 'Image::ExifTool::Exif::Main' ? 1 : undef;
-        my $isRiff = $tableName eq 'Image::ExifTool::RIFF::Info' ? 1 : undef;
+        my $isExif = ($tableName eq 'Image::ExifTool::Exif::Main');
+        my $isRiff = ($tableName eq 'Image::ExifTool::RIFF::Info');
+        my $isXmpMain = ($tableName eq 'Image::ExifTool::XMP::Main');
         my $info = $$tagNameInfo{$tableName};
         my $id = $$idLabel{$tableName};
@@ -1807,5 +2260,5 @@
         # widths of the different columns in the POD documentation
         my ($wID,$wTag,$wReq,$wGrp) = (8,36,24,10);
-        my ($composite, $derived, $notes, $prefix);
+        my ($composite, $derived, $notes, $longTags, $wasLong, $prefix);
         if ($short eq 'Shortcuts') {
             $derived = '<th>Refers To</th>';
@@ -1817,4 +2270,15 @@
             my $table = GetTagTable($tableName);
             $notes = $$table{NOTES};
+            if ($$table{NAMESPACE}) {
+                my $ns = $Image::ExifTool::XMP::stdXlatNS{$$table{NAMESPACE}} || $$table{NAMESPACE};
+                my $msg = "These tags belong to the ExifTool XMP-$ns family 1 group.";
+                if ($notes) {
+                    $notes =~ s/\s+$//;
+                    $notes .= "\n\n" . $msg;
+                } else {
+                    $notes = $msg;
+                }
+            }
+            $longTags = $$table{VARS}{LONG_TAGS} if $$table{VARS};
             if ($$table{GROUPS}{0} eq 'Composite') {
                 $composite = 1;
@@ -1828,5 +2292,5 @@
         if ($notes) {
             # remove unnecessary whitespace
-            $notes =~ s/(^\s+|\s+$)//g;
+            $notes =~ s/^\s+//; $notes =~ s/\s+$//;
             $notes =~ s/(^[ \t]+|[ \t]+$)//mg;
             if ($notes =~ /leading '(.*?_)' which/) {
@@ -1850,9 +2314,9 @@
             my $longTag = $self->{LONG_NAME}->{$tableName};
             if ($wTag < $longTag) {
-                warn "Notice: Long tags in $tableName table\n";
                 if ($wID - $longTag + $wTag >= 6) { # don't let ID column get too narrow
                     $wID -= $longTag - $wTag;
                     $wTag = $longTag;
                 }
+                $wasLong = 1 if $wID <= $self->{LONG_ID}->{$tableName};
             }
         } elsif ($composite) {
@@ -1863,7 +2327,8 @@
             $hid = '';
         }
-        if ($short eq 'EXIF') {
+        if ($short eq 'EXIF' or $short eq 'Extra') {
             $derived = '<th>Group</th>';
             $showGrp = 1;
+            $wGrp += 8 if $short eq 'Extra';    # tweak Group column width for "Extra" tags
             $wTag -= $wGrp + 1;
         }
@@ -1887,5 +2352,5 @@
         $line .= ' Writable';
         print PODFILE $line;
-        $line =~ s/^(\s*\w.{6}\w) /$1\t/;   # change space to tab after long ID label (ie. "Sequence")
+        $line =~ s/^(\s*\w.{6}\w) /$1\t/;   # change space to tab after long ID label (eg. "Sequence")
         $line =~ s/\S/-/g;
         $line =~ s/- -/---/g;
@@ -1910,7 +2375,12 @@
             if (not $id) {
                 $idStr = '  ';
-            } elsif ($tagIDstr =~ /^\d+(\.\d+)?$/) {
+            } elsif ($tagIDstr =~ /^-?\d+(\.\d+)?$/) {
                 $w = $wID - 3;
                 $idStr = sprintf "  %${w}g    ", $tagIDstr;
+                my $tooLong = length($idStr) - 6 - $w;
+                if ($tooLong) {
+                    $tooLong = 3 if $tooLong > 3;
+                    $idStr = substr($idStr, 0, -$tooLong);
+                }
                 $align = " class=r";
             } else {
@@ -1926,5 +2396,9 @@
                         # put tag name on next line if ID is too long
                         $idStr = "  $tagIDstr\n   " . (' ' x $w);
-                        warn "Notice: Split $$tagNames[0] line\n";
+                        if ($longTags) {
+                            --$longTags;
+                        } else {
+                            warn "Notice: Split $$tagNames[0] line\n";
+                        }
                     }
                 }
@@ -1938,5 +2412,5 @@
             my $wrStr = shift @vals;
             my $subdir;
-            my @masks = grep /^\[Mask 0x[\da-f]+\]/, @$values;
+            my @masks = grep /^\[val( >> \d+)? \& 0x[\da-f]+\]/, @$values;
             my $tag = shift @tags;
             # if this is a subdirectory or structure, print subdir name (from values) instead of writable
@@ -1945,7 +2419,7 @@
                 if (@masks) {
                     # combine any mask into the format string
-                    $wrStr .= " & $1" if $masks[0] =~ /(0x[\da-f]+)/;
+                    $wrStr .= PodMask($masks[0]);
                     shift @masks;
-                    @vals = grep !/^\[Mask 0x[\da-f]+\]/, @$values;
+                    @vals = grep !/^\[val( >> \d+)? \& 0x[\da-f]+\]/, @$values;
                 } else {
                     @vals = @$values;
@@ -1958,5 +2432,5 @@
                     $vals[$i] = $$writable[$i] unless defined $vals[$i];
                     if (@masks) {
-                        $vals[$i] .= " & $1" if $masks[0] =~ /(0x[\da-f]+)/;
+                        $vals[$i] .= PodMask($masks[0]);
                         shift @masks;
                     }
@@ -1964,5 +2438,5 @@
                 if ($$sepTable{$vals[0]}) {
                     $wrStr =~ s/^[-=]//;
-                    $wrStr = 'N' unless $wrStr;
+                    $wrStr = 'no' unless $wrStr;
                 } elsif ($$structs{$vals[0]}) {
                     my $flags = $wrStr =~ /([+_]+)$/ ? $1 : '';
@@ -1972,5 +2446,5 @@
                 }
                 shift @vals;
-            } elsif ($wrStr and $wrStr ne 'N' and @masks) {
+            } elsif ($wrStr and $wrStr ne 'no' and @masks) {
                 # fill in missing entries if masks are different
                 my $mask = shift @masks;
@@ -1981,16 +2455,37 @@
                 }
                 # add Mask to Writable column in POD doc
-                $wrStr .= " & $1" if $mask =~ /(0x[\da-f]+)/;
-            }
-            printf PODFILE "%s%-${wTag2}s", $idStr, $tag;
-            warn "Warning: Pushed $tag\n" if $id and length($tag) > $wTag2;
-            printf PODFILE " %-${wGrp}s", shift(@wGrp) || '-' if $showGrp;
+                $wrStr .= PodMask($mask);
+            }
+            my $pod = sprintf "%s%-${wTag2}s", $idStr, $tag;
+            my $tGrp = $wGrp;
+            if ($id and length($tag) > $wTag2) {
+                my $madeRoom;
+                if ($showGrp) {
+                    my $wGrp0 = length($wGrp[0] || '-');
+                    if (not $composite and $wGrp > $wGrp0) {
+                        $tGrp = $wGrp - (length($tag) - $wTag2);
+                        if ($tGrp < length $wGrp0) {
+                            $tGrp = length $wGrp0;
+                        } else {
+                            $madeRoom = 1;
+                        }
+                    }
+                }
+                warn "Warning: Pushed $tag\n" unless $madeRoom;
+            }
+            $pod .= sprintf " %-${tGrp}s", shift(@wGrp) || '-' if $showGrp;
             if ($composite) {
                 @reqs = @$require;
                 $w = $wReq; # Keep writable column in line
                 length($tag) > $wTag2 and $w -= length($tag) - $wTag2;
-                printf PODFILE " %-${w}s", shift(@reqs) || '';
-            }
-            printf PODFILE " $wrStr\n";
+                $pod .= sprintf " %-${w}s", shift(@reqs) || '';
+            }
+            $pod .= " $wrStr";
+            # limit line length to 82 characters (even if it means messing up column alignment)
+            if (length $pod > 82 and $pod !~ /\n/) {
+                my $remove = length($pod) - 82;
+                $pod =~ s/(\w)\s{$remove}/$1/;
+            }
+            print PODFILE $pod, "\n";
             my $numTags = scalar @$tagNames;
             my $n = 0;
@@ -2019,5 +2514,5 @@
                         $line .= " $val";
                         if (@masks) {
-                            $line .= " & $1" if $masks[0] =~ /(0x[\da-f]+)/;
+                            $line .= PodMask($masks[0]);
                             shift @masks;
                         }
@@ -2031,6 +2526,7 @@
                 push @htmlTags, EscapeHTML($_);
             }
-            if (($isExif and $exifSpec{hex $tagIDstr}) or
-                ($isRiff and $tagIDstr=~/(\w+)/ and $riffSpec{$1}))
+            if (($isExif and $Image::ExifTool::Validate::exifSpec{hex $tagIDstr}) or
+                ($isRiff and $tagIDstr=~/(\w+)/ and $riffSpec{$1}) or
+                ($isXmpMain and $tagIDstr=~/([-\w]+)/ and $xmpSpec{$1}))
             {
                 # underline "unknown" makernote tags only
@@ -2045,6 +2541,6 @@
             }
             # add tooltip for hex conversion of Tag ID
-            if ($tagIDstr =~ /^0x[0-9a-f]+$/i) {
-                $tip = sprintf(" title='$tagIDstr = %u'",hex $tagIDstr);
+            if ($tagIDstr =~ /^(0x[0-9a-f]+)(\.\d+)?$/i) {
+                $tip = sprintf(" title='$tagIDstr = %u%s'", hex($1), $2||'');
             } elsif ($tagIDstr =~ /^(\d+)(\.\d*)?$/) {
                 $tip = sprintf(" title='%u = 0x%x'", $1, $1);
@@ -2059,13 +2555,14 @@
                 '_' => 'Flattened',
                 '+' => 'List',
-                '/' => 'Avoided',
+                '/' => 'Avoid',
                 '~' => 'Writable only with -n',
                 '!' => '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) {
@@ -2098,4 +2595,5 @@
                     foreach (@$values) {
                         if (/^\(/) {
+                            $_ = Doc2Html($_);
                             # set the note font
                             $smallNote = 1 if $numTags < 2;
@@ -2104,5 +2602,13 @@
                         }
                         # make text in square brackets small
-                        /^\[/ and push(@values, "<span class=s>$_</span>"), next;
+                        if (/^\[/) {
+                            if (s/^\[!HTML\]//) {
+                                push @values, $_;
+                            } else {
+                                $_ = Doc2Html($_);
+                                push @values, "<span class=s>$_</span>";
+                            }
+                            next;
+                        }
                         /=/ and push(@values, $_), next;
                         my @names = split;
@@ -2112,13 +2618,17 @@
                             $suffix = ' Values';
                         }
-                        # currently all structures are in XMP documentation
-                        if ($$structs{$_} and $short =~ /^XMP/) {
-                            unshift @names, 'XMP';
+                        # handle structures specially
+                        if ($$structs{$_}) {
+                            # assume XMP module for this struct unless otherwise specified
+                            unshift @names, 'XMP' unless / /;
                             push @structs, $_;  # list this later
+                            # hack to put Area Struct in with XMP tags,
+                            # even though it is only used by the MWG module
+                            push @structs, 'Area' if $_ eq 'Dimensions';
                             $suffix = ' Struct';
                         }
                         $url = (shift @names) . '.html';
                         @names and $url .= '#' . join '_', @names;
-                        push @values, "--&gt; <a href='$url'>$_$suffix</a>";
+                        push @values, "--&gt; <a href='${url}'>$_$suffix</a>";
                     }
                     # put small note last
@@ -2151,6 +2661,10 @@
             print HTMLFILE "</td></tr>\n";
         }
+        warn "$longTags unaccounted-for long tags in $tableName\n" if $longTags;
+        if ($wasLong and not defined $longTags) {
+            warn "Notice: Long tags in $tableName table\n";
+        }
         unless ($infoCount) {
-            printf PODFILE "  [no tags known]\n";
+            print PODFILE "  [no tags known]\n";
             my $cols = 3;
             ++$cols if $hid;
@@ -2182,5 +2696,6 @@
 Image::ExifTool::TagNames.pod, as well as HTML tag name documentation.  It
 is used before each new ExifTool release to update the lookup tables and
-documentation, but it is not used otherwise.
+documentation, but it is not used otherwise.  It also performs some
+validation and consistency checks on the tag tables.
 
 =head1 SYNOPSIS
@@ -2190,7 +2705,15 @@
   $builder = new Image::ExifTool::BuildTagLookup;
 
+  # update Image::ExifTool::TagLookup
   $ok = $builder->WriteTagLookup('lib/Image/ExifTool/TagLookup.pm');
 
+  # update the tag name documentation
   $ok = $builder->WriteTagNames('lib/Image/ExifTool/TagNames.pod','html');
+
+  # print some statistics
+  my $count = $$builder{COUNT};
+  foreach (sort keys %$count) {
+      printf "%5d %s\n", $$count{$_}, $_;
+  }
 
 =head1 MEMBER VARIABLES
@@ -2210,9 +2733,13 @@
 WriteTagNames().
 
+=item WRITE_PSEUDO
+
+Returned list of writable pseudo tags.
+
 =back
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Canon.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Canon.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Canon.pm	(revision 34921)
@@ -39,4 +39,5 @@
 #              23) Magne Nilsen private communication (400D)
 #              24) Wolfgang Hoffmann private communication (40D)
+#              25) Laurent Clevy private communication
 #              26) Steve Balcombe private communication
 #              27) Chris Huebsch private communication (40D)
@@ -63,5 +64,13 @@
 #              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) 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
+#              NJ) Niels Kristian Bech Jensen private communication
 #------------------------------------------------------------------------------
 
@@ -69,5 +78,5 @@
 
 use strict;
-use vars qw($VERSION %canonModelID);
+use vars qw($VERSION %canonModelID %canonLensTypes);
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
@@ -76,18 +85,24 @@
 sub ProcessSerialData($$$);
 sub ProcessFilters($$$);
+sub ProcessCTMD($$$);
+sub ProcessExifInfo($$$);
 sub SwapWords($);
 
-$VERSION = '2.71';
+$VERSION = '4.44';
 
 # Note: Removed 'USM' from 'L' lenses since it is redundant - PH
 # (or is it?  Ref 32 shows 5 non-USM L-type lenses)
-my %canonLensTypes = ( #4
+# --> have relaxed this for new lenses because Canon has been
+#     consistent about keeping "USM" in the model name
+%canonLensTypes = ( #4
      Notes => q{
-        Decimal values differentiate lenses which would otherwise have the same
-        LensType, and are used by the Composite LensID tag when attempting to
-        identify the specific lens model.
+        Decimal values have been added to differentiate lenses which would otherwise
+        have the same LensType, and are used by the Composite LensID tag when
+        attempting to identify the specific lens model.
      },
+    -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
@@ -98,10 +113,11 @@
      6.1 => 'Sigma 18-50mm f/3.5-5.6 DC', #23
      6.2 => 'Sigma 18-125mm f/3.5-5.6 DC IF ASP',
-     6.3 => 'Tokina AF193-2 19-35mm f/3.5-4.5',
+     6.3 => 'Tokina AF 193-2 19-35mm f/3.5-4.5',
      6.4 => 'Sigma 28-80mm f/3.5-5.6 II Macro', #47
+     6.5 => 'Sigma 28-300mm f/3.5-6.3 DG Macro', #IB
      7 => 'Canon EF 100-300mm f/5.6L', #15
      8 => 'Canon EF 100-300mm f/5.6 or Sigma or Tokina Lens', #32
-     8.1 => 'Sigma 70-300mm f/4-5.6 [APO] DG Macro', #15 (both APO and non-APO, ref http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2947.0.html)
-     8.2 => 'Tokina AT-X242AF 24-200mm f/3.5-5.6', #15
+     8.1 => 'Sigma 70-300mm f/4-5.6 [APO] DG Macro', #15 (both APO and non-APO, ref forum2947)
+     8.2 => 'Tokina AT-X 242 AF 24-200mm f/3.5-5.6', #15
      9 => 'Canon EF 70-210mm f/4', #32
      9.1 => 'Sigma 55-200mm f/4-5.6 DC', #34
@@ -121,5 +137,5 @@
     21 => 'Canon EF 80-200mm f/2.8L',
     22 => 'Canon EF 20-35mm f/2.8L or Tokina Lens', #32
-    22.1 => 'Tokina AT-X280AF PRO 28-80mm f/2.8 Aspherical', #15
+    22.1 => 'Tokina AT-X 280 AF Pro 28-80mm f/2.8 Aspherical', #15
     23 => 'Canon EF 35-105mm f/3.5-4.5', #32
     24 => 'Canon EF 35-80mm f/4-5.6 Power Zoom', #32
@@ -130,9 +146,17 @@
     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
-    28.3 => 'Tamron AF 70-300mm f/4.5-5.6 Di LD 1:2 Macro Zoom', #11
+  # 28.3 => 'Tamron AF 70-300mm f/4.5-5.6 Di LD 1:2 Macro Zoom', #11
+    28.3 => 'Tamron AF 70-300mm f/4-5.6 Di LD 1:2 Macro', #47
     28.4 => 'Tamron AF Aspherical 28-200mm f/3.8-5.6', #14
     29 => 'Canon EF 50mm f/1.8 II',
@@ -142,14 +166,26 @@
     32 => 'Canon EF 24mm f/2.8 or Sigma Lens', #10
     32.1 => 'Sigma 15mm f/2.8 EX Fisheye', #11
-    33 => 'Voigtlander or Zeiss Lens',
+    33 => 'Voigtlander or Carl Zeiss Lens',
     33.1 => 'Voigtlander Ultron 40mm f/2 SLII Aspherical', #45
-    33.2 => 'Zeiss Distagon 35mm T* f/2 ZE', #PH
+    33.2 => 'Voigtlander Color Skopar 20mm f/3.5 SLII Aspherical', #50
+    33.3 => 'Voigtlander APO-Lanthar 90mm f/3.5 SLII Close Focus', #50
+    33.4 => 'Carl Zeiss Distagon T* 15mm f/2.8 ZE', #PH
+    33.5 => 'Carl Zeiss Distagon T* 18mm f/3.5 ZE', #PH
+    33.6 => 'Carl Zeiss Distagon T* 21mm f/2.8 ZE', #PH
+    33.7 => 'Carl Zeiss Distagon T* 25mm f/2 ZE', #IB
+    33.8 => 'Carl Zeiss Distagon T* 28mm f/2 ZE', #PH
+    33.9 => 'Carl Zeiss Distagon T* 35mm f/2 ZE', #PH
+   '33.10' => 'Carl Zeiss Distagon T* 35mm f/1.4 ZE', #IB
+   '33.11' => 'Carl Zeiss Planar T* 50mm f/1.4 ZE', #IB
+   '33.12' => 'Carl Zeiss Makro-Planar T* 50mm f/2 ZE', #IB
+   '33.13' => 'Carl Zeiss Makro-Planar T* 100mm f/2 ZE', #IB
+   '33.14' => 'Carl Zeiss Apo-Sonnar T* 135mm f/2 ZE', #JR
     35 => 'Canon EF 35-80mm f/4-5.6', #32
     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', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2937.0.html
+    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
     39 => 'Canon EF 75-300mm f/4-5.6',
@@ -157,9 +193,12 @@
     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
@@ -167,13 +206,29 @@
     51 => 'Canon EF-S 18-135mm f/3.5-5.6 IS', #PH
     52 => 'Canon EF-S 18-55mm f/3.5-5.6 IS II', #PH
+    53 => 'Canon EF-S 18-55mm f/3.5-5.6 III', #Jon Charnas
+    54 => 'Canon EF-S 55-250mm f/4-5.6 IS II', #47
+    60 => 'Irix 11mm f/4', #50
+    80 => 'Canon TS-E 50mm f/2.8L Macro', #42
+    81 => 'Canon TS-E 90mm f/2.8L Macro', #42
+    82 => 'Canon TS-E 135mm f/4L Macro', #42
     94 => 'Canon TS-E 17mm f/4L', #42
-    95 => 'Canon TS-E 24.0mm f/3.5 L II', #43
+    95 => 'Canon TS-E 24mm f/3.5L II', #43
+    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
-    129 => 'Canon EF 300mm f/2.8L', #32
-    130 => 'Canon EF 50mm f/1.0L', #10/15
-    131 => 'Canon EF 28-80mm f/2.8-4L or Sigma Lens', #32
+    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
     131.1 => 'Sigma 8mm f/3.5 EX DG Circular Fisheye', #15
     131.2 => 'Sigma 17-35mm f/2.8-4 EX DG Aspherical HSM', #15
@@ -183,23 +238,37 @@
            # 'Sigma APO 120-300mm f/2.8 EX DG HSM + 1.4x', #15
            # 'Sigma APO 120-300mm f/2.8 EX DG HSM + 2x', #15
-    132 => 'Canon EF 1200mm f/5.6L', #32
-    134 => 'Canon EF 600mm f/4L IS', #15
-    135 => 'Canon EF 200mm f/1.8L',
-    136 => 'Canon EF 300mm f/2.8L',
-    137 => 'Canon EF 85mm f/1.2L or Sigma or Tamron Lens', #10
+    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
-    137.3 => 'Sigma 18-250mm f/3.5-6.3 DC OS HSM', #PH
+    137.3 => 'Sigma 18-250mm f/3.5-6.3 DC OS HSM', #PH (also Sigma 18-250mm f/3.5-6.3 DC Macro OS HSM)
     137.4 => 'Sigma 24-70mm f/2.8 IF EX DG HSM', #PH
     137.5 => 'Sigma 18-125mm f/3.8-5.6 DC OS HSM', #PH
-    137.6 => 'Sigma 17-70mm f/2.8-4 DC Macro OS HSM', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2819.0.html
-    137.7 => 'Sigma 17-50mm f/2.8 OS HSM', #PH (from Exiv2)
-    137.8 => 'Tamron AF 18-270mm f/3.5-6.3 Di II VC PZD', #(model B008)http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3090.0.html
+    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 (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 (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',
-    140 => 'Canon EF 500mm f/4.5L', #32
-    141 => 'Canon EF 500mm f/4.5L',
-    142 => 'Canon EF 300mm f/2.8L IS', #15
-    143 => 'Canon EF 500mm f/4L IS', #15
+    139 => 'Canon EF 400mm f/2.8L USM',
+    140 => 'Canon EF 500mm f/4.5L USM', #32
+    141 => 'Canon EF 500mm f/4.5L USM',
+    142 => 'Canon EF 300mm f/2.8L IS USM', #15
+    143 => 'Canon EF 500mm f/4L IS USM or Sigma Lens', #15
+    143.1 => 'Sigma 17-70mm f/2.8-4 DC Macro OS HSM', #NJ (Exiv2 #1167)
     144 => 'Canon EF 35-135mm f/4-5.6 USM', #26
     145 => 'Canon EF 100-300mm f/4.5-5.6 USM', #32
@@ -208,40 +277,55 @@
     148 => 'Canon EF 28-80mm f/3.5-5.6 USM', #32
     149 => 'Canon EF 100mm f/2 USM', #9
-    150 => 'Canon EF 14mm f/2.8L or Sigma Lens', #10
+    150 => 'Canon EF 14mm f/2.8L USM or Sigma Lens', #10
     150.1 => 'Sigma 20mm EX f/1.8', #4
     150.2 => 'Sigma 30mm f/1.4 DC HSM', #15
     150.3 => 'Sigma 24mm f/1.8 DG Macro EX', #15
-    151 => 'Canon EF 200mm f/2.8L',
-    152 => 'Canon EF 300mm f/4L IS or Sigma Lens', #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)
-    153 => 'Canon EF 35-350mm f/3.5-5.6L or Sigma or Tamron Lens', #PH
+    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', #15
-    155 => 'Canon EF 85mm f/1.8 USM',
+    154 => 'Canon EF 20mm f/2.8 USM or Zeiss Lens', #15
+    154.1 => 'Zeiss Milvus 21mm f/2.8', #IB
+    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.0-5.6 Di VC USD', #PH (model A005)
+    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 12-24mm f/4 DX', #49 (not sure about specific model - PH)
+    160.2 => 'Tokina AT-X 124 AF Pro DX 12-24mm f/4', #49
     160.3 => 'Tokina AT-X 107 AF DX 10-17mm f/3.5-4.5 Fisheye', #PH (http://osdir.com/ml/digikam-devel/2011-04/msg00275.html)
-    161 => 'Canon EF 28-70mm f/2.8L or Sigma or Tamron Lens',
+    160.4 => 'Tokina AT-X 116 AF Pro DX 11-16mm f/2.8', #forum3967
+    160.5 => 'Tokina AT-X 11-20 F2.8 PRO DX Aspherical 11-20mm f/2.8', #NJ (Exiv2 #1166)
+    161 => 'Canon EF 28-70mm f/2.8L USM or Other Lens',
     161.1 => 'Sigma 24-70mm f/2.8 EX',
     161.2 => 'Sigma 28-70mm f/2.8 EX', #PH (http://www.breezesys.com/forum/showthread.php?t=3718)
-    161.3 => 'Tamron AF 17-50mm f/2.8 Di-II LD Aspherical', #40
-    161.4 => 'Tamron 90mm f/2.8',
-    162 => 'Canon EF 200mm f/2.8L', #32
+    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 (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
     163 => 'Canon EF 300mm f/4L', #32
     164 => 'Canon EF 400mm f/5.6L', #32
-    165 => 'Canon EF 70-200mm f/2.8 L',
-    166 => 'Canon EF 70-200mm f/2.8 L + 1.4x',
-    167 => 'Canon EF 70-200mm f/2.8 L + 2x',
-    168 => 'Canon EF 28mm f/1.8 USM', #15
-    169 => 'Canon EF 17-35mm f/2.8L or Sigma Lens', #15
+    165 => 'Canon EF 70-200mm f/2.8L USM',
+    166 => 'Canon EF 70-200mm f/2.8L USM + 1.4x',
+    167 => 'Canon EF 70-200mm f/2.8L USM + 2x',
+    168 => 'Canon EF 28mm f/1.8 USM or Sigma Lens', #15
+    168.1 => 'Sigma 50-100mm f/1.8 DC HSM | A', #IB
+    169 => 'Canon EF 17-35mm f/2.8L USM or Sigma Lens', #15
     169.1 => 'Sigma 18-200mm f/3.5-6.3 DC OS', #23
     169.2 => 'Sigma 15-30mm f/3.5-4.5 EX DG Aspherical', #4
@@ -250,35 +334,80 @@
     169.5 => 'Sigma 85mm f/1.4 EX DG HSM', #Rolando Ruzic
     169.6 => 'Sigma 30mm f/1.4 EX DC HSM', #Rodolfo Borges
-    170 => 'Canon EF 200mm f/2.8L II', #9
-    171 => 'Canon EF 300mm f/4L', #15
-    172 => 'Canon EF 400mm f/5.6L', #32
-    173 => 'Canon EF 180mm Macro f/3.5L or Sigma Lens', #9
+    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
+    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
-    174 => 'Canon EF 135mm f/2L or Sigma Lens', #9
+    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)
-    175 => 'Canon EF 400mm f/2.8L', #32
+    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', #9
+    177 => 'Canon EF 300mm f/4L IS USM', #9
     178 => 'Canon EF 28-135mm f/3.5-5.6 IS',
-    179 => 'Canon EF 24mm f/1.4L', #20
-    180 => 'Canon EF 35mm f/1.4L', #9
-    181 => 'Canon EF 100-400mm f/4.5-5.6L IS + 1.4x', #15
-    182 => 'Canon EF 100-400mm f/4.5-5.6L IS + 2x',
-    183 => 'Canon EF 100-400mm f/4.5-5.6L IS',
-    184 => 'Canon EF 400mm f/2.8L + 2x', #15
-    185 => 'Canon EF 600mm f/4L IS', #32
-    186 => 'Canon EF 70-200mm f/4L', #9
-    187 => 'Canon EF 70-200mm f/4L + 1.4x', #26
-    188 => 'Canon EF 70-200mm f/4L + 2x', #PH
-    189 => 'Canon EF 70-200mm f/4L + 2.8x', #32
-    190 => 'Canon EF 100mm f/2.8 Macro',
-    191 => 'Canon EF 400mm f/4 DO IS', #9
+    179 => 'Canon EF 24mm f/1.4L USM', #20
+    180 => 'Canon EF 35mm f/1.4L USM or Other Lens', #9
+    180.1 => 'Sigma 50mm f/1.4 DG HSM | A', #50
+    180.2 => 'Sigma 24mm f/1.4 DG HSM | A', #NJ
+    180.3 => 'Zeiss Milvus 50mm f/1.4', #IB
+    180.4 => 'Zeiss Milvus 85mm f/1.4', #IB
+    180.5 => 'Zeiss Otus 28mm f/1.4 ZE', #PH
+    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',
+    182.1 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | S + 2x', #PH (NC)
+    183 => 'Canon EF 100-400mm f/4.5-5.6L IS USM or Sigma Lens',
+    183.1 => 'Sigma 150mm f/2.8 EX DG OS HSM APO Macro', #50
+    183.2 => 'Sigma 105mm f/2.8 EX DG OS HSM Macro', #50
+    183.3 => 'Sigma 180mm f/2.8 EX DG OS HSM APO Macro', #IB
+    183.4 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | C', #47
+    183.5 => 'Sigma 150-600mm f/5-6.3 DG OS HSM | S', #forum7109 (Sports 014)
+    183.6 => 'Sigma 100-400mm f/5-6.3 DG OS HSM', #PH ("| C" ?)
+    183.7 => 'Sigma 180mm f/3.5 APO Macro EX DG IF HSM', #IB
+    184 => 'Canon EF 400mm f/2.8L USM + 2x', #15
+    185 => 'Canon EF 600mm f/4L IS USM', #32
+    186 => 'Canon EF 70-200mm f/4L USM', #9
+    187 => 'Canon EF 70-200mm f/4L USM + 1.4x', #26
+    188 => 'Canon EF 70-200mm f/4L USM + 2x', #PH
+    189 => 'Canon EF 70-200mm f/4L USM + 2.8x', #32
+    190 => 'Canon EF 100mm f/2.8 Macro USM', # (+USM ref 42)
+    191 => 'Canon EF 400mm f/4 DO IS or Sigma Lens', #9
+    191.1 => 'Sigma 500mm f/4 DG OS HSM', #AndrewSheih
     193 => 'Canon EF 35-80mm f/4-5.6 USM', #32
     194 => 'Canon EF 80-200mm f/4.5-5.6 USM', #32
     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',
-    198 => 'Canon EF 50mm f/1.4 USM', #9
+    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 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
@@ -286,43 +415,180 @@
     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',
+    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 (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',
-    224 => 'Canon EF 70-200mm f/2.8L IS', #11
-    225 => 'Canon EF 70-200mm f/2.8L IS + 1.4x', #11
-    226 => 'Canon EF 70-200mm f/2.8L IS + 2x', #14
-    227 => 'Canon EF 70-200mm f/2.8L IS + 2.8x', #32
+    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
+    227 => 'Canon EF 70-200mm f/2.8L IS USM + 2.8x', #32
     228 => 'Canon EF 28-105mm f/3.5-4.5 USM', #32
-    229 => 'Canon EF 16-35mm f/2.8L', #PH
-    230 => 'Canon EF 24-70mm f/2.8L', #9
-    231 => 'Canon EF 17-40mm f/4L',
+    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 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', #PH
-    234 => 'Canon EF-S 17-85mm f4-5.6 IS USM', #19
+    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
+    234.1 => 'Tokina AT-X 12-28 PRO DX 12-28mm f/4', #50/NJ
     235 => 'Canon EF-S 10-22mm f/3.5-4.5 USM', #15
     236 => 'Canon EF-S 60mm f/2.8 Macro USM', #15
-    237 => 'Canon EF 24-105mm f/4L IS', #15
-    238 => 'Canon EF 70-300mm f/4-5.6 IS USM', #15
-    239 => 'Canon EF 85mm f/1.2L II', #15
-    240 => 'Canon EF-S 17-55mm f/2.8 IS USM', #15
-    241 => 'Canon EF 50mm f/1.2L', #15
-    242 => 'Canon EF 70-200mm f/4L IS', #PH
-    243 => 'Canon EF 70-200mm f/4L IS + 1.4x', #15
-    244 => 'Canon EF 70-200mm f/4L IS + 2x', #PH
-    245 => 'Canon EF 70-200mm f/4L IS + 2.8x', #32
-    246 => 'Canon EF 16-35mm f/2.8L II', #PH
+    237 => 'Canon EF 24-105mm f/4L IS USM', #15
+    238 => 'Canon EF 70-300mm f/4-5.6 IS USM', #15 (and version II? ref 42)
+    239 => 'Canon EF 85mm f/1.2L II USM or Rokinon Lens', #15
+    239.1 => 'Rokinon SP 85mm f/1.2', #IB
+    240 => 'Canon EF-S 17-55mm f/2.8 IS USM or Sigma Lens', #15
+    240.1 => 'Sigma 17-50mm f/2.8 EX DC OS HSM', #https://github.com/Exiv2/exiv2/issues/397
+    241 => 'Canon EF 50mm f/1.2L USM', #15
+    242 => 'Canon EF 70-200mm f/4L IS USM', #PH
+    243 => 'Canon EF 70-200mm f/4L IS USM + 1.4x', #15
+    244 => 'Canon EF 70-200mm f/4L IS USM + 2x', #PH
+    245 => 'Canon EF 70-200mm f/4L IS USM + 2.8x', #32
+    246 => 'Canon EF 16-35mm f/2.8L II USM', #PH
     247 => 'Canon EF 14mm f/2.8L II USM', #32
-    248 => 'Canon EF 200mm f/2L IS', #42
-    249 => 'Canon EF 800mm f/5.6L IS', #35
-    250 => 'Canon EF 24 f/1.4L II', #41
+    248 => 'Canon EF 200mm f/2L IS USM or Sigma Lens', #42
+    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 => '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 Lens', #50
+    255.1 => 'Sigma 180mm f/2.8 EX DG OS HSM APO Macro', #50
+    255.2 => 'Tamron SP 70-200mm f/2.8 Di VC USD', #exiv issue 1202 (A009)
+    368 => 'Sigma 14-24mm f/2.8 DG HSM | A or other Sigma Lens', #IB (A018)
+    368.1 => 'Sigma 20mm f/1.4 DG HSM | A', #50 (newer firmware)
+    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 35mm f/1.4 DG HSM | A', #PH (012)
+   '368.11' => 'Sigma 70mm f/2.8 DG Macro', #IB (A018)
+   '368.12' => 'Sigma 18-35mm f/1.8 DC HSM | A', #50
     # 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
+    490 => 'Canon EF 8-15mm f/4L Fisheye USM', #Klaus Reinfeld (PH added "Fisheye")
+    491 => 'Canon EF 300mm f/2.8L IS II USM or Tamron Lens', #42
+    491.1 => 'Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025)', #IB
+    491.2 => 'Tamron 18-400mm f/3.5-6.3 Di II VC HLD (B028)', #IB
+    491.3 => 'Tamron 100-400mm f/4.5-6.3 Di VC USD (A035)', #IB
+    491.4 => 'Tamron 70-210mm f/4 Di VC USD (A034)', #IB
+    491.5 => 'Tamron 70-210mm f/4 Di VC USD (A034) + 1.4x', #IB
+    491.6 => 'Tamron SP 24-70mm f/2.8 Di VC USD G2 (A032)',
+    492 => 'Canon EF 400mm f/2.8L IS II USM', #PH
+    493 => 'Canon EF 500mm f/4L IS II USM or EF 24-105mm f4L IS USM', #PH
+    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 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 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 (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 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
+    754 => 'Canon EF 70-200mm f/4L IS II USM', #IB
+    757 => 'Canon EF 400mm f/2.8L IS III USM', #IB
+    758 => 'Canon EF 600mm f/4L IS III USM', #IB
+
+    1136 => 'Sigma 24-70mm f/2.8 DG OS HSM | A', #IB (017)
+    # (STM lenses - 0x10xx)
+    4142 => 'Canon EF-S 18-135mm f/3.5-5.6 IS STM',
+    4143 => 'Canon EF-M 18-55mm f/3.5-5.6 IS STM or Tamron Lens',
+    4143.1 => 'Tamron 18-200mm f/3.5-6.3 Di III VC', #42
+    4144 => 'Canon EF 40mm f/2.8 STM', #50
+    4145 => 'Canon EF-M 22mm f/2 STM', #34
+    4146 => 'Canon EF-S 18-55mm f/3.5-5.6 IS STM', #PH
+    4147 => 'Canon EF-M 11-22mm f/4-5.6 IS STM', #42
+    4148 => 'Canon EF-S 55-250mm f/4-5.6 IS STM', #42
+    4149 => 'Canon EF-M 55-200mm f/4.5-6.3 IS STM', #42
+    4150 => 'Canon EF-S 10-18mm f/4.5-5.6 IS STM', #42
+    4152 => 'Canon EF 24-105mm f/3.5-5.6 IS STM', #42
+    4153 => 'Canon EF-M 15-45mm f/3.5-6.3 IS STM', #PH
+    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 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
+    # (CN-E lenses - 0xf0xx)
+    61491 => 'Canon CN-E 14mm T3.1 L F', #PH
+    61492 => 'Canon CN-E 24mm T1.5 L F', #PH
+  # 61493 - missing CN-E 50mm T1.3 L F ?
+    61494 => 'Canon CN-E 85mm T1.3 L F', #PH
+    61495 => 'Canon CN-E 135mm T2.2 L F', #PH
+    61496 => 'Canon CN-E 35mm T1.5 L F', #PH
+    # see RFLensType tag for master list of 61182 RF lenses
+    61182 => 'Canon RF 50mm F1.2L USM or other Canon RF Lens',
+    61182.1 => 'Canon RF 24-105mm F4L IS USM',
+    61182.2 => 'Canon RF 28-70mm F2L USM',
+    61182.3 => 'Canon RF 35mm F1.8 MACRO IS STM',
+    61182.4 => 'Canon RF 85mm F1.2L USM',
+    61182.5 => 'Canon RF 85mm F1.2L USM DS',
+    61182.6 => 'Canon RF 24-70mm F2.8L IS USM',
+    61182.7 => 'Canon RF 15-35mm F2.8L IS USM',
+    61182.8 => 'Canon RF 24-240mm F4-6.3 IS USM',
+    61182.9 => 'Canon RF 70-200mm F2.8L IS USM',
+    61182.10 => 'Canon RF 85mm F2 MACRO IS STM',
+    61182.11 => 'Canon RF 600mm F11 IS STM',
+    61182.12 => 'Canon RF 600mm F11 IS STM + RF1.4x',
+    61182.13 => 'Canon RF 600mm F11 IS STM + RF2x',
+    61182.14 => 'Canon RF 800mm F11 IS STM',
+    61182.15 => 'Canon RF 800mm F11 IS STM + RF1.4x',
+    61182.16 => 'Canon RF 800mm F11 IS STM + RF2x',
+    61182.17 => 'Canon RF 24-105mm F4-7.1 IS STM',
+    61182.18 => 'Canon RF 100-500mm F4.5-7.1L IS USM',
+    61182.19 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF1.4x',
+    61182.20 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
+    65535 => 'n/a',
 );
 
@@ -450,5 +716,5 @@
     0x2800000 => 'PowerShot A495',
     0x2810000 => 'PowerShot A490',
-    0x2820000 => 'PowerShot A3100 IS',
+    0x2820000 => 'PowerShot A3100/A3150 IS', # (different cameras, same ID)
     0x2830000 => 'PowerShot A3000 IS',
     0x2840000 => 'PowerShot SD1400 IS / IXUS 130 / IXY 400F',
@@ -464,5 +730,5 @@
     0x2980000 => 'PowerShot A3300 IS',
     0x2990000 => 'PowerShot A3200 IS',
-    0x3000000 => 'PowerShot ELPH 500 HS / IXUS 310 HS / IXY 31 S',
+    0x3000000 => 'PowerShot ELPH 500 HS / IXUS 310 HS / IXY 31S',
     0x3010000 => 'PowerShot Pro90 IS',
     0x3010001 => 'PowerShot A800',
@@ -473,6 +739,107 @@
     0x3060000 => 'PowerShot A1200',
     0x3070000 => 'PowerShot SX220 HS',
+    0x3080000 => 'PowerShot G1 X',
+    0x3090000 => 'PowerShot SX150 IS',
+    0x3100000 => 'PowerShot ELPH 510 HS / IXUS 1100 HS / IXY 51S',
+    0x3110000 => 'PowerShot S100 (new)',
+    0x3130000 => 'PowerShot SX40 HS',
+    0x3120000 => 'PowerShot ELPH 310 HS / IXUS 230 HS / IXY 600F',
+    # the Canon page lists the IXY 32S as "Japan only", but many other
+    # sites list the ELPH 500 HS and IXUS 320 HS as being the same model.
+    # I haven't been able to find an IXUS 320 sample, and the ELPH 500 HS
+    # is already associated with other IXUS and IXY models - PH
+    0x3140000 => 'IXY 32S', # (PowerShot ELPH 500 HS / IXUS 320 HS ??)
+    0x3160000 => 'PowerShot A1300',
+    0x3170000 => 'PowerShot A810',
+    0x3180000 => 'PowerShot ELPH 320 HS / IXUS 240 HS / IXY 420F',
+    0x3190000 => 'PowerShot ELPH 110 HS / IXUS 125 HS / IXY 220F',
+    0x3200000 => 'PowerShot D20',
+    0x3210000 => 'PowerShot A4000 IS',
+    0x3220000 => 'PowerShot SX260 HS',
+    0x3230000 => 'PowerShot SX240 HS',
+    0x3240000 => 'PowerShot ELPH 530 HS / IXUS 510 HS / IXY 1',
+    0x3250000 => 'PowerShot ELPH 520 HS / IXUS 500 HS / IXY 3',
+    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',
+    0x3360000 => 'PowerShot S110 (new)',
+    0x3370000 => 'PowerShot SX500 IS',
+    0x3380000 => 'PowerShot N',
+    0x3390000 => 'IXUS 245 HS / IXY 430F', # (no PowerShot)
+    0x3400000 => 'PowerShot SX280 HS',
+    0x3410000 => 'PowerShot SX270 HS',
+    0x3420000 => 'PowerShot A3500 IS',
+    0x3430000 => 'PowerShot A2600',
+    0x3440000 => 'PowerShot SX275 HS', #forum8199
+    0x3450000 => 'PowerShot A1400',
+    0x3460000 => 'PowerShot ELPH 130 IS / IXUS 140 / IXY 110F',
+    0x3470000 => 'PowerShot ELPH 115/120 IS / IXUS 132/135 / IXY 90F/100F',
+    0x3490000 => 'PowerShot ELPH 330 HS / IXUS 255 HS / IXY 610F',
+    0x3510000 => 'PowerShot A2500',
+    0x3540000 => 'PowerShot G16',
+    0x3550000 => 'PowerShot S120',
+    0x3560000 => 'PowerShot SX170 IS',
+    0x3580000 => 'PowerShot SX510 HS',
+    0x3590000 => 'PowerShot S200 (new)',
+    0x3600000 => 'IXY 620F', # (no PowerShot or IXUS?)
+    0x3610000 => 'PowerShot N100',
+    0x3640000 => 'PowerShot G1 X Mark II',
+    0x3650000 => 'PowerShot D30',
+    0x3660000 => 'PowerShot SX700 HS',
+    0x3670000 => 'PowerShot SX600 HS',
+    0x3680000 => 'PowerShot ELPH 140 IS / IXUS 150 / IXY 130',
+    0x3690000 => 'PowerShot ELPH 135 / IXUS 145 / IXY 120',
+    0x3700000 => 'PowerShot ELPH 340 HS / IXUS 265 HS / IXY 630',
+    0x3710000 => 'PowerShot ELPH 150 IS / IXUS 155 / IXY 140',
+    0x3740000 => 'EOS M3', #IB
+    0x3750000 => 'PowerShot SX60 HS', #IB/NJ
+    0x3760000 => 'PowerShot SX520 HS', #IB
+    0x3770000 => 'PowerShot SX400 IS',
+    0x3780000 => 'PowerShot G7 X', #IB
+    0x3790000 => 'PowerShot N2',
+    0x3800000 => 'PowerShot SX530 HS',
+    0x3820000 => 'PowerShot SX710 HS',
+    0x3830000 => 'PowerShot SX610 HS',
+    0x3840000 => 'EOS M10',
+    0x3850000 => 'PowerShot G3 X',
+    0x3860000 => 'PowerShot ELPH 165 HS / IXUS 165 / IXY 160',
+    0x3870000 => 'PowerShot ELPH 160 / IXUS 160',
+    0x3880000 => 'PowerShot ELPH 350 HS / IXUS 275 HS / IXY 640',
+    0x3890000 => 'PowerShot ELPH 170 IS / IXUS 170',
+    0x3910000 => 'PowerShot SX410 IS',
+    0x3930000 => 'PowerShot G9 X',
+    0x3940000 => 'EOS M5', #IB
+    0x3950000 => 'PowerShot G5 X',
+    0x3970000 => 'PowerShot G7 X Mark II',
+    0x3980000 => 'EOS M100', #42
+    0x3990000 => 'PowerShot ELPH 360 HS / IXUS 285 HS / IXY 650',
+    0x4010000 => 'PowerShot SX540 HS',
+    0x4020000 => 'PowerShot SX420 IS',
+    0x4030000 => 'PowerShot ELPH 190 IS / IXUS 180 / IXY 190',
     0x4040000 => 'PowerShot G1',
+    0x4040001 => 'PowerShot ELPH 180 IS / IXUS 175 / IXY 180', #forum10402
+    0x4050000 => 'PowerShot SX720 HS',
+    0x4060000 => 'PowerShot SX620 HS',
+    0x4070000 => 'EOS M6',
+    0x4100000 => 'PowerShot G9 X Mark II',
+    0x412     => 'EOS M50 / Kiss M', # (yes, no "0000")
+    0x4150000 => 'PowerShot ELPH 185 / IXUS 185 / IXY 200',
+    0x4160000 => 'PowerShot SX430 IS',
+    0x4170000 => 'PowerShot SX730 HS',
+    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)
+
     0x4007d673 => 'DC19/DC21/DC22',
     0x4007d674 => 'XH A1',
@@ -487,4 +854,5 @@
     0x4007d81c => 'HF11',
     0x4007d878 => 'HV30',
+    0x4007d87c => 'XH A1S',
     0x4007d87e => 'DC301/DC310/DC311/DC320/DC330',
     0x4007d87f => 'FS100',
@@ -494,12 +862,17 @@
     0x4007d926 => 'HF S11', # (LEGRIA)
     0x4007d978 => 'HV40', # (LEGRIA)
-    0x4007d987 => 'DC410/DC420',
+    0x4007d987 => 'DC410/DC411/DC420',
     0x4007d988 => 'FS19/FS20/FS21/FS22/FS200', # (LEGRIA)
     0x4007d989 => 'HF20/HF200', # (LEGRIA)
     0x4007d98a => 'HF S10/S100', # (LEGRIA/VIXIA)
-    0x4007da8e => 'HF R16/R17/R18/R100/R106', # (LEGRIA/VIXIA)
-    0x4007da8f => 'HF M31/M36/M300', # (LEGRIA/VIXIA, probably also HF M30)
+    0x4007da8e => 'HF R10/R16/R17/R18/R100/R106', # (LEGRIA/VIXIA)
+    0x4007da8f => 'HF M30/M31/M36/M300/M306', # (LEGRIA/VIXIA)
     0x4007da90 => 'HF S20/S21/S200', # (LEGRIA/VIXIA)
-    0x4007da92 => 'FS36/FS37/FS305/FS306/FS307',
+    0x4007da92 => 'FS31/FS36/FS37/FS300/FS305/FS306/FS307',
+    0x4007dca0 => 'EOS C300',
+    0x4007dda9 => 'HF G25', # (LEGRIA)
+    0x4007dfb4 => 'XC10',
+    0x4007e1c3 => 'EOS C200',
+
     # NOTE: some pre-production models may have a model name of
     # "Canon EOS Kxxx", where "xxx" is the last 3 digits of the model ID below.
@@ -519,19 +892,64 @@
     0x80000215 => 'EOS-1Ds Mark III',
     0x80000218 => 'EOS 5D Mark II',
+    0x80000219 => 'WFT-E1',
     0x80000232 => 'EOS-1D Mark II N',
     0x80000234 => 'EOS 30D',
-    0x80000236 => 'EOS Digital Rebel XTi / 400D / Kiss Digital X', # and K236
+    0x80000236 => 'EOS Digital Rebel XTi / 400D / Kiss Digital X',
+    0x80000241 => 'WFT-E2',
+    0x80000246 => 'WFT-E3',
     0x80000250 => 'EOS 7D',
     0x80000252 => 'EOS Rebel T1i / 500D / Kiss X3',
     0x80000254 => 'EOS Rebel XS / 1000D / Kiss F',
     0x80000261 => 'EOS 50D',
+    0x80000269 => 'EOS-1D X',
     0x80000270 => 'EOS Rebel T2i / 550D / Kiss X4',
+    0x80000271 => 'WFT-E4',
+    0x80000273 => 'WFT-E5',
     0x80000281 => 'EOS-1D Mark IV',
+    0x80000285 => 'EOS 5D Mark III',
     0x80000286 => 'EOS Rebel T3i / 600D / Kiss X5',
     0x80000287 => 'EOS 60D',
     0x80000288 => 'EOS Rebel T3 / 1100D / Kiss X50',
+    0x80000289 => 'EOS 7D Mark II', #IB
+    0x80000297 => 'WFT-E2 II',
+    0x80000298 => 'WFT-E4 II',
+    0x80000301 => 'EOS Rebel T4i / 650D / Kiss X6i',
+    0x80000302 => 'EOS 6D', #25
+    0x80000324 => 'EOS-1D C', #(NC)
+    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
+    0x80000331 => 'EOS M',
+    0x80000350 => 'EOS 80D', #42
+    0x80000355 => 'EOS M2',
+    0x80000346 => 'EOS Rebel SL1 / 100D / Kiss X7',
+    0x80000347 => 'EOS Rebel T6s / 760D / 8000D',
+    0x80000349 => 'EOS 5D Mark IV', #42
+    0x80000382 => 'EOS 5DS',
+    0x80000393 => 'EOS Rebel T6i / 750D / Kiss X8i',
+    0x80000401 => 'EOS 5DS R',
+    0x80000404 => 'EOS Rebel T6 / 1300D / Kiss X80',
+    0x80000405 => 'EOS Rebel T7i / 800D / Kiss X9i',
+    0x80000406 => 'EOS 6D Mark II', #IB/42
+    0x80000408 => 'EOS 77D / 9000D',
+    0x80000417 => 'EOS Rebel SL2 / 200D / Kiss X9', #IB/42
+    0x80000421 => 'EOS R5', #PH
+    0x80000422 => 'EOS Rebel T100 / 4000D / 3000D', #IB (3000D in China; Kiss? - PH)
+    0x80000424 => 'EOS R', #IB
+    0x80000428 => 'EOS-1D X Mark III', #IB
+    0x80000432 => 'EOS Rebel T7 / 2000D / 1500D / Kiss X90', #IB
+    0x80000433 => 'EOS RP',
+    0x80000435 => 'EOS Rebel T8i / 850D / X10i', #JR/PH
+    0x80000436 => 'EOS SL3 / 250D / Kiss X10', #25
+    0x80000437 => 'EOS 90D', #IB
+    0x80000453 => 'EOS R6', #PH
+    0x80000467 => 'PowerShot ZOOM',
+    0x80000520 => 'EOS D2000C', #IB
+    0x80000560 => 'EOS D6000C', #PH (guess)
 );
 
 my %canonQuality = (
+    -1 => 'n/a', # (PH, EOS M MOV video)
     1 => 'Economy',
     2 => 'Normal',
@@ -539,7 +957,10 @@
     4 => 'RAW',
     5 => 'Superfine',
+    7 => 'CRAW', #42
     130 => 'Normal Movie', #22
+    131 => 'Movie (2)', #PH (7DmkII 1920x1080)
 );
 my %canonImageSize = (
+   -1 => 'n/a',
     0 => 'Large',
     1 => 'Medium',
@@ -559,4 +980,5 @@
     137 => '1280x720 Movie', #PH (S95 24fps; D60 50fps)
     142 => '1920x1080 Movie', #PH (D60 25fps)
+    143 => '4096x2160 Movie', #PH (C200)
 );
 my %canonWhiteBalance = (
@@ -584,5 +1006,5 @@
     21 => 'PC Set5', #PH
     # 22 - Custom 2?
-    # 23 - Custom 3?
+    23 => 'Auto (ambience priority)', #PH (5DS)
     # 30 - Click White Balance?
     # 31 - Shot Settings?
@@ -622,4 +1044,7 @@
     0x86 => 'Monochrome',
     0x87 => 'Auto', #PH
+    0x88 => 'Fine Detail', #PH
+    0xff => 'n/a', #PH (guess)
+    0xffff => 'n/a', #PH (guess)
 );
 my %userDefStyles = ( #12/48
@@ -638,4 +1063,5 @@
     0x85 => 'Faithful',
     0x86 => 'Monochrome',
+    0x87 => 'Auto', #PH
 );
 
@@ -643,5 +1069,5 @@
 my %psConv = (
     -559038737 => 'n/a', # = 0xdeadbeef ! LOL
-    OTHER => sub { return shift },
+    OTHER => sub { shift },
 );
 my %psInfo = (
@@ -690,4 +1116,6 @@
     WRITABLE => 1,
 );
+
+my %offOn = ( 0 => 'Off', 1 => 'On' );
 
 #------------------------------------------------------------------------------
@@ -706,7 +1134,5 @@
     0x2 => {
         Name => 'CanonFocalLength',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::FocalLength',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::FocalLength' },
     },
     0x3 => {
@@ -723,7 +1149,5 @@
     0x5 => {
         Name => 'CanonPanorama',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::Panorama',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::Panorama' },
     },
     0x6 => {
@@ -788,105 +1212,135 @@
             # (save size of this record as "CameraInfoCount" for later tests)
             Condition => '($$self{CameraInfoCount} = $count) and $$self{Model} =~ /\b1DS?$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo1D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1D' },
         },
         {
             Name => 'CanonCameraInfo1DmkII',
             Condition => '$$self{Model} =~ /\b1Ds? Mark II$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkII',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkII' },
         },
         {
             Name => 'CanonCameraInfo1DmkIIN',
             Condition => '$$self{Model} =~ /\b1Ds? Mark II N$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIIN',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIIN' },
         },
         {
             Name => 'CanonCameraInfo1DmkIII',
             Condition => '$$self{Model} =~ /\b1Ds? Mark III$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIII',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIII' },
         },
         {
             Name => 'CanonCameraInfo1DmkIV',
             Condition => '$$self{Model} =~ /\b1D Mark IV$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIV',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DmkIV' },
+        },
+        {
+            Name => 'CanonCameraInfo1DX',
+            Condition => '$$self{Model} =~ /EOS-1D X$/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1DX' },
         },
         {
             Name => 'CanonCameraInfo5D',
             Condition => '$$self{Model} =~ /EOS 5D$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo5D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo5D' },
         },
         {
             Name => 'CanonCameraInfo5DmkII',
             Condition => '$$self{Model} =~ /EOS 5D Mark II$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkII',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkII' },
+        },
+        {
+            Name => 'CanonCameraInfo5DmkIII',
+            Condition => '$$self{Model} =~ /EOS 5D Mark III$/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkIII' },
+        },
+        {
+            Name => 'CanonCameraInfo6D',
+            Condition => '$$self{Model} =~ /EOS 6D$/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo6D' },
         },
         {
             Name => 'CanonCameraInfo7D',
             Condition => '$$self{Model} =~ /EOS 7D$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo7D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo7D' },
         },
         {
             Name => 'CanonCameraInfo40D',
             Condition => '$$self{Model} =~ /EOS 40D$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo40D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo40D' },
         },
         {
             Name => 'CanonCameraInfo50D',
             Condition => '$$self{Model} =~ /EOS 50D$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo50D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo50D' },
         },
         {
             Name => 'CanonCameraInfo60D',
             Condition => '$$self{Model} =~ /EOS 60D$/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo60D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo60D' },
+        },
+        {
+            Name => 'CanonCameraInfo70D',
+            Condition => '$$self{Model} =~ /EOS 70D$/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo70D' },
+        },
+        {
+            Name => 'CanonCameraInfo80D',
+            Condition => '$$self{Model} =~ /EOS 80D$/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo80D' },
         },
         {
             Name => 'CanonCameraInfo450D',
             Condition => '$$self{Model} =~ /\b(450D|REBEL XSi|Kiss X2)\b/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo450D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo450D' },
         },
         {
             Name => 'CanonCameraInfo500D',
             Condition => '$$self{Model} =~ /\b(500D|REBEL T1i|Kiss X3)\b/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo500D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo500D' },
         },
         {
             Name => 'CanonCameraInfo550D',
             Condition => '$$self{Model} =~ /\b(550D|REBEL T2i|Kiss X4)\b/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo550D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo550D' },
+        },
+        {
+            Name => 'CanonCameraInfo600D',
+            Condition => '$$self{Model} =~ /\b(600D|REBEL T3i|Kiss X5)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo600D' },
+        },
+        {
+            Name => 'CanonCameraInfo650D',
+            Condition => '$$self{Model} =~ /\b(650D|REBEL T4i|Kiss X6i)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo650D' },
+        },
+        {
+            Name => 'CanonCameraInfo700D',
+            Condition => '$$self{Model} =~ /\b(700D|REBEL T5i|Kiss X7i)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo650D' },
+        },
+        {
+            Name => 'CanonCameraInfo750D',
+            Condition => '$$self{Model} =~ /\b(750D|Rebel T6i|Kiss X8i)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo750D' },
+        },
+        {
+            Name => 'CanonCameraInfo760D',
+            Condition => '$$self{Model} =~ /\b(760D|Rebel T6s|8000D)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo750D' },
         },
         {
             Name => 'CanonCameraInfo1000D',
             Condition => '$$self{Model} =~ /\b(1000D|REBEL XS|Kiss F)\b/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfo1000D',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo1000D' },
+        },
+        {
+            Name => 'CanonCameraInfo1100D',
+            Condition => '$$self{Model} =~ /\b(1100D|REBEL T3|Kiss X50)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo600D' },
+        },
+        {
+            Name => 'CanonCameraInfo1200D',
+            Condition => '$$self{Model} =~ /\b(1200D|REBEL T5|Kiss X70)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfo60D' },
         },
         {
@@ -894,7 +1348,5 @@
             # valid if format is int32u[138] or int32u[148]
             Condition => '$format eq "int32u" and ($count == 138 or $count == 148)',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfoPowerShot',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoPowerShot' },
         },
         {
@@ -905,7 +1357,5 @@
                 $count == 167 or $count == 171 or $count == 264)
             },
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfoPowerShot2',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoPowerShot2' },
         },
         {
@@ -913,20 +1363,14 @@
             Condition => '$format =~ /^int32/',
             # (counts of 72, 85, 86, 93, 94, 96, 104) - PH
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown32',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown32' },
         },
         {
             Name => 'CanonCameraInfoUnknown16',
             Condition => '$format =~ /^int16/',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown16',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown16' },
         },
         {
             Name => 'CanonCameraInfoUnknown',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraInfoUnknown' },
         },
     ],
@@ -1119,13 +1563,16 @@
         ValueConvInv => '"8 $val"',
         PrintConvColumns => 2,
-        PrintConv => { BITMASK => {
-            0 => 'People',
-            1 => 'Scenery',
-            2 => 'Events',
-            3 => 'User 1',
-            4 => 'User 2',
-            5 => 'User 3',
-            6 => 'To Do',
-        } },
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => {
+                0 => 'People',
+                1 => 'Scenery',
+                2 => 'Events',
+                3 => 'User 1',
+                4 => 'User 2',
+                5 => 'User 3',
+                6 => 'To Do',
+            },
+        },
     },
     0x24 => { #PH
@@ -1140,4 +1587,5 @@
         SubDirectory => {
             TagTable => 'Image::ExifTool::Canon::FaceDetect2',
+            # (can't validate because this record uses a 1-byte count instead of a 2-byte count)
         },
     },
@@ -1149,4 +1597,9 @@
             TagTable => 'Image::ExifTool::Canon::AFInfo2',
         },
+    },
+    0x27 => { #PH
+        Name => 'ContrastInfo',
+        Condition => '$$valPt =~ /^\x0a\0/', # (seems to be various versions of this information)
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ContrastInfo' },
     },
     # 0x27 - value 1 is 1 for high ISO pictures, 0 otherwise
@@ -1162,7 +1615,42 @@
         ValueConvInv => 'pack("H*", $val)',
     },
+    0x29 => { #IB (G9)
+        Name => 'WBInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::WBInfo' },
+    },
     # 0x2d - changes with categories (ref 31)
-    # 0x44 - ShootInfo
-    # 0x62 - UserSetting
+    0x2f => { #PH (G12)
+        Name => 'FaceDetect3',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            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 => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::TimeInfo',
+        },
+    },
+    0x38 => { #PH
+        Name => 'BatteryType',
+        Writable => 'undef',
+        Condition => '$count == 76',
+        RawConv => '$val=~/^.{4}([^\0]+)/s ? $1 : undef',
+        RawConvInv => 'substr("\x4c\0\0\0".$val.("\0"x72), 0, 76)',
+    },
+    0x3c => { #PH (G1XmkII)
+        Name => 'AFInfo3',
+        Condition => '$$self{AFInfo3} = 1',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::AFInfo2',
+        },
+    },
+    # 0x44 (ShootInfo)
+    # 0x62 (UserSetting)
     0x81 => { #13
         Name => 'RawDataOffset',
@@ -1177,5 +1665,5 @@
         # this is an offset to the original decision data block
         # (offset relative to start of file in JPEG images, but NOT DNG images!)
-        IsOffset => '$val and $$exifTool{FILE_TYPE} ne "JPEG"',
+        IsOffset => '$val and $$et{FILE_TYPE} ne "JPEG"',
         Protected => 2,
         DataTag => 'OriginalDecisionData',
@@ -1216,8 +1704,8 @@
     },
     0x95 => { #PH (observed in 5D sample image)
-        Name => 'LensModel',
+        Name => 'LensModel', # (LensName)
         Writable => 'string',
     },
-    0x96 => [ #PH
+    0x96 => [ #PH (CMOSNumber)
         {
             Name => 'SerialInfo',
@@ -1233,18 +1721,42 @@
         },
     ],
-    0x97 => { #PH
-        Name => 'DustRemovalData',
-        # some interesting stuff is stored in here, like LensType and InternalSerialNumber...
+    0x97 => { #PH (also see http://www.freepatentsonline.com/7657116.html)
+        Name => 'DustRemovalData', # (DustDeleteData)
         Writable => 'undef',
         Flags => [ 'Binary', 'Protected' ],
+        # 0x00: int8u  - Version (0 or 1)
+        # 0x01: int8u  - LensInfo ? (1)
+        # 0x02: int8u  - AVValue ? (int8u for version 0, int16u for version 1)
+        # 0x03: int8u  - POValue ? (int8u for version 0, int16u for version 1)
+        # 0x04: int16u - DustCount
+        # 0x06: int16u - FocalLength ?
+        # 0x08: int16u - LensID ?
+        # 0x0a: int16u - Width
+        # 0x0c: int16u - Height
+        # 0x0e: int16u - RAW_Width
+        # 0x10: int16u - RAW_Height
+        # 0x12: int16u - PixelPitch [um * 1000]
+        # 0x14: int16u - LpfDistance [mm * 1000]
+        # 0x16: int8u  - TopOffset
+        # 0x17: int8u  - BottomOffset
+        # 0x18: int8u  - LeftOffset
+        # 0x19: int8u  - RightOffset
+        # 0x1a: int8u  - Year [-1900]
+        # 0x1b: int8u  - Month
+        # 0x1c: int8u  - Day
+        # 0x1d: int8u  - Hour
+        # 0x1e: int8u  - Minutes
+        # 0x1f: int8u  - BrightDiff
+        # Table with DustCount entries:
+        # 0x22: int16u - DustX
+        # 0x24: int16u - DustY
+        # 0x26: int16u - DustSize
     },
     0x98 => { #PH
-        Name => 'CropInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::CropInfo',
-        },
+        Name => 'CropInfo', # (ImageSizeOffset)
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CropInfo' },
     },
     0x99 => { #PH (EOS 1D Mark III, 40D, etc)
-        Name => 'CustomFunctions2',
+        Name => 'CustomFunctions2', # (CustomFunEx)
         SubDirectory => {
             Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
@@ -1253,11 +1765,9 @@
     },
     0x9a => { #PH
-        Name => 'AspectInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::AspectInfo',
-        },
+        Name => 'AspectInfo', # (AspectRatioInfo)
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::AspectInfo' },
     },
     0xa0 => {
-        Name => 'ProcessingInfo',
+        Name => 'ProcessingInfo', # (DevelopParam)
         SubDirectory => {
             Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
@@ -1272,13 +1782,10 @@
         Name => 'ColorBalance',
         SubDirectory => {
-            # this offset is necessary because the table is interpreted as short rationals
-            # (4 bytes long) but the first entry is 2 bytes into the table.
-            Start => '$valuePtr + 2',
-            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart-2,$size+2)',
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
             TagTable => 'Image::ExifTool::Canon::ColorBalance',
         },
     },
     0xaa => {
-        Name => 'MeasuredColor',
+        Name => 'MeasuredColor', # (PresetWBDS)
         SubDirectory => {
             Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
@@ -1312,4 +1819,5 @@
             1 => 'sRGB',
             2 => 'Adobe RGB',
+            65535 => 'n/a',
         },
     },
@@ -1332,5 +1840,5 @@
     },
     0xe0 => { #12
-        Name => 'SensorInfo',
+        Name => 'SensorInfo', # (ImageAreaDesc)
         SubDirectory => {
             Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
@@ -1338,30 +1846,24 @@
         },
     },
-    0x4001 => [ #13
+    0x4001 => [ #13 (WBPacket)
         {   # (int16u[582]) - 20D and 350D
             Condition => '$count == 582',
             Name => 'ColorData1',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::ColorData1',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData1' },
         },
         {   # (int16u[653]) - 1DmkII and 1DSmkII
             Condition => '$count == 653',
             Name => 'ColorData2',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::ColorData2',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData2' },
         },
         {   # (int16u[796]) - 1DmkIIN, 5D, 30D, 400D
             Condition => '$count == 796',
             Name => 'ColorData3',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::ColorData3',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData3' },
         },
         {   # (int16u[692|674|702|1227|1250|1251|1337])
             # 40D (692), 1DmkIII (674), 1DSmkIII (702), 450D/1000D (1227)
             # 50D/5DmkII (1250), 500D/7D_pre-prod/1DmkIV_pre-prod (1251),
-            # 1DmkIV/7D/550D_pre-prod (1337), 550D (1338), 1100D (1346)
+            # 1DmkIV/7D/550D_pre-prod (1337), 550D (1338), 60D/1100D (1346)
             Condition => q{
                 $count == 692  or $count == 674  or $count == 702 or
@@ -1370,41 +1872,54 @@
             },
             Name => 'ColorData4',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::ColorData4',
-            },
-        },
-        {   # (int16u[5120]) - G10
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData4' },
+        },
+        {   # (int16u[5120]) - G10, G7X
             Condition => '$count == 5120',
             Name => 'ColorData5',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::ColorData5',
-            },
-        },
-        {   # (int16u[1273]) - 600D
-            Condition => '$count == 1273',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData5' },
+        },
+        {   # (int16u[1273|1275]) - 600D (1273), 1200D (1275)
+            Condition => '$count == 1273 or $count == 1275',
             Name => 'ColorData6',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::ColorData6',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData6' },
+        },
+        {   # (int16u[1312|1313|1316])
+            # 1DX/5DmkIII/650D/700D/M (1312), 6D/70D/100D (1313),
+            # 1DX firmware 1.x (1316), 7DmkII (1506)
+            Condition => '$count == 1312 or $count == 1313 or $count == 1316 or
+                          $count == 1506',
+            Name => 'ColorData7',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData7' },
+        },
+        {   # (int16u[1560|1592]) - 5DS/5DSR (1560), 80D (1592), 1300D (1353) ref IB
+            Condition => '$count == 1560 or $count == 1592 or $count == 1353 or $count == 1602',
+            Name => 'ColorData8',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData8' },
+        },
+        {   # (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' },
+        },
+        {   # (int16u[2024|3656]) - 1DXmkIII (2024) ref IB, R5/R6 (3656) ref PH
+            Condition => '$count == 2024 or $count == 3656',
+            Name => 'ColorData10',
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorData10' },
         },
         {
             Name => 'ColorDataUnknown',
-            SubDirectory => {
-                TagTable => 'Image::ExifTool::Canon::ColorDataUnknown',
-            },
+            SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorDataUnknown' },
         },
     ],
     0x4002 => { #PH
         # unknown data block in some JPEG and CR2 images
-        # (5kB for most models, but 22kb for 5D and 30D)
+        # (5kB for most models, but 22kb for 5D and 30D, and 43kB for 5DmkII so Drop it)
         Name => 'CRWParam',
         Format => 'undef',
-        Flags => [ 'Unknown', 'Binary' ],
+        Flags => [ 'Unknown', 'Binary', 'Drop' ],
     },
     0x4003 => { #PH
         Name => 'ColorInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::ColorInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorInfo' },
     },
     0x4005 => { #PH
@@ -1414,22 +1929,39 @@
         Flags => [ 'Unknown', 'Binary', 'Drop' ],
     },
-    0x4008 => { #PH guess (1DmkIII)
-        Name => 'BlackLevel', # (BasePictStyleOfUser)
-        Unknown => 1,
-    },
-    0x4010 => { #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2933.0.html
-        Name => 'CustomPictureStyleFileName',
+    0x4008 => { #53
+        Name => 'PictureStyleUserDef', # (BasePictStyleOfUser)
+        Writable => 'int16u',
+        Count => 3, # UserDef1, UserDef2, UserDef3
+        PrintHex => 1,
+        SeparateTable => 'PictureStyle',
+        PrintConv => [\%pictureStyles,\%pictureStyles,\%pictureStyles],
+    },
+    0x4009 => { #53
+        Name => 'PictureStylePC', # (BasePictStyleOfUser)
+        Writable => 'int16u',
+        Count => 3, # PC1, PC2, PC3
+        PrintHex => 1,
+        SeparateTable => 'PictureStyle',
+        PrintConv => [\%pictureStyles,\%pictureStyles,\%pictureStyles],
+    },
+    0x4010 => { #forum2933
+        Name => 'CustomPictureStyleFileName', # (PictStyleCaption)
         Writable => 'string',
     },
+    # 0x4011 (PictStyleAppendInfo)
+    # 0x4012 (CustomWBCaption)
     0x4013 => { #PH
-        Name => 'AFMicroAdj',
+        Name => 'AFMicroAdj', # (AFMicroAdjust)
         SubDirectory => {
-            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            # Canon DPP 3.13 is known to truncate this data to 0x14 bytes (from 0x2c),
+            # so specifically check for 0x2c to avoid giving a warning in this case
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size,0x2c)',
             TagTable => 'Image::ExifTool::Canon::AFMicroAdj',
         },
     },
-    0x4015 => {
-        Name => 'VignettingCorr',
-        Condition => '$$valPt !~ /^\0\0\0\0/', # (data may be all zeros for 60D)
+    # 0x4014 (similar to 0x83?)
+    0x4015 => [{
+        Name => 'VignettingCorr', # (LensPacket)
+        Condition => '$$valPt =~ /^\0/ and $$valPt !~ /^\0\0\0\0/', # (data may be all zeros for 60D)
         SubDirectory => {
             # (the size word is at byte 2 in this structure)
@@ -1437,7 +1969,23 @@
             TagTable => 'Image::ExifTool::Canon::VignettingCorr',
         },
-    },
+    },{
+        Name => 'VignettingCorrUnknown1',
+        Condition => '$$valPt =~ /^[\x01\x02\x10\x20]/ and $$valPt !~ /^\0\0\0\0/',
+        SubDirectory => {
+            # (the size word is at byte 2 in this structure)
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart+2,$size)',
+            TagTable => 'Image::ExifTool::Canon::VignettingCorrUnknown',
+        },
+    },{
+        Name => 'VignettingCorrUnknown2',
+        Condition => '$$valPt !~ /^\0\0\0\0/',
+        SubDirectory => {
+            # (the size word is at byte 4 for version 3 of this structure, but not always!)
+            # Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart+4,$size)',
+            TagTable => 'Image::ExifTool::Canon::VignettingCorrUnknown',
+        },
+    }],
     0x4016 => {
-        Name => 'VignettingCorr2',
+        Name => 'VignettingCorr2', # (ImageCorrectActual)
         SubDirectory => {
             # (the size word is actually 4 bytes, but it doesn't matter if little-endian)
@@ -1447,5 +1995,5 @@
     },
     0x4018 => { #PH
-        Name => 'LightingOpt',
+        Name => 'LightingOpt', # (ImageCorrect)
         SubDirectory => {
             Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
@@ -1454,5 +2002,5 @@
     },
     0x4019 => { #20
-        Name => 'LensInfo',
+        Name => 'LensInfo', # (LensInfoForService)
         SubDirectory => {
             TagTable => 'Image::ExifTool::Canon::LensInfo',
@@ -1467,4 +2015,11 @@
         }
     },
+    0x4021 => { #PH
+        Name => 'MultiExp', # (ExifDSTagMultipleExposure)
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::MultiExp',
+        }
+    },
     0x4024 => { #PH
         Name => 'FilterInfo',
@@ -1472,4 +2027,25 @@
             Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
             TagTable => 'Image::ExifTool::Canon::FilterInfo',
+        }
+    },
+    0x4025 => { #PH
+        Name => 'HDRInfo', # (HighDynamicRange)
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::HDRInfo',
+        }
+    },
+    0x4028 => { #PH
+        Name => 'AFConfig', # (AFTabInfo)
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::AFConfig',
+        }
+    },
+    0x403f => { #25
+        Name => 'RawBurstModeRoll',
+        SubDirectory => {
+            Validate => 'Image::ExifTool::Canon::Validate($dirData,$subdirStart,$size)',
+            TagTable => 'Image::ExifTool::Canon::RawBurstInfo',
         }
     },
@@ -1512,4 +2088,5 @@
         Name => 'CanonFlashMode',
         PrintConv => {
+            -1 => 'n/a', # (PH, EOS M MOV video)
             0 => 'Off',
             1 => 'Auto',
@@ -1532,4 +2109,8 @@
             5 => 'Continuous, High', #PH
             6 => 'Silent Single', #PH
+            # 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
             # 32-34 - Self-timer?
         },
@@ -1547,4 +2128,8 @@
            16 => 'Pan Focus', #PH
            # 137 - Single?
+           256 => 'AF + MF', #PH (NC, EOS M)
+           257 => 'Live View', #forum12082
+           512 => 'Movie Snap Focus', #48
+           519 => 'Movie Servo AF', #PH (NC, EOS M)
         },
     },
@@ -1560,5 +2145,11 @@
             6 => 'CR2', # +THM? (1D,30D,350D)
             7 => 'CR2+JPEG', # (S30)
-            9 => 'Video', # (S95 MOV)
+            9 => 'MOV', # (S95 MOV)
+            10 => 'MP4', # (SX280 MP4)
+            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)
         },
     },
@@ -1572,4 +2163,8 @@
         PrintConvColumns => 3,
         PrintConv => {
+            # references:
+            # A = http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm
+            # B = http://www.burren.cx/david/canon.html
+            # C = DPP 3.11.26
             0 => 'Full auto',
             1 => 'Manual',
@@ -1577,17 +2172,17 @@
             3 => 'Fast shutter',
             4 => 'Slow shutter',
-            5 => 'Night',
-            6 => 'Gray Scale', #PH
+            5 => 'Night', # (C='Night Scene')
+            6 => 'Gray Scale', #PH (A/B/C='Black & White')
             7 => 'Sepia',
             8 => 'Portrait',
             9 => 'Sports',
             10 => 'Macro',
-            11 => 'Black & White', #PH
-            12 => 'Pan focus',
-            13 => 'Vivid', #PH
-            14 => 'Neutral', #PH
-            15 => 'Flash Off',  #8
+            11 => 'Black & White', #PH (A='Black & White', B/C='Pan focus')
+            12 => 'Pan focus', # (A='Pan focus', C='Vivid')
+            13 => 'Vivid', #PH (A='Vivid', C='Neutral')
+            14 => 'Neutral', #PH (A='Natural', C='Black & White')
+            15 => 'Flash Off',  #8 (C=<none>)
             16 => 'Long Shutter', #PH
-            17 => 'Super Macro', #PH
+            17 => 'Super Macro', #PH (C='Macro')
             18 => 'Foliage', #PH
             19 => 'Indoor', #PH
@@ -1619,5 +2214,5 @@
             45 => 'Smile', #PH
             46 => 'Wink Self-timer', #PH
-            47 => 'Fisheye Effect', #PH (SX30IS)
+            47 => 'Fisheye Effect', #PH (SX30IS,IXUS240)
             48 => 'Miniature Effect', #PH (SD4500)
             49 => 'High-speed Burst', #PH
@@ -1625,5 +2220,20 @@
             51 => 'High Dynamic Range', #PH (S95)
             52 => 'Handheld Night Scene', #PH
-            59 => 'Scene Intelligent Auto', #PH (T3i)
+            53 => 'Movie Digest', #PH
+            54 => 'Live View Control', #PH
+            55 => 'Discreet', #PH
+            56 => 'Blur Reduction', #PH
+            57 => 'Monochrome', #PH (SX260 B&W,Sepia,Blue tone)
+            58 => 'Toy Camera Effect', #51
+            59 => 'Scene Intelligent Auto', #PH (T3i) (C='High-speed Burst HQ' !!)
+            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
@@ -1725,16 +2335,19 @@
             6 => 'M-Dep', #PH
             7 => 'Bulb', #30
+            8 => 'Flexible-priority AE', #ArnoldVanOostrum
         },
     },
     22 => { #4
         Name => 'LensType',
+        Format => 'int16u',
         RawConv => '$val ? $$self{LensType}=$val : undef', # don't use if value is zero
         Notes => 'this value is incorrect for EOS 7D images with lenses of type 256 or greater',
         SeparateTable => 1,
         DataMember => 'LensType',
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
     23 => {
-        Name => 'LongFocal',
+        Name => 'MaxFocalLength',
         Format => 'int16u',
         # this is a bit tricky, but we need the FocalUnits to convert this to mm
@@ -1746,5 +2359,5 @@
     },
     24 => {
-        Name => 'ShortFocal',
+        Name => 'MinFocalLength',
         Format => 'int16u',
         RawConvInv => '$val * ($$self{FocalUnits} || 1)',
@@ -1785,15 +2398,18 @@
         Name => 'FlashBits',
         PrintConvColumns => 2,
-        PrintConv => { BITMASK => {
-            0 => 'Manual', #PH
-            1 => 'TTL', #PH
-            2 => 'A-TTL', #PH
-            3 => 'E-TTL', #PH
-            4 => 'FP sync enabled',
-            7 => '2nd-curtain sync used',
-            11 => 'FP sync used',
-            13 => 'Built-in',
-            14 => 'External', #(may not be set in manual mode - ref 37)
-        } },
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => {
+                0 => 'Manual', #PH
+                1 => 'TTL', #PH
+                2 => 'A-TTL', #PH
+                3 => 'E-TTL', #PH
+                4 => 'FP sync enabled',
+                7 => '2nd-curtain sync used',
+                11 => 'FP sync used',
+                13 => 'Built-in',
+                14 => 'External', #(may not be set in manual mode - ref 37)
+            },
+        },
     },
     32 => {
@@ -1823,7 +2439,13 @@
             0 => 'Off',
             1 => 'On',
-            2 => 'On, Shot Only', #15 (panning for SX10IS)
-            3 => 'On, Panning', #PH (A570IS)
-            4 => 'On, Video', #PH (SX30IS)
+            2 => 'Shoot Only', #15
+            3 => 'Panning', # (A570IS)
+            4 => 'Dynamic', # (SX30IS) (was 'On, Video')
+            # (don't know what bit 0x100 indicates)
+            256 => 'Off (2)',
+            257 => 'On (2)',
+            258 => 'Shoot Only (2)',
+            259 => 'Panning (2)',
+            260 => 'Dynamic (2)',
         },
     },
@@ -1885,4 +2507,6 @@
         },
     },
+    # 47 - related to aspect ratio: 100=4:3,70=1:1/16:9,90=3:2,60=4:5 (PH G12)
+    #      (roughly image area in percent - 4:3=100%,1:1/16:9=75%,3:2=89%,4:5=60%)
 );
 
@@ -2047,4 +2671,5 @@
         Name => 'SequenceNumber',
         Description => 'Shot Number In Continuous Burst',
+        Notes => 'valid only for some models', #PH (eg. not the 5DmkIII)
     },
     10 => { #PH/17
@@ -2126,4 +2751,5 @@
             0 => 'n/a',
             1 => 'Camera Local Control',
+            # 2 - have seen this for EOS M studio picture
             3 => 'Computer Remote Control',
         },
@@ -2334,12 +2960,12 @@
     PrintConvInv => '$val=~s/\s*mm//;$val',
 );
-my %ciShortFocal = (
-    Name => 'ShortFocal',
+my %ciMinFocal = (
+    Name => 'MinFocalLength',
     Format => 'int16uRev', # byte order is big-endian
     PrintConv => '"$val mm"',
     PrintConvInv => '$val=~s/\s*mm//;$val',
 );
-my %ciLongFocal = (
-    Name => 'LongFocal',
+my %ciMaxFocal = (
+    Name => 'MaxFocalLength',
     Format => 'int16uRev', # byte order is big-endian
     PrintConv => '"$val mm"',
@@ -2377,8 +3003,9 @@
         SeparateTable => 1,
         RawConv => '$val ? $val : undef', # don't use if value is zero
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
     0x0e => {
-        Name => 'ShortFocal',
+        Name => 'MinFocalLength',
         Format => 'int16u',
         PrintConv => '"$val mm"',
@@ -2386,5 +3013,5 @@
     },
     0x10 => {
-        Name => 'LongFocal',
+        Name => 'MaxFocalLength',
         Format => 'int16u',
         PrintConv => '"$val mm"',
@@ -2491,8 +3118,9 @@
         SeparateTable => 1,
         RawConv => '$val ? $val : undef', # don't use if value is zero
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0x11 => { %ciShortFocal }, #9
-    0x13 => { %ciLongFocal }, #9
+    0x11 => { %ciMinFocal }, #9
+    0x13 => { %ciMaxFocal }, #9
     0x2d => { #9
         Name => 'FocalType',
@@ -2567,8 +3195,9 @@
         SeparateTable => 1,
         RawConv => '$val ? $val : undef', # don't use if value is zero
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0x11 => { %ciShortFocal },
-    0x13 => { %ciLongFocal },
+    0x11 => { %ciMinFocal },
+    0x13 => { %ciMaxFocal },
     0x36 => { #15
         Name => 'WhiteBalance',
@@ -2610,6 +3239,5 @@
 );
 
-# Canon camera information for 1DmkIII and 1DSmkIII (MakerNotes tag 0x0d)
-# (ref PH unless otherwise noted)
+# Canon camera information for 1DmkIII and 1DSmkIII (MakerNotes tag 0x0d) (ref PH)
 %Image::ExifTool::Canon::CameraInfo1DmkIII = (
     %binaryDataAttrs,
@@ -2626,6 +3254,6 @@
     0x1b => { %ciMacroMagnification }, #(NC)
     0x1d => { %ciFocalLength },
-    0x30 => {
-        Name => 'CameraOrientation', # <-- (always 9th byte after 0xbbbb for all models - Dave Coffin)
+    0x30 => { # <-- (follows pattern /\xbb\xbb(.{64})?\x01\x01\0\0.{4}/s for all models - Dave Coffin)
+        Name => 'CameraOrientation',
         PrintConv => {
             0 => 'Horizontal (normal)',
@@ -2662,8 +3290,9 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0x113 => { %ciShortFocal },
-    0x115 => { %ciLongFocal },
+    0x113 => { %ciMinFocal },
+    0x115 => { %ciMaxFocal },
     0x136 => { #15
         Name => 'FirmwareVersion',
@@ -2693,7 +3322,5 @@
     0x2aa => { #48
         Name => 'PictureStyleInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
     },
     0x45a => { #29
@@ -2732,8 +3359,26 @@
     FIRST_ENTRY => 0,
     PRIORITY => 0,
-    DATAMEMBER => [ 0x57 ],
-    IS_SUBDIR => [ 0x363, 0x368 ],
+    DATAMEMBER => [ 0x00, 0x56, 0x153 ],
+    IS_SUBDIR => [ 0x368 ],
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => 'CameraInfo tags for the 1DmkIV.',
+    NOTES => q{
+        CameraInfo tags for the EOS 1D Mark IV.  Indices shown are for firmware
+        versions 1.0.x, but they may be different for other firmware versions.
+    },
+    0x00 => {
+        Name => 'FirmwareVersionLookAhead',
+        Hidden => 1,
+        # look ahead to check location of FirmwareVersion string
+        Format => 'undef[0x1fd]',
+        RawConv => q{
+            my $t = substr($val, 0x1e8, 6); # 1 = firmware 4.2.1
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
+            $t = substr($val, 0x1ed, 6);    # 2 = firmware 1.0.4
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
+            $self->Warn('Unrecognized CameraInfo1DmkIV firmware version');
+            $$self{CanonFirm} = 0;
+            return undef;   # not a real tag
+        },
+    },
     0x03 => { %ciFNumber },
     0x04 => { %ciExposureTime },
@@ -2741,5 +3386,5 @@
     0x07 => {
         Name => 'HighlightTonePriority',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
     },
     0x08 => {
@@ -2784,89 +3429,34 @@
         Name => 'FocusDistanceLower',
         %focusDistanceByteSwap,
-    },
-    0x57 => {
-        Name => 'FirmwareVersionLookAhead',
-        Hidden => 1,
-        # must look ahead to check location of FirmwareVersion string
-        Format => 'undef[0x1a6]',
-        RawConv => q{
-            my $t = substr($val, 0x1e8 - 0x57, 6);
-            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirmA} = 1;
-            $t = substr($val, 0x1ed - 0x57, 6);
-            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirmB} = 1;
-            return undef;   # not a real tag
-        },
-    },
-    0x77 => {
+        Hook => '$varSize += ($$self{CanonFirm} ? -1 : 0x10000) if $$self{CanonFirm} < 2',
+    },
+    0x78 => {
         Name => 'WhiteBalance',
-        Condition => '$$self{CanonFirmA}',
-        Notes => 'firmware 4.2.1',
         Format => 'int16u',
         SeparateTable => 1,
         PrintConv => \%canonWhiteBalance,
     },
-    0x78 => {
-        Name => 'WhiteBalance',
-        Condition => '$$self{CanonFirmB}',
-        Notes => 'firmware 1.0.4',
-        Format => 'int16u',
-        SeparateTable => 1,
-        PrintConv => \%canonWhiteBalance,
-    },
-    0x7b => {
-        Name => 'ColorTemperature',
-        Condition => '$$self{CanonFirmA}',
-        Format => 'int16u',
-    },
     0x7c => {
         Name => 'ColorTemperature',
-        Condition => '$$self{CanonFirmB}',
         Format => 'int16u',
     },
-    0x14e => {
+    0x14f => {
         Name => 'LensType',
-        Condition => '$$self{CanonFirmA}',
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0x14f => {
-        Name => 'LensType',
-        Condition => '$$self{CanonFirmB}',
-        Format => 'int16uRev', # value is big-endian
-        SeparateTable => 1,
-        PrintConv => \%canonLensTypes,
-    },
-    0x150 => {
-        %ciShortFocal,
-        Condition => '$$self{CanonFirmA}',
-    },
-    0x151 => {
-        %ciShortFocal,
-        Condition => '$$self{CanonFirmB}',
-    },
-    0x152 => {
-        %ciLongFocal,
-        Condition => '$$self{CanonFirmA}',
-    },
-    0x153 => {
-        %ciLongFocal,
-        Condition => '$$self{CanonFirmB}',
-    },
-    0x1e8 => { # firmware 4.2.1 (pre-production)
+    0x151 => { %ciMinFocal },
+    0x153 => { %ciMaxFocal,
+        Hook => '$varSize -= 4 if $$self{CanonFirm} < 2',
+    },
+    0x1ed => {
         Name => 'FirmwareVersion',
-        Condition => '$$self{CanonFirmA}',
         Format => 'string[6]',
         Writable => 0,
     },
-    0x1ed => { # firmware 1.0.4
-        Name => 'FirmwareVersion',
-        Condition => '$$self{CanonFirmB}',
-        Format => 'string[6]',
-        Writable => 0,
-    },
-    0x227 => { #(NC)
+    0x22c => { #(NC)
         Name => 'FileIndex',
-        Condition => '$$self{CanonFirmA}',
         Groups => { 2 => 'Image' },
         Format => 'int32u',
@@ -2874,7 +3464,109 @@
         ValueConvInv => '$val - 1',
     },
-    0x22c => { #(NC)
+    0x238 => { #(NC)
+        Name => 'DirectoryIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
+    },
+    0x368 => {
+        Name => 'PictureStyleInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
+    },
+);
+
+# Camera information for 1D X (MakerNotes tag 0x0d) (ref PH)
+%Image::ExifTool::Canon::CameraInfo1DX = (
+    %binaryDataAttrs,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    DATAMEMBER => [ 0x00, 0x1b, 0x8e, 0x1ab ],
+    IS_SUBDIR => [ 0x3f4 ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        CameraInfo tags for the EOS 1D X.  Indices shown are for firmware version
+        1.0.2, but they may be different for other firmware versions.
+    },
+    0x00 => {
+        Name => 'FirmwareVersionLookAhead',
+        Hidden => 1,
+        # look ahead to check location of FirmwareVersion string
+        Format => 'undef[0x28b]',
+        RawConv => q{
+            my $t = substr($val, 0x271, 6); # 1 = firmware 5.7.1
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
+            $t = substr($val, 0x279, 6);    # 2 = firmware 6.5.1
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
+            $t = substr($val, 0x280, 6);    # 3 = firmware 0.0.8/1.0.2/1.1.1
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 3, return undef;
+            $t = substr($val, 0x285, 6);    # 4 = firmware 2.1.0
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 4, return undef;
+            $self->Warn('Unrecognized CameraInfo1DX firmware version');
+            $$self{CanonFirm} = 0;
+            return undef;   # not a real tag
+        },
+    },
+    0x03 => { %ciFNumber },
+    0x04 => { %ciExposureTime },
+    0x06 => { %ciISO },
+    0x1b => { %ciCameraTemperature,
+        Hook => '$varSize -= 3 if $$self{CanonFirm} < 3',
+    },
+    0x23 => { %ciFocalLength },
+    0x7d => {
+        Name => 'CameraOrientation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
+    0x8c => {
+        Name => 'FocusDistanceUpper',
+        %focusDistanceByteSwap,
+    },
+    0x8e => {
+        Name => 'FocusDistanceLower',
+        %focusDistanceByteSwap,
+        Hook => '$varSize -= 4 if $$self{CanonFirm} < 3; $varSize += 5 if $$self{CanonFirm} == 4',
+    },
+    0xbc => {
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        SeparateTable => 1,
+        PrintConv => \%canonWhiteBalance,
+    },
+    0xc0 => {
+        Name => 'ColorTemperature',
+        Format => 'int16u',
+    },
+    0xf4 => {
+        Name => 'PictureStyle',
+        Format => 'int8u',
+        Flags => ['PrintHex','SeparateTable'],
+        PrintConv => \%pictureStyles,
+    },
+    0x1a7 => {
+        Name => 'LensType',
+        Format => 'int16uRev', # value is big-endian
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%canonLensTypes,
+    },
+    0x1a9 => { %ciMinFocal },
+    0x1ab => { %ciMaxFocal,
+        # add another offset of -8 for firmware 5.7.1, and a large offset
+        # to effectively abort processing for unknown firmware
+        Hook => '$varSize += ($$self{CanonFirm} ? -8 : 0x10000) if $$self{CanonFirm} < 2',
+    },
+    0x280 => {
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+    },
+    0x2d0 => { # (doesn't seem to work for firmware 2.0.3 - PH)
         Name => 'FileIndex',
-        Condition => '$$self{CanonFirmB}',
         Groups => { 2 => 'Image' },
         Format => 'int32u',
@@ -2882,7 +3574,6 @@
         ValueConvInv => '$val - 1',
     },
-    0x233 => { #(NC)
+    0x2dc => { #(NC)
         Name => 'DirectoryIndex',
-        Condition => '$$self{CanonFirmA}',
         Groups => { 2 => 'Image' },
         Format => 'int32u',
@@ -2890,25 +3581,7 @@
         ValueConvInv => '$val + 1',
     },
-    0x238 => { #(NC)
-        Name => 'DirectoryIndex',
-        Condition => '$$self{CanonFirmB}',
-        Groups => { 2 => 'Image' },
-        Format => 'int32u',
-        ValueConv => '$val - 1',
-        ValueConvInv => '$val + 1',
-    },
-    0x363 => {
+    0x3f4 => {
         Name => 'PictureStyleInfo',
-        Condition => '$$self{CanonFirmA}',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
-    },
-    0x368 => {
-        Name => 'PictureStyleInfo',
-        Condition => '$$self{CanonFirmB}',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
     },
 );
@@ -2931,4 +3604,5 @@
         SeparateTable => 1,
         RawConv => '$val ? $val : undef', # don't use if value is zero
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
@@ -2948,21 +3622,23 @@
         Format => 'int16uRev',
         PrintConvColumns => 2,
-        PrintConv => { BITMASK => {
-            0 => 'Center',
-            1 => 'Top',
-            2 => 'Bottom',
-            3 => 'Upper-left',
-            4 => 'Upper-right',
-            5 => 'Lower-left',
-            6 => 'Lower-right',
-            7 => 'Left',
-            8 => 'Right',
-            9 => 'AI Servo1',
-           10 => 'AI Servo2',
-           11 => 'AI Servo3',
-           12 => 'AI Servo4',
-           13 => 'AI Servo5',
-           14 => 'AI Servo6',
-        } },
+        PrintConv => { 0 => '(none)',
+            BITMASK => {
+                0 => 'Center',
+                1 => 'Top',
+                2 => 'Bottom',
+                3 => 'Upper-left',
+                4 => 'Upper-right',
+                5 => 'Lower-left',
+                6 => 'Lower-right',
+                7 => 'Left',
+                8 => 'Right',
+                9 => 'AI Servo1',
+               10 => 'AI Servo2',
+               11 => 'AI Servo3',
+               12 => 'AI Servo4',
+               13 => 'AI Servo5',
+               14 => 'AI Servo6',
+           },
+        },
     },
     0x54 => { #15
@@ -2982,10 +3658,11 @@
         PrintConv => \%pictureStyles,
     },
-    0x93 => { %ciShortFocal }, #15
-    0x95 => { %ciLongFocal }, #15
+    0x93 => { %ciMinFocal }, #15
+    0x95 => { %ciMaxFocal }, #15
     0x97 => { #15
         Name => 'LensType',
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
@@ -2998,6 +3675,11 @@
         Format => 'string[16]',
     },
+    0xcc => { #PH (NC)
+        Name => 'DirectoryIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+    },
     0xd0 => {
-        Name => 'ImageNumber',
+        Name => 'FileIndex',
         Format => 'int16u',
         Groups => { 2 => 'Image' },
@@ -3094,6 +3776,5 @@
 );
 
-# Camera information for 5D Mark II (MakerNotes tag 0x0d)
-# (ref PH unless otherwise noted)
+# Camera information for 5D Mark II (MakerNotes tag 0x0d) (ref PH)
 %Image::ExifTool::Canon::CameraInfo5DmkII = (
     %binaryDataAttrs,
@@ -3101,7 +3782,26 @@
     FIRST_ENTRY => 0,
     PRIORITY => 0,
-    IS_SUBDIR => [ 0x15a, 0x17e ],
+    DATAMEMBER => [ 0x00, 0xea ],
+    IS_SUBDIR => [ 0x2f7 ],
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => 'CameraInfo tags for the EOS 5D Mark II.',
+    NOTES => q{
+        CameraInfo tags for the EOS 5D Mark II.  Indices shown are for firmware
+        version 1.0.6, but they may be different for other firmware versions.
+    },
+    0x00 => {
+        Name => 'FirmwareVersionLookAhead',
+        Hidden => 1,
+        # look ahead to check location of FirmwareVersion string
+        Format => 'undef[0x184]',
+        RawConv => q{
+            my $t = substr($val, 0x15a, 6); # 1 = firmware 3.4.6/3.6.1
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
+            $t = substr($val, 0x17e, 6);    # 2 = firmware 4.1.1/1.0.6
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
+            $self->Warn('Unrecognized CameraInfo5DmkII firmware version');
+            $$self{CanonFirm} = 0;
+            return undef;   # not a real tag
+        },
+    },
     0x03 => { %ciFNumber },
     0x04 => { %ciExposureTime },
@@ -3109,5 +3809,5 @@
     0x07 => {
         Name => 'HighlightTonePriority',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
     },
     0x1b => { %ciMacroMagnification }, #PH
@@ -3179,35 +3879,13 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0xe8 => { %ciShortFocal },
-    0xea => { %ciLongFocal },
-    0x15a => {
-        Name => 'CameraInfo5DmkII_2a',
-        Condition => '$$valPt =~ /^\d+\.\d+\.\d+[\s\0]/',
-        Notes => 'at this location for firmware 3.4.6 and 3.6.1',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkII_2',
-        },
+    0xe8 => { %ciMinFocal },
+    0xea => { %ciMaxFocal,
+        # offset changes after this for different firmware versions
+        Hook => '$varSize += ($$self{CanonFirm} ? -36 : 0x10000) if $$self{CanonFirm} < 2',
     },
     0x17e => {
-        Name => 'CameraInfo5DmkII_2b',
-        Condition => '$$valPt =~ /^\d+\.\d+\.\d+[\s\0]/',
-        Notes => 'at this location for firmware 1.0.6 and 4.1.1',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::CameraInfo5DmkII_2',
-        },
-    },
-);
-
-# variable-position Camera information for 5DmkII (ref PH)
-%Image::ExifTool::Canon::CameraInfo5DmkII_2 = (
-    %binaryDataAttrs,
-    FIRST_ENTRY => 0,
-    PRIORITY => 0,
-    IS_SUBDIR => [ 0x179 ],
-    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => 'More CameraInfo tags for the EOS 5D Mark II.',
-    0 => {
         Name => 'FirmwareVersion',
         Format => 'string[6]',
@@ -3216,5 +3894,5 @@
         RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
     },
-    0x3d => {
+    0x1bb => {
         Name => 'FileIndex',
         Groups => { 2 => 'Image' },
@@ -3223,5 +3901,5 @@
         ValueConvInv => '$val - 1',
     },
-    0x49 => { #(NC)
+    0x1c7 => { #(NC)
         Name => 'DirectoryIndex',
         Groups => { 2 => 'Image' },
@@ -3230,9 +3908,235 @@
         ValueConvInv => '$val + 1',
     },
-    0x179 => { #48
+    0x2f7 => { #48
         Name => 'PictureStyleInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
+    },
+);
+
+# Camera information for 5D Mark III (MakerNotes tag 0x0d) (ref PH)
+%Image::ExifTool::Canon::CameraInfo5DmkIII = (
+    %binaryDataAttrs,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    DATAMEMBER => [ 0x00, 0x1b, 0x23, 0x8e, 0x157 ],
+    IS_SUBDIR => [ 0x3b0 ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        CameraInfo tags for the EOS 5D Mark III.  Indices shown are for firmware
+        versions 1.0.x, but they may be different for other firmware versions.
+    },
+    0x00 => {
+        Name => 'FirmwareVersionLookAhead',
+        Hidden => 1,
+        # look ahead to check location of FirmwareVersion string
+        Format => 'undef[0x24d]',
+        RawConv => q{
+            my $t = substr($val, 0x22c, 6); # 1 = firmware 4.5.4/4.5.6
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
+            $t = substr($val, 0x22d, 6);    # 2 = firmware 5.2.2/5.3.1/5.4.2
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
+            $t = substr($val, 0x23c, 6);    # 3 = firmware 1.0.3/1.0.7
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 3, return undef;
+            $t = substr($val, 0x242, 6);    # 4 = firmware 1.2.1
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 4, return undef;
+            $t = substr($val, 0x247, 6);    # 5 = firmware 1.3.5
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 5, return undef;
+            $self->Warn('Unrecognized CameraInfo5DmkIII firmware version');
+            $$self{CanonFirm} = 0;
+            return undef;   # not a real tag
+        },
+    },
+    0x03 => { %ciFNumber },
+    0x04 => { %ciExposureTime },
+    0x06 => { %ciISO },
+    0x1b => { %ciCameraTemperature,
+        # decrement $varSize for missing byte after this tag with firmware 5.x and earlier
+        # (and add large offset to effectively abort processing if unknown firmware)
+        Hook => '$varSize += ($$self{CanonFirm} ? -1 : 0x10000) if $$self{CanonFirm} < 3',
+    },
+    0x23 => { %ciFocalLength,
+        Hook => q{
+            $varSize -= 3 if $$self{CanonFirm} == 1;
+            $varSize -= 2 if $$self{CanonFirm} == 2;
+            $varSize += 6 if $$self{CanonFirm} >= 4;
+        },
+    },
+    0x7d => {
+        Name => 'CameraOrientation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
+    0x8c => {
+        Name => 'FocusDistanceUpper',
+        %focusDistanceByteSwap,
+    },
+    0x8e => {
+        Name => 'FocusDistanceLower',
+        %focusDistanceByteSwap,
+        Hook => q{
+            $varSize -= 4 if $$self{CanonFirm} < 3;
+            $varSize += 5 if $$self{CanonFirm} > 4;
+        },
+    },
+    0xbc => {
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        SeparateTable => 1,
+        PrintConv => \%canonWhiteBalance,
+    },
+    0xc0 => {
+        Name => 'ColorTemperature',
+        Format => 'int16u',
+    },
+    0xf4 => {
+        Name => 'PictureStyle',
+        Format => 'int8u',
+        Flags => ['PrintHex','SeparateTable'],
+        PrintConv => \%pictureStyles,
+    },
+    0x153 => {
+        Name => 'LensType',
+        Format => 'int16uRev', # value is big-endian
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%canonLensTypes,
+    },
+    0x155 => { %ciMinFocal },
+    0x157 => { %ciMaxFocal,
+        Hook => '$varSize -= 8 if $$self{CanonFirm} < 3',
+    },
+    0x164 => {
+        Name => 'LensSerialNumber',
+        Format => 'undef[5]',
+        Priority => 0,
+        ValueConv => 'unpack("H*",$val)',
+        ValueConvInv => 'length($val) < 10 and $val = 0 x (10-length($val)) . $val; pack("H*",$val)',
+    },
+    0x23c => {
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+    },
+    # the 5DmkIII has "User setting1" and "User setting2" file naming options:
+    # - with "User setting1" 4 characters are selectable
+    # - with "User setting2", 3 characters are selectable, and the 4th character
+    # - in the file name corresponds to the image size:
+    #   L=large, M=medium, S=small1, T=small2, U=small3, _=movie
+    # - as shipped, the first 4 characters of the file name are unique to the camera
+    0x28c => { # used for file names like IMG_xxxx.JPG
+        Name => 'FileIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x290 => { # used for file names like 2F0Axxxx.JPG and 6T3Cxxxx.JPG
+        Name => 'FileIndex2',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x298 => { #(NC)
+        Name => 'DirectoryIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
+    },
+    0x29c => { #(NC)
+        Name => 'DirectoryIndex2',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
+    },
+    0x3b0 => {
+        Name => 'PictureStyleInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
+    },
+);
+
+# Camera information for 6D (MakerNotes tag 0x0d) (ref PH)
+%Image::ExifTool::Canon::CameraInfo6D = (
+    %binaryDataAttrs,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    IS_SUBDIR => [ 0x3c6 ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'CameraInfo tags for the EOS 6D.',
+    0x03 => { %ciFNumber },
+    0x04 => { %ciExposureTime },
+    0x06 => { %ciISO },
+    0x1b => { %ciCameraTemperature },
+    0x23 => { %ciFocalLength },
+    0x83 => { # (5DmkIII + 6)
+        Name => 'CameraOrientation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
+    0x92 => { # (5DmkIII + 6)
+        Name => 'FocusDistanceUpper',
+        %focusDistanceByteSwap,
+    },
+    0x94 => { # (5DmkIII + 6)
+        Name => 'FocusDistanceLower',
+        %focusDistanceByteSwap,
+    },
+    0xc2 => { # (5DmkIII + 6)
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        SeparateTable => 1,
+        PrintConv => \%canonWhiteBalance,
+    },
+    0xc6 => { # (5DmkIII + 6)
+        Name => 'ColorTemperature',
+        Format => 'int16u',
+    },
+    0xfa => { # (5DmkIII + 6)
+        Name => 'PictureStyle',
+        Format => 'int8u',
+        Flags => ['PrintHex','SeparateTable'],
+        PrintConv => \%pictureStyles,
+    },
+    0x161 => { # (5DmkIII + 0x0e)
+        Name => 'LensType',
+        Format => 'int16uRev', # value is big-endian
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%canonLensTypes,
+    },
+    0x163 => { %ciMinFocal }, # (5DmkIII + 0x0e)
+    0x165 => { %ciMaxFocal }, # (5DmkIII + 0x0e)
+    0x256 => { # (5DmkIII + 0x1a)
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+    },
+    0x2aa => { # (5DmkIII + 0x16 or 0x1e)
+        Name => 'FileIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x2b6 => { #(NC) (5DmkIII + 0x16 or 0x1e)
+        Name => 'DirectoryIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
+    },
+    0x3c6 => { # (5DmkIII + 0x16)
+        Name => 'PictureStyleInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
     },
 );
@@ -3244,8 +4148,26 @@
     FIRST_ENTRY => 0,
     PRIORITY => 0,
-    IS_SUBDIR => [ 0x20, 0x24 ],
-    DATAMEMBER => [ 0x1f ],
+    DATAMEMBER => [ 0x00, 0x1e ],
+    IS_SUBDIR => [ 0x327 ],
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => 'CameraInfo tags for the EOS 7D.',
+    NOTES => q{
+        CameraInfo tags for the EOS 7D.  Indices shown are for firmware versions
+        1.0.x, but they may be different for other firmware versions.
+    },
+    0x00 => {
+        Name => 'FirmwareVersionLookAhead',
+        Hidden => 1,
+        # look ahead to check location of FirmwareVersion string
+        Format => 'undef[0x1b2]',
+        RawConv => q{
+            my $t = substr($val, 0x1a8, 6); # 1 = firmware 3.7.5
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
+            $t = substr($val, 0x1ac, 6);    # 2 = firmware 1.0.7/1.0.8/1.1.0/1.2.1/1.2.2
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
+            $self->Warn('Unrecognized CameraInfo7D firmware version');
+            $$self{CanonFirm} = 0;
+            return undef;   # not a real tag
+        },
+    },
     0x03 => { %ciFNumber },
     0x04 => { %ciExposureTime },
@@ -3253,5 +4175,5 @@
     0x07 => {
         Name => 'HighlightTonePriority',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
     },
     0x08 => { #37
@@ -3280,46 +4202,8 @@
     },
     0x19 => { %ciCameraTemperature },
-    0x1e => { %ciFocalLength },
-    0x1f => {
-        Name => 'FirmwareVersionLookAhead',
-        Hidden => 1,
-        # must look ahead to check location of FirmwareVersion string
-        Format => 'undef[0x1a0]',
-        RawConv => q{
-            my $t = substr($val, 0x1a8 - 0x1f, 6);
-            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirmA} = 1;
-            $t = substr($val, 0x1ac - 0x1f, 6);
-            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirmB} = 1;
-            return undef;   # not a real tag
-        },
-    },
-    0x20 => {
-        Name => 'CameraInfo7D_2a',
-        Condition => '$$self{CanonFirmA}',
-        Notes => 'at this location for pre-production firmware version 3.7.5',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::CameraInfo7D_2',
-        },
-    },
-    0x24 => {
-        Name => 'CameraInfo7D_2b',
-        Condition => '$$self{CanonFirmB}',
-        Notes => 'at this location for firmware 1.0.7, 1.0.8, 1.1.0, 1.2.1 and 1.2.2',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::CameraInfo7D_2',
-        },
-    },
-);
-
-# variable-position Camera information for 7D (ref PH)
-%Image::ExifTool::Canon::CameraInfo7D_2 = (
-    %binaryDataAttrs,
-    FORMAT => 'int8u',
-    FIRST_ENTRY => 0,
-    PRIORITY => 0,
-    IS_SUBDIR => [ 0x303 ],
-    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => 'More CameraInfo tags for the EOS 7D.',
-    0x11 => {
+    0x1e => { %ciFocalLength,
+        Hook => '$varSize += ($$self{CanonFirm} ? -4 : 0x10000) if $$self{CanonFirm} < 2',
+    },
+    0x35 => {
         Name => 'CameraOrientation',
         PrintConv => {
@@ -3329,13 +4213,13 @@
         },
     },
-    0x30 => {
+    0x54 => {
         Name => 'FocusDistanceUpper',
         %focusDistanceByteSwap,
     },
-    0x32 => {
+    0x56 => {
         Name => 'FocusDistanceLower',
         %focusDistanceByteSwap,
     },
-    0x53 => {
+    0x77 => {
         Name => 'WhiteBalance',
         Format => 'int16u',
@@ -3343,9 +4227,24 @@
         PrintConv => \%canonWhiteBalance,
     },
-    0x57 => {
+    0x7b => {
         Name => 'ColorTemperature',
         Format => 'int16u',
     },
-    0xa5 => {
+    0xaf => {
+        Name => 'CameraPictureStyle',
+        PrintHex => 1,
+        PrintConv => {
+            0x81 => 'Standard',
+            0x82 => 'Portrait',
+            0x83 => 'Landscape',
+            0x84 => 'Neutral',
+            0x85 => 'Faithful',
+            0x86 => 'Monochrome',
+            0x21 => 'User Defined 1',
+            0x22 => 'User Defined 2',
+            0x23 => 'User Defined 3',
+        },
+    },
+    0xc9 => {
         Name => 'HighISONoiseReduction',
         PrintConv => {
@@ -3356,13 +4255,14 @@
         },
     },
-    0xee => {
+    0x112 => {
         Name => 'LensType',
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0xf0 => { %ciShortFocal },
-    0xf2 => { %ciLongFocal },
-    0x188 => {
+    0x114 => { %ciMinFocal },
+    0x116 => { %ciMaxFocal },
+    0x1ac => {
         Name => 'FirmwareVersion',
         Format => 'string[6]',
@@ -3371,5 +4271,5 @@
         RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
     },
-    0x1c7 => {
+    0x1eb => {
         Name => 'FileIndex',
         Groups => { 2 => 'Image' },
@@ -3378,5 +4278,5 @@
         ValueConvInv => '$val - 1',
     },
-    0x1d3 => { #(NC)
+    0x1f7 => { #(NC)
         Name => 'DirectoryIndex',
         Groups => { 2 => 'Image' },
@@ -3385,9 +4285,7 @@
         ValueConvInv => '$val + 1',
     },
-    0x303 => { #48
+    0x327 => { #48
         Name => 'PictureStyleInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
     },
 );
@@ -3450,8 +4348,9 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0xd8 => { %ciShortFocal }, #15
-    0xda => { %ciLongFocal }, #15
+    0xd8 => { %ciMinFocal }, #15
+    0xda => { %ciMaxFocal }, #15
     0xff => { #15
         Name => 'FirmwareVersion',
@@ -3475,7 +4374,5 @@
     0x25b => {
         Name => 'PictureStyleInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
     },
     0x92b => { #33
@@ -3485,6 +4382,5 @@
 );
 
-# Canon camera information for 50D (MakerNotes tag 0x0d)
-# (ref PH unless otherwise noted)
+# Canon camera information for 50D (MakerNotes tag 0x0d) (ref PH)
 %Image::ExifTool::Canon::CameraInfo50D = (
     %binaryDataAttrs,
@@ -3492,8 +4388,26 @@
     FIRST_ENTRY => 0,
     PRIORITY => 0,
-    DATAMEMBER => [ 0x15a, 0x15e ],
-    IS_SUBDIR => [ 0x2d3, 0x2d7 ],
+    DATAMEMBER => [ 0x00, 0xee ],
+    IS_SUBDIR => [ 0x2d7 ],
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => 'CameraInfo tags for the EOS 50D.',
+    NOTES => q{
+        CameraInfo tags for the EOS 50D.  Indices shown are for firmware versions
+        1.0.x, but they may be different for other firmware versions.
+    },
+    0x00 => {
+        Name => 'FirmwareVersionLookAhead',
+        Hidden => 1,
+        # look ahead to check location of FirmwareVersion string
+        Format => 'undef[0x164]',
+        RawConv => q{
+            my $t = substr($val, 0x15a, 6); # 1 = firmware 2.6.1
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 1, return undef;
+            $t = substr($val, 0x15e, 6);    # 2 = firmware 2.9.1/3.1.1/1.0.2/1.0.3
+            $t =~ /^\d+\.\d+\.\d+/ and $$self{CanonFirm} = 2, return undef;
+            $self->Warn('Unrecognized CameraInfo50D firmware version');
+            $$self{CanonFirm} = 0;
+            return undef;   # not a real tag
+        },
+    },
     0x03 => { %ciFNumber },
     0x04 => { %ciExposureTime },
@@ -3501,5 +4415,5 @@
     0x07 => {
         Name => 'HighlightTonePriority',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
     },
     0x15 => { #PH (580 EX II)
@@ -3569,25 +4483,18 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0xec => { %ciShortFocal },
-    0xee => { %ciLongFocal },
-    0x15a => {
-        Name => 'FirmwareVersion',
-        Format => 'string[6]',
-        Notes => 'at this location for firmware 2.6.1',
-        Writable => 0,
-        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $$self{CanonFirmA}=$val : undef',
+    0xec => { %ciMinFocal },
+    0xee => { %ciMaxFocal,
+        Hook => '$varSize += ($$self{CanonFirm} ? -4 : 0x10000) if $$self{CanonFirm} < 2',
     },
     0x15e => { #33
         Name => 'FirmwareVersion',
         Format => 'string[6]',
-        Notes => 'at this location for firmware 1.0.2, 1.0.3, 2.9.1 and 3.1.1',
         Writable => 0,
-        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $$self{CanonFirmB}=$val : undef',
-    },
-    0x197 => {
+    },
+    0x19b => {
         Name => 'FileIndex',
-        Condition => '$$self{CanonFirmA}',
         Groups => { 2 => 'Image' },
         Format => 'int32u',
@@ -3595,15 +4502,6 @@
         ValueConvInv => '$val - 1',
     },
-    0x19b => {
-        Name => 'FileIndex',
-        Condition => '$$self{CanonFirmB}',
-        Groups => { 2 => 'Image' },
-        Format => 'int32u',
-        ValueConv => '$val + 1',
-        ValueConvInv => '$val - 1',
-    },
-    0x1a3 => { #(NC)
+    0x1a7 => { #(NC)
         Name => 'DirectoryIndex',
-        Condition => '$$self{CanonFirmA}',
         Groups => { 2 => 'Image' },
         Format => 'int32u',
@@ -3611,30 +4509,11 @@
         ValueConvInv => '$val + 1',
     },
-    0x1a7 => { #(NC)
-        Name => 'DirectoryIndex',
-        Condition => '$$self{CanonFirmB}',
-        Groups => { 2 => 'Image' },
-        Format => 'int32u',
-        ValueConv => '$val - 1',
-        ValueConvInv => '$val + 1',
-    },
-    0x2d3 => {
-        Name => 'PictureStyleInfo',
-        Condition => '$$self{CanonFirmA}',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
-    },
     0x2d7 => {
         Name => 'PictureStyleInfo',
-        Condition => '$$self{CanonFirmB}',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
-    },
-);
-
-# Canon camera information for 60D (MakerNotes tag 0x0d)
-# (ref PH unless otherwise noted)
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
+    },
+);
+
+# Canon camera information for 60D/1200D (MakerNotes tag 0x0d) (ref PH)
 # NOTE: Can probably borrow more 50D tags here, possibly with an offset
 %Image::ExifTool::Canon::CameraInfo60D = (
@@ -3643,8 +4522,7 @@
     FIRST_ENTRY => 0,
     PRIORITY => 0,
-  #  DATAMEMBER => [ 0x199 ],
-    IS_SUBDIR => [ 0x321 ],
+    IS_SUBDIR => [ 0x2f9, 0x321 ],
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => 'CameraInfo tags for the EOS 60D.',
+    NOTES => 'CameraInfo tags for the EOS 60D and 1200D.',
     0x03 => { %ciFNumber },
     0x04 => { %ciExposureTime },
@@ -3654,4 +4532,6 @@
     0x36 => {
         Name => 'CameraOrientation',
+        Condition => '$$self{Model} =~ /EOS 60D$/', #(NC)
+        Notes => '60D only',
         PrintConv => {
             0 => 'Horizontal (normal)',
@@ -3660,14 +4540,30 @@
         },
     },
+    0x3a => { #IB
+        Name => 'CameraOrientation',
+        Condition => '$$self{Model} =~ /\b(1200D|REBEL T5|Kiss X70)\b/',
+        Notes => '1200D only',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
     0x55 => {
         Name => 'FocusDistanceUpper',
+        Condition => '$$self{Model} =~ /EOS 60D$/',
+        Notes => '60D only',
         %focusDistanceByteSwap,
     },
     0x57 => {
         Name => 'FocusDistanceLower',
+        Condition => '$$self{Model} =~ /EOS 60D$/',
+        Notes => '60D only',
         %focusDistanceByteSwap,
     },
     0x7d => {
         Name => 'ColorTemperature',
+        Condition => '$$self{Model} =~ /EOS 60D$/',
+        Notes => '60D only',
         Format => 'int16u',
     },
@@ -3676,16 +4572,96 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0xea => { %ciShortFocal },
-    0xec => { %ciLongFocal },
-    0x199 => {
+    0xea => { %ciMinFocal },
+    0xec => { %ciMaxFocal },
+    0x199 => {  # (at this location for 60D firmware 2.8.1/1.0.5, and 1200D 3.3.1/1.0.0)
         Name => 'FirmwareVersion',
         Format => 'string[6]',
-  #      Notes => 'at this location for firmware 2.8.1 and 1.0.5',
         Writable => 0,
-  #      RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $$self{CanonFirmA}=$val : undef',
     },
     0x1d9 => {
+        Name => 'FileIndex',
+        Condition => '$$self{Model} =~ /EOS 60D$/',
+        Notes => '60D only',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x1e5 => { #(NC)
+        Name => 'DirectoryIndex',
+        Condition => '$$self{Model} =~ /EOS 60D$/',
+        Notes => '60D only',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
+    },
+    0x2f9 => {
+        Name => 'PictureStyleInfo',
+        Condition => '$$self{Model} =~ /\b(1200D|REBEL T5|Kiss X70)\b/',
+        Notes => '1200D',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
+    },
+    0x321 => {
+        Name => 'PictureStyleInfo',
+        Condition => '$$self{Model} =~ /EOS 60D$/',
+        Notes => '60D',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
+    },
+);
+
+# Canon camera information for 70D (MakerNotes tag 0x0d) (ref PH)
+%Image::ExifTool::Canon::CameraInfo70D = (
+    %binaryDataAttrs,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    IS_SUBDIR => [ 0x3cf ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'CameraInfo tags for the EOS 70D.',
+    0x03 => { %ciFNumber },
+    0x04 => { %ciExposureTime },
+    0x06 => { %ciISO },
+    0x1b => { %ciCameraTemperature },
+    0x23 => { %ciFocalLength },
+    # 0x36 - focal length again?
+    0x84 => {
+        Name => 'CameraOrientation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
+    0x93 => {
+        Name => 'FocusDistanceUpper',
+        %focusDistanceByteSwap,
+    },
+    0x95 => {
+        Name => 'FocusDistanceLower',
+        %focusDistanceByteSwap,
+    },
+    0xc7 => {
+        Name => 'ColorTemperature',
+        Format => 'int16u',
+    },
+    0x166 => {
+        Name => 'LensType',
+        Format => 'int16uRev', # value is big-endian
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%canonLensTypes,
+    },
+    0x168 => { %ciMinFocal },
+    0x16a => { %ciMaxFocal },
+    0x25e => {  # (at this location for firmware 6.1.2, 1.0.4 and 1.1.1)
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+    },
+    0x2b3 => {
         Name => 'FileIndex',
         Groups => { 2 => 'Image' },
@@ -3694,5 +4670,5 @@
         ValueConvInv => '$val - 1',
     },
-    0x1e5 => { #(NC)
+    0x2bf => { #(NC)
         Name => 'DirectoryIndex',
         Groups => { 2 => 'Image' },
@@ -3701,9 +4677,70 @@
         ValueConvInv => '$val + 1',
     },
-    0x321 => {
-        Name => 'PictureStyleInfo2',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo2',
-        },
+    0x3cf => { #48
+        Name => 'PictureStyleInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
+    },
+);
+
+# Canon camera information for 80D (MakerNotes tag 0x0d) (ref PH)
+%Image::ExifTool::Canon::CameraInfo80D = (
+    %binaryDataAttrs,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'CameraInfo tags for the EOS 80D.',
+    0x03 => { %ciFNumber },
+    0x04 => { %ciExposureTime },
+    0x06 => { %ciISO },
+    0x1b => { %ciCameraTemperature },
+    0x23 => { %ciFocalLength },
+    0x96 => {
+        Name => 'CameraOrientation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
+    0xa5 => {
+        Name => 'FocusDistanceUpper',
+        %focusDistanceByteSwap,
+    },
+    0xa7 => {
+        Name => 'FocusDistanceLower',
+        %focusDistanceByteSwap,
+    },
+    0x13a => {
+        Name => 'ColorTemperature',
+        Format => 'int16u',
+    },
+    0x189 => {
+        Name => 'LensType',
+        Format => 'int16uRev', # value is big-endian
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%canonLensTypes,
+    },
+    0x18b => { %ciMinFocal },
+    0x18d => { %ciMaxFocal },
+    0x45a => {  # (at this location for firmware 1.0.1)
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+    },
+    0x4ae => {
+        Name => 'FileIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x4ba => { #(NC)
+        Name => 'DirectoryIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
     },
 );
@@ -3766,4 +4803,5 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
@@ -3790,7 +4828,5 @@
     0x263 => { #PH
         Name => 'PictureStyleInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
     },
     0x933 => { #33
@@ -3814,5 +4850,5 @@
     0x07 => {
         Name => 'HighlightTonePriority',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
     },
     0x15 => { #PH (580 EX II)
@@ -3882,8 +4918,9 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0xf8 => { %ciShortFocal },
-    0xfa => { %ciLongFocal },
+    0xf8 => { %ciMinFocal },
+    0xfa => { %ciMaxFocal },
     0x190 => {
         Name => 'FirmwareVersion',
@@ -3908,7 +4945,5 @@
     0x30b => {
         Name => 'PictureStyleInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
     },
 );
@@ -3928,5 +4963,5 @@
     0x07 => { #(NC)
         Name => 'HighlightTonePriority',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
     },
     0x15 => { #(NC)
@@ -3978,8 +5013,9 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
-    0x101 => { %ciShortFocal }, # (500D + 9)
-    0x103 => { %ciLongFocal }, # (500D + 9)
+    0x101 => { %ciMinFocal }, # (500D + 9)
+    0x103 => { %ciMaxFocal }, # (500D + 9)
     0x1a4 => { # (500D + 0x11)
         Name => 'FirmwareVersion',
@@ -4004,7 +5040,282 @@
     0x31c => { #48
         Name => 'PictureStyleInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
+    },
+);
+
+# Canon camera information for 600D and 1100D (MakerNotes tag 0x0d) (ref PH)
+%Image::ExifTool::Canon::CameraInfo600D = (
+    %binaryDataAttrs,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    IS_SUBDIR => [ 0x2fb ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'CameraInfo tags for the EOS 600D and 1100D.',
+    0x03 => { %ciFNumber },
+    0x04 => { %ciExposureTime },
+    0x06 => { %ciISO },
+    0x07 => { #(NC)
+        Name => 'HighlightTonePriority',
+        PrintConv => \%offOn,
+    },
+    0x15 => { #(NC)
+        Name => 'FlashMeteringMode',
+        PrintConv => {
+            0 => 'E-TTL',
+            3 => 'TTL',
+            4 => 'External Auto',
+            5 => 'External Manual',
+            6 => 'Off',
+        },
+    },
+    0x19 => { %ciCameraTemperature }, # (60D + 0)
+    0x1e => { %ciFocalLength }, # (60D + 0)
+    0x38 => { # (60D + 2)
+        Name => 'CameraOrientation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
+    0x57 => { # (60D + 2, 550D + 3)
+        Name => 'FocusDistanceUpper',
+        %focusDistanceByteSwap,
+    },
+    0x59 => { # (60D + 2, 550D + 3)
+        Name => 'FocusDistanceLower',
+        %focusDistanceByteSwap,
+    },
+    0x7b => { # (550D + 3)
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        SeparateTable => 1,
+        PrintConv => \%canonWhiteBalance,
+    },
+    0x7f => { # (60D + 2, 550D + 3)
+        Name => 'ColorTemperature',
+        Format => 'int16u',
+    },
+    0xb3 => { # (550D + 3)
+        Name => 'PictureStyle',
+        Format => 'int8u',
+        Flags => ['PrintHex','SeparateTable'],
+        PrintConv => \%pictureStyles,
+    },
+    0xea => { # (60D + 2, 550D + 3)
+        Name => 'LensType',
+        Format => 'int16uRev', # value is big-endian
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%canonLensTypes,
+    },
+    0xec => { %ciMinFocal }, # (60D + 2)
+    0xee => { %ciMaxFocal }, # (60D + 2)
+    0x19b => { # (60D + 2)
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
+    },
+    0x1db => { # (60D + 2) (NC)
+        Name => 'FileIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x1e7 => { # (60D + 2) (NC)
+        Name => 'DirectoryIndex',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
+    },
+    0x2fb => {
+        Name => 'PictureStyleInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
+    },
+);
+
+# Canon camera information for 650D/700D (MakerNotes tag 0x0d) (ref PH)
+%Image::ExifTool::Canon::CameraInfo650D = (
+    %binaryDataAttrs,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    IS_SUBDIR => [ 0x390 ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'CameraInfo tags for the EOS 650D and 700D.',
+    0x03 => { %ciFNumber },
+    0x04 => { %ciExposureTime },
+    0x06 => { %ciISO },
+    0x1b => { %ciCameraTemperature }, # (1DX/5DmkIII + 0)
+    0x23 => { %ciFocalLength }, # (1DX/5DmkIII + 3)
+    # 0x35 - seems to be the same as 0x54
+    0x7d => { # (1DX/5DmkIII + 3)
+        Name => 'CameraOrientation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
+    0x8c => { # (1DX + 3)
+        Name => 'FocusDistanceUpper',
+        %focusDistanceByteSwap,
+    },
+    0x8e => { # (1DX + 3)
+        Name => 'FocusDistanceLower',
+        %focusDistanceByteSwap,
+    },
+    0xbc => { # (1DX + 7)
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        SeparateTable => 1,
+        PrintConv => \%canonWhiteBalance,
+    },
+    0xc0 => { # (1DX + 7)
+        Name => 'ColorTemperature',
+        Format => 'int16u',
+    },
+    0xf4 => { # (1DX + 7)
+        Name => 'PictureStyle',
+        Format => 'int8u',
+        Flags => ['PrintHex','SeparateTable'],
+        PrintConv => \%pictureStyles,
+    },
+    0x127 => {
+        Name => 'LensType',
+        Format => 'int16uRev', # value is big-endian
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%canonLensTypes,
+    },
+    0x129 => { %ciMinFocal },
+    0x12b => { %ciMaxFocal },
+    0x21b => { # (650D version 1.0.1)
+        Name => 'FirmwareVersion',
+        Condition => '$$self{Model} =~ /(650D|REBEL T4i|Kiss X6i)\b/',
+        Notes => '650D',
+        Format => 'string[6]',
+        Writable => 0,
+        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
+    },
+    0x220 => { # (700D version 1.1.1/2.1.1)
+        Name => 'FirmwareVersion',
+        Condition => '$$self{Model} =~ /(700D|REBEL T5i|Kiss X7i)\b/',
+        Notes => '700D',
+        Format => 'string[6]',
+        Writable => 0,
+        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
+    },
+    0x270 => { #(NC)
+        Name => 'FileIndex',
+        Condition => '$$self{Model} =~ /(650D|REBEL T4i|Kiss X6i)\b/',
+        Notes => '650D',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x274 => { #(NC)
+        Name => 'FileIndex',
+        Condition => '$$self{Model} =~ /(700D|REBEL T5i|Kiss X7i)\b/',
+        Notes => '700D',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    0x27c => { #(NC)
+        Name => 'DirectoryIndex',
+        Condition => '$$self{Model} =~ /(650D|REBEL T4i|Kiss X6i)\b/',
+        Notes => '650D',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
+    },
+    0x280 => { #(NC)
+        Name => 'DirectoryIndex',
+        Condition => '$$self{Model} =~ /(700D|REBEL T5i|Kiss X7i)\b/',
+        Notes => '700D',
+        Groups => { 2 => 'Image' },
+        Format => 'int32u',
+        ValueConv => '$val - 1',
+        ValueConvInv => '$val + 1',
+    },
+    0x390 => {
+        Name => 'PictureStyleInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo2' },
+    },
+);
+
+# Canon camera information for 750D/760D (MakerNotes tag 0x0d) (ref PH)
+%Image::ExifTool::Canon::CameraInfo750D = (
+    %binaryDataAttrs,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'CameraInfo tags for the EOS 750D and 760D.',
+    0x03 => { %ciFNumber },
+    0x04 => { %ciExposureTime },
+    0x06 => { %ciISO },
+    0x1b => { %ciCameraTemperature }, # (700D + 0)
+    0x23 => { %ciFocalLength }, # (700D + 0)
+    0x96 => { #IB (700D + 0x19)
+        Name => 'CameraOrientation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+        },
+    },
+    0xa5 => { # (700D + 0x19)
+        Name => 'FocusDistanceUpper',
+        %focusDistanceByteSwap,
+    },
+    0xa7 => { # (700D + 0x19)
+        Name => 'FocusDistanceLower',
+        %focusDistanceByteSwap,
+    },
+    0x131 => { # (700D + 0x19)
+        Name => 'WhiteBalance',
+        Format => 'int16u',
+        SeparateTable => 1,
+        PrintConv => \%canonWhiteBalance,
+    },
+    0x135 => {
+        Name => 'ColorTemperature',
+        Format => 'int16u',
+    },
+    0x169 => {
+        Name => 'PictureStyle',
+        Format => 'int8u',
+        Flags => ['PrintHex','SeparateTable'],
+        PrintConv => \%pictureStyles,
+    },
+    0x184 => {
+        Name => 'LensType',
+        Format => 'int16uRev', # value is big-endian
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%canonLensTypes,
+    },
+    0x186 => { %ciMinFocal },
+    0x188 => { %ciMaxFocal },
+    0x43d => { # (750D/760D firmware 6.7.2)
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
+    },
+    0x449 => { # (750D/760D firmware 1.0.0)
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+        RawConv => '$val=~/^\d+\.\d+\.\d+\s*$/ ? $val : undef',
     },
 );
@@ -4065,6 +5376,9 @@
         Format => 'int16uRev', # value is big-endian
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%canonLensTypes,
     },
+    0xe4 => { %ciMinFocal }, #PH
+    0xe6 => { %ciMaxFocal }, #PH
     0x10b => { #PH
         Name => 'FirmwareVersion',
@@ -4085,7 +5399,5 @@
     0x267 => { #PH
         Name => 'PictureStyleInfo',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::PSInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::PSInfo' },
     },
     0x937 => { #PH
@@ -4242,4 +5554,10 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     NOTES => 'Unknown CameraInfo tags are divided into 3 tables based on format size.',
+    # This tag may be uncommented, and is useful for generating
+    # lists of models in the "Notes" below...
+    # 0 => {
+    #     Name => 'CameraInfoCount',
+    #     ValueConv => '$$self{CameraInfoCount}',
+    # },
     71 => { # [-1] <-- index relative to CameraInfoCount
         Name => 'CameraTemperature',
@@ -4277,25 +5595,88 @@
         PrintConvInv => '$val=~s/ ?C//; $val',
     },
-    466 => { # [-3]
+    -3 => {
         Name => 'CameraTemperature',
-        Condition => '$$self{CameraInfoCount} == 469',
-        Notes => 'A1200, A2200, A3200, A3300, 100HS, 300HS and 500HS',
+        Condition => '$$self{CameraInfoCount} > 400',
+        Notes => '3 entries from end of record for most newer camera models',
         PrintConv => '"$val C"',
         PrintConvInv => '$val=~s/ ?C//; $val',
     },
-    503 => { # [-3]
-        Name => 'CameraTemperature',
-        Condition => '$$self{CameraInfoCount} == 506',
-        Notes => 'A800',
-        PrintConv => '"$val C"',
-        PrintConvInv => '$val=~s/ ?C//; $val',
-    },
-    506 => { # [-3]
-        Name => 'CameraTemperature',
-        Condition => '$$self{CameraInfoCount} == 509',
-        Notes => 'SX230HS',
-        PrintConv => '"$val C"',
-        PrintConvInv => '$val=~s/ ?C//; $val',
-    },
+#    466 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 469',
+#        Notes => '100HS, 300HS, 500HS, A1200, A2200, A3200 and A3300',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    503 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 506',
+#        Notes => 'A800',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    506 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 509',
+#        Notes => 'SX230HS',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    520 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 523',
+#        Notes => '310HS, 510HS, G1X, S100 (new), SX40HS and SX150',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    524 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 527',
+#        Notes => '110HS, 520HS, A2300, A2400, A3400, A4000, D20 and SX260HS',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    532 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 535',
+#        Notes => 'S110 (new), G15, SX50, SX160IS and SX500IS',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    547 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 550',
+#        Notes => '130IS, A1400, A2500 and A2600',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    549 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 552',
+#        Notes => '115IS, 130IS, SX270, SX280, 330HS and A3500',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    552 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 555',
+#        Notes => 'S200 (new)',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    850 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 853',
+#        Notes => 'N',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
+#    895 => { # [-3]
+#        Name => 'CameraTemperature',
+#        Condition => '$$self{CameraInfoCount} == 898',
+#        Notes => 'G1XmkII, N100, SX600HS and SX700HS',
+#        PrintConv => '"$val C"',
+#        PrintConvInv => '$val=~s/ ?C//; $val',
+#    },
 );
 
@@ -4316,4 +5697,19 @@
     PRIORITY => 0,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x16b => {
+        Name => 'LensSerialNumber',
+        Condition => '$$self{Model} =~ /^Canon EOS 5DS/', # (good for 5DS and 5DSR)
+        Format => 'undef[5]',
+        Priority => 0,
+        ValueConv => 'unpack("H*",$val)',
+        ValueConvInv => 'length($val) < 10 and $val = 0 x (10-length($val)) . $val; pack("H*",$val)',
+    },
+    0x5c1 => {
+        Name => 'FirmwareVersion',
+        Format => 'string[6]',
+        Writable => 0,
+        Condition => '$$valPt =~ /^\d\.\d\.\d\0/',
+        Notes => 'M50', # (firmware 1.0.0)
+    },
 );
 
@@ -4473,5 +5869,5 @@
 );
 
-# Picture Style information for the 60D (ref 48)
+# Picture Style information for the 60D, etc (ref 48)
 %Image::ExifTool::Canon::PSInfo2 = (
     %binaryDataAttrs,
@@ -4479,5 +5875,5 @@
     PRIORITY => 0,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => 'Custom picture style information for the EOS 60D.',
+    NOTES => 'Custom picture style information for the EOS 5DmkIII, 60D, 600D and 1100D.',
     # (values expected to be "n/a" are flagged as Unknown)
     0x00 => { Name => 'ContrastStandard',      %psInfo },
@@ -4535,9 +5931,9 @@
         },
     },
-    0x90 => { Name => 'ContrastUnknown',        %psInfo, Unknown => 1 },
-    0x94 => { Name => 'SharpnessUnknown',       %psInfo, Unknown => 1 },
-    0x98 => { Name => 'SaturationUnknown',      %psInfo, Unknown => 1 },
-    0x9c => { Name => 'ColorToneUnknown',       %psInfo, Unknown => 1 },
-    0xa0 => { Name => 'FilterEffectUnknown',    %psInfo, Unknown => 1,
+    0x90 => { Name => 'ContrastAuto',          %psInfo },
+    0x94 => { Name => 'SharpnessAuto',         %psInfo },
+    0x98 => { Name => 'SaturationAuto',        %psInfo },
+    0x9c => { Name => 'ColorToneAuto',         %psInfo },
+    0xa0 => { Name => 'FilterEffectAuto',      %psInfo,
         PrintConv => {
             0 => 'None',
@@ -4549,5 +5945,5 @@
         },
     },
-    0xa4 => { Name => 'ToningEffectUnknown',    %psInfo, Unknown => 1,
+    0xa4 => { Name => 'ToningEffectAuto',      %psInfo,
         PrintConv => {
             0 => 'None',
@@ -4796,5 +6192,5 @@
 );
 
-# newer AF information (MakerNotes tag 0x26) - PH (A570IS,1DmkIII,40D)
+# newer AF information (MakerNotes tag 0x26 and 0x32) - PH (A570IS,1DmkIII,40D and G1XmkII)
 # (Note: this tag is out of sequence in A570IS maker notes)
 %Image::ExifTool::Canon::AFInfo2 = (
@@ -4805,6 +6201,6 @@
     NOTES => q{
         Newer version of the AFInfo record containing much of the same information
-        (and coordinate confusion) as the older version.  In this record, values of
-        9 and 45 have been observed for NumAFPoints.
+        (and coordinate confusion) as the older version.  In this record, NumAFPoints
+        may be 7, 9, 11, 19, 31, 45 or 61, depending on the camera model.
     },
     0 => {
@@ -4816,10 +6212,18 @@
         PrintConv => {
             0 => 'Off (Manual Focus)',
+            1 => 'AF Point Expansion (surround)', #PH
             2 => 'Single-point AF',
-            4 => 'Multi-point AF or AI AF', # AiAF on A570IS
+            # 3 - n/a
+            4 => 'Auto', #forum6237 (AiAF on A570IS)
             5 => 'Face Detect AF',
+            6 => 'Face + Tracking', #PH (NC, EOS M, live view)
             7 => 'Zone AF', #46
-            8 => 'AF Point Expansion', #46
+            8 => 'AF Point Expansion (4 point)', #46/PH/forum6237
             9 => 'Spot AF', #46
+            10 => 'AF Point Expansion (8 point)', #forum6237
+            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)
         },
     },
@@ -4882,5 +6286,102 @@
         # usually, but not always, the lowest number AF point in focus
         Name => 'PrimaryAFPoint',
-        Condition => '$$self{Model} !~ /EOS/',
+        Condition => '$$self{Model} !~ /EOS/ and not $$self{AFInfo3}', # (not valid for G1XmkII)
+    },
+);
+
+# contrast information (MakerNotes tag 0x27) - PH
+%Image::ExifTool::Canon::ContrastInfo = (
+    %binaryDataAttrs,
+    FORMAT => 'int16u',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    4 => {
+        Name => 'IntelligentContrast',
+        PrintHex => 1,
+        PrintConv => {
+            0x00 => 'Off',
+            0x08 => 'On',
+            0xffff => 'n/a',
+            OTHER => sub {
+                # 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+)/ or return undef;
+                    return $1;
+                } else {
+                    return sprintf("On (0x%.2x)",$val) if $val & 0x08;
+                    return sprintf("Off (0x%.2x)",$val);
+                }
+            },
+        },
+    },
+    # 6 - 0=normal, 257=i-Contrast On
+);
+
+# time information (MakerNotes tag 0x35) - PH (1DX, 5DmkIII)
+%Image::ExifTool::Canon::TimeInfo = (
+    %binaryDataAttrs,
+    FORMAT => 'int32s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Time' },
+    # 0 - size (16 bytes)
+    1 => {
+        Name => 'TimeZone',
+        PrintConv => 'Image::ExifTool::TimeZoneString($val)',
+        PrintConvInv => sub {
+            my $val = shift;
+            $val =~ /^([-+]?)(\d{1,2}):?(\d{2})$/ or return undef;
+            return(($1 eq '-' ? -1 : 1) * ($2 * 60 + $3));
+        },
+    },
+    2 => {
+        Name => 'TimeZoneCity',
+        PrintConvColumns => 3,
+        PrintConv => {
+            # [square brackets] = actual time zone for each city
+            # (round brackets) = observed time zone values from sample images
+            # --> unobserved entries have not been confirmed!
+            0 => 'n/a', # (PowerShot models)
+            1 => 'Chatham Islands', # [+12:45]
+            2 => 'Wellington',      # [+12] (+12:00,DST+0)
+            3 => 'Solomon Islands', # [+11]
+            4 => 'Sydney',          # [+10] (+11:00,DST+1)
+            5 => 'Adelaide',        # [+9:30]
+            6 => 'Tokyo',           # [+9] (+09:00,DST+0)
+            7 => 'Hong Kong',       # [+8] (+08:00,DST+0)
+            8 => 'Bangkok',         # [+7] (+08:00,DST+1)
+            9 => 'Yangon',          # [+6:30]
+            10 => 'Dhaka',          # [+6] (Canon uses old "Dacca" spelling)
+            11 => 'Kathmandu',      # [+5:45]
+            12 => 'Delhi',          # [+5:30]
+            13 => 'Karachi',        # [+5]
+            14 => 'Kabul',          # [+4:30]
+            15 => 'Dubai',          # [+4]
+            16 => 'Tehran',         # [+3:30]
+            17 => 'Moscow',         # [+4] (+03:00,DST+0) (! changed to +4 permanent DST in 2011)
+            18 => 'Cairo',          # [+2]
+            19 => 'Paris',          # [+1] (+01:10,DST+0; +02:00,DST+1)
+            20 => 'London',         # [0]  (+00:00,DST+0)
+            21 => 'Azores',         # [-1]
+            22 => 'Fernando de Noronha', # [-2]
+            23 => 'Sao Paulo',      # [-3]
+            24 => 'Newfoundland',   # [-3:30]
+            25 => 'Santiago',       # [-4]
+            26 => 'Caracas',        # [-4:30]
+            27 => 'New York',       # [-5] (-05:00,DST+0; -04:00,DST+1)
+            28 => 'Chicago',        # [-6]
+            29 => 'Denver',         # [-7]
+            30 => 'Los Angeles',    # [-8] (-08:00,DST+0; -07:00,DST+1)
+            31 => 'Anchorage',      # [-9]
+            32 => 'Honolulu',       # [-10]
+            33 => 'Samoa',          # [+13]
+            32766 => '(not set)',   #(NC)
+        },
+    },
+    3 => {
+        Name => 'DaylightSavings',
+        PrintConv => {
+            0 => 'Off',
+            60 => 'On',
+        },
     },
 );
@@ -4992,4 +6493,36 @@
 );
 
+# 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,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    # 0 - size (34 bytes)
+    # 1 - 1=4:3/16:9,2=1:1/3:2/4:5
+    # 2 - normally 1 if faces detected, but sometimes 0 (maybe if face wasn't in captured image?)
+    3 => 'FacesDetected',
+    # 4 - 240=4:3/4:5/1:1,180=16:9,212=3:2
+);
+
 # File number information (MakerNotes tag 0x93)
 %Image::ExifTool::Canon::FileInfo = (
@@ -4998,4 +6531,5 @@
     FIRST_ENTRY => 1,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    DATAMEMBER => [ 20 ],
     1 => [
         { #5
@@ -5065,4 +6599,9 @@
         { #7 (1DmkII, 1DSmkII, 1DSmkIIN)
             Name => 'ShutterCount',
+            # ref http://www.luminous-landscape.com/forum/index.php?topic=36469 :
+            Notes => q{
+                there are reports that the ShutterCount changed when loading a settings file
+                on the 1DSmkII
+            },
             Condition => '$$self{Model} =~ /\b1Ds? Mark II\b/',
             Format => 'int32u',
@@ -5163,5 +6702,24 @@
         # http://www.breezesys.com/forum/showthread.php?p=16980)
         Name => 'LiveViewShooting',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
+    },
+    20 => { #47
+        Name => 'FocusDistanceUpper',
+        DataMember => 'FocusDistanceUpper2',
+        Format => 'int16u',
+        RawConv => '($$self{FocusDistanceUpper2} = $val) || undef',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+        PrintConv => '$val > 655.345 ? "inf" : "$val m"',
+        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
+    },
+    21 => { #47
+        Name => 'FocusDistanceLower',
+        Condition => '$$self{FocusDistanceUpper2}',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        ValueConvInv => '$val * 100',
+        PrintConv => '$val > 655.345 ? "inf" : "$val m"',
+        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 655.35',
     },
     # 22 - values: 0, 1
@@ -5169,5 +6727,34 @@
     25 => { #PH
         Name => 'FlashExposureLock',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
+    },
+    0x3d => { #IB
+        Name => 'RFLensType',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'n/a',
+            257 => 'Canon RF 50mm F1.2L USM',
+            258 => 'Canon RF 24-105mm F4L IS USM',
+            259 => 'Canon RF 28-70mm F2L USM',
+            260 => 'Canon RF 35mm F1.8 MACRO IS STM',
+            261 => 'Canon RF 85mm F1.2L USM',
+            262 => 'Canon RF 85mm F1.2L USM DS',
+            263 => 'Canon RF 24-70mm F2.8L IS USM',
+            264 => 'Canon RF 15-35mm F2.8L IS USM',
+            265 => 'Canon RF 24-240mm F4-6.3 IS USM',
+            266 => 'Canon RF 70-200mm F2.8L IS USM',
+            267 => 'Canon RF 85mm F2 MACRO IS STM',
+            268 => 'Canon RF 600mm F11 IS STM',
+            269 => 'Canon RF 600mm F11 IS STM + RF1.4x',
+            270 => 'Canon RF 600mm F11 IS STM + RF2x',
+            271 => 'Canon RF 800mm F11 IS STM',
+            272 => 'Canon RF 800mm F11 IS STM + RF1.4x',
+            273 => 'Canon RF 800mm F11 IS STM + RF2x',
+            274 => 'Canon RF 24-105mm F4-7.1 IS STM',
+            275 => 'Canon RF 100-500mm F4.5-7.1L IS USM',
+            276 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF1.4x',
+            277 => 'Canon RF 100-500mm F4.5-7.1L IS USM + RF2x',
+            # Note: add new RF lenses to %canonLensTypes with ID 61182
+        },
     },
 );
@@ -5210,8 +6797,13 @@
             7 => '16:9',
             8 => '4:5',
-        },
-    },
-    1 => 'CroppedImageWidth', # (could use a better name for these)
+            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)
+    1 => 'CroppedImageWidth',
     2 => 'CroppedImageHeight',
+    3 => 'CroppedImageLeft', #forum4138
+    4 => 'CroppedImageTop', #ditto
 );
 
@@ -5287,13 +6879,22 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     # red,green1,green2,blue (ref 2)
-    0  => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
-    4  => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
-    8  => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
-    12 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
-    16 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
-    20 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
-    24 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
-    28 => { Name => 'WB_RGGBLevelsCustom',     Format => 'int16s[4]' },
-    32 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
+    1  => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
+    5  => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
+    9  => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
+    13 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
+    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',
+        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
 );
 
@@ -5395,4 +6996,5 @@
         OffsetPair => 5,   # point to associated offset
         DataTag => 'PreviewImage',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -5404,4 +7006,5 @@
         OffsetPair => 2,  # associated byte count tagID
         DataTag => 'PreviewImage',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -5611,5 +7214,8 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
     },
-    # 0xc5-0xc7: looks like black levels (ref 37)
+    0xc4 => { #IB
+        Name => 'PerChannelBlackLevel',
+        Format => 'int16u[4]',
+    },
     # 0xc8-0x1c7: some sort of color table (ref 37)
     0x248 => { #37
@@ -5651,5 +7257,5 @@
     NOTES => q{
         These tags are used by the 1DmkIII, 1DSmkIII, 1DmkIV, 5DmkII, 7D, 40D, 50D,
-        450D, 500D, 550D, 1000D and 1100D.
+        60D, 450D, 500D, 550D, 1000D and 1100D.
     },
     FORMAT => 'int16s',
@@ -5657,6 +7263,9 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     IS_SUBDIR => [ 0x3f, 0xa8 ],
+    DATAMEMBER => [ 0x00 ],
     0x00 => {
         Name => 'ColorDataVersion',
+        DataMember => 'ColorDataVersion',
+        RawConv => '$$self{ColorDataVersion} = $val',
         PrintConv => {
             2 => '2 (1DmkIII)',
@@ -5666,5 +7275,5 @@
             6 => '6 (50D/5DmkII)',
             7 => '7 (500D/550D/7D/1DmkIV)',
-            9 => '9 (1100D)',
+            9 => '9 (60D/1100D)',
         },
     },
@@ -5683,4 +7292,5 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
     },
+    0x0e7 => { Name => 'AverageBlackLevel',     Format => 'int16u[4]' }, #IB
     0x280 => { #PH
         Name => 'RawMeasuredRGGB',
@@ -5690,4 +7300,66 @@
         ValueConv => \&SwapWords,
         ValueConvInv => \&SwapWords,
+    },
+    0x2b4 => { #IB
+        Name => 'PerChannelBlackLevel',
+        Condition => '$$self{ColorDataVersion} == 4 or $$self{ColorDataVersion} == 5',
+        Format => 'int16u[4]',
+    },
+    0x2b8 => { #IB
+        Name => 'NormalWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 4 or $$self{ColorDataVersion} == 5',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+    },
+    0x2b9 => { #IB
+        Name => 'SpecularWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 4 or $$self{ColorDataVersion} == 5',
+        Format => 'int16u',
+    },
+    0x2ba => { #IB
+        Name => 'LinearityUpperMargin',
+        Condition => '$$self{ColorDataVersion} == 4 or $$self{ColorDataVersion} == 5',
+        Format => 'int16u',
+    },
+    0x2cb => { #IB
+        Name => 'PerChannelBlackLevel',
+        Condition => '$$self{ColorDataVersion} == 6 or $$self{ColorDataVersion} == 7',
+        Format => 'int16u[4]',
+    },
+    0x2cf => [{ #IB
+        Name => 'NormalWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 6 or $$self{ColorDataVersion} == 7',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+    },{
+        Name => 'PerChannelBlackLevel',
+        Condition => '$$self{ColorDataVersion} == 9',
+        Format => 'int16u[4]',
+    }],
+    0x2d0 => { #IB
+        Name => 'SpecularWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 6 or $$self{ColorDataVersion} == 7',
+        Format => 'int16u',
+    },
+    0x2d1 => { #IB
+        Name => 'LinearityUpperMargin',
+        Condition => '$$self{ColorDataVersion} == 6 or $$self{ColorDataVersion} == 7',
+        Format => 'int16u',
+    },
+    0x2d3 => { #IB
+        Name => 'NormalWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 9',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+    },
+    0x2d4 => { #IB
+        Name => 'SpecularWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 9',
+        Format => 'int16u',
+    },
+    0x2d5 => { #IB
+        Name => 'LinearityUpperMargin',
+        Condition => '$$self{ColorDataVersion} == 9',
+        Format => 'int16u',
     },
 );
@@ -5751,4 +7423,58 @@
 );
 
+# color coefficients (ref PH/IB)
+%Image::ExifTool::Canon::ColorCoefs2 = (
+    %binaryDataAttrs,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x00 => { Name => 'WB_RGGBLevelsAsShot',      Format => 'int16s[4]' },
+    0x07 => 'ColorTempAsShot',
+    0x08 => { Name => 'WB_RGGBLevelsAuto',        Format => 'int16s[4]' },
+    0x0f => 'ColorTempAuto',
+    0x10 => { Name => 'WB_RGGBLevelsMeasured',    Format => 'int16s[4]' },
+    0x17 => 'ColorTempMeasured',
+    0x18 => { Name => 'WB_RGGBLevelsUnknown',     Format => 'int16s[4]', Unknown => 1 },
+    0x1f => { Name => 'ColorTempUnknown', Unknown => 1 },
+    0x20 => { Name => 'WB_RGGBLevelsDaylight',    Format => 'int16s[4]' },
+    0x27 => 'ColorTempDaylight',
+    0x28 => { Name => 'WB_RGGBLevelsShade',       Format => 'int16s[4]' },
+    0x2f => 'ColorTempShade',
+    0x30 => { Name => 'WB_RGGBLevelsCloudy',      Format => 'int16s[4]' },
+    0x37 => 'ColorTempCloudy',
+    0x38 => { Name => 'WB_RGGBLevelsTungsten',    Format => 'int16s[4]' },
+    0x3f => 'ColorTempTungsten',
+    0x40 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
+    0x47 => 'ColorTempFluorescent',
+    0x48 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
+    0x4f => 'ColorTempKelvin',
+    0x50 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
+    0x57 => 'ColorTempFlash',
+    0x58 => { Name => 'WB_RGGBLevelsUnknown2',   Format => 'int16s[4]', Unknown => 1 },
+    0x5f => { Name => 'ColorTempUnknown2', Unknown => 1 },
+    0x60 => { Name => 'WB_RGGBLevelsUnknown3',   Format => 'int16s[4]', Unknown => 1 },
+    0x67 => { Name => 'ColorTempUnknown3', Unknown => 1 },
+    0x68 => { Name => 'WB_RGGBLevelsUnknown4',   Format => 'int16s[4]', Unknown => 1 },
+    0x6f => { Name => 'ColorTempUnknown4', Unknown => 1 },
+    0x70 => { Name => 'WB_RGGBLevelsUnknown5',   Format => 'int16s[4]', Unknown => 1 },
+    0x77 => { Name => 'ColorTempUnknown5', Unknown => 1 },
+    0x78 => { Name => 'WB_RGGBLevelsUnknown6',   Format => 'int16s[4]', Unknown => 1 },
+    0x7f => { Name => 'ColorTempUnknown6', Unknown => 1 },
+    0x80 => { Name => 'WB_RGGBLevelsUnknown7',   Format => 'int16s[4]', Unknown => 1 },
+    0x87 => { Name => 'ColorTempUnknown7', Unknown => 1 },
+    0x88 => { Name => 'WB_RGGBLevelsUnknown8',   Format => 'int16s[4]', Unknown => 1 },
+    0x8f => { Name => 'ColorTempUnknown8', Unknown => 1 },
+    0x90 => { Name => 'WB_RGGBLevelsUnknown9',   Format => 'int16s[4]', Unknown => 1 },
+    0x97 => { Name => 'ColorTempUnknown9', Unknown => 1 },
+    0x98 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
+    0x9f => { Name => 'ColorTempUnknown10', Unknown => 1 },
+    0xa0 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
+    0xa7 => { Name => 'ColorTempUnknown11', Unknown => 1 },
+    0xa8 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
+    0xaf => { Name => 'ColorTempUnknown12', Unknown => 1 },
+    0xb0 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
+    0xb7 => { Name => 'ColorTempUnknown13', Unknown => 1 },
+);
+
 # color calibration (ref 37)
 %Image::ExifTool::Canon::ColorCalib = (
@@ -5765,6 +7491,6 @@
     NOTES => q{
         Camera color calibration data.  For the 20D, 350D, 1DmkII and 1DSmkII the
-        order of the cooefficients is A, B, C, Temperature, but for newer models it
-        is B, C, A, Temperature.  These tags are extracted only when the Unknown
+        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 L<Unknown|../ExifTool.html#Unknown>
         option is used.
     },
@@ -5786,40 +7512,97 @@
 );
 
+# color calibration2
+%Image::ExifTool::Canon::ColorCalib2 = (
+    %binaryDataAttrs,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'B, C, A, D, Temperature.',
+    0x00 => { Name => 'CameraColorCalibration01', %cameraColorCalibration2 },
+    0x05 => { Name => 'CameraColorCalibration02', %cameraColorCalibration2 },
+    0x0a => { Name => 'CameraColorCalibration03', %cameraColorCalibration2 },
+    0x0f => { Name => 'CameraColorCalibration04', %cameraColorCalibration2 },
+    0x14 => { Name => 'CameraColorCalibration05', %cameraColorCalibration2 },
+    0x19 => { Name => 'CameraColorCalibration06', %cameraColorCalibration2 },
+    0x1e => { Name => 'CameraColorCalibration07', %cameraColorCalibration2 },
+    0x23 => { Name => 'CameraColorCalibration08', %cameraColorCalibration2 },
+    0x28 => { Name => 'CameraColorCalibration09', %cameraColorCalibration2 },
+    0x2d => { Name => 'CameraColorCalibration10', %cameraColorCalibration2 },
+    0x32 => { Name => 'CameraColorCalibration11', %cameraColorCalibration2 },
+    0x37 => { Name => 'CameraColorCalibration12', %cameraColorCalibration2 },
+    0x3c => { Name => 'CameraColorCalibration13', %cameraColorCalibration2 },
+    0x41 => { Name => 'CameraColorCalibration14', %cameraColorCalibration2 },
+    0x46 => { Name => 'CameraColorCalibration15', %cameraColorCalibration2 },
+);
+
 # Color data (MakerNotes tag 0x4001, count=5120) (ref PH)
 %Image::ExifTool::Canon::ColorData5 = (
     %binaryDataAttrs,
-    NOTES => 'These tags are used by the PowerShot G10.',
+    NOTES => 'These tags are used by many EOS M and PowerShot models.',
     FORMAT => 'int16s',
     FIRST_ENTRY => 0,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    IS_SUBDIR => [ 0x47 ],
-    # 0x00 - oddly, this isn't ColorDataVersion (probably should have been version 8)
-    0x47 => {
+    DATAMEMBER => [ 0x00 ],
+    IS_SUBDIR => [ 0x47, 0xba, 0xff ],
+    0x00 => {
+        Name => 'ColorDataVersion',
+        DataMember => 'ColorDataVersion',
+        RawConv => '$$self{ColorDataVersion} = $val',
+        PrintConv => {
+            -3 => '-3 (M10/M3)', # (and PowerShot G1X/G1XmkII/G10/G11/G12/G15/G16/G3X/G5X/G7X/G9X/S100/S110/S120/S90/S95/SX1IS/SX50HS/SX60HS)
+            -4 => '-4 (M100/M5/M6)', # (and PowerShot G1XmkIII/G7XmkII/G9XmkII)
+        },
+    },
+    0x47 => [{
         Name => 'ColorCoefs',
+        Condition => '$$self{ColorDataVersion} == -3',
         Format => 'undef[230]', # ColorTempUnknown13 is last entry
         SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCoefs' }
-    },
-    0xba => { Name => 'CameraColorCalibration01', %cameraColorCalibration2,
-              Notes => 'B, C, A, D, Temperature' },
-    0xbf => { Name => 'CameraColorCalibration02', %cameraColorCalibration2 },
-    0xc4 => { Name => 'CameraColorCalibration03', %cameraColorCalibration2 },
-    0xc9 => { Name => 'CameraColorCalibration04', %cameraColorCalibration2 },
-    0xce => { Name => 'CameraColorCalibration05', %cameraColorCalibration2 },
-    0xd3 => { Name => 'CameraColorCalibration06', %cameraColorCalibration2 },
-    0xd8 => { Name => 'CameraColorCalibration07', %cameraColorCalibration2 },
-    0xdd => { Name => 'CameraColorCalibration08', %cameraColorCalibration2 },
-    0xe2 => { Name => 'CameraColorCalibration09', %cameraColorCalibration2 },
-    0xe7 => { Name => 'CameraColorCalibration10', %cameraColorCalibration2 },
-    0xec => { Name => 'CameraColorCalibration11', %cameraColorCalibration2 },
-    0xf1 => { Name => 'CameraColorCalibration12', %cameraColorCalibration2 },
-    0xf6 => { Name => 'CameraColorCalibration13', %cameraColorCalibration2 },
-    0xfb => { Name => 'CameraColorCalibration14', %cameraColorCalibration2 },
-    0x100=> { Name => 'CameraColorCalibration15', %cameraColorCalibration2 },
-);
-
-# Color data (MakerNotes tag 0x4001, count=1273) (ref PH)
+    },{
+        Name => 'ColorCoefs2',
+        Condition => '$$self{ColorDataVersion} == -4',
+        Format => 'undef[368]',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCoefs2' }
+    }],
+    0xba => {
+        Name => 'ColorCalib2',
+        Condition => '$$self{ColorDataVersion} == -3',
+        Format => 'undef[150]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib2' }
+    },
+    0xff => {
+        Name => 'ColorCalib2',
+        Condition => '$$self{ColorDataVersion} == -4',
+        Format => 'undef[150]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib2' }
+    },
+    0x108=> { #IB
+        Name => 'PerChannelBlackLevel',
+        Condition => '$$self{ColorDataVersion} == -3',
+        Format => 'int16s[4]',
+    },
+    0x14d=> { #IB
+        Name => 'PerChannelBlackLevel',
+        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)
 %Image::ExifTool::Canon::ColorData6 = (
     %binaryDataAttrs,
-    NOTES => 'These tags are used by the EOS 600D.',
+    NOTES => 'These tags are used by the EOS 600D and 1200D.',
     FORMAT => 'int16s',
     FIRST_ENTRY => 0,
@@ -5829,5 +7612,5 @@
         Name => 'ColorDataVersion',
         PrintConv => {
-            10 => '10 (600D)',
+            10 => '10 (600D/1200D)',
         },
     },
@@ -5889,4 +7672,5 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
     },
+    0x0fb => { Name => 'AverageBlackLevel',     Format => 'int16u[4]' }, #IB
     0x194 => { #PH
         Name => 'RawMeasuredRGGB',
@@ -5897,4 +7681,560 @@
         ValueConvInv => \&SwapWords,
     },
+    0x1df => { Name => 'PerChannelBlackLevel',  Format => 'int16u[4]' }, #IB
+    0x1e3 => { Name => 'NormalWhiteLevel',      Format => 'int16u',  RawConv => '$val || undef' }, #IB
+    0x1e4 => { Name => 'SpecularWhiteLevel',    Format => 'int16u' }, #IB
+    0x1e5 => { Name => 'LinearityUpperMargin',  Format => 'int16u' }, #IB
+);
+
+# Color data (MakerNotes tag 0x4001, count=1312,1313,1316) (ref PH)
+%Image::ExifTool::Canon::ColorData7 = (
+    %binaryDataAttrs,
+    NOTES => 'These tags are used by the EOS 1DX, 5DmkIII, 6D, 100D, 650D, 700D, M and 7DmkII.',
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0x00 ],
+    IS_SUBDIR => [ 0xd5 ],
+    0x00 => {
+        Name => 'ColorDataVersion',
+        DataMember => 'ColorDataVersion',
+        RawConv => '$$self{ColorDataVersion} = $val',
+        PrintConv => {
+            10 => '10 (1DX/5DmkIII/6D/70D/100D/650D/700D/M)',
+            11 => '11 (7DmkII/750D/760D)',
+        },
+    },
+    # not really sure about the AsShot, Auto and Measured values any more - PH
+    0x3f => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
+    0x43 => 'ColorTempAsShot',
+    0x44 => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
+    0x48 => 'ColorTempAuto',
+    0x49 => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
+    0x4d => 'ColorTempMeasured',
+    0x4e => { Name => 'WB_RGGBLevelsUnknown',   Format => 'int16s[4]', Unknown => 1 },
+    0x52 => { Name => 'ColorTempUnknown',  Unknown => 1 },
+    0x53 => { Name => 'WB_RGGBLevelsUnknown2',  Format => 'int16s[4]', Unknown => 1 },
+    0x57 => { Name => 'ColorTempUnknown2', Unknown => 1 },
+    0x58 => { Name => 'WB_RGGBLevelsUnknown3',  Format => 'int16s[4]', Unknown => 1 },
+    0x5c => { Name => 'ColorTempUnknown3', Unknown => 1 },
+    0x5d => { Name => 'WB_RGGBLevelsUnknown4',  Format => 'int16s[4]', Unknown => 1 },
+    0x61 => { Name => 'ColorTempUnknown4', Unknown => 1 },
+    0x62 => { Name => 'WB_RGGBLevelsUnknown5',  Format => 'int16s[4]', Unknown => 1 },
+    0x66 => { Name => 'ColorTempUnknown5', Unknown => 1 },
+    0x67 => { Name => 'WB_RGGBLevelsUnknown6',  Format => 'int16s[4]', Unknown => 1 },
+    0x6b => { Name => 'ColorTempUnknown6', Unknown => 1 },
+    0x6c => { Name => 'WB_RGGBLevelsUnknown7',  Format => 'int16s[4]', Unknown => 1 },
+    0x70 => { Name => 'ColorTempUnknown7', Unknown => 1 },
+    0x71 => { Name => 'WB_RGGBLevelsUnknown8',  Format => 'int16s[4]', Unknown => 1 },
+    0x75 => { Name => 'ColorTempUnknown8', Unknown => 1 },
+    0x76 => { Name => 'WB_RGGBLevelsUnknown9',  Format => 'int16s[4]', Unknown => 1 },
+    0x7a => { Name => 'ColorTempUnknown9', Unknown => 1 },
+    0x7b => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
+    0x7f => { Name => 'ColorTempUnknown10', Unknown => 1 },
+    0x80 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
+    0x84 => 'ColorTempDaylight',
+    0x85 => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
+    0x89 => 'ColorTempShade',
+    0x8a => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
+    0x8e => 'ColorTempCloudy',
+    0x8f => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
+    0x93 => 'ColorTempTungsten',
+    0x94 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
+    0x98 => 'ColorTempFluorescent',
+    0x99 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
+    0x9d => 'ColorTempKelvin',
+    0x9e => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
+    0xa2 => 'ColorTempFlash',
+    0xa3 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
+    0xa7 => { Name => 'ColorTempUnknown11', Unknown => 1 },
+    0xa8 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
+    0xac => { Name => 'ColorTempUnknown12', Unknown => 1 },
+    0xad => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
+    0xb1 => { Name => 'ColorTempUnknown13', Unknown => 1 },
+    0xb2 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
+    0xb6 => { Name => 'ColorTempUnknown14', Unknown => 1 },
+    0xb7 => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
+    0xbb => { Name => 'ColorTempUnknown15', Unknown => 1 },
+    0xbc => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
+    0xc0 => { Name => 'ColorTempUnknown16', Unknown => 1 },
+    0xc1 => { Name => 'WB_RGGBLevelsUnknown17',  Format => 'int16s[4]', Unknown => 1 },
+    0xc5 => { Name => 'ColorTempUnknown17', Unknown => 1 },
+    0xc6 => { Name => 'WB_RGGBLevelsUnknown18',  Format => 'int16s[4]', Unknown => 1 },
+    0xca => { Name => 'ColorTempUnknown18', Unknown => 1 },
+    0xcb => { Name => 'WB_RGGBLevelsUnknown19',  Format => 'int16s[4]', Unknown => 1 },
+    0xcf => { Name => 'ColorTempUnknown19', Unknown => 1 },
+    0xd0 => { Name => 'WB_RGGBLevelsUnknown20',  Format => 'int16s[4]', Unknown => 1 },
+    0xd4 => { Name => 'ColorTempUnknown20', Unknown => 1 },
+    0xd5 => {
+        Name => 'ColorCalib',
+        Format => 'undef[120]',
+        Unknown => 1,
+        Notes => 'B, C, A, Temperature',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
+    },
+    0x114 => { Name => 'AverageBlackLevel',     Format => 'int16u[4]' }, #IB
+    0x1ad => {
+        Name => 'RawMeasuredRGGB',
+        Condition => '$$self{ColorDataVersion} == 10',
+        Format => 'int32u[4]',
+        Notes => 'raw MeasuredRGGB values, before normalization',
+        # swap words because the word ordering is big-endian, opposite to the byte ordering
+        ValueConv => \&SwapWords,
+        ValueConvInv => \&SwapWords,
+    },
+    0x1f8 => { #IB
+        Name => 'PerChannelBlackLevel',
+        Condition => '$$self{ColorDataVersion} == 10',
+        Format => 'int16u[4]',
+    },
+    0x1fc => { #IB
+        Name => 'NormalWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 10',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+    },
+    0x1fd => { #IB
+        Name => 'SpecularWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 10',
+        Format => 'int16u',
+    },
+    0x1fe => { #IB
+        Name => 'LinearityUpperMargin',
+        Condition => '$$self{ColorDataVersion} == 10',
+        Format => 'int16u',
+    },
+    0x26b => {
+        Name => 'RawMeasuredRGGB',
+        Condition => '$$self{ColorDataVersion} == 11',
+        Format => 'int32u[4]',
+        ValueConv => \&SwapWords,
+        ValueConvInv => \&SwapWords,
+    },
+    0x2d8 => {
+        Name => 'PerChannelBlackLevel',
+        Condition => '$$self{ColorDataVersion} == 11',
+        Format => 'int16u[4]',
+    },
+    0x2dc => {
+        Name => 'NormalWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 11',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+    },
+    0x2dd => {
+        Name => 'SpecularWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 11',
+        Format => 'int16u',
+    },
+    0x2de => {
+        Name => 'LinearityUpperMargin',
+        Condition => '$$self{ColorDataVersion} == 11',
+        Format => 'int16u',
+    },
+);
+
+# Color data (MakerNotes tag 0x4001, count=1560,etc) (ref IB)
+%Image::ExifTool::Canon::ColorData8 = (
+    %binaryDataAttrs,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0 ],
+    IS_SUBDIR => [ 0x107 ],
+    0x00 => {
+        Name => 'ColorDataVersion',
+        DataMember => 'ColorDataVersion',
+        RawConv => '$$self{ColorDataVersion} = $val',
+        PrintConv => {
+            12 => '12 (5DS/5DSR)',
+            13 => '13 (80D)', #PH
+            14 => '14 (1300D/2000D/4000D)', #IB
+            15 => '15 (6DmkII/77D/200D/800D)', #IB
+        },
+    },
+    0x3f => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
+    0x43 => 'ColorTempAsShot',
+    0x44 => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
+    0x48 => 'ColorTempAuto',
+    0x49 => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
+    0x4d => 'ColorTempMeasured',
+    0x4e => { Name => 'WB_RGGBLevelsUnknown',   Format => 'int16s[4]', Unknown => 1 },
+    0x52 => { Name => 'ColorTempUnknown',  Unknown => 1 },
+    0x53 => { Name => 'WB_RGGBLevelsUnknown2',  Format => 'int16s[4]', Unknown => 1 },
+    0x57 => { Name => 'ColorTempUnknown2', Unknown => 1 },
+    0x58 => { Name => 'WB_RGGBLevelsUnknown3',  Format => 'int16s[4]', Unknown => 1 },
+    0x5c => { Name => 'ColorTempUnknown3', Unknown => 1 },
+    0x5d => { Name => 'WB_RGGBLevelsUnknown4',  Format => 'int16s[4]', Unknown => 1 },
+    0x61 => { Name => 'ColorTempUnknown4', Unknown => 1 },
+    0x62 => { Name => 'WB_RGGBLevelsUnknown5',  Format => 'int16s[4]', Unknown => 1 },
+    0x66 => { Name => 'ColorTempUnknown5', Unknown => 1 },
+    0x67 => { Name => 'WB_RGGBLevelsUnknown6',  Format => 'int16s[4]', Unknown => 1 },
+    0x6b => { Name => 'ColorTempUnknown6', Unknown => 1 },
+    0x6c => { Name => 'WB_RGGBLevelsUnknown7',  Format => 'int16s[4]', Unknown => 1 },
+    0x70 => { Name => 'ColorTempUnknown7', Unknown => 1 },
+    0x71 => { Name => 'WB_RGGBLevelsUnknown8',  Format => 'int16s[4]', Unknown => 1 },
+    0x75 => { Name => 'ColorTempUnknown8', Unknown => 1 },
+    0x76 => { Name => 'WB_RGGBLevelsUnknown9',  Format => 'int16s[4]', Unknown => 1 },
+    0x7a => { Name => 'ColorTempUnknown9', Unknown => 1 },
+    0x7b => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
+    0x7f => { Name => 'ColorTempUnknown10', Unknown => 1 },
+    0x80 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
+    0x84 => { Name => 'ColorTempUnknown11', Unknown => 1 },
+    0x85 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
+    0x89 => 'ColorTempDaylight',
+    0x8a => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
+    0x8e => 'ColorTempShade',
+    0x8f => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
+    0x93 => 'ColorTempCloudy',
+    0x94 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
+    0x98 => 'ColorTempTungsten',
+    0x99 => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
+    0x9d => 'ColorTempFluorescent',
+    0x9e => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
+    0xa2 => 'ColorTempKelvin',
+    0xa3 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
+    0xa7 => 'ColorTempFlash',
+    0xa8 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
+    0xac => { Name => 'ColorTempUnknown12', Unknown => 1 },
+    0xad => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
+    0xb1 => { Name => 'ColorTempUnknown13', Unknown => 1 },
+    0xb2 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
+    0xb6 => { Name => 'ColorTempUnknown14', Unknown => 1 },
+    0xb7 => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
+    0xbb => { Name => 'ColorTempUnknown15', Unknown => 1 },
+    0xbc => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
+    0xc0 => { Name => 'ColorTempUnknown16', Unknown => 1 },
+    0xc1 => { Name => 'WB_RGGBLevelsUnknown17',  Format => 'int16s[4]', Unknown => 1 },
+    0xc5 => { Name => 'ColorTempUnknown17', Unknown => 1 },
+    0xc6 => { Name => 'WB_RGGBLevelsUnknown18',  Format => 'int16s[4]', Unknown => 1 },
+    0xca => { Name => 'ColorTempUnknown18', Unknown => 1 },
+    0xcb => { Name => 'WB_RGGBLevelsUnknown19',  Format => 'int16s[4]', Unknown => 1 },
+    0xcf => { Name => 'ColorTempUnknown19', Unknown => 1 },
+    0xd0 => { Name => 'WB_RGGBLevelsUnknown20',  Format => 'int16s[4]', Unknown => 1 },
+    0xd4 => { Name => 'ColorTempUnknown20', Unknown => 1 },
+    0xd5 => { Name => 'WB_RGGBLevelsUnknown21',  Format => 'int16s[4]', Unknown => 1 },
+    0xd9 => { Name => 'ColorTempUnknown21', Unknown => 1 },
+    0xda => { Name => 'WB_RGGBLevelsUnknown22',  Format => 'int16s[4]', Unknown => 1 },
+    0xde => { Name => 'ColorTempUnknown22', Unknown => 1 },
+    0xdf => { Name => 'WB_RGGBLevelsUnknown23',  Format => 'int16s[4]', Unknown => 1 },
+    0xe3 => { Name => 'ColorTempUnknown23', Unknown => 1 },
+    0xe4 => { Name => 'WB_RGGBLevelsUnknown24',  Format => 'int16s[4]', Unknown => 1 },
+    0xe8 => { Name => 'ColorTempUnknown24', Unknown => 1 },
+    0xe9 => { Name => 'WB_RGGBLevelsUnknown25',  Format => 'int16s[4]', Unknown => 1 },
+    0xed => { Name => 'ColorTempUnknown25', Unknown => 1 },
+    0xee => { Name => 'WB_RGGBLevelsUnknown26',  Format => 'int16s[4]', Unknown => 1 },
+    0xf2 => { Name => 'ColorTempUnknown26', Unknown => 1 },
+    0xf3 => { Name => 'WB_RGGBLevelsUnknown27',  Format => 'int16s[4]', Unknown => 1 },
+    0xf7 => { Name => 'ColorTempUnknown27', Unknown => 1 },
+    0xf8 => { Name => 'WB_RGGBLevelsUnknown28',  Format => 'int16s[4]', Unknown => 1 },
+    0xfc => { Name => 'ColorTempUnknown28', Unknown => 1 },
+    0xfd => { Name => 'WB_RGGBLevelsUnknown29',  Format => 'int16s[4]', Unknown => 1 },
+    0x101 => { Name => 'ColorTempUnknown29', Unknown => 1 },
+    0x102 => { Name => 'WB_RGGBLevelsUnknown30',  Format => 'int16s[4]', Unknown => 1 },
+    0x106 => { Name => 'ColorTempUnknown30', Unknown => 1 },
+
+    0x107 => {
+        Name => 'ColorCalib',
+        Format => 'undef[120]',
+        Unknown => 1,
+        Notes => 'B, C, A, Temperature',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
+    },
+    0x146 => { Name => 'AverageBlackLevel', Format => 'int16u[4]' },
+    0x22c => {
+        Name => 'PerChannelBlackLevel',
+        Condition => '$$self{ColorDataVersion} == 14',
+        Format => 'int16u[4]',
+        Notes => '1300D',
+    },
+    0x230 => {
+        Name => 'NormalWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 14',
+        Format => 'int16u',
+        Notes => '1300D',
+        RawConv => '$val || undef',
+    },
+    0x231 => {
+        Name => 'SpecularWhiteLevel',
+        Condition => '$$self{ColorDataVersion} == 14',
+        Format => 'int16u',
+        Notes => '1300D',
+    },
+    0x232 => {
+        Name => 'LinearityUpperMargin',
+        Condition => '$$self{ColorDataVersion} == 14',
+        Format => 'int16u',
+        Notes => '1300D',
+    },
+    0x30a => {
+        Name => 'PerChannelBlackLevel',
+        Condition => '$$self{ColorDataVersion} < 14 or $$self{ColorDataVersion} == 15',
+        Format => 'int16u[4]',
+        Notes => '5DS, 5DS R, 77D, 80D and 800D',
+    },
+    0x30e => {
+        Name => 'NormalWhiteLevel',
+        Condition => '$$self{ColorDataVersion} < 14 or $$self{ColorDataVersion} == 15',
+        Format => 'int16u',
+        Notes => '5DS, 5DS R, 77D, 80D and 800D',
+        RawConv => '$val || undef',
+    },
+    0x30f => {
+        Name => 'SpecularWhiteLevel',
+        Condition => '$$self{ColorDataVersion} < 14 or $$self{ColorDataVersion} == 15',
+        Format => 'int16u',
+        Notes => '5DS, 5DS R, 77D, 80D and 800D',
+    },
+    0x310 => {
+        Name => 'LinearityUpperMargin',
+        Condition => '$$self{ColorDataVersion} < 14 or $$self{ColorDataVersion} == 15',
+        Format => 'int16u',
+        Notes => '5DS, 5DS R, 77D, 80D and 800D',
+    },
+);
+
+# Color data (MakerNotes tag 0x4001, count=1820,etc) (ref PH)
+%Image::ExifTool::Canon::ColorData9 = (
+    %binaryDataAttrs,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0 ],
+    IS_SUBDIR => [ 0x10a ],
+    0x00 => {
+        Name => 'ColorDataVersion',
+        DataMember => 'ColorDataVersion',
+        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]' },
+    0x4b => 'ColorTempAsShot',
+    0x4c => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
+    0x50 => 'ColorTempAuto',
+    0x51 => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
+    0x55 => 'ColorTempMeasured',
+    0x56 => { Name => 'WB_RGGBLevelsUnknown',   Format => 'int16s[4]', Unknown => 1 },
+    0x5a => { Name => 'ColorTempUnknown',  Unknown => 1 },
+    0x5b => { Name => 'WB_RGGBLevelsUnknown2',  Format => 'int16s[4]', Unknown => 1 },
+    0x5f => { Name => 'ColorTempUnknown2', Unknown => 1 },
+    0x60 => { Name => 'WB_RGGBLevelsUnknown3',  Format => 'int16s[4]', Unknown => 1 },
+    0x64 => { Name => 'ColorTempUnknown3', Unknown => 1 },
+    0x65 => { Name => 'WB_RGGBLevelsUnknown4',  Format => 'int16s[4]', Unknown => 1 },
+    0x69 => { Name => 'ColorTempUnknown4', Unknown => 1 },
+    0x6a => { Name => 'WB_RGGBLevelsUnknown5',  Format => 'int16s[4]', Unknown => 1 },
+    0x6e => { Name => 'ColorTempUnknown5', Unknown => 1 },
+    0x6f => { Name => 'WB_RGGBLevelsUnknown6',  Format => 'int16s[4]', Unknown => 1 },
+    0x73 => { Name => 'ColorTempUnknown6', Unknown => 1 },
+    0x74 => { Name => 'WB_RGGBLevelsUnknown7',  Format => 'int16s[4]', Unknown => 1 },
+    0x78 => { Name => 'ColorTempUnknown7', Unknown => 1 },
+    0x79 => { Name => 'WB_RGGBLevelsUnknown8',  Format => 'int16s[4]', Unknown => 1 },
+    0x7d => { Name => 'ColorTempUnknown8', Unknown => 1 },
+    0x7e => { Name => 'WB_RGGBLevelsUnknown9',  Format => 'int16s[4]', Unknown => 1 },
+    0x82 => { Name => 'ColorTempUnknown9', Unknown => 1 },
+    0x83 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
+    0x87 => { Name => 'ColorTempUnknown10', Unknown => 1 },
+    0x88 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
+    0x8c => 'ColorTempDaylight',
+    0x8d => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
+    0x91 => 'ColorTempShade',
+    0x92 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
+    0x96 => 'ColorTempCloudy',
+    0x97 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
+    0x9b => 'ColorTempTungsten',
+    0x9c => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
+    0xa0 => 'ColorTempFluorescent',
+    0xa1 => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
+    0xa5 => 'ColorTempKelvin',
+    0xa6 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
+    0xaa => 'ColorTempFlash',
+    0xab => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
+    0xaf => { Name => 'ColorTempUnknown11', Unknown => 1 },
+    0xb0 => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
+    0xb4 => { Name => 'ColorTempUnknown12', Unknown => 1 },
+    0xb5 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
+    0xb9 => { Name => 'ColorTempUnknown13', Unknown => 1 },
+    0xba => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
+    0xbe => { Name => 'ColorTempUnknown14', Unknown => 1 },
+    0xbf => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
+    0xc3 => { Name => 'ColorTempUnknown15', Unknown => 1 },
+    0xc4 => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
+    0xc8 => { Name => 'ColorTempUnknown16', Unknown => 1 },
+    0xc9 => { Name => 'WB_RGGBLevelsUnknown17',  Format => 'int16s[4]', Unknown => 1 },
+    0xcd => { Name => 'ColorTempUnknown17', Unknown => 1 },
+    0xce => { Name => 'WB_RGGBLevelsUnknown18',  Format => 'int16s[4]', Unknown => 1 },
+    0xd2 => { Name => 'ColorTempUnknown18', Unknown => 1 },
+    0xd3 => { Name => 'WB_RGGBLevelsUnknown19',  Format => 'int16s[4]', Unknown => 1 },
+    0xd7 => { Name => 'ColorTempUnknown19', Unknown => 1 },
+    0xd8 => { Name => 'WB_RGGBLevelsUnknown20',  Format => 'int16s[4]', Unknown => 1 },
+    0xdc => { Name => 'ColorTempUnknown20', Unknown => 1 },
+    0xdd => { Name => 'WB_RGGBLevelsUnknown21',  Format => 'int16s[4]', Unknown => 1 },
+    0xe1 => { Name => 'ColorTempUnknown21', Unknown => 1 },
+    0xe2 => { Name => 'WB_RGGBLevelsUnknown22',  Format => 'int16s[4]', Unknown => 1 },
+    0xe6 => { Name => 'ColorTempUnknown22', Unknown => 1 },
+    0xe7 => { Name => 'WB_RGGBLevelsUnknown23',  Format => 'int16s[4]', Unknown => 1 },
+    0xeb => { Name => 'ColorTempUnknown23', Unknown => 1 },
+    0xec => { Name => 'WB_RGGBLevelsUnknown24',  Format => 'int16s[4]', Unknown => 1 },
+    0xf0 => { Name => 'ColorTempUnknown24', Unknown => 1 },
+    0xf1 => { Name => 'WB_RGGBLevelsUnknown25',  Format => 'int16s[4]', Unknown => 1 },
+    0xf5 => { Name => 'ColorTempUnknown25', Unknown => 1 },
+    0xf6 => { Name => 'WB_RGGBLevelsUnknown26',  Format => 'int16s[4]', Unknown => 1 },
+    0xfa => { Name => 'ColorTempUnknown26', Unknown => 1 },
+    0xfb => { Name => 'WB_RGGBLevelsUnknown27',  Format => 'int16s[4]', Unknown => 1 },
+    0xff => { Name => 'ColorTempUnknown27', Unknown => 1 },
+    0x100=> { Name => 'WB_RGGBLevelsUnknown28',  Format => 'int16s[4]', Unknown => 1 },
+    0x104=> { Name => 'ColorTempUnknown28', Unknown => 1 },
+    0x105=> { Name => 'WB_RGGBLevelsUnknown29',  Format => 'int16s[4]', Unknown => 1 },
+    0x109=> { Name => 'ColorTempUnknown29', Unknown => 1 },
+    0x10a => { #IB
+        Name => 'ColorCalib',
+        Format => 'undef[120]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
+    },
+    0x149 => { #IB
+        Name => 'PerChannelBlackLevel',
+        Format => 'int16u[4]',
+    },
+    # 0x318 - PerChannelBlackLevel again (ref IB)
+    0x31c => { #IB
+        Name => 'NormalWhiteLevel',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+    },
+    0x31d => { #IB
+        Name => 'SpecularWhiteLevel',
+        Format => 'int16u',
+    },
+    0x31e => { #IB
+        Name => 'LinearityUpperMargin',
+        Format => 'int16u',
+    },
+);
+
+# Color data (MakerNotes tag 0x4001, count=2024,3656)
+# (same as ColorData9 but shifted up by 0x0e, ref PH)
+%Image::ExifTool::Canon::ColorData10 = (
+    %binaryDataAttrs,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0 ],
+    IS_SUBDIR => [ 0x118 ],
+    0x00 => {
+        Name => 'ColorDataVersion',
+        DataMember => 'ColorDataVersion',
+        RawConv => '$$self{ColorDataVersion} = $val',
+        PrintConv => {
+            32 => '32 (1DXmkIII)', #IB
+            33 => '33 (R5/R6)',
+        },
+    },
+    0x55 => { Name => 'WB_RGGBLevelsAsShot',     Format => 'int16s[4]' },
+    0x59 => 'ColorTempAsShot',
+    0x5a => { Name => 'WB_RGGBLevelsAuto',       Format => 'int16s[4]' },
+    0x5e => 'ColorTempAuto',
+    0x5f => { Name => 'WB_RGGBLevelsMeasured',   Format => 'int16s[4]' },
+    0x63 => 'ColorTempMeasured',
+    0x64 => { Name => 'WB_RGGBLevelsUnknown',   Format => 'int16s[4]', Unknown => 1 },
+    0x68 => { Name => 'ColorTempUnknown',  Unknown => 1 },
+    0x69 => { Name => 'WB_RGGBLevelsUnknown2',  Format => 'int16s[4]', Unknown => 1 },
+    0x6d => { Name => 'ColorTempUnknown2', Unknown => 1 },
+    0x6e => { Name => 'WB_RGGBLevelsUnknown3',  Format => 'int16s[4]', Unknown => 1 },
+    0x72 => { Name => 'ColorTempUnknown3', Unknown => 1 },
+    0x73 => { Name => 'WB_RGGBLevelsUnknown4',  Format => 'int16s[4]', Unknown => 1 },
+    0x77 => { Name => 'ColorTempUnknown4', Unknown => 1 },
+    0x78 => { Name => 'WB_RGGBLevelsUnknown5',  Format => 'int16s[4]', Unknown => 1 },
+    0x7c => { Name => 'ColorTempUnknown5', Unknown => 1 },
+    0x7d => { Name => 'WB_RGGBLevelsUnknown6',  Format => 'int16s[4]', Unknown => 1 },
+    0x81 => { Name => 'ColorTempUnknown6', Unknown => 1 },
+    0x82 => { Name => 'WB_RGGBLevelsUnknown7',  Format => 'int16s[4]', Unknown => 1 },
+    0x86 => { Name => 'ColorTempUnknown7', Unknown => 1 },
+    0x87 => { Name => 'WB_RGGBLevelsUnknown8',  Format => 'int16s[4]', Unknown => 1 },
+    0x8b => { Name => 'ColorTempUnknown8', Unknown => 1 },
+    0x8c => { Name => 'WB_RGGBLevelsUnknown9',  Format => 'int16s[4]', Unknown => 1 },
+    0x90 => { Name => 'ColorTempUnknown9', Unknown => 1 },
+    0x91 => { Name => 'WB_RGGBLevelsUnknown10',  Format => 'int16s[4]', Unknown => 1 },
+    0x95 => { Name => 'ColorTempUnknown10', Unknown => 1 },
+    0x96 => { Name => 'WB_RGGBLevelsDaylight',   Format => 'int16s[4]' },
+    0x9a => 'ColorTempDaylight',
+    0x9b => { Name => 'WB_RGGBLevelsShade',      Format => 'int16s[4]' },
+    0x9f => 'ColorTempShade',
+    0xa0 => { Name => 'WB_RGGBLevelsCloudy',     Format => 'int16s[4]' },
+    0xa4 => 'ColorTempCloudy',
+    0xa5 => { Name => 'WB_RGGBLevelsTungsten',   Format => 'int16s[4]' },
+    0xa9 => 'ColorTempTungsten',
+    0xaa => { Name => 'WB_RGGBLevelsFluorescent',Format => 'int16s[4]' },
+    0xae => 'ColorTempFluorescent',
+    0xaf => { Name => 'WB_RGGBLevelsKelvin',     Format => 'int16s[4]' },
+    0xb3 => 'ColorTempKelvin',
+    0xb4 => { Name => 'WB_RGGBLevelsFlash',      Format => 'int16s[4]' },
+    0xb8 => 'ColorTempFlash',
+    0xb9 => { Name => 'WB_RGGBLevelsUnknown11',  Format => 'int16s[4]', Unknown => 1 },
+    0xbd => { Name => 'ColorTempUnknown11', Unknown => 1 },
+    0xbe => { Name => 'WB_RGGBLevelsUnknown12',  Format => 'int16s[4]', Unknown => 1 },
+    0xc2 => { Name => 'ColorTempUnknown12', Unknown => 1 },
+    0xc3 => { Name => 'WB_RGGBLevelsUnknown13',  Format => 'int16s[4]', Unknown => 1 },
+    0xc7 => { Name => 'ColorTempUnknown13', Unknown => 1 },
+    0xc8 => { Name => 'WB_RGGBLevelsUnknown14',  Format => 'int16s[4]', Unknown => 1 },
+    0xcc => { Name => 'ColorTempUnknown14', Unknown => 1 },
+    0xcd => { Name => 'WB_RGGBLevelsUnknown15',  Format => 'int16s[4]', Unknown => 1 },
+    0xd1 => { Name => 'ColorTempUnknown15', Unknown => 1 },
+    0xd2 => { Name => 'WB_RGGBLevelsUnknown16',  Format => 'int16s[4]', Unknown => 1 },
+    0xd6 => { Name => 'ColorTempUnknown16', Unknown => 1 },
+    0xd7 => { Name => 'WB_RGGBLevelsUnknown17',  Format => 'int16s[4]', Unknown => 1 },
+    0xdb => { Name => 'ColorTempUnknown17', Unknown => 1 },
+    0xdc => { Name => 'WB_RGGBLevelsUnknown18',  Format => 'int16s[4]', Unknown => 1 },
+    0xe0 => { Name => 'ColorTempUnknown18', Unknown => 1 },
+    0xe1 => { Name => 'WB_RGGBLevelsUnknown19',  Format => 'int16s[4]', Unknown => 1 },
+    0xe5 => { Name => 'ColorTempUnknown19', Unknown => 1 },
+    0xe6 => { Name => 'WB_RGGBLevelsUnknown20',  Format => 'int16s[4]', Unknown => 1 },
+    0xea => { Name => 'ColorTempUnknown20', Unknown => 1 },
+    0xeb => { Name => 'WB_RGGBLevelsUnknown21',  Format => 'int16s[4]', Unknown => 1 },
+    0xef => { Name => 'ColorTempUnknown21', Unknown => 1 },
+    0xf0 => { Name => 'WB_RGGBLevelsUnknown22',  Format => 'int16s[4]', Unknown => 1 },
+    0xf4 => { Name => 'ColorTempUnknown22', Unknown => 1 },
+    0xf5 => { Name => 'WB_RGGBLevelsUnknown23',  Format => 'int16s[4]', Unknown => 1 },
+    0xf9 => { Name => 'ColorTempUnknown23', Unknown => 1 },
+    0xfa => { Name => 'WB_RGGBLevelsUnknown24',  Format => 'int16s[4]', Unknown => 1 },
+    0xfe => { Name => 'ColorTempUnknown24', Unknown => 1 },
+    0xff => { Name => 'WB_RGGBLevelsUnknown25',  Format => 'int16s[4]', Unknown => 1 },
+    0x103=> { Name => 'ColorTempUnknown25', Unknown => 1 },
+    0x104=> { Name => 'WB_RGGBLevelsUnknown26',  Format => 'int16s[4]', Unknown => 1 },
+    0x108=> { Name => 'ColorTempUnknown26', Unknown => 1 },
+    0x109=> { Name => 'WB_RGGBLevelsUnknown27',  Format => 'int16s[4]', Unknown => 1 },
+    0x10d=> { Name => 'ColorTempUnknown27', Unknown => 1 },
+    0x10e=> { Name => 'WB_RGGBLevelsUnknown28',  Format => 'int16s[4]', Unknown => 1 },
+    0x112=> { Name => 'ColorTempUnknown28', Unknown => 1 },
+    0x113=> { Name => 'WB_RGGBLevelsUnknown29',  Format => 'int16s[4]', Unknown => 1 },
+    0x117=> { Name => 'ColorTempUnknown29', Unknown => 1 },
+    0x118 => {
+        Name => 'ColorCalib',
+        Format => 'undef[120]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorCalib' }
+    },
+    0x157 => {
+        Name => 'PerChannelBlackLevel',
+        Format => 'int16u[4]',
+    },
+    # 0x326 - PerChannelBlackLevel again
+    0x32a => {
+        Name => 'NormalWhiteLevel',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+    },
+    0x32b => {
+        Name => 'SpecularWhiteLevel',
+        Format => 'int16u',
+    },
+    0x32c => {
+        Name => 'LinearityUpperMargin',
+        Format => 'int16u',
+    },
 );
 
@@ -5905,4 +8245,5 @@
     FIRST_ENTRY => 0,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x00 => 'ColorDataVersion',
 );
 
@@ -5939,8 +8280,10 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     1 => {
-        Name => 'AFMicroAdjActive',
-        PrintConv => {
-            0 => 'No',
-            1 => 'Yes',
+        Name => 'AFMicroAdjMode',
+        PrintConv => {
+            0 => 'Disable',
+            1 => 'Adjust all by the same amount',
+            2 => 'Adjust by lens',
+          # 3 - seen this for EOS 77D, which doesn't have an AF Micro Adjust feature - PH
         },
     },
@@ -5957,14 +8300,28 @@
     FIRST_ENTRY => 1,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    NOTES => q{
-        This information is found in images from the 1DmkIV, 5DmkII, 7D, 50D, 500D
-        and 550D.
-    },
-    # 0 => 'PeripheralLightingVersion', value = 0x1000
+    NOTES => 'This information is found in images from newer EOS models.',
+    0 => {
+        Name => 'VignettingCorrVersion',
+        Format => 'int8u',
+        Writable => 0,
+    },
     2 => {
         Name => 'PeripheralLighting',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
+    },
+    3 => {
+        Name => 'DistortionCorrection',
+        PrintConv => \%offOn,
+    },
+    4 => {
+        Name => 'ChromaticAberrationCorr',
+        PrintConv => \%offOn,
+    },
+    5 => {
+        Name => 'ChromaticAberrationCorr',
+        PrintConv => \%offOn,
     },
     6 => 'PeripheralLightingValue',
+    9 => 'DistortionCorrectionValue',
     # 10 - flags?
     11 => {
@@ -5973,4 +8330,17 @@
     },
     12 => 'OriginalImageHeight',
+);
+
+%Image::ExifTool::Canon::VignettingCorrUnknown = (
+    %binaryDataAttrs,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Vignetting correction from PowerShot models.',
+    0 => {
+        Name => 'VignettingCorrVersion',
+        Format => 'int8u',
+        Writable => 0,
+    },
 );
 
@@ -5983,5 +8353,13 @@
     5 => {
         Name => 'PeripheralLightingSetting',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => \%offOn,
+    },
+    6 => {
+        Name => 'ChromaticAberrationSetting',
+        PrintConv => \%offOn,
+    },
+    7 => {
+        Name => 'DistortionCorrectionSetting',
+        PrintConv => \%offOn,
     },
 );
@@ -5994,4 +8372,8 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     NOTES => 'This information is new in images from the EOS 7D.',
+    1 => {
+        Name => 'PeripheralIlluminationCorr',
+        PrintConv => \%offOn,
+    },
     2 => {
         Name => 'AutoLightingOptimizer',
@@ -6003,4 +8385,28 @@
         },
     },
+    3 => {
+        Name => 'HighlightTonePriority',
+        PrintConv => \%offOn,
+    },
+    4 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'On',
+        },
+    },
+    5 => {
+        Name => 'HighISONoiseReduction',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Low',
+            2 => 'Strong',
+            3 => 'Off',
+        },
+    },
+    # 6 - related to ChromaticAberrationCorr
+    # 7 - related to DistortionCorrection (0=off, 1=On in a 5DmkIV sample)
+    # 8 - related to PeripheralIlluminationCorr and ChromaticAberrationCorr
 );
 
@@ -6010,5 +8416,5 @@
     FIRST_ENTRY => 0,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    0 => { # this doesn't seem to be valid for some models (ie. 550D, 7D?, 1DmkIV?)
+    0 => { # this doesn't seem to be valid for some models (eg. 550D, 7D?, 1DmkIV?)
         Name => 'LensSerialNumber',
         Notes => q{
@@ -6016,8 +8422,9 @@
             to the one printed on the lens
         },
-        Condition => '$$valPt !~ /^\0\0\0\0/', # (rules out 550D and older lenses)
         Format => 'undef[5]',
+        Priority => 0,
+        RawConv => '$val=~/^\0\0\0\0/ ? undef : $val', # (rules out 550D and older lenses)
         ValueConv => 'unpack("H*", $val)',
-        ValueConvInv => 'pack("H*", $val)',
+        ValueConvInv => 'length($val) < 10 and $val = 0 x (10-length($val)) . $val; pack("H*",$val)',
     },
 );
@@ -6045,4 +8452,36 @@
 );
 
+# Multi-exposure information (MakerNotes tag 0x4021) (ref PH)
+%Image::ExifTool::Canon::MultiExp = (
+    %binaryDataAttrs,
+    FORMAT => 'int32s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    1 => {
+        Name => 'MultiExposure',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (RAW)', #IB
+        },
+    },
+    2 => {
+        Name => 'MultiExposureControl',
+        PrintConv => {
+            0 => 'Additive',
+            1 => 'Average',
+            2 => 'Bright (comparative)',
+            3 => 'Dark (comparative)',
+        },
+    },
+    3 => 'MultiExposureShots',
+);
+
+my %filterConv = (
+    PrintConv => {
+        -1 => 'Off',
+        OTHER => sub { my $val=shift; return "On ($val)" },
+    },
+);
 # Creative filter information (MakerNotes tag 0x4024) (ref PH)
 %Image::ExifTool::Canon::FilterInfo = (
@@ -6053,23 +8492,10 @@
         Name => 'GrainyBWFilter',
         Description => 'Grainy B/W Filter',
-        PrintConv => '$val == -1 ? "Off" : "On ($val)"',
-        PrintConvInv => '$val =~ /([-+]?\d+)/ ? $1 : -1',
-    },
-    0x201 => {
-        Name => 'SoftFocusFilter',
-        PrintConv => '$val == -1 ? "Off" : "On ($val)"',
-        PrintConvInv => '$val =~ /([-+]?\d+)/ ? $1 : -1',
-    },
-    0x301 => {
-        Name => 'ToyCameraFilter',
-        PrintConv => '$val == -1 ? "Off" : "On ($val)"',
-        PrintConvInv => '$val =~ /([-+]?\d+)/ ? $1 : -1',
-    },
-    0x401 => {
-        Name => 'MiniatureFilter',
-        PrintConv => '$val == -1 ? "Off" : "On ($val)"',
-        PrintConvInv => '$val =~ /([-+]?\d+)/ ? $1 : -1',
-    },
-    0x0402 => {
+        %filterConv,
+    },
+    0x201 => { Name => 'SoftFocusFilter',   %filterConv },
+    0x301 => { Name => 'ToyCameraFilter',   %filterConv },
+    0x401 => { Name => 'MiniatureFilter',   %filterConv },
+    0x402 => {
         Name => 'MiniatureFilterOrientation',
         PrintConv => {
@@ -6078,19 +8504,434 @@
         },
     },
-    0x403=> 'MiniatureFilterPosition',
-    # 0x404 - value: 0, 345, 518, ... (miniature filter width maybe?)
-);
-
-# Canon CNTH atoms (ref PH)
+    0x403 => 'MiniatureFilterPosition',
+    0x404 => 'MiniatureFilterParameter', # but what is the meaning?
+    0x501 => { Name => 'FisheyeFilter',     %filterConv }, # (M2)
+    0x601 => { Name => 'PaintingFilter',    %filterConv }, # (M2)
+    0x701 => { Name => 'WatercolorFilter',  %filterConv }, # (M2)
+);
+
+# HDR information (MakerNotes tag 0x4025) (ref PH)
+%Image::ExifTool::Canon::HDRInfo = (
+    %binaryDataAttrs,
+    FORMAT => 'int32s',
+    FIRST_ENTRY => 1,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    1 => {
+        Name => 'HDR',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'On',
+        },
+    },
+    2 => {
+        Name => 'HDREffect',
+        PrintConv => {
+            0 => 'Natural',
+            1 => 'Art (standard)',
+            2 => 'Art (vivid)',
+            3 => 'Art (bold)',
+            4 => 'Art (embossed)',
+        },
+    },
+    # 3 - maybe related to AutoImageAlign?
+);
+
+# AF configuration info (MakerNotes tag 0x4028) (ref PH)
+%Image::ExifTool::Canon::AFConfig = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int32s',
+    FIRST_ENTRY => 1,
+    1 => {
+        Name => 'AFConfigTool',
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+        PrintConv => '"Case $val"',
+        PrintConvInv => '$val=~/(\d+)/ ? $1 : undef',
+    },
+    2 => 'AFTrackingSensitivity',
+    3 => {
+        Name => 'AFAccelDecelTracking',
+        Description => 'AF Accel/Decel Tracking',
+    },
+    4 => 'AFPointSwitching',
+    5 => { #52
+        Name => 'AIServoFirstImage',
+        PrintConv => {
+             0 => 'Equal Priority',
+             1 => 'Release Priority',
+             2 => 'Focus Priority',
+        },
+    },
+    6 => { #52
+        Name => 'AIServoSecondImage',
+        PrintConv => {
+             0 => 'Equal Priority',
+             1 => 'Release Priority',
+             2 => 'Focus Priority',
+             3 => 'Release High Priority',
+             4 => 'Focus High Priority',
+        },
+    },
+    7 => { #52
+        Name => 'USMLensElectronicMF',
+        PrintConv => {
+             0 => 'Enable After AF',
+             1 => 'Disable After AF',
+             2 => 'Disable in AF Mode',
+        },
+    },
+    8 => { #52
+        Name => 'AFAssistBeam',
+        PrintConv => {
+             0 => 'Enable',
+             1 => 'Disable',
+             2 => 'IR AF Assist Beam Only',
+        },
+    },
+    9 => { #52
+        Name => 'OneShotAFRelease',
+        PrintConv => {
+             0 => 'Focus Priority',
+             1 => 'Release Priority',
+        },
+    },
+    10 => { #52
+        Name => 'AutoAFPointSelEOSiTRAF',
+        Description => 'Auto AF Point Sel EOS iTR AF',
+        # valid for: 1DX, 1DXmkII, 7DmkII, 5DS, 5DSR
+        # not valid for: 5DmkIII
+        Notes => 'only valid for some models',
+        Condition => '$$self{Model} !~ /5D /',
+        PrintConv => {
+             0 => 'Enable',
+             1 => 'Disable',
+        },
+    },
+    11 => { #52
+        Name => 'LensDriveWhenAFImpossible',
+        PrintConv => {
+             0 => 'Continue Focus Search',
+             1 => 'Stop Focus Search',
+        },
+    },
+    12 => { #52
+        Name => 'SelectAFAreaSelectionMode',
+        PrintConv => { BITMASK => {
+            0 => 'Single-point AF',
+            1 => 'Auto', # (61 point)
+            2 => 'Zone AF',
+            3 => 'AF Point Expansion (4 point)',
+            4 => 'Spot AF',
+            5 => 'AF Point Expansion (8 point)',
+        }},
+    },
+    13 => { #52
+        Name => 'AFAreaSelectionMethod',
+        PrintConv => {
+             0 => 'M-Fn Button',
+             1 => 'Main Dial',
+        },
+    },
+    14 => { #52
+        Name => 'OrientationLinkedAF',
+        PrintConv => { # Covers both 1Dx (0-2) and 5D3 (0-1)
+             0 => 'Same for Vert/Horiz Points',
+             1 => 'Separate Vert/Horiz Points',
+             2 => 'Separate Area+Points',
+        },
+    },
+    15 => { #52
+        Name => 'ManualAFPointSelPattern',
+        PrintConv => {
+             0 => 'Stops at AF Area Edges',
+             1 => 'Continuous',
+        },
+    },
+    16 => { #52
+        Name => 'AFPointDisplayDuringFocus',
+        PrintConv => {
+             0 => 'Selected (constant)',
+             1 => 'All (constant)',
+             2 => 'Selected (pre-AF, focused)',
+             3 => 'Selected (focused)',
+             4 => 'Disabled',
+        },
+    },
+    17 => { #52
+        Name => 'VFDisplayIllumination',
+        PrintConv => {
+             0 => 'Auto',
+             1 => 'Enable',
+             2 => 'Disable',
+        },
+    },
+    18 => { #52
+        Name => 'AFStatusViewfinder',
+        Condition => '$$self{Model} =~ /1D X/',
+        Notes => '1D X only',
+        PrintConv => {
+             0 => 'Show in Field of View',
+             1 => 'Show Outside View',
+        },
+    },
+    19 => { #52
+        Name => 'InitialAFPointInServo',
+        Condition => '$$self{Model} =~ /1D X/',
+        Notes => '1D X only',
+        PrintConv => {
+             0 => 'Initial AF Point Selected',
+             1 => 'Manual AF Point',
+             2 => 'Auto', #PH (1DXmkII)
+        },
+    },
+);
+
+# 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.
+    },
+    CNCV => {
+        Name => 'CompressorVersion',
+        # use this to recognize the specific type of Canon RAW (CR3 or CRM)
+        RawConv => '$self->OverrideFileType($1) if $val =~ /^Canon(\w{3})/i; $val',
+    },
+    # CNDM - 4 bytes - 0xff,0xd8,0xff,0xd9
+    CNTH => {
+        Name => 'CanonCNTH',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CNTH' },
+    },
+    CCTP => { # (CR3 files)
+        Name => 'CanonCCTP',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::CCTP',
+            Start => '12',
+        },
+    },
+    # CTBO - (CR3 files) int32u entry count N, N x (int32u index, int64u offset, int64u size)
+    #        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)
+        Name => 'ExifIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            WriteProc => \&Image::ExifTool::WriteTIFF,
+        },
+    },
+    CMT3 => { # (CR3 files)
+        Name => 'MakerNoteCanon',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::Main',
+            ProcessProc => \&ProcessCMT3,
+            WriteProc => \&Image::ExifTool::WriteTIFF,
+        },
+    },
+    CMT4 => { # (CR3 files)
+        Name => 'GPSInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::GPS::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            WriteProc => \&Image::ExifTool::WriteTIFF,
+            DirName => 'GPS',
+        },
+    },
+    THMB => {
+        Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        RawConv => 'substr($val, 16)',
+        Binary => 1,
+    },
+    CNOP => { #PH (M50)
+        Name => 'CanonCNOP',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CNOP' },
+    },
+);
+
+# 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' },
+);
+
+# Canon CCTP atoms (ref PH, CR3 files)
+%Image::ExifTool::Canon::CCTP = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
+    # 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 => '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)
+%Image::ExifTool::Canon::CTMD = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessCTMD,
+    NOTES => q{
+        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.
+    },
+    1 => {
+        Name => 'TimeStamp',
+        Groups => { 2 => 'Time' },
+        RawConv => q{
+            my $fmt = GetByteOrder() eq 'MM' ? 'x2nCCCCCC' : 'x2vCCCCCC';
+            sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d.%.2d', unpack($fmt, $val));
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+  # 3 - 4 bytes, seen: ff ff ff ff
+    4 => {
+        Name => 'FocalInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::FocalInfo' },
+    },
+    5 => {
+        Name => 'ExposureInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ExposureInfo' },
+    },
+    7 => {
+        Name => 'ExifInfo7',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ExifInfo' },
+    },
+    8 => {
+        Name => 'ExifInfo8',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ExifInfo' },
+    },
+    9 => {
+        Name => 'ExifInfo9',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ExifInfo' },
+    },
+  # 10 - 60 bytes: all zeros with a pair of 0xff's at offset 0x02 (C200 CRM)
+  # 11 - 612 bytes: all zero with pairs of 0xff's at offset 0x6e and 0x116 (C200 CRM)
+);
+
+# Canon Timed MetaData (ref PH, CR3 files)
+%Image::ExifTool::Canon::ExifInfo = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessExifInfo,
+    0x8769 => {
+        Name => 'ExifIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+        },
+    },
+    0x927c => {
+        Name => 'MakerNoteCanon',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+        },
+    },
+);
+
+# timed focal length information (ref PH, CR3 files)
+%Image::ExifTool::Canon::FocalInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'FocalLength',
+        Format => 'rational32u',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+    },
+);
+
+# timed exposure information (ref PH, CR3 files)
+%Image::ExifTool::Canon::ExposureInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Image' },
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'FNumber',
+        Format => 'rational32u',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+    },
+    1 => {
+        Name => 'ExposureTime',
+        Format => 'rational32u',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    2 => {
+        Name => 'ISO',
+        Format => 'int32u',
+        ValueConv => '$val & 0x7fffffff',   # (not sure what high bit indicates)
+    },
+);
+
 %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',
+        Groups => { 2 => 'Preview' },
         Format => 'undef',
         Notes => 'the full THM image, embedded metadata is extracted as the first sub-document',
+        SetBase => 1,
         RawConv => q{
             $$self{DOC_NUM} = ++$$self{DOC_COUNT};
@@ -6099,5 +8940,21 @@
             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,C200)
+    # CNMI - 4 bytes: "0x20000001" (C200)
+    # CNCM - 48 bytes: original file name in bytes 24-31 (C200)
+);
+
+# 'skip' atom of Canon MOV videos (ref PH)
+%Image::ExifTool::Canon::Skip = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Canon', 2 => 'Video' },
+    NOTES => 'Information found in the "skip" atom of Canon MOV videos.',
+    CNDB => { Name => 'Unknown_CNDB', Unknown => 1, Binary => 1 },
 );
 
@@ -6119,6 +8976,6 @@
     Lens => {
         Require => {
-            0 => 'ShortFocal',
-            1 => 'LongFocal',
+            0 => 'Canon:MinFocalLength',
+            1 => 'Canon:MaxFocalLength',
         },
         ValueConv => '$val[0]',
@@ -6128,6 +8985,6 @@
         Description => 'Lens',
         Require => {
-            0 => 'ShortFocal',
-            1 => 'LongFocal',
+            0 => 'Canon:MinFocalLength',
+            1 => 'Canon:MaxFocalLength',
             3 => 'Lens',
         },
@@ -6272,5 +9129,12 @@
             FileIndex => '$val=~/(\d+)-(\d+)/; $2',
         },
-        ValueConv => 'sprintf("%.3d-%.4d",@val)',
+        ValueConv => q{
+            # fix the funny things that these numbers do when they wrap over 9999
+            # (it seems that FileIndex and DirectoryIndex actually store the
+            #  numbers from the previous image, so we need special logic
+            #  to handle the FileIndex wrap properly)
+            $val[1] == 10000 and $val[1] = 1, ++$val[0];
+            return sprintf("%.3d-%.4d",@val);
+        },
     },
 );
@@ -6302,13 +9166,49 @@
 
 #------------------------------------------------------------------------------
+# Attempt to calculate sensor size for Canon cameras
+# Inputs: 0/1) rational values for FocalPlaneX/YResolution
+# Returns: Sensor diagonal size in mm, or undef
+# Notes: This algorithm is fairly reliable, but has been found to give incorrect
+#        values for some firmware versions of the EOS 20D, A310, SD40 and IXUS 65
+# (ref http://wyw.dcweb.cn/download.asp?path=&file=jhead-2.96-ccdwidth_hack.zip)
+sub CalcSensorDiag($$)
+{
+    my ($xres, $yres) = @_;
+    # most Canon cameras store the sensor size in the denominator
+    if ($xres and $yres) {
+        # assumptions: 1) numerators are image width/height * 1000
+        # 2) denominators are sensor width/height in inches * 1000
+        my @xres = split /[ \/]/, $xres;
+        my @yres = split /[ \/]/, $yres;
+        # verify assumptions as best we can:
+            # numerators are always divisible by 1000
+        if ($xres[0] % 1000 == 0 and $yres[0] % 1000 == 0 and
+            # at least 640x480 pixels (DC models - PH)
+            $xres[0] >= 640000 and $yres[0] >= 480000 and
+            # ... but not too big!
+            $xres[0] < 10000000 and $yres[0] < 10000000 and
+            # minimum sensor size is 0.061 inches (DC models - PH)
+            $xres[1] >= 61 and $xres[1] < 1500 and
+            $yres[1] >= 61 and $yres[1] < 1000 and
+            # sensor isn't square (may happen if rationals have been reduced)
+            $xres[1] != $yres[1])
+        {
+            return sqrt($xres[1]*$xres[1] + $yres[1]*$yres[1]) * 0.0254;
+        }
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
 # Attempt to identify the specific lens if multiple lenses have the same LensType
-# Inputs: 0) PrintConv hash ref, 1) LensType, 2) ShortFocal, 3) LongFocal
+# Inputs: 0) PrintConv hash ref, 1) LensType, 2) MinFocalLength, 3) MaxFocalLength
 #         4) MaxAperture, 5) LensModel
-# Notes: PrintConv, LensType, ShortFocal and LongFocal must be defined.
+# Notes: PrintConv, LensType, MinFocalLength and MaxFocalLength must be defined.
 #        Other inputs are optional.
 sub PrintLensID(@)
 {
     my ($printConv, $lensType, $shortFocal, $longFocal, $maxAperture, $lensModel) = @_;
-    my $lens = $$printConv{$lensType};
+    my $lens;
+    $lens = $$printConv{$lensType} unless $lensType eq '-1' or $lensType eq '65535';
     if ($lens) {
         # return this lens unless other lenses have the same LensType
@@ -6321,11 +9221,10 @@
             push @lenses, $$printConv{"$lensType.$i"};
         }
+        my ($tc, @user, @maybe, @likely, @matches);
         # look for lens in user-defined lenses
         foreach $lens (@lenses) {
-            next unless $Image::ExifTool::userLens{$lens};
-            return LensWithTC($lens, $shortFocal);
+            push @user, $lens if $Image::ExifTool::userLens{$lens};
         }
         # attempt to determine actual lens
-        my ($tc, @maybe, @likely, @matches);
         foreach $tc (1, 1.4, 2, 2.8) {  # loop through teleconverter scaling factors
             foreach $lens (@lenses) {
@@ -6336,4 +9235,9 @@
                 $lf = $sf if $sf and not $lf;
                 $la = $sa if $sa and not $la;
+                # account for converter-specific LensType's (ie. end with " + #.#x")
+                if ($lens =~ / \+ (\d+(\.\d+)?)x$/) {
+                    $sf *= $1;  $lf *= $1;
+                    $sa *= $1;  $la *= $1;
+                }
                 next if abs($shortFocal - $sf * $tc) > 0.9;
                 my $tclens = $lens;
@@ -6351,11 +9255,42 @@
             last if @maybe;
         }
+        if (@user) {
+            # choose the best match if we have more than one
+            if (@user > 1) {
+                my ($try, @good);
+                foreach $try (\@matches, \@likely, \@maybe) {
+                    foreach (@$try) {
+                        $Image::ExifTool::userLens{$_} and push(@good, $_), next;
+                        # check for match with TC string removed
+                        next unless /^(.*) \+ \d+(\.\d+)?x$/;
+                        $Image::ExifTool::userLens{$1} and push(@good, $_);
+                    }
+                    return join(' or ', @good) if @good;
+                }
+            }
+            # default to returning the first user-defined lens
+            return LensWithTC($user[0], $shortFocal);
+        }
+        # differentiate Sigma Art/Contemporary/Sports models
+        if (@matches > 1 and $lensModel and $lensModel =~ /(\| [ACS])/) {
+            my $type = $1;
+            my @best;
+            foreach $lens (@matches) {
+                push @best, $lens if $lens =~ /\Q$type/;
+            }
+            @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 (add "Canon" to the start
-        # since the camera only understands Canon lenses anyway)
-        return "Canon $lensModel";
+        # use lens model as written by the camera
+        if ($printConv eq \%canonLensTypes) {
+            # add "Canon" to the start since the Canon cameras only understand Canon lenses
+            return "Canon $lensModel";
+        } else {
+            return $lensModel;
+        }
     }
     my $str = '';
@@ -6365,5 +9300,6 @@
         $str .= 'mm';
     }
-    return "Unknown$str" if $lensType eq '-1'; # (careful because Sigma LensType's may not be integer)
+    # (careful because Sigma LensType's may not be integer, so use string comparison)
+    return "Unknown$str" if $lensType eq '-1' or $lensType eq '65535';
     return "Unknown ($lensType)$str";
 }
@@ -6432,8 +9368,8 @@
 sub ReadODD($$)
 {
-    my ($exifTool, $offset) = @_;
+    my ($et, $offset) = @_;
     return undef unless $offset;
     my ($raf, $buff, $buf2, $i, $warn);
-    return undef unless defined($raf = $$exifTool{RAF});
+    return undef unless defined($raf = $$et{RAF});
     # the data block is a variable length and starts with 0xffffffff
     # followed a 4-byte (int32u) version number
@@ -6513,6 +9449,6 @@
         SetByteOrder($oldOrder);
         unless ($err) {
-            if ($exifTool->Options('HtmlDump')) {
-                $exifTool->HDump($offset, length $buff, '[OriginalDecisionData]', undef);
+            if ($et->Options('HtmlDump')) {
+                $et->HDump($offset, length $buff, '[OriginalDecisionData]', undef);
             }
             $raf->Seek($pos, 0);    # restore original file position
@@ -6520,5 +9456,5 @@
         }
     }
-    $exifTool->Warn($warn || 'Invalid original decision data');
+    $et->Warn($warn || 'Invalid original decision data');
     $raf->Seek($pos, 0);    # restore original file position
     return undef;
@@ -6579,21 +9515,22 @@
 #        at 0, and the corresponding values must be contiguous in memory.
 #        "Unknown" tags must be used to skip padding or unknown values.
+# (does not yet extract Rational values)
 sub ProcessSerialData($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $offset = $$dirInfo{DirStart};
     my $size = $$dirInfo{DirLen};
     my $base = $$dirInfo{Base} || 0;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $dataPos = $$dirInfo{DataPos} || 0;
 
     # temporarily set Unknown option so GetTagInfo() will return existing unknown tags
     # (require to maintain serial data synchronization)
-    my $unknown = $exifTool->Options(Unknown => 1);
+    my $unknown = $et->Options(Unknown => 1);
     # but disable unknown tag generation (because processing ends when we run out of tags)
-    $$exifTool{NO_UNKNOWN} = 1;
-
-    $verbose and $exifTool->VerboseDir('SerialData', undef, $size);
+    $$et{NO_UNKNOWN} = 1;
+
+    $verbose and $et->VerboseDir('SerialData', undef, $size);
 
     # get default format ('int8u' unless specified)
@@ -6603,5 +9540,5 @@
     my $pos = 0;
     for ($index=0; $$tagTablePtr{$index} and $pos <= $size; ++$index) {
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $index) or last;
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $index) or last;
         my $format = $$tagInfo{Format};
         my $count = 1;
@@ -6626,5 +9563,5 @@
         last unless defined $val;
         if ($verbose) {
-            $exifTool->VerboseInfo($index, $tagInfo,
+            $et->VerboseInfo($index, $tagInfo,
                 Index  => $index,
                 Table  => $tagTablePtr,
@@ -6640,5 +9577,5 @@
         $val{$index} = $val;
         if ($$tagInfo{SubDirectory}) {
-            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            my $subTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
             my %dirInfo = (
                 DataPt => \$val,
@@ -6647,13 +9584,13 @@
                 DirLen => length($val),
             );
-            $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $subTablePtr);
         } elsif (not $$tagInfo{Unknown} or $unknown) {
             # don't extract zero-length information
-            $exifTool->FoundTag($tagInfo, $val) if $count;
+            $et->FoundTag($tagInfo, $val) if $count;
         }
         $pos += $len;
     }
-    $exifTool->Options(Unknown => $unknown);    # restore Unknown option
-    delete $$exifTool{NO_UNKNOWN};
+    $et->Options(Unknown => $unknown);    # restore Unknown option
+    delete $$et{NO_UNKNOWN};
     return 1;
 }
@@ -6695,5 +9632,5 @@
         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) . ')';
 }
@@ -6702,5 +9639,5 @@
 # Convert Canon hex-based EV (modulo 0x20) to real number
 # Inputs: 0) value to convert
-# ie) 0x00 -> 0
+# eg) 0x00 -> 0
 #     0x0c -> 0.33333
 #     0x10 -> 0.5
@@ -6757,4 +9694,112 @@
 
 #------------------------------------------------------------------------------
+# Read CMT3 maker notes from CR3 file
+# Inputs: 0) ExifTool object reference, 1) dirInfo ref, 2) tag table ref
+# Returns: data block (may be empty if no Exif data) or undef on error
+sub ProcessCMT3($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+
+    # extract the static maker notes to copying to other file types if requested
+    # Note: this won't copy makernotes in the timed metadata since these are stored
+    # separately, but the only records they have that aren't in the static maker notes
+    # (for the M50) are: ColorData9, Flavor, CanonCameraInfoUnknown,
+    # VignettingCorrUnknown1, Canon_0x4033 and Canon_0x402e
+    if (($et->Options('MakerNotes') or $$et{REQ_TAG_LOOKUP}{makernotecanon}) and
+        $$dirInfo{DirLen} > 8)
+    {
+        my $dataPt = $$dirInfo{DataPt};
+        # remove old (unused) trailer
+        $$dataPt =~ s/(II\x2a\0|MM\0\x2a)\0{4,10}$//;
+        # remove TIFF header and append as the Canon makernote trailer
+        # (so offsets will be interpreted correctly)
+        my $val = substr($$dataPt,8) . substr($$dataPt,0,8);
+        $et->FoundTag($Image::ExifTool::Canon::uuid{CMT3}, \$val);
+    }
+    return $et->ProcessTIFF($dirInfo, $tagTablePtr);
+}
+
+#------------------------------------------------------------------------------
+# Process CTMD EXIF information
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessExifInfo($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $start);
+    my $dirEnd = $start + $dirLen;
+    # loop through TIFF-format EXIF/MakerNote records
+    my ($pos, $len, $tag);
+    for ($pos = $start; $pos + 8 < $dirEnd; $pos += $len) {
+        $len = Get32u($dataPt, $pos);
+        $tag = Get32u($dataPt, $pos + 4);
+        # test size/tag for valid ExifInfo (not EXIF in CRM files)
+        last if $len < 8 or $pos + $len > $dirEnd or not $$tagTablePtr{$tag};
+        $et->VerboseDir('ExifInfo', undef, $dirLen) if $pos == $start;
+        $et->HandleTag($tagTablePtr, $tag, undef,
+            DataPt  => $dataPt,
+            Base    => $$dirInfo{Base} + $pos + 8, # base for TIFF pointers
+            DataPos => -($pos + 8), # (relative to Base)
+            Start   => $pos + 8,
+            Size    => $len - 8,
+        );
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Canon Timed MetaData (ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessCTMD($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $verbose = $et->Options('Verbose');
+    my $dirLen = length $$dataPt;
+    my $pos = 0;
+    SetByteOrder('II');
+    while ($pos + 6 < $dirLen) {
+        my $size = Get32u($dataPt, $pos);
+        my $type = Get16u($dataPt, $pos + 4);
+        # what is the meaning of the 6-byte header of these records?:
+        #  type 1 - 00 00 00 01 zz zz - TimeStamp(CR3/CRM); zz=00(CR3),ff(CRM)
+        #  type 3 - 00 00 00 01 zz zz - ? "ff ff ff ff"; zz=00(CR3),ff(CRM)
+        #  type 4 - 00 00 00 01 ff ff - FocalInfo(CR3/CRM)
+        #  type 5 - 00 00 00 01 ff ff - ExposureInfo(CR3/CRM)
+        #  type 6 - 00 04 00 01 ff ff - ? "03 04 00 80 e0 15 ff ff"(CRM) [0x15e0 = ColorTemperature?]
+        #  type 7 - xx yy 00 01 ff ff - ExifIFD + MakerNotes(CR3), ?(CRM); xxyy=0101(CR3),0004(CRM)
+        #  type 8 - 01 yy 00 01 ff ff - MakerNotes(CR3), ?(CRM); yy=01(CR3),04(CRM)
+        #  type 9 - 01 yy 00 01 ff ff - MakerNotes(CR3), ?(CRM); yy=01(CR3),00(CRM)
+        #  type 10- 01 00 00 01 ff ff - ? (CRM)
+        #  type 11- 01 00 00 01 ff ff - ? (CRM)
+        # --> maybe yy == 01 for ExifInfo?
+        $size < 12 and $et->Warn('Short CTMD record'), last;
+        $pos + $size > $dirLen and $et->Warn('Truncated CTMD record'), last;
+        $et->VerboseDir("CTMD type $type", undef, $size - 6);
+        HexDump($dataPt, 6,     # dump 6-byte header
+            Start  => $pos + 6,
+            Addr   => $$dirInfo{Base} + $pos + 6,
+            Prefix => $$et{INDENT},
+        ) if $verbose > 2;
+        if ($$tagTablePtr{$type}) {
+            $et->HandleTag($tagTablePtr, $type, undef,
+                DataPt  => $dataPt,
+                Base    => $$dirInfo{Base},
+                Start   => $pos + 12,
+                Size    => $size - 12,
+            );
+        } elsif ($verbose) {
+            $et->VerboseDump($dataPt, Len=>$size-12, Start=>$pos+12, DataPos=>$$dirInfo{Base});
+        }
+        $pos += $size;
+    }
+    $et->Warn('Error parsing Canon CTMD data', 1) if $pos != $dirLen;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
 # Process a creative filter data
 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
@@ -6762,5 +9807,5 @@
 sub ProcessFilters($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart};
@@ -6768,9 +9813,9 @@
     my $dataPos = $$dirInfo{DataPos} || 0;
     my $end = $pos + $dirLen;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     return 0 if $dirLen < 8;
     my $numFilters = Get32u($dataPt, $pos + 4);
-    $verbose and $exifTool->VerboseDir('Creative Filter', $numFilters);
+    $verbose and $et->VerboseDir('Creative Filter', $numFilters);
     $pos += 8;
     my ($i, $j, $err);
@@ -6780,7 +9825,7 @@
         # 4 bytes - filter data length
         # 4 bytes - number of parameters:
-        # |  4 bytes - paramter ID
-        # |  4 bytes - paramter value count
-        # |  4 bytes * count - paramter values (NC)
+        # |  4 bytes - parameter ID
+        # |  4 bytes - parameter value count
+        # |  4 bytes * count - parameter values (NC)
         $pos + 12 > $end and $err = "Truncated data for filter $i", last;
         my $fnum = Get32u($dataPt, $pos); # (is this an index or an ID?)
@@ -6789,5 +9834,5 @@
         my $nxt = $pos + 4 + $size;
         $nxt > $end and $err = "Invalid size ($size) for filter $i", last;
-        $verbose and $exifTool->VerboseDir("Filter $fnum", $nparm, $size);
+        $verbose and $et->VerboseDir("Filter $fnum", $nparm, $size);
         $pos += 12;
         for ($j=0; $j<$nparm; ++$j) {
@@ -6798,5 +9843,5 @@
             $pos + 4 * $count > $end and $err = "Truncated value for filter $i param $j", last;
             my $val = ReadValue($dataPt, $pos, 'int32s', $count, 4 * $count);
-            $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            $et->HandleTag($tagTablePtr, $tag, $val,
                 DataPt  => $dataPt,
                 DataPos => $dataPos,
@@ -6808,5 +9853,5 @@
         $pos = $nxt;    # step to next filter
     }
-    $err and $exifTool->Warn($err, 1);
+    $err and $et->Warn($err, 1);
     return 1;
 }
@@ -6818,11 +9863,11 @@
 sub WriteCanon($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
-    my $dirData = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
+    my $dirData = Image::ExifTool::Exif::WriteExif($et, $dirInfo, $tagTablePtr);
     # add footer which is written by some Canon models (format of a TIFF header)
     if (defined $dirData and length $dirData and $$dirInfo{Fixup}) {
         $dirData .= GetByteOrder() . Set16u(42) . Set32u(0);
-        $dirInfo->{Fixup}->AddFixup(length($dirData) - 4);
+        $$dirInfo{Fixup}->AddFixup(length($dirData) - 4);
     }
     return $dirData;
@@ -6849,5 +9894,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -6866,5 +9911,5 @@
 =item L<http://homepage3.nifty.com/kamisaka/makernote/makernote_canon.htm>
 
-=item (...plus lots of testing with my 300D and my daughter's A570IS!)
+=item (...plus lots of testing with my 300D, A570IS and G12!)
 
 =back
@@ -6876,7 +9921,8 @@
 figuring out the 20D and 30D FileNumber, Denny Priebe for figuring out a
 couple of 1D tags, and Michael Tiemann, Rainer Honle, Dave Nicholson, Chris
-Huebsch, Ger Vermeulen, Darryl Zurn, D.J. Cristi, Bogdan and Vesa Kivisto for
-decoding a number of new tags.  Also thanks to everyone who made contributions
-to the LensType lookup list or the meanings of other tag values.
+Huebsch, Ger Vermeulen, Darryl Zurn, D.J. Cristi, Bogdan, Vesa Kivisto and
+Kai Harrekilde-Petersen for decoding a number of new tags.  Also thanks to
+everyone who made contributions to the LensType lookup list or the meanings
+of other tag values.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonCustom.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonCustom.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonCustom.pm	(revision 34921)
@@ -20,5 +20,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.40';
+$VERSION = '1.58';
 
 sub ProcessCanonCustom($$$);
@@ -1274,8 +1274,5 @@
             Name => 'ISOExpansion',
             Notes => 'other models',
-            PrintConv => {
-                0 => 'Off',
-                1 => 'On',
-            },
+            PrintConv => \%offOn,
         },
     ],
@@ -1293,15 +1290,25 @@
         },
     },
-    0x0106 => {
+    0x0106 => [{
         Name => 'AEBShotCount',
-        Count => -1,
-        Notes => '1 value for the 1DmkIII, 2 for the 1DmkIV',
-        PrintConv => [{
-            0 => 3,
-            1 => 2,
-            2 => 5,
-            3 => 7,
-        }],
-    },
+        Condition => '$count == 1',
+        Notes => 'one value for some models...',
+        PrintConv => {
+            0 => '3 shots',
+            1 => '2 shots',
+            2 => '5 shots',
+            3 => '7 shots',
+        },
+    },{
+        Name => 'AEBShotCount',
+        Count => 2,
+        Notes => 'two values for others',
+        PrintConv => {
+            '3 0' => '3 shots',
+            '2 1' => '2 shots',
+            '5 2' => '5 shots',
+            '7 3' => '7 shots',
+        },
+    }],
     0x0107 => {
         Name => 'SpotMeterLinkToAFPoint',
@@ -1313,5 +1320,5 @@
     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',
@@ -1320,5 +1327,11 @@
         },
     },
-    0x0109 => {
+    0x0109 => [{ # (1DXmkIII)
+        Name => 'UsableShootingModes',
+        Condition => '$count == 1',
+        Count => 1,
+        PrintConv => 'sprintf("Flags 0x%x",$val)',
+        PrintConvInv => '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+    },{
         Name => 'UsableShootingModes',
         Count => 2,
@@ -1331,8 +1344,14 @@
             '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
         ],
-    },
-    0x010a => {
+    }],
+    0x010a => [{ # (1DXmkIII)
         Name => 'UsableMeteringModes',
-        Count => 2,
+        Condition => '$count == 1',
+        Count => 1,
+        PrintConv => 'sprintf("Flags 0x%x",$val)',
+        PrintConvInv => '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+    },{
+        Name => 'UsableMeteringModes',
+        Count => 2, 
         PrintConv => [
             \%disableEnable,
@@ -1343,5 +1362,5 @@
             '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
         ],
-    },
+    }],
     0x010b => {
         Name => 'ExposureModeInManual',
@@ -1354,6 +1373,7 @@
         },
     },
-    0x010c => {
+    0x010c => [{
         Name => 'ShutterSpeedRange',
+        Condition => '$count == 3',
         Count => 3,
         ValueConv => [
@@ -1377,7 +1397,36 @@
             '$val=~m{([\d./]+)} ? eval $1 : 0',
         ],
-    },
-    0x010d => {
+    },{ # (EOS R)
+        Name => 'ShutterSpeedRange',
+        Condition => '$count == 4',
+        Count => 4,
+        ValueConv => [ # (NC)
+            'exp(-$val/(1600*log(2)))',
+            'exp(-$val/(1600*log(2)))',
+            'exp(-$val/(1600*log(2)))',
+            'exp(-$val/(1600*log(2)))',
+        ],
+        ValueConvInv => [
+            'int(-log($val)*1600*log(2) + 0.5)',
+            'int(-log($val)*1600*log(2) + 0.5)',
+            'int(-log($val)*1600*log(2) + 0.5)',
+            'int(-log($val)*1600*log(2) + 0.5)',
+        ],
+        PrintConv => [ # (NC)
+            '"Manual: Hi " . Image::ExifTool::Exif::PrintExposureTime($val)',
+            '"Lo " . Image::ExifTool::Exif::PrintExposureTime($val)',
+            '"Auto: Hi " . Image::ExifTool::Exif::PrintExposureTime($val)',
+            '"Lo " . Image::ExifTool::Exif::PrintExposureTime($val)',
+        ],
+        PrintConvInv => [
+            '$val=~m{([\d./]+)} ? eval $1 : 0',
+            '$val=~m{([\d./]+)} ? eval $1 : 0',
+            '$val=~m{([\d./]+)} ? eval $1 : 0',
+            '$val=~m{([\d./]+)} ? eval $1 : 0',
+        ],
+    }],
+    0x010d => [{
         Name => 'ApertureRange',
+        Condition => '$count == 3',
         Count => 3,
         ValueConv => [
@@ -1401,5 +1450,33 @@
             '$val=~/([\d.]+)/ ? $1 : 0',
         ],
-    },
+    },{ # (EOS R)
+        Name => 'ApertureRange',
+        Condition => '$count == 4',
+        Count => 4,
+        ValueConv => [ # (NC)
+            'exp($val/2400)',
+            'exp($val/2400)',
+            'exp($val/2400)',
+            'exp($val/2400)',
+        ],
+        ValueConvInv => [
+            'int(log($val)*2400) + 0.5)',
+            'int(log($val)*2400) + 0.5)',
+            'int(log($val)*2400) + 0.5)',
+            'int(log($val)*2400) + 0.5)',
+        ],
+        PrintConv => [ # (NC)
+            'sprintf("Manual: Closed %.2g",$val)',
+            'sprintf("Open %.2g",$val)',
+            'sprintf("Auto: Closed %.2g",$val)',
+            'sprintf("Open %.2g",$val)',
+        ],
+        PrintConvInv => [
+            '$val=~/([\d.]+)/ ? $1 : 0',
+            '$val=~/([\d.]+)/ ? $1 : 0',
+            '$val=~/([\d.]+)/ ? $1 : 0',
+            '$val=~/([\d.]+)/ ? $1 : 0',
+        ],
+    }],
     0x010e => {
         Name => 'ApplyShootingMeteringMode',
@@ -1410,6 +1487,6 @@
         {
             Name => 'FlashSyncSpeedAv',
-            Condition => '$$self{Model} =~ /\b40D\b/',
-            Notes => '40D',
+            Condition => '$$self{Model} =~ /\b(40D|1Ds Mark III)\b/',
+            Notes => '40D and 1Ds Mark III',
             PrintConv => {
                 0 => 'Auto',
@@ -1438,6 +1515,24 @@
         {
             Name => 'FlashSyncSpeedAv',
-            Condition => '$$self{Model} =~ /\b(5D Mark II|500D|T1i|Kiss X3|550D|T2i|Kiss X4)\b/',
-            Notes => '5D Mark II, 500D and 550D',
+            Condition => '$$self{Model} =~ /\bEOS-1Ds? Mark III\b/',
+            Notes => '1D Mark III and 1Ds Mark III',
+            PrintConv => {
+                0 => 'Auto',
+                1 => '1/300 Fixed',
+            },
+        },
+        {
+            Name => 'FlashSyncSpeedAv',
+            Condition => '$$self{Model} =~ /\bEOS-1D Mark IV\b/',
+            Notes => '1D Mark IV',
+            PrintConv => {
+                0 => 'Auto',
+                1 => '1/300-1/60 Auto',
+                2 => '1/300 Fixed',
+            },
+        },
+        {
+            Name => 'FlashSyncSpeedAv',
+            Notes => '5D Mark II, 5D Mark III, 500D, 550D, 600D and 1100D',
             PrintConv => {
                 0 => 'Auto',
@@ -1446,32 +1541,45 @@
             },
         },
-        {
-            Name => 'FlashSyncSpeedAv',
-            Condition => '$$self{Model} =~ /\b(EOS-1D Mark IV)\b/',
-            Notes => '1D Mark IV',
-            PrintConv => {
-                0 => 'Auto',
-                1 => '1/300-1/60 Auto',
-                2 => '1/300 Fixed',
-            },
-        },
-        {
-            Name => 'FlashSyncSpeedAv',
-            Notes => '1D Mark III',
-            PrintConv => {
-                0 => 'Auto',
-                1 => '1/300 Fixed',
-            },
-        },
     ],
     0x0110 => { # new for 1DmkIV
+        Name => 'AEMicroadjustment',
+        Count => 3,
+        PrintConv => [ \%disableEnable ],
+    },
+    0x0111 => { # new for 1DmkIV
         Name => 'FEMicroadjustment',
         Count => 3,
         PrintConv => [ \%disableEnable ],
     },
-    0x0111 => { # new for 1DmkIV
-        Name => 'AEMicroadjustment',
-        Count => 3,
-        PrintConv => [ \%disableEnable ],
+    0x0112 => [{ # (5DS)
+        Name => 'SameExposureForNewAperture',
+        PrintConv => {
+            0 => 'Disable',
+            1 => 'ISO Speed',
+            2 => 'Shutter Speed',
+        },
+    },{ # (EOS R)
+        Name => 'SameExposureForNewAperture',
+        Notes => 'EOS R',
+        PrintConv => {
+            0 => 'Disable',
+            1 => 'ISO Speed',
+            2 => 'ISO Speed/Shutter Speed',
+            3 => 'Shutter Speed',
+        },
+    }],
+    0x0113 => { # (200D)
+        Name => 'ExposureCompAutoCancel',
+        PrintConv => \%enableDisable,
+    },
+    0x0114 => { # (R)
+        Name => 'AELockMeterModeAfterFocus',
+        # metering modes where AE lock after focus applies:
+        PrintConv => { BITMASK => { # (NC)
+            0 => 'Evaluative',
+            1 => 'Partial',
+            2 => 'Spot',
+            3 => 'Center-weighted',
+        }},
     },
     #### 2a) Image
@@ -1487,6 +1595,9 @@
         {
             Name => 'HighISONoiseReduction',
-            Condition => '$$self{Model} =~ /\b(50D|60D|5D Mark II|7D|500D|T1i|Kiss X3|550D|T2i|Kiss X4)\b/',
-            Notes => '50D, 60D, 500D, 550D, 5DmkII and 7D',
+            Condition => q{
+                $$self{Model} =~ /\b(50D|60D|5D Mark II|7D|500D|T1i|Kiss X3|550D|T2i|Kiss X4)\b/ or
+                $$self{Model} =~ /\b(600D|T3i|Kiss X5|1100D|T3|Kiss X50)\b/
+            },
+            Notes => '50D, 60D, 500D, 550D, 600D, 1100D, 5DmkII and 7D',
             PrintConv => {
                 0 => 'Standard',
@@ -1524,4 +1635,5 @@
         },
     ],
+    # 0x0205 - Added in 5DmkII firmware update
     #### 2b) Flash exposure
     0x0304 => {
@@ -1576,4 +1688,30 @@
         },
     ],
+    0x040a => { # new for 5DmkIII
+        Name => 'ViewfinderWarnings',
+        PrintConv => { BITMASK => { #(NC)
+            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
+        Name => 'LVShootingAreaDisplay',
+        PrintConv => {
+            0 => 'Masked',
+            1 => 'Outlined',
+        },
+    },
+    0x040c => { # (7DmkII)
+        Name => 'LVShootingAreaDisplay',
+        PrintConv => {
+            0 => 'Masked',
+            1 => 'Outlined',
+        },
+    },
     #### 3a) Auto focus
     0x0501 => {
@@ -1588,9 +1726,9 @@
         Name => 'AIServoTrackingSensitivity',
         PrintConv => {
-           -2 => 'Slow',
-           -1 => 'Medium Slow',
+           -2 => 'Slow',        # (Locked on -2 for 6D)
+           -1 => 'Medium Slow', # (Locked on -1 for 6D)
             0 => 'Standard',
-            1 => 'Medium Fast',
-            2 => 'Fast',
+            1 => 'Medium Fast', # (Responsive +1 for 6D)
+            2 => 'Fast',        # (Responsive +2 for 6D)
         },
     },
@@ -1656,4 +1794,15 @@
         {
             Name => 'AFPointAreaExpansion',
+            Condition => '$$self{Model} =~ /\b1Ds Mark III\b/',
+            Notes => '1Ds Mark III',
+            PrintConv => {
+                0 => 'Disable',
+                1 => 'Enable (left/right Assist AF points)',
+                2 => 'Enable (surrounding Assist AF points)',
+            },
+        },
+        {
+            Name => 'AFPointAreaExpansion',
+            Notes => 'other models',
             PrintConv => {
                 0 => 'Disable',
@@ -1715,12 +1864,27 @@
         },
     },
-    0x050c => {
-        Name => 'AFPointDisplayDuringFocus',
-        PrintConv => {
-            0 => 'On',
-            1 => 'Off',
-            2 => 'On (when focus achieved)',
-        },
-    },
+    0x050c => [
+        {
+            Name => 'AFPointDisplayDuringFocus',
+            Condition => '$$self{Model} =~ /\b1D\b/',
+            Notes => '1D models',
+            PrintConv => {
+                0 => 'On',
+                1 => 'Off',
+                2 => 'On (when focus achieved)',
+            },
+        },
+        {
+            Name => 'AFPointDisplayDuringFocus',
+            Notes => 'other models', # (7D, 70D, 750D, 760D)
+            PrintConv => {
+                0 => 'Selected (constant)',
+                1 => 'All (constant)',
+                2 => 'Selected (pre-AF, focused)',
+                3 => 'Selected (focused)',
+                4 => 'Disable display',
+            },
+        },
+    ],
     0x050d => {
         Name => 'AFPointBrightness',
@@ -1733,6 +1897,6 @@
         {
             Name => 'AFAssistBeam',
-            Condition => '$$self{Model} =~ /\b1D Mark IV\b/',
-            Notes => '1D Mark IV',
+            Condition => '$$self{Model} =~ /\b(1D Mark IV|6D)\b/',
+            Notes => '1D Mark IV and 6D',
             PrintConv => {
                 0 => 'Emits',
@@ -1771,8 +1935,9 @@
             },
         },
+        # (this is 2 values for 90D,M6mkII, seen: "1046 1046")
     ],
     0x0510 => [ # new for 40D
         {
-            Name => 'VFDisplayIllumination',
+            Name => 'VFDisplayIllumination', # (7D quirk, or decoded incorrectly?)
             Condition => '$$self{Model} =~ /\b7D\b/',
             Notes => '7D',
@@ -1814,6 +1979,11 @@
                 2 => 'Register',
                 3 => 'Select AF-modes',
-            },
-            # must decode 2nd value
+                # also seen: 87 (90D), 1142 (RP)
+            },
+            'sprintf("Flags 0x%x",$val)', # (70D=Manual 1pt,Manual zone,Auto 19pt)
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
         ],
     },
@@ -1836,5 +2006,5 @@
         Name => 'OrientationLinkedAFPoint',
         PrintConv => {
-            0 => 'Same for verical and horizontal',
+            0 => 'Same for vertical and horizontal',
             1 => 'Select different AF points',
         },
@@ -1845,4 +2015,56 @@
             0 => 'Off',
             1 => 'AF point selection',
+        },
+    },
+    0x0518 => { # new for 6D
+        Name => 'AccelerationTracking',
+    },
+    0x0519 => { # new for 6D
+        Name => 'AIServoFirstImagePriority',
+        PrintConv => { #(NC)
+            -1 => 'Release priority',
+            0 => 'Equal priority',
+            1 => 'Focus priority',
+        },
+    },
+    0x051a => { # new for 6D
+        Name => 'AIServoSecondImagePriority',
+        PrintConv => { #(NC)
+            -1 => 'Shooting speed priority',
+            0 => 'Equal priority',
+            1 => 'Focus priority',
+        },
+    },
+    0x051b => { # (70D)
+        Name => 'AFAreaSelectMethod',
+        PrintConv => {
+            0 => 'AF area selection button',
+            1 => 'Main dial',
+        },
+    },
+    0x051c => { # (750D)
+        Name => 'AutoAFPointColorTracking',
+        PrintConv => {
+            0 => 'On-Shot AF only',
+            1 => 'Disable',
+        },
+    },
+    0x051d => { # (750D/760D)
+        Name => 'VFDisplayIllumination',
+        PrintConv => [{
+            0 => 'Auto',
+            1 => 'Enable',
+            2 => 'Disable',
+        },{
+            0 => 'Non-illuminated', #(NC)
+            1 => 'Illuminated', #(NC)
+        }],
+    },
+    0x051e => { # (80D)
+        Name => 'InitialAFPointAIServoAF',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Initial AF point selected',
+            2 => 'Manual AF point',
         },
     },
@@ -1857,5 +2079,43 @@
         },
     },
-    0x0610 => {
+    0x0610 => [{ # (1DXmkIII)
+        Name => 'ContinuousShootingSpeed',
+        Condition => '$count == 6',
+        Count => 6,
+        PrintConv => [
+            \%disableEnable,
+            '"Hi $val"',
+            '"Cont $val"',
+            '"Lo $val"',
+            '"Soft $val"',
+            '"Soft LS $val"',
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+        ],
+    },{ # (1DXmkIII firmware 1.3)
+        Name => 'ContinuousShootingSpeed',
+        Condition => '$count == 5',
+        Count => 5,
+        PrintConv => [
+            '"Hi $val"',
+            '"Cont $val"',
+            '"Lo $val"',
+            '"Soft $val"',
+            '"Soft LS $val"',
+        ],
+        PrintConvInv => [
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+            '$val=~/(\d+)/ ? $1 : 0',
+        ],
+    },{ # others
         Name => 'ContinuousShootingSpeed',
         Count => 3,
@@ -1870,5 +2130,5 @@
             '$val=~/(\d+)/ ? $1 : 0',
         ],
-    },
+    }],
     0x0611 => {
         Name => 'ContinuousShotLimit',
@@ -1883,10 +2143,31 @@
         ],
     },
+    0x0612 => [{ # (1DXmkIII)
+        Name => 'RestrictDriveModes',
+        Condition => '$count == 1',
+        Count => 1,
+        PrintConv => 'sprintf("Flags 0x%x",$val)',
+        PrintConvInv => '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+    },{ # (1DX)
+        Name => 'RestrictDriveModes',
+        Count => 2,
+        PrintConv => [
+            \%disableEnable,
+            'sprintf("Flags 0x%x",$val)', # (Single,Cont Hi,Cont Lo,Timer 10,Timer 2,Silent,Super Hi)
+        ],
+        PrintConvInv => [
+            undef,
+            '$val=~/0x([\dA-F]+)/i ? hex($1) : undef',
+        ],
+    }],
     #### 4a) Operation
     0x0701 => [
         {
             Name => 'Shutter-AELock',
-            Condition => '$$self{Model} =~ /\b(1000D|XS|Kiss F|500D|T1i|Kiss X3|550D|T2i|Kiss X4)\b/',
-            Notes => '500D, 550D and 1000D',
+            Condition => q{
+                $$self{Model} =~ /\b(1000D|XS|Kiss F|500D|T1i|Kiss X3|550D|T2i|Kiss X4)\b/ or
+                $$self{Model} =~ /\b(600D|T3i|Kiss X5|1100D|T3|Kiss X50)\b/
+            },
+            Notes => '500D, 550D, 600D, 1000D and 1100D',
             PrintConv => {
                 0 => 'AF/AE lock',
@@ -1894,4 +2175,15 @@
                 2 => 'AF/AF lock, No AE lock',
                 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',
             },
         },
@@ -1964,6 +2256,6 @@
         {
             Name => 'SetButtonWhenShooting',
-            Condition => '$$self{Model} =~ /\b(450D|XSi|Kiss X2|550D|T2i|Kiss X4)\b/',
-            Notes => '450D and 550D; value of 5 is new for 550D',
+            Condition => '$$self{Model} =~ /\b(450D|XSi|Kiss X2|550D|T2i|Kiss X4|600D|T3i|Kiss X5)\b/',
+            Notes => '450D, 550D and 600D; value of 5 is new for 550D',
             PrintConv => {
                 0 => 'Normal (disabled)',
@@ -1977,4 +2269,17 @@
         {
             Name => 'SetButtonWhenShooting',
+            Condition => '$$self{Model} =~ /\b(1100D|T3|Kiss X50)\b/',
+            Notes => '1100D',
+            PrintConv => {
+                0 => 'Normal (disabled)',
+                1 => 'Image quality',
+                2 => 'Flash exposure compensation',
+                3 => 'LCD monitor On/Off',
+                4 => 'Menu display',
+                5 => 'Depth-of-field preview',
+            },
+        },
+        {
+            Name => 'SetButtonWhenShooting',
             Condition => '$$self{Model} =~ /\b(1000D|XS|Kiss F)\b/',
             Notes => '1000D',
@@ -1999,4 +2304,11 @@
                 5 => 'Disabled',
             },
+        },
+        {
+            Name => 'SetButtonWhenShooting',
+            Notes => '250D',
+            Condition => '$count == 2',
+            # (not sure how to decode this.  seen: "37 0")
+            PrintConv => { },
         },
         {
@@ -2039,14 +2351,19 @@
             0 => 'Rear LCD panel',
             1 => 'LCD monitor',
+            2 => 'Off (disable button)', # (1DX)
         },
     },
     0x0709 => {
         Name => 'LockMicrophoneButton',
-        PrintConv => {
+        PrintConv => [{
             # called "sound" in 1DmkIII manual, and "memo" in 1DmkIV manual
             0 => 'Protect (hold:record memo)',
             1 => 'Record memo (protect:disable)',
             2 => 'Play memo (hold:record memo)', # new with 1DmkIV
-        },
+            3 => 'Rating (protect/memo:disable)', # new with 1DX
+        }],
+        # (not sure what the 2nd number is -- new for 1DX.  Seen a value of 31.
+        # Memo quality may be set to 48kHz or 8kHz through another option that
+        # doesn't seem to be stored separately -- is this it?)
     },
     0x070a => {
@@ -2078,4 +2395,63 @@
         },
     },
+    0x070e => { # new for 1100D
+        Name => 'FlashButtonFunction',
+        PrintConv => {
+            0 => 'Raise built-in flash',
+            1 => 'ISO speed',
+        },
+    },
+    0x070f => { # new for 5DmkIII
+        Name => 'MultiFunctionLock',
+        PrintConv => [
+            { #(NC)
+                0 => 'Off',
+                1 => 'On', # "On (main dial)" for 750D/760D?
+                2 => 'On (quick control dial)', #(NC)
+                3 => 'On (main dial and quick control dial)', #(NC)
+            },
+            { BITMASK => { #(NC)
+                0 => 'Main dial',
+                1 => 'Quick control dial',
+                2 => 'Multi-controller',
+            }},
+        ],
+    },
+    0x0710 => { # (M)
+        Name => 'TrashButtonFunction',
+        PrintConv => {
+            0 => 'Normal (set center AF point)',
+            1 => 'Depth-of-field preview',
+        },
+    },
+    0x0711 => { # (M)
+        Name => 'ShutterReleaseWithoutLens',
+        PrintConv => \%disableEnable,
+    },
+    0x0712 => { # (R)
+        Name => 'ControlRingRotation',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Reversed',
+        },
+    },
+    0x0713 => { # (R)
+        Name => 'FocusRingRotation',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Reversed',
+        },
+    },
+    0x0714 => { # (R)
+        Name => 'RFLensMFFocusRingSensitivity',
+        PrintConv => {
+            0 => 'Varies With Rotation Speed',
+            1 => 'Linked To Rotation Angle',
+        },
+    },
+    0x0715 => { # (R)
+        Name => 'CustomizeDials', # (NC, may be CustomizeM-FnBar)
+        # (too much stuff to decode)
+    },
     #### 4b) Others
     0x080b => [
@@ -2102,5 +2478,33 @@
         {
             Name => 'FocusingScreen',
-            Notes => '1DmkIII and 1DmkIV',
+            Condition => '$$self{Model} =~ /\b6D\b/',
+            Notes => '6D',
+            PrintConv => {
+                0 => 'Eg-A II',
+                1 => 'Eg-D',
+                2 => 'Eg-S',
+            },
+        },
+        {
+            Name => 'FocusingScreen',
+            Condition => '$$self{Model} =~ /\b7D Mark II\b/',
+            Notes => '7D Mark II',
+            PrintConv => {
+                0 => 'Eh-A',
+                1 => 'Eh-S',
+            },
+        },
+        {
+            Name => 'FocusingScreen',
+            Condition => '$$self{Model} =~ /\b1D X\b/',
+            Notes => '1DX',
+            PrintConv => {
+                0 => 'Ec-CV',
+                1 => 'Ec-A,B,D,H,I,L',
+            },
+        },
+        {
+            Name => 'FocusingScreen',
+            Notes => '1DmkIII, 1DSmkIII and 1DmkIV',
             PrintConv => {
                 0 => 'Ec-CIV',
@@ -2111,5 +2515,19 @@
         },
     ],
-    0x080c => {
+    0x080c => [{ # (1DXmkIII)
+        Name => 'TimerLength',
+        Condition => '$count == 3',
+        Count => 3,
+        PrintConv => [
+            '"6 s: $val"',
+            '"16 s: $val"',
+            '"After release: $val"',
+        ],
+        PrintConvInv => [
+            '$val=~/(\d+)$/ ? $1 : 0',
+            '$val=~/(\d+)$/ ? $1 : 0',
+            '$val=~/(\d+)$/ ? $1 : 0',
+        ],
+    },{
         Name => 'TimerLength',
         Count => 4,
@@ -2126,5 +2544,5 @@
             '$val=~/(\d+)$/ ? $1 : 0',
         ],
-    },
+    }],
     0x080d => {
         Name => 'ShortReleaseTimeLag',
@@ -2161,4 +2579,32 @@
         },
     },
+    0x0812 => { # (1DX)
+        Name => 'MemoAudioQuality',
+        PrintConv => {
+            0 => 'High (48 kHz)',
+            1 => 'Low (8 kHz)',
+        },
+    },
+    0x0813 => { # (5DmkIII)
+        Name => 'DefaultEraseOption',
+        PrintConv => {
+            0 => 'Cancel selected',
+            1 => 'Erase selected',
+            2 => 'Erase RAW selected', # (1DXmkIII)
+            3 => 'Erase non-RAW selected', # (1DXmkIII)
+        },
+    },
+    0x0814 => { # (5DS)
+        Name => 'RetractLensOnPowerOff',
+        PrintConv => \%enableDisable,
+    },
+    0x0815 => { # (R)
+        Name => 'AddIPTCInformation',
+        PrintConv => \%disableEnable,
+    },
+    0x0816 => { # (90D,RP)
+        Name => 'AudioCompression',
+        PrintConv => \%enableDisable,
+    }
 );
 
@@ -2181,21 +2627,22 @@
 
 #------------------------------------------------------------------------------
-# Read/Write Canon custom 2 directory (used by 1D Mark III)
+# Read/Write Canon custom 2 directory (new for 1D Mark III)
 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
 # Returns: 1 on success
 sub ProcessCanonCustom2($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $offset = $$dirInfo{DirStart};
     my $size = $$dirInfo{DirLen};
     my $write = $$dirInfo{Write};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $newTags;
 
+    return 0 if $size < 2;
     # first entry in array must be the size
     my $len = Get16u($dataPt, $offset);
     unless ($len == $size and $len >= 8) {
-        $exifTool->Warn("Invalid CanonCustom2 data");
+        $et->Warn('Invalid CanonCustom2 data');
         return 0;
     }
@@ -2203,8 +2650,8 @@
     my $count = Get32u($dataPt, $offset + 4);
     if ($write) {
-        $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
-        $exifTool->VPrint(0, "  Rewriting CanonCustom2\n");
+        $newTags = $et->GetNewTagInfoHash($tagTablePtr);
+        $et->VPrint(0, "  Rewriting CanonCustom2\n");
     } elsif ($verbose) {
-        $exifTool->VerboseDir('CanonCustom2', $count);
+        $et->VerboseDir('CanonCustom2', $count, $len);
     }
     my $pos = $offset + 8;
@@ -2219,7 +2666,11 @@
         $pos += 12;
         my $recPos = $pos;
-        my $recEnd = $pos + $recLen;
+        my $recEnd = $pos + $recLen - 8;
+        if ($recEnd > $end) {
+            $et->Warn("Corrupted CanonCustom2 group $recNum");
+            return 0;
+        }
         if ($verbose and not $write) {
-            $exifTool->VerboseDir("CanonCustom2 group $recNum", $recCount);
+            $et->VerboseDir("CanonCustom2 group $recNum", $recCount, $recLen);
         }
         my ($i, $num, $tag);
@@ -2227,23 +2678,33 @@
             $tag = Get32u($dataPt, $recPos);
             $num = Get32u($dataPt, $recPos + 4);
+            my $nextRec = $recPos + 8 + $num * 4;
+            last if $nextRec > $recEnd;
+            # patch for EOS-1DXmkIII firmware 1.0.0 bug:
+            if ($tag == 0x70c and $num == 0x66 and $nextRec + 8 < $recEnd) {
+                my $tmp = Get32u($dataPt, $nextRec + 4);
+                if ($tmp == 0x70f) {
+                    $et->Warn('Fixed incorrect CanonCustom tag 0x70c size', 1);
+                    ++$num; # (count should be one greater)
+                }
+            }
             $recPos += 8;
-            last if $recPos + $num * 4 > $recEnd;
             my $val = ReadValue($dataPt, $recPos, 'int32s', $num, $num * 4);
             if ($write) {
                 # write new value
                 my $tagInfo = $$newTags{$tag};
-                next unless $tagInfo;
-                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-                next unless Image::ExifTool::IsOverwriting($nvHash, $val);
-                my $newVal = Image::ExifTool::GetNewValues($nvHash);
+                next unless $$newTags{$tag};
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $tag, \$val, undef, $num) or next;
+                my $nvHash = $et->GetNewValueHash($tagInfo) or next;
+                next unless $et->IsOverwriting($nvHash, $val);
+                my $newVal = $et->GetNewValue($nvHash);
                 next unless defined $newVal;    # can't delete from a custom table
                 WriteValue($newVal, 'int32s', $num, $dataPt, $recPos);
-                $exifTool->VerboseValue("- CanonCustom:$$tagInfo{Name}", $val);
-                $exifTool->VerboseValue("+ CanonCustom:$$tagInfo{Name}", $newVal);
-                ++$exifTool->{CHANGED};
+                $et->VerboseValue("- CanonCustom:$$tagInfo{Name}", $val);
+                $et->VerboseValue("+ CanonCustom:$$tagInfo{Name}", $newVal);
+                ++$$et{CHANGED};
             } else {
                 # save extracted tag
                 my $oldInfo = $$tagTablePtr{$tag};
-                $exifTool->HandleTag($tagTablePtr, $tag, $val,
+                $et->HandleTag($tagTablePtr, $tag, $val,
                     Index  => $i,
                     Format => 'int32u',
@@ -2259,8 +2720,14 @@
             }
         }
-        $pos += $recLen - 8;
+        if ($i != $recCount) {
+            $et->Warn('Missing '.($recCount-$i)." entries in CanonCustom2 group $recNum directory", 1);
+        }
+        $pos = $recEnd;
     }
     if ($pos != $end) {
-        $exifTool->Warn('Possibly corrupted CanonCustom2 data');
+        # Note: a firmware bug in the EOS M5 and M6 stores an incorrect
+        # size for the 2nd CanonCustom2 record, so this message is expected
+        # for these models...
+        $et->Warn('Possibly corrupted CanonCustom2 data');
         return 0;
     }
@@ -2274,6 +2741,6 @@
 sub WriteCanonCustom2($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
     my $dataPt = $$dirInfo{DataPt};
     # edit a copy of the custom function 2 data
@@ -2285,5 +2752,5 @@
         Write    => 1,
     );
-    ProcessCanonCustom2($exifTool, \%dirInfo, $tagTablePtr) or return undef;
+    ProcessCanonCustom2($et, \%dirInfo, $tagTablePtr) or return undef;
     return $buff;
 }
@@ -2295,17 +2762,17 @@
 sub ProcessCanonCustom($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $offset = $$dirInfo{DirStart};
     my $size = $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     # first entry in array must be the size
     my $len = Get16u($dataPt,$offset);
-    unless ($len == $size or ($$exifTool{Model}=~/\bD60\b/ and $len+2 == $size)) {
-        $exifTool->Warn("Invalid CanonCustom data");
+    unless ($len == $size or ($$et{Model}=~/\bD60\b/ and $len+2 == $size)) {
+        $et->Warn("Invalid CanonCustom data");
         return 0;
     }
-    $verbose and $exifTool->VerboseDir('CanonCustom', $size/2-1);
+    $verbose and $et->VerboseDir('CanonCustom', $size/2-1);
     my $pos;
     for ($pos=2; $pos<$size; $pos+=2) {
@@ -2314,5 +2781,5 @@
         my $tag = ($val >> 8);
         $val = ($val & 0xff);
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $et->HandleTag($tagTablePtr, $tag, $val,
             Index  => $pos/2-1,
             Format => 'int8u',
@@ -2330,5 +2797,5 @@
 sub CheckCanonCustom($$$)
 {
-    my ($exifTool, $tagInfo, $valPtr) = @_;
+    my ($et, $tagInfo, $valPtr) = @_;
     return Image::ExifTool::CheckValue($valPtr, 'int8u');
 }
@@ -2340,6 +2807,6 @@
 sub WriteCanonCustom($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart} || 0;
@@ -2351,9 +2818,9 @@
     # first entry in array must be the size
     my $len = Get16u($dataPt, 0);
-    unless ($len == $dirLen or ($$exifTool{Model}=~/\bD60\b/ and $len+2 == $dirLen)) {
-        $exifTool->Warn("Invalid CanonCustom data");
+    unless ($len == $dirLen or ($$et{Model}=~/\bD60\b/ and $len+2 == $dirLen)) {
+        $et->Warn("Invalid CanonCustom data");
         return undef;
     }
-    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+    my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
     my $pos;
     for ($pos=2; $pos<$dirLen; $pos+=2) {
@@ -2362,13 +2829,13 @@
         my $tagInfo = $$newTags{$tag};
         next unless $tagInfo;
-        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
+        my $nvHash = $et->GetNewValueHash($tagInfo);
         $val = ($val & 0xff);
-        next unless Image::ExifTool::IsOverwriting($nvHash, $val);
-        my $newVal = Image::ExifTool::GetNewValues($nvHash);
+        next unless $et->IsOverwriting($nvHash, $val);
+        my $newVal = $et->GetNewValue($nvHash);
         next unless defined $newVal;    # can't delete from a custom table
         Set16u(($newVal & 0xff) + ($tag << 8), $dataPt, $pos);
-        $exifTool->VerboseValue("- $dirName:$$tagInfo{Name}", $val);
-        $exifTool->VerboseValue("+ $dirName:$$tagInfo{Name}", $newVal);
-        ++$exifTool->{CHANGED};
+        $et->VerboseValue("- $dirName:$$tagInfo{Name}", $val);
+        $et->VerboseValue("+ $dirName:$$tagInfo{Name}", $newVal);
+        ++$$et{CHANGED};
     }
     return $newData;
@@ -2397,5 +2864,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonRaw.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonRaw.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonRaw.pm	(revision 34921)
@@ -7,5 +7,4 @@
 #               12/02/2003 - P. Harvey Completely reworked and figured out many
 #                            more tags
-#               01/19/2004 - P. Harvey Added CleanRaw()
 #
 # References:   1) http://www.cybercom.net/~dcoffin/dcraw/
@@ -23,5 +22,5 @@
 use Image::ExifTool::Canon;
 
-$VERSION = '1.54';
+$VERSION = '1.58';
 
 sub WriteCRW($$);
@@ -76,7 +75,5 @@
         Name => 'CanonRawMakeModel',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::CanonRaw::MakeModel',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonRaw::MakeModel' },
     },
     0x080b => { Name => 'CanonFirmwareVersion', Writable => 'string[32]' },
@@ -122,14 +119,10 @@
         Name => 'CanonFocalLength',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::FocalLength',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::FocalLength' },
     },
     0x102a => {
         Name => 'CanonShotInfo',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::ShotInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ShotInfo' },
     },
     0x102c => {
@@ -144,7 +137,5 @@
         Name => 'CanonCameraSettings',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::CameraSettings',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CameraSettings' },
     },
     0x1030 => { #4
@@ -159,7 +150,5 @@
         Name => 'SensorInfo',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::SensorInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::SensorInfo' },
     },
     # this tag has only be verified for the 10D in CRW files, but the D30 and D60
@@ -203,7 +192,5 @@
         Name => 'CanonAFInfo',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::AFInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::AFInfo' },
     },
     0x1093 => {
@@ -217,10 +204,5 @@
         Name => 'ColorBalance',
         Writable => 0,
-        SubDirectory => {
-            # this offset is necessary because the table contains short rationals
-            # (4 bytes long) but the first entry is 2 bytes into the table.
-            Start => '2',
-            TagTable => 'Image::ExifTool::Canon::ColorBalance',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::ColorBalance' },
     },
     0x10b5 => { #PH
@@ -247,7 +229,5 @@
         Name => 'ImageFormat',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::CanonRaw::ImageFormat',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonRaw::ImageFormat' },
     },
     0x1804 => { Name => 'RecordID', Writable => 'int32u' }, #3
@@ -332,7 +312,5 @@
         Groups => { 1 => 'CIFF' }, # (only so CIFF shows up in group lists)
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::CanonRaw::ExposureInfo',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonRaw::ExposureInfo' },
     },
     0x1834 => { #PH
@@ -350,7 +328,5 @@
         Name => 'DecoderTable',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::CanonRaw::DecoderTable',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonRaw::DecoderTable' },
     },
     0x183b => { #PH
@@ -371,4 +347,5 @@
     0x2007 => {
         Name => 'JpgFromRaw',
+        Groups => { 2 => 'Preview' },
         Writable => 'resize',  # 'resize' allows this value to change size
         Permanent => 0,
@@ -377,4 +354,5 @@
     0x2008 => {
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
         Writable => 'resize',  # 'resize' allows this value to change size
         WriteCheck => '$self->CheckImage(\$val)',
@@ -636,11 +614,11 @@
 sub ProcessCanonRaw($$$)
 {
-    my ($exifTool, $dirInfo, $rawTagTable) = @_;
+    my ($et, $dirInfo, $rawTagTable) = @_;
     my $blockStart = $$dirInfo{DirStart};
     my $blockSize = $$dirInfo{DirLen};
     my $raf = $$dirInfo{RAF} or return 0;
     my $buff;
-    my $verbose = $exifTool->Options('Verbose');
-    my $buildMakerNotes = $exifTool->Options('MakerNotes');
+    my $verbose = $et->Options('Verbose');
+    my $buildMakerNotes = $et->Options('MakerNotes');
 
     # 4 bytes at end of block give directory position within block
@@ -654,5 +632,5 @@
     $raf->Read($buff, 10 * $entries) == 10 * $entries or return 0;
 
-    $verbose and $exifTool->VerboseDir('CIFF', $entries);
+    $verbose and $et->VerboseDir('CIFF', $entries);
     my $index;
     for ($index=0; $index<$entries; ++$index) {
@@ -663,5 +641,5 @@
         my $ptr = $valuePtr + $blockStart;  # all pointers relative to block start
         if ($tag & 0x8000) {
-            $exifTool->Warn('Bad CRW directory entry');
+            $et->Warn('Bad CRW directory entry');
             return 1;
         }
@@ -669,5 +647,5 @@
         my $tagType = ($tag >> 8) & 0x38;   # get tag type
         my $valueInDir = ($tag & 0x4000);   # flag for value in directory
-        my $tagInfo = $exifTool->GetTagInfo($rawTagTable, $tagID);
+        my $tagInfo = $et->GetTagInfo($rawTagTable, $tagID);
         if (($tagType==0x28 or $tagType==0x30) and not $valueInDir) {
             # this type of tag specifies a raw subdirectory
@@ -686,5 +664,5 @@
             if ($verbose) {
                 my $fakeInfo = { Name => $name, SubDirectory => { } };
-                $exifTool->VerboseInfo($tagID, $fakeInfo,
+                $et->VerboseInfo($tagID, $fakeInfo,
                     'Index'  => $index,
                     'Size'   => $size,
@@ -692,5 +670,5 @@
                 );
             }
-            $exifTool->ProcessDirectory(\%subdirInfo, $rawTagTable);
+            $et->ProcessDirectory(\%subdirInfo, $rawTagTable);
             next;
         }
@@ -706,5 +684,5 @@
         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);
@@ -716,10 +694,10 @@
             if ($size <= 512 or ($verbose > 2 and $size <= 65536)
                 or ($tagInfo and ($$tagInfo{SubDirectory}
-                or grep(/^$$tagInfo{Name}$/i, $exifTool->GetRequestedTags()) )))
+                or grep(/^$$tagInfo{Name}$/i, $et->GetRequestedTags()) )))
             {
                 # read value if size is small or specifically requested
                 # or if this is a SubDirectory
                 unless ($raf->Seek($ptr, 0) and $raf->Read($value, $size) == $size) {
-                    $exifTool->Warn(sprintf("Error reading %d bytes from 0x%x",$size,$ptr));
+                    $et->Warn(sprintf("Error reading %d bytes from 0x%x",$size,$ptr));
                     next;
                 }
@@ -727,8 +705,8 @@
                 $value = "Binary data $size bytes";
                 if ($tagInfo) {
-                    if ($exifTool->Options('Binary') or $verbose) {
+                    if ($et->Options('Binary') or $verbose) {
                         # read the value anyway
                         unless ($raf->Seek($ptr, 0) and $raf->Read($value, $size) == $size) {
-                            $exifTool->Warn(sprintf("Error reading %d bytes from 0x%x",$size,$ptr));
+                            $et->Warn(sprintf("Error reading %d bytes from 0x%x",$size,$ptr));
                             next;
                         }
@@ -752,5 +730,5 @@
             my $val = $value;
             $format and $val = ReadValue(\$val, 0, $format, $count, $size);
-            $exifTool->VerboseInfo($tagID, $tagInfo,
+            $et->VerboseInfo($tagID, $tagInfo,
                 Table   => $rawTagTable,
                 Index   => $index,
@@ -765,5 +743,5 @@
         if ($buildMakerNotes) {
             # build maker notes information if requested
-            BuildMakerNotes($exifTool, $tagID, $tagInfo, \$value, $format, $count);
+            BuildMakerNotes($et, $tagID, $tagInfo, \$value, $format, $count);
         }
         next unless defined $tagInfo;
@@ -795,11 +773,12 @@
                 Nesting  => $$dirInfo{Nesting} + 1,
                 RAF      => $raf,
+                DirName  => $name,
                 Parent   => $$dirInfo{DirName},
             );
             #### eval Validate ($dirData, $subdirStart, $size)
             if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
-                $exifTool->Warn("Invalid $name data");
+                $et->Warn("Invalid $name data");
             } else {
-                $exifTool->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
+                $et->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
             }
         } else {
@@ -807,5 +786,5 @@
             $format and $value = ReadValue(\$value, 0, $format, $count, $size);
             # save the information
-            $exifTool->FoundTag($tagInfo, $value);
+            $et->FoundTag($tagInfo, $value);
             delete $$tagInfo{RawConv} if $delRawConv;
         }
@@ -820,8 +799,8 @@
 sub ProcessCRW($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my ($buff, $sig);
     my $raf = $$dirInfo{RAF};
-    my $buildMakerNotes = $exifTool->Options('MakerNotes');
+    my $buildMakerNotes = $et->Options('MakerNotes');
 
     $raf->Read($buff,2) == 2      or return 0;
@@ -836,8 +815,8 @@
 
     # initialize maker note data if building maker notes
-    $buildMakerNotes and InitMakerNotes($exifTool);
-
-    # set the FileType tag unless already done (ie. APP0 CIFF record in JPEG image)
-    $exifTool->SetFileType();
+    $buildMakerNotes and InitMakerNotes($et);
+
+    # set the FileType tag unless already done (eg. APP0 CIFF record in JPEG image)
+    $et->SetFileType();
 
     # build directory information for main raw directory
@@ -853,15 +832,18 @@
     # process the raw directory
     my $rawTagTable = GetTagTable('Image::ExifTool::CanonRaw::Main');
-    unless ($exifTool->ProcessDirectory(\%dirInfo, $rawTagTable)) {
-        $exifTool->Warn('CRW file format error');
+    my $oldIndent = $$et{INDENT};
+    $$et{INDENT} .= '| ';
+    unless (ProcessCanonRaw($et, \%dirInfo, $rawTagTable)) {
+        $et->Warn('CRW file format error');
     }
+    $$et{INDENT} = $oldIndent;
 
     # finish building maker notes if necessary
-    $buildMakerNotes and SaveMakerNotes($exifTool);
+    $buildMakerNotes and SaveMakerNotes($et);
 
     # process trailers if they exist in CRW file (not in CIFF information!)
-    if ($$exifTool{FILE_TYPE} eq 'CRW') {
+    if ($$et{FILE_TYPE} eq 'CRW') {
         my $trailInfo = Image::ExifTool::IdentifyTrailer($raf);
-        $exifTool->ProcessTrailers($trailInfo) if $trailInfo;
+        $et->ProcessTrailers($trailInfo) if $trailInfo;
     }
 
@@ -896,5 +878,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -911,5 +893,5 @@
 =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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonVRD.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonVRD.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CanonVRD.pm	(revision 34921)
@@ -2,5 +2,5 @@
 # File:         CanonVRD.pm
 #
-# Description:  Read/write Canon VRD information
+# Description:  Read/write Canon VRD and DR4 information
 #
 # Revisions:    2006/10/30 - P. Harvey Created
@@ -10,7 +10,9 @@
 #               2010/06/18 - PH Support variable-length CustomPictureStyle data
 #               2010/09/14 - PH Added r/w support for XMP in VRD
+#               2015/05/16 - PH Added DR4 support (DPP 4.1.50.0)
+#               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)
 #------------------------------------------------------------------------------
 
@@ -20,6 +22,7 @@
 use vars qw($VERSION);
 use Image::ExifTool qw(:DataAccess :Utils);
-
-$VERSION = '1.12';
+use Image::ExifTool::Canon;
+
+$VERSION = '1.33';
 
 sub ProcessCanonVRD($$;$);
@@ -28,4 +31,6 @@
 sub ProcessIHL($$$);
 sub ProcessIHLExif($$$);
+sub ProcessDR4($$;$);
+sub SortDR4($$);
 
 # map for adding directories to VRD
@@ -35,5 +40,25 @@
 );
 
-my %noYes = ( 0 => 'No', 1 => 'Yes' );
+my %noYes = (
+    PrintConvColumns => 2,
+    PrintConv => { 0 => 'No', 1 => 'Yes' },
+);
+
+# DR4 format codes
+my %vrdFormat = (
+    1 => 'int32u',
+    2 => 'string',
+    8 => 'int32u',
+    9 => 'int32s',
+    13 => 'double',
+    33 => 'int32u', # (array)
+    38 => 'double', # (array)
+    # 254 => 'undef', ?
+    255 => 'undef',
+);
+
+# empty VRD header/footer for creating VRD from scratch
+my $blankHeader = "CANON OPTIONAL DATA\0\0\x01\0\0\0\0\0\0";
+my $blankFooter = "CANON OPTIONAL DATA\0" . ("\0" x 42) . "\xff\xd9";
 
 # main tag table blocks in CanonVRD trailer (ref PH)
@@ -43,9 +68,9 @@
     NOTES => q{
         Canon Digital Photo Professional writes VRD (Recipe Data) information as a
-        trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD
-        file.  The tags listed below represent information found in this record. 
-        The complete VRD data record may be accessed as a block using the Extra
-        'CanonVRD' tag, but this tag is not extracted or copied unless specified
-        explicitly.
+        trailer record to JPEG, TIFF, CRW and CR2 images, or as stand-alone VRD or
+        DR4 files.  The tags listed below represent information found in these
+        records.  The complete VRD/DR4 data record may be accessed as a block using
+        the Extra 'CanonVRD' or 'CanonDR4' tag, but this tag is not extracted or
+        copied unless specified explicitly.
     },
     0xffff00f4 => {
@@ -65,4 +90,8 @@
             TagTable => 'Image::ExifTool::XMP::Main',
         },
+    },
+    0xffff00f7 => {
+        Name => 'Edit4Data',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::Edit4' },
     },
 );
@@ -81,5 +110,4 @@
     1 => {
         Name => 'VRDStampTool',
-        # (size is variable, and obtained from int32u at end of last directory)
         Size => 0,      # size is variable, and obtained from int32u at directory start
         SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::StampTool' },
@@ -89,4 +117,17 @@
         Size => undef,  # size is the remaining edit data
         SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::Ver2' },
+    },
+);
+
+# Canon DPP version 4 edit information
+%Image::ExifTool::CanonVRD::Edit4 = (
+    WRITE_PROC => \&ProcessEditData,
+    PROCESS_PROC => \&ProcessEditData,
+    VARS => { ID_LABEL => 'Index' }, # change TagID label in documentation
+    NOTES => 'Canon DPP version 4 edit information.',
+    0 => {
+        Name => 'DR4',
+        Size => undef,  # size is the remaining edit data
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::DR4' },
     },
 );
@@ -110,6 +151,6 @@
             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,
@@ -122,13 +163,15 @@
         # (same size as the PreviewImage with DPP 3.0.2.6)
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
         Binary => 1,
     },
     4 => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         Binary => 1,
     },
     5 => {
         Name => 'RawCodecVersion',
-        ValueConv => '$val =~ s/\0.*//; $val',  # truncate string at null
+        ValueConv => '$val =~ s/\0.*//s; $val',  # truncate string at null
     },
     6 => {
@@ -157,14 +200,14 @@
         DataMember => 'VRDVersion',
         RawConv => '$$self{VRDVersion} = $val',
-        PrintConv => 'sprintf("%.2f", $val / 100)',
-    },
-    # 0x006 related somehow to RGB levels
-    0x008 => {
-        Name => 'WBAdjRGBLevels',
-        Format => 'int16u[3]',
+        PrintConv => '$val =~ s/^(\d)(\d*)(\d)$/$1.$2.$3/; $val',
+    },
+    0x006 => {
+        Name => 'WBAdjRGGBLevels',
+        Format => 'int16u[4]',
     },
     0x018 => {
         Name => 'WhiteBalanceAdj',
         Format => 'int16u',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'Auto',
@@ -185,9 +228,8 @@
     },
     # 0x01c similar to 0x006
-    # 0x01e similar to 0x008
     0x024 => {
         Name => 'WBFineTuneActive',
         Format => 'int16u',
-        PrintConv => \%noYes,
+        %noYes,
     },
     0x028 => {
@@ -227,4 +269,5 @@
         Name => 'ToneCurveProperty',
         Format => 'int16u',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'Shot Settings',
@@ -253,5 +296,5 @@
         Name => 'ToneCurveActive',
         Format => 'int16u',
-        PrintConv => \%noYes,
+        %noYes,
     },
     0x113 => {
@@ -338,5 +381,5 @@
         Name => 'CropActive',
         Format => 'int16u',
-        PrintConv => \%noYes,
+        %noYes,
     },
     0x246 => {
@@ -377,4 +420,6 @@
             10 => '5:4',
             11 => '1:1',
+            12 => 'Circle',
+            65535 => 'Custom',
         },
     },
@@ -422,5 +467,5 @@
         },
     },
-    # (VRD 1.0 edit data ends here -- 0x272 bytes)
+    # (VRD 1.0.0 edit data ends here -- 0x272 bytes)
 );
 
@@ -443,9 +488,11 @@
     FIRST_ENTRY => 0,
     FORMAT => 'int16s',
-    DATAMEMBER => [ 0x58 ], # (required for writable var-format tags)
+    DATAMEMBER => [ 0x58, 0xdc, 0xdf, 0xe0 ], # (required for DataMember and var-format tags)
+    IS_SUBDIR => [ 0xe0 ],
     GROUPS => { 2 => 'Image' },
     NOTES => 'Tags added in DPP version 2.0 and later.',
     0x02 => {
         Name => 'PictureStyle',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'Standard',
@@ -459,15 +506,14 @@
         },
     },
-    0x03 => {
-        Name => 'IsCustomPictureStyle',
-        PrintConv => \%noYes,
-    },
+    0x03 => { Name => 'IsCustomPictureStyle', %noYes },
+    # 0x08: 3
+    # 0x09: 4095
+    # 0x0a: 0
+    # 0x0b: 4095
+    # 0x0c: 0
     0x0d => 'StandardRawColorTone',
     0x0e => 'StandardRawSaturation',
     0x0f => 'StandardRawContrast',
-    0x10 => {
-        Name => 'StandardRawLinear',
-        PrintConv => \%noYes,
-    },
+    0x10 => { Name => 'StandardRawLinear', %noYes },
     0x11 => 'StandardRawSharpness',
     0x12 => 'StandardRawHighlightPoint',
@@ -478,8 +524,5 @@
     0x17 => 'PortraitRawSaturation',
     0x18 => 'PortraitRawContrast',
-    0x19 => {
-        Name => 'PortraitRawLinear',
-        PrintConv => \%noYes,
-    },
+    0x19 => { Name => 'PortraitRawLinear', %noYes },
     0x1a => 'PortraitRawSharpness',
     0x1b => 'PortraitRawHighlightPoint',
@@ -490,8 +533,5 @@
     0x20 => 'LandscapeRawSaturation',
     0x21 => 'LandscapeRawContrast',
-    0x22 => {
-        Name => 'LandscapeRawLinear',
-        PrintConv => \%noYes,
-    },
+    0x22 => { Name => 'LandscapeRawLinear', %noYes },
     0x23 => 'LandscapeRawSharpness',
     0x24 => 'LandscapeRawHighlightPoint',
@@ -502,8 +542,5 @@
     0x29 => 'NeutralRawSaturation',
     0x2a => 'NeutralRawContrast',
-    0x2b => {
-        Name => 'NeutralRawLinear',
-        PrintConv => \%noYes,
-    },
+    0x2b => { Name => 'NeutralRawLinear', %noYes },
     0x2c => 'NeutralRawSharpness',
     0x2d => 'NeutralRawHighlightPoint',
@@ -514,8 +551,5 @@
     0x32 => 'FaithfulRawSaturation',
     0x33 => 'FaithfulRawContrast',
-    0x34 => {
-        Name => 'FaithfulRawLinear',
-        PrintConv => \%noYes,
-    },
+    0x34 => { Name => 'FaithfulRawLinear', %noYes },
     0x35 => 'FaithfulRawSharpness',
     0x36 => 'FaithfulRawHighlightPoint',
@@ -544,8 +578,5 @@
     },
     0x3c => 'MonochromeContrast',
-    0x3d => {
-        Name => 'MonochromeLinear',
-        PrintConv => \%noYes,
-    },
+    0x3d => { Name => 'MonochromeLinear', %noYes },
     0x3e => 'MonochromeSharpness',
     0x3f => 'MonochromeRawHighlightPoint',
@@ -554,9 +585,5 @@
     0x42 => 'MonochromeOutputShadowPoint',
     0x45 => { Name => 'UnknownContrast',            Unknown => 1 },
-    0x46 => {
-        Name => 'UnknownLinear',
-        Unknown => 1,
-        PrintConv => \%noYes,
-    },
+    0x46 => { Name => 'UnknownLinear', %noYes,      Unknown => 1 },
     0x47 => { Name => 'UnknownSharpness',           Unknown => 1 },
     0x48 => { Name => 'UnknownRawHighlightPoint',   Unknown => 1 },
@@ -564,9 +591,8 @@
     0x4a => { Name => 'UnknownOutputHighlightPoint',Unknown => 1 },
     0x4b => { Name => 'UnknownOutputShadowPoint',   Unknown => 1 },
+    0x4c => 'CustomColorTone',
+    0x4d => 'CustomSaturation',
     0x4e => 'CustomContrast',
-    0x4f => {
-        Name => 'CustomLinear',
-        PrintConv => \%noYes,
-    },
+    0x4f => { Name => 'CustomLinear', %noYes },
     0x50 => 'CustomSharpness',
     0x51 => 'CustomRawHighlightPoint',
@@ -582,9 +608,9 @@
         RawConv => 'length($val) == 2 ? undef : $val', # ignore if no data
     },
-    # (VRD 2.0 edit data ends here: 178 bytes, index 0x59)
+    # (VRD 2.0.0 edit data ends here: 178 bytes, index 0x59)
     0x5e => [{
         Name => 'ChrominanceNoiseReduction',
         Condition => '$$self{VRDVersion} < 330',
-        Notes => 'VRDVersion prior to 3.30',
+        Notes => 'VRDVersion prior to 3.3.0',
         PrintConv => {
             0   => 'Off',
@@ -594,5 +620,5 @@
     },{ #1
         Name => 'ChrominanceNoiseReduction',
-        Notes => 'VRDVersion 3.30 or later',
+        Notes => 'VRDVersion 3.3.0 or later',
         PrintHex => 1,
         PrintConvColumns => 4,
@@ -624,5 +650,5 @@
         Name => 'LuminanceNoiseReduction',
         Condition => '$$self{VRDVersion} < 330',
-        Notes => 'VRDVersion prior to 3.30',
+        Notes => 'VRDVersion prior to 3.3.0',
         PrintConv => {
             0   => 'Off',
@@ -632,5 +658,5 @@
     },{ #1
         Name => 'LuminanceNoiseReduction',
-        Notes => 'VRDVersion 3.30 or later',
+        Notes => 'VRDVersion 3.3.0 or later',
         PrintHex => 1,
         PrintConvColumns => 4,
@@ -662,5 +688,5 @@
         Name => 'ChrominanceNR_TIFF_JPEG',
         Condition => '$$self{VRDVersion} < 330',
-        Notes => 'VRDVersion prior to 3.30',
+        Notes => 'VRDVersion prior to 3.3.0',
         PrintConv => {
             0   => 'Off',
@@ -670,5 +696,5 @@
     },{ #1
         Name => 'ChrominanceNR_TIFF_JPEG',
-        Notes => 'VRDVersion 3.30 or later',
+        Notes => 'VRDVersion 3.3.0 or later',
         PrintHex => 1,
         PrintConvColumns => 4,
@@ -697,21 +723,10 @@
         },
     }],
-    # (VRD 3.0 edit data ends here: 196 bytes, index 0x62)
-    0x62 => {
-        Name => 'ChromaticAberrationOn',
-        ValueConv => \%noYes,
-    },
-    0x63 => {
-        Name => 'DistortionCorrectionOn',
-        ValueConv => \%noYes,
-    },
-    0x64 => {
-        Name => 'PeripheralIlluminationOn',
-        ValueConv => \%noYes,
-    },
-    0x65 => {
-        Name => 'ColorBlur',
-        ValueConv => \%noYes,
-    },
+    # 0x61: 1
+    # (VRD 3.0.0 edit data ends here: 196 bytes, index 0x62)
+    0x62 => { Name => 'ChromaticAberrationOn',      %noYes },
+    0x63 => { Name => 'DistortionCorrectionOn',     %noYes },
+    0x64 => { Name => 'PeripheralIlluminationOn',   %noYes },
+    0x65 => { Name => 'ColorBlur',                  %noYes },
     0x66 => {
         Name => 'ChromaticAberration',
@@ -752,9 +767,6 @@
         ValueConvInv => 'int($val * 10 + 0.5)',
     },
-    # (VRD 3.4 edit data ends here: 220 bytes, index 0x6e)
-    0x6e => {
-        Name => 'AutoLightingOptimizerOn',
-        PrintConv => \%noYes,
-    },
+    # (VRD 3.4.0 edit data ends here: 220 bytes, index 0x6e)
+    0x6e => { Name => 'AutoLightingOptimizerOn', %noYes },
     0x6f => {
         Name => 'AutoLightingOptimizer',
@@ -766,5 +778,7 @@
         },
     },
-    # (VRD 3.5 edit data ends here: 232 bytes, index 0x74)
+    # 0x71: 200
+    # 0x73: 100
+    # (VRD 3.5.0 edit data ends here: 232 bytes, index 0x74)
     0x75 => {
         Name => 'StandardRawHighlight',
@@ -858,4 +872,5 @@
         Name => 'CheckMark2',
         Format => 'int16u',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'Clear',
@@ -867,14 +882,591 @@
         },
     },
-    # (VRD 3.8 edit data ends here: 286 bytes, index 0x8f)
+    # (VRD 3.8.0 edit data ends here: 286 bytes, index 0x8f)
     0x90 => {
         Name => 'UnsharpMask',
         PrintConv => { 0 => 'Off', 1 => 'On' },
     },
-    0x92 => 'UnsharpMaskStrength',
-    0x94 => 'UnsharpMaskFineness',
-    0x96 => 'UnsharpMaskThreshold',
-    # (VRD 3.91 edit data ends here: 392 bytes, index 0xc4)
+    0x92 => 'StandardUnsharpMaskStrength',
+    0x94 => 'StandardUnsharpMaskFineness',
+    0x96 => 'StandardUnsharpMaskThreshold',
+    0x98 => 'PortraitUnsharpMaskStrength',
+    0x9a => 'PortraitUnsharpMaskFineness',
+    0x9c => 'PortraitUnsharpMaskThreshold',
+    0x9e => 'LandscapeUnsharpMaskStrength',
+    0xa0 => 'LandscapeUnsharpMaskFineness',
+    0xa2 => 'LandscapeUnsharpMaskThreshold',
+    0xa4 => 'NeutraUnsharpMaskStrength',
+    0xa6 => 'NeutralUnsharpMaskFineness',
+    0xa8 => 'NeutralUnsharpMaskThreshold',
+    0xaa => 'FaithfulUnsharpMaskStrength',
+    0xac => 'FaithfulUnsharpMaskFineness',
+    0xae => 'FaithfulUnsharpMaskThreshold',
+    0xb0 => 'MonochromeUnsharpMaskStrength',
+    0xb2 => 'MonochromeUnsharpMaskFineness',
+    0xb4 => 'MonochromeUnsharpMaskThreshold',
+    0xb6 => 'CustomUnsharpMaskStrength',
+    0xb8 => 'CustomUnsharpMaskFineness',
+    0xba => 'CustomUnsharpMaskThreshold',
+    0xbc => 'CustomDefaultUnsharpStrength',
+    0xbe => 'CustomDefaultUnsharpFineness',
+    0xc0 => 'CustomDefaultUnsharpThreshold',
+    # (VRD 3.9.1 edit data ends here: 392 bytes, index 0xc4)
+    # 0xc9: 3    - some RawSharpness
+    # 0xca: 4095 - some RawHighlightPoint
+    # 0xcb: 0    - some RawShadowPoint
+    # 0xcc: 4095 - some OutputHighlightPoint
+    # 0xcd: 0    - some OutputShadowPoint
+    # 0xd1: 3    - some UnsharpMaskStrength
+    # 0xd3: 7    - some UnsharpMaskFineness
+    # 0xd5: 3,4  - some UnsharpMaskThreshold
+    0xd6 => { Name => 'CropCircleActive', %noYes },
+    0xd7 => 'CropCircleX',
+    0xd8 => 'CropCircleY',
+    0xd9 => 'CropCircleRadius',
+    # 0xda: 0, 1
+    # 0xdb: 100
+    0xdc => {
+        Name => 'DLOOn',
+        DataMember => 'DLOOn',
+        RawConv => '$$self{DLOOn} = $val',
+        %noYes,
+    },
+    0xdd => 'DLOSetting',
+    # (VRD 3.11.0 edit data ends here: 444 bytes, index 0xde)
+    0xde => {
+        Name => 'DLOShootingDistance',
+        Notes => '100% = infinity',
+        RawConv => '$val == 0x7fff ? undef : $val',
+        ValueConv => '1 - $val / 0x400',
+        ValueConvInv => 'int((1 - $val) * 0x400 + 0.5)',
+        PrintConv => 'sprintf("%.0f%%", $val * 100)',
+        PrintConvInv => 'ToFloat($val) / 100',
+    },
+    0xdf => {
+        Name => 'DLODataLength',
+        DataMember => 'DLODataLength',
+        Format => 'int32u',
+        Writable => 0,
+        RawConv => '$$self{DLODataLength} = $val',
+    },
+    0xe0 => { # (yes, this overlaps DLODataLength)
+        Name => 'DLOInfo',
+        # - have seen DLODataLengths of 65536,64869 when DLO is Off, so must test DLOOn flag
+        Condition => '$$self{DLOOn}',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::DLOInfo' },
+        Hook => '$varSize += $$self{DLODataLength} + 0x16',
+    },
+    0xe1 => 'CameraRawColorTone',
+    # (VRD 3.11.2 edit data ends here: 452 bytes, index 0xe2, unless DLO is on)
+    0xe2 => 'CameraRawSaturation',
+    0xe3 => 'CameraRawContrast',
+    0xe4 => { Name => 'CameraRawLinear', %noYes },
+    0xe5 => 'CameraRawSharpness',
+    0xe6 => 'CameraRawHighlightPoint',
+    0xe7 => 'CameraRawShadowPoint',
+    0xe8 => 'CameraRawOutputHighlightPoint',
+    0xe9 => 'CameraRawOutputShadowPoint',
 );
+
+# DLO tags (ref PH)
+%Image::ExifTool::CanonVRD::DLOInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 1,
+    FORMAT => 'int16s',
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'Tags added when DLO (Digital Lens Optimizer) is on.',
+    # 0x01 - seen 3112,3140
+    0x04 => 'DLOSettingApplied',
+    0x05 => {
+        Name => 'DLOVersion', #(NC)
+        Format => 'string[10]',
+    },
+    0x0a => {
+        Name => 'DLOData',
+        LargeTag => 1, # large tag, so avoid storing unnecessarily
+        Notes => 'variable-length Digital Lens Optimizer data, stored in JPEG-like format',
+        Format => 'undef[$$self{DLODataLength}]',
+        Writable => 0,
+        Binary => 1,
+    },
+);
+
+# VRD version 4 tags (ref PH)
+%Image::ExifTool::CanonVRD::DR4 = (
+    PROCESS_PROC => \&ProcessDR4,
+    WRITE_PROC => \&ProcessDR4,
+    WRITABLE => 1,
+    GROUPS => { 2 => 'Image' },
+    VARS => { HEX_ID => 1, SORT_PROC => \&SortDR4 },
+    NOTES => q{
+        Tags written by Canon DPP version 4 in CanonVRD trailers and DR4 files. Each
+        tag has three associated flag words which are stored with the directory
+        entry, some of which are extracted as a separate tag, indicated in the table
+        below by a decimal appended to the tag ID (.0, .1 or .2).
+    },
+    header => {
+        Name => 'DR4Header',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::DR4Header' },
+    },
+    0x10002 => 'Rotation', # left/right rotation 90,180,270
+    0x10003 => 'AngleAdj', # crop angle
+    # 0x10018 - fmt=8: 0
+    # 0x10020 - fmt=2: ''
+    0x10021 => 'CustomPictureStyle', # (string)
+    0x10101 => {
+        Name => 'CheckMark',
+        PrintConv => {
+            0 => 'Clear',
+            1 => 1,
+            2 => 2,
+            3 => 3,
+            4 => 4,
+            5 => 5,
+        },
+    },
+    0x10200 => {
+        Name => 'WorkColorSpace',
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+            3 => 'Wide Gamut RGB',
+            4 => 'Apple RGB',
+            5 => 'ColorMatch RGB',
+        },
+    },
+    # 0x10201 - fmt=9: 0
+    # 0x10f20 - fmt=9: 350
+    0x20001 => 'RawBrightnessAdj',
+    0x20101 => {
+        Name => 'WhiteBalanceAdj',
+        PrintConvColumns => 2,
+        PrintConv => {
+            -1 => 'Manual (Click)',
+            0 => 'Auto',
+            1 => 'Daylight',
+            2 => 'Cloudy',
+            3 => 'Tungsten',
+            4 => 'Fluorescent',
+            5 => 'Flash',
+            8 => 'Shade',
+            9 => 'Kelvin',
+            255 => 'Shot Settings',
+        },
+    },
+    0x20102 => 'WBAdjColorTemp',
+    0x20105 => 'WBAdjMagentaGreen',
+    0x20106 => 'WBAdjBlueAmber',
+    0x20125 => {
+        Name => 'WBAdjRGGBLevels',
+        PrintConv => '$val =~ s/^\d+ //; $val',  # remove first integer (14: what is this for?)
+        PrintConvInv => '"14 $val"',
+    },
+    0x20200 => { Name => 'GammaLinear', %noYes },
+    0x20301 => {
+        Name => 'PictureStyle',
+        PrintHex => 1,
+        PrintConv => {
+            0x81 => 'Standard',
+            0x82 => 'Portrait',
+            0x83 => 'Landscape',
+            0x84 => 'Neutral',
+            0x85 => 'Faithful',
+            0x86 => 'Monochrome',
+            0x87 => 'Auto',
+            0x88 => 'Fine Detail',
+            0xf0 => 'Shot Settings',
+            0xff => 'Custom',
+        },
+    },
+    # 0x20302 - Gamma curve data
+    0x20303 => 'ContrastAdj',
+    0x20304 => 'ColorToneAdj',
+    0x20305 => 'ColorSaturationAdj',
+    0x20306 => {
+        Name => 'MonochromeToningEffect',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Sepia',
+            2 => 'Blue',
+            3 => 'Purple',
+            4 => 'Green',
+        },
+    },
+    0x20307 => {
+        Name => 'MonochromeFilterEffect',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Yellow',
+            2 => 'Orange',
+            3 => 'Red',
+            4 => 'Green',
+        },
+    },
+    0x20308 => 'UnsharpMaskStrength',
+    0x20309 => 'UnsharpMaskFineness',
+    0x2030a => 'UnsharpMaskThreshold',
+    0x2030b => 'ShadowAdj',
+    0x2030c => 'HighlightAdj',
+    0x20310 => {
+        Name => 'SharpnessAdj',
+        PrintConv => {
+            0 => 'Sharpness',
+            1 => 'Unsharp Mask',
+        },
+    },
+   '0x20310.0' => { Name => 'SharpnessAdjOn', %noYes },
+    0x20311 => 'SharpnessStrength',
+    0x20400 => {
+        Name => 'ToneCurve',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::ToneCurve' },
+    },
+   '0x20400.1' => { Name => 'ToneCurveOriginal', %noYes },
+    # 0x20401 - fmt=33 (312 bytes)
+    0x20410 => 'ToneCurveBrightness',
+    0x20411 => 'ToneCurveContrast',
+    0x20500 => {
+        Name => 'AutoLightingOptimizer',
+        PrintConv => {
+            0 => 'Low',
+            1 => 'Standard',
+            2 => 'Strong',
+        },
+    },
+   '0x20500.0' => {
+        Name => 'AutoLightingOptimizerOn',
+        Notes => 'ignored if gamma is linear',
+        %noYes,
+    },
+    # 0x20501 - fmt=13: 0
+    # 0x20502 - fmt=13: 0
+    0x20600 => 'LuminanceNoiseReduction',
+    0x20601 => 'ChrominanceNoiseReduction',
+    # 0x20650 - fmt=9: 0 (JPG images)
+    0x20670 => 'ColorMoireReduction',
+   '0x20670.0' => { Name => 'ColorMoireReductionOn', %noYes },
+    0x20701 => {
+        Name => 'ShootingDistance',
+        Notes => '100% = infinity',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.0f%%", $val * 100)',
+        PrintConvInv => 'ToFloat($val) / 100',
+    },
+    0x20702 => {
+        Name => 'PeripheralIllumination',
+        PrintConv => 'sprintf "%g", $val',
+        PrintConvInv => '$val',
+    },
+   '0x20702.0' => { Name => 'PeripheralIlluminationOn', %noYes },
+    0x20703 => {
+        Name => 'ChromaticAberration',
+        PrintConv => 'sprintf "%g", $val',
+        PrintConvInv => '$val',
+    },
+   '0x20703.0' => { Name => 'ChromaticAberrationOn', %noYes },
+    0x20704 => { Name => 'ColorBlurOn', %noYes },
+    0x20705 => {
+        Name => 'DistortionCorrection',
+        PrintConv => 'sprintf "%g", $val',
+        PrintConvInv => '$val',
+    },
+   '0x20705.0' => { Name => 'DistortionCorrectionOn', %noYes },
+    0x20706 => 'DLOSetting',
+   '0x20706.0' => { Name => 'DLOOn', %noYes },
+    0x20707 => {
+        Name => 'ChromaticAberrationRed',
+        PrintConv => 'sprintf "%g", $val',
+        PrintConvInv => '$val',
+    },
+    0x20708 => {
+        Name => 'ChromaticAberrationBlue',
+        PrintConv => 'sprintf "%g", $val',
+        PrintConvInv => '$val',
+    },
+    0x20709 => {
+        Name => 'DistortionEffect',
+        PrintConv => {
+            0 => 'Shot Settings',
+            1 => 'Emphasize Linearity',
+            2 => 'Emphasize Distance',
+            3 => 'Emphasize Periphery',
+            4 => 'Emphasize Center',
+        },
+    },
+    # 0x20800 - fmt=1: 0
+    # 0x20801 - fmt=1: 0
+    0x2070b => { Name => 'DiffractionCorrectionOn', %noYes },
+    0x20900 => 'ColorHue',
+    0x20901 => 'SaturationAdj',
+    0x20910 => 'RedHSL',
+    0x20911 => 'OrangeHSL',
+    0x20912 => 'YellowHSL',
+    0x20913 => 'GreenHSL',
+    0x20914 => 'AquaHSL',
+    0x20915 => 'BlueHSL',
+    0x20916 => 'PurpleHSL',
+    0x20917 => 'MagentaHSL',
+    0x20a00 => {
+        Name => 'GammaInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::GammaInfo' },
+    },
+    # 0x20a01 - Auto picture style settings
+    # 0x20a02 - Standard picture style settings
+    # 0x20a03 - Portrait picture style settings
+    # 0x20a04 - Landscape picture style settings
+    # 0x20a05 - Neutral picture style settings
+    # 0x20a06 - Faithful picture style settings
+    # 0x20a07 - Monochrome picture style settings
+    # 0x20a08 - (unknown picture style settings)
+    # 0x20a09 - Custom picture style settings
+    # 0x20a20 - Fine Detail picture style settings
+    0x30101 => {
+        Name => 'CropAspectRatio',
+        PrintConv => {
+            0 => 'Free',
+            1 => 'Custom',
+            2 => '1:1',
+            3 => '3:2',
+            4 => '2:3',
+            5 => '4:3',
+            6 => '3:4',
+            7 => '5:4',
+            8 => '4:5',
+            9 => '16:9',
+            10 => '9:16',
+        },
+    },
+    0x30102 => 'CropAspectRatioCustom',
+    # 0x30103 - fmt=33: "0 0 8"
+    0xf0100 => {
+        Name => 'CropInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::CropInfo' },
+    },
+    0xf0500 => {
+        Name => 'CustomPictureStyleData',
+        Binary => 1,
+    },
+    0xf0510 => {
+        Name => 'StampInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::StampInfo' },
+    },
+    0xf0511 => {
+        Name => 'DustInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::CanonVRD::DustInfo' },
+    },
+    0xf0512 => 'LensFocalLength',
+    # 0xf0521 - DLO data
+    # 0xf0520 - DLO data
+    # 0xf0530 - created when dust delete data applied (4 bytes, all zero)
+    # 0xf0600 - fmt=253 (2308 bytes, JPG images)
+    # 0xf0601 - fmt=253 (2308 bytes, JPG images)
+    # 0x1ff52c - values: 129,130,132 (related to custom picture style somehow)
+    # to do:
+    # - find 8-15mm CR2 sample and decode linear distortion effect fine-tune
+);
+
+# Version 4 header information (ref PH)
+%Image::ExifTool::CanonVRD::DR4Header = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    GROUPS => { 2 => 'Image' },
+    # 0 - value: 'IIII' (presumably byte order)
+    # 1 - value: 0x00040004 (currently use this for magic number)
+    # 2 - value: 6
+    3 => {
+        Name => 'DR4CameraModel',
+        Writable => 'int32u',
+        PrintHex => 1,
+        SeparateTable => 'Canon CanonModelID',
+        PrintConv => \%Image::ExifTool::Canon::canonModelID,
+    },
+    # 4 - value: 3
+    # 5 - value: 4
+    # 6 - value: 5
+    # 7 - DR4 directory entry count
+);
+
+# Version 4 RGB tone curve information (ref PH)
+%Image::ExifTool::CanonVRD::ToneCurve = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    GROUPS => { 2 => 'Image' },
+    0x00 => {
+        Name => 'ToneCurveColorSpace',
+        PrintConv => {
+            0 => 'RGB',
+            1 => 'Luminance',
+        },
+    },
+    0x01 => {
+        Name => 'ToneCurveShape',
+        PrintConv => {
+            0 => 'Curve',
+            1 => 'Straight',
+        },
+    },
+    0x03 => { Name => 'ToneCurveInputRange',  Format => 'int32u[2]', Notes => '255 max' },
+    0x05 => { Name => 'ToneCurveOutputRange', Format => 'int32u[2]', Notes => '255 max' },
+    0x07 => {
+        Name => 'RGBCurvePoints',
+        Format => 'int32u[21]',
+        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
+        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
+    },
+    0x0a => 'ToneCurveX',
+    0x0b => 'ToneCurveY',
+    0x2d => {
+        Name => 'RedCurvePoints',
+        Format => 'int32u[21]',
+        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
+        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
+    },
+    0x53 => {
+        Name => 'GreenCurvePoints',
+        Format => 'int32u[21]',
+        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
+        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
+    },
+    0x79 => {
+        Name => 'BlueCurvePoints',
+        Format => 'int32u[21]',
+        PrintConv => 'Image::ExifTool::CanonVRD::ToneCurvePrint($val)',
+        PrintConvInv => 'Image::ExifTool::CanonVRD::ToneCurvePrintInv($val)',
+    },
+);
+
+# Version 4 gamma curve information (ref PH)
+%Image::ExifTool::CanonVRD::GammaInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    FORMAT => 'double',
+    GROUPS => { 2 => 'Image' },
+    0x02 => 'GammaContrast',
+    0x03 => 'GammaColorTone',
+    0x04 => 'GammaSaturation',
+    0x05 => 'GammaUnsharpMaskStrength',
+    0x06 => 'GammaUnsharpMaskFineness',
+    0x07 => 'GammaUnsharpMaskThreshold',
+    0x08 => 'GammaSharpnessStrength',
+    0x09 => 'GammaShadow',
+    0x0a => 'GammaHighlight',
+    # 0x0b-0x10 are the same as first 6 doubles of tag DR4_0x20302
+    # 0x0b - value: 14
+    0x0c => {
+        Name => 'GammaBlackPoint',
+        ValueConv => q{
+            return 0 if $val <= 0;
+            $val = log($val / 4.6875) / log(2) + 1;
+            return abs($val) > 1e-10 ? $val : 0;
+        },
+        ValueConvInv => '$val ? exp(($val - 1) * log(2)) * 4.6876 : 0',
+        PrintConv => 'sprintf("%+.3f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x0d => {
+        Name => 'GammaWhitePoint',
+        ValueConv => q{
+            return $val if $val <= 0;
+            $val = log($val / 4.6875) / log(2) - 11.77109325169954;
+            return abs($val) > 1e-10 ? $val : 0;
+        },
+        ValueConvInv => '$val ? exp(($val + 11.77109325169954) * log(2)) * 4.6875 : 0',
+        PrintConv => 'sprintf("%+.3f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x0e => {
+        Name => 'GammaMidPoint',
+        ValueConv => q{
+            return $val if $val <= 0;
+            $val = log($val / 4.6875) / log(2) - 8;
+            return abs($val) > 1e-10 ? $val : 0;
+        },
+        ValueConvInv => '$val ? exp(($val + 8) * log(2)) * 4.6876 : 0',
+        PrintConv => 'sprintf("%+.3f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x0f => { Name => 'GammaCurveOutputRange', Format => 'double[2]', Notes => '16383 max' },
+);
+
+# Version 4 crop information (ref PH)
+%Image::ExifTool::CanonVRD::CropInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32s',
+    GROUPS => { 2 => 'Image' },
+    0 => { Name => 'CropActive', %noYes },
+    1 => 'CropRotatedOriginalWidth',
+    2 => 'CropRotatedOriginalHeight',
+    3 => 'CropX',
+    4 => 'CropY',
+    5 => 'CropWidth',
+    6 => 'CropHeight',
+    8 => {
+        Name => 'CropRotation',
+        Format => 'double',
+        PrintConv => 'sprintf("%.7g",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0a => 'CropOriginalWidth',
+    0x0b => 'CropOriginalHeight',
+    # 0x0c double - value: 100
+);
+
+# DR4 Stamp Tool tags (ref PH)
+%Image::ExifTool::CanonVRD::StampInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    0x02 => 'StampToolCount',
+);
+
+# DR4 dust delete information (ref PH)
+%Image::ExifTool::CanonVRD::DustInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    0x02 => { Name => 'DustDeleteApplied', %noYes },
+);
+
+#------------------------------------------------------------------------------
+# sort DR4 tag ID's for the documentation
+sub SortDR4($$)
+{
+    my ($a, $b) = @_;
+    my ($aHex, $aDec, $bHex, $bDec);
+    ($aHex, $aDec) = ($1, $2) if $a =~ /^(0x[0-9a-f]+)?\.?(\d*?)$/;
+    ($bHex, $bDec) = ($1, $2) if $b =~ /^(0x[0-9a-f]+)?\.?(\d*?)$/;
+    if ($aHex) {
+        return 1 unless defined $bDec;  # $b is 'header';
+        return hex($aHex) <=> hex($bHex) || $aDec <=> $bDec if $bHex;
+        return hex($aHex) <=> $bDec || 1;
+    } elsif ($bHex) {
+        return -1 unless defined $aDec;
+        return $aDec <=> hex($bHex) || -1;
+    } else {
+        return 1 unless defined $bDec;
+        return -1 unless defined $aDec;
+        return $aDec <=> $bDec;
+    }
+}
 
 #------------------------------------------------------------------------------
@@ -913,6 +1505,6 @@
 sub ProcessEditData($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart};
@@ -920,10 +1512,18 @@
     my $outfile = $$dirInfo{OutFile};
     my $dirLen = $$dirInfo{DirLen};
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
+    my $oldChanged = $$et{CHANGED};
+
+    $et->VerboseDir('VRD Edit Data', 0, $dirLen) unless $outfile;
+
+    if ($outfile) {
+        # make a copy for editing in place
+        my $buff = substr($$dataPt, $pos, $dirLen);
+        $dataPt = $$dirInfo{DataPt} = \$buff;
+        $dataPos += $pos;
+        $pos = $$dirInfo{DirStart} = 0;
+    }
     my $dirEnd = $pos + $dirLen;
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
-    my $oldChanged = $$exifTool{CHANGED};
-
-    $exifTool->VerboseDir('VRD Edit Data', 0, $dirLen);
 
     # loop through all records in the edit data
@@ -935,14 +1535,18 @@
         } else {
             $recLen = Get32u($dataPt, $pos);
+            # (DR4 has a null terminator)
+            last if $recLen == 0 and $pos + 4 == $dirEnd;
         }
         $pos += 4;          # move to start of record
         if ($pos + $recLen > $dirEnd) {
-            $exifTool->Warn('Possibly corrupt CanonVRD Edit record');
+            $et->Warn('Possibly corrupt CanonVRD Edit record');
             $err = 1;
             last;
         }
+        my $saveRecLen = $recLen;
         if ($verbose > 1 and not $outfile) {
-            printf $out "$$exifTool{INDENT}CanonVRD Edit record ($recLen bytes at offset 0x%x)\n",
+            printf $out "$$et{INDENT}CanonVRD Edit record ($recLen bytes at offset 0x%x)\n",
                    $pos + $dataPos;
+            $et->VerboseDump($dataPt, Len => $recLen, Start => $pos, Addr => $pos + $dataPos) if $recNum;
         }
 
@@ -951,56 +1555,71 @@
 
         # process VRD edit information
-        my $subTablePtr = GetTagTable('Image::ExifTool::CanonVRD::Edit');
+        my $subTablePtr = $tagTablePtr;
         my $index;
-        my $editData = substr($$dataPt, $pos, $recLen);
         my %subdirInfo = (
-            DataPt => \$editData,
-            DataPos => $dataPos + $pos,
+            DataPt   => $dataPt,
+            DataPos  => $dataPos,
+            DirStart => $pos,
+            DirLen   => $recLen,
+            OutFile  => $outfile,
         );
-        my $start = 0;
+        my $subStart = 0;
         # loop through various sections of the VRD edit data
         for ($index=0; ; ++$index) {
             my $tagInfo = $$subTablePtr{$index} or last;
-            my $dirLen;
-            my $maxLen = $recLen - $start;
+            my $subLen;
+            my $maxLen = $recLen - $subStart;
             if ($$tagInfo{Size}) {
-                $dirLen = $$tagInfo{Size};
+                $subLen = $$tagInfo{Size};
             } elsif (defined $$tagInfo{Size}) {
-                # get size from int32u at $start
-                last unless $start + 4 <= $recLen;
-                $dirLen = Get32u(\$editData, $start);
-                $start += 4; # skip the length word
+                # get size from int32u at $subStart
+                last unless $subStart + 4 <= $recLen;
+                $subLen = Get32u($dataPt, $subStart + $pos);
+                $subStart += 4; # skip the length word
             } else {
-                $dirLen = $maxLen;
+                $subLen = $maxLen;
             }
-            $dirLen > $maxLen and $dirLen = $maxLen;
-            if ($dirLen) {
-                my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+            $subLen > $maxLen and $subLen = $maxLen;
+            if ($subLen) {
+                my $subTable = GetTagTable($$tagInfo{SubDirectory}{TagTable});
                 my $subName = $$tagInfo{Name};
-                $subdirInfo{DirStart} = $start;
-                $subdirInfo{DirLen} = $dirLen;
+                $subdirInfo{DirStart} = $subStart + $pos;
+                $subdirInfo{DirLen} = $subLen;
                 $subdirInfo{DirName} = $subName;
                 if ($outfile) {
                     # rewrite this section of the VRD edit information
                     $verbose and print $out "  Rewriting Canon $subName\n";
-                    my $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
-                    substr($$dataPt, $pos+$start, $dirLen) = $newVal if $newVal;
+                    my $newVal = $et->WriteDirectory(\%subdirInfo, $subTable);
+                    if ($newVal) {
+                        my $sizeDiff = length($newVal) - $subLen;
+                        substr($$dataPt, $pos+$subStart, $subLen) = $newVal;
+                        if ($sizeDiff) {
+                            $subLen = length $newVal;
+                            $recLen += $sizeDiff;
+                            $dirEnd += $sizeDiff;
+                            $dirLen += $sizeDiff;
+                        }
+                    }
                 } else {
-                    $exifTool->VPrint(0, "$$exifTool{INDENT}$subName (SubDirectory) -->\n");
-                    $exifTool->VerboseDump(\$editData,
-                        Start => $start,
-                        Addr  => $dataPos + $pos + $start,
-                        Len   => $dirLen,
+                    $et->VPrint(0, "$$et{INDENT}$subName (SubDirectory) -->\n");
+                    $et->VerboseDump($dataPt,
+                        Start => $pos + $subStart,
+                        Addr  => $dataPos + $pos + $subStart,
+                        Len   => $subLen,
                     );
                     # extract tags from this section of the VRD edit information
-                    $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
+                    $et->ProcessDirectory(\%subdirInfo, $subTable);
                 }
             }
             # next section starts at the end of this one
-            $start += $dirLen;
+            $subStart += $subLen;
+        }
+        if ($outfile and $saveRecLen ne $recLen) {
+            # update record length if necessary
+            Set32u($recLen, $dataPt, $pos - 4)
         }
     }
     if ($outfile) {
-        return undef if $oldChanged == $$exifTool{CHANGED};
+        return undef if $oldChanged == $$et{CHANGED};
         return substr($$dataPt, $$dirInfo{DirStart}, $dirLen);
     }
@@ -1014,5 +1633,5 @@
 sub ProcessIHL($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos};
@@ -1021,5 +1640,5 @@
     my $dirEnd = $pos + $dirLen;
 
-    $exifTool->VerboseDir('VRD IHL', 0, $dirLen);
+    $et->VerboseDir('VRD IHL', 0, $dirLen);
 
     SetByteOrder('II'); # (make up your mind, Canon!)
@@ -1027,5 +1646,5 @@
         my $hdr = substr($$dataPt, $pos, 48);
         unless ($hdr =~ /^IHL Created Optional Item Data\0\0/) {
-            $exifTool->Warn('Possibly corrupted VRD IHL data');
+            $et->Warn('Possibly corrupted VRD IHL data');
             last;
         }
@@ -1034,9 +1653,9 @@
         my $next = Get32u($dataPt, $pos + 44); # size of complete IHL record
         if ($size > $next or $pos + 48 + $next > $dirEnd) {
-            $exifTool->Warn(sprintf('Bad size for VRD IHL tag 0x%.4x', $tag));
+            $et->Warn(sprintf('Bad size for VRD IHL tag 0x%.4x', $tag));
             last;
         }
         $pos += 48;
-        $exifTool->HandleTag($tagTablePtr, $tag, substr($$dataPt, $pos, $size),
+        $et->HandleTag($tagTablePtr, $tag, substr($$dataPt, $pos, $size),
             DataPt  => $dataPt,
             DataPos => $dataPos,
@@ -1047,6 +1666,6 @@
     }
     return 1;
-}    
-    
+}
+
 #------------------------------------------------------------------------------
 # Process VRD IHL EXIF data
@@ -1055,12 +1674,220 @@
 sub ProcessIHLExif($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $$exifTool{DOC_NUM} = 1;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $$et{DOC_NUM} = 1;
     # the IHL-edited maker notes may look messed up, but the offsets should be OK
-    my $oldFix = $exifTool->Options(FixBase => 0);
-    my $rtnVal = $exifTool->ProcessTIFF($dirInfo, $tagTablePtr);
-    $exifTool->Options(FixBase => $oldFix);
-    delete $$exifTool{DOC_NUM};
+    my $oldFix = $et->Options(FixBase => 0);
+    my $rtnVal = $et->ProcessTIFF($dirInfo, $tagTablePtr);
+    $et->Options(FixBase => $oldFix);
+    delete $$et{DOC_NUM};
     return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Wrap DR4 data with the VRD header/footer and edit record
+# Inputs: 0) DR4 record
+# Returns: VRD[Edit[DR4]] data
+sub WrapDR4($)
+{
+    my $val = shift;
+    my $n = length $val;
+    my $oldOrder = GetByteOrder();
+    SetByteOrder('MM');
+    $val = $blankHeader . "\xff\xff\0\xf7" . Set32u($n+8) . Set32u($n) .
+                $val . "\0\0\0\0" . $blankFooter;
+    # update the new VRD length in the header/footer
+    Set32u($n + 16, \$val, 0x18);  # (extra 16 bytes for the edit record wrapper)
+    Set32u($n + 16, \$val, length($val) - 0x2c);
+    SetByteOrder($oldOrder);
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Read/Write DPP version 4 edit data or DR4 file
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns:
+#   Reading from memory (not RAF and not IsWriting): 1 on success
+#   Editing from memory (not RAF and IsWriting): modified edit data, or undef if nothing changed
+#   Reading file (RAF and not OutFile): 1 if a valid DR4 file, 0 if not
+#   Writing file (RAF and OutFile): 1 if valid DR4 file, 0 if not, -1 on write error
+# (serves me right for not having a consistent interface for the various modes of operation)
+sub ProcessDR4($$;$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access
+    my $dataPt = $$dirInfo{DataPt};
+    my $raf = $$dirInfo{RAF};
+    my $outfile = $$dirInfo{OutFile};
+    my $isWriting = $outfile || $$dirInfo{IsWriting};
+    my $dataPos = $$dirInfo{DataPos} || 0;
+    my $verbose = $et->Options('Verbose');
+    my $unknown = $et->Options('Unknown');
+    my ($pos, $dirLen, $numEntries, $err, $newTags);
+
+    # write CanonDR4 as a block if specified
+    if ($isWriting) {
+        my $nvHash;
+        my $newVal = $et->GetNewValue('CanonDR4', \$nvHash);
+        if ($newVal) {
+            $et->VPrint(0, "  Writing CanonDR4 as a block\n");
+            $$et{DidCanonVRD} = 1;  # set flag so we don't add this twice
+            ++$$et{CHANGED};
+            if ($outfile) {
+                Write($$dirInfo{OutFile}, $newVal) or return -1;
+                return 1;
+            } else {
+                return $newVal;
+            }
+        } elsif (not $dataPt and ($nvHash or $$et{DEL_GROUP}{CanonVRD})) {
+            $et->Error("Can't delete all CanonDR4 information from a DR4 file");
+            return 1;
+        }
+    }
+    if ($dataPt) {
+        $pos = $$dirInfo{DirStart} || 0;
+        $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $pos;
+    } else {
+        # load DR4 file into memory
+        my $buff;
+        $raf->Read($buff, 8) == 8 and $buff eq "IIII\x04\0\x04\0" or return 0;
+        $et->SetFileType();
+        $raf->Seek(0, 2) or return $err = 1;
+        $dirLen = $raf->Tell();
+        $raf->Seek(0, 0) or return $err = 1;
+        $raf->Read($buff, $dirLen) == $dirLen or $err = 1;
+        $err and $et->Warn('Error reading DR4 file'), return 1;
+        $tagTablePtr = GetTagTable('Image::ExifTool::CanonVRD::DR4');
+        $dataPt = \$buff;
+        $pos = 0;
+    }
+    my $dirEnd = $pos + $dirLen;
+
+    if (($$et{TAGS_FROM_FILE} and
+        not $$et{EXCL_TAG_LOOKUP}{canondr4}) or $$et{REQ_TAG_LOOKUP}{canondr4})
+    {
+        # extract CanonDR4 block if copying tags, or if requested
+        $et->FoundTag('CanonDR4', substr($$dataPt, $pos, $dirLen));
+    }
+
+    # version 4 header is 32 bytes (int32u[8])
+    if ($dirLen < 32) {
+        $err = 1;
+    } else {
+        SetByteOrder(substr($$dataPt, $pos, 2)) or $err = 1;
+        # process the DR4 header
+        my %hdrInfo = (
+            DataPt   => $dataPt,
+            DirStart => $pos,
+            DirLen   => 32,
+            DirName  => 'DR4Header',
+        );
+        my $hdrTable = GetTagTable('Image::ExifTool::CanonVRD::DR4Header');
+        if ($outfile) {
+            my $hdr = $et->WriteDirectory(\%hdrInfo, $hdrTable);
+            substr($$dataPt, $pos, 32) = $hdr if $hdr and length $hdr == 32;
+        } else {
+            $et->VerboseDir('DR4Header', undef, 32);
+            $et->ProcessDirectory(\%hdrInfo, $hdrTable);
+        }
+        # number of entries in the DR4 directory
+        $numEntries = Get32u($dataPt, $pos + 28);
+        $err = 1 if $dirLen < 36 + 28 * $numEntries;
+    }
+    $err and $et->Warn('Invalid DR4 directory'), return $outfile ? undef : 0;
+
+    if ($outfile) {
+        $newTags = $et->GetNewTagInfoHash($tagTablePtr);
+    } else {
+        $et->VerboseDir('DR4', $numEntries, $dirLen);
+    }
+
+    my $index;
+    for ($index=0; $index<$numEntries; ++$index) {
+        my ($val, @flg, $i);
+        my $entry = $pos + 36 + 28 * $index;
+        last if $entry + 28 > $dirEnd;
+        my $tag = Get32u($dataPt, $entry);
+        my $fmt = Get32u($dataPt, $entry + 4);
+        $flg[0] = Get32u($dataPt, $entry + 8);
+        $flg[1] = Get32u($dataPt, $entry + 12);
+        $flg[2] = Get32u($dataPt, $entry + 16);
+        my $off = Get32u($dataPt, $entry + 20) + $pos;
+        my $len = Get32u($dataPt, $entry + 24);
+        next if $off + $len >= $dirEnd;
+        my $format = $vrdFormat{$fmt};
+        if (not $format) {
+            $val = unpack 'H*', substr($$dataPt, $off, $len);
+            $format = 'undef';
+        } 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;
+        }
+        if ($outfile) {
+            # write (binary data) subdirectory if it exists
+            my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+            if ($tagInfo and $$tagInfo{SubDirectory}) {
+                my %subdirInfo = (
+                    DataPt   => $dataPt,
+                    DirStart => $off,
+                    DirLen   => $len,
+                    DirName  => $$tagInfo{Name},
+                );
+                my $subTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
+                my $saveChanged = $$et{CHANGED};
+                my $dat = $et->WriteDirectory(\%subdirInfo, $subTablePtr);
+                if (defined $dat and length($dat) == $len) {
+                    substr($$dataPt, $off, $len) = $dat;
+                } else {
+                    $$et{CHANGED} = $saveChanged;   # didn't change anything after all
+                }
+            } else {
+                # loop through main tag and flags (don't yet consider flag 2)
+                for ($i=-1; $i<2; ++$i) {
+                    $tagInfo = $$newTags{$i>=0 ? sprintf('0x%x.%d',$tag,$i) : $tag};
+                    next unless $tagInfo;
+                    if ($i >= 0) {
+                        $off = $entry + 8 + 4 * $i;
+                        $format = 'int32u';
+                        $len = 4;
+                        undef $val;
+                    }
+                    $val = ReadValue($dataPt, $off, $format, undef, $len) unless defined $val;
+                    my $nvHash;
+                    my $newVal = $et->GetNewValue($tagInfo, \$nvHash);
+                    if ($et->IsOverwriting($nvHash, $val) and defined $newVal) {
+                        my $count = int($len / Image::ExifTool::FormatSize($format));
+                        my $rtnVal = WriteValue($newVal, $format, $count, $dataPt, $off);
+                        if (defined $rtnVal) {
+                            $et->VerboseValue("- CanonVRD:$$tagInfo{Name}", $val);
+                            $et->VerboseValue("+ CanonVRD:$$tagInfo{Name}", $newVal);
+                            ++$$et{CHANGED};
+                        }
+                    }
+                }
+            }
+            next;
+        }
+        $et->HandleTag($tagTablePtr, $tag, $val,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Start   => $off,
+            Size    => $len,
+            Index   => $index,
+            Format  => $format,
+            # $flg[0] is on/off flag
+            # $flg[1] "is default" flag?
+            # $flg[2] changed to 0 when some unsharp mask settings were changed
+            Extra   => ", fmt=$fmt flags=" . join(',', @flg),
+        );
+        foreach $i (0..2) {
+            my $flagID = sprintf('0x%x.%d', $tag, $i);
+            $et->HandleTag($tagTablePtr, $flagID, $flg[$i]) if $$tagTablePtr{$flagID};
+        }
+    }
+    return 1 unless $isWriting;
+    return substr($$dataPt, $pos, $dirLen) unless $raf;
+    return 1 if Write($outfile, substr($$dataPt, $pos, $dirLen));
+    return -1;
 }
 
@@ -1071,5 +1898,5 @@
 sub ProcessVRD($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -1077,33 +1904,34 @@
 
     # initialize write directories if necessary
-    $exifTool->InitWriteDirs(\%vrdMap, 'XMP') if $$dirInfo{OutFile};
+    $et->InitWriteDirs(\%vrdMap, 'XMP') if $$dirInfo{OutFile};
 
     if (not $num and $$dirInfo{OutFile}) {
         # create new VRD file from scratch
-        my $newVal = $exifTool->GetNewValues('CanonVRD');
+        my $newVal = $et->GetNewValue('CanonVRD');
         if ($newVal) {
-            $exifTool->VPrint(0, "  Writing CanonVRD as a block\n");
+            $et->VPrint(0, "  Writing CanonVRD as a block\n");
             Write($$dirInfo{OutFile}, $newVal) or return -1;
-            ++$exifTool->{CHANGED};
+            $$et{DidCanonVRD} = 1;
+            ++$$et{CHANGED};
         } else {
             # allow VRD to be created from individual tags
-            if ($$exifTool{ADD_DIRS}{CanonVRD}) {
+            if ($$et{ADD_DIRS}{CanonVRD}) {
                 my $newVal = '';
-                if (ProcessCanonVRD($exifTool, { OutFile => \$newVal }) > 0) {
+                if (ProcessCanonVRD($et, { OutFile => \$newVal }) > 0) {
                     Write($$dirInfo{OutFile}, $newVal) or return -1;
-                    ++$exifTool->{CHANGED};
+                    ++$$et{CHANGED};
                     return 1;
                 }
             }
-            $exifTool->Error('No CanonVRD information to write');
+            $et->Error('No CanonVRD information to write');
         }
     } else {
         $num == 0x1c or return 0;
         $buff =~ /^CANON OPTIONAL DATA\0/ or return 0;
-        $exifTool->SetFileType();
+        $et->SetFileType();
         $$dirInfo{DirName} = 'CanonVRD';    # set directory name for verbose output
-        my $result = ProcessCanonVRD($exifTool, $dirInfo);
+        my $result = ProcessCanonVRD($et, $dirInfo);
         return $result if $result < 0;
-        $result or $exifTool->Warn('Format error in VRD file');
+        $result or $et->Warn('Format error in VRD file');
     }
     return 1;
@@ -1117,101 +1945,176 @@
 sub WriteCanonVRD($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access
-    my $nvHash = $exifTool->GetNewValueHash($Image::ExifTool::Extra{CanonVRD});
-    return undef unless Image::ExifTool::IsOverwriting($nvHash);
-    my $val = Image::ExifTool::GetNewValues($nvHash);
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access
+    my $nvHash = $et->GetNewValueHash($Image::ExifTool::Extra{CanonVRD});
+    my $val = $et->GetNewValue($nvHash);
     $val = '' unless defined $val;
-    ++$exifTool->{CHANGED};
+    return undef unless $et->IsOverwriting($nvHash, $val);
+    ++$$et{CHANGED};
     return $val;
 }
 
 #------------------------------------------------------------------------------
-# Read/write CanonVRD information
+# 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
 # Returns: 1 on success, 0 not valid VRD, or -1 error writing
 # - updates DataPos to point to start of CanonVRD information
-# - updates DirLen to trailer length
+# - updates DirLen to existing trailer length
 sub ProcessCanonVRD($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
     my $offset = $$dirInfo{Offset} || 0;
     my $outfile = $$dirInfo{OutFile};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
-    my ($buff, $footer, $header, $created, $err);
-    my ($blockLen, $blockType, $size, %didDir);
-
-    if (not $raf) {
-        my $vrdPt = $$dirInfo{DataPt};
-        unless ($vrdPt) {
+    my $dataPt = $$dirInfo{DataPt};
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
+    my ($buff, $created, $err, $blockLen, $blockType, %didDir, $fromFile);
+#
+# The CanonVRD trailer has a 0x1c-byte header and a 0x40-byte footer,
+# each beginning with "CANON OPTIONAL DATA\0" and containing an int32u
+# giving the size of the contained data (at byte 0x18 and 0x14 respectively)
+#
+    if ($raf) {
+        $fromFile = 1;
+    } else {
+        unless ($dataPt) {
             return 1 unless $outfile;
             # create blank VRD data from scratch
-            my $blank = "CANON OPTIONAL DATA\0\0\x01\0\0\0\0\0\0" .
-                        "CANON OPTIONAL DATA\0" . ("\0" x 42) . "\xff\xd9";
-            $vrdPt = \$blank;
-            $verbose and printf $out "  Creating CanonVRD trailer\n";
+            my $blank = $blankHeader . $blankFooter;
+            $dataPt = \$blank;
+            $verbose and print $out "  Creating CanonVRD trailer\n";
             $created = 1;
         }
-        $raf = new File::RandomAccess($vrdPt);
+        $raf = new File::RandomAccess($dataPt);
     }
-    # read and validate the trailer footer
-    $raf->Seek(-64-$offset, 2)    or return 0;
-    $raf->Read($footer, 64) == 64 or return 0;
-    $footer =~ /^CANON OPTIONAL DATA\0(.{4})/s or return 0;
-    $size = unpack('N', $1);
-
-    # read and validate the header too
-    # (header is 0x1c bytes and footer is 0x40 bytes)
-    unless (($size & 0x80000000) == 0 and
-            $raf->Seek(-$size-0x5c, 1) and
-            $raf->Read($header, 0x1c) == 0x1c and
-            $header =~ /^CANON OPTIONAL DATA\0/ and
-            $raf->Read($buff, $size) == $size)
+    # read and validate the footer
+    $raf->Seek(-0x40-$offset, 2)    or return 0;
+    $raf->Read($buff, 0x40) == 0x40 or return 0;
+    $buff =~ /^CANON OPTIONAL DATA\0(.{4})/s or return 0;
+    my $dirLen = unpack('N', $1) + 0x5c;  # size including header+footer
+
+    # read and validate the header
+    unless ($dirLen < 0x80000000 and
+            $raf->Seek(-$dirLen, 1) and
+            $raf->Read($buff, 0x1c) == 0x1c and
+            $buff =~ /^CANON OPTIONAL DATA\0/ and
+            $raf->Seek(-0x1c, 1))
     {
-        $exifTool->Warn('Bad CanonVRD trailer');
+        $et->Warn('Bad CanonVRD trailer');
         return 0;
     }
-    # extract CanonVRD block if Binary option set, or if requested
-    if ($exifTool->{OPTIONS}->{Binary} or $exifTool->{REQ_TAG_LOOKUP}->{canonvrd}) {
-        $exifTool->FoundTag('CanonVRD', $header . $buff . $footer);
+    # set variables returned in dirInfo hash
+    $$dirInfo{DataPos} = $raf->Tell();
+    $$dirInfo{DirLen} = $dirLen;
+
+    if ($outfile and ref $outfile eq 'SCALAR' and not length $$outfile) {
+        # write directly to outfile to avoid duplicating data in memory
+        $$outfile = $$dataPt unless $fromFile;
+        # TRICKY! -- copy to outfile memory buffer and edit in place
+        # (so we must disable all Write() calls for this case)
+        $dataPt = $outfile;
     }
-    # set variables returned in dirInfo hash
-    $$dirInfo{DataPos} = $raf->Tell() - $size - 0x1c;
-    $$dirInfo{DirLen} = $size + 0x5c;
+    if ($fromFile or $$dirInfo{DirStart}) {
+        $dataPt = \$buff unless $dataPt;
+        # read VRD data into memory if necessary
+        unless ($raf->Read($$dataPt, $dirLen) == $dirLen) {
+            $$dataPt = '' if $outfile and $outfile eq $dataPt;
+            $et->Warn('Error reading CanonVRD data');
+            return 0;
+        }
+    }
+    # exit quickly if writing and no CanonVRD tags are being edited
+    if ($outfile and not exists $$et{EDIT_DIRS}{CanonVRD}) {
+        print $out "$$et{INDENT}  [nothing changed]\n" if $verbose;
+        return 1 if $outfile eq $dataPt;
+        return Write($outfile, $$dataPt) ? 1 : -1;
+    }
+
+    my $vrdType = 'VRD';
 
     if ($outfile) {
-        $verbose and not $created and printf $out "  Rewriting CanonVRD trailer\n";
+        $verbose and not $created and print $out "  Rewriting CanonVRD trailer\n";
         # delete CanonVRD information if specified
-        if ($exifTool->{DEL_GROUP}->{CanonVRD} or $exifTool->{DEL_GROUP}->{Trailer} or
-            # also delete if writing as a block (will get added back again later)
-            $exifTool->{NEW_VALUE}->{$Image::ExifTool::Extra{CanonVRD}})
-        {
-            if ($exifTool->{FILE_TYPE} eq 'VRD') {
-                my $newVal = $exifTool->GetNewValues('CanonVRD');
+        my $doDel = $$et{DEL_GROUP}{CanonVRD};
+        unless ($doDel) {
+            $doDel = 1 if $$et{DEL_GROUP}{Trailer} and $$et{FILE_TYPE} ne 'VRD';
+            unless ($doDel) {
+                # also delete if writing as a block (will get added back again later)
+                if ($$et{NEW_VALUE}{$Image::ExifTool::Extra{CanonVRD}}) {
+                    # delete if this isn't version 4
+                    $doDel = 1 unless $$dataPt =~ /^.{28}\xff\xff\0\xf7/s;
+                }
+                if ($$et{NEW_VALUE}{$Image::ExifTool::Extra{CanonDR4}} and not $doDel) {
+                    # delete if this is version 4
+                    $doDel = 1 if $$dataPt =~ /^.{28}\xff\xff\0\xf7/s;
+                }
+            }
+        }
+        if ($doDel) {
+            if ($$et{FILE_TYPE} eq 'VRD') {
+                my $newVal = $et->GetNewValue('CanonVRD');
                 if ($newVal) {
-                    $verbose and printf $out "  Writing CanonVRD as a block\n";
-                    Write($outfile, $newVal) or return -1;
-                    ++$exifTool->{CHANGED};
+                    $verbose and print $out "  Writing CanonVRD as a block\n";
+                    if ($outfile eq $dataPt) {
+                        $$outfile = $newVal;
+                    } else {
+                        Write($outfile, $newVal) or return -1;
+                    }
+                    $$et{DidCanonVRD} = 1;
+                    ++$$et{CHANGED};
                 } else {
-                    $exifTool->Error("Can't delete all CanonVRD information from a VRD file");
+                    $et->Error("Can't delete all CanonVRD information from a VRD file");
                 }
             } else {
-                $verbose and printf $out "  Deleting CanonVRD trailer\n";
-                ++$exifTool->{CHANGED};
+                $verbose and print $out "  Deleting CanonVRD trailer\n";
+                $$outfile = '' if $outfile eq $dataPt;
+                ++$$et{CHANGED};
             }
             return 1;
         }
         # write now and return if CanonVRD was set as a block
-        my $val = $exifTool->GetNewValues('CanonVRD');
+        my $val = $et->GetNewValue('CanonVRD');
+        unless ($val) {
+            $val = $et->GetNewValue('CanonDR4');
+            $vrdType = 'DR4' if $val;
+        }
         if ($val) {
-            $verbose and print $out "  Writing CanonVRD as a block\n";
-            Write($outfile, $val) or return -1;
-            ++$exifTool->{CHANGED};
+            $verbose and print $out "  Writing Canon$vrdType as a block\n";
+            # must wrap DR4 data with the VRD header/footer and edit record
+            $val = WrapDR4($val) if $vrdType eq 'DR4';
+            if ($outfile eq $dataPt) {
+                $$outfile = $val;
+            } else {
+                Write($outfile, $val) or return -1;
+            }
+            $$et{DidCanonVRD} = 1;
+            ++$$et{CHANGED};
             return 1;
         }
-    } elsif ($verbose or $exifTool->{HTML_DUMP}) {
-        $exifTool->DumpTrailer($dirInfo) if $$dirInfo{RAF};
+    } elsif ($verbose or $$et{HTML_DUMP}) {
+        $et->DumpTrailer($dirInfo) if $$dirInfo{RAF};
     }
 
@@ -1219,40 +2122,31 @@
 
     # validate VRD trailer and get position and length of edit record
-    SetByteOrder('MM');
-    my $pos = 0;
-    my $vrdPos = $$dirInfo{DataPos} + length($header);
-    my $dataPt = \$buff;
+    SetByteOrder('MM'); # VRD header/footer is big-endian
+    my $pos = 0x1c;     # start at end of header
 
     # loop through the VRD blocks
     for (;;) {
-        if ($pos + 8 > $size) {
-            last if $pos == $size;
-            $blockLen = $size;  # mark as invalid
+        my $end = $dirLen - 0x40;   # end of last VRD block (and start of footer)
+        if ($pos + 8 > $end) {
+            last if $pos == $end;
+            $blockLen = $end;       # mark as invalid
         } else {
             $blockType = Get32u($dataPt, $pos);
             $blockLen = Get32u($dataPt, $pos + 4);
         }
-        $pos += 8;          # move to start of block
-        if ($pos + $blockLen > $size) {
-            $exifTool->Warn('Possibly corrupt CanonVRD block');
+        $vrdType = 'DR4' if $blockType == 0xffff00f7;
+        $pos += 8;  # move to start of block
+        if ($pos + $blockLen > $end) {
+            $et->Warn('Possibly corrupt CanonVRD block');
             last;
         }
         if ($verbose > 1 and not $outfile) {
             printf $out "  CanonVRD block 0x%.8x ($blockLen bytes at offset 0x%x)\n",
-                $blockType, $pos + $vrdPos;
-            if ($verbose > 2) {
-                my %parms = (
-                    Start  => $pos,
-                    Addr   => $pos + $vrdPos,
-                    Out    => $out,
-                    Prefix => $$exifTool{INDENT},
-                );
-                $parms{MaxLen} = $verbose == 3 ? 96 : 2048 if $verbose < 5;
-                Image::ExifTool::HexDump($dataPt, $blockLen, %parms);
-            }
+                $blockType, $pos + $$dirInfo{DataPos};
+            $et->VerboseDump($dataPt, Len => $blockLen, Start => $pos, Addr => $pos + $$dirInfo{DataPos});
         }
         my $tagInfo = $$tagTablePtr{$blockType};
         unless ($tagInfo) {
-            unless ($exifTool->Options('Unknown')) {
+            unless ($et->Options('Unknown')) {
                 $pos += $blockLen;  # step to next block
                 next;
@@ -1266,5 +2160,5 @@
                 Binary      => 1,
             };
-            Image::ExifTool::AddTagToTable($tagTablePtr, $blockType, $tagInfo);
+            AddTagToTable($tagTablePtr, $blockType, $tagInfo);
         }
         if ($$tagInfo{SubDirectory}) {
@@ -1273,5 +2167,5 @@
                 DataPt   => $dataPt,
                 DataLen  => length $$dataPt,
-                DataPos  => $vrdPos,
+                DataPos  => $$dirInfo{DataPos},
                 DirStart => $pos,
                 DirLen   => $blockLen,
@@ -1283,40 +2177,38 @@
                 # set flag indicating we did this directory
                 $didDir{$$tagInfo{Name}} = 1;
-                my $dat;
-                if ($$exifTool{NEW_VALUE}{$tagInfo}) {
+                my ($dat, $diff);
+                if ($$et{NEW_VALUE}{$tagInfo}) {
                     # write as a block
-                    $exifTool->VPrint(0, "Writing $$tagInfo{Name} as a block\n");
-                    $dat = $exifTool->GetNewValues($tagInfo);
+                    $et->VPrint(0, "Writing $$tagInfo{Name} as a block\n");
+                    $dat = $et->GetNewValue($tagInfo);
                     $dat = '' unless defined $dat;
-                    ++$$exifTool{CHANGED};
+                    ++$$et{CHANGED};
                 } else {
-                    $dat = $exifTool->WriteDirectory(\%subdirInfo, $subTablePtr);
+                    $dat = $et->WriteDirectory(\%subdirInfo, $subTablePtr);
                 }
                 # update data with new directory
                 if (defined $dat) {
-                    my $buf2;
-                    if (length $dat or $$exifTool{FILE_TYPE} !~ /^(CRW|VRD)$/) {
+                    if (length $dat or $$et{FILE_TYPE} !~ /^(CRW|VRD)$/) {
                         # replace with new block (updating the block length word)
-                        $buf2 = substr($$dataPt, 0, $pos - 4) . Set32u(length $dat) . $dat;
+                        substr($$dataPt, $pos-4, $blockLen+4) = Set32u(length $dat) . $dat;
                     } else {
                         # remove block totally (CRW/VRD files only)
-                        $buf2 = substr($$dataPt, 0, $pos - 8);
+                        substr($$dataPt, $pos-8, $blockLen+8) = '';
                     }
-                    my $oldBlockEnd = $pos + $blockLen;
-                    $pos = length $$dataPt; # set to start of next block
-                    $buf2 .= substr($$dataPt, $oldBlockEnd);
-                    undef $$dataPt;         # free the memory
-                    $dataPt = \$buf2;
-                    # update the new VRD length in the header/footer
-                    Set32u(length($buf2), \$header, 0x18);
-                    Set32u(length($buf2), \$footer, 0x14);
-                    next;
+                    # make necessary adjustments if block changes length
+                    if (($diff = length($$dataPt) - $dirLen) != 0) {
+                        $pos += $diff;
+                        $dirLen += $diff;
+                        # update the new VRD length in the header/footer
+                        Set32u($dirLen - 0x5c, $dataPt, 0x18);
+                        Set32u($dirLen - 0x5c, $dataPt, $dirLen - 0x2c);
+                    }
                 }
             } else {
                 # extract as a block if requested
-                $exifTool->ProcessDirectory(\%subdirInfo, $subTablePtr);
+                $et->ProcessDirectory(\%subdirInfo, $subTablePtr);
             }
         } else {
-            $exifTool->HandleTag($tagTablePtr, $blockType, substr($$dataPt, $pos, $blockLen));
+            $et->HandleTag($tagTablePtr, $blockType, substr($$dataPt, $pos, $blockLen));
         }
         $pos += $blockLen;  # step to next block
@@ -1324,22 +2216,29 @@
     if ($outfile) {
         # create XMP block if necessary (CRW/VRD files only)
-        if ($$exifTool{ADD_DIRS}{CanonVRD} and not $didDir{XMP}) {
+        if ($$et{ADD_DIRS}{CanonVRD} and not $didDir{XMP}) {
             my $subTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
-            my $dat = $exifTool->WriteDirectory({ Parent => 'CanonVRD' }, $subTablePtr);
+            my $dat = $et->WriteDirectory({ Parent => 'CanonVRD' }, $subTablePtr);
             if ($dat) {
-                $$dataPt .= Set32u(0xffff00f6) . Set32u(length $dat) . $dat;
+                my $blockLen = length $dat;
+                substr($$dataPt, -0x40, 0) = Set32u(0xffff00f6) . Set32u(length $dat) . $dat;
+                $dirLen = length $$dataPt;
                 # update the new VRD length in the header/footer
-                Set32u(length($$dataPt), \$header, 0x18);
-                Set32u(length($$dataPt), \$footer, 0x14);
+                Set32u($dirLen - 0x5c, $dataPt, 0x18);
+                Set32u($dirLen - 0x5c, $dataPt, $dirLen - 0x2c);
             }
         }
         # write CanonVRD trailer unless it is empty
         if (length $$dataPt) {
-            Write($outfile, $header, $$dataPt, $footer) or $err = 1;
+            Write($outfile, $$dataPt) or $err = 1 unless $outfile eq $dataPt;
         } else {
-            $verbose and printf $out "  Deleting CanonVRD trailer\n";
-        }
+            $verbose and print $out "  Deleting CanonVRD trailer\n";
+        }
+    } elsif ($vrdType eq 'VRD' and (($$et{TAGS_FROM_FILE} and
+        not $$et{EXCL_TAG_LOOKUP}{canonvrd}) or $$et{REQ_TAG_LOOKUP}{canonvrd}))
+    {
+        # extract CanonVRD block if copying tags, or if requested (and not DR4 info)
+        $et->FoundTag('CanonVRD', $buff);
     }
-    undef $$dataPt;
+    undef $buff;
     return $err ? -1 : 1;
 }
@@ -1351,5 +2250,5 @@
 =head1 NAME
 
-Image::ExifTool::CanonVRD - Read/write Canon VRD information
+Image::ExifTool::CanonVRD - Read/write Canon VRD and DR4 information
 
 =head1 SYNOPSIS
@@ -1360,11 +2259,11 @@
 
 This module contains definitions required by Image::ExifTool to read and
-write VRD Recipe Data information as written by the Canon Digital Photo
-Professional software.  This information is written to VRD files, and as a
-trailer in JPEG, CRW, CR2 and TIFF images.
+write VRD and DR4 Recipe Data information as written by the Canon Digital
+Photo Professional software.  This information is written to VRD and DR4
+files, and as a trailer in JPEG, CRW, CR2 and TIFF images.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CaptureOne.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CaptureOne.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/CaptureOne.pm	(revision 34921)
@@ -18,5 +18,5 @@
 use Image::ExifTool::ZIP;
 
-$VERSION = '1.02';
+$VERSION = '1.04';
 
 # CaptureOne COS XML tags
@@ -34,7 +34,9 @@
 # Inputs: 0) attribute list ref, 1) attr hash ref,
 #         2) property name ref, 3) property value ref
+# Returns: true if value was changed
 sub HandleCOSAttrs($$$$)
 {
     my ($attrList, $attrs, $prop, $valPt) = @_;
+    my $changed;
     if (not length $$valPt and defined $$attrs{K} and defined $$attrs{V}) {
         $$prop = $$attrs{K};
@@ -51,5 +53,7 @@
             }
         }
-    }
+        $changed = 1;
+    }
+    return $changed;
 }
 
@@ -62,9 +66,9 @@
 sub FoundCOS($$$$;$)
 {
-    my ($exifTool, $tagTablePtr, $props, $val, $attrs) = @_;
+    my ($et, $tagTablePtr, $props, $val, $attrs) = @_;
 
     my $tag = $$props[-1];
     unless ($$tagTablePtr{$tag}) {
-        $exifTool->VPrint(0, "  | [adding $tag]\n");
+        $et->VPrint(0, "  | [adding $tag]\n");
         my $name = ucfirst $tag;
         $name =~ tr/-_a-zA-Z0-9//dc;
@@ -78,11 +82,11 @@
             $tagInfo{PrintConv} = '$self->ConvertDateTime($val)';
         }
-        Image::ExifTool::AddTagToTable($tagTablePtr, $tag, \%tagInfo);
+        AddTagToTable($tagTablePtr, $tag, \%tagInfo);
     }
     # convert from UTF8 to ExifTool Charset
-    $val = $exifTool->Decode($val, "UTF8");
+    $val = $et->Decode($val, "UTF8");
     # un-escape XML character entities
     $val = Image::ExifTool::XMP::UnescapeXML($val);
-    $exifTool->HandleTag($tagTablePtr, $tag, $val);
+    $et->HandleTag($tagTablePtr, $tag, $val);
     return 0;
 }
@@ -94,5 +98,5 @@
 sub ProcessCOS($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
 
     # process using XMP module, but override handling of attributes and tags
@@ -102,5 +106,5 @@
     };
     my $tagTablePtr = GetTagTable('Image::ExifTool::CaptureOne::Main');
-    my $success = $exifTool->ProcessDirectory($dirInfo, $tagTablePtr);
+    my $success = $et->ProcessDirectory($dirInfo, $tagTablePtr);
     delete $$dirInfo{XMLParseArgs};
     return $success;
@@ -116,9 +120,9 @@
 sub ProcessEIP($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $zip = $$dirInfo{ZIP};
     my ($file, $buff, $status, $member, %parseFile);
 
-    $exifTool->SetFileType('EIP');
+    $et->SetFileType('EIP');
 
     # must catch all Archive::Zip warnings
@@ -156,8 +160,8 @@
         $file = $member->fileName();
         next unless defined $file;
-        $exifTool->VPrint(0, "File: $file\n");
+        $et->VPrint(0, "File: $file\n");
         # set the document number and extract ZIP tags
-        $$exifTool{DOC_NUM} = ++$docNum;
-        Image::ExifTool::ZIP::HandleMember($exifTool, $member);
+        $$et{DOC_NUM} = ++$docNum;
+        Image::ExifTool::ZIP::HandleMember($et, $member);
         if (%parseFile) {
             next unless $parseFile{$file};
@@ -170,5 +174,5 @@
         # Note: this could use a LOT of memory here for RAW images...
         ($buff, $status) = $zip->contents($member);
-        $status and $exifTool->Warn("Error extracting $file"), next;
+        $status and $et->Warn("Error extracting $file"), next;
         if ($file =~ /\.cos$/i) {
             # process Capture One Settings files
@@ -178,16 +182,16 @@
                 DataLen => length $buff,
             );
-            ProcessCOS($exifTool, \%dirInfo);
+            ProcessCOS($et, \%dirInfo);
         } else {
             # set HtmlDump error if necessary because it doesn't work with embedded files
-            if ($$exifTool{HTML_DUMP}) {
-                $$exifTool{HTML_DUMP}{Error} = "Sorry, can't dump images embedded in ZIP files";
+            if ($$et{HTML_DUMP}) {
+                $$et{HTML_DUMP}{Error} = "Sorry, can't dump images embedded in ZIP files";
             }
             # process IIQ, JPEG and TIFF images
-            $exifTool->ExtractInfo(\$buff, { ReEntry => 1 });
+            $et->ExtractInfo(\$buff, { ReEntry => 1 });
         }
         undef $buff;    # (free memory now)
     }
-    delete $$exifTool{DOC_NUM};
+    delete $$et{DOC_NUM};
     return 1;
 }
@@ -218,5 +222,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Casio.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Casio.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Casio.pm	(revision 34921)
@@ -10,6 +10,7 @@
 #               2) Joachim Loehr private communication
 #               3) http://homepage3.nifty.com/kamisaka/makernote/makernote_casio.htm
-#               4) http://www.gvsoft.homedns.org/exif/makernote-casio.html
+#               4) http://gvsoft.homedns.org/exif/makernote-casio-type1.html
 #               5) Robert Chi private communication (EX-F1)
+#               6) https://exiftool.org/forum/index.php/topic,3701.html
 #               JD) Jens Duttke private communication
 #------------------------------------------------------------------------------
@@ -21,5 +22,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.32';
+$VERSION = '1.38';
 
 # older Casio maker notes (ref 1)
@@ -236,7 +237,7 @@
             5 => 'Far Left/Right of Center',
             6 => 'Far Left/Right of Center/Bottom',
-            7 => 'Top Near-Left',
+            7 => 'Top Near-left',
             8 => 'Near Upper/Left',
-            9 => 'Top Near-Right',
+            9 => 'Top Near-right',
             10 => 'Top Left',
             11 => 'Top Center',
@@ -291,4 +292,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -300,4 +302,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -401,4 +404,5 @@
         # (nasty that they double-reference the image!)
         %Image::ExifTool::previewImageTagInfo,
+        Groups => { 2 => 'Preview' },
     },
     0x2001 => { #PH
@@ -442,4 +446,5 @@
            0 => 'Manual',
            1 => 'Daylight', #3
+           2 => 'Cloudy', #PH (EX-ZR20, NC)
            3 => 'Shade', #3
            4 => 'Flash?',
@@ -487,4 +492,5 @@
             # have also seen '1 1 1', '2 2 4', '4 3 3', '4 4 4'
             # '0 0 14' and '0 0 42' - premium auto night shot (EX-Z2300)
+            # and '0 0 2' for Art HDR
         },
     },
@@ -571,12 +577,993 @@
         Writable => 'string',
     },
-    0x3007 => {
-        Name => 'BestShotMode',
-        Writable => 'int16u',
-        # unfortunately these numbers are model-dependent,
+    # unfortunately the BestShotMode numbers are model-dependent - PH
+    #http://search.casio-intl.com/search?q=BEST+SHOT+sets+up+the+camera+CASIO+EX+ZR100+BEST+SHOT&btnG=Search&output=xml_no_dtd&oe=UTF-8&ie=UTF-8&site=casio-intl_com&client=search_casio-intl_com&proxystylesheet=search_casio-intl_com
+    # NOTE: BestShotMode is not used unless RecordMode is "Best Shot"
+    0x3007 => [{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-FC100"',
+        Notes => 'EX-FC100',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Portrait',
+            3 => 'Scenery',
+            4 => 'Portrait with Scenery',
+            5 => 'Children',
+            6 => 'Sports',
+            7 => 'Pet',
+            8 => 'Flower',
+            9 => 'Natural Green',
+            10 => 'Autumn Leaves',
+            11 => 'Sundown',
+            12 => 'High Speed Night Scene',
+            13 => 'Night Scene Portrait',
+            14 => 'Fireworks',
+            15 => 'High Speed Anti Shake',
+            16 => 'Multi-motion Image',
+            17 => 'High Speed Best Selection',
+            18 => 'Move Out CS',
+            19 => 'Move In CS',
+            20 => 'Pre-record Movie',
+            21 => 'For YouTube',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-FC150"',
+        Notes => 'EX-FC150',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Expression CS',
+            3 => 'Baby CS',
+            4 => 'Child CS',
+            5 => 'Pet CS',
+            6 => 'Sports CS',
+            7 => 'Child High Speed Movie',
+            8 => 'Pet High Speed Movie',
+            9 => 'Sports High Speed Movie',
+            10 => 'Lag Correction',
+            11 => 'High Speed Lighting',
+            12 => 'High Speed Night Scene',
+            13 => 'High Speed Night Scene and Portrait',
+            14 => 'High Speed Anti Shake',
+            15 => 'High Speed Best Selection',
+            16 => 'Portrait',
+            17 => 'Scenery',
+            18 => 'Portrait With Scenery',
+            19 => 'Flower',
+            20 => 'Natural Green',
+            21 => 'Autumn Leaves',
+            22 => 'Sundown',
+            23 => 'Fireworks',
+            24 => 'Multi-motion Image',
+            25 => 'Move Out CS',
+            26 => 'Move In CS',
+            27 => 'Pre-record Movie',
+            28 => 'For YouTube',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-FC200S"',
+        Notes => 'EX-FC200S',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Slow Motion Swing (behind)',
+            2 => 'Slow Motion Swing (front)',
+            3 => 'Self Slow Motion (behind)',
+            4 => 'Self Slow Motion (front)',
+            5 => 'Swing Burst',
+            6 => 'HDR',
+            7 => 'HDR Art',
+            8 => 'High Speed Night Scene',
+            9 => 'High Speed Night Scene and Portrait',
+            10 => 'High Speed Anti Shake',
+            11 => 'Multi SR Zoom',
+            12 => 'Blurred Background',
+            13 => 'Wide Shot',
+            14 => 'Slide Panorama',
+            15 => 'High Speed Best Selection',
+            16 => 'Lag Correction',
+            17 => 'High Speed CS',
+            18 => 'Child CS',
+            19 => 'Pet CS',
+            20 => 'Sports CS',
+            21 => 'Child High Speed Movie',
+            22 => 'Pet High Speed Movie',
+            23 => 'Sports High Speed Movie',
+            24 => 'Portrait',
+            25 => 'Scenery',
+            26 => 'Portrait with Scenery',
+            27 => 'Children',
+            28 => 'Sports',
+            29 => 'Candlelight Portrait',
+            30 => 'Party',
+            31 => 'Pet',
+            32 => 'Flower',
+            33 => 'Natural Green',
+            34 => 'Autumn Leaves',
+            35 => 'Soft Flowing Water',
+            36 => 'Splashing Water',
+            37 => 'Sundown',
+            38 => 'Fireworks',
+            39 => 'Food',
+            40 => 'Text',
+            41 => 'Collection',
+            42 => 'Auction',
+            43 => 'Pre-record Movie',
+            44 => 'For YouTube',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-FH100"',
+        Notes => 'EX-FH100',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Expression CS',
+            2 => 'Baby CS',
+            3 => 'Child CS',
+            4 => 'Pet CS',
+            5 => 'Sports CS',
+            6 => 'Child High Speed Movie',
+            7 => 'Pet High Speed Movie',
+            8 => 'Sports High Speed Movie',
+            9 => 'Lag Correction',
+            10 => 'High Speed Lighting',
+            11 => 'High Speed Night Scene',
+            12 => 'High Speed Night Scene and Portrait',
+            13 => 'High Speed Anti Shake',
+            14 => 'High Speed Best Selection',
+            15 => 'Portrait',
+            16 => 'Scenery',
+            17 => 'Portrait With Scenery',
+            18 => 'Flower',
+            19 => 'Natural Green',
+            20 => 'Autumn Leaves',
+            21 => 'Sundown',
+            22 => 'Fireworks',
+            23 => 'Multi-motion Image',
+            24 => 'Move Out CS',
+            25 => 'Move In CS',
+            26 => 'Pre-record Movie',
+            27 => 'For YouTube',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-G1"',
+        Notes => 'EX-G1',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Auto Best Shot',
+            3 => 'Dynamic Photo',
+            4 => 'Interval Snapshot',
+            5 => 'Interval Movie',
+            6 => 'Portrait',
+            7 => 'Scenery',
+            8 => 'Portrait with Scenery',
+            9 => 'Underwater',
+            10 => 'Beach',
+            11 => 'Snow',
+            12 => 'Children',
+            13 => 'Sports',
+            14 => 'Pet',
+            15 => 'Flower',
+            16 => 'Sundown',
+            17 => 'Night Scene',
+            18 => 'Night Scene Portrait',
+            19 => 'Fireworks',
+            20 => 'Food',
+            21 => 'For eBay',
+            22 => 'Multi-motion Image',
+            23 => 'Pre-record Movie',
+            24 => 'For YouTube',
+            25 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-S10"',
+        Notes => 'EX-S10',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Portrait',
+            3 => 'Scenery',
+            4 => 'Portrait with Scenery',
+            5 => 'Self-portrait (1 person)',
+            6 => 'Self-portrait (2 people)',
+            7 => 'Children',
+            8 => 'Sports',
+            9 => 'Candlelight Portrait',
+            10 => 'Party',
+            11 => 'Pet',
+            12 => 'Flower',
+            13 => 'Natural Green',
+            14 => 'Autumn Leaves',
+            15 => 'Soft Flowing Water',
+            16 => 'Splashing Water',
+            17 => 'Sundown',
+            18 => 'Night Scene',
+            19 => 'Night Scene Portrait',
+            20 => 'Fireworks',
+            21 => 'Food',
+            22 => 'Text',
+            23 => 'Collection',
+            24 => 'Auction',
+            25 => 'Backlight',
+            26 => 'Anti Shake',
+            27 => 'High Sensitivity',
+            28 => 'Underwater',
+            29 => 'Monochrome',
+            30 => 'Retro',
+            31 => 'Business Cards',
+            32 => 'White Board',
+            33 => 'Silent',
+            34 => 'Pre-record Movie',
+            35 => 'For YouTube',
+            36 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-S880"',
+        Notes => 'EX-S880',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Portrait',
+            3 => 'Scenery',
+            4 => 'Portrait with Scenery',
+            5 => 'Children',
+            6 => 'Sports',
+            7 => 'Candlelight Portrait',
+            8 => 'Party',
+            9 => 'Pet',
+            10 => 'Flower',
+            11 => 'Natural Green',
+            12 => 'Autumn Leaves',
+            13 => 'Soft Flowing Water', # (wrong in documentation)
+            14 => 'Splashing Water',
+            15 => 'Sundown',
+            16 => 'Night Scene',
+            17 => 'Night Scene Portrait',
+            18 => 'Fireworks',
+            19 => 'Food',
+            20 => 'Text',
+            21 => 'Collection',
+            22 => 'Auction',
+            23 => 'Backlight',
+            24 => 'Anti Shake',
+            25 => 'High Sensitivity',
+            26 => 'Monochrome',
+            27 => 'Retro',
+            28 => 'Twilight',
+            29 => 'Layout (2 images)',
+            30 => 'Layout (3 images)',
+            31 => 'Auto Framing',
+            32 => 'Old Photo',
+            33 => 'Business Cards',
+            34 => 'White Board',
+            35 => 'Silent',
+            36 => 'Short Movie',
+            37 => 'Past Movie',
+            38 => 'For YouTube',
+            39 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-Z16"',
+        Notes => 'EX-Z16',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Portrait',
+            3 => 'Scenery',
+            4 => 'Portrait with Scenery',
+            5 => 'Children',
+            6 => 'Sports',
+            7 => 'Candlelight Portrait',
+            8 => 'Party',
+            9 => 'Pet',
+            10 => 'Flower',
+            11 => 'Soft Flowing Water',
+            12 => 'Sundown',
+            13 => 'Night Scene',
+            14 => 'Night Scene Portrait',
+            15 => 'Fireworks',
+            16 => 'Food',
+            17 => 'Text',
+            18 => 'For eBay',
+            19 => 'Backlight',
+            20 => 'Anti Shake',
+            21 => 'High Sensitivity',
+            22 => 'For YouTube',
+            23 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-Z9"',
+        Notes => 'EX-Z9',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Movie',
+            3 => 'Portrait',
+            4 => 'Scenery',
+            5 => 'Children',
+            6 => 'Sports',
+            7 => 'Candlelight Portrait',
+            8 => 'Party',
+            9 => 'Pet',
+            10 => 'Flower',
+            11 => 'Soft Flowing Water',
+            12 => 'Sundown',
+            13 => 'Night Scene',
+            14 => 'Night Scene Portrait',
+            15 => 'Fireworks',
+            16 => 'Food',
+            17 => 'Text',
+            18 => 'Auction',
+            19 => 'Backlight',
+            20 => 'Anti Shake',
+            21 => 'High Sensitivity',
+            22 => 'For YouTube',
+            23 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-Z80"',
+        Notes => 'EX-Z80',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Portrait',
+            3 => 'Scenery',
+            4 => 'Portrait with Scenery',
+            5 => 'Pet',
+            6 => 'Self-portrait (1 person)',
+            7 => 'Self-portrait (2 people)',
+            8 => 'Flower',
+            9 => 'Food',
+            10 => 'Fashion Accessories',
+            11 => 'Magazine',
+            12 => 'Monochrome',
+            13 => 'Retro',
+            14 => 'Cross Filter',
+            15 => 'Pastel',
+            16 => 'Night Scene',
+            17 => 'Night Scene Portrait',
+            18 => 'Party',
+            19 => 'Sports',
+            20 => 'Children',
+            21 => 'Sundown',
+            22 => 'Fireworks',
+            23 => 'Underwater',
+            24 => 'Backlight',
+            25 => 'High Sensitivity',
+            26 => 'Auction',
+            27 => 'White Board',
+            28 => 'Pre-record Movie',
+            29 => 'For YouTube',
+            30 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} =~ /^EX-Z(100|200)$/',
+        Notes => 'EX-Z100 and EX-Z200',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Auto Best Shot',
+            3 => 'Portrait',
+            4 => 'Scenery',
+            5 => 'Portrait with Scenery',
+            6 => 'Self-portrait (1 person)',
+            7 => 'Self-portrait (2 people)',
+            8 => 'Children',
+            9 => 'Sports',
+            10 => 'Candlelight Portrait',
+            11 => 'Party',
+            12 => 'Pet',
+            13 => 'Flower',
+            14 => 'Natural Green',
+            15 => 'Autumn Leaves',
+            16 => 'Soft Flowing Water',
+            17 => 'Splashing Water',
+            18 => 'Sundown',
+            19 => 'Night Scene',
+            20 => 'Night Scene Portrait',
+            21 => 'Fireworks',
+            22 => 'Food',
+            23 => 'Text',
+            24 => 'Collection',
+            25 => 'Auction',
+            26 => 'Backlight',
+            27 => 'Anti Shake',
+            28 => 'High Sensitivity',
+            29 => 'Underwater',
+            30 => 'Monochrome',
+            31 => 'Retro',
+            32 => 'Twilight',
+            33 => 'ID Photo',
+            34 => 'Business Cards',
+            35 => 'White Board',
+            36 => 'Silent',
+            37 => 'Pre-record Movie',
+            38 => 'For YouTube',
+            39 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z750" and $$self{FILE_TYPE} eq "JPEG"',
+        Notes => 'EX-Z750 JPEG images',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Portrait',
+            2 => 'Scenery',
+            3 => 'Portrait with Scenery',
+            4 => 'Children',
+            5 => 'Sports',
+            6 => 'Candlelight Portrait',
+            7 => 'Party',
+            8 => 'Pet',
+            9 => 'Flower',
+            10 => 'Natural Green',
+            11 => 'Soft Flowing Water',
+            12 => 'Splashing Water',
+            13 => 'Sundown',
+            14 => 'Night Scene',
+            15 => 'Night Scene Portrait',
+            16 => 'Fireworks',
+            17 => 'Food',
+            18 => 'Text',
+            19 => 'Collection',
+            20 => 'Backlight',
+            21 => 'Anti Shake',
+            22 => 'Pastel',
+            23 => 'Illustration',
+            24 => 'Cross Filter',
+            25 => 'Monochrome',
+            26 => 'Retro',
+            27 => 'Twilight',
+            28 => 'Old Photo',
+            29 => 'ID Photo',
+            30 => 'Business Cards',
+            31 => 'White Board',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z750" and $$self{FILE_TYPE} =~ /^(MOV|AVI)$/',
+        Notes => 'EX-Z750 movies',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Portrait',
+            2 => 'Scenery',
+            3 => 'Night Scene',
+            4 => 'Fireworks',
+            5 => 'Backlight',
+            6 => 'Silent',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z850" and $$self{FILE_TYPE} eq "JPEG"',
+        Notes => 'EX-Z850 JPEG images',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Portrait',
+            2 => 'Scenery',
+            3 => 'Portrait with Scenery',
+            4 => 'Children',
+            5 => 'Sports',
+            6 => 'Candlelight Portrait',
+            7 => 'Party',
+            8 => 'Pet',
+            9 => 'Flower',
+            10 => 'Natural Green',
+            11 => 'Autumn Leaves',
+            12 => 'Soft Flowing Water',
+            13 => 'Splashing Water',
+            14 => 'Sundown',
+            15 => 'Night Scene',
+            16 => 'Night Scene Portrait',
+            17 => 'Fireworks',
+            18 => 'Food',
+            19 => 'Text',
+            20 => 'Collection',
+            21 => 'For eBay',
+            22 => 'Backlight',
+            23 => 'Anti Shake',
+            24 => 'High Sensitivity',
+            25 => 'Pastel',
+            26 => 'Illustration',
+            27 => 'Cross Filter',
+            28 => 'Monochrome',
+            29 => 'Retro',
+            30 => 'Twilight',
+            31 => 'ID Photo',
+            32 => 'Old Photo',
+            33 => 'Business Cards',
+            34 => 'White Board',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z850" and $$self{FILE_TYPE} =~ /^(MOV|AVI)$/',
+        Notes => 'EX-Z850 movies',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Portrait',
+            2 => 'Scenery',
+            3 => 'Night Scene',
+            4 => 'Fireworks',
+            5 => 'Backlight',
+            6 => 'High Sensitivity',
+            7 => 'Silent',
+            8 => 'Short Movie',
+            9 => 'Past Movie',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z1050"',
+        Notes => 'EX-Z1050',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Movie',
+            3 => 'Portrait',
+            4 => 'Scenery',
+            5 => 'Portrait with Scenery',
+            6 => 'Children',
+            7 => 'Sports',
+            8 => 'Candlelight Portrait',
+            9 => 'Party',
+            10 => 'Pet',
+            11 => 'Flower',
+            12 => 'Natural Green',
+            13 => 'Autumn Leaves',
+            14 => 'Soft Flowing Water',
+            15 => 'Splashing Water',
+            16 => 'Sundown',
+            17 => 'Night Scene',
+            18 => 'Night Scene Portrait',
+            19 => 'Fireworks',
+            20 => 'Food',
+            21 => 'Text',
+            22 => 'Collection',
+            23 => 'For eBay',
+            24 => 'Backlight',
+            25 => 'Anti Shake',
+            26 => 'High Sensitivity',
+            27 => 'Underwater',
+            28 => 'Monochrome',
+            29 => 'Retro',
+            30 => 'Twilight',
+            31 => 'Layout (2 images)',
+            32 => 'Layout (3 images)',
+            33 => 'Auto Framing',
+            34 => 'ID Photo',
+            35 => 'Old Photo',
+            36 => 'Business Cards',
+            37 => 'White Board',
+            38 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z1080"',
+        Notes => 'EX-Z1080',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Movie',
+            3 => 'Portrait',
+            4 => 'Scenery',
+            5 => 'Portrait with Scenery',
+            6 => 'Children',
+            7 => 'Sports',
+            8 => 'Candlelight Portrait',
+            9 => 'Party',
+            10 => 'Pet',
+            11 => 'Flower',
+            12 => 'Natural Green',
+            13 => 'Autumn Leaves',
+            14 => 'Soft Flowing Water',
+            15 => 'Splashing Water',
+            16 => 'Sundown',
+            17 => 'Night Scene',
+            18 => 'Night Scene Portrait',
+            19 => 'Fireworks',
+            20 => 'Food',
+            21 => 'Text',
+            22 => 'Collection',
+            23 => 'For eBay',
+            24 => 'Backlight',
+            25 => 'Anti Shake',
+            26 => 'High Sensitivity',
+            27 => 'Underwater',
+            28 => 'Monochrome',
+            29 => 'Retro',
+            30 => 'Twilight',
+            31 => 'Layout (2 images)',
+            32 => 'Layout (3 images)',
+            33 => 'Auto Framing',
+            34 => 'ID Photo',
+            35 => 'Old Photo',
+            36 => 'Business Cards',
+            37 => 'White Board',
+            38 => 'Short Movie',
+            39 => 'Past Movie',
+            40 => 'For YouTube',
+            41 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z1200" and $$self{FILE_TYPE} eq "JPEG"',
+        Notes => 'EX-Z1200 JPEG images',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Portrait',
+            2 => 'Scenery',
+            3 => 'Portrait with Scenery',
+            4 => 'Children',
+            5 => 'Sports',
+            6 => 'Candlelight Portrait',
+            7 => 'Party',
+            8 => 'Pet',
+            9 => 'Flower',
+            10 => 'Natural Green',
+            11 => 'Autumn Leaves',
+            12 => 'Soft Flowing Water',
+            13 => 'Splashing Water',
+            14 => 'Sundown',
+            15 => 'Night Scene',
+            16 => 'Night Scene Portrait',
+            17 => 'Fireworks',
+            18 => 'Food',
+            19 => 'Text',
+            20 => 'Collection',
+            21 => 'Auction',
+            22 => 'Backlight',
+            23 => 'High Sensitivity',
+            24 => 'Underwater',
+            25 => 'Monochrome',
+            26 => 'Retro',
+            27 => 'Twilight',
+            28 => 'Layout (2 images)',
+            29 => 'Layout (3 images)',
+            30 => 'Auto Framing',
+            31 => 'ID Photo',
+            32 => 'Old Photo',
+            33 => 'Business Cards',
+            34 => 'White Board',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z1200" and $$self{FILE_TYPE} =~ /^(MOV|AVI)$/',
+        Notes => 'EX-Z1200 movies',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Portrait',
+            2 => 'Scenery',
+            3 => 'Night Scene',
+            4 => 'Fireworks',
+            5 => 'Backlight',
+            6 => 'High Sensitivity',
+            7 => 'Silent',
+            8 => 'Short Movie',
+            9 => 'Past Movie',
+        },
+    },
+    # (the following weren't numbered in the documentation:
+    #  G1, Z300, Z250, Z85, Z19, Z150, F1, FH20)
+    {
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-Z2000"',
+        Notes => 'EX-Z2000',
+        PrintConvColumns => 3,
+        #http://support.casio.com/download_files/001/faq_pdf/Z2000/EXZ2000_BS_US_a.pdf
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Premium Auto',
+            3 => 'Dynamic Photo',
+            4 => 'Portrait',
+            5 => 'Scenery',
+            6 => 'Portrait with Scenery',
+            7 => 'Children',
+            8 => 'Sports',
+            9 => 'Candlelight Portrait',
+            10 => 'Party',
+            11 => 'Pet',
+            12 => 'Flower',
+            13 => 'Natural Green',
+            14 => 'Autumn Leaves',
+            15 => 'Soft Flowing Water',
+            16 => 'Splashing Water',
+            17 => 'Sundown',
+            18 => 'Night Scene',
+            19 => 'Night Scene Portrait',
+            20 => 'Fireworks',
+            21 => 'Food',
+            22 => 'Text',
+            23 => 'Collection',
+            24 => 'For eBay',
+            25 => 'Backlight',
+            26 => 'High Sensitivity',
+            27 => 'Oil Painting',
+            28 => 'Crayon',
+            29 => 'Water Color',
+            30 => 'Monochrome',
+            31 => 'Retro',
+            32 => 'Twilight',
+            33 => 'Multi-motion Image',
+            34 => 'ID Photo',
+            35 => 'Business Cards',
+            36 => 'White Board',
+            37 => 'Silent',
+            38 => 'Pre-record Movie',
+            39 => 'For YouTube',
+            40 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        # (Movies have different BestShot numbers for this camera)
+        Condition => '$$self{Model} eq "EX-Z2300"',
+        Notes => 'EX-Z2300',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            2 => 'Premium Auto',
+            3 => 'Dynamic Photo',
+            4 => 'Portrait',
+            5 => 'Scenery',
+            6 => 'Portrait with Scenery',
+            7 => 'Children',
+            8 => 'Sports',
+            9 => 'Candlelight Portrait',
+            10 => 'Party',
+            11 => 'Pet',
+            12 => 'Flower',
+            13 => 'Natural Green',
+            14 => 'Autumn Leaves',
+            15 => 'Soft Flowing Water',
+            16 => 'Splashing Water',
+            17 => 'Sundown',
+            18 => 'Night Scene',
+            19 => 'Night Scene Portrait',
+            20 => 'Fireworks',
+            21 => 'Food',
+            22 => 'Text',
+            23 => 'Collection',
+            24 => 'Auction',
+            25 => 'Backlight',
+            26 => 'High Sensitivity',
+            27 => 'Oil Painting',
+            28 => 'Crayon',
+            29 => 'Water Color',
+            30 => 'Monochrome',
+            31 => 'Retro',
+            32 => 'Twilight',
+            33 => 'Multi-motion Image',
+            34 => 'ID Photo',
+            35 => 'Business Cards',
+            36 => 'White Board',
+            37 => 'Silent',
+            38 => 'Pre-record Movie',
+            39 => 'For YouTube',
+            40 => 'Voice Recording',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-Z3000"',
+        Notes => 'EX-Z3000',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Portrait',
+            2 => 'Scenery',
+            3 => 'Portrait With Scenery',
+            4 => 'Children',
+            5 => 'Sports',
+            6 => 'Night Scene',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-ZR100"',
+        Notes => 'EX-ZR100',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Child CS',
+            2 => 'Pet CS',
+            3 => 'Sports CS',
+            4 => 'Child High Speed Movie',
+            5 => 'Pet High Speed Movie',
+            6 => 'Sports High Speed Movie',
+            7 => 'Multi SR Zoom',
+            8 => 'Lag Correction',
+            9 => 'High Speed Night Scene',
+            10 => 'High Speed Night Scene and Portrait',
+            11 => 'High Speed Anti Shake',
+            12 => 'Portrait',
+            13 => 'Scenery',
+            14 => 'Portrait with Scenery',
+            15 => 'Children',
+            16 => 'Sports',
+            17 => 'Candlelight Portrait',
+            18 => 'Party',
+            19 => 'Pet',
+            20 => 'Flower',
+            21 => 'Natural Green',
+            22 => 'Autumn Leaves',
+            23 => 'Soft Flowing Water',
+            24 => 'Splashing Water',
+            25 => 'Sundown',
+            26 => 'Fireworks',
+            27 => 'Food',
+            28 => 'Text',
+            29 => 'Collection',
+            30 => 'For eBay',
+            31 => 'Pre-record Movie',
+            32 => 'For YouTube',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-ZR200"',
+        Notes => 'EX-ZR200',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'High Speed Night Scene',
+            2 => 'High Speed Night Scene and Portrait',
+            3 => 'High Speed Anti Shake',
+            4 => 'Blurred Background',
+            5 => 'Wide Shot',
+            6 => 'High Speed Best Selection',
+            7 => 'Lag Correction',
+            8 => 'Child CS',
+            9 => 'Pet CS',
+            10 => 'Sports CS',
+            11 => 'Child High Speed Movie',
+            12 => 'Pet High Speed Movie',
+            13 => 'Sports High Speed Movie',
+            14 => 'Portrait',
+            15 => 'Scenery',
+            16 => 'Portrait with Scenery',
+            17 => 'Children',
+            18 => 'Sports',
+            19 => 'Candlelight Portrait',
+            20 => 'Party',
+            21 => 'Pet',
+            22 => 'Flower',
+            23 => 'Natural Green',
+            24 => 'Autumn Leaves',
+            25 => 'Soft Flowing Water',
+            26 => 'Splashing Water',
+            27 => 'Sundown',
+            28 => 'Fireworks',
+            29 => 'Food',
+            30 => 'Text',
+            31 => 'Collection',
+            32 => 'Auction',
+            33 => 'Pre-record Movie',
+            34 => 'For YouTube',
+        },
+    },{ #http://ftp.casio.co.jp/pub/world_manual/qv/en/qv_4000/BS.pdf
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "QV-4000"',
+        Notes => 'QV-4000',
+        PrintConvColumns => 3,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'People',
+            2 => 'Scenery',
+            3 => 'Flower',
+            4 => 'Night Scene',
+            5 => 'Soft Focus',
+            # this camera also supports 100 modes that you can apparently load
+            # from a CD-ROM, but I don't know how these map into these numbers
+        },
+    },{ #Manfred, email
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Condition => '$$self{Model} eq "EX-ZR300"',
+        Notes => 'EX-ZR300',
+        PrintConvColumns => 2,
+        PrintConv => {
+            1 => 'High Speed Night Shot',
+            2 => 'Blurred Background',
+            3 => 'Toy Camera',
+            4 => 'Soft Focus',
+            5 => 'Light Tone',
+            6 => 'Pop',
+            7 => 'Sepia',
+            8 => 'Monochrome',
+            9 => 'Miniature',
+            10 => 'Wide Shot',
+            11 => 'High Speed Best Selection',
+            12 => 'Lag Correction',
+            13 => 'High Speed Night Scene',
+            14 => 'High Speed Night Scene and Portrait',
+            15 => 'High Speed Anti Shake',
+            16 => 'Portrait',
+            17 => 'Scenery',
+            18 => 'Portrait with Scenery',
+            19 => 'Children',
+            20 => 'Sports',
+            21 => 'Candlelight Portrait',
+            22 => 'Party',
+            23 => 'Pet',
+            24 => 'Flower',
+            25 => 'Natural Green',
+            26 => 'Autumn Leaves',
+            27 => 'Soft Flowing Water',
+            28 => 'Splashing Water',
+            29 => 'Sundown',
+            30 => 'Fireworks',
+            31 => 'Food',
+            32 => 'Text',
+            33 => 'Collection',
+            34 => 'Auction',
+            35 => 'Prerecord (Movie)',
+            36 => 'For YouTube',
+        },
+    },{
+        Name => 'BestShotMode',
+        Writable => 'int16u',
+        Notes => 'other models not yet decoded',
         # so we can't use a lookup as usual - PH
         PrintConv => '$val ? $val : "Off"',
         PrintConvInv => '$val=~/(\d+)/ ? $1 : 0',
-    },
+    }],
     0x3008 => { #3
         Name => 'AutoISO',
@@ -590,12 +1577,14 @@
         },
     },
-    0x3009 => { #PH (EX-Z77)
+    0x3009 => { #6
         Name => 'AFMode',
         Writable => 'int16u',
         PrintConv => {
             0 => 'Off',
-            1 => 'On',
-            # have seen 2(EX-Z35 macro/portrait), 3(portrait) and 5(auto mode)
-            4 => 'Face Recognition', # "Family First"
+            1 => 'Spot',
+            2 => 'Multi',
+            3 => 'Face Detection',
+            4 => 'Tracking', # (but saw this for "Family First" mode with EX-Z77 - PH)
+            5 => 'Intelligent',
         },
     },
@@ -623,5 +1612,5 @@
         Name => 'ColorMode',
         Writable => 'int16u',
-        PrintConv => {  
+        PrintConv => {
             0 => 'Off',
             2 => 'Black & White', #PH (EX-Z400,FH20)
@@ -654,7 +1643,6 @@
     },
     0x301b => { #PH
-        Name => 'UnknownMode',
-        Writable => 'int16u',
-        Unknown => 1,
+        Name => 'ArtMode',
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Normal',
@@ -665,5 +1653,10 @@
             49 => 'Crayon Drawing', # (EX-2300)
             51 => 'Panorama', # (EX-ZR10)
-            52 => 'Art HDR', # (EX-ZR10)
+            52 => 'Art HDR', # (EX-ZR10,EX-Z3000)
+            62 => 'High Speed Night Shot', # (EX-ZR20)
+            64 => 'Monochrome', # (EX-ZR20)
+            67 => 'Toy Camera', # (EX-ZR20)
+            68 => 'Pop Art', # (EX-ZR20)
+            69 => 'Light Tone', # (EX-ZR20)
         },
     },
@@ -685,13 +1678,18 @@
             1 => 'On',
             2 => 'Best Shot',
-            # 3 observed in MOV videos (EX-V7)
+            3 => 'Movie Anti-Shake', # (EX-V7, EX-TR100)
             # (newer models write 2 numbers here - PH)
             '0 0' => 'Off', #PH
-            # have seen '0 1' for EX-Z2000 which has 5 modes: Auto, Camera AS, Image AS, DEMO, Off
             '16 0' => 'Slow Shutter', #PH (EX-Z77)
             '18 0' => 'Anti-Shake', #PH (EX-Z77)
             '20 0' => 'High Sensitivity', #PH (EX-Z77)
-            '0 3' => 'CCD Shift', #PH (guess)
-            '2 3' => 'High Speed Anti-Shake', #PH (EX-FC150)
+            # EX-Z2000 in 'Auto' mode gives '0 3' or '2 3' (ref 6)
+            '0 1' => 'Off (1)', #6
+            '0 3' => 'CCD Shift', #PH/6 ("Camera AS" in EX-Z2000 manual)
+            '2 1' => 'High Sensitivity', #6
+            '2 3' => 'CCD Shift + High Sensitivity', #PH (EX-FC150)
+            # have also seen:
+            # '2 0' - EX-Z15 1/60s ISO 200, EX-Z77 1/1000s ISO 50
+            # '16 1' - EX-Z2300 1/125s ISO 50
         },
     },
@@ -759,4 +1757,13 @@
         },
     },
+    0x310b => { #PH (NC)
+        Name => 'ArtModeParameters',
+        Writable => 'int8u',
+        Count => 3,
+        # "0 1 0" = Toy camera 1
+        # "0 2 0" = Toy camera 1
+        # "0 3 0" = Toy camera 1
+        # Have also seen "0 0 0" and "2 0 0"
+    },
     0x4001 => { #PH (AVI videos)
         Name => 'CaptureFrameRate',
@@ -889,4 +1896,5 @@
             2 => 'Rotate 270 CW',
             3 => 'Rotate 180', # (NC)
+            # (have seen 64 here, but image had no face)
         },
         Notes => 'orientation of face relative to unrotated image',
@@ -1027,5 +2035,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.07';
+$VERSION = '1.11';
 
 my %charsetTable;   # character set tables we've loaded
@@ -58,4 +58,7 @@
     Latin        => 0x101,
     Latin2       => 0x101,
+    DOSLatinUS   => 0x101,
+    DOSLatin1    => 0x101,
+    DOSCyrillic  => 0x101,
     MacCroatian  => 0x101,
     MacCyrillic  => 0x101,
@@ -107,4 +110,31 @@
 
 #------------------------------------------------------------------------------
+# Does an array contain valid UTF-16 characters?
+# Inputs: 0) array reference to list of UCS-2 values
+# Returns: 0=invalid UTF-16, 1=valid UTF-16 with no surrogates, 2=valid UTF-16 with surrogates
+sub IsUTF16($)
+{
+    local $_;
+    my $uni = shift;
+    my $surrogate;
+    foreach (@$uni) {
+        my $hiBits = ($_ & 0xfc00);
+        if ($hiBits == 0xfc00) {
+            # check for invalid values in UTF-16
+            return 0 if $_ == 0xffff or $_ == 0xfffe or ($_ >= 0xfdd0 and $_ <= 0xfdef);
+        } elsif ($surrogate) {
+            return 0 if $hiBits != 0xdc00;
+            $surrogate = 0;
+        } else {
+            return 0 if $hiBits == 0xdc00;
+            $surrogate = 1 if $hiBits == 0xd800;
+        }
+    }
+    return 1 if not defined $surrogate;
+    return 2 unless $surrogate;
+    return 0;
+}
+
+#------------------------------------------------------------------------------
 # Decompose string with specified encoding into an array of integer code points
 # Inputs: 0) ExifTool object ref (or undef), 1) string, 2) character set name,
@@ -115,8 +145,9 @@
 # - byte order mark observed and then removed with UCS2 and UCS4
 # - no warnings are issued if ExifTool object is not provided
+# - sets ExifTool WrongByteOrder flag if byte order is Unknown and current order is wrong
 sub Decompose($$$;$)
 {
     local $_;
-    my ($exifTool, $val, $charset) = @_; # ($byteOrder assigned later if required)
+    my ($et, $val, $charset) = @_; # ($byteOrder assigned later if required)
     my $type = $csType{$charset};
     my (@uni, $conv);
@@ -126,5 +157,5 @@
         unless ($conv) {
             # (shouldn't happen)
-            $exifTool->Warn("Invalid character set $charset") if $exifTool;
+            $et->Warn("Invalid character set $charset") if $et;
             return \@uni;   # error!
         }
@@ -141,7 +172,7 @@
             @uni = unpack($] < 5.010000 ? 'U0U*' : 'C0U*', $val);
             # issue warning if we had errors
-            if ($Image::ExifTool::evalWarning and $exifTool and not $$exifTool{WarnBadUTF8}) {
-                $exifTool->Warn('Malformed UTF-8 character(s)');
-                $$exifTool{WarnBadUTF8} = 1;
+            if ($Image::ExifTool::evalWarning and $et and not $$et{WarnBadUTF8}) {
+                $et->Warn('Malformed UTF-8 character(s)');
+                $$et{WarnBadUTF8} = 1;
             }
         }
@@ -196,4 +227,5 @@
                     $fmt =~ tr/nvNV/vnVN/;
                     @uni = unpack($fmt, $val);
+                    $$et{WrongByteOrder} = 1;
                 }
             }
@@ -225,5 +257,8 @@
                 }
                 # use this byte order if there are fewer errors
-                return \@try if $e2 < $e1;
+                if ($e2 < $e1) {
+                    $$et{WrongByteOrder} = 1;
+                    return \@try;
+                }
             }
         } else {
@@ -275,7 +310,7 @@
 {
     local $_;
-    my ($exifTool, $uni, $charset) = @_; # ($byteOrder assigned later if required)
+    my ($et, $uni, $charset) = @_; # ($byteOrder assigned later if required)
     my ($outVal, $conv, $inv);
-    $charset or $charset = $$exifTool{OPTIONS}{Charset};
+    $charset or $charset = $$et{OPTIONS}{Charset};
     my $csType = $csType{$charset};
     if ($csType == 0x100) {     # UTF8 (also treat ASCII as UTF8)
@@ -294,5 +329,5 @@
         $conv = LoadCharset($charset);
         unless ($conv) {
-            $exifTool->Warn("Missing charset $charset") if $exifTool;
+            $et->Warn("Missing charset $charset") if $et;
             return '';
         }
@@ -301,5 +336,5 @@
         unless ($inv) {
             if (not $csType or $csType & 0x802) {
-                $exifTool->Warn("Invalid destination charset $charset") if $exifTool;
+                $et->Warn("Invalid destination charset $charset") if $et;
                 return '';
             }
@@ -322,7 +357,7 @@
             next if $_ < 0x100 and not $$conv{$_};
             $_ = ord('?');  # set invalid characters to '?'
-            if ($exifTool and not $$exifTool{EncodingError}) {
-                $exifTool->Warn("Some character(s) could not be encoded in $charset");
-                $$exifTool{EncodingError} = 1;
+            if ($et and not $$et{EncodingError}) {
+                $et->Warn("Some character(s) could not be encoded in $charset");
+                $$et{EncodingError} = 1;
             }
         }
@@ -374,16 +409,17 @@
 
   UTF8, UTF16, UCS2, UCS4, Arabic, Baltic, Cyrillic, Greek, Hebrew, JIS,
-  Latin, Latin2, MacArabic, MacChineseCN, MacChineseTW, MacCroatian,
-  MacCyrillic, MacGreek, MacHebrew, MacIceland, MacJapanese, MacKorean,
-  MacLatin2, MacRSymbol, MacRoman, MacRomanian, MacThai, MacTurkish,
-  PDFDoc, RSymbol, ShiftJIS, Symbol, Thai, Turkish, Vietnam
+  Latin, Latin2, DOSLatinUS, DOSLatin1, DOSCyrillic, MacArabic,
+  MacChineseCN, MacChineseTW, MacCroatian, MacCyrillic, MacGreek, MacHebrew,
+  MacIceland, MacJapanese, MacKorean, MacLatin2, MacRSymbol, MacRoman,
+  MacRomanian, MacThai, MacTurkish, PDFDoc, RSymbol, ShiftJIS, Symbol, Thai,
+  Turkish, Vietnam
 
 However, only some of these character sets are available to the user via
-ExifTool options; the multi-byte character sets are used only internally
+ExifTool options -- the multi-byte character sets are used only internally
 when decoding certain types of information.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSCyrillic.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSCyrillic.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSCyrillic.pm	(revision 34921)
@@ -0,0 +1,49 @@
+#------------------------------------------------------------------------------
+# File:         DOSCyrillic.pm
+#
+# Description:  cp866 to Unicode
+#
+# Revisions:    2020/03/23 - P. Harvey created
+#
+# References:   1) https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/CP866.TXT
+#
+# Notes:        The table omits 1-byte characters with the same values as Unicode
+#------------------------------------------------------------------------------
+use strict;
+
+%Image::ExifTool::Charset::DOSCyrillic = (
+  0x80 => 0x0410, 0x81 => 0x0411, 0x82 => 0x0412, 0x83 => 0x0413,
+  0x84 => 0x0414, 0x85 => 0x0415, 0x86 => 0x0416, 0x87 => 0x0417,
+  0x88 => 0x0418, 0x89 => 0x0419, 0x8a => 0x041a, 0x8b => 0x041b,
+  0x8c => 0x041c, 0x8d => 0x041d, 0x8e => 0x041e, 0x8f => 0x041f,
+  0x90 => 0x0420, 0x91 => 0x0421, 0x92 => 0x0422, 0x93 => 0x0423,
+  0x94 => 0x0424, 0x95 => 0x0425, 0x96 => 0x0426, 0x97 => 0x0427,
+  0x98 => 0x0428, 0x99 => 0x0429, 0x9a => 0x042a, 0x9b => 0x042b,
+  0x9c => 0x042c, 0x9d => 0x042d, 0x9e => 0x042e, 0x9f => 0x042f,
+  0xa0 => 0x0430, 0xa1 => 0x0431, 0xa2 => 0x0432, 0xa3 => 0x0433,
+  0xa4 => 0x0434, 0xa5 => 0x0435, 0xa6 => 0x0436, 0xa7 => 0x0437,
+  0xa8 => 0x0438, 0xa9 => 0x0439, 0xaa => 0x043a, 0xab => 0x043b,
+  0xac => 0x043c, 0xad => 0x043d, 0xae => 0x043e, 0xaf => 0x043f,
+  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 => 0x0440, 0xe1 => 0x0441, 0xe2 => 0x0442, 0xe3 => 0x0443,
+  0xe4 => 0x0444, 0xe5 => 0x0445, 0xe6 => 0x0446, 0xe7 => 0x0447,
+  0xe8 => 0x0448, 0xe9 => 0x0449, 0xea => 0x044a, 0xeb => 0x044b,
+  0xec => 0x044c, 0xed => 0x044d, 0xee => 0x044e, 0xef => 0x044f,
+  0xf0 => 0x0401, 0xf1 => 0x0451, 0xf2 => 0x0404, 0xf3 => 0x0454,
+  0xf4 => 0x0407, 0xf5 => 0x0457, 0xf6 => 0x040e, 0xf7 => 0x045e,
+  0xf8 => 0x00b0, 0xf9 => 0x2219, 0xfa => 0x00b7, 0xfb => 0x221a,
+  0xfc => 0x2116, 0xfd => 0x00a4, 0xfe => 0x25a0, 0xff => 0x00a0,
+);
+
+1; # end
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSLatin1.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSLatin1.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSLatin1.pm	(revision 34921)
@@ -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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSLatinUS.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSLatinUS.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Charset/DOSLatinUS.pm	(revision 34921)
@@ -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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DICOM.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DICOM.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DICOM.pm	(revision 34921)
@@ -21,5 +21,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.11';
+$VERSION = '1.22';
 
 # DICOM VR (Value Representation) format conversions
@@ -50,5 +50,5 @@
 %Image::ExifTool::DICOM::Main = (
     GROUPS => { 2 => 'Image' },
-    PROCESS_PROC => 0,  # set this to zero to omit tags from lookup (way too many!)
+    VARS => { NO_LOOKUP => 1 }, # omit tags from lookup (way too many!)
     NOTES => q{
         The DICOM format is based on the ACR-NEMA specification, but adds a file
@@ -58,4 +58,7 @@
         L<http://medical.nema.org/>).  The table below contains tags from the DICOM
         2009 and earlier specifications plus some vendor-specific private tags.
+
+        Note that DICOM information may be saved in other file formats using the
+        L<XMP DICOM Tags|Image::ExifTool::TagNames/XMP DICOM Tags>.
     },
     # file meta information group (names end with VR)
@@ -2341,5 +2344,5 @@
     '0072,0514' => { VR => 'FD', Name => 'ReformattingInterval' },
     '0072,0516' => { VR => 'CS', Name => 'ReformattingOpInitialViewDir' },
-    '0072,0520' => { VR => 'CS', Name => '3DRenderingType' },
+    '0072,0520' => { VR => 'CS', Name => 'RenderingType3D' },
     '0072,0600' => { VR => 'SQ', Name => 'SortingOperationsSequence' },
     '0072,0602' => { VR => 'CS', Name => 'SortByCategory' },
@@ -3405,4 +3408,7 @@
     '1.2.840.10008.5.1.4.1.1.13.1.1' => 'X-Ray 3D Angiographic Image Storage',
     '1.2.840.10008.5.1.4.1.1.13.1.2' => 'X-Ray 3D Craniofacial Image Storage',
+    '1.2.840.10008.5.1.4.1.1.13.1.3' => 'Breast Tomosynthesis Image Storage',
+    '1.2.840.10008.5.1.4.1.1.14.1' => 'Intravascular Optical Coherence Tomography Image Storage - For Presentation',
+    '1.2.840.10008.5.1.4.1.1.14.2' => 'Intravascular Optical Coherence Tomography Image Storage - For Processing',
     '1.2.840.10008.5.1.4.1.1.20' => 'Nuclear Medicine Image Storage',
     '1.2.840.10008.5.1.4.1.1.66' => 'Raw Data Storage',
@@ -3425,4 +3431,15 @@
     '1.2.840.10008.5.1.4.1.1.77.1.5.3' => 'Stereometric Relationship Storage',
     '1.2.840.10008.5.1.4.1.1.77.1.5.4' => 'Ophthalmic Tomography Image Storage',
+    '1.2.840.10008.5.1.4.1.1.77.1.6' => 'VL Whole Slide Microscopy Image Storage',
+    '1.2.840.10008.5.1.4.1.1.78.1' => 'Lensometry Measurements Storage',
+    '1.2.840.10008.5.1.4.1.1.78.2' => 'Autorefraction Measurements Storage',
+    '1.2.840.10008.5.1.4.1.1.78.3' => 'Keratometry Measurements Storage',
+    '1.2.840.10008.5.1.4.1.1.78.4' => 'Subjective Refraction Measurements Storage',
+    '1.2.840.10008.5.1.4.1.1.78.5' => 'Visual Acuity Measurements Storage',
+    '1.2.840.10008.5.1.4.1.1.78.6' => 'Spectacle Prescription Report Storage',
+    '1.2.840.10008.5.1.4.1.1.78.7' => 'Ophthalmic Axial Measurements Storage',
+    '1.2.840.10008.5.1.4.1.1.78.8' => 'Intraocular Lens Calculations Storage',
+    '1.2.840.10008.5.1.4.1.1.79.1' => 'Macular Grid Thickness and Volume Report Storage SOP Class',
+    '1.2.840.10008.5.1.4.1.1.80.1' => 'Ophthalmic Visual Field Static Perimetry Measurements Storage',
     '1.2.840.10008.5.1.4.1.1.88.1' => 'Text SR Storage - Trial (Retired)',
     '1.2.840.10008.5.1.4.1.1.88.2' => 'Audio SR Storage - Trial (Retired)',
@@ -3437,4 +3454,6 @@
     '1.2.840.10008.5.1.4.1.1.88.65' => 'Chest CAD SR',
     '1.2.840.10008.5.1.4.1.1.88.67' => 'X-Ray Radiation Dose SR Storage',
+    '1.2.840.10008.5.1.4.1.1.88.69' => 'Colon CAD SR',
+    '1.2.840.10008.5.1.4.1.1.88.70' => 'Implantation Plan SR Document Storage',
     '1.2.840.10008.5.1.4.1.1.104.1' => 'Encapsulated PDF Storage',
     '1.2.840.10008.5.1.4.1.1.104.2' => 'Encapsulated CDA Storage',
@@ -3474,4 +3493,11 @@
     '1.2.840.10008.5.1.4.34.4.4' => 'Unified Procedure Step - Event SOP Class',
     '1.2.840.10008.5.1.4.34.5' => 'Unified Worklist and Procedure Step SOP Instance',
+    '1.2.840.10008.5.1.4.34.6.1' => 'Unified Procedure Step - Push SOP Class',
+    '1.2.840.10008.5.1.4.34.6.2' => 'Unified Procedure Step - Watch SOP Class',
+    '1.2.840.10008.5.1.4.34.6.3' => 'Unified Procedure Step - Pull SOP Class',
+    '1.2.840.10008.5.1.4.34.6.4' => 'Unified Procedure Step - Event SOP Class',
+    '1.2.840.10008.5.1.4.34.7' => 'RT Beams Delivery Instruction Storage',
+    '1.2.840.10008.5.1.4.34.8' => 'RT Conventional Machine Verification',
+    '1.2.840.10008.5.1.4.34.9' => 'RT Ion Machine Verification',
     '1.2.840.10008.5.1.4.37.1' => 'General Relevant Patient Information Query',
     '1.2.840.10008.5.1.4.37.2' => 'Breast Imaging Relevant Patient Information Query',
@@ -3480,6 +3506,22 @@
     '1.2.840.10008.5.1.4.38.2' => 'Hanging Protocol Information Model - FIND',
     '1.2.840.10008.5.1.4.38.3' => 'Hanging Protocol Information Model - MOVE',
+    '1.2.840.10008.5.1.4.39.1' => 'Color Palette Storage',
+    '1.2.840.10008.5.1.4.39.2' => 'Color Palette Information Model - FIND',
+    '1.2.840.10008.5.1.4.39.3' => 'Color Palette Information Model - MOVE',
+    '1.2.840.10008.5.1.4.39.4' => 'Color Palette Information Model - GET',
     '1.2.840.10008.5.1.4.41' => 'Product Characteristics Query SOP Class',
     '1.2.840.10008.5.1.4.42' => 'Substance Approval Query SOP Class',
+    '1.2.840.10008.5.1.4.43.1' => 'Generic Implant Template Storage',
+    '1.2.840.10008.5.1.4.43.2' => 'Generic Implant Template Information Model - FIND',
+    '1.2.840.10008.5.1.4.43.3' => 'Generic Implant Template Information Model - MOVE',
+    '1.2.840.10008.5.1.4.43.4' => 'Generic Implant Template Information Model - GET',
+    '1.2.840.10008.5.1.4.44.1' => 'Implant Assembly Template Storage',
+    '1.2.840.10008.5.1.4.44.2' => 'Implant Assembly Template Information Model - FIND',
+    '1.2.840.10008.5.1.4.44.3' => 'Implant Assembly Template Information Model - MOVE',
+    '1.2.840.10008.5.1.4.44.4' => 'Implant Assembly Template Information Model - GET',
+    '1.2.840.10008.5.1.4.45.1' => 'Implant Template Group Storage',
+    '1.2.840.10008.5.1.4.45.2' => 'Implant Template Group Information Model - FIND',
+    '1.2.840.10008.5.1.4.45.3' => 'Implant Template Group Information Model - MOVE',
+    '1.2.840.10008.5.1.4.45.4' => 'Implant Template Group Information Model - GET',
     '1.2.840.10008.15.0.3.1' => 'dicomDeviceName',
     '1.2.840.10008.15.0.3.2' => 'dicomDescription',
@@ -3527,10 +3569,10 @@
 # Inputs: 0) ExifTool object reference, 1) DirInfo reference
 # Returns: 1 on success, 0 if this wasn't a valid DICOM file
-sub ProcessDICM($$)
+sub ProcessDICOM($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my $unknown = $exifTool->Options('Unknown');
-    my $verbose = $exifTool->Options('Verbose');
+    my $unknown = $et->Options('Unknown');
+    my $verbose = $et->Options('Verbose');
     my ($hdr, $buff, $implicit, $vr, $len);
 #
@@ -3543,5 +3585,5 @@
         # file meta information transfer syntax is explicit little endian
         SetByteOrder('II');
-        $exifTool->SetFileType('DICOM');
+        $et->SetFileType('DICOM');
     } else {
         # test for a RAW DCM image (ACR-NEMA format, ie. no header)
@@ -3573,5 +3615,5 @@
         }
         $raf->Seek(0, 0) or return 0;   # rewind to start of file
-        $exifTool->SetFileType('ACR');
+        $et->SetFileType('ACR');
     }
 #
@@ -3595,5 +3637,5 @@
             # 1.2.840.10008.1.2.1.99 = deflated
             unless ($transferSyntax =~ /^1\.2\.840\.10008\.1\.2(\.\d+)?(\.\d+)?/) {
-                $exifTool->Warn("Unrecognized transfer syntax $transferSyntax");
+                $et->Warn("Unrecognized transfer syntax $transferSyntax");
                 last;
             }
@@ -3605,5 +3647,5 @@
             } elsif ($1 eq '.1' and $2 and $2 eq '.99') {
                 # inflate compressed data stream
-                if (eval 'require Compress::Zlib') {
+                if (eval { require Compress::Zlib }) {
                     # must use undocumented zlib feature to disable zlib header information
                     # because DICOM deflated data doesn't have the zlib header (ref 3)
@@ -3621,5 +3663,5 @@
                                 last if $stat == Compress::Zlib::Z_STREAM_END();
                             } else {
-                                $exifTool->Warn('Error inflating compressed data stream');
+                                $et->Warn('Error inflating compressed data stream');
                                 return 1;
                             }
@@ -3632,9 +3674,9 @@
                         $group = Get16u(\$buff, 0);
                     } else {
-                        $exifTool->Warn('Error initializing inflation');
+                        $et->Warn('Error initializing inflation');
                         return 1;
                     }
                 } else {
-                    $exifTool->Warn('Install Compress::Zlib to decode compressed data stream');
+                    $et->Warn('Install Compress::Zlib to decode compressed data stream');
                     return 1;
                 }
@@ -3667,6 +3709,6 @@
             if ($verbose) {
                 # start list of items in verbose output
-                $exifTool->VPrint(0, "$exifTool->{INDENT}+ [List of items]\n");
-                $exifTool->{INDENT} .= '| ';
+                $et->VPrint(0, "$$et{INDENT}+ [List of items]\n");
+                $$et{INDENT} .= '| ';
             }
         }
@@ -3707,5 +3749,5 @@
                 }
                 $$tagInfo{Unknown} = 1;
-                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+                AddTagToTable($tagTablePtr, $tag, $tagInfo);
             }
         }
@@ -3718,9 +3760,12 @@
         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;
-            if ($exifTool->Options('Binary') or ($tagInfo and
-                $exifTool->{REQ_TAG_LOOKUP}->{lc($$tagInfo{Name})}))
+            my $lcTag = $tagInfo ? lc($$tagInfo{Name}) : 'unknown';
+            if ($$et{REQ_TAG_LOOKUP}{$lcTag} or
+                ($$et{OPTIONS}{Binary} and not $$et{EXCL_TAG_LOOKUP}{$lcTag}))
             {
                 $binData = $buff;   # must make a copy
@@ -3736,11 +3781,11 @@
             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
@@ -3749,6 +3794,11 @@
             } elsif ($vr eq 'UI') {
                 # add PrintConv to translate registered UID's
-                $val =~ s/\0.*//; # truncate at null
+                $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
             }
         }
@@ -3760,5 +3810,5 @@
 
         # handle the new tag information
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $et->HandleTag($tagTablePtr, $tag, $val,
             DataPt => \$buff,
             DataPos => $pos - $len,
@@ -3770,7 +3820,7 @@
 
         # stop indenting for list if we reached EndOfItems tag
-        $exifTool->{INDENT} =~ s/..$// if $verbose and $tag eq 'FFFE,E00D';
+        $$et{INDENT} =~ s/..$// if $verbose and $tag eq 'FFFE,E00D';
     }
-    $err and $exifTool->Warn('Error reading DICOM file (corrupted?)');
+    $err and $et->Warn('Error reading DICOM file (corrupted?)');
     return 1;
 }
@@ -3804,5 +3854,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DJI.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DJI.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DJI.pm	(revision 34921)
@@ -0,0 +1,164 @@
+#------------------------------------------------------------------------------
+# 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.03';
+
+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 },
+);
+
+# thermal parameters in APP4 of DJI ZH20T images (ref forum11401)
+%Image::ExifTool::DJI::ThermalParams = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'APP4', 2 => 'Image' },
+    NOTES => 'Thermal parameters extracted from APP4 of DJI RJPEG files from the ZH20T.',
+  # 0x00 - 0xaa551206 - temperature header magic number 
+    0x24 => { Name => 'K1', Format => 'float' },
+    0x28 => { Name => 'K2', Format => 'float' },
+    0x2c => { Name => 'K3', Format => 'float' },
+    0x30 => { Name => 'K4', Format => 'float' },
+    0x34 => { Name => 'KF', Format => 'float' },
+    0x38 => { Name => 'B1', Format => 'float' },
+    0x3c => { Name => 'B2', Format => 'float' },
+    0x44 => { Name => 'ObjectDistance',     Format => 'int16u' },
+    0x46 => { Name => 'RelativeHumidity',   Format => 'int16u' },
+    0x48 => { Name => 'Emissivity',         Format => 'int16u' },
+    0x4a => { Name => 'Reflection',         Format => 'int16u',  },
+    0x4c => { Name => 'AmbientTemperature', Format => 'int16u' }, # (aka D1)
+    0x50 => { Name => 'D2', Format => 'int32s' },
+    0x54 => { Name => 'KJ', Format => 'int16u' },
+    0x56 => { Name => 'DB', Format => 'int16u' },
+    0x58 => { Name => 'KK', Format => 'int16u' },
+  # 0x500 - 0x55aa1206 - device header magic number 
+    # (nothing yet decoded from device header)
+);
+
+%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-2021, 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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DNG.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DNG.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DNG.pm	(revision 34921)
@@ -18,5 +18,5 @@
 use Image::ExifTool::CanonRaw;
 
-$VERSION = '1.15';
+$VERSION = '1.23';
 
 sub ProcessOriginalRaw($$$);
@@ -49,5 +49,5 @@
 
 %Image::ExifTool::DNG::AdobeData = ( #PH
-    GROUPS => { 0 => 'MakerNotes', 1 => 'Adobe', 2 => 'Image' },
+    GROUPS => { 0 => 'MakerNotes', 1 => 'AdobeDNG', 2 => 'Image' },
     PROCESS_PROC => \&ProcessAdobeData,
     WRITE_PROC => \&WriteAdobeStuff,
@@ -144,5 +144,5 @@
 sub ProcessOriginalRaw($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $start = $$dirInfo{DirStart};
@@ -156,5 +156,5 @@
         my $val = Get32u($dataPt, $pos);
         $val or $pos += 4, next; # ignore zero values
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $index);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $index);
         $tagInfo or $err = "Missing DNG tag $index", last;
         if ($index & 0x02) {
@@ -169,8 +169,9 @@
             my $tag = $$tagInfo{Name};
             # only extract this information if requested (because it takes time)
-            if ($exifTool->{OPTIONS}->{Binary} or
-                $exifTool->{REQ_TAG_LOOKUP}->{lc($tag)})
+            my $lcTag = lc $tag;
+            if (($$et{OPTIONS}{Binary} and not $$et{EXCL_TAG_LOOKUP}{$lcTag}) or
+                $$et{REQ_TAG_LOOKUP}{$lcTag})
             {
-                unless (eval 'require Compress::Zlib') {
+                unless (eval { require Compress::Zlib }) {
                     $err = 'Install Compress::Zlib to extract compressed images';
                     last;
@@ -208,7 +209,7 @@
             }
         }
-        $exifTool->FoundTag($tagInfo, $val);
-    }
-    $exifTool->Warn($err || 'Bad OriginalRawFileData') if defined $err;
+        $et->FoundTag($tagInfo, $val);
+    }
+    $et->Warn($err || 'Bad OriginalRawFileData') if defined $err;
     return 1;
 }
@@ -220,5 +221,5 @@
 sub ProcessAdobeData($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos};
@@ -226,15 +227,15 @@
     my $end = $$dirInfo{DirLen} + $pos;
     my $outfile = $$dirInfo{OutFile};
-    my $verbose = $exifTool->Options('Verbose');
-    my $htmlDump = $exifTool->Options('HtmlDump');
+    my $verbose = $et->Options('Verbose');
+    my $htmlDump = $et->Options('HtmlDump');
 
     return 0 unless $$dataPt =~ /^Adobe\0/;
     unless ($outfile) {
-        $exifTool->VerboseDir($dirInfo);
+        $et->VerboseDir($dirInfo);
         # don't parse makernotes if FastScan > 1
-        my $fast = $exifTool->Options('FastScan');
+        my $fast = $et->Options('FastScan');
         return 1 if $fast and $fast > 1;
     }
-    $htmlDump and $exifTool->HDump($dataPos, 6, 'Adobe DNGPrivateData header');
+    $htmlDump and $et->HDump($dataPos, 6, 'Adobe DNGPrivateData header');
     SetByteOrder('MM'); # always big endian
     $pos += 6;
@@ -247,13 +248,13 @@
             my $name = "Adobe$tag";
             $name =~ tr/ //d;
-            $exifTool->HDump($dataPos + $pos - 8, 8, "$name header", "Data Size: $size bytes");
+            $et->HDump($dataPos + $pos - 8, 8, "$name header", "Data Size: $size bytes");
             # dump non-EXIF format data
             unless ($tag =~ /^(MakN|SR2 )$/) {
-                $exifTool->HDump($dataPos + $pos, $size, "$name data");
+                $et->HDump($dataPos + $pos, $size, "$name data");
             }
         }
         if ($verbose and not $outfile) {
-            $tagInfo or $exifTool->VPrint(0, "$$exifTool{INDENT}Unsupported DNGAdobeData record: ($tag)\n");
-            $exifTool->VerboseInfo($tag,
+            $tagInfo or $et->VPrint(0, "$$et{INDENT}Unsupported DNGAdobeData record: ($tag)\n");
+            $et->VerboseInfo($tag,
                 ref $tagInfo eq 'HASH' ? $tagInfo : undef,
                 DataPt => $dataPt,
@@ -272,5 +273,5 @@
                         $value = substr($$dataPt, $pos, $size);
                     } else {
-                        $exifTool->HandleTag($tagTablePtr, $tag, substr($$dataPt, $pos, $size));
+                        $et->HandleTag($tagTablePtr, $tag, substr($$dataPt, $pos, $size));
                     }
                     last;
@@ -295,10 +296,10 @@
             if ($outfile) {
                 $dirInfo{Proc} = $processProc;  # WriteAdobeStuff() calls this to do the actual writing
-                $value = $exifTool->WriteDirectory(\%dirInfo, $subTable, \&WriteAdobeStuff);
+                $value = $et->WriteDirectory(\%dirInfo, $subTable, \&WriteAdobeStuff);
                 # use old directory if an error occurred
                 defined $value or $value = substr($$dataPt, $pos, $size);
             } else {
                 # override process proc for MakN
-                $exifTool->ProcessDirectory(\%dirInfo, $subTable, $processProc);
+                $et->ProcessDirectory(\%dirInfo, $subTable, $processProc);
             }
             last;
@@ -313,5 +314,5 @@
         ++$pos if $size & 0x01; # (darn padding)
     }
-    $pos == $end or $exifTool->Warn("$pos $end Adobe private data is corrupt");
+    $pos == $end or $et->Warn("$pos $end Adobe private data is corrupt");
     return 1;
 }
@@ -326,10 +327,10 @@
 sub ProcessAdobeCRW($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $start = $$dirInfo{DirStart};
     my $end = $start + $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
-    my $buildMakerNotes = $exifTool->Options('MakerNotes');
+    my $verbose = $et->Options('Verbose');
+    my $buildMakerNotes = $et->Options('MakerNotes');
     my $outfile = $$dirInfo{OutFile};
     my ($newTags, $oldChanged);
@@ -341,14 +342,14 @@
 
     # initialize maker note data if building maker notes
-    $buildMakerNotes and Image::ExifTool::CanonRaw::InitMakerNotes($exifTool);
+    $buildMakerNotes and Image::ExifTool::CanonRaw::InitMakerNotes($et);
 
     my $entries = Get16u($dataPt, $start + 2);
     my $pos = $start + 4;
-    $exifTool->VerboseDir($dirInfo, $entries) unless $outfile;
+    $et->VerboseDir($dirInfo, $entries) unless $outfile;
     if ($outfile) {
         # get hash of new tags
-        $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+        $newTags = $et->GetNewTagInfoHash($tagTablePtr);
         $$outfile = substr($$dataPt, $start, 4);
-        $oldChanged = $exifTool->{CHANGED};
+        $oldChanged = $$et{CHANGED};
     }
     # loop through entries in Adobe CRW information
@@ -365,5 +366,5 @@
         my $format = $Image::ExifTool::CanonRaw::crwTagFormat{$tagType};
         my $count;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$value);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID, \$value);
         if ($tagInfo) {
             $format = $$tagInfo{Format} if $$tagInfo{Format};
@@ -405,7 +406,7 @@
                     #### eval Validate ($dirData, $subdirStart, $size)
                     if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
-                        $exifTool->Warn("Invalid $name data");
+                        $et->Warn("Invalid $name data");
                     } else {
-                        $subdir = $exifTool->WriteDirectory(\%subdirInfo, $newTagTable);
+                        $subdir = $et->WriteDirectory(\%subdirInfo, $newTagTable);
                         if (defined $subdir and length $subdir) {
                             if ($subdirStart) {
@@ -418,7 +419,7 @@
                     }
                 } elsif ($$newTags{$tagID}) {
-                    my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-                    if (Image::ExifTool::IsOverwriting($nvHash, $val)) {
-                        my $newVal = Image::ExifTool::GetNewValues($nvHash);
+                    my $nvHash = $et->GetNewValueHash($tagInfo);
+                    if ($et->IsOverwriting($nvHash, $val)) {
+                        my $newVal = $et->GetNewValue($nvHash);
                         my $verboseVal;
                         $verboseVal = $newVal if $verbose > 1;
@@ -428,8 +429,8 @@
                         }
                         if (defined $newVal) {
-                            $exifTool->VerboseValue("- CanonRaw:$$tagInfo{Name}", $value);
-                            $exifTool->VerboseValue("+ CanonRaw:$$tagInfo{Name}", $verboseVal);
+                            $et->VerboseValue("- CanonRaw:$$tagInfo{Name}", $value);
+                            $et->VerboseValue("+ CanonRaw:$$tagInfo{Name}", $verboseVal);
                             $value = $newVal;
-                            ++$exifTool->{CHANGED};
+                            ++$$et{CHANGED};
                         }
                     }
@@ -441,5 +442,5 @@
             $$outfile .= Set16u($tag) . Set32u(length($value)) . $value;
         } else {
-            $exifTool->HandleTag($tagTablePtr, $tagID, $val,
+            $et->HandleTag($tagTablePtr, $tagID, $val,
                 Index   => $index,
                 DataPt  => $dataPt,
@@ -451,5 +452,5 @@
             if ($buildMakerNotes) {
                 # build maker notes information if requested
-                Image::ExifTool::CanonRaw::BuildMakerNotes($exifTool, $tagID, $tagInfo,
+                Image::ExifTool::CanonRaw::BuildMakerNotes($et, $tagID, $tagInfo,
                                                            \$value, $format, $count);
             }
@@ -457,23 +458,23 @@
         # (we lost the directory structure, but the second tag 0x0805
         # should be in the ImageDescription directory)
-        $exifTool->{DIR_NAME} = 'ImageDescription' if $tagID == 0x0805;
+        $$et{DIR_NAME} = 'ImageDescription' if $tagID == 0x0805;
         SetByteOrder('MM');
         $pos += $size;
     }
     if ($outfile and (not defined $$outfile or $index != $entries or
-        $exifTool->{CHANGED} ==  $oldChanged))
+        $$et{CHANGED} ==  $oldChanged))
     {
-        $exifTool->{CHANGED} = $oldChanged; # nothing changed
+        $$et{CHANGED} = $oldChanged; # nothing changed
         undef $$outfile;    # rewrite old directory
     }
     if ($index != $entries) {
-        $exifTool->Warn('Truncated CRW notes');
+        $et->Warn('Truncated CRW notes');
     } elsif ($pos < $end) {
-        $exifTool->Warn($end-$pos . ' extra bytes at end of CRW notes');
+        $et->Warn($end-$pos . ' extra bytes at end of CRW notes');
     }
     # finish building maker notes if necessary
     if ($buildMakerNotes) {
         SetByteOrder($byteOrder);
-        Image::ExifTool::CanonRaw::SaveMakerNotes($exifTool);
+        Image::ExifTool::CanonRaw::SaveMakerNotes($et);
     }
     return 1;
@@ -487,5 +488,5 @@
 sub ProcessAdobeMRW($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = $$dirInfo{DirLen};
@@ -499,5 +500,5 @@
     my $raf = new File::RandomAccess(\$buff);
     my %dirInfo = ( RAF => $raf, OutFile => $outfile );
-    my $rtnVal = Image::ExifTool::MinoltaRaw::ProcessMRW($exifTool, \%dirInfo);
+    my $rtnVal = Image::ExifTool::MinoltaRaw::ProcessMRW($et, \%dirInfo);
     if ($outfile and defined $$outfile and length $$outfile) {
         # remove MRW header and add Adobe header
@@ -513,5 +514,5 @@
 sub ProcessAdobeRAF($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     return 0 if $$dirInfo{OutFile}; # (can't write this yet)
     my $dataPt = $$dirInfo{DataPt};
@@ -524,8 +525,8 @@
         $pos += 2;
     } else {
-        $exifTool->Warn('Invalid DNG RAF data');
+        $et->Warn('Invalid DNG RAF data');
         return 0;
     }
-    $exifTool->VerboseDir($dirInfo);
+    $et->VerboseDir($dirInfo);
     # make fake RAF object for processing (same acronym, different meaning)
     my $raf = new File::RandomAccess($dataPt);
@@ -545,10 +546,10 @@
             DirStart => $pos - $len,
         );
-        $$exifTool{SET_GROUP1} = "RAF$num";
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr) or $warn = 1;
-        delete $$exifTool{SET_GROUP1};
+        $$et{SET_GROUP1} = "RAF$num";
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr) or $warn = 1;
+        delete $$et{SET_GROUP1};
         $num = ($num || 1) + 1;
     }
-    $warn and $exifTool->Warn('Possibly corrupt RAF information');
+    $warn and $et->Warn('Possibly corrupt RAF information');
     return 1;
 }
@@ -561,5 +562,5 @@
 sub ProcessAdobeSR2($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     return 0 if $$dirInfo{OutFile}; # (can't write this yet)
     my $dataPt = $$dirInfo{DataPt};
@@ -572,5 +573,5 @@
     return 0 unless SetByteOrder(substr($$dataPt, $start, 2));
 
-    $exifTool->VerboseDir($dirInfo);
+    $et->VerboseDir($dirInfo);
     my $dataPos = $$dirInfo{DataPos};
     my $dirStart = $start + 6;  # pointer to maker note directory
@@ -589,9 +590,9 @@
         Parent    => $$dirInfo{DirName},
     );
-    if ($exifTool->Options('HtmlDump')) {
-        $exifTool->HDump($dataPos + $start, 6, 'Adobe SR2 data');
+    if ($et->Options('HtmlDump')) {
+        $et->HDump($dataPos + $start, 6, 'Adobe SR2 data');
     }
     # parse the SR2 directory
-    $exifTool->ProcessDirectory(\%subdirInfo, $tagTablePtr);
+    $et->ProcessDirectory(\%subdirInfo, $tagTablePtr);
     return 1;
 }
@@ -604,5 +605,5 @@
 sub ProcessAdobeIFD($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     return 0 if $$dirInfo{OutFile}; # (can't write this yet)
     my $dataPt = $$dirInfo{DataPt};
@@ -616,8 +617,8 @@
     # 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);
-    $exifTool->VerboseDir($dirInfo, $entries);
+    $et->VerboseDir($dirInfo, $entries);
     $pos += 4;
 
@@ -632,5 +633,5 @@
         if ($format < 1 or $format > 13) {
             # warn unless the IFD was just padded with zeros
-            $format and $exifTool->Warn(
+            $format and $et->Warn(
                 sprintf("Unknown format ($format) for $$dirInfo{DirName} tag 0x%x",$tagID));
             return 0; # must be corrupted
@@ -641,5 +642,5 @@
         SetByteOrder($dataOrder);   # data stored in native order
         my $val = ReadValue($dataPt, $pos + 8, $formatStr, $count, $size);
-        $exifTool->HandleTag($tagTablePtr, $tagID, $val,
+        $et->HandleTag($tagTablePtr, $tagID, $val,
             Index   => $index,
             DataPt  => $dataPt,
@@ -651,5 +652,5 @@
     }
     if ($index < $entries) {
-        $exifTool->Warn("Truncated $$dirInfo{DirName} directory");
+        $et->Warn("Truncated $$dirInfo{DirName} directory");
         return 0;
     }
@@ -662,7 +663,8 @@
 # Returns: 1 on success, otherwise returns 0 and sets a Warning
 # Notes: data has 6 byte header (2 for byte order and 4 for original offset)
+#        --> or 18 bytes for DNG converted from JPG by Adobe Camera Raw!
 sub ProcessAdobeMakN($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $start = $$dirInfo{DirStart};
@@ -675,11 +677,17 @@
     return 0 unless SetByteOrder(substr($$dataPt, $start, 2));
 
-    $exifTool->VerboseDir($dirInfo) unless $outfile;
+    $et->VerboseDir($dirInfo) unless $outfile;
     my $dataPos = $$dirInfo{DataPos};
-    my $dirStart = $start + 6;  # pointer to maker note directory
-    my $dirLen = $len - 6;
+    my $hdrLen = 6;
+
+    # hack for extra 12 bytes in MakN header of JPEG converted to DNG by Adobe Camera Raw
+    # (4 bytes "00 00 00 01" followed by 8 unknown bytes)
+    $hdrLen += 12 if $len >= 18 and substr($$dataPt, $start+6, 4) eq "\0\0\0\x01";
+
+    my $dirStart = $start + $hdrLen;    # pointer to maker note directory
+    my $dirLen = $len - $hdrLen;
 
     my $hdr = substr($$dataPt, $dirStart, $dirLen < 48 ? $dirLen : 48);
-    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 'MakN', \$hdr);
+    my $tagInfo = $et->GetTagInfo($tagTablePtr, 'MakN', \$hdr);
     return 0 unless $tagInfo and $$tagInfo{SubDirectory};
     my $subdir = $$tagInfo{SubDirectory};
@@ -701,12 +709,12 @@
     );
     # look for start of maker notes IFD
-    my $loc = Image::ExifTool::MakerNotes::LocateIFD($exifTool,\%subdirInfo);
+    my $loc = Image::ExifTool::MakerNotes::LocateIFD($et,\%subdirInfo);
     unless (defined $loc) {
-        $exifTool->Warn('Maker notes could not be parsed');
+        $et->Warn('Maker notes could not be parsed');
         return 0;
     }
-    if ($exifTool->Options('HtmlDump')) {
-        $exifTool->HDump($dataPos + $start, 6, 'Adobe MakN data');
-        $exifTool->HDump($dataPos + $dirStart, $loc, "$$tagInfo{Name} header") if $loc;
+    if ($et->Options('HtmlDump')) {
+        $et->HDump($dataPos + $start, $hdrLen, 'Adobe MakN data');
+        $et->HDump($dataPos + $dirStart, $loc, "$$tagInfo{Name} header") if $loc;
     }
 
@@ -721,9 +729,9 @@
         # rewrite the maker notes directory
         my $fixup = $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
-        my $oldChanged = $$exifTool{CHANGED};
-        my $buff = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+        my $oldChanged = $$et{CHANGED};
+        my $buff = $et->WriteDirectory(\%subdirInfo, $subTable);
         # nothing to do if error writing directory or nothing changed
-        unless (defined $buff and $exifTool->{CHANGED} != $oldChanged) {
-            $exifTool->{CHANGED} = $oldChanged;
+        unless (defined $buff and $$et{CHANGED} != $oldChanged) {
+            $$et{CHANGED} = $oldChanged;
             return 1;
         }
@@ -746,14 +754,14 @@
         $fixup->{Shift} += $loc;    # adjust for makernotes header
         $fixup->ApplyFixup(\$buff); # fix up pointer offsets
-        # get copy of original Adobe header (6) and makernotes header ($loc)
-        my $header = substr($$dataPt, $start, 6 + $loc);
+        # get copy of original Adobe header (6 or 18) and makernotes header ($loc)
+        my $header = substr($$dataPt, $start, $hdrLen + $loc);
         # add Adobe and makernotes headers to new directory
         $$outfile = $header . $buff;
     } else {
         # parse the maker notes directory
-        $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $$subdir{ProcessProc});
+        $et->ProcessDirectory(\%subdirInfo, $subTable, $$subdir{ProcessProc});
         # extract maker notes as a block if specified
-        if ($exifTool->Options('MakerNotes') or
-            $exifTool->{REQ_TAG_LOOKUP}->{lc($$tagInfo{Name})})
+        if ($et->Options('MakerNotes') or
+            $$et{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})})
         {
             my $val;
@@ -764,6 +772,8 @@
                 $subdirInfo{DirLen}   = $dirLen;
                 # rebuild the maker notes to identify all offsets that require fixing up
-                $val = Image::ExifTool::Exif::RebuildMakerNotes($exifTool, $subTable, \%subdirInfo);
-                defined $val or $exifTool->Warn('Error rebuilding maker notes (may be corrupt)');
+                $val = Image::ExifTool::Exif::RebuildMakerNotes($et, \%subdirInfo, $subTable);
+                if (not defined $val and $dirLen > 4) {
+                    $et->Warn('Error rebuilding maker notes (may be corrupt)');
+                }
             } else {
                 # extract this directory as a block if specified
@@ -771,5 +781,5 @@
             }
             $val = substr($$dataPt, 20) unless defined $val;
-            $exifTool->FoundTag($tagInfo, $val);
+            $et->FoundTag($tagInfo, $val);
         }
     }
@@ -783,10 +793,10 @@
 sub WriteAdobeStuff($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access
     my $proc = $$dirInfo{Proc} || \&ProcessAdobeData;
     my $buff;
     $$dirInfo{OutFile} = \$buff;
-    &$proc($exifTool, $dirInfo, $tagTablePtr) or undef $buff;
+    &$proc($et, $dirInfo, $tagTablePtr) or undef $buff;
     return $buff;
 }
@@ -811,5 +821,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DPX.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DPX.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DPX.pm	(revision 34921)
@@ -0,0 +1,236 @@
+#------------------------------------------------------------------------------
+# File:         DPX.pm
+#
+# Description:  Read DPX meta information
+#
+# Revisions:    2013-09-19 - P. Harvey created
+#
+# References:   1) http://www.cineon.com/ff_draft.php
+#               2) Harry Mallon private communication
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::DPX;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.05';
+
+# DPX tags
+%Image::ExifTool::DPX::Main = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
+    NOTES => 'Tags extracted from DPX (Digital Picture Exchange) images.',
+    0   => { Name => 'ByteOrder',     Format => 'undef[4]', PrintConv => { SDPX => 'Big-endian', XPDS => 'Little-endian' } },
+    8   => { Name => 'HeaderVersion', Format => 'string[8]' },
+    # 24 => { Name => 'GenericHeaderSize', Format => 'int32u' }, # = 1664
+    # 28 => { Name => 'IndustryStandardHeaderSize', Format => 'int32u' }, # = 384
+    16  => { Name => 'DPXFileSize',   Format => 'int32u' },
+    20  => { Name => 'DittoKey',      Format => 'int32u', PrintConv => { 0 => 'Same', 1 => 'New' } },
+    36  => { Name => 'ImageFileName', Format => 'string[100]' },
+    136 => {
+        Name => 'CreateDate',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+        ValueConv => '$val =~ s/(\d{4}:\d{2}:\d{2}):/$1 /; $val',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    160 => { Name => 'Creator',       Format => 'string[100]', Groups => { 2 => 'Author' } },
+    260 => { Name => 'Project',       Format => 'string[200]' },
+    460 => { Name => 'Copyright',     Format => 'string[200]', Groups => { 2 => 'Author' } },
+    660 => { Name => 'EncryptionKey', Format => 'int32u', PrintConv => 'sprintf("%.8x",$val)' },
+    768 => {
+        Name => 'Orientation',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Mirror vertical',
+            2 => 'Mirror horizontal',
+            3 => 'Rotate 180',
+            4 => 'Mirror horizontal and rotate 270 CW',
+            5 => 'Rotate 90 CW',
+            6 => 'Rotate 270 CW',
+            7 => 'Mirror horizontal and rotate 90 CW',
+        },
+    },
+    770 => { Name => 'ImageElements', Format => 'int16u' },
+    772 => { Name => 'ImageWidth',    Format => 'int32u' },
+    776 => { Name => 'ImageHeight',   Format => 'int32u' },
+    780 => { Name => 'DataSign',      Format => 'int32u', PrintConv => { 0 => 'Unsigned', 1 => 'Signed' } },
+    800 => {
+        Name => 'ComponentsConfiguration',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'User-defined single component',
+            1 => 'Red (R)',
+            2 => 'Green (G)',
+            3 => 'Blue (B)',
+            4 => 'Alpha (matte)',
+            6 => 'Luminance (Y)',
+            7 => 'Chrominance (Cb, Cr, subsampled by two)',
+            8 => 'Depth (Z)',
+            9 => 'Composite video',
+            50 => 'R, G, B',
+            51 => 'R, G, B, Alpha',
+            52 => 'Alpha, B, G, R',
+            100 => 'Cb, Y, Cr, Y (4:2:2)',
+            101 => 'Cb, Y, A, Cr, Y, A (4:2:2:4)',
+            102 => 'Cb, Y, Cr (4:4:4)',
+            103 => 'Cb, Y, Cr, A (4:4:4:4)',
+            150 => 'User-defined 2 component element',
+            151 => 'User-defined 3 component element',
+            152 => 'User-defined 4 component element',
+            153 => 'User-defined 5 component element',
+            154 => 'User-defined 6 component element',
+            155 => 'User-defined 7 component element',
+            156 => 'User-defined 8 component element',
+        },
+    },
+    801 => { #2
+        Name => 'TransferCharacteristic',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'User-defined',
+            1 => 'Printing density',
+            2 => 'Linear',
+            3 => 'Logarithmic',
+            4 => 'Unspecified video',
+            5 => 'SMPTE 274M',
+            6 => 'ITU-R 704-4',
+            7 => 'ITU-R 601-5 system B or G (625)',
+            8 => 'ITU-R 601-5 system M (525)',
+            9 => 'Composite video (NTSC)',
+            10 => 'Composite video (PAL)',
+            11 => 'Z (depth) - linear',
+            12 => 'Z (depth) - homogeneous',
+            13 => 'SMPTE ADX',
+            14 => 'ITU-R 2020 NCL',
+            15 => 'ITU-R 2020 CL',
+            16 => 'IEC 61966-2-4 xvYCC',
+            17 => 'ITU-R 2100 NCL/PQ',
+            18 => 'ITU-R 2100 ICtCp/PQ',
+            19 => 'ITU-R 2100 NCL/HLG',
+            20 => 'ITU-R 2100 ICtCp/HLG',
+            21 => 'RP 431-2:2011 Gama 2.6',
+            22 => 'IEC 61966-2-1 sRGB',
+        },
+    },
+    802 => { #2
+        Name => 'ColorimetricSpecification',
+        Format => 'int8u',
+        PrintConv => {
+            0 => 'User-defined',
+            1 => 'Printing density',
+            4 => 'Unspecified video',
+            5 => 'SMPTE 274M',
+            6 => 'ITU-R 704-4',
+            7 => 'ITU-R 601-5 system B or G (625)',
+            8 => 'ITU-R 601-5 system M (525)',
+            9 => 'Composite video (NTSC)',
+            10 => 'Composite video (PAL)',
+            13 => 'SMPTE ADX',
+            14 => 'ITU-R 2020',
+            15 => 'P3D65',
+            16 => 'P3DCI',
+            17 => 'P3D60',
+            18 => 'ACES',
+        },
+    },
+    803 => { Name => 'BitDepth',      Format => 'int8u' },
+    820 => { Name => 'ImageDescription',  Format => 'string[32]' },
+    892 => { Name => 'Image2Description', Format => 'string[32]', RawConv => '$val=~/[^\xff]/ ? $val : undef' },
+    964 => { Name => 'Image3Description', Format => 'string[32]', RawConv => '$val=~/[^\xff]/ ? $val : undef' },
+    1036=> { Name => 'Image4Description', Format => 'string[32]', RawConv => '$val=~/[^\xff]/ ? $val : undef' },
+    1108=> { Name => 'Image5Description', Format => 'string[32]', RawConv => '$val=~/[^\xff]/ ? $val : undef' },
+    1180=> { Name => 'Image6Description', Format => 'string[32]', RawConv => '$val=~/[^\xff]/ ? $val : undef' },
+    1252=> { Name => 'Image7Description', Format => 'string[32]', RawConv => '$val=~/[^\xff]/ ? $val : undef' },
+    1324=> { Name => 'Image8Description', Format => 'string[32]', RawConv => '$val=~/[^\xff]/ ? $val : undef' },
+    # 1408=> { Name => 'XOffset',           Format => 'int32u' },
+    # 1412=> { Name => 'YOffset',           Format => 'int32u' },
+    # 1416=> { Name => 'XCenter',           Format => 'float' },
+    # 1420=> { Name => 'YCenter',           Format => 'float' },
+    # 1424=> { Name => 'XOriginalSize',     Format => 'int32u' },
+    # 1428=> { Name => 'YOriginalSize',     Format => 'int32u' },
+    1432=> { Name => 'SourceFileName',    Format => 'string[100]' },
+    1532=> { Name => 'SourceCreateDate',  Format => 'string[24]' },
+    1556=> { Name => 'InputDeviceName',   Format => 'string[32]' },
+    1588=> { Name => 'InputDeviceSerialNumber', Format => 'string[32]' },
+    # 1620=> { Name => 'AspectRatio',       Format => 'int32u' },
+    1724 => { Name => 'OriginalFrameRate',Format => 'float' },
+    1728 => { Name => 'ShutterAngle',     Format => 'float', RawConv => '($val =~ /\d/ and $val !~ /nan/i) ? $val : undef' }, #2
+    1732 => { Name => 'FrameID',          Format => 'string[32]' },
+    1764 => { Name => 'SlateInformation', Format => 'string[100]' },
+    1920 => { Name => 'TimeCode',         Format => 'int32u' }, #2
+    1940 => { Name => 'FrameRate',        Format => 'float', RawConv => '($val =~ /\d/ and $val !~ /nan/i) ? $val : undef' }, #2
+    1972 => { Name => 'Reserved5',        Format => 'string[76]', Unknown => 1 },
+    2048 => { Name => 'UserID',           Format => 'string[32]' },
+);
+
+#------------------------------------------------------------------------------
+# Extract EXIF information from a DPX image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid DPX file
+sub ProcessDPX($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    # verify this is a valid DPX file
+    return 0 unless $raf->Read($buff, 2080) == 2080;
+    return 0 unless $buff =~ /^(SDPX|XPDS)/;
+    SetByteOrder($1 eq 'SDPX' ? 'MM' : 'II');
+    $et->SetFileType();   # set the FileType tag
+    my $hdrLen = Get32u(\$buff,24) + Get32u(\$buff,28);
+    $hdrLen == 2048 or $et->Warn("Unexpected DPX header length ($hdrLen)");
+    my %dirInfo = (
+        DataPt => \$buff,
+        DirStart => 0,
+        DirLen => length($buff),
+    );
+    my $tagTablePtr = GetTagTable('Image::ExifTool::DPX::Main');
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::DPX - Read DPX meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read
+metadata from DPX (Digital Picture Exchange) images.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.cineon.com/ff_draft.php>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/DPX Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DV.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DV.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DV.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.00';
+$VERSION = '1.02';
 
 # DV profiles (ref 1)
@@ -25,5 +25,4 @@
         FrameSize => 120000,
         VideoFormat => 'IEC 61834, SMPTE-314M - 525/60 (NTSC)',
-        VideoScanType => 'Progressive',
         Colorimetry => '4:1:1',
         FrameRate => 30000/1001,
@@ -35,5 +34,4 @@
         FrameSize => 144000,
         VideoFormat => 'IEC 61834 - 625/50 (PAL)',
-        VideoScanType => 'Progressive',
         Colorimetry => '4:2:0',
         FrameRate => 25/1,
@@ -45,5 +43,4 @@
         FrameSize => 144000,
         VideoFormat => 'SMPTE-314M - 625/50 (PAL)',
-        VideoScanType => 'Progressive',
         Colorimetry => '4:1:1',
         FrameRate => 25/1,
@@ -55,5 +52,4 @@
         FrameSize => 240000,
         VideoFormat => 'DVCPRO50: SMPTE-314M - 525/60 (NTSC) 50 Mbps',
-        VideoScanType => 'Progressive',
         Colorimetry => '4:2:2',
         FrameRate => 30000/1001,
@@ -65,5 +61,4 @@
         FrameSize => 288000,
         VideoFormat => 'DVCPRO50: SMPTE-314M - 625/50 (PAL) 50 Mbps',
-        VideoScanType => 'Progressive',
         Colorimetry => '4:2:2',
         FrameRate => 25/1,
@@ -75,5 +70,4 @@
         FrameSize => 480000,
         VideoFormat => 'DVCPRO HD: SMPTE-370M - 1080i60 100 Mbps',
-        VideoScanType => 'Interlaced',
         Colorimetry => '4:2:2',
         FrameRate => 30000/1001,
@@ -85,5 +79,4 @@
         FrameSize => 576000,
         VideoFormat => 'DVCPRO HD: SMPTE-370M - 1080i50 100 Mbps',
-        VideoScanType => 'Interlaced',
         Colorimetry => '4:2:2',
         FrameRate => 25/1,
@@ -95,5 +88,4 @@
         FrameSize => 240000,
         VideoFormat => 'DVCPRO HD: SMPTE-370M - 720p60 100 Mbps',
-        VideoScanType => 'Progressive',
         Colorimetry => '4:2:2',
         FrameRate => 60000/1001,
@@ -105,5 +97,4 @@
         FrameSize => 288000,
         VideoFormat => 'DVCPRO HD: SMPTE-370M - 720p50 100 Mbps',
-        VideoScanType => 'Progressive',
         Colorimetry => '4:2:2',
         FrameRate => 50/1,
@@ -115,5 +106,4 @@
         FrameSize => 144000,
         VideoFormat => 'IEC 61883-5 - 625/50 (PAL)',
-        VideoScanType => 'Progressive',
         Colorimetry => '4:2:0',
         FrameRate => 25/1,
@@ -137,4 +127,5 @@
     NOTES => 'The following tags are extracted from DV videos.',
     DateTimeOriginal => {
+        Description => 'Date/Time Original',
         Groups => { 2 => 'Time' },
         PrintConv => '$self->ConvertDateTime($val)',
@@ -160,5 +151,5 @@
 sub ProcessDV($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     local $_;
     my $raf = $$dirInfo{RAF};
@@ -180,8 +171,8 @@
     return 0 if $start + 80 * 6 > $len;
 
-    $exifTool->SetFileType();
+    $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;
 
@@ -195,5 +186,5 @@
             last;
         }
-        $profile or $exifTool->Warn("Unrecognized DV profile"), return 1;
+        $profile or $et->Warn("Unrecognized DV profile"), return 1;
     }
     my $tagTablePtr = GetTagTable('Image::ExifTool::DV::Main');
@@ -201,5 +192,5 @@
     # calculate total bit rate and duration
     my $byteRate = $$profile{FrameSize} * $$profile{FrameRate};
-    my $fileSize = $$exifTool{VALUE}{FileSize};
+    my $fileSize = $$et{VALUE}{FileSize};
     $$profile{TotalBitrate} = 8 * $byteRate;
     $$profile{Duration} = $fileSize / $byteRate if defined $fileSize;
@@ -208,5 +199,6 @@
     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;
@@ -220,4 +212,5 @@
                 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
@@ -245,5 +238,8 @@
     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';
+        }
     }
 
@@ -271,5 +267,5 @@
     foreach $tag (@dvTags) {
         next unless defined $$profile{$tag};
-        $exifTool->HandleTag($tagTablePtr, $tag, $$profile{$tag});
+        $et->HandleTag($tagTablePtr, $tag, $$profile{$tag});
     }
 
@@ -296,5 +292,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DarwinCore.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DarwinCore.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DarwinCore.pm	(revision 34921)
@@ -0,0 +1,381 @@
+#------------------------------------------------------------------------------
+# File:         DarwinCore.pm
+#
+# Description:  Darwin Core XMP tags
+#
+# Revisions:    2013-01-28 - P. Harvey Created
+#
+# References:   1) http://rs.tdwg.org/dwc/index.htm
+#               2) https://exiftool.org/forum/index.php/topic,4442.0/all.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::DarwinCore;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::XMP;
+
+$VERSION = '1.05';
+
+my %dateTimeInfo = (
+    # NOTE: Do NOT put "Groups" here because Groups hash must not be common!
+    Writable => 'date',
+    Shift => 'Time',
+    PrintConv => '$self->ConvertDateTime($val)',
+    PrintConvInv => '$self->InverseDateTime($val,undef,1)',
+);
+
+my %materialSample = (
+    STRUCT_NAME => 'DarwinCore MaterialSample',
+    NAMESPACE => 'dwc',
+    materialSampleID    => { },
+);
+
+my %event = (
+    STRUCT_NAME => 'DarwinCore Event',
+    NAMESPACE => 'dwc',
+    day                 => { Writable => 'integer', Groups => { 2 => 'Time' } },
+    earliestDate        => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+    endDayOfYear        => { Writable => 'integer', Groups => { 2 => 'Time' } },
+    eventDate           => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+    eventID             => { },
+    eventRemarks        => { Writable => 'lang-alt' },
+    eventTime => {
+        Groups => { 2 => 'Time' },
+        Writable => 'string', # (so we can format this ourself)
+        Shift => 'Time',
+        # (allow date/time or just time value)
+        ValueConv => 'Image::ExifTool::XMP::ConvertXMPDate($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+        ValueConvInv => 'Image::ExifTool::XMP::FormatXMPDate($val) or $val',
+        PrintConvInv => q{
+            my $v = $self->InverseDateTime($val,undef,1);
+            undef $Image::ExifTool::evalWarning;
+            return $v if $v;
+            # allow time-only values by adding dummy date (thanks Herb)
+            my $v = $self->InverseDateTime("2000:01:01 $val",undef,1);
+            undef $Image::ExifTool::evalWarning;
+            return $v if $v and $v =~ s/.* //;  # strip off dummy date
+            $Image::ExifTool::evalWarning = 'Invalid date/time or time-only value (use HH:MM:SS[.ss][+/-HH:MM|Z])';
+            return undef;
+        },
+    },
+    fieldNotes          => { },
+    fieldNumber         => { },
+    habitat             => { },
+    latestDate          => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+    month               => { Writable => 'integer', Groups => { 2 => 'Time' } },
+    parentEventID       => { },
+    samplingEffort      => { },
+    samplingProtocol    => { },
+    sampleSizeValue     => { },
+    sampleSizeUnit      => { },
+    startDayOfYear      => { Writable => 'integer', Groups => { 2 => 'Time' } },
+    verbatimEventDate   => { Groups => { 2 => 'Time' } },
+    year                => { Writable => 'integer', Groups => { 2 => 'Time' } },
+);
+
+# Darwin Core tags
+%Image::ExifTool::DarwinCore::Main = (
+    GROUPS    => { 0 => 'XMP', 1 => 'XMP-dwc', 2 => 'Other' },
+    NAMESPACE => 'dwc',
+    WRITABLE  => 'string',
+    NOTES => q{
+        Tags defined in the Darwin Core (dwc) XMP namespace.  See
+        L<http://rs.tdwg.org/dwc/index.htm> for the official specification.
+    },
+    Event => {
+        Name => 'DCEvent',  # (avoid conflict with XMP-iptcExt:Event)
+        FlatName => 'Event',
+        Struct => \%event,
+    },
+    # tweak a few of the flattened tag names
+    EventEventDate    => { Name => 'EventDate',     Flat => 1 },
+    EventEventID      => { Name => 'EventID',       Flat => 1 },
+    EventEventRemarks => { Name => 'EventRemarks',  Flat => 1 },
+    EventEventTime    => { Name => 'EventTime',     Flat => 1 },
+    FossilSpecimen    => { Struct => \%materialSample },
+    GeologicalContext => {
+        FlatName => '', # ('GeologicalContext' is too long)
+        Struct => {
+            STRUCT_NAME => 'DarwinCore GeologicalContext',
+            NAMESPACE => 'dwc',
+            bed                         => { },
+            earliestAgeOrLowestStage    => { },
+            earliestEonOrLowestEonothem => { },
+            earliestEpochOrLowestSeries => { },
+            earliestEraOrLowestErathem  => { },
+            earliestPeriodOrLowestSystem=> { },
+            formation                   => { },
+            geologicalContextID         => { },
+            group                       => { },
+            highestBiostratigraphicZone => { },
+            latestAgeOrHighestStage     => { },
+            latestEonOrHighestEonothem  => { },
+            latestEpochOrHighestSeries  => { },
+            latestEraOrHighestErathem   => { },
+            latestPeriodOrHighestSystem => { },
+            lithostratigraphicTerms     => { },
+            lowestBiostratigraphicZone  => { },
+            member                      => { },
+        },
+    },
+    GeologicalContextBed        => { Name => 'GeologicalContextBed',        Flat => 1 },
+    GeologicalContextFormation  => { Name => 'GeologicalContextFormation',  Flat => 1 },
+    GeologicalContextGroup      => { Name => 'GeologicalContextGroup',      Flat => 1 },
+    GeologicalContextMember     => { Name => 'GeologicalContextMember',     Flat => 1 },
+    HumanObservation => { Struct => \%event },
+    Identification => {
+        FlatName => '', # ('Identification' is redundant)
+        Struct => {
+            STRUCT_NAME => 'DarwinCore Identification',
+            NAMESPACE => 'dwc',
+            dateIdentified              => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+            identificationID            => { },
+            identificationQualifier     => { },
+            identificationReferences    => { },
+            identificationRemarks       => { },
+            identificationVerificationStatus => { },
+            identifiedBy                => { },
+            typeStatus                  => { },
+        },
+    },
+    LivingSpecimen      => { Struct => \%materialSample },
+    MachineObservation  => { Struct => \%event },
+    MaterialSample      => { Struct => \%materialSample },
+    MaterialSampleMaterialSampleID => { Name => 'MaterialSampleID', Flat => 1 },
+    MeasurementOrFact => {
+        FlatName => '', # ('MeasurementOrFact' is redundant and too long)
+        Struct => {
+            STRUCT_NAME => 'DarwinCore MeasurementOrFact',
+            NAMESPACE => 'dwc',
+            measurementAccuracy         => { Format => 'real' },
+            measurementDeterminedBy     => { },
+            measurementDeterminedDate   => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+            measurementID               => { },
+            measurementMethod           => { },
+            measurementRemarks          => { },
+            measurementType             => { },
+            measurementUnit             => { },
+            measurementValue            => { },
+        },
+    },
+    Occurrence => {
+        Struct => {
+            STRUCT_NAME => 'DarwinCore Occurrence',
+            NAMESPACE => 'dwc',
+            associatedMedia             => { },
+            associatedOccurrences       => { },
+            associatedReferences        => { },
+            associatedSequences         => { },
+            associatedTaxa              => { },
+            behavior                    => { },
+            catalogNumber               => { },
+            disposition                 => { },
+            establishmentMeans          => { },
+            individualCount             => { },
+            individualID                => { },
+            lifeStage                   => { },
+            occurrenceDetails           => { },
+            occurrenceID                => { },
+            occurrenceRemarks           => { },
+            occurrenceStatus            => { },
+            organismQuantity            => { },
+            organismQuantityType        => { },
+            otherCatalogNumbers         => { },
+            preparations                => { },
+            previousIdentifications     => { },
+            recordedBy                  => { },
+            recordNumber                => { },
+            reproductiveCondition       => { },
+            sex                         => { },
+        },
+    },
+    OccurrenceOccurrenceDetails => { Name => 'OccurrenceDetails', Flat => 1 },
+    OccurrenceOccurrenceID      => { Name => 'OccurrenceID',      Flat => 1 },
+    OccurrenceOccurrenceRemarks => { Name => 'OccurrenceRemarks', Flat => 1 },
+    OccurrenceOccurrenceStatus  => { Name => 'OccurrenceStatus',  Flat => 1 },
+    Organism => {
+        Struct => {
+            STRUCT_NAME => 'DarwinCore Organism',
+            NAMESPACE => 'dwc',
+            associatedOccurrences       => { },
+            associatedOrganisms         => { },
+            organismID                  => { },
+            organismName                => { },
+            organismRemarks             => { },
+            organismScope               => { },
+            previousIdentifications     => { },
+        },
+    },
+    OrganismOrganismID      => { Name => 'OrganismID',      Flat => 1 },
+    OrganismOrganismName    => { Name => 'OrganismName',    Flat => 1 },
+    OrganismOrganismRemarks => { Name => 'OrganismRemarks', Flat => 1 },
+    OrganismOrganismScope   => { Name => 'OrganismScope',   Flat => 1 },
+    PreservedSpecimen       => { Struct => \%materialSample },
+    Record => {
+        Struct => {
+            STRUCT_NAME => 'DarwinCore Record',
+            NAMESPACE => 'dwc',
+            basisOfRecord               => { },
+            collectionCode              => { },
+            collectionID                => { },
+            dataGeneralizations         => { },
+            datasetID                   => { },
+            datasetName                 => { },
+            dynamicProperties           => { },
+            informationWithheld         => { },
+            institutionCode             => { },
+            institutionID               => { },
+            ownerInstitutionCode        => { },
+        },
+    },
+    ResourceRelationship => {
+        FlatName => '', # ('ResourceRelationship' is redundant and too long)
+        Struct => {
+            STRUCT_NAME => 'DarwinCore ResourceRelationship',
+            NAMESPACE => 'dwc',
+            relatedResourceID           => { },
+            relationshipAccordingTo     => { },
+            relationshipEstablishedDate => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+            relationshipOfResource      => { },
+            relationshipRemarks         => { },
+            resourceID                  => { },
+            resourceRelationshipID      => { },
+        },
+    },
+    Taxon => {
+        Struct => {
+            STRUCT_NAME => 'DarwinCore Taxon',
+            NAMESPACE => 'dwc',
+            acceptedNameUsage           => { },
+            acceptedNameUsageID         => { },
+            class                       => { },
+            family                      => { },
+            genus                       => { },
+            higherClassification        => { },
+            infraspecificEpithet        => { },
+            kingdom                     => { },
+            nameAccordingTo             => { },
+            nameAccordingToID           => { },
+            namePublishedIn             => { },
+            namePublishedInID           => { },
+            namePublishedInYear         => { },
+            nomenclaturalCode           => { },
+            nomenclaturalStatus         => { },
+            order                       => { },
+            originalNameUsage           => { },
+            originalNameUsageID         => { },
+            parentNameUsage             => { },
+            parentNameUsageID           => { },
+            phylum                      => { },
+            scientificName              => { },
+            scientificNameAuthorship    => { },
+            scientificNameID            => { },
+            specificEpithet             => { },
+            subgenus                    => { },
+            taxonConceptID              => { },
+            taxonID                     => { },
+            taxonRank                   => { },
+            taxonRemarks                => { },
+            taxonomicStatus             => { },
+            verbatimTaxonRank           => { },
+            vernacularName              => { Writable => 'lang-alt' },
+        },
+    },
+    TaxonTaxonConceptID => { Name => 'TaxonConceptID',  Flat => 1 },
+    TaxonTaxonID        => { Name => 'TaxonID',         Flat => 1 },
+    TaxonTaxonRank      => { Name => 'TaxonRank',       Flat => 1 },
+    TaxonTaxonRemarks   => { Name => 'TaxonRemarks',    Flat => 1 },
+    dctermsLocation => {
+        Name => 'DCTermsLocation',
+        Groups => { 2 => 'Location' },
+        FlatName => 'DC', # ('dctermsLocation' is too long)
+        Struct => {
+            STRUCT_NAME => 'DarwinCore DCTermsLocation',
+            NAMESPACE => 'dwc',
+            continent                   => { },
+            coordinatePrecision         => { },
+            coordinateUncertaintyInMeters => { },
+            country                     => { },
+            countryCode                 => { },
+            county                      => { },
+            decimalLatitude             => { },
+            decimalLongitude            => { },
+            footprintSpatialFit         => { },
+            footprintSRS                => { },
+            footprintWKT                => { },
+            geodeticDatum               => { },
+            georeferencedBy             => { },
+            georeferencedDate           => { },
+            georeferenceProtocol        => { },
+            georeferenceRemarks         => { },
+            georeferenceSources         => { },
+            georeferenceVerificationStatus => { },
+            higherGeography             => { },
+            higherGeographyID           => { },
+            island                      => { },
+            islandGroup                 => { },
+            locality                    => { },
+            locationAccordingTo         => { },
+            locationID                  => { },
+            locationRemarks             => { },
+            maximumDepthInMeters        => { },
+            maximumDistanceAboveSurfaceInMeters => { },
+            maximumElevationInMeters    => { },
+            minimumDepthInMeters        => { },
+            minimumDistanceAboveSurfaceInMeters => { },
+            minimumElevationInMeters    => { },
+            municipality                => { },
+            pointRadiusSpatialFit       => { },
+            stateProvince               => { },
+            verbatimCoordinates         => { },
+            verbatimCoordinateSystem    => { },
+            verbatimDepth               => { },
+            verbatimElevation           => { },
+            verbatimLatitude            => { },
+            verbatimLocality            => { },
+            verbatimLongitude           => { },
+            verbatimSRS                 => { },
+            waterBody                   => { },
+        },
+    },
+);
+
+1;  #end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::DarwinCore - Darwin Core XMP tags
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This file contains tag definitions for the Darwin Core XMP namespace.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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://rs.tdwg.org/dwc/index.htm>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/XMP Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DjVu.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DjVu.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/DjVu.pm	(revision 34921)
@@ -19,5 +19,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.03';
+$VERSION = '1.06';
 
 sub ParseAnt($);
@@ -29,5 +29,8 @@
 %Image::ExifTool::DjVu::Main = (
     GROUPS => { 2 => 'Image' },
-    NOTES => 'Information is extracted from the following chunks in DjVu images.',
+    NOTES => q{
+        Information is extracted from the following chunks in DjVu images. See
+        L<http://www.djvu.org/> for the DjVu specification.
+    },
     INFO => {
         SubDirectory => { TagTable => 'Image::ExifTool::DjVu::Info' },
@@ -136,5 +139,5 @@
         documentation endorses tags borrowed from two standards: 1) BibTeX
         bibliography system tags (all lowercase Tag ID's in the table below), and 2)
-        PDF DocInfo tags (uppercase Tag ID's).
+        PDF DocInfo tags (capitalized Tag ID's).
     },
     # BibTeX tags (ref http://en.wikipedia.org/wiki/BibTeX)
@@ -225,4 +228,6 @@
                 $tok .= '"';    # quote is part of the string
             }
+            # must protect unescaped "$" and "@" symbols, and "\" at end of string
+            $tok =~ s{\\(.)|([\$\@]|\\$)}{'\\'.($2 || $1)}sge;
             # convert C escape sequences (allowed in quoted text)
             $tok = eval qq{"$tok"};
@@ -231,6 +236,5 @@
             # 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;
@@ -247,5 +251,5 @@
 sub ProcessAnt($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
 
@@ -265,8 +269,8 @@
         if ($tag eq 'metadata') {
             # ProcessMeta() takes array reference
-            $exifTool->HandleTag($tagTablePtr, $tag, $ant);
+            $et->HandleTag($tagTablePtr, $tag, $ant);
         } else {
             next if ref $$ant[0];   # only process simple values
-            $exifTool->HandleTag($tagTablePtr, $tag, $$ant[0]);
+            $et->HandleTag($tagTablePtr, $tag, $$ant[0]);
         }
     }
@@ -281,8 +285,8 @@
 sub ProcessMeta($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     return 0 unless ref $$dataPt eq 'ARRAY';
-    $exifTool->VerboseDir('Metadata', scalar @$$dataPt);
+    $et->VerboseDir('Metadata', scalar @$$dataPt);
     my ($item, $err);
     foreach $item (@$$dataPt) {
@@ -295,9 +299,9 @@
             $name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
             length $name or $err = 1, next;
-            Image::ExifTool::AddTagToTable($tagTablePtr, $$item[0], { Name => ucfirst($name) });
+            AddTagToTable($tagTablePtr, $$item[0], { Name => ucfirst($name) });
         }
-        $exifTool->HandleTag($tagTablePtr, $$item[0], $$item[1]);
-    }
-    $err and $exifTool->Warn('Ignored invalid metadata entry(s)');
+        $et->HandleTag($tagTablePtr, $$item[0], $$item[1]);
+    }
+    $err and $et->Warn('Ignored invalid metadata entry(s)');
     return 1;
 }
@@ -309,16 +313,16 @@
 sub ProcessBZZ($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     require Image::ExifTool::BZZ;
     my $buff = Image::ExifTool::BZZ::Decode($$dirInfo{DataPt});
     unless (defined $buff) {
-        $exifTool->Warn("Error decoding $$dirInfo{DirName}");
+        $et->Warn("Error decoding $$dirInfo{DirName}");
         return 0;
     }
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     if ($verbose >= 3) {
         # dump the decoded data in very verbose mode
-        $exifTool->VerboseDir("Decoded $$dirInfo{DirName}", 0, length $buff);
-        $exifTool->VerboseDump(\$buff);
+        $et->VerboseDir("Decoded $$dirInfo{DirName}", 0, length $buff);
+        $et->VerboseDump(\$buff);
     }
     $$dirInfo{DataPt} = \$buff;
@@ -326,5 +330,5 @@
     # process the data using the default process proc for this table
     my $processProc = $$tagTablePtr{PROCESS_PROC} or return 0;
-    return &$processProc($exifTool, $dirInfo, $tagTablePtr);
+    return &$processProc($et, $dirInfo, $tagTablePtr);
 }
 
@@ -349,5 +353,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/EXE.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/EXE.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/EXE.pm	(revision 34921)
@@ -5,4 +5,5 @@
 #
 # Revisions:    2008/08/28 - P. Harvey Created
+#               2011/07/12 - P. Harvey Added CHM (ok, not EXE, but it fits here)
 #
 # References:   1) http://www.openwatcom.org/ftp/devel/docs/pecoff.pdf
@@ -21,5 +22,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.04';
+$VERSION = '1.17';
 
 sub ProcessPEResources($$);
@@ -49,4 +50,124 @@
     23 => 'HTML',
     24 => 'Manifest',
+);
+
+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',
+    '0401' => 'Arabic',
+    '0402' => 'Bulgarian',
+    '0403' => 'Catalan',
+    '0404' => 'Chinese (Traditional)',
+    '0405' => 'Czech',
+    '0406' => 'Danish',
+    '0407' => 'German',
+    '0408' => 'Greek',
+    '0409' => 'English (U.S.)',
+    '040A' => 'Spanish (Castilian)',
+    '040B' => 'Finnish',
+    '040C' => 'French',
+    '040D' => 'Hebrew',
+    '040E' => 'Hungarian',
+    '040F' => 'Icelandic',
+    '0410' => 'Italian',
+    '0411' => 'Japanese',
+    '0412' => 'Korean',
+    '0413' => 'Dutch',
+    '0414' => 'Norwegian (Bokml)',
+    '0415' => 'Polish',
+    '0416' => 'Portuguese (Brazilian)',
+    '0417' => 'Rhaeto-Romanic',
+    '0418' => 'Romanian',
+    '0419' => 'Russian',
+    '041A' => 'Croato-Serbian (Latin)',
+    '041B' => 'Slovak',
+    '041C' => 'Albanian',
+    '041D' => 'Swedish',
+    '041E' => 'Thai',
+    '041F' => 'Turkish',
+    '0420' => 'Urdu',
+    # 0421-0493 ref 6
+    '0421' => 'Indonesian',
+    '0422' => 'Ukrainian',
+    '0423' => 'Belarusian',
+    '0424' => 'Slovenian',
+    '0425' => 'Estonian',
+    '0426' => 'Latvian',
+    '0427' => 'Lithuanian',
+    '0428' => 'Maori',
+    '0429' => 'Farsi',
+    '042a' => 'Vietnamese',
+    '042b' => 'Armenian',
+    '042c' => 'Azeri',
+    '042d' => 'Basque',
+    '042e' => 'Sorbian',
+    '042f' => 'Macedonian',
+    '0430' => 'Sutu',
+    '0431' => 'Tsonga',
+    '0432' => 'Tswana',
+    '0433' => 'Venda',
+    '0434' => 'Xhosa',
+    '0435' => 'Zulu',
+    '0436' => 'Afrikaans',
+    '0437' => 'Georgian',
+    '0438' => 'Faeroese',
+    '0439' => 'Hindi',
+    '043a' => 'Maltese',
+    '043b' => 'Saami',
+    '043c' => 'Gaelic',
+    '043e' => 'Malay',
+    '043f' => 'Kazak',
+    '0440' => 'Kyrgyz',
+    '0441' => 'Swahili',
+    '0443' => 'Uzbek',
+    '0444' => 'Tatar',
+    '0445' => 'Bengali',
+    '0446' => 'Punjabi',
+    '0447' => 'Gujarati',
+    '0448' => 'Oriya',
+    '0449' => 'Tamil',
+    '044a' => 'Telugu',
+    '044b' => 'Kannada',
+    '044c' => 'Malayalam',
+    '044d' => 'Assamese',
+    '044e' => 'Marathi',
+    '044f' => 'Sanskrit',
+    '0450' => 'Mongolian',
+    '0456' => 'Galician',
+    '0457' => 'Konkani',
+    '0458' => 'Manipuri',
+    '0459' => 'Sindhi',
+    '045a' => 'Syriac',
+    '0460' => 'Kashmiri',
+    '0461' => 'Nepali',
+    '0465' => 'Divehi',
+    '047f' => 'Invariant',
+    '048f' => 'Esperanto',
+    '0490' => 'Walon',
+    '0491' => 'Cornish',
+    '0492' => 'Welsh',
+    '0493' => 'Breton',
+    '0800' => 'Neutral 2',
+    '0804' => 'Chinese (Simplified)',
+    '0807' => 'German (Swiss)',
+    '0809' => 'English (British)',
+    '080A' => 'Spanish (Mexican)',
+    '080C' => 'French (Belgian)',
+    '0810' => 'Italian (Swiss)',
+    '0813' => 'Dutch (Belgian)',
+    '0814' => 'Norwegian (Nynorsk)',
+    '0816' => 'Portuguese',
+    '081A' => 'Serbo-Croatian (Cyrillic)',
+    '0C07' => 'German (Austrian)',
+    '0C09' => 'English (Australian)',
+    '0C0A' => 'Spanish (Modern)',
+    '0C0C' => 'French (Canadian)',
+    '1009' => 'English (Canadian)',
+    '100C' => 'French (Swiss)',
 );
 
@@ -102,8 +223,30 @@
         PrintConv => '$self->ConvertDateTime($val)',
     },
+    9 => {
+        Name => 'ImageFileCharacteristics',
+        # ref https://docs.microsoft.com/en-us/windows/desktop/api/winnt/ns-winnt-_image_file_header
+        PrintConv => { BITMASK => {
+            0 => 'No relocs',
+            1 => 'Executable',
+            2 => 'No line numbers',
+            3 => 'No symbols',
+            4 => 'Aggressive working-set trim',
+            5 => 'Large address aware',
+            7 => 'Bytes reversed lo',
+            8 => '32-bit',
+            9 => 'No debug',
+            10 => 'Removable run from swap',
+            11 => 'Net run from swap',
+            12 => 'System file',
+            13 => 'DLL',
+            14 => 'Uniprocessor only',
+            15 => 'Bytes reversed hi',
+        }},
+    },
     10 => {
         Name => 'PEType',
         PrintHex => 1,
         PrintConv => {
+            0x107 => 'ROM Image',
             0x10b => 'PE32',
             0x20b => 'PE32+',
@@ -154,5 +297,5 @@
             2 => 'Windows GUI',
             3 => 'Windows command line',
-            5 => 'OS/2 Command line', #5
+            5 => 'OS/2 command line', #5
             7 => 'POSIX command line',
             9 => 'Windows CE GUI',
@@ -259,5 +402,5 @@
     },
     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)
@@ -265,119 +408,6 @@
         # (not a complete set)
         PrintString => 1,
-        PrintConv => {
-            '0000' => 'Neutral',
-            '007F' => 'Invariant',
-            '0400' => 'Process default',
-            '0401' => 'Arabic',
-            '0402' => 'Bulgarian',
-            '0403' => 'Catalan',
-            '0404' => 'Chinese (Traditional)',
-            '0405' => 'Czech',
-            '0406' => 'Danish',
-            '0407' => 'German',
-            '0408' => 'Greek',
-            '0409' => 'English (U.S.)',
-            '040A' => 'Spanish (Castilian)',
-            '040B' => 'Finnish',
-            '040C' => 'French',
-            '040D' => 'Hebrew',
-            '040E' => 'Hungarian',
-            '040F' => 'Icelandic',
-            '0410' => 'Italian',
-            '0411' => 'Japanese',
-            '0412' => 'Korean',
-            '0413' => 'Dutch',
-            '0414' => 'Norwegian (Bokml)',
-            '0415' => 'Polish',
-            '0416' => 'Portuguese (Brazilian)',
-            '0417' => 'Rhaeto-Romanic',
-            '0418' => 'Romanian',
-            '0419' => 'Russian',
-            '041A' => 'Croato-Serbian (Latin)',
-            '041B' => 'Slovak',
-            '041C' => 'Albanian',
-            '041D' => 'Swedish',
-            '041E' => 'Thai',
-            '041F' => 'Turkish',
-            '0420' => 'Urdu',
-            # 0421-0493 ref 6
-            '0421' => 'Indonesian',
-            '0422' => 'Ukrainian',
-            '0423' => 'Belarusian',
-            '0424' => 'Slovenian',
-            '0425' => 'Estonian',
-            '0426' => 'Latvian',
-            '0427' => 'Lithuanian',
-            '0428' => 'Maori',
-            '0429' => 'Farsi',
-            '042a' => 'Vietnamese',
-            '042b' => 'Armenian',
-            '042c' => 'Azeri',
-            '042d' => 'Basque',
-            '042e' => 'Sorbian',
-            '042f' => 'Macedonian',
-            '0430' => 'Sutu',
-            '0431' => 'Tsonga',
-            '0432' => 'Tswana',
-            '0433' => 'Venda',
-            '0434' => 'Xhosa',
-            '0435' => 'Zulu',
-            '0436' => 'Afrikaans',
-            '0437' => 'Georgian',
-            '0438' => 'Faeroese',
-            '0439' => 'Hindi',
-            '043a' => 'Maltese',
-            '043b' => 'Saami',
-            '043c' => 'Gaelic',
-            '043e' => 'Malay',
-            '043f' => 'Kazak',
-            '0440' => 'Kyrgyz',
-            '0441' => 'Swahili',
-            '0443' => 'Uzbek',
-            '0444' => 'Tatar',
-            '0445' => 'Bengali',
-            '0446' => 'Punjabi',
-            '0447' => 'Gujarati',
-            '0448' => 'Oriya',
-            '0449' => 'Tamil',
-            '044a' => 'Telugu',
-            '044b' => 'Kannada',
-            '044c' => 'Malayalam',
-            '044d' => 'Assamese',
-            '044e' => 'Marathi',
-            '044f' => 'Sanskrit',
-            '0450' => 'Mongolian',
-            '0456' => 'Galician',
-            '0457' => 'Konkani',
-            '0458' => 'Manipuri',
-            '0459' => 'Sindhi',
-            '045a' => 'Syriac',
-            '0460' => 'Kashmiri',
-            '0461' => 'Nepali',
-            '0465' => 'Divehi',
-            '047f' => 'Invariant',
-            '048f' => 'Esperanto',
-            '0490' => 'Walon',
-            '0491' => 'Cornish',
-            '0492' => 'Welsh',
-            '0493' => 'Breton',
-            '0800' => 'Neutral 2',
-            '0804' => 'Chinese (Simplified)',
-            '0807' => 'German (Swiss)',
-            '0809' => 'English (British)',
-            '080A' => 'Spanish (Mexican)',
-            '080C' => 'French (Belgian)',
-            '0810' => 'Italian (Swiss)',
-            '0813' => 'Dutch (Belgian)',
-            '0814' => 'Norwegian (Nynorsk)',
-            '0816' => 'Portuguese',
-            '081A' => 'Serbo-Croatian (Cyrillic)',
-            '0C07' => 'German (Austrian)',
-            '0C09' => 'English (Australian)',
-            '0C0A' => 'Spanish (Modern)',
-            '0C0C' => 'French (Canadian)',
-            '1009' => 'English (Canadian)',
-            '100C' => 'French (Swiss)',
-        },
+        SeparateTable => 1,
+        PrintConv => \%languageCode,
     },
     CharacterSet => {
@@ -412,5 +442,5 @@
     LegalCopyright  => { },
     LegalTrademarks => { },
-    OriginalFilename=> { },
+    OriginalFilename=> { Name => 'OriginalFileName' },
     PrivateBuild    => { },
     ProductName     => { },
@@ -595,5 +625,37 @@
             8 => 'Dynamically bound bundle',
             9 => 'Shared library stub for static linking',
+            # (the following from Apple loader.h header file)
+            10 => 'Debug information',
+            11 => 'x86_64 kexts',
         },
+    },
+    6 => {
+        Name => 'ObjectFlags',
+        PrintHex => 1,
+        # ref Apple loader.h header file
+        PrintConv => { BITMASK => {
+             0 => 'No undefs',
+             1 => 'Incrementa link',
+             2 => 'Dyld link',
+             3 => 'Bind at load',
+             4 => 'Prebound',
+             5 => 'Split segs',
+             6 => 'Lazy init',
+             7 => 'Two level',
+             8 => 'Force flat',
+             9 => 'No multi defs',
+             10 => 'No fix prebinding',
+             11 => 'Prebindable',
+             12 => 'All mods bound',
+             13 => 'Subsections via symbols',
+             14 => 'Canonical',
+             15 => 'Weak defines',
+             16 => 'Binds to weak',
+             17 => 'Allow stack execution',
+             18 => 'Dead strippable dylib',
+             19 => 'Root safe',
+             20 => 'No reexported dylibs',
+             21 => 'Random address',
+        }},
     },
 );
@@ -699,15 +761,75 @@
 );
 
+# Information extracted from static library archives
+# (ref http://opensource.apple.com//source/xnu/xnu-1456.1.26/EXTERNAL_HEADERS/ar.h)
+%Image::ExifTool::EXE::AR = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Other' },
+    NOTES => q{
+        Information extracted from static libraries.
+    },
+  #  0  string[16] ar_name
+    16 => {
+        Name => 'CreateDate',
+        Groups => { 2 => 'Time' },
+        Format => 'string[12]',
+        ValueConv => 'ConvertUnixTime($val,1)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+  # 28  string[6]  ar_uid
+  # 34  string[6]  ar_gid
+  # 40  string[8]  ar_mode
+  # 48  string[10] ar_size
+  # 58  string[2]  terminator "`\n"
+);
+
+# Microsoft compiled help format (ref http://www.russotto.net/chm/chmformat.html)
+%Image::ExifTool::EXE::CHM = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Other' },
+    NOTES => 'Tags extracted from Microsoft Compiled HTML files.',
+    FORMAT => 'int32u',
+    1 => { Name => 'CHMVersion' },
+    # 2 - total header length
+    # 3 - 1
+    # 4 - low bits of date/time value plus 42 (ref http://www.nongnu.org/chmspec/latest/ITSF.html)
+    5 => {
+        Name => 'LanguageCode',
+        SeparateTable => 1,
+        ValueConv => 'sprintf("%.4X", $val)',
+        PrintConv => \%languageCode,
+    },
+);
+
+#------------------------------------------------------------------------------
+# Extract information from a CHM file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid CHM file
+sub ProcessCHM($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    return 0 unless $raf->Read($buff, 56) == 56 and
+        $buff =~ /^ITSF.{20}\x10\xfd\x01\x7c\xaa\x7b\xd0\x11\x9e\x0c\0\xa0\xc9\x22\xe6\xec/s;
+    my $tagTablePtr = GetTagTable('Image::ExifTool::EXE::CHM');
+    $et->SetFileType();
+    SetByteOrder('II');
+    $et->ProcessDirectory({ DataPt => \$buff }, $tagTablePtr);
+    return 1;
+}
+
 #------------------------------------------------------------------------------
 # Read Unicode string (null terminated) from resource
-# Inputs: 0) data ref, 1) start offset, 2) optional ExifTool object ref
+# Inputs: 0) data ref, 1) start offset, 2) data end, 3) optional ExifTool object ref
 # Returns: 0) Unicode string translated to UTF8, or current CharSet with ExifTool ref
 #          1) end pos (rounded up to nearest 4 bytes)
-sub ReadUnicodeStr($$;$)
+sub ReadUnicodeStr($$$;$)
 {
-    my ($dataPt, $pos, $exifTool) = @_;
-    my $len = length $$dataPt;
+    my ($dataPt, $pos, $end, $et) = @_;
+    $end = length $$dataPt if $end > length $$dataPt;   # (be safe)
     my $str = '';
-    while ($pos + 2 <= $len) {
+    while ($pos + 2 <= $end) {
         my $ch = substr($$dataPt, $pos, 2);
         $pos += 2;
@@ -716,5 +838,5 @@
     }
     $pos += 2 if $pos & 0x03;
-    my $to = $exifTool ? $exifTool->Options('Charset') : 'UTF8';
+    my $to = $et ? $et->Options('Charset') : 'UTF8';
     return (Image::ExifTool::Decode(undef,$str,'UCS2','II',$to), $pos);
 }
@@ -726,5 +848,5 @@
 sub ProcessPEVersion($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart};
@@ -740,8 +862,8 @@
         $type = Get16u($dataPt, $pos + 4);
         return 0 unless $len or $valLen;  # prevent possible infinite loop
-        ($string, $strEnd) = ReadUnicodeStr($dataPt, $pos + 6);
+        ($string, $strEnd) = ReadUnicodeStr($dataPt, $pos + 6, $pos + $len);
         return 0 if $strEnd + $valLen > $end;
         unless ($index or $string eq 'VS_VERSION_INFO') {
-            $exifTool->Warn('Invalid Version Info block');
+            $et->Warn('Invalid Version Info block');
             return 0;
         }
@@ -751,5 +873,5 @@
             $$dirInfo{DirLen} = $valLen;
             my $subTablePtr = GetTagTable('Image::ExifTool::EXE::PEVersion');
-            $exifTool->ProcessDirectory($dirInfo, $subTablePtr);
+            $et->ProcessDirectory($dirInfo, $subTablePtr);
             $pos = $strEnd + $valLen;
         } elsif ($string eq 'StringFileInfo' and $valLen == 0) {
@@ -762,6 +884,7 @@
                 $valLen = Get16u($dataPt, $pt + 2);
                 # $type = Get16u($dataPt, $pt + 4);
+                my $entryEnd = $pt + $len;
                 # get tag ID (converted to UTF8)
-                ($string, $pt) = ReadUnicodeStr($dataPt, $pt + 6);
+                ($string, $pt) = ReadUnicodeStr($dataPt, $pt + 6, $entryEnd);
                 unless ($index) {
                     # separate the language code and character set
@@ -774,6 +897,6 @@
                         $string = substr($string, 0, 4);
                     }
-                    $exifTool->HandleTag($tagTablePtr, 'LanguageCode', uc $string);
-                    $exifTool->HandleTag($tagTablePtr, 'CharacterSet', uc $char) if $char;
+                    $et->HandleTag($tagTablePtr, 'LanguageCode', uc $string);
+                    $et->HandleTag($tagTablePtr, 'CharacterSet', uc $char) if $char;
                     next;
                 }
@@ -784,13 +907,15 @@
                     $name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
                     next unless length $name;
-                    Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
+                    AddTagToTable($tagTablePtr, $tag, { Name => $name });
                 }
                 # get tag value (converted to current Charset)
                 if ($valLen) {
-                    ($string, $pt) = ReadUnicodeStr($dataPt, $pt, $exifTool);
+                    ($string, $pt) = ReadUnicodeStr($dataPt, $pt, $entryEnd, $et);
                 } else {
                     $string = '';
                 }
-                $exifTool->HandleTag($tagTablePtr, $tag, $string);
+                $et->HandleTag($tagTablePtr, $tag, $string);
+                # step to next entry (padded to an even word)
+                $pt = ($entryEnd + 3) & 0xfffffffc;
             }
         } else {
@@ -808,10 +933,10 @@
 sub ProcessPEResources($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $base = $$dirInfo{Base};
     my $dirStart = $$dirInfo{DirStart} + $base;
     my $level = $$dirInfo{Level} || 0;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my ($buff, $buf2, $item);
 
@@ -833,5 +958,5 @@
             # ignore everything but the Version resource unless verbose
             if ($verbose) {
-                $exifTool->VPrint(0, "$resType resource:\n");
+                $et->VPrint(0, "$resType resource:\n");
             } else {
                 next unless $resType eq 'Version';
@@ -843,5 +968,5 @@
             $$dirInfo{DirStart} = $entryPos & 0x7fffffff;
             $$dirInfo{Level} = $level + 1;
-            ProcessPEResources($exifTool, $dirInfo) or return 0;
+            ProcessPEResources($et, $dirInfo) or return 0;
             --$$dirInfo{Level};
         } elsif ($$dirInfo{ResType} eq 'Version' and $level == 2 and
@@ -863,10 +988,10 @@
             return 0 unless $filePos;
             $raf->Seek($filePos, 0) and $raf->Read($buf2, $len) == $len or return 0;
-            ProcessPEVersion($exifTool, {
+            ProcessPEVersion($et, {
                 DataPt   => \$buf2,
                 DataLen  => $len,
                 DirStart => 0,
                 DirLen   => $len,
-            }) or $exifTool->Warn('Possibly corrupt Version resource');
+            }) or $et->Warn('Possibly corrupt Version resource');
             $$dirInfo{GotVersion} = 1;  # set flag so we don't do this again
         }
@@ -881,9 +1006,9 @@
 sub ProcessPEDict($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = length($$dataPt);
-    my ($pos, @sections, %dirInfo);
+    my ($pos, @sections, %dirInfo, $rsrcFound);
 
     # loop through all sections
@@ -895,5 +1020,7 @@
         # remember the section offsets for the VirtualAddress lookup later
         push @sections, { Base => $offset, Size => $size, VirtualAddress => $va };
-        # save details of the first resource section
+        # save details of the first resource section (or .text if .rsrc not found, ref forum11465)
+        next unless ($name eq ".rsrc\0\0\0" and not $rsrcFound and defined($rsrcFound = 1)) or
+                    ($name eq ".text\0\0\0" and not %dirInfo);
         %dirInfo = (
             RAF      => $raf,
@@ -902,9 +1029,77 @@
             DirLen   => $size,
             Sections => \@sections,
-        ) if $name eq ".rsrc\0\0\0" and not %dirInfo;
+        );
     }
     # process the first resource section
-    ProcessPEResources($exifTool, \%dirInfo) or return 0 if %dirInfo;
+    ProcessPEResources($et, \%dirInfo) or return 0 if %dirInfo;
     return 1;
+}
+
+#------------------------------------------------------------------------------
+# Override file type if necessary for Mach object files and libraries
+# Inputs: 0) ExifTool ref, 1) ObjectFileType number, 2) flag for fat binary
+my %machOverride = (
+    1 => [ 'object file', 'O' ],
+    6 => [ 'dynamic link library', 'DYLIB' ],
+    8 => [ 'dynamic bound bundle', 'DYLIB' ],
+    9 => [ 'dynamic link library stub', 'DYLIB' ],
+);
+sub MachOverride($$;$)
+{
+    my ($et, $objType, $fat) = @_;
+    my $override = $machOverride{$objType};
+    if ($override) {
+        my $desc = 'Mach-O ' . ($fat ? 'fat ' : '') . $$override[0];
+        $et->OverrideFileType($desc, undef, $$override[1]);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Extract tags from Mach header
+# Inputs: 0) ExifTool ref, 1) data ref, 2) flag to extract object type
+# Returns: true if Mach header was found
+# Mach type based on magic number
+# [bit depth, byte order starting with "Little" or "Big"]
+my %machType = (
+    "\xfe\xed\xfa\xce" => ['32 bit', 'Big endian'],
+    "\xce\xfa\xed\xfe" => ['32 bit', 'Little endian'],
+    "\xfe\xed\xfa\xcf" => ['64 bit', 'Big endian'],
+    "\xcf\xfa\xed\xfe" => ['64 bit', 'Little endian'],
+);
+sub ExtractMachTags($$;$)
+{
+    my ($et, $dataPt, $doObj) = @_;
+    # get information about mach header based on the magic number (first 4 bytes)
+    my $info = $machType{substr($$dataPt, 0, 4)};
+    if ($info) {
+        # Mach header structure:
+        #  0 int32u magic
+        #  4 int32u cputype
+        #  8 int32u cpusubtype
+        # 12 int32u filetype
+        # 16 int32u ncmds
+        # 20 int32u sizeofcmds
+        # 24 int32u flags
+        my $tagTablePtr = GetTagTable('Image::ExifTool::EXE::MachO');
+        SetByteOrder($$info[1]);
+        my $cpuType = Get32s($dataPt, 4);
+        my $subType = Get32s($dataPt, 8);
+        $et->HandleTag($tagTablePtr, 0, $$info[0]);
+        $et->HandleTag($tagTablePtr, 1, $$info[1]);
+        $et->HandleTag($tagTablePtr, 3, $cpuType);
+        $et->HandleTag($tagTablePtr, 4, "$cpuType $subType");
+        if ($doObj) {
+            my $objType = Get32u($dataPt, 12);
+            my $flags = Get32u($dataPt, 24);
+            $et->HandleTag($tagTablePtr, 5, $objType);
+            $et->HandleTag($tagTablePtr, 6, $flags);
+            # override file type if this is an object file or library
+            MachOverride($et, $objType);
+        } else { # otherwise this was a static library
+            $et->OverrideFileType('Mach-O static library', undef, 'A');
+        }
+        return 1;
+    }
+    return 0;
 }
 
@@ -915,9 +1110,10 @@
 sub ProcessEXE($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my ($buff, $buf2, $type, $tagTablePtr, %dirInfo);
+    my ($buff, $buf2, $type, $mime, $ext, $tagTablePtr, %dirInfo);
 
     my $size = $raf->Read($buff, 0x40) or return 0;
+    my $fast3 = $$et{OPTIONS}{FastScan} && $$et{OPTIONS}{FastScan} == 3;
 #
 # DOS and Windows EXE
@@ -927,38 +1123,39 @@
         # validate DOS header
         # (ref http://www.delphidabbler.com/articles?article=8&part=2)
-        #   0  magic   : int16u    # Magic number ("MZ")
-        #   2  cblp    : int16u    # Bytes on last page of file
-        #   4  cp      : int16u    # Pages in file
-        #   6  crlc    : int16u    # Relocations
-        #   8  cparhdr : int16u    # Size of header in paragraphs
-        #  10  minalloc: int16u    # Minimum extra paragraphs needed
-        #  12  maxalloc: int16u    # Maximum extra paragraphs needed
-        #  14  ss      : int16u    # Initial (relative) SS value
-        #  16  sp      : int16u    # Initial SP value
-        #  18  csum    : int16u    # Checksum
-        #  20  ip      : int16u    # Initial IP value
-        #  22  cs      : int16u    # Initial (relative) CS value
-        #  24  lfarlc  : int16u    # Address of relocation table
-        #  26  ovno    : int16u    # Overlay number
-        #  28  res     : int16u[4] # Reserved words
-        #  36  oemid   : int16u    # OEM identifier (for oeminfo)
-        #  38  oeminfo : int16u    # OEM info; oemid specific
-        #  40  res2    : int16u[10]# Reserved words
-        #  60  lfanew  : int32u;   # File address of new exe header
+        #   0 int16u     magic    - Magic number ("MZ")
+        #   2 int16u     cblp     - Bytes on last page of file
+        #   4 int16u     cp       - Pages in file
+        #   6 int16u     crlc     - Relocations
+        #   8 int16u     cparhdr  - Size of header in paragraphs
+        #  10 int16u     minalloc - Minimum extra paragraphs needed
+        #  12 int16u     maxalloc - Maximum extra paragraphs needed
+        #  14 int16u     ss       - Initial (relative) SS value
+        #  16 int16u     sp       - Initial SP value
+        #  18 int16u     csum     - Checksum
+        #  20 int16u     ip       - Initial IP value
+        #  22 int16u     cs       - Initial (relative) CS value
+        #  24 int16u     lfarlc   - Address of relocation table
+        #  26 int16u     ovno     - Overlay number
+        #  28 int16u[4]  res      - Reserved words
+        #  36 int16u     oemid    - OEM identifier (for oeminfo)
+        #  38 int16u     oeminfo  - OEM info; oemid specific
+        #  40 int16u[10] res2     - Reserved words
+        #  60 int32u;    lfanew   - File address of new exe header
         SetByteOrder('II');
         my ($cblp, $cp, $lfarlc, $lfanew) = unpack('x2v2x18vx34V', $buff);
         my $fileSize = ($cp - ($cblp ? 1 : 0)) * 512 + $cblp;
-        return 0 if $fileSize < 0x40 or $fileSize < $lfarlc;
-        # read the Windows PE header
-        if ($lfarlc == 0x40 and $fileSize > $lfanew + 2 and
-            # read the Windows NE, PE or LE (virtual device driver) header
-            $raf->Seek($lfanew, 0) and $raf->Read($buff, 0x40) and
-            $buff =~ /^(NE|PE|LE)/)
-        {
+        #(patch to accommodate observed 64-bit files)
+        #return 0 if $fileSize < 0x40 or $fileSize < $lfarlc;
+        #return 0 if $fileSize < 0x40; (changed to warning in ExifTool 12.08)
+        $et->Warn('Invalid file size in DOS header') if $fileSize < 0x40;
+        # read the Windows NE, PE or LE (virtual device driver) header
+        #if ($lfarlc == 0x40 and $fileSize > $lfanew + 2 and ...
+        if ($raf->Seek($lfanew, 0) and $raf->Read($buff, 0x40) and $buff =~ /^(NE|PE|LE)/) {
             if ($1 eq 'NE') {
                 if ($size >= 0x40) { # NE header is 64 bytes (ref 2)
                     # check for DLL
                     my $appFlags = Get16u(\$buff, 0x0c);
-                    $type = 'Win16 ' . ($appFlags & 0x80 ? 'DLL' : 'EXE');
+                    $ext = $appFlags & 0x80 ? 'DLL' : 'EXE';
+                    $type = "Win16 $ext";
                     # offset 0x02 is 2 bytes with linker version and revision numbers
                     # offset 0x36 is executable type (2 = Windows)
@@ -974,6 +1171,11 @@
                 #  22 int16u Characteristics
                 if ($size >= 24) {  # PE header is 24 bytes (plus optional header)
-                    my $flags = Get16u(\$buff, 22);
-                    $exifTool->SetFileType('Win32 ' . ($flags & 0x2000 ? 'DLL' : 'EXE'));
+                    my $mach = Get16u(\$buff, 4);   # MachineType
+                    my $flags = Get16u(\$buff, 22); # ImageFileCharacteristics
+                    my $machine = $Image::ExifTool::EXE::Main{0}{PrintConv}{$mach} || '';
+                    my $winType = $machine =~ /64/ ? 'Win64' : 'Win32';
+                    $ext = $flags & 0x2000 ? 'DLL' : 'EXE';
+                    $et->SetFileType("$winType $ext", undef, $ext);
+                    return 1 if $fast3;
                     # read the rest of the optional header if necessary
                     my $optSize = Get16u(\$buff, 20);
@@ -984,11 +1186,12 @@
                             $size += $more;
                             my $magic = Get16u(\$buff, 24);
-                            # verify PE32/PE32+ magic number
-                            unless ($magic == 0x10b or $magic == 0x20b) {
-                                $exifTool->Warn('Unknown PE magic number');
+                            # verify PE magic number
+                            unless ($magic == 0x107 or $magic == 0x10b or $magic == 0x20b) {
+                                $et->Warn('Unknown PE magic number');
                                 return 1;
                             }
+                            # --> 64-bit if $magic is 0x20b ????
                         } else {
-                            $exifTool->Warn('Error reading optional header');
+                            $et->Warn('Error reading optional header');
                         }
                     }
@@ -1000,7 +1203,7 @@
                         DataLen => $size,
                         DirStart => 4,
-                        DirLen => $size,
+                        DirLen => $size - 4,
                     );
-                    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
                     # process data dictionary
                     my $num = Get16u(\$buff, 6);    # NumberOfSections
@@ -1010,5 +1213,5 @@
                             DataPt => \$buff,
                         );
-                        ProcessPEDict($exifTool, \%dirInfo) or $exifTool->Warn('Error processing PE data dictionary');
+                        ProcessPEDict($et, \%dirInfo) or $et->Warn('Error processing PE data dictionary');
                     }
                     return 1;
@@ -1016,7 +1219,9 @@
             } else {
                 $type = 'Virtual Device Driver';
+                $ext = '386';
             }
         } else {
             $type = 'DOS EXE';
+            $ext = 'exe';
         }
 #
@@ -1029,10 +1234,11 @@
         if ($1 eq "\xca\xfe\xba\xbe") {
             SetByteOrder('MM');
-            $exifTool->SetFileType('Mach-O fat binary executable');
+            $et->SetFileType('Mach-O fat binary executable', undef, '');
+            return 1 if $fast3;
             my $count = Get32u(\$buff, 4);  # get architecture count
             my $more = $count * 20 - ($size - 8);
             if ($more > 0) {
                 unless ($raf->Read($buf2, $more) == $more) {
-                    $exifTool->Warn('Error reading fat-arch headers');
+                    $et->Warn('Error reading fat-arch headers');
                     return 1;
                 }
@@ -1040,11 +1246,11 @@
                 $size += $more;
             }
-            $exifTool->HandleTag($tagTablePtr, 2, $count);
+            $et->HandleTag($tagTablePtr, 2, $count);
             my $i;
             for ($i=0; $i<$count; ++$i) {
                 my $cpuType = Get32s(\$buff, 8 + $i * 20);
-                my $cpuSubtype = Get32u(\$buff, 12 + $i * 20);
-                $exifTool->HandleTag($tagTablePtr, 3, $cpuType);
-                $exifTool->HandleTag($tagTablePtr, 4, "$cpuType $cpuSubtype");
+                my $subType = Get32s(\$buff, 12 + $i * 20);
+                $et->HandleTag($tagTablePtr, 3, $cpuType);
+                $et->HandleTag($tagTablePtr, 4, "$cpuType $subType");
             }
             # load first Mach-O header to get the object file type
@@ -1053,33 +1259,23 @@
                 if ($buf2 =~ /^(\xfe\xed\xfa(\xce|\xcf)|(\xce|\xcf)\xfa\xed\xfe)/) {
                     SetByteOrder($buf2 =~ /^\xfe\xed/ ? 'MM' : 'II');
-                    my $objType = Get32s(\$buf2, 12);
-                    $exifTool->HandleTag($tagTablePtr, 5, $objType);
+                    my $objType = Get32u(\$buf2, 12);
+                    $et->HandleTag($tagTablePtr, 5, $objType);
+                    # override file type if this is a library or object file
+                    MachOverride($et, $objType, 'fat');
                 } elsif ($buf2 =~ /^!<arch>\x0a/) {
                     # .a libraries use this magic number
-                    $exifTool->HandleTag($tagTablePtr, 5, -1);
+                    $et->HandleTag($tagTablePtr, 5, -1);
+                    # override file type since this is a library
+                    $et->OverrideFileType('Mach-O fat static library', undef, 'A');
                 } else {
-                    $exifTool->Warn('Unrecognized object file type');
+                    $et->Warn('Unrecognized object file type');
                 }
             } else {
-                $exifTool->Warn('Error reading file');
+                $et->Warn('Error reading file');
             }
-       } elsif ($size >= 16) {
-            $exifTool->SetFileType('Mach-O executable');
-            my $info = {
-                "\xfe\xed\xfa\xce" => ['32 bit', 'Big endian'],
-                "\xce\xfa\xed\xfe" => ['32 bit', 'Little endian'],
-                "\xfe\xed\xfa\xcf" => ['64 bit', 'Big endian'],
-                "\xcf\xfa\xed\xfe" => ['64 bit', 'Little endian'],
-            }->{substr($buff, 0, 4)};
-            my $byteOrder = ($buff =~ /^\xfe/) ? 'MM' : 'II';
-            SetByteOrder($byteOrder);
-            my $cpuType = Get32s(\$buff, 4);
-            my $cpuSubtype = Get32s(\$buff, 8);
-            my $objType = Get32s(\$buff, 12);
-            $exifTool->HandleTag($tagTablePtr, 0, $$info[0]);
-            $exifTool->HandleTag($tagTablePtr, 1, $$info[1]);
-            $exifTool->HandleTag($tagTablePtr, 3, $cpuType);
-            $exifTool->HandleTag($tagTablePtr, 4, "$cpuType $cpuSubtype");
-            $exifTool->HandleTag($tagTablePtr, 5, $objType);
+        } elsif ($size >= 16) {
+            $et->SetFileType('Mach-O executable', undef, '');
+            return 1 if $fast3;
+            ExtractMachTags($et, \$buff, 1);
         }
         return 1;
@@ -1089,5 +1285,6 @@
     } elsif ($buff =~ /^Joy!peff/ and $size > 12) {
         # ref http://developer.apple.com/documentation/mac/pdf/MacOS_RT_Architectures.pdf
-        $exifTool->SetFileType('Classic MacOS executable');
+        $et->SetFileType('Classic MacOS executable', undef, '');
+        return 1 if $fast3;
         SetByteOrder('MM');
         $tagTablePtr = GetTagTable('Image::ExifTool::EXE::PEF');
@@ -1099,5 +1296,5 @@
             DirLen => $size,
         );
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         return 1;
 #
@@ -1105,15 +1302,58 @@
 #
     } elsif ($buff =~ /^\x7fELF/ and $size >= 16) {
-        $exifTool->SetFileType("ELF executable");
+        $et->SetFileType('ELF executable', undef, '');
+        return 1 if $fast3;
         SetByteOrder(Get8u(\$buff,5) == 1 ? 'II' : 'MM');
         $tagTablePtr = GetTagTable('Image::ExifTool::EXE::ELF');
         %dirInfo = (
-            DataPt => \$buff,
+            DataPt  => \$buff,
             DataPos => 0,
             DataLen => $size,
-            DirStart => 0,
-            DirLen => $size,
+            DirLen  => $size,
         );
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        # override file type if this is a library or object file
+        my $override = {
+            1 => [ 'ELF object file', 'O' ],
+            3 => [ 'ELF shared library', 'SO' ],
+        }->{$$et{VALUE}{ObjectFileType} || 0};
+        $et->OverrideFileType($$override[0], undef, $$override[1]) if $override;
+        return 1;
+#
+# .a libraries
+#
+    } elsif ($buff =~ /^!<arch>\x0a/) {
+        $et->SetFileType('Static library', undef, 'A');
+        return 1 if $fast3;
+        my $pos = 8;    # current file position
+        my $max = 10;   # maximum number of archive files to check
+        # read into list of ar structures (each 60 bytes long):
+        while ($max-- > 0) {
+            # seek to start of the ar structure and read it
+            $raf->Seek($pos, 0) and $raf->Read($buff, 60) == 60 or last;
+            substr($buff, 58, 2) eq "`\n" or $et->Warn('Invalid archive header'), last;
+            unless ($tagTablePtr) {
+                # extract some information from first file in archive
+                $tagTablePtr = GetTagTable('Image::ExifTool::EXE::AR');
+                %dirInfo = (
+                    DataPt  => \$buff,
+                    DataPos => $pos,
+                );
+                $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            }
+            my $name = substr($buff, 0, 16);
+            if ($name =~ m{^#1/(\d+) *$}) { # check for extended archive (BSD variant)
+                my $len = $1;
+                $len > 256 and $et->Warn('Invalid extended archive name length'), last;
+                # (we read the name here just to move the file pointer)
+                $raf->Read($name, $len) == $len or $et->Warn('Error reading archive name'), last;
+            }
+            my $arSize = substr($buff, 48, 10);
+            $arSize =~ s/^(\d+).*/$1/s or last;     # make sure archive size is a number
+            $raf->Read($buff, 28) == 28 or last;    # read (possible) Mach header
+            ExtractMachTags($et, \$buff) and last;  # try to extract tags
+            $pos += 60 + $arSize;   # step to next entry
+            ++$pos if $pos & 0x01;  # padded to an even byte
+        }
         return 1;
 #
@@ -1121,13 +1361,19 @@
 #
     } elsif ($buff =~ m{^#!\s*/\S*bin/(\w+)}) {
-        $type = "$1 script";
-#
-# .a libraries
-#
-    } elsif ($buff =~ /^!<arch>\x0a/) {
-        $type = 'Static library',
+        my $prog = $1;
+        $prog = $1 if $prog eq 'env' and $buff =~ /\b(perl|python|ruby|php)\b/;
+        $type = "$prog script";
+        $mime = "text/x-$prog";
+        $ext = {
+            perl   => 'pl',
+            python => 'py',
+            ruby   => 'rb',
+            php    => 'php',
+        }->{$prog};
+        # use '.sh' for extension of all shell scripts
+        $ext = $prog =~ /sh$/ ? 'sh' : '' unless defined $ext;
     }
     return 0 unless $type;
-    $exifTool->SetFileType($type);
+    $et->SetFileType($type, $mime, $ext);
     return 1;
 }
@@ -1153,5 +1399,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Exif.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Exif.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Exif.pm	(revision 34921)
@@ -35,7 +35,14 @@
 #              23) MetaMorph Stack (STK) Image File Format:
 #                  --> ftp://ftp.meta.moleculardevices.com/support/stack/STK.doc
-#              24) http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf (Exif 2.3)
+#              24) http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf (Exif 2.3)
 #              25) Vesa Kivisto private communication (7D)
 #              26) Jeremy Brown private communication
+#              27) Gregg Lee private communication
+#              28) http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/cinemadng/pdfs/CinemaDNG_Format_Specification_v1_1.pdf
+#              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
 #------------------------------------------------------------------------------
@@ -46,9 +53,9 @@
 use vars qw($VERSION $AUTOLOAD @formatSize @formatName %formatNumber %intFormat
             %lightSource %flash %compression %photometricInterpretation %orientation
-            %subfileType);
+            %subfileType %saveForValidate);
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::MakerNotes;
 
-$VERSION = '3.21';
+$VERSION = '4.33';
 
 sub ProcessExif($$$);
@@ -58,7 +65,9 @@
 sub EncodeExifText($$);
 sub ValidateIFD($;$);
+sub ValidateImageData($$$;$);
 sub ProcessTiffIFD($$$);
 sub PrintParameter($$$);
 sub GetOffList($$$$$);
+sub PrintOpcode($$$);
 sub PrintLensInfo($);
 sub ConvertLensInfo($);
@@ -71,9 +80,9 @@
 
 @formatName = (
-    undef, 'int8u', 'string', 'int16u',
-    'int32u', 'rational64u', 'int8s', 'undef',
-    'int16s', 'int32s', 'rational64s', 'float',
-    'double', 'ifd', 'unicode', 'complex',
-    'int64u', 'int64s', 'ifd64', # (new BigTIFF formats)
+     undef,    'int8u',      'string',     'int16u',
+    'int32u',  'rational64u','int8s',      'undef',
+    'int16s',  'int32s',     'rational64s','float',
+    'double',  'ifd',        'unicode',    'complex',
+    'int64u',  'int64s',     'ifd64', # (new BigTIFF formats)
 );
 
@@ -88,5 +97,5 @@
     'int8s'       => 6,  # SBYTE
     'undef'       => 7,  # UNDEFINED
-    'binary'      => 7,  # (treat binary data as undef)
+    'binary'      => 7,  # (same as undef)
     'int16s'      => 8,  # SSHORT
     'int32s'      => 9,  # SLONG
@@ -204,4 +213,5 @@
     32770 => 'Samsung SRW Compressed', #PH
     32771 => 'CCIRLEW', #3
+    32772 => 'Samsung SRW Compressed 2', #PH (NX3000,NXmini)
     32773 => 'PackBits',
     32809 => 'Thunderscan', #3
@@ -213,6 +223,9 @@
     32908 => 'PixarFilm', #3
     32909 => 'PixarLog', #3
+  # 32910,32911 - Pixar reserved
     32946 => 'Deflate', #3
     32947 => 'DCS', #3
+    33003 => 'Aperio JPEG 2000 YCbCr', #https://openslide.org/formats/aperio/
+    33005 => 'Aperio JPEG 2000 RGB', #https://openslide.org/formats/aperio/
     34661 => 'JBIG', #3
     34676 => 'SGILog', #3
@@ -224,4 +237,12 @@
     34719 => 'Microsoft Document Imaging (MDI) Progressive Transform Codec', #18
     34720 => 'Microsoft Document Imaging (MDI) Vector', #18
+    34887 => 'ESRI Lerc', #LibTiff
+  # 34888,34889 - ESRI reserved
+    34892 => 'Lossy JPEG', # (DNG 1.4)
+    34925 => 'LZMA2', #LibTiff
+    34926 => 'Zstd', #LibTiff
+    34927 => 'WebP', #LibTiff
+    34933 => 'PNG', # (TIFF mail list)
+    34934 => 'JPEG XR', # (TIFF mail list)
     65000 => 'Kodak DCR Compressed', #PH
     65535 => 'Pentax PEF Compressed', #Jens
@@ -242,5 +263,7 @@
     32844 => 'Pixar LogL', #3
     32845 => 'Pixar LogLuv', #3
+    32892 => 'Sequential Color Filter', #JR (Sony ARQ)
     34892 => 'Linear Raw', #2
+    51177 => 'Depth Map', # (DNG 1.5)
 );
 
@@ -257,5 +280,5 @@
 
 %subfileType = (
-    0 => 'Full-resolution Image',
+    0 => 'Full-resolution image',
     1 => 'Reduced-resolution image',
     2 => 'Single page of multi-page image',
@@ -265,4 +288,8 @@
     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 => {
@@ -270,6 +297,6 @@
         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)
     },
 );
@@ -281,4 +308,12 @@
         OTHER => \&Image::ExifTool::Exif::PrintParameter,
     },
+);
+
+# convert DNG UTF-8 string values (may be string or int8u format)
+my %utf8StringConv = (
+    Writable => 'string',
+    Format => 'string',
+    ValueConv => '$self->Decode($val, "UTF8")',
+    ValueConvInv => '$self->Encode($val,"UTF8")',
 );
 
@@ -299,8 +334,45 @@
 );
 
+# save the values of these tags for additional validation checks
+%saveForValidate = (
+    0x100 => 1, # ImageWidth
+    0x101 => 1, # ImageHeight
+    0x102 => 1, # BitsPerSample
+    0x103 => 1, # Compression
+    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'},
     WRITE_PROC => \&WriteExif,
+    CHECK_PROC => \&CheckExif,
     WRITE_GROUP => 'ExifIFD',   # default write group
     SET_GROUP1 => 1, # set group1 name to directory name for all tags in table
@@ -308,4 +380,7 @@
         Name => 'InteropIndex',
         Description => 'Interoperability Index',
+        Protected => 1,
+        Writable => 'string',
+        WriteGroup => 'InteropIFD',
         PrintConv => {
             R98 => 'R98 - DCF basic file (sRGB)',
@@ -317,12 +392,22 @@
         Name => 'InteropVersion',
         Description => 'Interoperability Version',
+        Protected => 1,
+        Writable => 'undef',
+        Mandatory => 1,
+        WriteGroup => 'InteropIFD',
         RawConv => '$val=~s/\0+$//; $val',  # (some idiots add null terminators)
     },
     0x0b => { #PH
         Name => 'ProcessingSoftware',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
         Notes => 'used by ACD Systems Digital Imaging',
     },
     0xfe => {
         Name => 'SubfileType',
+        Notes => 'called NewSubfileType by the TIFF specification',
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
         # set priority directory if this is the full resolution image
         DataMember => 'SubfileType',
@@ -332,4 +417,8 @@
     0xff => {
         Name => 'OldSubfileType',
+        Notes => 'called SubfileType by the TIFF specification',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         # set priority directory if this is the full resolution image
         RawConv => '$self->SetPriorityDir() if $val eq "1"; $val',
@@ -345,6 +434,9 @@
         # so it will show up in the group lists
         Groups => { 1 => 'IFD1' },
+        Protected => 1,
+        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,
     },
@@ -352,12 +444,23 @@
         Name => 'ImageHeight',
         Notes => 'called ImageLength by the EXIF spec.',
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
         Priority => 0,
     },
     0x102 => {
         Name => 'BitsPerSample',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => -1, # can be 1 or 3: -1 means 'variable'
         Priority => 0,
     },
     0x103 => {
         Name => 'Compression',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Mandatory => 1,
         DataMember => 'Compression',
         SeparateTable => 'Compression',
@@ -371,4 +474,7 @@
     0x106 => {
         Name => 'PhotometricInterpretation',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         PrintConv => \%photometricInterpretation,
         Priority => 0,
@@ -376,4 +482,7 @@
     0x107 => {
         Name => 'Thresholding',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         PrintConv => {
             1 => 'No dithering or halftoning',
@@ -382,8 +491,21 @@
         },
     },
-    0x108 => 'CellWidth',
-    0x109 => 'CellLength',
+    0x108 => {
+        Name => 'CellWidth',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x109 => {
+        Name => 'CellLength',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
     0x10a => {
         Name => 'FillOrder',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         PrintConv => {
             1 => 'Normal',
@@ -391,7 +513,13 @@
         },
     },
-    0x10d => 'DocumentName',
+    0x10d => {
+        Name => 'DocumentName',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
     0x10e => {
         Name => 'ImageDescription',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
         Priority => 0,
     },
@@ -399,4 +527,6 @@
         Name => 'Make',
         Groups => { 2 => 'Camera' },
+        Writable => 'string',
+        WriteGroup => 'IFD0',
         DataMember => 'Make',
         # remove trailing blanks and save as an ExifTool member variable
@@ -411,4 +541,6 @@
         Description => 'Camera Model Name',
         Groups => { 2 => 'Camera' },
+        Writable => 'string',
+        WriteGroup => 'IFD0',
         DataMember => 'Model',
         # remove trailing blanks and save as an ExifTool member variable
@@ -429,7 +561,9 @@
         },
         {
+            # (APP1 IFD2 is for Leica JPEG preview)
             Condition => q[
-                ($$self{TIFF_TYPE} ne 'CR2' or $$self{DIR_NAME} ne 'IFD0') and
-                ($$self{TIFF_TYPE} ne 'DNG' or $$self{DIR_NAME} !~ /^SubIFD[12]$/)
+                not ($$self{TIFF_TYPE} eq 'CR2' and $$self{DIR_NAME} eq 'IFD0') 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',
@@ -439,20 +573,23 @@
         },
         {
-            Condition => '$$self{DIR_NAME} eq "IFD0"',
+            # PreviewImageStart in IFD0 of CR2 images
+            Condition => '$$self{TIFF_TYPE} eq "CR2"',
             Name => 'PreviewImageStart',
             IsOffset => 1,
             OffsetPair => 0x117,
             Notes => q{
-                PreviewImageStart in IFD0 of CR2 images and SubIFD1 of DNG images, and
-                JpgFromRawStart in SubIFD2 of DNG images
+                called StripOffsets in most locations, but it is PreviewImageStart in IFD0
+                of CR2 images and various IFD's of DNG images except for SubIFD2 where it is
+                JpgFromRawStart
             },
             DataTag => 'PreviewImage',
             Writable => 'int32u',
             WriteGroup => 'IFD0',
-            WriteCondition => '$$self{TIFF_TYPE} eq "CR2"',
             Protected => 2,
+            Permanent => 1,
         },
         {
-            Condition => '$$self{DIR_NAME} eq "SubIFD1"',
+            # PreviewImageStart in various IFD's of DNG images except SubIFD2
+            Condition => '$$self{DIR_NAME} ne "SubIFD2"',
             Name => 'PreviewImageStart',
             IsOffset => 1,
@@ -460,9 +597,10 @@
             DataTag => 'PreviewImage',
             Writable => 'int32u',
-            WriteGroup => 'SubIFD1',
-            WriteCondition => '$$self{TIFF_TYPE} eq "DNG"',
+            WriteGroup => 'All',    # (writes to specific group of associated Composite tag)
             Protected => 2,
+            Permanent => 1,
         },
         {
+            # JpgFromRawStart in various IFD's of DNG images except SubIFD2
             Name => 'JpgFromRawStart',
             IsOffset => 1,
@@ -471,10 +609,12 @@
             Writable => 'int32u',
             WriteGroup => 'SubIFD2',
-            WriteCondition => '$$self{TIFF_TYPE} eq "DNG"',
             Protected => 2,
+            Permanent => 1,
         },
     ],
     0x112 => {
         Name => 'Orientation',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         PrintConv => \%orientation,
         Priority => 0,  # so PRIORITY_DIR takes precedence
@@ -482,8 +622,14 @@
     0x115 => {
         Name => 'SamplesPerPixel',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         Priority => 0,
     },
     0x116 => {
         Name => 'RowsPerStrip',
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
         Priority => 0,
     },
@@ -501,7 +647,9 @@
         },
         {
+            # (APP1 IFD2 is for Leica JPEG preview)
             Condition => q[
-                ($$self{TIFF_TYPE} ne 'CR2' or $$self{DIR_NAME} ne 'IFD0') and
-                ($$self{TIFF_TYPE} ne 'DNG' or $$self{DIR_NAME} !~ /^SubIFD[12]$/)
+                not ($$self{TIFF_TYPE} eq 'CR2' and $$self{DIR_NAME} eq 'IFD0') 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',
@@ -510,28 +658,32 @@
         },
         {
-            Condition => '$$self{DIR_NAME} eq "IFD0"',
+            # PreviewImageLength in IFD0 of CR2 images
+            Condition => '$$self{TIFF_TYPE} eq "CR2"',
             Name => 'PreviewImageLength',
             OffsetPair => 0x111,
             Notes => q{
-                PreviewImageLength in IFD0 of CR2 images and SubIFD1 of DNG images, and
-                JpgFromRawLength in SubIFD2 of DNG images
+                called StripByteCounts in most locations, but it is PreviewImageLength in
+                IFD0 of CR2 images and various IFD's of DNG images except for SubIFD2 where
+                it is JpgFromRawLength
             },
             DataTag => 'PreviewImage',
             Writable => 'int32u',
             WriteGroup => 'IFD0',
-            WriteCondition => '$$self{TIFF_TYPE} eq "CR2"',
             Protected => 2,
+            Permanent => 1,
         },
         {
-            Condition => '$$self{DIR_NAME} eq "SubIFD1"',
+            # PreviewImageLength in various IFD's of DNG images except SubIFD2
+            Condition => '$$self{DIR_NAME} ne "SubIFD2"',
             Name => 'PreviewImageLength',
             OffsetPair => 0x111,
             DataTag => 'PreviewImage',
             Writable => 'int32u',
-            WriteGroup => 'SubIFD1',
-            WriteCondition => '$$self{TIFF_TYPE} eq "DNG"',
+            WriteGroup => 'All',    # (writes to specific group of associated Composite tag)
             Protected => 2,
+            Permanent => 1,
         },
         {
+            # JpgFromRawLength in SubIFD2 of DNG images
             Name => 'JpgFromRawLength',
             OffsetPair => 0x111,
@@ -539,20 +691,37 @@
             Writable => 'int32u',
             WriteGroup => 'SubIFD2',
-            WriteCondition => '$$self{TIFF_TYPE} eq "DNG"',
             Protected => 2,
+            Permanent => 1,
         },
     ],
-    0x118 => 'MinSampleValue',
-    0x119 => 'MaxSampleValue',
+    0x118 => {
+        Name => 'MinSampleValue',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
+    0x119 => {
+        Name => 'MaxSampleValue',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+    },
     0x11a => {
         Name => 'XResolution',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Mandatory => 1,
         Priority => 0,  # so PRIORITY_DIR takes precedence
     },
     0x11b => {
         Name => 'YResolution',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Mandatory => 1,
         Priority => 0,
     },
     0x11c => {
         Name => 'PlanarConfiguration',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         PrintConv => {
             1 => 'Chunky',
@@ -561,7 +730,21 @@
         Priority => 0,
     },
-    0x11d => 'PageName',
-    0x11e => 'XPosition',
-    0x11f => 'YPosition',
+    0x11d => {
+        Name => 'PageName',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0x11e => {
+        Name => 'XPosition',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    0x11f => {
+        Name => 'YPosition',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+    },
+    # FreeOffsets/FreeByteCounts are used by Ricoh for RMETA information
+    # in TIFF images (not yet supported)
     0x120 => {
         Name => 'FreeOffsets',
@@ -577,4 +760,6 @@
     0x122 => {
         Name => 'GrayResponseUnit',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         PrintConv => { #3
             1 => 0.1,
@@ -606,4 +791,7 @@
         Name => 'ResolutionUnit',
         Notes => 'the value 1 is not standard EXIF',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Mandatory => 1,
         PrintConv => {
             1 => 'None',
@@ -613,13 +801,25 @@
         Priority => 0,
     },
-    0x129 => 'PageNumber',
+    0x129 => {
+        Name => 'PageNumber',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+    },
     0x12c => 'ColorResponseUnit', #9
     0x12d => {
         Name => 'TransferFunction',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => 768,
         Binary => 1,
     },
     0x131 => {
         Name => 'Software',
-        RawConv => '$val =~ s/\s+$//; $val', # trim trailing blanks
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+        DataMember => 'Software',
+        RawConv => '$val =~ s/\s+$//; $$self{Software} = $val', # trim trailing blanks
     },
     0x132 => {
@@ -627,5 +827,10 @@
         Groups => { 2 => 'Time' },
         Notes => 'called DateTime by the EXIF spec.',
+        Writable => 'string',
+        Shift => 'Time',
+        WriteGroup => 'IFD0',
+        Validate => 'ValidateExifDate($val)',
         PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,0)',
     },
     0x13b => {
@@ -633,12 +838,26 @@
         Groups => { 2 => 'Author' },
         Notes => 'becomes a list-type tag when the MWG module is loaded',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
         RawConv => '$val =~ s/\s+$//; $val', # trim trailing blanks
     },
-    0x13c => 'HostComputer',
+    0x13c => {
+        Name => 'HostComputer',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
     0x13d => {
         Name => 'Predictor',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         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)
         },
     },
@@ -646,7 +865,13 @@
         Name => 'WhitePoint',
         Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 2,
     },
     0x13f => {
         Name => 'PrimaryChromaticities',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 6,
         Priority => 0,
     },
@@ -656,7 +881,22 @@
         Binary => 1,
     },
-    0x141 => 'HalftoneHints',
-    0x142 => 'TileWidth',
-    0x143 => 'TileLength',
+    0x141 => {
+        Name => 'HalftoneHints',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+    },
+    0x142 => {
+        Name => 'TileWidth',
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+    },
+    0x143 => {
+        Name => 'TileLength',
+        Protected => 1,
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+    },
     0x144 => {
         Name => 'TileOffsets',
@@ -699,5 +939,5 @@
             SubDirectory => {
                 Start => '$val',
-                MaxSubdirs => 3,
+                MaxSubdirs => 10, # (have seen 5 in a DNG 1.4 image)
             },
         },
@@ -707,9 +947,13 @@
             DataMember => 'A100DataOffset',
             RawConv => '$$self{A100DataOffset} = $val',
+            WriteGroup => 'IFD0', # (only for Validate)
             IsOffset => 1,
+            Protected => 2,
         },
     ],
     0x14c => {
         Name => 'InkSet',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         PrintConv => { #3
             1 => 'CMYK',
@@ -720,5 +964,9 @@
     0x14e => 'NumberofInks', #3
     0x150 => 'DotRange',
-    0x151 => 'TargetPrinter',
+    0x151 => {
+        Name => 'TargetPrinter',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
     0x152 => {
         Name => 'ExtraSamples',
@@ -732,4 +980,5 @@
         Name => 'SampleFormat',
         Notes => 'SamplesPerPixel values',
+        WriteGroup => 'SubIFD', # (only for Validate)
         PrintConvColumns => 2,
         PrintConv => [ \%sampleFormat, \%sampleFormat, \%sampleFormat, \%sampleFormat ],
@@ -765,4 +1014,5 @@
             DirName => 'GlobParamIFD',
             Start => '$val',
+            MaxSubdirs => 1,
         },
     },
@@ -818,5 +1068,5 @@
             Notes => q{
                 ThumbnailOffset in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW
-                images and AVI videos, and the SubIFD in IFD1 of SRW images;
+                images and AVI and MOV videos, and the SubIFD in IFD1 of SRW images;
                 PreviewImageStart in MakerNotes and IFD0 of ARW and SR2 images;
                 JpgFromRawStart in SubIFD of NEF images and IFD2 of PEF images; and
@@ -824,8 +1074,12 @@
             },
             # thumbnail is found in IFD1 of JPEG and TIFF images, and
-            # IFD0 of EXIF information in FujiFilm AVI (RIFF) videos
+            # IFD0 of EXIF information in FujiFilm AVI (RIFF) and MOV videos
             Condition => q{
+                # recognize NRW file from a JPEG-compressed thumbnail in IFD0
+                if ($$self{TIFF_TYPE} eq 'NEF' and $$self{DIR_NAME} eq 'IFD0' and $$self{Compression} == 6) {
+                    $self->OverrideFileType($$self{TIFF_TYPE} = 'NRW');
+                }
                 $$self{DIR_NAME} eq 'IFD1' or
-                ($$self{FILE_TYPE} eq 'RIFF' and $$self{DIR_NAME} eq 'IFD0')
+                ($$self{DIR_NAME} eq 'IFD0' and $$self{FILE_TYPE} =~ /^(RIFF|MOV)$/)
             },
             IsOffset => 1,
@@ -838,5 +1092,5 @@
             # use IFD1 for a JPEG-compressed thumbnail:  CR2, ARW, SR2 and PEF.
             # (SRF also stores a JPEG image in IFD1, but it is actually a preview
-            # and we don't yet write SRF anyway) 
+            # and we don't yet write SRF anyway)
             WriteCondition => q{
                 $$self{FILE_TYPE} ne "TIFF" or
@@ -848,5 +1102,6 @@
             Name => 'ThumbnailOffset',
             # thumbnail in IFD0 of MRW images (Minolta A200)
-            Condition => '$$self{DIR_NAME} eq "IFD0" and $$self{TIFF_TYPE} eq "MRW"',
+            # and IFD0 of NRW images (Nikon Coolpix P6000,P7000,P7100)
+            Condition => '$$self{DIR_NAME} eq "IFD0" and $$self{TIFF_TYPE} =~ /^(MRW|NRW)$/',
             IsOffset => 1,
             OffsetPair => 0x202,
@@ -856,6 +1111,6 @@
             Writable => 'int32u',
             WriteGroup => 'IFD0',
-            WriteCondition => '$$self{FILE_TYPE} eq "MRW"',
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -871,6 +1126,6 @@
             Writable => 'int32u',
             WriteGroup => 'SubIFD',
-            WriteCondition => '$$self{TIFF_TYPE} eq "SRW"',
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -882,6 +1137,6 @@
             Writable => 'int32u',
             WriteGroup => 'MakerNotes',
-            # (no WriteCondition necessary because MakerNotes won't be created)
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -894,6 +1149,6 @@
             Writable => 'int32u',
             WriteGroup => 'IFD0',
-            WriteCondition => '$$self{TIFF_TYPE} =~ /^(ARW|SR2)$/',
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -906,6 +1161,6 @@
             WriteGroup => 'SubIFD',
             # JpgFromRaw is in SubIFD of NEF, NRW and SRW files
-            WriteCondition => '$$self{TIFF_TYPE} =~ /^(NEF|NRW|SRW)$/',
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -918,6 +1173,28 @@
             WriteGroup => 'IFD2',
             # JpgFromRaw is in IFD2 of PEF files
-            WriteCondition => '$$self{TIFF_TYPE} eq "PEF"',
             Protected => 2,
+            Permanent => 1,
+        },
+        {
+            Name => 'OtherImageStart',
+            Condition => '$$self{DIR_NAME} eq "SubIFD1"',
+            IsOffset => 1,
+            OffsetPair => 0x202,
+            DataTag => 'OtherImage',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD1',
+            Protected => 2,
+            Permanent => 1,
+        },
+        {
+            Name => 'OtherImageStart',
+            Condition => '$$self{DIR_NAME} eq "SubIFD2"',
+            IsOffset => 1,
+            OffsetPair => 0x202,
+            DataTag => 'OtherImage',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD2',
+            Protected => 2,
+            Permanent => 1,
         },
         {
@@ -932,5 +1209,5 @@
             Notes => q{
                 ThumbnailLength in IFD1 of JPEG and some TIFF-based images, IFD0 of MRW
-                images and AVI videos, and the SubIFD in IFD1 of SRW images;
+                images and AVI and MOV videos, and the SubIFD in IFD1 of SRW images;
                 PreviewImageLength in MakerNotes and IFD0 of ARW and SR2 images;
                 JpgFromRawLength in SubIFD of NEF images, and IFD2 of PEF images; and
@@ -939,5 +1216,5 @@
             Condition => q{
                 $$self{DIR_NAME} eq 'IFD1' or
-                ($$self{FILE_TYPE} eq 'RIFF' and $$self{DIR_NAME} eq 'IFD0')
+                ($$self{DIR_NAME} eq 'IFD0' and $$self{FILE_TYPE} =~ /^(RIFF|MOV)$/)
             },
             OffsetPair => 0x201,
@@ -954,11 +1231,12 @@
             Name => 'ThumbnailLength',
             # thumbnail in IFD0 of MRW images (Minolta A200)
-            Condition => '$$self{DIR_NAME} eq "IFD0" and $$self{TIFF_TYPE} eq "MRW"',
+            # and IFD0 of NRW images (Nikon Coolpix P6000,P7000,P7100)
+            Condition => '$$self{DIR_NAME} eq "IFD0" and $$self{TIFF_TYPE} =~ /^(MRW|NRW)$/',
             OffsetPair => 0x201,
             DataTag => 'ThumbnailImage',
             Writable => 'int32u',
             WriteGroup => 'IFD0',
-            WriteCondition => '$$self{FILE_TYPE} eq "MRW"',
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -973,6 +1251,6 @@
             Writable => 'int32u',
             WriteGroup => 'SubIFD',
-            WriteCondition => '$$self{TIFF_TYPE} eq "SRW"',
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -983,6 +1261,6 @@
             Writable => 'int32u',
             WriteGroup => 'MakerNotes',
-            # (no WriteCondition necessary because MakerNotes won't be created)
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -994,6 +1272,6 @@
             Writable => 'int32u',
             WriteGroup => 'IFD0',
-            WriteCondition => '$$self{TIFF_TYPE} =~ /^(ARW|SR2)$/',
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -1004,6 +1282,6 @@
             Writable => 'int32u',
             WriteGroup => 'SubIFD',
-            WriteCondition => '$$self{TIFF_TYPE} =~ /^(NEF|NRW|SRW)$/',
             Protected => 2,
+            Permanent => 1,
         },
         {
@@ -1014,6 +1292,26 @@
             Writable => 'int32u',
             WriteGroup => 'IFD2',
-            WriteCondition => '$$self{TIFF_TYPE} eq "PEF"',
             Protected => 2,
+            Permanent => 1,
+        },
+        {
+            Name => 'OtherImageLength',
+            Condition => '$$self{DIR_NAME} eq "SubIFD1"',
+            OffsetPair => 0x201,
+            DataTag => 'OtherImage',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD1',
+            Protected => 2,
+            Permanent => 1,
+        },
+        {
+            Name => 'OtherImageLength',
+            Condition => '$$self{DIR_NAME} eq "SubIFD2"',
+            OffsetPair => 0x201,
+            DataTag => 'OtherImage',
+            Writable => 'int32u',
+            WriteGroup => 'SubIFD2',
+            Protected => 2,
+            Permanent => 1,
         },
         {
@@ -1045,8 +1343,16 @@
     0x211 => {
         Name => 'YCbCrCoefficients',
+        Protected => 1,
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 3,
         Priority => 0,
     },
     0x212 => {
         Name => 'YCbCrSubSampling',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Count => 2,
         PrintConvColumns => 2,
         PrintConv => \%Image::ExifTool::JPEG::yCbCrSubSampling,
@@ -1055,4 +1361,8 @@
     0x213 => {
         Name => 'YCbCrPositioning',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Mandatory => 1,
         PrintConv => {
             1 => 'Centered',
@@ -1063,11 +1373,21 @@
     0x214 => {
         Name => 'ReferenceBlackWhite',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 6,
         Priority => 0,
     },
+  # 0x220 - int32u: 0 (IFD0, Xaiomi Redmi models)
+  # 0x221 - int32u: 0 (IFD0, Xaiomi Redmi models)
+  # 0x222 - int32u: 0 (IFD0, Xaiomi Redmi models)
+  # 0x223 - int32u: 0 (IFD0, Xaiomi Redmi models)
+  # 0x224 - int32u: 0,1 (IFD0, Xaiomi Redmi models)
+  # 0x225 - string: "" (IFD0, Xaiomi Redmi models)
     0x22f => 'StripRowCounts',
     0x2bc => {
         Name => 'ApplicationNotes', # (writable directory!)
+        Format => 'undef',
         Writable => 'int8u',
-        Format => 'undef',
+        WriteGroup => 'IFD0', # (only for Validate)
         Flags => [ 'Binary', 'Protected' ],
         # this could be an XMP block
@@ -1078,12 +1398,30 @@
     },
     0x3e7 => 'USPTOMiscellaneous', #20
-    0x1000 => 'RelatedImageFileFormat', #5
-    0x1001 => 'RelatedImageWidth', #5
+    0x1000 => { #5
+        Name => 'RelatedImageFileFormat',
+        Protected => 1,
+        Writable => 'string',
+        WriteGroup => 'InteropIFD',
+    },
+    0x1001 => { #5
+        Name => 'RelatedImageWidth',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'InteropIFD',
+    },
     0x1002 => { #5
         Name => 'RelatedImageHeight',
         Notes => 'called RelatedImageLength by the DCF spec.',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'InteropIFD',
     },
     # (0x474x tags written by MicrosoftPhoto)
-    0x4746 => 'Rating', #PH
+    0x4746 => { #PH
+        Name => 'Rating',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Avoid => 1,
+    },
     0x4747 => { # (written by Digital Image Pro)
         Name => 'XP_DIP_XML',
@@ -1092,5 +1430,5 @@
         # http://social.msdn.microsoft.com/Forums/en-US/isvvba/thread/ce6edcbb-8fc2-40c6-ad98-85f5d835ddfb
         ValueConv => '$self->Decode($val,"UCS2","II")',
-    }, 
+    },
     0x4748 => {
         Name => 'StitchInfo',
@@ -1100,5 +1438,109 @@
         },
     },
-    0x4749 => 'RatingPercent', #PH
+    0x4749 => { #PH
+        Name => 'RatingPercent',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Avoid => 1,
+    },
+    0x7000 => { #JR
+        Name => 'SonyRawFileType',
+        # (only valid if Sony:FileFormat >= ARW 2.0, ref IB)
+        # Writable => 'int16u', (don't allow writes for now)
+        PrintConv => {
+            0 => 'Sony Uncompressed 14-bit RAW',
+            1 => 'Sony Uncompressed 12-bit RAW', #IB
+            2 => 'Sony Compressed RAW', # (lossy, ref IB)
+            3 => 'Sony Lossless Compressed RAW', #IB
+            4 => 'Sony Lossless Compressed RAW 2', #JR (ILCE-1)
+        },
+    },
+    # 0x7001 - int16u[1] (in SubIFD of Sony ARW images) - values: 0,1
+    0x7010 => { #IB
+        Name => 'SonyToneCurve',
+        # int16u[4] (in SubIFD of Sony ARW images -- don't allow writes for now)
+        # - only the middle 4 points are stored (lower comes from black level,
+        #   and upper from data maximum)
+    },
+    # 0x7011 - int16u[4] (in SubIFD of Sony ARW images) - values: "0 4912 8212 12287","4000 7200 10050 12075"
+    # 0x7020 - int32u[1] (in SubIFD of Sony ARW images) - values: 0,3
+    0x7031 => {
+        Name => 'VignettingCorrection',
+        Notes => 'found in Sony ARW images',
+        Protected => 1,
+        Writable => 'int16s',
+        WriteGroup => 'SubIFD',
+        PrintConv => {
+            256 => 'Off',
+            257 => 'Auto',
+            272 => 'Auto (ILCE-1)', #JR
+            511 => 'No correction params available',
+        },
+    },
+    0x7032 => {
+        Name => 'VignettingCorrParams', #forum7640
+        Notes => 'found in Sony ARW images',
+        Protected => 1,
+        Writable => 'int16s',
+        WriteGroup => 'SubIFD',
+        Count => 17,
+    },
+    0x7034 => {
+        Name => 'ChromaticAberrationCorrection',
+        Notes => 'found in Sony ARW images',
+        Protected => 1,
+        Writable => 'int16s',
+        WriteGroup => 'SubIFD',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            255 => 'No correction params available',
+        },
+    },
+    0x7035 => {
+        Name => 'ChromaticAberrationCorrParams', #forum6509
+        Notes => 'found in Sony ARW images',
+        Protected => 1,
+        Writable => 'int16s',
+        WriteGroup => 'SubIFD',
+        Count => 33,
+    },
+    0x7036 => {
+        Name => 'DistortionCorrection',
+        Notes => 'found in Sony ARW images',
+        Protected => 1,
+        Writable => 'int16s',
+        WriteGroup => 'SubIFD',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto',
+            17 => 'Auto fixed by lens',
+            255 => 'No correction params available',
+        },
+    },
+    0x7037 => {
+        Name => 'DistortionCorrParams', #forum6509
+        Notes => 'found in Sony ARW images',
+        Protected => 1,
+        Writable => 'int16s',
+        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
@@ -1109,13 +1551,36 @@
         PrintConv => 'length($val) <= 64 ? $val : \$val',
     },
+    # tags 0x80b8-0x80bc are registered to Island Graphics
+    0x80b9 => 'ImageReferencePoints', #29
+    0x80ba => 'RegionXformTackPoint', #29
+    0x80bb => 'WarpQuadrilateral', #29
+    0x80bc => 'AffineTransformMat', #29
     0x80e3 => 'Matteing', #9
     0x80e4 => 'DataType', #9
     0x80e5 => 'ImageDepth', #9
     0x80e6 => 'TileDepth', #9
-    0x827d => 'Model2',
-    0x828d => 'CFARepeatPatternDim', #12
+    # tags 0x8214-0x8219 are registered to Pixar
+    0x8214 => 'ImageFullWidth', #29
+    0x8215 => 'ImageFullHeight', #29
+    0x8216 => 'TextureFormat', #29
+    0x8217 => 'WrapModes', #29
+    0x8218 => 'FovCot', #29
+    0x8219 => 'MatrixWorldToScreen', #29
+    0x821a => 'MatrixWorldToCamera', #29
+    0x827d => 'Model2', #29 (Eastman Kodak)
+    0x828d => { #12
+        Name => 'CFARepeatPatternDim',
+        Protected => 1,
+        Writable => 'int16u',
+        WriteGroup => 'SubIFD',
+        Count => 2,
+    },
     0x828e => {
         Name => 'CFAPattern2', #12
         Format => 'int8u',  # (written incorrectly as 'undef' in Nikon NRW images)
+        Protected => 1,
+        Writable => 'int8u',
+        WriteGroup => 'SubIFD',
+        Count => -1,
     },
     0x828f => { #12
@@ -1132,4 +1597,5 @@
             DirName => 'KodakIFD',
             Start => '$val',
+            MaxSubdirs => 1,
         },
     },
@@ -1138,7 +1604,11 @@
         Groups => { 2 => 'Author' },
         Format => 'undef',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
         Notes => q{
             may contain copyright notices for photographer and editor, separated by a
-            newline in ExifTool
+            newline.  As per the EXIF specification, the newline is replaced by a null
+            byte when writing to file, but this may be avoided by disabling the print
+            conversion
         },
         # internally the strings are separated by a null character in this format:
@@ -1146,17 +1616,40 @@
         # Both:              photographer + NULL + editor + NULL
         # Editor only:       SPACE + NULL + editor + NULL
-        # 1) translate first NULL to a newline, removing trailing blanks
-        # 2) truncate at second NULL and remove trailing blanks
-        # 3) remove trailing newline if it exists
         # (this is done as a RawConv so conditional replaces will work properly)
-        RawConv => '$_=$val; s/ *\0/\n/; s/ *\0.*//s; s/\n$//; $_',
+        RawConv => sub {
+            my ($val, $self) = @_;
+            $val =~ s/ *\0/\n/;  # translate first NULL to a newline, removing trailing blanks
+            $val =~ s/ *\0.*//s; # truncate at second NULL and remove trailing blanks
+            $val =~ s/\n$//;     # remove trailing newline if it exists
+            # decode if necessary (note: this is the only non-'string' EXIF value like this)
+            my $enc = $self->Options('CharsetEXIF');
+            $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',
+        Writable => 'rational64u',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => '$val',
     },
     0x829d => {
         Name => 'FNumber',
-        PrintConv => 'sprintf("%.1f",$val)',
+        Writable => 'rational64u',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
     },
     0x82a5 => { #3
@@ -1171,5 +1664,10 @@
     0x82ab => 'MDPrepTime', #3
     0x82ac => 'MDFileUnits', #3
-    0x830e => 'PixelScale',
+    0x830e => { #30 (GeoTiff)
+        Name => 'PixelScale',
+        Writable => 'double',
+        WriteGroup => 'IFD0',
+        Count => 3,
+    },
     0x8335 => 'AdventScale', #20
     0x8336 => 'AdventRevision', #20
@@ -1179,5 +1677,5 @@
     0x835f => 'UIC4Tag', #23
     0x83bb => { #12
-        Name => 'IPTC-NAA', # (writable directory!)
+        Name => 'IPTC-NAA', # (writable directory! -- but see note below)
         # this should actually be written as 'undef' (see
         # http://www.awaresystems.be/imaging/tiff/tifftags/iptc.html),
@@ -1192,12 +1690,23 @@
             TagTable => 'Image::ExifTool::IPTC::Main',
         },
+        # Note: This directory may be written as a block via the IPTC-NAA tag,
+        # but this technique is not recommended.  Instead, it is better to
+        # write the Extra IPTC tag and let ExifTool decide where it should go.
     },
     0x847e => 'IntergraphPacketData', #3
     0x847f => 'IntergraphFlagRegisters', #3
-    0x8480 => 'IntergraphMatrix',
+    0x8480 => { #30 (GeoTiff, obsolete)
+        Name => 'IntergraphMatrix',
+        Writable => 'double',
+        WriteGroup => 'IFD0',
+        Count => -1,
+    },
     0x8481 => 'INGRReserved', #20
-    0x8482 => {
+    0x8482 => { #30 (GeoTiff)
         Name => 'ModelTiePoint',
         Groups => { 2 => 'Location' },
+        Writable => 'double',
+        WriteGroup => 'IFD0',
+        Count => -1,
     },
     0x84e0 => 'Site', #9
@@ -1249,4 +1758,6 @@
         Name => 'SEMInfo',
         Notes => 'found in some scanning electron microscope images',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
     },
     0x8568 => {
@@ -1259,7 +1770,11 @@
     },
     0x85b8 => 'PixelMagicJBIGOptions', #20
-    0x85d8 => {
+    0x85d7 => 'JPLCartoIFD', #exifprobe (NC)
+    0x85d8 => { #30 (GeoTiff)
         Name => 'ModelTransform',
         Groups => { 2 => 'Location' },
+        Writable => 'double',
+        WriteGroup => 'IFD0',
+        Count => 16,
     },
     0x8602 => { #16
@@ -1279,4 +1794,5 @@
         Name => 'PhotoshopSettings',
         Format => 'binary',
+        WriteGroup => 'IFD0', # (only for Validate)
         SubDirectory => {
             DirName => 'Photoshop',
@@ -1287,4 +1803,5 @@
         Name => 'ExifOffset',
         Groups => { 1 => 'ExifIFD' },
+        WriteGroup => 'IFD0', # (only for Validate)
         SubIFD => 2,
         SubDirectory => {
@@ -1295,4 +1812,5 @@
     0x8773 => {
         Name => 'ICC_Profile',
+        WriteGroup => 'IFD0', # (only for Validate)
         SubDirectory => {
             TagTable => 'Image::ExifTool::ICC_Profile::Main',
@@ -1335,22 +1853,57 @@
     0x8782 => 'T88Options', #20
     0x87ac => 'ImageLayer',
-    0x87af => {
+    0x87af => { #30
         Name => 'GeoTiffDirectory',
-        Format => 'binary',
+        Format => 'undef',
+        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
+        },
+        WriteGroup => 'IFD0',
         Binary => 1,
-    },
-    0x87b0 => {
+        RawConv => '$val . GetByteOrder()', # save byte order
+        # swap byte order if necessary
+        RawConvInv => q{
+            return $val if length $val < 2;
+            my $order = substr($val, -2);
+            return $val unless $order eq 'II' or $order eq 'MM';
+            $val = substr($val, 0, -2);
+            return $val if $order eq GetByteOrder();
+            return pack('v*',unpack('n*',$val));
+        },
+    },
+    0x87b0 => { #30
         Name => 'GeoTiffDoubleParams',
-        Format => 'binary',
+        Format => 'undef',
+        Writable => 'double',
+        WriteGroup => 'IFD0',
         Binary => 1,
-    },
-    0x87b1 => {
+        RawConv => '$val . GetByteOrder()', # save byte order
+        # swap byte order if necessary
+        RawConvInv => q{
+            return $val if length $val < 2;
+            my $order = substr($val, -2);
+            return $val unless $order eq 'II' or $order eq 'MM';
+            $val = substr($val, 0, -2);
+            return $val if $order eq GetByteOrder();
+            $val =~ s/(.{4})(.{4})/$2$1/sg; # swap words
+            return pack('V*',unpack('N*',$val));
+        },
+    },
+    0x87b1 => { #30
         Name => 'GeoTiffAsciiParams',
+        Format => 'undef',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
         Binary => 1,
     },
+    0x87be => 'JBIGOptions', #29
     0x8822 => {
         Name => 'ExposureProgram',
         Groups => { 2 => 'Camera' },
         Notes => 'the value of 9 is not standard EXIF, but is used by the Canon EOS 7D',
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Not Defined',
@@ -1369,8 +1922,10 @@
         Name => 'SpectralSensitivity',
         Groups => { 2 => 'Camera' },
+        Writable => 'string',
     },
     0x8825 => {
         Name => 'GPSInfo',
         Groups => { 1 => 'GPS' },
+        WriteGroup => 'IFD0', # (only for Validate)
         Flags => 'SubIFD',
         SubDirectory => {
@@ -1378,4 +1933,5 @@
             TagTable => 'Image::ExifTool::GPS::Main',
             Start => '$val',
+            MaxSubdirs => 1,
         },
     },
@@ -1386,5 +1942,8 @@
             2.3 spec.
         },
+        Writable => 'int16u',
+        Count => -1,
         PrintConv => '$val=~s/\s+/, /g; $val',
+        PrintConvInv => '$val=~tr/,//d; $val',
     },
     0x8828 => {
@@ -1394,9 +1953,21 @@
     },
     0x8829 => 'Interlace', #12
-    0x882a => 'TimeZoneOffset', #12
-    0x882b => 'SelfTimerMode', #12
+    0x882a => { #12
+        Name => 'TimeZoneOffset',
+        Writable => 'int16s',
+        Count => -1, # can be 1 or 2
+        Notes => q{
+            1 or 2 values: 1. The time zone offset of DateTimeOriginal from GMT in
+            hours, 2. If present, the time zone offset of ModifyDate
+        },
+    },
+    0x882b => { #12
+        Name => 'SelfTimerMode',
+        Writable => 'int16u',
+    },
     0x8830 => { #24
         Name => 'SensitivityType',
         Notes => 'applies to EXIF:ISO tag',
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Unknown',
@@ -1410,18 +1981,31 @@
         },
     },
-    0x8831 => 'StandardOutputSensitivity', #24
-    0x8832 => 'RecommendedExposureIndex', #24
-    0x8833 => 'ISOSpeed', #24
+    0x8831 => { #24
+        Name => 'StandardOutputSensitivity',
+        Writable => 'int32u',
+    },
+    0x8832 => { #24
+        Name => 'RecommendedExposureIndex',
+        Writable => 'int32u',
+    },
+    0x8833 => { #24
+        Name => 'ISOSpeed',
+        Writable => 'int32u',
+    },
     0x8834 => { #24
         Name => 'ISOSpeedLatitudeyyy',
         Description => 'ISO Speed Latitude yyy',
+        Writable => 'int32u',
     },
     0x8835 => { #24
         Name => 'ISOSpeedLatitudezzz',
         Description => 'ISO Speed Latitude zzz',
+        Writable => 'int32u',
     },
     0x885c => 'FaxRecvParams', #9
     0x885d => 'FaxSubAddress', #9
     0x885e => 'FaxRecvTime', #9
+    0x8871 => 'FedexEDR', #exifprobe (NC)
+  # 0x8889 - string: "portrait" (ExifIFD, Xiaomi POCO F1)
     0x888a => { #PH
         Name => 'LeafSubIFD',
@@ -1434,7 +2018,16 @@
         },
     },
+  # 0x8891 - int16u: 35 (ExifIFD, Xiaomi POCO F1)
+  # 0x8894 - int16u: 0 (ExifIFD, Xiaomi POCO F1)
+  # 0x8895 - int16u: 0 (ExifIFD, Xiaomi POCO F1)
+  # 0x889a - int16u: 0 (ExifIFD, Xiaomi POCO F1)
+  # 0x89ab - seen "11 100 130 16 0 0 0 0" in IFD0 of TIFF image from IR scanner (forum8470)
     0x9000 => {
         Name => 'ExifVersion',
+        Writable => 'undef',
+        Mandatory => 1,
         RawConv => '$val=~s/\0+$//; $val',  # (some idiots add null terminators)
+        # (allow strings like "2.31" when writing)
+        PrintConvInv => '$val=~tr/.//d; $val=~/^\d{4}$/ ? $val : $val =~ /^\d{3}$/ ? "0$val" : undef',
     },
     0x9003 => {
@@ -1443,5 +2036,9 @@
         Groups => { 2 => 'Time' },
         Notes => 'date/time when original image was taken',
+        Writable => 'string',
+        Shift => 'Time',
+        Validate => 'ValidateExifDate($val)',
         PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,0)',
     },
     0x9004 => {
@@ -1449,9 +2046,57 @@
         Groups => { 2 => 'Time' },
         Notes => 'called DateTimeDigitized by the EXIF spec.',
+        Writable => 'string',
+        Shift => 'Time',
+        Validate => 'ValidateExifDate($val)',
         PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,0)',
+    },
+    0x9009 => { # undef[44] (or undef[11]) written by Google Plus uploader - PH
+        Name => 'GooglePlusUploadCode',
+        Format => 'int8u',
+        Writable => 'undef',
+        Count => -1,
+    },
+    0x9010 => {
+        Name => 'OffsetTime',
+        Groups => { 2 => 'Time' },
+        Notes => 'time zone for ModifyDate',
+        Writable => 'string',
+        PrintConvInv => q{
+            return "+00:00" if $val =~ /\d{2}Z$/;
+            return sprintf("%s%.2d:%.2d",$1,$2,$3) if $val =~ /([-+])(\d{1,2}):(\d{2})/;
+            return undef;
+        },
+    },
+    0x9011 => {
+        Name => 'OffsetTimeOriginal',
+        Groups => { 2 => 'Time' },
+        Notes => 'time zone for DateTimeOriginal',
+        Writable => 'string',
+        PrintConvInv => q{
+            return "+00:00" if $val =~ /\d{2}Z$/;
+            return sprintf("%s%.2d:%.2d",$1,$2,$3) if $val =~ /([-+])(\d{1,2}):(\d{2})/;
+            return undef;
+        },
+    },
+    0x9012 => {
+        Name => 'OffsetTimeDigitized',
+        Groups => { 2 => 'Time' },
+        Notes => 'time zone for CreateDate',
+        Writable => 'string',
+        PrintConvInv => q{
+            return "+00:00" if $val =~ /\d{2}Z$/;
+            return sprintf("%s%.2d:%.2d",$1,$2,$3) if $val =~ /([-+])(\d{1,2}):(\d{2})/;
+            return undef;
+        },
     },
     0x9101 => {
         Name => 'ComponentsConfiguration',
         Format => 'int8u',
+        Protected => 1,
+        Writable => 'undef',
+        Count => 4,
+        Mandatory => 1,
+        ValueConvInv => '$val=~tr/,//d; $val',  # (so we can copy from XMP with -n)
         PrintConvColumns => 2,
         PrintConv => {
@@ -1485,37 +2130,64 @@
         },
     },
-    0x9102 => 'CompressedBitsPerPixel',
+    0x9102 => {
+        Name => 'CompressedBitsPerPixel',
+        Protected => 1,
+        Writable => 'rational64u',
+    },
+    # 0x9103 - int16u: 1 (found in Pentax XG-1 samples)
     0x9201 => {
         Name => 'ShutterSpeedValue',
+        Notes => 'displayed in seconds, but stored as an APEX value',
         Format => 'rational64s', # Leica M8 patch (incorrectly written as rational64u)
+        Writable => 'rational64s',
         ValueConv => 'abs($val)<100 ? 2**(-$val) : 0',
+        ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     },
     0x9202 => {
         Name => 'ApertureValue',
+        Notes => 'displayed as an F number, but stored as an APEX value',
+        Writable => 'rational64u',
         ValueConv => '2 ** ($val / 2)',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
         PrintConv => 'sprintf("%.1f",$val)',
-    },
-    0x9203 => 'BrightnessValue',
+        PrintConvInv => '$val',
+    },
+    # Wikipedia: BrightnessValue = Bv = Av + Tv - Sv
+    # ExifTool:  LightValue = LV = Av + Tv - Sv + 5 (5 is the Sv for ISO 100 in Exif usage)
+    0x9203 => {
+        Name => 'BrightnessValue',
+        Writable => 'rational64s',
+    },
     0x9204 => {
         Name => 'ExposureCompensation',
         Format => 'rational64s', # Leica M8 patch (incorrectly written as rational64u)
         Notes => 'called ExposureBiasValue by the EXIF spec.',
+        Writable => 'rational64s',
         PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+        PrintConvInv => '$val',
     },
     0x9205 => {
         Name => 'MaxApertureValue',
+        Notes => 'displayed as an F number, but stored as an APEX value',
         Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
         ValueConv => '2 ** ($val / 2)',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
         PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
     },
     0x9206 => {
         Name => 'SubjectDistance',
         Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
         PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "${val} m"',
+        PrintConvInv => '$val=~s/\s*m$//;$val',
     },
     0x9207 => {
         Name => 'MeteringMode',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Unknown',
@@ -1532,4 +2204,5 @@
         Name => 'LightSource',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         SeparateTable => 'LightSource',
         PrintConv => \%lightSource,
@@ -1538,4 +2211,5 @@
         Name => 'Flash',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         Flags => 'PrintHex',
         SeparateTable => 'Flash',
@@ -1545,8 +2219,10 @@
         Name => 'FocalLength',
         Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
         PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
     },
     # Note: tags 0x920b-0x9217 are duplicates of 0xa20b-0xa217
-    # (The TIFF standard uses 0xa2xx, but you'll find both in images)
+    # (The EXIF standard uses 0xa2xx, but you'll find both in images)
     0x920b => { #12
         Name => 'FlashEnergy',
@@ -1568,7 +2244,11 @@
         },
     },
-    0x9211 => 'ImageNumber', #12
+    0x9211 => { #12
+        Name => 'ImageNumber',
+        Writable => 'int32u',
+    },
     0x9212 => { #12
         Name => 'SecurityClassification',
+        Writable => 'string',
         PrintConv => {
             T => 'Top Secret',
@@ -1579,8 +2259,13 @@
         },
     },
-    0x9213 => 'ImageHistory', #12
+    0x9213 => { #12
+        Name => 'ImageHistory',
+        Writable => 'string',
+    },
     0x9214 => {
         Name => 'SubjectArea',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
+        Count => -1, # 2, 3 or 4 values
     },
     0x9215 => 'ExposureIndex', #12
@@ -1589,17 +2274,16 @@
         Name => 'SensingMethod',
         Groups => { 2 => 'Camera' },
-        Notes => 'values 1 and 6 are not standard EXIF',
         PrintConv => {
-            1 => 'Monochrome area', #12 (not standard EXIF)
+            # (values 1 and 6 are not used by corresponding EXIF tag 0xa217)
+            1 => 'Monochrome area',
             2 => 'One-chip color area',
             3 => 'Two-chip color area',
             4 => 'Three-chip color area',
             5 => 'Color sequential area',
-            6 => 'Monochrome linear', #12 (not standard EXIF)
+            6 => 'Monochrome linear',
             7 => 'Trilinear',
             8 => 'Color sequential linear',
         },
     },
-    0x9213 => 'ImageHistory',
     0x923a => 'CIP3DataFile', #20
     0x923b => 'CIP3Sheet', #20
@@ -1610,22 +2294,37 @@
     0x9286 => {
         Name => 'UserComment',
-        # may consider forcing a Format of 'undef' for this tag because I have
-        # seen other applications write it incorrectly as 'string' or 'int8u'
-        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        # I have seen other applications write it incorrectly as 'string' or 'int8u'
+        Format => 'undef',
+        Writable => 'undef',
+        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,1,$tag)',
+        #  (starts with "ASCII\0\0\0", "UNICODE\0", "JIS\0\0\0\0\0" or "\0\0\0\0\0\0\0\0")
+        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
+        # SHOULD ADD SPECIAL LOGIC TO ALLOW CONDITIONAL OVERWRITE OF
+        # "UNKNOWN" VALUES FILLED WITH SPACES
     },
     0x9290 => {
         Name => 'SubSecTime',
         Groups => { 2 => 'Time' },
+        Notes => 'fractional seconds for ModifyDate',
+        Writable => 'string',
         ValueConv => '$val=~s/ +$//; $val', # trim trailing blanks
+        # extract fractional seconds from a full date/time value
+        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
     },
     0x9291 => {
         Name => 'SubSecTimeOriginal',
         Groups => { 2 => 'Time' },
+        Notes => 'fractional seconds for DateTimeOriginal',
+        Writable => 'string',
         ValueConv => '$val=~s/ +$//; $val', # trim trailing blanks
+        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
     },
     0x9292 => {
         Name => 'SubSecTimeDigitized',
         Groups => { 2 => 'Time' },
+        Notes => 'fractional seconds for CreateDate',
+        Writable => 'string',
         ValueConv => '$val=~s/ +$//; $val', # trim trailing blanks
+        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
     },
     # The following 3 tags are found in MSOffice TIFF images
@@ -1644,16 +2343,66 @@
     },
     0x935c => { #3/19
-        Name => 'ImageSourceData',
+        Name => 'ImageSourceData', # (writable directory!)
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
+        SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::DocumentData' },
         Binary => 1,
-    },
+        Protected => 1,     # (because this can be hundreds of megabytes)
+        ReadFromRAF => 1,   # don't load into memory when reading
+    },
+    0x9400 => {
+        Name => 'AmbientTemperature',
+        Notes => 'ambient temperature in degrees C, called Temperature by the EXIF spec.',
+        Writable => 'rational64s',
+        PrintConv => '"$val C"',
+        PrintConvInv => '$val=~s/ ?C//; $val',
+    },
+    0x9401 => {
+        Name => 'Humidity',
+        Notes => 'ambient relative humidity in percent',
+        Writable => 'rational64u',
+    },
+    0x9402 => {
+        Name => 'Pressure',
+        Notes => 'air pressure in hPa or mbar',
+        Writable => 'rational64u',
+    },
+    0x9403 => {
+        Name => 'WaterDepth',
+        Notes => 'depth under water in metres, negative for above water',
+        Writable => 'rational64s',
+    },
+    0x9404 => {
+        Name => 'Acceleration',
+        Notes => 'directionless camera acceleration in units of mGal, or 10-5 m/s2',
+        Writable => 'rational64u',
+    },
+    0x9405 => {
+        Name => 'CameraElevationAngle',
+        Writable => 'rational64s',
+    },
+  # 0x9999 - string: camera settings (ExifIFD, Xiaomi POCO F1)
+  # 0x9aaa - int8u[2176]: ? (ExifIFD, Xiaomi POCO F1)
     0x9c9b => {
         Name => 'XPTitle',
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Notes => q{
+            tags 0x9c9b-0x9c9f are used by Windows Explorer; special characters
+            in these values are converted to UTF-8 by default, or Windows Latin1
+            with the -L option.  XPTitle is ignored by Windows Explorer if
+            ImageDescription exists
+        },
         ValueConv => '$self->Decode($val,"UCS2","II")',
+        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
     },
     0x9c9c => {
         Name => 'XPComment',
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
         ValueConv => '$self->Decode($val,"UCS2","II")',
+        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
     },
     0x9c9d => {
@@ -1661,19 +2410,32 @@
         Groups => { 2 => 'Author' },
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Notes => 'ignored by Windows Explorer if Artist exists',
         ValueConv => '$self->Decode($val,"UCS2","II")',
+        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
     },
     0x9c9e => {
         Name => 'XPKeywords',
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
         ValueConv => '$self->Decode($val,"UCS2","II")',
+        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
     },
     0x9c9f => {
         Name => 'XPSubject',
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
         ValueConv => '$self->Decode($val,"UCS2","II")',
+        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
     },
     0xa000 => {
         Name => 'FlashpixVersion',
+        Writable => 'undef',
+        Mandatory => 1,
         RawConv => '$val=~s/\0+$//; $val',  # (some idiots add null terminators)
+        PrintConvInv => '$val=~tr/.//d; $val=~/^\d{4}$/ ? $val : undef',
     },
     0xa001 => {
@@ -1684,4 +2446,6 @@
             0xfffd and 0xfffe are also non-standard, and are used by some Sony cameras
         },
+        Writable => 'int16u',
+        Mandatory => 1,
         PrintHex => 1,
         PrintConv => {
@@ -1698,10 +2462,17 @@
         Name => 'ExifImageWidth',
         Notes => 'called PixelXDimension by the EXIF spec.',
+        Writable => 'int16u',
+        Mandatory => 1,
     },
     0xa003 => {
         Name => 'ExifImageHeight',
         Notes => 'called PixelYDimension by the EXIF spec.',
-    },
-    0xa004 => 'RelatedSoundFile',
+        Writable => 'int16u',
+        Mandatory => 1,
+    },
+    0xa004 => {
+        Name => 'RelatedSoundFile',
+        Writable => 'string',
+    },
     0xa005 => {
         Name => 'InteropOffset',
@@ -1712,9 +2483,32 @@
             DirName => 'InteropIFD',
             Start => '$val',
-        },
+            MaxSubdirs => 1,
+        },
+    },
+    # the following 4 tags found in SubIFD1 of some Samsung SRW images
+    0xa010 => {
+        Name => 'SamsungRawPointersOffset',
+        IsOffset => 1,
+        OffsetPair => 0xa011,  # point to associated byte count
+    },
+    0xa011 => {
+        Name => 'SamsungRawPointersLength',
+        OffsetPair => 0xa010,  # point to associated offset
+    },
+    0xa101 => {
+        Name => 'SamsungRawByteOrder',
+        Format => 'undef',
+        # this is written incorrectly as string[1], but is "\0\0MM" or "II\0\0"
+        FixedSize => 4,
+        Count => 1,
+    },
+    0xa102 => {
+        Name => 'SamsungRawUnknown',
+        Unknown => 1,
     },
     0xa20b => {
         Name => 'FlashEnergy',
         Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
     },
     0xa20c => {
@@ -1723,10 +2517,19 @@
     },
     0xa20d => 'Noise',
-    0xa20e => { Name => 'FocalPlaneXResolution', Groups => { 2 => 'Camera' } },
-    0xa20f => { Name => 'FocalPlaneYResolution', Groups => { 2 => 'Camera' } },
+    0xa20e => {
+        Name => 'FocalPlaneXResolution',
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
+    },
+    0xa20f => {
+        Name => 'FocalPlaneYResolution',
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
+    },
     0xa210 => {
         Name => 'FocalPlaneResolutionUnit',
         Groups => { 2 => 'Camera' },
         Notes => 'values 1, 4 and 5 are not standard EXIF',
+        Writable => 'int16u',
         PrintConv => {
             1 => 'None', # (not standard EXIF)
@@ -1743,10 +2546,13 @@
         Name => 'SubjectLocation',
         Groups => { 2 => 'Camera' },
-    },
-    0xa215 => 'ExposureIndex',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0xa215 => { Name => 'ExposureIndex', Writable => 'rational64u' },
     0xa216 => 'TIFF-EPStandardID',
     0xa217 => {
         Name => 'SensingMethod',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => {
             1 => 'Not defined',
@@ -1757,8 +2563,11 @@
             7 => 'Trilinear',
             8 => 'Color sequential linear',
+            # 15 - used by DJI XT2
         },
     },
     0xa300 => {
         Name => 'FileSource',
+        Writable => 'undef',
+        ValueConvInv => '($val=~/^\d+$/ and $val < 256) ? chr($val) : $val',
         PrintConv => {
             1 => 'Film Scanner',
@@ -1771,4 +2580,6 @@
     0xa301 => {
         Name => 'SceneType',
+        Writable => 'undef',
+        ValueConvInv => 'chr($val)',
         PrintConv => {
             1 => 'Directly photographed',
@@ -1777,11 +2588,31 @@
     0xa302 => {
         Name => 'CFAPattern',
+        Writable => 'undef',
+        RawConv => 'Image::ExifTool::Exif::DecodeCFAPattern($self, $val)',
+        RawConvInv => q{
+            my @a = split ' ', $val;
+            return $val if @a <= 2; # also accept binary data for backward compatibility
+            return pack(GetByteOrder() eq 'II' ? 'v2C*' : 'n2C*', @a);
+        },
         PrintConv => 'Image::ExifTool::Exif::PrintCFAPattern($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::GetCFAPattern($val)',
     },
     0xa401 => {
         Name => 'CustomRendered',
+        Writable => 'int16u',
+        Notes => q{
+            only 0 and 1 are standard EXIF, but other values are used by Apple iOS
+            devices
+        },
         PrintConv => {
             0 => 'Normal',
             1 => 'Custom',
+            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 => 'Portrait HDR',            #32 non-standard (Apple iOS)
+            8 => 'Portrait', # non-standard (Apple iOS, blurred background)
+            # 9 - also seen (Apple iOS) (HDR Portrait?)
         },
     },
@@ -1789,9 +2620,10 @@
         Name => 'ExposureMode',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Auto',
             1 => 'Manual',
             2 => 'Auto bracket',
-            # have seen 3 for Samsung EX1 images - PH
+            # have seen 3 from Samsung EX1, NX30, NX200 - PH
         },
     },
@@ -1799,4 +2631,5 @@
         Name => 'WhiteBalance',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         # set Priority to zero to keep this WhiteBalance from overriding the
         # MakerNotes WhiteBalance, since the MakerNotes WhiteBalance and is more
@@ -1811,4 +2644,5 @@
         Name => 'DigitalZoomRatio',
         Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
     },
     0xa405 => {
@@ -1816,9 +2650,13 @@
         Notes => 'called FocalLengthIn35mmFilm by the EXIF spec.',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => '"$val mm"',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
     },
     0xa406 => {
         Name => 'SceneCaptureType',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
+        Notes => 'the value of 4 is non-standard, and used by some Samsung models',
         PrintConv => {
             0 => 'Standard',
@@ -1826,4 +2664,5 @@
             2 => 'Portrait',
             3 => 'Night',
+            4 => 'Other', # (non-standard Samsung, ref forum 5724)
         },
     },
@@ -1831,4 +2670,5 @@
         Name => 'GainControl',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => {
             0 => 'None',
@@ -1842,4 +2682,5 @@
         Name => 'Contrast',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Normal',
@@ -1847,8 +2688,10 @@
             2 => 'High',
         },
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
     },
     0xa409 => {
         Name => 'Saturation',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Normal',
@@ -1856,8 +2699,10 @@
             2 => 'High',
         },
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
     },
     0xa40a => {
         Name => 'Sharpness',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Normal',
@@ -1865,4 +2710,5 @@
             2 => 'Hard',
         },
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
     },
     0xa40b => {
@@ -1874,4 +2720,5 @@
         Name => 'SubjectDistanceRange',
         Groups => { 2 => 'Camera' },
+        Writable => 'int16u',
         PrintConv => {
             0 => 'Unknown',
@@ -1883,12 +2730,14 @@
     # 0xa40d - int16u: 0 (GE E1486 TW)
     # 0xa40e - int16u: 1 (GE E1486 TW)
-    0xa420 => 'ImageUniqueID',
+    0xa420 => { Name => 'ImageUniqueID', Writable => 'string' },
     0xa430 => { #24
         Name => 'OwnerName',
         Notes => 'called CameraOwnerName by the EXIF spec.',
+        Writable => 'string',
     },
     0xa431 => { #24
         Name => 'SerialNumber',
         Notes => 'called BodySerialNumber by the EXIF spec.',
+        Writable => 'string',
     },
     0xa432 => { #24
@@ -1898,13 +2747,85 @@
             by the EXIF spec.
         },
+        Writable => 'rational64u',
+        Count => 4,
         # convert to the form "12-20mm f/3.8-4.5" or "50mm f/1.4"
-        PrintConv => \&Image::ExifTool::Exif::PrintLensInfo,
-    },
-    0xa433 => 'LensMake', #24
-    0xa434 => 'LensModel', #24
-    0xa435 => 'LensSerialNumber', #24
-    0xa480 => 'GDALMetadata', #3
-    0xa481 => 'GDALNoData', #3
-    0xa500 => 'Gamma',
+        PrintConv => \&PrintLensInfo,
+        PrintConvInv => \&ConvertLensInfo,
+    },
+    0xa433 => { Name => 'LensMake',         Writable => 'string' }, #24
+    0xa434 => { Name => 'LensModel',        Writable => 'string' }, #24
+    0xa435 => { Name => 'LensSerialNumber', Writable => 'string' }, #24
+    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)
@@ -1913,4 +2834,5 @@
     0xafc4 => 'ExpandScanner', #JD (Opanda)
     0xafc5 => 'ExpandFlashLamp', #JD (Opanda)
+    0xb4c3 => { Name => 'HasselbladRawImage', Format => 'undef', Binary => 1 }, #IB
 #
 # Windows Media Photo / HD Photo (WDP/HDP) tags
@@ -2067,8 +2989,26 @@
         Writable => 'undef',
         WriteGroup => 'IFD0',
+        Binary => 1,
+        # (don't make Binary/Protected because we can't copy individual PrintIM tags anyway)
         Description => 'Print Image Matching',
         SubDirectory => {
             TagTable => 'Image::ExifTool::PrintIM::Main',
         },
+        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?)
+        # (it is a 'string', but obscure, so don't make it writable)
     },
     0xc580 => { #20
@@ -2080,4 +3020,21 @@
         },
     },
+    # 0xc5d8 - found in CR2 images
+    # 0xc5d9 - found in CR2 images
+    0xc5e0 => { #forum8153 (CR2 images)
+        Name => 'CR2CFAPattern',
+        ValueConv => {
+            1 => '0 1 1 2',
+            2 => '2 1 1 0',
+            3 => '1 2 0 1',
+            4 => '1 0 2 1',
+        },
+        PrintConv => {
+            '0 1 1 2' => '[Red,Green][Green,Blue]',
+            '2 1 1 0' => '[Blue,Green][Green,Red]',
+            '1 2 0 1' => '[Green,Blue][Red,Green]',
+            '1 0 2 1' => '[Green,Red][Blue,Green]',
+        },
+    },
 #
 # DNG tags 0xc6XX and 0xc7XX (ref 2 unless otherwise stated)
@@ -2085,18 +3042,42 @@
     0xc612 => {
         Name => 'DNGVersion',
-        Notes => 'tags 0xc612-0xc761 are used in DNG images unless otherwise noted',
+        Notes => q{
+            tags 0xc612-0xc7b5 are defined by the DNG specification unless otherwise
+            noted.  See L<https://helpx.adobe.com/photoshop/digital-negative.html> for
+            the specification
+        },
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 4,
+        Protected => 1, # (confuses Apple Preview if written to a TIFF image)
         DataMember => 'DNGVersion',
         RawConv => '$$self{DNGVersion} = $val',
         PrintConv => '$val =~ tr/ /./; $val',
-    },
-    0xc613 => 'DNGBackwardVersion',
-    0xc614 => 'UniqueCameraModel',
+        PrintConvInv => '$val =~ tr/./ /; $val',
+    },
+    0xc613 => {
+        Name => 'DNGBackwardVersion',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 4,
+        Protected => 1,
+        PrintConv => '$val =~ tr/ /./; $val',
+        PrintConvInv => '$val =~ tr/./ /; $val',
+    },
+    0xc614 => {
+        Name => 'UniqueCameraModel',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
     0xc615 => {
         Name => 'LocalizedCameraModel',
-        Format => 'string',
+        WriteGroup => 'IFD0',
+        %utf8StringConv,
         PrintConv => '$self->Printable($val, 0)',
+        PrintConvInv => '$val',
     },
     0xc616 => {
         Name => 'CFAPlaneColor',
+        WriteGroup => 'SubIFD', # (only for Validate)
         PrintConv => q{
             my @cols = qw(Red Green Blue Cyan Magenta Yellow White);
@@ -2107,4 +3088,5 @@
     0xc617 => {
         Name => 'CFALayout',
+        WriteGroup => 'SubIFD', # (only for Validate)
         PrintConv => {
             1 => 'Rectangular',
@@ -2120,39 +3102,196 @@
         },
     },
-    0xc618 => { Name => 'LinearizationTable', Binary => 1 },
-    0xc619 => 'BlackLevelRepeatDim',
-    0xc61a => 'BlackLevel',
-    0xc61b => { Name => 'BlackLevelDeltaH', %longBin },
-    0xc61c => { Name => 'BlackLevelDeltaV', %longBin },
-    0xc61d => 'WhiteLevel',
-    0xc61e => 'DefaultScale',
-    0xc61f => 'DefaultCropOrigin',
-    0xc620 => 'DefaultCropSize',
-    0xc621 => 'ColorMatrix1',
-    0xc622 => 'ColorMatrix2',
-    0xc623 => 'CameraCalibration1',
-    0xc624 => 'CameraCalibration2',
-    0xc625 => 'ReductionMatrix1',
-    0xc626 => 'ReductionMatrix2',
-    0xc627 => 'AnalogBalance',
-    0xc628 => 'AsShotNeutral',
-    0xc629 => 'AsShotWhiteXY',
-    0xc62a => 'BaselineExposure',
-    0xc62b => 'BaselineNoise',
-    0xc62c => 'BaselineSharpness',
-    0xc62d => 'BayerGreenSplit',
-    0xc62e => 'LinearResponseLimit',
+    0xc618 => {
+        Name => 'LinearizationTable',
+        Writable => 'int16u',
+        WriteGroup => 'SubIFD',
+        Count => -1,
+        Protected => 1,
+        Binary => 1,
+    },
+    0xc619 => {
+        Name => 'BlackLevelRepeatDim',
+        Writable => 'int16u',
+        WriteGroup => 'SubIFD',
+        Count => 2,
+        Protected => 1,
+    },
+    0xc61a => {
+        Name => 'BlackLevel',
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc61b => {
+        Name => 'BlackLevelDeltaH',
+        %longBin,
+        Writable => 'rational64s',
+        WriteGroup => 'SubIFD',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc61c => {
+        Name => 'BlackLevelDeltaV',
+        %longBin,
+        Writable => 'rational64s',
+        WriteGroup => 'SubIFD',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc61d => {
+        Name => 'WhiteLevel',
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc61e => {
+        Name => 'DefaultScale',
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+        Count => 2,
+        Protected => 1,
+    },
+    0xc61f => {
+        Name => 'DefaultCropOrigin',
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => 2,
+        Protected => 1,
+    },
+    0xc620 => {
+        Name => 'DefaultCropSize',
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => 2,
+        Protected => 1,
+    },
+    0xc621 => {
+        Name => 'ColorMatrix1',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc622 => {
+        Name => 'ColorMatrix2',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc623 => {
+        Name => 'CameraCalibration1',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc624 => {
+        Name => 'CameraCalibration2',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc625 => {
+        Name => 'ReductionMatrix1',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc626 => {
+        Name => 'ReductionMatrix2',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc627 => {
+        Name => 'AnalogBalance',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc628 => {
+        Name => 'AsShotNeutral',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc629 => {
+        Name => 'AsShotWhiteXY',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+        Protected => 1,
+    },
+    0xc62a => {
+        Name => 'BaselineExposure',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
+    0xc62b => {
+        Name => 'BaselineNoise',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
+    0xc62c => {
+        Name => 'BaselineSharpness',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
+    0xc62d => {
+        Name => 'BayerGreenSplit',
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Protected => 1,
+    },
+    0xc62e => {
+        Name => 'LinearResponseLimit',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
     0xc62f => {
         Name => 'CameraSerialNumber',
         Groups => { 2 => 'Camera' },
+        Writable => 'string',
+        WriteGroup => 'IFD0',
     },
     0xc630 => {
         Name => 'DNGLensInfo',
         Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 4,
         PrintConv =>\&PrintLensInfo,
-    },
-    0xc631 => 'ChromaBlurRadius',
-    0xc632 => 'AntiAliasStrength',
-    0xc633 => 'ShadowScale',
+        PrintConvInv => \&ConvertLensInfo,
+    },
+    0xc631 => {
+        Name => 'ChromaBlurRadius',
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+        Protected => 1,
+    },
+    0xc632 => {
+        Name => 'AntiAliasStrength',
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+        Protected => 1,
+    },
+    0xc633 => {
+        Name => 'ShadowScale',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
     0xc634 => [
         {
@@ -2162,8 +3301,9 @@
             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)
+            WriteGroup => 'IFD0', # (for Validate)
             SubDirectory => {
                 DirName => 'SR2Private',
@@ -2175,13 +3315,23 @@
             Condition => '$$valPt =~ /^Adobe\0/',
             Name => 'DNGAdobeData',
+            Flags => [ 'Binary', 'Protected' ],
+            Writable => 'undef', # (writable directory!) (to make it possible to delete this mess)
+            WriteGroup => 'IFD0',
             NestedHtmlDump => 1,
             SubDirectory => { TagTable => 'Image::ExifTool::DNG::AdobeData' },
-            Format => 'undef',  # written incorrectly as int8u (change to undef for speed)
+            Format => 'undef',  # but written as int8u (change to undef for speed)
         },
         {
-            Condition => '$$valPt =~ /^(PENTAX |SAMSUNG)\0/',
+            # Pentax/Samsung models that write AOC maker notes in JPG images:
+            # K-5,K-7,K-m,K-x,K-r,K10D,K20D,K100D,K110D,K200D,K2000,GX10,GX20
+            # (Note: the following expression also appears in WriteExif.pl)
+            Condition => q{
+                $$valPt =~ /^(PENTAX |SAMSUNG)\0/ and
+                $$self{Model} =~ /\b(K(-[57mrx]|(10|20|100|110|200)D|2000)|GX(10|20))\b/
+            },
             Name => 'MakerNotePentax',
             MakerNotes => 1,    # (causes "MakerNotes header" to be identified in HtmlDump output)
             Binary => 1,
+            WriteGroup => 'IFD0', # (for Validate)
             # Note: Don't make this block-writable for a few reasons:
             # 1) It would be dangerous (possibly confusing Pentax software)
@@ -2194,14 +3344,52 @@
                 ByteOrder => 'Unknown', # easier to do this than read byteorder word
             },
-            Format => 'undef',  # written incorrectly as int8u (change to undef for speed)
-        },
+            Format => 'undef',  # but written as int8u (change to undef for speed)
+        },
+        {
+            # must duplicate the above tag with a different name for more recent
+            # Pentax models which use the "PENTAX" instead of the "AOC" maker notes
+            # in JPG images (needed when copying maker notes from DNG to JPG)
+            Condition => '$$valPt =~ /^(PENTAX |SAMSUNG)\0/',
+            Name => 'MakerNotePentax5',
+            MakerNotes => 1,
+            Binary => 1,
+            WriteGroup => 'IFD0', # (for Validate)
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Pentax::Main',
+                Start => '$valuePtr + 10',
+                Base => '$start - 10',
+                ByteOrder => 'Unknown',
+            },
+            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',
-            Binary => 1,
+            Flags => [ 'Binary', 'Protected' ],
             Format => 'undef',
+            Writable => 'int8u',
+            WriteGroup => 'IFD0',
         },
     ],
     0xc635 => {
         Name => 'MakerNoteSafety',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
         PrintConv => {
             0 => 'Unsafe',
@@ -2219,4 +3407,7 @@
     0xc65a => {
         Name => 'CalibrationIlluminant1',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
         SeparateTable => 'LightSource',
         PrintConv => \%lightSource,
@@ -2224,12 +3415,25 @@
     0xc65b => {
         Name => 'CalibrationIlluminant2',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
         SeparateTable => 'LightSource',
         PrintConv => \%lightSource,
     },
-    0xc65c => 'BestQualityScale',
+    0xc65c => {
+        Name => 'BestQualityScale',
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+        Protected => 1,
+    },
     0xc65d => {
         Name => 'RawDataUniqueID',
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 16,
+        Protected => 1,
         ValueConv => 'uc(unpack("H*",$val))',
+        ValueConvInv => 'pack("H*", $val)',
     },
     0xc660 => { #3
@@ -2239,5 +3443,7 @@
     0xc68b => {
         Name => 'OriginalRawFileName',
-        Format => 'string', # sometimes written as int8u
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
     },
     0xc68c => {
@@ -2250,10 +3456,28 @@
         },
     },
-    0xc68d => 'ActiveArea',
-    0xc68e => 'MaskedAreas',
+    0xc68d => {
+        Name => 'ActiveArea',
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => 4,
+        Protected => 1,
+    },
+    0xc68e => {
+        Name => 'MaskedAreas',
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD',
+        Count => -1,
+        Protected => 1,
+    },
     0xc68f => {
-        Name => 'AsShotICCProfile',
+        Name => 'AsShotICCProfile', # (writable directory)
         Binary => 1,
         Writable => 'undef', # must be defined here so tag will be extracted if specified
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        WriteCheck => q{
+            require Image::ExifTool::ICC_Profile;
+            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
+        },
         SubDirectory => {
             DirName => 'AsShotICCProfile',
@@ -2261,7 +3485,13 @@
         },
     },
-    0xc690 => 'AsShotPreProfileMatrix',
+    0xc690 => {
+        Name => 'AsShotPreProfileMatrix',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
     0xc691 => {
-        Name => 'CurrentICCProfile',
+        Name => 'CurrentICCProfile', # (writable directory)
         Binary => 1,
         Writable => 'undef', # must be defined here so tag will be extracted if specified
@@ -2270,7 +3500,26 @@
             TagTable => 'Image::ExifTool::ICC_Profile::Main',
         },
-    },
-    0xc692 => 'CurrentPreProfileMatrix',
-    0xc6bf => 'ColorimetricReference',
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        WriteCheck => q{
+            require Image::ExifTool::ICC_Profile;
+            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
+        },
+    },
+    0xc692 => {
+        Name => 'CurrentPreProfileMatrix',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc6bf => {
+        Name => 'ColorimetricReference',
+        Writable => 'int16u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
+    0xc6c5 => { Name => 'SRawType', Description => 'SRaw Type', WriteGroup => 'IFD0' }, #exifprobe (CR2 proprietary)
     0xc6d2 => { #JD (Panasonic DMC-TZ5)
         # this text is UTF-8 encoded (hooray!) - PH (TZ5)
@@ -2278,8 +3527,11 @@
         Format => 'string', # written incorrectly as 'undef'
         Notes => 'proprietary Panasonic tag used for baby/pet name, etc',
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
         # panasonic always records this tag (64 zero bytes),
         # so ignore it unless it contains valid information
         RawConv => 'length($val) ? $val : undef',
         ValueConv => '$self->Decode($val, "UTF8")',
+        ValueConvInv => '$self->Encode($val,"UTF8")',
     },
     0xc6d3 => { #PH (Panasonic DMC-FS7)
@@ -2287,15 +3539,31 @@
         Format => 'string', # written incorrectly as 'undef'
         Notes => 'proprietary Panasonic tag used for baby/pet name with age',
+        Writable => 'undef',
+        WriteGroup => 'IFD0',
         # panasonic always records this tag (128 zero bytes),
         # so ignore it unless it contains valid information
         RawConv => 'length($val) ? $val : undef',
         ValueConv => '$self->Decode($val, "UTF8")',
-    },
-    0xc6f3 => 'CameraCalibrationSig',
-    0xc6f4 => 'ProfileCalibrationSig',
+        ValueConvInv => '$self->Encode($val,"UTF8")',
+    },
+    # 0xc6dc - int32u[4]: found in CR2 images (PH, 7DmkIII)
+    # 0xc6dd - int16u[256]: found in CR2 images (PH, 5DmkIV)
+    0xc6f3 => {
+        Name => 'CameraCalibrationSig',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
+    },
+    0xc6f4 => {
+        Name => 'ProfileCalibrationSig',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
+    },
     0xc6f5 => {
         Name => 'ProfileIFD', # (ExtraCameraProfiles)
         Groups => { 1 => 'ProfileIFD' },
         Flags => 'SubIFD',
+        WriteGroup => 'IFD0', # (only for Validate)
         SubDirectory => {
             ProcessProc => \&ProcessTiffIFD,
@@ -2308,16 +3576,58 @@
         },
     },
-    0xc6f6 => 'AsShotProfileName',
-    0xc6f7 => 'NoiseReductionApplied',
-    0xc6f8 => 'ProfileName',
-    0xc6f9 => 'ProfileHueSatMapDims',
-    0xc6fa => 'ProfileHueSatMapData1',
-    0xc6fb => 'ProfileHueSatMapData2',
+    0xc6f6 => {
+        Name => 'AsShotProfileName',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
+    },
+    0xc6f7 => {
+        Name => 'NoiseReductionApplied',
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+        Protected => 1,
+    },
+    0xc6f8 => {
+        Name => 'ProfileName',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
+    },
+    0xc6f9 => {
+        Name => 'ProfileHueSatMapDims',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Count => 3,
+        Protected => 1,
+    },
+    0xc6fa => {
+        Name => 'ProfileHueSatMapData1',
+        %longBin,
+        Writable => 'float',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc6fb => {
+        Name => 'ProfileHueSatMapData2',
+        %longBin,
+        Writable => 'float',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
     0xc6fc => {
         Name => 'ProfileToneCurve',
+        Writable => 'float',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
         Binary => 1,
     },
     0xc6fd => {
         Name => 'ProfileEmbedPolicy',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
         PrintConv => {
             0 => 'Allow Copying',
@@ -2327,71 +3637,412 @@
         },
     },
-    0xc6fe => 'ProfileCopyright',
-    0xc714 => 'ForwardMatrix1',
-    0xc715 => 'ForwardMatrix2',
-    0xc716 => 'PreviewApplicationName',
-    0xc717 => 'PreviewApplicationVersion',
-    0xc718 => 'PreviewSettingsName',
+    0xc6fe => {
+        Name => 'ProfileCopyright',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
+    },
+    0xc714 => {
+        Name => 'ForwardMatrix1',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc715 => {
+        Name => 'ForwardMatrix2',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc716 => {
+        Name => 'PreviewApplicationName',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
+    },
+    0xc717 => {
+        Name => 'PreviewApplicationVersion',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
+    },
+    0xc718 => {
+        Name => 'PreviewSettingsName',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        %utf8StringConv,
+    },
     0xc719 => {
         Name => 'PreviewSettingsDigest',
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
         ValueConv => 'unpack("H*", $val)',
-    },
-    0xc71a => 'PreviewColorSpace',
+        ValueConvInv => 'pack("H*", $val)',
+    },
+    0xc71a => {
+        Name => 'PreviewColorSpace',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'Gray Gamma 2.2',
+            2 => 'sRGB',
+            3 => 'Adobe RGB',
+            4 => 'ProPhoto RGB',
+        },
+    },
     0xc71b => {
         Name => 'PreviewDateTime',
         Groups => { 2 => 'Time' },
+        Writable => 'string',
+        Shift => 'Time',
+        WriteGroup => 'IFD0',
+        Protected => 1,
         ValueConv => q{
             require Image::ExifTool::XMP;
             return Image::ExifTool::XMP::ConvertXMPDate($val);
         },
+        ValueConvInv => q{
+            require Image::ExifTool::XMP;
+            return Image::ExifTool::XMP::FormatXMPDate($val);
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,1,1)',
     },
     0xc71c => {
         Name => 'RawImageDigest',
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 16,
+        Protected => 1,
         ValueConv => 'unpack("H*", $val)',
+        ValueConvInv => 'pack("H*", $val)',
     },
     0xc71d => {
         Name => 'OriginalRawFileDigest',
         Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 16,
+        Protected => 1,
         ValueConv => 'unpack("H*", $val)',
+        ValueConvInv => 'pack("H*", $val)',
     },
     0xc71e => 'SubTileBlockSize',
     0xc71f => 'RowInterleaveFactor',
-    0xc725 => 'ProfileLookTableDims',
+    0xc725 => {
+        Name => 'ProfileLookTableDims',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Count => 3,
+        Protected => 1,
+    },
     0xc726 => {
         Name => 'ProfileLookTableData',
+        Writable => 'float',
+        WriteGroup => 'IFD0',
+        Count => -1,
+        Protected => 1,
         Binary => 1,
     },
-    0xc740 => { # DNG 1.3
-        Name => 'OpcodeList1',
-        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',
-        Binary => 1,
-    },
-    0xc74e => { # DNG 1.3
-        Name => 'OpcodeList3',
-        Binary => 1,
-    },
-    0xc761 => 'NoiseProfile', # DNG 1.3
+    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',
+        WriteGroup => 'SubIFD',
+        Count => -1,
+        Protected => 1,
+    },
+    0xc763 => { #28
+        Name => 'TimeCodes',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => -1, # (8 * number of time codes, max 10)
+        ValueConv => q{
+            my @a = split ' ', $val;
+            my @v;
+            push @v, join('.', map { sprintf('%.2x',$_) } splice(@a,0,8)) while @a >= 8;
+            join ' ', @v;
+        },
+        ValueConvInv => q{
+            my @a = map hex, split /[. ]+/, $val;
+            join ' ', @a;
+        },
+        # Note: Currently ignore the flags:
+        #   byte 0 0x80 - color frame
+        #   byte 0 0x40 - drop frame
+        #   byte 1 0x80 - field phase
+        PrintConv => q{
+            my @a = map hex, split /[. ]+/, $val;
+            my @v;
+            while (@a >= 8) {
+                my $str = sprintf("%.2x:%.2x:%.2x.%.2x", $a[3]&0x3f,
+                                 $a[2]&0x7f, $a[1]&0x7f, $a[0]&0x3f);
+                if ($a[3] & 0x80) { # date+timezone exist if BGF2 is set
+                    my $tz = $a[7] & 0x3f;
+                    my $bz = sprintf('%.2x', $tz);
+                    $bz = 100 if $bz =~ /[a-f]/i; # not BCD
+                    if ($bz < 26) {
+                        $tz = ($bz < 13 ? 0 : 26) - $bz;
+                    } elsif ($bz == 32) {
+                        $tz = 12.75;
+                    } elsif ($bz >= 28 and $bz <= 31) {
+                        $tz = 0;    # UTC
+                    } elsif ($bz < 100) {
+                        undef $tz;  # undefined or user-defined
+                    } elsif ($tz < 0x20) {
+                        $tz = (($tz < 0x10 ? 10 : 20) - $tz) - 0.5;
+                    } else {
+                        $tz = (($tz < 0x30 ? 53 : 63) - $tz) + 0.5;
+                    }
+                    if ($a[7] & 0x80) { # MJD format (/w UTC time)
+                        my ($h,$m,$s,$f) = split /[:.]/, $str;
+                        my $jday = sprintf('%x%.2x%.2x', reverse @a[4..6]);
+                        $str = ConvertUnixTime(($jday - 40587) * 24 * 3600
+                                 + ((($h+$tz) * 60) + $m) * 60 + $s) . ".$f";
+                        $str =~ s/^(\d+):(\d+):(\d+) /$1-$2-${3}T/;
+                    } else { # YYMMDD (Note: CinemaDNG 1.1 example seems wrong)
+                        my $yr = sprintf('%.2x',$a[6]) + 1900;
+                        $yr += 100 if $yr < 1970;
+                        $str = sprintf('%d-%.2x-%.2xT%s',$yr,$a[5],$a[4],$str);
+                    }
+                    $str .= TimeZoneString($tz*60) if defined $tz;
+                }
+                push @v, $str;
+                splice @a, 0, 8;
+            }
+            join ' ', @v;
+        },
+        PrintConvInv => q{
+            my @a = split ' ', $val;
+            my @v;
+            foreach (@a) {
+                my @td = reverse split /T/;
+                my $tz = 0x39; # default to unknown timezone
+                if ($td[0] =~ s/([-+])(\d+):(\d+)$//) {
+                    if ($3 == 0) {
+                        $tz = hex(($1 eq '-') ? $2 : 0x26 - $2);
+                    } elsif ($3 == 30) {
+                        if ($1 eq '-') {
+                            $tz = $2 + 0x0a;
+                            $tz += 0x0a if $tz > 0x0f;
+                        } else {
+                            $tz = 0x3f - $2;
+                            $tz -= 0x0a if $tz < 0x3a;
+                        }
+                    } elsif ($3 == 45) {
+                        $tz = 0x32 if $1 eq '+' and $2 == 12;
+                    }
+                }
+                my @t = split /[:.]/, $td[0];
+                push @t, '00' while @t < 4;
+                my $bg;
+                if ($td[1]) {
+                    # date was specified: fill in date & timezone
+                    my @d = split /[-]/, $td[1];
+                    next if @d < 3;
+                    $bg = sprintf('.%.2d.%.2d.%.2d.%.2x', $d[2], $d[1], $d[0]%100, $tz);
+                    $t[0] = sprintf('%.2x', hex($t[0]) + 0xc0); # set BGF1+BGF2
+                } else { # time only
+                    $bg = '.00.00.00.00';
+                }
+                push @v, join('.', reverse(@t[0..3])) . $bg;
+            }
+            join ' ', @v;
+        },
+    },
+    0xc764 => { #28
+        Name => 'FrameRate',
+        Writable => 'rational64s',
+        WriteGroup => 'IFD0',
+        PrintConv => 'int($val * 1000 + 0.5) / 1000',
+        PrintConvInv => '$val',
+    },
+    0xc772 => { #28
+        Name => 'TStop',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => -1, # (1 or 2)
+        PrintConv => 'join("-", map { sprintf("%.2f",$_) } split " ", $val)',
+        PrintConvInv => '$val=~tr/-/ /; $val',
+    },
+    0xc789 => { #28
+        Name => 'ReelName',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0xc791 => { # DNG 1.4
+        Name => 'OriginalDefaultFinalSize',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+        Protected => 1,
+    },
+    0xc792 => { # DNG 1.4
+        Name => 'OriginalBestQualitySize',
+        Notes => 'called OriginalBestQualityFinalSize by the DNG spec',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+        Protected => 1,
+    },
+    0xc793 => { # DNG 1.4
+        Name => 'OriginalDefaultCropSize',
+        Writable => 'rational64u',
+        WriteGroup => 'IFD0',
+        Count => 2,
+        Protected => 1,
+    },
+    0xc7a1 => {  #28
+        Name => 'CameraLabel',
+        Writable => 'string',
+        WriteGroup => 'IFD0',
+    },
+    0xc7a3 => { # DNG 1.4
+        Name => 'ProfileHueSatMapEncoding',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        PrintConv => {
+            0 => 'Linear',
+            1 => 'sRGB',
+        },
+    },
+    0xc7a4 => { # DNG 1.4
+        Name => 'ProfileLookTableEncoding',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        PrintConv => {
+            0 => 'Linear',
+            1 => 'sRGB',
+        },
+    },
+    0xc7a5 => { # DNG 1.4
+        Name => 'BaselineExposureOffset',
+        Writable => 'rational64s', # (incorrectly "RATIONAL" in DNG 1.4 spec)
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
+    0xc7a6 => { # DNG 1.4
+        Name => 'DefaultBlackRender',
+        Writable => 'int32u',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'None',
+        },
+    },
+    0xc7a7 => { # DNG 1.4
+        Name => 'NewRawImageDigest',
+        Format => 'undef',
+        Writable => 'int8u',
+        WriteGroup => 'IFD0',
+        Count => 16,
+        Protected => 1,
+        ValueConv => 'unpack("H*", $val)',
+        ValueConvInv => 'pack("H*", $val)',
+    },
+    0xc7a8 => { # DNG 1.4
+        Name => 'RawToPreviewGain',
+        Writable => 'double',
+        WriteGroup => 'IFD0',
+        Protected => 1,
+    },
+    # 0xc7a9 - CacheBlob (ref 31)
+    0xc7aa => { #31 undocumented DNG tag written by LR4 (val=256, related to fast load data?)
+        Name => 'CacheVersion',
+        Writable => 'int32u',
+        WriteGroup => 'SubIFD2',
+        Format => 'int8u',
+        Count => 4,
+        Protected => 1,
+        PrintConv => '$val =~ tr/ /./; $val',
+        PrintConvInv => '$val =~ tr/./ /; $val',
+    },
+    0xc7b5 => { # DNG 1.4
+        Name => 'DefaultUserCrop',
+        Writable => 'rational64u',
+        WriteGroup => 'SubIFD',
+        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,
+        Protected => 1,
         Writable => 'undef',
         # must start with 0x1c 0xea by the WM Photo specification
@@ -2403,4 +4054,6 @@
         Name => 'OffsetSchema',
         Notes => "Microsoft's ill-conceived maker note offset difference",
+        Protected => 1,
+        Writable => 'int32s',
         # From the Microsoft documentation:
         #
@@ -2428,11 +4081,133 @@
         # they have taken no steps to address this.
     },
+    # 0xefee - int16u: 0 - seen this from a WIC-scanned image
 
     # 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 => {
+        Name => 'OwnerName',
+        Condition => '$$self{TIFF_TYPE} ne "DCR"', # (used for another purpose in Kodak DCR images)
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Owner's Name: $val"},
+        Notes => q{
+            tags 0xfde8-0xfdea and 0xfe4c-0xfe58 are generated by Photoshop Camera RAW.
+            Some names are the same as other EXIF tags, but ExifTool will avoid writing
+            these unless they already exist in the file
+        },
+    },
+    0xfde9 => {
+        Name => 'SerialNumber',
+        Condition => '$$self{TIFF_TYPE} ne "DCR"', # (used for another purpose in Kodak DCR SubIFD)
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Serial Number: $val"},
+    },
+    0xfdea => {
+        Name => 'Lens',
+        Condition => '$$self{TIFF_TYPE} ne "DCR"', # (used for another purpose in Kodak DCR SubIFD)
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Lens: $val"},
+    },
+    0xfe4c => {
+        Name => 'RawFile',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Raw File: $val"},
+    },
+    0xfe4d => {
+        Name => 'Converter',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Converter: $val"},
+    },
+    0xfe4e => {
+        Name => 'WhiteBalance',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"White Balance: $val"},
+    },
+    0xfe51 => {
+        Name => 'Exposure',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Exposure: $val"},
+    },
+    0xfe52 => {
+        Name => 'Shadows',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Shadows: $val"},
+    },
+    0xfe53 => {
+        Name => 'Brightness',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Brightness: $val"},
+    },
+    0xfe54 => {
+        Name => 'Contrast',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Contrast: $val"},
+    },
+    0xfe55 => {
+        Name => 'Saturation',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Saturation: $val"},
+    },
+    0xfe56 => {
+        Name => 'Sharpness',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Sharpness: $val"},
+    },
+    0xfe57 => {
+        Name => 'Smoothness',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Smoothness: $val"},
+    },
+    0xfe58 => {
+        Name => 'MoireFilter',
+        Avoid => 1,
+        PSRaw => 1,
+        Writable => 'string',
+        ValueConv => '$val=~s/^.*: //;$val',
+        ValueConvInv => q{"Moire Filter: $val"},
+    },
+
+    #-------------
     0xfe00 => {
         Name => 'KDC_IFD',
@@ -2448,4 +4223,23 @@
 );
 
+# conversions for Composite SubSec date/time tags
+my %subSecConv = (
+    # @val array: 0) date/time, 1) sub-seconds, 2) time zone offset
+    RawConv => q{
+        my $v;
+        if (defined $val[1] and $val[1]=~/^(\d+)/) {
+            my $subSec = $1;
+            # 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);
+        }
+        return $v;
+    },
+    PrintConv => '$self->ConvertDateTime($val)',
+    PrintConvInv => '$self->InverseDateTime($val)',
+);
+
 # EXIF Composite tags (plus other more general Composite tags)
 %Image::ExifTool::Exif::Composite = (
@@ -2459,11 +4253,20 @@
             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]";
-        },
+            return "$val[0] $val[1]" if IsFloat($val[0]) and IsFloat($val[1]);
+            return undef;
+        },
+        PrintConv => '$val =~ tr/ /x/; $val',
+    },
+    Megapixels => {
+        Require => 'ImageSize',
+        ValueConv => 'my @d = ($val =~ /\d+/g); $d[0] * $d[1] / 1000000',
+        PrintConv => 'sprintf("%.*f", ($val >= 1 ? 1 : ($val >= 0.001 ? 3 : 6)), $val)',
     },
     # pick the best shutter speed value
@@ -2484,8 +4287,11 @@
         RawConv => '($val[0] || $val[1]) ? $val : undef',
         ValueConv => '$val[0] || $val[1]',
-        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
     },
     LightValue => {
-        Notes => 'calculated LV -- similar to exposure value but includes ISO speed',
+        Notes => q{
+            calculated LV = 2 * log2(Aperture) - log2(ShutterSpeed) - log2(ISO/100);
+            similar to exposure value but normalized to ISO 100
+        },
         Require => {
             0 => 'Aperture',
@@ -2511,5 +4317,8 @@
     ScaleFactor35efl => { #26/PH
         Description => 'Scale Factor To 35 mm Equivalent',
-        Notes => 'this value and any derived values may be incorrect if image has been resized',
+        Notes => q{
+            this value and any derived values may be incorrect if the image has been
+            resized
+        },
         Groups => { 2 => 'Camera' },
         Desire => {
@@ -2518,23 +4327,24 @@
             2 => 'Composite:DigitalZoom',
             3 => 'FocalPlaneDiagonal',
-            4 => 'FocalPlaneXSize',
-            5 => 'FocalPlaneYSize',
-            6 => 'FocalPlaneResolutionUnit',
-            7 => 'FocalPlaneXResolution',
-            8 => 'FocalPlaneYResolution',
-            9 => 'ExifImageWidth',
-           10 => 'ExifImageHeight',
-           11 => 'CanonImageWidth',
-           12 => 'CanonImageHeight',
-           13 => 'ImageWidth',
-           14 => 'ImageHeight',
-        },
-        ValueConv => 'Image::ExifTool::Exif::CalcScaleFactor35efl(@val)',
+            4 => 'SensorSize',
+            5 => 'FocalPlaneXSize',
+            6 => 'FocalPlaneYSize',
+            7 => 'FocalPlaneResolutionUnit',
+            8 => 'FocalPlaneXResolution',
+            9 => 'FocalPlaneYResolution',
+           10 => 'ExifImageWidth',
+           11 => 'ExifImageHeight',
+           12 => 'CanonImageWidth',
+           13 => 'CanonImageHeight',
+           14 => 'ImageWidth',
+           15 => 'ImageHeight',
+        },
+        ValueConv => 'Image::ExifTool::Exif::CalcScaleFactor35efl($self, @val)',
         PrintConv => 'sprintf("%.1f", $val)',
     },
     CircleOfConfusion => {
         Notes => q{
-            this value may be incorrect if the image has been resized.  Calculated as
-            D/1440, where D is the focal plane diagonal in mm
+            calculated as D/1440, where D is the focal plane diagonal in mm.  This value
+            may be incorrect if the image has been resized
         },
         Groups => { 2 => 'Camera' },
@@ -2570,4 +4380,7 @@
             4 => 'SubjectDistance',
             5 => 'ObjectDistance',
+            6 => 'ApproximateFocusDistance',
+            7 => 'FocusDistanceLower',
+            8 => 'FocusDistanceUpper',
         },
         ValueConv => q{
@@ -2577,6 +4390,9 @@
                 $d or $d = 1e10;    # (use large number for infinity)
             } else {
-                $d = $val[4] || $val[5];
-                return undef unless defined $d;
+                $d = $val[4] || $val[5] || $val[6];
+                unless (defined $d) {
+                    return undef unless defined $val[7] and defined $val[8];
+                    $d = ($val[7] + $val[8]) / 2;
+                }
             }
             return 0 unless $f and $val[2];
@@ -2590,5 +4406,7 @@
             my @v = split ' ', $val;
             $v[1] or return sprintf("inf (%.2f m - inf)", $v[0]);
-            return sprintf("%.2f m (%.2f - %.2f)",$v[1]-$v[0],$v[0],$v[1]);
+            my $dof = $v[1] - $v[0];
+            my $fmt = ($dof>0 and $dof<0.02) ? "%.3f" : "%.2f";
+            return sprintf("$fmt m ($fmt - $fmt m)",$dof,$v[0],$v[1]);
         },
     },
@@ -2596,5 +4414,5 @@
         Description => 'Field Of View',
         Notes => q{
-            calculated for the long image dimension, this value may be incorrect for
+            calculated for the long image dimension.  This value may be incorrect for
             fisheye lenses, or if the image has been resized
         },
@@ -2640,7 +4458,7 @@
             2 => 'TimeCreated',
         },
+        RawConv => '($val[1] and $val[2]) ? $val : undef',
         ValueConv => q{
             return $val[0] if $val[0] and $val[0]=~/ /;
-            return undef unless $val[1] and $val[2];
             return "$val[1] $val[2]";
         },
@@ -2648,5 +4466,7 @@
     },
     ThumbnailImage => {
+        Groups => { 0 => 'EXIF', 1 => 'IFD1', 2 => 'Preview' },
         Writable => 1,
+        WriteGroup => 'All',
         WriteCheck => '$self->CheckImage(\$val)',
         WriteAlso => {
@@ -2659,9 +4479,45 @@
             1 => 'ThumbnailLength',
         },
+        Notes => q{
+            this tag is writable, and may be used to update existing thumbnails, but may
+            only create a thumbnail in IFD1 of certain types of files.  Note that for
+            this and other Composite embedded-image tags the family 0 and 1 groups match
+            those of the originating tags
+        },
         # retrieve the thumbnail from our EXIF data
-        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"ThumbnailImage")',
+        RawConv => q{
+            @grps = $self->GetGroup($$val{0});  # set groups from ThumbnailOffsets
+            Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"ThumbnailImage");
+        },
+    },
+    ThumbnailTIFF => {
+        Groups => { 2 => 'Preview' },
+        Require => {
+            0 => 'SubfileType',
+            1 => 'Compression',
+            2 => 'ImageWidth',
+            3 => 'ImageHeight',
+            4 => 'BitsPerSample',
+            5 => 'PhotometricInterpretation',
+            6 => 'StripOffsets',
+            7 => 'SamplesPerPixel',
+            8 => 'RowsPerStrip',
+            9 => 'StripByteCounts',
+        },
+        Desire => {
+            10 => 'PlanarConfiguration',
+            11 => 'Orientation',
+        },
+        # rebuild the TIFF thumbnail from our EXIF data
+        RawConv => q{
+            my $tiff;
+            ($tiff, @grps) = Image::ExifTool::Exif::RebuildTIFF($self, @val);
+            return $tiff;
+        },
     },
     PreviewImage => {
+        Groups => { 0 => 'EXIF', 1 => 'SubIFD', 2 => 'Preview' },
         Writable => 1,
+        WriteGroup => 'All',
         WriteCheck => '$self->CheckImage(\$val)',
         DelCheck => '$val = ""; return undef', # can't delete, so set to empty string
@@ -2669,5 +4525,5 @@
             PreviewImageStart  => 'defined $val ? 0xfeedfeed : undef',
             PreviewImageLength => 'defined $val ? 0xfeedfeed : undef',
-            PreviewImageValid  => 'defined $val and length $val ? 1 : 0',
+            PreviewImageValid  => 'defined $val and length $val ? 1 : 0', # (for Olympus)
         },
         Require => {
@@ -2680,4 +4536,8 @@
             3 => 'PreviewImageStart (1)',
             4 => 'PreviewImageLength (1)',
+        },
+        Notes => q{
+            this tag is writable, and may be used to update existing embedded images,
+            but not create or delete them
         },
         # note: extract 2nd preview, but ignore double-referenced preview
@@ -2693,10 +4553,16 @@
             }
             return undef if defined $val[2] and not $val[2];
+            @grps = $self->GetGroup($$val{0});
             return Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],'PreviewImage');
         },
     },
     JpgFromRaw => {
+        Groups => { 0 => 'EXIF', 1 => 'SubIFD', 2 => 'Preview' },
         Writable => 1,
+        WriteGroup => 'All',
         WriteCheck => '$self->CheckImage(\$val)',
+        # Note: ExifTool 10.38 had disabled the ability to delete this -- why?
+        # --> added the DelCheck in 10.61 to re-enable this
+        DelCheck => '$val = ""; return undef', # can't delete, so set to empty string
         WriteAlso => {
             JpgFromRawStart  => 'defined $val ? 0xfeedfeed : undef',
@@ -2707,13 +4573,36 @@
             1 => 'JpgFromRawLength',
         },
-        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"JpgFromRaw")',
+        Notes => q{
+            this tag is writable, and may be used to update existing embedded images,
+            but not create or delete them
+        },
+        RawConv => q{
+            @grps = $self->GetGroup($$val{0});
+            return Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"JpgFromRaw");
+        },
     },
     OtherImage => {
+        Groups => { 0 => 'EXIF', 1 => 'SubIFD', 2 => 'Preview' },
+        Writable => 1,
+        WriteGroup => 'All',
+        WriteCheck => '$self->CheckImage(\$val)',
+        DelCheck => '$val = ""; return undef', # can't delete, so set to empty string
+        WriteAlso => {
+            OtherImageStart  => 'defined $val ? 0xfeedfeed : undef',
+            OtherImageLength => 'defined $val ? 0xfeedfeed : undef',
+        },
         Require => {
             0 => 'OtherImageStart',
             1 => 'OtherImageLength',
         },
+        Notes => q{
+            this tag is writable, and may be used to update existing embedded images,
+            but not create or delete them
+        },
         # retrieve the thumbnail from our EXIF data
-        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"OtherImage")',
+        RawConv => q{
+            @grps = $self->GetGroup($$val{0});
+            Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"OtherImage");
+        },
     },
     PreviewImageSize => {
@@ -2727,40 +4616,57 @@
         Description => 'Date/Time Original',
         Groups => { 2 => 'Time' },
+        Writable => 1,
+        Shift => 0, # don't shift this tag
         Require => {
             0 => 'EXIF:DateTimeOriginal',
+        },
+        Desire => {
             1 => 'SubSecTimeOriginal',
-        },
-        # be careful here just in case there is a timezone following the seconds
-        ValueConv => q{
-            return undef if $val[1] eq '';
-            $_ = $val[0]; s/( \d{2}:\d{2}:\d{2})/$1\.$val[1]/; $_;
-        },
-        PrintConv => '$self->ConvertDateTime($val)',
+            2 => 'OffsetTimeOriginal',
+        },
+        WriteAlso => {
+            'EXIF:DateTimeOriginal' => '($val and $val=~/^(\d{4}:\d{2}:\d{2} \d{2}:\d{2}:\d{2})/) ? $1 : undef',
+            'EXIF:SubSecTimeOriginal' => '($val and $val=~/\.(\d+)/) ? $1 : undef',
+            'EXIF:OffsetTimeOriginal' => '($val and $val=~/([-+]\d{2}:\d{2}|Z)$/) ? ($1 eq "Z" ? "+00:00" : $1) : undef',
+        },
+        %subSecConv,
     },
     SubSecCreateDate => {
         Description => 'Create Date',
         Groups => { 2 => 'Time' },
+        Writable => 1,
+        Shift => 0, # don't shift this tag
         Require => {
             0 => 'EXIF:CreateDate',
+        },
+        Desire => {
             1 => 'SubSecTimeDigitized',
-        },
-        ValueConv => q{
-            return undef if $val[1] eq '';
-            $_ = $val[0]; s/( \d{2}:\d{2}:\d{2})/$1\.$val[1]/; $_;
-        },
-        PrintConv => '$self->ConvertDateTime($val)',
+            2 => 'OffsetTimeDigitized',
+        },
+        WriteAlso => {
+            'EXIF:CreateDate' => '($val and $val=~/^(\d{4}:\d{2}:\d{2} \d{2}:\d{2}:\d{2})/) ? $1 : undef',
+            'EXIF:SubSecTimeDigitized' => '($val and $val=~/\.(\d+)/) ? $1 : undef',
+            'EXIF:OffsetTimeDigitized' => '($val and $val=~/([-+]\d{2}:\d{2}|Z)$/) ? ($1 eq "Z" ? "+00:00" : $1) : undef',
+        },
+        %subSecConv,
     },
     SubSecModifyDate => {
         Description => 'Modify Date',
         Groups => { 2 => 'Time' },
+        Writable => 1,
+        Shift => 0, # don't shift this tag
         Require => {
             0 => 'EXIF:ModifyDate',
+        },
+        Desire => {
             1 => 'SubSecTime',
-        },
-        ValueConv => q{
-            return undef if $val[1] eq '';
-            $_ = $val[0]; s/( \d{2}:\d{2}:\d{2})/$1\.$val[1]/; $_;
-        },
-        PrintConv => '$self->ConvertDateTime($val)',
+            2 => 'OffsetTime',
+        },
+        WriteAlso => {
+            'EXIF:ModifyDate' => '($val and $val=~/^(\d{4}:\d{2}:\d{2} \d{2}:\d{2}:\d{2})/) ? $1 : undef',
+            'EXIF:SubSecTime' => '($val and $val=~/\.(\d+)/) ? $1 : undef',
+            'EXIF:OffsetTime' => '($val and $val=~/([-+]\d{2}:\d{2}|Z)$/) ? ($1 eq "Z" ? "+00:00" : $1) : undef',
+        },
+        %subSecConv,
     },
     CFAPattern => {
@@ -2774,5 +4680,5 @@
             my @b = split / /, $val[1];
             return '?' unless @a==2 and @b==$a[0]*$a[1];
-            return Set16u($a[0]) . Set16u($a[1]) . pack('C*', @b);
+            return "$a[0] $a[1] @b";
         },
         PrintConv => 'Image::ExifTool::Exif::PrintCFAPattern($val)',
@@ -2788,7 +4694,8 @@
             5 => 'WB_GBRGLevels',
             6 => 'WB_RGBLevels',
-            7 => 'WB_RBLevels',
-            8 => 'WBRedLevel', # red
-            9 => 'WBGreenLevel',
+            7 => 'WB_GRBLevels',
+            8 => 'WB_RBLevels',
+            9 => 'WBRedLevel', # red
+           10 => 'WBGreenLevel',
         },
         ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(0,@val)',
@@ -2805,7 +4712,8 @@
             5 => 'WB_GBRGLevels',
             6 => 'WB_RGBLevels',
-            7 => 'WB_RBLevels',
-            8 => 'WBBlueLevel', # blue
-            9 => 'WBGreenLevel',
+            7 => 'WB_GRBLevels',
+            8 => 'WB_RBLevels',
+            9 => 'WBBlueLevel', # blue
+           10 => 'WBGreenLevel',
         },
         ValueConv => 'Image::ExifTool::Exif::RedBlueBalance(1,@val)',
@@ -2818,20 +4726,24 @@
             1 => 'GPSLongitude',
         },
-        ValueConv => '"$val[0] $val[1]"',
+        Priority => 0,
+        ValueConv => '(length($val[0]) or length($val[1])) ? "$val[0] $val[1]" : undef',
         PrintConv => '"$prt[0], $prt[1]"',
     },
     LensID => {
         Groups => { 2 => 'Camera' },
-        Require => {
-            0 => 'LensType',
-        },
+        Require => 'LensType',
         Desire => {
             1 => 'FocalLength',
             2 => 'MaxAperture',
             3 => 'MaxApertureValue',
-            4 => 'ShortFocal',
-            5 => 'LongFocal',
+            4 => 'MinFocalLength',
+            5 => 'MaxFocalLength',
             6 => 'LensModel',
             7 => 'LensFocalRange',
+            8 => 'LensSpec',
+            9 => 'LensType2',
+            10 => 'LensType3',
+            11 => 'LensFocalLength', # (for Pentax to check for converter)
+            12 => 'RFLensType',
         },
         Notes => q{
@@ -2841,10 +4753,63 @@
         },
         # this LensID is only valid if the LensType has a PrintConv or is a model name
+        RawConv => q{
+            my $printConv = $$self{TAG_INFO}{LensType}{PrintConv};
+            return $val if ref $printConv eq 'HASH' or (ref $printConv eq 'ARRAY' and
+                ref $$printConv[0] eq 'HASH') or $val[0] =~ /(mm|\d\/F)/;
+            return undef;
+        },
+        ValueConv => '$val',
+        PrintConv => q{
+            my $pcv;
+            # use LensType2 instead of LensType if available and valid (Sony E-mount lenses)
+            # (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};
+            }
+            # use Canon RFLensType if available
+            if ($val[12]) {
+                $val[0] = $val[12];
+                $prt[0] = $prt[12];
+                $pcv = $$self{TAG_INFO}{RFLensType}{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[11] and $val[1] and $lens) {
+                my $conv = $val[1] / $val[11];
+                $lens .= sprintf(' + %.1fx converter', $conv) if $conv > 1.1;
+            }
+            return $lens;
+        },
+    },
+    'LensID-2' => {
+        Name => 'LensID',
+        Groups => { 2 => 'Camera' },
+        Desire => {
+            0 => 'LensModel',
+            1 => 'Lens',
+            2 => 'XMP-aux:LensID',
+            3 => 'Make',
+        },
+        Inhibit => {
+            4 => 'Composite:LensID',
+        },
+        RawConv => q{
+            return undef if defined $val[2] and defined $val[3];
+            return $val if defined $val[0] and $val[0] =~ /(mm|\d\/F)/;
+            return $val if defined $val[1] and $val[1] =~ /(mm|\d\/F)/;
+            return undef;
+        },
         ValueConv => q{
-            return $val[0] if ref $$self{TAG_INFO}{LensType}{PrintConv} eq "HASH" or
-                              $prt[0] =~ /(mm|\d\/F)/;
-            return undef;
-        },
-        PrintConv => 'Image::ExifTool::Exif::PrintLensID($self, $prt[0], @val)',
+            return $val[0] if defined $val[0] and $val[0] =~ /(mm|\d\/F)/;
+            return $val[1];
+        },
+        PrintConv => '$_=$val; s/(\d)\/F/$1mm F/; s/mmF/mm F/; s/(\d) mm/${1}mm/; s/ - /-/; $_',
     },
 );
@@ -2874,9 +4839,9 @@
 sub IdentifyRawFile($$)
 {
-    my ($exifTool, $comp) = @_;
-    if ($$exifTool{FILE_TYPE} eq 'TIFF' and not $$exifTool{IdentifiedRawFile}) {
+    my ($et, $comp) = @_;
+    if ($$et{FILE_TYPE} eq 'TIFF' and not $$et{IdentifiedRawFile}) {
         if ($compression{$comp} and $compression{$comp} =~ /^\w+ ([A-Z]{3}) Compressed$/) {
-            $exifTool->OverrideFileType($$exifTool{TIFF_TYPE} = $1);
-            $$exifTool{IdentifiedRawFile} = 1;
+            $et->OverrideFileType($$et{TIFF_TYPE} = $1);
+            $$et{IdentifiedRawFile} = 1;
         }
     }
@@ -2897,21 +4862,25 @@
     }
     # (A light value of 0 is defined as f/1.0 at 1 second with ISO 100)
-    return (2*log($_[0]) - log($_[1]) - log($_[2]/100)) / log(2);
+    return log($_[0] * $_[0] * 100 / ($_[1] * $_[2])) / log(2);
 }
 
 #------------------------------------------------------------------------------
 # Calculate scale factor for 35mm effective focal length (ref 26/PH)
-# Inputs: 0) Focal length
-#         1) Focal length in 35mm format
-#         2) Canon digital zoom factor
-#         3) Focal plane diagonal size (in mm)
-#         4/5) Focal plane X/Y size (in mm)
-#         6) focal plane resolution units (1=None,2=inches,3=cm,4=mm,5=um)
-#         7/8) Focal plane X/Y resolution
-#         9/10,11/12...) Image width/height in order of precedence (first valid pair is used)
+# Inputs: 0) ExifTool object ref
+#         1) Focal length
+#         2) Focal length in 35mm format
+#         3) Canon digital zoom factor
+#         4) Focal plane diagonal size (in mm)
+#         5) Sensor size (X and Y in mm)
+#         6/7) Focal plane X/Y size (in mm)
+#         8) focal plane resolution units (1=None,2=inches,3=cm,4=mm,5=um)
+#         9/10) Focal plane X/Y resolution
+#         11/12,13/14...) Image width/height in order of precedence (first valid pair is used)
 # Returns: 35mm conversion factor (or undefined if it can't be calculated)
 sub CalcScaleFactor35efl
 {
-    my $res = $_[6];    # save resolution units (in case they have been converted to string)
+    my $et = shift;
+    my $res = $_[7];    # save resolution units (in case they have been converted to string)
+    my $sensXY = $_[4];
     Image::ExifTool::ToFloat(@_);
     my $focal = shift;
@@ -2922,13 +4891,27 @@
     my $digz = shift || 1;
     my $diag = shift;
+    my $sens = shift;
+    # calculate Canon sensor size using a dedicated algorithm
+    if ($$et{Make} eq 'Canon') {
+        require Image::ExifTool::Canon;
+        my $canonDiag = Image::ExifTool::Canon::CalcSensorDiag(
+            $$et{RATIONAL}{FocalPlaneXResolution},
+            $$et{RATIONAL}{FocalPlaneYResolution},
+        );
+        $diag = $canonDiag if $canonDiag;
+    }
     unless ($diag and Image::ExifTool::IsFloat($diag)) {
-        undef $diag;
-        my $xsize = shift;
-        my $ysize = shift;
-        if ($xsize and $ysize) {
-            # validate by checking aspect ratio because FocalPlaneX/YSize is not reliable
-            my $a = $xsize / $ysize;
-            if (abs($a-1.3333) < .1 or abs($a-1.5) < .1) {
-                $diag = sqrt($xsize * $xsize + $ysize * $ysize);
+        if ($sens and $sensXY =~ / (\d+(\.?\d*)?)$/) {
+            $diag = sqrt($sens * $sens + $1 * $1);
+        } else {
+            undef $diag;
+            my $xsize = shift;
+            my $ysize = shift;
+            if ($xsize and $ysize) {
+                # validate by checking aspect ratio because FocalPlaneX/YSize is not reliable
+                my $a = $xsize / $ysize;
+                if (abs($a-1.3333) < .1 or abs($a-1.5) < .1) {
+                    $diag = sqrt($xsize * $xsize + $ysize * $ysize);
+                }
             }
         }
@@ -2938,5 +4921,5 @@
             my $units = $lkup{ shift() || $res || '' } || 25.4;
             my $x_res = shift || return undef;
-            my $y_res = shift || return undef;
+            my $y_res = shift || $x_res;
             Image::ExifTool::IsFloat($x_res) and $x_res != 0 or return undef;
             Image::ExifTool::IsFloat($y_res) and $y_res != 0 or return undef;
@@ -2997,31 +4980,52 @@
 #------------------------------------------------------------------------------
 # Convert EXIF text to something readable
-# Inputs: 0) ExifTool object reference, 1) EXIF text
+# Inputs: 0) ExifTool object reference, 1) EXIF text,
+#         2) [optional] 1 to apply CharsetEXIF to ASCII text,
+#         3) tag name for warning message (may be argument 2)
 # Returns: text encoded according to Charset option (with trailing spaces removed)
-sub ConvertExifText($$)
+sub ConvertExifText($$;$$)
 {
-    my ($exifTool, $val) = @_;
+    my ($et, $val, $asciiFlex, $tag) = @_;
     return $val if length($val) < 8;
     my $id = substr($val, 0, 8);
     my $str = substr($val, 8);
+    my $type;
+
+    delete $$et{WrongByteOrder};
+    if ($$et{OPTIONS}{Validate} and $id =~ /^(ASCII|UNICODE|JIS)?\0* \0*$/) {
+        $et->Warn(($1 || 'Undefined') . ' text header' . ($tag ? " for $tag" : '') . ' has spaces instead of nulls');
+    }
     # Note: allow spaces instead of nulls in the ID codes because
     # it is fairly common for camera manufacturers to get this wrong
-    if ($id =~ /^(ASCII)?[\0 ]+$/) {
+    # (also handle Canon ZoomBrowser EX 4.5 null followed by 7 bytes of garbage)
+    if ($id =~ /^(ASCII)?(\0|[\0 ]+$)/) {
         # truncate at null terminator (shouldn't have a null based on the
         # EXIF spec, but it seems that few people actually read the spec)
         $str =~ s/\0.*//s;
+        # allow ASCII text to contain any other specified encoding
+        if ($asciiFlex and $asciiFlex eq '1') {
+            my $enc = $et->Options('CharsetEXIF');
+            $str = $et->Decode($str, $enc) if $enc;
+        }
     # by the EXIF spec, the following string should be "UNICODE\0", but
     # apparently Kodak sometimes uses "Unicode\0" in the APP3 "Meta" information.
     # However, unfortunately Ricoh uses "Unicode\0" in the RR30 EXIF UserComment
     # when the text is actually ASCII, so only recognize uppercase "UNICODE\0".
-    } elsif ($id =~ /^UNICODE[\0 ]$/) {
+    } elsif ($id =~ /^(UNICODE)[\0 ]$/) {
+        $type = $1;
         # MicrosoftPhoto writes as little-endian even in big-endian EXIF,
         # so we must guess at the true byte ordering
-        $str = $exifTool->Decode($str, 'UCS2', 'Unknown');
-    } elsif ($id =~ /^JIS[\0 ]{5}$/) {
-        $str = $exifTool->Decode($str, 'JIS', 'Unknown');
+        $str = $et->Decode($str, 'UTF16', 'Unknown');
+    } elsif ($id =~ /^(JIS)[\0 ]{5}$/) {
+        $type = $1;
+        $str = $et->Decode($str, 'JIS', 'Unknown');
     } else {
-        $exifTool->Warn("Invalid EXIF text encoding");
+        $tag = $asciiFlex if $asciiFlex and $asciiFlex ne '1';
+        $et->Warn('Invalid EXIF text encoding' . ($tag ? " for $tag" : ''));
         $str = $id . $str;
+    }
+    if ($$et{WrongByteOrder} and $$et{OPTIONS}{Validate}) {
+        $et->Warn('Wrong byte order for EXIF' . ($tag ? " $tag" : '') .
+                  ($type ? " $type" : '') . ' text');
     }
     $str =~ s/ +$//;    # trim trailing blanks
@@ -3088,5 +5092,5 @@
 #------------------------------------------------------------------------------
 # Calculate Red/BlueBalance
-# Inputs: 0) 0=red, 1=blue, 1-7) WB_RGGB/RGBG/RBGG/GRBG/GRGB/RGB/RBLevels,
+# Inputs: 0) 0=red, 1=blue, 1-8) WB_RGGB/RGBG/RBGG/GRBG/GRGB/RGB/GRB/RBLevels,
 #         8) red or blue level, 9) green level
 my @rggbLookup = (
@@ -3099,5 +5103,6 @@
     [ 2, 3, 0, 1 ], # 5 GBRG
     [ 0, 1, 1, 2 ], # 6 RGB
-    [ 0, 256, 256, 1 ], # 7 RB (green level is 256)
+    [ 1, 0, 0, 2 ], # 7 GRB
+    [ 0, 256, 256, 1 ], # 8 RB (green level is 256)
 );
 sub RedBlueBalance($@)
@@ -3138,29 +5143,84 @@
 
 #------------------------------------------------------------------------------
+# Print FNumber
+sub PrintFNumber($)
+{
+    my $val = shift;
+    if (Image::ExifTool::IsFloat($val) and $val > 0) {
+        # round to 1 decimal place, or 2 for values < 1.0
+        $val = sprintf(($val<1 ? "%.2f" : "%.1f"), $val);
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Decode raw CFAPattern value
+# Inputs: 0) ExifTool ref, 1) binary value
+# Returns: string of numbers
+sub DecodeCFAPattern($$)
+{
+    my ($self, $val) = @_;
+    # some panasonic cameras (SV-AS3, SV-AS30) write this in ascii (very odd)
+    if ($val =~ /^[0-6]+$/) {
+        $self->Warn('Incorrectly formatted CFAPattern', 1);
+        $val =~ tr/0-6/\x00-\x06/;
+    }
+    return $val unless length($val) >= 4;
+    my @a = unpack(GetByteOrder() eq 'II' ? 'v2C*' : 'n2C*', $val);
+    my $end = 2 + $a[0] * $a[1];
+    if ($end > @a) {
+        # try swapping byte order (I have seen this order different than in EXIF)
+        my ($x, $y) = unpack('n2',pack('v2',$a[0],$a[1]));
+        if (@a < 2 + $x * $y) {
+            $self->Warn('Invalid CFAPattern', 1);
+        } else {
+            ($a[0], $a[1]) = ($x, $y);
+            # (can't technically be wrong because the order isn't well defined by the EXIF spec)
+            # $self->Warn('Wrong byte order for CFAPattern');
+        }
+    }
+    return "@a";
+}
+
+#------------------------------------------------------------------------------
 # Print CFA Pattern
 sub PrintCFAPattern($)
 {
     my $val = shift;
-    return '<truncated data>' unless length $val > 4;
-    # some panasonic cameras (SV-AS3, SV-AS30) write this in ascii (very odd)
-    $val =~ /^[0-6]+$/ and $val =~ tr/0-6/\x00-\x06/;
-    my ($nx, $ny) = (Get16u(\$val, 0), Get16u(\$val, 2));
-    return '<zero pattern size>' unless $nx and $ny;
-    my $end = 4 + $nx * $ny;
-    if ($end > length $val) {
-        # try swapping byte order (I have seen this order different than in EXIF)
-        ($nx, $ny) = unpack('n2',pack('v2',$nx,$ny));
-        $end = 4 + $nx * $ny;
-        return '<invalid pattern size>' if $end > length $val;
-    }
+    my @a = split ' ', $val;
+    return '<truncated data>' unless @a >= 2;
+    return '<zero pattern size>' unless $a[0] and $a[1];
+    my $end = 2 + $a[0] * $a[1];
+    return '<invalid pattern size>' if $end > @a;
     my @cfaColor = qw(Red Green Blue Cyan Magenta Yellow White);
-    my ($pos, $rtnVal) = (4, '[');
+    my ($pos, $rtnVal) = (2, '[');
     for (;;) {
-        $rtnVal .= $cfaColor[Get8u(\$val,$pos)] || 'Unknown';
+        $rtnVal .= $cfaColor[$a[$pos]] || 'Unknown';
         last if ++$pos >= $end;
-        ($pos - 4) % $ny and $rtnVal .= ',', next;
+        ($pos - 2) % $a[1] and $rtnVal .= ',', next;
         $rtnVal .= '][';
     }
     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;
 }
 
@@ -3181,7 +5241,9 @@
     }
     return $val unless $c == 4;
-    $val = "$vals[1]mm f/$vals[2]";
-    $val = "$vals[0]-$val" if $vals[0] ne $vals[1];
-    $val .= "-$vals[3]" if $vals[3] ne $vals[2];
+    $val = $vals[0];
+    # (the Pentax Q writes zero for upper value of fixed-focal-length lenses)
+    $val .= "-$vals[1]" if $vals[1] and $vals[1] ne $vals[0];
+    $val .= "mm f/$vals[2]";
+    $val .= "-$vals[3]" if $vals[3] and $vals[3] ne $vals[2];
     return $val;
 }
@@ -3211,29 +5273,116 @@
 
 #------------------------------------------------------------------------------
+# 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 string, 2) LensType value,
-#         3) FocalLength, 4) MaxAperture, 5) MaxApertureValue, 6) ShortFocal,
-#         7) LongFocal, 8) LensModel, 9) LensFocalRange
+# 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 ($exifTool, $lensTypePrt, $lensType, $focalLength, $maxAperture,
-        $maxApertureValue, $shortFocal, $longFocal, $lensModel, $lensFocalRange) = @_;
-    # the rest of the logic relies on the LensType lookup:
+    my ($et, $lensTypePrt, $printConv, $lensSpecPrt, $lensType, $focalLength,
+        $maxAperture, $maxApertureValue, $shortFocal, $longFocal, $lensModel,
+        $lensFocalRange, $lensSpec) = @_;
+    # this logic relies on the LensType lookup:
     return undef unless defined $lensType;
-    my $printConv = $exifTool->{TAG_INFO}{LensType}{PrintConv};
+    # get print conversion hash if necessary
+    $printConv or $printConv = $$et{TAG_INFO}{LensType}{PrintConv};
     # just copy LensType PrintConv value if it was a lens name
     # (Olympus or Panasonic -- just exclude things like Nikon and Leaf LensType)
     unless (ref $printConv eq 'HASH') {
-        return $lensTypePrt if $lensTypePrt =~ /mm/;
-        return $lensTypePrt if $lensTypePrt =~ s/(\d)\/F/$1mm F/;
-        return undef;
+        if (ref $printConv eq 'ARRAY' and ref $$printConv[0] eq 'HASH') {
+            $printConv = $$printConv[0];
+            $lensTypePrt =~ s/;.*//;
+            $lensType =~ s/ .*//;
+        } else {
+            return $lensTypePrt if $lensTypePrt =~ /mm/;
+            return $lensTypePrt if $lensTypePrt =~ s/(\d)\/F/$1mm F/;
+            return undef;
+        }
+    }
+    # get LensSpec information if available (Sony)
+    my ($sf0, $lf0, $sa0, $la0);
+    if ($lensSpecPrt) {
+        ($sf0, $lf0, $sa0, $la0) = GetLensInfo($lensSpecPrt);
+        undef $sf0 unless $sa0; # (make sure aperture isn't zero)
     }
     # use MaxApertureValue if MaxAperture is not available
     $maxAperture = $maxApertureValue unless $maxAperture;
-    if ($lensFocalRange and $lensFocalRange =~ /^(\d+)(?: to (\d+))?$/) {
+    if ($lensFocalRange and $lensFocalRange =~ /^(\d+)(?: (?:to )?(\d+))?$/) {
         ($shortFocal, $longFocal) = ($1, $2 || $1);
     }
-    if ($shortFocal and $longFocal) {
-        # Canon includes makernote information which allows better lens identification
+    if ($$et{Make} eq 'SONY') {
+        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);
+                require Image::ExifTool::Canon;
+                $printConv = \%Image::ExifTool::Canon::canonLensTypes;
+                $lensTypePrt = $$printConv{$lensType} if $$printConv{$lensType};
+            # Test for Sigma MC-11 SA-E adapter with Sigma SA lens using 0x4900 offset.
+            # (upper limit of test cuts off two highest Sigma lenses, but prevents
+            # conflict with old Minolta 25xxx and higher ID's)
+            } elsif ($lensType >= 0x4900 and $lensType <= 0x590a) {
+                require Image::ExifTool::Sigma;
+                $lensType -= 0x4900;
+                $printConv = \%Image::ExifTool::Sigma::sigmaLensTypes;
+                $lensTypePrt = $$printConv{$lensType} if $$printConv{$lensType};
+            }
+        }
+    # (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;
         return Image::ExifTool::Canon::PrintLensID($printConv, $lensType,
@@ -3253,10 +5402,30 @@
     my (@matches, @best, @user, $diff);
     foreach $lens (@lenses) {
-        if ($Image::ExifTool::userLens{$lens}) {
-            push @user, $lens;
+        push @user, $lens if $Image::ExifTool::userLens{$lens};
+        # sf = short focal
+        # lf = long focal
+        # sa = max aperture at short focal
+        # la = max aperture at long focal
+        my ($sf, $lf, $sa, $la) = GetLensInfo($lens);
+        next unless $sf;
+        # check against LensSpec parameters if available
+        if ($sf0) {
+            next if abs($sf - $sf0) > 0.5 or abs($sa - $sa0) > 0.15 or
+                    abs($lf - $lf0) > 0.5 or abs($la - $la0) > 0.15;
+            # the basic parameters match, but also check against additional lens features:
+            # for Sony A and E lenses, the full LensSpec string should match with end of LensType,
+            # 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( \(| 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;
         }
-        my ($sf, $lf, $sa, $la) = GetLensInfo($lens);
-        next unless $sf;
+        # adjust focal length and aperture if teleconverter is attached (Minolta)
+        if ($lens =~ / \+ .*? (\d+(\.\d+)?)x( |$)/) {
+            $sf *= $1;  $lf *= $1;
+            $sa *= $1;  $la *= $1;
+        }
         # see if we can rule out this lens using FocalLength and MaxAperture
         if ($focalLength) {
@@ -3274,6 +5443,9 @@
             # now determine the best match for this aperture
             my $aa; # approximate maximum aperture at this focal length
-            if ($sf == $lf or $sa == $la) {
+            if ($sf == $lf or $sa == $la or $focalLength <= $sf) {
+                # either 1) prime lens, 2) fixed-aperture zoom, or 3) zoom at min focal
                 $aa = $sa;
+            } elsif ($focalLength >= $lf) {
+                $aa = $la;
             } else {
                 # assume a log-log variation of max aperture with focal length
@@ -3281,4 +5453,6 @@
                 $aa = exp(log($sa) + (log($la)-log($sa)) / (log($lf)-log($sf)) *
                                      (log($focalLength)-log($sf)));
+                # a linear relationship between 1/FocalLength and 1/MaxAperture fits Sony better (ref 27)
+                #$aa = 1 / (1/$sa + (1/$focalLength - 1/$sf) * (1/$la - 1/$sa) / (1/$lf - 1/$sf));
             }
             my $d = abs($maxAperture - $aa);
@@ -3292,12 +5466,29 @@
         push @matches, $lens;
     }
-    return join(' or ', @user) if @user;
-    return join(' or ', @best) if @best;
-    return join(' or ', @matches) if @matches;
-    return $$printConv{$lensType};
+    # return the user-defined lens if it exists
+    if (@user) {
+        # choose the best match if we have more than one
+        if (@user > 1) {
+            my ($try, @good);
+            foreach $try (\@best, \@matches) {
+                $Image::ExifTool::userLens{$_} and push @good, $_ foreach @$try;
+                return join(' or ', @good) if @good;
+            }
+        }
+        return join(' or ', @user);
+    }
+    # 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;
 }
 
 #------------------------------------------------------------------------------
-# translate date into standard EXIF format
+# Translate date into standard EXIF format
 # Inputs: 0) date
 # Returns: date in format '2003:10:22'
@@ -3308,16 +5499,17 @@
     my $date = shift;
     $date =~ s/\0$//;       # remove any null terminator
-    # separate year:month:day with colons (instead of -, /, space or nothing)
-    $date =~ s/(\d{4})[- \/:]*(\d{2})[- \/:]*(\d{2})$/$1:$2:$3/;
+    # separate year:month:day with colons
+    # (have seen many other characters, including nulls, used erroneously)
+    $date =~ s/(\d{4})[^\d]*(\d{2})[^\d]*(\d{2})$/$1:$2:$3/;
     return $date;
 }
 
 #------------------------------------------------------------------------------
-# translate time into standard EXIF format
+# Translate time into standard EXIF format
 # Inputs: 0) time
 # Returns: time in format '10:30:55'
 # - bad formats recognized: '10 30 55', '103055', '103055+0500'
 # - removes null terminator if it exists
-# - leaves time zone intact if specified (ie. '10:30:55+05:00')
+# - leaves time zone intact if specified (eg. '10:30:55+05:00')
 sub ExifTime($)
 {
@@ -3332,5 +5524,119 @@
 
 #------------------------------------------------------------------------------
-# extract image from file
+# Generate TIFF file from scratch (in current byte order)
+# Inputs: 0) hash of IFD entries (TagID => Value; multiple values space-delimited)
+#         1) raw image data reference
+# Returns: TIFF image data, or undef on error
+sub GenerateTIFF($$)
+{
+    my ($entries, $dataPt) = @_;
+    my ($rtnVal, $tag, $offsetPos);
+
+    my $num = scalar keys %$entries;
+    my $ifdBuff = GetByteOrder() . Set16u(42) .  Set32u(8) .  Set16u($num);
+    my $valBuff = '';
+    my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
+    foreach $tag (sort { $a <=> $b } keys %$entries) {
+        my $tagInfo = $$tagTablePtr{$tag};
+        my $fmt = ref $tagInfo eq 'HASH' ? $$tagInfo{Writable} : 'int32u';
+        return undef unless defined $fmt;
+        my $val = Image::ExifTool::WriteValue($$entries{$tag}, $fmt, -1);
+        return undef unless defined $val;
+        my $format = $formatNumber{$fmt};
+        $ifdBuff .= Set16u($tag) . Set16u($format) . Set32u(length($val)/$formatSize[$format]);
+        $offsetPos = length($ifdBuff) if $tag == 0x111; # (remember StripOffsets position)
+        if (length $val > 4) {
+            $ifdBuff .= Set32u(10 + 12 * $num + 4 + length($valBuff));
+            $valBuff .= $val;
+        } else {
+            $val .= "\0" x (4 - length($val)) if length $val < 4;
+            $ifdBuff .= $val;
+        }
+    }
+    $ifdBuff .= "\0\0\0\0"; # (no IFD1)
+    return undef unless $offsetPos;
+    Set32u(length($ifdBuff) + length($valBuff), \$ifdBuff, $offsetPos);
+    return $ifdBuff . $valBuff . $$dataPt;
+}
+
+#------------------------------------------------------------------------------
+# Rebuild TIFF thumbnail(s)/preview(s) into stand-alone files with current byte order
+# Inputs: 0) ExifTool ref, 1) SubfileType, 2) Compression, 3) ImageWidth, 4) ImageHeight,
+#         5) BitsPerSample, 6) PhotometricInterpretation, 7) StripOffsets, 8) SamplesPerPixel,
+#         9) RowsPerStrip, 10) StripByteCounts, 10) PlanarConfiguration, 11) Orientation
+# Returns: 0) TIFF image or undef, 1/2) Family 0/1 groups for TIFF preview IFD
+sub RebuildTIFF($;@)
+{
+    local $_;
+    my $et = $_[0];
+    my $value = $$et{VALUE};
+    my ($i, $j, $rtn, $grp0, $grp1);
+    return undef if $$et{FILE_TYPE} eq 'RWZ';
+SubFile:
+    for ($i=0; ; ++$i) {
+        my $key = 'SubfileType' . ($i ? " ($i)" : '');
+        last unless defined $$value{$key};
+        next unless $$value{$key} == 1; # (reduced-resolution image)
+        my $grp = $et->GetGroup($key, 1);
+        my $cmp = $et->FindValue('Compression', $grp);
+        next unless $cmp == 1; # (no compression)
+        my %vals = (Compression=>$cmp, PlanarConfiguration=>1, Orientation=>1);
+        foreach (qw(ImageWidth ImageHeight BitsPerSample PhotometricInterpretation
+                    StripOffsets SamplesPerPixel RowsPerStrip StripByteCounts
+                    PlanarConfiguration Orientation))
+        {
+            my $val = $et->FindValue($_, $grp);
+            defined $val and $vals{$_} = $val, next;
+            next SubFile unless defined $vals{$_};
+        }
+        my ($w, $h) = @vals{'ImageWidth', 'ImageHeight'};
+        my @bits = split ' ', $vals{BitsPerSample};
+        my $rowBytes = 0;
+        $rowBytes += $w * int(($_+7)/8) foreach @bits;
+        my $dat = '';
+        my @off = split ' ', $vals{StripOffsets};
+        my @len = split ' ', $vals{StripByteCounts};
+        # read the image data
+        for ($j=0; $j<@off; ++$j) {
+            next SubFile unless $len[$j] == $rowBytes * $vals{RowsPerStrip};
+            my $tmp = $et->ExtractBinary($off[$j], $len[$j]);
+            next SubFile unless defined $tmp;
+            $dat .= $tmp;
+        }
+        # generate the TIFF image
+        my %entries = (
+            0x0fe => 0,                 # SubfileType = 0
+            0x100 => $w,                # ImageWidth
+            0x101 => $h,                # ImageHeight
+            0x102 => $vals{BitsPerSample},# BitsPerSample
+            0x103 => $vals{Compression},# Compression
+            0x106 => $vals{PhotometricInterpretation}, # PhotometricInterpretation
+            0x111 => 0,                 # StripOffsets (will be adjusted later)
+            0x112 => $vals{Orientation},# Orientation
+            0x115 => $vals{SamplesPerPixel}, # SamplesPerPixel
+            0x116 => $h,                # RowsPerStrip
+            0x117 => $h * $rowBytes,    # StripByteCounts
+            0x11a => 72,                # XResolution = 72
+            0x11b => 72,                # YResolution = 72
+            0x11c => $vals{PlanarConfiguration}, # PlanarConfiguration
+            0x128 => 2,                 # ResolutionUnit = 2
+        );
+        my $img = GenerateTIFF(\%entries, \$dat);
+
+        if (not defined $img) {
+            $et->Warn('Invalid ' . ($w > 256 ? 'Preview' : 'Thumbnail') . 'TIFF data');
+        } elsif ($rtn or $w > 256) { # (call it a preview if larger than 256 pixels)
+            $et->FoundTag('PreviewTIFF', \$img, $et->GetGroup($key));
+        } else {
+            $rtn = \$img;
+            ($grp0, $grp1) = $et->GetGroup($key);
+        }
+    }
+    return $rtn unless wantarray;
+    return ($rtn, $grp0, $grp1);
+}
+
+#------------------------------------------------------------------------------
+# Extract image from file
 # Inputs: 0) ExifTool object reference, 1) data offset (in file), 2) data length
 #         3) [optional] tag name
@@ -3339,11 +5645,11 @@
 sub ExtractImage($$$$)
 {
-    my ($exifTool, $offset, $len, $tag) = @_;
-    my $dataPt = \$exifTool->{EXIF_DATA};
-    my $dataPos = $exifTool->{EXIF_POS};
+    my ($et, $offset, $len, $tag) = @_;
+    my $dataPt = \$$et{EXIF_DATA};
+    my $dataPos = $$et{EXIF_POS};
     my $image;
 
     # no image if length is zero, and don't try to extract binary from XMP file
-    return undef if not $len or $$exifTool{FILE_TYPE} eq 'XMP';
+    return undef if not $len or $$et{FILE_TYPE} eq 'XMP';
 
     # take data from EXIF block if possible
@@ -3351,20 +5657,46 @@
         $image = substr($$dataPt, $offset-$dataPos, $len);
     } else {
-        $image = $exifTool->ExtractBinary($offset, $len, $tag);
+        $image = $et->ExtractBinary($offset, $len, $tag);
         return undef unless defined $image;
         # patch for incorrect ThumbnailOffset in some Sony DSLR-A100 ARW images
-        if ($tag and $tag eq 'ThumbnailImage' and $$exifTool{TIFF_TYPE} eq 'ARW' and
-            $$exifTool{Model} eq 'DSLR-A100' and $offset < 0x10000 and
+        if ($tag and $tag eq 'ThumbnailImage' and $$et{TIFF_TYPE} eq 'ARW' and
+            $$et{Model} eq 'DSLR-A100' and $offset < 0x10000 and
             $image !~ /^(Binary data|\xff\xd8\xff)/)
         {
-            my $try = $exifTool->ExtractBinary($offset + 0x10000, $len, $tag);
+            my $try = $et->ExtractBinary($offset + 0x10000, $len, $tag);
             if (defined $try and $try =~ /^\xff\xd8\xff/) {
                 $image = $try;
-                $exifTool->{VALUE}->{ThumbnailOffset} += 0x10000;
-                $exifTool->Warn('Adjusted incorrect A100 ThumbnailOffset', 1);
+                $$et{VALUE}{ThumbnailOffset} += 0x10000;
+                $et->Warn('Adjusted incorrect A100 ThumbnailOffset', 1);
             }
         }
     }
-    return $exifTool->ValidateImage(\$image, $tag);
+    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);
 }
 
@@ -3377,5 +5709,5 @@
 sub ProcessExif($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos} || 0;
@@ -3387,27 +5719,38 @@
     my $firstBase = $base;
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
-    my $htmlDump = $exifTool->{HTML_DUMP};
+    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);
-    my $inMakerNotes = $tagTablePtr->{GROUPS}{0} eq 'MakerNotes';
+    my ($tagKey, $dirSize, $makerAddr, $strEnc, %offsetInfo, $offName, $nextOffName);
+    my $inMakerNotes = $$tagTablePtr{GROUPS}{0} eq 'MakerNotes';
+    my $isExif = ($tagTablePtr eq \%Image::ExifTool::Exif::Main);
+
+    # set encoding to assume for strings
+    $strEnc = $et->Options('CharsetEXIF') if $$tagTablePtr{GROUPS}{0} eq 'EXIF';
 
     # ignore non-standard EXIF while in strict MWG compatibility mode
-    if ($Image::ExifTool::MWG::strict and $dirName eq 'IFD0' and
-        $tagTablePtr eq \%Image::ExifTool::Exif::Main and
-        $$exifTool{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
+    if (($validate or $Image::ExifTool::MWG::strict) and $dirName eq 'IFD0' and
+        $isExif and $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
     {
-        my $path = $exifTool->MetadataPath();
+        my $path = $et->MetadataPath();
         unless ($path =~ /^(JPEG-APP1-IFD0|TIFF-IFD0|PSD-EXIFInfo-IFD0)$/) {
-            $exifTool->Warn("Ignored non-standard EXIF at $path");
-            return 1;
+            if ($Image::ExifTool::MWG::strict) {
+                $et->Warn("Ignored non-standard EXIF at $path");
+                return 1;
+            } else {
+                $et->Warn("Non-standard EXIF at $path", 1);
+            }
         }
     }
-    $verbose = -1 if $htmlDump; # mix htmlDump into verbose so we can test for both at once
+    # mix htmlDump and Validate into verbose so we can test for all at once
+    $verbose = -1 if $htmlDump;
+    $verbose = -2 if $validate and not $verbose;
     $dirName eq 'EXIF' and $dirName = $$dirInfo{DirName} = 'IFD0';
     $$dirInfo{Multi} = 1 if $dirName =~ /^(IFD0|SubIFD)$/ and not defined $$dirInfo{Multi};
     # get a more descriptive name for MakerNote sub-directories
-    my $name = $$dirInfo{Name};
-    $name = $dirName unless $name and $inMakerNotes and $name !~ /^MakerNote/;
+    my $dir = $$dirInfo{Name};
+    $dir = $dirName unless $dir and $inMakerNotes and $dir !~ /^MakerNote/;
 
     my ($numEntries, $dirEnd);
@@ -3418,7 +5761,9 @@
         $dirEnd = $dirStart + $dirSize;
         if ($dirSize > $dirLen) {
-            if ($verbose > 0 and not $$dirInfo{SubIFD}) {
+            if (($verbose > 0 or $validate) and not $$dirInfo{SubIFD}) {
                 my $short = $dirSize - $dirLen;
-                $exifTool->Warn("Short directory size (missing $short bytes)");
+                $$et{INDENT} =~ s/..$//; # keep indent the same
+                $et->Warn("Short directory size for $dir (missing $short bytes)");
+                $$et{INDENT} .= '| ';
             }
             undef $dirSize if $dirEnd > $dataLen; # read from file if necessary
@@ -3450,17 +5795,22 @@
             }
         }
-        unless ($success) {
-            $exifTool->Warn("Bad $name directory");
-            return 0;
+        if ($success) {
+            $numEntries = Get16u($dataPt, $dirStart);
+        } else {
+            $et->Warn("Bad $dir directory", $inMakerNotes);
+            return 0 unless $inMakerNotes and $dirLen >= 14 and $dirStart >= 0 and
+                            $dirStart + $dirLen <= length($$dataPt);
+            $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;
     }
-    $verbose > 0 and $exifTool->VerboseDir($dirName, $numEntries);
+    $verbose > 0 and $et->VerboseDir($dirName, $numEntries);
     my $bytesFromEnd = $dataLen - $dirEnd;
     if ($bytesFromEnd < 4) {
         unless ($bytesFromEnd==2 or $bytesFromEnd==0) {
-            $exifTool->Warn(sprintf"Illegal $name directory size (0x%x entries)",$numEntries);
+            $et->Warn("Illegal $dir directory size ($numEntries entries)");
             return 0;
         }
@@ -3470,5 +5820,5 @@
         $makerAddr = $$dirInfo{MakerNoteAddr};
         delete $$dirInfo{MakerNoteAddr};
-        if (Image::ExifTool::MakerNotes::FixBase($exifTool, $dirInfo)) {
+        if (Image::ExifTool::MakerNotes::FixBase($et, $dirInfo)) {
             $base = $$dirInfo{Base};
             $dataPos = $$dirInfo{DataPos};
@@ -3476,27 +5826,33 @@
     }
     if ($htmlDump) {
-        my $longName = $name eq 'MakerNotes' ? ($$dirInfo{Name} || $name) : $name;
+        $offName = $$dirInfo{OffsetName};
+        my $longName = $dir eq 'MakerNotes' ? ($$dirInfo{Name} || $dir) : $dir;
         if (defined $makerAddr) {
             my $hdrLen = $dirStart + $dataPos + $base - $makerAddr;
-            $exifTool->HDump($makerAddr, $hdrLen, "MakerNotes header", $longName) if $hdrLen > 0;
+            $et->HDump($makerAddr, $hdrLen, "MakerNotes header", $longName) if $hdrLen > 0;
         }
-        $exifTool->HDump($dirStart + $dataPos + $base, 2, "$longName entries",
-                 "Entry count: $numEntries");
+        unless ($$dirInfo{NoDumpEntryCount}) {
+            $et->HDump($dirStart + $dataPos + $base, 2, "$longName entries",
+                       "Entry count: $numEntries", undef, $offName);
+        }
         my $tip;
+        my $id = $offName;
         if ($bytesFromEnd >= 4) {
-            my $nxt = ($name =~ /^(.*?)(\d+)$/) ? $1 . ($2 + 1) : 'Next IFD';
-            $tip = sprintf("$nxt offset: 0x%.4x", Get32u($dataPt, $dirEnd));
+            my $nxt = ($dir =~ /^(.*?)(\d+)$/) ? $1 . ($2 + 1) : 'Next IFD';
+            my $off = Get32u($dataPt, $dirEnd);
+            $tip = sprintf("$nxt offset: 0x%.4x", $off);
+            ($nextOffName, $id) = NextOffsetName($et, $offName) if $off;
         }
-        $exifTool->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)
     # (must do this before parsing directory or CameraSettings offset will be suspicious)
-    if ($inMakerNotes and $$exifTool{Model} eq 'Canon EOS 40D') {
+    if ($inMakerNotes and $$et{Model} eq 'Canon EOS 40D' and $numEntries) {
         my $entry = $dirStart + 2 + 12 * ($numEntries - 1);
         my $fmt = Get16u($dataPt, $entry + 2);
         if ($fmt < 1 or $fmt > 13) {
-            $exifTool->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
-                     "Bad format type: $fmt", 1);
+            $et->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
+                       "Bad format type: $fmt", 1, $offName);
             # adjust the number of directory entries
             --$numEntries;
@@ -3505,10 +5861,15 @@
     }
 
+    # make sure that Compression and SubfileType are defined for this IFD (for Condition's)
+    $$et{Compression} = $$et{SubfileType} = '';
+
     # loop through all entries in an EXIF directory (IFD)
-    my ($index, $valEnd, $offList, $offHash);
-    my $warnCount = 0;
+    my ($index, $valEnd, $offList, $offHash, $mapFmt, @valPos);
+    $mapFmt = $$tagTablePtr{VARS}{MAP_FORMAT} if $$tagTablePtr{VARS};
+
+    my ($warnCount, $lastID) = (0, -1);
     for ($index=0; $index<$numEntries; ++$index) {
         if ($warnCount > 10) {
-            $exifTool->Warn("Too many warnings -- $name parsing aborted", 1) and return 0;
+            $et->Warn("Too many warnings -- $dir parsing aborted", 2) and return 0;
         }
         my $entry = $dirStart + 2 + 12 * $index;
@@ -3517,13 +5878,18 @@
         my $count = Get32u($dataPt, $entry+4);
         if ($format < 1 or $format > 13) {
-            $exifTool->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
-                     "Bad format type: $format", 1);
-            # warn unless the IFD was just padded with zeros
-            if ($format) {
-                $exifTool->Warn(sprintf("Unknown format ($format) for $name tag 0x%x",$tagID));
-                ++$warnCount;
+            if ($mapFmt and $$mapFmt{$format}) {
+                $format = $$mapFmt{$format};
+            } else {
+                $et->HDump($entry+$dataPos+$base,12,"[invalid IFD entry]",
+                           "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);
+                    ++$warnCount;
+                }
+                # assume corrupted IFD if this is our first entry (except Sony ILCE-7M2 firmware 1.21)
+                return 0 unless $index or $$et{Model} eq 'ILCE-7M2';
+                next;
             }
-            return 0 unless $index; # assume corrupted IFD if this is our first entry
-            next;
         }
         my $formatStr = $formatName[$format];   # get name of this format
@@ -3532,6 +5898,8 @@
         my $valueDataLen = $dataLen;
         my $valuePtr = $entry + 8;      # pointer to value within $$dataPt
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
-        my $origFormStr;
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
+        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}) {
@@ -3545,13 +5913,34 @@
             }
         }
+        $validate and not $inMakerNotes and Image::ExifTool::Validate::ValidateExif(
+            $et, $tagTablePtr, $tagID, $tagInfo, $lastID, $dir, $count, $formatStr);
         my $size = $count * $formatSize[$format];
         my $readSize = $size;
         if ($size > 4) {
             if ($size > 0x7fffffff) {
-                $exifTool->Warn(sprintf("Invalid size ($size) for $name tag 0x%x",$tagID));
+                $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) {
+                my $tagName = TagName($tagID, $tagInfo);
+                $et->Warn("Odd offset for $dir $tagName", 1) if $valuePtr & 0x01;
+                if ($valuePtr < 8 || ($valuePtr + $size > length($$dataPt) and
+                                      $valuePtr + $size > $$et{VALUE}{FileSize}))
+                {
+                    $et->Warn("Invalid offset for $dir $tagName");
+                    ++$warnCount;
+                    next;
+                }
+                if ($valuePtr + $size > $dirStart + $dataPos and $valuePtr < $dirEnd + $dataPos + 4) {
+                    $et->Warn("Value for $dir $tagName overlaps IFD");
+                }
+                foreach (@valPos) {
+                    next if $$_[0] >= $valuePtr + $size or $$_[0] + $$_[1] <= $valuePtr;
+                    $et->Warn("Value for $dir $tagName overlaps $$_[2]");
+                }
+                push @valPos, [ $valuePtr, $size, $tagName ];
+            }
             # fix valuePtr if necessary
             if ($$dirInfo{FixOffsets}) {
@@ -3563,8 +5952,8 @@
             my $suspect;
             # offset shouldn't point into TIFF header
-            $valuePtr < 8 and $suspect = $warnCount;
+            $valuePtr < 8 and not $$dirInfo{ZeroOffsetOK} and $suspect = $warnCount;
             # convert offset to pointer in $$dataPt
             if ($$dirInfo{EntryBased} or (ref $$tagTablePtr{$tagID} eq 'HASH' and
-                $tagTablePtr->{$tagID}{EntryBased}))
+                $$tagTablePtr{$tagID}{EntryBased}))
             {
                 $valuePtr += $entry;
@@ -3580,5 +5969,4 @@
                 if ($raf) {
                     # avoid loading large binary data unless necessary
-                    # (ie. ImageSourceData -- layers in Photoshop TIFF image)
                     while ($size > BINARY_DATA_LIMIT) {
                         if ($tagInfo) {
@@ -3586,11 +5974,14 @@
                             $$tagInfo{Binary} = 1 if $$tagInfo{Unknown};
                             last unless $$tagInfo{Binary};      # must read non-binary data
-                            last if $$tagInfo{SubDirectory};    # must read SubDirectory data
-                            if ($exifTool->{OPTIONS}{Binary}) {
+                            last if $$tagInfo{SubDirectory};
+                            my $lcTag = lc($$tagInfo{Name});
+                            if ($$et{OPTIONS}{Binary} and
+                                not $$et{EXCL_TAG_LOOKUP}{$lcTag})
+                            {
                                 # read binary data if specified unless tagsFromFile won't use it
-                                last unless $$exifTool{TAGS_FROM_FILE} and $$tagInfo{Protected};
+                                last unless $$et{TAGS_FROM_FILE} and $$tagInfo{Protected};
                             }
                             # must read if tag is specified by name
-                            last if $exifTool->{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})};
+                            last if $$et{REQ_TAG_LOOKUP}{$lcTag};
                         } else {
                             # must read value if needed for a condition
@@ -3605,25 +5996,44 @@
                     }
                     # read from file if necessary
-                    unless (defined $buff or
-                            ($raf->Seek($base + $valuePtr + $dataPos,0) and
-                             $raf->Read($buff,$size) == $size))
-                    {
-                        $exifTool->Warn("Error reading value for $name entry $index", $inMakerNotes);
-                        return 0 unless $inMakerNotes;
-                        ++$warnCount;
-                        $buff = '' unless defined $buff;
-                        $readSize = length $buff;
+                    unless (defined $buff) {
+                        my $wrn;
+                        my $readFromRAF = ($tagInfo and $$tagInfo{ReadFromRAF});
+                        if (not $raf->Seek($base + $valuePtr + $dataPos, 0)) {
+                            $wrn = "Invalid offset for $dir entry $index";
+                        } elsif ($readFromRAF and $size > BINARY_DATA_LIMIT and
+                            not $$et{REQ_TAG_LOOKUP}{lc $$tagInfo{Name}})
+                        {
+                            $buff = "$$tagInfo{Name} data $size bytes";
+                            $readSize = length $buff;
+                        } elsif ($raf->Read($buff,$size) != $size) {
+                            $wrn = "Error reading value for $dir entry $index";
+                        } elsif ($readFromRAF) {
+                            # seek back to the start of the value
+                            $raf->Seek($base + $valuePtr + $dataPos, 0);
+                        }
+                        if ($wrn) {
+                            $et->Warn($wrn, $inMakerNotes);
+                            return 0 unless $inMakerNotes or $htmlDump;
+                            ++$warnCount;
+                            $buff = '' unless defined $buff;
+                            $readSize = length $buff;
+                            $bad = 1;
+                        }
                     }
+                    $valueDataLen = length $buff;
                     $valueDataPt = \$buff;
                     $valueDataPos = $valuePtr + $dataPos;
-                    $valueDataLen = length $buff;
                     $valuePtr = 0;
                 } else {
-                    my ($tagStr, $tmpInfo);
+                    my ($tagStr, $tmpInfo, $leicaTrailer);
                     if ($tagInfo) {
                         $tagStr = $$tagInfo{Name};
+                        $leicaTrailer = $$tagInfo{LeicaTrailer};
                     } elsif (defined $tagInfo) {
-                        $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \ '', $formatStr, $count);
-                        $tagStr = $$tmpInfo{Name} if $tmpInfo;
+                        $tmpInfo = $et->GetTagInfo($tagTablePtr, $tagID, \ '', $formatStr, $count);
+                        if ($tmpInfo) {
+                            $tagStr = $$tmpInfo{Name};
+                            $leicaTrailer = $$tmpInfo{LeicaTrailer};
+                        }
                     }
                     if ($tagInfo and $$tagInfo{ChangeBase}) {
@@ -3633,37 +6043,39 @@
                         $valuePtr += $newBase;
                     }
-                    $tagStr or $tagStr = sprintf("tag 0x%x",$tagID);
+                    $tagStr or $tagStr = sprintf("tag 0x%.4x",$tagID);
                     # allow PreviewImage to run outside EXIF data
-                    if ($tagStr eq 'PreviewImage' and $exifTool->{RAF}) {
-                        my $pos = $exifTool->{RAF}->Tell();
-                        $buff = $exifTool->ExtractBinary($base + $valuePtr + $dataPos, $size, 'PreviewImage');
-                        $exifTool->{RAF}->Seek($pos, 0);
+                    if ($tagStr eq 'PreviewImage' and $$et{RAF}) {
+                        my $pos = $$et{RAF}->Tell();
+                        $buff = $et->ExtractBinary($base + $valuePtr + $dataPos, $size, 'PreviewImage');
+                        $$et{RAF}->Seek($pos, 0);
                         $valueDataPt = \$buff;
                         $valueDataPos = $valuePtr + $dataPos;
                         $valueDataLen = $size;
                         $valuePtr = 0;
-                    } elsif ($tagStr eq 'MakerNoteLeica6' and $exifTool->{RAF}) {
+                    } elsif ($leicaTrailer and $$et{RAF}) {
                         if ($verbose > 0) {
-                            $exifTool->VPrint(0, "$$exifTool{INDENT}$index) $tagStr --> (outside APP1 segment)\n");
+                            $et->VPrint(0, "$$et{INDENT}$index) $tagStr --> (outside APP1 segment)\n");
                         }
-                        if ($exifTool->Options('FastScan')) {
-                            $exifTool->Warn('Ignored Leica MakerNote trailer');
+                        if ($et->Options('FastScan')) {
+                            $et->Warn('Ignored Leica MakerNote trailer');
                         } else {
-                            $$exifTool{LeicaTrailer} = {
+                            require Image::ExifTool::Fixup;
+                            $$et{LeicaTrailer} = {
                                 TagInfo => $tagInfo || $tmpInfo,
                                 Offset  => $base + $valuePtr + $dataPos,
                                 Size    => $size,
+                                Fixup   => new Image::ExifTool::Fixup,
                             };
                         }
                     } else {
-                        $exifTool->Warn("Bad $name offset for $tagStr");
+                        $et->Warn("Bad offset for $dir $tagStr", $inMakerNotes);
                         ++$warnCount;
                     }
                     unless (defined $buff) {
-                        next unless $htmlDump and $size < 1000000;
-                        $valueDataPt = \ (' ' x $size);
+                        $valueDataPt = '';
                         $valueDataPos = $valuePtr + $dataPos;
-                        $valueDataLen = -1; # flag the bad pointer
+                        $valueDataLen = 0;
                         $valuePtr = 0;
+                        $bad = 1;
                     }
                 }
@@ -3672,5 +6084,5 @@
             if (defined $suspect and $suspect == $warnCount) {
                 my $tagStr = $tagInfo ? $$tagInfo{Name} : sprintf('tag 0x%.4x', $tagID);
-                if ($exifTool->Warn("Suspicious $name offset for $tagStr", $inMakerNotes)) {
+                if ($et->Warn("Suspicious $dir offset for $tagStr", $inMakerNotes)) {
                     ++$warnCount;
                     next unless $verbose;
@@ -3682,7 +6094,9 @@
 
         my ($val, $subdir, $wrongFormat);
-        if ($tagID > 0xf000 and $tagTablePtr eq \%Image::ExifTool::Exif::Main) {
+        if ($tagID > 0xf000 and $isExif) {
             my $oldInfo = $$tagTablePtr{$tagID};
-            if (not $oldInfo or (ref $oldInfo eq 'HASH' and $$oldInfo{Condition})) {
+            if ((not $oldInfo or (ref $oldInfo eq 'HASH' and $$oldInfo{Condition} and
+                not $$oldInfo{PSRaw})) and not $bad)
+            {
                 # handle special case of Photoshop RAW tags (0xfde8-0xfe58)
                 # --> generate tags from the value if possible
@@ -3696,7 +6110,9 @@
                         $tagInfo = {
                             Name => $tag,
-                            ValueConv => '$_=$val;s/.*: //;$_', # remove descr
+                            Condition => '$$self{TIFF_TYPE} ne "DCR"',
+                            ValueConv => '$_=$val;s/^.*: //;$_', # remove descr
+                            PSRaw => 1, # (just as flag to avoid adding this again)
                         };
-                        Image::ExifTool::AddTagToTable($tagTablePtr, $tagID, $tagInfo);
+                        AddTagToTable($tagTablePtr, $tagID, $tagInfo);
                         # generate conditional list if a conditional tag already existed
                         $$tagTablePtr{$tagID} = [ $oldInfo, $tagInfo ] if $oldInfo;
@@ -3706,24 +6122,33 @@
         }
         if (defined $tagInfo and not $tagInfo) {
-            # GetTagInfo() required the value for a Condition
-            my $tmpVal = substr($$valueDataPt, $valuePtr, $readSize < 128 ? $readSize : 128);
-            # (use original format name in this call -- $formatStr may have been changed to int8u)
-            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$tmpVal,
-                                             $formatName[$format], $count);
+            if ($bad) {
+                undef $tagInfo;
+            } else {
+                # GetTagInfo() required the value for a Condition
+                my $tmpVal = substr($$valueDataPt, $valuePtr, $readSize < 128 ? $readSize : 128);
+                # (use original format name in this call -- $formatStr may have been changed to int8u)
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID, \$tmpVal,
+                                           $formatName[$format], $count);
+            }
         }
         # make sure we are handling the 'ifd' format properly
         if (($format == 13 or $format == 18) and (not $tagInfo or not $$tagInfo{SubIFD})) {
             my $str = sprintf('%s tag 0x%.4x IFD format not handled', $dirName, $tagID);
-            $exifTool->Warn($str, $inMakerNotes);
+            $et->Warn($str, $inMakerNotes);
         }
         if (defined $tagInfo) {
+            my $readFormat = $$tagInfo{Format};
             $subdir = $$tagInfo{SubDirectory};
+            # unless otherwise specified, all SubDirectory data except
+            # EXIF SubIFD offsets should be unformatted
+            $readFormat = 'undef' if $subdir and not $$tagInfo{SubIFD} and not $readFormat;
             # override EXIF format if specified
-            if ($$tagInfo{Format}) {
-                $formatStr = $$tagInfo{Format};
+            if ($readFormat) {
+                $formatStr = $readFormat;
                 my $newNum = $formatNumber{$formatStr};
                 if ($newNum and $newNum != $format) {
                     $origFormStr = $formatName[$format] . '[' . $count . ']';
                     $format = $newNum;
+                    $size = $readSize = $$tagInfo{FixedSize} if $$tagInfo{FixedSize};
                     # adjust number of items for new format size
                     $count = int($size / $formatSize[$format]);
@@ -3732,5 +6157,9 @@
             # verify that offset-type values are integral
             if (($$tagInfo{IsOffset} or $$tagInfo{SubIFD}) and not $intFormat{$formatStr}) {
-                $exifTool->Warn("Wrong format ($formatStr) for $name $$tagInfo{Name}");
+                $et->Warn(sprintf('Wrong format (%s) for %s 0x%.4x %s',$formatStr,$dir,$tagID,$$tagInfo{Name}));
+                if ($validate) {
+                    $$et{WrongFormat}{"$dir:$$tagInfo{Name}"} = 1;
+                    $offsetInfo{$tagID} = [ $tagInfo, '' ];
+                }
                 next unless $verbose;
                 $wrongFormat = 1;
@@ -3739,15 +6168,24 @@
             next unless $verbose;
         }
-        # convert according to specified format
-        $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize);
+        unless ($bad) {
+            # limit maximum length of data to reformat
+            # (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 != 196608) {
+                    my $minor = $count > 2000000 ? 0 : 2;
+                    next if $et->Warn("Ignoring $dirName $tagName with excessive count", $minor);
+                }
+            }
+            # convert according to specified format
+            $val = ReadValue($valueDataPt,$valuePtr,$formatStr,$count,$readSize,\$rational);
+            # re-code if necessary
+            $val = $et->Decode($val, $strEnc) if $strEnc and $formatStr eq 'string' and defined $val;
+        }
 
         if ($verbose) {
             my $tval = $val;
-            if ($formatStr =~ /^rational64([su])$/ and defined $tval) {
-                # show numerator/denominator separately
-                my $f = ReadValue($valueDataPt,$valuePtr,"int32$1",$count*2,$readSize);
-                $f =~ s/(-?\d+) (-?\d+)/$1\/$2/g;
-                $tval .= " ($f)";
-            }
+            # also show as a rational
+            $tval .= " ($rational)" if defined $rational;
             if ($htmlDump) {
                 my ($tagName, $colName);
@@ -3759,5 +6197,5 @@
                     $tagName = sprintf("Tag 0x%.4x",$tagID);
                 }
-                my $dname = sprintf("${name}-%.2d", $index);
+                my $dname = sprintf("${dir}-%.2d", $index);
                 # build our tool tip
                 $size < 0 and $size = $count * $formatSize[$format];
@@ -3769,8 +6207,9 @@
                 if ($size > 4) {
                     my $offPt = Get32u($dataPt,$entry+8);
-                    my $actPt = $valuePtr + $valueDataPos + $base - ($$exifTool{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 = ($valueDataLen < 0 or not defined $tval) ? 'V' : 'H';
+                    my $style = ($bad or not defined $tval) ? 'V' : 'H';
                     if ($actPt != $offPt) {
                         $tip .= sprintf("Actual offset: 0x%.4x\n", $actPt);
@@ -3778,4 +6217,7 @@
                         $tip .= sprintf("Offset base: ${sign}0x%.4x\n", abs($actPt - $offPt));
                         $style = 'F' if $style eq 'H';  # purple for different offsets
+                    }
+                    if ($$et{EXIF_POS} and not $$et{BASE_FUDGE}) {
+                        $tip .= sprintf("File offset:   0x%.4x\n", $actPt + $$et{EXIF_POS})
                     }
                     $colName = "<span class=$style>$tagName</span>";
@@ -3785,6 +6227,8 @@
                 }
                 $colName .= ' <span class=V>(err)</span>' if $wrongFormat;
-                if ($valueDataLen < 0 or not defined $tval) {
-                    $tval = '<bad offset>';
+                $colName .= ' <span class=V>(seq)</span>' if $tagID <= $lastID and not $inMakerNotes;
+                $lastID = $tagID;
+                if (not defined $tval) {
+                    $tval = '<bad size/offset>';
                 } else {
                     $tval = substr($tval,0,28) . '[...]' if length($tval) > 32;
@@ -3795,5 +6239,5 @@
                         if ($$tagInfo{IsOffset} or $$tagInfo{SubIFD}) {
                             $tval = sprintf('0x%.4x', $tval);
-                            my $actPt = $val + $base - ($$exifTool{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);
@@ -3807,5 +6251,8 @@
                 }
                 $tip .= "Value: $tval";
-                $exifTool->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) {
@@ -3820,20 +6267,31 @@
                     }
                     # add value data block (underlining maker notes data)
-                    $exifTool->HDump($exifDumpPos,$size,"$tagName value",'SAME', $flag);
+                    $et->HDump($exifDumpPos,$size,"$tagName value",'SAME', $flag, $sid);
                 }
             } else {
-                my $fstr = $formatName[$format];
-                $fstr = "$origFormStr read as $fstr" if $origFormStr;
-                $exifTool->VerboseInfo($tagID, $tagInfo,
-                    Table   => $tagTablePtr,
-                    Index   => $index,
-                    Value   => $tval,
-                    DataPt  => $valueDataPt,
-                    DataPos => $valueDataPos + $base,
-                    Size    => $size,
-                    Start   => $valuePtr,
-                    Format  => $fstr,
-                    Count   => $count,
-                );
+                if ($tagID <= $lastID and not $inMakerNotes) {
+                    my $str = $tagInfo ? ' '.$$tagInfo{Name} : '';
+                    if ($tagID == $lastID) {
+                        $et->Warn(sprintf('Duplicate tag 0x%.4x%s in %s', $tagID, $str, $dirName));
+                    } else {
+                        $et->Warn(sprintf('Tag ID 0x%.4x%s out of sequence in %s', $tagID, $str, $dirName));
+                    }
+                }
+                $lastID = $tagID;
+                if ($verbose > 0) {
+                    my $fstr = $formatName[$format];
+                    $fstr = "$origFormStr read as $fstr" if $origFormStr;
+                    $et->VerboseInfo($tagID, $tagInfo,
+                        Table   => $tagTablePtr,
+                        Index   => $index,
+                        Value   => $tval,
+                        DataPt  => $valueDataPt,
+                        DataPos => $valueDataPos + $base,
+                        Size    => $size,
+                        Start   => $valuePtr,
+                        Format  => $fstr,
+                        Count   => $count,
+                    );
+                }
             }
             next if not $tagInfo or $wrongFormat;
@@ -3847,5 +6305,5 @@
             unless ($size) {
                 unless ($$tagInfo{MakerNotes} or $inMakerNotes) {
-                    $exifTool->Warn("Empty $$tagInfo{Name} data", 1);
+                    $et->Warn("Empty $$tagInfo{Name} data", 1);
                 }
                 next;
@@ -3858,6 +6316,6 @@
                 my $over = @values - $$subdir{MaxSubdirs};
                 if ($over > 0) {
-                    $exifTool->Warn("Ignoring $over $tagStr directories");
-                    pop @values while $over--;
+                    $et->Warn("Ignoring $over $tagStr directories");
+                    splice @values, $$subdir{MaxSubdirs};
                 }
                 $val = shift @values;
@@ -3882,11 +6340,13 @@
                     my $newStart = eval($$subdir{Start});
                     unless (Image::ExifTool::IsInt($newStart)) {
-                        $exifTool->Warn("Bad value for $tagStr");
+                        $et->Warn("Bad value for $tagStr");
                         last;
                     }
                     # convert back to relative to $subdirDataPt
                     $newStart -= $subdirDataPos;
-                    # must adjust directory size if start changed
-                    $size -= $newStart - $subdirStart unless $$subdir{BadOffset};
+                    # adjust directory size if necessary
+                    unless ($$tagInfo{SubIFD} or $$subdir{BadOffset}) {
+                        $size -= $newStart - $subdirStart;
+                    }
                     $subdirStart = $newStart;
                 }
@@ -3906,5 +6366,5 @@
                     } elsif ($subdirStart + 2 <= $subdirDataLen) {
                         # attempt to determine the byte ordering by checking
-                        # at the number of directory entries.  This is an int16u
+                        # the number of directory entries.  This is an int16u
                         # that should be a reasonable value.
                         my $num = Get16u($subdirDataPt, $subdirStart);
@@ -3932,5 +6392,5 @@
                     my $pos = eval $$subdir{OffsetPt};
                     if ($pos + 4 > $subdirDataLen) {
-                        $exifTool->Warn("Bad $tagStr OffsetPt");
+                        $et->Warn("Bad $tagStr OffsetPt");
                         last;
                     }
@@ -3956,5 +6416,5 @@
                             }
                         }
-                        $exifTool->Warn($msg);
+                        $et->Warn($msg, $inMakerNotes);
                         last;
                     }
@@ -3982,9 +6442,10 @@
                     SubIFD     => $$tagInfo{SubIFD},
                     Subdir     => $subdir,
+                    OffsetName => $subOffName,
                 );
                 # (remember: some cameras incorrectly write maker notes in IFD0)
                 if ($$tagInfo{MakerNotes}) {
                     # don't parse makernotes if FastScan > 1
-                    my $fast = $exifTool->Options('FastScan');
+                    my $fast = $et->Options('FastScan');
                     last if $fast and $fast > 1;
                     $subdirInfo{MakerNoteAddr} = $valuePtr + $valueDataPos + $base;
@@ -3992,8 +6453,8 @@
                 }
                 # set directory IFD name from group name of family 1 if it exists,
-                # unless the tag is extracted as a block in which case group 1 may
-                # have been set automatically if the block was previously extracted
-                if ($$tagInfo{Groups} and not $$tagInfo{BlockExtract}) {
-                    $subdirInfo{DirName} = $tagInfo->{Groups}{1};
+                # unless the tag is writable as a block in which case group 1 may
+                # have been set automatically
+                if ($$tagInfo{Groups} and not $$tagInfo{Writable}) {
+                    $subdirInfo{DirName} = $$tagInfo{Groups}{1};
                     # number multiple subdirectories
                     $subdirInfo{DirName} =~ s/\d*$/$dirNum/ if $dirNum;
@@ -4005,14 +6466,17 @@
                 my $ok = 0;
                 if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
-                    $exifTool->Warn("Invalid $tagStr data");
+                    $et->Warn("Invalid $tagStr data");
                     $invalid = 1;
                 } else {
+                    if (not $subdirInfo{DirName} and $inMakerNotes) {
+                        $subdirInfo{DirName} = $$tagInfo{Name};
+                    }
                     # process the subdirectory
-                    $ok = $exifTool->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
+                    $ok = $et->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
                 }
                 # print debugging information if there were errors
                 if (not $ok and $verbose > 1 and $subdirStart != $valuePtr) {
-                    my $out = $exifTool->Options('TextOut');
-                    printf $out "%s    (SubDirectory start = 0x%x)\n", $exifTool->{INDENT}, $subdirStart;
+                    my $out = $et->Options('TextOut');
+                    printf $out "%s    (SubDirectory start = 0x%x)\n", $$et{INDENT}, $subdirStart;
                 }
                 SetByteOrder($oldByteOrder);    # restore original byte swapping
@@ -4021,20 +6485,19 @@
                 $val = shift @values;           # continue with next subdir
             }
-            my $doMaker = $exifTool->Options('MakerNotes');
-            next unless $doMaker or $exifTool->{REQ_TAG_LOOKUP}{lc($tagStr)} or
-                        $$tagInfo{BlockExtract};
+            my $doMaker = $et->Options('MakerNotes');
+            next unless $doMaker or $$et{REQ_TAG_LOOKUP}{lc($tagStr)} or $$tagInfo{BlockExtract};
             # extract as a block if specified
             if ($$tagInfo{MakerNotes}) {
                 # save maker note byte order (if it was significant and valid)
                 if ($$subdir{ByteOrder} and not $invalid) {
-                    $exifTool->{MAKER_NOTE_BYTE_ORDER} =
-                        defined ($exifTool->{UnknownByteOrder}) ?
-                                 $exifTool->{UnknownByteOrder} : $newByteOrder;
+                    $$et{MAKER_NOTE_BYTE_ORDER} =
+                        defined ($$et{UnknownByteOrder}) ?
+                                 $$et{UnknownByteOrder} : $newByteOrder;
                 }
                 if ($doMaker and $doMaker eq '2') {
                     # extract maker notes without rebuilding (no fixup information)
-                    delete $exifTool->{MAKER_NOTE_FIXUP};
-                } elsif (not $$tagInfo{NotIFD}) {
-                    # this is a pain, but we must rebuild EXIF-typemaker notes to
+                    delete $$et{MAKER_NOTE_FIXUP};
+                } elsif (not $$tagInfo{NotIFD} or $$tagInfo{IsPhaseOne}) {
+                    # this is a pain, but we must rebuild EXIF-type maker notes to
                     # include all the value data if data was outside the maker notes
                     my %makerDirInfo = (
@@ -4052,11 +6515,18 @@
                         TagInfo    => $tagInfo,
                     );
-                    $makerDirInfo{FixBase} = 1 if $$subdir{FixBase};
-                    # rebuild maker notes (creates $exifTool->{MAKER_NOTE_FIXUP})
-                    my $val2 = RebuildMakerNotes($exifTool, $newTagTable, \%makerDirInfo);
+                    my $val2;
+                    if ($$tagInfo{IsPhaseOne}) {
+                        $$et{DropTags} = 1;
+                        $val2 = Image::ExifTool::PhaseOne::WritePhaseOne($et, \%makerDirInfo, $newTagTable);
+                        delete $$et{DropTags};
+                    } else {
+                        $makerDirInfo{FixBase} = 1 if $$subdir{FixBase};
+                        # rebuild maker notes (creates $$et{MAKER_NOTE_FIXUP})
+                        $val2 = RebuildMakerNotes($et, \%makerDirInfo, $newTagTable);
+                    }
                     if (defined $val2) {
                         $val = $val2;
-                    } else {
-                        $exifTool->Warn('Error rebuilding maker notes (may be corrupt)');
+                    } elsif ($size > 4) {
+                        $et->Warn('Error rebuilding maker notes (may be corrupt)');
                     }
                 }
@@ -4068,11 +6538,11 @@
  #..............................................................................
         # convert to absolute offsets if this tag is an offset
-        #### eval IsOffset ($val, $exifTool)
+        #### eval IsOffset ($val, $et)
         if ($$tagInfo{IsOffset} and eval $$tagInfo{IsOffset}) {
             my $offsetBase = $$tagInfo{IsOffset} eq '2' ? $firstBase : $base;
-            $offsetBase += $$exifTool{BASE};
+            $offsetBase += $$et{BASE};
             # handle offsets which use a wrong base (Minolta A200)
             if ($$tagInfo{WrongBase}) {
-                my $self = $exifTool;
+                my $self = $et;
                 #### eval WrongBase ($self)
                 $offsetBase += eval $$tagInfo{WrongBase} || 0;
@@ -4084,10 +6554,25 @@
             $val = join(' ', @vals);
         }
+        if ($validate) {
+            if ($$tagInfo{OffsetPair}) {
+                $offsetInfo{$tagID} = [ $tagInfo, $val ];
+            } elsif ($saveForValidate{$tagID} and $isExif) {
+                $offsetInfo{$tagID} = $val;
+            }
+        }
         # save the value of this tag
-        $tagKey = $exifTool->FoundTag($tagInfo, $val);
-        # set the group 1 name for tags in specified tables
-        if (defined $tagKey and $$tagTablePtr{SET_GROUP1}) {
-            $exifTool->SetGroup($tagKey, $dirName);
+        $tagKey = $et->FoundTag($tagInfo, $val);
+        if (defined $tagKey) {
+            # set the group 1 name for tags in specified tables
+            $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;
         }
+    }
+
+    # validate image data offsets for this IFD
+    if ($validate and %offsetInfo) {
+        Image::ExifTool::Validate::ValidateOffsetInfo($et, \%offsetInfo, $$dirInfo{DirName}, $inMakerNotes)
     }
 
@@ -4105,12 +6590,13 @@
             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)) {
-                $exifTool->{INDENT} =~ s/..$//; # keep indent the same
-                my $cur = pop @{$$exifTool{PATH}};
-                $exifTool->ProcessDirectory(\%newDirInfo, $tagTablePtr) or $success = 0;
-                push @{$$exifTool{PATH}}, $cur;
-            } elsif ($verbose or $exifTool->{TIFF_TYPE} eq 'TIFF') {
-                $exifTool->Warn('Ignored bad IFD linked from SubIFD');
+                $$et{INDENT} =~ s/..$//; # keep indent the same
+                my $cur = pop @{$$et{PATH}};
+                $et->ProcessDirectory(\%newDirInfo, $tagTablePtr) or $success = 0;
+                push @{$$et{PATH}}, $cur;
+            } elsif ($verbose or $$et{TIFF_TYPE} eq 'TIFF') {
+                $et->Warn('Ignored bad IFD linked from SubIFD');
             }
         }
@@ -4138,5 +6624,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -4149,5 +6635,5 @@
 =item L<http://www.exif.org/Exif2-2.PDF>
 
-=item L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf>
+=item L<http://www.cipa.jp/std/documents/e/DC-008-2012_E.pdf>
 
 =item L<http://partners.adobe.com/asn/developer/pdfs/tn/TIFF6.pdf>
@@ -4184,4 +6670,8 @@
 
 =item L<http://tools.ietf.org/html/draft-ietf-fax-tiff-fx-extension1-01>
+
+=item L<http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/cinemadng/pdfs/CinemaDNG_Format_Specification_v1_1.pdf>
+
+=item L<http://geotiff.maptools.org/spec/geotiffhome.html>
 
 =back
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FITS.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FITS.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FITS.pm	(revision 34921)
@@ -0,0 +1,151 @@
+#------------------------------------------------------------------------------
+# 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.01';
+
+# 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' } },
+    COMMENT  => 'Comment',
+    HISTORY  => 'History',
+);
+
+#------------------------------------------------------------------------------
+# 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;
+            # ignore lines other than tags, COMMENT or HISTORY
+            next unless substr($buff,8,2) eq '= ' or $key eq 'COMMENT' or $key eq 'HISTORY';
+            # 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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLAC.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLAC.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLAC.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.03';
+$VERSION = '1.08';
 
 sub ProcessBitStream($$$);
@@ -29,12 +29,18 @@
         SubDirectory => { TagTable => 'Image::ExifTool::FLAC::StreamInfo' },
     },
+    1 => { Name => 'Padding',     Binary => 1, Unknown => 1 },
+    2 => { Name => 'Application', Binary => 1, Unknown => 1 },
+    3 => { Name => 'SeekTable',   Binary => 1, Unknown => 1 },
     4 => {
         Name => 'VorbisComment',
         SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Comments' },
     },
+    5 => { Name => 'CueSheet',    Binary => 1, Unknown => 1 },
     6 => {
         Name => 'Picture',
         SubDirectory => { TagTable => 'Image::ExifTool::FLAC::Picture' },
     },
+    # 7-126 - Reserved
+    # 127 - Invalid
 );
 
@@ -57,4 +63,9 @@
     },
     'Bit108-143' => 'TotalSamples',
+    'Bit144-271' => { #Tim Eliseo
+        Name => 'MD5Signature',
+        Format => 'undef',
+        ValueConv => 'unpack("H*",$val)',
+    },
 );
 
@@ -105,4 +116,5 @@
     8 => {
         Name => 'Picture',
+        Groups => { 2 => 'Preview' },
         Format => 'undef[$val{7}]',
         Binary => 1,
@@ -117,5 +129,5 @@
             1 => 'FLAC:TotalSamples',
         },
-        ValueConv => '$val[0] and $val[1] ? $val[1] / $val[0] : undef',
+        ValueConv => '($val[0] and $val[1]) ? $val[1] / $val[0] : undef',
         PrintConv => 'ConvertDuration($val)',
     },
@@ -131,18 +143,18 @@
 # Notes: Byte order is used to determine the ordering of bits in the stream:
 # 'MM' = bit 0 is most significant, 'II' = bit 0 is least significant
-# - can handle arbitrarily wide values (ie. 8-byte or larger integers)
+# - can handle arbitrarily wide values (eg. 8-byte or larger integers)
 sub ProcessBitStream($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt   = $$dirInfo{DataPt};
     my $dataPos  = $$dirInfo{DataPos};
     my $dirStart = $$dirInfo{DirStart} || 0;
     my $dirLen   = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
-    my $verbose  = $exifTool->Options('Verbose');
+    my $verbose  = $et->Options('Verbose');
     my $byteOrder = GetByteOrder();
     my $tag;
 
     if ($verbose) {
-        $exifTool->VPrint(0, "  + [BitStream directory, $dirLen bytes, '$byteOrder' order]\n");
+        $et->VPrint(0, "  + [BitStream directory, $dirLen bytes, '${byteOrder}' order]\n");
     }
     foreach $tag (sort keys %$tagTablePtr) {
@@ -152,46 +164,51 @@
         my ($f1, $f2) = ($b1 % 8, $b2 % 8); # start/end bit numbers within each byte
         last if $i2 >= $dirLen;
-        my $val = 0;
-        my ($i, $mask, $extra);
-        $extra = ', Mask=0x' if $verbose and ($f1 != 0 or $f2 != 7);
-        if ($byteOrder eq 'MM') {
-            # loop from high byte to low byte
-            for ($i=$i1; $i<=$i2; ++$i) {
-                $mask = 0xff;
-                if ($i == $i1 and $f1) {
-                    # mask off high bits in first word (0 is high bit)
-                    foreach ((8-$f1) .. 7) { $mask ^= (1 << $_) }
+        my ($val, $extra);
+        # if Format is unspecified, convert the specified number of bits to an unsigned integer,
+        # otherwise allow HandleTag to convert whole bytes the normal way (via undefined $val)
+        if (ref $$tagTablePtr{$tag} ne 'HASH' or not $$tagTablePtr{$tag}{Format}) {
+            my ($i, $mask);
+            $val = 0;
+            $extra = ', Mask=0x' if $verbose and ($f1 != 0 or $f2 != 7);
+            if ($byteOrder eq 'MM') {
+                # loop from high byte to low byte
+                for ($i=$i1; $i<=$i2; ++$i) {
+                    $mask = 0xff;
+                    if ($i == $i1 and $f1) {
+                        # mask off high bits in first word (0 is high bit)
+                        foreach ((8-$f1) .. 7) { $mask ^= (1 << $_) }
+                    }
+                    if ($i == $i2 and $f2 < 7) {
+                        # mask off low bits in last word (7 is low bit)
+                        foreach (0 .. (6-$f2)) { $mask ^= (1 << $_) }
+                    }
+                    $val = $val * 256 + ($mask & Get8u($dataPt, $i + $dirStart));
+                    $extra .= sprintf('%.2x', $mask) if $extra;
                 }
-                if ($i == $i2 and $f2 < 7) {
-                    # mask off low bits in last word (7 is low bit)
-                    foreach (0 .. (6-$f2)) { $mask ^= (1 << $_) }
+            } else {
+                # (FLAC is big-endian, but support little-endian bit streams
+                #  so this routine can be used by other modules)
+                # loop from high byte to low byte
+                for ($i=$i2; $i>=$i1; --$i) {
+                    $mask = 0xff;
+                    if ($i == $i1 and $f1) {
+                        # mask off low bits in first word (0 is low bit)
+                        foreach (0 .. ($f1-1)) { $mask ^= (1 << $_) }
+                    }
+                    if ($i == $i2 and $f2 < 7) {
+                        # mask off high bits in last word (7 is high bit)
+                        foreach (($f2+1) .. 7) { $mask ^= (1 << $_) }
+                    }
+                    $val = $val * 256 + ($mask & Get8u($dataPt, $i + $dirStart));
+                    $extra .= sprintf('%.2x', $mask) if $extra;
                 }
-                $val = $val * 256 + ($mask & Get8u($dataPt, $i + $dirStart));
-                $extra .= sprintf('%.2x', $mask) if $extra;
             }
-        } else {
-            # (FLAC is big-endian, but support little-endian bit streams
-            #  so this routine can be used by other modules)
-            # loop from high byte to low byte
-            for ($i=$i2; $i>=$i1; --$i) {
-                $mask = 0xff;
-                if ($i == $i1 and $f1) {
-                    # mask off low bits in first word (0 is low bit)
-                    foreach (0 .. ($f1-1)) { $mask ^= (1 << $_) }
-                }
-                if ($i == $i2 and $f2 < 7) {
-                    # mask off high bits in last word (7 is high bit)
-                    foreach (($f2+1) .. 7) { $mask ^= (1 << $_) }
-                }
-                $val = $val * 256 + ($mask & Get8u($dataPt, $i + $dirStart));
-                $extra .= sprintf('%.2x', $mask) if $extra;
+            # shift word down until low bit is in position 0
+            until ($mask & 0x01) {
+                $val /= 2;
+                $mask >>= 1;
             }
         }
-        # shift word down until low bit is in position 0
-        until ($mask & 0x01) {
-            $val /= 2;
-            $mask >>= 1;
-        }
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $et->HandleTag($tagTablePtr, $tag, $val,
             DataPt  => $dataPt,
             DataPos => $dataPos,
@@ -210,19 +227,19 @@
 sub ProcessFLAC($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
 
     # must first check for leading/trailing ID3 information
-    unless ($exifTool->{DoneID3}) {
+    unless ($$et{DoneID3}) {
         require Image::ExifTool::ID3;
-        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
+        Image::ExifTool::ID3::ProcessID3($et, $dirInfo) and return 1;
     }
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     my ($buff, $err);
 
     # check FLAC signature
     $raf->Read($buff, 4) == 4 and $buff eq 'fLaC' or return 0;
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('MM');
     my $tagTablePtr = GetTagTable('Image::ExifTool::FLAC::Main');
@@ -237,7 +254,7 @@
         if ($verbose) {
             print $out "FLAC metadata block, type $tag:\n";
-            $exifTool->VerboseDump(\$buff, DataPos => $raf->Tell() - $size);
+            $et->VerboseDump(\$buff, DataPos => $raf->Tell() - $size);
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, undef,
+        $et->HandleTag($tagTablePtr, $tag, undef,
             DataPt  => \$buff,
             DataPos => $raf->Tell() - $size,
@@ -245,5 +262,5 @@
         last if $last;   # all done if  is set
     }
-    $err and $exifTool->Warn('Format error in FLAC file');
+    $err and $et->Warn('Format error in FLAC file');
     return 1;
 }
@@ -268,5 +285,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -284,4 +301,5 @@
 
 L<Image::ExifTool::TagNames/FLAC Tags>,
+L<Image::ExifTool::TagNames/Ogg Tags>,
 L<Image::ExifTool(3pm)|Image::ExifTool>
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLIF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLIF.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLIF.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLIR.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLIR.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FLIR.pm	(revision 34921)
@@ -0,0 +1,1630 @@
+#------------------------------------------------------------------------------
+# File:         FLIR.pm
+#
+# Description:  Read FLIR meta information
+#
+# Revisions:    2013/03/28 - P. Harvey Created
+#
+# 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) https://exiftool.org/forum/index.php/topic,5538.0.html
+#               JD) Jens Duttke private communication
+#
+# Glossary:     FLIR = Forward Looking Infra Red
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::FLIR;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+use Image::ExifTool::GPS;
+
+$VERSION = '1.18';
+
+sub ProcessFLIR($$;$);
+sub ProcessFLIRText($$$);
+sub ProcessMeasInfo($$$);
+sub GetImageType($$$);
+
+my %temperatureInfo = (
+    Writable => 'rational64u',
+    Format => 'rational64s', # (have seen negative values)
+);
+
+# tag information for floating point Kelvin tag
+my %floatKelvin = (
+    Format => 'float',
+    ValueConv => '$val - 273.15',
+    PrintConv => 'sprintf("%.1f C",$val)',
+);
+
+# commonly used tag information elements
+my %float1f = ( Format => 'float', PrintConv => 'sprintf("%.1f",$val)' );
+my %float2f = ( Format => 'float', PrintConv => 'sprintf("%.2f",$val)' );
+my %float6f = ( Format => 'float', PrintConv => 'sprintf("%.6f",$val)' );
+my %float8g = ( Format => 'float', PrintConv => 'sprintf("%.8g",$val)' );
+
+# FLIR makernotes tags (ref PH)
+%Image::ExifTool::FLIR::Main = (
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITABLE => 1,
+    PRIORITY => 0, # (unreliable)
+    NOTES => q{
+        Information extracted from the maker notes of JPEG images from thermal
+        imaging cameras by FLIR Systems Inc.
+    },
+    0x01 => { #2
+        Name => 'ImageTemperatureMax',
+        %temperatureInfo,
+        Notes => q{
+            these temperatures may be in Celsius, Kelvin or Fahrenheit, but there is no
+            way to tell which
+        },
+    },
+    0x02 => { Name => 'ImageTemperatureMin', %temperatureInfo }, #2
+    0x03 => { #1
+        Name => 'Emissivity',
+        Writable => 'rational64u',
+        PrintConv => 'sprintf("%.2f",$val)',
+        PrintConvInv => '$val',
+    },
+    # 0x04 does not change with temperature units; often 238, 250 or 457
+    0x04 => { Name => 'UnknownTemperature', %temperatureInfo, Unknown => 1 },
+    # 0x05,0x06 are unreliable.  As written by FLIR tools, these are the
+    # CameraTemperatureRangeMax/Min, but the units vary depending on the
+    # options settings.  But as written by some cameras, the values are different.
+    0x05 => { Name => 'CameraTemperatureRangeMax', %temperatureInfo, Unknown => 1 },
+    0x06 => { Name => 'CameraTemperatureRangeMin', %temperatureInfo, Unknown => 1 },
+    # 0x07 - string[33] (some sort of image ID?)
+    # 0x08 - string[33]
+    # 0x09 - undef (tool info)
+    # 0x0a - int32u: 1
+    # 0x0f - rational64u: 0/1000
+    # 0x10,0x11,0x12 - int32u: 0
+    # 0x13 - rational64u: 0/1000
+);
+
+# FLIR FFF tag table (ref PH)
+%Image::ExifTool::FLIR::FFF = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessFLIR,
+    VARS => { ALPHA_FIRST => 1 },
+    NOTES => q{
+        Information extracted from FLIR FFF images and the APP1 FLIR segment of JPEG
+        images.  These tags may also be extracted from the first frame of an FLIR
+        SEQ file.
+    },
+    "_header" => {
+        Name => 'FFFHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::Header' },
+    },
+    # 0 = free (ref 3)
+    0x01 => {
+        Name => 'RawData',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::RawData' },
+    },
+    # 2 = GainMap (ref 3)
+    # 3 = OffsMap (ref 3)
+    # 4 = DeadMap (ref 3)
+    0x05 => { #6
+        Name => 'GainDeadData',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::GainDeadData' },
+    },
+    0x06 => { #6
+        Name => 'CoarseData',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::CoarseData' },
+    },
+    # 7 = ImageMap (ref 3)
+    0x0e => {
+        Name => 'EmbeddedImage',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::EmbeddedImage' },
+    },
+    0x20 => {
+        Name => 'CameraInfo', # (BasicData - ref 3)
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::CameraInfo' },
+    },
+    0x21 => { #6
+        Name => 'MeasurementInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::MeasInfo' },
+    },
+    0x22 => {
+        Name => 'PaletteInfo', # (ColorPal - ref 3)
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::PaletteInfo' },
+    },
+    0x23 => {
+        Name => 'TextInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::TextInfo' },
+    },
+    0x24 => {
+        Name => 'EmbeddedAudioFile',
+        # (sometimes has an unknown 8-byte header)
+        RawConv => q{
+            return \$val if $val =~ s/^.{0,16}?RIFF/RIFF/s;
+            $self->Warn('Unknown EmbeddedAudioFile format');
+            return undef;
+        },
+    },
+    # 0x27: 01 00 08 00 10 00 00 00
+    0x28 => {
+        Name => 'PaintData',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::PaintData' },
+    },
+    0x2a => {
+        Name => 'PiP',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FLIR::PiP',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    0x2b => {
+        Name => 'GPSInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FLIR::GPSInfo',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    0x2c => {
+        Name => 'MeterLink',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FLIR::MeterLink' ,
+            ByteOrder => 'LittleEndian'
+        },
+    },
+    0x2e => {
+        Name => 'ParameterInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::ParamInfo' },
+    },
+);
+
+# FFF file header (ref PH)
+%Image::ExifTool::FLIR::Header = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    NOTES => 'Tags extracted from the FLIR FFF/AFF header.',
+    4 => { Name => 'CreatorSoftware', Format => 'string[16]' },
+);
+
+# FLIR raw data record (ref PH)
+%Image::ExifTool::FLIR::RawData = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        The thermal image data may be stored either as raw data, or in PNG format.
+        If stored as raw data, ExifTool adds a TIFF header to allow the data to be
+        viewed as a TIFF image.  If stored in PNG format, the PNG image is extracted
+        as-is.  Note that most FLIR cameras using the PNG format seem to write the
+        16-bit raw image data in the wrong byte order.
+    },
+    0x00 => {
+        # use this tag only to determine the byte order of the raw data
+        # (the value should be 0x0002 if the byte order is correct)
+        # - always "II" when RawThermalImageType is "TIFF"
+        # - seen both "II" and "MM" when RawThermalImageType is "PNG"
+        Name => 'RawDataByteOrder',
+        Hidden => 1,
+        RawConv => 'ToggleByteOrder() if $val >= 0x0100; undef',
+    },
+    0x01 => {
+        Name => 'RawThermalImageWidth',
+        RawConv => '$$self{RawThermalImageWidth} = $val',
+    },
+    0x02 => {
+        Name => 'RawThermalImageHeight',
+        RawConv => '$$self{RawThermalImageHeight} = $val',
+    },
+    # 0x03-0x05: 0
+    # 0x06: raw image width - 1
+    # 0x07: 0
+    # 0x08: raw image height - 1
+    # 0x09: 0,15,16
+    # 0x0a: 0,2,3,11,12,13,30
+    # 0x0b: 0,2
+    # 0x0c: 0 or a large number
+    # 0x0d: 0,3,4,6
+    # 0x0e-0x0f: 0
+    16 => {
+        Name => 'RawThermalImageType',
+        Format => 'undef[$size-0x20]',
+        RawConv => 'Image::ExifTool::FLIR::GetImageType($self, $val, "RawThermalImage")',
+    },
+    16.1 => {
+        Name => 'RawThermalImage',
+        Groups => { 2 => 'Preview' },
+        RawConv => '\$$self{RawThermalImage}',
+    },
+);
+
+# GainDeadMap record (ref 6) (see RawData above)
+%Image::ExifTool::FLIR::GainDeadData = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    NOTES => 'Information found in FFF-format .GAN calibration image files.',
+    0x00 => {
+        Name => 'GainDeadMapByteOrder',
+        Hidden => 1,
+        RawConv => 'ToggleByteOrder() if $val >= 0x0100; undef',
+    },
+    0x01 => {
+        Name => 'GainDeadMapImageWidth',
+        RawConv => '$$self{GainDeadMapImageWidth} = $val',
+    },
+    0x02 => {
+        Name => 'GainDeadMapImageHeight',
+        RawConv => '$$self{GainDeadMapImageHeight} = $val',
+    },
+    16 => {
+        Name => 'GainDeadMapImageType',
+        Format => 'undef[$size-0x20]',
+        RawConv => 'Image::ExifTool::FLIR::GetImageType($self, $val, "GainDeadMapImage")',
+    },
+    16.1 => {
+        Name => 'GainDeadMapImage',
+        RawConv => '\$$self{GainDeadMapImage}',
+    },
+);
+
+# CoarseMap record (ref 6) (see RawData above)
+%Image::ExifTool::FLIR::CoarseData = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    NOTES => 'Information found in FFF-format .CRS correction image files.',
+    0x00 => {
+        Name => 'CoarseMapByteOrder',
+        Hidden => 1,
+        RawConv => 'ToggleByteOrder() if $val >= 0x0100; undef',
+    },
+    0x01 => {
+        Name => 'CoarseMapImageWidth',
+        RawConv => '$$self{CoarseMapImageWidth} = $val',
+    },
+    0x02 => {
+        Name => 'CoarseMapImageHeight',
+        RawConv => '$$self{CoarseMapImageHeight} = $val',
+    },
+    16 => {
+        Name => 'CoarseMapImageType',
+        Format => 'undef[$size-0x20]',
+        RawConv => 'Image::ExifTool::FLIR::GetImageType($self, $val, "CoarseMapImage")',
+    },
+    16.1 => {
+        Name => 'CoarseMapImage',
+        RawConv => '\$$self{CoarseMapImage}',
+    },
+);
+
+# "Paint colors" record (ref PH)
+%Image::ExifTool::FLIR::PaintData = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    NOTES => 'Information generated by FLIR Tools "Paint colors" tool.',
+    0x01 => {
+        Name => 'PaintByteOrder',
+        Hidden => 1,
+        RawConv => 'ToggleByteOrder() if $val >= 0x0100; undef',
+    },
+    0x05 => {
+        Name => 'PaintImageWidth',
+        RawConv => '$$self{PaintImageWidth} = $val',
+    },
+    0x06 => {
+        Name => 'PaintImageHeight',
+        RawConv => '$$self{PaintImageHeight} = $val',
+    },
+    20 => {
+        Name => 'PaintImageType',
+        Format => 'undef[$size-0x28]',
+        RawConv => 'Image::ExifTool::FLIR::GetImageType($self, $val, "PaintImage")',
+    },
+    20.1 => {
+        Name => 'PaintImage',
+        RawConv => '\$$self{PaintImage}',
+    },
+);
+
+# FLIR embedded image (ref 1)
+%Image::ExifTool::FLIR::EmbeddedImage = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    0 => {
+        # use this tag only to determine the byte order
+        # (the value should be 0x0003 if the byte order is correct)
+        Name => 'EmbeddedImageByteOrder',
+        Format => 'int16u',
+        Hidden => 1,
+        RawConv => 'ToggleByteOrder() if $val >= 0x0100; undef',
+    },
+    1 => 'EmbeddedImageWidth',
+    2 => 'EmbeddedImageHeight',
+    16 => {
+        Name => 'EmbeddedImageType',
+        Format => 'undef[4]',
+        RawConv => '$val =~ /^\x89PNG/s ? "PNG" : ($val =~ /^\xff\xd8\xff/ ? "JPG" : "DAT")',
+        Notes => q{
+            "PNG" for PNG image in Y Cb Cr colors, "JPG" for a JPEG image, or "DAT" for
+            other image data
+        },
+    },
+    16.1 => {
+        Name => 'EmbeddedImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$size-0x20]',
+        Binary => 1,
+    },
+);
+
+# FLIR camera record (ref PH)
+%Image::ExifTool::FLIR::CameraInfo = (
+    GROUPS => { 0 => 'APP1', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        FLIR camera information.  The Planck tags are variables used in the
+        temperature calculation.  See
+        L<https://exiftool.org/forum/index.php?topic=4898.msg23972#msg23972>
+        for details.
+    },
+    0x00 => {
+        # use this tag only to determine the byte order
+        # (the value should be 0x0002 if the byte order is correct)
+        Name => 'CameraInfoByteOrder',
+        Format => 'int16u',
+        Hidden => 1,
+        RawConv => 'ToggleByteOrder() if $val >= 0x0100; undef',
+    },
+    # 0x02 - int16u: image width
+    # 0x04 - int16u: image height
+    # 0x0c - int32u: image width - 1
+    # 0x10 - int32u: image height - 1
+    0x20 => { Name => 'Emissivity',                   %float2f },
+    0x24 => { Name => 'ObjectDistance', Format => 'float', PrintConv => 'sprintf("%.2f m",$val)' },
+    0x28 => { Name => 'ReflectedApparentTemperature', %floatKelvin },
+    0x2c => { Name => 'AtmosphericTemperature',       %floatKelvin },
+    0x30 => { Name => 'IRWindowTemperature',          %floatKelvin },
+    0x34 => { Name => 'IRWindowTransmission',         %float2f },
+    # 0x38: 0
+    0x3c => {
+        Name => 'RelativeHumidity',
+        Format => 'float',
+        ValueConv => '$val > 2 ? $val / 100 : $val', # have seen value expressed as percent in FFF file
+        PrintConv => 'sprintf("%.1f %%",$val*100)',
+    },
+    # 0x40 - float: 0,6
+    # 0x44,0x48,0x4c: 0
+    # 0x50 - int32u: 1
+    # 0x54: 0
+    0x58 => { Name => 'PlanckR1', %float8g }, #1
+    0x5c => { Name => 'PlanckB',  %float8g }, #1
+    0x60 => { Name => 'PlanckF',  %float8g }, #1
+    # 0x64,0x68,0x6c: 0
+    0x070 => { Name => 'AtmosphericTransAlpha1', %float6f }, #1 (value: 0.006569)
+    0x074 => { Name => 'AtmosphericTransAlpha2', %float6f }, #1 (value: 0.012620)
+    0x078 => { Name => 'AtmosphericTransBeta1',  %float6f }, #1 (value: -0.002276)
+    0x07c => { Name => 'AtmosphericTransBeta2',  %float6f }, #1 (value: -0.006670)
+    0x080 => { Name => 'AtmosphericTransX',      %float6f }, #1 (value: 1.900000)
+    # 0x84,0x88: 0
+    # 0x8c - float: 0,4,6
+    0x90 => { Name => 'CameraTemperatureRangeMax', %floatKelvin },
+    0x94 => { Name => 'CameraTemperatureRangeMin', %floatKelvin },
+    0x98 => { Name => 'CameraTemperatureMaxClip', %floatKelvin }, # 50 degrees over camera max
+    0x9c => { Name => 'CameraTemperatureMinClip', %floatKelvin }, # usually 10 or 20 degrees below camera min
+    0xa0 => { Name => 'CameraTemperatureMaxWarn', %floatKelvin }, # same as camera max
+    0xa4 => { Name => 'CameraTemperatureMinWarn', %floatKelvin }, # same as camera min
+    0xa8 => { Name => 'CameraTemperatureMaxSaturated', %floatKelvin }, # usually 50 or 88 degrees over camera max
+    0xac => { Name => 'CameraTemperatureMinSaturated', %floatKelvin }, # usually 10, 20 or 40 degrees below camera min
+    0xd4 => { Name => 'CameraModel',        Format => 'string[32]' },
+    0xf4 => { Name => 'CameraPartNumber',   Format => 'string[16]' }, #1
+    0x104 => { Name => 'CameraSerialNumber',Format => 'string[16]' }, #1
+    0x114 => { Name => 'CameraSoftware',    Format => 'string[16]' }, #1/PH (NC)
+    0x170 => { Name => 'LensModel',         Format => 'string[32]' },
+    # note: it seems that FLIR updated their lenses at some point, so lenses with the same
+    # name may have different part numbers (eg. the FOL38 is either 1196456 or T197089)
+    0x190 => { Name => 'LensPartNumber',    Format => 'string[16]' },
+    0x1a0 => { Name => 'LensSerialNumber',  Format => 'string[16]' },
+    0x1b4 => { Name => 'FieldOfView',       Format => 'float', PrintConv => 'sprintf("%.1f deg", $val)' }, #1
+    # 0x1d0 - int16u: 0,12,24,25,46
+    # 0x1d2 - int16u: 170,180,190,380,760,52320
+    0x1ec => { Name => 'FilterModel',       Format => 'string[16]' },
+    0x1fc => { Name => 'FilterPartNumber',  Format => 'string[32]' },
+    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 => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Format => 'undef[10]',
+        Groups => { 2 => 'Time' },
+        RawConv => q{
+            my $tm = Get32u(\$val, 0);
+            my $ss = Get32u(\$val, 4) & 0xffff;
+            my $tz = Get16s(\$val, 8);
+            ConvertUnixTime($tm - $tz * 60) . sprintf('.%.3d', $ss) . TimeZoneString(-$tz);
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    0x390 => { Name => 'FocusStepCount', Format => 'int16u' },
+    0x45c => { Name => 'FocusDistance',  Format => 'float', PrintConv => 'sprintf("%.1f m",$val)' },
+    # 0x43c - string: either "Live" or the file name
+    0x464 => { Name => 'FrameRate',  Format => 'int16u' }, #SebastianHani
+);
+
+# FLIR measurement tools record (ref 6)
+%Image::ExifTool::FLIR::MeasInfo = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessMeasInfo,
+    FORMAT => 'int16u',
+    VARS => { NO_ID => 1 },
+    NOTES => q{
+        Tags listed below are only for the first measurement tool, however multiple
+        measurements may be added, and information is extracted for all of them. 
+        Tags for subsequent measurements are generated as required with the prefixes
+        "Meas2", "Meas3", etc.
+    },
+    Meas1Type => {
+        PrintConv => {
+            1 => 'Spot',
+            2 => 'Area',
+            3 => 'Ellipse',
+            4 => 'Line',
+            5 => 'Endpoint', #PH (NC, FLIR Tools v2.0 for Mac generates an empty one of these after each Line)
+            6 => 'Alarm', #PH seen params: "0 1 0 1 9142 0 9142 0" (called "Isotherm" by Mac version)
+            7 => 'Unused', #PH (NC) (or maybe "Free"?)
+            8 => 'Difference',
+        },
+    },
+    Meas1Params => {
+        Notes => 'Spot=X,Y; Area=X1,Y1,W,H; Ellipse=XC,YC,X1,Y1,X2,Y2; Line=X1,Y1,X2,Y2',
+    },
+    Meas1Label => { },
+);
+
+# FLIR palette record (ref PH/JD)
+%Image::ExifTool::FLIR::PaletteInfo = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    0x00 => { #JD
+        Name => 'PaletteColors',
+        RawConv => '$$self{PaletteColors} = $val',
+    },
+    0x06 => { Name => 'AboveColor',     Format => 'int8u[3]', Notes => 'Y Cr Cb color components' }, #JD
+    0x09 => { Name => 'BelowColor',     Format => 'int8u[3]' }, #JD
+    0x0c => { Name => 'OverflowColor',  Format => 'int8u[3]' }, #JD
+    0x0f => { Name => 'UnderflowColor', Format => 'int8u[3]' }, #JD
+    0x12 => { Name => 'Isotherm1Color', Format => 'int8u[3]' }, #JD
+    0x15 => { Name => 'Isotherm2Color', Format => 'int8u[3]' }, #JD
+    0x1a => { Name => 'PaletteMethod' }, #JD
+    0x1b => { Name => 'PaletteStretch' }, #JD
+    0x30 => {
+        Name => 'PaletteFileName',
+        Format => 'string[32]',
+        # (not valid for all images)
+        RawConv => q{
+            $val =~ s/\0.*//;
+            $val =~ /^[\x20-\x7e]{3,31}$/ ? $val : undef;
+        },
+    },
+    0x50 => {
+        Name => 'PaletteName',
+        Format => 'string[32]',
+        # (not valid for all images)
+        RawConv => q{
+            $val =~ s/\0.*//;
+            $val =~ /^[\x20-\x7e]{3,31}$/ ? $val : undef;
+        },
+    },
+    0x70 => {
+        Name => 'Palette',
+        Format => 'undef[3*$$self{PaletteColors}]',
+        Notes => 'Y Cr Cb byte values for each palette color',
+        Binary => 1,
+    },
+);
+
+# FLIR text information record (ref PH)
+%Image::ExifTool::FLIR::TextInfo = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessFLIRText,
+    VARS => { NO_ID => 1 },
+    Label0 => { },
+    Value0 => { },
+    Label1 => { },
+    Value1 => { },
+    Label2 => { },
+    Value2 => { },
+    Label3 => { },
+    Value3 => { },
+    # (there could be more, and we will generate these on the fly if necessary)
+);
+
+# FLIR parameter information record (ref PH)
+%Image::ExifTool::FLIR::ParamInfo = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessFLIRText,
+    VARS => { NO_ID => 1 },
+    Generated => {
+        Name => 'DateTimeGenerated',
+        Description => 'Date/Time Generated',
+        Groups => { 2 => 'Time' },
+        ValueConv => '$val =~ tr/-/:/; $val',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    Param0 => { },
+    Param1 => { },
+    Param2 => { },
+    Param3 => { },
+    # (there could be more, and we will generate these on the fly if necessary)
+);
+
+# FLIR Picture in Picture record (ref 1)
+%Image::ExifTool::FLIR::PiP = (
+    GROUPS => { 0 => 'APP1', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    NOTES => 'FLIR Picture in Picture tags.',
+    FORMAT => 'int16s',
+    0x00 => {
+        Name => 'Real2IR',
+        Format => 'float',
+    },
+    2 => {
+        Name => 'OffsetX',
+        Notes => 'offset from of insertion point from center',
+        PrintConv => 'sprintf("%+d",$val)', # (add sign for direct use with IM convert)
+    },
+    3 => {
+        Name => 'OffsetY',
+        PrintConv => 'sprintf("%+d",$val)',
+    },
+    4 => {
+        Name => 'PiPX1',
+        Description => 'PiP X1',
+        Notes => 'crop size for radiometric image',
+    },
+    5 => { Name => 'PiPX2', Description => 'PiP X2' },
+    6 => { Name => 'PiPY1', Description => 'PiP Y1' },
+    7 => { Name => 'PiPY2', Description => 'PiP Y2' },
+);
+
+# FLIR GPS record (ref PH/JD/forum9615)
+%Image::ExifTool::FLIR::GPSInfo = (
+    GROUPS => { 0 => 'APP1', 2 => 'Location' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    0x00 => {
+        Name => 'GPSValid',
+        Format => 'int32u',
+        RawConv => '$$self{GPSValid} = $val',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0x04 => {
+        Name => 'GPSVersionID',
+        Format => 'undef[4]',
+        RawConv => '$val eq "\0\0\0\0" ? undef : $val',
+        PrintConv => 'join ".", split //, $val',
+    },
+    0x08 => {
+        Name => 'GPSLatitudeRef',
+        Format => 'string[2]',
+        RawConv => 'length($val) ? $val : undef',
+        PrintConv => {
+            N => 'North',
+            S => 'South',
+        },
+    },
+    0x0a => {
+        Name => 'GPSLongitudeRef',
+        Format => 'string[2]',
+        RawConv => 'length($val) ? $val : undef',
+        PrintConv => {
+            E => 'East',
+            W => 'West',
+        },
+    },
+  # 0x0c - 4 unknown bytes
+    0x10 => {
+        Name => 'GPSLatitude',
+        Condition => '$$self{GPSValid}',    # valid only if GPSValid is 1
+        Format => 'double', # (signed)
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    },
+    0x18 => {
+        Name => 'GPSLongitude',
+        Condition => '$$self{GPSValid}',    # valid only if GPSValid is 1
+        Format => 'double', # (signed)
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    },
+    0x20 => {
+        Name => 'GPSAltitude',
+        Condition => '$$self{GPSValid}',    # valid only if GPSValid is 1
+        Format => 'float',
+        # (have seen likely invalid value of -1 when GPSValid is 1)
+        PrintConv => 'sprintf("%.2f m", $val)',
+    },
+  # 0x24 - 28 unknown bytes:
+  # 0x28 - int8u: seen 0,49,51,55,57 (ASCII "1","3","7","9")
+  # 0x29 - int8u: seen 0,48 (ASCII "0")
+    0x40 => {
+        Name => 'GPSDOP',
+        Description => 'GPS Dilution Of Precision',
+        Format => 'float',
+        RawConv => '$val > 0 ? $val : undef', # (have also seen likely invalid value of 1)
+        PrintConv => 'sprintf("%.2f", $val)',
+    },
+    0x44 => {
+        Name => 'GPSSpeedRef',
+        Format => 'string[2]',
+        RawConv => 'length($val) ? $val : undef',
+        PrintConv => {
+            K => 'km/h',
+            M => 'mph',
+            N => 'knots',
+        },
+    },
+    0x46 => {
+        Name => 'GPSTrackRef',
+        Format => 'string[2]',
+        RawConv => 'length($val) ? $val : undef',
+        PrintConv => {
+            M => 'Magnetic North',
+            T => 'True North',
+        },
+    },
+  # 0x48 - int32u: seen 0,77
+    0x4c => {
+        Name => 'GPSSpeed',
+        %float2f,
+        RawConv => '$val < 0 ? undef : $val',
+    },
+    0x50 => {
+        Name => 'GPSTrack',
+        %float2f,
+        RawConv => '$val < 0 ? undef : $val',
+    },
+  # 0x54 - float: seen 0,-1
+    0x58 => {
+        Name => 'GPSMapDatum',
+        Format => 'string[16]',
+        RawConv => 'length($val) ? $val : undef',
+    },
+  # 0xa4 - string[6]: seen 000208,081210,020409,000608,010408,020808,091011
+  # 0x78 - double[2]: seen "-1 -1","0 0"
+  # 0x78 - float[2]: seen "-1 -1","0 0"
+  # 0xb2 - string[2]?: seen "5\0"
+);
+
+# humidity meter information
+# (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' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    NOTES => 'Tags containing Meterlink humidity meter information.',
+    26 => {
+        Name => 'Reading1Units',
+        DataMember => 'Reading1Units',
+        RawConv => '$$self{Reading1Units} = $val',
+        PrintHex => 1,
+        PrintConv => {
+            0x0d => 'C',
+            0x1b => '%',
+            0x1d => 'Relative',
+            0x24 => 'g/kg',
+        },
+    },
+    28 => {
+        Name => 'Reading1Description',
+        DataMember => 'Reading1Description',
+        RawConv => '$$self{Reading1Description} = $val',
+        PrintConv => {
+            0 => 'Humidity',
+            3 => 'Moisture', # Pinless Moisture Readings with INTernal sensor
+            7 => 'Dew Point',
+            8 => 'Air Temperature',
+            9 => 'IR Temperature',
+            11 => 'Difference Temperature', # Difference Temp: IR-Temp and DewPoint
+        },
+    },
+    32 => {
+        Name => 'Reading1Device',
+        Format => 'string[16]',
+    },
+    96 => {
+        Name => 'Reading1Value',
+        Format => 'double',
+        # 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;
+            return $val;
+        },
+    },
+    # add 100 for subsequent readings
+    126 => {
+        Name => 'Reading2Units',
+        DataMember => 'Reading2Units',
+        RawConv => '$$self{Reading2Units} = $val',
+        PrintHex => 1,
+        PrintConv => {
+            0x0d => 'C',
+            0x1b => '%',
+            0x1d => 'rel',
+            0x24 => 'g/kg',
+        },
+    },
+    128 => {
+        Name => 'Reading2Description',
+        DataMember => 'Reading2Description',
+        RawConv => '$$self{Reading2Description} = $val',
+        PrintConv => {
+            0 => 'Humidity',
+            3 => 'Moisture',
+            7 => 'Dew Point',
+            8 => 'Air Temperature',
+            9 => 'IR Temperature',
+            11 => 'Difference Temperature', # Difference Temp: IR-Temp and DewPoint
+        },
+    },
+    132 => {
+        Name => 'Reading2Device',
+        Format => 'string[16]',
+    },
+    196 => {
+        Name => 'Reading2Value',
+        Format => 'double',
+        # 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;
+            return $val;
+        },
+    },
+    226 => {
+        Name => 'Reading3Units',
+        DataMember => 'Reading3Units',
+        RawConv => '$$self{Reading3Units} = $val',
+        PrintHex => 1,
+        PrintConv => {
+            0x0d => 'C',
+            0x1b => '%',
+            0x1d => 'rel',
+            0x24 => 'g/kg',
+        },
+    },
+    228 => {
+        Name => 'Reading3Description',
+        DataMember => 'Reading3Description',
+        RawConv => '$$self{Reading3Description} = $val',
+        PrintConv => {
+            0 => 'Humidity',
+            3 => 'Moisture',
+            7 => 'Dew Point',
+            8 => 'Air Temperature',
+            9 => 'IR Temperature',
+            11 => 'Difference Temperature', # Difference Temp: IR-Temp and DewPoint
+        },
+    },
+    232 => {
+        Name => 'Reading3Device',
+        Format => 'string[16]',
+    },
+    296 => {
+        Name => 'Reading3Value',
+        Format => 'double',
+        # 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;
+            return $val;
+        },
+    },
+
+    326 => {
+        Name => 'Reading4Units',
+        DataMember => 'Reading4Units',
+        RawConv => '$$self{Reading4Units} = $val',
+        PrintHex => 1,
+        PrintConv => {
+            0x0d => 'C',
+            0x1b => '%',
+            0x1d => 'rel',
+            0x24 => 'g/kg',
+        },
+    },
+    328 => {
+        Name => 'Reading4Description',
+        DataMember => 'Reading4Description',
+        RawConv => '$$self{Reading4Description} = $val',
+        PrintConv => {
+            0 => 'Humidity',
+            3 => 'Moisture',
+            7 => 'Dew Point',
+            8 => 'Air Temperature',
+            9 => 'IR Temperature',
+            11 => 'Difference Temperature', # Difference Temp: IR-Temp and DewPoint
+        },
+    },
+    332 => {
+        Name => 'Reading4Device',
+        Format => 'string[16]',
+    },
+    396 => {
+        Name => 'Reading4Value',
+        Format => 'double',
+        # 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;
+            return $val;
+        },
+    },
+);
+
+# FLIR public image format (ref 4/5)
+%Image::ExifTool::FLIR::FPF = (
+    GROUPS => { 0 => 'FLIR', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    NOTES => 'Tags extracted from FLIR Public image Format (FPF) files.',
+    0x20 => { Name => 'FPFVersion',         Format => 'int32u' },
+    0x24 => { Name => 'ImageDataOffset',    Format => 'int32u' },
+    0x28 => {
+        Name => 'ImageType',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Temperature',
+            1 => 'Temperature Difference',
+            2 => 'Object Signal',
+            3 => 'Object Signal Difference',
+        },
+    },
+    0x2a => {
+        Name => 'ImagePixelFormat',
+        Format => 'int16u',
+        PrintConv => {
+            0 => '2-byte short integer',
+            1 => '4-byte long integer',
+            2 => '4-byte float',
+            3 => '8-byte double',
+        },
+    },
+    0x2c => { Name => 'ImageWidth',         Format => 'int16u' },
+    0x2e => { Name => 'ImageHeight',        Format => 'int16u' },
+    0x30 => { Name => 'ExternalTriggerCount',Format => 'int32u' },
+    0x34 => { Name => 'SequenceFrameNumber',Format => 'int32u' },
+    0x78 => { Name => 'CameraModel',        Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0x98 => { Name => 'CameraPartNumber',   Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0xb8 => { Name => 'CameraSerialNumber', Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0xd8 => { Name => 'CameraTemperatureRangeMin', %floatKelvin,    Groups => { 2 => 'Camera' } },
+    0xdc => { Name => 'CameraTemperatureRangeMax', %floatKelvin,    Groups => { 2 => 'Camera' } },
+    0xe0 => { Name => 'LensModel',          Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0x100 => { Name => 'LensPartNumber',    Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0x120 => { Name => 'LensSerialNumber',  Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0x140 => { Name => 'FilterModel',       Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0x150 => { Name => 'FilterPartNumber',  Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0x180 => { Name => 'FilterSerialNumber',Format => 'string[32]', Groups => { 2 => 'Camera' } },
+    0x1e0 => { Name => 'Emissivity',        %float2f },
+    0x1e4 => { Name => 'ObjectDistance',    Format => 'float', PrintConv => 'sprintf("%.2f m",$val)' },
+    0x1e8 => { Name => 'ReflectedApparentTemperature', %floatKelvin },
+    0x1ec => { Name => 'AtmosphericTemperature',       %floatKelvin },
+    0x1f0 => { Name => 'RelativeHumidity',  Format => 'float', PrintConv => 'sprintf("%.1f %%",$val*100)' },
+    0x1f4 => { Name => 'ComputedAtmosphericTrans', %float2f },
+    0x1f8 => { Name => 'EstimatedAtmosphericTrans',%float2f },
+    0x1fc => { Name => 'ReferenceTemperature', %floatKelvin },
+    0x200 => { Name => 'IRWindowTemperature',  %floatKelvin, Groups => { 2 => 'Camera' } },
+    0x204 => { Name => 'IRWindowTransmission', %float2f,     Groups => { 2 => 'Camera' } },
+    0x248 => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        Format => 'int32u[7]',
+        ValueConv => 'sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d.%.3d",split(" ",$val))',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    # Notes (based on ref 4):
+    # 1) The above date/time structure is documented to be 32 bytes for FPFVersion 1, but in
+    #    fact it is only 28.  Maybe this is why the full header length of my FPFVersion 2
+    #    sample is 892 bytes instead of 896.  If this was a documentation error, we are OK,
+    #    but if the alignment was really different in version 1, then the temperatures below
+    #    will be mis-aligned.  I don't have any version 1 samples to check this.
+    # 2) The following temperatures may not always be in Kelvin
+    0x2a4 => { Name => 'CameraScaleMin',    %float1f },
+    0x2a8 => { Name => 'CameraScaleMax',    %float1f },
+    0x2ac => { Name => 'CalculatedScaleMin',%float1f },
+    0x2b0 => { Name => 'CalculatedScaleMax',%float1f },
+    0x2b4 => { Name => 'ActualScaleMin',    %float1f },
+    0x2b8 => { Name => 'ActualScaleMax',    %float1f },
+);
+
+# top-level user data written by FLIR cameras in MP4 videos
+%Image::ExifTool::FLIR::UserData = (
+    GROUPS => { 1 => 'FLIR', 2 => 'Camera' },
+    NOTES => q{
+        Tags written by some FLIR cameras in a top-level (!) "udta" atom of MP4
+        videos.
+    },
+    uuid => [
+        {
+            Name => 'FLIR_Parts',
+            Condition => '$$valPt=~/^\x43\xc3\x99\x3b\x0f\x94\x42\x4b\x82\x05\x6b\x66\x51\x3f\x48\x5d/s',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::FLIR::Parts',
+                Start => 16,
+            },
+        },
+        {
+            Name => 'FLIR_Serial',
+            Condition => '$$valPt=~/^\x57\xf5\xb9\x3e\x51\xe4\x48\xaf\xa0\xd9\xc3\xef\x1b\x37\xf7\x12/s',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::FLIR::SerialNums',
+                Start => 16,
+            },
+        },
+        {
+            Name => 'FLIR_Params',
+            Condition => '$$valPt=~/^\x41\xe5\xdc\xf9\xe8\x0a\x41\xce\xad\xfe\x7f\x0c\x58\x08\x2c\x19/s',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::FLIR::Params',
+                Start => 16,
+            },
+        },
+        {
+            Name => 'FLIR_UnknownUUID',
+            Condition => '$$valPt=~/^\x57\x45\x20\x50\x2c\xbb\x44\xad\xae\x54\x15\xe9\xb8\x39\xd9\x03/s',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::FLIR::UnknownUUID',
+                Start => 16,
+            },
+        },
+        {
+            Name => 'FLIR_GPS',
+            Condition => '$$valPt=~/^\x7f\x2e\x21\x00\x8b\x46\x49\x18\xaf\xb1\xde\x70\x9a\x74\xf6\xf5/s',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::FLIR::GPS_UUID',
+                Start => 16,
+            },
+        },
+        {
+            Name => 'FLIR_MoreInfo',
+            Condition => '$$valPt=~/^\x2b\x45\x2f\xdc\x74\x35\x40\x94\xba\xee\x22\xa6\xb2\x3a\x7c\xf8/s',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::FLIR::MoreInfo',
+                Start => 16,
+            },
+        },
+        {
+            Name => 'SoftwareComponents',
+            Condition => '$$valPt=~/^\x78\x3f\xc7\x83\x0c\x95\x4b\x00\x8c\xc7\xac\xf1\xec\xb4\xd3\x9a/s',
+            Unknown => 1,
+            ValueConv => 'join " ", unpack "x20N4xZ*", $val',
+        },
+        {
+            Name => 'FLIR_Unknown',
+            Condition => '$$valPt=~/^\x52\xae\xda\x45\x17\x1e\x48\xb1\x92\x47\x93\xa4\x21\x4e\x43\xf5/s',
+            Unknown => 1,
+            ValueConv => 'unpack "x20C*", $val',
+        },
+        {
+            Name => 'Units',
+            Condition => '$$valPt=~/^\xf8\xab\x72\x1e\x84\x73\x44\xa0\xb8\xc8\x1b\x04\x82\x6e\x07\x24/s',
+            List => 1,
+            RawConv => 'my @a = split "\0", substr($val, 20); \@a',
+        },
+        {
+            Name => 'ThumbnailImage',
+            Groups => { 2 => 'Preview' },
+            Condition => '$$valPt=~/^\x91\xaf\x9b\x93\x45\x9b\x44\x56\x98\xd1\x5e\x76\xea\x01\x04\xac....\xff\xd8\xff/s',
+            RawConv => 'substr($val, 20)',
+            Binary => 1,
+        },
+    ],
+);
+
+# uuid 43c3993b0f94424b82056b66513f485d box of MP4 videos (ref PH)
+%Image::ExifTool::FLIR::Parts = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'FLIR', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'undef',
+    NOTES => q{
+        Tags extracted from the "uuid" box with ID 43c3993b0f94424b82056b66513f485d
+        in FLIR MP4 videos.
+    },
+    4 => [
+        {
+            Name => 'BAHPVer',
+            Condition => '$$valPt =~ /^bahpver\0/',
+            Format => 'undef[$size]',
+            RawConv => 'join " ", split "\0", substr($val, 8)',
+        },
+        {
+            Name => 'BALPVer',
+            Condition => '$$valPt =~ /^balpver\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 8)',
+        },
+        {
+            Name => 'Battery',
+            Condition => '$$valPt =~ /^battery\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 8)',
+        },
+        {
+            Name => 'BAVPVer',
+            Condition => '$$valPt =~ /^bavpver\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 8)',
+            # (the first string corresponds with a lens part number)
+        },
+        {
+            Name => 'CamCore',
+            Condition => '$$valPt =~ /^camcore\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 8)',
+        },
+        {
+            Name => 'DetectorBoard',
+            Condition => '$$valPt =~ /^det_board\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 10)',
+        },
+        {
+            Name => 'Detector',
+            Condition => '$$valPt =~ /^detector\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 9)',
+        },
+        {
+            Name => 'GIDCVer',
+            Condition => '$$valPt =~ /^gidcver\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 8)',
+        },
+        {
+            Name => 'GIDPVer',
+            Condition => '$$valPt =~ /^gidpver\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 8)',
+        },
+        {
+            Name => 'GIPC_CPLD',
+            Condition => '$$valPt =~ /^gipccpld\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 9)',
+        },
+        {
+            Name => 'GIPCVer',
+            Condition => '$$valPt =~ /^gipcver\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 8)',
+        },
+        {
+            Name => 'GIXIVer',
+            Condition => '$$valPt =~ /^gixiver\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 8)',
+        },
+        {
+            Name => 'MainBoard',
+            Condition => '$$valPt =~ /^mainboard\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 10)',
+        },
+        {
+            Name => 'Optics',
+            Condition => '$$valPt =~ /^optics\0/',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", substr($val, 7)',
+        },
+        {
+            Name => 'PartNumber',
+            Format => 'undef[$size]',
+            ValueConv => 'join " ", split "\0", $val',
+        },
+    ],
+);
+
+# uuid 57f5b93e51e448afa0d9c3ef1b37f712 box of MP4 videos (ref PH)
+%Image::ExifTool::FLIR::SerialNums = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'FLIR', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        Tags extracted from the "uuid" box with ID 57f5b93e51e448afa0d9c3ef1b37f712
+        in FLIR MP4 videos.
+    },
+    # (not sure if these offsets are constant)
+    0x0c => { Name => 'UnknownSerial1',     Format => 'string[33]', Unknown => 1 },
+    0x2d => { Name => 'UnknownSerial2',     Format => 'string[33]', Unknown => 1 },
+    0x4e => { Name => 'UnknownSerial3',     Format => 'string[33]', Unknown => 1 },
+    0x6f => { Name => 'UnknownSerial4',     Format => 'string[11]', Unknown => 1 },
+    0x7b => { Name => 'UnknownNumber',      Format => 'string[3]',  Unknown => 1 },
+    0x7e => { Name => 'CameraSerialNumber', Format => 'string[9]' },
+);
+
+# uuid 41e5dcf9e80a41ceadfe7f0c58082c19 box of MP4 videos (ref PH)
+%Image::ExifTool::FLIR::Params = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'FLIR', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'float',
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        Tags extracted from the "uuid" box with ID 41e5dcf9e80a41ceadfe7f0c58082c19
+        in FLIR MP4 videos.
+    },
+    1 => { Name => 'ReflectedApparentTemperature', %floatKelvin },
+    2 => { Name => 'AtmosphericTemperature',       %floatKelvin },
+    3 => { Name => 'Emissivity',                   %float2f },
+    4 => { Name => 'ObjectDistance',   PrintConv => 'sprintf("%.2f m",$val)' },
+    5 => { Name => 'RelativeHumidity', PrintConv => 'sprintf("%.1f %%",$val*100)' },
+    6 => { Name => 'EstimatedAtmosphericTrans',    %float2f },
+    7 => { Name => 'IRWindowTemperature',          %floatKelvin },
+    8 => { Name => 'IRWindowTransmission',         %float2f },
+);
+
+# uuid 574520502cbb44adae5415e9b839d903 box of MP4 videos (ref PH)
+%Image::ExifTool::FLIR::UnknownUUID = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'FLIR', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'float',
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        Tags extracted from the "uuid" box with ID 574520502cbb44adae5415e9b839d903
+        in FLIR MP4 videos.
+    },
+    # 1 - 1
+    # 2 - 0
+    # 3 - 0
+);
+
+# uuid 7f2e21008b464918afb1de709a74f6f5 box of MP4 videos (ref PH)
+%Image::ExifTool::FLIR::GPS_UUID = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'FLIR', 2 => 'Location' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'float',
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        Tags extracted from the "uuid" box with ID 7f2e21008b464918afb1de709a74f6f5
+        in FLIR MP4 videos.
+    },
+    1 => {
+        Name => 'GPSLatitude',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    },
+    2 => {
+        Name => 'GPSLongitude',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    },
+    3 => {
+        Name => 'GPSAltitude',
+        PrintConv => '$val=int($val*100+0.5)/100;"$val m"',
+    },
+    # 4 - int32u: 0x0001bf74
+    # 5 - int32u: 0
+    # 6 - int32u: 1
+);
+
+# uuid 2b452fdc74354094baee22a6b23a7cf8 box of MP4 videos (ref PH)
+%Image::ExifTool::FLIR::MoreInfo = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'FLIR', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        Tags extracted from the "uuid" box with ID 2b452fdc74354094baee22a6b23a7cf8
+        in FLIR MP4 videos.
+    },
+    5 => { Name => 'LensModel', Format => 'string[6]' },
+    11 => { Name => 'UnknownTemperature1', %floatKelvin, Unknown => 1 }, # (-14.9 C)
+    15 => { Name => 'UnknownTemperature2', %floatKelvin, Unknown => 1 }, # (60.0 C)
+);
+
+# FLIR AFF tag table (ref PH)
+%Image::ExifTool::FLIR::AFF = (
+    GROUPS => { 0 => 'FLIR', 1 => 'FLIR', 2 => 'Image' },
+    NOTES => 'Tags extracted from FLIR "AFF" SEQ images.',
+    VARS => { ALPHA_FIRST => 1 },
+    "_header" => {
+        Name => 'AFFHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::Header' },
+    },
+    0x01 => {
+        Name => 'AFF1',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::AFF1' },
+    },
+    0x05 => {
+        Name => 'AFF5',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::AFF5' },
+    },
+);
+
+# AFF record type 1 (ref forum?topic=4898.msg27627)
+%Image::ExifTool::FLIR::AFF1 = (
+    GROUPS => { 0 => 'FLIR', 1 => 'FLIR', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    0x00 => {
+        # use this tag only to determine the byte order of the raw data
+        # (the value should be 0x0002 if the byte order is correct)
+        Name => 'RawDataByteOrder',
+        Hidden => 1,
+        RawConv => 'ToggleByteOrder() if $val >= 0x0100; undef',
+    },
+    0x01 => { Name => 'SensorWidth',  Format => 'int16u' },
+    0x02 => { Name => 'SensorHeight', Format => 'int16u' },
+);
+
+# AFF record type 5 (ref forum?topic=4898.msg27628)
+%Image::ExifTool::FLIR::AFF5 = (
+    GROUPS => { 0 => 'FLIR', 1 => 'FLIR', 2 => 'Camera' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    0x12 => {
+        # use this tag only to determine the byte order of the raw data
+        # (the value should be 0x0002 if the byte order is correct)
+        Name => 'RawDataByteOrder',
+        Hidden => 1,
+        RawConv => 'ToggleByteOrder() if $val >= 0x0100; undef',
+    },
+    0x13 => { Name => 'SensorWidth',  Format => 'int16u' },
+    0x14 => { Name => 'SensorHeight', Format => 'int16u' },
+);
+
+# FLIR composite tags (ref 1)
+%Image::ExifTool::FLIR::Composite = (
+    GROUPS => { 1 => 'FLIR', 2 => 'Camera' },
+    PeakSpectralSensitivity => {
+        Require => 'FLIR:PlanckB',
+        ValueConv => '14387.6515/$val',
+        PrintConv => 'sprintf("%.1f um", $val)',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::FLIR');
+
+#------------------------------------------------------------------------------
+# Get image type from raw image data
+# Inputs: 0) ExifTool ref, 1) image data, 2) tag name
+# Returns: image type (PNG, JPG, TIFF or undef)
+# - image itself is stored in $$et{$tag}
+sub GetImageType($$$)
+{
+    my ($et, $val, $tag) = @_;
+    my ($w, $h) = @$et{"${tag}Width","${tag}Height"};
+    my $type = 'DAT';
+    # add TIFF header only if this looks like 16-bit raw data
+    # (note: MakeTiffHeader currently works only for little-endian,
+    #  and I haven't seen any big-endian samples, but check anwyay)
+    if ($val =~ /^\x89PNG\r\n\x1a\n/) {
+        $type = 'PNG';
+    } elsif ($val =~ /^\xff\xd8\xff/) { # (haven't seen this, but just in case - PH)
+        $type = 'JPG';
+    } elsif (length $val != $w * $h * 2) {
+        $et->Warn("Unrecognized FLIR $tag data format");
+    } elsif (GetByteOrder() eq 'II') {
+        $val = Image::ExifTool::MakeTiffHeader($w,$h,1,16) . $val;
+        $type = 'TIFF';
+    } else {
+        $et->Warn("Don't yet support big-endian TIFF $tag");
+    }
+    # save image data
+    $$et{$tag} = $val;
+    return $type;
+}
+
+#------------------------------------------------------------------------------
+# Unescape FLIR Unicode character
+# Inputs: 0) escaped character code
+# Returns: UTF8 character
+sub UnescapeFLIR($)
+{
+    my $char = shift;
+    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;
+    return Image::ExifTool::PackUTF8($val);
+}
+
+#------------------------------------------------------------------------------
+# Process FLIR text info record (ref PH)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessFLIRText($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen};
+
+    return 0 if $dirLen < 12;
+
+    $et->VerboseDir('FLIR Text');
+
+    my $dat = substr($$dataPt, $dirStart+12, $dirLen-12);
+    $dat =~ s/\0.*//s; # truncate at null
+
+    # the parameter text contains an additional header entry...
+    if ($tagTablePtr eq \%Image::ExifTool::FLIR::ParamInfo and
+        $dat =~ /# (Generated) at (.*?)[\n\r]/)
+    {
+        $et->HandleTag($tagTablePtr, $1, $2);
+    }
+
+    for (;;) {
+        $dat =~ /.(\d+).(label|value|param) (unicode|text) "(.*)"/g or last;
+        my ($tag, $val) = (ucfirst($2) . $1, $4);
+        if ($3 eq 'unicode' and $val =~ /\\/) {
+            # convert escaped Unicode characters (backslash followed by 4 hex digits)
+            $val =~ s/\\([0-9a-fA-F]{4}|.)/UnescapeFLIR($1)/sge;
+            $et->Decode($val, 'UTF8');
+        }
+        $$tagTablePtr{$tag} or AddTagToTable($tagTablePtr, $tag, { Name => $tag });
+        $et->HandleTag($tagTablePtr, $tag, $val);
+    }
+
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process FLIR measurement tool record (ref 6)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+# (code-driven decoding isn't pretty, but sometimes it is necessary)
+sub ProcessMeasInfo($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dataPos = $$dirInfo{DataPos};
+    my $dirEnd = $dirStart + $$dirInfo{DirLen};
+
+    my $pos = $dirStart + 12;
+    return 0 if $pos > $dirEnd;
+    ToggleByteOrder() if Get16u($dataPt, $dirStart) >= 0x100;
+    my ($i, $t, $p);
+    for ($i=1; ; ++$i) {
+        last if $pos + 2 > $dirEnd;
+        my $recLen = Get16u($dataPt, $pos);
+        last if $recLen < 0x28 or $pos + $recLen > $dirEnd;
+        my $pre = 'Meas' . $i;
+        $et->VerboseDir("MeasInfo $i", undef, $recLen);
+        $et->VerboseDump($dataPt, Len => $recLen, Start=>$pos, DataPos=>$dataPos);
+        my $coordLen = Get16u($dataPt, $pos+4);
+        # generate tag table entries for this tool if necessary
+        foreach $t ('Type', 'Params', 'Label') {
+            my $tag = $pre . $t;
+            last if $$tagTablePtr{$tag};
+            my $tagInfo = { Name => $tag };
+            $$tagInfo{PrintConv} = $$tagTablePtr{"Meas1$t"}{PrintConv};
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        # extract measurement tool type
+        $et->HandleTag($tagTablePtr, "${pre}Type", undef,
+            DataPt=>$dataPt, DataPos=>$dataPos, Start=>$pos+0x0a, Size=>2);
+        last if $pos + 0x24 + $coordLen > $dirEnd;
+        # extract measurement parameters
+        $et->HandleTag($tagTablePtr, "${pre}Params", undef,
+            DataPt=>$dataPt, DataPos=>$dataPos, Start=>$pos+0x24, Size=>$coordLen);
+        my @uni;
+        # extract label (sometimes-null-terminated Unicode)
+        for ($p=0x24+$coordLen; $p<$recLen-1; $p+=2) {
+            my $ch = Get16u($dataPt, $p+$pos);
+            # FLIR Tools v2.0 for Mac doesn't properly null-terminate these strings,
+            # so end the string at any funny character
+            last if $ch < 0x20 or $ch > 0x7f;
+            push @uni, $ch;
+        }
+        # convert to the ExifTool character set
+        require Image::ExifTool::Charset;
+        my $val = Image::ExifTool::Charset::Recompose($et, \@uni);
+        $et->HandleTag($tagTablePtr, "${pre}Label", $val,
+            DataPt=>$dataPt, DataPos=>$dataPos, Start=>$pos+0x24+$coordLen, Size=>2*scalar(@uni));
+        $pos += $recLen;    # step to next record
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process FLIR FFF record (ref PH/1/3)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 if this was a valid FFF record
+sub ProcessFLIR($$;$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $raf = $$dirInfo{RAF} || new File::RandomAccess($$dirInfo{DataPt});
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
+    my ($i, $hdr, $buff, $rec);
+
+    # read and verify FFF header
+    $raf->Read($hdr, 0x40) == 0x40 and $hdr =~ /^([AF]FF)\0/ or return 0;
+
+    my $type = $1;
+
+    # set file type if reading from FFF or SEQ file ($tagTablePtr will not be defined)
+    $et->SetFileType($type eq 'FFF' ? 'FLIR' : 'SEQ') unless $tagTablePtr;
+
+    # FLIR file header (ref 3)
+    # 0x00 - string[4] file format ID = "FFF\0"
+    # 0x04 - string[16] file creator: seen "\0","MTX IR\0","CAMCTRL\0"
+    # 0x14 - int32u file format version = 100
+    # 0x18 - int32u offset to record directory
+    # 0x1c - int32u number of entries in record directory
+    # 0x20 - int32u next free index ID = 2
+    # 0x24 - int16u swap pattern = 0 (?)
+    # 0x28 - int16u[7] spares
+    # 0x34 - int32u[2] reserved
+    # 0x3c - int32u checksum
+
+    # determine byte ordering by validating version number
+    # (in my samples FLIR APP1 is big-endian, FFF files are little-endian)
+    for ($i=0; ; ++$i) {
+        my $ver = Get32u(\$hdr, 0x14);
+        last if $ver >= 100 and $ver < 200; # (have seen 100 and 101 - PH)
+        ToggleByteOrder();
+        $i and $et->Warn("Unsupported FLIR $type version"), return 1;
+    }
+
+    # read the FLIR record directory
+    my $pos = Get32u(\$hdr, 0x18);
+    my $num = Get32u(\$hdr, 0x1c);
+    unless ($raf->Seek($pos) and $raf->Read($buff, $num * 0x20) == $num * 0x20) {
+        $et->Warn('Truncated FLIR FFF directory');
+        return 1;
+    }
+
+    unless ($tagTablePtr) {
+        $tagTablePtr = GetTagTable("Image::ExifTool::FLIR::$type");
+        $$et{SET_GROUP0} = 'FLIR'; # (set group 0 to 'FLIR' for FFF files)
+    }
+
+    # process the header data
+    $et->HandleTag($tagTablePtr, '_header', $hdr);
+
+    my $oldIndent = $$et{INDENT};
+    $$et{INDENT} .= '| ';
+    $et->VerboseDir($type, $num);
+
+    for ($i=0; $i<$num; ++$i) {
+
+        # FLIR record entry (ref 3):
+        # 0x00 - int16u record type
+        # 0x02 - int16u record subtype: RawData 1=BE, 2=LE, 3=PNG; 1 for other record types
+        # 0x04 - int32u record version: seen 0x64,0x66,0x67,0x68,0x6f,0x104
+        # 0x08 - int32u index id = 1
+        # 0x0c - int32u record offset from start of FLIR data
+        # 0x10 - int32u record length
+        # 0x14 - int32u parent = 0 (?)
+        # 0x18 - int32u object number = 0 (?)
+        # 0x1c - int32u checksum: 0 for no checksum
+
+        my $entry = $i * 0x20;
+        my $recType = Get16u(\$buff, $entry);
+        if ($recType == 0) {
+            $verbose and print $out "$$et{INDENT}$i) FLIR Record 0x00 (empty)\n";
+            next;
+        }
+        my $recPos = Get32u(\$buff, $entry + 0x0c);
+        my $recLen = Get32u(\$buff, $entry + 0x10);
+
+        $verbose and printf $out "%s%d) FLIR Record 0x%.2x, offset 0x%.4x, length 0x%.4x\n",
+                                 $$et{INDENT}, $i, $recType, $recPos, $recLen;
+
+        unless ($raf->Seek($recPos) and $raf->Read($rec, $recLen) == $recLen) {
+            $et->Warn('Invalid FLIR record');
+            last;
+        }
+        if ($$tagTablePtr{$recType}) {
+            $et->HandleTag($tagTablePtr, $recType, undef,
+                DataPt  => \$rec,
+                DataPos => $recPos,
+                Start   => 0,
+                Size    => $recLen,
+            );
+        } elsif ($verbose > 2) {
+            $et->VerboseDump(\$rec, Len => $recLen, DataPos => $recPos);
+        }
+    }
+    delete $$et{SET_GROUP0};
+    $$et{INDENT} = $oldIndent;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process FLIR public image format (FPF) file (ref PH/4)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 if this was a valid FFF file
+sub ProcessFPF($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+
+    $raf->Read($buff, 892) == 892 and $buff =~ /^FPF Public Image Format\0/ or return 0;
+
+    # I think these are always little-endian, but check FPFVersion just in case
+    SetByteOrder('II');
+    ToggleByteOrder() unless Get32u(\$buff, 0x20) & 0xffff;
+
+    my $tagTablePtr = GetTagTable('Image::ExifTool::FLIR::FPF');
+    $et->SetFileType();
+    $et->ProcessDirectory( { DataPt => \$buff, Parent => 'FPF' }, $tagTablePtr);
+    return 1;
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::FLIR - Read FLIR 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 FLIR
+Systems Inc. thermal image files (FFF, FPF and JPEG format).
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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://exiftool.org/forum/index.php/topic,4898.0.html>
+
+=item L<http://www.nuage.ch/site/flir-i7-some-analysis/>
+
+=item L<http://www.workswell.cz/manuals/flir/hardware/A3xx_and_A6xx_models/Streaming_format_ThermoVision.pdf>
+
+=item L<http://support.flir.com/DocDownload/Assets/62/English/1557488%24A.pdf>
+
+=item L<http://code.google.com/p/dvelib/source/browse/trunk/flirPublicFormat/fpfConverter/Fpfimg.h?spec=svn3&r=3>
+
+=item L<https://exiftool.org/forum/index.php/topic,5538.0.html>
+
+=back
+
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Tomas for his hard work in decoding much of this information, and
+to Jens Duttke for getting me started on this format.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/FLIR Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Fixup.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Fixup.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Fixup.pm	(revision 34921)
@@ -9,4 +9,5 @@
 #               06/21/2006 - P. Harvey Patch to work with negative offsets
 #               07/07/2006 - P. Harvey Added support for 16-bit pointers
+#               02/19/2013 - P. Harvey Added IsEmpty()
 #
 # Data Members:
@@ -18,4 +19,16 @@
 #               string (with "2" added if pointer is 16-bit [default is 32-bit],
 #               plus "_$marker" suffix if tagged with a marker name).
+#
+# Procedure:
+#
+#            1. Create a Fixup object for each data block containing pointers
+#            2. Call AddFixup with the offset of each pointer in the block
+#               - pointer is assumed int32u with the current byte order
+#               - may also be called with a fixup reference for contained blocks
+#            3. Add the necessary pointer offset to $$fixup{Shift}
+#            4. Add data size to $$fixup{Start} if data is added before the block
+#               - automatically also shifts pointers by this amount
+#            5. Call ApplyFixup to apply the fixup to all pointers
+#               - resets Shift and Start to 0 after applying fixup
 #------------------------------------------------------------------------------
 
@@ -27,5 +40,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.04';
+$VERSION = '1.05';
 
 sub AddFixup($$;$$);
@@ -169,4 +182,22 @@
 
 #------------------------------------------------------------------------------
+# Is this Fixup empty?
+# Inputs: 0) Fixup object ref
+# Returns: True if there are no offsets to fix
+sub IsEmpty($)
+{
+    my $self = shift;
+    my $phash = $self->{Pointers};
+    if ($phash) {
+        my $key;
+        foreach $key (keys %$phash) {
+            next unless ref $$phash{$key} eq 'ARRAY';
+            return 0 if @{$$phash{$key}};
+        }
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
 # Does specified marker exist?
 # Inputs: 0) Fixup object reference, 1) marker name
@@ -304,4 +335,6 @@
     $fixup->Dump();               # dump debugging information
 
+    $fixup->IsEmpty();            # return true if no offsets to fix
+
 =head1 DESCRIPTION
 
@@ -322,5 +355,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Flash.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Flash.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Flash.pm	(revision 34921)
@@ -27,5 +27,5 @@
 use Image::ExifTool::FLAC;
 
-$VERSION = '1.09';
+$VERSION = '1.12';
 
 sub ProcessMeta($$$;$);
@@ -53,5 +53,5 @@
     },
     69 => {
-        Name => 'FileAttributes',
+        Name => 'FlashAttributes',
         PrintConv => { BITMASK => {
             0 => 'UseNetwork',
@@ -290,5 +290,5 @@
 sub ProcessMeta($$$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr, $single) = @_;
+    my ($et, $dirInfo, $tagTablePtr, $single) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos};
@@ -297,5 +297,5 @@
     my ($type, $val, $rec);
 
-    $exifTool->VerboseDir('Meta') unless $single;
+    $et->VerboseDir('Meta') unless $single;
 
 Record: for ($rec=0; ; ++$rec) {
@@ -342,5 +342,5 @@
             $pos += 2 + $len;
         } elsif ($isStruct{$type}) {   # object, mixed array or typed object
-            $exifTool->VPrint(1, "  + [$amfType[$type]]\n");
+            $et->VPrint(1, "  + [$amfType[$type]]\n");
             my $getName;
             $val = '';  # dummy value
@@ -357,5 +357,5 @@
                 my $len = Get16u($dataPt, $pos);
                 if ($pos + 2 + $len > $dirLen) {
-                    $exifTool->Warn("Truncated $amfType[$type] record");
+                    $et->Warn("Truncated $amfType[$type] record");
                     last Record;
                 }
@@ -364,5 +364,5 @@
                 # first string of a typed object is the object name
                 if ($getName) {
-                    $exifTool->VPrint(1,"  | (object name '$tag')\n");
+                    $et->VPrint(1,"  | (object name '${tag}')\n");
                     undef $getName;
                     next; # (ignore name for now)
@@ -386,5 +386,5 @@
                 $tag = $structName . ucfirst($tag) if defined $structName;
                 $$dirInfo{StructName} = $tag;       # set new structure name
-                my ($t, $v) = ProcessMeta($exifTool, $dirInfo, $subTablePtr, 1);
+                my ($t, $v) = ProcessMeta($et, $dirInfo, $subTablePtr, 1);
                 $$dirInfo{StructName} = $structName;# restore original structure name
                 $pos = $$dirInfo{Pos};  # update to new position in packet
@@ -395,8 +395,8 @@
                 last if $t == 0x09; # (end of object)
                 if (not $$subTablePtr{$tag} and $tag =~ /^\w+$/) {
-                    Image::ExifTool::AddTagToTable($subTablePtr, $tag, { Name => ucfirst($tag) });
-                    $exifTool->VPrint(1, "  | (adding $tag)\n");
+                    AddTagToTable($subTablePtr, $tag, { Name => ucfirst($tag) });
+                    $et->VPrint(1, "  | (adding $tag)\n");
                 }
-                $exifTool->HandleTag($subTablePtr, $tag, $v,
+                $et->HandleTag($subTablePtr, $tag, $v,
                     DataPt  => $dataPt,
                     DataPos => $dataPos,
@@ -419,9 +419,9 @@
             $$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;
-                my ($t, $v) = ProcessMeta($exifTool, $dirInfo, $tagTablePtr, 1);
+                my ($t, $v) = ProcessMeta($et, $dirInfo, $tagTablePtr, 1);
                 last Record unless defined $v;
                 # save value unless contained in a sub-structure
@@ -441,5 +441,5 @@
         } else {
             my $t = $amfType[$type] || sprintf('type 0x%x',$type);
-            $exifTool->Warn("AMF $t record not yet supported");
+            $et->Warn("AMF $t record not yet supported");
             undef $type;    # (so we don't print another warning)
             last;           # can't continue
@@ -450,15 +450,15 @@
             if ($type == 0x02 and not $rec) {
                 my $verb = $processMetaPacket{$val} ? 'processing' : 'ignoring';
-                $exifTool->VPrint(0, "  | ($verb $val information)\n");
+                $et->VPrint(0, "  | ($verb $val information)\n");
                 last unless $processMetaPacket{$val};
             } else {
                 # give verbose indication if we ignore a lone value
                 my $t = $amfType[$type] || sprintf('type 0x%x',$type);
-                $exifTool->VPrint(1, "  | (ignored lone $t value '$val')\n");
+                $et->VPrint(1, "  | (ignored lone $t value '${val}')\n");
             }
         }
     }
     if (not defined $val and defined $type) {
-        $exifTool->Warn(sprintf("Truncated AMF record 0x%x",$type));
+        $et->Warn(sprintf("Truncated AMF record 0x%x",$type));
     }
     return 1 unless $single;    # all done
@@ -473,6 +473,6 @@
 sub ProcessFLV($$)
 {
-    my ($exifTool, $dirInfo) = @_;
-    my $verbose = $exifTool->Options('Verbose');
+    my ($et, $dirInfo) = @_;
+    my $verbose = $et->Options('Verbose');
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -481,5 +481,5 @@
     $buff =~ /^FLV\x01/ or return 0;
     SetByteOrder('MM');
-    $exifTool->SetFileType();
+    $et->SetFileType();
     my ($flags, $offset) = unpack('x4CN', $buff);
     $raf->Seek($offset-9, 1) or return 1 if $offset > 9;
@@ -492,8 +492,8 @@
         my $type = $len >> 24;
         $len &= 0x00ffffff;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $type);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $type);
         if ($verbose > 1) {
             my $name = $tagInfo ? $$tagInfo{Name} : "type $type";
-            $exifTool->VPrint(1, "FLV $name packet, len $len\n");
+            $et->VPrint(1, "FLV $name packet, len $len\n");
         }
         undef $buff;
@@ -508,5 +508,5 @@
                         $len -= 1;
                     } else {
-                        $exifTool->Warn("Bad $$tagInfo{Name} packet");
+                        $et->Warn("Bad $$tagInfo{Name} packet");
                         last;
                     }
@@ -515,10 +515,10 @@
                 $len = 0;
             } else {
-                $exifTool->Warn('Truncated Meta packet');
+                $et->Warn('Truncated Meta packet');
                 last;
             }
         }
         if (defined $buff) {
-            $exifTool->HandleTag($tagTablePtr, $type, undef,
+            $et->HandleTag($tagTablePtr, $type, undef,
                 DataPt  => \$buff,
                 DataPos => $raf->Tell() - length($buff),
@@ -536,6 +536,6 @@
 sub FoundFlashTag($$$)
 {
-    my ($exifTool, $tag, $val) = @_;
-    $exifTool->HandleTag(\%Image::ExifTool::Flash::Main, $tag, $val);
+    my ($et, $tag, $val) = @_;
+    $et->HandleTag(\%Image::ExifTool::Flash::Main, $tag, $val);
 }
 
@@ -558,5 +558,5 @@
     if ($inflate) {
         unless (ref $inflate) {
-            unless (eval 'require Compress::Zlib') {
+            unless (eval { require Compress::Zlib }) {
                 $_[3] = 'Install Compress::Zlib to extract compressed information';
                 return 0;
@@ -597,5 +597,5 @@
 sub ProcessSWF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $hasMeta);
@@ -606,14 +606,14 @@
 
     SetByteOrder('II');
-    $exifTool->SetFileType();
+    $et->SetFileType();
     GetTagTable('Image::ExifTool::Flash::Main');  # make sure table is initialized
 
-    FoundFlashTag($exifTool, FlashVersion => $vers);
-    FoundFlashTag($exifTool, Compressed => $compressed);
+    FoundFlashTag($et, FlashVersion => $vers);
+    FoundFlashTag($et, Compressed => $compressed);
 
     # read the next 64 bytes of the file (and inflate if necessary)
     $buff = '';
     unless (ReadCompressed($raf, $buff, 64, $compressed)) {
-        $exifTool->Warn($compressed) if $compressed;
+        $et->Warn($compressed) if $compressed;
         return 1;
     }
@@ -624,5 +624,5 @@
     my $nBytes = int(($totBits + 7) / 8);   # byte length of Rect structure
     if (length $buff < $nBytes + 4) {
-        $exifTool->Warn('Truncated Flash file');
+        $et->Warn('Truncated Flash file');
         return 1;
     }
@@ -634,14 +634,14 @@
 
     # calculate and store ImageWidth/Height
-    FoundFlashTag($exifTool, ImageWidth  => ($vals[1] - $vals[0]) / 20);
-    FoundFlashTag($exifTool, ImageHeight => ($vals[3] - $vals[2]) / 20);
+    FoundFlashTag($et, ImageWidth  => ($vals[1] - $vals[0]) / 20);
+    FoundFlashTag($et, ImageHeight => ($vals[3] - $vals[2]) / 20);
 
     # get frame rate and count
     @vals = unpack("x${nBytes}v2", $buff);
-    FoundFlashTag($exifTool, FrameRate => $vals[0] / 256);
-    FoundFlashTag($exifTool, FrameCount => $vals[1]);
-    FoundFlashTag($exifTool, Duration => $vals[1] * 256 / $vals[0]) if $vals[0];
-
-    # scan through the tags to find FileAttributes and XMP
+    FoundFlashTag($et, FrameRate => $vals[0] / 256);
+    FoundFlashTag($et, FrameCount => $vals[1]);
+    FoundFlashTag($et, Duration => $vals[1] * 256 / $vals[0]) if $vals[0];
+
+    # scan through the tags to find FlashAttributes and XMP
     $buff = substr($buff, $nBytes + 4);
     for (;;) {
@@ -652,5 +652,5 @@
         my $tag = $code >> 6;
         my $size = $code & 0x3f;
-        $exifTool->VPrint(1, "SWF tag $tag ($size bytes):\n");
+        $et->VPrint(1, "SWF tag $tag ($size bytes):\n");
         last unless $tag == 69 or $tag == 77 or $hasMeta;
         # read enough to get a complete short record
@@ -658,5 +658,5 @@
             # (read 2 extra bytes if available to get next tag word)
             unless (ReadCompressed($raf, $buff, $size + 2, $compressed)) {
-                $exifTool->Warn($compressed) if $compressed;
+                $et->Warn($compressed) if $compressed;
                 return 1;
             }
@@ -672,5 +672,5 @@
             if ($pos + $size > $buffLen) {
                 unless (ReadCompressed($raf, $buff, $size + 2, $compressed)) {
-                    $exifTool->Warn($compressed) if $compressed;
+                    $et->Warn($compressed) if $compressed;
                     return 1;
                 }
@@ -678,15 +678,15 @@
                 last if $pos + $size > $buffLen;
             }
-            $exifTool->VPrint(1, "  [extended size $size bytes]\n");
-        }
-        if ($tag == 69) {       # FileAttributes
+            $et->VPrint(1, "  [extended size $size bytes]\n");
+        }
+        if ($tag == 69) {       # FlashAttributes
             last unless $size;
             my $flags = Get8u(\$buff, $pos);
-            FoundFlashTag($exifTool, $tag => $flags);
+            FoundFlashTag($et, $tag => $flags);
             last unless $flags & 0x10;  # only continue if we have metadata (XMP)
             $hasMeta = 1;
         } elsif ($tag == 77) {  # Metadata
             my $val = substr($buff, $pos, $size);
-            FoundFlashTag($exifTool, $tag => $val);
+            FoundFlashTag($et, $tag => $val);
             last;
         }
@@ -722,5 +722,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FlashPix.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FlashPix.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FlashPix.pm	(revision 34921)
@@ -10,4 +10,6 @@
 #               3) http://search.cpan.org/~jdb/libwin32/
 #               4) http://msdn.microsoft.com/en-us/library/aa380374.aspx
+#               5) http://www.cpan.org/modules/by-authors/id/H/HC/HCARVEY/File-MSWord-0.1.zip
+#               6) https://msdn.microsoft.com/en-us/library/cc313153(v=office.12).aspx
 #------------------------------------------------------------------------------
 
@@ -20,5 +22,5 @@
 use Image::ExifTool::ASF;   # for GetGUID()
 
-$VERSION = '1.19';
+$VERSION = '1.38';
 
 sub ProcessFPX($$);
@@ -28,5 +30,10 @@
 sub ProcessHyperlinks($$);
 sub ProcessContents($$$);
+sub ProcessWordDocument($$$);
+sub ProcessDocumentTable($);
+sub ProcessCommentBy($$$);
+sub ProcessLastSavedBy($$$);
 sub SetDocNum($$;$$$);
+sub ConvertDTTM($);
 
 # sector type constants
@@ -80,5 +87,5 @@
     30 => 'VT_LPSTR',   # VT_LPSTR (int32u count, followed by string)
     31 => 'VT_LPWSTR',  # VT_LPWSTR (int32u word count, followed by Unicode string)
-    64 => 'VT_FILETIME',# VT_FILETIME (int64u, number of nanoseconds since Jan 1, 1601)
+    64 => 'VT_FILETIME',# VT_FILETIME (int64u, 100 ns increments since Jan 1, 1601)
     65 => 'VT_BLOB',    # VT_BLOB
 #   66 => 'VT_STREAM',
@@ -119,5 +126,5 @@
 # (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',
@@ -299,5 +306,6 @@
         popular.  However, some of the structures used in FlashPix streams are part
         of the EXIF specification, and are still being used in the APP2 FPXR segment
-        of JPEG images by some Kodak and Hewlett-Packard digital cameras.
+        of JPEG images by some digital cameras from manufacturers such as FujiFilm,
+        Hewlett-Packard, Kodak and Sanyo.
 
         ExifTool extracts FlashPix information from both FPX images and the APP2
@@ -306,5 +314,6 @@
         (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.
@@ -371,5 +380,5 @@
     },
 #   'Subimage 0000 Data'
-    "\x05Data Object" => {  # plus instance number (ie. " 000000")
+    "\x05Data Object" => {  # plus instance number (eg. " 000000")
         Name => 'DataObject',
         SubDirectory => {
@@ -377,6 +386,6 @@
         },
     },
-#   "\x05Data Object Store" => { # plus instance number (ie. " 000000")
-    "\x05Transform" => {    # plus instance number (ie. " 000000")
+#   "\x05Data Object Store" => { # plus instance number (eg. " 000000")
+    "\x05Transform" => {    # plus instance number (eg. " 000000")
         Name => 'Transform',
         SubDirectory => {
@@ -384,5 +393,5 @@
         },
     },
-    "\x05Operation" => {    # plus instance number (ie. " 000000")
+    "\x05Operation" => {    # plus instance number (eg. " 000000")
         Name => 'Operation',
         SubDirectory => {
@@ -396,5 +405,5 @@
         },
     },
-    "\x05Screen Nail" => { # plus class ID (ie. "_bd0100609719a180")
+    "\x05Screen Nail" => { # plus class ID (eg. "_bd0100609719a180")
         Name => 'ScreenNail',
         Groups => { 2 => 'Other' },
@@ -408,5 +417,5 @@
         },
     },
-    'Audio Stream' => { # plus instance number (ie. " 000000")
+    'Audio Stream' => { # plus instance number (eg. " 000000")
         Name => 'AudioStream',
         Groups => { 2 => 'Audio' },
@@ -423,4 +432,38 @@
             return undef if $len < 0 or length $val < $size + 8;
             return substr($val, 8 + $pos, $len);
+        },
+    },
+    'WordDocument' => {
+        Name => 'WordDocument',
+        SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::WordDocument' },
+    },
+    # save these tables until after the WordDocument was processed
+    '0Table' => {
+        Name => 'Table0',
+        Hidden => 1, # (used only as temporary storage until table is processed)
+        Binary => 1,
+    },
+    '1Table' => {
+        Name => 'Table1',
+        Hidden => 1, # (used only as temporary storage until table is processed)
+        Binary => 1,
+    },
+    Preview => {
+        Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
+        Binary => 1,
+        Notes => 'written by some FujiFilm models',
+        # skip 47-byte Fuji header
+        RawConv => q{
+            return undef unless length $val > 47;
+            $val = substr($val, 47);
+            return $val =~ /^\xff\xd8\xff/ ? $val : undef;
+        },
+    },
+    Property => {
+        Name => 'PreviewInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::PreviewInfo',
+            ByteOrder => 'BigEndian',
         },
     },
@@ -464,5 +507,9 @@
     0x0f => 'Words',
     0x10 => 'Characters',
-    0x11 => { Name => 'ThumbnailClip',  Binary => 1 },
+    0x11 => {
+        Name => 'ThumbnailClip',
+        # (not a displayable format, so not in the "Preview" group)
+        Binary => 1,
+    },
     0x12 => {
         Name => 'Software',
@@ -474,10 +521,15 @@
         PrintConv => {
             0 => 'None',
-            1 => 'Password protected',
-            2 => 'Read-only recommended',
-            4 => 'Read-only enforced',
-            8 => 'Locked for annotations',
-        },
-    },
+            BITMASK => {
+                0 => 'Password protected',
+                1 => 'Read-only recommended',
+                2 => 'Read-only enforced',
+                3 => 'Locked for annotations',
+            },
+        },
+    },
+    0x22 => { Name => 'CreatedBy', Groups => { 2 => 'Author' } }, #PH (guess) (MAX files)
+    0x23 => 'DocumentID', # PH (guess) (MAX files)
+  # 0x25 ? seen values 1.0-1.97 (MAX files)
     0x80000000 => { Name => 'LocaleIndicator', Groups => { 2 => 'Other' } },
 );
@@ -507,5 +559,12 @@
     },
     0x0c => 'HeadingPairs',
-    0x0d => 'TitleOfParts',
+    0x0d => {
+        Name => 'TitleOfParts',
+        # look for "3ds Max" software name at beginning of TitleOfParts
+        RawConv => q{
+            (ref $val eq 'ARRAY' ? $$val[0] : $val) =~ /^(3ds Max)/ and $$self{Software} = $1;
+            return $val;
+        }
+    },
     0x0e => 'Manager',
     0x0f => 'Company',
@@ -515,19 +574,30 @@
     },
     0x11 => 'CharCountWithSpaces',
-  # 0x12 ?
+  # 0x12 ? seen -32.1850395202637,-386.220672607422,-9.8100004196167,-9810,...
     0x13 => { #PH (unconfirmed)
         Name => 'SharedDoc',
         PrintConv => { 0 => 'No', 1 => 'Yes' },
     },
-  # 0x14 ?
-  # 0x15 ?
+  # 0x14 ? seen -1
+  # 0x15 ? seen 1
     0x16 => {
         Name => 'HyperlinksChanged',
         PrintConv => { 0 => 'No', 1 => 'Yes' },
     },
-    0x17 => { #PH (unconfirmed handling of lower 16 bits)
+    0x17 => { #PH (unconfirmed handling of lower 16 bits, not valid for MAX files)
         Name => 'AppVersion',
         ValueConv => 'sprintf("%d.%.4d",$val >> 16, $val & 0xffff)',
     },
+  # 0x18 ? seen -1
+  # 0x19 ? seen 0
+  # 0x1a ? seen 0
+  # 0x1b ? seen 0
+  # 0x1c ? seen 0,1
+  # 0x1d ? seen 1
+  # 0x1e ? seen 1
+  # 0x1f ? seen 1,5
+  # 0x20 ? seen 0,5
+  # 0x21 ? seen -1
+  # 0x22 ? seen 0
    '_PID_LINKBASE' => {
         Name => 'HyperlinkBase',
@@ -985,8 +1055,239 @@
 );
 
+# decode Word document FIB header (ref [MS-DOC].pdf)
+%Image::ExifTool::FlashPix::WordDocument = (
+    PROCESS_PROC => \&ProcessWordDocument,
+    GROUPS => { 2 => 'Other' },
+    FORMAT => 'int16u',
+    NOTES => 'Tags extracted from the Microsoft Word document stream.',
+    0 => {
+        Name => 'Identification',
+        PrintHex => 1,
+        PrintConv => {
+            0x6a62 => 'MS Word 97',
+            0x626a => 'Word 98 Mac',
+            0xa5dc => 'Word 6.0/7.0',
+            0xa5ec => 'Word 8.0',
+        },
+    },
+    3 => {
+        Name => 'LanguageCode',
+        PrintHex => 1,
+        PrintConv => {
+            0x0400 => 'None',
+            0x0401 => 'Arabic',
+            0x0402 => 'Bulgarian',
+            0x0403 => 'Catalan',
+            0x0404 => 'Traditional Chinese',
+            0x0804 => 'Simplified Chinese',
+            0x0405 => 'Czech',
+            0x0406 => 'Danish',
+            0x0407 => 'German',
+            0x0807 => 'German (Swiss)',
+            0x0408 => 'Greek',
+            0x0409 => 'English (US)',
+            0x0809 => 'English (British)',
+            0x0c09 => 'English (Australian)',
+            0x040a => 'Spanish (Castilian)',
+            0x080a => 'Spanish (Mexican)',
+            0x040b => 'Finnish',
+            0x040c => 'French',
+            0x080c => 'French (Belgian)',
+            0x0c0c => 'French (Canadian)',
+            0x100c => 'French (Swiss)',
+            0x040d => 'Hebrew',
+            0x040e => 'Hungarian',
+            0x040f => 'Icelandic',
+            0x0410 => 'Italian',
+            0x0810 => 'Italian (Swiss)',
+            0x0411 => 'Japanese',
+            0x0412 => 'Korean',
+            0x0413 => 'Dutch',
+            0x0813 => 'Dutch (Belgian)',
+            0x0414 => 'Norwegian (Bokmal)',
+            0x0814 => 'Norwegian (Nynorsk)',
+            0x0415 => 'Polish',
+            0x0416 => 'Portuguese (Brazilian)',
+            0x0816 => 'Portuguese',
+            0x0417 => 'Rhaeto-Romanic',
+            0x0418 => 'Romanian',
+            0x0419 => 'Russian',
+            0x041a => 'Croato-Serbian (Latin)',
+            0x081a => 'Serbo-Croatian (Cyrillic)',
+            0x041b => 'Slovak',
+            0x041c => 'Albanian',
+            0x041d => 'Swedish',
+            0x041e => 'Thai',
+            0x041f => 'Turkish',
+            0x0420 => 'Urdu',
+            0x0421 => 'Bahasa',
+            0x0422 => 'Ukrainian',
+            0x0423 => 'Byelorussian',
+            0x0424 => 'Slovenian',
+            0x0425 => 'Estonian',
+            0x0426 => 'Latvian',
+            0x0427 => 'Lithuanian',
+            0x0429 => 'Farsi',
+            0x042d => 'Basque',
+            0x042f => 'Macedonian',
+            0x0436 => 'Afrikaans',
+            0x043e => 'Malaysian',
+        },
+    },
+    5 => {
+        Name => 'DocFlags',
+        Mask => 0xff0f, # ignore save count
+        RawConv => '$$self{DocFlags} = $val',
+        PrintConv => { BITMASK => {
+            0 => 'Template',
+            1 => 'AutoText only',
+            2 => 'Complex',
+            3 => 'Has picture',
+            # 4-7 = number of incremental saves
+            8 => 'Encrypted',
+            9 => '1Table',
+            10 => 'Read only',
+            11 => 'Passworded',
+            12 => 'ExtChar',
+            13 => 'Load override',
+            14 => 'Far east',
+            15 => 'Obfuscated',
+        }},
+    },
+    9.1 => {
+        Name => 'System',
+        Mask => 0x0001,
+        PrintConv => {
+            0x0000 => 'Windows',
+            0x0001 => 'Macintosh',
+        },
+    },
+    9.2 => {
+        Name => 'Word97',
+        Mask => 0x0010,
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+);
+
+# tags decoded from Word document table
+%Image::ExifTool::FlashPix::DocTable = (
+    GROUPS => { 1 => 'MS-DOC', 2 => 'Document' },
+    NOTES => 'Tags extracted from the Microsoft Word document table.',
+    VARS => { NO_ID => 1 },
+    CommentBy => {
+        Groups => { 2 => 'Author' },
+        Notes => 'enable L<Duplicates|../ExifTool.html#Duplicates> option to extract all entries',
+    },
+    LastSavedBy => {
+        Groups => { 2 => 'Author' },
+        Notes => 'enable L<Duplicates|../ExifTool.html#Duplicates> option to extract history of up to 10 entries',
+    },
+    DOP => { SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::DOP' } },
+    ModifyDate => {
+        Groups => { 2 => 'Time' },
+        Format => 'int64u',
+        Priority => 0,
+        RawConv => q{
+            $val = $val * 1e-7 - 11644473600;   # convert to seconds since 1970
+            return $val > 0 ? $val : undef;
+        },
+        ValueConv => 'ConvertUnixTime($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+#
+# tags below are used internally in intermediate steps to extract the tags above
+#
+    TableOffsets => { Hidden => 1 }, # stores offsets to extract data from document table
+    CommentByBlock => {   # entire block of CommentBy entries
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::DocTable',
+            ProcessProc => \&ProcessCommentBy,
+        },
+        Hidden => 1,
+    },
+    LastSavedByBlock => {   # entire block of LastSavedBy entries
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FlashPix::DocTable',
+            ProcessProc => \&ProcessLastSavedBy,
+        },
+        Hidden => 1,
+    },
+);
+
+# Microsoft Office Document Properties (ref [MS-DOC].pdf)
+%Image::ExifTool::FlashPix::DOP = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 1 => 'MS-DOC', 2 => 'Document' },
+    NOTES => 'Microsoft office document properties.',
+    20 => {
+        Name => 'CreateDate',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        Priority => 0,
+        RawConv => \&ConvertDTTM,
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    24 => {
+        Name => 'ModifyDate',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        Priority => 0,
+        RawConv => \&ConvertDTTM,
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    28 => {
+        Name => 'LastPrinted',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        RawConv => \&ConvertDTTM,
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    32 => { Name => 'RevisionNumber', Format => 'int16u' },
+    34 => {
+        Name => 'TotalEditTime',
+        Format => 'int32u',
+        PrintConv => 'ConvertTimeSpan($val,60)',
+    },
+    # (according to the MS-DOC specification, the following are accurate only if
+    # flag 'X' is set, and flag 'u' specifies whether the main or subdoc tags are
+    # used, but in my tests it seems that both are filled in with reasonable values,
+    # so just extract the main counts and ignore the subdoc counts for now - PH)
+    38 => { Name => 'Words',      Format => 'int32u' },
+    42 => { Name => 'Characters', Format => 'int32u' },
+    46 => { Name => 'Pages',      Format => 'int16u' },
+    48 => { Name => 'Paragraphs', Format => 'int32u' },
+    56 => { Name => 'Lines',      Format => 'int32u' },
+    #60 => { Name => 'WordsWithSubdocs',      Format => 'int32u' },
+    #64 => { Name => 'CharactersWithSubdocs', Format => 'int32u' },
+    #68 => { Name => 'PagesWithSubdocs',      Format => 'int16u' },
+    #70 => { Name => 'ParagraphsWithSubdocs', Format => 'int32u' },
+    #74 => { Name => 'LinesWithSubdocs',      Format => 'int32u' },
+);
+
+# FujiFilm "Property" information (ref PH)
+%Image::ExifTool::FlashPix::PreviewInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'Preview information written by some FujiFilm models.',
+    FIRST_ENTRY => 0,
+    # values are all constant for for my samples except the two decoded tags
+    # 0x0000: 01 01 00 00 02 01 00 00 00 00 00 00 00 xx xx 01
+    # 0x0010: 01 00 00 00 00 00 00 xx xx 00 00 00 00 00 00 00
+    # 0x0020: 00 00 00 00 00
+    0x0d => {
+        Name => 'PreviewImageWidth',
+        Format => 'int16u',
+    },
+    0x17 => {
+        Name => 'PreviewImageHeight',
+        Format => 'int16u',
+    },
+);
+
 # composite FlashPix tags
 %Image::ExifTool::FlashPix::Composite = (
     GROUPS => { 2 => 'Image' },
     PreviewImage => {
+        Groups => { 2 => 'Preview' },
         # extract JPEG preview from ScreenNail if possible
         Require => {
@@ -996,4 +1297,5 @@
         RawConv => q{
             return undef unless $val[0] =~ /\xff\xd8\xff/g;
+            @grps = $self->GetGroup($$val{0});  # set groups from ScreenNail
             return substr($val[0], pos($val[0])-3);
         },
@@ -1003,4 +1305,20 @@
 # add our composite tags
 Image::ExifTool::AddCompositeTags('Image::ExifTool::FlashPix');
+
+#------------------------------------------------------------------------------
+# Convert Microsoft DTTM structure to date/time
+# Inputs: 0) DTTM value
+# Returns: EXIF-format date/time string ("0000:00:00 00:00:00" for zero date/time)
+sub ConvertDTTM($)
+{
+    my $val = shift;
+    my $yr  = ($val >> 20) & 0x1ff;
+    my $mon = ($val >> 16) & 0x0f;
+    my $day = ($val >> 11) & 0x1f;
+    my $hr  = ($val >> 6)  & 0x1f;
+    my $min = ($val & 0x3f);
+    $yr += 1900 if $val;
+    return sprintf("%.4d:%.2d:%.2d %.2d:%.2d:00%s",$yr,$mon,$day,$hr,$min,$val ? 'Z' : '');
+}
 
 #------------------------------------------------------------------------------
@@ -1011,5 +1329,5 @@
 sub ProcessHyperlinks($$)
 {
-    my ($val, $exifTool) = @_;
+    my ($val, $et) = @_;
 
     # process as an array of VT_VARIANT's
@@ -1021,5 +1339,5 @@
     for ($i=0; $i<$num; ++$i) {
         # read VT_BLOB entries as an array of VT_VARIANT's
-        my $value = ReadFPXValue($exifTool, \$val, $valPos, VT_VARIANT, $dirEnd);
+        my $value = ReadFPXValue($et, \$val, $valPos, VT_VARIANT, $dirEnd);
         last unless defined $value;
         push @vals, $value;
@@ -1042,5 +1360,5 @@
 sub ReadFPXValue($$$$$;$$)
 {
-    my ($exifTool, $dataPt, $valPos, $type, $dirEnd, $noPad, $codePage) = @_;
+    my ($et, $dataPt, $valPos, $type, $dirEnd, $noPad, $codePage) = @_;
     my @vals;
 
@@ -1078,15 +1396,30 @@
                 my $subType = Get32u($dataPt, $valPos);
                 $valPos += $size;
-                $val = ReadFPXValue($exifTool, $dataPt, $valPos, $subType, $dirEnd, $noPad, $codePage);
+                $val = ReadFPXValue($et, $dataPt, $valPos, $subType, $dirEnd, $noPad, $codePage);
                 last unless defined $val;
                 push @vals, $val;
                 next;   # avoid adding $size to $valPos again
             } elsif ($format eq 'VT_FILETIME') {
-                # get time in seconds
+                # convert from time in 100 ns increments to time in seconds
                 $val = 1e-7 * Image::ExifTool::Get64u($dataPt, $valPos);
                 # print as date/time if value is greater than one year (PH hack)
-                if ($val > 365 * 24 * 3600) {
+                my $secDay = 24 * 3600;
+                if ($val > 365 * $secDay) {
                     # shift from Jan 1, 1601 to Jan 1, 1970
-                    $val -= 134774 * 24 * 3600 if $val != 0;
+                    my $unixTimeZero = 134774 * $secDay;
+                    $val -= $unixTimeZero;
+                    # there are a lot of bad programmers out there...
+                    my $sec100yr = 100 * 365 * $secDay;
+                    if ($val < 0 || $val > $sec100yr) {
+                        # some software writes the wrong byte order (but the proper word order)
+                        my @w = unpack("x${valPos}NN", $$dataPt);
+                        my $v2 = ($w[0] + $w[1] * 4294967296) * 1e-7 - $unixTimeZero;
+                        if ($v2 > 0 && $v2 < $sec100yr) {
+                            $val = $v2;
+                        # also check for wrong time base
+                        } elsif ($val < 0 && $val + $unixTimeZero > 0) {
+                            $val += $unixTimeZero;
+                        }
+                    }
                     $val = Image::ExifTool::ConvertUnixTime($val);
                 }
@@ -1103,11 +1436,11 @@
                 if ($format eq 'VT_LPWSTR') {
                     # convert wide string from Unicode
-                    $val = $exifTool->Decode($val, 'UCS2');
+                    $val = $et->Decode($val, 'UCS2');
                 } elsif ($codePage) {
                     my $charset = $Image::ExifTool::charsetName{"cp$codePage"};
                     if ($charset) {
-                        $val = $exifTool->Decode($val, $charset);
-                    } elsif ($codePage eq 1200) {   # UTF-16, little endian
-                        $val = $exifTool->Decode(undef, 'UCS2', 'II');
+                        $val = $et->Decode($val, $charset);
+                    } elsif ($codePage == 1200) {   # UTF-16, little endian
+                        $val = $et->Decode($val, 'UCS2', 'II');
                     }
                 }
@@ -1131,5 +1464,5 @@
         }
         # join VT_ values with commas unless we want an array
-        @vals = ( join $exifTool->Options('ListSep'), @vals ) if @vals > 1 and not wantarray;
+        @vals = ( join $et->Options('ListSep'), @vals ) if @vals > 1 and not wantarray;
         last;   # didn't really want to loop
     }
@@ -1153,15 +1486,15 @@
 sub ProcessContents($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $isFLA;
 
-    # all of my FLA samples contain "Contents" data, an no other FPX-like samples have
+    # all of my FLA samples contain "Contents" data, and no other FPX-like samples have
     # this, but check the data for a familiar pattern to be sure this is FLA: the
     # Contents of all of my FLA samples start with two bytes (0x29,0x38,0x3f,0x43 or 0x47,
     # then 0x01) followed by a number of zero bytes (from 0x18 to 0x26 of them, related
     # somehow to the value of the first byte), followed by the string "DocumentPage"
-    $isFLA = 1 if $$dataPt =~ /^..\0+\xff\xff\x01\0\x0d\0CDocumentPage/;
-    
+    $isFLA = 1 if $$dataPt =~ /^..\0+\xff\xff\x01\0\x0d\0CDocumentPage/s;
+
     # do a brute-force scan of the "Contents" for UTF-16 XMP
     # (this may always be little-endian, but allow for either endianness)
@@ -1170,11 +1503,189 @@
         if ($$dataPt =~ /<\0\?\0x\0p\0a\0c\0k\0e\0t\0 \0e\0n\0d\0=\0['"]\0[wr]\0['"]\0\?\0>\0?/g) {
             $$dirInfo{DirLen} = pos($$dataPt) - $$dirInfo{DirStart};
-            Image::ExifTool::XMP::ProcessXMP($exifTool, $dirInfo, $tagTablePtr);
+            Image::ExifTool::XMP::ProcessXMP($et, $dirInfo, $tagTablePtr);
             # override format if not already FLA but XMP-dc:Format indicates it is
-            $isFLA = 1 if $$exifTool{FILE_TYPE} ne 'FLA' and $$exifTool{VALUE}{Format} and
-                          $$exifTool{VALUE}{Format} eq 'application/vnd.adobe.fla';
-        }
-    }
-    $exifTool->OverrideFileType('FLA') if $isFLA;
+            $isFLA = 1 if $$et{FILE_TYPE} ne 'FLA' and $$et{VALUE}{Format} and
+                          $$et{VALUE}{Format} eq 'application/vnd.adobe.fla';
+        }
+    }
+    $et->OverrideFileType('FLA') if $isFLA;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process WordDocument stream of MSWord doc file (ref 6)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessWordDocument($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt} or return 0;
+    my $dirLen = length $$dataPt;
+    # validate the FIB signature
+    unless ($dirLen > 2 and Get16u($dataPt,0) == 0xa5ec) {
+        $et->WarnOnce('Invalid FIB signature', 1);
+        return 0;
+    }
+    $et->ProcessBinaryData($dirInfo, $tagTablePtr); # process FIB
+    # continue parsing the WordDocument stream until we find the FibRgFcLcb
+    my $pos = 32;
+    return 0 if $pos + 2 > $dirLen;
+    my $n = Get16u($dataPt, $pos);  # read csw
+    $pos += 2 + $n * 2;             # skip fibRgW
+    return 0 if $pos + 2 > $dirLen;
+    $n = Get16u($dataPt, $pos);     # read cslw
+    $pos += 2 + $n * 4;             # skip fibRgLw
+    return 0 if $pos + 2 > $dirLen;
+    $n = Get16u($dataPt, $pos);     # read cbRgFcLcb
+    $pos += 2;  # point to start of fibRgFcLcbBlob
+    return 0 if $pos + $n * 8 > $dirLen;
+    my ($off, @tableOffsets);
+    # save necessary entries for later processing of document table
+    # (DOP, CommentBy, LastSavedBy)
+    foreach $off (0xf8, 0x120, 0x238) {
+        last if $off + 8 > $n * 8;
+        push @tableOffsets, Get32u($dataPt, $pos + $off);
+        push @tableOffsets, Get32u($dataPt, $pos + $off + 4);
+    }
+    my $tbl = GetTagTable('Image::ExifTool::FlashPix::DocTable');
+    # extract ModifyDate if it exists
+    $et->HandleTag($tbl, 'ModifyDate', undef,
+        DataPt => $dataPt,
+        Start  => $pos + 0x2b8,
+        Size   => 8,
+    );
+    $et->HandleTag($tbl, TableOffsets => \@tableOffsets);   # save for later
+    # $pos += $n * 8;                 # skip fibRgFcLcbBlob
+    # return 0 if $pos + 2 > $dirLen;
+    # $n = Get16u($dataPt, $pos);     # read cswNew
+    # return 0 if $pos + 2 + $n * 2 > $dirLen;
+    # my $nFib = Get16u($dataPt, 2 + ($n ? $pos : 0));
+    # $pos += 2 + $n * 2;             # skip fibRgCswNew
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Microsoft Word Document Table
+# Inputs: 0) ExifTool object ref
+sub ProcessDocumentTable($)
+{
+    my $et = shift;
+    my $value = $$et{VALUE};
+    my $extra = $$et{TAG_EXTRA};
+    my ($i, $j, $tag);
+    # loop through TableOffsets for each sub-document
+    for ($i=0; ; ++$i) {
+        my $key = 'TableOffsets' . ($i ? " ($i)" : '');
+        my $offsets = $$value{$key};
+        last unless defined $offsets;
+        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;
+            $tmp = $$extra{$key}{G3} if $$extra{$key};
+            $tmp = '' unless $tmp;
+            if ($tmp eq $doc) {
+                $docFlags = $$value{$key};
+                last;
+            }
+        }
+        next unless defined $docFlags;
+        $tag = $docFlags & 0x200 ? 'Table1' : 'Table0';
+        # get table for this sub-document
+        for ($j=0; ; ++$j) {
+            my $key = $tag . ($j ? " ($j)" : '');
+            last unless defined $$value{$key};
+            my $tmp;
+            $tmp = $$extra{$key}{G3} if $$extra{$key};
+            $tmp = '' unless $tmp;
+            if ($tmp eq $doc) {
+                $docTable = \$$value{$key};
+                last;
+            }
+        }
+        next unless defined $docTable;
+        # extract DOP and LastSavedBy information from document table
+        $$et{DOC_NUM} = $doc;   # use same document number
+        my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::DocTable');
+        foreach $tag (qw(DOP CommentByBlock LastSavedByBlock)) {
+            last unless @$offsets;
+            my $off = shift @$offsets;
+            my $len = shift @$offsets;
+            next unless $len and $off + $len <= length $$docTable;
+            $et->HandleTag($tagTablePtr, $tag, undef,
+                DataPt => $docTable,
+                Start  => $off,
+                Size   => $len,
+            );
+        }
+        delete $$et{DOC_NUM};
+    }
+    # delete intermediate tags
+    foreach $tag (qw(TableOffsets Table0 Table1)) {
+        for ($i=0; ; ++$i) {
+            my $key = $tag . ($i ? " ($i)" : '');
+            last unless defined $$value{$key};
+            $et->DeleteTag($key);
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Extract names of comment authors (ref 6)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessCommentBy($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    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);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract last-saved-by names (ref 5)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessLastSavedBy($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $pos = $$dirInfo{DirStart};
+    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;
+    }
     return 1;
 }
@@ -1200,19 +1711,19 @@
 sub ProcessProperties($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart} || 0;
     my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $pos;
     my $dirEnd = $pos + $dirLen;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $n;
 
     if ($dirLen < 48) {
-        $exifTool->Warn('Truncated FPX properties');
+        $et->Warn('Truncated FPX properties');
         return 0;
     }
     # check and set our byte order if necessary
     unless (CheckBOM($dataPt, $pos)) {
-        $exifTool->Warn('Bad FPX property byte order mark');
+        $et->Warn('Bad FPX property byte order mark');
         return 0;
     }
@@ -1220,5 +1731,5 @@
     $pos = Get32u($dataPt, $pos + 44);
     if ($pos < 48) {
-        $exifTool->Warn('Bad FPX property section offset');
+        $et->Warn('Bad FPX property section offset');
         return 0;
     }
@@ -1231,7 +1742,7 @@
         last unless $size;
         my $numEntries = Get32u($dataPt, $pos + 4);
-        $verbose and $exifTool->VerboseDir('Property Info', $numEntries, $size);
+        $verbose and $et->VerboseDir('Property Info', $numEntries, $size);
         if ($pos + 8 + 8 * $numEntries > $dirEnd) {
-            $exifTool->Warn('Truncated property list');
+            $et->Warn('Truncated property list');
             last;
         }
@@ -1263,6 +1774,6 @@
                     $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
                     next unless length $name;
-                    $exifTool->VPrint(0, "$$exifTool{INDENT}\[adding $name]\n") if $verbose;
-                    Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
+                    $et->VPrint(0, "$$et{INDENT}\[adding $name]\n") if $verbose;
+                    AddTagToTable($tagTablePtr, $tag, { Name => $name });
                 }
                 next;
@@ -1274,6 +1785,6 @@
                 $custom = 1;
             }
-            my @vals = ReadFPXValue($exifTool, $dataPt, $valPos, $type, $dirEnd, undef, $codePage);
-            @vals or $exifTool->Warn('Error reading property value');
+            my @vals = ReadFPXValue($et, $dataPt, $valPos, $type, $dirEnd, undef, $codePage);
+            @vals or $et->Warn('Error reading property value');
             $val = @vals > 1 ? \@vals : $vals[0];
             my $format = $type & 0x0fff;
@@ -1287,5 +1798,5 @@
                 # get tagInfo from SummaryInfo table
                 my $summaryTable = GetTagTable('Image::ExifTool::FlashPix::SummaryInfo');
-                $tagInfo = $exifTool->GetTagInfo($summaryTable, $tag);
+                $tagInfo = $et->GetTagInfo($summaryTable, $tag);
                 if ($tag == 1) {
                     $val += 0x10000 if $val < 0; # (may be incorrectly stored as int16s)
@@ -1293,5 +1804,5 @@
                 }
             } elsif ($$tagTablePtr{$tag}) {
-                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
             } elsif ($$tagTablePtr{VARS} and not $custom) {
                 # mask off insignificant bits of tag ID if necessary
@@ -1300,10 +1811,10 @@
                 foreach $mask (keys %$masked) {
                     if ($masked->{$mask}->{$tag & $mask}) {
-                        $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag & $mask);
+                        $tagInfo = $et->GetTagInfo($tagTablePtr, $tag & $mask);
                         last;
                     }
                 }
             }
-            $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            $et->HandleTag($tagTablePtr, $tag, $val,
                 DataPt  => $dataPt,
                 Start   => $valStart,
@@ -1316,5 +1827,5 @@
         }
         # issue warning if we hit end of property section prematurely
-        $exifTool->Warn('Truncated property data') if $index < $numEntries;
+        $et->Warn('Truncated property data') if $index < $numEntries;
         last unless $$dirInfo{Multi};
         $pos += $size;
@@ -1355,12 +1866,12 @@
 sub ProcessFPXR($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
     my $dirLen = $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     if ($dirLen < 13) {
-        $exifTool->Warn('FPXR segment to small');
+        $et->Warn('FPXR segment too small');
         return 0;
     }
@@ -1371,17 +1882,17 @@
     if ($type == 1) {   # a "Contents List" segment
 
-        $vers != 0 and $exifTool->Warn("Untested FPXR version $vers");
-        if ($$exifTool{FPXR}) {
-            $exifTool->Warn('Multiple FPXR contents lists');
-            delete $$exifTool{FPXR};
+        $vers != 0 and $et->Warn("Untested FPXR version $vers");
+        if ($$et{FPXR}) {
+            $et->Warn('Multiple FPXR contents lists');
+            delete $$et{FPXR};
         }
         my $numEntries = unpack('x7n', $$dataPt);
         my @contents;
-        $verbose and $exifTool->VerboseDir('Contents List', $numEntries);
+        $verbose and $et->VerboseDir('Contents List', $numEntries);
         my $pos = 9;
         my $entry;
         for ($entry = 0; $entry < $numEntries; ++$entry) {
             if ($pos + 4 > $dirLen) {
-                $exifTool->Warn('Truncated FPXR contents');
+                $et->Warn('Truncated FPXR contents');
                 return 0;
             }
@@ -1392,5 +1903,5 @@
             # and the first char must be '/'
             unless ($$dataPt =~ m{\G(/\0(..)*?)\0\0}sg) {
-                $exifTool->Warn('Invalid FPXR stream name');
+                $et->Warn('Invalid FPXR stream name');
                 return 0;
             }
@@ -1399,5 +1910,5 @@
             if ($verbose) {
                 my $psize = ($size == 0xffffffff) ? 'storage' : "$size bytes";
-                $exifTool->VPrint(0,"  |  $entry) Name: '$name' [$psize]\n");
+                $et->VPrint(0,"  |  $entry) Name: '${name}' [$psize]\n");
             }
             # remove directory specification
@@ -1407,9 +1918,17 @@
             if ($size == 0xffffffff) {
                 unless ($$dataPt =~ m{(.{16})}sg) {
-                    $exifTool->Warn('Truncated FPXR storage class ID');
+                    $et->Warn('Truncated FPXR storage class ID');
                     return 0;
                 }
                 # unpack class ID in case we want to use it sometime
                 $classID = Image::ExifTool::ASF::GetGUID($1);
+            }
+            # find the tagInfo if available
+            my $tagInfo;
+            unless ($$tagTablePtr{$name}) {
+                # remove instance number or class ID from tag if necessary
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $1) if
+                    ($name =~ /(.*) \d{6}$/s and $$tagTablePtr{$1}) or
+                    ($name =~ /(.*)_[0-9a-f]{16}$/s and $$tagTablePtr{$1});
             }
             # update position in list
@@ -1421,9 +1940,10 @@
                 Default => $default,
                 ClassID => $classID,
+                TagInfo => $tagInfo,
             };
         }
-        # save contents list as $exifTool member variable
+        # save contents list as $et member variable
         # (must do this last so we don't save list on error)
-        $$exifTool{FPXR} = \@contents;
+        $$et{FPXR} = \@contents;
 
     } elsif ($type == 2) {  # a "Stream Data" segment
@@ -1431,5 +1951,5 @@
         # get the contents list index and stream data offset
         my ($index, $offset) = unpack('x7nN', $$dataPt);
-        my $fpxr = $$exifTool{FPXR};
+        my $fpxr = $$et{FPXR};
         if ($fpxr and $$fpxr[$index]) {
             my $obj = $$fpxr[$index];
@@ -1440,66 +1960,47 @@
                 $$obj{Stream} = substr($$dataPt, $dirStart+13);
             } else {
-                # add data to the stream at the proper offset
-                my $pad = $offset - length($$obj{Stream});
-                if ($pad >= 0) {
-                    if ($pad) {
-                        if ($pad > 0x10000) {
-                            $exifTool->Warn("Bad FPXR stream offset ($offset)");
-                        } else {
-                            # pad with default value to specified offset
-                            $exifTool->Warn("Padding FPXR stream with $pad default bytes",1);
-                            $$obj{Stream} .= ($$obj{Default} x $pad);
-                        }
-                    }
-                    # concatenate data with this stream
-                    $$obj{Stream} .= substr($$dataPt, $dirStart+13);
+                # add data at the proper offset to the stream
+                my $overlap = length($$obj{Stream}) - $offset;
+                my $start = $dirStart + 13;
+                if ($overlap < 0 or $dirLen - $overlap < 13) {
+                    $et->WarnOnce("Bad FPXR stream $index offset",1);
                 } else {
-                    $exifTool->Warn("Duplicate FPXR stream data at offset $offset");
-                    substr($$obj{Stream}, $offset, -$pad) = substr($$dataPt, $dirStart+13);
+                    # ignore any overlapping data in this segment
+                    # (this seems to be the convention)
+                    $start += $overlap;
                 }
+                # concatenate data with this stream
+                $$obj{Stream} .= substr($$dataPt, $start);
             }
             # save value for this tag if stream is complete
             my $len = length $$obj{Stream};
             if ($len >= $$obj{Size}) {
-                if ($verbose) {
-                    $exifTool->VPrint(0, "  + [FPXR stream, Contents index $index, $len bytes]\n");
-                }
+                $et->VPrint(0, "  + [FPXR stream $index, $len bytes]\n") if $verbose;
                 if ($len > $$obj{Size}) {
-                    $exifTool->Warn('Extra data in FPXR segment (truncated)');
+                    $et->Warn('Extra data in FPXR segment (truncated)');
                     $$obj{Stream} = substr($$obj{Stream}, 0, $$obj{Size});
                 }
-                my $tag = $$obj{Name};
-                my $tagInfo;
-                unless ($$tagTablePtr{$tag}) {
-                    # remove instance number or class ID from tag if necessary
-                    $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $1) if
-                        ($tag =~ /(.*) \d{6}$/s and $$tagTablePtr{$1}) or
-                        ($tag =~ /(.*)_[0-9a-f]{16}$/s and $$tagTablePtr{$1});
-                }
-                # save the data for this tag
-                $exifTool->HandleTag($tagTablePtr, $tag, $$obj{Stream},
+                # handle this tag
+                $et->HandleTag($tagTablePtr, $$obj{Name}, $$obj{Stream},
                     DataPt => \$$obj{Stream},
-                    TagInfo => $tagInfo,
+                    TagInfo => $$obj{TagInfo},
                 );
                 delete $$obj{Stream}; # done with this stream
             }
         # hack for improperly stored FujiFilm PreviewImage (stored with no contents list)
-        } elsif ($index == 512 and $dirLen > 60 and ($$exifTool{FujiPreview} or
+        } elsif ($index == 512 and $dirLen > 60 and ($$et{FujiPreview} or
             ($dirLen > 64 and substr($$dataPt, $dirStart+60, 4) eq "\xff\xd8\xff\xdb")))
         {
-            # recombine PreviewImage, skipping unknown 60 byte header
-            if ($$exifTool{FujiPreview}) {
-                $$exifTool{FujiPreview} .= substr($$dataPt, $dirStart+60);
-            } else {
-                $$exifTool{FujiPreview} = substr($$dataPt, $dirStart+60);
-            }
+            $$et{FujiPreview} = '' unless defined $$et{FujiPreview};
+            # recombine PreviewImage, skipping 13-byte FPXR header + 47-byte Fuji header
+            $$et{FujiPreview} .= substr($$dataPt, $dirStart+60);
         } else {
             # (Kodak uses index 255 for a free segment in images from some cameras)
-            $exifTool->Warn("Unlisted FPXR segment (index $index)") if $index != 255;
-        }
-
-    } elsif ($type ne 3) {  # not a "Reserved" segment
-
-        $exifTool->Warn("Unknown FPXR segment (type $type)");
+            $et->Warn("Unlisted FPXR segment (index $index)") if $index != 255;
+        }
+
+    } elsif ($type != 3) {  # not a "Reserved" segment
+
+        $et->Warn("Unknown FPXR segment (type $type)");
 
     }
@@ -1507,16 +2008,19 @@
     # clean up if this was the last FPXR segment
     if ($$dirInfo{LastFPXR}) {
-        if ($$exifTool{FPXR}) {
+        if ($$et{FPXR}) {
             my $obj;
-            my $i = 0;
-            foreach $obj (@{$$exifTool{FPXR}}) {
-                $exifTool->Warn("Missing stream for FPXR object $i") if defined $$obj{Stream};
-                ++$i;
+            foreach $obj (@{$$et{FPXR}}) {
+                next unless defined $$obj{Stream} and length $$obj{Stream};
+                # parse it even though it isn't the proper length
+                $et->HandleTag($tagTablePtr, $$obj{Name}, $$obj{Stream},
+                    DataPt => \$$obj{Stream},
+                    TagInfo => $$obj{TagInfo},
+                );
             }
-            delete $$exifTool{FPXR};    # delete our temporary variables
-        }
-        if ($$exifTool{FujiPreview}) {
-            $exifTool->FoundTag('PreviewImage', $$exifTool{FujiPreview});
-            delete $$exifTool{FujiPreview};
+            delete $$et{FPXR};    # delete our temporary variables
+        }
+        if ($$et{FujiPreview}) {
+            $et->FoundTag('PreviewImage', $$et{FujiPreview});
+            delete $$et{FujiPreview};
         }
     }
@@ -1549,5 +2053,5 @@
             $subDoc[-1] = ++$$used[$#subDoc];
         }
-        SetDocNum($hier, $$obj{Child}, \@subDoc, $used, not $meta) 
+        SetDocNum($hier, $$obj{Child}, \@subDoc, $used, not $meta);
     }
 }
@@ -1559,8 +2063,8 @@
 sub ProcessFPX($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my ($buff, $out, %dumpParms, $oldIndent, $miniStreamBuff);
-    my ($tag, %hier, %objIndex);
+    my ($buff, $out, $oldIndent, $miniStreamBuff);
+    my ($tag, %hier, %objIndex, %loadedDifSect);
 
     # read header
@@ -1570,12 +2074,12 @@
 
     # set FileType initially based on file extension (we may override this later)
-    my $fileType = $exifTool->{FILE_EXT};
+    my $fileType = $$et{FILE_EXT};
     $fileType = 'FPX' unless $fileType and $fpxFileType{$fileType};
-    $exifTool->SetFileType($fileType);
+    $et->SetFileType($fileType);
     SetByteOrder(substr($buff, 0x1c, 2) eq "\xff\xfe" ? 'MM' : 'II');
     my $tagTablePtr = GetTagTable('Image::ExifTool::FlashPix::Main');
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     # copy LargeFileSupport option to RAF for use in LoadChain
-    $$raf{LargeFileSupport} = $exifTool->Options('LargeFileSupport');
+    $$raf{LargeFileSupport} = $et->Options('LargeFileSupport');
 
     my $sectSize = 1 << Get16u(\$buff, 0x1e);
@@ -1590,7 +2094,5 @@
 
     if ($verbose) {
-        $out = $exifTool->Options('TextOut');
-        $dumpParms{Out} = $out;
-        $dumpParms{MaxLen} = 96 if $verbose == 3;
+        $out = $et->Options('TextOut');
         print $out "  Sector size=$sectSize\n  FAT: Count=$fatCount\n";
         print $out "  DIR: Start=$dirStart\n";
@@ -1605,4 +2107,7 @@
     my $fat = '';
     my $fatCountCheck = 0;
+    my $difCountCheck = 0;
+    my $hdrSize = $sectSize > HDR_SIZE ? $sectSize : HDR_SIZE;
+
     for (;;) {
         while ($pos <= $endPos - 4) {
@@ -1610,10 +2115,10 @@
             $pos += 4;
             next if $sect == FREE_SECT;
-            my $offset = $sect * $sectSize + HDR_SIZE;
+            my $offset = $sect * $sectSize + $hdrSize;
             my $fatSect;
             unless ($raf->Seek($offset, 0) and
                     $raf->Read($fatSect, $sectSize) == $sectSize)
             {
-                $exifTool->Error("Error reading FAT from sector $sect");
+                $et->Error("Error reading FAT from sector $sect");
                 return 1;
             }
@@ -1623,9 +2128,18 @@
         last if $difStart >= END_OF_CHAIN;
         # read next DIF (Dual Indirect FAT) sector
-        my $offset = $difStart * $sectSize + HDR_SIZE;
+        if (++$difCountCheck > $difCount) {
+            $et->Warn('Unterminated DIF FAT');
+            last;
+        }
+        if ($loadedDifSect{$difStart}) {
+            $et->Warn('Cyclical reference in DIF FAT');
+            last;
+        }
+        my $offset = $difStart * $sectSize + $hdrSize;
         unless ($raf->Seek($offset, 0) and $raf->Read($buff, $sectSize) == $sectSize) {
-            $exifTool->Error("Error reading DIF sector $difStart");
+            $et->Error("Error reading DIF sector $difStart");
             return 1;
         }
+        $loadedDifSect{$difStart} = 1;
         # set end of sector information in this DIF
         $pos = 0;
@@ -1635,22 +2149,22 @@
     }
     if ($fatCountCheck != $fatCount) {
-        $exifTool->Warn("Bad number of FAT sectors (expected $fatCount but found $fatCountCheck)");
+        $et->Warn("Bad number of FAT sectors (expected $fatCount but found $fatCountCheck)");
     }
 #
 # load the mini-FAT and the directory
 #
-    my $miniFat = LoadChain($raf, $miniStart, \$fat, $sectSize, HDR_SIZE);
-    my $dir = LoadChain($raf, $dirStart, \$fat, $sectSize, HDR_SIZE);
+    my $miniFat = LoadChain($raf, $miniStart, \$fat, $sectSize, $hdrSize);
+    my $dir = LoadChain($raf, $dirStart, \$fat, $sectSize, $hdrSize);
     unless (defined $miniFat and defined $dir) {
-        $exifTool->Error('Error reading mini-FAT or directory stream');
+        $et->Error('Error reading mini-FAT or directory stream');
         return 1;
     }
     if ($verbose) {
         print $out "  FAT [",length($fat)," bytes]:\n";
-        Image::ExifTool::HexDump(\$fat, undef, %dumpParms) if $verbose > 2;
+        $et->VerboseDump(\$fat);
         print $out "  Mini-FAT [",length($miniFat)," bytes]:\n";
-        Image::ExifTool::HexDump(\$miniFat, undef, %dumpParms) if $verbose > 2;
+        $et->VerboseDump(\$miniFat);
         print $out "  Directory [",length($dir)," bytes]:\n";
-        Image::ExifTool::HexDump(\$dir, undef, %dumpParms) if $verbose > 2;
+        $et->VerboseDump(\$dir);
     }
 #
@@ -1658,7 +2172,7 @@
 #
     if ($verbose) {
-        $oldIndent = $exifTool->{INDENT};
-        $exifTool->{INDENT} .= '| ';
-        $exifTool->VerboseDir('FPX', undef, length $dir);
+        $oldIndent = $$et{INDENT};
+        $$et{INDENT} .= '| ';
+        $et->VerboseDir('FPX', undef, length $dir);
     }
     my $miniStream;
@@ -1673,5 +2187,5 @@
         next if $type == 0; # skip invalid entries
         if ($type > 5) {
-            $exifTool->Warn("Invalid directory entry type $type");
+            $et->Warn("Invalid directory entry type $type");
             last;   # rest of directory is probably garbage
         }
@@ -1689,7 +2203,7 @@
         # load Ministream (referenced from first directory entry)
         unless ($miniStream) {
-            $miniStreamBuff = LoadChain($raf, $sect, \$fat, $sectSize, HDR_SIZE);
+            $miniStreamBuff = LoadChain($raf, $sect, \$fat, $sectSize, $hdrSize);
             unless (defined $miniStreamBuff) {
-                $exifTool->Warn('Error loading Mini-FAT stream');
+                $et->Warn('Error loading Mini-FAT stream');
                 last;
             }
@@ -1699,8 +2213,8 @@
         my $tagInfo;
         if ($$tagTablePtr{$tag}) {
-            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         } else {
             # remove instance number or class ID from tag if necessary
-            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $1) if
+            $tagInfo = $et->GetTagInfo($tagTablePtr, $1) if
                 ($tag =~ /(.*) \d{6}$/s and $$tagTablePtr{$1}) or
                 ($tag =~ /(.*)_[0-9a-f]{16}$/s and $$tagTablePtr{$1});
@@ -1711,5 +2225,5 @@
         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} = { };
@@ -1730,5 +2244,5 @@
             if ($size >= $miniCutoff) {
                 # stream is in the main FAT
-                $buff = LoadChain($raf, $sect, \$fat, $sectSize, HDR_SIZE);
+                $buff = LoadChain($raf, $sect, \$fat, $sectSize, $hdrSize);
             } elsif ($size) {
                 # stream is in the mini-FAT
@@ -1739,5 +2253,5 @@
             unless (defined $buff) {
                 my $name = $tagInfo ? $$tagInfo{Name} : 'unknown';
-                $exifTool->Warn("Error reading $name stream");
+                $et->Warn("Error reading $name stream");
                 $buff = '';
             }
@@ -1756,5 +2270,5 @@
             $extra .= " Right=$rSib" unless $rSib == FREE_SECT;
             $extra .= " Child=$chld" unless $chld == FREE_SECT;
-            $exifTool->VerboseInfo($tag, $tagInfo,
+            $et->VerboseInfo($tag, $tagInfo,
                 Index  => $index,
                 Value  => $buff,
@@ -1765,5 +2279,5 @@
         }
         if ($tagInfo and $buff) {
-            my $num = $$exifTool{NUM_FOUND};
+            my $num = $$et{NUM_FOUND};
             my $subdir = $$tagInfo{SubDirectory};
             if ($subdir) {
@@ -1775,19 +2289,19 @@
                 );
                 my $subTablePtr = GetTagTable($$subdir{TagTable});
-                $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr,  $$subdir{ProcessProc});
+                $et->ProcessDirectory(\%dirInfo, $subTablePtr,  $$subdir{ProcessProc});
             } else {
-                $exifTool->FoundTag($tagInfo, $buff);
+                $et->FoundTag($tagInfo, $buff);
             }
             # save object index number for all found tags
-            my $num2 = $$exifTool{NUM_FOUND};
+            my $num2 = $$et{NUM_FOUND};
             $objIndex{++$num} = $index while $num < $num2;
         }
     }
     # set document numbers for tags extracted from embedded documents
-    unless ($$exifTool{DOC_NUM}) {
+    unless ($$et{DOC_NUM}) {
         # initialize document number for all objects, beginning at root (index 0)
         SetDocNum(\%hier, 0);
         # set family 3 group name for all tags in embedded documents
-        my $order = $$exifTool{FILE_ORDER};
+        my $order = $$et{FILE_ORDER};
         my (@pri, $copy, $member);
         foreach $tag (keys %$order) {
@@ -1797,5 +2311,5 @@
             my $docNums = $$obj{DocNum};
             next unless $docNums and @$docNums;
-            $$exifTool{TAG_EXTRA}{$tag}{G3} = join '-', @$docNums;
+            $$et{TAG_EXTRA}{$tag}{G3} = join '-', @$docNums;
             push @pri, $tag unless $tag =~ / /; # save keys for priority sub-doc tags
         }
@@ -1804,9 +2318,9 @@
             for ($copy=1; ;++$copy) {
                 my $key = "$tag ($copy)";
-                last unless defined $$exifTool{VALUE}{$key};
-                my $extra = $$exifTool{TAG_EXTRA}{$key};
+                last unless defined $$et{VALUE}{$key};
+                my $extra = $$et{TAG_EXTRA}{$key};
                 next if $extra and $$extra{G3}; # not Main if family 3 group is set
                 foreach $member ('PRIORITY','VALUE','FILE_ORDER','TAG_INFO','TAG_EXTRA') {
-                    my $pHash = $$exifTool{$member};
+                    my $pHash = $$et{$member};
                     my $t = $$pHash{$tag};
                     $$pHash{$tag} = $$pHash{$key};
@@ -1817,18 +2331,21 @@
         }
     }
-    $exifTool->{INDENT} = $oldIndent if $verbose;
+    $$et{INDENT} = $oldIndent if $verbose;
     # try to better identify the file type
-    if ($$exifTool{VALUE}{FileType} eq 'FPX') {
-        my $val = $$exifTool{CompObjUserType} || $$exifTool{Software};
+    if ($$et{VALUE}{FileType} eq 'FPX') {
+        my $val = $$et{CompObjUserType} || $$et{Software};
         if ($val) {
-            my %type = ( Word => 'DOC', PowerPoint => 'PPT', Excel => 'XLS' );
+            my %type = ( '^3ds Max' => 'MAX', Word => 'DOC', PowerPoint => 'PPT', Excel => 'XLS' );
             my $pat;
             foreach $pat (sort keys %type) {
                 next unless $val =~ /$pat/;
-                $exifTool->OverrideFileType($type{$pat});
+                $et->OverrideFileType($type{$pat});
                 last;
             }
         }
     }
+    # process Word document table
+    ProcessDocumentTable($et);
+
     return 1;
 }
@@ -1854,5 +2371,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Font.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Font.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Font.pm	(revision 34921)
@@ -20,5 +20,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.05';
+$VERSION = '1.10';
 
 sub ProcessOTF($$);
@@ -81,5 +81,5 @@
   # 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
@@ -89,5 +89,5 @@
     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',
@@ -95,12 +95,12 @@
     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',
@@ -118,5 +118,5 @@
   #  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',
@@ -216,6 +216,6 @@
         The following tags are extracted from the TrueType font "name" table found
         in OTF, TTF, TTC and DFONT files.  These tags support localized languages by
-        adding a hyphen followed by a language code to the end of the tag name (ie.
-        "Copyright-fr" or "Licence-en-US").  Tags with no language code use the
+        adding a hyphen followed by a language code to the end of the tag name (eg.
+        "Copyright-fr" or "License-en-US").  Tags with no language code use the
         default language of "en".
     },
@@ -336,5 +336,5 @@
 sub ProcessTTC($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $i);
@@ -346,17 +346,18 @@
     # might as well put a limit on the number of fonts we will parse (< 256)
     return 0 unless $num < 0x100 and $raf->Read($buff, $num * 4) == $num * 4;
-    $exifTool->SetFileType('TTC');
+    $et->SetFileType('TTC');
+    return 1 if $$et{OPTIONS}{FastScan} and $$et{OPTIONS}{FastScan} == 3;
     my $tagTablePtr = GetTagTable('Image::ExifTool::Font::Main');
-    $exifTool->HandleTag($tagTablePtr, 'numfonts', $num);
+    $et->HandleTag($tagTablePtr, 'numfonts', $num);
     # loop through all fonts in the collection
     for ($i=0; $i<$num; ++$i) {
         my $n = $i + 1;
-        $exifTool->VPrint(0, "Font $n:\n");
-        $$exifTool{SET_GROUP1} = "+$n";
+        $et->VPrint(0, "Font $n:\n");
+        $$et{SET_GROUP1} = "+$n";
         my $offset = Get32u(\$buff, $i * 4);
         $raf->Seek($offset, 0) or last;
-        ProcessOTF($exifTool, $dirInfo) or last;
+        ProcessOTF($et, $dirInfo) or last;
     }
-    delete $$exifTool{SET_GROUP1};
+    delete $$et{SET_GROUP1};
     return 1;
 }
@@ -368,5 +369,5 @@
 sub ProcessOTF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($tbl, $buff, $pos, $i);
@@ -374,7 +375,8 @@
 
     return 0 unless $raf->Read($buff, 12) == 12;
-    return 0 unless $buff =~ /^(\0\x01\0\0|OTTO|true|typ1)[\0\x01]/;
-
-    $exifTool->SetFileType($1 eq 'OTTO' ? 'OTF' : 'TTF');
+    return 0 unless $buff =~ /^(\0\x01\0\0|OTTO|true|typ1|\xa5(kbd|lst))[\0\x01]/;
+
+    $et->SetFileType($1 eq 'OTTO' ? 'OTF' : 'TTF');
+    return 1 if $$et{OPTIONS}{FastScan} and $$et{OPTIONS}{FastScan} == 3;
     SetByteOrder('MM');
     my $numTables = Get16u(\$buff, 4);
@@ -383,8 +385,8 @@
     return 0 unless $raf->Read($tbl, $len) == $len;
 
-    my $verbose = $exifTool->Options('Verbose');
-    my $oldIndent = $$exifTool{INDENT};
-    $$exifTool{INDENT} .= '| ';
-    $exifTool->VerboseDir('TrueType', $numTables) if $verbose;
+    my $verbose = $et->Options('Verbose');
+    my $oldIndent = $$et{INDENT};
+    $$et{INDENT} .= '| ';
+    $et->VerboseDir('TrueType', $numTables) if $verbose;
 
     for ($pos=0; $pos<$len; $pos+=16) {
@@ -395,5 +397,5 @@
         my $size   = Get32u(\$tbl, $pos + 12);
         unless ($raf->Seek($offset+$base, 0) and $raf->Read($buff, $size) == $size) {
-            $exifTool->Warn("Error reading '$tag' data");
+            $et->Warn("Error reading '${tag}' data");
             next;
         }
@@ -401,7 +403,7 @@
             $tag =~ s/([\0-\x1f\x80-\xff])/sprintf('\x%.2x',ord $1)/ge;
             my $str = sprintf("%s%d) Tag '%s' (offset 0x%.4x, %d bytes)\n",
-                              $$exifTool{INDENT}, $pos/16, $tag, $offset, $size);
-            $exifTool->VPrint(0, $str);
-            $exifTool->VerboseDump(\$buff, Addr => $offset) if $verbose > 2;
+                              $$et{INDENT}, $pos/16, $tag, $offset, $size);
+            $et->VPrint(0, $str);
+            $et->VerboseDump(\$buff, Addr => $offset) if $verbose > 2;
             next unless $tag eq 'name';
         }
@@ -410,10 +412,10 @@
         my $recEnd = 6 + $entries * 12;
         if ($recEnd > $size) {
-            $exifTool->Warn('Truncated name record');
+            $et->Warn('Truncated name record');
             last;
         }
         my $strStart = Get16u(\$buff, 4);
         if ($strStart < $recEnd or $strStart > $size) {
-            $exifTool->Warn('Invalid string offset');
+            $et->Warn('Invalid string offset');
             last;
         }
@@ -431,5 +433,5 @@
                     last if $langPt + $langLen > $size;
                     my $lang = substr($buff, $langPt, $langLen);
-                    $lang = $exifTool->Decode($lang,'UCS2','MM','UTF8');
+                    $lang = $et->Decode($lang,'UCS2','MM','UTF8');
                     $lang =~ tr/-_a-zA-Z0-9//dc;    # remove naughty characters
                     $langTag{$i + 0x8000} = $lang;
@@ -438,6 +440,6 @@
         }
         my $tagTablePtr = GetTagTable('Image::ExifTool::Font::Name');
-        $$exifTool{INDENT} .= '| ';
-        $exifTool->VerboseDir('Name', $entries) if $verbose;
+        $$et{INDENT} .= '| ';
+        $et->VerboseDir('Name', $entries) if $verbose;
         for ($i=0; $i<$entries; ++$i) {
             my $pt = 6 + $i * 12;
@@ -457,17 +459,17 @@
                     $charset = $ttCharset{$sys}{$encoding};
                     if (not $charset) {
-                        if (not defined $charset and not $$exifTool{FontWarn}) {
-                            $exifTool->Warn("Unknown $sys character set ($encoding)");
-                            $$exifTool{FontWarn} = 1;
+                        if (not defined $charset and not $$et{FontWarn}) {
+                            $et->Warn("Unknown $sys character set ($encoding)");
+                            $$et{FontWarn} = 1;
                         }
                     } else {
                         # translate to ExifTool character set
-                        $val = $exifTool->Decode($val, $charset);
+                        $val = $et->Decode($val, $charset);
                     }
                 } else {
-                    $exifTool->Warn("Unknown platform ($platform) for name $nameID");
+                    $et->Warn("Unknown platform ($platform) for name $nameID");
                 }
                 # get the tagInfo for our specific language (use 'en' for default)
-                my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $nameID);
+                my $tagInfo = $et->GetTagInfo($tagTablePtr, $nameID);
                 if ($tagInfo and $lang and $lang ne 'en') {
                     my $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang);
@@ -475,10 +477,10 @@
                 }
                 if ($verbose) {
-                	$langID > 0x400 and $langID = sprintf('0x%x', $langID);
+                    $langID > 0x400 and $langID = sprintf('0x%x', $langID);
                     $extra = ", Plat=$platform/" . ($sys || 'Unknown') . ', ' .
                                "Enc=$encoding/" . ($charset || 'Unknown') . ', ' .
                                "Lang=$langID/" . ($lang || 'Unknown');
                 }
-                $exifTool->HandleTag($tagTablePtr, $nameID, $val,
+                $et->HandleTag($tagTablePtr, $nameID, $val,
                     TagInfo => $tagInfo,
                     DataPt  => \$buff,
@@ -491,8 +493,8 @@
             }
         }
-        $$exifTool{INDENT} = $oldIndent . '| ';
+        $$et{INDENT} = $oldIndent . '| ';
         last unless $verbose;
     }
-    $$exifTool{INDENT} = $oldIndent;
+    $$et{INDENT} = $oldIndent;
     return 1;
 }
@@ -504,5 +506,5 @@
 sub ProcessAFM($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $comment);
@@ -513,5 +515,6 @@
     return 0 unless $buff =~ /^Start(Comp|Master)?FontMetrics\s+\d+/;
     my $ftyp = $1 ? ($1 eq 'Comp' ? 'ACFM' : 'AMFM') : 'AFM';
-    $exifTool->SetFileType($ftyp, 'application/x-font-afm');
+    $et->SetFileType($ftyp, 'application/x-font-afm');
+    return 1 if $$et{OPTIONS}{FastScan} and $$et{OPTIONS}{FastScan} == 3;
     my $tagTablePtr = GetTagTable('Image::ExifTool::Font::AFM');
 
@@ -519,5 +522,5 @@
         $raf->ReadLine($buff) or last;
         if (defined $comment and $buff !~ /^Comment\s/) {
-            $exifTool->FoundTag('Comment', $comment);
+            $et->FoundTag('Comment', $comment);
             undef $comment;
         }
@@ -533,5 +536,5 @@
             next;
         }
-        unless ($exifTool->HandleTag($tagTablePtr, $tag, $val)) {
+        unless ($et->HandleTag($tagTablePtr, $tag, $val)) {
             # end parsing if we start any subsection
             last if $tag =~ /^Start/ and $tag ne 'StartDirection';
@@ -547,18 +550,18 @@
 sub ProcessFont($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $buf2, $rtnVal);
     return 0 unless $raf->Read($buff, 24) and $raf->Seek(0,0);
     if ($buff =~ /^(\0\x01\0\0|OTTO|true|typ1)[\0\x01]/) {        # OTF, TTF
-        $rtnVal = ProcessOTF($exifTool, $dirInfo);
+        $rtnVal = ProcessOTF($et, $dirInfo);
     } elsif ($buff =~ /^ttcf\0[\x01\x02]\0\0/) {                  # TTC
-        $rtnVal = ProcessTTC($exifTool, $dirInfo);
+        $rtnVal = ProcessTTC($et, $dirInfo);
     } elsif ($buff =~ /^Start(Comp|Master)?FontMetrics\s+\d+/s) { # AFM
-        $rtnVal = ProcessAFM($exifTool, $dirInfo);
+        $rtnVal = ProcessAFM($et, $dirInfo);
     } elsif ($buff =~ /^(.{6})?%!(PS-(AdobeFont-|Bitstream )|FontType1-)/s) {# PFA, PFB
-        $raf->Seek(6,0) and $exifTool->SetFileType('PFB') if $1;
+        $raf->Seek(6,0) and $et->SetFileType('PFB') if $1;
         require Image::ExifTool::PostScript;
-        $rtnVal = Image::ExifTool::PostScript::ProcessPS($exifTool, $dirInfo);
+        $rtnVal = Image::ExifTool::PostScript::ProcessPS($et, $dirInfo);
     } elsif ($buff =~ /^\0[\x01\x02]/ and $raf->Seek(0, 2) and    # PFM
              # validate file size
@@ -572,9 +575,10 @@
              $raf->Read($buf2, 11) == 11 and lc($buf2) eq "postscript\0")
     {
-        $exifTool->SetFileType('PFM');
+        $et->SetFileType('PFM');
+        return 1 if $$et{OPTIONS}{FastScan} and $$et{OPTIONS}{FastScan} == 3;
         SetByteOrder('II');
         my $tagTablePtr = GetTagTable('Image::ExifTool::Font::Main');
         # process the PFM header
-        $exifTool->HandleTag($tagTablePtr, 'PFM', $buff);
+        $et->HandleTag($tagTablePtr, 'PFM', $buff);
         # extract the font names
         my $nameOff = Get32u(\$buff, 105);
@@ -582,7 +586,12 @@
             $buff =~ /^([\x20-\xff]+)\0([\x20-\xff]+)\0/)
         {
-            $exifTool->HandleTag($tagTablePtr, 'fontname', $1);
-            $exifTool->HandleTag($tagTablePtr, 'postfont', $2);
-        }
+            $et->HandleTag($tagTablePtr, 'fontname', $1);
+            $et->HandleTag($tagTablePtr, 'postfont', $2);
+        }
+        $rtnVal = 1;
+    } elsif ($buff =~ /^(wOF[F2])/) {
+        my $type = $1 eq 'wOFF' ? 'woff' : 'woff2';
+        $et->SetFileType(uc($type), "font/$type");
+        # (don't yet extract metadata from these files)
         $rtnVal = 1;
     } else {
@@ -608,9 +617,11 @@
 This module contains the routines required by Image::ExifTool to read meta
 information from various format font files.  Currently recognized font file
-types are OTF, TTF, TTC, DFONT, PFA, PFB, PFM, AFM, ACFM and AMFM.
+types are OTF, TTF, TTC, DFONT, PFA, PFB, PFM, AFM, ACFM and AMFM.  As well,
+WOFF and WOFF2 font files are identified, but metadata is not currently
+extracted from these formats.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FotoStation.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FotoStation.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FotoStation.pm	(revision 34921)
@@ -13,5 +13,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.00';
+$VERSION = '1.04';
 
 sub ProcessFotoStation($$);
@@ -39,4 +39,5 @@
     0x03 => {
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
         Writable => 1,
         RawConv => '$self->ValidateImage(\$val,$tag)',
@@ -44,4 +45,5 @@
     0x04 => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         Writable => 1,
         RawConv => '$self->ValidateImage(\$val,$tag)',
@@ -119,12 +121,12 @@
 sub ProcessFotoStation($$)
 {
-    my ($exifTool, $dirInfo) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
     my ($buff, $footer, $dirBuff, $tagTablePtr);
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
     my $offset = $$dirInfo{Offset} || 0;
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     my $rtnVal = 0;
 
@@ -152,6 +154,6 @@
         unless ($outfile) {
             # print verbose trailer information
-            if ($verbose or $exifTool->{HTML_DUMP}) {
-                $exifTool->DumpTrailer({
+            if ($verbose or $$et{HTML_DUMP}) {
+                $et->DumpTrailer({
                     RAF => $raf,
                     DataPos => $$dirInfo{DataPos},
@@ -161,19 +163,20 @@
             }
             # extract information for this tag
-            $exifTool->HandleTag($tagTablePtr, $tag, $buff,
-                                 DataPt => \$buff,
-                                 Start => 0,
-                                 Size => $size,
-                                 DataPos => $$dirInfo{DataPos});
+            $et->HandleTag($tagTablePtr, $tag, $buff,
+                DataPt => \$buff,
+                Start => 0,
+                Size => $size,
+                DataPos => $$dirInfo{DataPos},
+            );
             next;
         }
-        if ($exifTool->{DEL_GROUP}->{FotoStation}) {
-            $verbose and printf $out "  Deleting FotoStation trailer\n";
+        if ($$et{DEL_GROUP}{FotoStation}) {
+            $verbose and print $out "  Deleting FotoStation trailer\n";
             $verbose = 0;   # no more verbose messages after this
-            ++$exifTool->{CHANGED};
+            ++$$et{CHANGED};
             next;
         }
         # rewrite this information
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($tagInfo) {
             my $newVal;
@@ -189,9 +192,9 @@
                 );
                 my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
-                $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                $newVal = $et->WriteDirectory(\%subdirInfo, $subTable);
             } else {
-                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-                if (Image::ExifTool::IsOverwriting($nvHash) > 0) {
-                    $newVal = Image::ExifTool::GetNewValues($nvHash);
+                my $nvHash = $et->GetNewValueHash($tagInfo);
+                if ($et->IsOverwriting($nvHash) > 0) {
+                    $newVal = $et->GetNewValue($nvHash);
                     $newVal = '' unless defined $newVal;
                     if ($verbose > 1) {
@@ -200,5 +203,5 @@
                         print $out "    + FotoStation:$tagName ($n bytes)\n" if $n;
                     }
-                    ++$exifTool->{CHANGED};
+                    ++$$et{CHANGED};
                 }
             }
@@ -241,5 +244,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FujiFilm.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FujiFilm.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/FujiFilm.pm	(revision 34921)
@@ -5,5 +5,5 @@
 #
 # 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
@@ -14,4 +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) https://exiftool.org/forum/index.php/topic,5223.0.html
+#               9) Zilvinas Brobliauskas private communication
+#               10) Albert Shan private communication
+#               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
 #------------------------------------------------------------------------------
@@ -24,5 +32,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.31';
+$VERSION = '1.79';
 
 sub ProcessFujiDir($$$);
@@ -30,21 +38,34 @@
 
 # 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, S5600, S6000fd, S6500fd, HS10/HS11, S200EXR, X100 (all Ver1.00)',
-    '0102' => 'S100FS Ver1.02',
+    '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',
+    '0102' => 'S100FS, X10 Ver1.02',
+    '0103' => 'IS Pro Ver1.03',
     '0104' => 'S5Pro Ver1.04',
     '0106' => 'S5Pro Ver1.06',
     '0111' => 'S5Pro Ver1.11',
     '0114' => 'S9600 Ver1.00',
+    '0132' => 'X-T2 Ver1.32',
+    '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',
-    '0264' => 'F700  Ver2.00',
+    '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',
+   # 0400  - expect to see this for X-T1
+    '0540' => 'X-T1 Ver5.40',
     '0712' => 'S5000 Ver3.00',
-    '0716' => 'S5000 Ver3.00', # (yes, 2 RAF versions with the same firmware version)
+    '0716' => 'S5000 Ver3.00', # (yes, 2 RAF versions with the same Software version)
+    '0Dgi' => 'X-A10 Ver1.01 and X-A3 Ver1.02', # (yes, non-digits in the firmware number)
 );
 
@@ -68,20 +89,32 @@
         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
-        },
-        # ie)  "FPX20017035 592D31313034060427796060110384"
+            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";
-        },
-        PrintConvInv => '$_=$val; s/ (19|20)(\d{2}):(\d{2}):(\d{2}) /$2$3$4/; $_',
+            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;
+        },
+        # (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 => {
@@ -94,11 +127,13 @@
         Writable => 'int16u',
         PrintConv => {
-            0x01 => 'Soft',
-            0x02 => 'Soft2',
-            0x03 => 'Normal',
-            0x04 => 'Hard',
-            0x05 => 'Hard2',
-            0x82 => 'Medium Soft', #2
-            0x84 => 'Medium Hard', #2
+            0x00 => '-4 (softest)', #10
+            0x01 => '-3 (very soft)',
+            0x02 => '-2 (soft)',
+            0x03 => '0 (normal)',
+            0x04 => '+2 (hard)',
+            0x05 => '+3 (very hard)',
+            0x06 => '+4 (hardest)',
+            0x82 => '-1 (medium soft)', #2
+            0x84 => '+1 (medium hard)', #2
             0x8000 => 'Film Simulation', #2
             0xffff => 'n/a', #2
@@ -111,4 +146,6 @@
         PrintConv => {
             0x0   => 'Auto',
+            0x1   => 'Auto (white priority)', #forum10890
+            0x2   => 'Auto (ambiance priority)', #forum10890
             0x100 => 'Daylight',
             0x200 => 'Cloudy',
@@ -120,4 +157,5 @@
             0x400 => 'Incandescent',
             0x500 => 'Flash', #4
+            0x600 => 'Underwater', #forum6109
             0xf00 => 'Custom',
             0xf01 => 'Custom2', #2
@@ -134,14 +172,23 @@
         Writable => 'int16u',
         PrintConv => {
-            0x0   => 'Normal',
-            0x080 => 'Medium High', #2
-            0x100 => 'High',
-            0x180 => 'Medium Low', #2
+            0x0   => '0 (normal)', # # ("Color 0", ref 8)
+            0x080 => '+1 (medium high)', #2 ("Color +1", ref 8)
+            0x100 => '+2 (high)', # ("Color +2", ref 8)
+            0x0c0 => '+3 (very high)',
+            0x0e0 => '+4 (highest)',
+            0x180 => '-1 (medium low)', #2 ("Color -1", ref 8)
             0x200 => 'Low',
             0x300 => 'None (B&W)', #2
-            0x301 => 'B&W Green Filter', #PH (X100)
+            0x301 => 'B&W Red Filter', #PH/8
             0x302 => 'B&W Yellow Filter', #PH (X100)
-            0x303 => 'B&W Blue Filter', #PH (X100)
+            0x303 => 'B&W Green Filter', #PH/8
             0x310 => 'B&W Sepia', #PH (X100)
+            0x400 => '-2 (low)', #8 ("Color -2")
+            0x4c0 => '-3 (very low)',
+            0x4e0 => '-4 (lowest)',
+            0x500 => 'Acros', #PH (X-Pro2)
+            0x501 => 'Acros Red Filter', #PH (X-Pro2)
+            0x502 => 'Acros Yellow Filter', #PH (X-Pro2)
+            0x503 => 'Acros Green Filter', #PH (X-Pro2)
             0x8000 => 'Film Simulation', #2
         },
@@ -185,4 +232,5 @@
         Flags => 'PrintHex',
         Writable => 'int16u',
+        RawConv => '$val == 0x100 ? undef : $val',
         PrintConv => {
             0x40 => 'Low',
@@ -192,11 +240,17 @@
     },
     0x100e => { #PH (X100)
-        Name => 'HighISONoiseReduction',
+        Name => 'NoiseReduction',
         Flags => 'PrintHex',
         Writable => 'int16u',
         PrintConv => {
-            0x000 => 'Normal',
-            0x100 => 'Strong',
-            0x200 => 'Weak',
+            0x000 => '0 (normal)', # ("NR 0, ref 8)
+            0x100 => '+2 (strong)', # ("NR+2, ref 8)
+            0x180 => '+1 (medium strong)', #8 ("NR+1")
+            0x1c0 => '+3 (very strong)',
+            0x1e0 => '+4 (strongest)',
+            0x200 => '-2 (weak)', # ("NR-2, ref 8)
+            0x280 => '-1 (medium weak)', #8 ("NR-1")
+            0x2c0 => '-3 (very weak)', #10 (-3)
+            0x2e0 => '-4 (weakest)', #10 (-4)
         },
     },
@@ -204,4 +258,5 @@
         Name => 'FujiFlashMode',
         Writable => 'int16u',
+        PrintHex => 1,
         PrintConv => {
             0 => 'Auto',
@@ -210,4 +265,24 @@
             3 => 'Red-eye reduction',
             4 => 'External', #JD
+            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
         },
     },
@@ -230,5 +305,29 @@
             0 => 'Auto',
             1 => 'Manual',
-        },
+            65535 => 'Movie', #forum10766
+        },
+    },
+    0x1022 => { #8/forum6579
+        Name => 'AFMode',
+        Writable => 'int16u',
+        Notes => '"No" for manual and some AF-multi focus modes',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Single Point',
+            256 => 'Zone',
+            512 => 'Wide/Tracking',
+        },
+    },
+    0x102b => {
+        Name => 'PrioritySettings',
+        SubDirectory => { TagTable => 'Image::ExifTool::FujiFilm::PrioritySettings' },
+    },
+    0x102d => {
+        Name => 'FocusSettings',
+        SubDirectory => { TagTable => 'Image::ExifTool::FujiFilm::FocusSettings' },
+    },
+    0x102e => {
+        Name => 'AFCSettings',
+        SubDirectory => { TagTable => 'Image::ExifTool::FujiFilm::AFCSettings' },
     },
     0x1023 => { #2
@@ -250,5 +349,5 @@
         Writable => 'int16u',
         PrintConv => {
-            0x0 => 'Auto',
+            0x0 => 'Auto', # (or 'SR+' if SceneRecognition present, ref 11)
             0x1 => 'Portrait',
             0x2 => 'Landscape',
@@ -270,5 +369,14 @@
             0x12 => 'Fireworks', #3
             0x13 => 'Underwater', #3
+            0x14 => 'Portrait with Skin Correction', #7
             0x16 => 'Panorama', #PH (X100)
+            0x17 => 'Night (tripod)', #7
+            0x18 => 'Pro Low-light', #7
+            0x19 => 'Pro Focus', #7
+            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',
@@ -276,9 +384,9 @@
         },
     },
-# this usually has a value of 1
-#    0x1032 => { #2
-#        Name => 'ShutterCount',
-#        Writable => 'int16u',
-#    },
+    0x1032 => { #8
+        Name => 'ExposureCount',
+        Writable => 'int16u',
+        Notes => 'number of exposures used for this image',
+    },
     0x1033 => { #6
         Name => 'EXRAuto',
@@ -299,6 +407,100 @@
         },
     },
-    0x1100 => {
+    0x1040 => { #8
+        Name => 'ShadowTone',
+        Writable => 'int32s',
+        PrintConv => {
+            -64 => '+4 (hardest)',
+            -48 => '+3 (very hard)',
+            -32 => '+2 (hard)',
+            -16 => '+1 (medium hard)',
+            0 => '0 (normal)',
+            16 => '-1 (medium soft)',
+            32 => '-2 (soft)',
+        },
+    },
+    0x1041 => { #8
+        Name => 'HighlightTone',
+        Writable => 'int32s',
+        PrintConv => {
+            -64 => '+4 (hardest)',
+            -48 => '+3 (very hard)',
+            -32 => '+2 (hard)',
+            -16 => '+1 (medium hard)',
+            0 => '0 (normal)',
+            16 => '-1 (medium soft)',
+            32 => '-2 (soft)',
+        },
+    },
+    0x1044 => { #forum7668
+        Name => 'DigitalZoom',
+        Writable => 'int32u',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+    },
+    0x1045 => { #12
+        Name => 'LensModulationOptimizer',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x1047 => { #12
+        Name => 'GrainEffect',
+        Writable => 'int32s',
+        PrintConv => {
+            0 => 'Off',
+            32 => 'Weak',
+            64 => 'Strong',
+        },
+    },
+    0x1048 => { #12
+        Name => 'ColorChromeEffect',
+        Writable => 'int32s',
+        PrintConv => {
+            0 => 'Off',
+            32 => 'Weak',
+            64 => 'Strong',
+        },
+    },
+    0x1049 => { #12
+        Name => 'BWAdjustment',
+        Notes => 'positive values are warm, negative values are cool',
+        Format => 'int8s',
+        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',
+        PrintConv => {
+            0 => 'Mechanical',
+            1 => 'Electronic',
+            2 => 'Electronic (long shutter speed)', #12
+            3 => 'Electronic Front Curtain', #10
+        },
+    },
+    0x1100 => [{
         Name => 'AutoBracketing',
+        Condition => '$$self{Model} eq "X-T3"',
+        Notes => 'X-T3 only',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'Pre-shot', #12 (Electronic Shutter and Continuous High drive mode only)
+        },
+    },{
+        Name => 'AutoBracketing',
+        Notes => 'other models',
         Writable => 'int16u',
         PrintConv => {
@@ -307,8 +509,50 @@
             2 => 'No flash & flash', #3
         },
-    },
+    }],
     0x1101 => {
         Name => 'SequenceNumber',
         Writable => 'int16u',
+    },
+    0x1103 => {
+        Name => 'DriveSettings',
+        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); 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',
+    },
+    0x1154 => { #forum7668
+        Name => 'PanoramaDirection',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Right',
+            2 => 'Up',
+            3 => 'Left',
+            4 => 'Down',
+        },
+    },
+    0x1201 => { #forum6109
+        Name => 'AdvancedFilter',
+        Writable => 'int32u',
+        PrintHex => 1,
+        PrintConv => {
+            0x10000 => 'Pop Color',
+            0x20000 => 'Hi Key',
+            0x30000 => 'Toy Camera',
+            0x40000 => 'Miniature',
+            0x50000 => 'Dynamic Tone',
+            0x60001 => 'Partial Color Red',
+            0x60002 => 'Partial Color Yellow',
+            0x60003 => 'Partial Color Green',
+            0x60004 => 'Partial Color Blue',
+            0x60005 => 'Partial Color Orange',
+            0x60006 => 'Partial Color Purple',
+            0x70000 => 'Soft Focus',
+            0x90000 => 'Low Key',
+        },
     },
     0x1210 => { #2
@@ -349,5 +593,5 @@
         Name => 'GEImageSize',
         Condition => '$$self{Make} =~ /^GENERAL IMAGING/',
-        Format => 'string',
+        Writable => 'string',
         Notes => 'GE models only',
     },
@@ -366,12 +610,19 @@
         PrintHex => 1,
         PrintConv => {
-            0x000 => 'F0/Standard',
+            0x000 => 'F0/Standard (Provia)', # X-Pro2 "Provia/Standard"
             0x100 => 'F1/Studio Portrait',
             0x110 => 'F1a/Studio Portrait Enhanced Saturation',
-            0x120 => 'F1b/Studio Portrait Smooth Skin Tone',
+            0x120 => 'F1b/Studio Portrait Smooth Skin Tone (Astia)', # X-Pro2 "Astia/Soft"
             0x130 => 'F1c/Studio Portrait Increased Sharpness',
-            0x200 => 'F2/Fujichrome',
+            0x200 => 'F2/Fujichrome (Velvia)', # X-Pro2 "Velvia/Vivid"
             0x300 => 'F3/Studio Portrait Ex',
             0x400 => 'F4/Velvia',
+            0x500 => 'Pro Neg. Std', #PH (X-Pro1)
+            0x501 => 'Pro Neg. Hi', #PH (X-Pro1)
+            0x600 => 'Classic Chrome', #forum6109
+            0x700 => 'Eterna', #12
+            0x800 => 'Classic Negative', #forum10536
+            0x900 => 'Bleach Bypass', #forum10890
+            0xa00 => 'Nostalgic Neg', #forum12085
         },
     },
@@ -381,5 +632,5 @@
         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%)',
@@ -392,4 +643,5 @@
         Name => 'DevelopmentDynamicRange',
         Writable => 'int16u',
+        # (shows 200, 400 or 800 for HDR200,HDR400,HDR800, ref forum10799)
     },
     0x1404 => { #2
@@ -411,5 +663,5 @@
     # 0x1408 - values: '0100', 'S100', 'VQ10'
     # 0x1409 - values: same as 0x1408
-    # 0x140a - values: 0, 1, 3, 5, 7
+    # 0x140a - values: 0, 1, 3, 5, 7 (bit 2=red-eye detection, ref 11/13)
     0x140b => { #6
         Name => 'AutoDynamicRange',
@@ -418,8 +670,147 @@
         PrintConvInv => '$val=~s/\s*\%$//; $val',
     },
-    # 0x140b - DR value for AutoDR???? (ref 6) - values: 100
-    # 0x3820 - int16u video frame rate? - PH (HS20EXR)
-    # 0x3821 - int16u video frame width? - PH (HS20EXR)
-    # 0x3822 - int16u video frame height? - PH (HS20EXR)
+    0x104e => { #forum10800 (X-Pro3)
+        Name => 'ColorChromeFXBlue',
+        Writable => 'int32s',
+        PrintConv => {
+            0 => 'Off',
+            32 => 'Weak', # (NC)
+            64 => 'Strong',
+        },
+    },
+    0x1422 => { #8
+        Name => 'ImageStabilization',
+        Writable => 'int16u',
+        Count => 3,
+        PrintConv => [{
+            0 => 'None',
+            1 => 'Optical', #PH
+            2 => 'Sensor-shift', #PH
+            3 => 'OIS Lens', #forum9815 (optical+sensor?)
+            512 => 'Digital', #PH
+        },{
+            0 => 'Off',
+            1 => 'On (mode 1, continuous)',
+            2 => 'On (mode 2, shooting only)',
+        }],
+    },
+    0x1425 => { # if present and 0x1031 PictureMode is zero, then PictureMode is SR+, not Auto (ref 11)
+        Name => 'SceneRecognition',
+        Writable => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0 => 'Unrecognized',
+            0x100 => 'Portrait Image',
+            0x103 => 'Night Portrait', #forum10651
+            0x105 => 'Backlit Portrait', #forum10651
+            0x200 => 'Landscape Image',
+            0x300 => 'Night Scene',
+            0x400 => 'Macro',
+        },
+    },
+    0x1431 => { #forum6109
+        Name => 'Rating',
+        Groups => { 2 => 'Image' },
+        Writable => 'int32u',
+        Priority => 0,
+    },
+    0x1436 => { #8
+        Name => 'ImageGeneration',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Original Image',
+            1 => 'Re-developed from RAW',
+        },
+    },
+    0x1438 => { #forum6579 (X-T1 firmware version 3)
+        Name => 'ImageCount',
+        Notes => 'may reset to 0 when new firmware is installed',
+        Writable => 'int16u',
+        ValueConv => '$val & 0x7fff',
+        ValueConvInv => '$val | 0x8000',
+    },
+    0x1443 => { #12 (X-T3)
+        Name => 'DRangePriority',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Auto', 1 => 'Fixed' },
+    },
+    0x1444 => { #12 (X-T3, only exists if DRangePriority is 'Auto')
+        Name => 'DRangePriorityAuto',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Weak',
+            2 => 'Strong',
+            3 => 'Plus',    #forum10799
+        },
+    },
+    0x1445 => { #12 (X-T3, only exists if DRangePriority is 'Fixed')
+        Name => 'DRangePriorityFixed',
+        Writable => 'int16u',
+        PrintConv => { 1 => 'Weak', 2 => 'Strong' },
+    },
+    0x1446 => { #12
+        Name => 'FlickerReduction',
+        Writable => 'int32u',
+        # seen values: Off=0x0000, On=0x2100,0x3100
+        PrintConv => q{
+            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',
+        Groups => { 2 => 'Video' },
+    },
+    0x3821 => { #PH (HS20EXR MOV)
+        Name => 'FrameWidth',
+        Writable => 'int16u',
+        Groups => { 2 => 'Video' },
+    },
+    0x3822 => { #PH (HS20EXR MOV)
+        Name => 'FrameHeight',
+        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',
@@ -435,5 +826,31 @@
         },
     },
+    0x4200 => { #11
+        Name => 'NumFaceElements',
+        Writable => 'int16u',
+    },
+    0x4201 => { #11
+        Name => 'FaceElementTypes',
+        Writable => 'int8u',
+        Count => -1,
+        PrintConv => [{
+            1 => 'Face',
+            2 => 'Left Eye',
+            3 => 'Right Eye',
+        },'REPEAT'],
+    },
+    # 0x4202 int8u[-1] - number of cooredinates in each rectangle? (ref 11)
+    0x4203 => { #11
+        Name => 'FaceElementPositions',
+        Writable => 'int16u',
+        Count => -1,
+        Notes => q{
+            left, top, right and bottom coordinates in full-sized image for each face
+            element
+        },
+    },
+    # 0x4101-0x4105 - exist only if face detection active
     # 0x4104 - also related to face detection (same number of entries as FacePositions)
+    # 0x4200 - same as 0x4100?
     # 0x4203 - same as 0x4103
     # 0x4204 - same as 0x4104
@@ -461,4 +878,158 @@
     },
     # 0xb212 - also found in MPIMage2 images - PH
+);
+
+# Focus Priority settings, tag 0x102b (X-T3, ref forum 9607)
+%Image::ExifTool::FujiFilm::PrioritySettings = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int16u',
+    WRITABLE => 1,
+    0.1 => {
+        Name => 'AF-SPriority',
+        Mask => 0x000f,
+        PrintConv => {
+            1 => 'Release',
+            2 => 'Focus',
+        },
+    },
+    0.2 => {
+        Name => 'AF-CPriority',
+        Mask => 0x00f0,
+        PrintConv => {
+            1 => 'Release',
+            2 => 'Focus',
+        },
+    },
+);
+
+# Focus settings, tag 0x102d (X-T3, ref forum 9607)
+%Image::ExifTool::FujiFilm::FocusSettings = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int32u',
+    WRITABLE => 1,
+    0.1 => {
+        Name => 'FocusMode2',
+        Mask => 0x000000ff,
+        PrintConv => {
+            0x00 => 'AF-M',
+            0x01 => 'AF-S',
+            0x02 => 'AF-C',
+            0x11 => 'AF-S (Auto)',
+        },
+    },
+    0.2 => {
+        Name => 'AFAreaMode',
+        Mask => 0x0f00,
+        PrintConv => {
+            0 => 'Single Point',
+            1 => 'Zone',
+            2 => 'Wide/Tracking',
+        },
+    },
+    0.3 => {
+        Name => 'AFAreaPointSize',
+        Mask => 0xf000,
+        PrintConv => {
+            0 => 'n/a',
+            OTHER => sub { return $_[0] },
+        },
+    },
+    0.4 => {
+        Name => 'AFAreaZoneSize',
+        Mask => 0xf0000,
+        PrintConv => {
+            0 => 'n/a',
+            OTHER => sub {
+                my ($val, $inv) = @_;
+                return "$val x $val" unless $inv;
+                $val =~ s/ ?x.*//;
+                return $val;
+            },
+        },
+    },
+);
+
+# AF-C settings, tag 0x102e (ref forum 9607)
+%Image::ExifTool::FujiFilm::AFCSettings = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int32u',
+    WRITABLE => 1,
+    0 => {
+        Name => 'AF-CSetting',
+        PrintHex => 3,
+        PrintSort => 1, # sort PrintConv by value
+        # decode in-camera preset values (X-T3)
+        PrintConv => {
+            0x102 => 'Set 1 (multi-purpose)',              # (2,0,Auto)
+            0x203 => 'Set 2 (ignore obstacles)',           # (3,0,Center)
+            0x122 => 'Set 3 (accelerating subject)',       # (2,2,Auto)
+            0x010 => 'Set 4 (suddenly appearing subject)', # (0,1,Front)
+            0x123 => 'Set 5 (erratic motion)',             # (3,2,Auto)
+            OTHER => sub {
+                my ($val, $inv) = @_;
+                return $val =~ /(0x\w+)/ ? hex $1 : undef if $inv;
+                return sprintf 'Set 6 (custom 0x%.3x)', $val;
+            },
+        },
+    },
+    0.1 => {
+        Name => 'AF-CTrackingSensitivity',
+        Mask => 0x000f, # (values 0-4)
+    },
+    0.2 => {
+        Name => 'AF-CSpeedTrackingSensitivity',
+        Mask => 0x00f0,
+        # (values 0-2)
+    },
+    0.3 => {
+        Name => 'AF-CZoneAreaSwitching',
+        Mask => 0x0f00,
+        PrintConv => {
+            0 => 'Front',
+            1 => 'Auto',
+            2 => 'Center',
+        },
+    },
+);
+
+# DriveMode settings, tag 0x1103 (X-T3, ref forum 9607)
+%Image::ExifTool::FujiFilm::DriveSettings = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int32u',
+    WRITABLE => 1,
+    0.1 => {
+        Name => 'DriveMode',
+        Mask => 0x000000ff,
+        PrintConv => {
+            0 => 'Single',
+            1 => 'Continuous Low',
+            2 => 'Continuous High',
+        },
+    },
+    0.2 => {
+        Name => 'DriveSpeed',
+        Mask => 0xff000000,
+        PrintConv => {
+            0 => 'n/a',
+            OTHER => sub {
+                my ($val, $inv) = @_;
+                return "$val fps" unless $inv;
+                $val =~ s/ ?fps$//;
+                return $val;
+            },
+        },
+    },
 );
 
@@ -512,6 +1083,27 @@
         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 => [
@@ -550,4 +1142,57 @@
         },
     },
+    0x131 => { #5
+        Name => 'XTransLayout',
+        Description => 'X-Trans Layout',
+        Format => 'int8u',
+        Count => 36,
+        PrintConv => '$val =~ tr/012 /RGB/d; join " ", $val =~ /....../g',
+    },
+    0x2000 => { #IB
+        Name => 'WB_GRGBLevelsAuto',
+        Format => 'int16u',
+        Count => 4, # (ignore the duplicate values)
+    },
+    0x2100 => { #IB
+        Name => 'WB_GRGBLevelsDaylight',
+        Format => 'int16u',
+        Count => 4,
+    },
+    0x2200 => { #IB
+        Name => 'WB_GRGBLevelsCloudy',
+        Format => 'int16u',
+        Count => 4,
+    },
+    0x2300 => { #IB
+        Name => 'WB_GRGBLevelsDaylightFluor',
+        Format => 'int16u',
+        Count => 4,
+    },
+    0x2301 => { #IB
+        Name => 'WB_GRGBLevelsDayWhiteFluor',
+        Format => 'int16u',
+        Count => 4,
+    },
+    0x2302 => { #IB
+        Name => 'WB_GRGBLevelsWhiteFluorescent',
+        Format => 'int16u',
+        Count => 4,
+    },
+    0x2310 => { #IB
+        Name => 'WB_GRGBLevelsWarmWhiteFluor',
+        Format => 'int16u',
+        Count => 4,
+    },
+    0x2311 => { #IB
+        Name => 'WB_GRGBLevelsLivingRoomWarmWhiteFluor',
+        Format => 'int16u',
+        Count => 4,
+    },
+    0x2400 => { #IB
+        Name => 'WB_GRGBLevelsTungsten',
+        Format => 'int16u',
+        Count => 4,
+    },
+    # 0x2f00 => WB_GRGBLevelsCustom: int32u count, then count * (int16u GRGBGRGB), ref IB
     0x2ff0 => {
         Name => 'WB_GRGBLevels',
@@ -555,4 +1200,124 @@
         Count => 4,
     },
+    0x9200 => { #Frank Markesteijn
+        Name => 'RelativeExposure',
+        Format => 'rational32s',
+        ValueConv => 'log($val) / log(2)',
+        ValueConvInv => 'exp($val * log(2))',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    # 0x9200 - relative exposure? (ref Frank Markesteijn)
+    0x9650 => { #Frank Markesteijn
+        Name => 'RawExposureBias',
+        Format => 'rational32s',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    0xc000 => {
+        Name => 'RAFData',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FujiFilm::RAFData',
+            ByteOrder => 'Little-endian',
+        }
+    },
+);
+
+%Image::ExifTool::FujiFilm::RAFData = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0, 4, 8 ],
+    FIRST_ENTRY => 0,
+    # (FujiFilm image dimensions are REALLY confusing)
+    # --> this needs some cleaning up
+    # [Note to self: See email from Iliah Borg for more information about WB settings in this data]
+    0 => {
+        Name => 'RawImageWidth',
+        Format => 'int32u',
+        DataMember => 'FujiWidth',
+        RawConv => '$val < 10000 ? $$self{FujiWidth} = $val : undef', #5
+        ValueConv => '$$self{FujiLayout} ? ($val / 2) : $val',
+    },
+    4 => [
+        {
+            Name => 'RawImageWidth',
+            Condition => 'not $$self{FujiWidth}',
+            Format => 'int32u',
+            DataMember => 'FujiWidth',
+            RawConv => '$val < 10000 ? $$self{FujiWidth} = $val : undef', #PH
+            ValueConv => '$$self{FujiLayout} ? ($val / 2) : $val',
+        },
+        {
+            Name => 'RawImageHeight',
+            Format => 'int32u',
+            DataMember => 'FujiHeight',
+            RawConv => '$$self{FujiHeight} = $val',
+            ValueConv => '$$self{FujiLayout} ? ($val * 2) : $val',
+        },
+    ],
+    8 => [
+        {
+            Name => 'RawImageWidth',
+            Condition => 'not $$self{FujiWidth}',
+            Format => 'int32u',
+            DataMember => 'FujiWidth',
+            RawConv => '$val < 10000 ? $$self{FujiWidth} = $val : undef', #PH
+            ValueConv => '$$self{FujiLayout} ? ($val / 2) : $val',
+        },
+        {
+            Name => 'RawImageHeight',
+            Condition => 'not $$self{FujiHeight}',
+            Format => 'int32u',
+            DataMember => 'FujiHeight',
+            RawConv => '$$self{FujiHeight} = $val',
+            ValueConv => '$$self{FujiLayout} ? ($val * 2) : $val',
+        },
+    ],
+    12 => {
+        Name => 'RawImageHeight',
+        Condition => 'not $$self{FujiHeight}',
+        Format => 'int32u',
+        ValueConv => '$$self{FujiLayout} ? ($val * 2) : $val',
+    },
+);
+
+# TIFF IFD-format information stored in FujiFilm RAF images (ref 5)
+%Image::ExifTool::FujiFilm::IFD = (
+    PROCESS_PROC => \&Image::ExifTool::Exif::ProcessExif,
+    GROUPS => { 0 => 'RAF', 1 => 'FujiIFD', 2 => 'Image' },
+    NOTES => 'Tags found in the FujiIFD information of RAF images from some models.',
+    0xf000 => {
+        Name => 'FujiIFD',
+        Groups => { 1 => 'FujiIFD' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FujiFilm::IFD',
+            DirName => 'FujiSubIFD',
+            Start => '$val',
+        },
+    },
+    0xf001 => 'RawImageFullWidth',
+    0xf002 => 'RawImageFullHeight',
+    0xf003 => 'BitsPerSample',
+    # 0xf004 - values: 4
+    # 0xf005 - values: 1374, 1668
+    # 0xf006 - some sort of flag indicating packed format?
+    0xf007 => {
+        Name => 'StripOffsets',
+        IsOffset => 1,
+        OffsetPair => 0xf008,  # point to associated byte counts
+    },
+    0xf008 => {
+        Name => 'StripByteCounts',
+        OffsetPair => 0xf007,  # point to associated offsets
+    },
+    # 0xf009 - values: 0, 3
+    0xf00a => 'BlackLevel', #IB
+    0xf00b => 'GeometricDistortionParams', #9 (rational64s[23, 35 or 43])
+    0xf00c => 'WB_GRBLevelsStandard', #IB (GRBXGRBX; X=17 is standard illuminant A, X=21 is D65)
+    0xf00d => 'WB_GRBLevelsAuto', #IB
+    0xf00e => 'WB_GRBLevels',
+    0xf00f => 'ChromaticAberrationParams', # (rational64s[23])
+    0xf010 => 'VignettingParams', #9 (rational64s[31 or 64])
 );
 
@@ -569,4 +1334,38 @@
 );
 
+# tags in FujiFilm QuickTime videos (ref PH)
+# (similar information in Kodak,Minolta,Nikon,Olympus,Pentax and Sanyo videos)
+%Image::ExifTool::FujiFilm::MOV = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    NOTES => 'This information is found in MOV videos from some FujiFilm cameras.',
+    0x00 => {
+        Name => 'Make',
+        Format => 'string[24]',
+    },
+    0x18 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[16]',
+    },
+    0x2e => { # (NC)
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val ? 1 / $val : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x32 => {
+        Name => 'FNumber',
+        Format => 'rational64u',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x3a => { # (NC)
+        Name => 'ExposureCompensation',
+        Format => 'rational64s',
+        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
+    },
+);
+
 #------------------------------------------------------------------------------
 # decode information from FujiFilm face recognition information
@@ -575,5 +1374,5 @@
 sub ProcessFaceRec($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos} + ($$dirInfo{Base} || 0);
@@ -583,5 +1382,5 @@
     my $end = $dirStart + $dirLen;
     my ($i, $n, $p, $val);
-    $exifTool->VerboseDir('FaceRecInfo');
+    $et->VerboseDir('FaceRecInfo');
     for ($i=1; ; ++$i) {
         last if $pos + 8 > $end;
@@ -598,5 +1397,5 @@
         last if $p < $dirStart or $p + $n > $end;
         $val = substr($$dataPt, $p, $n);
-        $exifTool->HandleTag($tagTablePtr, "Face${i}Name", $val,
+        $et->HandleTag($tagTablePtr, "Face${i}Name", $val,
             DataPt  => $dataPt,
             DataPos => $dataPos,
@@ -609,5 +1408,5 @@
         $val = substr($$dataPt, $p, $n);
         $val =~ s/(\d{4})(\d{2})(\d{2})/$1:$2:$2/;
-        $exifTool->HandleTag($tagTablePtr, "Face${i}Birthday", $val,
+        $et->HandleTag($tagTablePtr, "Face${i}Birthday", $val,
             DataPt  => $dataPt,
             DataPos => $dataPos,
@@ -615,5 +1414,5 @@
             Size    => $n,
         );
-        $exifTool->HandleTag($tagTablePtr, "Face${i}Category", undef,
+        $et->HandleTag($tagTablePtr, "Face${i}Category", undef,
             DataPt  => $dataPt,
             DataPos => $dataPos,
@@ -632,5 +1431,5 @@
 sub ProcessFujiDir($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
     my $offset = $$dirInfo{DirStart};
@@ -640,5 +1439,5 @@
     my $entries = unpack 'N', $buff;
     $entries < 256 or return 0;
-    $exifTool->Options('Verbose') and $exifTool->VerboseDir('Fuji', $entries);
+    $et->Options('Verbose') and $et->VerboseDir('Fuji', $entries);
     SetByteOrder('MM');
     my $pos = $offset + 4;
@@ -649,5 +1448,5 @@
         my ($val, $vbuf);
         $raf->Read($vbuf, $len) or return 0;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($tagInfo and $$tagInfo{Format}) {
             $val = ReadValue(\$vbuf, 0, $$tagInfo{Format}, $$tagInfo{Count}, $len);
@@ -660,5 +1459,5 @@
             $val = \$vbuf;
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $et->HandleTag($tagTablePtr, $tag, $val,
             Index   => $index,
             DataPt  => \$vbuf,
@@ -678,5 +1477,5 @@
 sub WriteRAF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($hdr, $jpeg, $outJpeg, $offset, $err, $buff);
@@ -685,5 +1484,5 @@
     $hdr =~ /^FUJIFILM/            or return 0;
     my $ver = substr($hdr, 0x3c, 4);
-    $ver =~ /^\d{4}$/              or return 0;
+    $ver =~ /^\d{4}$/ or $testedRAF{$ver} or return 0;
 
     # get the position and size of embedded JPEG
@@ -691,18 +1490,19 @@
     # check to be sure the JPEG starts in the expected location
     if ($jpos > 0x94 or $jpos < 0x68 or $jpos & 0x03) {
-        $exifTool->Error("Unsupported or corrupted RAF image (version $ver)");
+        $et->Error("Unsupported or corrupted RAF image (version $ver)");
         return 1;
     }
     # check to make sure this version of RAF has been tested
-    unless ($testedRAF{$ver}) {
-        $exifTool->Error("RAF version $ver not yet tested", 1) and return 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) {
-        $exifTool->Error('Error reading RAF meta information');
+        $et->Error('Error reading RAF meta information');
         return 1;
     }
     # use same write directories as JPEG
-    $exifTool->InitWriteDirs('JPEG');
+    $et->InitWriteDirs('JPEG');
     # rewrite the embedded JPEG in memory
     my %jpegInfo = (
@@ -711,9 +1511,9 @@
         OutFile => \$outJpeg,
     );
-    $$exifTool{FILE_TYPE} = 'JPEG';
-    my $success = $exifTool->WriteJPEG(\%jpegInfo);
-    $$exifTool{FILE_TYPE} = 'RAF';
+    $$et{FILE_TYPE} = 'JPEG';
+    my $success = $et->WriteJPEG(\%jpegInfo);
+    $$et{FILE_TYPE} = 'RAF';
     unless ($success and $outJpeg) {
-        $exifTool->Error("Invalid RAF format");
+        $et->Error("Invalid RAF format");
         return 1;
     }
@@ -736,11 +1536,11 @@
             $raf->Read($buff, $oldPadLen) != $oldPadLen)
         {
-            $exifTool->Error('Bad RAF pointer at 0x5c');
+            $et->Error('Bad RAF pointer at 0x5c');
             return 1;
         }
         # make sure padding is only zero bytes (can be >100k for HS10)
+        # (have seen non-null padding in X-Pro1)
         if ($buff =~ /[^\0]/) {
-            $exifTool->Error('Non-null bytes found in padding');
-            return 1;
+            return 1 if $et->Error('Non-null bytes found in padding', 2);
         }
     }
@@ -749,5 +1549,5 @@
     # update necessary pointers in header
     foreach $offset (0x5c, 0x64, 0x78, 0x80) {
-        last if $offset >= $jpos;    # some versions have a short header
+        last if $offset >= $jpos;   # some versions have a short header
         my $oldPtr = Get32u(\$hdr, $offset);
         next unless $oldPtr;        # don't update if pointer is zero
@@ -761,5 +1561,5 @@
     # copy over the rest of the RAF image
     unless ($raf->Seek($nextPtr, 0)) {
-        $exifTool->Error('Error reading RAF image');
+        $et->Error('Error reading RAF image');
         return 1;
     }
@@ -776,5 +1576,5 @@
 sub ProcessRAF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my ($buff, $jpeg, $warn, $offset);
 
@@ -787,5 +1587,6 @@
     $raf->Read($jpeg, $jlen) == $jlen or return 0;
 
-    $exifTool->FoundTag('RAFVersion', substr($buff, 0x3c, 4));
+    $et->SetFileType();
+    $et->FoundTag('RAFVersion', substr($buff, 0x3c, 4));
 
     # extract information from embedded JPEG
@@ -794,12 +1595,12 @@
         RAF    => new File::RandomAccess(\$jpeg),
     );
-    $$exifTool{BASE} += $jpos;
-    my $rtnVal = $exifTool->ProcessJPEG(\%dirInfo);
-    $$exifTool{BASE} -= $jpos;
-    $exifTool->FoundTag('PreviewImage', \$jpeg) if $rtnVal;
-
-    # extract information from Fuji RAF directories
-    my $num = '';
-    foreach $offset (0x5c, 0x78) {
+    $$et{BASE} += $jpos;
+    my $rtnVal = $et->ProcessJPEG(\%dirInfo);
+    $$et{BASE} -= $jpos;
+    $et->FoundTag('PreviewImage', \$jpeg) if $rtnVal;
+
+    # extract information from Fuji RAF and TIFF directories
+    my ($rafNum, $ifdNum) = ('','');
+    foreach $offset (0x5c, 0x64, 0x78, 0x80) {
         last if $offset >= $jpos;
         unless ($raf->Seek($offset, 0) and $raf->Read($buff, 4)) {
@@ -809,17 +1610,30 @@
         my $start = unpack('N',$buff);
         next unless $start;
-
-        %dirInfo = (
-            RAF      => $raf,
-            DirStart => $start,
-        );
-        $$exifTool{SET_GROUP1} = "RAF$num";
-        my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::RAF');
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr) or $warn = 1;
-        delete $$exifTool{SET_GROUP1};
-
-        $num = ($num || 1) + 1;
+        if ($offset == 0x64 or $offset == 0x80) {
+            # parse FujiIFD directory
+            %dirInfo = (
+                RAF  => $raf,
+                Base => $start,
+            );
+            $$et{SET_GROUP1} = "FujiIFD$ifdNum";
+            my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::IFD');
+            # this is TIFF-format data only for some models, so no warning if it fails
+            $et->ProcessTIFF(\%dirInfo, $tagTablePtr, \&Image::ExifTool::ProcessTIFF);
+            delete $$et{SET_GROUP1};
+            $ifdNum = ($ifdNum || 1) + 1;
+        } else {
+            # parse RAF directory
+            %dirInfo = (
+                RAF      => $raf,
+                DirStart => $start,
+            );
+            $$et{SET_GROUP1} = "RAF$rafNum";
+            my $tagTablePtr = GetTagTable('Image::ExifTool::FujiFilm::RAF');
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr) or $warn = 1;
+            delete $$et{SET_GROUP1};
+            $rafNum = ($rafNum || 1) + 1;
+        }
     }
-    $warn and $exifTool->Warn('Possibly corrupt RAF information');
+    $warn and $et->Warn('Possibly corrupt RAF information');
 
     return $rtnVal;
@@ -846,5 +1660,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GE.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GE.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GE.pm	(revision 34921)
@@ -19,4 +19,5 @@
 
 # GE type 1 maker notes (ref PH)
+# (similar to Kodak::Type11 and Ricoh::Type2)
 %Image::ExifTool::GE::Main = (
     WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
@@ -68,5 +69,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GIF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GIF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GIF.pm	(revision 34921)
@@ -5,8 +5,12 @@
 #
 # Revisions:    10/18/2005 - P. Harvey Separated from ExifTool.pm
+#               05/23/2008 - P. Harvey Added ability to read/write XMP
+#               10/28/2011 - P. Harvey Added ability to read/write ICC_Profile
 #
 # References:   1) http://www.w3.org/Graphics/GIF/spec-gif89a.txt
 #               2) http://www.adobe.com/devnet/xmp/
 #               3) http://graphcomp.com/info/specs/ani_gif.html
+#               4) http://www.color.org/icc_specs2.html
+#               5) http://www.midiox.com/mmgif.htm
 #------------------------------------------------------------------------------
 
@@ -17,9 +21,10 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.06';
+$VERSION = '1.18';
 
 # road map of directory locations in GIF images
 my %gifMap = (
-    XMP => 'GIF',
+    XMP         => 'GIF',
+    ICC_Profile => 'GIF',
 );
 
@@ -38,5 +43,5 @@
         # 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   => {
@@ -47,9 +52,36 @@
         SubDirectory => { TagTable => 'Image::ExifTool::GIF::Screen' },
     },
-    AnimationExtension => {
-        SubDirectory => { TagTable => 'Image::ExifTool::GIF::Animate' },
-    },
-    XMPExtension => { # (for documentation only)
+    Extensions => { # (for documentation only)
+        SubDirectory => { TagTable => 'Image::ExifTool::GIF::Extensions' },
+    },
+);
+
+# GIF89a application extensions:
+%Image::ExifTool::GIF::Extensions = (
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'Tags extracted from GIF89a application extensions.',
+    'NETSCAPE/2.0' => { #3
+        Name => 'Animation',
+        SubDirectory => { TagTable => 'Image::ExifTool::GIF::Animation' },
+    },
+    'XMP Data/XMP' => { #2
+        Name => 'XMP',
+        IncludeLengthBytes => 1, # length bytes are included in the data
+        Writable => 2,
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
+    },
+    'ICCRGBG1/012' => { #4
+        Name => 'ICC_Profile',
+        Writable => 2,
+        SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
+    },
+    'MIDICTRL/Jon' => { #5
+        Name => 'MIDIControl',
+        SubDirectory => { TagTable => 'Image::ExifTool::GIF::MIDIControl' },
+    },
+    'MIDISONG/Dm7' => { #5
+        Name => 'MIDISong',
+        Groups => { 2 => 'Audio' },
+        Binary => 1,
     },
 );
@@ -71,10 +103,10 @@
         Name => 'HasColorMap',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'No', 0x80 => 'Yes' },
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
     },
     4.2 => {
         Name => 'ColorResolutionDepth',
         Mask => 0x70,
-        ValueConv => '($val >> 4) + 1',
+        ValueConv => '$val + 1',
     },
     4.3 => {
@@ -84,15 +116,42 @@
     },
     5 => 'BackgroundColor',
+    6 => {
+        Name => 'PixelAspectRatio',
+        RawConv => '$val ? $val : undef',
+        ValueConv => '($val + 15) / 64',
+    },
 );
 
-# GIF Netscape 2.0 animation extension
-%Image::ExifTool::GIF::Animate = (
+# GIF Netscape 2.0 animation extension (ref 3)
+%Image::ExifTool::GIF::Animation = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     GROUPS => { 2 => 'Image' },
     NOTES => 'Information extracted from the "NETSCAPE2.0" animation extension.',
-    2 => {
+    1 => {
         Name => 'AnimationIterations',
         Format => 'int16u',
         PrintConv => '$val ? $val : "Infinite"',
+    },
+);
+
+# GIF MIDICTRL extension (ref 5)
+%Image::ExifTool::GIF::MIDIControl = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    NOTES => 'Information extracted from the MIDI control block extension.',
+    0 => 'MIDIControlVersion',
+    1 => 'SequenceNumber',
+    2 => 'MelodicPolyphony',
+    3 => 'PercussivePolyphony',
+    4 => {
+        Name => 'ChannelUsage',
+        Format => 'int16u',
+        PrintConv => 'sprintf("0x%.4x", $val)',
+    },
+    6 => {
+        Name => 'DelayTime',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        PrintConv => '$val . " s"',
     },
 );
@@ -105,11 +164,11 @@
 sub ProcessGIF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $outfile = $$dirInfo{OutFile};
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
-    my ($a, $s, $ch, $length, $buff, $comment);
-    my ($err, $newComment, $setComment);
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
+    my ($a, $s, $ch, $length, $buff);
+    my ($err, $newComment, $setComment, $nvComment);
     my ($addDirs, %doneDir);
     my ($frameCount, $delayTime) = (0, 0);
@@ -126,25 +185,17 @@
 
     if ($outfile) {
-        $exifTool->InitWriteDirs(\%gifMap, 'XMP'); # make XMP the preferred group for GIF
-        $addDirs = $exifTool->{ADD_DIRS};
+        $et->InitWriteDirs(\%gifMap, 'XMP'); # make XMP the preferred group for GIF
+        $addDirs = $$et{ADD_DIRS};
         # determine if we are editing the File:Comment tag
-        my $delGroup = $exifTool->{DEL_GROUP};
-        if ($$delGroup{File}) {
-            $setComment = 1;
-            if ($$delGroup{File} == 2) {
-                $newComment = $exifTool->GetNewValues('Comment');
-            }
-        } else {
-            my $nvHash;
-            $newComment = $exifTool->GetNewValues('Comment', \$nvHash);
-            $setComment = 1 if $nvHash;
-        }
-        # change to GIF 89a if adding comment or XMP
-        $buff = 'GIF89a' if $$addDirs{XMP} or defined $newComment;
+        my $delGroup = $$et{DEL_GROUP};
+        $newComment = $et->GetNewValue('Comment', \$nvComment);
+        $setComment = 1 if $nvComment or $$delGroup{File};
+        # change to GIF 89a if adding comment, XMP or ICC_Profile
+        $buff = 'GIF89a' if $$addDirs{XMP} or $$addDirs{ICC_Profile} or defined $newComment;
         Write($outfile, $buff, $s) or $err = 1;
     } else {
-        $exifTool->SetFileType();   # set file type
-        $exifTool->HandleTag($tagTablePtr, 'GIFVersion', $ver);
-        $exifTool->HandleTag($tagTablePtr, 'ScreenDescriptor', $s);
+        $et->SetFileType();   # set file type
+        $et->HandleTag($tagTablePtr, 'GIFVersion', $ver);
+        $et->HandleTag($tagTablePtr, 'ScreenDescriptor', $s);
     }
     my $flags = Get8u(\$s, 4);
@@ -155,23 +206,4 @@
         Write($outfile, $buff) or $err = 1 if $outfile;
     }
-    # write the comment first if necessary
-    if ($outfile and defined $newComment) {
-        # write comment marker
-        Write($outfile, "\x21\xfe") or $err = 1;
-        $verbose and print $out "  + Comment = $newComment\n";
-        my $len = length($newComment);
-        # write out the comment in 255-byte chunks, each
-        # chunk beginning with a length byte
-        my $n;
-        for ($n=0; $n<$len; $n+=255) {
-            my $size = $len - $n;
-            $size > 255 and $size = 255;
-            my $str = substr($newComment,$n,$size);
-            Write($outfile, pack('C',$size), $str) or $err = 1;
-        }
-        Write($outfile, "\0") or $err = 1;  # empty chunk as terminator
-        undef $newComment;
-        ++$exifTool->{CHANGED};     # increment file changed flag
-    }
 #
 # loop through GIF blocks
@@ -180,5 +212,26 @@
     for (;;) {
         last unless $raf->Read($ch, 1);
+        # write out any new metadata now if this isn't an extension block
         if ($outfile and ord($ch) != 0x21) {
+            # write the comment first if necessary
+            if (defined $newComment and $$nvComment{IsCreating}) {
+                # write comment marker
+                Write($outfile, "\x21\xfe") or $err = 1;
+                $verbose and print $out "  + Comment = $newComment\n";
+                my $len = length($newComment);
+                # write out the comment in 255-byte chunks, each
+                # chunk beginning with a length byte
+                my $n;
+                for ($n=0; $n<$len; $n+=255) {
+                    my $size = $len - $n;
+                    $size > 255 and $size = 255;
+                    my $str = substr($newComment,$n,$size);
+                    Write($outfile, pack('C',$size), $str) or $err = 1;
+                }
+                Write($outfile, "\0") or $err = 1;  # empty chunk as terminator
+                undef $newComment;
+                undef $nvComment;   # delete any other extraneous comments
+                ++$$et{CHANGED};    # increment file changed flag
+            }
             # add application extension containing XMP block if necessary
             # (this will place XMP before the first non-extension block)
@@ -189,5 +242,5 @@
                 my %dirInfo = ( Parent => 'GIF' );
                 $verbose and print $out "Creating XMP application extension block:\n";
-                $buff = $exifTool->WriteDirectory(\%dirInfo, $xmpTable);
+                $buff = $et->WriteDirectory(\%dirInfo, $xmpTable);
                 if (defined $buff and length $buff) {
                     my $lz = pack('C*',1,reverse(0..255),0);
@@ -196,4 +249,28 @@
                 } else {
                     $verbose and print $out "  -> no XMP to add\n";
+                }
+            }
+            # add application extension containing ICC_Profile if necessary
+            if (exists $$addDirs{ICC_Profile} and not defined $doneDir{ICC_Profile}) {
+                $doneDir{ICC_Profile} = 1;
+                # write new ICC_Profile
+                my $iccTable = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+                my %dirInfo = ( Parent => 'GIF' );
+                $verbose and print $out "Creating ICC_Profile application extension block:\n";
+                $buff = $et->WriteDirectory(\%dirInfo, $iccTable);
+                if (defined $buff and length $buff) {
+                    my $pos = 0;
+                    Write($outfile, "\x21\xff\x0bICCRGBG1012") or $err = 1;
+                    my $len = length $buff;
+                    while ($pos < $len) {
+                        my $n = $len - $pos;
+                        $n = 255 if $n > 255;
+                        Write($outfile, chr($n), substr($buff, $pos, $n)) or $err = 1;
+                        $pos += $n;
+                    }
+                    Write($outfile, "\0") or $err = 1;  # write null terminator
+                    ++$doneDir{ICC_Profile};    # set to 2 to indicate we added a new profile
+                } else {
+                    $verbose and print $out "  -> no ICC_Profile to add\n";
                 }
             }
@@ -247,34 +324,57 @@
         if ($a == 0xfe) {                           # comment extension
 
-            if ($setComment) {
-                ++$exifTool->{CHANGED}; # increment the changed flag
-            } else {
-                Write($outfile, $ch, $s) or $err = 1 if $outfile;
-            }
+            my $comment = '';
             while ($length) {
                 last unless $raf->Read($buff, $length) == $length;
-                if ($verbose > 2 and not $outfile) {
-                    Image::ExifTool::HexDump(\$buff, undef, Out => $out);
-                }
+                $et->VerboseDump(\$buff) unless $outfile;
                 # add buffer to comment string
-                $comment = defined $comment ? $comment . $buff : $buff;
+                $comment .= $buff;
                 last unless $raf->Read($ch, 1);  # read next block header
                 $length = ord($ch);  # get next block size
-
-                # write or delete comment
-                next unless $outfile;
+            }
+            last if $length;    # was a read error if length isn't zero
+            if ($outfile) {
+                my $isOverwriting;
                 if ($setComment) {
-                    $verbose and print $out "  - Comment = $buff\n";
+                    if ($nvComment) {
+                        $isOverwriting = $et->IsOverwriting($nvComment,$comment);
+                        # get new comment again (may have been shifted)
+                        $newComment = $et->GetNewValue($nvComment) if defined $newComment;
+                    } else {
+                        # group delete, or deleting additional comments after writing one
+                        $isOverwriting = 1;
+                    }
+                }
+                if ($isOverwriting) {
+                    ++$$et{CHANGED};     # increment file changed flag
+                    $et->VerboseValue('- Comment', $comment);
+                    $comment = $newComment;
+                    $et->VerboseValue('+ Comment', $comment) if defined $comment;
+                    undef $nvComment;   # just delete remaining comments
                 } else {
-                    Write($outfile, $buff, $ch) or $err = 1;
-                }
-            }
-            last if $length;    # was a read error if length isn't zero
-            unless ($outfile) {
+                    undef $setComment;  # leave remaining comments alone
+                }
+                if (defined $comment) {
+                    # write comment marker
+                    Write($outfile, "\x21\xfe") or $err = 1;
+                    my $len = length($comment);
+                    # write out the comment in 255-byte chunks, each
+                    # chunk beginning with a length byte
+                    my $n;
+                    for ($n=0; $n<$len; $n+=255) {
+                        my $size = $len - $n;
+                        $size > 255 and $size = 255;
+                        my $str = substr($comment,$n,$size);
+                        Write($outfile, pack('C',$size), $str) or $err = 1;
+                    }
+                    Write($outfile, "\0") or $err = 1;  # empty chunk as terminator
+                }
+                undef $newComment;  # don't write the new comment again
+            } else {
                 $rtnVal = 1;
-                $exifTool->FoundTag('Comment', $comment) if $comment;
+                $et->FoundTag('Comment', $comment) if $comment;
                 undef $comment;
                 # assume no more than one comment in FastScan mode
-                last if $exifTool->Options('FastScan');
+                last if $et->Options('FastScan');
             }
             next;
@@ -283,71 +383,94 @@
 
             last unless $raf->Read($buff, $length) == $length;
-            if ($verbose) {
-                my @a = unpack('a8a3', $buff);
-                s/\0.*//s foreach @a;
-                print $out "Application Extension: @a\n";
-            }
-            if ($buff eq 'XMP DataXMP') {   # XMP data (ref 2)
-                my $hdr = "$ch$s$buff";
-                # read XMP data
-                my $xmp = '';
-                for (;;) {
-                    $raf->Read($ch, 1) or last Block;   # read next block header
-                    $length = ord($ch) or last;         # get next block size
-                    $raf->Read($buff, $length) == $length or last Block;
-                    $xmp .= $ch . $buff;
-                }
-                # get length of XMP without landing zone data
-                # (note that LZ data may not be exactly the same as what we use)
-                my $xmpLen;
-                if ($xmp =~ /<\?xpacket end=['"][wr]['"]\?>/g) {
-                    $xmpLen = pos($xmp);
-                } else {
-                    $xmpLen = length($xmp);
+            my $hdr = "$ch$s$buff";
+            # add "/" for readability
+            my $tag = substr($buff, 0, 8) . '/' . substr($buff, 8);
+            $tag =~ tr/\0-\x1f//d;   # remove nulls and control characters
+            $verbose and print $out "Application Extension: $tag\n";
+
+            my $extTable = GetTagTable('Image::ExifTool::GIF::Extensions');
+            my $extInfo = $$extTable{$tag};
+            my ($subdir, $inclLen, $justCopy);
+            if ($extInfo) {
+                $subdir = $$extInfo{SubDirectory};
+                $inclLen = $$extInfo{IncludeLengthBytes};
+                # rewrite as-is unless this is a writable subdirectory
+                $justCopy = 1 if $outfile and (not $subdir or not $$extInfo{Writable});
+            } else {
+                $justCopy = 1 if $outfile;
+            }
+            Write($outfile, $hdr) or $err = 1 if $justCopy;
+
+            # read the extension data
+            my $dat = '';
+            for (;;) {
+                $raf->Read($ch, 1) or last Block;   # read next block header
+                $length = ord($ch) or last;         # get next block size
+                $raf->Read($buff, $length) == $length or last Block;
+                Write($outfile, $ch, $buff) or $err = 1 if $justCopy;
+                $dat .= $inclLen ? $ch . $buff : $buff;
+            }
+            Write($outfile, "\0") if $justCopy;
+
+            if ($subdir) {
+                my $dirLen = length $dat;
+                my $name = $$extInfo{Name};
+                if ($name eq 'XMP') {
+                    # get length of XMP without landing zone data
+                    # (note that LZ data may not be exactly the same as what we use)
+                    $dirLen = pos($dat) if $dat =~ /<\?xpacket end=['"][wr]['"]\?>/g;
                 }
                 my %dirInfo = (
-                    DataPt  => \$xmp,
-                    DataLen => length $xmp,
-                    DirLen  => $xmpLen,
+                    DataPt  => \$dat,
+                    DataLen => length $dat,
+                    DirLen  => $dirLen,
+                    DirName => $name,
                     Parent  => 'GIF',
                 );
-                my $xmpTable = GetTagTable('Image::ExifTool::XMP::Main');
-                if ($outfile) {
-                    if ($doneDir{XMP} and $doneDir{XMP} > 1) {
-                        $exifTool->Warn('Duplicate XMP block created');
+                my $subTable = GetTagTable($$subdir{TagTable});
+                if (not $outfile) {
+                    $et->ProcessDirectory(\%dirInfo, $subTable);
+                } elsif ($$extInfo{Writable}) {
+                    if ($doneDir{$name} and $doneDir{$name} > 1) {
+                        $et->Warn("Duplicate $name block created");
                     }
-                    my $newXMP = $exifTool->WriteDirectory(\%dirInfo, $xmpTable);
-                    if (not defined $newXMP) {
-                        Write($outfile, $hdr, $xmp) or $err = 1;  # write original XMP
-                        $doneDir{XMP} = 1;
-                    } elsif (length $newXMP) {
-                        if ($newXMP =~ /\0/) { # (check just to be safe)
-                            $exifTool->Error('XMP contained NULL character');
-                        } else {
-                            # write new XMP and landing zone
-                            my $lz = pack('C*',1,reverse(0..255),0);
-                            Write($outfile, $hdr, $newXMP, $lz) or $err = 1;
+                    $buff = $et->WriteDirectory(\%dirInfo, $subTable);
+                    if (defined $buff) {
+                        next unless length $buff;   # delete this extension if length is zero
+                        # check for null just to be safe
+                        $et->Error("$name contained NULL character") if $buff =~ /\0/;
+                        $dat = $buff;
+                        # add landing zone (without terminator, which will be added later)
+                        $dat .= pack('C*',1,reverse(0..255)) if $$extInfo{IncludeLengthBytes};
+                    } # (else rewrite original data)
+
+                    $doneDir{$name} = 1;
+
+                    if ($$extInfo{IncludeLengthBytes}) {
+                        # write data and landing zone
+                        Write($outfile, $hdr, $dat) or $err = 1;
+                    } else {
+                        # write as sub-blocks
+                        Write($outfile, $hdr) or $err = 1;
+                        my $pos = 0;
+                        my $len = length $dat;
+                        while ($pos < $len) {
+                            my $n = $len - $pos;
+                            $n = 255 if $n > 255;
+                            Write($outfile, chr($n), substr($dat, $pos, $n)) or $err = 1;
+                            $pos += $n;
                         }
-                        $doneDir{XMP} = 1;
-                    } # else we are deleting the XMP
-                } else {
-                    $exifTool->ProcessDirectory(\%dirInfo, $xmpTable);
-                }
-                next;
-            } elsif ($buff eq 'NETSCAPE2.0') {      # animated GIF extension (ref 3)
-                $raf->Read($buff, 5) == 5 or last;
-                # make sure this contains the expected data
-                if ($buff =~ /^\x03\x01(..)\0$/) {
-                    $exifTool->HandleTag($tagTablePtr, 'AnimationExtension', $buff);
-                }
-                $raf->Seek(-$length-5, 1) or last;  # seek back to start of block
-            } else {
-                $raf->Seek(-$length, 1) or last;
-            }
+                    }
+                    Write($outfile, "\0") or $err = 1;  # write null terminator
+                }
+            } elsif (not $outfile) {
+                $et->HandleTag($extTable, $tag, $dat);
+            }
+            next;
 
         } 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;
@@ -372,5 +495,5 @@
             }
             Write($outfile, "\0") or $err = 1 if $outfile;  # write terminator block
-            $exifTool->HandleTag($tagTablePtr, 'Text', $text);
+            $et->HandleTag($tagTablePtr, 'Text', $text);
             next;
         }
@@ -386,8 +509,6 @@
     }
     unless ($outfile) {
-        $exifTool->HandleTag($tagTablePtr, 'FrameCount', $frameCount) if $frameCount > 1;
-        $exifTool->HandleTag($tagTablePtr, 'Duration', $delayTime/100) if $delayTime;
-        # for historical reasons, the GIF Comment tag is in the Extra table
-        $exifTool->FoundTag('Comment', $comment) if $comment;
+        $et->HandleTag($tagTablePtr, 'FrameCount', $frameCount) if $frameCount > 1;
+        $et->HandleTag($tagTablePtr, 'Duration', $delayTime/100) if $delayTime;
     }
 
@@ -417,5 +538,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -432,4 +553,8 @@
 =item L<http://graphcomp.com/info/specs/ani_gif.html>
 
+=item L<http://www.color.org/icc_specs2.html>
+
+=item L<http://www.midiox.com/mmgif.htm>
+
 =back
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GIMP.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GIMP.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GIMP.pm	(revision 34921)
@@ -5,7 +5,8 @@
 #
 # Revisions:    2010/10/05 - P. Harvey Created
+#               2018/08/21 - PH Updated to current XCF specification (v013)
 #
 # References:   1) GIMP source code
-#               2) http://svn.gnome.org/viewvc/gimp/trunk/devel-docs/xcf.txt?view=markup
+#               2) https://gitlab.gnome.org/GNOME/gimp/blob/master/devel-docs/xcf.txt
 #------------------------------------------------------------------------------
 
@@ -16,5 +17,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.01';
+$VERSION = '1.03';
 
 sub ProcessParasites($$$);
@@ -29,4 +30,7 @@
     },
     header => { SubDirectory => { TagTable => 'Image::ExifTool::GIMP::Header' } },
+    # recognized properties
+    # 1 - ColorMap
+    # 17 - SamplePoints? (doc says 17 is also "PROP_SAMPLE_POINTS"??)
     17 => {
         Name => 'Compression',
@@ -39,12 +43,30 @@
         },
     },
+    # 18 - Guides
     19 => {
         Name => 'Resolution',
         SubDirectory => { TagTable => 'Image::ExifTool::GIMP::Resolution' },
     },
+    20 => {
+        Name => 'Tattoo',
+        Format => 'int32u',
+    },
     21 => {
         Name => 'Parasites',
         SubDirectory => { TagTable => 'Image::ExifTool::GIMP::Parasite' },
     },
+    22 => {
+        Name => 'Units',
+        Format => 'int32u',
+        PrintConv => {
+            1 => 'Inches',
+            2 => 'mm',
+            3 => 'Points',
+            4 => 'Picas',
+        },
+    },
+    # 23 Paths
+    # 24 UserUnit
+    # 25 Vectors
 );
 
@@ -56,8 +78,11 @@
         Name => 'XCFVersion',
         Format => 'string[5]',
+        DataMember => 'XCFVersion',
+        RawConv => '$$self{XCFVersion} = $val',
         PrintConv => {
             'file' => '0',
             'v001' => '1',
             'v002' => '2',
+            OTHER => sub { my $val = shift; $val =~ s/^v0*//; return $val },
         },
     },
@@ -73,4 +98,5 @@
         },
     },
+    # 26 - [XCF 4 or later] Precision
 );
 
@@ -127,4 +153,11 @@
         },
     },
+    'gimp-image-metadata' => {
+        Name => 'XML',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::XML' },
+    },
+    # Seen, but not yet decoded:
+    #  gimp-image-grid
+    #  jpeg-settings
 );
 
@@ -135,10 +168,10 @@
 sub ProcessParasites($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    my $unknown = $exifTool->Options('Unknown') || $exifTool->Options('Verbose');
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $unknown = $et->Options('Unknown') || $et->Options('Verbose');
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart} || 0;
     my $end = length $$dataPt;
-    $exifTool->VerboseDir('Parasites', undef, $end);
+    $et->VerboseDir('Parasites', undef, $end);
     for (;;) {
         last if $pos + 4 > $end;
@@ -161,7 +194,7 @@
             $name =~ s/([a-z])-([a-z])/$1\u$2/g;
             $name = "GIMP-$name" unless length($name) > 1;
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name, Unknown => 1 });
+            AddTagToTable($tagTablePtr, $tag, { Name => $name, Unknown => 1 });
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, undef,
+        $et->HandleTag($tagTablePtr, $tag, undef,
             DataPt => $dataPt,
             Start  => $pos,
@@ -179,5 +212,5 @@
 sub ProcessXCF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -187,10 +220,13 @@
 
     my $tagTablePtr = GetTagTable('Image::ExifTool::GIMP::Main');
-    my $verbose = $exifTool->Options('Verbose');
-    $exifTool->SetFileType();
+    my $verbose = $et->Options('Verbose');
+    $et->SetFileType();
     SetByteOrder('MM');
 
     # process the XCF header
-    $exifTool->HandleTag($tagTablePtr, 'header', $buff);
+    $et->HandleTag($tagTablePtr, 'header', $buff);
+
+    # 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
@@ -199,5 +235,5 @@
         my $tag  = Get32u(\$buff, 0) or last;
         my $size = Get32u(\$buff, 4);
-        $verbose and $exifTool->VPrint(0, "XCF property $tag ($size bytes):\n");
+        $verbose and $et->VPrint(0, "XCF property $tag ($size bytes):\n");
         unless ($$tagTablePtr{$tag}) {
             $raf->Seek($size, 1);
@@ -205,5 +241,5 @@
         }
         $raf->Read($buff, $size) == $size or last;
-        $exifTool->HandleTag($tagTablePtr, $tag, undef,
+        $et->HandleTag($tagTablePtr, $tag, undef,
             DataPt  => \$buff,
             DataPos => $raf->Tell() - $size,
@@ -235,5 +271,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GPS.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GPS.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GPS.pm	(revision 34921)
@@ -13,5 +13,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.34';
+$VERSION = '1.52';
 
 my %coordConv = (
@@ -39,4 +39,9 @@
         Name => 'GPSLatitudeRef',
         Writable => 'string',
+        Notes => q{
+            tags 0x0001-0x0006 used for camera location according to MWG 2.0. ExifTool
+            will also accept a number when writing GPSLatitudeRef, positive for north
+            latitudes or negative for south, or a string ending in N or S
+        },
         Count => 2,
         PrintConv => {
@@ -46,6 +51,6 @@
                 my ($val, $inv) = @_;
                 return undef unless $inv;
-                return uc $1 if $val =~ /\b([NS])$/i;
-                return $1 eq '-' ? 'S' : 'N' if $val =~ /^([-+]?)\d+(\.\d*)?$/;
+                return uc $1 if $val =~ /\b([NS])\b/i;
+                return $1 eq '-' ? 'S' : 'N' if $val =~ /([-+]?)\d+/;
                 return undef;
             },
@@ -64,4 +69,8 @@
         Writable => 'string',
         Count => 2,
+        Notes => q{
+            ExifTool will also accept a number when writing this tag, positive for east
+            longitudes or negative for west, or a string ending in E or W
+        },
         PrintConv => {
             # extract E/W if written from Composite:GPSLongitude
@@ -70,6 +79,6 @@
                 my ($val, $inv) = @_;
                 return undef unless $inv;
-                return uc $1 if $val =~ /\b([EW])$/i;
-                return $1 eq '-' ? 'W' : 'E' if $val =~ /^([-+]?)\d+(\.\d*)?$/;
+                return uc $1 if $val =~ /\b([EW])\b/i;
+                return $1 eq '-' ? 'W' : 'E' if $val =~ /([-+]?)\d+/;
                 return undef;
             },
@@ -87,5 +96,14 @@
         Name => 'GPSAltitudeRef',
         Writable => 'int8u',
-        PrintConv => {
+        Notes => q{
+            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 =~ /^([-+0-9])/;
+                return($1 eq '-' ? 1 : 0);
+            },
             0 => 'Above Sea Level',
             1 => 'Below Sea Level',
@@ -107,13 +125,15 @@
         Shift => 'Time',
         Notes => q{
-            when writing, date is stripped off if present, and time is adjusted to UTC
-            if it includes a timezone
+            UTC time of GPS fix.  When writing, date is stripped off if present, and
+            time is adjusted to UTC if it includes a timezone
         },
         ValueConv => 'Image::ExifTool::GPS::ConvertTimeStamp($val)',
         ValueConvInv => '$val=~tr/:/ /;$val',
+        PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)',
         # pull time out of any format date/time string
         # (converting to UTC if a timezone is given)
         PrintConvInv => sub {
-            my $v = shift;
+            my ($v, $et) = @_;
+            $v = $et->TimeNow() if lc($v) eq 'now';
             my @tz;
             if ($v =~ s/([-+])(.*)//s) {    # remove timezone
@@ -210,9 +230,7 @@
         Name => 'GPSDestLatitudeRef',
         Writable => 'string',
-        Count => 2,
-        PrintConv => {
-            N => 'North',
-            S => 'South',
-        },
+        Notes => 'tags 0x0013-0x001a used for subject location according to MWG 2.0',
+        Count => 2,
+        PrintConv => { N => 'North', S => 'South' },
     },
     0x0014 => {
@@ -226,8 +244,5 @@
         Writable => 'string',
         Count => 2,
-        PrintConv => {
-            E => 'East',
-            W => 'West',
-        },
+        PrintConv => { E => 'East', W => 'West' },
     },
     0x0016 => {
@@ -268,5 +283,5 @@
         Writable => 'undef',
         Notes => 'values of "GPS", "CELLID", "WLAN" or "MANUAL" by the EXIF spec.',
-        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,1,$tag)',
         RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
     },
@@ -274,5 +289,5 @@
         Name => 'GPSAreaInformation',
         Writable => 'undef',
-        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,1,$tag)',
         RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
     },
@@ -281,11 +296,12 @@
         Groups => { 2 => 'Time' },
         Writable => 'string',
-        Notes => 'YYYY:mm:dd',
+        Format => 'undef', # (Casio EX-H20G uses "\0" instead of ":" as a separator)
         Count => 11,
         Shift => 'Time',
         Notes => q{
             when writing, time is stripped off if present, after adjusting date/time to
-            UTC if time includes a timezone
-        },
+            UTC if time includes a timezone.  Format is YYYY:mm:dd
+        },
+        RawConv => '$val =~ s/\0+$//; $val',
         ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
         ValueConvInv => '$val',
@@ -294,4 +310,5 @@
         PrintConvInv => q{
             my $secs;
+            $val = $self->TimeNow() if lc($val) eq 'now';
             if ($val =~ /[-+]/ and ($secs = Image::ExifTool::GetUnixTime($val, 1))) {
                 $val = Image::ExifTool::ConvertUnixTime($secs);
@@ -315,4 +332,6 @@
         Writable => 'rational64u',
     },
+    # 0xea1c - Nokia Lumina 1020, Samsung GT-I8750, and other Windows 8
+    #          phones write this (padding) in GPS IFD - PH
 );
 
@@ -352,5 +371,5 @@
     },
     GPSAltitude => {
-        SubDoc => 1,    # generate for all sub-documents
+        SubDoc => [1,3], # generate for sub-documents if Desire 1 or 3 has a chance to exist
         Desire => {
             0 => 'GPS:GPSAltitude',
@@ -364,11 +383,28 @@
             my $alt = $val[0];
             $alt = $val[2] unless defined $alt;
-            return undef unless defined $alt;
-            return ($val[1] || $val[3]) ? -$alt : $alt;
+            return undef unless defined $alt and IsFloat($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 => {
+        Require => {
+            0 => 'GPS:GPSDestLatitude',
+            1 => 'GPS:GPSDestLatitudeRef',
+        },
+        ValueConv => '$val[1] =~ /^S/i ? -$val[0] : $val[0]',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    },
+    GPSDestLongitude => {
+        SubDoc => 1,    # generate for all sub-documents
+        Require => {
+            0 => 'GPS:GPSDestLongitude',
+            1 => 'GPS:GPSDestLongitudeRef',
+        },
+        ValueConv => '$val[1] =~ /^W/i ? -$val[0] : $val[0]',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
     },
 );
@@ -388,12 +424,25 @@
     $h = int($f / 3600); $f -= $h * 3600;
     $m = int($f / 60);   $f -= $m * 60;
-    $s = int($f);        $f -= $s;
-    $f = int($f * 1000000 + 0.5);
-    if ($f) {
-        ($f = sprintf(".%.6d", $f)) =~ s/0+$//;
+    my $ss = sprintf('%012.9f', $f);
+    if ($ss >= 60) {
+        $ss = '00';
+        ++$m >= 60 and $m -= 60, ++$h;
     } else {
-        $f = ''
+        $ss =~ s/\.?0+$//;  # trim trailing zeros + decimal
     }
-    return sprintf("%.2d:%.2d:%.2d$f",$h,$m,$s);
+    return sprintf("%.2d:%.2d:%s",$h,$m,$ss);
+}
+
+#------------------------------------------------------------------------------
+# Print GPS timestamp
+# Inputs: 0) EXIF-formatted time string
+# Returns: time rounded to the nearest microsecond
+sub PrintTimeStamp($)
+{
+    my $val = shift;
+    return $val unless $val =~ s/:(\d{2}\.\d+)$//;
+    my $s = int($1 * 1000000 + 0.5) / 1000000;
+    $s = "0$s" if $s < 10;
+    return "${val}:$s";
 }
 
@@ -406,11 +455,19 @@
 sub ToDMS($$;$$)
 {
-    my ($exifTool, $val, $doPrintConv, $ref) = @_;
-    my ($fmt, $num);
-
+    my ($et, $val, $doPrintConv, $ref) = @_;
+    my ($fmt, @fmt, $num, $sign, $rtnVal);
+
+    unless (length $val) {
+        # don't convert an empty value
+        return $val if $doPrintConv and $doPrintConv eq '1';  # avoid hiding existing tag when extracting
+        return undef; # avoid writing empty value
+    }
     if ($ref) {
         if ($val < 0) {
             $val = -$val;
             $ref = {N => 'S', E => 'W'}->{$ref};
+            $sign = '-';
+        } else {
+            $sign = '+';
         }
         $ref = " $ref" unless $doPrintConv and $doPrintConv eq '2';
@@ -421,24 +478,51 @@
     if ($doPrintConv) {
         if ($doPrintConv eq '1') {
-            $fmt = ($exifTool->Options('CoordFormat') || q{%d deg %d' %.2f"}) . $ref;
+            $fmt = $et->Options('CoordFormat');
+            if (not $fmt) {
+                $fmt = q{%d deg %d' %.2f"} . $ref;
+            } elsif ($ref) {
+                # use signed value instead of reference direction if specified
+                $fmt =~ s/%\+/$sign%/g or $fmt .= $ref;
+            } else {
+                $fmt =~ s/%\+/%/g;  # don't know sign, so don't print it
+            }
         } else {
-            $fmt = "%d,%.6f$ref";   # use XMP standard format
+            $fmt = "%d,%.8f$ref";   # use XMP format with 8 decimal minutes
         }
-        # count the number of format specifiers
-        $num = ($fmt =~ tr/%/%/);
+        # count (and capture) the format specifiers (max 3)
+        while ($fmt =~ /(%(%|[^%]*?[diouxXDOUeEfFgGcs]))/g) {
+            next if $1 eq '%%';
+            push @fmt, $1;
+            last if @fmt >= 3;
+        }
+        $num = scalar @fmt;
     } else {
         $num = 3;
     }
-    my ($d, $m, $s);
-    $d = $val;
+    my @c;  # coordinates (D) or (D,M) or (D,M,S)
+    $c[0] = $val;
     if ($num > 1) {
-        $d = int($d);
-        $m = ($val - $d) * 60;
+        $c[0] = int($c[0]);
+        $c[1] = ($val - $c[0]) * 60;
         if ($num > 2) {
-            $m = int($m);
-            $s = ($val - $d - $m / 60) * 3600;
+            $c[1] = int($c[1]);
+            $c[2] = ($val - $c[0] - $c[1] / 60) * 3600;
+        }
+        # handle round-off errors to ensure minutes and seconds are
+        # less than 60 (eg. convert "72 59 60.00" to "73 0 0.00")
+        $c[-1] = $doPrintConv ? sprintf($fmt[-1], $c[-1]) : ($c[-1] . '');
+        if ($c[-1] >= 60) {
+            $c[-1] -= 60;
+            ($c[-2] += 1) >= 60 and $num > 2 and $c[-2] -= 60, $c[-3] += 1;
         }
     }
-    return $doPrintConv ? sprintf($fmt, $d, $m, $s) : "$d $m $s$ref";
+    if ($doPrintConv) {
+        $rtnVal = sprintf($fmt, @c);
+        # trim trailing zeros in XMP
+        $rtnVal =~ s/(\d)0+$ref$/$1$ref/ if $doPrintConv eq '2';
+    } else {
+        $rtnVal = "@c$ref";
+    }
+    return $rtnVal;
 }
 
@@ -451,7 +535,9 @@
 {
     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);
-    my $deg = ($d || 0) + (($m || 0) + ($s || 0)/60) / 60;
+    return '' unless defined $d;
+    my $deg = $d + (($m || 0) + ($s || 0)/60) / 60;
     # make negative if S or W coordinate
     $deg = -$deg if $doSign ? $val =~ /[^A-Z](S|W)$/i : $deg < 0;
@@ -479,5 +565,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GeoTiff.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GeoTiff.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GeoTiff.pm	(revision 34921)
@@ -5,8 +5,11 @@
 #
 # Revisions:    02/23/2004 - P. Harvey Created
-#               02/25/2004 - P. Harvey Added new codes from libgeotiff-1.2.1
-#               02/01/2007 - P. Harvey Added new codes from libgeotiff-1.2.3
+#               02/25/2004 - PH Added new codes from libgeotiff-1.2.1
+#               02/01/2007 - PH Added new codes from libgeotiff-1.2.3
+#               01/22/2014 - PH Added new code from libgeotiff-1.4.0
+#               01/19/2015 - PH Added ChartTIFF tags
 #
-# Reference:    ftp://ftp.remotesensing.org/geotiff/libgeotiff/libgeotiff-1.1.4.tar.gz
+# References:   1) ftp://ftp.remotesensing.org/geotiff/libgeotiff/libgeotiff-1.1.4.tar.gz
+#               2) http://www.charttiff.com/whitepapers.shtml
 #------------------------------------------------------------------------------
 
@@ -17,9 +20,10 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.07';
+$VERSION = '1.12';
 
 # format codes for geoTiff directory entries
 my %geoTiffFormat = (
-    0      => 'int16u',
+    0      => 'int16u', # (value is stored in offset, and count is 1)
+    0x87af => 'int16u', # (value is stored after directory)
     0x87b0 => 'double',
     0x87b1 => 'string',
@@ -50,4 +54,47 @@
     9107 => 'Angular DMS',
     9108 => 'Angular DMS Hemisphere',
+    32767 => 'User Defined',
+);
+
+my %epsg_vertcs = (
+    0 => 'Undefined',
+    5001 => 'Airy 1830 ellipsoid',
+    5002 => 'Airy Modified 1849 ellipsoid',
+    5003 => 'ANS ellipsoid',
+    5004 => 'Bessel 1841 ellipsoid',
+    5005 => 'Bessel Modified ellipsoid',
+    5006 => 'Bessel Namibia ellipsoid',
+    5007 => 'Clarke 1858 ellipsoid',
+    5008 => 'Clarke 1866 ellipsoid',
+    5010 => 'Clarke 1880 Benoit ellipsoid',
+    5011 => 'Clarke 1880 IGN ellipsoid',
+    5012 => 'Clarke 1880 RGS ellipsoid',
+    5013 => 'Clarke 1880 Arc ellipsoid',
+    5014 => 'Clarke 1880 SGA 1922 ellipsoid',
+    5015 => 'Everest 1830 1937 Adjustment ellipsoid',
+    5016 => 'Everest 1830 1967 Definition ellipsoid',
+    5017 => 'Everest 1830 1975 Definition ellipsoid',
+    5018 => 'Everest 1830 Modified ellipsoid',
+    5019 => 'GRS 1980 ellipsoid',
+    5020 => 'Helmert 1906 ellipsoid',
+    5021 => 'INS ellipsoid',
+    5022 => 'International 1924 ellipsoid',
+    5023 => 'International 1967 ellipsoid',
+    5024 => 'Krassowsky 1940 ellipsoid',
+    5025 => 'NWL 9D ellipsoid',
+    5026 => 'NWL 10D ellipsoid',
+    5027 => 'Plessis 1817 ellipsoid',
+    5028 => 'Struve 1860 ellipsoid',
+    5029 => 'War Office ellipsoid',
+    5030 => 'WGS 84 ellipsoid',
+    5031 => 'GEM 10C ellipsoid',
+    5032 => 'OSU86F ellipsoid',
+    5033 => 'OSU91A ellipsoid',
+    5101 => 'Newlyn',
+    5102 => 'North American Vertical Datum 1929',
+    5103 => 'North American Vertical Datum 1988',
+    5104 => 'Yellow Sea 1956',
+    5105 => 'Baltic Sea',
+    5106 => 'Caspian Sea',
     32767 => 'User Defined',
 );
@@ -505,4 +552,5 @@
     },
     2061 => 'GeogPrimeMeridianLong',
+    2062 => 'GeogToWGS84',
     3072 => {
         Name => 'ProjectedCSType',
@@ -526,4 +574,6 @@
             3057 => 'ISN93 Lambert 1993',
             3300 => 'Estonian Coordinate System of 1992',
+            3786 => 'Popular Visualisation CRS / Mercator', #PH (NC)
+            3857 => 'WGS 84 / Pseudo-Mercator', #PH (NC)
             20137 => 'Adindan UTM zone 37N',
             20138 => 'Adindan UTM zone 38N',
@@ -556,5 +606,5 @@
             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',
@@ -2006,54 +2056,12 @@
     4096 => {
         Name => 'VerticalCSType',
-        PrintConv => {
-            # epsg_vertcs
-            5001 => 'Airy 1830 ellipsoid',
-            5002 => 'Airy Modified 1849 ellipsoid',
-            5003 => 'ANS ellipsoid',
-            5004 => 'Bessel 1841 ellipsoid',
-            5005 => 'Bessel Modified ellipsoid',
-            5006 => 'Bessel Namibia ellipsoid',
-            5007 => 'Clarke 1858 ellipsoid',
-            5008 => 'Clarke 1866 ellipsoid',
-            5010 => 'Clarke 1880 Benoit ellipsoid',
-            5011 => 'Clarke 1880 IGN ellipsoid',
-            5012 => 'Clarke 1880 RGS ellipsoid',
-            5013 => 'Clarke 1880 Arc ellipsoid',
-            5014 => 'Clarke 1880 SGA 1922 ellipsoid',
-            5015 => 'Everest 1830 1937 Adjustment ellipsoid',
-            5016 => 'Everest 1830 1967 Definition ellipsoid',
-            5017 => 'Everest 1830 1975 Definition ellipsoid',
-            5018 => 'Everest 1830 Modified ellipsoid',
-            5019 => 'GRS 1980 ellipsoid',
-            5020 => 'Helmert 1906 ellipsoid',
-            5021 => 'INS ellipsoid',
-            5022 => 'International 1924 ellipsoid',
-            5023 => 'International 1967 ellipsoid',
-            5024 => 'Krassowsky 1940 ellipsoid',
-            5025 => 'NWL 9D ellipsoid',
-            5026 => 'NWL 10D ellipsoid',
-            5027 => 'Plessis 1817 ellipsoid',
-            5028 => 'Struve 1860 ellipsoid',
-            5029 => 'War Office ellipsoid',
-            5030 => 'WGS 84 ellipsoid',
-            5031 => 'GEM 10C ellipsoid',
-            5032 => 'OSU86F ellipsoid',
-            5033 => 'OSU91A ellipsoid',
-            5101 => 'Newlyn',
-            5102 => 'North American Vertical Datum 1929',
-            5103 => 'North American Vertical Datum 1988',
-            5104 => 'Yellow Sea 1956',
-            5105 => 'Baltic Sea',
-            5106 => 'Caspian Sea',
-            32767 => 'User Defined',
-        },
+        SeparateTable => 'VerticalCS',
+        PrintConv => \%epsg_vertcs,
     },
     4097 => 'VerticalCitation',
     4098 => {
         Name => 'VerticalDatum',
-        PrintConv => {
-            1 => 'Vertical Datum Base',
-            32767 => 'User Defined',
-        },
+        SeparateTable => 'VerticalCS',
+        PrintConv => \%epsg_vertcs,
     },
     4099 => {
@@ -2062,4 +2070,60 @@
         PrintConv => \%epsg_units,
     },
+#
+# ChartTiff extensions (ref 2)
+#
+    47001 => {
+        Name => 'ChartFormat',
+        PrintConv => {
+            47500 => 'General',
+            47501 => 'Coastal',
+            47502 => 'Harbor',
+            47503 => 'SailingInternational',
+            47504 => 'SmallCraft Route',
+            47505 => 'SmallCraftArea',
+            47506 => 'SmallCraftFolio',
+            47507 => 'Topographic',
+            47508 => 'Recreation',
+            47509 => 'Index',
+            47510 => 'Inset',
+        },
+    },
+    47002 => 'ChartSource',
+    47003 => 'ChartSourceEdition',
+    47004 => 'ChartSourceDate',
+    47005 => 'ChartCorrDate',
+    47006 => 'ChartCountryOrigin',
+    47007 => 'ChartRasterEdition',
+    47008 => {
+        Name => 'ChartSoundingDatum',
+        PrintConv => {
+            47600 => 'Equatorial Spring Low Water',
+            47601 => 'Indian Spring Low Water',
+            47602 => 'Lowest Astronomical Tide',
+            47603 => 'Lowest Low Water',
+            47604 => 'Lowest Normal Low Water',
+            47605 => 'Mean Higher High Water',
+            47606 => 'Mean High Water',
+            47607 => 'Mean High Water Springs',
+            47608 => 'Mean Lower Low Water',
+            47609 => 'Mean Lower Low Water Springs',
+            47610 => 'Mean Low Water',
+            47611 => 'Mean Sea Level',
+            47612 => 'Tropic Higher High Water',
+            47613 => 'Tropic Lower Low Water',
+        },
+    },
+    47009 => {
+        Name => 'ChartDepthUnits',
+        SeparateTable => 'Units',
+        PrintConv => \%epsg_units,
+    },
+    47010 => 'ChartMagVar',
+    47011 => 'ChartMagVarYear',
+    47012 => 'ChartMagVarAnnChange',
+    47013 => 'ChartWGSNSShift',
+    47015 => 'InsetNWPixelX',
+    47016 => 'InsetNWPixelY',
+    47017 => 'ChartContourInterval',
 );
 
@@ -2069,11 +2133,15 @@
 sub ProcessGeoTiff($)
 {
-    my $exifTool = shift;
-    my $dirData = $exifTool->GetValue('GeoTiffDirectory', 'ValueConv') or return;
-    my $doubleData = $exifTool->GetValue('GeoTiffDoubleParams', 'ValueConv');
-    my $asciiData = $exifTool->GetValue('GeoTiffAsciiParams', 'ValueConv');
-    my $verbose = $exifTool->Options('Verbose');
-
-    # restore or original EXIF byte order setting
+    my $et = shift;
+    my $dirData = $et->GetValue('GeoTiffDirectory', 'ValueConv') or return;
+
+    # avoid re-processing if another EXIF directory is found
+    $$et{DidGeoTiff} and $$et{DidGeoTiff} eq $dirData and return;
+    $$et{DidGeoTiff} = $dirData;
+
+    my $doubleData = $et->GetValue('GeoTiffDoubleParams', 'ValueConv');
+    my $asciiData = $et->GetValue('GeoTiffAsciiParams', 'ValueConv');
+    my $verbose = $et->Options('Verbose');
+
     if (length($$dirData) >= 8 and
         length($$dirData) >= 8 * (Get16u($dirData,6) + 1))
@@ -2085,11 +2153,11 @@
 
         if ($verbose) {
-            $exifTool->{INDENT} .= '| ';
-            $exifTool->VerboseDir('GeoTiff',$numEntries);
+            $$et{INDENT} .= '| ';
+            $et->VerboseDir('GeoTiff',$numEntries);
         }
         # generate version number tag (not a real GeoTiff tag)
         my $tagTable = GetTagTable("Image::ExifTool::GeoTiff::Main");
-        my $tagInfo = $exifTool->GetTagInfo($tagTable, 1);
-        $tagInfo and $exifTool->FoundTag($tagInfo,"$version.$revision.$minorRev");
+        my $tagInfo = $et->GetTagInfo($tagTable, 1);
+        $tagInfo and $et->FoundTag($tagInfo,"$version.$revision.$minorRev");
 
         my $i;
@@ -2097,5 +2165,5 @@
             my $pt = 8 * ($i + 1);
             my $tag    = Get16u($dirData, $pt);
-            $tagInfo   = $exifTool->GetTagInfo($tagTable, $tag) or next;
+            $tagInfo   = $et->GetTagInfo($tagTable, $tag) or next;
             my $loc    = Get16u($dirData, $pt+2);
             my $count  = Get16u($dirData, $pt+4);
@@ -2103,22 +2171,29 @@
             my $format = $geoTiffFormat{$loc};
             my ($val, $dataPt);
-            if ($format eq 'double') {          # in the double parms
+            if (not $format) {
+                $et->Warn("Unknown GeoTiff location ($loc) for $$tagInfo{Name}");
+                next;
+            } elsif ($format eq 'double') {     # in the double parms
                 $dataPt = $doubleData;
-                $offset *= 8;
-                $val = Image::ExifTool::ReadValue($dataPt, $offset, $format,
-                                                  $count, length($$doubleData)-$offset);
             } elsif ($format eq 'string') {     # in the ASCII parms
                 $dataPt = $asciiData;
-                $val = substr($$dataPt, $offset, $count);
-                $val =~ s/(\0|\|)$//;   # remove trailing terminator (NULL or '|')
-            } elsif ($format eq 'int16u') {     # use the offset as the value
+            } elsif ($format eq 'int16u') {     # in the GeoTiffDirectory data
                 $dataPt = $dirData;
-                $val = $offset;
-                $offset = $pt+6;
-            } else {
-                $exifTool->Warn("Unknown GeoTiff location: $loc");
+                unless ($loc) {                 # is value is stored in offset?
+                    $count = 1;                 # (implied by location of 0)
+                    $offset = ($pt + 6) / 2;    # offset of the "offset" value
+                }
+            }
+            my $size = Image::ExifTool::FormatSize($format);
+            if (not $dataPt or length($$dataPt) < $size*($offset+$count)) {
+                $et->Warn("Missing $format data for $$tagInfo{Name}");
                 next;
             }
-            $verbose and $exifTool->VerboseInfo($tag, $tagInfo,
+            $offset *= $size;
+            $val = Image::ExifTool::ReadValue($dataPt, $offset, $format,
+                                              $count, length($$dataPt)-$offset);
+            # remove trailing terminator (NULL or '|') from string value
+            $val =~ s/(\0|\|)$// if $format eq 'string';
+            $verbose and $et->VerboseInfo($tag, $tagInfo,
                 'Table'  => $tagTable,
                 'Index'  => $i,
@@ -2128,19 +2203,20 @@
                 'Format' => $format,
                 'Count'  => $count,
-                'Size'   => $count * Image::ExifTool::FormatSize($format),
+                'Size'   => $count * $size,
             );
-            $exifTool->FoundTag($tagInfo, $val);
+            $et->FoundTag($tagInfo, $val);
         }
         if ($verbose) {
-            $exifTool->{INDENT} =~ s/..$//;
+            $$et{INDENT} =~ s/..$//;
         }
     } else {
-        $exifTool->Warn('Bad GeoTIFF directory');
+        $et->Warn('Bad GeoTIFF directory');
     }
-    # must delete these tags once we've processed this information
-    # (to avoid re-processing if another EXIF directory is found)
-    $exifTool->DeleteTag('GeoTiffDirectory');
-    $exifTool->DeleteTag('GeoTiffDoubleParams');
-    $exifTool->DeleteTag('GeoTiffAsciiParams');
+    # extract block tags only if requested
+    unless ($$et{OPTIONS}{RequestAll}) {
+        $et->DeleteTag('GeoTiffDirectory')    unless $$et{REQ_TAG_LOOKUP}{geotiffdirectory};
+        $et->DeleteTag('GeoTiffDoubleParams') unless $$et{REQ_TAG_LOOKUP}{geotiffdoubleparams};
+        $et->DeleteTag('GeoTiffAsciiParams')  unless $$et{REQ_TAG_LOOKUP}{geotiffasciiparams};
+    }
 }
 
@@ -2167,5 +2243,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -2178,4 +2254,6 @@
 =item ftp://ftp.remotesensing.org/geotiff/libgeotiff/libgeotiff-1.1.4.tar.gz
 
+=item http://www.charttiff.com/whitepapers.shtml
+
 =back
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Geotag.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Geotag.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Geotag.pm	(revision 34921)
@@ -6,4 +6,13 @@
 # Revisions:    2009/04/01 - P. Harvey Created
 #               2009/09/27 - PH Added Geosync feature
+#               2009/06/25 - PH Read Garmin TCX track logs
+#               2009/09/11 - PH Read ITC GPS track logs
+#               2012/01/08 - PH Extract orientation information from PTNTHPR
+#               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
+#               2020/12/01 - PH Added ability to read DJI CSV log files
 #
 # References:   1) http://www.topografix.com/GPX/1/1/
@@ -18,8 +27,14 @@
 use vars qw($VERSION);
 use Image::ExifTool qw(:Public);
-
-$VERSION = '1.24';
-
+use Image::ExifTool::GPS;
+
+$VERSION = '1.64';
+
+sub JITTER() { return 2 }       # maximum time jitter
+
+sub GetTime($);
 sub SetGeoValues($$;$);
+sub PrintFixTime($);
+sub PrintFix($@);
 
 # XML tags that we recognize (keys are forced to lower case)
@@ -42,6 +57,13 @@
     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
+    begin       => 'begin',     # KML TimeSpan
+    end         => 'time',      # KML TimeSpan
+    course      => 'dir',       # (written by Arduino)
+    pitch       => 'pitch',     # (written by Arduino)
+    roll        => 'roll',      # (written by Arduino)
     # XML containers (fix is reset at the opening tag of these properties)
     wpt         => '',          # GPX
@@ -50,4 +72,28 @@
     trackpoint  => '',          # Garmin
     placemark   => '',          # KML
+);
+
+# fix information keys which must be interpolated around a circle
+my %cyclical = (lon => 1, track => 1, dir => 1, roll => 1);
+
+# fix information keys for each of our general categories
+my %fixInfoKeys = (
+   'pos'   => [ 'lat', 'lon' ],
+    track  => [ 'track', 'speed' ],
+    alt    => [ 'alt' ],
+    orient => [ 'dir', 'pitch', 'roll' ],
+    atemp  => [ 'atemp' ],
+);
+
+my %isOrient = ( dir => 1, pitch => 1, roll => 1 ); # test for orientation key
+
+# conversion factors for GPSSpeed
+my %speedConv = (
+    'K' => 1.852,       # km/h per knot
+    'M' => 1.150779448, # mph per knot
+    'k' => 'K',         # (allow lower case)
+    'm' => 'M',
+    'km/h' => 'K',      # (allow other formats)
+    'mph' => 'M',
 );
 
@@ -63,4 +109,5 @@
 #       NoDate - flag if some points have no date (ie. referenced to 1970:01:01)
 #       IsDate - flag if some points have date
+#       Has    - hash of flags for available information (track, orient, alt)
 # - the fix information hash may contain:
 #       lat    - signed latitude (required)
@@ -74,4 +121,9 @@
 #       sats   - comma-separated list of active satellites
 #       nsats  - number of active satellites
+#       track  - track heading (deg true)
+#       dir    - image direction (deg true)
+#       pitch  - pitch angle (deg)
+#       roll   - roll angle (deg)
+#       speed  - speed (knots)
 #       first  - flag set for first fix of track
 # - concatenates new data with existing track data stored in ExifTool NEW_VALUE
@@ -80,16 +132,26 @@
 {
     local ($_, $/, *EXIFTOOL_TRKFILE);
-    my ($exifTool, $val) = @_;
+    my ($et, $val) = @_;
     my ($raf, $from, $time, $isDate, $noDate, $noDateChanged, $lastDate, $dateFlarm);
-    my ($nmeaStart, $fixSecs, @fixTimes, $canCut, $cutPDOP, $cutHDOP, $cutSats, $lastFix);
-
-    unless (eval 'require Time::Local') {
+    my ($nmeaStart, $fixSecs, @fixTimes, $lastFix, %nmea, @csvHeadings);
+    my ($canCut, $cutPDOP, $cutHDOP, $cutSats, $e0, $e1, @tmp, $trackFile, $trackTime);
+
+    unless (eval { require Time::Local }) {
         return 'Geotag feature requires Time::Local installed';
     }
     # add data to existing track
-    my $geotag = $exifTool->GetNewValues('Geotag') || { };
+    my $geotag = $et->GetNewValue('Geotag') || { };
+
+    # initialize track points lookup
+    my $points = $$geotag{Points};
+    $points or $points = $$geotag{Points} = { };
+
+    # get lookup for available information types
+    my $has = $$geotag{Has};
+    $has or $has = $$geotag{Has} = { 'pos' => 1 };
+
     my $format = '';
     # is $val track log data?
-    if ($val =~ /^(\xef\xbb\xbf)?<(\?xml|gpx)\s/) {
+    if ($val =~ /^(\xef\xbb\xbf)?<(\?xml|gpx)[\s>]/) {
         $format = 'XML';
         $/ = '>';   # set input record separator to '>' for XML/GPX data
@@ -98,22 +160,31 @@
     } else {
         # $val is track file name
-        open EXIFTOOL_TRKFILE, $val or return "Error opening GPS file '$val'";
-        $raf = new File::RandomAccess(\*EXIFTOOL_TRKFILE);
-        unless ($raf->Read($_, 256)) {
-            close EXIFTOOL_TRKFILE;
-            return "Empty track file '$val'";
-        }
-        # look for XML or GPX header (might as well allow UTF-8 BOM)
-        if (/^(\xef\xbb\xbf)?<(\?xml|gpx)\s/) {
-            $format = 'XML';
-            $/ = '>';   # set input record separator to '>' for XML/GPX data
-        } elsif (/(\x0d\x0a|\x0d|\x0a)/) {
-            $/ = $1;
+        if ($et->Open(\*EXIFTOOL_TRKFILE, $val)) {
+            $trackFile = $val;
+            $raf = new File::RandomAccess(\*EXIFTOOL_TRKFILE);
+            unless ($raf->Read($_, 256)) {
+                close EXIFTOOL_TRKFILE;
+                return "Empty track file '${val}'";
+            }
+            # look for XML or GPX header (might as well allow UTF-8 BOM)
+            if (/^(\xef\xbb\xbf)?<(\?xml|gpx)[\s>]/) {
+                $format = 'XML';
+                $/ = '>';   # set input record separator to '>' for XML/GPX data
+            } elsif (/(\x0d\x0a|\x0d|\x0a)/) {
+                $/ = $1;
+            } else {
+                close EXIFTOOL_TRKFILE;
+                return "Invalid track file '${val}'";
+            }
+            $raf->Seek(0,0);
+            $from = "file '${val}'";
+        } elsif ($val eq 'DATETIMEONLY') {
+            $$geotag{DateTimeOnly} = 1;
+            $$geotag{IsDate} = 1;
+            $et->VPrint(0, 'Geotagging date/time only');
+            return $geotag;
         } else {
-            close EXIFTOOL_TRKFILE;
-            return "Invalid track file '$val'";
-        }
-        $raf->Seek(0,0);
-        $from = "file '$val'";
+            return "Error opening GPS file '${val}'";
+        }
     }
     unless ($from) {
@@ -122,12 +193,9 @@
         $from = 'data';
     }
-    # initialize track points lookup
-    my $points = $$geotag{Points};
-    $points or $points = $$geotag{Points} = { };
 
     # initialize cuts
-    my $maxHDOP = $exifTool->Options('GeoMaxHDOP');
-    my $maxPDOP = $exifTool->Options('GeoMaxPDOP');
-    my $minSats = $exifTool->Options('GeoMinSats');
+    my $maxHDOP = $et->Options('GeoMaxHDOP');
+    my $maxPDOP = $et->Options('GeoMaxPDOP');
+    my $minSats = $et->Options('GeoMinSats');
     my $isCut = $maxHDOP || $maxPDOP || $minSats;
 
@@ -136,11 +204,16 @@
     my $lastSecs = 0;
     my $fix = { };
+    my $csvDelim = $et->Options('CSVDelim');
+    $csvDelim = ',' unless defined $csvDelim;
+    my (@saveFix, $timeSpan);
     for (;;) {
         $raf->ReadLine($_) or last;
         # determine file format
         if (not $format) {
-            if (/^<(\?xml|gpx)\s/) { # look for XML or GPX header
+            if (/^<(\?xml|gpx)[\s>]/) { # look for XML or GPX header
                 $format = 'XML';
-            } elsif (/^\$(PMGNTRK|GP(RMC|GGA|GLL|GSA)),/) {
+            # 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),/) {
                 $format = 'NMEA';
                 $nmeaStart = $2 || $1;    # save type of first sentence
@@ -149,7 +222,7 @@
                 $nmeaStart = 'B' ;
                 next;
-            } elsif (/^HFDTE(\d{2})(\d{2})(\d{2})/) {
+            } elsif (/^HFDTE(?:DATE:)?(\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';
@@ -157,5 +230,57 @@
             } elsif ($nmeaStart and /^B/) {
                 # parse IGC fixes without a date
-                $format = 'IGC';                
+                $format = 'IGC';
+            } elsif (/^TP,D,/) {
+                $format = 'Winplus';
+            } elsif (/^\s*\d+\s+.*\sypr\s*$/ and (@tmp=split) == 12) {
+                $format = 'Bramor';
+            } elsif (((/\b(GPS)?Date/i and /\b(GPS)?(Date)?Time/i) or /\bTime\(seconds\)/i) and /\Q$csvDelim/) {
+                chomp;
+                @csvHeadings = split /\Q$csvDelim/;
+                $format = 'CSV';
+                # convert recognized headings to our parameter names
+                foreach (@csvHeadings) {
+                    my $param;
+                    s/^GPS ?//; # remove leading "GPS" to simplify regex patterns
+                    if (/^Time ?\(seconds\)$/i) { # DJI
+                        # DJI CSV log files have a column "Time(seconds)" which is seconds since
+                        # the start of the flight.  The date/time is obtained from the file name.
+                        $param = 'runtime';
+                        if ($trackFile and $trackFile =~ /(\d{4})-(\d{2})-(\d{2})[^\/]+(\d{2})-(\d{2})-(\d{2})[^\/]*$/) {
+                            $trackTime = Image::ExifTool::TimeLocal($6,$5,$4,$3,$2-1,$1);
+                            my $utc = PrintFixTime($trackTime);
+                            my $tzs = Image::ExifTool::TimeZoneString([$6,$5,$4,$3,$2-1,$1-1900],$trackTime);
+                            $et->VPrint(2, "  DJI start time:  $utc (local timezone is $tzs)\n");
+                        } else {
+                            return 'Error getting start time from file name for DJI CSV track file';
+                        }
+                    } elsif (/^Date ?Time/i) {  # ExifTool addition
+                        $param = 'datetime';
+                    } elsif (/^Date/i) {
+                        $param = 'date';
+                    } elsif (/^Time(?! ?\(text\))/i) { # (ignore DJI "Time(text)" column)
+                        $param = 'time';
+                    } elsif (/^(Pos)?Lat/i) {
+                        $param = 'lat';
+                    } elsif (/^(Pos)?Lon/i) {
+                        $param = 'lon';
+                    } elsif (/^(Pos)?Alt/i) {
+                        $param = 'alt';
+                    } elsif (/^(Angle)?(Heading|Track)/i) {
+                        $param = 'track';
+                    } elsif (/^(Angle)?Pitch/i or /^Camera ?Elevation ?Angle/i) {
+                        $param = 'pitch';
+                    } elsif (/^(Angle)?Roll/i) {
+                        $param = 'roll';
+                    }
+                    if ($param) {
+                        $et->VPrint(2, "CSV column '${_}' is $param\n");
+                        $_ = $param;
+                    } else {
+                        $et->VPrint(2, "CSV column '${_}' ignored\n");
+                        $_ = '';    # ignore this column
+                    }
+                }
+                next;
             } else {
                 # search only first 50 lines of file for a valid fix
@@ -170,10 +295,24 @@
             my ($arg, $tok, $td);
             s/\s*=\s*(['"])\s*/=$1/g;  # remove unnecessary white space in attributes
+            # Workaround for KML generated by Google Location History:
+            # lat/lon/alt are space-separated; we want commas.
+            s{(\S+)\s+(\S+)\s+(\S+)(</gx:coord>)}{$1,$2,$3$4};
             foreach $arg (split) {
-                # parse attributes (ie. GPX 'lat' and 'lon')
+                # parse attributes (eg. GPX 'lat' and 'lon')
                 # (note: ignore namespace prefixes if they exist)
                 if ($arg =~ /^(\w+:)?(\w+)=(['"])(.*?)\3/g) {
                     my $tag = $xmlTag{lc $2};
-                    $$fix{$tag} = $4 if $tag;
+                    if ($tag) {
+                        $$fix{$tag} = $4;
+                        if ($isOrient{$tag}) {
+                            $$has{orient} = 1;
+                        } elsif ($tag eq 'alt') {
+                            # 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;
+                        }
+                    }
                 }
                 # loop through XML elements
@@ -186,4 +325,5 @@
                             # opened: start a new fix
                             $lastFix = $fix = { };
+                            undef @saveFix;
                             next;
                         } elsif ($fix and $lastFix and %$fix) {
@@ -198,8 +338,21 @@
                         if ($tag) {
                             if ($tag eq 'coords') {
+                                # save other fixes if there are more than one
+                                if (defined $$fix{lon} and defined $$fix{lat} and defined $$fix{alt}) {
+                                    push @saveFix, [ @$fix{'lon','lat','alt'} ];
+                                }
                                 # read KML "Point" coordinates
                                 @$fix{'lon','lat','alt'} = split ',', $1;
                             } else {
                                 $$fix{$tag} = $1;
+                                if ($isOrient{$tag}) {
+                                    $$has{orient} = 1;
+                                } elsif ($tag eq 'alt') {
+                                    # 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;
+                                }
                             }
                         }
@@ -209,29 +362,41 @@
                     }
                     # validate and store GPS fix
-                    if (defined $$fix{lat} and defined $$fix{lon} and $$fix{'time'} and
-                        $$fix{lat} =~ /^[+-]?\d+\.?\d*/ and
-                        $$fix{lon} =~ /^[+-]?\d+\.?\d*/ and
-                        $$fix{'time'} =~ /^(\d{4})-(\d+)-(\d+)T(\d+):(\d+):(\d+)(\.\d+)?(.*)/)
-                    {
-                        $time = Time::Local::timegm($6,$5,$4,$3,$2-1,$1-1900);
-                        $time += $7 if $7;  # add fractional seconds
-                        my $tz = $8;
-                        # adjust for time zone (otherwise assume UTC)
-                        # - allow timezone of +-HH:MM, +-H:MM, +-HHMM or +-HH since
-                        #   the spec is unclear about timezone format
-                        if ($tz =~ /^([-+])(\d+):(\d{2})\b/ or $tz =~ /^([-+])(\d{2})(\d{2})?\b/) {
-                            $tz = ($2 * 60 + ($3 || 0)) * 60;
-                            $tz *= -1 if $1 eq '+'; # opposite sign to change back to UTC
-                            $time += $tz;
+                    next unless defined $$fix{lat} and defined $$fix{lon} and $$fix{'time'};
+                    unless ($$fix{lat} =~ /^[+-]?\d+\.?\d*/ and $$fix{lon} =~ /^[+-]?\d+\.?\d*/) {
+                        $e0 or $et->VPrint(0, "Coordinate format error in $from\n"), $e0 = 1;
+                        next;
+                    }
+                    unless (defined($time = GetTime($$fix{'time'}))) {
+                        $e1 or $et->VPrint(0, "Timestamp format error in $from\n"), $e1 = 1;
+                        next;
+                    }
+                    $isDate = 1;
+                    $canCut= 1 if defined $$fix{pdop} or defined $$fix{hdop} or defined $$fix{nsats};
+                    # generate extra fixes assuming an equally spaced track
+                    if ($$fix{begin}) {
+                        my $begin = GetTime($$fix{begin});
+                        undef $$fix{begin};
+                        if (defined $begin and $begin < $time) {
+                            $$fix{span} = $timeSpan = ($timeSpan || 0) + 1;
+                            my $i;
+                            # duplicate the fix if there is only one so we will have
+                            # a fix and the start and end of the TimeSpan
+                            @saveFix or push @saveFix, [ @$fix{'lon','lat','alt'} ];
+                            for ($i=0; $i<@saveFix; ++$i) {
+                                my $t = $begin + ($time - $begin) * ($i / scalar(@saveFix));
+                                my %f;
+                                @f{'lon','lat','alt'} = @{$saveFix[$i]};
+                                $t += 0.001 if not $i and $$points{$t}; # (avoid dupicates)
+                                $f{span} = $timeSpan;
+                                $$points{$t} = \%f;
+                                push @fixTimes, $t;
+                            }
                         }
-                        # validate altitude
-                        undef $$fix{alt} if defined $$fix{alt} and $$fix{alt} !~ /^[+-]?\d+\.?\d*/;
-                        $isDate = 1;
-                        $canCut= 1 if defined $$fix{pdop} or defined $$fix{hdop} or defined $$fix{nsats};
-                        $$points{$time} = $fix;
-                        push @fixTimes, $time;  # save times of all fixes in order
-                        $fix = { };
-                        ++$numPoints;
                     }
+                    $$points{$time} = $fix;
+                    push @fixTimes, $time;  # save times of all fixes in order
+                    $fix = { };
+                    undef @saveFix;
+                    ++$numPoints;
                 }
             }
@@ -240,15 +405,107 @@
                 /[\s>](\d{4}-\d{2}-\d{2})[T ](\d{2}:\d{2}:\d{2}(\.\d+)?)/;
             next;
+#
+# Winplus Beacon text file
+#
+        } elsif ($format eq 'Winplus') {
+            # TP,D, 44.933666667, -93.186555556, 10/26/2011, 19:07:28, 0
+            #       latitude      longitude      date        time
+            /^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);
+DoneFix:    $isDate = 1;
+            $$points{$time} = $fix;
+            push @fixTimes, $time;
+            $fix = { };
+            ++$numPoints;
+            next;
+#
+# Bramor gEO log file
+#
+        } elsif ($format eq 'Bramor') {
+            #   1 0015   18.723675   50.672752  149 169.31 22/04/2015 07:06:55 169.31    8.88   28.07 ypr
+            #   ? index  latitude    longitude  alt track  date       time     dir       pitch  roll
+            my @parts = split ' ', $_;
+            next unless @parts == 12 and $parts[11] eq 'ypr';
+            my @d = split m{/}, $parts[6];  # date (dd/mm/YYYY)
+            my @t = split m{:}, $parts[7];  # time (HH:MM:SS)
+            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]) + $t[2];
+            # set necessary flags for extra available information
+            @$has{qw(alt track orient)} = (1,1,1);
+            goto DoneFix;   # save this fix
+        } elsif ($format eq 'CSV') {
+            chomp;
+            my @vals = split /\Q$csvDelim/;
+#
+# CSV format output of GPS/IMU POS system
+#   Date*           - date in DD/MM/YYYY format
+#   Time*           - time in HH:MM:SS.SSS format
+#   [Pos]Lat*       - latitude in decimal degrees
+#   [Pos]Lon*       - longitude in decimal degrees
+#   [Pos]Alt*       - altitude in m relative to sea level
+#   [Angle]Heading* - GPSTrack in degrees true
+#   [Angle]Pitch*   - pitch angle in degrees
+#   [Angle]Roll*    - roll angle in degrees
+# (ExifTool enhancements allow for standard tag names or descriptions as the column headings,
+#  add support for time zones and flexible coordinates, and allow new DateTime and Shift columns)
+#
+            my ($param, $date, $secs);
+            foreach $param (@csvHeadings) {
+                my $val = shift @vals;
+                last unless defined $val;
+                next unless $param;
+                if ($param eq 'datetime') {
+                    local $SIG{'__WARN__'} = sub { };
+                    my $dateTime = $et->InverseDateTime($val);
+                    if ($dateTime) {
+                        $date = Image::ExifTool::GetUnixTime($val, 2);
+                        $secs = 0;
+                    }
+                } elsif ($param eq 'date') {
+                    if ($val =~ m{^(\d{2})/(\d{2})/(\d{4})$}) {
+                        $date = Time::Local::timegm(0,0,0,$1,$2-1,$3);
+                    } elsif ($val =~ /(\d{4}).*?(\d{2}).*?(\d{2})/) {
+                        $date = Time::Local::timegm(0,0,0,$3,$2-1,$1);
+                    }
+                } elsif ($param eq 'time') {
+                    if ($val =~ /^(\d{1,2}):(\d{2}):(\d{2}(\.\d+)?).*?(([-+])(\d{1,2}):?(\d{2}))?/) {
+                        $secs = (($1 * 60) + $2) * 60 + $3;
+                        # adjust for time zone if specified
+                        $secs += ($7 * 60 + $8) * ($6 eq '-' ? 60 : -60) if $5;
+                    }
+                } elsif ($param eq 'lat' or $param eq 'lon') {
+                    $$fix{$param} = Image::ExifTool::GPS::ToDegrees($val, 1);
+                } elsif ($param eq 'runtime') {
+                    $date = $trackTime;
+                    $secs = $val;
+                } else {
+                    $$fix{$param} = $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
-            next unless /^\$(PMGNTRK|GP(RMC|GGA|GLL|GSA)),/;
-            $nmea = $2 || $1;
+            # (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 = $3 || $2;
+            $_ = substr($_, length($1)) if length($1);
         }
 #
 # IGC (flarm) (ref 4)
 #
-        if ( $format eq 'IGC' ) {
+        if ($format eq 'IGC') {
             # B0939564531208N00557021EA007670089100207
             # BHHMMSSDDMMmmmNDDDMMmmmEAaaaaaAAAAAxxyy
@@ -262,25 +519,8 @@
             # wrap to next day if necessary
             if ($dateFlarm) {
-                $dateFlarm += $secPerDay if $secs < $lastSecs;
+                $dateFlarm += $secPerDay if $secs < $lastSecs - JITTER();
                 $date = $dateFlarm;
             }
             $nmea = 'B';
-#
-# Magellan eXplorist NMEA-like PMGNTRK sentence (optionally contains date)
-#
-        } elsif ($nmea eq 'PMGNTRK') {
-            # $PMGNTRK,4415.026,N,07631.091,W,00092,M,185031.06,A,,020409*65
-            # $PMGNTRK,ddmm.mmm,N/S,dddmm.mmm,E/W,alt,F/M,hhmmss.ss,A/V,trkname,DDMMYY*cs
-            /^\$PMGNTRK,(\d+)(\d{2}\.\d+),([NS]),(\d+)(\d{2}\.\d+),([EW]),(-?\d+\.?\d*),([MF]),(\d{2})(\d{2})(\d+)(\.\d+)?,A,(?:[^,]*,(\d{2})(\d{2})(\d+))?/ or next;
-            $fix{lat} = ($1 + $2/60) * ($3 eq 'N' ? 1 : -1);
-            $fix{lon} = ($4 + $5/60) * ($6 eq 'E' ? 1 : -1);
-            $fix{alt} = $8 eq 'M' ? $7 : $7 * 12 * 0.0254;
-            $secs = (($9 * 60) + $10) * 60 + $11;
-            $secs += $12 if $12;    # add fractional seconds
-            if (defined $15) {
-                # 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);
-            }
 #
 # NMEA RMC sentence (contains date)
@@ -288,12 +528,15 @@
         } elsif ($nmea eq 'RMC') {
             #  $GPRMC,092204.999,A,4250.5589,S,14718.5084,E,0.00,89.68,211200,,*25
+            #  $GPRMC,093657.007,,3652.835020,N,01053.104094,E,1.642,,290913,,,A*0F
             #  $GPRMC,hhmmss.sss,A/V,ddmm.mmmm,N/S,ddmmm.mmmm,E/W,spd(knots),dir(deg),DDMMYY,,*cs
-            /^\$GPRMC,(\d{2})(\d{2})(\d+)(\.\d+)?,A,(\d+)(\d{2}\.\d+),([NS]),(\d+)(\d{2}\.\d+),([EW]),[^,]*,[^,]*,(\d{2})(\d{2})(\d+)/ or next;
-            $fix{lat} = ($5 + $6/60) * ($7 eq 'N' ? 1 : -1);
-            $fix{lon} = ($8 + $9/60) * ($10 eq 'E' ? 1 : -1);
-            my $year = $13 + ($13 >= 70 ? 1900 : 2000);
+            /^\$[A-Z]{2}RMC,(\d{2})(\d{2})(\d+(\.\d*)?),A?,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d*\.?\d*),(\d*\.?\d*),(\d{2})(\d{2})(\d+)/ or next;
+            next if $13 > 31 or $14 > 12 or $15 > 99;   # validate day/month/year
+            $fix{lat} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1);
+            $fix{lon} = (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1);
+            $fix{speed} = $11 if length $11;
+            $fix{track} = $12 if length $12;
+            my $year = $15 + ($15 >= 70 ? 1900 : 2000);
             $secs = (($1 * 60) + $2) * 60 + $3;
-            $secs += $4 if $4;      # add fractional seconds
-            $date = Time::Local::timegm(0,0,0,$11,$12-1,$year-1900);
+            $date = Time::Local::timegm(0,0,0,$13,$14-1,$year);
 #
 # NMEA GGA sentence (no date)
@@ -301,13 +544,11 @@
         } elsif ($nmea eq 'GGA') {
             #  $GPGGA,092204.999,4250.5589,S,14718.5084,E,1,04,24.4,19.7,M,,,,0000*1F
+            #  $GPGGA,093657.000,3652.835020,N,01053.104094,E,,8,,166.924,M,40.9,M,,*77
             #  $GPGGA,hhmmss.sss,ddmm.mmmm,N/S,dddmm.mmmm,E/W,0=invalid,sats,hdop,alt,M,...
-            /^\$GPGGA,(\d{2})(\d{2})(\d+)(\.\d+)?,(\d+)(\d{2}\.\d+),([NS]),(\d+)(\d{2}\.\d+),([EW]),[1-6],(\d+)?,(\.\d+|\d+\.?\d*)?,(-?\d+\.?\d*)?,M?,/ or next;
-            $fix{lat} = ($5 + $6/60) * ($7 eq 'N' ? 1 : -1);
-            $fix{lon} = ($8 + $9/60) * ($10 eq 'E' ? 1 : -1);
-            $fix{nsats} = $11;
-            $fix{hdop} = $12;
-            $fix{alt} = $13;
+            /^\$[A-Z]{2}GGA,(\d{2})(\d{2})(\d+(\.\d*)?),(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),[1-6]?,(\d+)?,(\.\d+|\d+\.?\d*)?,(-?\d+\.?\d*)?,M?/ or next;
+            $fix{lat} = (($5 || 0) + $6/60) * ($7 eq 'N' ? 1 : -1);
+            $fix{lon} = (($8 || 0) + $9/60) * ($10 eq 'E' ? 1 : -1);
+            @fix{qw(nsats hdop alt)} = ($11,$12,$13);
             $secs = (($1 * 60) + $2) * 60 + $3;
-            $secs += $4 if $4;      # add fractional seconds
             $canCut = 1;
 #
@@ -317,9 +558,8 @@
             #  $GPGLL,4250.5589,S,14718.5084,E,092204.999,A*2D
             #  $GPGLL,ddmm.mmmm,N/S,dddmm.mmmm,E/W,hhmmss.sss,A/V*cs
-            /^\$GPGLL,(\d+)(\d{2}\.\d+),([NS]),(\d+)(\d{2}\.\d+),([EW]),(\d{2})(\d{2})(\d+)(\.\d+),A/ or next;
-            $fix{lat} = ($1 + $2/60) * ($3 eq 'N' ? 1 : -1);
-            $fix{lon} = ($4 + $5/60) * ($6 eq 'E' ? 1 : -1);
+            /^\$[A-Z]{2}GLL,(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),(\d{2})(\d{2})(\d+(\.\d*)?),A/ or next;
+            $fix{lat} = (($1 || 0) + $2/60) * ($3 eq 'N' ? 1 : -1);
+            $fix{lon} = (($4 || 0) + $5/60) * ($6 eq 'E' ? 1 : -1);
             $secs = (($7 * 60) + $8) * 60 + $9;
-            $secs += $10 if $10;    # add fractional seconds
 #
 # NMEA GSA sentence (satellite status, no date)
@@ -327,5 +567,5 @@
         } elsif ($nmea eq 'GSA') {
             # $GPGSA,A,3,04,05,,,,,,,,,,,pdop,hdop,vdop*HH
-            /^\$GPGSA,[AM],([23]),((?:\d*,){11}(?:\d*)),(\d+\.?\d*|\.\d+)?,(\d+\.?\d*|\.\d+)?,(\d+\.?\d*|\.\d+)?\*/ or next;
+            /^\$[A-Z]{2}GSA,[AM],([23]),((?:\d*,){11}(?:\d*)),(\d+\.?\d*|\.\d+)?,(\d+\.?\d*|\.\d+)?,(\d+\.?\d*|\.\d+)?\*/ or next;
             @fix{qw(fixtype sats pdop hdop vdop)} = ($1.'d',$2,$3,$4,$5);
             # count the number of acquired satellites
@@ -333,12 +573,52 @@
             $fix{nsats} = scalar @a;
             $canCut = 1;
+#
+# NMEA ZDA sentence (date/time, contains date)
+#
+        } elsif ($nmea eq 'ZDA') {
+            #  $GPZDA,093655.000,29,09,2013,,*58
+            #  $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);
+#
+# Magellan eXplorist PMGNTRK (Proprietary MaGellaN TRacK) sentence (optional date)
+#
+        } elsif ($nmea eq 'PMGNTRK') {
+            # $PMGNTRK,4415.026,N,07631.091,W,00092,M,185031.06,A,,020409*65
+            # $PMGNTRK,ddmm.mmm,N/S,dddmm.mmm,E/W,alt,F/M,hhmmss.ss,A/V,trkname,DDMMYY*cs
+            /^\$PMGNTRK,(\d+)(\d{2}\.\d+),([NS]),(\d+)(\d{2}\.\d+),([EW]),(-?\d+\.?\d*),([MF]),(\d{2})(\d{2})(\d+(\.\d*)?),A,(?:[^,]*,(\d{2})(\d{2})(\d+))?/ or next;
+            $fix{lat} = ($1 + $2/60) * ($3 eq 'N' ? 1 : -1);
+            $fix{lon} = ($4 + $5/60) * ($6 eq 'E' ? 1 : -1);
+            $fix{alt} = $8 eq 'M' ? $7 : $7 * 12 * 0.0254;
+            $secs = (($9 * 60) + $10) * 60 + $11;
+            if (defined $15) {
+                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);
+            }
+#
+# Honeywell HMR3000 PTNTHPR (Heading Pitch Roll) sentence (no date)
+# (ref http://www.gpsarea.com/uploadfile/download/introduce/hmr3000_manual.pdf)
+#
+        } elsif ($nmea eq 'PTNTHPR') {
+            # $PTNTHPR,85.9,N,-0.9,N,0.8,N*HH
+            # $PTNTHPR,heading,heading status,pitch,pitch status,roll,roll status,*cs
+            # status: L=low alarm, M=low warning, N=normal, O=high warning
+            #         P=high alarm, C=tuning analog circuit
+            # (ignore this information on any alarm status)
+            /^\$PTNTHPR,(-?[\d.]+),[MNO],(-?[\d.]+),[MNO],(-?[\d.]+),[MNO]/ or next;
+            @fix{qw(dir pitch roll)} = ($1,$2,$3);
 
         } else {
             next;   # this shouldn't happen
         }
+        # remember the NMEA formats we successfully read
+        $nmea{$nmea} = 1;
         # use last date if necessary (and appropriate)
         if (defined $secs and not defined $date and defined $lastDate) {
             # wrap to next day if necessary
-            if ($secs < $lastSecs) {
+            if ($secs < $lastSecs - JITTER()) {
                 $lastSecs -= $secPerDay;
                 $lastDate += $secPerDay;
@@ -360,5 +640,5 @@
         }
 #
-# Add NMEA fix to our lookup
+# Add NMEA/IGC fix to our lookup
 # (this is much more complicated than it needs to be because
 #  the stupid NMEA format provides no end-of-fix indication)
@@ -426,7 +706,7 @@
     if ($noDate and not $$geotag{NoDate}) {
         if ($isDate) {
-            $exifTool->Warn('Fixes are date-less -- will use time-only interpolation');
+            $et->Warn('Fixes are date-less -- will use time-only interpolation');
         } else {
-            $exifTool->Warn('Some fixes are date-less -- may use time-only interpolation');
+            $et->Warn('Some fixes are date-less -- may use time-only interpolation');
         }
         $$geotag{NoDate} = 1;
@@ -466,24 +746,21 @@
         last;
     }
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     if ($verbose) {
-        my $out = $exifTool->Options('TextOut');
-        print $out "Loaded $numPoints points from GPS track log $from\n";
+        my $out = $et->Options('TextOut');
+        $format or $format = 'unknown';
+        print $out "Loaded $numPoints points from $format-format GPS track log $from\n";
         print $out "Ignored $cutPDOP points due to GeoMaxPDOP cut\n" if $cutPDOP;
         print $out "Ignored $cutHDOP points due to GeoMaxHDOP cut\n" if $cutHDOP;
         print $out "Ignored $cutSats points due to GeoMinSats cut\n" if $cutSats;
         if ($numPoints and $verbose > 1) {
-            print $out '  GPS track start: ' . Image::ExifTool::ConvertUnixTime($fixTimes[0]) . " UTC\n";
+            my @lbl = ('start:', 'end:  ');
+            # (fixes may be in reverse order in GPX files)
+            @lbl = reverse @lbl if $fixTimes[0] > $fixTimes[-1];
+            print $out "  GPS track $lbl[0] " . PrintFixTime($fixTimes[0]) . "\n";
             if ($verbose > 3) {
-                foreach $time (@fixTimes) {
-                    $fix = $$points{$time} or next;
-                    print $out '    ',Image::ExifTool::ConvertUnixTime($time),' UTC -';
-                    foreach (sort keys %$fix) {
-                        print $out " $_=$$fix{$_}" unless $_ eq 'time';
-                    }
-                    print $out "\n";
-                }
-            }
-            print $out '  GPS track end:   ' . Image::ExifTool::ConvertUnixTime($fixTimes[-1]) . " UTC\n";
+                print $out PrintFix($points, $_) foreach @fixTimes;
+            }
+            print $out "  GPS track $lbl[1] " . PrintFixTime($fixTimes[-1]) . "\n";
         }
     }
@@ -491,7 +768,34 @@
         # reset timestamp list to force it to be regenerated
         delete $$geotag{Times};
+        # set flags for available information
+        $$has{alt} = 1 if $nmea{GGA} or $nmea{PMGNTRK} or $nmea{B}; # alt
+        $$has{track} = 1 if $nmea{RMC};                             # track, speed
+        $$has{orient} = 1 if $nmea{PTNTHPR};                        # dir, pitch, roll
         return $geotag;     # success!
     }
     return "No track points found in GPS $from";
+}
+
+
+#------------------------------------------------------------------------------
+# Get floating point UTC time
+# Inputs: 0) XML time string
+# Returns: floating point time or undef on error
+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);
+    $time += $7 if $7;  # add fractional seconds
+    my $tz = $8;
+    # adjust for time zone (otherwise assume UTC)
+    # - allow timezone of +-HH:MM, +-H:MM, +-HHMM or +-HH since
+    #   the spec is unclear about timezone format
+    if ($tz =~ /^([-+])(\d+):(\d{2})\b/ or $tz =~ /^([-+])(\d{2})(\d{2})?\b/) {
+        $tz = ($2 * 60 + ($3 || 0)) * 60;
+        $tz *= -1 if $1 eq '+'; # opposite sign to change back to UTC
+        $time += $tz;
+    }
+    return $time;
 }
 
@@ -502,6 +806,6 @@
 sub ApplySyncCorr($$)
 {
-    my ($exifTool, $time) = @_;
-    my $sync = $exifTool->GetNewValues('Geosync');
+    my ($et, $time) = @_;
+    my $sync = $et->GetNewValue('Geosync');
     if (ref $sync eq 'HASH') {
         my $syncTimes = $$sync{Times};
@@ -511,9 +815,5 @@
             while ($i1 > $i0 + 1) {
                 my $pt = int(($i0 + $i1) / 2);
-                if ($time < $$syncTimes[$pt]) {
-                    $i1 = $pt;
-                } else {
-                    $i0 = $pt;
-                }
+                ($time < $$syncTimes[$pt] ? $i1 : $i0) = $pt;
             }
             my ($t0, $t1) = ($$syncTimes[$i0], $$syncTimes[$i1]);
@@ -530,4 +830,59 @@
     }
     return $sync;
+}
+
+#------------------------------------------------------------------------------
+# Scan outwards for a fix containing the requested parameter
+# Inputs: 0) name of fix parameter, 1) reference to list of fix times,
+#         2) reference to fix points hash, 3) index of starting time,
+#         4) direction to scan (-1 or +1), 5) maximum time difference
+# Returns: 0) time for fix containing requested information (or undef)
+#          1) the corresponding fix, 2) the value of the requested fix parameter
+sub ScanOutwards($$$$$$)
+{
+    my ($key, $times, $points, $i, $dir, $maxSecs) = @_;
+    my $t0 = $$times[$i];
+    for (;;) {
+        $i += $dir;
+        last if $i < 0 or $i >= scalar @$times;
+        my $t = $$times[$i];
+        last if abs($t - $t0) > $maxSecs;   # don't look too far
+        my $p = $$points{$t};
+        my $v = $$p{$key};
+        return($t,$p,$v) if defined $v;
+    }
+    return();
+}
+
+#------------------------------------------------------------------------------
+# Find nearest fix containing the specified parameter
+# Inputs: 0) ExifTool ref, 1) name of fix parameter, 2) reference to list of fix times,
+#         3) reference to fix points hash, 4) index of starting time,
+#         5) direction to scan (-1, +1 or undef), 6) maximum time difference
+# Returns: reference to fix hash or undef
+sub FindFix($$$$$$$)
+{
+    my ($et, $key, $times, $points, $i, $dir, $maxSecs) = @_;
+    my ($t,$p);
+    if ($dir) {
+        ($t,$p) = ScanOutwards($key, $times, $points, $i, $dir, $maxSecs);
+    } else {
+        my ($t1, $p1) = ScanOutwards($key, $times, $points, $i, -1, $maxSecs);
+        my ($t2, $p2) = ScanOutwards($key, $times, $points, $i, 1, $maxSecs);
+        if (defined $t1) {
+            if (defined $t2) {
+                # both surrounding points are valid, so take the closest one
+                ($t, $p) = ($t - $t1 < $t2 - $t) ? ($t1, $p1) : ($t2, $p2);
+            } else {
+                ($t, $p) = ($t1, $p1);
+            }
+        } elsif (defined $t2) {
+            ($t, $p) = ($t2, $p2);
+        }
+    }
+    if (defined $p and $$et{OPTIONS}{Verbose} > 2) {
+        $et->VPrint(2, "  Taking $key from fix:\n", PrintFix($points, $t))
+    }
+    return $p;
 }
 
@@ -541,7 +896,8 @@
 {
     local $_;
-    my ($exifTool, $val, $writeGroup) = @_;
-    my $geotag = $exifTool->GetNewValues('Geotag');
-    my ($fix, $time, $fsec, $noDate, $secondTry);
+    my ($et, $val, $writeGroup) = @_;
+    my $geotag = $et->GetNewValue('Geotag');
+    my $verbose = $et->Options('Verbose');
+    my ($fix, $time, $fsec, $noDate, $secondTry, $iExt, $iDir);
 
     # remove date if none of our fixes had date information
@@ -549,11 +905,14 @@
 
     # maximum time (sec) from nearest GPS fix when position is still considered valid
-    my $geoMaxIntSecs = $exifTool->Options('GeoMaxIntSecs');
-    my $geoMaxExtSecs = $exifTool->Options('GeoMaxExtSecs');
+    my $geoMaxIntSecs = $et->Options('GeoMaxIntSecs');
+    my $geoMaxExtSecs = $et->Options('GeoMaxExtSecs');
+
     # use 30 minutes for a default
     defined $geoMaxIntSecs or $geoMaxIntSecs = 1800;
     defined $geoMaxExtSecs or $geoMaxExtSecs = 1800;
 
+    my $times = $$geotag{Times};
     my $points = $$geotag{Points};
+    my $has = $$geotag{Has};
     my $err = '';
     # loop to try date/time value first, then time-only value
@@ -563,5 +922,4 @@
             last;
         }
-        my $times = $$geotag{Times};
         unless ($times) {
             # generate sorted timestamp list for binary search
@@ -569,9 +927,9 @@
             $times = $$geotag{Times} = \@times;
         }
-        unless ($times and @$times) {
+        unless ($times and @$times or $$geotag{DateTimeOnly}) {
             $err = 'GPS track is empty';
             last;
         }
-        unless (eval 'require Time::Local') {
+        unless (eval { require Time::Local }) {
             $err = 'Geotag feature requires Time::Local installed';
             last;
@@ -593,5 +951,5 @@
         }
         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') {
@@ -601,5 +959,5 @@
         } 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
@@ -607,30 +965,47 @@
 
         # bring UTC time back to Jan. 1 if no date is given
-        $time %= $secPerDay if $noDate;
+        # (don't use '%' operator here because it drops fractional seconds)
+        $time -= int($time / $secPerDay) * $secPerDay if $noDate;
 
         # apply time synchronization if available
-        my $sync = ApplySyncCorr($exifTool, $time);
+        my $sync = ApplySyncCorr($et, $time);
 
         # save fractional seconds string
         $fsec = ($time =~ /(\.\d+)$/) ? $1 : '';
 
-        if ($exifTool->Options('Verbose') > 1 and not $secondTry) {
-            my $out = $exifTool->Options('TextOut');
-            my $str = "$fsec UTC";
+        if ($et->Options('Verbose') > 1 and not $secondTry) {
+            my $out = $et->Options('TextOut');
+            my $str = '';
             $str .= sprintf(" (incl. Geosync offset of %+.3f sec)", $sync) if defined $sync;
-            print $out '  Geotime value:   ' . Image::ExifTool::ConvertUnixTime(int $time) . "$str\n";
-        }
+            unless ($tz) {
+                my $tzs = Image::ExifTool::TimeZoneString([$sec,$min,$hr,$day,$mon-1,$year-1900],$time);
+                $str .= " (local timezone is $tzs)";
+            }
+            print $out '  Geotime value:   ' . PrintFixTime($time) . "$str\n";
+        }
+        if (not $times or not @$times) {
+            $fix = { }; # dummy fix to geotag date/time only
         # interpolate GPS track at $time
-        if ($time < $$times[0]) {
+        } elsif ($time < $$times[0]) {
             if ($time < $$times[0] - $geoMaxExtSecs) {
                 $err or $err = 'Time is too far before track';
+                $et->VPrint(2, '  Track start:     ', PrintFixTime($$times[0]), "\n") if $verbose > 2;
+                $fix = { } if $$geotag{DateTimeOnly};
             } else {
                 $fix = $$points{$$times[0]};
+                $iExt = 0;  $iDir = 1;
+                $et->VPrint(2, "  Taking pos from fix:\n",
+                    PrintFix($points, $$times[0])) if $verbose > 2;
             }
         } elsif ($time > $$times[-1]) {
             if ($time > $$times[-1] + $geoMaxExtSecs) {
                 $err or $err = 'Time is too far beyond track';
+                $et->VPrint(2, '  Track end:       ', PrintFixTime($$times[-1]), "\n") if $verbose > 2;
+                $fix = { } if $$geotag{DateTimeOnly};
             } else {
                 $fix = $$points{$$times[-1]};
+                $iExt = $#$times;  $iDir = -1;
+                $et->VPrint(2, "  Taking pos from fix:\n",
+                    PrintFix($points, $$times[-1])) if $verbose > 2;
             }
         } else {
@@ -639,9 +1014,5 @@
             while ($i1 > $i0 + 1) {
                 my $pt = int(($i0 + $i1) / 2);
-                if ($time < $$times[$pt]) {
-                    $i1 = $pt;
-                } else {
-                    $i0 = $pt;
-                }
+                ($time < $$times[$pt] ? $i1 : $i0) = $pt;
             }
             # do linear interpolation for position
@@ -650,22 +1021,87 @@
             my $p1 = $$points{$t1};
             # check to see if we are extrapolating before the first entry in a track
-            my $maxSecs = $$p1{first} ? $geoMaxExtSecs : $geoMaxIntSecs;
+            my $maxSecs = ($$p1{first} and $geoMaxIntSecs) ? $geoMaxExtSecs : $geoMaxIntSecs;
             # don't interpolate if fixes are too far apart
-            if ($t1 - $t0 > $maxSecs) {
+            # (but always interpolate fixes inside the same TimeSpan)
+            if ($t1 - $t0 > $maxSecs and (not $$p1{span} or not $$points{$t0}{span} or
+                $$p1{span} != $$points{$t0}{span}))
+            {
                 # treat as an extrapolation -- use nearest fix if close enough
-                my $tn = ($time - $t0 < $t1 - $time) ? $t0 : $t1;
+                my $tn;
+                if ($time - $t0 < $t1 - $time) {
+                    $tn = $t0;
+                    $iExt = $i0;
+                } else {
+                    $tn = $t1;
+                    $iExt = $i1;
+                }
                 if (abs($time - $tn) > $geoMaxExtSecs) {
                     $err or $err = 'Time is too far from nearest GPS fix';
+                    $et->VPrint(2, '  Nearest fix:     ', PrintFixTime($tn), "\n") if $verbose > 2;
+                    $fix = { } if $$geotag{DateTimeOnly};
                 } else {
                     $fix = $$points{$tn};
+                    $et->VPrint(2, "  Taking pos from fix:\n",
+                        PrintFix($points, $tn)) if $verbose > 2;
                 }
             } else {
-                my $f = $t1 == $t0 ? 0 : ($time - $t0) / ($t1 - $t0);
+                my $f0 = $t1 == $t0 ? 0 : ($time - $t0) / ($t1 - $t0);
                 my $p0 = $$points{$t0};
+                $et->VPrint(2, "  Interpolating between fixes (f=$f0):\n",
+                    PrintFix($points, $t0, $t1)) if $verbose > 2;
                 $fix = { };
-                # loop through latitude, longitude, and altitude if available
-                foreach (qw(lat lon alt)) {
-                    next unless defined $$p0{$_} and defined $$p1{$_};
-                    $$fix{$_} = $$p1{$_} * $f + $$p0{$_} * (1 - $f);
+                # loop through available fix information categories
+                # (pos, track, alt, orient)
+                my ($category, $key);
+Category:       foreach $category (qw{pos track alt orient atemp}) {
+                    next unless $$has{$category};
+                    my ($f, $p0b, $p1b, $f0b);
+                    # loop through specific fix information keys
+                    # (lat, lon, alt, track, speed, dir, pitch, roll)
+                    foreach $key (@{$fixInfoKeys{$category}}) {
+                        my $v0 = $$p0{$key};
+                        my $v1 = $$p1{$key};
+                        if (defined $v0 and defined $v1) {
+                            $f = $f0;
+                        } elsif (defined $f0b) {
+                            $v0 = $$p0b{$key};
+                            $v1 = $$p1b{$key};
+                            next unless defined $v0 and defined $v1;
+                            $f = $f0b;
+                        } else {
+                            # scan outwards looking for fixes with the required information
+                            # (NOTE: SHOULD EVENTUALLY DO THIS FOR EXTRAPOLATION TOO!)
+                            my ($t0b, $t1b);
+                            if (defined $v0) {
+                                $t0b = $t0;  $p0b = $p0;
+                            } else {
+                                ($t0b,$p0b,$v0) = ScanOutwards($key,$times,$points,$i0,-1,$maxSecs);
+                                next Category unless defined $t0b;
+                            }
+                            if (defined $v1) {
+                                $t1b = $t1;  $p1b = $p1;
+                            } else {
+                                ($t1b,$p1b,$v1) = ScanOutwards($key,$times,$points,$i1,1,$maxSecs);
+                                next Category unless defined $t1b;
+                            }
+                            # re-calculate the interpolation factor
+                            $f = $f0b = $t1b == $t0b ? 0 : ($time - $t0b) / ($t1b - $t0b);
+                            $et->VPrint(2, "  Interpolating $category between fixes (f=$f):\n",
+                                PrintFix($points, $t0b, $t1b)) if $verbose > 2;
+                        }
+                        # must interpolate cyclical values differently
+                        if ($cyclical{$key} and abs($v1 - $v0) > 180) {
+                            # the acute angle spans the discontinuity, so add
+                            # 360 degrees to the smaller angle before interpolating
+                            $v0 < $v1 ? $v0 += 360 : $v1 += 360;
+                            $$fix{$key} = $v1 * $f + $v0 * (1 - $f);
+                            # longitude and roll ranges are -180 to 180, others are 0 to 360
+                            my $max = ($key eq 'lon' or $key eq 'roll') ? 180 : 360;
+                            $$fix{$key} -= 360 if $$fix{$key} >= $max;
+                        } else {
+                            # simple linear interpolation
+                            $$fix{$key} = $v1 * $f + $v0 * (1 - $f);
+                        }
+                    }
                 }
             }
@@ -690,4 +1126,10 @@
             $gpsAlt = abs $$fix{alt};
             $gpsAltRef = ($$fix{alt} < 0 ? 1 : 0);
+        } elsif ($$has{alt} and defined $iExt) {
+            my $tFix = FindFix($et,'alt',$times,$points,$iExt,$iDir,$geoMaxExtSecs);
+            if ($tFix) {
+                $gpsAlt = abs $$tFix{alt};
+                $gpsAltRef = ($$tFix{alt} < 0 ? 1 : 0);
+            }
         }
         # set new GPS tag values (EXIF, or XMP if write group is 'xmp')
@@ -700,13 +1142,59 @@
         }
         # (capture error messages by calling SetNewValue in list context)
-        @r = $exifTool->SetNewValue(GPSLatitude => $$fix{lat}, %opts);
-        @r = $exifTool->SetNewValue(GPSLongitude => $$fix{lon}, %opts);
-        @r = $exifTool->SetNewValue(GPSAltitude => $gpsAlt, %opts);
-        @r = $exifTool->SetNewValue(GPSAltitudeRef => $gpsAltRef, %opts);
+        @r = $et->SetNewValue(GPSLatitude => $$fix{lat}, %opts);
+        @r = $et->SetNewValue(GPSLongitude => $$fix{lon}, %opts);
+        @r = $et->SetNewValue(GPSAltitude => $gpsAlt, %opts);
+        @r = $et->SetNewValue(GPSAltitudeRef => $gpsAltRef, %opts);
+        if ($$has{track}) {
+            my $tFix = $fix;
+            if (not defined $$fix{track} and defined $iExt) {
+                my $p = FindFix($et,'track',$times,$points,$iExt,$iDir,$geoMaxExtSecs);
+                $tFix = $p if $p;
+            }
+            @r = $et->SetNewValue(GPSTrack => $$tFix{track}, %opts);
+            @r = $et->SetNewValue(GPSTrackRef => (defined $$tFix{track} ? 'T' : undef), %opts);
+            my ($spd, $ref);
+            if (defined($spd = $$tFix{speed})) {
+                $ref = $$et{OPTIONS}{GeoSpeedRef};
+                if ($ref and defined $speedConv{$ref}) {
+                    $ref = $speedConv{$ref} if $speedConv{$speedConv{$ref}};
+                    $spd *= $speedConv{$ref};
+                } else {
+                    $ref = 'N';     # knots by default
+                }
+            }
+            @r = $et->SetNewValue(GPSSpeed => $spd, %opts);
+            @r = $et->SetNewValue(GPSSpeedRef => $ref, %opts);
+        }
+        if ($$has{orient}) {
+            my $tFix = $fix;
+            if (not defined $$fix{dir} and defined $iExt) {
+                my $p = FindFix($et,'dir',$times,$points,$iExt,$iDir,$geoMaxExtSecs);
+                $tFix = $p if $p;
+            }
+            @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) {
-            @r = $exifTool->SetNewValue(GPSLatitudeRef => ($$fix{lat} > 0 ? 'N' : 'S'), %opts);
-            @r = $exifTool->SetNewValue(GPSLongitudeRef => ($$fix{lon} > 0 ? 'E' : 'W'), %opts);
-            @r = $exifTool->SetNewValue(GPSDateStamp => $gpsDate, %opts);
-            @r = $exifTool->SetNewValue(GPSTimeStamp => $gpsTime, %opts);
+            my ($latRef, $lonRef);
+            $latRef = ($$fix{lat} > 0 ? 'N' : 'S') if defined $$fix{lat};
+            $lonRef = ($$fix{lon} > 0 ? 'E' : 'W') if defined $$fix{lon};
+            @r = $et->SetNewValue(GPSLatitudeRef => $latRef, %opts);
+            @r = $et->SetNewValue(GPSLongitudeRef => $lonRef, %opts);
+            @r = $et->SetNewValue(GPSDateStamp => $gpsDate, %opts);
+            @r = $et->SetNewValue(GPSTimeStamp => $gpsTime, %opts);
             # set options to edit XMP:GPSDateTime only if it already exists
             $opts{EditOnly} = 1;
@@ -714,15 +1202,19 @@
         }
         unless ($exif) {
-            @r = $exifTool->SetNewValue(GPSDateTime => "$gpsDate $gpsTime", %opts);
+            @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))
+                    GPSAltitude GPSAltitudeRef GPSDateStamp GPSTimeStamp GPSDateTime
+                    GPSTrack GPSTrackRef GPSSpeed GPSSpeedRef GPSImgDirection
+                    GPSImgDirectionRef GPSPitch GPSRoll CameraElevationAngle
+                    AmbientTemperature))
         {
-            my @r = $exifTool->SetNewValue($_, undef, %opts);
+            my @r = $et->SetNewValue($_, undef, %opts);
         }
     }
@@ -735,20 +1227,19 @@
 #         1) time difference string ("[+-]DD MM:HH:SS.ss"), geosync'd file name,
 #            "GPSTIME@IMAGETIME", or "GPSTIME@FILENAME"
-# Returns: geosync hash
+# Returns: geosync hash:
+#           Offset = Offset in seconds for latest synchronization (GPS - image time)
+#           Points = hash of all sync offsets keyed by image times in seconds
+#           Times = sorted list of image synchronization times (keys in Points hash)
 # Notes: calling this routine with more than one geosync'd file causes time drift
 #        correction to be implemented
 sub ConvertGeosync($$)
 {
-    my ($exifTool, $val) = @_;
-    my $sync = $exifTool->GetNewValues('Geosync') || { };
+    my ($et, $val) = @_;
+    my $sync = $et->GetNewValue('Geosync') || { };
     my ($syncFile, $gpsTime, $imgTime);
 
     if ($val =~ /(.*?)\@(.*)/) {
         $gpsTime = $1;
-        if (-f $2) {
-            $syncFile = $2;
-        } else {
-            $imgTime = $2;
-        }
+        (-f $2 ? $syncFile : $imgTime) = $2;
     # (take care because "-f '1:30'" crashes ActivePerl 5.10)
     } elsif ($val !~ /^\d/ or $val !~ /:/) {
@@ -764,15 +1255,18 @@
                                  'GPSDateTime', 'GPSTimeStamp');
             $$info{Error} and warn("$$info{Err}\n"), return undef;
-            $gpsTime or $gpsTime = $$info{GPSDateTime} || $$info{GPSTimeStamp};
+            unless ($gpsTime) {
+                $gpsTime = $$info{GPSDateTime} || $$info{GPSTimeStamp};
+                $gpsTime .= 'Z' if $gpsTime and not $$info{GPSDateTime};
+            }
+            $gpsTime or warn("No GPSTimeStamp in '$syncFile\n"), return undef;
             my $tag;
             foreach $tag (@timeTags) {
                 if ($$info{$tag}) {
                     $imgTime = $$info{$tag};
-                    $exifTool->VPrint(2, "Geosyncing with $tag from '$syncFile'\n");
+                    $et->VPrint(2, "Geosyncing with $tag from '${syncFile}'\n");
                     last;
                 }
             }
-            $gpsTime or warn("No GPSTimeStamp in '$syncFile\n"), return undef;
-            $imgTime or warn("No image timestamp in '$syncFile'\n"), return undef;
+            $imgTime or warn("No image timestamp in '${syncFile}'\n"), return undef;
         }
         # add date to date-less timestamps
@@ -799,7 +1293,7 @@
         # calculate Unix seconds since the epoch
         my $imgSecs = Image::ExifTool::GetUnixTime($imgDateTime, 1);
-        defined $imgSecs or warn("Invalid image time '$imgTime'\n"), return undef;
+        defined $imgSecs or warn("Invalid image time '${imgTime}'\n"), return undef;
         my $gpsSecs = Image::ExifTool::GetUnixTime($gpsDateTime, 1);
-        defined $gpsSecs or warn("Invalid GPS time '$gpsTime'\n"), return undef;
+        defined $gpsSecs or warn("Invalid GPS time '${gpsTime}'\n"), return undef;
         # add fractional seconds
         $gpsSecs += $1 if $gpsTime =~ /(\.\d+)/;
@@ -823,13 +1317,9 @@
             $$sync{Points}{$imgSecs} = $$sync{Offset};
             # print verbose output
-            if ($exifTool->Options('Verbose') > 1) {
+            if ($et->Options('Verbose') > 1) {
                 # print GPS and image timestamps in UTC
-                my $gps = Image::ExifTool::ConvertUnixTime($gpsSecs);
-                my $img = Image::ExifTool::ConvertUnixTime($imgSecs);
-                $gps .= $1 if $gpsTime =~ /(\.\d+)/;
-                $img .= $1 if $imgTime =~ /(\.\d+)/;
-                $exifTool->VPrint(1, "Added Geosync point:\n",
-                                     "  GPS time stamp:  $gps UTC\n",
-                                     "  Image date/time: $img UTC\n");
+                $et->VPrint(1, "Added Geosync point:\n",
+                               '  GPS time stamp:  ', PrintFixTime($gpsSecs), "\n",
+                               '  Image date/time: ', PrintFixTime($imgSecs), "\n");
             }
             # save sorted list of image sync times if we have more than one
@@ -857,4 +1347,38 @@
 
 #------------------------------------------------------------------------------
+# Print fix time
+# Inputs: 0) time since the epoch
+# Returns: UTC time string with fractional seconds
+sub PrintFixTime($)
+{
+    my $time = $_[0] + 0.0005;  # round off to nearest ms
+    my $fsec = int(($time - int($time)) * 1000);
+    return sprintf('%s.%.3d UTC', Image::ExifTool::ConvertUnixTime($time), $fsec);
+}
+
+#------------------------------------------------------------------------------
+# Print fix information
+# Inputs: 0) lookup for all fix points, 1-n) list of fix times
+# Returns: fix string (including leading indent and trailing newline)
+sub PrintFix($@)
+{
+    local $_;
+    my $points = shift;
+    my $str = '';
+    while (@_) {
+        my $time = shift;
+        $str .= '    ' . PrintFixTime($time) . ' -';
+        my $fix = $$points{$time};
+        if ($fix) {
+            foreach (sort keys %$fix) {
+                $str .= " $_=$$fix{$_}" unless $_ eq 'time' or not defined $$fix{$_};
+            }
+        }
+        $str .= "\n";
+    }
+    return $str;
+}
+
+#------------------------------------------------------------------------------
 1;  # end
 
@@ -873,6 +1397,7 @@
 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, and
-Magellan PMGNTRK.
+formats are GPX, NMEA RMC/GGA/GLL, KML, IGC, Garmin XML and TCX, Magellan
+PMGNTRK, Honeywell PTNTHPR, Winplus Beacon text, IMU CSV, DJI CSV, and
+Bramor gEO log files.
 
 Methods in this module should not be called directly.  Instead, the Geotag
@@ -881,7 +1406,12 @@
 in the tag name documentation).
 
+=head1 NOTES
+
+To take advantage of attitude information in the PTNTHPR NMEA sentence, the
+user-defined tag GPSRoll, must be active.
+
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -912,3 +1442,2 @@
 
 =cut
-
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GoPro.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GoPro.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/GoPro.pm	(revision 34921)
@@ -0,0 +1,742 @@
+#------------------------------------------------------------------------------
+# 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.06';
+
+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,
+    },
+  # ANGX (GPMF-GEOC) - seen -0.05 (fmt d, Max)
+  # ANGY (GPMF-GEOC) - seen 179.9 (fmt d, Max)
+  # ANGZ (GPMF-GEOC) - seen 0.152 (fmt d, Max)
+    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)
+  # CALH (GPMF-GEOC) - seen 3040 (fmt L, Max)
+  # CALW (GPMF-GEOC) - seen 4056 (fmt L, Max)
+    CASN => 'CameraSerialNumber', #PH (GPMF - seen: 'C3221324545448', fmt c)
+  # CINF (GPMF) - seen: 0x67376be7709bc8876a8baf3940908618, 0xe230988539b30cf5f016627ae8fc5395,
+  #                     0x8bcbe424acc5b37d7d77001635198b3b (fmt B) (Camera INFormation?)
+  # CMOD (GPMF) - seen: 12,13,17 [12 360 video, 13 time-laps video, 17 JPEG] (fmt B)
+  # CRTX (GPMF-BACK/FRNT) - double[1]
+  # CRTY (GPMF-BACK/FRNT) - double[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,
+    },
+    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,
+    },
+    DEVC => { #PH (gpmd,GPMF, fmt \0)
+        Name => 'DeviceContainer',
+        SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
+        # (Max) DVID=1,DVNM='Global Settings',VERS,FMWR,LINF,CINF,CASN,MINF,MUID,CMOD,MTYP,OREN,
+        #       DZOM,DZST,SMTR,PRTN,PTWB,PTSH,PTCL,EXPT,PIMX,PIMN,PTEV,RATE,SROT,ZFOV,VLTE,VLTA,
+        #       EISE,EISA,AUPT,AUDO,BROD,BRID,PVUL,PRJT,SOFF
+        # (Max) DVID='GEOC',DVNM='Geometry Calibrations',SHFX,SHFY,SHFZ,ANGX,ANGY,ANGZ,CALW,CALH
+        # (Max) DVID='BACK',DVNM='Back Lens',KLNS,CTRX,CTRY,MFOV,SFTR
+        # (Max) DVID='FRNT',DVNM='Front Lens',KLNS,CTRX,CTRY,MFOV,SFTR
+        # (Max) DVID='HLMT',DVNM='Highlights'
+    },
+  # DVID (GPMF) - DeviceID; seen: 1 (fmt L), HLMT (fmt F), GEOC (fmt F), 'BACK' (fmt F, Max)
+    DVID => { Name => 'DeviceID', Unknown => 1 }, #2 (gpmd)
+  # DVNM (GPMF) seen: 'Video Global Settings' (fmt c), 'Highlights' (fmt c), 'Geometry Calibrations' (Max)
+  # 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','N/A' (fmt c) [N was for a time-lapse video]
+        Name => 'ElectronicImageStabilization',
+    },
+  # EISE (GPMF) - seen: 'Y','N' (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' },
+    },
+  # KLNS (GPMF-BACK/FRNT) - double[5] (fmt d, Max)
+  # LINF (GPMF) - seen: LAJ7061916601668,C3341326002180,C33632245450981 (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)
+  # MFOV (GPMF-BACK/FRNT) - seen: 100 (fmt d, Max)
+    MINF => { #PH (GPMF - seen: HERO6 Black, fmt c)
+        Name => 'Model',
+        Groups => { 2 => 'Camera' },
+        Description => 'Camera Model Name',
+    },
+  # MTYP (GPMF) - seen: 0,1,5,11 [1 for time-lapse video, 5 for 360 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', 'Y' (fmt c)
+    PRES => 'PhotoResolution', #PH (APP6 - seen: '12MP_W')
+  # PRJT (APP6) - seen: 'GPRO','EACO' (fmt F, Hero8, Max)
+    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)
+  # PVUL (APP6) - seen: 'F' (fmt c, Hero8, Max)
+    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,
+    },
+  # SFTR (GPMF-BACK/FRNT) - seen 0.999,1.00004 (fmt d, Max)
+  # SHFX (GPMF-GEOC) - seen 22.92 (fmt d, Max)
+  # SHFY (GPMF-GEOC) - seen 0.123 (fmt d, Max)
+  # SHFZ (GPMF-GEOC) - seen 36.06 (fmt d, Max)
+    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)
+  # SOFF (APP6) - seen: 0 (fmt L, Hero8, Max)
+  # SROT (GPMF) - seen 20.60 (fmt f, Max)
+    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")',
+    },
+    VERS => {
+        Name => 'MetadataVersion',
+        PrintConv => '$val =~ tr/ /./; $val',
+    },
+    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,
+    },
+  # ZFOV (APP6,GPMF) - seen: 148.34, 0 (fmt f, Hero8, Max)
+);
+
+# 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
+# - with hack to check for encrypted text in gpmd data (Rove Stealth 4K)
+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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/H264.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/H264.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/H264.pm	(revision 34921)
@@ -13,4 +13,5 @@
 #               6) Dave Nicholson private communication
 #               7) http://www.freepatentsonline.com/20050076039.pdf
+#               8) Michael Reitinger private communication (RX100)
 #
 # Glossary:     RBSP = Raw Byte Sequence Payload
@@ -23,6 +24,7 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
-
-$VERSION = '1.06';
+use Image::ExifTool::GPS;
+
+$VERSION = '1.17';
 
 sub ProcessSEI($$);
@@ -35,4 +37,5 @@
     0x0108 => 'Sony',
     0x1011 => 'Canon',
+    0x1104 => 'JVC', #Rob Lewis
 );
 
@@ -62,5 +65,5 @@
         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).
     },
@@ -82,6 +85,10 @@
     # 0x11 - TitleRemainTime (ref 7)
     # 0x12 - TitleChapterTotalNo (ref 7)
-    # 0x13 - TitleTimecode
-    # 0x14 - TitleBinaryGroup
+    0x13 => {
+        Name => 'TimeCode',
+        Notes => 'hours:minutes:seconds:frames',
+        ValueConv => 'sprintf("%.2x:%.2x:%.2x:%.2x",reverse unpack("C*",$val))',
+    },
+    # 0x14 - TitleBinaryGroup - val: 0x00000000,0x14200130
     # 0x15 - TitleCassetteNo (ref 7)
     # 0x16-0x17 - TitleSoftID (ref 7)
@@ -95,5 +102,5 @@
         # first byte is timezone information:
         #   0x80 - unused
-        #   0x40 - DST flag (not currently decoded)
+        #   0x40 - DST flag
         #   0x20 - TimeZoneSign
         #   0x1e - TimeZoneValue
@@ -101,7 +108,8 @@
         ValueConv => q{
             my ($tz, @a) = unpack('C*',$val);
-            return sprintf('%.2x%.2x:%.2x:%.2x %.2x:%.2x:%.2x%s%.2d:%s', @a,
+            return sprintf('%.2x%.2x:%.2x:%.2x %.2x:%.2x:%.2x%s%.2d:%s%s', @a,
                            $tz & 0x20 ? '-' : '+', ($tz >> 1) & 0x0f,
-                           $tz & 0x01 ? '30' : '00');
+                           $tz & 0x01 ? '30' : '00',
+                           $tz & 0x40 ? ' DST' : '');
         },
         PrintConv => '$self->ConvertDateTime($val)',
@@ -127,6 +135,6 @@
         SubDirectory => { TagTable => 'Image::ExifTool::H264::Camera2' },
     },
-    # 0x73 Lens - val: 0x75ffffd3,0x0effffd3,0x59ffffd3,0x79ffffd3,0xffffffd3...
-    # 0x74 Gain
+    # 0x73 Lens - val: 0x04ffffd3,0x0effffd3,0x15ffffd3,0x41ffffd3,0x52ffffd3,0x59ffffd3,0x65ffffd3,0x71ffffd3,0x75ffffd3,0x79ffffd3,0x7fffffd3,0xffffffd3...
+    # 0x74 Gain - val: 0xb8ffff0f
     # 0x75 Pedestal
     # 0x76 Gamma
@@ -292,4 +300,5 @@
         Notes => 'combined with tags 0xbc and 0xbd',
         ValueConv => 'Image::ExifTool::GPS::ConvertTimeStamp($val)',
+        PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)',
     },
     0xbe => {
@@ -368,4 +377,13 @@
     },
     # 0xc9-0xcf - GPSOption
+    # 0xc9 - val: 0x001d0203
+    0xca => { #PH (Sony DSC-HX7V)
+        Name => 'GPSDateStamp',
+        Format => 'string',
+        Groups => { 1 => 'GPS', 2 => 'Time' },
+        Combine => 2,    # the next 2 tags contain the rest of the string
+        Notes => 'combined with tags 0xcb and 0xcc',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+    },
     0xe0 => {
         Name => 'MakeModel',
@@ -374,5 +392,4 @@
     # 0xe1-0xef - MakerOption
     # 0xe1 - val: 0x01000670,0x01000678,0x06ffffff,0x01ffffff,0x01000020,0x01000400...
-    # 0xe2-0xe8 - val: 0x00000000 in many samples
     0xe1 => { #6
         Name => 'RecInfo',
@@ -381,13 +398,19 @@
         SubDirectory => { TagTable => 'Image::ExifTool::H264::RecInfo' },
     },
+    # 0xe2-0xe8 - val: 0x00000000 in many samples
+    # 0xe2 - val: 0x00000000,0x01000000,0x01010000,0x8080900c,0x8080a074
+    # 0xe3 - val: 0x00801f89,0x00801f8b,0x00c01f89,0xc9c01f80
     0xe4 => { #PH
         Name => 'Model',
-        Condition => '$$self{Make} eq "Sony"',
+        Condition => '$$self{Make} eq "Sony"', # (possibly also Canon models?)
         Description => 'Camera Model Name',
-        Notes => 'Sony cameras only, combined with tags 0xe5 and 0xe6',
+        Notes => 'Sony only, combined with tags 0xe5 and 0xe6',
         Format => 'string',
         Combine => 2, # (not sure about 0xe6, but include it just in case)
         RawConv => '$val eq "" ? undef : $val',
     },
+    # 0xeb - val: 0x008a0a00,0x0a300000,0x508a0a00,0x52880a00,0x528a0a00
+    # 0xec - val: 0x0b700000
+    # 0xed - val: 0x0ce0f819
     0xee => { #6 (HFS200)
         Name => 'FrameInfo',
@@ -396,4 +419,5 @@
         SubDirectory => { TagTable => 'Image::ExifTool::H264::FrameInfo' },
     },
+    # 0xef - val: 0x01c00000,0x0e00000c
 );
 
@@ -417,17 +441,19 @@
         Name => 'Gain',
         Mask => 0x0f,
+        # (0x0f would translate to 42 dB, but this value is used by the Sony
+        #  HXR-NX5U for any out-of-range value such as -6 dB or "hyper gain" - PH)
         ValueConv => '($val - 1) * 3',
-        PrintConv => '"$val dB"',
+        PrintConv => '$val==42 ? "Out of range" : "$val dB"',
     },
     1.1 => {
         Name => 'ExposureProgram',
         Mask => 0xf0,
-        ValueConv => '$val == 0xf0 ? undef : $val',
-        PrintConv => {
-            0x00 => 'Program AE',
-            0x10 => 'Gain', #?
-            0x20 => 'Shutter speed priority AE',
-            0x30 => 'Aperture-priority AE',
-            0x40 => 'Manual',
+        ValueConv => '$val == 15 ? undef : $val',
+        PrintConv => {
+            0 => 'Program AE',
+            1 => 'Gain', #?
+            2 => 'Shutter speed priority AE',
+            3 => 'Aperture-priority AE',
+            4 => 'Manual',
         },
     },
@@ -435,10 +461,10 @@
         Name => 'WhiteBalance',
         Mask => 0xe0,
-        ValueConv => '$val == 0xe0 ? undef : $val',
-        PrintConv => {
-            0x00 => 'Auto',
-            0x20 => 'Hold',
-            0x40 => '1-Push',
-            0x60 => 'Daylight',
+        ValueConv => '$val == 7 ? undef : $val',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Hold',
+            2 => '1-Push',
+            3 => 'Daylight',
         },
     },
@@ -448,5 +474,5 @@
         PrintConv => q{
             my $foc = ($val & 0x7e) / (($val & 0x01) ? 40 : 400);
-            return ($val & 0x80 ? 'Manual' : 'Auto') . " ($foc)";
+            return(($val & 0x80 ? 'Manual' : 'Auto') . " ($foc)");
         },
     },
@@ -462,6 +488,9 @@
     1 => {
         Name => 'ImageStabilization',
+        PrintHex => 1,
         PrintConv => {
             0 => 'Off',
+            0x3f => 'On (0x3f)', #8
+            0xbf => 'Off (0xbf)', #8
             0xff => 'n/a',
             OTHER => sub {
@@ -485,5 +514,5 @@
         Mask => 0x7fff, # (what is bit 0x8000 for?)
         RawConv => '$val == 0x7fff ? undef : $val', #7
-        ValueConv => '$val / 33640', #PH (conversion factor determined empirically)
+        ValueConv => '$val / 28125', #PH (Vixia HF G30, ref forum5588) (was $val/33640 until 9.49)
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
     },
@@ -502,10 +531,21 @@
         PrintConv => \%convMake,
     },
-    # 1 => ModelIDCode according to ref 4/5 (I think not)
-    # vals: 0x3001 - Sony HDR-CX105E/TG3E/XR500V
+    # 1 => ModelIDCode according to ref 4/5 (I think not - PH)
+    # 1 => { Name => 'ModelIDCode', PrintConv => 'sprintf("%.4x",$val)' },
+    # vals: 0x0313 - various Pansonic HDC models
+    #       0x0345 - Panasonic HC-V7272
+    #       0x0414 - Panasonic AG-AF100
+    #       0x0591 - various Panasonic DMC models
+    #       0x0802 - Panasonic DMC-TZ60 with GPS information off
+    #       0x0803 - Panasonic DMC-TZ60 with GPS information on
+    #       0x3001 - various Sony DSC, HDR, NEX and SLT models
+    #       0x3003 - various Sony DSC models
+    #       0x3100 - various Sony DSC, ILCE, NEX and SLT models
     #       0x1000 - Sony HDR-UX1
+    #       0x2000 - Canon HF100 (60i)
     #       0x3000 - Canon HF100 (30p)
-    #       0x2000 - Canon HF100 (60i)
     #       0x3101 - Canon HFM300 (PH, all qualities and frame rates)
+    #       0x3102 - Canon HFS200
+    #       0x4300 - Canon HFG30
 );
 
@@ -686,13 +726,14 @@
 #------------------------------------------------------------------------------
 # Parse H.264 sequence parameter set RBSP (ref 1)
-# Inputs) 0) ExifTool ref, 1) tag table ref, 2) data ref
+# Inputs: 0) ExifTool ref, 1) tag table ref, 2) data ref
+# Notes: All this just to get the image size!
 sub ParseSeqParamSet($$$)
 {
-    my ($exifTool, $tagTablePtr, $dataPt) = @_;
+    my ($et, $tagTablePtr, $dataPt) = @_;
     # initialize our bitstream object
     my $bstr = NewBitStream($dataPt) or return;
     my ($t, $i, $j, $n);
     # the messy nature of H.264 encoding makes it difficult to use
-    # data-driven structure parsing, so I code it explicitely (yuck!)
+    # data-driven structure parsing, so I code it explicitly (yuck!)
     $t = GetIntN($bstr, 8);         # profile_idc
     GetIntN($bstr, 16);             # constraints and level_idc
@@ -746,6 +787,6 @@
     return unless $$bstr{Mask};
     if ($w>=160 and $w<=4096 and $h>=120 and $h<=3072) {
-        $exifTool->HandleTag($tagTablePtr, ImageWidth => $w);
-        $exifTool->HandleTag($tagTablePtr, ImageHeight => $h);
+        $et->HandleTag($tagTablePtr, ImageWidth => $w);
+        $et->HandleTag($tagTablePtr, ImageHeight => $h);
         # (whew! -- so much work just to get ImageSize!!)
     }
@@ -778,6 +819,6 @@
     if ($t) {
         return if BitsLeft($bstr) < 65;
-        $$exifTool{VUI_units} = GetIntN($bstr, 32); # num_units_in_tick
-        $$exifTool{VUI_scale} = GetIntN($bstr, 32); # time_scale
+        $$et{VUI_units} = GetIntN($bstr, 32); # num_units_in_tick
+        $$et{VUI_scale} = GetIntN($bstr, 32); # time_scale
         GetIntN($bstr, 1);          # fixed_frame_rate_flag
     }
@@ -786,5 +827,5 @@
         $t = GetIntN($bstr, 1);     # nal_/vcl_hrd_parameters_present_flag
         if ($t) {
-            $$exifTool{VUI_hard} = 1;
+            $$et{VUI_hard} = 1;
             $hard = 1;
             $n = GetGolomb($bstr);  # cpb_cnt_minus1
@@ -796,11 +837,11 @@
             }
             GetIntN($bstr, 5);      # initial_cpb_removal_delay_length_minus1
-            $$exifTool{VUI_clen} = GetIntN($bstr, 5); # cpb_removal_delay_length_minus1
-            $$exifTool{VUI_dlen} = GetIntN($bstr, 5); # dpb_output_delay_length_minus1
-            $$exifTool{VUI_toff} = GetIntN($bstr, 5); # time_offset_length
+            $$et{VUI_clen} = GetIntN($bstr, 5); # cpb_removal_delay_length_minus1
+            $$et{VUI_dlen} = GetIntN($bstr, 5); # dpb_output_delay_length_minus1
+            $$et{VUI_toff} = GetIntN($bstr, 5); # time_offset_length
         }
     }
     GetIntN($bstr, 1) if $hard;     # low_delay_hrd_flag
-    $$exifTool{VUI_pic} = GetIntN($bstr, 1);    # pic_struct_present_flag
+    $$et{VUI_pic} = GetIntN($bstr, 1);    # pic_struct_present_flag
     # (don't yet decode the rest of the vui data)
 }
@@ -808,8 +849,10 @@
 #------------------------------------------------------------------------------
 # Parse H.264 picture timing SEI message (payload type 1) (ref 1)
-# Inputs) 0) ExifTool ref, 1) data ref
+# Inputs: 0) ExifTool ref, 1) data ref
+# Notes: this routine is for test purposes only, and not called unless the
+#        $parsePictureTiming flag is set
 sub ParsePictureTiming($$)
 {
-    my ($exifTool, $dataPt) = @_;
+    my ($et, $dataPt) = @_;
     my $bstr = NewBitStream($dataPt) or return;
     my ($i, $t, $n);
@@ -817,9 +860,9 @@
     # exist if the VUI hardware parameters are present, or if
     # "determined by the application, by some means not specified" -- WTF??
-    if ($$exifTool{VUI_hard}) {
-        GetIntN($bstr, $$exifTool{VUI_clen} + 1);   # cpb_removal_delay
-        GetIntN($bstr, $$exifTool{VUI_dlen} + 1);   # dpb_output_delay
-    }
-    if ($$exifTool{VUI_pic}) {
+    if ($$et{VUI_hard}) {
+        GetIntN($bstr, $$et{VUI_clen} + 1);   # cpb_removal_delay
+        GetIntN($bstr, $$et{VUI_dlen} + 1);   # dpb_output_delay
+    }
+    if ($$et{VUI_pic}) {
         $t = GetIntN($bstr, 4);     # pic_struct
         # determine NumClockTS ($n)
@@ -853,6 +896,6 @@
                 }
             }
-            if ($$exifTool{VUI_toff}) {
-                $o = GetIntN($bstr, $$exifTool{VUI_toff});  # time_offset
+            if ($$et{VUI_toff}) {
+                $o = GetIntN($bstr, $$et{VUI_toff});  # time_offset
             }
             last;   # only parse the first clock timestamp found
@@ -863,9 +906,29 @@
 #------------------------------------------------------------------------------
 # Process H.264 Supplementary Enhancement Information (ref 1/PH)
-# Inputs: 0) Exiftool ref, 1) dirInfo ref, 2) tag table ref
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
 # Returns: 1 if we processed payload type 5
+# Payload types:
+#   0 - buffer period
+#   1 - pic timing
+#   2 - pan scan rect
+#   3 - filler payload
+#   4 - user data registered itu t t35
+#   5 - user data unregistered
+#   6 - recovery point
+#   7 - dec ref pic marking repetition
+#   8 - spare pic
+#   9 - sene info
+#  10 - sub seq info
+#  11 - sub seq layer characteristics
+#  12 - sub seq characteristics
+#  13 - full frame freeze
+#  14 - full frame freeze release
+#  15 - full frame snapshot
+#  16 - progressive refinement segment start
+#  17 - progressive refinement segment end
+#  18 - motion constrained slice group set
 sub ProcessSEI($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $end = length($$dataPt);
@@ -891,8 +954,9 @@
         }
         return 0 if $pos + $size > $end;
+        $et->VPrint(1,"    (SEI type $type)\n");
         if ($type == 1) {                   # picture timing information
             if ($parsePictureTiming) {
                 my $buff = substr($$dataPt, $pos, $size);
-                ParsePictureTiming($exifTool, $dataPt);
+                ParsePictureTiming($et, $dataPt);
             }
         } elsif ($type == 5) {              # unregistered user data
@@ -904,11 +968,7 @@
     # look for our 16-byte UUID
     # - plus "MDPM" for "ModifiedDVPackMeta"
-    # - plus "GA94" for closed-caption data (not currently decoded)
+    # - plus "GA94" for closed-caption data (currently not decoded)
     return 0 unless $size > 20 and substr($$dataPt, $pos, 20) eq
         "\x17\xee\x8c\x60\xf8\x4d\x11\xd9\x8c\xd6\x08\0\x20\x0c\x9a\x66MDPM";
-
-    # load the GPS module because it contains conversion routines and
-    # Composite tags needed for a number of tags we may be extracting
-    require Image::ExifTool::GPS;
 #
 # parse the MDPM records in the UUID 17ee8c60f84d11d98cd60800200c9a66
@@ -916,16 +976,16 @@
 #
     my $tagTablePtr = GetTagTable('Image::ExifTool::H264::MDPM');
-    my $oldIndent = $$exifTool{INDENT};
-    $$exifTool{INDENT} .= '| ';
+    my $oldIndent = $$et{INDENT};
+    $$et{INDENT} .= '| ';
     $end = $pos + $size;    # end of payload
     $pos += 20;             # skip UUID + "MDPM"
     my $num = Get8u($dataPt, $pos++);   # get entry count
     my $lastTag = 0;
-    $exifTool->VerboseDir('MDPM', $num) if $exifTool->Options('Verbose');
+    $et->VerboseDir('MDPM', $num) if $et->Options('Verbose');
     # walk through entries in the MDPM payload
     for ($index=0; $index<$num and $pos<$end; ++$index) {
         my $tag = Get8u($dataPt, $pos);
         if ($tag <= $lastTag) { # should be in numerical order (PH)
-            $exifTool->Warn('Entries in MDPM directory are out of sequence');
+            $et->Warn('Entries in MDPM directory are out of sequence');
             last;
         }
@@ -933,5 +993,5 @@
         my $buff = substr($$dataPt, $pos + 1, 4);
         my $from;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($tagInfo) {
             # use our own print conversion for Unknown tags
@@ -953,5 +1013,5 @@
                 --$combine;
             }
-            $exifTool->HandleTag($tagTablePtr, $tag, undef,
+            $et->HandleTag($tagTablePtr, $tag, undef,
                 TagInfo => $tagInfo,
                 DataPt  => \$buff,
@@ -962,5 +1022,5 @@
         $pos += 5;
     }
-    $$exifTool{INDENT} = $oldIndent;
+    $$et{INDENT} = $oldIndent;
     return 1;
 }
@@ -972,7 +1032,7 @@
 sub ParseH264Video($$)
 {
-    my ($exifTool, $dataPt) = @_;
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my ($et, $dataPt) = @_;
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     my $tagTablePtr = GetTagTable('Image::ExifTool::H264::Main');
     my %parseNalUnit = ( 0x06 => 1, 0x07 => 1 );    # NAL unit types to parse
@@ -996,5 +1056,5 @@
         ++$pos;
         # check forbidden_zero_bit
-        $nal_unit_type & 0x80 and $exifTool->Warn('H264 forbidden bit error'), last;
+        $nal_unit_type & 0x80 and $et->Warn('H264 forbidden bit error'), last;
         $nal_unit_type &= 0x1f;
         # ignore this NAL unit unless we will parse it
@@ -1011,7 +1071,5 @@
         if ($verbose > 1) {
             printf $out "  NAL Unit Type: 0x%x (%d bytes)\n",$nal_unit_type, length $buff;
-            my %parms = ( Out => $out );
-            $parms{MaxLen} = 96 if $verbose < 4;
-            Image::ExifTool::HexDump(\$buff, undef, %parms) if $verbose > 2;
+            $et->VerboseDump(\$buff);
         }
         pos($$dataPt) = $pos = $nextPos;
@@ -1019,21 +1077,21 @@
         if ($nal_unit_type == 0x06) {       # sei_rbsp (supplemental enhancement info)
 
-            if ($$exifTool{GotNAL06}) {
+            if ($$et{GotNAL06}) {
                 # process only the first SEI unless ExtractEmbedded is set
-                next unless $exifTool->Options('ExtractEmbedded');
-                $$exifTool{DOC_NUM} = $$exifTool{GotNAL06};
+                next unless $et->Options('ExtractEmbedded');
+                $$et{DOC_NUM} = $$et{GotNAL06};
             }
-            $foundUserData = ProcessSEI($exifTool, { DataPt => \$buff } );
-            delete $$exifTool{DOC_NUM};
+            $foundUserData = ProcessSEI($et, { DataPt => \$buff } );
+            delete $$et{DOC_NUM};
             # keep parsing SEI's until we find the user data
             next unless $foundUserData;
-            $$exifTool{GotNAL06} = ($$exifTool{GotNAL06} || 0) + 1;
+            $$et{GotNAL06} = ($$et{GotNAL06} || 0) + 1;
 
         } elsif ($nal_unit_type == 0x07) {  # sequence_parameter_set_rbsp
 
             # process this NAL unit type only once
-            next if $$exifTool{GotNAL07};
-            $$exifTool{GotNAL07} = 1;
-            ParseSeqParamSet($exifTool, $tagTablePtr, \$buff);
+            next if $$et{GotNAL07};
+            $$et{GotNAL07} = 1;
+            ParseSeqParamSet($et, $tagTablePtr, \$buff);
         }
         # we were successful, so don't parse this NAL unit type again
@@ -1042,6 +1100,6 @@
     # parse one extra H264 frame if we didn't find the user data in this one
     # (Panasonic cameras don't put the SEI in the first frame)
-    return 0 if $foundUserData or $$exifTool{ParsedH264};
-    $$exifTool{ParsedH264} = 1;
+    return 0 if $foundUserData or $$et{ParsedH264};
+    $$et{ParsedH264} = 1;
     return 1;
 }
@@ -1066,5 +1124,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HP.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HP.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HP.pm	(revision 34921)
@@ -13,5 +13,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.02';
+$VERSION = '1.04';
 
 sub ProcessHP($$$);
@@ -44,4 +44,5 @@
    'PreviewImage' => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         RawConv => '$self->ValidateImage(\$val,$tag)',
     },
@@ -119,5 +120,5 @@
         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
@@ -142,11 +143,11 @@
 sub ProcessTDHD($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos};
     my $pos = $$dirInfo{DirStart};
     my $dirEnd = $pos + $$dirInfo{DirLen};
-    my $unknown = $exifTool->Options('Unknown') || $exifTool->Options('Verbose');
-    $exifTool->VerboseDir('TDHD', undef, $$dirInfo{DirLen});
+    my $unknown = $et->Options('Unknown') || $et->Options('Verbose');
+    $et->VerboseDir('TDHD', undef, $$dirInfo{DirLen});
     SetByteOrder('II');
     while ($pos + 12 < $dirEnd) {
@@ -164,5 +165,5 @@
                 DirLen   => $size,
             );
-            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         } else {
             if (not $$tagTablePtr{$tag} and $unknown) {
@@ -183,7 +184,7 @@
                     $tagInfo{Binary} = 1;
                 }
-                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, \%tagInfo);
+                AddTagToTable($tagTablePtr, $tag, \%tagInfo);
             }
-            $exifTool->HandleTag($tagTablePtr, $tag, undef,
+            $et->HandleTag($tagTablePtr, $tag, undef,
                 DataPt  => $dataPt,
                 DataPos => $dataPos,
@@ -203,5 +204,5 @@
 sub ProcessHP($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataLen = $$dirInfo{DataLen};
@@ -217,5 +218,5 @@
     # brute-force scan for PreviewImage
     if ($$tagTablePtr{PreviewImage} and $$dataPt =~ /(\xff\xd8\xff\xdb.*\xff\xd9)/gs) {
-        $exifTool->HandleTag($tagTablePtr, 'PreviewImage', $1);
+        $et->HandleTag($tagTablePtr, 'PreviewImage', $1);
         # truncate preview to speed subsequent tag scans
         my $buff = substr($$dataPt, 0, pos($$dataPt)-length($1));
@@ -226,5 +227,5 @@
         next if $tagID eq 'PreviewImage';
         next unless $$dataPt =~ /$tagID:\s*([\x20-\x7f]+)/i;
-        $exifTool->HandleTag($tagTablePtr, $tagID, $1);
+        $et->HandleTag($tagTablePtr, $tagID, $1);
     }
     return 1;
@@ -250,5 +251,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HTML.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HTML.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HTML.pm	(revision 34921)
@@ -21,5 +21,5 @@
 require Exporter;
 
-$VERSION = '1.11';
+$VERSION = '1.16';
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(EscapeHTML UnescapeHTML);
@@ -161,4 +161,5 @@
     author          => { },
     classification  => { },
+   'content-language'=>{ Name => 'ContentLanguage' },
     copyright       => { },
     description     => { },
@@ -169,4 +170,5 @@
     formatter       => { },
     generator       => { },
+    generatorversion=> { Name => 'GeneratorVersion' },
     googlebot       => { Name => 'GoogleBot' },
     keywords        => { List => 1 },
@@ -335,6 +337,6 @@
 sub SetHTMLCharset($$)
 {
-    my ($val, $exifTool) = @_;
-    $$exifTool{HTMLCharset} = $htmlCharset{lc $1} if $val =~ /charset=['"]?([-\w]+)/;
+    my ($val, $et) = @_;
+    $$et{HTMLCharset} = $htmlCharset{lc $1} if $val =~ /charset=['"]?([-\w]+)/;
     return $val;
 }
@@ -343,5 +345,5 @@
 # Convert single UTF-8 character to HTML character reference
 # Inputs: 0) UTF-8 character sequence
-# Returns: HTML character reference (ie. "&quot;");
+# Returns: HTML character reference (eg. "&quot;");
 # Note: Must be called via EscapeHTML to load name lookup
 sub EscapeChar($)
@@ -362,9 +364,9 @@
 #------------------------------------------------------------------------------
 # 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);
@@ -381,6 +383,12 @@
         # 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;
@@ -389,9 +397,10 @@
 #------------------------------------------------------------------------------
 # 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);
 }
 
@@ -402,5 +411,5 @@
 sub ProcessHTML($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -408,12 +417,12 @@
     # validate HTML or XHTML file
     $raf->Read($buff, 256) or return 0;
-    $buff =~ /^<(!DOCTYPE\s+HTML|HTML|\?xml)/i or return 0;
-    $buff =~ /<(!DOCTYPE\s+)?HTML/i or return 0 if $1 eq '?xml';
-    $exifTool->SetFileType();
-
-    $raf->Seek(0,0) or $exifTool->Warn('Seek error'), return 1;
+    $buff =~ /^(\xef\xbb\xbf)?\s*<(!DOCTYPE\s+HTML|HTML|\?xml)/i or return 0;
+    $buff =~ /<(!DOCTYPE\s+)?HTML/i or return 0 if $2 eq '?xml';
+    $et->SetFileType();
+
+    $raf->Seek(0,0) or $et->Warn('Seek error'), return 1;
 
     local $/ = Image::ExifTool::PostScript::GetInputRecordSeparator($raf);
-    $/ or $exifTool->Warn('Invalid HTML data'), return 1;
+    $/ or $et->Warn('Invalid HTML data'), return 1;
 
     # extract header information
@@ -438,5 +447,7 @@
         my $tag = lc($tagName);
         my ($val, $grp);
-        unless ($attrs =~ m{/$}) {  # self-contained XHTML tags end in '/>'
+        if ($attrs =~ m{/$}) {  # self-contained XHTML tags end in '/>'
+            $val = '';
+        } else {
             # look for element close
             my $pos = pos($doc);
@@ -450,4 +461,5 @@
                 pos($doc) = $pos;
                 next unless $tag eq 'meta'; # META tags don't need to be closed
+                $val = '';
             }
         }
@@ -457,19 +469,24 @@
             undef $tag;
             # tag name is in NAME or HTTP-EQUIV attribute
-            if ($attrs =~ /name=['"]?([\w:.-]+)/si) {
+            if ($attrs =~ /\bname\s*=\s*['"]?([\w:.-]+)/si) {
                 $tagName = $1;
-            } elsif ($attrs =~ /http-equiv=['"]?([\w:.-]+)/si) {
+            } elsif ($attrs =~ /\bhttp-equiv\s*=\s*['"]?([\w:.-]+)/si) {
                 $tagName = "HTTP-equiv.$1";
             } else {
                 next;   # no name
             }
-            $tag = lc($tagName);
+            $tag = lc($tagName) or next;
             # tag value is in CONTENT attribute
-            $val = $2 if $attrs =~ /content=(['"])(.*?)\1/si;
-            next unless $tag and defined $val;
+            if ($attrs =~ /\bcontent\s*=\s*(['"])(.*?)\1/si or
+                $attrs =~ /\bcontent\s*=\s*(['"]?)([\w:.-]+)/si)
+            {
+                $val = $2;
+            } else {
+                next unless length $val;
+            }
             # isolate group name (separator is '.' in HTML, but ':' in ref 2)
             if ($tag =~ /^([\w-]+)[:.]([\w-]+)/) {
                 ($grp, $tag) = ($1, $2);
-                my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $grp);
+                my $tagInfo = $et->GetTagInfo($tagTablePtr, $grp);
                 if ($tagInfo and $$tagInfo{SubDirectory}) {
                     $table = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
@@ -479,10 +496,10 @@
             }
         } elsif ($tag eq 'xml') {
-            $exifTool->VPrint(0, "Parsing XML\n");
+            $et->VPrint(0, "Parsing XML\n");
             # parse XML tags (quick-and-dirty)
             my $xml = $val;
             while ($xml =~ /<([\w-]+):([\w-]+)(\s.*?)?>([^<]*?)<\/\1:\2>/g) {
                 ($grp, $tag, $val) = ($1, $2, $4);
-                my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $grp);
+                my $tagInfo = $et->GetTagInfo($tagTablePtr, $grp);
                 next unless $tagInfo and $$tagInfo{SubDirectory};
                 $table = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
@@ -492,9 +509,9 @@
                     $name =~ s/\s(.)/\U$1/g;     # capitalize all words in tag name
                     $name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters (also hex code wide chars)
-                    Image::ExifTool::AddTagToTable($table, $tag, { Name => $name });
-                    $exifTool->VPrint(0, "  [adding $tag '$name']\n");
+                    AddTagToTable($table, $tag, { Name => $name });
+                    $et->VPrint(0, "  [adding $tag '${name}']\n");
                 }
-                $val = $exifTool->Decode($val, $$exifTool{HTMLCharset}) if $$exifTool{HTMLCharset};
-                $exifTool->HandleTag($table, $tag, UnescapeXML($val));
+                $val = $et->Decode($val, $$et{HTMLCharset}) if $$et{HTMLCharset};
+                $et->HandleTag($table, $tag, UnescapeXML($val));
             }
             next;
@@ -508,12 +525,12 @@
             my $info = { Name => $name, Groups => { 0 => 'HTML' } };
             $info->{Groups}->{1} = ($grp eq 'http-equiv' ? 'HTTP-equiv' : "HTML-$grp") if $grp;
-            Image::ExifTool::AddTagToTable($table, $tag, $info);
-            $exifTool->VPrint(0, "  [adding $tag '$tagName']\n");
+            AddTagToTable($table, $tag, $info);
+            $et->VPrint(0, "  [adding $tag '${tagName}']\n");
         }
         # recode if necessary
-        $val = $exifTool->Decode($val, $$exifTool{HTMLCharset}) if $$exifTool{HTMLCharset};
+        $val = $et->Decode($val, $$et{HTMLCharset}) if $$et{HTMLCharset};
         $val =~ s{\s*$/\s*}{ }sg;   # replace linefeeds and indenting spaces
         $val = UnescapeHTML($val);  # unescape HTML character references
-        $exifTool->HandleTag($table, $tag, $val);
+        $et->HandleTag($table, $tag, $val);
     }
     return 1;
@@ -539,5 +556,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HtmlDump.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HtmlDump.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/HtmlDump.pm	(revision 34921)
@@ -14,7 +14,7 @@
 use Image::ExifTool::HTML qw(EscapeHTML);
 
-$VERSION = '1.30';
-
-sub DumpTable($$$;$$$$$);
+$VERSION = '1.39';
+
+sub DumpTable($$$;$$$$$$);
 sub Open($$$;@);
 sub Write($@);
@@ -33,4 +33,5 @@
 my $htmlHeader2 = <<_END_PART_2_;
 </title>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 <style type="text/css">
 <!--
@@ -61,8 +62,10 @@
     position: absolute;
     background: #ffffdd;
+    zoom: 1;
+    -moz-opacity: 0.8;
+    -khtml-opacity: 0.8;
+    -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';
+    filter: alpha(opacity=80);
     opacity: 0.8;
-    -moz-opacity: 0.8;
-    filter: alpha(opacity=80);
-    -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity=80)';
     z-index: 2;
 }
@@ -95,5 +98,6 @@
 var ie6 = navigator.userAgent.toLowerCase().indexOf('msie 6') >= 0;
 var mspan = new Array;
-var hlist, tt, tb;
+var clicked = 0;
+var hlist, tt, tb, firstOutEvt, lastInEvt;
 
 function GetElementsByClass(classname, tagname) {
@@ -110,6 +114,19 @@
     }
   }
-  delete list;
   return found;
+}
+
+// click mouse
+function doClick(e)
+{
+  if (!clicked) {
+    firstOutEvt = lastInEvt = undefined;
+    high(e, 2);
+    if (hlist) clicked = 1;
+  } else {
+    clicked = 0;
+    if (firstOutEvt) high(firstOutEvt, 0);
+    if (lastInEvt) high(lastInEvt, 1);
+  }
 }
 
@@ -161,4 +178,10 @@
 // highlight/unhighlight text
 function high(e,on) {
+  if (on) {
+    lastInEvt = e;
+  } else {
+    if (!firstOutEvt) firstOutEvt = e;
+  }
+  if (clicked) return;
   var targ;
   if (e.target) targ = e.target;
@@ -170,5 +193,7 @@
     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;
@@ -189,18 +214,23 @@
       }
       // 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 = on == 2 ? '#ffbbbb' : '#ffcc99';
+        }
       }
     }
@@ -218,5 +248,5 @@
 <tr><td valign='top'><pre>];
 
-my $preMouse = q(<pre onmouseover="high(event,1)" onmouseout="high(event,0)" onmousemove="move(event)">);
+my $preMouse = q(<pre onmouseover="high(event,1)" onmouseout="high(event,0)" onmousemove="move(event)" onmousedown="doClick(event)">);
 
 #------------------------------------------------------------------------------
@@ -235,5 +265,5 @@
 # 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
@@ -243,7 +273,7 @@
 #       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} = [ ];
@@ -262,5 +292,5 @@
         ++$self->{TipNum};
     }
-    push @{$$block{$start}}, [ $size, $msg, $htip, $flag, $self->{TipNum} ];
+    push @{$$block{$start}}, [ $size, $msg, $htip, $flag, $self->{TipNum}, $ifd ];
 }
 
@@ -313,11 +343,18 @@
     # only do dump if we didn't have a serious error
     @starts = sort { $a <=> $b } keys %$block unless $$self{Error};
-    for ($i=0; $i<@starts; ++$i) {
+    for ($i=0; $i<=@starts; ++$i) {
         my $start = $starts[$i];
-        my $parmList = $$block{$start};
+        my $parmList;
+        if (defined $start) {
+            $parmList = $$block{$start};
+        } elsif ($bkgEnd and $pos < $bkgEnd and not defined $wasUnused) {
+            $start = $bkgEnd;   # finish last bkg block
+        } else {
+            last;
+        }
         my $len = $start - $pos;
         if ($len > 0 and not $wasUnused) {
-            # we have an unused bytes before this data block
-            --$i;           # dump the data block next time around
+            # we have a unused bytes before this data block
+            --$i;   # dump the data block next time around
             # split unused data into 2 blocks if it spans end of a bkg block
             my ($nextBkgEnd, $bkg);
@@ -343,5 +380,5 @@
         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;
@@ -359,6 +396,8 @@
             }
             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,
@@ -375,5 +414,7 @@
                 $end = $start + $len;
                 # only load as much of the block as we are going to dump
-                my $size = ($len > $limit) ? $limit / 2 : $len;
+                # (read 32 more bytes than necessary just in case there
+                # is only one skipped line that we decide to print)
+                my $size = ($len > $limit + 32) ? $limit / 2 + 16 : $len;
                 if ($start >= $dataPos and $end <= $dataEnd) {
                     $buff = substr($$dataPt, $start-$dataPos, $size);
@@ -418,5 +459,5 @@
             }
             $self->DumpTable($start-$dataPos, \$buff, $msg, $name,
-                             $flag, $len, $pos-$dataPos);
+                             $flag, $len, $pos-$dataPos, $ifd);
             undef $buff;
             $pos = $end if $pos < $end;
@@ -548,8 +589,8 @@
 # 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;
@@ -578,5 +619,6 @@
             ++$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 {
@@ -643,5 +685,6 @@
             $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);
@@ -713,5 +756,5 @@
 sub FinishTiffDump($$$)
 {
-    my ($self, $exifTool, $size) = @_;
+    my ($self, $et, $size) = @_;
     my ($tag, $key, $start, $blockInfo, $i);
 
@@ -729,19 +772,20 @@
         MPImageStart      => 'MPImageLength',
         IDCPreviewStart   => 'IDCPreviewLength',
+        SamsungRawPointersOffset => 'SamsungRawPointersLength',
     );
 
     # add TIFF data to html dump
     foreach $tag (keys %offsetPair) {
-        my $info = $exifTool->GetInfo($tag);
+        my $info = $et->GetInfo($tag);
         next unless %$info;
         # Panasonic hack: StripOffsets is not valid for Panasonic RW2 files,
         # and StripRowBytes is not valid for some RAW images
-        if ($tag eq 'StripOffsets' and $exifTool->{TAG_INFO}{$tag}{PanasonicHack}) {
+        if ($tag eq 'StripOffsets' and $$et{TAG_INFO}{$tag}{PanasonicHack}) {
             # use RawDataOffset instead if available since it is valid in RW2
-            my $info2 = $exifTool->GetInfo('RawDataOffset');
+            my $info2 = $et->GetInfo('RawDataOffset');
             $info2 = $info unless %$info2;
             my @keys = keys %$info2;
             my $offset = $$info2{$keys[0]};
-            my $raf = $$exifTool{RAF};
+            my $raf = $$et{RAF};
             # ignore StripByteCounts and assume raw data runs to the end of file
             if (@keys == 1 and $offset =~ /^\d+$/ and $raf) {
@@ -759,6 +803,6 @@
         foreach $key (keys %$info) {
             my $name = Image::ExifTool::GetTagName($key);
-            my $grp1 = $exifTool->GetGroup($key, 1);
-            my $info2 = $exifTool->GetInfo($offsetPair{$tag}, { Group1 => $grp1 });
+            my $grp1 = $et->GetGroup($key, 1);
+            my $info2 = $et->GetInfo($offsetPair{$tag}, { Group1 => $grp1 });
             my $key2 = $offsetPair{$tag};
             $key2 .= $1 if $key =~ /( .*)/; # use same instance number as $tag
@@ -791,5 +835,5 @@
                     }
                 }
-                my $msg = $exifTool->GetGroup($key, 1) . ':' . $tag;
+                my $msg = $et->GetGroup($key, 1) . ':' . $tag;
                 $msg =~ s/(Offsets?|Start)$/ /;
                 if ($num > 1) {
@@ -815,5 +859,5 @@
     }
     my $diff = $size - $last;
-    if ($diff > 0 and ($last or $exifTool->Options('Unknown'))) {
+    if ($diff > 0 and ($last or $et->Options('Unknown'))) {
         if ($diff > 1 or $size & 0x01) {
             $self->Add($last, $diff, "[unknown data]", "Size: $diff bytes", 0x08);
@@ -874,5 +918,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ICC_Profile.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ICC_Profile.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ICC_Profile.pm	(revision 34921)
@@ -11,4 +11,5 @@
 #               4) http://www.color.org/privatetag2007-01.pdf
 #               5) http://www.color.org/icc_specs2.xalter (approved revisions, 2010-07-16)
+#               6) Eef Vreeland private communication
 #
 # Notes:        The ICC profile information is different: the format of each
@@ -24,5 +25,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.22';
+$VERSION = '1.36';
 
 sub ProcessICC($$);
@@ -53,4 +54,281 @@
     nkpf => 'Nikon Input Device Profile (NON-STANDARD!)', # (written by Nikon utilities)
 );
+my %manuSig = ( #6
+    'NONE' => 'none',
+    'none' => 'none', #PH
+    ''     => '', #PH
+    '4d2p' => 'Erdt Systems GmbH & Co KG',
+    'AAMA' => 'Aamazing Technologies, Inc.',
+    'ACER' => 'Acer Peripherals',
+    'ACLT' => 'Acolyte Color Research',
+    'ACTI' => 'Actix Systems, Inc.',
+    'ADAR' => 'Adara Technology, Inc.',
+    'ADBE' => 'Adobe Systems Inc.',
+    'ADI ' => 'ADI Systems, Inc.',
+    'AGFA' => 'Agfa Graphics N.V.',
+    'ALMD' => 'Alps Electric USA, Inc.',
+    'ALPS' => 'Alps Electric USA, Inc.',
+    'ALWN' => 'Alwan Color Expertise',
+    'AMTI' => 'Amiable Technologies, Inc.',
+    'AOC ' => 'AOC International (U.S.A), Ltd.',
+    'APAG' => 'Apago',
+    'APPL' => 'Apple Computer Inc.',
+    'appl' => 'Apple Computer Inc.',
+    'AST ' => 'AST',
+    'AT&T' => 'AT&T Computer Systems',
+    'BAEL' => 'BARBIERI electronic',
+    'berg' => 'bergdesign incorporated',
+    'bICC' => 'basICColor GmbH',
+    'BRCO' => 'Barco NV',
+    'BRKP' => 'Breakpoint Pty Limited',
+    'BROT' => 'Brother Industries, LTD',
+    'BULL' => 'Bull',
+    'BUS ' => 'Bus Computer Systems',
+    'C-IT' => 'C-Itoh',
+    'CAMR' => 'Intel Corporation',
+    'CANO' => 'Canon, Inc. (Canon Development Americas, Inc.)',
+    'CARR' => 'Carroll Touch',
+    'CASI' => 'Casio Computer Co., Ltd.',
+    'CBUS' => 'Colorbus PL',
+    'CEL ' => 'Crossfield',
+    'CELx' => 'Crossfield',
+    'ceyd' => 'Integrated Color Solutions, Inc.',
+    'CGS ' => 'CGS Publishing Technologies International GmbH',
+    'CHM ' => 'Rochester Robotics',
+    'CIGL' => 'Colour Imaging Group, London',
+    'CITI' => 'Citizen',
+    'CL00' => 'Candela, Ltd.',
+    'CLIQ' => 'Color IQ',
+    'clsp' => 'MacDermid ColorSpan, Inc.',
+    'CMCO' => 'Chromaco, Inc.',
+    'CMiX' => 'CHROMiX',
+    'COLO' => 'Colorgraphic Communications Corporation',
+    'COMP' => 'COMPAQ Computer Corporation',
+    'COMp' => 'Compeq USA/Focus Technology',
+    'CONR' => 'Conrac Display Products',
+    'CORD' => 'Cordata Technologies, Inc.',
+    'CPQ ' => 'Compaq Computer Corporation',
+    'CPRO' => 'ColorPro',
+    'CRN ' => 'Cornerstone',
+    'CTX ' => 'CTX International, Inc.',
+    'CVIS' => 'ColorVision',
+    'CWC ' => 'Fujitsu Laboratories, Ltd.',
+    'DARI' => 'Darius Technology, Ltd.',
+    'DATA' => 'Dataproducts',
+    'DCP ' => 'Dry Creek Photo',
+    'DCRC' => 'Digital Contents Resource Center, Chung-Ang University',
+    'DELL' => 'Dell Computer Corporation',
+    'DIC ' => 'Dainippon Ink and Chemicals',
+    'DICO' => 'Diconix',
+    'DIGI' => 'Digital',
+    'DL&C' => 'Digital Light & Color',
+    'DPLG' => 'Doppelganger, LLC',
+    'DS  ' => 'Dainippon Screen',
+    'ds  ' => 'Dainippon Screen',
+    'DSOL' => 'DOOSOL',
+    'DUPN' => 'DuPont',
+    'dupn' => 'DuPont',
+    'Eizo' => 'EIZO NANAO CORPORATION',
+    'EPSO' => 'Epson',
+    'ESKO' => 'Esko-Graphics',
+    'ETRI' => 'Electronics and Telecommunications Research Institute',
+    'EVER' => 'Everex Systems, Inc.',
+    'EXAC' => 'ExactCODE GmbH',
+    'FALC' => 'Falco Data Products, Inc.',
+    'FF  ' => 'Fuji Photo Film Co.,LTD',
+    'FFEI' => 'FujiFilm Electronic Imaging, Ltd.',
+    'ffei' => 'FujiFilm Electronic Imaging, Ltd.',
+    'flux' => 'FluxData Corporation',
+    'FNRD' => 'fnord software',
+    'FORA' => 'Fora, Inc.',
+    'FORE' => 'Forefront Technology Corporation',
+    'FP  ' => 'Fujitsu',
+    'FPA ' => 'WayTech Development, Inc.',
+    'FUJI' => 'Fujitsu',
+    'FX  ' => 'Fuji Xerox Co., Ltd.',
+    'GCC ' => 'GCC Technologies, Inc.',
+    'GGSL' => 'Global Graphics Software Limited',
+    'GMB ' => 'Gretagmacbeth',
+    'GMG ' => 'GMG GmbH & Co. KG',
+    'GOLD' => 'GoldStar Technology, Inc.',
+    'GOOG' => 'Google', #PH
+    'GPRT' => 'Giantprint Pty Ltd',
+    'GTMB' => 'Gretagmacbeth',
+    'GVC ' => 'WayTech Development, Inc.',
+    'GW2K' => 'Sony Corporation',
+    'HCI ' => 'HCI',
+    'HDM ' => 'Heidelberger Druckmaschinen AG',
+    'HERM' => 'Hermes',
+    'HITA' => 'Hitachi America, Ltd.',
+    'HiTi' => 'HiTi Digital, Inc.',
+    'HP  ' => 'Hewlett-Packard',
+    'HTC ' => 'Hitachi, Ltd.',
+    'IBM ' => 'IBM Corporation',
+    'IDNT' => 'Scitex Corporation, Ltd.',
+    'Idnt' => 'Scitex Corporation, Ltd.',
+    'IEC ' => 'Hewlett-Packard',
+    'IIYA' => 'Iiyama North America, Inc.',
+    'IKEG' => 'Ikegami Electronics, Inc.',
+    'IMAG' => 'Image Systems Corporation',
+    'IMI ' => 'Ingram Micro, Inc.',
+    'Inca' => 'Inca Digital Printers Ltd.',
+    'INTC' => 'Intel Corporation',
+    'INTL' => 'N/A (INTL)',
+    'INTR' => 'Intra Electronics USA, Inc.',
+    'IOCO' => 'Iocomm International Technology Corporation',
+    'IPS ' => 'InfoPrint Solutions Company',
+    'IRIS' => 'Scitex Corporation, Ltd.',
+    'Iris' => 'Scitex Corporation, Ltd.',
+    'iris' => 'Scitex Corporation, Ltd.',
+    'ISL ' => 'Ichikawa Soft Laboratory',
+    'ITNL' => 'N/A (ITNL)',
+    'IVM ' => 'IVM',
+    'IWAT' => 'Iwatsu Electric Co., Ltd.',
+    'JPEG' => 'Joint Photographic Experts Group', #PH
+    'JSFT' => 'Jetsoft Development',
+    'JVC ' => 'JVC Information Products Co.',
+    'KART' => 'Scitex Corporation, Ltd.',
+    'Kart' => 'Scitex Corporation, Ltd.',
+    'kart' => 'Scitex Corporation, Ltd.',
+    'KFC ' => 'KFC Computek Components Corporation',
+    'KLH ' => 'KLH Computers',
+    'KMHD' => 'Konica Minolta Holdings, Inc.',
+    'KNCA' => 'Konica Corporation',
+    'KODA' => 'Kodak',
+    'KYOC' => 'Kyocera',
+    'LCAG' => 'Leica Camera AG',
+    'LCCD' => 'Leeds Colour',
+    'lcms' => 'Little CMS', #NealKrawetz
+    'LDAK' => 'Left Dakota',
+    'LEAD' => 'Leading Technology, Inc.',
+    'Leaf' => 'Leaf', #PH
+    'LEXM' => 'Lexmark International, Inc.',
+    'LINK' => 'Link Computer, Inc.',
+    'LINO' => 'Linotronic',
+    'Lino' => 'Linotronic', #PH (NC)
+    'lino' => 'Linotronic', #PH (NC)
+    'LITE' => 'Lite-On, Inc.',
+    'MAGC' => 'Mag Computronic (USA) Inc.',
+    'MAGI' => 'MAG Innovision, Inc.',
+    'MANN' => 'Mannesmann',
+    'MICN' => 'Micron Technology, Inc.',
+    'MICR' => 'Microtek',
+    'MICV' => 'Microvitec, Inc.',
+    'MINO' => 'Minolta',
+    'MITS' => 'Mitsubishi Electronics America, Inc.',
+    'MITs' => 'Mitsuba Corporation',
+    'Mits' => 'Mitsubishi Electric Corporation Kyoto Works',
+    'MNLT' => 'Minolta',
+    'MODG' => 'Modgraph, Inc.',
+    'MONI' => 'Monitronix, Inc.',
+    'MONS' => 'Monaco Systems Inc.',
+    'MORS' => 'Morse Technology, Inc.',
+    'MOTI' => 'Motive Systems',
+    'MSFT' => 'Microsoft Corporation',
+    'MUTO' => 'MUTOH INDUSTRIES LTD.',
+    'NANA' => 'NANAO USA Corporation',
+    'NEC ' => 'NEC Corporation',
+    'NEXP' => 'NexPress Solutions LLC',
+    'NISS' => 'Nissei Sangyo America, Ltd.',
+    'NKON' => 'Nikon Corporation',
+    'ob4d' => 'Erdt Systems GmbH & Co KG',
+    'obic' => 'Medigraph GmbH',
+    'OCE ' => 'Oce Technologies B.V.',
+    'OCEC' => 'OceColor',
+    'OKI ' => 'Oki',
+    'OKID' => 'Okidata',
+    'OKIP' => 'Okidata',
+    'OLIV' => 'Olivetti',
+    'OLYM' => 'OLYMPUS OPTICAL CO., LTD',
+    'ONYX' => 'Onyx Graphics',
+    'OPTI' => 'Optiquest',
+    'PACK' => 'Packard Bell',
+    'PANA' => 'Matsushita Electric Industrial Co., Ltd.',
+    'PANT' => 'Pantone, Inc.',
+    'PBN ' => 'Packard Bell',
+    'PFU ' => 'PFU Limited',
+    'PHIL' => 'Philips Consumer Electronics Co.',
+    'PNTX' => 'HOYA Corporation PENTAX Imaging Systems Division',
+    'POne' => 'Phase One A/S',
+    'PREM' => 'Premier Computer Innovations',
+    'PRIN' => 'Princeton Graphic Systems',
+    'PRIP' => 'Princeton Publishing Labs',
+    'QLUX' => 'Hong Kong',
+    'QMS ' => 'QMS, Inc.',
+    'QPCD' => 'QPcard AB',
+    'QUAD' => 'QuadLaser',
+    'quby' => 'Qubyx Sarl',
+    'QUME' => 'Qume Corporation',
+    'RADI' => 'Radius, Inc.',
+    'RDDx' => 'Integrated Color Solutions, Inc.',
+    'RDG ' => 'Roland DG Corporation',
+    'REDM' => 'REDMS Group, Inc.',
+    'RELI' => 'Relisys',
+    'RGMS' => 'Rolf Gierling Multitools',
+    'RICO' => 'Ricoh Corporation',
+    'RNLD' => 'Edmund Ronald',
+    'ROYA' => 'Royal',
+    'RPC ' => 'Ricoh Printing Systems,Ltd.',
+    'RTL ' => 'Royal Information Electronics Co., Ltd.',
+    'SAMP' => 'Sampo Corporation of America',
+    'SAMS' => 'Samsung, Inc.',
+    'SANT' => 'Jaime Santana Pomares',
+    'SCIT' => 'Scitex Corporation, Ltd.',
+    'Scit' => 'Scitex Corporation, Ltd.',
+    'scit' => 'Scitex Corporation, Ltd.',
+    'SCRN' => 'Dainippon Screen',
+    'scrn' => 'Dainippon Screen',
+    'SDP ' => 'Scitex Corporation, Ltd.',
+    'Sdp ' => 'Scitex Corporation, Ltd.',
+    'sdp ' => 'Scitex Corporation, Ltd.',
+    'SEC ' => 'SAMSUNG ELECTRONICS CO.,LTD',
+    'SEIK' => 'Seiko Instruments U.S.A., Inc.',
+    'SEIk' => 'Seikosha',
+    'SGUY' => 'ScanGuy.com',
+    'SHAR' => 'Sharp Laboratories',
+    'SICC' => 'International Color Consortium',
+    'siwi' => 'SIWI GRAFIKA CORPORATION',
+    'SONY' => 'SONY Corporation',
+    'Sony' => 'Sony Corporation',
+    'SPCL' => 'SpectraCal',
+    'STAR' => 'Star',
+    'STC ' => 'Sampo Technology Corporation',
+    'TALO' => 'Talon Technology Corporation',
+    'TAND' => 'Tandy',
+    'TATU' => 'Tatung Co. of America, Inc.',
+    'TAXA' => 'TAXAN America, Inc.',
+    'TDS ' => 'Tokyo Denshi Sekei K.K.',
+    'TECO' => 'TECO Information Systems, Inc.',
+    'TEGR' => 'Tegra',
+    'TEKT' => 'Tektronix, Inc.',
+    'TI  ' => 'Texas Instruments',
+    'TMKR' => 'TypeMaker Ltd.',
+    'TOSB' => 'TOSHIBA corp.',
+    'TOSH' => 'Toshiba, Inc.',
+    'TOTK' => 'TOTOKU ELECTRIC Co., LTD',
+    'TRIU' => 'Triumph',
+    'TSBT' => 'TOSHIBA TEC CORPORATION',
+    'TTX ' => 'TTX Computer Products, Inc.',
+    'TVM ' => 'TVM Professional Monitor Corporation',
+    'TW  ' => 'TW Casper Corporation',
+    'ULSX' => 'Ulead Systems',
+    'UNIS' => 'Unisys',
+    'UTZF' => 'Utz Fehlau & Sohn',
+    'VARI' => 'Varityper',
+    'VIEW' => 'Viewsonic',
+    'VISL' => 'Visual communication',
+    'VIVO' => 'Vivo Mobile Communication Co., Ltd',
+    'WANG' => 'Wang',
+    'WLBR' => 'Wilbur Imaging',
+    'WTG2' => 'Ware To Go',
+    'WYSE' => 'WYSE Technology',
+    'XERX' => 'Xerox Corporation',
+    'XRIT' => 'X-Rite',
+    'yxym' => 'YxyMaster GmbH',
+    'Z123' => "Lavanya's test Company",
+    'Zebr' => 'Zebra Technologies Inc',
+    'ZRAN' => 'Zoran Corporation',
+    # also seen: "    ",ACMS,KCMS,UCCM,etc2,SCTX
+);
 
 # ICC_Profile tag table
@@ -86,5 +364,5 @@
     targ => {
         Name => 'CharTarget',
-        ValueConv => 'length $val > 128 ? \$val : $val',
+        ValueConv => '$val=~s/\0.*//; length $val > 128 ? \$val : $val',
     },
     chad => 'ChromaticAdaptation',
@@ -257,4 +535,9 @@
     MS00 => 'WCSProfiles',
 
+    psd3 => { #6
+        Name => 'PostScript2CRD3',
+        Binary => 1, # (NC)
+    },
+
     # the following entry represents the ICC profile header, and doesn't
     # exist as a tag in the directory.  It is only in this table to provide
@@ -275,4 +558,6 @@
         Name => 'ProfileCMMType',
         Format => 'string[4]',
+        SeparateTable => 'ManuSig',
+        PrintConv => \%manuSig,
     },
     8 => {
@@ -327,10 +612,11 @@
         Name => 'DeviceManufacturer',
         Format => 'string[4]',
-        # KODA = Kodak
+        SeparateTable => 'ManuSig',
+        PrintConv => \%manuSig,
     },
     52 => {
         Name => 'DeviceModel',
         Format => 'string[4]',
-        # ROMM = Refrence Output Medium Metric
+        # ROMM = Reference Output Medium Metric
     },
     56 => {
@@ -362,5 +648,6 @@
         Name => 'ProfileCreator',
         Format => 'string[4]',
-        # KODA = Kodak
+        SeparateTable => 'ManuSig',
+        PrintConv => \%manuSig,
     },
     84 => {
@@ -410,4 +697,5 @@
         Format => 'int32u',
         PrintConv => {
+            0 => 'Unknown',
             1 => '0/45 or 45/0',
             2 => '0/d or d/0',
@@ -517,5 +805,5 @@
 
 #------------------------------------------------------------------------------
-# print ICC Profile ID in hex
+# Print ICC Profile ID in hex
 # Inputs: 1) string of numbers
 # Returns: string of hex digits
@@ -532,10 +820,10 @@
 
 #------------------------------------------------------------------------------
-# get formatted value from ICC tag (which has the type embedded)
+# Get formatted value from ICC tag (which has the type embedded)
 # Inputs: 0) data reference, 1) offset to tag data, 2) tag data size
 # Returns: Formatted value or undefined if format not supported
 # Notes: The following types are handled by BinaryTables:
 #  chromaticityType, colorantTableType, measurementType, viewingConditionsType
-# The following types are not currently handled (most are large tables):
+# The following types are currently not handled (most are large tables):
 #  curveType, lut16Type, lut8Type, lutAtoBType, lutBtoAType, namedColor2Type,
 #  parametricCurveType, profileSeqDescType, responseCurveSet16Type
@@ -628,18 +916,18 @@
 sub ProcessMetadata($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
     my $dirLen = $$dirInfo{DirLen};
     my $dirEnd = $dirStart + $dirLen;
-    
+
     if ($dirLen < 16 or substr($$dataPt, $dirStart, 4) ne 'dict') {
-        $exifTool->Warn('Invalid ICC meta dictionary');
+        $et->Warn('Invalid ICC meta dictionary');
         return 0;
     }
     my $num = Get32u($dataPt, $dirStart + 8);
-    $exifTool->VerboseDir('Metadata', $num);
+    $et->VerboseDir('Metadata', $num);
     my $size = Get32u($dataPt, $dirStart + 12);
-    $size < 16 and $exifTool->Warn('Invalid ICC meta record size'), return 0;
+    $size < 16 and $et->Warn('Invalid ICC meta record size'), return 0;
     # NOTE: In the example the minimum offset is 20,
     # but this doesn't jive with the table (both in ref 5)
@@ -649,5 +937,5 @@
         my $entry = $dirStart + 16 + $size * $index;
         if ($entry + $size > $dirEnd) {
-            $exifTool->Warn('Truncated ICC meta dictionary');
+            $et->Warn('Truncated ICC meta dictionary');
             last;
         }
@@ -660,11 +948,11 @@
             $valuePtr < $minPtr or $valuePtr + $valueLen > $dirLen)
         {
-            $exifTool->Warn('Corrupted ICC meta dictionary');
+            $et->Warn('Corrupted ICC meta dictionary');
             last;
         }
         my $tag = substr($dataPt, $dirStart + $namePtr, $nameLen);
         my $val = substr($dataPt, $dirStart + $valuePtr, $valueLen);
-        $tag = $exifTool->Decode($tag, 'UTF16', 'MM', 'UTF8');
-        $val = $exifTool->Decode($val, 'UTF16', 'MM');
+        $tag = $et->Decode($tag, 'UTF16', 'MM', 'UTF8');
+        $val = $et->Decode($val, 'UTF16', 'MM');
         # generate tagInfo if it doesn't exist
         unless ($$tagTablePtr{$tag}) {
@@ -673,7 +961,7 @@
             $name =~ tr/-_a-zA-Z0-9//dc;
             next unless length $name;
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
+            AddTagToTable($tagTablePtr, $tag, { Name => $name });
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+        $et->HandleTag($tagTablePtr, $tag, $val);
     }
     return 1;
@@ -687,5 +975,5 @@
 sub WriteICC($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     # first make sure this is a valid ICC file (or no file at all)
     my $raf = $$dirInfo{RAF};
@@ -693,9 +981,9 @@
     return 0 if $raf->Read($buff, 24) and ValidateICC(\$buff);
     # now write the new ICC
-    $buff = WriteICC_Profile($exifTool, $dirInfo);
+    $buff = WriteICC_Profile($et, $dirInfo);
     if (defined $buff and length $buff) {
         Write($$dirInfo{OutFile}, $buff) or return -1;
     } else {
-        $exifTool->Error('No ICC information to write');
+        $et->Error('No ICC information to write');
     }
     return 1;
@@ -710,14 +998,14 @@
 sub WriteICC_Profile($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access
     my $dirName = $$dirInfo{DirName} || 'ICC_Profile';
     # (don't write AsShotICCProfile or CurrentICCProfile here)
     return undef unless $dirName eq 'ICC_Profile';
-    my $nvHash = $exifTool->GetNewValueHash($Image::ExifTool::Extra{$dirName});
-    return undef unless Image::ExifTool::IsOverwriting($nvHash);
-    my $val = Image::ExifTool::GetNewValues($nvHash);
+    my $nvHash = $et->GetNewValueHash($Image::ExifTool::Extra{$dirName});
+    my $val = $et->GetNewValue($nvHash);
     $val = '' unless defined $val;
-    ++$exifTool->{CHANGED};
+    return undef unless $et->IsOverwriting($nvHash, $val);
+    ++$$et{CHANGED};
     return $val;
 }
@@ -747,5 +1035,5 @@
 sub ProcessICC($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -753,14 +1041,14 @@
     # check to see if this is a valid ICC profile file
     return 0 if ValidateICC(\$buff);
-    $exifTool->SetFileType();
+    $et->SetFileType();
     # read the profile
     my $size = unpack('N', $buff);
     if ($size < 128 or $size & 0x80000000) {
-        $exifTool->Error("Bad ICC Profile length ($size)");
+        $et->Error("Bad ICC Profile length ($size)");
         return 1;
     }
     $raf->Seek(0, 0);
-    unless ($raf->Read($buff, $size)) {
-        $exifTool->Error('Truncated ICC profile');
+    unless ($raf->Read($buff, $size) == $size) {
+        $et->Error('Truncated ICC profile');
         return 1;
     }
@@ -772,5 +1060,5 @@
     );
     my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
-    return ProcessICC_Profile($exifTool, \%dirInfo, $tagTablePtr);
+    return ProcessICC_Profile($et, \%dirInfo, $tagTablePtr);
 }
 
@@ -782,18 +1070,19 @@
 sub ProcessICC_Profile($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
-    my $dirStart = $$dirInfo{DirStart};
+    my $dirStart = $$dirInfo{DirStart} || 0;
     my $dirLen = $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     return 0 if $dirLen < 4;
 
     # extract binary ICC_Profile data block if binary mode or requested
-    if ($exifTool->{OPTIONS}->{Binary} or $exifTool->{REQ_TAG_LOOKUP}->{icc_profile} and
+    if ((($$et{TAGS_FROM_FILE} and not $$et{EXCL_TAG_LOOKUP}{icc_profile}) or
+        $$et{REQ_TAG_LOOKUP}{icc_profile}) and
         # (don't extract from AsShotICCProfile or CurrentICCProfile)
         (not $$dirInfo{Name} or $$dirInfo{Name} eq 'ICC_Profile'))
     {
-        $exifTool->FoundTag('ICC_Profile', substr($$dataPt, $dirStart, $dirLen));
+        $et->FoundTag('ICC_Profile', substr($$dataPt, $dirStart, $dirLen));
     }
 
@@ -803,5 +1092,5 @@
     my $len = Get32u($dataPt, $dirStart);
     if ($len != $dirLen or $len < 128) {
-        $exifTool->Warn("Bad length ICC_Profile (length $len)");
+        $et->Warn("Bad length ICC_Profile (length $len)");
         return 0 if $len < 128 or $dirLen < $len;
     }
@@ -811,16 +1100,16 @@
         or $numEntries * 12 + 132 > $dirLen)
     {
-        $exifTool->Warn("Bad ICC_Profile table ($numEntries entries)");
+        $et->Warn("Bad ICC_Profile table ($numEntries entries)");
         return 0;
     }
 
     if ($verbose) {
-        $exifTool->VerboseDir('ICC_Profile', $numEntries, $dirLen);
+        $et->VerboseDir('ICC_Profile', $numEntries, $dirLen);
         my $fakeInfo = { Name=>'ProfileHeader', SubDirectory => { } };
-        $exifTool->VerboseInfo(undef, $fakeInfo);
+        $et->VerboseInfo(undef, $fakeInfo);
     }
     # increment ICC dir count
-    my $dirCount = $exifTool->{DIR_COUNT}->{ICC} = ($exifTool->{DIR_COUNT}->{ICC} || 0) + 1;
-    $exifTool->{SET_GROUP1} = '+' . $dirCount if $dirCount > 1;
+    my $dirCount = $$et{DIR_COUNT}{ICC} = ($$et{DIR_COUNT}{ICC} || 0) + 1;
+    $$et{SET_GROUP1} = '+' . $dirCount if $dirCount > 1;
     # process the header block
     my %subdirInfo = (
@@ -831,7 +1120,8 @@
         DirLen   => 128,
         Parent   => $$dirInfo{DirName},
+        DirName  => 'Header',
     );
     my $newTagTable = GetTagTable('Image::ExifTool::ICC_Profile::Header');
-    $exifTool->ProcessDirectory(\%subdirInfo, $newTagTable);
+    $et->ProcessDirectory(\%subdirInfo, $newTagTable);
 
     $pos += 4;    # skip item count
@@ -842,15 +1132,15 @@
         my $size   = Get32u($dataPt, $pos + 8);
         $pos += 12;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
         # unknown tags aren't generated automatically by GetTagInfo()
         # if the tagID's aren't numeric, so we must do this manually:
-        if (not $tagInfo and $exifTool->{OPTIONS}->{Unknown}) {
+        if (not $tagInfo and $$et{OPTIONS}{Unknown}) {
             $tagInfo = { Unknown => 1 };
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tagID, $tagInfo);
+            AddTagToTable($tagTablePtr, $tagID, $tagInfo);
         }
         next unless defined $tagInfo;
 
         if ($offset + $size > $dirLen) {
-            $exifTool->Warn("Bad ICC_Profile table (truncated)");
+            $et->Warn("Bad ICC_Profile table (truncated)");
             last;
         }
@@ -880,8 +1170,8 @@
                     my $strLen = Get32u($dataPt, $recPos + 4);
                     my $strPos = Get32u($dataPt, $recPos + 8);
-                    last if $strPos + $strLen > $size; 
+                    last if $strPos + $strLen > $size;
                     my $str = substr($$dataPt, $valuePtr + $strPos, $strLen);
-                    $str = $exifTool->Decode($str, 'UTF16');
-                    $exifTool->HandleTag($tagTablePtr, $tagID, $str,
+                    $str = $et->Decode($str, 'UTF16');
+                    $et->HandleTag($tagTablePtr, $tagID, $str,
                         TagInfo => $langInfo || $tagInfo,
                         Table  => $tagTablePtr,
@@ -891,8 +1181,8 @@
                         Size   => $strLen,
                         Start  => $valuePtr + $strPos,
-                        Format => "type '$fmt'",
+                        Format => "type '${fmt}'",
                     );
                 }
-                $exifTool->Warn("Corrupted $$tagInfo{Name} data") if $i < $count;
+                $et->Warn("Corrupted $$tagInfo{Name} data") if $i < $count;
                 next;
             }
@@ -901,5 +1191,5 @@
         }
         $value = FormatICCTag($dataPt, $valuePtr, $size) unless $subdir;
-        $verbose and $exifTool->VerboseInfo($tagID, $tagInfo,
+        $verbose and $et->VerboseInfo($tagID, $tagInfo,
             Table  => $tagTablePtr,
             Index  => $index,
@@ -908,5 +1198,5 @@
             Size   => $size,
             Start  => $valuePtr,
-            Format => "type '$fmt'",
+            Format => "type '${fmt}'",
         );
         if ($subdir) {
@@ -930,4 +1220,5 @@
                 DirStart => $valuePtr,
                 DirLen   => $size,
+                DirName  => $name,
                 Parent   => $$dirInfo{DirName},
             );
@@ -935,18 +1226,18 @@
             #### eval Validate ($type)
             if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
-                $exifTool->Warn("Invalid $name data");
+                $et->Warn("Invalid ICC $name data");
             } else {
-                $exifTool->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
+                $et->ProcessDirectory(\%subdirInfo, $newTagTable, $$subdir{ProcessProc});
             }
         } elsif (defined $value) {
-            $exifTool->FoundTag($tagInfo, $value);
+            $et->FoundTag($tagInfo, $value);
         } else {
             $value = substr($$dataPt, $valuePtr, $size);
             # treat unsupported formats as binary data
             $$tagInfo{ValueConv} = '\$val' unless defined $$tagInfo{ValueConv};
-            $exifTool->FoundTag($tagInfo, $value);
+            $et->FoundTag($tagInfo, $value);
         }
     }
-    delete $exifTool->{SET_GROUP1};
+    delete $$et{SET_GROUP1};
     return 1;
 }
@@ -974,5 +1265,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ID3.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ID3.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ID3.pm	(revision 34921)
@@ -2,11 +2,13 @@
 # File:         ID3.pm
 #
-# Description:  Read ID3 meta information
+# Description:  Read ID3 and Lyrics3 meta information
 #
 # Revisions:    09/12/2005 - P. Harvey Created
+#               09/08/2020 - PH Added Lyrics3 support
 #
 # References:   1) http://www.id3.org/
 #               2) http://www.mp3-tech.org/
 #               3) http://www.fortunecity.com/underworld/sonic/3/id3tag.html
+#               4) https://id3.org/Lyrics3
 #------------------------------------------------------------------------------
 
@@ -17,17 +19,19 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.28';
+$VERSION = '1.55';
 
 sub ProcessID3v2($$$);
 sub ProcessPrivate($$$);
+sub ProcessSynText($$$);
 sub ConvertID3v1Text($$);
+sub ConvertTimeStamp($);
 
 # audio formats that we process after an ID3v2 header (in order)
 my @audioFormats = qw(APE MPC FLAC OGG MP3);
 
-# audio formats where the processing proc is in a different module
+# audio formats where the processing proc is in a differently-named module
 my %audioModule = (
     MP3 => 'ID3',
-    OGG => 'Vorbis',
+    OGG => 'Ogg',
 );
 
@@ -67,13 +71,11 @@
     VARS => { NO_ID => 1 },
     NOTES => q{
-        ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and
-        RealAudio files.  ID3v2 tags which support multiple languages (ie. Comment
-        and Lyrics) are extracted by specifying the tag name, followed by a dash
-        ('-'), then a 3-character
-        ISO 639-2
-        language code (ie. "Comment-spa"). See L<http://www.id3.org/> for the
-        official ID3 specification and
-        L<http://www.loc.gov/standards/iso639-2/php/code_list.php> for a list of ISO
-        639-2 language codes.
+        ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG, AIFF, OGG,
+        FLAC, APE, MPC and RealAudio files.  ID3v2 tags which support multiple
+        languages (eg. Comment and Lyrics) are extracted by specifying the tag name,
+        followed by a dash ('-'), then a 3-character ISO 639-2 language code (eg.
+        "Comment-spa"). See L<http://www.id3.org/> for the official ID3
+        specification and L<http://www.loc.gov/standards/iso639-2/php/code_list.php>
+        for a list of ISO 639-2 language codes.
     },
     ID3v1 => {
@@ -97,4 +99,22 @@
         SubDirectory => { TagTable => 'Image::ExifTool::ID3::v2_4' },
     },
+);
+
+# Lyrics3 tags (ref 4)
+%Image::ExifTool::ID3::Lyrics3 = (
+    GROUPS => { 1 => 'Lyrics3', 2 => 'Audio' },
+    NOTES => q{
+        ExifTool extracts Lyrics3 version 1.00 and 2.00 tags from any file that
+        supports ID3.  See L<https://id3.org/Lyrics3> for the specification.
+    },
+    IND => 'Indications',
+    LYR => 'Lyrics',
+    INF => 'AdditionalInfo',
+    AUT => { Name => 'Author', Groups => { 2 => 'Author' } },
+    EAL => 'ExtendedAlbumName',
+    EAR => 'ExtendedArtistName',
+    ETT => 'ExtendedTrackTitle',
+    IMG => 'AssociatedImageFile',
+    CRC => 'CRC', #PH
 );
 
@@ -141,5 +161,5 @@
      38 => 'Gospel',
      39 => 'Noise',
-     40 => 'AlternRock',
+     40 => 'Alt. Rock', # (was AlternRock)
      41 => 'Bass',
      42 => 'Soul',
@@ -160,5 +180,5 @@
      57 => 'Comedy',
      58 => 'Cult',
-     59 => 'Gangsta',
+     59 => 'Gangsta Rap', # (was Gansta)
      60 => 'Top 40',
      61 => 'Christian Rap',
@@ -168,5 +188,5 @@
      65 => 'Cabaret',
      66 => 'New Wave',
-     67 => 'Psychadelic',
+     67 => 'Psychedelic', # (was misspelt)
      68 => 'Rave',
      69 => 'Showtunes',
@@ -186,6 +206,6 @@
      82 => 'National Folk',
      83 => 'Swing',
-     84 => 'Fast Fusion',
-     85 => 'Bebob',
+     84 => 'Fast-Fusion', # (was Fast Fusion)
+     85 => 'Bebop', # (was misspelt)
      86 => 'Latin',
      87 => 'Revival',
@@ -225,5 +245,5 @@
     121 => 'Punk Rock',
     122 => 'Drum Solo',
-    123 => 'Acapella',
+    123 => 'A Cappella', # (was Acapella)
     124 => 'Euro-House',
     125 => 'Dance Hall',
@@ -236,12 +256,12 @@
     131 => 'Indie',
     132 => 'BritPop',
-    133 => 'Negerpunk',
+    133 => 'Afro-Punk', # (was Negerpunk)
     134 => 'Polsk Punk',
     135 => 'Beat',
-    136 => 'Christian Gangsta',
+    136 => 'Christian Gangsta Rap', # (was Christian Gangsta)
     137 => 'Heavy Metal',
     138 => 'Black Metal',
     139 => 'Crossover',
-    140 => 'Contemporary C',
+    140 => 'Contemporary Christian', # (was Contemporary C)
     141 => 'Christian Rock',
     142 => 'Merengue',
@@ -250,5 +270,51 @@
     145 => 'Anime',
     146 => 'JPop',
-    147 => 'SynthPop',
+    147 => 'Synthpop', # (was SynthPop)
+    # ref http://alicja.homelinux.com/~mats/text/Music/MP3/ID3/Genres.txt
+    # (also used to update some Genres above)
+    148 => 'Abstract',
+    149 => 'Art Rock',
+    150 => 'Baroque',
+    151 => 'Bhangra',
+    152 => 'Big Beat',
+    153 => 'Breakbeat',
+    154 => 'Chillout',
+    155 => 'Downtempo',
+    156 => 'Dub',
+    157 => 'EBM',
+    158 => 'Eclectic',
+    159 => 'Electro',
+    160 => 'Electroclash',
+    161 => 'Emo',
+    162 => 'Experimental',
+    163 => 'Garage',
+    164 => 'Global',
+    165 => 'IDM',
+    166 => 'Illbient',
+    167 => 'Industro-Goth',
+    168 => 'Jam Band',
+    169 => 'Krautrock',
+    170 => 'Leftfield',
+    171 => 'Lounge',
+    172 => 'Math Rock',
+    173 => 'New Romantic',
+    174 => 'Nu-Breakz',
+    175 => 'Post-Punk',
+    176 => 'Post-Rock',
+    177 => 'Psytrance',
+    178 => 'Shoegaze',
+    179 => 'Space Rock',
+    180 => 'Trop Rock',
+    181 => 'World Music',
+    182 => 'Neoclassical',
+    183 => 'Audiobook',
+    184 => 'Audio Theatre',
+    185 => 'Neue Deutsche Welle',
+    186 => 'Podcast',
+    187 => 'Indie Rock',
+    188 => 'G-Funk',
+    189 => 'Dubstep',
+    190 => 'Garage Rock',
+    191 => 'Psybient',
     255 => 'None',
     # ID3v2 adds some text short forms...
@@ -358,5 +424,5 @@
         in the tables below are those extracted by ExifTool, and don't represent a
         complete list of available ID3v2 tags.
-        
+
         ID3 version 2.2 tags.  (These are the tags written by iTunes 5.0.)
     },
@@ -366,5 +432,5 @@
     PIC => {
         Name => 'Picture',
-        Groups => { 2 => 'Image' },
+        Groups => { 2 => 'Preview' },
         Binary => 1,
         Notes => 'the 3 tags below are also extracted from this PIC frame',
@@ -378,8 +444,11 @@
     },
     'PIC-3' => { Name => 'PictureDescription', Groups => { 2 => 'Image' } },
-  # POP => 'Popularimeter',
+    POP => {
+        Name => 'Popularimeter',
+        PrintConv => '$val=~s/^(.*?) (\d+) (\d+)$/$1 Rating=$2 Count=$3/s; $val',
+    },
     SLT => {
-        Name => 'SynchronizedLyricText',
-        Binary => 1,
+        Name => 'SynLyrics',
+        SubDirectory => { TagTable => 'Image::ExifTool::ID3::SynLyrics' },
     },
     TAL => 'Album',
@@ -391,5 +460,5 @@
         PrintConv => 'Image::ExifTool::ID3::PrintGenre($val)',
     },
-    TCP => 'Compilation', # not part of spec, but used by iTunes
+    TCP => { Name => 'Compilation', PrintConv => { 0 => 'No', 1 => 'Yes' } }, # iTunes
     TCR => { Name => 'Copyright', Groups => { 2 => 'Author' } },
     TDA => { Name => 'Date', Groups => { 2 => 'Time' } },
@@ -403,5 +472,5 @@
     TMT => 'Media',
     TOA => { Name => 'OriginalArtist', Groups => { 2 => 'Author' } },
-    TOF => 'OriginalFilename',
+    TOF => 'OriginalFileName',
     TOL => 'OriginalLyricist',
     TOR => 'OriginalReleaseYear',
@@ -432,4 +501,13 @@
     WPB => 'PublisherURL',
     WXX => 'UserDefinedURL',
+    # the following written by iTunes 10.5 (ref PH)
+    RVA => 'RelativeVolumeAdjustment',
+    TST => 'TitleSortOrder',
+    TSA => 'AlbumSortOrder',
+    TSP => 'PerformerSortOrder',
+    TS2 => 'AlbumArtistSortOrder',
+    TSC => 'ComposerSortOrder',
+    ITU => { Name => 'iTunesU', Description => 'iTunes U', Binary => 1, Unknown => 1 },
+    PCS => { Name => 'Podcast', Binary => 1, Unknown => 1 },
 );
 
@@ -439,9 +517,9 @@
     APIC => {
         Name => 'Picture',
-        Groups => { 2 => 'Image' },
+        Groups => { 2 => 'Preview' },
         Binary => 1,
-        Notes => 'the 3 tags below are also extracted from this PIC frame',
-    },
-    'APIC-1' => { Name => 'PictureMimeType',    Groups => { 2 => 'Image' } },
+        Notes => 'the 3 tags below are also extracted from this APIC frame',
+    },
+    'APIC-1' => { Name => 'PictureMIMEType',    Groups => { 2 => 'Image' } },
     'APIC-2' => {
         Name => 'PictureType',
@@ -460,7 +538,10 @@
     MCDI => { Name => 'MusicCDIdentifier', Binary => 1 },
   # MLLT => 'MPEGLocationLookupTable',
-  # OWNE => 'Ownership', # enc(1), _price, 00, _date(8), Seller
+    OWNE => 'Ownership',
     PCNT => 'PlayCounter',
-  # POPM => 'Popularimeter', # _email, 00, rating(1), counter(4-N)
+    POPM => {
+        Name => 'Popularimeter',
+        PrintConv => '$val=~s/^(.*?) (\d+) (\d+)$/$1 Rating=$2 Count=$3/s; $val',
+    },
   # POSS => 'PostSynchronization',
     PRIV => {
@@ -471,6 +552,6 @@
   # RVRB => 'Reverb',
     SYLT => {
-        Name => 'SynchronizedLyricText',
-        Binary => 1,
+        Name => 'SynLyrics',
+        SubDirectory => { TagTable => 'Image::ExifTool::ID3::SynLyrics' },
     },
   # SYTC => 'SynchronizedTempoCodes',
@@ -501,5 +582,5 @@
     TMED => 'Media',
     TOAL => 'OriginalAlbum',
-    TOFN => 'OriginalFilename',
+    TOFN => 'OriginalFileName',
     TOLY => 'OriginalLyricist',
     TOPE => { Name => 'OriginalArtist', Groups => { 2 => 'Author' } },
@@ -517,5 +598,5 @@
     TSSE => 'EncoderSettings',
     TXXX => 'UserDefinedText',
-  # UFID => 'UniqueFileID',
+  # UFID => 'UniqueFileID', (not extracted because it is long and nasty and not very useful)
     USER => 'TermsOfUse',
     USLT => 'Lyrics',
@@ -529,4 +610,31 @@
     WPUB => 'PublisherURL',
     WXXX => 'UserDefinedURL',
+#
+# non-standard frames
+#
+    # the following are written by iTunes 10.5 (ref PH)
+    TSO2 => 'AlbumArtistSortOrder',
+    TSOC => 'ComposerSortOrder',
+    ITNU => { Name => 'iTunesU', Description => 'iTunes U', Binary => 1, Unknown => 1 },
+    PCST => { Name => 'Podcast', Binary => 1, Unknown => 1 },
+    # other proprietary Apple tags (ref http://help.mp3tag.de/main_tags.html)
+    TDES => 'PodcastDescription',
+    TGID => 'PodcastID',
+    WFED => 'PodcastURL',
+    TKWD => 'PodcastKeywords',
+    TCAT => 'PodcastCategory',
+    # more non-standard tags (ref http://eyed3.nicfit.net/compliance.html)
+    # NCON - unknown MusicMatch binary data
+    XDOR => { Name => 'OriginalReleaseTime',Groups => { 2 => 'Time' }, %dateTimeConv },
+    XSOA => 'AlbumSortOrder',
+    XSOP => 'PerformerSortOrder',
+    XSOT => 'TitleSortOrder',
+    XOLY => {
+        Name => 'OlympusDSS',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::DSS' },
+    },
+    GRP1 => 'Grouping',
+    MVNM => 'MovementName', # (NC)
+    MVIN => 'MovementNumber', # (NC)
 );
 
@@ -535,5 +643,8 @@
     PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
     GROUPS => { 1 => 'ID3v2_3', 2 => 'Audio' },
-    NOTES => 'ID3 version 2.3 tags',
+    NOTES => q{
+        ID3 version 2.3 tags.  Includes some non-standard tags written by other
+        software.
+    },
     %id3v2_common,  # include common tags
   # EQUA => 'Equalization',
@@ -552,8 +663,11 @@
     PROCESS_PROC => \&Image::ExifTool::ID3::ProcessID3v2,
     GROUPS => { 1 => 'ID3v2_4', 2 => 'Audio' },
-    NOTES => 'ID3 version 2.4 tags',
+    NOTES => q{
+        ID3 version 2.4 tags.  Includes some non-standard tags written by other
+        software.
+    },
     %id3v2_common,  # include common tags
   # EQU2 => 'Equalization',
-  # RVA2 => 'RelativeVolumeAdjustment',
+    RVA2 => 'RelativeVolumeAdjustment',
   # SEEK => 'Seek',
   # SIGN => 'Signature',
@@ -573,9 +687,46 @@
 );
 
+# Synchronized lyrics/text
+%Image::ExifTool::ID3::SynLyrics = (
+    GROUPS => { 1 => 'ID3', 2 => 'Audio' },
+    VARS => { NO_ID => 1 },
+    PROCESS_PROC => \&ProcessSynText,
+    NOTES => 'The following tags are extracted from synchronized lyrics/text frames.',
+    desc => { Name => 'SynchronizedLyricsDescription' },
+    type => {
+        Name => 'SynchronizedLyricsType',
+        PrintConv => {
+            0 => 'Other',
+            1 => 'Lyrics',
+            2 => 'Text Transcription',
+            3 => 'Movement/part Name',
+            4 => 'Events',
+            5 => 'Chord',
+            6 => 'Trivia/"pop-up" Information',
+            7 => 'Web Page URL',
+            8 => 'Image URL',
+        },
+    },
+    text => {
+        Name => 'SynchronizedLyricsText',
+        List => 1,
+        Notes => q{
+            each list item has a leading time stamp in square brackets.  Time stamps may
+            be in seconds with format [MM:SS.ss], or MPEG frames with format [FFFF],
+            depending on how this information was stored
+        },
+        PrintConv => \&ConvertTimeStamp,
+    },
+);
+
 # ID3 PRIV tags (ref PH)
 %Image::ExifTool::ID3::Private = (
     PROCESS_PROC => \&Image::ExifTool::ID3::ProcessPrivate,
     GROUPS => { 1 => 'ID3', 2 => 'Audio' },
-    NOTES => 'ID3 private (PRIV) tags.',
+    VARS => { NO_ID => 1 },
+    NOTES => q{
+        ID3 private (PRIV) tags.  ExifTool will decode any private tags found, even
+        if they do not appear in this table.
+    },
     XMP => {
         SubDirectory => {
@@ -590,4 +741,66 @@
         ValueConv => 'length($val)==4 ? unpack("V",$val) : \$val',
     },
+    # Windows Media attributes ("/" in tag ID is converted to "_" by ProcessPrivate)
+    WM_WMContentID => {
+        Name => 'WM_ContentID',
+        ValueConv => 'require Image::ExifTool::ASF; Image::ExifTool::ASF::GetGUID($val)',
+    },
+    WM_WMCollectionID => {
+        Name => 'WM_CollectionID',
+        ValueConv => 'require Image::ExifTool::ASF; Image::ExifTool::ASF::GetGUID($val)',
+    },
+    WM_WMCollectionGroupID => {
+        Name => 'WM_CollectionGroupID',
+        ValueConv => 'require Image::ExifTool::ASF; Image::ExifTool::ASF::GetGUID($val)',
+    },
+    WM_MediaClassPrimaryID => {
+        ValueConv => 'require Image::ExifTool::ASF; Image::ExifTool::ASF::GetGUID($val)',
+    },
+    WM_MediaClassSecondaryID => {
+        ValueConv => 'require Image::ExifTool::ASF; Image::ExifTool::ASF::GetGUID($val)',
+    },
+    WM_Provider => {
+        ValueConv => '$self->Decode($val,"UCS2","II")', #PH (NC)
+    },
+    # there are lots more WM tags that could be decoded if I had samples or documentation - PH
+    # WM/AlbumArtist
+    # WM/AlbumTitle
+    # WM/Category
+    # WM/Composer
+    # WM/Conductor
+    # WM/ContentDistributor
+    # WM/ContentGroupDescription
+    # WM/EncodingTime
+    # WM/Genre
+    # WM/GenreID
+    # WM/InitialKey
+    # WM/Language
+    # WM/Lyrics
+    # WM/MCDI
+    # WM/MediaClassPrimaryID
+    # WM/MediaClassSecondaryID
+    # WM/Mood
+    # WM/ParentalRating
+    # WM/Period
+    # WM/ProtectionType
+    # WM/Provider
+    # WM/ProviderRating
+    # WM/ProviderStyle
+    # WM/Publisher
+    # WM/SubscriptionContentID
+    # WM/SubTitle
+    # WM/TrackNumber
+    # WM/UniqueFileIdentifier
+    # WM/WMCollectionGroupID
+    # WM/WMCollectionID
+    # WM/WMContentID
+    # WM/Writer
+    # WM/Year
+);
+
+# lookup to check for existence of tags in other ID3 versions
+my %otherTable = (
+    \%Image::ExifTool::ID3::v2_4 => \%Image::ExifTool::ID3::v2_3,
+    \%Image::ExifTool::ID3::v2_3 => \%Image::ExifTool::ID3::v2_4,
 );
 
@@ -640,6 +853,86 @@
 sub ConvertID3v1Text($$)
 {
-    my ($exifTool, $val) = @_;
-    return $exifTool->Decode($val, $exifTool->Options('CharsetID3'));
+    my ($et, $val) = @_;
+    return $et->Decode($val, $et->Options('CharsetID3'));
+}
+
+#------------------------------------------------------------------------------
+# Re-format time stamp in synchronized lyrics
+# Inputs: 0) synchronized lyrics entry (eg. "[84.030]Da do do do")
+# Returns: entry with formatted timestamp (eg. "[01:24.03]Da do do do")
+sub ConvertTimeStamp($)
+{
+    my $val = shift;
+    # do nothing if this isn't a time stamp (frame count doesn't contain a decimal)
+    return $val unless $val =~ /^\[(\d+\.\d+)\]/g;
+    my $time = $1;
+    # print hours only if more than 60 minutes
+    my $h = int($time / 3600);
+    if ($h) {
+        $time -= $h * 3600;
+        $h = "$h:";
+    } else {
+        $h = '';
+    }
+    my $m = int($time / 60);
+    my $s = $time - $m * 60;
+    my $ss = sprintf('%05.2f', $s);
+    if ($ss >= 60) {
+        $ss = '00.00';
+        ++$m >= 60 and $m -= 60, ++$h;
+    }
+    return sprintf('[%s%.2d:%s]', $h, $m, $ss) . substr($val, pos($val));
+}
+
+#------------------------------------------------------------------------------
+# Process ID3 synchronized lyrics/text
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+sub ProcessSynText($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+
+    $et->VerboseDir('SynLyrics', 0, length $$dataPt);
+    return unless length $$dataPt > 6;
+
+    my ($enc,$lang,$timeCode,$type) = unpack('Ca3CC', $$dataPt);
+    $lang = lc $lang;
+    undef $lang if $lang !~ /^[a-z]{3}$/ or $lang eq 'eng';
+    pos($$dataPt) = 6;
+    my ($termLen, $pat);
+    if ($enc == 1 or $enc == 2) {
+        $$dataPt =~ /\G(..)*?\0\0/sg or return;
+        $termLen = 2;
+        $pat = '\G(?:..)*?\0\0(....)';
+    } else {
+        $$dataPt =~ /\0/g or return;
+        $termLen = 1;
+        $pat = '\0(....)';
+    }
+    my $desc = substr($$dataPt, 6, pos($$dataPt) - 6 - $termLen);
+    $desc = DecodeString($et, $desc, $enc);
+
+    my $tagInfo = $et->GetTagInfo($tagTablePtr, 'desc');
+    $tagInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang) if $lang;
+    $et->HandleTag($tagTablePtr, 'type', $type);
+    $et->HandleTag($tagTablePtr, 'desc', $desc, TagInfo => $tagInfo);
+    $tagInfo = $et->GetTagInfo($tagTablePtr, 'text');
+    $tagInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang) if $lang;
+
+    for (;;) {
+        my $pos = pos $$dataPt;
+        last unless $$dataPt =~ /$pat/sg;
+        my $time = unpack('N', $1);
+        my $text = substr($$dataPt, $pos, pos($$dataPt) - $pos - 4 - $termLen);
+        $text = DecodeString($et, $text, $enc);
+        my $timeStr;
+        if ($timeCode == 2) { # time in ms
+            $timeStr = sprintf('%.3f', $time / 1000);
+        } else {              # time in MPEG frames
+            $timeStr = sprintf('%.4d', $time);
+            $timeStr .= '?' if $timeCode != 1;
+        }
+        $et->HandleTag($tagTablePtr, 'text', "[$timeStr]$text", TagInfo => $tagInfo);
+    }
 }
 
@@ -649,8 +942,9 @@
 sub ProcessPrivate($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my ($tag, $start);
-    if ($$dataPt =~ /^(.*?)\0/) {
+    $et->VerboseDir('PRIV', 0, length $$dataPt);
+    if ($$dataPt =~ /^(.*?)\0/s) {
         $tag = $1;
         $start = length($tag) + 1;
@@ -663,9 +957,9 @@
         $tag = 'private' unless $tag =~ /^[-\w]{1,24}$/;
         unless ($$tagTablePtr{$tag}) {
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag,
+            AddTagToTable($tagTablePtr, $tag,
                 { Name => ucfirst($tag), Binary => 1 });
         }
     }
-    my $key = $exifTool->HandleTag($tagTablePtr, $tag, undef,
+    my $key = $et->HandleTag($tagTablePtr, $tag, undef,
         Size  => length($$dataPt) - $start,
         Start => $start,
@@ -673,5 +967,5 @@
     );
     # set group1 name
-    $exifTool->SetGroup($key, $$exifTool{ID3_Ver}) if $key;
+    $et->SetGroup($key, $$et{ID3_Ver}) if $key;
 }
 
@@ -690,11 +984,20 @@
     # (genre numbers are separated by nulls in ID3v2.4,
     #  but nulls are converted to '/' by DecodeString())
-    while ($val =~ /(?:^|\/)(\d+)/g) {
+    while ($val =~ /(?:^|\/)(\d+)(\/|$)/g) {
         $genre{$1} or $genre{$1} = "Unknown ($1)";
     }
     $val =~ s/\((\d+)\)/\($genre{$1}\)/g;
-    $val =~ s/(^|\/)(\d+)/$1$genre{$2}/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);
 }
 
@@ -707,5 +1010,5 @@
 sub DecodeString($$;$)
 {
-    my ($exifTool, $val, $enc) = @_;
+    my ($et, $val, $enc) = @_;
     return '' unless length $val;
     unless (defined $enc) {
@@ -719,5 +1022,5 @@
         @vals = split "\0", $val;
         foreach $val (@vals) {
-            $val = $exifTool->Decode($val, $enc ? 'UTF8' : 'Latin');
+            $val = $et->Decode($val, $enc ? 'UTF8' : 'Latin');
         }
     } elsif ($enc == 1 or $enc == 2) {  # UTF-16 with BOM, or UTF-16BE
@@ -727,5 +1030,5 @@
             my $v;
             # split string at null terminators on word boundaries
-            if ($val =~ s/((..)*?)\0\0//) {
+            if ($val =~ s/((..)*?)\0\0//s) {
                 $v = $1;
             } else {
@@ -735,5 +1038,5 @@
             }
             $bom = $1 if $v =~ s/^(\xfe\xff|\xff\xfe)//;
-            push @vals, $exifTool->Decode($v, 'UCS2', $order{$bom});
+            push @vals, $et->Decode($v, 'UCS2', $order{$bom});
         }
     } else {
@@ -764,13 +1067,14 @@
 sub ProcessID3v2($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt  = $$dirInfo{DataPt};
     my $offset  = $$dirInfo{DirStart};
     my $size    = $$dirInfo{DirLen};
     my $vers    = $$dirInfo{Version};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $len;    # frame data length
 
-    $verbose and $exifTool->VerboseDir($tagTablePtr->{GROUPS}->{1}, 0, $size);
+    $et->VerboseDir($tagTablePtr->{GROUPS}->{1}, 0, $size);
+    $et->VerboseDump($dataPt, Len => $size, Start => $offset);
 
     for (;;$offset+=$len) {
@@ -796,5 +1100,5 @@
                 $len =  UnSyncSafe($len);
                 if (not defined $len or $offset + $len + 10 > $size) {
-                    $exifTool->Warn('Invalid ID3 frame size');
+                    $et->Warn('Invalid ID3 frame size');
                     last;
                 }
@@ -810,16 +1114,22 @@
         }
         last if $offset + $len > $size;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $id);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $id);
         unless ($tagInfo) {
-            next unless $verbose or $exifTool->Options('Unknown');
-            $id =~ tr/-A-Za-z0-9_//dc;
-            $id = 'unknown' unless length $id;
-            unless ($$tagTablePtr{$id}) {
-                $tagInfo = { Name => "ID3_$id", Binary => 1 };
-                Image::ExifTool::AddTagToTable($tagTablePtr, $id, $tagInfo);
+            my $otherTable = $otherTable{$tagTablePtr};
+            $tagInfo = $et->GetTagInfo($otherTable, $id) if $otherTable;
+            if ($tagInfo) {
+                $et->WarnOnce("Frame '${id}' is not valid for this ID3 version", 1);
+            } else {
+                next unless $verbose or $et->Options('Unknown');
+                $id =~ tr/-A-Za-z0-9_//dc;
+                $id = 'unknown' unless length $id;
+                unless ($$tagTablePtr{$id}) {
+                    $tagInfo = { Name => "ID3_$id", Binary => 1 };
+                    AddTagToTable($tagTablePtr, $id, $tagInfo);
+                }
             }
         }
         # decode v2.3 and v2.4 flags
-        my %flags;
+        my (%flags, %extra);
         if ($flags) {
             if ($vers < 0x0400) {
@@ -838,5 +1148,5 @@
         }
         if ($flags{Encrypt}) {
-            $exifTool->WarnOnce('Encrypted frames currently not supported');
+            $et->WarnOnce('Encrypted frames currently not supported');
             next;
         }
@@ -849,5 +1159,5 @@
         # read grouping identity
         if ($flags{GroupID}) {
-            length($val) >= 1 or $exifTool->Warn("Short $id frame"), next;
+            length($val) >= 1 or $et->Warn("Short $id frame"), next;
             $val = substr($val, 1); # (ignore it)
         }
@@ -855,5 +1165,5 @@
         my $dataLen;
         if ($flags{DataLen} or $flags{Compress}) {
-            length($val) >= 4 or $exifTool->Warn("Short $id frame"), next;
+            length($val) >= 4 or $et->Warn("Short $id frame"), next;
             $dataLen = unpack('N', $val);   # save the data length word
             $val = substr($val, 4);
@@ -861,5 +1171,5 @@
         # uncompress data
         if ($flags{Compress}) {
-            if (eval 'require Compress::Zlib') {
+            if (eval { require Compress::Zlib }) {
                 my $inflate = Compress::Zlib::inflateInit();
                 my ($buff, $stat);
@@ -868,9 +1178,9 @@
                     $val = $buff;
                 } else {
-                    $exifTool->Warn("Error inflating $id frame");
+                    $et->Warn("Error inflating $id frame");
                     next;
                 }
             } else {
-                $exifTool->WarnOnce('Install Compress::Zlib to decode compressed frames');
+                $et->WarnOnce('Install Compress::Zlib to decode compressed frames');
                 next;
             }
@@ -879,18 +1189,24 @@
         if (defined $dataLen) {
             $dataLen = UnSyncSafe($dataLen);
-            defined $dataLen or $exifTool->Warn("Invalid length for $id frame"), next;
-            $dataLen == length($val) or $exifTool->Warn("Wrong length for $id frame"), next;
-        }
-        $verbose and $exifTool->VerboseInfo($id, $tagInfo,
-            Table   => $tagTablePtr,
-            Value   => $val,
-            DataPt  => $dataPt,
-            DataPos => $$dirInfo{DataPos},
-            Size    => $len,
-            Start   => $offset,
-        );
-        next unless $tagInfo;
+            defined $dataLen or $et->Warn("Invalid length for $id frame"), next;
+            $dataLen == length($val) or $et->Warn("Wrong length for $id frame"), next;
+        }
+        unless ($tagInfo) {
+            next unless $verbose;
+            %flags and $extra{Extra} = ', Flags=' . join(',', sort keys %flags);
+            $et->VerboseInfo($id, $tagInfo,
+                Table   => $tagTablePtr,
+                Value   => $val,
+                DataPt  => $dataPt,
+                DataPos => $$dirInfo{DataPos},
+                Size    => $len,
+                Start   => $offset,
+                %extra
+            );
+            next;
+        }
 #
-# decode data in this frame
+# decode data in this frame (it is bad form to hard-code these, but the ID3 frame formats
+# are so variable that it would be more work to define format types for each of them)
 #
         my $lang;
@@ -898,9 +1214,9 @@
         if ($id =~ /^(TXX|TXXX)$/) {
             # two encoded strings separated by a null
-            my @vals = DecodeString($exifTool, $val);
+            my @vals = DecodeString($et, $val);
             foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
             ($val = "($vals[0]) $vals[1]") =~ s/^\(\) //;
         } elsif ($id =~ /^T/ or $id =~ /^(IPL|IPLS)$/) {
-            $val = DecodeString($exifTool, $val);
+            $val = DecodeString($et, $val);
         } elsif ($id =~ /^(WXX|WXXX)$/) {
             # one encoded string and one Latin string separated by a null
@@ -908,37 +1224,34 @@
             my $url;
             if ($enc == 1 or $enc == 2) {
-                ($val, $url) = ($val =~ /^(.(?:..)*?)\0\0(.*)/);
+                ($val, $url) = ($val =~ /^(.(?:..)*?)\0\0(.*)/s);
             } else {
-                ($val, $url) = ($val =~ /^(..*?)\0(.*)/);
+                ($val, $url) = ($val =~ /^(..*?)\0(.*)/s);
             }
             unless (defined $val and defined $url) {
-                $exifTool->Warn("Invalid $id frame value");
+                $et->Warn("Invalid $id frame value");
                 next;
             }
-            $val = DecodeString($exifTool, $val);
-            $url =~ s/\0.*//;
+            $val = DecodeString($et, $val);
+            $url =~ s/\0.*//s;
             $val = length($val) ? "($val) $url" : $url;
         } elsif ($id =~ /^W/) {
-            $val =~ s/\0.*//;   # truncate at null
+            $val =~ s/\0.*//s;  # truncate at null
         } elsif ($id =~ /^(COM|COMM|ULT|USLT)$/) {
-            $valLen > 4 or $exifTool->Warn("Short $id frame"), next;
+            $valLen > 4 or $et->Warn("Short $id frame"), next;
             $lang = substr($val,1,3);
-            my @vals = DecodeString($exifTool, substr($val,4), Get8u(\$val,0));
+            my @vals = DecodeString($et, substr($val,4), Get8u(\$val,0));
             foreach (0..1) { $vals[$_] = '' unless defined $vals[$_]; }
             $val = length($vals[0]) ? "($vals[0]) $vals[1]" : $vals[1];
         } elsif ($id eq 'USER') {
-            $valLen > 4 or $exifTool->Warn('Short USER frame'), next;
+            $valLen > 4 or $et->Warn("Short $id frame"), next;
             $lang = substr($val,1,3);
-            $val = DecodeString($exifTool, substr($val,4), Get8u(\$val,0));
+            $val = DecodeString($et, substr($val,4), Get8u(\$val,0));
         } elsif ($id =~ /^(CNT|PCNT)$/) {
-            $valLen >= 4 or $exifTool->Warn("Short $id frame"), next;
-            my $cnt = unpack('N', $val);
-            my $i;
-            for ($i=4; $i<$valLen; ++$i) {
-                $cnt = $cnt * 256 + unpack("x${i}C", $val);
-            }
+            $valLen >= 4 or $et->Warn("Short $id frame"), next;
+            my ($cnt, @xtra) = unpack('NC*', $val);
+            $cnt = ($cnt << 8) + $_ foreach @xtra;
             $val = $cnt;
         } elsif ($id =~ /^(PIC|APIC)$/) {
-            $valLen >= 4 or $exifTool->Warn("Short $id frame"), next;
+            $valLen >= 4 or $et->Warn("Short $id frame"), next;
             my ($hdr, $attr);
             my $enc = unpack('C', $val);
@@ -949,20 +1262,88 @@
             }
             # remove header (encoding, image format or MIME type, picture type, description)
-            $val =~ s/^$hdr//s or $exifTool->Warn("Invalid $id frame"), next;
-            my @attrs = ($1, ord($2), DecodeString($exifTool, $3, $enc));
+            $val =~ s/^$hdr//s or $et->Warn("Invalid $id frame"), next;
+            my @attrs = ($1, ord($2), DecodeString($et, $3, $enc));
             my $i = 1;
             foreach $attr (@attrs) {
                 # must store descriptions even if they are empty to maintain
                 # sync between copy numbers when multiple images
-                $exifTool->HandleTag($tagTablePtr, "$id-$i", $attr);
+                $et->HandleTag($tagTablePtr, "$id-$i", $attr);
                 ++$i;
             }
+        } elsif ($id eq 'POP' or $id eq 'POPM') {
+            # _email, 00, rating(1), counter(4-N)
+            my ($email, $dat) = ($val =~ /^([^\0]*)\0(.*)$/s);
+            unless (defined $dat and length($dat)) {
+                $et->Warn("Invalid $id frame");
+                next;
+            }
+            my ($rating, @xtra) = unpack('C*', $dat);
+            my $cnt = 0;
+            $cnt = ($cnt << 8) + $_ foreach @xtra;
+            $val = "$email $rating $cnt";
+        } elsif ($id eq 'OWNE') {
+            # enc(1), _price, 00, _date(8), Seller
+            my @strs = DecodeString($et, $val);
+            $strs[1] =~ s/^(\d{4})(\d{2})(\d{2})/$1:$2:$3 /s if $strs[1]; # format date
+            $val = "@strs";
+        } elsif ($id eq 'RVA' or $id eq 'RVAD') {
+            my @dat = unpack('C*', $val);
+            my $flag = shift @dat;
+            my $bits = shift @dat or $et->Warn("Short $id frame"), next;
+            my $bytes = int(($bits + 7) / 8);
+            my @parse = (['Right',0,2,0x01],['Left',1,3,0x02],['Back-right',4,6,0x04],
+                         ['Back-left',5,7,0x08],['Center',8,9,0x10],['Bass',10,11,0x20]);
+            $val = '';
+            while (@parse) {
+                my $elem = shift @parse;
+                my $j = $$elem[2] * $bytes;
+                last if scalar(@dat) < $j + $bytes;
+                my $i = $$elem[1] * $bytes;
+                $val .= ', ' if $val;
+                my ($rel, $pk, $b);
+                for ($rel=0, $pk=0, $b=0; $b<$bytes; ++$b) {
+                    $rel = $rel * 256 + $dat[$i + $b];
+                    $pk  = $pk  * 256 + $dat[$j + $b]; # (peak - not used in printout)
+                }
+                $rel =-$rel unless $flag & $$elem[3];
+                $val .= sprintf("%+.1f%% %s", 100 * $rel / ((1<<$bits)-1), $$elem[0]);
+            }
+        } elsif ($id eq 'RVA2') {
+            my ($pos, $id) = $val=~/^([^\0]*)\0/s ? (length($1)+1, $1) : (1, '');
+            my @vals;
+            while ($pos + 4 <= $valLen) {
+                my $type = Get8u(\$val, $pos);
+                my $str = ({
+                    0 => 'Other',
+                    1 => 'Master',
+                    2 => 'Front-right',
+                    3 => 'Front-left',
+                    4 => 'Back-right',
+                    5 => 'Back-left',
+                    6 => 'Front-centre',
+                    7 => 'Back-centre',
+                    8 => 'Subwoofer',
+                }->{$type} || "Unknown($type)");
+                my $db = Get16s(\$val,$pos+1) / 512;
+                # convert dB to percent as displayed by iTunes 10.5
+                # (not sure why I need to divide by 20 instead of 10 as expected - PH)
+                push @vals, sprintf('%+.1f%% %s', 10**($db/20+2)-100, $str);
+                # step to next channel (ignoring peak volume)
+                $pos += 4 + int((Get8u(\$val,$pos+3) + 7) / 8);
+            }
+            $val = join ', ', @vals;
+            $val .= " ($id)" if $id;
         } elsif ($id eq 'PRIV') {
             # save version number to set group1 name for tag later
-            $exifTool->{ID3_Ver} = $tagTablePtr->{GROUPS}->{1};
-            $exifTool->HandleTag($tagTablePtr, $id, $val);
+            $$et{ID3_Ver} = $$tagTablePtr{GROUPS}{1};
+            $et->HandleTag($tagTablePtr, $id, $val);
             next;
+        } elsif ($$tagInfo{Format} or $$tagInfo{SubDirectory}) {
+            $et->HandleTag($tagTablePtr, $id, undef, DataPt => \$val);
+            next;
+        } elsif ($id eq 'GRP1' or $id eq 'MVNM' or $id eq 'MVIN') {
+            $val =~ s/(^\0+|\0+$)//g;   # (PH guess)
         } elsif (not $$tagInfo{Binary}) {
-            $exifTool->Warn("Don't know how to handle $id frame");
+            $et->Warn("Don't know how to handle $id frame");
             next;
         }
@@ -970,5 +1351,13 @@
             $tagInfo = Image::ExifTool::GetLangInfo($tagInfo, lc $lang);
         }
-        $exifTool->FoundTag($tagInfo, $val);
+        %flags and $extra{Extra} = ', Flags=' . join(',', sort keys %flags);
+        $et->HandleTag($tagTablePtr, $id, $val,
+            TagInfo => $tagInfo,
+            DataPt  => $dataPt,
+            DataPos => $$dirInfo{DataPos},
+            Size    => $len,
+            Start   => $offset,
+            %extra
+        );
     }
 }
@@ -979,11 +1368,11 @@
 # Returns: 1 on success, 0 if this file didn't contain ID3 information
 # - also processes audio data if any ID3 information was found
-# - sets ExifTool DoneID3 to 1 when called, or to 2 if an ID3v1 trailer exists
+# - sets ExifTool DoneID3 to 1 when called, or to trailer size if an ID3v1 trailer exists
 sub ProcessID3($$)
 {
-    my ($exifTool, $dirInfo) = @_;
-
-    return 0 if $exifTool->{DoneID3};  # avoid infinite recursion
-    $exifTool->{DoneID3} = 1;
+    my ($et, $dirInfo) = @_;
+
+    return 0 if $$et{DoneID3};  # avoid infinite recursion
+    $$et{DoneID3} = 1;
 
     # allow this to be called with either RAF or DataPt
@@ -1002,15 +1391,15 @@
     while ($buff =~ /^ID3/) {
         $rtnVal = 1;
-        $raf->Read($hBuff, 7) == 7 or $exifTool->Warn('Short ID3 header'), last;
+        $raf->Read($hBuff, 7) == 7 or $et->Warn('Short ID3 header'), last;
         my ($vers, $flags, $size) = unpack('nCN', $hBuff);
         $size = UnSyncSafe($size);
-        defined $size or $exifTool->Warn('Invalid ID3 header'), last;
+        defined $size or $et->Warn('Invalid ID3 header'), last;
         my $verStr = sprintf("2.%d.%d", $vers >> 8, $vers & 0xff);
         if ($vers >= 0x0500) {
-            $exifTool->Warn("Unsupported ID3 version: $verStr");
+            $et->Warn("Unsupported ID3 version: $verStr");
             last;
         }
         unless ($raf->Read($hBuff, $size) == $size) {
-            $exifTool->Warn('Truncated ID3 data');
+            $et->Warn('Truncated ID3 data');
             last;
         }
@@ -1023,8 +1412,8 @@
         if ($flags & 0x40) {
             # skip the extended header
-            $size >= 4 or $exifTool->Warn('Bad ID3 extended header'), last;
+            $size >= 4 or $et->Warn('Bad ID3 extended header'), last;
             my $len = unpack('N', $hBuff);
             if ($len > length($hBuff) - 4) {
-                $exifTool->Warn('Truncated ID3 extended header');
+                $et->Warn('Truncated ID3 extended header');
                 last;
             }
@@ -1058,6 +1447,7 @@
 # read ID3v1 trailer if it exists
 #
+    my $trailSize = 0;
     if ($raf->Seek(-128, 2) and $raf->Read($tBuff, 128) == 128 and $tBuff =~ /^TAG/) {
-        $exifTool->{DoneID3} = 2;  # set to 2 as flag that trailer exists
+        $trailSize = 128;
         %id3Trailer = (
             DataPt   => \$tBuff,
@@ -1069,6 +1459,57 @@
         $rtnVal = 1;
         # load 'Enhanced TAG' information if available
-        if ($raf->Seek(-355, 2) and $raf->Read($eBuff, 227) == 227 and $eBuff =~ /^TAG+/) {
+        my $eSize = 227;    # size of ID3 Enhanced TAG info
+        if ($raf->Seek(-$trailSize - $eSize, 2) and $raf->Read($eBuff, $eSize) == $eSize and $eBuff =~ /^TAG+/) {
             $id3Trailer{EnhancedTAG} = \$eBuff;
+            $trailSize += $eSize;
+        }
+        $$et{DoneID3} = $trailSize; # save trailer size
+    }
+#
+# read Lyrics3 trailer if it exists
+#
+    if ($raf->Seek(-$trailSize-15, 2) and $raf->Read($buff, 15) == 15 and $buff =~ /^(.{6})LYRICS(END|200)$/) {
+        my $ver = $2;   # Lyrics3 version ('END' for version 1)
+        my $len = ($ver eq 'END') ? 5100 : $1 + 15; # max Lyrics3 length
+        my $tbl = GetTagTable('Image::ExifTool::ID3::Lyrics3');
+        $len = $raf->Tell() if $len > $raf->Tell();
+        if ($raf->Seek(-$len, 1) and $raf->Read($buff, $len) == $len and $buff =~ /LYRICSBEGIN/g) {
+            my $pos = pos($buff);
+            $$et{DoneID3} = $trailSize + $len - $pos + 11;  # update trailer length
+            my $oldIndent = $$et{INDENT};
+            $$et{INDENT} .= '| ';
+            if ($et->Options('Verbose')) {
+                $et->VPrint(0, "Lyrics3:\n");
+                $et->VerboseDir('Lyrics3', undef, $len);
+                if ($pos > 11) {
+                    $buff = substr($buff, $pos - 11);
+                    $pos = 11;
+                }
+                $et->VerboseDump(\$buff);
+            }
+            if ($ver eq 'END') {
+                # Lyrics3 v1.00
+                my $val = substr($buff, $pos, $len - $pos - 9);
+                $et->HandleTag($tbl, 'LYR', $et->Decode($val, 'Latin'));
+            } else {
+                # Lyrics3 v2.00
+                for (;;) {
+                    # (note: the size field is 5 digits,, not 6 as per the documentation)
+                    last unless $buff =~ /\G(.{3})(\d{5})/g;
+                    my ($tag, $size) = ($1, $2);
+                    $pos += 8;
+                    last if $pos + $size > length($buff);
+                    unless ($$tbl{$tag}) {
+                        AddTagToTable($tbl, $tag, { Name => Image::ExifTool::MakeTagName("Lyrics3_$tag") });
+                    }
+                    $et->HandleTag($tbl, $tag, $et->Decode(substr($buff, $pos, $size), 'Latin'));
+                    $pos += $size;
+                    pos($buff) = $pos;
+                }
+                $pos == length($buff) - 15 or $et->Warn('Malformed Lyrics3 v2.00 block');
+            }
+            $$et{INDENT} = $oldIndent;
+        } else {
+            $et->Warn('Error reading Lyrics3 trailer');
         }
     }
@@ -1079,5 +1520,5 @@
         # first process audio data if it exists
         if ($$dirInfo{RAF}) {
-            my $oldType = $exifTool->{FILE_TYPE};   # save file type
+            my $oldType = $$et{FILE_TYPE};   # save file type
             # check current file type first
             my @types = grep /^$oldType$/, @audioFormats;
@@ -1088,5 +1529,5 @@
                 $raf->Seek($hdrEnd, 0);
                 # set type for this file if we are successful
-                $exifTool->{FILE_TYPE} = $type;
+                $$et{FILE_TYPE} = $type;
                 my $module = $audioModule{$type} || $type;
                 require "Image/ExifTool/$module.pm" or next;
@@ -1094,32 +1535,32 @@
                 # process the file
                 no strict 'refs';
-                &$func($exifTool, $dirInfo) and last;
+                &$func($et, $dirInfo) and last;
                 use strict 'refs';
             }
-            $exifTool->{FILE_TYPE} = $oldType;      # restore original file type
+            $$et{FILE_TYPE} = $oldType;      # restore original file type
         }
         # set file type to MP3 if we didn't find audio data
-        $exifTool->SetFileType('MP3');
-        # record the size if the ID3 metadata
-        $exifTool->FoundTag('ID3Size', $id3Len);
+        $et->SetFileType('MP3');
+        # record the size of the ID3 metadata
+        $et->FoundTag('ID3Size', $id3Len);
         # process ID3v2 header if it exists
         if (%id3Header) {
-            $exifTool->VPrint(0, "$id3Header{DirName}:\n");
-            $exifTool->ProcessDirectory(\%id3Header, $tagTablePtr);
+            $et->VPrint(0, "$id3Header{DirName}:\n");
+            $et->ProcessDirectory(\%id3Header, $tagTablePtr);
         }
         # process ID3v1 trailer if it exists
         if (%id3Trailer) {
-            $exifTool->VPrint(0, "ID3v1:\n");
+            $et->VPrint(0, "ID3v1:\n");
             SetByteOrder('MM');
             $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v1');
-            $exifTool->ProcessDirectory(\%id3Trailer, $tagTablePtr);
+            $et->ProcessDirectory(\%id3Trailer, $tagTablePtr);
             # process "Enhanced TAG" information if available
             if ($id3Trailer{EnhancedTAG}) {
-                $exifTool->VPrint(0, "ID3v1 Enhanced TAG:\n");
+                $et->VPrint(0, "ID3v1 Enhanced TAG:\n");
                 $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v1_Enh');
                 $id3Trailer{DataPt} = $id3Trailer{EnhancedTAG};
                 $id3Trailer{DataPos} -= 227; # (227 = length of Enhanced TAG block)
                 $id3Trailer{DirLen} = 227;
-                $exifTool->ProcessDirectory(\%id3Trailer, $tagTablePtr);
+                $et->ProcessDirectory(\%id3Trailer, $tagTablePtr);
             }
         }
@@ -1136,30 +1577,44 @@
 sub ProcessMP3($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
+    my $rtnVal = 0;
 
     # must first check for leading/trailing ID3 information
-    unless ($exifTool->{DoneID3}) {
-        ProcessID3($exifTool, $dirInfo) and return 1;
-    }
-    my $raf = $$dirInfo{RAF};
-    my $rtnVal = 0;
-    my $buff;
+    # (and process the rest of the file if found)
+    unless ($$et{DoneID3}) {
+        $rtnVal = ProcessID3($et, $dirInfo);
+    }
+
+    # check for MPEG A/V data if not already processed above
+    unless ($rtnVal) {
+        my $raf = $$dirInfo{RAF};
+        my $buff;
 #
 # extract information from first audio/video frame headers
 # (if found in the first $scanLen bytes)
 #
-    # scan further into a file that should be an MP3
-    my $scanLen = ($$exifTool{FILE_EXT} and $$exifTool{FILE_EXT} eq 'MP3') ? 8192 : 256;
-    if ($raf->Read($buff, $scanLen)) {
-        require Image::ExifTool::MPEG;
-        if ($buff =~ /\0\0\x01(\xb3|\xc0)/) {
-            # look for A/V headers in first 64kB
-            my $buf2;
-            $raf->Read($buf2, 0x10000 - $scanLen) and $buff .= $buf2;
-            $rtnVal = 1 if Image::ExifTool::MPEG::ParseMPEGAudioVideo($exifTool, \$buff);
-        } else {
-            # look for audio frame sync in first $scanLen bytes
-            $rtnVal = 1 if Image::ExifTool::MPEG::ParseMPEGAudio($exifTool, \$buff);
-        }
+        # scan further into a file that should be an MP3
+        my $scanLen = ($$et{FILE_EXT} and $$et{FILE_EXT} eq 'MP3') ? 8192 : 256;
+        if ($raf->Read($buff, $scanLen)) {
+            require Image::ExifTool::MPEG;
+            if ($buff =~ /\0\0\x01(\xb3|\xc0)/) {
+                # look for A/V headers in first 64kB
+                my $buf2;
+                $raf->Read($buf2, 0x10000 - $scanLen) and $buff .= $buf2;
+                $rtnVal = 1 if Image::ExifTool::MPEG::ParseMPEGAudioVideo($et, \$buff);
+            } else {
+                # look for audio frame sync in first $scanLen bytes
+                # (set MP3 flag to 1 so this will fail unless layer 3 audio)
+                my $ext = $$et{FILE_EXT} || '';
+                my $mp3 = ($ext eq 'MUS') ? 0 : 1;  # MUS files are MP2
+                $rtnVal = 1 if Image::ExifTool::MPEG::ParseMPEGAudio($et, \$buff, $mp3);
+            }
+        }
+    }
+
+    # check for an APE trailer if this was a valid A/V file and we haven't already done it
+    if ($rtnVal and not $$et{DoneAPE}) {
+        require Image::ExifTool::APE;
+        Image::ExifTool::APE::ProcessAPE($et, $dirInfo);
     }
     return $rtnVal;
@@ -1186,5 +1641,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -1201,4 +1656,6 @@
 =item L<http://www.fortunecity.com/underworld/sonic/3/id3tag.html>
 
+=item L<https://id3.org/Lyrics3>
+
 =back
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/IPTC.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/IPTC.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/IPTC.pm	(revision 34921)
@@ -14,6 +14,7 @@
 use strict;
 use vars qw($VERSION $AUTOLOAD %iptcCharset);
-
-$VERSION = '1.42';
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.57';
 
 %iptcCharset = (
@@ -32,4 +33,24 @@
 sub PrintCodedCharset($);
 sub PrintInvCodedCharset($);
+
+# standard IPTC locations
+# (MWG specifies locations only for JPEG, TIFF and PSD -- the rest are ExifTool-defined)
+my %isStandardIPTC = (
+    'JPEG-APP13-Photoshop-IPTC' => 1,
+    'TIFF-IFD0-IPTC'            => 1,
+    'PSD-IPTC'                  => 1,
+    'MIE-IPTC'                  => 1,
+    'EPS-Photoshop-IPTC'        => 1,
+    'PS-Photoshop-IPTC'         => 1,
+    'EXV-APP13-Photoshop-IPTC'  => 1,
+    # set file types to 0 if they have a standard location
+    JPEG => 0,
+    TIFF => 0,
+    PSD  => 0,
+    MIE  => 0,
+    EPS  => 0,
+    PS   => 0,
+    EXV  => 0,
+);
 
 my %fileFormat = (
@@ -182,4 +203,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     80 => {
@@ -190,4 +212,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     90 => {
@@ -206,4 +229,5 @@
         Protected => 1,
         Format => 'string[0,32]',
+        ValueConvInv => '$val =~ /^UTF-?8$/i ? "\x1b%G" : $val',
         # convert ISO 2022 escape sequences to a more readable format
         PrintConv => \&PrintCodedCharset,
@@ -317,4 +341,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     35 => {
@@ -325,4 +350,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     37 => {
@@ -333,4 +359,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     38 => {
@@ -341,4 +368,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     40 => {
@@ -353,5 +381,5 @@
             '01' => 'Object Kill',
             '02' => 'Object Replace',
-            '03' => 'Ojbect Append',
+            '03' => 'Object Append',
             '04' => 'Object Reference',
         },
@@ -370,4 +398,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     50 => {
@@ -383,4 +412,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     60 => {
@@ -391,4 +421,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     62 => {
@@ -399,4 +430,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcDate($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     63 => {
@@ -407,4 +439,5 @@
         ValueConv => 'Image::ExifTool::Exif::ExifTime($val)',
         ValueConvInv => 'Image::ExifTool::IPTC::IptcTime($val)',
+        PrintConvInv => 'Image::ExifTool::IPTC::InverseDateOrTime($self,$val)',
     },
     65 => {
@@ -465,4 +498,5 @@
         Name => 'OriginalTransmissionReference',
         Format => 'string[0,32]',
+        Notes => 'now used as a job identifier',
     },
     105 => {
@@ -502,5 +536,5 @@
             225-232, so I have just make them writable as strings with
             reasonable length.  Beware that if this is wrong, other utilities
-            won't be able to read these tags as written by ExifTool
+            may not be able to read these tags as written by ExifTool
         },
     },
@@ -607,5 +641,5 @@
     202 => {
         Name => 'ObjectPreviewData',
-        Groups => { 2 => 'Image' },
+        Groups => { 2 => 'Preview' },
         Format => 'undef[0,256000]',
         Binary => 1,
@@ -642,4 +676,6 @@
         Name => 'DocumentHistory',
         Format => 'string[0,256]', # (guess)
+        ValueConv => '$val =~ s/\0+/\n/g; $val', # (have seen embedded nulls)
+        ValueConvInv => '$val',
     },
     232 => {
@@ -954,5 +990,5 @@
 sub HandleCodedCharset($$)
 {
-    my ($exifTool, $val) = @_;
+    my ($et, $val) = @_;
     my $xlat = $iptcCharset{$val};
     unless ($xlat) {
@@ -961,9 +997,9 @@
             $xlat = 'bad';  # flag unsupported coding
         } else {
-            $xlat = $exifTool->Options('CharsetIPTC');
+            $xlat = $et->Options('CharsetIPTC');
         }
     }
     # no need to translate if Charset is the same
-    undef $xlat if $xlat eq $exifTool->Options('Charset');
+    undef $xlat if $xlat eq $et->Options('Charset');
     return $xlat;
 }
@@ -976,15 +1012,15 @@
 sub TranslateCodedString($$$$)
 {
-    my ($exifTool, $valPtr, $xlatPtr, $read) = @_;
+    my ($et, $valPtr, $xlatPtr, $read) = @_;
     if ($$xlatPtr eq 'bad') {
-        $exifTool->Warn('Some IPTC characters not converted (unsupported CodedCharacterSet)');
+        $et->Warn('Some IPTC characters not converted (unsupported CodedCharacterSet)');
         undef $$xlatPtr;
     } elsif (not $read) {
-        $$valPtr = $exifTool->Decode($$valPtr, undef, undef, $$xlatPtr);
+        $$valPtr = $et->Decode($$valPtr, undef, undef, $$xlatPtr);
     } elsif ($$valPtr !~ /[\x14\x15\x1b]/) {
-        $$valPtr = $exifTool->Decode($$valPtr, $$xlatPtr);
+        $$valPtr = $et->Decode($$valPtr, $$xlatPtr);
     } else {
         # don't yet support reading ISO 2022 shifted character sets
-        $exifTool->WarnOnce('Some IPTC characters not converted (ISO 2022 shifting not supported)');
+        $et->WarnOnce('Some IPTC characters not converted (ISO 2022 shifting not supported)');
     }
 }
@@ -993,9 +1029,12 @@
 # Is this IPTC in a standard location?
 # Inputs: 0) Current metadata path string
-# Returns: true if path is standard
+# Returns: true if path is standard, 0 if file type doesn't have standard IPTC,
+#          or undef if IPTC is non-standard
 sub IsStandardIPTC($)
 {
     my $path = shift;
-    return $path =~ /^(JPEG-APP13-Photoshop-IPTC|TIFF-IFD0-IPTC|PSD-IPTC|MIE-IPTC)$/
+    return 1 if $isStandardIPTC{$path};
+    return 0 unless $path =~ /^(\w+)/ and defined $isStandardIPTC{$1};
+    return undef;   # non-standard
 }
 
@@ -1007,44 +1046,59 @@
 sub ProcessIPTC($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart} || 0;
     my $dirLen = $$dirInfo{DirLen} || 0;
     my $dirEnd = $pos + $dirLen;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
+    my $validate = $et->Options('Validate');
     my $success = 0;
     my ($lastRec, $recordPtr, $recordName);
 
-    $verbose and $dirInfo and $exifTool->VerboseDir('IPTC', 0, $$dirInfo{DirLen});
+    $verbose and $dirInfo and $et->VerboseDir('IPTC', 0, $$dirInfo{DirLen});
 
     if ($tagTablePtr eq \%Image::ExifTool::IPTC::Main) {
-        # calculate MD5 if Digest::MD5 is available (for standard IPTC only)
-        my $path = $exifTool->MetadataPath();
-        if (IsStandardIPTC($path)) {
-            my $md5;
-            if (eval 'require Digest::MD5') {
-                if ($pos or $dirLen != length($$dataPt)) {
-                    $md5 = Digest::MD5::md5(substr $$dataPt, $pos, $dirLen);
+        my $path = $et->MetadataPath();
+        my $isStd = IsStandardIPTC($path);
+        if (defined $isStd and not $$et{DIR_COUNT}{STD_IPTC}) {
+            # set flag to ensure we only have one family 1 "IPTC" group
+            $$et{DIR_COUNT}{STD_IPTC} = 1;
+            # calculate MD5 if Digest::MD5 is available (truly standard IPTC only)
+            if ($isStd) {
+                my $md5;
+                if (eval { require Digest::MD5 }) {
+                    if ($pos or $dirLen != length($$dataPt)) {
+                        $md5 = Digest::MD5::md5(substr $$dataPt, $pos, $dirLen);
+                    } else {
+                        $md5 = Digest::MD5::md5($$dataPt);
+                    }
                 } else {
-                    $md5 = Digest::MD5::md5($$dataPt);
+                    # a zero digest indicates IPTC exists but we don't have Digest::MD5
+                    $md5 = "\0" x 16;
                 }
-            } else {
-                # a zero digest indicates IPTC exists but we don't have Digest::MD5
-                $md5 = "\0" x 16;
+                $et->FoundTag('CurrentIPTCDigest', $md5);
             }
-            $exifTool->FoundTag('CurrentIPTCDigest', $md5);
-        } elsif ($Image::ExifTool::MWG::strict and $$exifTool{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/) {
-            # ignore non-standard IPTC while in strict MWG compatibility mode
-            $exifTool->Warn("Ignored non-standard IPTC at $path");
-            return 1;
+        } else {
+            if (($Image::ExifTool::MWG::strict or $et->Options('Validate')) and
+                $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
+            {
+                if ($Image::ExifTool::MWG::strict) {
+                    # ignore non-standard IPTC while in strict MWG compatibility mode
+                    $et->Warn("Ignored non-standard IPTC at $path");
+                    return 1;
+                } else {
+                    $et->Warn("Non-standard IPTC at $path", 1);
+                }
+            }
+            # extract non-standard IPTC
+            my $count = ($$et{DIR_COUNT}{IPTC} || 0) + 1;  # count non-standard IPTC
+            $$et{DIR_COUNT}{IPTC} = $count;
+            $$et{LOW_PRIORITY_DIR}{IPTC} = 1;       # lower priority of non-standard IPTC
+            $$et{SET_GROUP1} = '+' . ($count + 1);  # add number to family 1 group name
         }
-        # set family 1 group name if multiple IPTC directories
-        my $dirCount = ($exifTool->{DIR_COUNT}->{IPTC} || 0) + 1;
-        $exifTool->{DIR_COUNT}->{IPTC} = $dirCount;
-        $exifTool->{SET_GROUP1} = '+' . $dirCount if $dirCount > 1;
     }
     # begin by assuming default IPTC encoding
-    my $xlat = $exifTool->Options('CharsetIPTC');
-    undef $xlat if $xlat eq $exifTool->Options('Charset');
+    my $xlat = $et->Options('CharsetIPTC');
+    undef $xlat if $xlat eq $et->Options('Charset');
 
     # quick check for improperly byte-swapped IPTC
@@ -1052,5 +1106,5 @@
                          substr($$dataPt, $pos + 3, 1) eq "\x1c")
     {
-        $exifTool->Warn('IPTC data was improperly byte-swapped');
+        $et->Warn('IPTC data was improperly byte-swapped');
         my $newData = pack('N*', unpack('V*', substr($$dataPt, $pos, $dirLen) . "\0\0\0"));
         $dataPt = \$newData;
@@ -1058,4 +1112,14 @@
         $dirEnd = $pos + $dirLen;
         # NOTE: MUST NOT access $dirInfo DataPt, DirStart or DataLen after this!
+    }
+    # extract IPTC as a block if specified
+    if ($$et{REQ_TAG_LOOKUP}{iptc} or ($$et{TAGS_FROM_FILE} and
+        not $$et{EXCL_TAG_LOOKUP}{iptc}))
+    {
+        if ($pos or $dirLen != length($$dataPt)) {
+            $et->FoundTag('IPTC', substr($$dataPt, $pos, $dirLen));
+        } else {
+            $et->FoundTag('IPTC', $$dataPt);
+        }
     }
     while ($pos + 5 <= $dirEnd) {
@@ -1069,22 +1133,6 @@
                 last unless $remaining =~ /[^\0]/;
             }
-            $exifTool->Warn(sprintf('Bad IPTC data tag (marker 0x%x)',$id));
+            $et->Warn(sprintf('Bad IPTC data tag (marker 0x%x)',$id));
             last;
-        }
-        if (not defined $lastRec or $lastRec != $rec) {
-            my $tableInfo = $tagTablePtr->{$rec};
-            unless ($tableInfo) {
-                $exifTool->Warn("Unrecognized IPTC record $rec, subsequent records ignored");
-                last;   # stop now because we're probably reading garbage
-            }
-            my $tableName = $tableInfo->{SubDirectory}->{TagTable};
-            unless ($tableName) {
-                $exifTool->Warn("No table for IPTC record $rec!");
-                last;   # this shouldn't happen
-            }
-            $recordName = $$tableInfo{Name};
-            $recordPtr = Image::ExifTool::GetTagTable($tableName);
-            $exifTool->VPrint(0,$$exifTool{INDENT},"-- $recordName record --\n");
-            $lastRec = $rec;
         }
         $pos += 5;      # step to after field header
@@ -1093,5 +1141,5 @@
             my $n = $len & 0x7fff; # get num bytes in length field
             if ($pos + $n > $dirEnd or $n > 8) {
-                $exifTool->VPrint(0, "Invalid extended IPTC entry (tag $tag)\n");
+                $et->VPrint(0, "Invalid extended IPTC entry (dataset $rec:$tag, len $len)\n");
                 $success = 0;
                 last;
@@ -1103,7 +1151,27 @@
         }
         if ($pos + $len > $dirEnd) {
-            $exifTool->VPrint(0, "Invalid IPTC entry (tag $tag, len $len)\n");
+            $et->VPrint(0, "Invalid IPTC entry (dataset $rec:$tag, len $len)\n");
             $success = 0;
             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)");
+                $pos += $len;
+                next;   # ignore this entry
+            }
+            my $tableName = $tableInfo->{SubDirectory}->{TagTable};
+            unless ($tableName) {
+                $et->Warn("No table for IPTC record $rec!");
+                last;   # this shouldn't happen
+            }
+            $recordName = $$tableInfo{Name};
+            $recordPtr = Image::ExifTool::GetTagTable($tableName);
+            $et->VPrint(0,$$et{INDENT},"-- $recordName record --\n");
+            $lastRec = $rec;
         }
         my $val = substr($$dataPt, $pos, $len);
@@ -1113,15 +1181,32 @@
             # - no Format so format is auto-detected
             # - no Name so name is generated automatically with decimal tag number
-            Image::ExifTool::AddTagToTable($recordPtr, $tag, { Unknown => 1 });
+            AddTagToTable($recordPtr, $tag, { Unknown => 1 });
         }
 
-        my $tagInfo = $exifTool->GetTagInfo($recordPtr, $tag);
+        my $tagInfo = $et->GetTagInfo($recordPtr, $tag);
         my $format;
         # (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) {
@@ -1135,20 +1220,25 @@
                 }
             } 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($exifTool, $val) if $tag == 90;
+                    $xlat = HandleCodedCharset($et, $val) if $tag == 90;
                 # translate characters if necessary and special characters exist
                 } elsif ($xlat and $rec < 7 and $val =~ /[\x80-\xff]/) {
                     # translate to specified character set
-                    TranslateCodedString($exifTool, \$val, \$xlat, 1);
+                    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 $exifTool->VerboseInfo($tag, $tagInfo,
+        $verbose and $et->VerboseInfo($tag, $tagInfo,
             Table   => $tagTablePtr,
             Value   => $val,
@@ -1160,10 +1250,11 @@
             Format  => $format,
         );
-        $exifTool->FoundTag($tagInfo, $val) if $tagInfo;
+        $et->FoundTag($tagInfo, $val) if $tagInfo;
         $success = 1;
 
         $pos += $len;   # increment to next field
     }
-    delete $exifTool->{SET_GROUP1};
+    delete $$et{SET_GROUP1};
+    delete $$et{LOW_PRIORITY_DIR}{IPTC};
     return $success;
 }
@@ -1190,5 +1281,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ISO.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ISO.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ISO.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ITC.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ITC.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ITC.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.00';
+$VERSION = '1.02';
 
 sub ProcessITC($$);
@@ -69,5 +69,5 @@
         Name => 'ImageType',
         Format => 'undef[4]',
-        PrintConv => {
+        ValueConv => { # (not PrintConv because the unconverted JPEG value is nasty)
             'PNGf' => 'PNG',
             "\0\0\0\x0d" => 'JPEG',
@@ -84,5 +84,5 @@
 sub ProcessITC($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $rtnVal = 0;
@@ -106,5 +106,5 @@
             last unless $tag eq 'itch';
             last unless $size >= 0x1c and $size < 0x10000;
-            $exifTool->SetFileType();
+            $et->SetFileType();
             SetByteOrder('MM');
             $rtnVal = 1;    # this is an ITC file
@@ -122,5 +122,5 @@
             );
             my $tagTablePtr = GetTagTable('Image::ExifTool::ITC::Header');
-            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         } elsif ($tag eq 'item') {
             # don't want to read the entire item data (includes image)
@@ -142,5 +142,5 @@
             $raf->Read($buff, $len) == $len or last;
             unless ($len >= 0xb4 and substr($buff, 0xb0, 4) eq 'data') {
-                $exifTool->Warn('Parsing error. Please submit this ITC file for testing');
+                $et->Warn('Parsing error. Please submit this ITC file for testing');
                 last;
             }
@@ -151,12 +151,12 @@
             );
             $tagTablePtr = GetTagTable('Image::ExifTool::ITC::Item');
-            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
             # extract embedded image
             $pos += $len;
             if ($size > 0) {
                 $tagTablePtr = GetTagTable('Image::ExifTool::ITC::Main');
-                my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 'data');
-                my $image = $exifTool->ExtractBinary($pos, $size, $$tagInfo{Name});
-                $exifTool->FoundTag($tagInfo, \$image);
+                my $tagInfo = $et->GetTagInfo($tagTablePtr, 'data');
+                my $image = $et->ExtractBinary($pos, $size, $$tagInfo{Name});
+                $et->FoundTag($tagInfo, \$image);
                 # skip the rest of the block if necessary
                 $raf->Seek($pos+$size, 0) or last
@@ -165,9 +165,9 @@
             }
         } else {
-            $exifTool->VPrint(0, "Unknown $tag block ($size bytes)\n");
+            $et->VPrint(0, "Unknown $tag block ($size bytes)\n");
             $raf->Seek($size-8, 1) or last;
         }
     }
-    $err and $exifTool->Warn('ITC file format error');
+    $err and $et->Warn('ITC file format error');
     return $rtnVal;
 }
@@ -192,5 +192,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Import.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Import.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Import.pm	(revision 34921)
@@ -13,5 +13,5 @@
 use vars qw($VERSION @ISA @EXPORT_OK);
 
-$VERSION = '1.00';
+$VERSION = '1.10';
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(ReadCSV ReadJSON);
@@ -19,22 +19,33 @@
 sub ReadJSONObject($;$);
 
-my %unescapeJSON = ( 't'=>"\t", 'n'=>"\n", 'r'=>"\r" );
+my %unescapeJSON = ( 't'=>"\t", 'n'=>"\n", 'r'=>"\r", 'b' => "\b", 'f' => "\f" );
 my $charset;
 
 #------------------------------------------------------------------------------
 # Read CSV file
-# Inputs: 0) CSV file name, 1) database hash ref, 2) flag to delete "-" tags
+# Inputs: 0) CSV file name, file ref or RAF ref, 1) database hash ref,
+#         2) missing tag value, 3) delimiter if other than ','
 # Returns: undef on success, or error string
 # Notes: There are various flavours of CSV, but here we assume that only
 #        double quotes are escaped, and they are escaped by doubling them
-sub ReadCSV($$;$)
+sub ReadCSV($$;$$)
 {
     local ($_, $/);
-    my ($file, $database, $delDash) = @_;
-    my ($buff, @tags, $found, $err);
-
-    open CSVFILE, $file or return "Error opening CSV file '$file'";
-    binmode CSVFILE;
-    my $raf = new File::RandomAccess(\*CSVFILE);
+    my ($file, $database, $missingValue, $delim) = @_;
+    my ($buff, @tags, $found, $err, $raf, $openedFile);
+
+    if (UNIVERSAL::isa($file, 'File::RandomAccess')) {
+        $raf = $file;
+        $file = 'CSV file';
+    } elsif (ref $file eq 'GLOB') {
+        $raf = new File::RandomAccess($file);
+        $file = 'CSV file';
+    } else {
+        open CSVFILE, $file or return "Error opening CSV file '${file}'";
+        binmode CSVFILE;
+        $openedFile = 1;
+        $raf = new File::RandomAccess(\*CSVFILE);
+    }
+    $delim = ',' unless defined $delim;
     # set input record separator by first newline found in the file
     # (safe because first line should contain only tag names)
@@ -45,5 +56,5 @@
     while ($raf->ReadLine($buff)) {
         my (@vals, $v, $i, %fileInfo);
-        my @toks = split ',', $buff;
+        my @toks = split /\Q$delim/, $buff;
         while (@toks) {
             ($v = shift @toks) =~ s/^ +//;  # remove leading spaces
@@ -52,9 +63,9 @@
                 while ($v !~ /("+)\s*$/ or not length($1) & 1) {
                     if (@toks) {
-                        $v .= ',' . shift @toks;
+                        $v .= $delim . shift @toks;
                     } else {
                         # read another line from the file
                         $raf->ReadLine($buff) or last;
-                        @toks = split ',', $buff;
+                        @toks = split /\Q$delim/, $buff;
                         last unless @toks;
                         $v .= shift @toks;
@@ -71,7 +82,9 @@
             # save values for each tag
             for ($i=0; $i<@vals and $i<@tags; ++$i) {
-                next unless length $vals[$i];   # ignore empty entries
-                # delete tag if value (set value to undef) is '-' and -f option is used
-                $fileInfo{$tags[$i]} = ($vals[$i] eq '-' and $delDash) ? undef : $vals[$i];
+                # ignore empty entries unless missingValue is empty too
+                next unless length $vals[$i] or defined $missingValue and $missingValue eq '';
+                # delete tag (set value to undef) if value is same as missing tag
+                $fileInfo{$tags[$i]} =
+                    (defined $missingValue and $vals[$i] eq $missingValue) ? undef : $vals[$i];
             }
             # figure out the file name to use
@@ -83,12 +96,17 @@
             # the first row should be the tag names
             foreach (@vals) {
-                /^[-\w]+(:[-\w+]+)?#?$/ or $err = "Invalid tag name '$_'", last;
+                # terminate at first blank tag name (eg. extra comma at end of line)
+                last unless length $_;
+                @tags or s/^\xef\xbb\xbf//; # remove UTF-8 BOM if it exists
+                /^[-\w]+(:[-\w+]+)?#?$/ or $err = "Invalid tag name '${_}'", last;
                 push(@tags, $_);
             }
             last if $err;
             @tags or $err = 'No tags found', last;
-        }
-    }
-    close CSVFILE;
+            # fix "SourceFile" case if necessary
+            $tags[0] = 'SourceFile' if lc $tags[0] eq 'sourcefile';
+        }
+    }
+    close CSVFILE if $openedFile;
     undef $raf;
     $err = 'No SourceFile column' unless $found or $err;
@@ -108,5 +126,6 @@
 #------------------------------------------------------------------------------
 # Read JSON object from file
-# Inputs: 0) JSON file handle, 1) optional file buffer reference
+# Inputs: 0) RAF reference or undef, 1) optional scalar reference for data
+#            to read before reading from file (ie. the file read buffer)
 # Returns: JSON object (scalar, hash ref, or array ref), or undef on EOF or
 #          empty object or array (and sets $$buffPt to empty string on EOF)
@@ -114,9 +133,10 @@
 sub ReadJSONObject($;$)
 {
-    my ($fp, $buffPt) = @_;
+    my ($raf, $buffPt) = @_;
     # initialize buffer if necessary
-    my ($pos, $readMore, $rtnVal, $tok, $key);
+    my ($pos, $readMore, $rtnVal, $tok, $key, $didBOM);
     if ($buffPt) {
         $pos = pos $$buffPt;
+        $pos = pos($$buffPt) = 0 unless defined $pos;
     } else {
         my $buff = '';
@@ -125,9 +145,22 @@
     }
 Tok: for (;;) {
+        # (didn't spend the time to understand how $pos could be undef, but
+        #  put a test here to be safe because one user reported this problem)
+        last unless defined $pos;
         if ($pos >= length $$buffPt or $readMore) {
+            last unless defined $raf;
             # read another 64kB and add to unparsed data
             my $offset = length($$buffPt) - $pos;
-            $$buffPt = substr($$buffPt, $pos) if $offset;
-            read $fp, $$buffPt, 65536, $offset or $$buffPt = '', last;
+            if ($offset) {
+                my $buff;
+                $raf->Read($buff, 65536) or $$buffPt = '', last;
+                $$buffPt = substr($$buffPt, $pos) . $buff;
+            } else {
+                $raf->Read($$buffPt, 65536) or $$buffPt = '', last;
+            }
+            unless ($didBOM) {
+                $$buffPt =~ s/^\xef\xbb\xbf//;  # remove UTF-8 BOM if it exists
+                $didBOM = 1;
+            }
             $pos = pos($$buffPt) = 0;
             $readMore = 0;
@@ -145,5 +178,5 @@
                 # read "KEY":"VALUE" pairs
                 unless (defined $key) {
-                    $key = ReadJSONObject($fp, $buffPt);
+                    $key = ReadJSONObject($raf, $buffPt);
                     $pos = pos $$buffPt;
                 }
@@ -153,5 +186,5 @@
                     $$buffPt =~ /(\S)/g or $readMore = 1, next Tok;
                     $1 eq ':' or return undef;  # error if not a colon
-                    my $val = ReadJSONObject($fp, $buffPt);
+                    my $val = ReadJSONObject($raf, $buffPt);
                     $pos = pos $$buffPt;
                     return undef unless defined $val;
@@ -167,5 +200,5 @@
             $rtnVal = [ ] unless defined $rtnVal;
             for (;;) {
-                my $item = ReadJSONObject($fp, $buffPt);
+                my $item = ReadJSONObject($raf, $buffPt);
                 $pos = pos $$buffPt;
                 # ($item may be undef for empty array)
@@ -185,4 +218,9 @@
             $rtnVal =~ s/\\u([0-9a-f]{4})/ToUTF8(hex $1)/ige;
             $rtnVal =~ s/\\(.)/$unescapeJSON{$1}||$1/sge;
+            # decode base64 (binary data) values
+            if ($rtnVal =~ /^base64:[A-Za-z0-9+\/]*={0,2}$/ and length($rtnVal) % 4 == 3) {
+                require Image::ExifTool::XMP;
+                $rtnVal = ${Image::ExifTool::XMP::DecodeBase64(substr($rtnVal,7))};
+            }
         } elsif ($tok eq ']' or $tok eq '}' or $tok eq ',') {
             # return undef for empty object, array, or list item
@@ -201,32 +239,53 @@
 #------------------------------------------------------------------------------
 # Read JSON file
-# Inputs: 0) JSON file name, 1) database hash ref, 2) flag to delete "-" tags
-#         2) character set
+# Inputs: 0) JSON file name, file ref or RAF ref, 1) database hash ref,
+#         2) flag to delete "-" tags, 3) character set
 # Returns: undef on success, or error string
 sub ReadJSON($$;$$)
 {
     local $_;
-    my ($file, $database, $delDash, $chset) = @_;
+    my ($file, $database, $missingValue, $chset) = @_;
+    my ($raf, $openedFile);
 
     # initialize character set for converting "\uHHHH" chars
     $charset = $chset || 'UTF8';
-    open JSONFILE, $file or return "Error opening JSON file '$file'";
-    binmode JSONFILE;
-    my $obj = ReadJSONObject(\*JSONFILE);
-    close JSONFILE;
+    if (UNIVERSAL::isa($file, 'File::RandomAccess')) {
+        $raf = $file;
+        $file = 'JSON file';
+    } elsif (ref $file eq 'GLOB') {
+        $raf = new File::RandomAccess($file);
+        $file = 'JSON file';
+    } else {
+        open JSONFILE, $file or return "Error opening JSON file '${file}'";
+        binmode JSONFILE;
+        $openedFile = 1;
+        $raf = new File::RandomAccess(\*JSONFILE);
+    }
+    my $obj = ReadJSONObject($raf);
+    close JSONFILE if $openedFile;
     unless (ref $obj eq 'ARRAY') {
-        ref $obj eq 'HASH' or return "Format error in JSON file '$file'";
+        ref $obj eq 'HASH' or return "Format error in JSON file '${file}'";
         $obj = [ $obj ];
     }
     my ($info, $found);
     foreach $info (@$obj) {
-        next unless ref $info eq 'HASH' and $$info{SourceFile};
-        if ($delDash) {
-            $$info{$_} eq '-' and $$info{$_} = undef foreach keys %$info;
+        next unless ref $info eq 'HASH';
+        # fix "SourceFile" case, or assume '*' if SourceFile not specified
+        unless (defined $$info{SourceFile}) {
+            my ($key) = grep /^SourceFile$/i, keys %$info;
+            if ($key) {
+                $$info{SourceFile} = $$info{$key};
+                delete $$info{$key};
+            } else {
+                $$info{SourceFile} = '*';
+            }
+        }
+        if (defined $missingValue) {
+            $$info{$_} eq $missingValue and $$info{$_} = undef foreach keys %$info;
         }
         $$database{$$info{SourceFile}} = $info;
         $found = 1;
     }
-    return $found ? undef : "No SourceFile entries in '$file'";
+    return $found ? undef : "No valid JSON objects in '${file}'";
 }
 
@@ -267,14 +326,15 @@
 =item Inputs:
 
-0) CSV file name.
+0) CSV file name or file reference.
 
 1) Hash reference for database object.
 
-2) Optional flag to set '-' values to undef in the database.  (Used for
-deleting tags.)
-
-3) [ReadJSON only] Optional character set for converting Unicode escape
-sequences in strings.  Defaults to "UTF8".  See the ExifTool Charset option
-for a list of valid settings.
+2) Optional string used to represent an undefined (missing) tag value. 
+(Used for deleting tags.)
+
+3) For ReadCSV this gives the delimiter for CSV entries, with a default of
+",".  For ReadJSON this is the character set for converting Unicode escape
+sequences in strings, with a default of "UTF8".  See the ExifTool Charset
+option for a list of valid character sets.
 
 =item Return Value:
@@ -289,5 +349,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/InDesign.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/InDesign.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/InDesign.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.02';
+$VERSION = '1.06';
 
 # map for writing metadata to InDesign files (currently only write XMP)
@@ -33,5 +33,5 @@
 sub ProcessIND($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
@@ -42,5 +42,5 @@
     return 0 unless $hdr eq $masterPageGUID;
     return 0 unless $raf->Read($buff, 8) == 8;
-    $exifTool->SetFileType($buff eq 'DOCUMENT' ? 'INDD' : 'IND');   # set the FileType tag
+    $et->SetFileType($buff eq 'DOCUMENT' ? 'INDD' : 'IND');   # set the FileType tag
 
     # read the master pages
@@ -74,5 +74,5 @@
     $pages < 2 and $err = 'Invalid page count', goto DONE;
     my $pos = $pages * 4096;
-    if ($pos > 0x7fffffff and not $exifTool->Options('LargeFileSupport')) {
+    if ($pos > 0x7fffffff and not $et->Options('LargeFileSupport')) {
         $err = 'InDesign files larger than 2 GB not supported (LargeFileSupport not set)';
         goto DONE;
@@ -80,5 +80,5 @@
     if ($outfile) {
         # make XMP the preferred group for writing
-        $exifTool->InitWriteDirs(\%indMap, 'XMP');
+        $et->InitWriteDirs(\%indMap, 'XMP');
 
         Write($outfile, $buff, $buf2) or $err = 1, goto DONE;
@@ -93,6 +93,6 @@
     }
     # scan through the contiguous objects for XMP
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     for (;;) {
         $raf->Read($hdr, 32) or last;
@@ -106,8 +106,7 @@
             printf $out "Contiguous object at offset 0x%x (%d bytes):\n", $raf->Tell(), $len;
             if ($verbose > 2) {
-                my %parms = (Addr => $raf->Tell());
-                $parms{MaxLen} = $verbose > 3 ? 1024 : 96 if $verbose < 5;
-                $raf->Seek(-$raf->Read($buff, $len), 1) or $err = 1;
-                Image::ExifTool::HexDump(\$buff, undef, %parms);
+                my $len2 = $len < 1024000 ? $len : 1024000;
+                $raf->Seek(-$raf->Read($buff, $len2), 1) or $err = 1;
+                $et->VerboseDump(\$buff, Addr => $raf->Tell());
             }
         }
@@ -119,4 +118,20 @@
                 my $lenWord = $1;   # save length word for writing later
                 $len -= 4;          # get length of XMP only
+                $foundXMP = 1;
+                # I have a sample where the XMP is 107 MB, and ActivePerl may run into
+                # memory troubles (with its apparent 1 GB limit) if the XMP is larger
+                # than about 400 MB, so guard against this
+                if ($len > 300 * 1024 * 1024) {
+                    my $msg = sprintf('Insanely large XMP (%.0f MB)', $len / (1024 * 1024));
+                    if ($outfile) {
+                        $et->Error($msg, 2) and $err = 1, last;
+                    } elsif ($et->Options('IgnoreMinorErrors')) {
+                        $et->Warn($msg);
+                    } else {
+                        $et->Warn("$msg. Ignored.", 1);
+                        $err = 1;
+                        last;
+                    }
+                }
                 # load and parse the XMP data
                 unless ($raf->Seek(-52, 1) and $raf->Read($buff, $len) == $len) {
@@ -124,5 +139,4 @@
                     last;
                 }
-                $foundXMP = 1;
                 my %dirInfo = (
                     DataPt  => \$buff,
@@ -130,16 +144,20 @@
                     NoDelete => 1, # do not allow this to be deleted when writing
                 );
+                # validate xmp data length (should be same as length in header - 4)
+                my $xmpLen = unpack($streamInt32u, $lenWord);
+                unless ($xmpLen == $len) {
+                    if ($xmpLen < $len) {
+                        $dirInfo{DirLen} = $xmpLen;
+                    } else {
+                        $err = 'Truncated XMP stream (missing ' . ($xmpLen - $len) . ' bytes)';
+                    }
+                }
                 my $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
                 if ($outfile) {
-                    # validate xmp data length (should be same as length in header - 4)
-                    my $xmpLen = unpack($streamInt32u, $lenWord);
-                    unless ($xmpLen == $len) {
-                        $err = "Incorrect XMP stream length ($xmpLen should be $len)";
-                        last;
-                    }
+                    last if $err;
                     # make sure that XMP is writable
                     my $classID = Get32u(\$hdr, 20);
                     $classID & 0x40000000 or $err = 'XMP stream is not writable', last;
-                    my $xmp = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+                    my $xmp = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
                     if ($xmp and length $xmp) {
                         # write new xmp with leading length word
@@ -149,11 +167,11 @@
                         Set32u(0xffffffff, \$hdr, 28);
                     } else {
-                        $$exifTool{CHANGED} = 0;    # didn't change anything
-                        $exifTool->Warn("Can't delete XMP as a block from InDesign file") if defined $xmp;
+                        $$et{CHANGED} = 0;    # didn't change anything
+                        $et->Warn("Can't delete XMP as a block from InDesign file") if defined $xmp;
                         # put length word back at start of stream
                         $buff = $lenWord . $buff;
                     }
                 } else {
-                    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
                 }
                 $len = 0;   # we got the full stream (nothing left to read)
@@ -198,12 +216,12 @@
 DONE:
     if (not $err) {
-        $exifTool->Warn('No XMP stream to edit') if $outfile and not $foundXMP;
+        $et->Warn('No XMP stream to edit') if $outfile and not $foundXMP;
         return 1;       # success!
     } elsif (not $outfile) {
         # issue warning on read error
-        $exifTool->Warn($err) unless $err eq '1';
+        $et->Warn($err) unless $err eq '1';
     } elsif ($err ne '1') {
         # set error and return success code
-        $exifTool->Error($err);
+        $et->Error($err);
     } else {
         return -1;      # write error
@@ -236,10 +254,10 @@
 InDesign files which previously contained XMP.
 
-3) File sizes of greater than 2 GB and are not currently supported because
-the ability to handle large files like this is system dependent.
+3) File sizes of greater than 2 GB are supported only if the system supports
+them and the LargeFileSupport option is enabled.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JPEG.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JPEG.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JPEG.pm	(revision 34921)
@@ -12,12 +12,15 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.13';
-
-sub ProcessScalado($$$);
+$VERSION = '1.30';
+
 sub ProcessOcad($$$);
-
-# (this main JPEG table is for documentation purposes only)
+sub ProcessJPEG_HDR($$$);
+
+# (most of the tags in this table are for documentation purposes only)
 %Image::ExifTool::JPEG::Main = (
-    NOTES => 'This table lists information extracted by ExifTool from JPEG images.',
+    NOTES => q{
+        This table lists information extracted by ExifTool from JPEG images. See
+        L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JPEG specification.
+    },
     APP0 => [{
         Name => 'JFIF',
@@ -57,4 +60,15 @@
         Condition => '$$valPt =~ /^QVCI\0/',
         SubDirectory => { TagTable => 'Image::ExifTool::Casio::QVCI' },
+      }, {
+        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 => [{
@@ -72,6 +86,6 @@
       }, {
         Name => 'PreviewImage',
-        Condition => '$$valPt =~ /^\xff\xd8\xff\xdb/',
-        Notes => 'Samsung large preview',
+        Condition => '$$valPt =~ /^(|QVGA\0|BGTH)\xff\xd8\xff\xdb/',
+        Notes => 'Samsung APP2 preview image', # (Samsung/GoPro="", BenQ="QVGA\0", Digilife="BGTH")
     }],
     APP3 => [{
@@ -84,12 +98,18 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Stim::Main' },
       }, {
+        Name => 'ThermalData', # (written by DJI FLIR models)
+        Condition => '$$self{Make} eq "DJI"',
+        Notes => 'DJI raw thermal data',
+        Groups => { 0 => 'APP3', 1 => 'DJI', 2 => 'Image' },
+        Binary => 1,
+      }, {
         Name => 'PreviewImage', # (written by HP R837 and Samsung S1060)
         Condition => '$$valPt =~ /^\xff\xd8\xff\xdb/',
-        Notes => 'Hewlett-Packard or Samsung preview image',
+        Notes => 'Samsung/HP preview image', # (Samsung, HP, BenQ)
     }],
     APP4 => [{
         Name => 'Scalado',
         Condition => '$$valPt =~ /^SCALADO\0/',
-        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::Scalado' },
+        SubDirectory => { TagTable => 'Image::ExifTool::Scalado::Main' },
       }, {
         Name => 'FPXR', # (non-standard location written by some HP models)
@@ -97,12 +117,29 @@
         SubDirectory => { TagTable => 'Image::ExifTool::FlashPix::Main' },
       }, {
-        Name => 'PreviewImage', # (written by S1060)
-        Notes => 'Continued Samsung preview from APP3',
-    }],
-    APP5 => {
+        Name => 'ThermalParams', # (written by DJI FLIR models)
+        Condition => '$$self{Make} eq "DJI" and $$valPt =~ /^\xaa\x55\x12\x06/',
+        SubDirectory => { TagTable => 'Image::ExifTool::DJI::ThermalParams' },
+      }, {
+        Name => 'PreviewImage', # (eg. Samsung S1060)
+        Notes => 'continued from APP3',
+    }],
+    APP5 => [{
         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 => 'ThermalCalibration', # (written by DJI FLIR models)
+        Condition => '$$self{Make} eq "DJI"',
+        Notes => 'DJI thermal calibration data',
+        Groups => { 0 => 'APP5', 1 => 'DJI', 2 => 'Image' },
+        Binary => 1,
+      }, {
+        Name => 'PreviewImage', # (eg. BenQ DC E1050)
+        Notes => 'continued from APP4',
+    }],
     APP6 => [{
         Name => 'EPPIM',
@@ -117,4 +154,28 @@
         Condition => '$$valPt =~ /^TDHD\x01\0\0\0/',
         SubDirectory => { TagTable => 'Image::ExifTool::HP::TDHD' },
+      }, {
+        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
+      }, {
+        Name => 'DJI_DTAT', # (written by ZH20T)
+        Condition => '$$valPt =~ /^DTAT\0\0.\{/s',
+        Groups => { 0 => 'APP6', 1 => 'DJI' },
+        Notes => 'DJI Thermal Analysis Tool record',
+        ValueConv => 'substr($val,7)',
+    }],
+    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/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Qualcomm::Main' },
     }],
     APP8 => {
@@ -123,8 +184,18 @@
         SubDirectory => { TagTable => 'Image::ExifTool::JPEG::SPIFF' },
     },
+    APP9 => {
+        Name => 'MediaJukebox',
+        Condition => '$$valPt =~ /^Media Jukebox\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::MediaJukebox' },
+    },
     APP10 => {
         Name => 'Comment',
         Condition => '$$valPt =~ /^UNICODE\0/',
         Notes => 'PhotoStudio Unicode comment',
+    },
+    APP11 => {
+        Name => 'JPEG-HDR',
+        Condition => '$$valPt =~ /^HDR_RI /',
+        SubDirectory => { TagTable => 'Image::ExifTool::JPEG::HDR' },
     },
     APP12 => [{
@@ -149,4 +220,5 @@
         Name => 'Adobe',
         Condition => '$$valPt =~ /^Adobe/',
+        Writable => 2,  # (for docs only)
         SubDirectory => { TagTable => 'Image::ExifTool::JPEG::Adobe' },
     },
@@ -156,9 +228,10 @@
         SubDirectory => { TagTable => 'Image::ExifTool::JPEG::GraphConv' },
     },
+    # APP15 - Also unknown "TEXT\0" segment stored by Casio/FujiFilm
     COM => {
         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 => {
@@ -168,5 +241,5 @@
     DQT => {
         Name => 'DefineQuantizationTable',
-        Notes => 'used to calculate the Extra:JPEGDigest tag value',
+        Notes => 'used to calculate the Extra JPEGDigest tag value',
     },
     Trailer => [{
@@ -194,7 +267,18 @@
         SubDirectory => { TagTable => 'Image::ExifTool::MIE::Main' },
       }, {
+        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)
     }],
 );
@@ -210,4 +294,5 @@
         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',
@@ -218,5 +303,5 @@
 );
 
-# SPIFF APP8 segment.  Refs:
+# APP8 SPIFF segment.  Refs:
 # 1) http://www.fileformat.info/format/spiff/
 # 2) http://www.jpeg.org/public/spiff.pdf
@@ -305,4 +390,46 @@
 );
 
+# APP9 Media Jukebox segment (ref PH)
+%Image::ExifTool::JPEG::MediaJukebox = (
+    GROUPS => { 0 => 'XML', 1 => 'MediaJukebox', 2 => 'Image' },
+    VARS => { NO_ID => 1 },
+    NOTES => 'Tags found in the XML metadata of the APP9 "Media Jukebox" segment.',
+    Date => {
+        Groups => { 2 => 'Time' },
+        # convert from days since Dec 30, 1899 to seconds since Jan 1, 1970
+        ValueConv => 'ConvertUnixTime(($val - (70 * 365 + 17 + 2)) * 24 * 3600)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    Album        => { },
+    Caption      => { },
+    Keywords     => { },
+    Name         => { },
+    People       => { },
+    Places       => { },
+    Tool_Name    => { },
+    Tool_Version => { },
+);
+
+# JPEG-HDR APP11 information (ref PH, guessed from http://anyhere.com/gward/papers/cic05.pdf)
+%Image::ExifTool::JPEG::HDR = (
+    GROUPS => { 0 => 'APP11', 1 => 'JPEG-HDR', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessJPEG_HDR,
+    TAG_PREFIX => '', # (no prefix for unknown tags)
+    NOTES => 'Information extracted from APP11 of a JPEG-HDR image.',
+    ver => 'JPEG-HDRVersion',
+    # (need names for the next 3 tags)
+    ln0 => { Description => 'Ln0' },
+    ln1 => { Description => 'Ln1' },
+    s2n => { Description => 'S2n' },
+    alp => { Name => 'Alpha' }, # (Alpha/Beta are saturation parameters)
+    bet => { Name => 'Beta' },
+    cor => { Name => 'CorrectionMethod' },
+    RatioImage => {
+        Groups => { 2 => 'Preview' },
+        Notes => 'the embedded JPEG-compressed ratio image',
+        Binary => 1,
+    },
+);
+
 # AdobeCM APP13 (no references)
 %Image::ExifTool::JPEG::AdobeCM = (
@@ -310,5 +437,5 @@
     GROUPS => { 0 => 'APP13', 1 => 'AdobeCM', 2 => 'Image' },
     NOTES => q{
-        The "Adobe_CM" APP13 segment presumably contains color management
+        The APP13 "Adobe_CM" segment presumably contains color management
         information, but the meaning of the data is currently unknown.  If anyone
         has an idea about what this means, please let me know.
@@ -324,16 +451,27 @@
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     GROUPS => { 0 => 'APP14', 1 => 'Adobe', 2 => 'Image' },
-    NOTES => 'The "Adobe" APP14 segment stores image encoding information for DCT filters.',
+    NOTES => q{
+        The APP14 "Adobe" segment stores image encoding information for DCT filters.
+        This segment may be copied or deleted as a block using the Extra "Adobe"
+        tag, but note that it is not deleted by default when deleting all metadata
+        because it may affect the appearance of the image.
+    },
     FORMAT => 'int16u',
     0 => 'DCTEncodeVersion',
     1 => {
         Name => 'APP14Flags0',
-        PrintConv => { BITMASK => {
-            15 => 'Encoded with Blend=1 downsampling'
-        } },
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => {
+                15 => 'Encoded with Blend=1 downsampling'
+            },
+        },
     },
     2 => {
         Name => 'APP14Flags1',
-        PrintConv => { BITMASK => { } },
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => { },
+        },
     },
     3 => {
@@ -355,5 +493,5 @@
 );
 
-# AVI1 APP0 segment (ref http://www.schnarff.com/file-formats/bmp/BMPDIB.TXT)
+# APP0 AVI1 segment (ref http://www.schnarff.com/file-formats/bmp/BMPDIB.TXT)
 %Image::ExifTool::JPEG::AVI1 = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -368,11 +506,12 @@
             2 => 'Even',
         },
-    },    
-);
-
-# Ocad APP0 segment (ref PH)
+    },
+);
+
+# APP0 Ocad segment (ref PH)
 %Image::ExifTool::JPEG::Ocad = (
     PROCESS_PROC => \&ProcessOcad,
     GROUPS => { 0 => 'APP0', 1 => 'Ocad', 2 => 'Image' },
+    TAG_PREFIX => 'Ocad',
     FIRST_ENTRY => 0,
     NOTES => q{
@@ -386,5 +525,5 @@
 );
 
-# NITF APP6 segment (National Imagery Transmission Format)
+# APP6 NITF segment (National Imagery Transmission Format)
 # ref http://www.gwg.nga.mil/ntb/baseline/docs/n010697/bwcguide25aug98.pdf
 %Image::ExifTool::JPEG::NITF = (
@@ -446,44 +585,4 @@
 );
 
-# information written by Scalado software (PhotoFusion maybe?)
-%Image::ExifTool::JPEG::Scalado = (
-    GROUPS => { 0 => 'APP4', 1 => 'Scalado', 2 => 'Image' },
-    PROCESS_PROC => \&ProcessScalado,
-    TAG_PREFIX => 'Scalado',
-    FORMAT => 'int32s',
-    # I presume this was written by 
-    NOTES => q{
-        Tags extracted from the JPEG APP4 "SCALADO" segment (presumably written by
-        Scalado mobile software, L<http://www.scalado.com/>).
-    },
-    SPMO => {
-        Name => 'DataLength',
-        Unkown => 1,
-    },
-    WDTH => {
-        Name => 'PreviewImageWidth',
-        ValueConv => '$val ? abs($val) : undef',
-    },
-    HGHT => {
-        Name => 'PreviewImageHeight',
-        ValueConv => '$val ? abs($val) : undef',
-    },
-    QUAL => {
-        Name => 'PreviewQuality',
-        ValueConv => '$val ? abs($val) : undef',
-    },
-    # tags not yet decoded with observed values:
-    # CHKH: 0, -9010
-    # CHKL: -2664, -12852
-    # CLEN: -1024
-    # CSPC: -2232593
-    # DATA: (+ve data length)
-    # HDEC: 0
-    # MAIN: 0
-    # SCI0: (+ve data length)
-    # SCX1: (+ve data length)
-    # WDEC: 0
-);
-
 #------------------------------------------------------------------------------
 # Extract information from the JPEG APP0 Ocad segment
@@ -492,15 +591,13 @@
 sub ProcessOcad($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
-    $exifTool->VerboseDir('APP0 Ocad', undef, length $$dataPt);
+    $et->VerboseDir('APP0 Ocad', undef, length $$dataPt);
     for (;;) {
         last unless $$dataPt =~ /\$(\w+):([^\0\$]+)/g;
         my ($tag, $val) = ($1, $2);
-        $val =~ s/(^\s+|\s+$)//g;   # remove leading/trailing spaces
-        unless ($$tagTablePtr{$tag}) {
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => "Ocad_$tag" });
-        }
-        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+        $val =~ s/^\s+//; $val =~ s/\s+$//;     # remove leading/trailing spaces
+        AddTagToTable($tagTablePtr, $tag) unless $$tagTablePtr{$tag};
+        $et->HandleTag($tagTablePtr, $tag, $val);
     }
     return 1;
@@ -508,29 +605,21 @@
 
 #------------------------------------------------------------------------------
-# Extract information from the JPEG APP4 SCALADO segment
+# Extract information from the JPEG APP0 Ocad segment
 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
 # Returns: 1 on success
-sub ProcessScalado($$$)
+sub ProcessJPEG_HDR($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
-    my $pos = 0;
-    my $end = length $$dataPt;
-    SetByteOrder('MM');
-    $exifTool->VerboseDir('APP4 SCALADO', undef, $end);
-    for (;;) {
-        last if $pos + 12 > $end;
-        my $tag = substr($$dataPt, $pos, 4);
-        my $unk = Get32u($dataPt, $pos + 4); # (what is this?)
-        $exifTool->HandleTag($tagTablePtr, $tag, undef,
-            DataPt  => $dataPt,
-            Start   => $pos + 8,
-            Size    => 4,
-            Extra   => ", unk $unk",
-        );
-        # shorten directory size by length of SPMO
-        $end -= Get32u($dataPt, $pos + 8) if $tag eq 'SPMO';
-        $pos += 12;
+    $$dataPt =~ /~\0/g or $et->Warn('Unrecognized JPEG-HDR format'), return 0;
+    my $pos = pos $$dataPt;
+    my $meta = substr($$dataPt, 7, $pos-9);
+    $et->VerboseDir('APP11 JPEG-HDR', undef, length $$dataPt);
+    while ($meta =~ /(\w+)=([^,\s]*)/g) {
+        my ($tag, $val) = ($1, $2);
+        AddTagToTable($tagTablePtr, $tag) unless $$tagTablePtr{$tag};
+        $et->HandleTag($tagTablePtr, $tag, $val);
     }
+    $et->HandleTag($tagTablePtr, 'RatioImage', substr($$dataPt, $pos));
     return 1;
 }
@@ -556,5 +645,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JPEGDigest.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JPEGDigest.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JPEGDigest.pm	(revision 34921)
@@ -2,10 +2,12 @@
 # File:         JPEGDigest.pm
 #
-# Description:  Lookup for JPEGDigest values
+# Description:  Calculate JPEGDigest and JPEGQualityEstimate
 #
 # Revisions:    2008/09/15 - P. Harvey Created
+#               2016/01/05 - PH Added calculation of JPEGQualityEstimate
 #
 # References:   JD) Jens Duttke
 #               2) Franz Buchinger private communication
+#               3) https://github.com/ImageMagick/ImageMagick/blob/master/coders/jpeg.c
 #------------------------------------------------------------------------------
 
@@ -14,5 +16,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.02';
+$VERSION = '1.06';
 
 # the print conversion for the JPEGDigest tag
@@ -282,5 +284,5 @@
     '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',
@@ -2443,12 +2445,107 @@
 
 #------------------------------------------------------------------------------
-# Calculate JPEGDigest
+# Estimate JPEG quality from quantization tables (ref 3)
+# Inputs: 0) 1) DQT segments array ref
+# Returns: JPEG quality, or undefined if it can't be calculated
+sub EstimateQuality($)
+{
+    local $_;
+    my $dqtList = shift;
+    my ($i, $dqt, @qtbl, $quality, @hash, @sums);
+
+    # unpack DQT segments and sum quantization tables
+    my $sum=0;
+DQT: foreach $dqt (@$dqtList) {
+        next unless defined $dqt;
+        for ($i=1; $i+64<=length($dqt); $i+=65) {
+            my @qt = unpack("x$i C64", $dqt);
+            $sum += $_ foreach @qt;
+            push @qtbl, \@qt;
+            last DQT if @qtbl >= 4;
+        }
+    }
+    return undef unless @qtbl;
+
+    my $qval = $qtbl[0][2] + $qtbl[0][53];
+    if (@qtbl > 1) {
+        # color JPEG
+        $qval += $qtbl[1][0] + $qtbl[1][63];
+        @hash =(
+            1020, 1015,  932,  848,  780,  735,  702,  679,  660,  645,
+             632,  623,  613,  607,  600,  594,  589,  585,  581,  571,
+             555,  542,  529,  514,  494,  474,  457,  439,  424,  410,
+             397,  386,  373,  364,  351,  341,  334,  324,  317,  309,
+             299,  294,  287,  279,  274,  267,  262,  257,  251,  247,
+             243,  237,  232,  227,  222,  217,  213,  207,  202,  198,
+             192,  188,  183,  177,  173,  168,  163,  157,  153,  148,
+             143,  139,  132,  128,  125,  119,  115,  108,  104,   99,
+              94,   90,   84,   79,   74,   70,   64,   59,   55,   49,
+              45,   40,   34,   30,   25,   20,   15,   11,    6,    4
+        );
+        @sums = (
+            32640, 32635, 32266, 31495, 30665, 29804, 29146, 28599, 28104, 27670,
+            27225, 26725, 26210, 25716, 25240, 24789, 24373, 23946, 23572, 22846,
+            21801, 20842, 19949, 19121, 18386, 17651, 16998, 16349, 15800, 15247,
+            14783, 14321, 13859, 13535, 13081, 12702, 12423, 12056, 11779, 11513,
+            11135, 10955, 10676, 10392, 10208,  9928,  9747,  9564,  9369,  9193,
+             9017,  8822,  8639,  8458,  8270,  8084,  7896,  7710,  7527,  7347,
+             7156,  6977,  6788,  6607,  6422,  6236,  6054,  5867,  5684,  5495,
+             5305,  5128,  4945,  4751,  4638,  4442,  4248,  4065,  3888,  3698,
+             3509,  3326,  3139,  2957,  2775,  2586,  2405,  2216,  2037,  1846,
+             1666,  1483,  1297,  1109,   927,   735,   554,   375,   201,   128
+        );
+    } else {
+        # greyscale JPEG
+        @hash = (
+            510,  505,  422,  380,  355,  338,  326,  318,  311,  305,
+            300,  297,  293,  291,  288,  286,  284,  283,  281,  280,
+            279,  278,  277,  273,  262,  251,  243,  233,  225,  218,
+            211,  205,  198,  193,  186,  181,  177,  172,  168,  164,
+            158,  156,  152,  148,  145,  142,  139,  136,  133,  131,
+            129,  126,  123,  120,  118,  115,  113,  110,  107,  105,
+            102,  100,   97,   94,   92,   89,   87,   83,   81,   79,
+             76,   74,   70,   68,   66,   63,   61,   57,   55,   52,
+             50,   48,   44,   42,   39,   37,   34,   31,   29,   26,
+             24,   21,   18,   16,   13,   11,    8,    6,    3,    2
+        );
+        @sums = (
+            16320, 16315, 15946, 15277, 14655, 14073, 13623, 13230, 12859, 12560,
+            12240, 11861, 11456, 11081, 10714, 10360, 10027,  9679,  9368,  9056,
+             8680,  8331,  7995,  7668,  7376,  7084,  6823,  6562,  6345,  6125,
+             5939,  5756,  5571,  5421,  5240,  5086,  4976,  4829,  4719,  4616,
+             4463,  4393,  4280,  4166,  4092,  3980,  3909,  3835,  3755,  3688,
+             3621,  3541,  3467,  3396,  3323,  3247,  3170,  3096,  3021,  2952,
+             2874,  2804,  2727,  2657,  2583,  2509,  2437,  2362,  2290,  2211,
+             2136,  2068,  1996,  1915,  1858,  1773,  1692,  1620,  1552,  1477,
+             1398,  1326,  1251,  1179,  1109,  1031,   961,   884,   814,   736,
+              667,   592,   518,   441,   369,   292,   221,   151,    86,    64
+        );
+    }
+    for ($i=0; $i<100; ++$i) {
+        next if $qval < $hash[$i] and $sum < $sums[$i];
+        $quality = $i + 1 if ($qval <= $hash[$i] and $sum <= $sums[$i]) or $i >= 50;
+        last;
+    }
+    return $quality;
+}
+
+#------------------------------------------------------------------------------
+# Calculate JPEGDigest and/or JPEGQualityEstimate
 # Inputs: 0) ExifTool object ref, 1) DQT segments array ref, 2) subsampling string
 sub Calculate($$$)
 {
-    my ($exifTool, $dqtList, $subSampling) = @_;
-
-    unless (eval 'require Digest::MD5') {
-        $exifTool->Warn('Digest::MD5 must be installed to calculate JPEGDigest');
+    my ($et, $dqtList, $subSampling) = @_;
+
+    # estimate JPEG quality if requested
+    my $all = ($$et{OPTIONS}{RequestAll} and $$et{OPTIONS}{RequestAll} > 2);
+    if ($all or $$et{REQ_TAG_LOOKUP}{jpegqualityestimate}) {
+        my $quality = EstimateQuality($dqtList);
+        $quality = '<unknown>' unless defined $quality;
+        $et->FoundTag('JPEGQualityEstimate', $quality);
+    }
+    return unless ($all or $$et{REQ_TAG_LOOKUP}{jpegdigest}) and $subSampling;
+
+    unless (eval { require Digest::MD5 }) {
+        $et->Warn('Digest::MD5 must be installed to calculate JPEGDigest');
         return;
     }
@@ -2470,5 +2567,5 @@
     # bulk up the documentation and slow down loading unnecessarily
     $Image::ExifTool::Extra{JPEGDigest}{PrintConv} = \%PrintConv;
-    $exifTool->FoundTag('JPEGDigest', $md5);
+    $et->FoundTag('JPEGDigest', $md5);
 }
 
@@ -2480,5 +2577,5 @@
 =head1 NAME
 
-Image::ExifTool::JPEGDigest - Lookup for JPEGDigest values
+Image::ExifTool::JPEGDigest - Calculate JPEGDigest and JPEGQualityEstimate
 
 =head1 SYNOPSIS
@@ -2489,13 +2586,22 @@
 
 This module contains a lookup for values of the JPEG DQT digest, allowing
-some image identification from JPEG data alone.
+some image identification from JPEG data alone.  It also calculates an
+estimated JPEG quality if requested.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, 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/ImageMagick/ImageMagick/blob/master/coders/jpeg.c>
+
+=back
+
 =head1 ACKNOWLEDGEMENTS
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JSON.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JSON.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JSON.pm	(revision 34921)
@@ -0,0 +1,165 @@
+#------------------------------------------------------------------------------
+# 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.02';
+
+sub ProcessTag($$$$%);
+
+%Image::ExifTool::JSON::Main = (
+    GROUPS => { 0 => 'JSON', 1 => 'JSON', 2 => 'Other' },
+    VARS => { NO_ID => 1 },
+    NOTES => q{
+        Other than a few tags in the table below, JSON tags have not been
+        pre-defined.  However, ExifTool will read any existing tags from basic
+        JSON-formatted files.
+    },
+    # ON1 settings tags
+    ON1_SettingsData => {
+        RawConv => q{
+            require Image::ExifTool::XMP;
+            $val = Image::ExifTool::XMP::DecodeBase64($val);
+        },
+        SubDirectory => { TagTable => 'Image::ExifTool::PLIST::Main' },
+    },
+    ON1_SettingsMetadataCreated     => { Groups => { 2 => 'Time' } },
+    ON1_SettingsMetadataModified    => { Groups => { 2 => 'Time' } },
+    ON1_SettingsMetadataName        => { },
+    ON1_SettingsMetadataPluginID    => { },
+    ON1_SettingsMetadataTimestamp   => { Groups => { 2 => 'Time' } },
+    ON1_SettingsMetadataUsage       => { },
+    ON1_SettingsMetadataVisibleToUser=>{ },
+);
+
+#------------------------------------------------------------------------------
+# 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) = @_;
+
+    # special case to reformat ON1 tag names
+    if ($tag =~ s/^settings\w{8}-\w{4}-\w{4}-\w{4}-\w{12}(Data|Metadata.+)$/ON1_Settings$1/) {
+        $et->OverrideFileType('ONP','application/on1') if $$et{FILE_TYPE} eq 'JSON';
+    }
+
+    # avoid conflict with special table entries
+    $tag .= '!' if $Image::ExifTool::specialTags{$tag};
+
+    AddTagToTable($tagTablePtr, $tag, {
+        Name => Image::ExifTool::MakeTagName($tag),
+        %flags,
+        Temporary => 1,
+    }) 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} if $$tagTablePtr{$key}{Temporary};
+    }
+
+    # 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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JVC.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JVC.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/JVC.pm	(revision 34921)
@@ -11,7 +11,8 @@
 use strict;
 use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
 
-$VERSION = '1.02';
+$VERSION = '1.03';
 
 sub ProcessJVCText($$$);
@@ -63,26 +64,26 @@
 sub ProcessJVCText($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart} || 0;
     my $dataLen = $$dirInfo{DataLen};
     my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     my $data = substr($$dataPt, $dirStart, $dirLen);
     # validate text maker notes
     unless ($data =~ /^VER:/) {
-        $exifTool->Warn('Bad JVC text maker notes');
+        $et->Warn('Bad JVC text maker notes');
         return 0;
     }
     while ($data =~ m/([A-Z]+):(.{3,4})/sg) {
         my ($tag, $val) = ($1, $2);
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
-        $exifTool->VerboseInfo($tag, $tagInfo,
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        $et->VerboseInfo($tag, $tagInfo,
             Table  => $tagTablePtr,
             Value  => $val,
         ) if $verbose;
         unless ($tagInfo) {
-            next unless $exifTool->{OPTIONS}->{Unknown};
+            next unless $$et{OPTIONS}{Unknown};
             $tagInfo = {
                 Name => "JVC_Text_$tag",
@@ -91,7 +92,7 @@
             };
             # add tag information to table
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
         }
-        $exifTool->FoundTag($tagInfo, $val);
+        $et->FoundTag($tagInfo, $val);
     }
     return 1;
@@ -117,5 +118,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Jpeg2000.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Jpeg2000.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Jpeg2000.pm	(revision 34921)
@@ -17,5 +17,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.16';
+$VERSION = '1.27';
 
 sub ProcessJpeg2000Box($$$);
@@ -58,4 +58,6 @@
 my %uuid = (
     'UUID-EXIF'   => 'JpgTiffExif->JP2',
+    'UUID-EXIF2'  => '',    # (flags a warning when writing)
+    'UUID-EXIF_bad' => '0', # (flags a warning when reading and writing)
     'UUID-IPTC'   => "\x33\xc7\xa4\xd2\xb8\x1d\x47\x23\xa0\xba\xf1\xa3\xe0\x97\xad\x38",
     'UUID-XMP'    => "\xbe\x7a\xcf\xcb\x97\xa9\x42\xe8\x9c\x71\x99\x94\x91\xe3\xaf\xac",
@@ -64,9 +66,45 @@
 );
 
+# JPEG2000 codestream markers (ref ISO/IEC FCD15444-1/2)
+my %j2cMarker = (
+    0x4f => 'SOC', # start of codestream
+    0x51 => 'SIZ', # image and tile size
+    0x52 => 'COD', # coding style default
+    0x53 => 'COC', # coding style component
+    0x55 => 'TLM', # tile-part lengths
+    0x57 => 'PLM', # packet length, main header
+    0x58 => 'PLT', # packet length, tile-part header
+    0x5c => 'QCD', # quantization default
+    0x5d => 'QCC', # quantization component
+    0x5e => 'RGN', # region of interest
+    0x5f => 'POD', # progression order default
+    0x60 => 'PPM', # packed packet headers, main
+    0x61 => 'PPT', # packed packet headers, tile-part
+    0x63 => 'CRG', # component registration
+    0x64 => 'CME', # comment and extension
+    0x90 => 'SOT', # start of tile-part
+    0x91 => 'SOP', # start of packet
+    0x92 => 'EPH', # end of packet header
+    0x93 => 'SOD', # start of data
+    # extensions (ref ISO/IEC FCD15444-2)
+    0x70 => 'DCO', # variable DC offset
+    0x71 => 'VMS', # visual masking
+    0x72 => 'DFS', # downsampling factor style
+    0x73 => 'ADS', # arbitrary decomposition style
+  # 0x72 => 'ATK', # arbitrary transformation kernels ?
+    0x78 => 'CBD', # component bit depth
+    0x74 => 'MCT', # multiple component transformation definition
+    0x75 => 'MCC', # multiple component collection
+    0x77 => 'MIC', # multiple component intermediate collection
+    0x76 => 'NLT', # non-linearity point transformation
+);
+
 # JPEG 2000 "box" (ie. atom) names
+# Note: only tags with a defined "Format" are extracted
 %Image::ExifTool::Jpeg2000::Main = (
     GROUPS => { 2 => 'Image' },
     PROCESS_PROC => \&ProcessJpeg2000Box,
     WRITE_PROC => \&ProcessJpeg2000Box,
+    PREFERRED => 1, # always add these tags when writing
     NOTES => q{
         The tags below are extracted from JPEG 2000 images, however ExifTool
@@ -93,29 +131,10 @@
         },
         bpcc => 'BitsPerComponent',
-        colr => [
-            {
-                Name => 'ICC_Profile',
-                Condition => '$$valPt =~ /^(\x02|\x03)/',
-                SubDirectory => {
-                    TagTable => 'Image::ExifTool::ICC_Profile::Main',
-                    Start => '$valuePtr + 3',
-                },
-            },
-            {
-                Name => 'Colorspace',
-                Condition => '$$valPt =~ /^\x01/',
-                Format => 'binary',
-                ValueConv => 'unpack("x3N", $val)',
-                PrintConv => {
-                    16 => 'sRGB',
-                    17 => 'Grayscale',
-                    18 => 'sYCC',
-                },
-            },
-            {
-                Name => 'ColorSpecification',
-                Binary => 1,
-            },
-        ],
+        colr => {
+            Name => 'ColorSpecification',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Jpeg2000::ColorSpec',
+            },
+        },
         pclr => 'Palette',
         cdef => 'ComponentDefinition',
@@ -168,5 +187,9 @@
     copt => 'CompositionOptions',
     inst => 'InstructionSet',
-    asoc => 'Association',
+    asoc => {
+        Name => 'Association',
+        SubDirectory => { },
+    },
+        # (Association box may contain any other sub-box)
     nlst => 'NumberList',
     bfil => 'BinaryFilter',
@@ -180,18 +203,26 @@
     jp2i => {
         Name => 'IntellectualProperty',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::XMP::Main',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     },
    'xml '=> {
         Name => 'XML',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::XMP::Main',
-        },
+        Writable => 'undef',
+        Flags => [ 'Binary', 'Protected', 'BlockExtract' ],
+        List => 1,
+        Notes => q{
+            by default, the XML data in this tag is parsed using the ExifTool XMP module
+            to to allow individual tags to be accessed when reading, but it may also be
+            extracted as a block via the "XML" tag, which is also how this tag is
+            written and copied.  This is a List-type tag because multiple XML blocks may
+            exist
+        },
+        # (note: extracting as a block was broken in 11.04, and finally fixed in 12.14)
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::XML' },
     },
     uuid => [
         {
             Name => 'UUID-EXIF',
-            Condition => '$$valPt=~/^JpgTiffExif->JP2/',
+            # (this is the EXIF that we create)
+            Condition => '$$valPt=~/^JpgTiffExif->JP2(?!Exif\0\0)/',
             SubDirectory => {
                 TagTable => 'Image::ExifTool::Exif::Main',
@@ -203,6 +234,40 @@
         },
         {
+            Name => 'UUID-EXIF2',
+            # written by Photoshop 7.01+Adobe JPEG2000-plugin v1.5
+            Condition => '$$valPt=~/^\x05\x37\xcd\xab\x9d\x0c\x44\x31\xa7\x2a\xfa\x56\x1f\x2a\x11\x3e/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Exif::Main',
+                ProcessProc => \&Image::ExifTool::ProcessTIFF,
+                WriteProc => \&Image::ExifTool::WriteTIFF,
+                DirName => 'EXIF',
+                Start => '$valuePtr + 16',
+            },
+        },
+        {
+            Name => 'UUID-EXIF_bad',
+            # written by Digikam
+            Condition => '$$valPt=~/^JpgTiffExif->JP2/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Exif::Main',
+                ProcessProc => \&Image::ExifTool::ProcessTIFF,
+                WriteProc => \&Image::ExifTool::WriteTIFF,
+                DirName => 'EXIF',
+                Start => '$valuePtr + 22',
+            },
+        },
+        {
             Name => 'UUID-IPTC',
+            # (this is the IPTC that we create)
             Condition => '$$valPt=~/^\x33\xc7\xa4\xd2\xb8\x1d\x47\x23\xa0\xba\xf1\xa3\xe0\x97\xad\x38/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::IPTC::Main',
+                Start => '$valuePtr + 16',
+            },
+        },
+        {
+            Name => 'UUID-IPTC2',
+            # written by Photoshop 7.01+Adobe JPEG2000-plugin v1.5
+            Condition => '$$valPt=~/^\x09\xa1\x4e\x97\xc0\xb4\x42\xe0\xbe\xbf\x36\xdf\x6f\x0c\xe3\x6f/',
             SubDirectory => {
                 TagTable => 'Image::ExifTool::IPTC::Main',
@@ -230,6 +295,20 @@
         },
         {
+            Name => 'UUID-Photoshop',
+            # written by Photoshop 7.01+Adobe JPEG2000-plugin v1.5
+            Condition => '$$valPt=~/^\x2c\x4c\x01\x00\x85\x04\x40\xb9\xa0\x3e\x56\x21\x48\xd6\xdf\xeb/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Photoshop::Main',
+                Start => '$valuePtr + 16',
+            },
+        },
+        {
             Name => 'UUID-Unknown',
         },
+        # also written by Adobe JPEG2000 plugin v1.5:
+        # 3a 0d 02 18 0a e9 41 15 b3 76 4b ca 41 ce 0e 71 - 1 byte (01)
+        # 47 c9 2c cc d1 a1 45 81 b9 04 38 bb 54 67 71 3b - 1 byte (01)
+        # bc 45 a7 74 dd 50 4e c6 a9 f6 f3 a1 37 f4 7e 90 - 4 bytes (00 00 00 32)
+        # d7 c8 c5 ef 95 1f 43 b2 87 57 04 25 00 f5 38 e8 - 4 bytes (00 00 00 32)
     ],
     uinf => {
@@ -308,5 +387,5 @@
         Format => 'undef[$size-8]',
         # ignore any entry with a null, and return others as a list
-        ValueConv => 'my @a=($val=~/.{4}/sg); @a=grep(!/\0/,@a); \@a', 
+        ValueConv => 'my @a=($val=~/.{4}/sg); @a=grep(!/\0/,@a); \@a',
     },
 );
@@ -360,15 +439,109 @@
 );
 
+%Image::ExifTool::Jpeg2000::ColorSpec = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int8s',
+    0 => {
+        Name => 'ColorSpecMethod',
+        RawConv => '$$self{ColorSpecMethod} = $val',
+        PrintConv => {
+            1 => 'Enumerated',
+            2 => 'Restricted ICC',
+            3 => 'Any ICC',
+            4 => 'Vendor Color',
+        },
+    },
+    1 => 'ColorSpecPrecedence',
+    2 => {
+        Name => 'ColorSpecApproximation',
+        PrintConv => {
+            0 => 'Not Specified',
+            1 => 'Accurate',
+            2 => 'Exceptional Quality',
+            3 => 'Reasonable Quality',
+            4 => 'Poor Quality',
+        },
+    },
+    3 => [
+        {
+            Name => 'ICC_Profile',
+            Condition => q{
+                $$self{ColorSpecMethod} == 2 or
+                $$self{ColorSpecMethod} == 3
+            },
+            Format => 'undef[$size-3]',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::ICC_Profile::Main',
+            },
+        },
+        {
+            Name => 'ColorSpace',
+            Condition => '$$self{ColorSpecMethod} == 1',
+            Format => 'int32u',
+            PrintConv => { # ref 15444-2 2002-05-15
+                0 => 'Bi-level',
+                1 => 'YCbCr(1)',
+                3 => 'YCbCr(2)',
+                4 => 'YCbCr(3)',
+                9 => 'PhotoYCC',
+                11 => 'CMY',
+                12 => 'CMYK',
+                13 => 'YCCK',
+                14 => 'CIELab',
+                15 => 'Bi-level(2)', # (incorrectly listed as 18 in 15444-2 2000-12-07)
+                16 => 'sRGB',
+                17 => 'Grayscale',
+                18 => 'sYCC',
+                19 => 'CIEJab',
+                20 => 'e-sRGB',
+                21 => 'ROMM-RGB',
+                # incorrect in 15444-2 2000-12-07
+                #22 => 'sRGB based YCbCr',
+                #23 => 'YPbPr(1125/60)',
+                #24 => 'YPbPr(1250/50)',
+                22 => 'YPbPr(1125/60)',
+                23 => 'YPbPr(1250/50)',
+                24 => 'e-sYCC',
+            },
+        },
+        {
+            Name => 'ColorSpecData',
+            Format => 'undef[$size-3]',
+            Binary => 1,
+        },
+    ],
+);
+
 #------------------------------------------------------------------------------
 # Create new JPEG 2000 boxes when writing
-# (Currently only supports adding certain UUID boxes)
+# (Currently only supports adding top-level Writable JPEG2000 tags and certain UUID boxes)
 # Inputs: 0) ExifTool object ref, 1) Output file or scalar ref
 # Returns: 1 on success
 sub CreateNewBoxes($$)
 {
-    my ($exifTool, $outfile) = @_;
-    my $addDirs = $$exifTool{AddJp2Dirs};
-    delete $$exifTool{AddJp2Dirs};
-    my $dirName;
+    my ($et, $outfile) = @_;
+    my $addTags = $$et{AddJp2Tags};
+    my $addDirs = $$et{AddJp2Dirs};
+    delete $$et{AddJp2Tags};
+    delete $$et{AddJp2Dirs};
+    my ($tag, $dirName);
+    # add JPEG2000 tags
+    foreach $tag (sort keys %$addTags) {
+        my $tagInfo = $$addTags{$tag};
+        my $nvHash = $et->GetNewValueHash($tagInfo);
+        # (native JPEG2000 information is always preferred, so don't check IsCreating)
+        next unless $$tagInfo{List} or $et->IsOverwriting($nvHash) > 0;
+        next if $$nvHash{EditOnly};
+        my @vals = $et->GetNewValue($nvHash);
+        my $val;
+        foreach $val (@vals) {
+            my $boxhdr = pack('N', length($val) + 8) . $$tagInfo{TagID};
+            Write($outfile, $boxhdr, $val) or return 0;
+            ++$$et{CHANGED};
+            $et->VerboseValue("+ Jpeg2000:$$tagInfo{Name}", $val);
+        }
+    }
+    # add UUID boxes
     foreach $dirName (sort keys %$addDirs) {
         next unless $uuid{$dirName};
@@ -382,5 +555,8 @@
                 Parent => 'JP2',
             );
-            my $newdir = $exifTool->WriteDirectory(\%dirInfo, $tagTable, $$subdir{WriteProc});
+            # remove "UUID-" from start of directory name to allow appropriate
+            # directories to be written as a block
+            $dirInfo{DirName} =~ s/^UUID-//;
+            my $newdir = $et->WriteDirectory(\%dirInfo, $tagTable, $$subdir{WriteProc});
             if (defined $newdir and length $newdir) {
                 my $boxhdr = pack('N', length($newdir) + 24) . 'uuid' . $uuid{$dirName};
@@ -400,5 +576,5 @@
 sub ProcessJpeg2000Box($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataLen = $$dirInfo{DataLen};
@@ -406,4 +582,5 @@
     my $dirLen = $$dirInfo{DirLen} || 0;
     my $dirStart = $$dirInfo{DirStart} || 0;
+    my $base = $$dirInfo{Base} || 0;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
@@ -419,5 +596,6 @@
     } else {
         # (must not set verbose flag when writing!)
-        $verbose = $exifTool->{OPTIONS}->{Verbose};
+        $verbose = $$et{OPTIONS}{Verbose};
+        $et->VerboseDir($$dirInfo{DirName}) if $verbose;
     }
     # loop through all contained boxes
@@ -425,35 +603,44 @@
     for ($pos=$dirStart; ; $pos+=$boxLen) {
         my ($boxID, $buff, $valuePtr);
+        my $hdrLen = 8;     # the box header length
         if ($raf) {
-            $dataPos = $raf->Tell();
-            my $n = $raf->Read($buff,8);
-            unless ($n == 8) {
+            $dataPos = $raf->Tell() - $base;
+            my $n = $raf->Read($buff,$hdrLen);
+            unless ($n == $hdrLen) {
                 $n and $err = '', last;
                 if ($outfile) {
-                    CreateNewBoxes($exifTool, $outfile) or $err = 1;
+                    CreateNewBoxes($et, $outfile) or $err = 1;
                 }
                 last;
             }
             $dataPt = \$buff;
-            $dirLen = 8;
+            $dirLen = $dirEnd = $hdrLen;
             $pos = 0;
-        } elsif ($pos >= $dirEnd - 8) {
+        } elsif ($pos >= $dirEnd - $hdrLen) {
             $err = '' unless $pos == $dirEnd;
             last;
         }
-        $boxLen = unpack("x$pos N",$$dataPt);
+        $boxLen = unpack("x$pos N",$$dataPt);   # (length includes header and data)
         $boxID = substr($$dataPt, $pos+4, 4);
-        $pos += 8;
+        $pos += $hdrLen;                # move to end of box header
         if ($boxLen == 1) {
-            if (not $raf and $pos < $dirLen - 8) {
-                $err = 'JPEG 2000 format error';
-            } else {
-                $err = "Can't currently handle huge JPEG 2000 boxes";
+            # box header contains an additional 8-byte integer for length
+            $hdrLen += 8;
+            if ($raf) {
+                my $buf2;
+                if ($raf->Read($buf2,8) == 8) {
+                    $buff .= $buf2;
+                    $dirLen = $dirEnd = $hdrLen;
+                }
             }
-            last;
+            $pos > $dirEnd - 8 and $err = '', last;
+            my ($hi, $lo) = unpack("x$pos N2",$$dataPt);
+            $hi and $err = "Can't currently handle JPEG 2000 boxes > 4 GB", last;
+            $pos += 8;                  # move to end of extended-length box header
+            $boxLen = $lo - $hdrLen;    # length of remaining box data
         } elsif ($boxLen == 0) {
             if ($raf) {
                 if ($outfile) {
-                    CreateNewBoxes($exifTool, $outfile) or $err = 1;
+                    CreateNewBoxes($et, $outfile) or $err = 1;
                     # copy over the rest of the file
                     Write($outfile, $$dataPt) or $err = 1;
@@ -461,13 +648,16 @@
                         Write($outfile, $buff) or $err = 1;
                     }
+                } elsif ($verbose) {
+                    my $msg = sprintf("offset 0x%.4x to end of file", $dataPos + $base + $pos);
+                    $et->VPrint(0, "$$et{INDENT}- Tag '${boxID}' ($msg)\n");
                 }
                 last;   # (ignore the rest of the file when reading)
             }
-            $boxLen = $dirLen - $pos;
+            $boxLen = $dirEnd - $pos;   # data runs to end of file
         } else {
-            $boxLen -= 8;
+            $boxLen -= $hdrLen;         # length of remaining box data
         }
         $boxLen < 0 and $err = 'Invalid JPEG 2000 box length', last;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $boxID);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $boxID);
         unless (defined $tagInfo or $verbose) {
             # no need to process this box
@@ -481,5 +671,5 @@
                 }
             } elsif ($outfile) {
-                Write($outfile, substr($$dataPt, $pos-8, $boxLen+8)) or $err = '', last;
+                Write($outfile, substr($$dataPt, $pos-$hdrLen, $boxLen+$hdrLen)) or $err = '', last;
             }
             next;
@@ -487,9 +677,9 @@
         if ($raf) {
             # read the box data
-            $dataPos = $raf->Tell();
+            $dataPos = $raf->Tell() - $base;
             $raf->Read($buff,$boxLen) == $boxLen or $err = '', last;
             $valuePtr = 0;
             $dataLen = $boxLen;
-        } elsif ($boxLen + $pos > $dirStart + $dirLen) {
+        } elsif ($pos + $boxLen > $dirEnd) {
             $err = '';
             last;
@@ -500,18 +690,37 @@
             # GetTagInfo() required the value for a Condition
             my $tmpVal = substr($$dataPt, $valuePtr, $boxLen < 128 ? $boxLen : 128);
-            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $boxID, \$tmpVal);
-        }
-        # delete all UUID boxes if deleting all information
-        if ($outfile and $boxID eq 'uuid' and $exifTool->{DEL_GROUP}->{'*'}) {
-            $exifTool->VPrint(0, "  Deleting $$tagInfo{Name}\n");
-            ++$exifTool->{CHANGED};
-            next;
+            $tagInfo = $et->GetTagInfo($tagTablePtr, $boxID, \$tmpVal);
+        }
+        # delete all UUID boxes and any writable box if deleting all information
+        if ($outfile and $tagInfo) {
+            if ($boxID eq 'uuid' and $$et{DEL_GROUP}{'*'}) {
+                $et->VPrint(0, "  Deleting $$tagInfo{Name}\n");
+                ++$$et{CHANGED};
+                next;
+            } elsif ($$tagInfo{Writable}) {
+                my $isOverwriting;
+                if ($$et{DEL_GROUP}{Jpeg2000}) {
+                    $isOverwriting = 1;
+                } else {
+                    my $nvHash = $et->GetNewValueHash($tagInfo);
+                    $isOverwriting = $et->IsOverwriting($nvHash);
+                }
+                if ($isOverwriting) {
+                    my $val = substr($$dataPt, $valuePtr, $boxLen);
+                    $et->VerboseValue("- Jpeg2000:$$tagInfo{Name}", $val);
+                    ++$$et{CHANGED};
+                    next;
+                } elsif (not $$tagInfo{List}) {
+                    delete $$et{AddJp2Tags}{$boxID};
+                }
+            }
         }
         if ($verbose) {
-            $exifTool->VerboseInfo($boxID, $tagInfo,
+            $et->VerboseInfo($boxID, $tagInfo,
                 Table  => $tagTablePtr,
                 DataPt => $dataPt,
                 Size   => $boxLen,
                 Start  => $valuePtr,
+                Addr   => $valuePtr + $dataPos + $base,
             );
             next unless $tagInfo;
@@ -528,5 +737,5 @@
                 Parent => 'JP2',
                 DataPt => $dataPt,
-                DataPos => $dataPos,
+                DataPos => -$subdirStart, # (relative to Base)
                 DataLen => $dataLen,
                 DirStart => $subdirStart,
@@ -534,15 +743,20 @@
                 DirName => $$subdir{DirName} || $$tagInfo{Name},
                 OutFile => $outfile,
-                Base => $dataPos + $subdirStart,
+                Base => $base + $dataPos + $subdirStart,
             );
+            my $uuid = $uuid{$$tagInfo{Name}};
+            # remove "UUID-" prefix to allow appropriate directories to be written as a block
+            $subdirInfo{DirName} =~ s/^UUID-//;
             my $subTable = GetTagTable($$subdir{TagTable}) || $tagTablePtr;
             if ($outfile) {
                 # remove this directory from our create list
-                delete $exifTool->{AddJp2Dirs}->{$$tagInfo{Name}};
+                delete $$et{AddJp2Dirs}{$$tagInfo{Name}};
                 my $newdir;
                 # only edit writable UUID boxes
-                if ($uuid{$$tagInfo{Name}}) {
-                    $newdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
+                if ($uuid) {
+                    $newdir = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
                     next if defined $newdir and not length $newdir; # next if deleting the box
+                } elsif (defined $uuid) {
+                    $et->Warn("Not editing $$tagInfo{Name} box", 1);
                 }
                 # use old box data if not changed
@@ -552,16 +766,25 @@
                 $boxhdr .= substr($$dataPt, $valuePtr, $prefixLen) if $prefixLen;
                 Write($outfile, $boxhdr, $newdir) or $err = 1;
-            } elsif (not $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $$subdir{ProcessProc})) {
-                if ($subTable eq $tagTablePtr) {
-                    $err = 'JPEG 2000 format error';
-                } else {
-                    $err = "Unrecognized $$tagInfo{Name} box";
+            } else {
+                # extract as a block if specified
+                $subdirInfo{BlockInfo} = $tagInfo if $$tagInfo{BlockExtract};
+                $et->Warn("Reading non-standard $$tagInfo{Name} box") if defined $uuid and $uuid eq '0';
+                unless ($et->ProcessDirectory(\%subdirInfo, $subTable, $$subdir{ProcessProc})) {
+                    if ($subTable eq $tagTablePtr) {
+                        $err = 'JPEG 2000 format error';
+                        last;
+                    }
+                    $et->Warn("Unrecognized $$tagInfo{Name} box");
                 }
-                last;
             }
         } elsif ($$tagInfo{Format} and not $outfile) {
             # only save tag values if Format was specified
-            my $val = ReadValue($dataPt, $valuePtr, $$tagInfo{Format}, undef, $boxLen);
-            $exifTool->FoundTag($tagInfo, $val) if defined $val;
+            my $rational;
+            my $val = ReadValue($dataPt, $valuePtr, $$tagInfo{Format}, undef, $boxLen, \$rational);
+            if (defined $val) {
+                my $key = $et->FoundTag($tagInfo, $val);
+                # save Rational value
+                $$et{RATIONAL}{$key} = $rational if defined $rational and defined $key;
+            }
         } elsif ($outfile) {
             my $boxhdr = pack('N', $boxLen + 8) . $boxID;
@@ -572,8 +795,8 @@
         $err or $err = 'Truncated JPEG 2000 box';
         if ($outfile) {
-            $exifTool->Error($err) unless $err eq '1';
+            $et->Error($err) unless $err eq '1';
             return $raf ? -1 : undef;
         }
-        $exifTool->Warn($err);
+        $et->Warn($err);
     }
     return $outBuff if $outfile and not $raf;
@@ -587,5 +810,6 @@
 sub ProcessJP2($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    local $_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
@@ -594,13 +818,27 @@
     # check to be sure this is a valid JPG2000 file
     return 0 unless $raf->Read($hdr,12) == 12;
-    return 0 unless $hdr eq "\x00\x00\x00\x0cjP  \x0d\x0a\x87\x0a" or     # (ref 1)
-                    $hdr eq "\x00\x00\x00\x0cjP\x1a\x1a\x0d\x0a\x87\x0a"; # (ref 2)
-
+    unless ($hdr eq "\x00\x00\x00\x0cjP  \x0d\x0a\x87\x0a" or     # (ref 1)
+            $hdr eq "\x00\x00\x00\x0cjP\x1a\x1a\x0d\x0a\x87\x0a") # (ref 2)
+    {
+        return 0 unless $hdr =~ /^\xff\x4f\xff\x51\0/;  # check for JP2 codestream format
+        if ($outfile) {
+            $et->Error('Writing of J2C files is not yet supported');
+            return 0
+        }
+        # add J2C markers if not done already
+        unless ($Image::ExifTool::jpegMarker{0x4f}) {
+            $Image::ExifTool::jpegMarker{$_} = $j2cMarker{$_} foreach keys %j2cMarker;
+        }
+        $et->SetFileType('J2C');
+        $raf->Seek(0,0);
+        return $et->ProcessJPEG($dirInfo);    # decode with JPEG processor
+    }
     if ($outfile) {
         Write($outfile, $hdr) or return -1;
-        $exifTool->InitWriteDirs(\%jp2Map);
+        $et->InitWriteDirs(\%jp2Map);
         # save list of directories to create
-        my %addDirs = %{$$exifTool{ADD_DIRS}};
-        $$exifTool{AddJp2Dirs} = \%addDirs;
+        my %addDirs = %{$$et{ADD_DIRS}};
+        $$et{AddJp2Dirs} = \%addDirs;
+        $$et{AddJp2Tags} = $et->GetNewTagInfoHash(\%Image::ExifTool::Jpeg2000::Main);
     } else {
         my ($buff, $fileType);
@@ -611,5 +849,5 @@
         }
         $raf->Seek(-length($buff), 1) if defined $buff;
-        $exifTool->SetFileType($fileType);
+        $et->SetFileType($fileType);
     }
     SetByteOrder('MM'); # JPEG 2000 files are big-endian
@@ -620,5 +858,5 @@
     );
     my $tagTablePtr = GetTagTable('Image::ExifTool::Jpeg2000::Main');
-    return $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    return $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
 }
 
@@ -642,5 +880,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Kodak.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Kodak.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Kodak.pm	(revision 34921)
@@ -9,4 +9,6 @@
 #               2) http://www.ozhiker.com/electronics/pjmt/jpeg_info/meta.html
 #               3) http://www.cybercom.net/~dcoffin/dcraw/
+#               4) Jim McGarvey private communication
+#               IB) Iliah Borg private communication (LibRaw)
 #
 # Notes:        There really isn't much public information about Kodak formats.
@@ -21,10 +23,12 @@
 use strict;
 use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
 
-$VERSION = '1.27';
+$VERSION = '1.47';
 
 sub ProcessKodakIFD($$$);
 sub ProcessKodakText($$$);
+sub ProcessPose($$$);
 sub WriteKodakIFD($$$);
 
@@ -188,4 +192,5 @@
             2 => 'Tungsten',
             3 => 'Daylight',
+            # 5 - seen this for "Auto" with a ProBack 645M
         },
     },
@@ -371,4 +376,6 @@
     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
@@ -438,4 +445,6 @@
     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,
@@ -749,9 +758,17 @@
         Notes => 'Kodak only',
     },
-    0xa8 => { # (not confirmed)
-        Name => 'SerialNumber',
-        Condition => '$$self{Make} =~ /Kodak/i',
+    0xa8 => {
+        Name => 'UnknownNumber', # (was SerialNumber, but not unique for all cameras. eg. C1013)
+        Condition => '$$self{Make} =~ /Kodak/i and $$valPt =~ /^([A-Z0-9]{1,11}\0|[A-Z0-9]{12})/i',
         Format => 'string[12]',
         Notes => 'Kodak only',
+        Writable => 0,
+    },
+    0xc4 => {
+        Name => 'UnknownNumber', # (confirmed NOT to be serial number for Easyshare Mini - PH)
+        Condition => '$$self{Make} =~ /Kodak/i and $$valPt =~ /^([A-Z0-9]{1,11}\0|[A-Z0-9]{12})/i',
+        Format => 'string[12]',
+        Notes => 'Kodak only',
+        Writable => 0,
     },
 );
@@ -772,4 +789,6 @@
         Writable => 'int16u',
         Count => 2,
+        PrintConv => '$val =~ tr/ /x/; $val',
+        PrintConvInv => '$val =~ tr/x/ /; $val',
     },
     # 0x03 int32u - ranges from about 33940 to 40680
@@ -837,4 +856,38 @@
 );
 
+# Kodak PixPro S-1 maker notes (ref PH)
+# (similar to Ricoh::Type2 and GE::Main)
+%Image::ExifTool::Kodak::Type11 = (
+    # (can't currently write these)
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES =>q{
+        These tags are found in models such as the PixPro S-1.  They are not
+        writable because the inconsistency of Kodak maker notes is beginning to get
+        on my nerves.
+    },
+    # (these are related to the Kodak QuickTime UserData tags)
+    0x0104 => 'FirmwareVersion',
+    0x0203 => {
+        Name => 'PictureEffect',
+        PrintConv => {
+            0 => 'None',
+            3 => 'Monochrome',
+            9 => 'Kodachrome',
+        },
+    },
+    # 0x0204 - ExposureComp or FlashExposureComp maybe?
+    0x0207 => 'KodakModel',
+    0x0300 => 'KodakMake',
+    0x0308 => 'LensSerialNumber',
+    0x0309 => 'LensModel',
+    0x030d => { Name => 'LevelMeter', Unknown => 1 }, # (guess)
+    0x0311 => 'Pitch', # Units??
+    0x0312 => 'Yaw',   # Units??
+    0x0313 => 'Roll',  # Units??
+    0x0314 => { Name => 'CX',   Unknown => 1 },
+    0x0315 => { Name => 'CY',   Unknown => 1 },
+    0x0316 => { Name => 'Rads', Unknown => 1 },
+);
+
 # Kodak SubIFD0 tags (ref PH)
 %Image::ExifTool::Kodak::SubIFD0 = (
@@ -846,5 +899,6 @@
         Name => 'SceneMode',
         Writable => 'int16u',
-        Notes => 'may not be valid for some models', # ie. M580?
+        Notes => 'may not be valid for some models', # eg. M580?
+        PrintConvColumns => 2,
         PrintConv => {
             1 => 'Sport',
@@ -867,6 +921,6 @@
             28 => 'Candlelight',
             29 => 'Sunset',
-            31 => 'Panorama Left-Right',
-            32 => 'Panorama Right-Left',
+            31 => 'Panorama Left-right',
+            32 => 'Panorama Right-left',
             33 => 'Smart Scene',
             34 => 'High ISO',
@@ -948,9 +1002,9 @@
     },
     0xfa57 => {
-        Name => 'PreviewWidth',
+        Name => 'PreviewImageWidth',
         Writable => 'int16u',
     },
     0xfa58 => {
-        Name => 'PreviewHeight',
+        Name => 'PreviewImageHeight',
         Writable => 'int16u',
     },
@@ -1008,4 +1062,5 @@
         Name => 'SceneModeUsed',
         Writable => 'int32u',
+        PrintConvColumns => 2,
         PrintConv => \%sceneModeUsed,
     },
@@ -1028,4 +1083,5 @@
         Name => 'SceneModeUsed',
         Writable => 'int32u',
+        PrintConvColumns => 2,
         PrintConv => \%sceneModeUsed,
     },
@@ -1297,15 +1353,19 @@
     },
     # 0x0000: int8u[4]    - values: "1 0 0 0" (DC50), "1 1 0 0" (DC120)
+    0x0000 => { #4
+        Name => 'KodakVersion',
+        Writable => 'int8u',
+        Count => 4,
+        PrintConv => '$val =~ tr/ /./; $val',
+        PrintConvInv => '$val =~ tr/./ /; $val',
+    },
     0x0001 => {
         # (related to EV but exact meaning unknown)
-        Name => 'UnknownEV',
+        Name => 'UnknownEV', # ("DeletedTag", ref 4)
         Writable => 'rational64u',
         Unknown => 1,
     },
     # 0x0002: int8u       - values: 0
-    0x0003 => {
-        Name => 'ExposureValue',
-        Writable => 'rational64u',
-    },
+    0x0003 => { Name => 'ExposureValue',    Writable => 'rational64u' },
     # 0x0004: rational64u - values: 2.875,3.375,3.625,4,4.125,7.25
     # 0x0005: int8u       - values: 0
@@ -1313,14 +1373,56 @@
     # 0x0007: int32u[3]   - values: "65536 67932 69256"
     0x03e9 => { Name => 'OriginalFileName', Writable => 'string' },
-    0x03eb => 'SensorLeftBorder',
-    0x03ec => 'SensorTopBorder',
-    0x03ed => 'SensorImageWidth',
-    0x03ee => 'SensorImageHeight',
+    0x03ea => { Name => 'KodakTag',         Writable => 'int32u' }, #4
+    0x03eb => { Name => 'SensorLeftBorder', Writable => 'int16u' }, # ("FinishedImageX", ref 4)
+    0x03ec => { Name => 'SensorTopBorder',  Writable => 'int16u' }, # ("FinishedImageY", ref 4)
+    0x03ed => { Name => 'SensorImageWidth', Writable => 'int16u' }, # ("FinishedImageWidth", ref 4)
+    0x03ee => { Name => 'SensorImageHeight',Writable => 'int16u' }, # ("FinishedImageHeight", ref 4)
+    0x03ef => { Name => 'BlackLevelTop',    Writable => 'int16u' }, #4
+    0x03f0 => { Name => 'BlackLevelBottom', Writable => 'int16u' }, #4
     0x03f1 => {
-        Name => 'TextualInfo',
+        Name => 'TextualInfo', # ("CameraSettingString", ref 4)
         SubDirectory => {
             TagTable => 'Image::ExifTool::Kodak::TextualInfo',
         },
     },
+    0x03f2 => { #IB/4
+        Name => 'FlashMode',
+        Writable => 'int16u',
+        Unknown => 1,
+        Priority => 0,
+    },
+    0x03f3 => { #IB/4
+        Name => 'FlashCompensation',
+        Writable => 'rational64s',
+    },
+    0x03f4 => { #4
+        Name => 'WindMode',
+        Writable => 'int16u',
+        Unknown => 1,
+    },
+    0x03f5 => { #4
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        Unknown => 1,
+        Priority => 0,
+    },
+    0x03f8 => { #IB/4
+        Name => 'MinAperture',
+        Writable => 'rational64u',
+    },
+    0x03f9 => { #IB/4
+        Name => 'MaxAperture',
+        Writable => 'rational64u',
+    },
+    0x03fa => { #4
+        Name => 'WhiteBalanceMode',
+        Writable => 'int16u',
+        Unknown => 1,
+    },
+    0x03fb => { #4
+        Name => 'WhiteBalanceDetected',
+        Writable => 'int16u',
+        Unknown => 1,
+    },
     0x03fc => { #3
         Name => 'WhiteBalance',
@@ -1329,5 +1431,5 @@
         PrintConv => { },   # no values yet known
     },
-    0x03fd => { #3
+    0x03fd => [{ #3
         Name => 'Processing',
         Condition => '$count == 72',
@@ -1335,29 +1437,1127 @@
             TagTable => 'Image::ExifTool::Kodak::Processing',
         },
-    },
+    },{
+        Name => 'ProcessingParameters', #4
+        Binary => 1,
+        # int8u[256]
+    }],
+    0x03fe => { Name => 'ImageAbsoluteX',       Writable => 'int16s', }, #4
+    0x03ff => { Name => 'ImageAbsoluteY',       Writable => 'int16s' }, #4
+    0x0400 => { Name => 'ApplicationKeyString', Writable => 'string' }, #4
     0x0401 => {
-        Name => 'Time',
+        Name => 'Time', # ("CaptureTime", ref 4)
         Groups => { 2 => 'Time' },
         Writable => 'string',
     },
-    0x0414 => { Name => 'NCDFileInfo',      Writable => 'string' },
-    0x0846 => { #3
+    0x0402 => { #4
+        Name => 'GPSString',
+        Groups => { 2 => 'Location' },
+        Writable => 'string',
+    },
+    0x0403 => { #4
+        Name => 'EventLogCapture',
+        Binary => 1,
+        Unknown => 1,
+        # int32u[3072]
+    },
+    0x0404 => { #4
+        Name => 'ComponentTable',
+        Binary => 1,
+        Unknown => 1,
+    },
+    0x0405 => { #4
+        Name => 'CustomIlluminant',
+        Writable => 'int16u',
+        Unknown => 1,
+    },
+    0x0406 => [{ #IB/4
+        Name => 'CameraTemperature',
+        Condition => '$count == 1',
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational64s',
+        PrintConv => '"$val C"',
+        PrintConvInv => '$val=~s/ ?C//; $val',
+    },{
+        Name => 'CameraTemperature',
+        # (when count is 2, values seem related to temperature, but are not Celius)
+    }],
+    0x0407 => { #IB/4
+        Name => 'AdapterVoltage',
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
+    },
+    0x0408 => { #IB/4
+        Name => 'BatteryVoltage',
+        Groups => { 2 => 'Camera' },
+        Writable => 'rational64u',
+    },
+    0x0409 => { #4
+        Name => 'DacVoltages',
+        # rational64u[8]
+    },
+    0x040a => { #4
+        Name => 'IlluminantDetectorData',
+        Binary => 1,
+        Unknown => 1,
+    },
+    0x040b => { #4
+        Name => 'PixelClockFrequency',
+        Writable => 'int32u',
+    },
+    0x040c => { #4
+        Name => 'CenterPixel',
+        Writable => 'int16u',
+        Count => 3,
+    },
+    0x040d => { #4
+        Name => 'BurstCount',
+        Writable => 'int16u',
+    },
+    0x040e => { #4
+        Name => 'BlackLevelRough',
+        Writable => 'int16u',
+    },
+    0x040f => { #4
+        Name => 'OffsetMapHorizontal',
+        Binary => 1,
+        Unknown => 1,
+        # int16s[1736]
+    },
+    0x0410 => { #4
+        Name => 'OffsetMapVertical',
+        Binary => 1,
+        Unknown => 1,
+        # int16s[1160]
+    },
+    0x0411 => { #4
+        Name => 'Histogram',
+        Binary => 1,
+        Unknown => 1,
+        # int16u[256]
+    },
+    0x0412 => { #4
+        Name => 'VerticalClockOverlaps',
+        Writable => 'int16u',
+        Count => 2,
+    },
+    0x0413 => 'SensorTemperature', #4
+    0x0414 => { Name => 'XilinxVersion',        Writable => 'string' }, #4
+    0x0415 => { Name => 'FirmwareVersion',      Writable => 'int32u' }, #4
+    0x0416 => { Name => 'BlackLevelRoughAfter', Writable => 'int16u' }, #4
+    0x0417 => 'BrightRowsTop', #4
+    0x0418 => 'EventLogProcess', #4
+    0x0419 => 'DacVoltagesFlush', #4
+    0x041a => 'FlashUsed', #4
+    0x041b => 'FlashType', #4
+    0x041c => 'SelfTimer', #4
+    0x041d => 'AFMode', #4
+    0x041e => 'LensType', #4
+    0x041f => { Name => 'ImageCropX',           Writable => 'int16s' }, #4
+    0x0420 => { Name => 'ImageCropY',           Writable => 'int16s' }, #4
+    0x0421 => 'AdjustedTbnImageWidth', #4
+    0x0422 => 'AdjustedTbnImageHeight', #4
+    0x0423 => { Name => 'IntegrationTime',      Writable => 'int32u' }, #4
+    0x0424 => 'BracketingMode', #4
+    0x0425 => 'BracketingStep', #4
+    0x0426 => 'BracketingCounter', #4
+    0x042e => 'HuffmanTableLength', #4 (int8u[16])
+    0x042f => 'HuffmanTableValue', #4 (int8u[13])
+    0x0438 => { Name => 'MainBoardVersion',     Writable => 'int32u' }, #4
+    0x0439 => { Name => 'ImagerBoardVersion',   Writable => 'int32u' }, #4
+    0x044c => 'FocusEdgeMap', #4
+    0x05e6 => 'IdleTiming', #4
+    0x05e7 => 'FlushTiming', #4
+    0x05e8 => 'IntegrateTiming', #4
+    0x05e9 => 'RegisterReadTiming', #4
+    0x05ea => 'FirstLineTransferTiming', #4
+    0x05eb => 'ShiftTiming', #4
+    0x05ec => 'NormalLineTransferTiming', #4
+    0x05ed => 'TestTransferTiming', #4
+    # 0x05f0-0x05f9 "TestTiming", ref 4
+    0x05fa => 'MinimumFlushRows', #4
+    0x05fd => { Name => 'ImagerPowerOnDelayMsec', Writable => 'int32u' }, #4
+    0x05fe => 'ImagerInitialTimingCode', #4
+    0x05ff => 'ImagerLogicProgram', #4
+    0x0600 => { Name => 'ImagerBiasSettlingDelayMsec', Writable => 'int32u' }, #4
+    0x0604 => 'IdleSequence', #4
+    0x0605 => 'FirstFlushSequence', #4
+    0x0606 => 'FinalFlushSequence', #4
+    0x0607 => 'SampleBlackSequence', #4
+    0x0608 => 'TransferSequence', #4
+    0x060e => 'DacCountsPerVolt', #4
+    0x060f => 'BlackDacChannel', #4
+    0x0610 => 'BlackAdCountsPerDacVolt', #4
+    0x0611 => 'BlackTarget', #4
+    0x0612 => 'BlackDacSettlingMsec', #4
+    # 0x0618-0x062b - reserved for .IF file use, ref 4
+    0x07d0 => { #4
+        Name => 'StandardMatrixDaylight',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07d1 => { #4
+        Name => 'StandardMatrixTungsten',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07d2 => { #4
+        Name => 'StandardMatrixFluorescent',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07d3 => { #4
+        Name => 'StandardMatrixFlash',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07d4 => { #4 (never used)
+        Name => 'StandardMatrixCustom',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07da => { #4
+        Name => 'DeviantMatrixDaylight',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07db => { #4
+        Name => 'DeviantMatrixTungsten',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07dc => { #4
+        Name => 'DeviantMatrixFluorescent',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07dd => { #4
+        Name => 'DeviantMatrixFlash',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07de => { #4 (never used)
+        Name => 'DeviantMatrixCustom',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07e4 => { #4
+        Name => 'UniqueMatrixDaylight',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07e5 => { #4
+        Name => 'UniqueMatrixTungsten',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07e6 => { #4
+        Name => 'UniqueMatrixFluorescent',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07e7 => { #4
+        Name => 'UniqueMatrixFlash',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07e8 => { #4
+        Name => 'UniqueMatrixCustom',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x07e9 => { #4
+        Name => 'UniqueMatrixAuto',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x0834 => { #4
+        Name => 'StandardWhiteDaylight',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x0835 => { #4
+        Name => 'StandardWhiteTungsten',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x0836 => { #4
+        Name => 'StandardWhiteFluorescent',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x0837 => { #4
+        Name => 'StandardWhiteFlash',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x0838 => { #4 (never used)
+        Name => 'StandardWhiteCustom',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x083e => { #4
+        Name => 'DeviantWhiteDaylight',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x083f => { #4
+        Name => 'DeviantWhiteTungsten',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x0840 => { #4
+        Name => 'DeviantWhiteFluorescent',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x0841 => { #4
+        Name => 'DeviantWhiteFlash',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    0x0842 => { #4 (never used)
+        Name => 'DeviantWhiteCustom',
+        Writable => 'rational64s',
+        Count => 3,
+    },
+    # 0x0843 - rational64u[3]
+    # 0x0844 - rational64u[3]
+    0x0846 => { #3 ("WhiteBalanceKelvin", ref 4)
         Name => 'ColorTemperature',
         Writable => 'int16u',
     },
-    0x0852 => 'WB_RGBMul0', #3
-    0x0853 => 'WB_RGBMul1', #3
-    0x0854 => 'WB_RGBMul2', #3
-    0x0855 => 'WB_RGBMul3', #3
-    0x085c => { Name => 'WB_RGBCoeffs0', Binary => 1 }, #3
-    0x085d => { Name => 'WB_RGBCoeffs1', Binary => 1 }, #3
-    0x085e => { Name => 'WB_RGBCoeffs2', Binary => 1 }, #3
-    0x085f => { Name => 'WB_RGBCoeffs3', Binary => 1 }, #3
-    # 0x090d: linear table (ref 3)
-    # 0x0c81: some sort of date (manufacture date?) - PH
-    0x0ce5 => { Name => 'FirmwareVersion',  Writable => 'string' },
-    # 0x1390: value: "DCSProSLRn" (tone curve name?) - PH
-    0x1391 => { Name => 'ToneCurveFileName',Writable => 'string' },
-    0x1784 => { Name => 'ISO',              Writable => 'int32u' }, #3
+    0x0847 => 'WB_RGBLevelsAsShot', #4
+    0x0848 => 'WB_RGBLevelsDaylight', #IB (rational64s/u[3]) ("UniqueWhiteDaylight", ref 4)
+    0x0849 => 'WB_RGBLevelsTungsten', #IB (rational64s/u[3]) ("UniqueWhiteTungsten", ref 4)
+    0x084a => 'WB_RGBLevelsFluorescent', #IB (rational64s/u[3]) ("UniqueWhiteFluorescent", ref 4)
+    0x084b => 'WB_RGBLevelsFlash', #IB (rational64s/u[3]) ("UniqueWhiteFlash", ref 4)
+    0x084c => 'WB_RGBLevelsCustom', #IB (rational64u[3]) ("UniqueWhiteCustom", ref 4)
+    0x084d => 'WB_RGBLevelsAuto', #IB (rational64u[3]) ("UniqueWhiteAuto", ref 4)
+    0x0852 => { #3/4
+        Name => 'WB_RGBMulDaylight', # ("AdjustWhiteFactorsDaylight", ref 4)
+        Writable => 'rational64u',
+        Count => 3,
+    },
+    0x0853 => { #3/4
+        Name => 'WB_RGBMulTungsten', # ("AdjustWhiteFactorsTungsten", ref 4)
+        Writable => 'rational64u',
+        Count => 3,
+    },
+    0x0854 => { #3/4
+        Name => 'WB_RGBMulFluorescent', # ("AdjustWhiteFactorsFluorescent", ref 4)
+        Writable => 'rational64u',
+        Count => 3,
+    },
+    0x0855 => { #3/4
+        Name => 'WB_RGBMulFlash', # ("AdjustWhiteFactorsFlash", ref 4)
+        Writable => 'rational64u',
+        Count => 3,
+    },
+    0x085c => { Name => 'WB_RGBCoeffsDaylight', Binary => 1 }, #3 ("WhiteBalanceParametersDaylight", ref 4)
+    0x085d => { Name => 'WB_RGBCoeffsTungsten', Binary => 1 }, #3 ("WhiteBalanceParametersTungsten", ref 4)
+    0x085e => { Name => 'WB_RGBCoeffsFluorescent',Binary=>1 }, #3 ("WhiteBalanceParametersFluorescent", ref 4)
+    0x085f => { Name => 'WB_RGBCoeffsFlash',    Binary => 1 }, #3 ("WhiteBalanceParametersFlash", ref 4)
+    0x0898 => { Name => 'ExposureGainDaylight', Writable => 'rational64s' }, #4
+    0x0899 => { Name => 'ExposureGainTungsten', Writable => 'rational64s' }, #4
+    0x089a => { Name => 'ExposureGainFluorescent',Writable=>'rational64s' }, #4
+    0x089b => { Name => 'ExposureGainFlash',    Writable => 'rational64s' }, #4
+    0x089c => { Name => 'ExposureGainCustom',   Writable => 'rational64s' }, #4 (never used)
+    0x089d => { Name => 'AnalogISOTable',       Writable => 'rational64u', Count => 3 }, #4
+    0x089e => { Name => 'AnalogCaptureISO',     Writable => 'int32u' }, #4
+    0x089f => { Name => 'ISOCalibrationGain',   Writable => 'rational64u' }, #4
+    0x08a0 => 'ISOCalibrationGainTable', #4
+    0x08a1 => 'ExposureHeadroomFactor', #4
+    0x08ab => 'LinearitySplineTags', #4 (int16u[24])
+    # 0x08ac-0x08fb - LinearitySpline(n) (rational64s[75])
+    0x08fc => { #4
+        Name => 'MonitorMatrix',
+        Writable => 'rational64s',
+        Count => 9,
+    },
+    0x08fd => 'TonScaleTable', #4
+    0x08fe => { Name => 'Gamma',                Writable => 'rational64u' }, #4
+    0x08ff => 'LogLinTable', #4
+    0x0900 => 'LinLogTable', #4
+    0x0901 => { Name => 'GammaTable',           Binary => 1 }, #4 (int16u[4096])
+    0x0902 => { Name => 'LogScale',             Writable => 'rational64u' }, #4
+    0x0903 => { Name => 'BaseISO',              Writable => 'rational64u' }, #IB (ISO before digital gain)
+    0x0904 => { Name => 'LinLogCoring',         Writable => 'int16u' }, #4
+    0x0905 => { Name => 'PatternGainConversionTable', Binary => 1 }, #4 (int8u[256])
+    0x0906 => 'DefectCount', #4
+    0x0907 => { Name => 'DefectList',           Binary => 1 }, #4 (undef[48])
+    0x0908 => { Name => 'DefectListPacked',     Binary => 1 }, #4 (int16u[296])
+    0x0909 => { Name => 'ImageSpace',           Writable => 'int16u' }, #4
+    0x090a => { Name => 'ThumbnailCompressionTable',Binary => 1 }, #4 (int8u[4096])
+    0x090b => { Name => 'ThumbnailExpansionTable',  Binary => 1 }, #4 (int16u[256])
+    0x090c => { Name => 'ImageCompressionTable',    Binary => 1 }, #4 (int16u[4096])
+    0x090d => { Name => 'ImageExpansionTable',      Binary => 1 }, #4 (int16u[1024/4096])
+    0x090e => 'EighteenPercentPoint', #4
+    0x090f => { Name => 'DefectIsoCode',        Writable => 'int16u' }, #4
+    0x0910 => { Name => 'BaseISODaylight',      Writable => 'rational64u' }, #4
+    0x0911 => { Name => 'BaseISOTungsten',      Writable => 'rational64u' }, #4
+    0x0912 => { Name => 'BaseISOFluorescent',   Writable => 'rational64u' }, #4
+    0x0913 => { Name => 'BaseISOFlash',         Writable => 'rational64u' }, #4
+    0x091a => { Name => 'MatrixSelectThreshold',Writable => 'int16s' }, #4
+    0x091b => { Name => 'MatrixSelectK',        Writable => 'rational64u' }, #4
+    0x091c => { Name => 'IlluminantDetectTable',Binary => 1 }, #4 (int16u[200])
+    0x091d => 'RGTable', #4
+    0x091e => { Name => 'MatrixSelectThreshold1', Writable => 'int16s' }, #4
+    0x091f => { Name => 'MatrixSelectThreshold2', Writable => 'int16s' }, #4
+    0x0924 => 'PortraitMatrix', #4
+    0x0925 => 'PortraitToneScaleTable', #4
+    0x092e => { Name => 'EnableSharpening',     Writable => 'int16u' }, #4
+    0x092f => { #4
+        Name => 'SharpeningKernel',
+        Writable => 'int16s',
+        Count => 25,
+    },
+    0x0930 => { Name => 'EdgeMapSlope',         Writable => 'int16u' }, #4
+    0x0931 => { Name => 'EdgeMapX1',            Writable => 'int16u' }, #4
+    0x0932 => { Name => 'EdgeMapX2',            Writable => 'int16u' }, #4
+    0x0933 => { #4
+        Name => 'KernelDenominators',
+        Writable => 'int16u',
+        Count => 3,
+    },
+    0x0934 => { Name => 'EdgeMapX3',            Writable => 'int16u' }, #4
+    0x0935 => { Name => 'EdgeMapX4',            Writable => 'int16u' }, #4
+    0x0936 => 'SharpenForThumbnail', #4
+    0x0937 => 'EdgeSpline', #4
+    0x0938 => 'DownSampleBy2Hor', #4 (int16s[4])
+    0x0939 => 'DownSampleBy2Ver', #4 (int16s[4])
+    0x093a => 'DownSampleBy4Hor', #4 (int16s[6])
+    0x093b => 'DownSampleBy4Ver', #4 (int16s[6])
+    0x093c => 'DownSampleBy3Hor', #4 (int16s[6])
+    0x093d => 'DownSampleBy3Ver', #4 (int16s[6])
+    0x093e => 'DownSampleBy6Hor', #4 (int16s[8])
+    0x093f => 'DownSampleBy6Ver', #4 (int16s[8])
+    0x0940 => 'DownSampleBy2Hor3MPdcr', #4
+    0x0941 => 'DownSampleBy2Ver3MPdcr', #4
+    0x0942 => 'ThumbnailResizeRatio', #4
+    0x0943 => { Name => 'AtCaptureUserCrop',    Writable => 'int32u', Count => 4 }, #4 (Top, Left, Bottom, Right)
+    0x0944 => { Name => 'ImageResolution',      Writable => 'int32u' }, #4 (Contains enum for imageDcrRes or imageJpegRes)
+    0x0945 => { Name => 'ImageResolutionJpg',   Writable => 'int32u' }, #4 (Contains enum for imageJpegRes)
+    0x094c => 'USMParametersLow', #4 (int16s[8])
+    0x094d => 'USMParametersMed', #4 (int16s[8])
+    0x094e => 'USMParametersHigh', #4 (int16s[8])
+    0x094f => 'USMParametersHost', #4 (int16s[10])
+    0x0950 => { Name => 'EdgeSplineLow', Binary => 1 }, #4 (rational64s[57])
+    0x0951 => { Name => 'EdgeSplineMed', Binary => 1 }, #4 (rational64s[69])
+    0x0952 => { Name => 'EdgeSplineHigh',Binary => 1 }, #4 (rational64s[69])
+    0x0953 => 'USMParametersHost6MP', #4 (int16s[10])
+    0x0954 => 'USMParametersHost3MP', #4 (int16s[10])
+    0x0960 => { Name => 'PatternImagerWidth',   Writable => 'int16u' }, #4
+    0x0961 => { Name => 'PatternImagerHeight',  Writable => 'int16u' }, #4
+    0x0962 => { Name => 'PatternAreaWidth',     Writable => 'int16u' }, #4
+    0x0963 => { Name => 'PatternAreaHeight',    Writable => 'int16u' }, #4
+    0x0964 => { Name => 'PatternCorrectionGains', Binary => 1 }, #4 (undef[48174])
+    0x0965 => 'PatternCorrectionOffsets', #4
+    0x0966 => { Name => 'PatternX',             Writable => 'int16u' }, #4
+    0x0967 => { Name => 'PatternY',             Writable => 'int16u' }, #4
+    0x0968 => { Name => 'PatternCorrectionFactors', Binary => 1 }, #4 (undef[48174])
+    0x0969 => { Name => 'PatternCorrectionFactorScale', Writable => 'int16u' }, #4
+    0x096a => { Name => 'PatternCropRows1',     Writable => 'int16u' }, #4
+    0x096b => { Name => 'PatternCropRows2',     Writable => 'int16u' }, #4
+    0x096c => { Name => 'PatternCropCols1',     Writable => 'int16u' }, #4
+    0x096d => { Name => 'PatternCropCols2',     Writable => 'int16u' }, #4
+    0x096e => 'PixelCorrectionGains', #4
+    0x096f => 'StitchRows', #4 (int16u[6])
+    0x0970 => 'StitchColumns', #4 (int16u)
+    0x0971 => { Name => 'PixelCorrectionScale', Writable => 'int16u' }, #4
+    0x0972 => { Name => 'PixelCorrectionOffset',Writable => 'int16u' }, #4
+    0x0988 => 'LensTableIndex', #4
+    0x0992 => 'DiffTileGains602832', #4
+    0x0993 => 'DiffTileGains24t852822', #4 (reserved tags 2450-2459)
+    0x099c => 'TileGainDeterminationTable', #4 (int16s[0])
+    0x099d => 'NemoBlurKernel', #4 (int16s[14])
+    0x099e => 'NemoTileSize', #4 (int16u)
+    0x099f => 'NemoGainFactors', #4 (rational64s[4])
+    0x09a0 => 'NemoDarkLimit', #4 (int16u)
+    0x09a1 => 'NemoHighlight12Limit', #4
+    0x09c4 => { Name => 'ImagerFileProductionLevel',Writable => 'int16u' }, #4
+    0x09c5 => { Name => 'ImagerFileDateCreated',    Writable => 'int32u' }, #4 (unknown encoding - PH)
+    0x09c6 => { Name => 'CalibrationVersion',       Writable => 'string' }, #4
+    0x09c7 => { Name => 'ImagerFileTagsVersionStandard', Writable => 'int16u' }, #4
+    0x09c8 => { Name => 'IFCameraModel',            Writable => 'string' }, #4
+    0x09c9 => { Name => 'CalibrationHistory',       Writable => 'string' }, #4
+    0x09ca => { Name => 'CalibrationLog',           Binary => 1 }, #4 (undef[1140])
+    0x09ce => { Name => 'SensorSerialNumber', Writable => 'string', Groups => { 2 => 'Camera' } }, #IB/4
+    0x09f6 => 'DefectConcealArtCorrectThres', #4 (no longer used)
+    0x09f7 => 'SglColDCACThres1', #4
+    0x09f8 => 'SglColDCACThres2', #4
+    0x09f9 => 'SglColDCACTHres3', #4
+    0x0a01 => 'DblColDCACThres1', #4
+    0x0a02 => 'DblColDCACThres2', #4
+    0x0a0a => { Name => 'DefectConcealThresTable',  Binary => 1 }, #4 (int16u[121/79])
+    0x0a28 => 'MonoUniqueMatrix', #4
+    0x0a29 => 'MonoMonitorMatrix', #4
+    0x0a2a => 'MonoToneScaleTable', #4
+    # 0x0a32-0x0a3b "OmenInitialSurfaceRed(n)", ref 4
+    # 0x0a3c-0x0a45 "OmenInitialSurfaceGoR(n)", ref 4
+    # 0x0a46-0x0a4f "OmenInitialSurfaceBlue(n)", ref 4
+    # 0x0a50-0x0a59 "OmenInitialSurfaceGoB(n)", ref 4
+    0x0a5a => 'OmenInitialScaling', #4
+    0x0a5b => 'OmenInitialRows', #4
+    0x0a5c => 'OmenInitialColumns', #4
+    0x0a5d => { Name => 'OmenInitialIPFStrength',Writable => 'int32s', Count => 4 }, #4
+    0x0a5e => { Name => 'OmenEarlyStrength',     Writable => 'int32s', Count => 4 }, #4
+    0x0a5f => { Name => 'OmenAutoStrength',      Writable => 'int32s', Count => 4 }, #4
+    0x0a60 => { Name => 'OmenAtCaptureStrength', Writable => 'int32s', Count => 4 }, #4
+    0x0a61 => 'OmenAtCaptureMode', #4
+    0x0a62 => { Name => 'OmenFocalLengthLimit',  Writable => 'int16s' }, #4
+    0x0a64 => { Name => 'OmenSurfaceIndex',      Writable => 'int16s' }, #4 (which InitialSurface to use)
+    0x0a65 => 'OmenPercentToRationalLimitsRed', #4 (signed rationals for 0 and 100)
+    0x0a66 => 'OmenPercentToRationalLimitsGoR', #4 (signed rationals for 0 and 100)
+    0x0a67 => 'OmenPercentToRationalLimitsBlue', #4 (signed rationals for 0 and 100)
+    0x0a68 => 'OmenPercentToRationalLimitsGoB', #4 (signed rationals for 0 and 100)
+    0x0a6e => 'OmenEarlyGoBSurface', #4
+    0x0a6f => 'OmenEarlyGoBRows', #4
+    0x0a70 => 'OmenEarlyGoBColumns', #4
+    0x0a73 => 'OmenSmoothingKernel', #4
+    0x0a74 => 'OmenGradientOffset', #4
+    0x0a75 => 'OmenGradientKernel', #4
+    0x0a76 => 'OmenGradientKernelTaps', #4
+    0x0a77 => 'OmenRatioClipFactors', #4
+    0x0a78 => 'OmenRatioExclusionFactors', #4
+    0x0a79 => 'OmenGradientExclusionLimits', #4
+    0x0a7a => 'OmenROICoordinates', #4
+    0x0a7b => 'OmenROICoefficients', #4
+    0x0a7c => 'OmenRangeWeighting', #4
+    0x0a7d => 'OmenMeanToStrength', #4
+    0x0bb8 => 'FactoryWhiteGainsDaylight', #4
+    0x0bb9 => 'FactoryWhiteOffsetsDaylight', #4
+    0x0bba => 'DacGainsCoarse', #4
+    0x0bbb => 'DacGainsFine', #4
+    0x0bbc => 'DigitalExposureGains', #4
+    0x0bbd => 'DigitalExposureBiases', #4
+    0x0bbe => 'BlackClamp', #4
+    0x0bbf => 'ChannelCoarseGainAdjust', #4
+    0x0bc0 => 'BlackClampOffset', #4
+    0x0bf4 => 'DMPixelThresholdFactor', #4 (TIFF_RATIONAL)
+    0x0bf5 => 'DMWindowThresholdFactor', #4 (TIFF_RATIONAL)
+    0x0bf6 => 'DMTrimFraction', #4 (TIFF_RATIONAL)
+    0x0bf7 => 'DMSmoothRejThresh', #4 (TIFF_RATIONAL)
+    0x0bf8 => 'DMFillRejThresh', #4 (TIFF_RATIONAL)
+    0x0bf9 => 'VMWsize', #4 (TIFF_SHORT)
+    0x0bfa => 'DMErodeRadius', #4 (TIFF_SHORT)
+    0x0bfb => 'DMNumPatches', #4 (TIFF_SHORT)
+    0x0bfc => 'DMNoiseScale', #4 (TIFF_RATIONAL)
+    0x0bfe => 'BrightDefectThreshold', #4
+    0x0bff => 'BrightDefectIntegrationMS', #4
+    0x0c00 => 'BrightDefectIsoCode', #4
+    0x0c03 => 'TopDarkRow1', #4 (support 330 dark map generation algorithm)
+    0x0c04 => 'TopDarkRow2', #4 (these tags were 3175-3192 prior to 18Jan2001)
+    0x0c05 => 'BottomDarkRow1', #4
+    0x0c06 => 'BottomDarkRow2', #4
+    0x0c07 => 'LeftDarkCol1', #4
+    0x0c08 => 'LeftDarkCol2', #4
+    0x0c09 => 'RightDarkCol1', #4
+    0x0c0a => 'RightDarkCol2', #4
+    0x0c0b => 'HMPixThresh', #4
+    0x0c0c => 'HMColThresh', #4
+    0x0c0d => 'HMWsize', #4
+    0x0c0e => 'HMColRejThresh', #4
+    0x0c0f => 'VMPixThresh', #4
+    0x0c10 => 'VMColThresh', #4
+    0x0c11 => 'VMNbands', #4
+    0x0c12 => 'VMColDropThresh', #4
+    0x0c13 => 'VMPatchResLimit', #4
+    0x0c14 => 'MapScale', #4
+    0x0c1c => 'Klut', #4
+    0x0c1d => 'RimNonlinearity', #4 (Obsolete)
+    0x0c1e => 'InverseRimNonlinearity', #4 (Obsolete)
+    0x0c1f => 'RembrandtToneScale', #4 (Obsolete)
+    0x0c20 => 'RimToNifColorTransform', #4 (Obsolete)
+    0x0c21 => 'RimToNifScaleFactor', #4 (Obsolete)
+    0x0c22 => 'NifNonlinearity', #4 (Obsolete)
+    0x0c23 => 'SBALogTransform', #4 (Obsolete)
+    0x0c24 => 'InverseSBALogTransform', #4 (Obsolete)
+    0x0c25 => { Name => 'SBABlack',         Writable => 'int16u' }, #4
+    0x0c26 => { Name => 'SBAGray',          Writable => 'int16u' }, #4
+    0x0c27 => { Name => 'SBAWhite',         Writable => 'int16u' }, #4
+    0x0c28 => { Name => 'GaussianWeights',  Binary => 1 }, #4 (int16u[864])
+    0x0c29 => { Name => 'SfsBoundary',      Binary => 1 }, #4 (int16u[6561])
+    0x0c2a => 'CoringTableBest', #4 (Obsolete)
+    0x0c2b => 'CoringTableBetter', #4 (Obsolete)
+    0x0c2c => 'CoringTableGood', #4 (Obsolete)
+    0x0c2d => 'ExposureReferenceGain', #4 (Obsolete)
+    0x0c2e => 'ExposureReferenceOffset', #4 (Obsolete)
+    0x0c2f => 'SBARedBalanceLut', #4 (Obsolete)
+    0x0c30 => 'SBAGreenBalanceLut', #4 (Obsolete)
+    0x0c31 => 'SBABlueBalanceLut', #4 (Obsolete)
+    0x0c32 => { Name => 'SBANeutralBAL',        Writable => 'int32s' }, #4
+    0x0c33 => { Name => 'SBAGreenMagentaBAL',   Writable => 'int32s' }, #4
+    0x0c34 => { Name => 'SBAIlluminantBAL',     Writable => 'int32s' }, #4
+    0x0c35 => { Name => 'SBAAnalysisComplete',  Writable => 'int8u' }, #4
+    0x0c36 => 'JPEGQTableBest', #4
+    0x0c37 => 'JPEGQTableBetter', #4
+    0x0c38 => 'JPEGQTableGood', #4
+    0x0c39 => 'RembrandtPortraitToneScale', #4 (Obsolete)
+    0x0c3a => 'RembrandtConsumerToneScale', #4 (Obsolete)
+    0x0c3b => 'CFAGreenThreshold1', #4 (Now CFAGreenThreshold1H)
+    0x0c3c => 'CFAGreenThreshold2', #4 (Now CFAGreenThreshold2V)
+    0x0c3d => { Name => 'QTableLarge50Pct',     Binary => 1 }, #4 (undef[130])
+    0x0c3e => { Name => 'QTableLarge67Pct',     Binary => 1 }, #4 (undef[130])
+    0x0c3f => { Name => 'QTableLarge100Pct',    Binary => 1 }, #4 (undef[130])
+    0x0c40 => { Name => 'QTableMedium50Pct',    Binary => 1 }, #4 (undef[130])
+    0x0c41 => { Name => 'QTableMedium67Pct',    Binary => 1 }, #4 (undef[130])
+    0x0c42 => { Name => 'QTableMedium100Pct',   Binary => 1 }, #4 (undef[130])
+    0x0c43 => { Name => 'QTableSmall50Pct',     Binary => 1 }, #4 (undef[130])
+    0x0c44 => { Name => 'QTableSmall67Pct',     Binary => 1 }, #4 (undef[130])
+    0x0c45 => { Name => 'QTableSmall100Pct',    Binary => 1 }, #4 (undef[130])
+    0x0c46 => { Name => 'SBAHighGray',          Writable => 'int16u' }, #4
+    0x0c47 => { Name => 'SBALowGray',           Writable => 'int16u' }, #4
+    0x0c48 => { Name => 'CaptureLook',          Writable => 'int16u' }, #4 (was "ToneScaleFlag")
+    0x0c49 => { Name => 'SBAIllOffset',         Writable => 'int16s' }, #4
+    0x0c4a => { Name => 'SBAGmOffset',          Writable => 'int16s' }, #4
+    0x0c4b => 'NifNonlinearity12Bit', #4 (Obsolete)
+    0x0c4c => 'SharpeningOn', #4 (Obsolete)
+    0x0c4d => 'NifNonlinearity16Bit', #4 (Obsolete)
+    0x0c4e => 'RawHistogram', #4
+    0x0c4f => 'RawCFAComponentAverages', #4
+    0x0c50 => 'DisableFlagsPresent', #4
+    0x0c51 => 'DelayCols', #4
+    0x0c52 => 'DummyColsLeft', #4
+    0x0c53 => 'TrashColsRight', #4
+    0x0c54 => 'BlackColsRight', #4
+    0x0c55 => 'DummyColsRight', #4
+    0x0c56 => 'OverClockColsRight', #4
+    0x0c57 => 'UnusedBlackRowsTopOut', #4
+    0x0c58 => 'TrashRowsBottom', #4
+    0x0c59 => 'BlackRowsBottom', #4
+    0x0c5a => 'OverClockRowsBottom', #4
+    0x0c5b => 'BlackColsLeft', #4
+    0x0c5c => 'BlackRowsTop', #4
+    0x0c5d => 'PartialActiveColsLeft', #4
+    0x0c5e => 'PartialActiveColsRight', #4
+    0x0c5f => 'PartialActiveRowsTop', #4
+    0x0c60 => 'PartialActiveRowsBottom', #4
+    0x0c61 => { Name => 'ProcessBorderColsLeft',    Writable => 'int16u' }, #4
+    0x0c62 => { Name => 'ProcessBorderColsRight',   Writable => 'int16u' }, #4
+    0x0c63 => { Name => 'ProcessBorderRowsTop',     Writable => 'int16u' }, #4
+    0x0c64 => { Name => 'ProcessBorderRowsBottom',  Writable => 'int16u' }, #4
+    0x0c65 => 'ActiveCols', #4
+    0x0c66 => 'ActiveRows', #4
+    0x0c67 => 'FirstLines', #4
+    0x0c68 => 'UnusedBlackRowsTopIn', #4
+    0x0c69 => 'UnusedBlackRowsBottomIn', #4
+    0x0c6a => 'UnusedBlackRowsBottomOut', #4
+    0x0c6b => 'UnusedBlackColsLeftOut', #4
+    0x0c6c => 'UnusedBlackColsLeftIn', #4
+    0x0c6d => 'UnusedBlackColsRightIn', #4
+    0x0c6e => 'UnusedBlackColsRightOut', #4
+    0x0c6f => { Name => 'CFAOffsetRows',            Writable => 'int32u' }, #4
+    0x0c70 => { Name => 'ShiftCols',                Writable => 'int16s' }, #4
+    0x0c71 => { Name => 'CFAOffsetCols',            Writable => 'int32u' }, #4
+    0x0c76 => 'DarkMapScale', #4
+    0x0c77 => 'HMapHandling', #4
+    0x0c78 => 'VMapHandling', #4
+    0x0c79 => 'DarkThreshold', #4
+    0x0c7a => { Name => 'DMDitherMatrix',           Writable => 'int16u' }, #4
+    0x0c7b => { Name => 'DMDitherMatrixWidth',      Writable => 'int16u' }, #4
+    0x0c7c => { Name => 'DMDitherMatrixHeight',     Writable => 'int16u' }, #4
+    0x0c7d => { Name => 'MaxPixelValueThreshold',   Writable => 'int16u' }, #4
+    0x0c7e => { Name => 'HoleFillDeltaThreshold',   Writable => 'int16u' }, #4
+    0x0c7f => { Name => 'DarkPedestal',             Writable => 'int16u' }, #4
+    0x0c80 => { Name => 'ImageProcessingFileTagsVersionNumber', Writable => 'int16u' }, #4
+    0x0c81 => { Name => 'ImageProcessingFileDateCreated', Writable => 'string', Groups => { 2 => 'Time' } }, #4
+    0x0c82 => { Name => 'DoublingMicrovolts',       Writable => 'int32s' }, #4
+    0x0c83 => { #4
+        Name => 'DarkFrameShortExposure',
+        Writable => 'int32u',
+        ValueConv => '$val / 1e6', # (microseconds)
+        ValueConvInv => '$val * 1e6',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => '$val',
+    },
+    0x0c84 => { #4
+        Name => 'DarkFrameLongExposure',
+        Writable => 'int32u',
+        ValueConv => '$val / 1e6', # (microseconds)
+        ValueConvInv => '$val * 1e6',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => '$val',
+    },
+    0x0c85 => { Name => 'DarkFrameCountFactor',     Writable => 'rational64u' }, #4
+    0x0c88 => { Name => 'HoleFillDarkDeltaThreshold', Writable => 'int16u' }, #4
+    0x0c89 => 'FarkleWhiteThreshold', #4
+    0x0c8a => { Name => 'ColumnResetOffsets',       Binary => 1 }, #4 (int16u[3012])
+    0x0c8b => { Name => 'ColumnGainFactors',        Binary => 1 }, #4 (int16u[3012])
+    # 0x0c94-0x0c9d ColumnOffsets (int16u[3012]), ref 4
+    0x0c8c => 'Channel0LagKernel', #4
+    0x0c8d => 'Channel1LagKernel', #4
+    0x0c8e => 'Channel2LagKernel', #4
+    0x0c8f => 'Channel3LagKernel', #4
+    0x0c90 => 'BluegrassTable', #4
+    0x0c91 => 'BluegrassScale1', #4
+    0x0c92 => 'BluegrassScale2', #4
+    0x0ce4 => 'FinishedFileProcessingRequest', #4
+    0x0ce5 => { Name => 'FirmwareVersion',  Writable => 'string', Groups => { 2 => 'Camera' } }, # ("ProcessingSoftware", ref 4)
+    0x0ce6 => 'HostSoftwareExportVersion', #4 (ULONG only exists if made by host SW)
+    0x0ce7 => { #4
+        Name => 'HostSoftwareRendering',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Normal (sRGB)',
+            1 => 'Linear (camera RGB)',
+            2 => 'Pro Photo RGB',
+            3 => 'Unknown',
+            4 => 'Other Profile',
+        },
+    },
+    0x0dac => 'DCS3XXProcessingInfoIFD', #4 (Obsolete)
+    0x0dad => 'DCS3XXProcessingInfo', #4 (Obsolete)
+    0x0dae => { Name => 'IPAVersion',       Writable => 'int32u' }, #4
+    0x0db6 => 'FinishIPAVersion', #4
+    0x0db7 => 'FinishIPFVersion', #4
+    0x0db8 => { #4
+        Name => 'FinishFileType',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'JPEG Best',
+            1 => 'JPEG Better',
+            2 => 'JPEG Good',
+            3 => 'TIFF RGB',
+        },
+    },
+    0x0db9 => { #4
+        Name => 'FinishResolution',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => '100%',
+            1 => '67%',
+            2 => '50%',
+            3 => '25%',
+        },
+    },
+    0x0dba => { #4
+        Name => 'FinishNoise',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Strong',
+            2 => 'Low',
+        },
+    },
+    0x0dbb => { #4
+        Name => 'FinishSharpening',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'None',
+            1 => 'High',
+            2 => 'Medium',
+            3 => 'Low',
+        },
+    },
+    0x0dbc => { #4
+        Name => 'FinishLook',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Product',
+            1 => 'Portrait',
+            2 => 'Product Reduced',
+            3 => 'Portrait Reduced',
+            4 => 'Monochrome Product',
+            5 => 'Monochrome Portrait',
+            6 => 'Wedding',
+            7 => 'Event',
+            8 => 'Product Hi Color',
+            9 => 'Portrait Hi Color',
+            # (past this is not yet implemented)
+            10 => 'Product Hi Color Hold',
+            11 => 'Portrait Hi Color Hold',
+            13 => 'DCS BW Normal',
+            14 => 'DCS BW Wratten 8',
+            15 => 'DCS BW Wratten 25',
+            16 => 'DCS Sepia 1',
+            17 => 'DCS Sepia 2',
+        },
+    },
+    0x0dbd => { #4
+        Name => 'FinishExposure',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'Yes', 1 => 'No' },
+    },
+    0x0e0b => { Name => 'SigmaScalingFactorLowRes', Writable => 'rational64u' }, #4 (for scaling sigma tables in-camera)
+    0x0e0c => { Name => 'SigmaScalingFactorCamera', Writable => 'rational64u' }, #4 (for scaling sigma tables in-camera)
+    0x0e0d => { Name => 'SigmaImpulseParameters',   Writable => 'int16u', Count => -1 }, #4 (for impulse reduction control)
+    0x0e0e => { Name => 'SigmaNoiseThreshTableV2',  Binary => 1 }, #4 (replaces V2 caltable)
+    0x0e0f => { Name => 'SigmaSizeTable',           Writable => 'int16u', Count => -1 }, #4
+    0x0e10 => 'DacGainsCoarseAdjPreIF41', #4 (Tag not used due to abandoned implementation)
+    0x0e11 => { Name => 'SigmaNoiseFilterCalTableV1', Binary => 1 }, #4 (undef[418]) (Defines Version 1 of Sigma Noise Filter table within .IF/.IPF)
+    0x0e12 => { Name => 'SigmaNoiseFilterTableV1',  Binary => 1}, #4 (Defines Version 1 of Sigma Noise Filter table within image)
+    0x0e13 => 'Lin12ToKlut8', #4
+    0x0e14 => 'SigmaNoiseFilterTableV1Version', #4 (int16u/int32u) (This tag describes the version level of the SigmaNoiseFilterTableV1 class of tags)
+    0x0e15 => 'Lin12ToKlut12', #4
+    0x0e16 => 'Klut12ToLin12', #4
+    0x0e17 => { Name => 'NifNonlinearity12To16',    Binary => 1 }, #4 (int16u[4096])
+    0x0e18 => { Name => 'SBALog12Transform',        Binary => 1 }, #4 (int16u[4096])
+    0x0e19 => { Name => 'InverseSBALog12Transform', Binary=> 1 }, #4 (int16u[3613])
+    0x0e1a => { Name => 'ToneScale0',   Binary => 1 }, #4 (int16u[4096]) (Was Portrait12ToneScale on DCS3XX 1.3.1)
+    0x0e1b => { Name => 'ToneScale1',   Binary => 1 }, #4 (int16u[4096]) (Was Consumer12ToneScale on DCS3XX 1.3.1)
+    0x0e1c => { Name => 'ToneScale2',   Binary => 1 }, #4 (int16u[4096])
+    0x0e1d => { Name => 'ToneScale3',   Binary => 1 }, #4 (int16u[4096])
+    0x0e1e => { Name => 'ToneScale4',   Binary => 1 }, #4 (int16u[4096])
+    0x0e1f => { Name => 'ToneScale5',   Binary => 1 }, #4 (int16u[4096])
+    0x0e20 => { Name => 'ToneScale6',   Binary => 1 }, #4 (int16u[4096])
+    0x0e21 => { Name => 'ToneScale7',   Binary => 1 }, #4 (int16u[4096])
+    0x0e22 => { Name => 'ToneScale8',   Binary => 1 }, #4 (int16u[4096])
+    0x0e23 => { Name => 'ToneScale9',   Binary => 1 }, #4 (int16u[4096])
+    0x0e24 => 'DayMat0', #4 (Obsolete)
+    0x0e25 => 'DayMat1', #4 (Obsolete)
+    0x0e26 => 'DayMat2', #4 (Obsolete)
+    0x0e27 => 'DayMat3', #4 (Obsolete)
+    0x0e28 => 'DayMat4', #4 (Obsolete)
+    0x0e29 => 'DayMat5', #4 (Obsolete)
+    0x0e2a => 'DayMat6', #4 (Obsolete)
+    0x0e2b => 'DayMat7', #4 (Obsolete)
+    0x0e2c => 'DayMat8', #4 (Obsolete)
+    0x0e2d => 'DayMat9', #4 (Obsolete)
+    0x0e2e => 'TungMat0', #4 (Obsolete)
+    0x0e2f => 'TungMat1', #4 (Obsolete)
+    0x0e30 => 'TungMat2', #4 (Obsolete)
+    0x0e31 => 'TungMat3', #4 (Obsolete)
+    0x0e32 => 'TungMat4', #4 (Obsolete)
+    0x0e33 => 'TungMat5', #4 (Obsolete)
+    0x0e34 => 'TungMat6', #4 (Obsolete)
+    0x0e35 => 'TungMat7', #4 (Obsolete)
+    0x0e36 => 'TungMat8', #4 (Obsolete)
+    0x0e37 => 'TungMat9', #4 (Obsolete)
+    0x0e38 => 'FluorMat0', #4 (Obsolete)
+    0x0e39 => 'FluorMat1', #4 (Obsolete)
+    0x0e3a => 'FluorMat2', #4 (Obsolete)
+    0x0e3b => 'FluorMat3', #4 (Obsolete)
+    0x0e3c => 'FluorMat4', #4 (Obsolete)
+    0x0e3d => 'FluorMat5', #4 (Obsolete)
+    0x0e3e => 'FluorMat6', #4 (Obsolete)
+    0x0e3f => 'FluorMat7', #4 (Obsolete)
+    0x0e40 => 'FluorMat8', #4 (Obsolete)
+    0x0e41 => 'FluorMat9', #4 (Obsolete)
+    0x0e42 => 'FlashMat0', #4 (Obsolete)
+    0x0e43 => 'FlashMat1', #4 (Obsolete)
+    0x0e44 => 'FlashMat2', #4 (Obsolete)
+    0x0e45 => 'FlashMat3', #4 (Obsolete)
+    0x0e46 => 'FlashMat4', #4 (Obsolete)
+    0x0e47 => 'FlashMat5', #4 (Obsolete)
+    0x0e48 => 'FlashMat6', #4 (Obsolete)
+    0x0e49 => 'FlashMat7', #4 (Obsolete)
+    0x0e4a => 'FlashMat8', #4 (Obsolete)
+    0x0e4b => 'FlashMat9', #4 (Obsolete)
+    0x0e4c => { #IB
+        Name => 'KodakLook', # ("LookNameTable", ref 4)
+        Format => 'undef',
+        Writable => 'string',
+        ValueConv => '$val=~tr/\0/\n/; $val',
+        ValueConvInv => '$val=~tr/\n/\0/; $val',
+    },
+    0x0e4d => { Name => 'IPFCameraModel',   Writable => 'string' }, #4
+    0x0e4e => { Name => 'AH2GreenInterpolationThreshold',   Writable => 'int16u' }, #4
+    0x0e4f => { Name => 'ResamplingKernelDenominators067',  Writable => 'int16u', Count => 3 }, #4 (table of sharpening denoms; 0=Low, 1=Medium, 2=High)
+    0x0e50 => { Name => 'ResamplingKernelDenominators050',  Writable => 'int16u', Count => 3 }, #4 (table of sharpening denoms; 0=Low, 1=Medium, 2=High)
+    0x0e51 => { Name => 'ResamplingKernelDenominators100',  Writable => 'int16u', Count => 3 }, #4 (table of sharpening denoms; 0=Low, 1=Medium, 2=High)
+    0x0e56 => 'LookMat0', #4 (rational64s[9])
+    0x0e57 => 'LookMat1', #4 (rational64s[9])
+    0x0e58 => 'LookMat2', #4 (rational64s[9])
+    0x0e59 => 'LookMat3', #4 (rational64s[9])
+    0x0e5a => 'LookMat4', #4 (rational64s[9])
+    0x0e5b => 'LookMat5', #4 (rational64s[9])
+    0x0e5c => 'LookMat6', #4 (rational64s[9])
+    0x0e5d => 'LookMat7', #4 (rational64s[9])
+    0x0e5e => 'LookMat8', #4 (rational64s[9])
+    0x0e5f => 'LookMat9', #4 (rational64s[9])
+    0x0e60 => { #4
+        Name => 'CFAInterpolationAlgorithm',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'AH2', 1 => 'Karnak' },
+    },
+    0x0e61 => { #4
+        Name => 'CFAInterpolationMetric',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Linear12', 1 => 'KLUT12' },
+    },
+    0x0e62 => { Name => 'CFAZipperFixThreshold',            Writable => 'int16u' }, #4
+    0x0e63 => { Name => 'NoiseReductionParametersKhufuRGB', Writable => 'int16u', Count => 9 }, #4
+    0x0e64 => { Name => 'NoiseReductionParametersKhufu6MP', Writable => 'int16u', Count => 9 }, #4
+    0x0e65 => { Name => 'NoiseReductionParametersKhufu3MP', Writable => 'int16u', Count => 9 }, #4
+    0x0e6a => { Name => 'ChromaNoiseHighFThresh',           Writable => 'int32u', Count => 2 }, #4
+    0x0e6b => { Name => 'ChromaNoiseLowFThresh',            Writable => 'int32u', Count => 2 }, #4
+    0x0e6c => { Name => 'ChromaNoiseEdgeMapThresh',         Writable => 'int32u' }, #4
+    0x0e6d => { Name => 'ChromaNoiseColorSpace',            Writable => 'int32u' }, #4
+    0x0e6e => { Name => 'EnableChromaNoiseReduction',       Writable => 'int16u' }, #4
+    # 9 values for noise reduction parameters:
+    #  0 - NRLowType
+    #  1 - NRLowRadius
+    #  2 - NRLowStrength
+    #  3 - NRMediumType
+    #  4 - NRMediumRadius
+    #  5 - NRMediumStrength
+    #  6 - NRHighType
+    #  7 - NRHighRadius
+    #  8 - NRHighStrength
+    # NRType values:
+    #  0 = None
+    #  1 = SigmaChroma
+    #  2 = SigmaOnly
+    #  3 = SigmaMoire
+    #  4 = SigmaChromaWithRadius
+    #  5 = SigmaMoireWithRadius
+    #  6 = SigmaExpert (aka Khufu)
+    #  7 = SigmaWithRadius
+    0x0e6f => { Name => 'NoiseReductionParametersHostRGB',  Writable => 'int16u', Count => 9 }, #4
+    0x0e70 => { Name => 'NoiseReductionParametersHost6MP',  Writable => 'int16u', Count => 9 }, #4
+    0x0e71 => { Name => 'NoiseReductionParametersHost3MP',  Writable => 'int16u', Count => 9 }, #4
+    0x0e72 => { Name => 'NoiseReductionParametersCamera',   Writable => 'int16u', Count => 6 }, #4
+    0x0e73 => { #4
+        Name => 'NoiseReductionParametersAtCapture',
+        Writable => 'int16u',
+        Count => 6,
+        # 6 values:
+        #  0 - Algorithm type
+        #  1 - Radius
+        #  2 - Strength
+        #  3 - Khufu Luma
+        #  4 - Reserved 1
+        #  5 - Reserved 2
+    },
+    0x0e74 => { Name => 'LCDMatrix',            Writable => 'rational64s', Count => 9 }, #4
+    0x0e75 => { Name => 'LCDMatrixChickFix',    Writable => 'rational64s', Count => 9 }, #4
+    0x0e76 => { Name => 'LCDMatrixMarvin',      Writable => 'rational64s', Count => 9 }, #4
+    0x0e7c => { Name => 'LCDGammaTableChickFix',Binary => 1 }, #4 (int16u[4096])
+    0x0e7d => { Name => 'LCDGammaTableMarvin',  Binary => 1 }, #4 (int16u[4096])
+    0x0e7e => { Name => 'LCDGammaTable',        Binary => 1 }, #4 (int16u[4096])
+    0x0e7f => 'LCDSharpeningF1', #4 (int16s[4])
+    0x0e80 => 'LCDSharpeningF2', #4
+    0x0e81 => 'LCDSharpeningF3', #4
+    0x0e82 => 'LCDSharpeningF4', #4
+    0x0e83 => 'LCDEdgeMapX1', #4
+    0x0e84 => 'LCDEdgeMapX2', #4
+    0x0e85 => 'LCDEdgeMapX3', #4
+    0x0e86 => 'LCDEdgeMapX4', #4
+    0x0e87 => 'LCDEdgeMapSlope', #4
+    0x0e88 => 'YCrCbMatrix', #4
+    0x0e89 => 'LCDEdgeSpline', #4 (rational64s[9])
+    0x0e92 => { Name => 'Fac18Per',     Writable => 'int16u' }, #4
+    0x0e93 => { Name => 'Fac170Per',    Writable => 'int16u' }, #4
+    0x0e94 => { Name => 'Fac100Per',    Writable => 'int16u' }, #4
+    0x0e9b => 'ExtraTickLocations', #4 (int16u[7])
+    0x0e9c => { Name => 'RGBtoeV0',     Binary => 1 }, #4 (int16s[256])
+    0x0e9d => { Name => 'RGBtoeV1',     Binary => 1 }, #4 (int16s[256])
+    0x0e9e => { Name => 'RGBtoeV2',     Binary => 1 }, #4 (int16s[256])
+    0x0e9f => { Name => 'RGBtoeV3',     Binary => 1 }, #4 (int16s[256])
+    0x0ea0 => { Name => 'RGBtoeV4',     Binary => 1 }, #4 (int16s[256])
+    0x0ea1 => { Name => 'RGBtoeV5',     Binary => 1 }, #4 (int16s[256])
+    0x0ea2 => { Name => 'RGBtoeV6',     Binary => 1 }, #4 (int16s[256])
+    0x0ea3 => { Name => 'RGBtoeV7',     Binary => 1 }, #4 (int16s[256])
+    0x0ea4 => { Name => 'RGBtoeV8',     Binary => 1 }, #4 (int16s[256])
+    0x0ea5 => { Name => 'RGBtoeV9',     Binary => 1 }, #4 (int16s[256])
+    0x0ea6 => { Name => 'LCDHistLUT0',  Binary => 1 }, #4 (rational64s[48])
+    0x0ea7 => { Name => 'LCDHistLUT1',  Binary => 1 }, #4 (rational64s[57])
+    0x0ea8 => { Name => 'LCDHistLUT2',  Binary => 1 }, #4 (rational64s[48])
+    0x0ea9 => { Name => 'LCDHistLUT3',  Binary => 1 }, #4 (rational64s[57])
+    0x0eaa => { Name => 'LCDHistLUT4',  Binary => 1 }, #4 (rational64s[48])
+    0x0eab => { Name => 'LCDHistLUT5',  Binary => 1 }, #4 (rational64s[57])
+    0x0eac => { Name => 'LCDHistLUT6',  Binary => 1 }, #4 (rational64s[48])
+    0x0ead => { Name => 'LCDHistLUT7',  Binary => 1 }, #4 (rational64s[48])
+    0x0eae => { Name => 'LCDHistLUT8',  Binary => 1 }, #4
+    0x0eaf => { Name => 'LCDHistLUT9',  Binary => 1 }, #4
+    0x0eb0 => 'LCDLinearClipValue', #4
+    0x0ece => 'LCDStepYvalues', #4 (int8u[10])
+    0x0ecf => 'LCDStepYvaluesChickFix', #4 (int8u[10])
+    0x0ed0 => 'LCDStepYvaluesMarvin', #4 (int8u[10])
+    0x0ed8 => { Name => 'InterpolationCoefficients', Binary => 1 }, #4 (int16s[69])
+    0x0ed9 => 'InterpolationCoefficients6MP', #4
+    0x0eda => 'InterpolationCoefficients3MP', #4
+    0x0f00 => { Name => 'NoiseReductionParametersHostNormal',  Binary => 1 }, #4 (int16u[140])
+    0x0f01 => { Name => 'NoiseReductionParametersHostStrong',  Binary => 1 }, #4 (int16u[140])
+    0x0f02 => { Name => 'NoiseReductionParametersHostLow',  Binary => 1 }, #4
+    0x0f0a => { Name => 'MariahTextureThreshold',   Writable => 'int16u' }, #4
+    0x0f0b => { Name => 'MariahMapLoThreshold',     Writable => 'int16u' }, #4
+    0x0f0c => { Name => 'MariahMapHiThreshold',     Writable => 'int16u' }, #4
+    0x0f0d => { Name => 'MariahChromaBlurSize',     Writable => 'int16u' }, #4
+    0x0f0e => { Name => 'MariahSigmaThreshold',     Writable => 'int16u' }, #4
+    0x0f0f => { Name => 'MariahThresholds',         Binary => 1 }, #4
+    0x0f10 => { Name => 'MariahThresholdsNormal',   Binary => 1 }, #4 (int16u[140])
+    0x0f11 => { Name => 'MariahThresholdsStrong',   Binary => 1 }, #4 (int16u[140])
+    0x0f12 => { Name => 'MariahThresholdsLow',      Binary => 1 }, #4
+    0x0f14 => 'KhufuLinearRedMixingCoefficient', #4
+    0x0f15 => 'KhufuLinearGreenMixingCoefficient', #4
+    0x0f16 => 'KhufuLinearBlueMixingCoefficient', #4
+    0x0f17 => 'KhufuUSpaceC2MixingCoefficient', #4
+    0x0f18 => 'KhufuSigmaGaussianWeights', #4
+    0x0f19 => 'KhufuSigmaScalingFactors6MP', #4 (rational64u[6])
+    0x0f1a => 'KhufuSigmaScalingFactors3MP', #4 (rational64u[6])
+    0x0f1b => 'KhufuSigmaScalingFactors14MP', #4
+    # 0x0f1e-0x0f27 - KhufuLinearRGBtoLogRGB(n), (for Khufu) ref 4
+    # 0x0f28-0x0f31 - KhufuLogRGBtoLinearRGB(n), (for Khufu) ref 4
+    0x0f32 => { Name => 'KhufuI0Thresholds',    Binary => 1 }, #4 (int32s[348])
+    0x0f33 => { Name => 'KhufuI1Thresholds',    Binary => 1 }, #4 (int32s[348])
+    0x0f34 => { Name => 'KhufuI2Thresholds',    Binary => 1 }, #4 (int32s[348])
+    0x0f35 => { Name => 'KhufuI3Thresholds',    Binary => 1 }, #4 (int32s[348])
+    0x0f36 => { Name => 'KhufuI4Thresholds',    Binary => 1 }, #4 (int32s[348])
+    0x0f37 => { Name => 'KhufuI5Thresholds',    Binary => 1 }, #4 (int32s[348])
+    0x0f3c => { Name => 'CondadoDayBVThresh',   Writable => 'int16u' }, #4
+    0x0f3d => { Name => 'CondadoNeuRange',      Writable => 'int16u' }, #4
+    0x0f3e => { Name => 'CondadoBVFactor',      Writable => 'int16s' }, #4
+    0x0f3f => { Name => 'CondadoIllFactor',     Writable => 'int16s' }, #4
+    0x0f40 => { Name => 'CondadoTunThresh',     Writable => 'int16s' }, #4
+    0x0f41 => { Name => 'CondadoFluThresh',     Writable => 'int16s' }, #4
+    0x0f42 => { Name => 'CondadoDayOffsets',    Writable => 'int16s', Count => 2 }, #4
+    0x0f43 => { Name => 'CondadoTunOffsets',    Writable => 'int16s', Count => 2 }, #4
+    0x0f44 => { Name => 'CondadoFluOffsets',    Writable => 'int16s', Count => 2 }, #4
+    0x0f5a => 'ERIMMToCRGB0Spline', #4 (rational64s[33])
+    0x0f5b => 'ERIMMToCRGB1Spline', #4 (rational64s[36])
+    0x0f5c => 'ERIMMToCRGB2Spline', #4 (rational64s[33])
+    0x0f5d => 'ERIMMToCRGB3Spline', #4 (rational64s[33])
+    0x0f5e => 'ERIMMToCRGB4Spline', #4 (rational64s[33])
+    0x0f5f => 'ERIMMToCRGB5Spline', #4 (rational64s[33])
+    0x0f60 => 'ERIMMToCRGB6Spline', #4 (rational64s[33])
+    0x0f61 => 'ERIMMToCRGB7Spline', #4 (rational64s[33])
+    0x0f62 => 'ERIMMToCRGB8Spline', #4
+    0x0f63 => 'ERIMMToCRGB9Spline', #4
+    0x0f64 => 'CRGBToERIMM0Spline', #4 (rational64s[27])
+    0x0f65 => 'CRGBToERIMM1Spline', #4 (rational64s[54])
+    0x0f66 => 'CRGBToERIMM2Spline', #4 (rational64s[27])
+    0x0f67 => 'CRGBToERIMM3Spline', #4 (rational64s[54])
+    0x0f68 => 'CRGBToERIMM4Spline', #4 (rational64s[27])
+    0x0f69 => 'CRGBToERIMM5Spline', #4 (rational64s[54])
+    0x0f6a => 'CRGBToERIMM6Spline', #4 (rational64s[27])
+    0x0f6b => 'CRGBToERIMM7Spline', #4 (rational64s[27])
+    0x0f6c => 'CRGBToERIMM8Spline', #4
+    0x0f6d => 'CRGBToERIMM9Spline', #4
+    0x0f6e => 'ERIMMNonLinearitySpline', #4 (rational64s[42])
+    0x0f6f => 'Delta12To8Spline', #4 (rational64s[12])
+    0x0f70 => 'Delta8To12Spline', #4 (rational64s[12])
+    0x0f71 => 'InverseMonitorMatrix', #4 (rational64s[9])
+    0x0f72 => { Name => 'NifNonlinearityExt', Binary => 1 }, #4 (int16s[8000])
+    0x0f73 => { Name => 'InvNifNonLinearity', Binary => 1 }, #4 (int16u[256])
+    0x0f74 => 'RIMM13ToERIMM12Spline', #4 (rational64s[51])
+    0x0f78 => 'ToneScale0Spline', #4 (rational64s[57])
+    0x0f79 => 'ToneScale1Spline', #4 (rational64s[51])
+    0x0f7a => 'ToneScale2Spline', #4 (rational64s[57])
+    0x0f7b => 'ToneScale3Spline', #4 (rational64s[51])
+    0x0f7c => 'ToneScale4Spline', #4 (rational64s[57])
+    0x0f7d => 'ToneScale5Spline', #4 (rational64s[51])
+    0x0f7e => 'ToneScale6Spline', #4 (rational64s[57])
+    0x0f7f => 'ToneScale7Spline', #4 (rational64s[57])
+    0x0f80 => 'ToneScale8Spline', #4
+    0x0f81 => 'ToneScale9Spline', #4
+    0x0f82 => 'ERIMMToneScale0Spline', #4 (rational64s[60])
+    0x0f83 => 'ERIMMToneScale1Spline', #4 (rational64s[54])
+    0x0f84 => 'ERIMMToneScale2Spline', #4 (rational64s[60])
+    0x0f85 => 'ERIMMToneScale3Spline', #4 (rational64s[54])
+    0x0f86 => 'ERIMMToneScale4Spline', #4 (rational64s[60])
+    0x0f87 => 'ERIMMToneScale5Spline', #4 (rational64s[54])
+    0x0f88 => 'ERIMMToneScale6Spline', #4 (rational64s[60])
+    0x0f89 => 'ERIMMToneScale7Spline', #4 (rational64s[60])
+    0x0f8a => 'ERIMMToneScale8Spline', #4
+    0x0f8b => 'ERIMMToneScale9Spline', #4
+    0x0f8c => 'RIMMToCRGB0Spline', #4 (rational64s[66])
+    0x0f8d => 'RIMMToCRGB1Spline', #4 (rational64s[84])
+    0x0f8e => 'RIMMToCRGB2Spline', #4 (rational64s[66])
+    0x0f8f => 'RIMMToCRGB3Spline', #4 (rational64s[84])
+    0x0f90 => 'RIMMToCRGB4Spline', #4 (rational64s[66])
+    0x0f91 => 'RIMMToCRGB5Spline', #4 (rational64s[84])
+    0x0f92 => 'RIMMToCRGB6Spline', #4 (rational64s[66])
+    0x0f93 => 'RIMMToCRGB7Spline', #4 (rational64s[66])
+    0x0f94 => 'RIMMToCRGB8Spline', #4
+    0x0f95 => 'RIMMToCRGB9Spline', #4
+    0x0fa0 => 'QTableLarge25Pct', #4
+    0x0fa1 => 'QTableMedium25Pct', #4
+    0x0fa2 => 'QTableSmall25Pct', #4
+    0x1130 => 'NoiseReductionKernel', #4 (Noise filter kernel.  No longer needed)
+    0x1388 => 'UserMetaData', #4 (undef[0])
+    0x1389 => { Name => 'InputProfile',     Writable => 'undef', Binary => 1 }, #IB ("SourceProfile", ref 4)
+    0x138a => { Name => 'KodakLookProfile', Writable => 'undef', Binary => 1 }, #IB ("LookProfile", ref 4)
+    0x138b => { Name => 'OutputProfile',    Writable => 'undef', Binary => 1 }, #IB ("DestinationProfile", ref 4)
+    0x1390 => { Name => 'SourceProfilePrefix',  Writable => 'string' }, #4 (eg. 'DCSProSLRn')
+    0x1391 => { Name => 'ToneCurveProfileName', Writable => 'string' }, #4
+    0x1392 => { Name => 'InputProfile', SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' } }, #4
+    0x1393 => { Name => 'ProcessParametersV2',  Binary => 1 }, #4 (Used by the SDK, Firmware should not use!)
+    0x1394 => 'ReservedBlob2', #4
+    0x1395 => 'ReservedBlob3', #4
+    0x1396 => 'ReservedBlob4', #4
+    0x1397 => 'ReservedBlob5', #4
+    0x1398 => 'ReservedBlob6', #4
+    0x1399 => 'ReservedBlob7', #4
+    0x139a => 'ReservedBlob8', #4
+    0x139b => 'ReservedBlob9', #4
+    0x1770 => { Name => 'ScriptVersion',    Writable => 'int32u' }, #4
+    0x177a => 'ImagerTimingData', #4
+    0x1784 => { Name => 'ISO',              Writable => 'int32u' }, #3 ("NsecPerIcCode", ref 4)
+    0x17a2 => 'Scav11Cols', #4
+    0x17a3 => 'Scav12Cols', #4
+    0x17a4 => 'Scav21Cols', #4
+    0x17a5 => 'Scav22Cols', #4
+    0x17a6 => 'ActiveCTEMonitor1Cols', #4
+    0x17a7 => 'ActiveCTEMonitor2Cols', #4
+    0x17a8 => 'ActiveCTEMonitorRows', #4
+    0x17a9 => 'ActiveBuf1Cols', #4
+    0x17aa => 'ActiveBuf2Cols', #4
+    0x17ab => 'ActiveBuf1Rows', #4
+    0x17ac => 'ActiveBuf2Rows', #4
+    0x17c0 => 'HRNoiseLines', #4
+    0x17c1 => 'RNoiseLines', #4
+    0x17c2 => 'ANoiseLines', #4
+    0x17d4 => { Name => 'ImagerCols',   Writable => 'int16u' }, #4
+    0x17de => { Name => 'ImagerRows',   Writable => 'int16u' }, #4
+    0x17e8 => { Name => 'PartialActiveCols1',   Writable => 'int32u' }, #4
+    0x17f2 => { Name => 'PartialActiveCols2',   Writable => 'int32u' }, #4
+    0x17fc => { Name => 'PartialActiveRows1',   Writable => 'int32u' }, #4
+    0x1806 => { Name => 'PartialActiveRows2',   Writable => 'int32u' }, #4
+    0x1810 => { Name => 'ElectricalBlackColumns',Writable=> 'int32u' }, #4
+    0x181a => { Name => 'ResetBlackSegRows',    Writable => 'int32u' }, #4
+    0x1838 => { Name => 'CaptureWidthNormal',   Writable => 'int32u' }, #4
+    0x1839 => { Name => 'CaptureHeightNormal',  Writable => 'int32u' }, #4
+    0x183a => 'CaptureWidthResetBlackSegNormal', #4
+    0x183b => 'CaptureHeightResetBlackSegNormal', #4
+    0x183c => 'DarkRefOffsetNormal', #4
+    0x1842 => { Name => 'CaptureWidthTest',     Writable => 'int32u' }, #4
+    0x1843 => 'CaptureHeightTest', #4
+    0x1844 => 'CaptureWidthResetBlackSegTest', #4
+    0x1845 => 'CaptureHeightResetBlackSegTest', #4
+    0x1846 => 'DarkRefOffsetTest', #4
+    0x184c => { Name => 'ImageSegmentStartLine',Writable => 'int32u' }, #4
+    0x184d => { Name => 'ImageSegmentLines',    Writable => 'int32u' }, #4
+    0x184e => { Name => 'SkipLineTime',         Writable => 'int32u' }, #4
+    0x1860 => { Name => 'FastResetLineTime',    Writable => 'int32u' }, #4
+    0x186a => { Name => 'NormalLineTime',       Writable => 'int32u' }, #4
+    0x1874 => { Name => 'MinIntegrationRows',   Writable => 'int32u' }, #4
+    0x187e => { Name => 'PreReadFastResetCount',Writable => 'int32u' }, #4
+    0x1888 => { Name => 'TransferTimeNormal',   Writable => 'int32u' }, #4
+    0x1889 => { Name => 'TransferTimeTest',     Writable => 'int32u' }, #4
+    0x188a => { Name => 'QuietTime',            Writable => 'int32u' }, #4
+    0x189c => { Name => 'OverClockCols',        Writable => 'int16u' }, #4
+    0x18a6 => { Name => 'H2ResetBlackPixels',   Writable => 'int32u' }, #4
+    0x18b0 => { Name => 'H3ResetBlackPixels',   Writable => 'int32u' }, #4
+    0x18ba => { Name => 'BlackAcquireRows',     Writable => 'int32u' }, #4
+    0x18c4 => { Name => 'OverClockRows',        Writable => 'int16u' }, #4
+    0x18ce => { Name => 'H3ResetBlackColumns',  Writable => 'int32u' }, #4
+    0x18d8 => { Name => 'DarkBlackSegRows',     Writable => 'int32u' }, #4
+    0x1900 => 'CrossbarEnable', #4
+    0x1901 => { Name => 'FifoenOnePixelDelay',  Writable => 'int32u' }, #4
+    0x1902 => { Name => 'ReadoutTypeRequested', Writable => 'int32u' }, #4
+    0x1903 => { Name => 'ReadoutTypeActual',    Writable => 'int32u' }, #4
+    0x190a => { Name => 'OffsetDacValue',       Writable => 'int32u' }, #4
+    0x1914 => { Name => 'TempAmpGainX100',      Writable => 'int32u' }, #4
+    0x191e => { Name => 'VarrayDacNominalValues',Writable=> 'int32u', Count => 3 }, #4
+    0x1928 => 'VddimDacNominalValues', #4
+    0x1964 => { Name => 'C14Configuration',     Writable => 'int32u' }, #4
+    0x196e => { Name => 'TDA1Offset',           Writable => 'int32u', Count => 3 }, #4
+    0x196f => { Name => 'TDA1Bandwidth',        Writable => 'int32u' }, #4
+    0x1970 => { Name => 'TDA1Gain',             Writable => 'int32u', Count => 3 }, #4
+    0x1971 => { Name => 'TDA1EdgePolarity',     Writable => 'int32u' }, #4
+    0x1978 => { Name => 'TDA2Offset',           Writable => 'int32u', Count => 3 }, #4
+    0x1979 => { Name => 'TDA2Bandwidth',        Writable => 'int32u' }, #4
+    0x197a => { Name => 'TDA2Gain',             Writable => 'int32u', Count => 3 }, #4
+    0x197b => { Name => 'TDA2EdgePolarity',     Writable => 'int32u' }, #4
+    0x1982 => { Name => 'TDA3Offset',           Writable => 'int32u', Count => 3 }, #4
+    0x1983 => { Name => 'TDA3Bandwidth',        Writable => 'int32u' }, #4
+    0x1984 => { Name => 'TDA3Gain',             Writable => 'int32u', Count => 3 }, #4
+    0x1985 => { Name => 'TDA3EdgePolarity',     Writable => 'int32u' }, #4
+    0x198c => { Name => 'TDA4Offset',           Writable => 'int32u', Count => 3 }, #4
+    0x198d => { Name => 'TDA4Bandwidth',        Writable => 'int32u' }, #4
+    0x198e => { Name => 'TDA4Gain',             Writable => 'int32u', Count => 3 }, #4
+    0x198f => { Name => 'TDA4EdgePolarity',     Writable => 'int32u' }, #4
+    0xfde8 => { Name => 'ComLenBlkSize',        Writable => 'int16u' }, #4
 );
 
@@ -1444,4 +2644,5 @@
         Name => 'ExposureMode',
         PrintConv => {
+            OTHER => sub { shift }, # pass other values straight through
             'M' => 'Manual',
             'A' => 'Aperture Priority', #(NC -- I suppose this could be "Auto" too)
@@ -1450,4 +2651,5 @@
             'B' => 'Bulb', #(NC)
             # have seen "Manual (M)" written by DCS760C - PH
+            # and "Aperture priority AE (Av)" written by a ProBack 645M
         },
     },
@@ -1464,4 +2666,5 @@
     'ISO'           => 'ISO',
     'ISO Speed'     => 'ISO',
+    'Lens'          => { Name => 'Lens', Priority => 0 },
     'Max Aperture'  => {
         Name => 'MaxAperture',
@@ -1508,5 +2711,5 @@
         Name => 'CameraOwner',
         Writable => 'undef',
-        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,$tag)',
         RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
     },
@@ -1515,5 +2718,5 @@
         Writable => 'undef',
         Groups => { 2 => 'Camera' },
-        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)', #PH
+        RawConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,$tag)', #PH
         RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
     },
@@ -1543,4 +2746,5 @@
     0xc366 => 'EditTagArray',
     0xc367 => 'Magnification',
+    # 0xc36b - string[8]: "1.0"
     0xc36c => 'NativeXResolution',
     0xc36d => 'NativeYResolution',
@@ -1569,4 +2773,5 @@
     0xc46c => 'PrintQuality',
     0xc46e => 'ImagePrintStatus',
+    # 0cx46f - int16u: 1
 );
 
@@ -1578,5 +2783,5 @@
     1 => {
         Name => 'DigitalEffectsName',
-        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,"DigitalEffectsName")',
     },
     2 => 'DigitalEffectsType',
@@ -1590,5 +2795,5 @@
     1 => {
         Name => 'BorderName',
-        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,"BorderName")',
     },
     2 => 'BorderID',
@@ -1604,5 +2809,8 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     FIRST_ENTRY => 0,
-    NOTES => 'This information is found in Kodak MOV videos from models such as the P880.',
+    NOTES => q{
+        This information is found in the TAGS atom of MOV videos from Kodak models
+        such as the P880.
+    },
     0 => {
         Name => 'Make',
@@ -1640,4 +2848,171 @@
         PrintConv => 'sprintf("%.1f mm",$val)',
     },
+);
+
+# Kodak DcMD atoms (ref PH)
+%Image::ExifTool::Kodak::DcMD = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
+    NOTES => 'Metadata directory found in MOV and MP4 videos from some Kodak cameras.',
+    Cmbo => {
+        Name => 'CameraByteOrder',
+        PrintConv => {
+            II => 'Little-endian (Intel, II)',
+            MM => 'Big-endian (Motorola, MM)',
+        },
+    },
+    CMbo => { # (as written by Kodak Playsport video camera)
+        Name => 'CameraByteOrder',
+        PrintConv => {
+            II => 'Little-endian (Intel, II)',
+            MM => 'Big-endian (Motorola, MM)',
+        },
+    },
+    DcME => {
+        Name => 'DcME',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::DcME',
+        },
+    },
+    DcEM => {
+        Name => 'DcEM',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::DcEM',
+        },
+    },
+);
+
+# Kodak DcME atoms (ref PH)
+%Image::ExifTool::Kodak::DcME = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
+    # Mtmd - 24 bytes: ("00 00 00 00 00 00 00 01" x 3)
+    # Keyw - keywords? (six bytes all zero)
+    # Rate -  2 bytes: 00 00
+);
+
+# Kodak DcEM atoms (ref PH)
+%Image::ExifTool::Kodak::DcEM = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
+    # Mtmd - 24 bytes: ("00 00 00 00 00 00 00 01" x 3)
+    # Csat - 16 bytes: 00 06 00 00 62 00 61 00 73 00 69 00 63 00 00 00 [....b.a.s.i.c...]
+    # Ksre -  8 bytes: 00 01 00 00 00 00
+);
+
+# tags in "free" atom of Kodak M5370 MP4 videos (ref PH)
+%Image::ExifTool::Kodak::Free = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
+    NOTES => q{
+        Information stored in the "free" atom of Kodak MP4 videos. (VERY bad form
+        for Kodak to store useful information in an atom intended for unused space!)
+    },
+    # (2012/01/19: Kodak files for bankruptcy -- this is poetic metadata justice)
+    Seri => {
+        Name => 'SerialNumber',
+        # byte 0 is string length;  byte 1 is zero;  string starts at byte 2
+        ValueConv => 'substr($val, 2, unpack("C",$val))',
+    },
+    SVer => {
+        Name => 'FirmwareVersion',
+        ValueConv => 'substr($val, 2, unpack("C",$val))',
+    },
+    # Clor - 2 bytes: 0 1  (?)
+    # CapM - 2 bytes: 0 1  (capture mode? = exposure mode?)
+    # WBMD - 2 bytes: 0 0  (white balance?)
+    Expc => { # (NC)
+        Name => 'ExposureCompensation',
+        Format => 'int16s',
+        ValueConv => '$val / 3', # (guess)
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+    },
+    # Zone - 2 bytes: 0 2  (time zone? focus zone?)
+    # FoMD - 2 bytes: 0 0  (focus mode?)
+    # Shap - 2 bytes: 0 2  (sharpness?)
+    Expo => {
+        Name => 'ExposureTime',
+        Format => 'rational32u',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    FNum => {
+        Name => 'FNumber',
+        Format => 'int16u',
+        ValueConv => '$val / 100',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+    },
+    ISOS => { Name => 'ISO', Format => 'int16u' },
+    StSV => {
+        Name => 'ShutterSpeedValue',
+        Format => 'int16s',
+        ValueConv => 'abs($val)<100 ? 2**(-$val/3) : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    AprV => {
+        Name => 'ApertureValue',
+        Format => 'int16s',
+        ValueConv => '2 ** ($val / 2000)',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    BrtV => { # (NC)
+        Name => 'BrightnessValue',
+        Format => 'int32s',
+        ValueConv => '$val / 1000', # (guess)
+    },
+    FoLn => {
+        Name => 'FocalLength',
+        Groups => { 2 => 'Camera' },
+        Format => 'int16u',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+    },
+    FL35 => {
+        Name => 'FocalLengthIn35mmFormat',
+        Groups => { 2 => 'Camera' },
+        Format => 'int16u',
+        PrintConv => '"$val mm"',
+    },
+    Scrn => {
+        Name => 'PreviewInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Kodak::Scrn' },
+    },
+);
+
+# tags in "frea" atom of Kodak PixPro SP360 MP4 videos (ref PH)
+%Image::ExifTool::Kodak::frea = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    NOTES => 'Information stored in the "frea" atom of Kodak PixPro SP360 MP4 videos.',
+    tima => {
+        Name => 'Duration',
+        Format => 'int32u',
+        Priority => 0,  # (only integer seconds)
+        PrintConv => 'ConvertDuration($val)',
+    },
+   'ver '=> { Name => 'KodakVersion' },
+    thma => { Name => 'ThumbnailImage', Groups => { 2 => 'Preview' }, Binary => 1 },
+    scra => { Name => 'PreviewImage',   Groups => { 2 => 'Preview' }, Binary => 1 },
+);
+
+# preview information in free/Scrn atom of MP4 videos (ref PH)
+%Image::ExifTool::Kodak::Scrn = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int16u',
+    0 => 'PreviewImageWidth',
+    1 => 'PreviewImageHeight',
+    2 => { Name => 'PreviewImageLength', Format => 'int32u' },
+    4 => {
+        Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{2}]',
+        RawConv => '$self->ValidateImage(\$val, $tag)',
+    },
+);
+
+# acceleration information extracted from 'pose' atom of MP4 videos (ref PH, PixPro 4KVR360)
+%Image::ExifTool::Kodak::pose = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
+    PROCESS_PROC => \&ProcessPose,
+    NOTES => q{
+        Streamed orientation information from the PixPro 4KVR360, extracted as
+        sub-documents when the L<Duplicates|../ExifTool.html#Duplicates> option is used.
+    },
+    Accelerometer => { }, # up, back, left?  units of g
+    AngularVelocity => { } # left, up, ccw?  units?
 );
 
@@ -1693,4 +3068,50 @@
 # add our composite tags
 Image::ExifTool::AddCompositeTags('Image::ExifTool::Kodak');
+
+#------------------------------------------------------------------------------
+# Process Kodak accelerometer data (ref PH)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessPose($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = length $$dataPt;
+    my $ee = $et->Options('ExtractEmbedded');
+    my ($i, $pos);
+
+    return 0 if $dirLen < 0x14;
+    my $num = Get32u($dataPt, 0x10);
+    return 0 if $dirLen < 0x14 + $num * 24;
+
+    $et->VerboseDir('Kodak pose', undef, $dirLen);
+
+    $$et{DOC_NUM} = 0;
+    for ($i=0, $pos=0x14; $i<$num; ++$i, $pos+=24) {
+        $et->HandleTag($tagTablePtr, AngularVelocity =>
+            Image::ExifTool::GetRational64s($dataPt, $pos) . ' ' .
+            Image::ExifTool::GetRational64s($dataPt, $pos + 8) . ' ' .
+            Image::ExifTool::GetRational64s($dataPt, $pos + 16));
+        $ee or $pos += $num * 24, last;
+        ++$$et{DOC_NUM};
+    }
+    $$et{DOC_NUM} = 0;
+
+    return 1 if $dirLen < $pos + 0x10;
+    $num = Get32u($dataPt, $pos + 0x0c);
+    return 1 if $dirLen < $pos + 0x10 + $num * 24;
+
+    for ($i=0, $pos+=0x10; $i<$num; ++$i, $pos+=24) {
+        $et->HandleTag($tagTablePtr, Accelerometer =>
+            Image::ExifTool::GetRational64s($dataPt, $pos) . ' ' .
+            Image::ExifTool::GetRational64s($dataPt, $pos + 8) . ' ' .
+            Image::ExifTool::GetRational64s($dataPt, $pos + 16));
+        $ee or $pos += $num * 24, last;
+        ++$$et{DOC_NUM};
+    }
+    $$et{DOC_NUM} = 0;
+    $ee or $et->Warn('Use the ExtractEmbedded option to extract all accelerometer data',3);
+    return 1;
+}
 
 #------------------------------------------------------------------------------
@@ -1724,5 +3145,5 @@
 sub ProcessKodakText($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart} || 0;
@@ -1732,10 +3153,10 @@
     my @lines = split /[\n\r]+/, $data;
     my ($line, $success, @other, $tagInfo);
-    $exifTool->VerboseDir('Kodak Text');
+    $et->VerboseDir('Kodak Text');
     foreach $line (@lines) {
         if ($line =~ /(.*?):\s*(.*)/) {
             my ($tag, $val) = ($1, $2);
             if ($$tagTablePtr{$tag}) {
-                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
             } else {
                 my $tagName = $tag;
@@ -1746,7 +3167,7 @@
                 $tagName = 'NoName' unless $tagName;
                 $tagInfo = { Name => $tagName };
-                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+                AddTagToTable($tagTablePtr, $tag, $tagInfo);
             }
-            $exifTool->HandleTag($tagTablePtr, $tag, $val, TagInfo => $tagInfo);
+            $et->HandleTag($tagTablePtr, $tag, $val, TagInfo => $tagInfo);
             $success = 1;
         } else {
@@ -1757,9 +3178,9 @@
     if ($success) {
         if (@other) {
-            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, '_other_info');
-            $exifTool->FoundTag($tagInfo, \@other);
+            $tagInfo = $et->GetTagInfo($tagTablePtr, '_other_info');
+            $et->FoundTag($tagInfo, \@other);
         }
     } else {
-        $exifTool->Warn("Can't parse Kodak TextualInfo data", 1);
+        $et->Warn("Can't parse Kodak TextualInfo data", 1);
     }
     return $success;
@@ -1772,19 +3193,19 @@
 sub ProcessKodakIFD($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dirStart = $$dirInfo{DirStart} || 0;
     return 1 if $dirStart <= 0 or $dirStart + 2 > $$dirInfo{DataLen};
     my $byteOrder = substr(${$$dirInfo{DataPt}}, $dirStart, 2);
     unless (Image::ExifTool::SetByteOrder($byteOrder)) {
-        $exifTool->Warn("Invalid Kodak $$dirInfo{Name} directory");
+        $et->Warn("Invalid Kodak $$dirInfo{Name} directory");
         return 1;
     }
     $$dirInfo{DirStart} += 2;   # skip byte order mark
     $$dirInfo{DirLen} -= 2;
-    if ($exifTool->{HTML_DUMP}) {
+    if ($$et{HTML_DUMP}) {
         my $base = $$dirInfo{Base} + $$dirInfo{DataPos};
-        $exifTool->HDump($dirStart+$base, 2, "Byte Order Mark");
+        $et->HDump($dirStart+$base, 2, "Byte Order Mark");
     }
-    return Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+    return Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
 }
 
@@ -1795,5 +3216,5 @@
 sub WriteKodakIFD($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dirStart = $$dirInfo{DirStart} || 0;
     return '' if $dirStart <= 0 or $dirStart + 2 > $$dirInfo{DataLen};
@@ -1802,5 +3223,5 @@
     $$dirInfo{DirStart} += 2;   # skip byte order mark
     $$dirInfo{DirLen} -= 2;
-    my $buff = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
+    my $buff = Image::ExifTool::Exif::WriteExif($et, $dirInfo, $tagTablePtr);
     return $buff unless defined $buff and length $buff;
     # apply one-time fixup for length of byte order mark
@@ -1832,5 +3253,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/KyoceraRaw.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/KyoceraRaw.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/KyoceraRaw.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.02';
+$VERSION = '1.03';
 
 sub ProcessRAW($$);
@@ -112,5 +112,5 @@
 sub ProcessRAW($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $size = 156; # size of header
@@ -120,5 +120,5 @@
     # validate Make string ('KYOCERA' reversed)
     substr($buff, 0x19, 7) eq 'ARECOYK' or return 0;
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('MM');
     my %dirInfo = (
@@ -130,5 +130,5 @@
     );
     my $tagTablePtr = GetTagTable('Image::ExifTool::KyoceraRaw::Main');
-    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
     return 1;
 }
@@ -153,5 +153,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/LNK.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/LNK.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/LNK.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.03';
+$VERSION = '1.07';
 
 sub ProcessItemID($$$);
@@ -25,4 +25,5 @@
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     GROUPS => { 2 => 'Other' },
+    VARS => { HEX_ID => 1 },    # print hex ID's in documentation
     NOTES => 'Information extracted from MS Shell Link (Windows shortcut) files.',
     # maybe the Flags aren't very useful to the user (since they are
@@ -236,5 +237,5 @@
     PROCESS_PROC => \&ProcessItemID,
     # (can't find any documentation on these items)
-    0x0032 => { 
+    0x0032 => {
         Name => 'Item0032',
         SubDirectory => { TagTable => 'Image::ExifTool::LNK::Item0032' },
@@ -380,5 +381,5 @@
         RawConv => q{
             $val = $self->Decode($val, 'UCS2');
-            $val =~ s/\0.*//;
+            $val =~ s/\0.*//s;
             return length($val) ? $val : undef;
         },
@@ -460,5 +461,5 @@
 sub ProcessItemID($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataLen = length $$dataPt;
@@ -468,5 +469,5 @@
         DataPos => $$dirInfo{DataPos},
     );
-    $exifTool->VerboseDir('ItemID', undef, $dataLen);
+    $et->VerboseDir('ItemID', undef, $dataLen);
     for (;;) {
         last if $pos + 4 >= $dataLen;
@@ -474,9 +475,9 @@
         last if $size < 2 or $pos + $size > $dataLen;
         my $tag = Get16u($dataPt, $pos+2); # (just a guess -- may not be a tag at all)
-        Image::ExifTool::AddTagToTable($tagTablePtr, $tag, {
+        AddTagToTable($tagTablePtr, $tag, {
             Name => sprintf('Item%.4x', $tag),
             SubDirectory => { TagTable => 'Image::ExifTool::LNK::UnknownData' },
         }) unless $$tagTablePtr{$tag};
-        $exifTool->HandleTag($tagTablePtr, $tag, undef, %opts, Start => $pos, Size => $size);
+        $et->HandleTag($tagTablePtr, $tag, undef, %opts, Start => $pos, Size => $size);
         $pos += $size;
     }
@@ -489,5 +490,5 @@
 sub ProcessLinkInfo($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataLen = length $$dataPt;
@@ -501,5 +502,5 @@
     );
     my ($off, $unicode, $pos, $val, $size);
-    $exifTool->VerboseDir('LinkInfo', undef, $dataLen);
+    $et->VerboseDir('LinkInfo', undef, $dataLen);
     if ($lif & 0x01) {
         # read Volume ID
@@ -507,5 +508,5 @@
         if ($off + 0x20 <= $dataLen) {
             # my $len = Get32u($dataPt, $off);
-            $exifTool->HandleTag($tagTablePtr, 'DriveType', undef, %opts, Start=>$off+4);
+            $et->HandleTag($tagTablePtr, 'DriveType', undef, %opts, Start=>$off+4);
             $pos = Get32u($dataPt, $off + 0x0c);
             if ($pos == 0x14) {
@@ -518,6 +519,6 @@
             if (defined $val) {
                 $size = length $val;
-                $val = $exifTool->Decode($val, 'UCS2') if $unicode;
-                $exifTool->HandleTag($tagTablePtr, 'VolumeLabel', $val, %opts, Start=>$pos, Size=>$size);
+                $val = $et->Decode($val, 'UCS2') if $unicode;
+                $et->HandleTag($tagTablePtr, 'VolumeLabel', $val, %opts, Start=>$pos, Size=>$size);
             }
         }
@@ -533,6 +534,6 @@
         if (defined $val) {
             $size = length $val;
-            $val = $exifTool->Decode($val, 'UCS2') if $unicode;
-            $exifTool->HandleTag($tagTablePtr, 'LocalBasePath', $val, %opts, Start=>$pos, Size=>$size);
+            $val = $et->Decode($val, 'UCS2') if $unicode;
+            $et->HandleTag($tagTablePtr, 'LocalBasePath', $val, %opts, Start=>$pos, Size=>$size);
         }
     }
@@ -552,6 +553,6 @@
             if (defined $val) {
                 $size = length $val;
-                $val = $exifTool->Decode($val, 'UCS2') if $unicode;
-                $exifTool->HandleTag($tagTablePtr, 'NetName', $val, %opts, Start=>$pos, Size=>$size);
+                $val = $et->Decode($val, 'UCS2') if $unicode;
+                $et->HandleTag($tagTablePtr, 'NetName', $val, %opts, Start=>$pos, Size=>$size);
             }
             my $flg = Get32u($dataPt, $off + 0x04);
@@ -567,11 +568,11 @@
                 if (defined $val) {
                     $size = length $val;
-                    $val = $exifTool->Decode($val, 'UCS2') if $unicode;
-                    $exifTool->HandleTag($tagTablePtr, 'DeviceName', $val, %opts, Start=>$pos, Size=>$size);
+                    $val = $et->Decode($val, 'UCS2') if $unicode;
+                    $et->HandleTag($tagTablePtr, 'DeviceName', $val, %opts, Start=>$pos, Size=>$size);
                 }
             }
             if ($flg & 0x02) {
                 $val = Get32u($dataPt, $off + 0x10);
-                $exifTool->HandleTag($tagTablePtr, 'NetProviderType', $val, %opts, Start=>$off + 0x10);
+                $et->HandleTag($tagTablePtr, 'NetProviderType', $val, %opts, Start=>$off + 0x10);
             }
         }
@@ -586,5 +587,5 @@
 sub ProcessLNK($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $buf2, $len, $i);
@@ -599,5 +600,5 @@
         $buff .= $buf2;
     }
-    $exifTool->SetFileType('Windows Shortcut');
+    $et->SetFileType();
     SetByteOrder('II');
 
@@ -609,5 +610,5 @@
         DirLen => length $buff,
     );
-    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
 
     my $flags = Get32u(\$buff, 0x14);
@@ -618,5 +619,5 @@
         $len = unpack('v', $buff);
         $raf->Read($buff, $len) == $len or return 1;
-        $exifTool->HandleTag($tagTablePtr, 0x10000, undef,
+        $et->HandleTag($tagTablePtr, 0x10000, undef,
             DataPt  => \$buff,
             DataPos => $raf->Tell() - $len,
@@ -632,5 +633,5 @@
         $raf->Read($buf2, $len - 4) == $len - 4 or return 1;
         $buff .= $buf2;
-        $exifTool->HandleTag($tagTablePtr, 0x20000, undef,
+        $et->HandleTag($tagTablePtr, 0x20000, undef,
             DataPt  => \$buff,
             DataPos => $raf->Tell() - $len,
@@ -647,9 +648,9 @@
         $raf->Read($buff, 2) or return 1;
         $len = unpack('v', $buff);
-        $len *= 2 if $flags & 0x80;  # characters are 2 bytes if Unicode flag is set   
+        $len *= 2 if $flags & 0x80;  # characters are 2 bytes if Unicode flag is set
         $raf->Read($buff, $len) or return 1;
         my $val;
-        $val = $exifTool->Decode($buff, 'UCS2') if $flags & 0x80;
-        $exifTool->HandleTag($tagTablePtr, 0x30000 | $mask, $val,
+        $val = $et->Decode($buff, 'UCS2') if $flags & 0x80;
+        $et->HandleTag($tagTablePtr, 0x30000 | $mask, $val,
             DataPt  => \$buff,
             DataPos => $raf->Tell() - $len,
@@ -671,5 +672,5 @@
             $tagInfo = $$tagTablePtr{0xa0000000};
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, undef,
+        $et->HandleTag($tagTablePtr, $tag, undef,
             DataPt  => \$buff,
             DataPos => $raf->Tell() - $len - 4,
@@ -699,5 +700,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/cs.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/cs.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/cs.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.04';
+$VERSION = '1.07';
 
 %Image::ExifTool::Lang::cs::Translate = (
@@ -227,4 +227,5 @@
       Description => 'BarevnÃœ prostor',
       PrintConv => {
+        'ICC Profile' => 'ICC Profil',
         'Uncalibrated' => 'NekalibrovÃ¡n',
       },
@@ -450,4 +451,12 @@
    'ExposureTime2' => 'ExpoziÄnÃ­ Äas 2',
    'FNumber' => 'F hodnota',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (nahoru/vlevo)',
+        'Rotate 180' => '180Â° (dolÅ¯/vpravo)',
+        'Rotate 270 CW' => '90Â° po smÄru HR (vlevo/dolÅ¯)',
+        'Rotate 90 CW' => '90Â° ptoti smÄru HR (vpravo/nahoru)',
+      },
+    },
    'FaxProfile' => {
       PrintConv => {
@@ -471,4 +480,5 @@
     },
    'FileType' => 'Typ',
+   'Filename' => 'JmÃ©no',
    'FillOrder' => {
       Description => 'PoÅadÃ­ vÃœplnÄ',
@@ -788,4 +798,5 @@
    'HostComputer' => 'Host',
    'Hue' => 'OdstÃ­n',
+   'ICCProfile' => 'ICC-Profil',
    'IPTC-NAA' => 'IPTC-NAA metadata',
    'ISO' => 'Citlivost ISO',
@@ -841,4 +852,9 @@
    'InteropVersion' => 'Verze kompatibility',
    'JFIFVersion' => 'JFIF verze',
+   'JPEGQuality' => {
+      PrintConv => {
+        'Standard' => 'NormÃ¡lnÃ­',
+      },
+    },
    'Keyword' => 'KlÃ­ÄovÃ¡ slova',
    'Keywords' => 'KlÃ­ÄovÃ¡ slova',
@@ -1171,5 +1187,5 @@
       PrintConv => {
         'None' => 'ÅœÃ¡dnÃ¡',
-        'cm' => 'pixely/cm',
+        'cm' => 'Pixely/cm',
         'inches' => 'Palce',
       },
@@ -1459,5 +1475,7 @@
    'WBAdjLighting' => {
       PrintConv => {
-        'Daylight' => 'DennÃ­ svÄtlo',
+        'Daylight (direct sunlight)' => 'DennÃ­ svÄtlo (0)',
+        'Daylight (shade)' => 'DennÃ­ svÄtlo (1)',
+        'Daylight (cloudy)' => 'DennÃ­ svÄtlo (2)',
         'Flash' => 'Blesk',
         'None' => 'ÅœÃ¡dnÃ¡',
@@ -1553,5 +1571,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/de.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/de.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/de.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.21';
+$VERSION = '1.36';
 
 %Image::ExifTool::Lang::de::Translate = (
@@ -38,4 +38,11 @@
    'AEExposureTime' => 'AE-Belichtungszeit',
    'AEExtra' => 'AE-Extra?',
+   'AEFlags' => {
+      PrintConv => {
+        'AE lock' => 'AE Speicherung',
+        'Aperture wide open' => 'Offene Blende',
+        'Flash recommended?' => 'Blitz erforderlich',
+      },
+    },
    'AEInfo' => 'Automatikbelichtungs-Informationen',
    'AELock' => {
@@ -72,5 +79,11 @@
     },
    'AEMeteringSegments' => 'AE-Messfelder',
-   'AEMicroadjustment' => 'AE Feinabstimmung',
+   'AEMicroadjustment' => {
+      Description => 'AE Feinabstimmung',
+      PrintConv => {
+        'Disable' => 'Deaktiviert',
+        'Enable' => 'Aktiviert',
+      },
+    },
    'AEMinAperture' => 'Kleinste AE-Blende',
    'AEMinExposureTime' => 'KÃŒrzeste AE Belichtungszeit',
@@ -93,8 +106,8 @@
         'Night Scene Portrait' => 'Nacht-PortrÃ€t',
         'No Flash' => 'Kein Blitz',
-        'Pet' => 'Haustier',
+        'Pet' => 'Haustiere',
         'Portrait' => 'PortrÃ€t',
         'Sunset' => 'Sonnenuntergang',
-        'Surf & Snow' => 'Surf + Schnee',
+        'Surf & Snow' => 'Surf & Schnee',
         'Sv or Green Mode' => 'Sv oder "GrÃŒnes" AE-Programm',
       },
@@ -103,5 +116,8 @@
       Description => 'AE-Einstellung',
       PrintConv => {
-        'Exposure Compensation' => 'Belichtungsausgleich',
+        'AE Lock' => 'AE-Speicherung',
+        'AE Lock + Exposure Comp.' => 'AE-Speicherung + Belichtungskorrektur',
+        'Exposure Compensation' => 'Belichtungskorrektur',
+        'No AE' => 'Kein AE',
       },
     },
@@ -143,6 +159,16 @@
     },
    'AFAdjustment' => 'AF-Korrektur',
+   'AFAndMeteringButtons' => {
+      Description => 'AF And Mess-Tasten',
+      PrintConv => {
+        'AE lock' => 'AE Speicherung',
+        'AF stop' => 'AE Stopp',
+        'Metering + AF start' => 'Messung + AF Start',
+        'Metering start' => 'Messung Start',
+        'No function' => 'Keine Funktion',
+      },
+    },
    'AFAperture' => 'AF-Blende',
-   'AFArea' => 'AF-Feld',
+   'AFArea' => 'AF Bereich',
    'AFAreaHeight' => 'AF-BereichshÃ¶he',
    'AFAreaHeights' => 'AF-BereichshÃ¶he',
@@ -158,15 +184,64 @@
       Description => 'Messfeldsteuerung',
       PrintConv => {
+        '1-area' => '1 Bereich',
+        '1-area (high speed)' => '1 Bereich (kurze VerschluÃzeit)',
+        '23-area' => '23 Bereiche',
+        '3-area (center)?' => '3 Bereiche (mitte)',
+        '3-area (high speed)' => '3 Bereiche (kurze VerschluÃzeit)',
+        '3-area (left)?' => '3 Bereiche (links)',
+        '3-area (right)?' => '3 Bereiche (rechts)',
+        '5-area' => '5 Bereiche',
+        '9-area' => '9 Bereiche',
+        'AF Point Expansion' => 'AF Punkt-Erweiterung',
+        'Auto (41 points)' => 'Automatisch (41 Punkte)',
         'Auto-area' => 'Autom. Messfeldgr.',
+        'Center' => 'Mitte',
+        'Contrast-detect' => 'Kontrasterkennung',
+        'Contrast-detect (face priority)' => 'Kontrasterkennung (Gesichtserkennung)',
+        'Contrast-detect (normal area)' => 'Kontrasterkennung (Standardbereich)',
+        'Contrast-detect (subject tracking)' => 'Kontrasterkennung (Objektverfolgung)',
+        'Contrast-detect (wide area)' => 'Kontrasterkennung (groÃer Bereich)',
+        'Default' => 'Standard',
         'Dynamic Area' => 'Dynamisch',
+        'Dynamic Area (21 points)' => 'Dynamischer Bereich (21 Punkte)',
+        'Dynamic Area (3D-tracking)' => 'Dynamischer Bereich (3D-NachfÃŒhrung)',
+        'Dynamic Area (51 points)' => 'Dynamischer Bereich (51 Punkte)',
+        'Dynamic Area (51 points, 3D-tracking)' => 'Dynamischer Bereich (51 Punkte, 3D-NachfÃŒhrung)',
+        'Dynamic Area (9 points)' => 'Dynamischer Bereich (9 Punkte)',
         'Dynamic Area (closest subject)' => 'Dynamic Messfeldgruppensteuerung (prioritÃ€t der kÃŒrzesten Aufnahmedistanz)',
         'Dynamic Area (wide)' => 'Dynamische Messfeldsteuerung (groÃ)',
+        'Dynamic Area (wide, 3D-tracking)' => 'Dynamischer Bereich (groÃ, 3D-NachfÃŒhrung)',
+        'Face + Tracking' => 'Gesichtserkennung + NachfÃŒhrung',
+        'Face Detect' => 'Gesichtserkennung',
         'Face Detect AF' => 'Gesichtserkennung AF',
+        'Face Priority (41 points)' => 'Gesichtserkennung (41 Punkte)',
+        'Face Tracking' => 'Gesichtserkennung',
+        'Flexible' => 'Angepasst',
+        'Flexible Spot' => 'Gesetzter Punkt',
+        'Flexizone Multi' => 'Mehrpunkt-Bereich',
+        'Flexizone Single' => 'Einpunkt-Bereich',
         'Group Dynamic' => 'Dynamische Messfeldgruppensteuerung',
+        'Local' => 'Lokal',
+        'Manual' => 'Manuell',
+        'Multi' => 'Mehrpunkt',
         'Multi-point AF or AI AF' => 'Mehrpunkt AF oder AI AF',
+        'Normal?' => 'Normal',
         'Off (Manual Focus)' => 'Aus (Manueller Fokus)',
+        'Selective (for Miniature effect)' => 'Selektiv (fÃŒr Vorschau-Effekt)',
+        'Single (135 points)' => 'Einpunkt (135 Punkte)',
         'Single Area' => 'Einzelfeld',
         'Single Area (wide)' => 'Einzelfeldmessung (groÃ)',
         'Single-point AF' => 'Einpunkt AF',
+        'Spot Focusing' => 'Spotfokussierung',
+        'Spot Focusing 2' => 'Spotfokussierung 2',
+        'Spot Mode Off' => 'Spot-Modus Aus',
+        'Spot Mode On' => 'Spot-Modus Ein',
+        'Subject Tracking (41 points)' => 'Objektverfolgung (41 Punkte)',
+        'Touch' => 'BerÃŒhrungspunkt',
+        'Tracking' => 'NachfÃŒhrung',
+        'Wide' => 'Weit',
+        'Zone' => 'Bereich',
+        'Zone AF' => 'Zonen AF',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -174,12 +249,24 @@
       Description => 'Messfeldsteuerung',
       PrintConv => {
+        '3D-tracking (11 points)' => '3D NachfÃŒhrung (11 Punkte)',
+        'Auto-area' => 'Automatischer Bereich',
+        'Center' => 'Mitte',
         'Closest Subject' => 'NÃ€chstes Objekt',
         'Dynamic Area' => 'Dynamisch',
+        'Flexible Spot' => 'Gesetzter Punkt',
+        'Local' => 'Lokal',
+        'Multi' => 'Mehrpunkt',
         'Single Area' => 'Einzelfeld',
+        'Wide' => 'Weit',
+        'Zone' => 'Bereich',
       },
     },
    'AFAreaWidth' => 'AF-Bereichsbreite',
    'AFAreaWidths' => 'AF-Bereichsbreite',
+   'AFAreaXPosition' => 'AF-Bereich X Position',
+   'AFAreaXPosition1' => 'AF-Bereich X Position 1',
    'AFAreaXPositions' => 'AF Bereich X Positionen',
+   'AFAreaYPosition' => 'AF-Bereich Y Position',
+   'AFAreaYPosition1' => 'AF-Bereich Y Position 1',
    'AFAreaYPositions' => 'AF Bereich Y Positionen',
    'AFAreas' => 'AF-Bereiche',
@@ -203,4 +290,13 @@
       },
     },
+   'AFAssistLamp' => {
+      Description => 'AF Hilfslicht',
+      PrintConv => {
+        'Disabled and Not Required' => 'Nicht eingestellt, war nicht nÃ¶tig',
+        'Disabled but Required' => 'Nicht eingestellt, war aber nÃ¶tig',
+        'Enabled but Not Used' => 'Eingestellt, aber nicht verwendet',
+        'Fired' => 'Blitz wurde ausgelÃ¶st',
+      },
+    },
    'AFDefocus' => 'AF-Defocus',
    'AFDuringLiveView' => {
@@ -213,18 +309,39 @@
       },
     },
-   'AFFineTune' => 'AF-Feinabstimmung',
+   'AFFineTune' => {
+      Description => 'AF-Feinabstimmung',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On (1)' => 'Ein (1)',
+        'On (2)' => 'Ein (2)',
+      },
+    },
    'AFFineTuneAdj' => 'AF-Feinabstimmung',
+   'AFIlluminator' => {
+      PrintConv => {
+        'Off' => 'Aus',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'AFImageHeight' => 'AF-BildhÃ¶he',
    'AFImageWidth' => 'AF-Bildbreite',
+   'AFInFocus' => 'AF in Fokus',
    'AFInfo' => 'AF-Modus',
    'AFInfo2' => 'AF-Informationen',
    'AFInfo2Version' => 'AF-Info-Version',
    'AFIntegrationTime' => 'AF-Messzeit',
-   'AFMicroAdjActive' => {
-      PrintConv => {
-        'No' => 'Nein',
-        'Yes' => 'Ja',
-      },
-    },
+   'AFMicroAdj' => 'AF Feinabstimmung',
+   'AFMicroAdjMode' => {
+      Description => 'AF Feinabstimmung Modus',
+      PrintConv => {
+        'Adjust all by the same amount' => 'Korrektur immer um gleichen Wert',
+        'Adjust by lens' => 'Korrektur objektivabhÃ€ngig',
+        'Disable' => 'Deaktiviert',
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'AFMicroAdjRegisteredLenses' => 'AF Feinabstimmung bekannte Objektive',
+   'AFMicroAdjValue' => 'AF Feinabstimmung Wert',
    'AFMicroadjustment' => {
       Description => 'AF Feinabstimmung',
@@ -235,5 +352,13 @@
       },
     },
-   'AFMode' => 'AF-Modus',
+   'AFMode' => {
+      Description => 'AF-Modus',
+      PrintConv => {
+        'Face Detection' => 'Gesichtserkennung',
+        'Off' => 'Aus',
+        'Tracking' => 'NachfÃŒhrung',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'AFOnAELockButtonSwitch' => {
       Description => 'AF-ON/AELocktaste- Schalter',
@@ -246,34 +371,151 @@
       Description => 'GewÃ€hlter AF-Punkt',
       PrintConv => {
+        '(none)' => '(keiner)',
         'Auto AF point selection' => 'Automatische Wahl des AF-Punktes',
         'Bottom' => 'Unten',
+        'Bottom (horizontal)' => 'Unten (horizontal)',
+        'Bottom (vertical)' => 'Unten (vertikal)',
+        'Bottom Center' => 'Unten Mitte',
+        'Bottom Left' => 'Unten Links',
+        'Bottom Right' => 'Unten Rechts',
+        'Bottom-center (horizontal)' => 'Unten Mitte (horizontal)',
+        'Bottom-center (vertical)' => 'Unten Mitte (vertikal)',
+        'Bottom-left' => 'Unten Links',
+        'Bottom-left (horizontal)' => 'Unten Links (horizontal)',
+        'Bottom-left (vertical)' => 'Unten Links (vertikal)',
+        'Bottom-right' => 'Unten Rechts',
+        'Bottom-right (horizontal)' => 'Unten Rechts (horizontal)',
+        'Bottom-right (vertical)' => 'Unten Rechts (vertikal)',
         'Center' => 'Mitte',
         'Center (horizontal)' => 'Mitte (horizontal)',
-        'Center (vertical)' => 'Mitte (vertical)',
+        'Center (vertical)' => 'Mitte (vertikal)',
+        'Center Left' => 'Mitte Links',
+        'Center Right' => 'Mitte Rechts',
         'Face Detect' => 'Gesichtserkennung',
-        'Far Left' => 'Ganz links',
-        'Far Right' => 'Ganz rechts',
+        'Far Left' => 'Weit links',
+        'Far Left (horizontal)' => 'Weit links (horizontal)',
+        'Far Left (vertical)' => 'Weit links (vertikal)',
+        'Far Left/Right of Center' => 'Weit Links/Rechts der Mitte',
+        'Far Left/Right of Center/Bottom' => 'Weit Links/Rechts der Mitte/Unten',
+        'Far Right' => 'Weit rechts',
+        'Far Right (horizontal)' => 'Weit rechts (horizontal)',
+        'Far Right (vertical)' => 'Weit rechts (vertikal)',
         'Left' => 'Links',
-        'Lower-left' => 'Unten-Links',
-        'Lower-right' => 'Unten-Rechts',
+        'Left (horizontal)' => 'Links (horizontal)',
+        'Left (or n/a)' => 'Links (oder Nicht gesetzt)',
+        'Left (vertical)' => 'Links (vertikal)',
+        'Lower Far Left' => 'Unten ganz links',
+        'Lower Far Right' => 'Unten ganz rechts',
+        'Lower-left' => 'Links unten',
+        'Lower-left (horizontal)' => 'Links unten (horizontal)',
+        'Lower-left (vertical)' => 'Links unten (vertikal)',
+        'Lower-middle' => 'Untere Mitte',
+        'Lower-right' => 'Rechts unten',
+        'Lower-right (horizontal)' => 'Rechts unten (horizontal)',
+        'Lower-right (vertical)' => 'Unten rechts (vertikal)',
         'Manual AF point selection' => 'Manuell gewÃ€hlter AF-Punkt',
-        'Mid-left' => 'Links-Mitte',
-        'Mid-right' => 'Rechts-Mitte',
-        'None' => 'Kein',
-        'None (MF)' => 'Kein (MF)',
+        'Mid-left' => 'Links mitte',
+        'Mid-left (horizontal)' => 'Links mitte (horizontal)',
+        'Mid-left (vertical)' => 'Links mitte (vertikal)',
+        'Mid-right' => 'Rechts mitte',
+        'Mid-right (horizontal)' => 'Rechts mitte (horizontal)',
+        'Mid-right (vertical)' => 'Rechts mitte (vertikal)',
+        'Near Left' => 'Nahe Links',
+        'Near Left/Right of Center' => 'Nahe Links/Rechts der Mitte',
+        'Near Right' => 'Nahe Rechts',
+        'Near Upper/Left' => 'Nahe Links oben',
+        'None' => 'Keiner',
+        'None (MF)' => 'Keiner (MF)',
         'Right' => 'Rechts',
+        'Right (horizontal)' => 'Rechts (horizontal)',
+        'Right (vertical)' => 'Rechts (vertikal)',
         'Top' => 'Oben',
-        'Upper-left' => 'Oben-Links',
-        'Upper-right' => 'Oben-Rechts',
-      },
-    },
-   'AFPointActivationArea' => 'AF-Messfeld-Aktivierungsbereich',
+        'Top (horizontal)' => 'Oben (horizontal)',
+        'Top (vertical)' => 'Oben (vertikal)',
+        'Top Center' => 'Oben Mitte',
+        'Top Left' => 'Oben Links',
+        'Top Near-left' => 'Oben nahe-Links',
+        'Top Near-right' => 'Nahe Rechts-oben',
+        'Top Right' => 'Oben Rechts',
+        'Top-center (horizontal)' => 'Oben Mitte (horizontal)',
+        'Top-center (vertical)' => 'Oben Mitte (vertikal)',
+        'Top-left' => 'Oben Links',
+        'Top-left (horizontal)' => 'Oben Links (horizontal)',
+        'Top-left (vertical)' => 'Oben Links (vertikal)',
+        'Top-right' => 'Oben Rechts',
+        'Top-right (horizontal)' => 'Oben Rechts (horizontal)',
+        'Top-right (vertical)' => 'Oben Rechts (vertikal)',
+        'Upper Far Left' => 'Oben ganz links',
+        'Upper Far Right' => 'Oben ganz rechts',
+        'Upper Left' => 'Links oben',
+        'Upper Right' => 'Rechts oben',
+        'Upper-left' => 'Links oben',
+        'Upper-left (horizontal)' => 'Links oben (horizontal)',
+        'Upper-left (vertical)' => 'Links oben (vertikal)',
+        'Upper-middle' => 'Obere Mitte',
+        'Upper-right' => 'Rechts oben',
+        'Upper-right (horizontal)' => 'Rechts oben (horizontal)',
+        'Upper-right (vertical)' => 'Oben rechts (vertikal)',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'AFPointActivationArea' => {
+      Description => 'AF-Messfeld-Aktivierungsbereich',
+      PrintConv => {
+        'Expanded' => 'Erweitert',
+      },
+    },
    'AFPointAreaExpansion' => {
       Description => 'AF-Messbereich Ausweitung',
       PrintConv => {
+        'All 45 points area' => 'Alle 45 Punkte',
         'Disable' => 'Aus',
-        'Enable' => 'An',
+        'Enable' => 'Ein',
         'Left/right AF points' => 'MÃ¶glich (linkes/rechtes zusÃ€tzliches AF-Messfeld)',
         'Surrounding AF points' => 'MÃ¶glich (entsprechendes zusÃ€tzliches AF-Messfeld)',
+      },
+    },
+   'AFPointAtShutterRelease' => {
+      Description => 'AF-Punkt beim AuslÃ¶sen',
+      PrintConv => {
+        '(out of focus)' => '(ausserhalb Fokus)',
+        'Bottom (horizontal)' => 'Unten (horizontal)',
+        'Bottom (vertical)' => 'Unten (vertikal)',
+        'Center (horizontal)' => 'Mitte (horizontal)',
+        'Center (vertical)' => 'Mitte (vertikal)',
+        'Far Left' => 'Weit links',
+        'Far Left (horizontal)' => 'Weit links (horizontal)',
+        'Far Left (vertical)' => 'Weit links (vertikal)',
+        'Far Right' => 'Weit rechts',
+        'Far Right (horizontal)' => 'Weit rechts (horizontal)',
+        'Far Right (vertical)' => 'Weit rechts (vertikal)',
+        'Left' => 'Links',
+        'Left (horizontal)' => 'Links (horizontal)',
+        'Left (vertical)' => 'Links (vertikal)',
+        'Lower Far Left' => 'Unten ganz links',
+        'Lower Far Right' => 'Unten ganz rechts',
+        'Lower-left' => 'Links unten',
+        'Lower-left (horizontal)' => 'Links unten (horizontal)',
+        'Lower-left (vertical)' => 'Links unten (vertikal)',
+        'Lower-middle' => 'Unten mitte',
+        'Lower-right' => 'Rechts unten',
+        'Lower-right (horizontal)' => 'Rechts unten (horizontal)',
+        'Lower-right (vertical)' => 'Rechts unten (vertikal)',
+        'Near Left' => 'Nahe links',
+        'Near Right' => 'Nahe rechts',
+        'Right' => 'Rechts',
+        'Right (horizontal)' => 'Rechts (horizontal)',
+        'Right (vertical)' => 'Rechts (vertikal)',
+        'Top (horizontal)' => 'Oben (horizontal)',
+        'Top (vertical)' => 'Oben (vertikal)',
+        'Upper Far Left' => 'Oben ganz links',
+        'Upper Far Right' => 'Oben ganz rechts',
+        'Upper-left' => 'Links oben',
+        'Upper-left (horizontal)' => 'Links oben (horizontal)',
+        'Upper-left (vertical)' => 'Links oben (vertikal)',
+        'Upper-middle' => 'Oben mitte',
+        'Upper-right' => 'Rechts oben',
+        'Upper-right (horizontal)' => 'Rechts oben (horizontal)',
+        'Upper-right (vertical)' => 'Rechts oben (vertikal)',
       },
     },
@@ -290,4 +532,7 @@
       PrintConv => {
         'Brighter' => 'Heller',
+        'Extra High' => 'Extra Hoch',
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
       },
     },
@@ -308,4 +553,48 @@
       },
     },
+   'AFPointInFocus' => {
+      Description => 'AF-Punkt im Fokus',
+      PrintConv => {
+        '(none)' => '(keiner)',
+        'Bottom (horizontal)' => 'Unten (horizontal)',
+        'Bottom (vertical)' => 'Unten (vertikal)',
+        'Center (horizontal)' => 'Mitte (horizontal)',
+        'Center (vertical)' => 'Mitte (vertikal)',
+        'Far Left' => 'Weit links',
+        'Far Left (horizontal)' => 'Weit links(horizontal)',
+        'Far Left (vertical)' => 'Weit links (vertikal)',
+        'Far Right' => 'Weit rechts',
+        'Far Right (horizontal)' => 'Weit rechts (horizontal)',
+        'Far Right (vertical)' => 'Weit rechts (vertikal)',
+        'Left' => 'Links',
+        'Left (horizontal)' => 'Links (horizontal)',
+        'Left (vertical)' => 'Links (vertikal)',
+        'Lower Far Left' => 'Unten ganz Links',
+        'Lower Far Right' => 'Unten ganz rechts',
+        'Lower-left' => 'Links unten',
+        'Lower-left (horizontal)' => 'Links unten (horizontal)',
+        'Lower-left (vertical)' => 'Links unten (vertikal)',
+        'Lower-middle' => 'Unten mitte',
+        'Lower-right' => 'Rechts unten',
+        'Lower-right (horizontal)' => 'Rechts unten (horizontal)',
+        'Lower-right (vertical)' => 'Rechts unten (vertikal)',
+        'Near Left' => 'Nahe links',
+        'Near Right' => 'Nahe rechts',
+        'Right' => 'Rechts',
+        'Right (horizontal)' => 'Rechts (horizontal)',
+        'Right (vertical)' => 'Rechts (vertikal)',
+        'Top (horizontal)' => 'Oben (horizontal)',
+        'Top (vertical)' => 'Oben (vertikal)',
+        'Upper Far Left' => 'Oben ganz links',
+        'Upper Far Right' => 'Oben ganz rechts',
+        'Upper-left' => 'Links oben',
+        'Upper-left (horizontal)' => 'Links oben (horizontal)',
+        'Upper-left (vertical)' => 'Links oben (vertikal)',
+        'Upper-middle' => 'Oben mitte',
+        'Upper-right' => 'Rechts oben',
+        'Upper-right (horizontal)' => 'Rechts oben (horizontal)',
+        'Upper-right (vertical)' => 'Rechts oben (vertikal)',
+      },
+    },
    'AFPointMode' => {
       Description => 'AF-Punkt-Modus',
@@ -314,4 +603,5 @@
       },
     },
+   'AFPointPosition' => 'AF-Punkt Position',
    'AFPointRegistration' => {
       Description => 'AF-Feld Speicherung',
@@ -328,27 +618,52 @@
     },
    'AFPointSelected' => {
-      Description => 'GewÃ€hlter AF-Punkt',
+      Description => 'AF gewÃ€hlter Punkt',
       PrintConv => {
         'Auto' => 'Automatisch',
         'Automatic Tracking AF' => 'NachfÃŒhr AF',
         'Bottom' => 'Unten',
+        'Bottom-left' => 'Unten-links',
+        'Bottom-right' => 'Unten-rechts',
         'Center' => 'Mitte',
         'Face Detect AF' => 'Gesichtserkennungs-AF',
+        'Far Left' => 'Weit links',
+        'Far Right' => 'Weit rechts',
         'Fixed Center' => 'Auf Mitte fixiert',
         'Left' => 'Links',
-        'Lower-left' => 'Unten-links',
-        'Lower-right' => 'Unten-rechts',
-        'Mid-left' => 'Links-Mitte',
-        'Mid-right' => 'Rechts-Mitte',
+        'Lower Far Left' => 'Unten weit Links',
+        'Lower Far Right' => 'Unten weit Rechts',
+        'Lower-left' => 'Links unten',
+        'Lower-middle' => 'Untere Mitte',
+        'Lower-right' => 'Rechts unten',
+        'Mid-left' => 'Links mitte',
+        'Mid-right' => 'Rechts mitte',
+        'Near Left' => 'Nahe Links',
+        'Near Right' => 'Nahe Rechts',
         'Right' => 'Rechts',
         'Top' => 'Oben',
-        'Upper-left' => 'Oben-links',
-        'Upper-right' => 'Oben-rechts',
+        'Top-left' => 'Oben-links',
+        'Top-right' => 'Oben-rechts',
+        'Upper Far Left' => 'Oben weit Links',
+        'Upper Far Right' => 'Oben weit Rechts',
+        'Upper-left' => 'Links oben',
+        'Upper-middle' => 'Obere Mitte',
+        'Upper-right' => 'Rechts oben',
       },
     },
    'AFPointSelected2' => {
-      Description => 'GewÃ€hlter AF-Punkt 2',
+      Description => 'AF gewÃ€hlter Punkt 2',
       PrintConv => {
         'Auto' => 'Automatisch',
+        'Bottom' => 'Unten',
+        'Center' => 'Mitte',
+        'Left' => 'Links',
+        'Lower-left' => 'Links unten',
+        'Lower-right' => 'Rechts unten',
+        'Mid-left' => 'Links mitte',
+        'Mid-right' => 'Rechts mitte',
+        'Right' => 'Rechts',
+        'Top' => 'Oben',
+        'Upper-left' => 'Links oben',
+        'Upper-right' => 'Rechts oben',
       },
     },
@@ -365,4 +680,11 @@
         'Multi-controller direct' => 'Multicontroller',
         'Quick Control Dial direct' => 'Schnelleinstellrad',
+      },
+    },
+   'AFPointSet' => {
+      Description => 'AF-Punkt Einstellung',
+      PrintConv => {
+        'No' => 'Nein',
+        'Yes' => 'Ja',
       },
     },
@@ -372,7 +694,10 @@
       Description => 'AF-Punkte im Fokus',
       PrintConv => {
+        '(none)' => '(Keine)',
+        'All' => 'Alle',
+        'All 11 Points' => 'Alle 11 Punkte',
         'Bottom' => 'Unten',
-        'Bottom, Center' => 'Unten + Mitte',
-        'Bottom-center' => 'Unten-Mitte',
+        'Bottom, Center' => 'Unten, Mitte',
+        'Bottom-center' => 'Unten-mitte',
         'Bottom-left' => 'Unten-links',
         'Bottom-right' => 'Unten-rechts',
@@ -380,40 +705,69 @@
         'Center (horizontal)' => 'Mitte (horizontal)',
         'Center (vertical)' => 'Mitte (vertikal)',
-        'Far Left' => 'Ganz links',
-        'Far Right' => 'Ganz rechts',
+        'Center+Right' => 'Mitte Rechts',
+        'Far Left' => 'Weit links',
+        'Far Right' => 'Weit rechts',
         'Fixed Center or Multiple' => 'Auf Mitte fixiert oder mehrere',
         'Left' => 'Links',
-        'Lower-left' => 'Unten-Links',
-        'Lower-left, Bottom' => 'Unten-links + Unten',
-        'Lower-left, Mid-left' => 'Unten-links + Links-Mitte',
-        'Lower-right' => 'Unten-Rechts',
-        'Lower-right, Bottom' => 'Unten-rechts + Unten',
-        'Lower-right, Mid-right' => 'Unten-rechts + Rechts-Mitte',
-        'Mid-left' => 'Links-Mitte',
-        'Mid-left, Center' => 'Links-Mitte + Mitte',
-        'Mid-right' => 'Rechts-Mitte',
-        'Mid-right, Center' => 'Rechts-Mitte + Mitte',
+        'Left+Center' => 'Links Mitte',
+        'Left+Right' => 'Links Rechts',
+        'Lower-left' => 'Links unten',
+        'Lower-left, Bottom' => 'Links unten, Unten',
+        'Lower-left, Mid-left' => 'Links unten, Links mitte',
+        'Lower-right' => 'Rechts unten',
+        'Lower-right, Bottom' => 'Rechts unten, Unten',
+        'Lower-right, Mid-right' => 'Rechts unten, Rechts mitte',
+        'Mid-left' => 'Links mitte',
+        'Mid-left, Center' => 'Links mitte, Mitte',
+        'Mid-right' => 'Rechts mitte',
+        'Mid-right, Center' => 'Rechts mitte, Mitte',
         'None' => 'Keiner',
+        'None (MF)' => 'Keiner (MF)',
         'Right' => 'Rechts',
         'Top' => 'Oben',
-        'Top, Center' => 'Oben + Mitte',
+        'Top, Center' => 'Oben, Mitte',
         'Top-center' => 'Oben-Mitte',
         'Top-left' => 'Oben-links',
         'Top-right' => 'Oben-rechts',
-        'Upper-left' => 'Oben-Links',
-        'Upper-left, Mid-left' => 'Oben-links + Links-mitte',
-        'Upper-left, Top' => 'Oben-links + Oben',
-        'Upper-right' => 'Oben-Rechts',
-        'Upper-right, Mid-right' => 'Oben-rechts + Rechts-Mitte',
-        'Upper-right, Top' => 'Oben-rechts + Oben',
+        'Upper-left' => 'Links oben',
+        'Upper-left, Mid-left' => 'Links oben, Links mitte',
+        'Upper-left, Top' => 'Links oben, Oben',
+        'Upper-right' => 'Rechts oben',
+        'Upper-right, Mid-right' => 'Rechts oben, Rechts mitte',
+        'Upper-right, Top' => 'Rechts oben, Oben',
       },
     },
    'AFPointsInFocus1D' => 'AF-Punkte im Fokus 1D',
-   'AFPointsInFocus5D' => 'AF-Punkte im Fokus',
-   'AFPointsSelected' => 'GewÃ€hlte AF-Punkte',
+   'AFPointsInFocus5D' => {
+      Description => 'AF-Punkte im Fokus',
+      PrintConv => {
+        'Bottom' => 'Unten',
+        'Center' => 'Mitte',
+        'Left' => 'Links',
+        'Lower-left' => 'Unten links',
+        'Lower-right' => 'Rechts unten',
+        'Right' => 'Rechts',
+        'Top' => 'Oben',
+        'Upper-left' => 'Links oben',
+        'Upper-right' => 'Rechts oben',
+      },
+    },
+   'AFPointsSelected' => 'AF gewÃ€hlte Punkte',
    'AFPointsUnknown1' => {
+      Description => 'AF-Punkte Unbekannt 1',
       PrintConv => {
         'All' => 'Alle',
+        'Bottom' => 'Unten',
+        'Center' => 'Mitte',
         'Central 9 points' => 'Alle mittleren 9 Punkte',
+        'Left' => 'Links',
+        'Lower-left' => 'Links unten',
+        'Lower-right' => 'Rechts unten',
+        'Mid-left' => 'Links mitte',
+        'Mid-right' => 'Rechts mitte',
+        'Right' => 'Rechts',
+        'Top' => 'Oben',
+        'Upper-left' => 'Links oben',
+        'Upper-right' => 'Rechts oben',
       },
     },
@@ -422,4 +776,15 @@
       PrintConv => {
         'Auto' => 'Automatisch',
+        'Bottom' => 'Unten',
+        'Center' => 'Mitte',
+        'Left' => 'Links',
+        'Lower-left' => 'Links unten',
+        'Lower-right' => 'Rechts unten',
+        'Mid-left' => 'Links mitte',
+        'Mid-right' => 'Rechts mitte',
+        'Right' => 'Rechts',
+        'Top' => 'Oben',
+        'Upper-left' => 'Links oben',
+        'Upper-right' => 'Rechts oben',
       },
     },
@@ -427,15 +792,16 @@
       Description => 'Verwendete AF-Punkte',
       PrintConv => {
+        'All 11 Points' => 'Alle 11 Punkte',
         'Bottom' => 'Unten',
         'Center' => 'Mitte',
-        'Far Left' => 'Ganz links',
-        'Far Right' => 'Ganz rechts',
-        'Lower-left' => 'Unten-Links',
-        'Lower-right' => 'Unten-Rechts',
-        'Mid-left' => 'Links-Mitte',
-        'Mid-right' => 'Rechts-Mitte',
+        'Far Left' => 'Weit links',
+        'Far Right' => 'Weit rechts',
+        'Lower-left' => 'Links unten',
+        'Lower-right' => 'Rechts unten',
+        'Mid-left' => 'Links mitte',
+        'Mid-right' => 'Rechts mitte',
         'Top' => 'Oben',
-        'Upper-left' => 'Oben-Links',
-        'Upper-right' => 'Oben-Rechts',
+        'Upper-left' => 'Links oben',
+        'Upper-right' => 'Rechts oben',
       },
     },
@@ -449,4 +815,108 @@
       },
     },
+   'AFSensorActive' => {
+      Description => 'Aktiver AF Sensor',
+      PrintConv => {
+        'Bottom' => 'Unten',
+        'Bottom-left' => 'Unten Links',
+        'Bottom-right' => 'Unten Rechts',
+        'Center Vertical' => 'Mitte vertikal',
+        'Middle Horizontal' => 'Mitte horizontal',
+        'Top' => 'Oben',
+        'Top-left' => 'Oben Links',
+        'Top-right' => 'Rechts Oben',
+      },
+    },
+   'AFStatusActiveSensor' => {
+      Description => 'Status aktiver AF Sensor',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusBottom' => {
+      Description => 'AF Status Unten',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusBottom-left' => {
+      Description => 'AF Status Unten Links',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusBottom-right' => {
+      Description => 'AF Status Unten Rechts',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusCenterHorizontal' => {
+      Description => 'AF Status Mitte horizontal',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusCenterVertical' => {
+      Description => 'AF Status Mitte vertikal',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusLeft' => {
+      Description => 'AF Status Links',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusMiddleHorizontal' => {
+      Description => 'AF Status Mitte horizontal',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusRight' => {
+      Description => 'AF Status Rechts',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusTop' => {
+      Description => 'AF Status Oben',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusTop-left' => {
+      Description => 'AF Status Oben Links',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFStatusTop-right' => {
+      Description => 'AF Status Oben Rechts',
+      PrintConv => {
+        'In Focus' => 'Im Fokus',
+        'Out of Focus' => 'Nicht im Fokus',
+      },
+    },
+   'AFType' => {
+      Description => 'AF-Typ',
+      PrintConv => {
+        '15-point' => '15 Punkte',
+        '19-point' => '19 Punkte',
+      },
+    },
    'AIServoContinuousShooting' => 'AuslÃ¶seprioritÃ€t',
    'AIServoImagePriority' => {
@@ -456,4 +926,5 @@
         '1: AF, 2: Tracking' => 'AF-PrioritÃ€t/NachfÃŒhrprioritÃ€t',
         '1: Release, 2: Drive speed' => 'AuslÃ¶sung/Transportgeschwindigkeit',
+        '1: Release, 2: Tracking' => '1: AuslÃ¶sung, 2: NachfÃŒhrung',
       },
     },
@@ -468,5 +939,7 @@
       Description => 'AI Servo Empfindlichkeit',
       PrintConv => {
-        'Fast' => 'Rapide',
+        'Fast' => 'Schnell',
+        'Medium Fast' => 'Mittel-Schnell',
+        'Medium Slow' => 'Mittel',
         'Slow' => 'Langsam',
       },
@@ -475,4 +948,5 @@
    'ARMVersion' => 'ARM-Version',
    'AccessDate' => 'Zugriffsdatum',
+   'AccessoryType' => 'ZubehÃ¶r-Typ',
    'ActionAdvised' => 'Aktion empfohlen',
    'ActiveArea' => 'Aktiver Bereich',
@@ -507,4 +981,5 @@
     },
    'Address' => 'Adresse',
+   'AdjustmentMode' => 'Korrekturmodus',
    'AdultContentWarning' => {
       PrintConv => {
@@ -518,4 +993,18 @@
       },
     },
+   'AdvancedSceneMode' => {
+      Description => 'Erweiteter Szenenmodus',
+      PrintConv => {
+        'Off' => 'Aus',
+        'Creative Macro' => 'Makro kreativ',
+        'Flower' => 'Blumen',
+        'HDR B&W' => 'HDR Schwarz-WeiÃ',
+        'High Key' => 'High-Key',
+        'Indoor Sports' => 'Hallensport',
+        'Low Key' => 'Low-Key',
+        'Outdoor Sports' => 'Freiluftsport',
+      },
+    },
+   'AdvancedSceneType' => 'Erweiterter Szenentyp',
    'AlphaByteCount' => 'Anzahl Bytes der Alpha-Kanal-Daten',
    'AlphaChannelsNames' => 'Alpha-Kanal-Namen',
@@ -530,16 +1019,20 @@
     },
    'AlphaOffset' => 'Alpha-Kanal-Datenposition',
+   'AlreadyApplied' => 'Bereits zugewiesen',
    'AnalogBalance' => 'Analog-Balance',
    'Annotation' => 'Anmerkung',
+   'Annotations' => 'Anmerkungen',
    'Anti-Blur' => {
-      Description => 'Verwacklungsschutz-Modus',
+      Description => 'Verwacklungsschutz',
       PrintConv => {
         'Off' => 'Aus',
         'On (Continuous)' => 'Ein (Kontinuierlich)',
         'On (Shooting)' => 'Ein (Aufnahme)',
-        'n/a' => 'Nicht gesetzt',
-      },
-    },
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'AntiAliasStrength' => 'Anti-Aliasing StÃ€rke',
    'Aperture' => 'Blende',
+   'ApertureDisplayed' => 'Angezeigte Blende',
    'ApertureRange' => {
       Description => 'Einstellung Verschlusszeitenbereich',
@@ -556,4 +1049,5 @@
       },
     },
+   'ApertureSetting' => 'Blendeneinstellung',
    'ApertureValue' => 'Blende',
    'ApplicationRecordVersion' => 'IPTC-Modell-2-Version',
@@ -565,6 +1059,56 @@
       },
     },
+   'ApproximateFNumber' => 'F-Wert angenÃ€hert',
+   'ApproximateFocusDistance' => 'Fokus-Distanz angenÃ€hert',
+   'ArtFilter' => {
+      Description => 'Kunst Filter',
+      PrintConv => {
+        'Drawing' => 'Zeichnung',
+        'Fish Eye' => 'Fischauge',
+        'Off' => 'Aus',
+        'Reflection' => 'Reflektierung',
+        'Soft Focus' => 'Weichzeichner',
+        'Soft Focus 2' => 'Weichzeichner 2',
+        'Sparkle' => 'Perleffekt',
+        'Watercolor' => 'Wasserfarbe',
+        'Watercolor II' => 'Wasserfarbe II',
+      },
+    },
+   'ArtFilterEffect' => {
+      Description => 'Filtereffekt Kunst',
+      PrintConv => {
+        'B&W' => 'Schwarz/WeiÃ',
+        'Drawing' => 'Zeichnung',
+        'Fish Eye' => 'Fischauge',
+        'No Effect' => 'Ohne Effekt',
+        'Off' => 'Aus',
+        'Reflection' => 'Reflektierung',
+        'Soft Focus' => 'Weichzeichner',
+        'Soft Focus 2' => 'Weichzeichner 2',
+        'Sparkle' => 'Perleffekt',
+        'Watercolor' => 'Wasserfarbe',
+        'Watercolor II' => 'Wasserfarbe II',
+      },
+    },
+   'ArtMode' => {
+      PrintConv => {
+        'Silent Movie' => 'Stillleben',
+      },
+    },
    'Artist' => 'KÃŒnstler',
+   'ArtworkCreator' => 'Artwork Ersteller',
+   'AsShotICCProfile' => 'Aufnahme Farbprofil',
+   'AsShotNeutral' => 'Aufnahme Neutral',
+   'AsShotPreProfileMatrix' => 'Aufnahme Pre Profil Matrix',
+   'AsShotProfileName' => 'Aufnahme Pre Profilname',
+   'AsShotWhiteXY' => 'Aufnahme WeiÃ XY',
    'AspectRatio' => 'Bildformat',
+   'AssignBktButton' => {
+      Description => 'Zugeordnete Belichtungsreihen-Taste',
+      PrintConv => {
+        'Auto Bracketing' => 'Automatische Belichtungsreihe',
+        'Multiple Exposure' => 'Mehrfachbelichtung',
+      },
+    },
    'AssignFuncButton' => {
       Description => 'FUNC.-Taste zuordnen',
@@ -590,4 +1134,9 @@
         'No' => 'Nein',
         'Yes' => 'Ja',
+      },
+    },
+   'AudioCodecID' => {
+      PrintConv => {
+        'Unknown -' => 'Unbekannt -',
       },
     },
@@ -598,4 +1147,5 @@
    'AudioType' => 'Audiotyp',
    'Author' => 'Autor',
+   'AuthorURL' => 'Autor URL',
    'AuthorsPosition' => 'Autorenposition',
    'AutoAperture' => {
@@ -622,4 +1172,5 @@
         'AE & Flash' => 'Belichtung & Blitz',
         'AE Only' => 'Nur Belichtung',
+        'Exposure' => 'Belichtung',
         'Flash Only' => 'Nur Blitz',
         'WB Bracketing' => 'WeiÃabgleichs-Belichtungsreihe',
@@ -629,9 +1180,34 @@
       Description => 'Automatische Belichtungsreihe',
       PrintConv => {
+        'AE' => 'Belichtung',
+        'Contrast' => 'Kontrast',
+        'Effect' => 'Effekt',
         'No flash & flash' => 'Kein Blitz & Blitz',
         'Off' => 'Aus',
-        'On' => 'An',
-      },
-    },
+        'On' => 'Ein',
+        'Pre-shot' => 'VorauslÃ¶sung',
+        'WB' => 'WeiÃabgleich',
+        'WB2' => 'WeiÃabgleich 2',
+      },
+    },
+   'AutoBracketingSet' => {
+      Description => 'Automatische Belichtungsreihen-Einstellung',
+      PrintConv => {
+        'AE & Flash' => 'Belichtung & Blitz',
+        'AE Only' => 'Nur Belichtung',
+        'Flash Only' => 'Nur Blitz',
+        'WB Bracketing' => 'WeiÃabgleich-Belichtungsreihe',
+      },
+    },
+   'AutoBrightness' => 'Helligkeit Auto',
+   'AutoContrast' => 'Kontrast Auto',
+   'AutoDistortionControl' => {
+      Description => 'Automatische Verzeichnungskontrolle',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'AutoExposure' => 'Belichtung Auto',
    'AutoExposureBracketing' => {
       Description => 'Auto-Belichtungsreihe',
@@ -660,4 +1236,5 @@
         'Off' => 'Aus',
         'On' => 'Ein',
+        'On (high sensitivity)' => 'Ein (Hohe Empfindlichkeit)',
       },
     },
@@ -672,5 +1249,5 @@
         'Off' => 'Aus',
         'Strong' => 'Stark',
-        'n/a' => 'Nicht gesetzt',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -681,4 +1258,10 @@
       },
     },
+   'AutoPortraitFramed' => {
+      PrintConv => {
+        'No' => 'Nein',
+        'Yes' => 'Ja',
+      },
+    },
    'AutoRedEye' => {
       PrintConv => {
@@ -691,10 +1274,11 @@
       PrintConv => {
         'None' => 'Keine',
-        'Rotate 180' => '180Â° (unten/rechts)',
-        'Rotate 270 CW' => '90Â° im Uhrzeigersinn (links/unten)',
-        'Rotate 90 CW' => '90Â° gegen den Uhrzeigersinn (rechts/oben)',
-        'n/a' => 'Unbekannt',
-      },
-    },
+        'Rotate 180' => '180Â° gedreht',
+        'Rotate 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotate 90 CW' => '90Â° im Uhrzeigersinn',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'AutoShadows' => 'Schatten Auto',
    'AuxiliaryLens' => 'Vorsatzlinse',
    'AvApertureSetting' => 'Av Blenden-Einstellung',
@@ -711,7 +1295,13 @@
       PrintConv => {
         'Off' => 'Aus',
-        'On' => 'An',
-      },
-    },
+        'On' => 'Ein',
+      },
+    },
+   'BabyAge' => 'Kindesalter',
+   'BabyName' => 'Kindesname',
+   'BackLight' => 'Hintergrundbeleuchtung',
+   'BackgroundColor' => 'Hintergrundfarbe',
+   'BackgroundColorIndicator' => 'Indikator Hintergrundfarbe',
+   'BackgroundColorValue' => 'Hintergrundfarbwert',
    'BackgroundTiling' => {
       PrintConv => {
@@ -722,10 +1312,15 @@
    'BannerImageType' => {
       PrintConv => {
-        'None' => 'Keine',
+        'None' => 'Keines',
       },
     },
    'BaseExposureCompensation' => 'Basis-Belichtungskorrektur',
    'BaseISO' => 'Basis-ISO',
+   'BaseName' => 'Basisname',
    'BaseURL' => 'Basis URL',
+   'BaselineExposure' => 'Referenzbelichtung',
+   'BaselineExposureOffset' => 'Referenzbelichtung Abweichung',
+   'BaselineNoise' => 'Grundrauschen',
+   'BaselineSharpness' => 'ReferenzschÃ€rfe',
    'BatteryInfo' => 'Stromquelle',
    'BatteryLevel' => 'Batteriestatus',
@@ -737,4 +1332,16 @@
       },
     },
+   'BatteryState' => {
+      Description => 'Batteriestatus',
+      PrintConv => {
+        'Almost full' => 'Fast Voll',
+        'Empty' => 'Leer',
+        'Full' => 'Voll',
+        'Half full' => 'Halb Voll',
+        'Low' => 'Niedrig',
+      },
+    },
+   'BayerGreenSplit' => 'Pixelaufteilung nach Bayer',
+   'BayerPattern' => 'Bayer Matrix',
    'Beep' => {
       Description => 'Tonsignal',
@@ -746,10 +1353,63 @@
       },
     },
+   'BestShotMode' => {
+      Description => 'Bester Aufnahmemodus',
+      PrintConv => {
+        'Autumn Leaves' => 'Herbstlaub',
+        'Baby CS' => 'Kleinkind',
+        'Backlight' => 'Hintergrundbeleuchtung',
+        'Beach' => 'Strand',
+        'Candlelight Portrait' => 'Kerzenlicht PortrÃ€t',
+        'Child CS' => 'Kinder',
+        'Children' => 'Kinder',
+        'Collection' => 'Sammlung',
+        'Fireworks' => 'Feuerwerk',
+        'Flower' => 'Blumen',
+        'Food' => 'Lebensmittel',
+        'For YouTube' => 'FÃŒr YouTube',
+        'For eBay' => 'FÃŒr eBay',
+        'High Sensitivity' => 'Hohe Empfindlichkeit',
+        'Natural Green' => 'NaturgrÃŒn',
+        'Night Scene' => 'Nachtszene',
+        'Night Scene Portrait' => 'Nacht-PortrÃ€t',
+        'People' => 'Menschen',
+        'Pet' => 'Haustiere',
+        'Pet CS' => 'Haustiere',
+        'Portrait' => 'PortrÃ€t',
+        'Silent' => 'Stillleben',
+        'Snow' => 'Schnee',
+        'Sports' => 'Sport',
+        'Sports CS' => 'Sport CS',
+        'Sundown' => 'Sonnenuntergang',
+        'Twilight' => 'DÃ€mmerung',
+        'Underwater' => 'Unterwasser',
+      },
+    },
+   'BigImage' => 'Big Image Vorschaubild',
    'BitDepth' => 'Bit-Tiefe',
    'BitsPerSample' => 'Anzahl der Bits pro Komponente',
+   'BlackLevel' => 'Schwarzwert',
+   'BlackLevel2' => 'Schwarzwert 2',
+   'BlackLevelData' => 'Schwarzwert Daten',
+   'BlackLevelDeltaH' => 'Schwarzwert Delta H',
+   'BlackLevelDeltaV' => 'Schwarzwert Delta V',
    'BlackPoint' => 'Schwarzpunkt',
+   'BlueAdjust' => 'Blau-Korrektur',
    'BlueBalance' => 'Farbabgleich Blau',
+   'BlueHue' => 'Farbton Blau',
    'BlueMatrixColumn' => 'Blau-Matrixspalte',
+   'BlueSaturation' => 'SÃ€ttigung Blau',
    'BlueTRC' => 'Blau-Tonwertwiedergabe-Kurve',
+   'BlueX' => 'Blaupunkt X',
+   'BlueY' => 'Blaupunkt Y',
+   'BlurControl' => {
+      Description => 'Bildstabilisierung',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'Medium' => 'Mittel',
+        'Off' => 'Aus',
+      },
+    },
    'BlurWarning' => {
       Description => 'Verwackelungswarnung',
@@ -777,9 +1437,13 @@
       },
     },
+   'BracketSequence' => 'Belichtungsreihen-Abfolge',
+   'BracketShot' => 'Belichtungsreihen-Aufnahme',
    'BracketShotNumber' => {
       Description => 'Belichtungsreihen-Bildnummer',
       PrintConv => {
+        '1 of 2' => '1 von 2',
         '1 of 3' => '1 von 3',
         '1 of 5' => '1 von 5',
+        '2 of 2' => '2 von 2',
         '2 of 3' => '2 von 3',
         '2 of 5' => '2 von 5',
@@ -788,5 +1452,5 @@
         '4 of 5' => '4 von 5',
         '5 of 5' => '5 von 5',
-        'n/a' => 'Nicht gesetzt',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -801,12 +1465,18 @@
    'BracketValue' => 'Belichtungsreihen-Wert',
    'Brightness' => 'Helligkeit',
+   'BrightnessAdj' => 'Helligkeitskorrektur',
    'BrightnessValue' => 'Helligkeit',
    'BulbDuration' => 'Bulb-Dauer',
    'BurstMode' => {
-      PrintConv => {
-        'Off' => 'Aus',
-        'On' => 'Ein',
-      },
-    },
+      Description => 'Burst Modus',
+      PrintConv => {
+        'Auto Exposure Bracketing (AEB)' => 'Automatische Belichtungsreihe',
+        'Off' => 'Aus',
+        'On' => 'Ein',
+        'Unlimited' => 'Unbegrenzt',
+      },
+    },
+   'BurstMode2' => 'Burst Modus 2',
+   'BurstShot' => 'Burst Aufnahme',
    'ButtonFunctionControlOff' => {
       Description => 'Tastenfunktion wenn Schnelleinstellrad OFF',
@@ -818,10 +1488,21 @@
    'By-line' => 'Ersteller',
    'By-lineTitle' => 'Beruf des Erstellers',
+   'ByteOrder' => 'Bytereihenfolge',
+   'CCDSensitivity' => 'CCD Empfindlichkeit',
+   'CFALayout' => {
+      Description => 'Farbfilter Anordnung',
+      PrintConv => {
+        'Rectangular' => 'Rechteckig',
+      },
+    },
    'CFAPattern' => 'Farbfiltermatrix',
    'CFAPattern2' => 'Farbfiltermatrix 2',
+   'CFAPatternColumns' => 'Farbfiltermatrix Spalten',
+   'CFAPatternRows' => 'Farbfiltermatrix Zeilen',
+   'CFAPatternValues' => 'Farbfiltermatrix Werte',
    'CFARepeatPatternDim' => 'Farbfiltermatrix-GrÃ¶Ãe',
    'CLModeShootingSpeed' => 'Lowspeed-Bildrate',
    'CMContrast' => 'CM Kontrast',
-   'CMExposureCompensation' => 'CM Belichtungsausgleich',
+   'CMExposureCompensation' => 'CM Belichtungskorrektur',
    'CMHue' => 'CM Farbton',
    'CMMFlags' => 'CMM-Flags',
@@ -832,4 +1513,11 @@
    'CMWhiteBalanceGrayPoint' => 'CM WeiÃabgleich Graupunkt',
    'CPUArchitecture' => 'CPU Architektur',
+   'CPUByteOrder' => {
+      Description => 'CPU Bytereihenfolge',
+      PrintConv => {
+        'Big endian' => 'Big-endian',
+        'Little endian' => 'Little-endian',
+      },
+    },
    'CPUCount' => 'Anzahl CPU',
    'CPUFirmwareVersion' => 'CPU-Firmware-Version',
@@ -840,4 +1528,6 @@
         'Any' => 'Unbestimmt',
         'None' => 'Unbestimmt',
+        'i860 big endian' => 'i860 big-endian',
+        'i860 little endian' => 'i860 little-endian',
       },
     },
@@ -889,4 +1579,5 @@
     },
    'CameraBody' => 'Kamera GehÃ€use',
+   'CameraByteOrder' => 'Kamera Bytereihenfolge',
    'CameraCalibration1' => 'Kamerakalibrierung 1',
    'CameraCalibration2' => 'Kamerakalibrierung 2',
@@ -909,18 +1600,32 @@
    'CameraISO' => 'Kamera-ISO',
    'CameraInfo' => 'Pentax-Modell',
+   'CameraInfoByteOrder' => 'Kamerainformation Bytereihenfolge',
    'CameraModel' => 'Kamera Modell',
    'CameraOrientation' => {
-      Description => 'Ausrichtung des Bildes',
-      PrintConv => {
-        'Horizontal (normal)' => '0Â° (oben/links)',
-        'Rotate 270 CW' => '90Â° im Uhrzeigersinn (links/unten)',
-        'Rotate 90 CW' => '90Â° gegen den Uhrzeigersinn (rechts/oben)',
-      },
-    },
+      Description => 'Ausrichtung der Kamera',
+      PrintConv => {
+        'Downwards' => 'AbwÃ€rts',
+        'Rotate 180' => '180Â° gedreht',
+        'Rotate 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotate 90 CW' => '90Â° im Uhrzeigersinn',
+        'Upwards' => 'AufwÃ€rts',
+      },
+    },
+   'CameraProfile' => 'Kameraprofil',
+   'CameraProfileDigest' => 'Kennwert des Kameraprofils',
    'CameraSerialNumber' => 'Kamera-Seriennummer',
    'CameraSettings' => 'Kameraeinstellungen',
    'CameraSettingsVersion' => 'Kameraeinstellungen-Version',
    'CameraTemperature' => 'Kamera-Temperatur',
-   'CameraType' => 'Kameratyp',
+   'CameraType' => {
+      Description => 'Kameratyp',
+      PrintConv => {
+        'Compact' => 'Kompakt',
+        'DV Camera' => 'DV Kamera',
+        'EOS High-end' => 'EOS Highend',
+        'EOS Mid-range' => 'EOS Mittelklasse',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'CameraType2' => 'Kameratyp 2',
    'CanonAFInfo' => 'AF-Info',
@@ -936,4 +1641,5 @@
       },
     },
+   'CanonFileDescription' => 'Canon Dateibeschreibung',
    'CanonFileInfo' => 'Dateiinformationen',
    'CanonFileLength' => 'DateilÃ€nge',
@@ -949,4 +1655,5 @@
         'Red-eye reduction (Auto)' => 'Rote-Augen-Reduzierung (Automatisch)',
         'Red-eye reduction (On)' => 'Rote-Augen-Reduzierung (Ein)',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -973,5 +1680,6 @@
    'CanonImageType' => 'Canon-Bildtyp',
    'CanonImageWidth' => 'Canon-Bildbreite',
-   'CanonModelID' => 'Canon-Modell',
+   'CanonModelID' => 'Canon-Modell ID',
+   'Caption' => 'Bildtext',
    'Caption-Abstract' => 'Beschreibung/Zusammenfassung',
    'CaptionWriter' => 'Bildtextautor',
@@ -986,8 +1694,16 @@
       },
     },
-   'Categories' => 'Kategorien',
+   'CasioImageSize' => 'Casio BildgrÃ¶Ãe',
+   'CatalogSets' => 'Katalogzusammenstellungen',
+   'Categories' => {
+      Description => 'Kategorien',
+      PrintConv => {
+        'People' => 'Menschen',
+        'Scenery' => 'Szene',
+      },
+    },
    'Category' => 'Kategorie',
    'CenterAFArea' => {
-      Description => 'AF-MessfeldgrÃ¶Ãe',
+      Description => 'AF-Messfeld Mitte',
       PrintConv => {
         'Normal Zone' => 'Normal',
@@ -995,6 +1711,13 @@
       },
     },
+   'CenterFocusPoint' => {
+      Description => 'Fokuspunkt Mitte',
+      PrintConv => {
+        'Normal Zone' => 'Normaler Bereich',
+        'Wide Zone' => 'GroÃer Bereich',
+      },
+    },
    'CenterWeightedAreaSize' => {
-      Description => 'MessfeldgrÃ¶Ãe',
+      Description => 'MessfeldgrÃ¶Ãe Mitte',
       PrintConv => {
         'Average' => 'Durchschnitt',
@@ -1005,4 +1728,32 @@
    'Chapter' => 'Kapitel',
    'CharacterSet' => 'Zeichensatz',
+   'Children' => 'Kinder',
+   'ChromaticAberration' => 'Farbabweichung',
+   'ChromaticAberrationB' => 'Farbabweichung B',
+   'ChromaticAberrationBlue' => 'Farbabweichung Blau',
+   'ChromaticAberrationCorr' => {
+      Description => 'Farbabweichung Korrektur',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'ChromaticAberrationCorrection' => {
+      Description => 'Farbabweichung Korrektur',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'ChromaticAberrationOn' => 'Farbabweichung Ein',
+   'ChromaticAberrationR' => 'Farbabweichung R',
+   'ChromaticAberrationRed' => 'Farbabweichung Rot',
+   'ChromaticAberrationSetting' => {
+      Description => 'Farbabweichung Einstellung',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
    'Chromaticity' => 'ChromatizitÃ€t',
    'ChrominanceNR_TIFF_JPEG' => {
@@ -1023,4 +1774,18 @@
    'City' => 'Stadt/Ort',
    'ClassifyState' => 'Klassifizierungs-Status',
+   'CodePage' => {
+      PrintConv => {
+        'Unicode UTF-16, big endian' => 'Unicode UTF-16, Big-endian',
+        'Unicode UTF-16, little endian' => 'Unicode UTF-16, Little-endian',
+        'Unicode UTF-32, big endian' => 'Unicode UTF-32, Big-endian',
+        'Unicode UTF-32, little endian' => 'Unicode UTF-32, Little-endian',
+      },
+    },
+   'CodedCharacterSet' => 'IPTC Characterset',
+   'CodedContentScanningKind' => {
+      PrintConv => {
+        'Unknown' => 'Unbekannt',
+      },
+    },
    'ColorAberrationControl' => {
       PrintConv => {
@@ -1029,23 +1794,34 @@
       },
     },
+   'ColorAdjustment' => 'Farbeinstellung',
    'ColorAdjustmentMode' => {
-      Description => 'Farbtonkorrektur Modus',
-      PrintConv => {
-        'Off' => 'Aus',
-        'On' => 'Ein',
-      },
-    },
+      Description => 'Farbeinstellung Modus',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'ColorBW' => 'Schwarz/WeiÃ',
    'ColorBalance' => 'Farbabgleich',
    'ColorBalance1' => 'Farbabgleich 1',
    'ColorBalanceA' => 'Farbabgleich A',
    'ColorBalanceAdj' => {
-      PrintConv => {
-        'Off' => 'Aus',
-        'On' => 'Ein',
-      },
-    },
-   'ColorBalanceBlue' => 'Farbbalance Blau',
-   'ColorBalanceGreen' => 'Farbbalance GrÃŒn',
-   'ColorBalanceRed' => 'Farbbalance Rot',
+      Description => 'Farbabgleich Korrektur',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'ColorBalanceBlue' => 'Farbabgleich Blau',
+   'ColorBalanceGreen' => 'Farbabgleich GrÃŒn',
+   'ColorBalanceRed' => 'Farbangleich Rot',
+   'ColorBalanceVersion' => 'Farbabgleich Version',
+   'ColorBitDepth' => 'Farbtiefe',
+   'ColorBoostType' => {
+      PrintConv => {
+        'Nature' => 'Natur',
+        'People' => 'Menschen',
+      },
+    },
    'ColorBooster' => {
       PrintConv => {
@@ -1054,9 +1830,13 @@
       },
     },
+   'ColorCompensationFilter' => 'Farbkorrektur-Filter',
    'ColorComponents' => 'Anzahl der Bildkomponenten',
+   'ColorCorrection' => 'Farbkorrektur',
    'ColorDataVersion' => 'Farbdaten Version',
    'ColorEffect' => {
+      Description => 'Farbeffekt',
       PrintConv => {
         'Black & White' => 'Schwarz/WeiÃ',
+        'Cool' => 'KÃŒhl',
         'Off' => 'Aus',
       },
@@ -1084,13 +1864,22 @@
       Description => 'Farbmodus',
       PrintConv => {
+        'Autumn' => 'Herbst',
         'Autumn Leaves' => 'Herbstlaub',
         'B & W' => 'S/W',
-        'B&W' => 'Schwarz-WeiÃ',
+        'B&W' => 'Schwarz/WeiÃ',
+        'B&W Red Filter' => 'Schwarz-WeiÃ Rotfilter',
+        'B&W Yellow Filter' => 'Schwarz-WeiÃ Gelbfilter',
         'Black & White' => 'Schwarz/WeiÃ',
+        'Chrome' => 'Farbe',
         'Clear' => 'Klar',
         'Deep' => 'Tief',
+        'Duotone' => 'Zweiton',
         'Evening' => 'Abends',
+        'Grayscale' => 'Graustufen',
+        'Indexed' => 'Indiziert',
+        'Indexed Color' => 'Indizierte Farben',
         'Landscape' => 'Landschaft',
         'Light' => 'Hell',
+        'Multichannel' => 'Mehrkanal',
         'Natural' => 'NatÃŒrlich',
         'Natural color' => 'NatÃŒrliche Farben',
@@ -1100,11 +1889,13 @@
         'Night Scene' => 'Nachtszene',
         'Night View' => 'Abendszene',
-        'Night View/Portrait' => 'Abendszene',
+        'Night View/Portrait' => 'Abendszene/PortrÃ€t',
         'Off' => 'Aus',
         'Portrait' => 'PortrÃ€t',
+        'RGB Color' => 'RGB Farbe',
         'Solarization' => 'Solarisation',
         'Sunset' => 'Sonnenuntergang',
         'Vivid' => 'Lebhafte Farbe',
         'Vivid color' => 'Lebhafte Farbe',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -1122,4 +1913,8 @@
       },
     },
+   'ColorNoiseReduction' => 'FarbrauschunterdrÃŒckung',
+   'ColorNoiseReductionDetail' => 'FarbrauschunterdrÃŒckung Detail',
+   'ColorPalette' => 'Farbpalette',
+   'ColorPlanes' => 'Farbebenen',
    'ColorProfile' => {
       Description => 'Farbprofil',
@@ -1129,8 +1924,11 @@
       },
     },
+   'ColorRepresentation' => 'Farbdarstellung',
    'ColorReproduction' => 'Farbreproduktion',
+   'ColorSequence' => 'Farbreihenfolge',
    'ColorSpace' => {
       Description => 'Farbraum',
       PrintConv => {
+        'B&W' => 'Schwarz/WeiÃ',
         'ICC Profile' => 'ICC-Profil',
         'Monochrome' => 'Monochrom',
@@ -1138,4 +1936,5 @@
         'Natural+ sRGB' => 'Neutral+ sRGB',
         'Uncalibrated' => 'Nicht festgelegt',
+        'Undefined' => 'Nicht definiert',
       },
     },
@@ -1166,5 +1965,9 @@
    'ColorTempUnknown15' => 'Farbtemperatur Unbekannt 15',
    'ColorTempUnknown16' => 'Farbtemperatur Unbekannt 16',
+   'ColorTempUnknown17' => 'Farbtemperatur Unbekannt 17',
+   'ColorTempUnknown18' => 'Farbtemperatur Unbekannt 18',
+   'ColorTempUnknown19' => 'Farbtemperatur Unbekannt 19',
    'ColorTempUnknown2' => 'Farbtemperatur Unbekannt 2',
+   'ColorTempUnknown20' => 'Farbtemperatur Unbekannt 20',
    'ColorTempUnknown3' => 'Farbtemperatur Unbekannt 3',
    'ColorTempUnknown4' => 'Farbtemperatur Unbekannt 4',
@@ -1175,8 +1978,74 @@
    'ColorTempUnknown9' => 'Farbtemperatur Unbekannt 9',
    'ColorTemperature' => 'Farbtemperatur',
-   'ColorTone' => {
-      Description => 'Farbton',
-      PrintConv => {
-        'Normal' => 'Standard',
+   'ColorTemperatureAdj' => 'Farbtemperaturkorrektur',
+   'ColorTemperatureSetting' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+      },
+    },
+   'ColorTone' => 'Farbton',
+   'ColorToneAdj' => 'Farbtonkorrektur',
+   'ColorToneFaithful' => {
+      Description => 'Farbton NatÃŒrlich',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorToneLandscape' => {
+      Description => 'Farbton Landschaft',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorToneMonochrome' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorToneNeutral' => {
+      Description => 'Farbton Neutral',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorTonePortrait' => {
+      Description => 'Farbton PortrÃ€t',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorToneStandard' => {
+      Description => 'Farbton Standard',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorToneUnknown' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorToneUserDef1' => {
+      Description => 'Farbton Benutzerdefiniert 1',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorToneUserDef2' => {
+      Description => 'Farbton Benutzerdefiniert 2',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorToneUserDef3' => {
+      Description => 'Farbton Benutzerdefiniert 3',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ColorTransform' => {
+      Description => 'Farbtransformation',
+      PrintConv => {
+        'Unknown (RGB or CMYK)' => 'Unbekannt (RGB oder CMYK)',
       },
     },
@@ -1228,4 +2097,5 @@
     },
    'CommanderGroupA_TTL-AAComp' => 'Master-Steuerung Gruppe A TTL/AA Korr',
+   'CommanderGroupA_TTLComp' => 'Master-Steuerung Gruppe-A TTL-Korrektur',
    'CommanderGroupBManualOutput' => 'Master-Steuerung Gruppe B M Korr',
    'CommanderGroupBMode' => {
@@ -1238,4 +2108,5 @@
     },
    'CommanderGroupB_TTL-AAComp' => 'Master-Steuerung Gruppe B TTL/AA Korr',
+   'CommanderGroupB_TTLComp' => 'Master-Steuerung Gruppe-B TTL-Korrektur',
    'CommanderInternalFlash' => {
       Description => 'Master-Steuerung Intgr. Blitz Modus',
@@ -1255,4 +2126,5 @@
       },
     },
+   'ComponentBitDepth' => 'Komponente Farbtiefe',
    'ComponentsConfiguration' => 'Bedeutung jeder Komponente',
    'CompressedBitsPerPixel' => 'Bildkomprimierungsmodus',
@@ -1261,31 +2133,47 @@
       Description => 'Komprimierungsschema',
       PrintConv => {
+        'Bitfields' => 'Bitfelder',
+        'JBIG B&W' => 'JBIG Schwarz-WeiÃ',
+        'JBIG Color' => 'JBIG Farbe',
         'JPEG' => 'JPEG-Komprimierung',
         'JPEG (old-style)' => 'JPEG (alte Version)',
-        'Kodak DCR Compressed' => 'Kodak DCR-komprimiert',
-        'Kodak KDC Compressed' => 'Kodak KDC-komprimiert',
+        'Kodak DCR Compressed' => 'Kodak DCR-Komprimierung',
+        'Kodak KDC Compressed' => 'Kodak KDC-Komprimierung',
         'Next' => 'NeXT 2-Bit Kodierung',
-        'Nikon NEF Compressed' => 'Nikon NEF-komprimiert',
-        'None' => 'Keine',
-        'Pentax PEF Compressed' => 'Pentax PEF-komprimiert',
+        'Nikon NEF Compressed' => 'Nikon NEF-Komprimierung',
+        'None' => 'Keines',
+        'PNG' => 'PNG-Komprimierung',
+        'Pentax PEF Compressed' => 'Pentax PEF-Komprimierung',
         'SGILog' => 'SGI 32-Bit Log Luminance Kodierung',
         'SGILog24' => 'SGI 24-Bit Log Luminance Kodierung',
-        'Sony ARW Compressed' => 'Sony ARW-komprimiert',
+        'Sony ARW Compressed' => 'Sony ARW-Komprimierung',
         'Thunderscan' => 'ThunderScan 4-Bit Kodierung',
         'Uncompressed' => 'Nicht komprimiert',
       },
     },
-   'CompressionFactor' => 'Kompressionsfaktor',
-   'CompressionRatio' => 'Kompressionsrate',
+   'CompressionFactor' => 'Komprimierungsfaktor',
+   'CompressionLevel' => 'Komprimierungsgrad',
+   'CompressionRatio' => 'Komprimierungsrate',
    'CompressionType' => {
-      PrintConv => {
-        'None' => 'Keine',
-      },
-    },
-   'ConditionalFEC' => 'Blitzbelichtungsausgleich',
+      Description => 'Komprimierungsschema',
+      PrintConv => {
+        'Little-endian, no compression' => 'Little-endian, keine Komprimierung',
+        'None' => 'Keines',
+      },
+    },
+   'ConditionalFEC' => 'Blitzbelichtungskorrektur',
    'ConnectionSpaceIlluminant' => 'WeiÃpunkt des Verbindungsfarbraums',
+   'ConstrainedCropHeight' => 'Ausschnitt erzeugte HÃ¶he',
+   'ConstrainedCropWidth' => 'Ausschnitt erzeugte Breite',
    'Contact' => 'Kontakt',
    'ContentLocationCode' => 'Inhaltspositionscode',
    'ContentLocationName' => 'Inhaltspositionsname',
+   'ContinuousBracketing' => {
+      Description => 'Serienbild-Belichtungsreihe',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+      },
+    },
    'ContinuousDrive' => {
       Description => 'Aufnahme-Modus',
@@ -1293,4 +2181,5 @@
         'Continuous' => 'Serienaufnahme',
         'Movie' => 'Filmen',
+        'Silent Single' => 'Stillleben',
         'Single' => 'Einzelbild',
       },
@@ -1313,4 +2202,10 @@
       Description => 'Kontrast',
       PrintConv => {
+        '+1 (medium high)' => '+1 (Leicht erhÃ¶ht)',
+        '+2 (high)' => '+2 (Stark)',
+        '+3 (very high)' => '+3 (Sehr hoch)',
+        '-1 (medium low)' => '-1 (Leicht verringert)',
+        '-2 (low)' => '-2 (Leicht)',
+        '-3 (very low)' => '-3 (Sehr gering)',
         'Film Simulation' => 'Film-Simulation',
         'High' => 'Stark',
@@ -1320,24 +2215,115 @@
         'Medium High' => 'Mittel-Hoch',
         'Medium Low' => 'Mittel-Gering',
-        'Normal' => 'Standard',
         'Very High' => 'Sehr hoch',
         'Very Low' => 'Sehr gering',
-      },
-    },
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'Contrast2012' => 'Kontrast 2012',
+   'ContrastAdj' => 'Kontrastkorrektur',
    'ContrastAdjustment' => 'Kontrastkorrektur',
    'ContrastCurve' => 'Kontrast-Kurve',
+   'ContrastDetectAFArea' => 'AF-Bereich Kontrast gesteuert',
+   'ContrastFaithful' => {
+      Description => 'Kontrast NatÃŒrlich',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ContrastHighlightShadowAdj' => {
+      Description => 'Kontrast helle Stellen',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'ContrastLandscape' => {
+      Description => 'Kontrast Landschaft',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ContrastMode' => {
+      Description => 'Kontrast Modus',
+      PrintConv => {
+        'High' => 'Hoch',
+        'High Dynamic' => 'Hoch dynamisch',
+        'Low' => 'Niedrig',
+        'Low Key' => 'Low-Key',
+        'Medium High' => 'Mitte hoch',
+        'Medium Low' => 'Mitte niedrig',
+      },
+    },
+   'ContrastMonochrome' => {
+      Description => 'Kontrast Monochrom',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ContrastNeutral' => {
+      Description => 'Kontrast Neutral',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ContrastPortrait' => {
+      Description => 'Kontrast PortrÃ€t',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'ContrastSetting' => 'Kontrasteinstellung',
+   'ContrastShadow' => 'Kontrast dunkle Stellen',
+   'ContrastStandard' => {
+      Description => 'Kontrast Standard',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ContrastUnknown' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ContrastUserDef1' => {
+      Description => 'Kontrast Benutzerdefiniert 1',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ContrastUserDef2' => {
+      Description => 'Kontrast Benutzerdefiniert 2',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ContrastUserDef3' => {
+      Description => 'Kontrast Benutzerdefiniert 3',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'Contributor' => 'Mitwirkender',
    'Contributors' => 'Mitwirkende',
+   'ControlDialSet' => {
+      PrintConv => {
+        'Aperture' => 'Blende',
+        'Shutter Speed' => 'Belichtungszeit',
+      },
+    },
    'ControlMode' => {
       Description => 'Steuerungsmethode',
       PrintConv => {
-        'n/a' => 'Nicht gesetzt',
+        'Camera Local Control' => 'Lokale Kamerasteuerung',
+        'Computer Remote Control' => 'Kamerasteuerung per Computer',
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'ConversionLens' => {
+      Description => 'Vorsatzlinse',
       PrintConv => {
         'Macro' => 'Makro',
         'Off' => 'Aus',
+        'Telephoto' => 'Tele',
       },
     },
@@ -1350,17 +2336,52 @@
       },
     },
-   'Country' => 'Staat',
-   'Country-PrimaryLocationCode' => 'ISO-Landescode',
-   'Country-PrimaryLocationName' => 'Staat',
-   'CountryCode' => 'LÃ€nderkennzeichen',
+   'CoringValues' => 'Coring Werte',
+   'Country' => 'Land',
+   'Country-PrimaryLocationCode' => 'ISO-LÃ€ndercode',
+   'Country-PrimaryLocationName' => 'Land',
+   'CountryCode' => 'ISO-LÃ€ndercode',
+   'Coverage' => 'Anwendungsbereich',
    'CreateDate' => 'Digitalisierungsdatum/-uhrzeit',
    'CreationDate' => 'Aufnahmedatum',
-   'CreativeStyle' => 'Kreativmodus',
+   'CreativeStyle' => {
+      Description => 'Kreativmodus',
+      PrintConv => {
+        'Autumn' => 'Herbst',
+        'Autumn Leaves' => 'Herbstlaub',
+        'B&W' => 'Schwarz/WeiÃ',
+        'Clear' => 'Klar',
+        'Deep' => 'Tief',
+        'Landscape' => 'Landschaft',
+        'Light' => 'Hell',
+        'Night View/Portrait' => 'Abendszene/PortrÃ€t',
+        'Portrait' => 'PortrÃ€t',
+        'Sunset' => 'Sonnenuntergang',
+        'Vivid' => 'Lebhafte Farbe',
+      },
+    },
+   'CreativeStyleSetting' => {
+      PrintConv => {
+        'B&W' => 'Schwarz/WeiÃ',
+        'Landscape' => 'Landschaft',
+        'Portrait' => 'PortrÃ€t',
+        'Sunset' => 'Sonnenuntergang',
+      },
+    },
    'Creator' => 'Ersteller',
    'CreatorAddress' => 'Ersteller - Adresse',
+   'CreatorAppID' => {
+      Description => 'Ersteller App ID',
+      PrintConv => {
+        'Unknown' => 'Unbekannt',
+      },
+    },
+   'CreatorAppVersion' => 'Ersteller App Version',
+   'CreatorApplication' => 'Ersteller der Applikation',
    'CreatorCity' => 'Ersteller - Ort',
+   'CreatorContactInfo' => 'Ersteller Kontaktinfo',
    'CreatorCountry' => 'Ersteller - Land',
    'CreatorPostalCode' => 'Ersteller - PLZ',
-   'CreatorRegion' => 'Ersteller - Staat/Provinz',
+   'CreatorRegion' => 'Ersteller - Bundesland/Kanton',
+   'CreatorTool' => 'Erstellertool',
    'CreatorWorkEmail' => 'Ersteller - E-Mail',
    'CreatorWorkTelephone' => 'Ersteller - Telefon',
@@ -1368,4 +2389,5 @@
    'Credit' => 'Anbieter',
    'CropActive' => {
+      Description => 'Ausschnitt aktiviert',
       PrintConv => {
         'No' => 'Nein',
@@ -1373,5 +2395,55 @@
       },
     },
-   'CropHiSpeed' => 'Highspeed-Bildformat',
+   'CropAngle' => 'Ausschnitt Winkel',
+   'CropAspectRatio' => {
+      Description => 'Ausschnitt Bildformat',
+      PrintConv => {
+        'A-size Landscape' => 'DIN A Querformat',
+        'A-size Portrait' => 'DIN A Hochformat',
+        'Circle' => 'Kreis',
+        'Custom' => 'Benutzerdefiniert',
+        'Free' => 'Frei',
+        'Letter-size Landscape' => 'Letter Querformat',
+        'Letter-size Portrait' => 'Letter Querformat',
+      },
+    },
+   'CropBottom' => 'Ausschnitt Unten',
+   'CropBottomMargin' => 'Ausschnitt Rand Unten',
+   'CropCircleActive' => {
+      PrintConv => {
+        'No' => 'Nein',
+        'Yes' => 'Ja',
+      },
+    },
+   'CropHeight' => 'Ausschnitt HÃ¶he',
+   'CropHiSpeed' => 'Ausschnitt Highspeed',
+   'CropLeft' => 'Ausschnitt Links',
+   'CropLeftMargin' => 'Ausschnitt Rand Links',
+   'CropRight' => 'Ausschnitt Rechts',
+   'CropRightMargin' => 'Ausschnitt Rand Rechts',
+   'CropRotation' => 'Ausschnitt Drehung',
+   'CropTop' => 'Ausschnitt Oben',
+   'CropTopMargin' => 'Ausschnitt Rand Oben',
+   'CropUnit' => {
+      Description => 'Ausschnitt Einheit',
+      PrintConv => {
+        'inches' => 'Zoll',
+        'pixels' => 'Pixel',
+      },
+    },
+   'CropUnits' => {
+      Description => 'Ausschnitt Einheiten',
+      PrintConv => {
+        'inches' => 'Zoll',
+        'pixels' => 'Pixel',
+      },
+    },
+   'CropWidth' => 'Ausschnitt Breite',
+   'CroppedImageHeight' => 'Ausschnitt BildhÃ¶he',
+   'CroppedImageLeft' => 'Ausschnitt Bildanfang Links',
+   'CroppedImageTop' => 'Ausschnitt Bildanfang Oben',
+   'CroppedImageWidth' => 'Ausschnitt Bildbreite',
+   'CurrentICCProfile' => 'Aktuelles ICC-Profile',
+   'CurrentIPTCDigest' => 'Aktueller IPTC Kennwert',
    'Curves' => {
       PrintConv => {
@@ -1382,4 +2454,13 @@
    'Custom1' => 'Benutzerdefiniert 1',
    'Custom2' => 'Benutzerdefiniert 2',
+   'Custom3' => 'Benutzerdefiniert 3',
+   'Custom4' => 'Benutzerdefiniert 4',
+   'CustomLinear' => {
+      PrintConv => {
+        'No' => 'Nein',
+        'Yes' => 'Ja',
+      },
+    },
+   'CustomPictureStyleFileName' => 'Benutzer-Bildstil Dateiname',
    'CustomRendered' => {
       Description => 'Benutzerdefinierte Bildverarbeitung',
@@ -1405,4 +2486,10 @@
         'Off' => 'Aus',
         'On' => 'Ein',
+      },
+    },
+   'D-RangeOptimizerMode' => {
+      PrintConv => {
+        'Manual' => 'Manuell',
+        'Off' => 'Aus',
       },
     },
@@ -1415,8 +2502,16 @@
       },
     },
+   'DLOOn' => {
+      PrintConv => {
+        'No' => 'Nein',
+        'Yes' => 'Ja',
+      },
+    },
    'DNGBackwardVersion' => 'DNG VersionskompatibilitÃ€t',
-   'DNGLensInfo' => 'Kleinste Brennweite',
+   'DNGLensInfo' => 'DNG Objektiv-Informationen',
    'DNGVersion' => 'DNG-Version',
+   'DOF' => 'SchÃ€rfentiefe',
    'DSPFirmwareVersion' => 'DSP-Firmware-Version',
+   'DataCompressionMethod' => 'Daten Komprimierungsmethode',
    'DataDump' => 'Daten-Dump',
    'DataDump2' => 'Daten-Dump 2',
@@ -1461,4 +2556,17 @@
     },
    'Declination' => 'Deklination',
+   'DefaultCropOrigin' => 'System-Ausschnitt Beginn',
+   'DefaultCropSize' => 'System-Ausschnitt GrÃ¶Ãe',
+   'DefaultDisplayHeight' => 'Default AnzeigehÃ¶he',
+   'DefaultDisplayWidth' => 'Default Anzeigebreite',
+   'DefaultEraseOption' => {
+      Description => 'System-LÃ¶scheinstellung',
+      PrintConv => {
+        'Cancel selected' => 'Abbruch',
+        'Erase selected' => 'LÃ¶schen',
+      },
+    },
+   'DefaultImageColor' => 'System-Bildfarbe',
+   'DefaultScale' => 'SystemmaÃ',
    'DeletedImageCount' => 'Anzahl gelÃ¶schter Bilder',
    'Description' => 'Beschreibung',
@@ -1475,6 +2583,6 @@
    'DevelopmentDynamicRange' => 'Dynamikbereich Entwicklung',
    'DeviceAttributes' => 'GerÃ€te-Eigenschaften',
-   'DeviceManufacturer' => 'GerÃ€te-Hersteller',
-   'DeviceMfgDesc' => 'GerÃ€te-Hersteller-Bezeichnung',
+   'DeviceManufacturer' => 'GerÃ€tehersteller',
+   'DeviceMfgDesc' => 'GerÃ€tehersteller-Bezeichnung',
    'DeviceModel' => 'GerÃ€te-Modell',
    'DeviceModelDesc' => 'GerÃ€te-Modell-Bezeichnung',
@@ -1489,4 +2597,145 @@
    'DigitalCreationDateTime' => 'Digitalisierungsdatum/-uhrzeit',
    'DigitalCreationTime' => 'Digitalisierungszeit',
+   'DigitalFilter01' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter02' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter03' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter04' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter05' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter06' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter07' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter08' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter09' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter10' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter11' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter12' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter13' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter14' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter15' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter16' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter17' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter18' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter19' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalFilter20' => {
+      PrintConv => {
+        'Color Filter' => 'Farbfilter',
+        'Fisheye' => 'Fischauge',
+        'High Contrast' => 'Hoher Kontrast',
+      },
+    },
+   'DigitalGain' => 'Digitale VerstÃ€rkung',
    'DigitalZoom' => {
       Description => 'Digital-Zoom',
@@ -1508,5 +2757,27 @@
    'DirectoryIndex' => 'Verzeichnis-Index',
    'DirectoryNumber' => 'Ordner-Nummer',
+   'Disclaimer' => 'HaftungsbeschrÃ€nkung',
+   'DisplayAllAFPoints' => {
+      Description => 'Anzeige aller AF-Punkte',
+      PrintConv => {
+        'Disable' => 'Deaktiviert',
+        'Enable' => 'Aktiviert',
+      },
+    },
    'DisplayAperture' => 'Angezeigte Blende',
+   'DisplayHeight' => 'AnzeigehÃ¶he',
+   'DisplayUnit' => {
+      PrintConv => {
+        'Pixels' => 'Pixel',
+        'inches' => 'Zoll',
+      },
+    },
+   'DisplayUnits' => {
+      Description => 'Anzeigeeinheit',
+      PrintConv => {
+        'inches' => 'Zoll',
+        'meters' => 'Meter',
+      },
+    },
    'DisplayXResolutionUnit' => {
       PrintConv => {
@@ -1522,5 +2793,5 @@
       Description => 'Einheit der horiz. AuflÃ¶sung',
       PrintConv => {
-        'inches' => 'Inch',
+        'inches' => 'Zoll',
       },
     },
@@ -1528,22 +2799,49 @@
       Description => 'Einheit der vert. AuflÃ¶sung',
       PrintConv => {
-        'inches' => 'Inch',
+        'inches' => 'Zoll',
+      },
+    },
+   'DistortionControl' => {
+      Description => 'Verzeichnungskontrolle',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
       },
     },
    'DistortionCorrection' => {
-      Description => 'Verzeichnungsausgleich',
-      PrintConv => {
-        'Off' => 'Aus',
-        'On' => 'Ein',
+      Description => 'Verzeichnungskorrektur',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'DistortionCorrection2' => {
-      Description => 'Verzeichnungsausgleich 2',
-      PrintConv => {
-        'Off' => 'Aus',
-        'On' => 'Ein',
-      },
-    },
+      Description => 'Verzeichnungskorrektur 2',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'DistortionCorrectionOn' => 'Verzeichnungskorrektur Ein',
+   'DistortionN' => 'Verzeichnung N',
+   'DistortionParam02' => 'Verzeichnungsparameter 02',
+   'DistortionParam04' => 'Verzeichnungsparameter 04',
+   'DistortionParam08' => 'Verzeichnungsparameter 08',
+   'DistortionParam09' => 'Verzeichnungsparameter 09',
+   'DistortionParam11' => 'Verzeichnungsparameter 11',
+   'DistortionScale' => 'VerzeichnungsausmaÃ',
+   'DistortionVersion' => 'Verzeichnung Version',
    'DjVuVersion' => 'DjVu-Version',
+   'DocSecurity' => {
+      Description => 'Dokumentensicherheit',
+      PrintConv => {
+        'Locked for annotations' => 'Gesperrt fÃŒr Anmerkungen',
+        'None' => 'Keine',
+        'Password protected' => 'Passwort geschÃŒtzt',
+        'Read-only enforced' => 'Nur Lesen - erzwungen',
+        'Read-only recommended' => 'Nur Lesen - vorgeschlagen',
+      },
+    },
    'Document' => 'Dokument',
    'DocumentHistory' => 'Historie des Dokuments',
@@ -1553,10 +2851,18 @@
       Description => 'Aufnahmeart',
       PrintConv => {
+        '10 s Timer' => 'SelbstauslÃ¶ser 10 s',
+        '2 s Timer' => 'SelbstauslÃ¶ser 2 s',
+        'Auto Bracket' => 'Belichtungsreihe',
         'Bracketing' => 'Belichtungsreihe',
         'Continuous' => 'Serienaufnahme',
+        'Continuous (Lo)' => 'Serienaufnahme (Niedrig)',
         'Continuous Bracketing' => 'Serienbild-Belichtungsreihe',
+        'Continuous Exposure Bracketing' => 'Serienaufnahme Belichtungsreihe',
         'Continuous High' => 'Serienaufnahme (Hi)',
+        'Continuous Low' => 'Serienaufnahme Niedrig',
         'Continuous Shooting' => 'Serienaufnahme',
         'HS continuous' => 'High-Speed Serienbild',
+        'Mirror Lock-up' => 'Spiegel hochgeklappt',
+        'Multi Shot' => 'Serienaufnahme',
         'Multiple Exposure' => 'Mehrfachbelichtung',
         'No Timer' => 'Ohne SelbstauslÃ¶ser',
@@ -1564,7 +2870,10 @@
         'Remote Control' => 'FernauslÃ¶ser',
         'Remote Control (3 s delay)' => 'FernauslÃ¶ser (3 Sek. VerzÃ¶gerung)',
+        'Self-Timer 2 sec' => 'SelbstauslÃ¶ser 2 s',
         'Self-timer' => 'SelbstauslÃ¶ser',
         'Self-timer (12 s)' => 'SelbstauslÃ¶ser (12 Sek.)',
         'Self-timer (2 s)' => 'SelbstauslÃ¶ser (2 Sek.)',
+        'Self-timer 10 sec' => 'SelbstauslÃ¶ser 10 s',
+        'Self-timer 2 sec, Mirror Lock-up' => 'SelbstauslÃ¶ser 2 s, Spiegel hochgeklappt',
         'Self-timer Operation' => 'SelbstauslÃ¶ser',
         'Shutter Button' => 'Kamera-AuslÃ¶ser',
@@ -1575,7 +2884,12 @@
         'Single-Frame Bracketing' => 'Einzelbild-Belichtungsreihe',
         'Single-frame' => 'Einzelbild',
+        'Single-frame Bracketing' => 'Einzelbild-Belichtungsreihe',
+        'Single-frame Exposure Bracketing' => 'Einzelbild Belichtungsreihe',
         'Single-frame Shooting' => 'Einzelbild',
         'UHS continuous' => 'Ultra High-Speed Serienbild',
         'White Balance Bracketing' => 'WeiÃabgleichs-Belichtungsreihe',
+        'White Balance Bracketing High' => 'WeiÃabgleich-Belichtungsreihe Hoch',
+        'White Balance Bracketing Low' => 'WeiÃabgleich-Belichtungsreihe Niedrig',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -1583,8 +2897,49 @@
       Description => 'Mehrfachbelichtung',
       PrintConv => {
+        'Continous Bracketing Low' => 'Serienaufnahme Belichtungsreihe Niedrig',
+        'Continuous' => 'Serienaufnahme',
+        'Continuous (Lo)' => 'Serienaufnahme (Niedrig)',
+        'Continuous Bracketing' => 'Serienaufnahme Belichtungsreihe',
+        'Continuous Bracketing 0.3 EV' => 'Serienaufnahme Belichtungsreihe 0.3 EV',
+        'Continuous Bracketing 0.7 EV' => 'Serienaufnahme Belichtungsreihe 0.7 EV',
+        'Continuous Bracketing High' => 'Serienaufnahme Belichtungsreihe Hoch',
+        'Continuous High' => 'Serienaufnahme Hoch',
+        'Continuous Low' => 'Serienaufnahme Niedrig',
+        'Exposure Bracket' => 'Belichtungsreihe',
+        'Mirror Lock-up' => 'Spiegel hochgeklappt',
+        'Multiple Exposure' => 'Mehrfachbelichtung',
+        'Remote Control' => 'FernauslÃ¶ser',
+        'Remote Control (3 s delay)' => 'FernauslÃ¶ser (3 s verzÃ¶gert)',
+        'Self-timer (12 s)' => 'SelbstauslÃ¶ser (12 s)',
+        'Self-timer (2 s)' => 'SelbstauslÃ¶ser (2 s)',
+        'Self-timer 10 sec' => 'SelbstauslÃ¶ser 10 s',
+        'Self-timer 2 sec' => 'SelbstauslÃ¶ser 2 s',
+        'Self-timer 2 sec, Mirror Lock-up' => 'SelbstauslÃ¶ser 2 s, Spiegel hochgeklappt',
+        'Single Frame' => 'Einzelbild',
         'Single-frame' => 'Einzelbildaufnahme',
+        'Single-frame Bracketing' => 'Einzelbild Belichtungsreihe',
+        'Single-frame Bracketing High' => 'Einzelbild Belichtungsreihe Hoch',
+        'Single-frame Bracketing Low' => 'Einzelbild Belichtungsreihe Niedrig',
+        'White Balance Bracketing High' => 'WeiÃabgleich Belichtungsreihe Hoch',
+        'White Balance Bracketing Low' => 'WeiÃabgleich Belichtungsreihe Niedrig',
+      },
+    },
+   'DriveModeSetting' => {
+      Description => 'Aufnahmeart Einstellung',
+      PrintConv => {
+        'Continuous High' => 'Serienaufnahme Hoch',
+        'Continuous Low' => 'Serienaufnahme Niedrig',
+        'Self-timer 10 sec' => 'SelbstauslÃ¶ser 10 s',
+        'Self-timer 2 sec, Mirror Lock-up' => 'SelbstauslÃ¶ser 2 s, Spiegel hochgeklappt',
+        'Single Frame' => 'Einzelbild',
+      },
+    },
+   'DriveType' => {
+      PrintConv => {
+        'Unknown' => 'Unbekannt',
       },
     },
    'Duration' => 'Dauer',
+   'DustRemovalData' => 'Dunstentfernungsdaten',
    'DynamicAFArea' => {
       Description => 'Dynamisches AF-Messfeld',
@@ -1622,4 +2977,16 @@
       },
     },
+   'DynamicRangeOptimizerBracket' => {
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'Off' => 'Aus',
+      },
+    },
+   'DynamicRangeOptimizerMode' => {
+      PrintConv => {
+        'Off' => 'Aus',
+      },
+    },
    'DynamicRangeSetting' => {
       Description => 'Dynamikbereich-Einstellungen',
@@ -1635,5 +3002,4 @@
       },
     },
-   'EMail' => 'E-Mail',
    'ETTLII' => {
       PrintConv => {
@@ -1657,6 +3023,7 @@
       },
     },
+   'EasyExposureComp' => 'Easy Belichtungskorrektur',
    'EasyExposureCompensation' => {
-      Description => 'Belichtungskorrektur',
+      Description => 'Easy Belichtungskorrektur',
       PrintConv => {
         'Off' => 'Aus',
@@ -1670,14 +3037,21 @@
         'Beach' => 'Strand',
         'Black & White' => 'Schwarz/WeiÃ',
+        'Blur Reduction' => 'UnschÃ€rfereduktion',
         'Color Accent' => 'Farbton',
         'Color Swap' => 'Farbwechsel',
+        'Digital Macro' => 'Digitales Makro',
         'Fireworks' => 'Feuerwerk',
         'Foliage' => 'Laub',
+        'Full auto' => 'Vollautomatisch',
         'Indoor' => 'Innenaufnahme',
         'Kids & Pets' => 'Kinder & Tiere',
         'Landscape' => 'Landschaft',
+        'Live View Control' => 'Live View Kontrolle',
+        'Low Light' => 'Wenig Licht',
+        'Low Light 2' => 'Wenig Licht 2',
         'Macro' => 'Makro',
         'Manual' => 'Manuell',
         'Night' => 'Nachtszene',
+        'Night Scene' => 'Nachtszene',
         'Night Snapshot' => 'Nacht Schnappschuss',
         'Pan focus' => 'Pan Fokus',
@@ -1685,9 +3059,13 @@
         'Snow' => 'Schnee',
         'Sports' => 'Sport',
+        'Sunset' => 'Sonnenuntergang',
         'Super Macro' => 'Super-Makro',
-        'Underwater' => 'Tauchen',
+        'Super Macro 2' => 'Super Makro 2',
+        'Underwater' => 'Unterwasser',
+        'Zoom Blur' => 'Zoom UnschÃ€rfe',
       },
     },
    'EdgeNoiseReduction' => {
+      Description => 'RauschunterdrÃŒckung Ecken',
       PrintConv => {
         'Off' => 'Aus',
@@ -1700,7 +3078,19 @@
    'EffectiveLV' => 'Effektiver LW',
    'EffectiveMaxAperture' => 'Effektiv grÃ¶Ãte Blende',
+   'Email' => 'E-Mail',
+   'EmbeddedImage' => 'Eingebettetes Bild',
+   'EmbeddedImageByteOrder' => 'Eingebettetes Bild Bytereihenfolge',
+   'EmbeddedImageHeight' => 'Eingebettetes Bild BildhÃ¶he',
+   'EmbeddedImageType' => 'Eingebettetes Bild Bildtyp',
+   'EmbeddedImageWidth' => 'Eingebettetes Bild Bildbreite',
    'Emphasis' => {
       PrintConv => {
         'None' => 'Keine',
+        'reserved' => 'reserviert',
+      },
+    },
+   'Encoding' => {
+      PrintConv => {
+        'Unknown -' => 'Unbekannt -',
       },
     },
@@ -1708,4 +3098,5 @@
    'Encryption' => 'VerschlÃŒsselung',
    'EnhanceDarkTones' => {
+      Description => 'Dunkle Stellen aufhellen',
       PrintConv => {
         'Off' => 'Aus',
@@ -1719,4 +3110,5 @@
         'Off' => 'Aus',
         'Red' => 'Rot',
+        'Underwater' => 'Unterwasser',
       },
     },
@@ -1724,9 +3116,9 @@
       Description => 'PrioritÃ€t',
       PrintConv => {
-        '0 (reserved)' => '0 (Reserviert fÃŒr zukÃŒnftige Verwendung)',
-        '1 (most urgent)' => '1 (sehr wichtig)',
-        '5 (normal urgency)' => '5 (normale Wichtigkeit)',
+        '0 (reserved)' => '0 (reserviert)',
+        '1 (most urgent)' => '1 (sehr dringend)',
+        '5 (normal urgency)' => '5 (normale Dringlichkeit)',
         '8 (least urgent)' => '8 (geringe Wichtigkeit)',
-        '9 (user-defined priority)' => '9 (Benutzerdefinierte PrioritÃ€t)',
+        '9 (user-defined priority)' => '9 (benutzerdefinierte PrioritÃ€t)',
       },
     },
@@ -1734,4 +3126,5 @@
    'EpsonImageHeight' => 'Epson-BildhÃ¶he',
    'EpsonImageWidth' => 'Epson-Bildbreite',
+   'Equipment' => 'Equipment-IFD-Zeiger',
    'EquipmentVersion' => 'Equipment-Version',
    'Error' => 'Fehler',
@@ -1754,8 +3147,14 @@
    'ExpirationTime' => 'Ablaufzeit',
    'Exposure' => 'Belichtung',
+   'Exposure2012' => 'Belichtung 2012',
+   'ExposureAdj' => 'Belichtungskorrektur',
+   'ExposureAdj2' => 'Belichtungskorrektur 2',
+   'ExposureAdjust' => 'Belichtungskorrektur',
+   'ExposureBias' => 'Belichtungskorrekturwert',
+   'ExposureBracketShotNumber' => 'Belichtungsreihen-Bildnummer',
    'ExposureBracketStepSize' => 'Belichtungsreihen-Stufenabstand',
    'ExposureBracketValue' => 'Belichtungsreihenwert',
    'ExposureCompStepSize' => {
-      Description => 'Belichtungskorrekturwert',
+      Description => 'Belichtungskorrekturstufe',
       PrintConv => {
         '1 EV' => '1 LW',
@@ -1765,4 +3164,6 @@
     },
    'ExposureCompensation' => 'Belichtungskorrektur',
+   'ExposureCompensation2' => 'Belichtungskorrektur 2',
+   'ExposureCompensationMode' => 'Belichtungskorrekturmodus',
    'ExposureControlStepSize' => {
       Description => 'Belichtungswert',
@@ -1795,4 +3196,5 @@
       Description => 'Belichtungsmodus',
       PrintConv => {
+        'Anti Motion Blur' => 'Verwackelungsschutz',
         'Aperture Priority' => 'BlendenprioritÃ€t',
         'Aperture-priority AE' => 'BlendenprioritÃ€t',
@@ -1800,10 +3202,19 @@
         'Auto bracket' => 'Belichtungsreihe',
         'Auto?' => 'Automatisch?',
+        'Backlight Correction HDR' => 'Hintergrundbeleuchtung HDR Korrektur',
+        'Beach' => 'Strand',
         'Bulb' => 'Bulb-Modus',
+        'Fireworks' => 'Feuerwerk',
+        'Food' => 'Lebensmittel',
+        'High Sensitivity' => 'Hohe Empfindlichkeit',
         'Landscape' => 'Landschaft',
+        'Macro' => 'Makro',
         'Manual' => 'Manuelle Belichtung',
-        'Night Scene / Twilight' => 'Nachtszene',
+        'Night Scene / Twilight' => 'Nachtszene / DÃ€mmerung',
+        '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',
@@ -1811,4 +3222,10 @@
         'Shutter Priority' => 'VerschlussprioritÃ€t',
         'Shutter speed priority AE' => 'VerschlussprioritÃ€t',
+        'Snow' => 'Schnee',
+        'Sports' => 'Sport',
+        'Sunset' => 'Sonnenuntergang',
+        'Twilight Portrait' => 'DÃ€mmerung PortÃ€t',
+        'Underwater' => 'Unterwasser',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -1827,15 +3244,22 @@
       PrintConv => {
         'Action (High speed)' => 'Kreativ-Programm (ausgerichtet auf schnelle Verschlussgeschwindigkeit)',
+        'Anti Motion Blur' => 'Verwackelungsschutz',
         'Aperture Priority' => 'BlendenprioritÃ€t',
         'Aperture-priority AE' => 'BlendenprioritÃ€t',
         'Creative (Slow speed)' => 'Kreativ-Programm (ausgerichtet auf SchÃ€rfentiefe)',
-        'Landscape' => 'Landschaftsmodus',
+        'Landscape' => 'Landschaft',
+        'Macro' => 'Makro',
         'Manual' => 'Manuell',
+        'Night Portrait' => 'NachtportrÃ€t',
+        'Night view' => 'Abendszene',
+        'Night view/portrait' => 'Abendszene/PortrÃ€t',
         'Not Defined' => 'Nicht definiert',
-        'Portrait' => 'PortrÃ€t-Modus',
-        'Program' => 'Programm',
-        'Program AE' => 'Normal-Programm',
+        'Portrait' => 'PortrÃ€t',
+        'Program' => 'Programmautomatik',
+        'Program AE' => 'Programmautomatik',
         'Shutter Priority' => 'VerschlussprioritÃ€t',
         'Shutter speed priority AE' => 'VerschlussprioritÃ€t',
+        'Sports' => 'Sport',
+        'Sunset' => 'Sonnenuntergang',
       },
     },
@@ -1859,11 +3283,19 @@
       Description => 'Konverter',
       PrintConv => {
-        'None' => 'Kein',
+        'None' => 'Keiner',
       },
     },
    'ExtenderFirmwareVersion' => 'Konverter-Firmware-Version',
-   'ExtenderMake' => 'Konverter Hersteller',
+   'ExtenderMake' => 'Konverterhersteller',
    'ExtenderModel' => 'Konverter-Modell',
    'ExtenderSerialNumber' => 'Konverter-Seriennummer',
+   'ExtenderStatus' => {
+      Description => 'Status Telekonverter',
+      PrintConv => {
+        'Attached' => 'Angesetzt',
+        'Not attached' => 'Nicht angesetzt',
+        'Removed' => 'Entfernt',
+      },
+    },
    'ExternalFlash' => {
       Description => 'Externer Blitz',
@@ -1873,4 +3305,8 @@
       },
     },
+   'ExternalFlashAE1' => 'Externer Blitz AE1',
+   'ExternalFlashAE1_0' => 'Externer Blitz AE1 0',
+   'ExternalFlashAE2' => 'Externer Blitz AE2',
+   'ExternalFlashAE2_0' => 'Externer Blitz AE2 0',
    'ExternalFlashBounce' => {
       Description => 'Externer Blitz - Bounce',
@@ -1880,7 +3316,8 @@
         'No' => 'Nein',
         'Yes' => 'Ja',
-        'n/a' => 'Nicht gesetzt',
-      },
-    },
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ExternalFlashCompensation' => 'Externe Blitzbelichtungskorrektur',
    'ExternalFlashExposureComp' => {
       Description => 'Belichtungskorrektur des externen BlitzgerÃ€ts',
@@ -1895,9 +3332,21 @@
         '0.5' => '0.5 LW',
         '1.0' => '1.0 LW',
-        'n/a' => 'Nicht gesetzt (Aus oder Auto-Modi)',
+        'n/a' => 'Nicht gesetzt  (Aus oder Auto-Modi)',
         'n/a (Manual Mode)' => 'Nicht gesetzt (Manueller Modus)',
       },
     },
-   'ExternalFlashFlags' => 'Externer Blitz Flags',
+   'ExternalFlashFirmware' => {
+      Description => 'Externer Blitz Firmware',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ExternalFlashFlags' => {
+      Description => 'Externer Blitz Flags',
+      PrintConv => {
+        'Fired' => 'AusgelÃ¶st',
+      },
+    },
+   'ExternalFlashGValue' => 'Externer Blitz Leitzahl',
    'ExternalFlashGuideNumber' => 'Leitzahl des externen BlitzgerÃ€ts',
    'ExternalFlashMode' => {
@@ -1917,17 +3366,80 @@
     },
    'ExternalFlashZoom' => 'Externer Blitz-Zoom',
+   'ExternalSensorBrightnessValue' => 'Externer Sensor Helligkeitswert',
    'ExtraSamples' => 'ZusÃ€tzliche Komponenten',
-   'FEMicroadjustment' => 'FE Feinabstimmung',
+   'FEMicroadjustment' => {
+      Description => 'FE Feinabstimmung',
+      PrintConv => {
+        'Disable' => 'Deaktiviert',
+        'Enable' => 'Aktiviert',
+      },
+    },
    'FNumber' => 'F-Wert',
    'FOV' => 'Sichtfeld',
    'Face0Position' => 'Position, 0. Gesicht',
+   'Face10Position' => 'Position, 10. Gesicht',
+   'Face10Size' => 'GrÃ¶Ãe, 10. Gesicht',
+   'Face11Position' => 'Position, 11. Gesicht',
+   'Face11Size' => 'GrÃ¶Ãe, 11. Gesicht',
+   'Face12Position' => 'Position, 12. Gesicht',
+   'Face12Size' => 'GrÃ¶Ãe, 12. Gesicht',
+   'Face13Position' => 'Position, 13. Gesicht',
+   'Face13Size' => 'GrÃ¶Ãe, 13. Gesicht',
+   'Face14Position' => 'Position, 14. Gesicht',
+   'Face14Size' => 'GrÃ¶Ãe, 14. Gesicht',
+   'Face15Position' => 'Position, 15. Gesicht',
+   'Face15Size' => 'GrÃ¶Ãe, 15. Gesicht',
+   'Face16Position' => 'Position, 16. Gesicht',
+   'Face16Size' => 'GrÃ¶Ãe, 16. Gesicht',
+   'Face17Position' => 'Position, 17. Gesicht',
+   'Face17Size' => 'GrÃ¶Ãe, 17. Gesicht',
+   'Face18Position' => 'Position, 18. Gesicht',
+   'Face18Size' => 'GrÃ¶Ãe, 18. Gesicht',
+   'Face19Position' => 'Position, 19. Gesicht',
+   'Face19Size' => 'GrÃ¶Ãe, 19. Gesicht',
    'Face1Position' => 'Position, 1. Gesicht',
+   'Face1Size' => 'GrÃ¶Ãe, 1. Gesicht',
+   'Face20Position' => 'Position, 20. Gesicht',
+   'Face20Size' => 'GrÃ¶Ãe, 20. Gesicht',
+   'Face21Position' => 'Position, 21. Gesicht',
+   'Face21Size' => 'GrÃ¶Ãe, 21. Gesicht',
+   'Face22Position' => 'Position, 22. Gesicht',
+   'Face22Size' => 'GrÃ¶Ãe, 22. Gesicht',
+   'Face23Position' => 'Position, 23. Gesicht',
+   'Face23Size' => 'GrÃ¶Ãe, 23. Gesicht',
+   'Face24Position' => 'Position, 24. Gesicht',
+   'Face24Size' => 'GrÃ¶Ãe, 24. Gesicht',
+   'Face25Position' => 'Position, 25. Gesicht',
+   'Face25Size' => 'GrÃ¶Ãe, 25. Gesicht',
+   'Face26Position' => 'Position, 26. Gesicht',
+   'Face26Size' => 'GrÃ¶Ãe, 26. Gesicht',
+   'Face27Position' => 'Position, 27. Gesicht',
+   'Face27Size' => 'GrÃ¶Ãe, 27. Gesicht',
+   'Face28Position' => 'Position, 28. Gesicht',
+   'Face28Size' => 'GrÃ¶Ãe, 28. Gesicht',
+   'Face29Position' => 'Position, 29. Gesicht',
+   'Face29Size' => 'GrÃ¶Ãe, 29. Gesicht',
    'Face2Position' => 'Position, 2. Gesicht',
+   'Face2Size' => 'GrÃ¶Ãe, 2. Gesicht',
+   'Face30Position' => 'Position, 30. Gesicht',
+   'Face30Size' => 'GrÃ¶Ãe, 30. Gesicht',
+   'Face31Position' => 'Position, 31. Gesicht',
+   'Face31Size' => 'GrÃ¶Ãe, 31. Gesicht',
+   'Face32Position' => 'Position, 32. Gesicht',
+   'Face32Size' => 'GrÃ¶Ãe, 32. Gesicht',
    'Face3Position' => 'Position, 3. Gesicht',
+   'Face3Size' => 'GrÃ¶Ãe, 3. Gesicht',
    'Face4Position' => 'Position, 4. Gesicht',
+   'Face4Size' => 'GrÃ¶Ãe, 4. Gesicht',
    'Face5Position' => 'Position, 5. Gesicht',
+   'Face5Size' => 'GrÃ¶Ãe, 5. Gesicht',
    'Face6Position' => 'Position, 6. Gesicht',
+   'Face6Size' => 'GrÃ¶Ãe, 6. Gesicht',
    'Face7Position' => 'Position, 7. Gesicht',
+   'Face7Size' => 'GrÃ¶Ãe, 7. Gesicht',
    'Face8Position' => 'Position, 8. Gesicht',
+   'Face8Size' => 'GrÃ¶Ãe, 8. Gesicht',
+   'Face9Position' => 'Position, 9. Gesicht',
+   'Face9Size' => 'GrÃ¶Ãe, 9. Gesicht',
    'FaceDetect' => {
       Description => 'Gesichtserkennung',
@@ -1938,6 +3450,22 @@
     },
    'FaceDetectArea' => 'Gesichtserkennung Bereich',
-   'FaceDetectFrameSize' => 'BereichsgrÃ¶Ãe',
-   'FacesDetected' => 'Gesichter erkannt',
+   'FaceDetectFrameSize' => 'Gesichtserkennung BereichsgrÃ¶Ãe',
+   'FaceInfoUnknown' => 'Gesichterinformation Unbekannt',
+   'FaceOrientation' => {
+      Description => 'Ausrichtung Gesichtserkennung',
+      PrintConv => {
+        'Rotate 180' => '180Â° gedreht',
+        'Rotate 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotate 90 CW' => '90Â° im Uhrzeigersinn',
+      },
+    },
+   'FacePositions' => 'Positionen der Gesichter',
+   'FacesDetected' => {
+      Description => 'Gesichter erkannt',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FacesRecognized' => 'Gesichter erkannt',
    'FastSeek' => {
       PrintConv => {
@@ -1947,4 +3475,5 @@
     },
    'FaxProfile' => {
+      Description => 'Faxprofil',
       PrintConv => {
         'Unknown' => 'Unbekannt',
@@ -1954,9 +3483,13 @@
    'FaxRecvTime' => 'Fax-Empfangszeit',
    'FaxSubAddress' => 'Fax-Sub-Adresse',
+   'FileAccessDate' => 'Datum/Uhrzeit des letzten Dateizugriffs',
+   'FileCreateDate' => 'Datum/Uhrzeit der Dateierstellung',
    'FileDescription' => 'Dateibeschreibung',
+   'FileExtension' => 'Dateiendung',
    'FileFormat' => 'Dateiformat',
    'FileIndex' => 'Datei-Index',
    'FileInfo' => 'Datei-Informationen',
    'FileInfoVersion' => 'Datei-Informationen-Version',
+   'FileInodeChangeDate' => 'Datum/Uhrzeit der letzten Inode-Ãnderung',
    'FileModifyDate' => 'Datum/Uhrzeit der DateiÃ€nderung',
    'FileName' => 'Dateiname',
@@ -1977,4 +3510,5 @@
     },
    'FilePermissions' => 'Dateiberechtigungen',
+   'FileSequence' => 'Dateireihenfolge',
    'FileSize' => 'DateigrÃ¶Ãe',
    'FileSource' => {
@@ -1984,8 +3518,11 @@
         'Film Scanner' => 'Film-Scanner',
         'Reflection Print Scanner' => 'Scanner',
+        'Sigma Digital Camera' => 'Sigma Digital-Kamera',
       },
     },
    'FileType' => 'Dateityp',
+   'FileTypeDescription' => 'Dateityp Beschreibung',
    'FileVersion' => 'Dateiformatversion',
+   'Filename' => 'Dateiname',
    'FillFlashAutoReduction' => {
       Description => 'E-TTL II-Automatikblitz-System',
@@ -2000,12 +3537,14 @@
         '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' => 'F1b/Studio-PortrÃ€t Weiche HauttÃ¶ne',
+        '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)',
       },
     },
    'FilmType' => 'Filmtyp',
    'FilterEffect' => {
-      Description => 'Filter-Effekt',
+      Description => 'Filtereffekt',
       PrintConv => {
         'Green' => 'GrÃŒn',
@@ -2014,13 +3553,85 @@
         'Red' => 'Rot',
         'Yellow' => 'Gelb',
-        'n/a' => 'Nicht gesetzt',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectFaithful' => {
+      Description => 'Filtereffekt NatÃŒrlich',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectLandscape' => {
+      Description => 'Filtereffekt Landschaft',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'FilterEffectMonochrome' => {
+      Description => 'Filtereffekt Monochrom',
       PrintConv => {
         'Green' => 'GrÃŒn',
-        'None' => 'Keine',
+        'None' => 'Keiner',
         'Red' => 'Rot',
         'Yellow' => 'Gelb',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectNeutral' => {
+      Description => 'Filtereffekt Neutral',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectPortrait' => {
+      Description => 'Filtereffekt PortrÃ€t',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectStandard' => {
+      Description => 'Filtereffekt Standard',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectUnknown' => {
+      Description => 'Filtereffekt Unbekannt',
+      PrintConv => {
+        'Green' => 'GrÃŒn',
+        'None' => 'Keiner',
+        'Red' => 'Rot',
+        'Yellow' => 'Gelb',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectUserDef1' => {
+      Description => 'Filtereffekt Benutzerdefiniert 1',
+      PrintConv => {
+        'Green' => 'GrÃŒn',
+        'None' => 'Keiner',
+        'Red' => 'Rot',
+        'Yellow' => 'Gelb',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectUserDef2' => {
+      Description => 'Filtereffekt Benutzerdefineirt 2',
+      PrintConv => {
+        'Green' => 'GrÃŒn',
+        'None' => 'Keiner',
+        'Red' => 'Rot',
+        'Yellow' => 'Gelb',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FilterEffectUserDef3' => {
+      Description => 'Filtereffekt Benutzerdefiniert 3',
+      PrintConv => {
+        'Green' => 'GrÃŒn',
+        'None' => 'Keiner',
+        'Red' => 'Rot',
+        'Yellow' => 'Gelb',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -2032,12 +3643,21 @@
       },
     },
-   'FineTuneOptCenterWeighted' => 'Feinabst. der Bel.Messung Mittenbetonte Messung',
-   'FineTuneOptMatrixMetering' => 'Feinabst. der Bel.Messung Matrixmessung',
-   'FineTuneOptSpotMetering' => 'Feinabst. der Bel.Messung Spotmessung',
+   'FineSharpness' => {
+      Description => 'Detail-SchÃ€rfe',
+      PrintConv => {
+        'Extra fine' => 'Extra',
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'FineTuneOptCenterWeighted' => 'Feinabstimmung Mittenbetonte Messung',
+   'FineTuneOptMatrixMetering' => 'Feinabstimmung Matrixmessung',
+   'FineTuneOptSpotMetering' => 'Feinabstimmung Spotmessung',
    'FirmwareRevision' => 'Firmware-Revision',
+   'FirmwareRevision2' => 'Firmware-Revision 2',
    'FirmwareVersion' => 'Firmware-Version',
    'FixtureIdentifier' => 'Kennzeichnung',
    'Flash' => {
-      Description => 'Blitz',
+      Description => 'Blitzmodus',
       PrintConv => {
         'Auto, Did not fire' => 'Blitz wurde nicht ausgelÃ¶st, Automodus',
@@ -2073,7 +3693,25 @@
       },
     },
+   'FlashAction2' => {
+      PrintConv => {
+        'Did not fire' => 'Blitz wurde nicht ausgelÃ¶st',
+        'Fired' => 'Blitz wurde ausgelÃ¶st',
+      },
+    },
    'FlashActivity' => 'Blitz-Leistung',
    'FlashBatteryLevel' => 'Blitz Batteriestatus',
-   'FlashBits' => 'Blitz-Details',
+   'FlashBias' => 'Blitzkorrektur',
+   'FlashBits' => {
+      Description => 'Blitz-Details',
+      PrintConv => {
+        '2nd-curtain sync used' => 'Synchronisatiopn auf 2. VerschluÃvorhang',
+        'Built-in' => 'Integrierter Blitz',
+        'External' => 'Extern',
+        'FP sync enabled' => 'FP Synchronisation eingestellt',
+        'FP sync used' => 'FP Synchronistaion',
+        'Manual' => 'Manuell',
+      },
+    },
+   'FlashColorFilter' => 'Blitz Farbfilter',
    'FlashCommanderMode' => {
       Description => 'Master-Steuerung',
@@ -2084,4 +3722,9 @@
     },
    'FlashCompensation' => 'Blitzbelichtungs-Korrektur',
+   'FlashControlBuilt-in' => {
+      PrintConv => {
+        'Commander Mode' => 'Master-Steuerung',
+      },
+    },
    'FlashControlMode' => {
       Description => 'Blitzlichtsteuerungsmodus',
@@ -2091,4 +3734,17 @@
         'Off' => 'Aus',
         'Repeating Flash' => 'Stroboskopblitz',
+      },
+    },
+   'FlashCurtain' => {
+      Description => 'Blitzsynchronisation auf VerschluÃ',
+      PrintConv => {
+        '1st' => '1. Vorhang',
+        '2nd' => '2. Vorhang',
+      },
+    },
+   'FlashDefault' => {
+      Description => 'Systemblitz',
+      PrintConv => {
+        'Fill Flash' => 'Aufhellblitz',
       },
     },
@@ -2099,12 +3755,48 @@
         'Internal' => 'Intern',
         'Internal + External' => 'Intern + Extern',
-        'None' => 'Keins',
-      },
-    },
+        'None' => 'Keines',
+      },
+    },
+   'FlashDistance' => 'Blitzabstand',
    'FlashEnergy' => 'BlitzstÃ€rke',
    'FlashExposureBracketValue' => 'Blitzbelichtungsreihenwert',
-   'FlashExposureComp' => 'Blitzbelichtungsausgleich',
+   'FlashExposureComp' => 'Blitzbelichtungskorrektur',
+   'FlashExposureComp2' => 'Blitzbelichtungskorrektur 2',
+   'FlashExposureComp3' => 'Blitzbelichtungskorrektur 3',
+   'FlashExposureComp4' => 'Blitzbelichtungskorrektur 4',
    'FlashExposureCompSet' => 'Eingestellte Blitz-Belichtungskorrektur',
+   'FlashExposureCompSet2' => 'Blitzbelichtungskorrektur 2',
+   'FlashExposureIndicator' => {
+      Description => 'Blitz-Belichtungsindikator',
+      PrintConv => {
+        'Bottom of Scale' => 'Unterer Wert',
+        'Not Indicated' => 'Nicht angezeigt',
+        'Over Scale' => 'Wert zu hoch',
+        'Top of Scale' => 'Oberer Wert',
+        'Under Scale' => 'Wert zu niedrig',
+      },
+    },
+   'FlashExposureIndicatorLast' => {
+      Description => 'Blitz-Ende-Belichtungsindikator',
+      PrintConv => {
+        'Bottom of Scale' => 'Unterer Wert',
+        'Not Indicated' => 'Nicht angezeigt',
+        'Over Scale' => 'Wert zu hoch',
+        'Top of Scale' => 'Oberer Wert',
+        'Under Scale' => 'Wert zu niedrig',
+      },
+    },
+   'FlashExposureIndicatorNext' => {
+      Description => 'Blitz-Folge-Belichtungsindikator',
+      PrintConv => {
+        'Bottom of Scale' => 'Unterer Wert',
+        'Not Indicated' => 'Nicht angezeigt',
+        'Over Scale' => 'Wert zu hoch',
+        'Top of Scale' => 'Oberer Wert',
+        'Under Scale' => 'Wert zu niedrig',
+      },
+    },
    'FlashExposureLock' => {
+      Description => 'Blitzbelichtung-Speicherung',
       PrintConv => {
         'Off' => 'Aus',
@@ -2115,5 +3807,7 @@
       Description => 'Blitz wurde ausgelÃ¶st',
       PrintConv => {
+        'False' => 'Nein',
         'No' => 'Nein',
+        'True' => 'Ja',
         'Yes' => 'Ja',
       },
@@ -2128,5 +3822,21 @@
    'FlashFirmwareVersion' => 'Blitz-Firmware-Version',
    'FlashFocalLength' => 'Blitz-Brennweite',
-   'FlashGNDistance' => 'Blitzleitzahl Entfernung',
+   'FlashFunction' => {
+      Description => 'Blitzfunktion',
+      PrintConv => {
+        'Built-in flash' => 'Integrierter Blitz',
+        'False' => 'Nein',
+        'Manual' => 'Manuell',
+        'No flash' => 'Kein Blitz',
+        'Strobe' => 'Stroboskop',
+        'True' => 'Ja',
+      },
+    },
+   'FlashGNDistance' => {
+      Description => 'Blitzleitzahl Entfernung',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'FlashGroupACompensation' => 'Gruppe A, Blitzbelichtungs-Korrektur',
    'FlashGroupAControlMode' => {
@@ -2167,4 +3877,5 @@
    'FlashInfoVersion' => 'Blitz-Informationen-Version',
    'FlashIntensity' => {
+      Description => 'Blitz StÃ€rke',
       PrintConv => {
         'High' => 'Hoch',
@@ -2172,6 +3883,12 @@
       },
     },
-   'FlashLevel' => 'Blitzbelichtungskorr.',
-   'FlashMake' => 'BlitzgerÃ€t-Hersteller',
+   'FlashLevel' => {
+      Description => 'Blitzbelichtungskorr.',
+      PrintConv => {
+        'High' => 'Hoch',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'FlashMake' => 'BlitzgerÃ€tehersteller',
    'FlashMetering' => {
       Description => 'Blitz-Messung',
@@ -2179,4 +3896,12 @@
         'Manual flash control' => 'Manuelle Blitz-Kontrolle',
         'Pre-flash TTL' => 'Vorblitz TTL',
+      },
+    },
+   'FlashMeteringMode' => {
+      Description => 'Blitz-Belichtungsmessmethode',
+      PrintConv => {
+        'External Auto' => 'Extern Automatisch',
+        'External Manual' => 'Extern Manuell',
+        'Off' => 'Aus',
       },
     },
@@ -2185,4 +3910,5 @@
       Description => 'Blitz-Modus',
       PrintConv => {
+        '2nd Curtain' => 'Auf 2. VerschluÃvorhang',
         'Auto' => 'Automatisch',
         'Auto, Did not fire' => 'Auto, nicht ausgelÃ¶st',
@@ -2191,4 +3917,5 @@
         'Auto, Fired, Red-eye reduction' => 'Auto, ausgelÃ¶st, Rote-Augen-Reduzierung',
         'Did Not Fire' => 'Nicht ausgelÃ¶st',
+        'Disabled' => 'Deaktiviert',
         'External, Auto' => 'Extern, Auto',
         'External, Contrast-control Sync' => 'Extern, Kontrast-Steuerungs-Synchronisation',
@@ -2200,4 +3927,5 @@
         'External, Wireless, High-speed Sync' => 'Extern, Drahtlos, High-Speed-Synchronisation',
         'Fill flash' => 'Aufhellblitz',
+        'Fill-in' => 'Aufhellen',
         'Fired, Commander Mode' => 'AusgelÃ¶st, Befehlsmodus',
         'Fired, External' => 'AusgelÃ¶st, Extern',
@@ -2205,4 +3933,5 @@
         'Fired, TTL Mode' => 'AusgelÃ¶st, TTL-Modus',
         'Internal' => 'Intern',
+        'Not Ready' => 'Nicht bereit',
         'Off' => 'Aus',
         'Off, Did not fire' => 'Aus',
@@ -2210,4 +3939,5 @@
         'On' => 'Ein',
         'On, Did not fire' => 'Ein, nicht ausgelÃ¶st',
+        'On, Did not fire, Wireless (Master)' => 'Ein, nicht ausgelÃ¶st, Drahtlos (Hauptblitz)',
         'On, Fired' => 'Ein',
         'On, Red-eye reduction' => 'Ein, Rote-Augen-Reduzierung',
@@ -2219,4 +3949,5 @@
         'On, Wireless (Master)' => 'Ein, Drahtlos (Hauptblitz)',
         'Rear flash sync' => 'Synchronisation auf den zweiten Verschlussvorhang',
+        'Red eye' => 'Rote-Augen-Reduzierung',
         'Red-eye' => 'Rote Augen',
         'Red-eye Reduction' => 'Rote-Augen-Reduzierung',
@@ -2260,4 +3991,27 @@
     },
    'FlashOutput' => 'BlitzstÃ€rke',
+   'FlashRedEyeMode' => {
+      Description => 'Blitz Rote-Augen-Modus',
+      PrintConv => {
+        'False' => 'Nein',
+        'True' => 'Ja',
+      },
+    },
+   'FlashRemoteControl' => {
+      Description => 'Blitz FernauslÃ¶ser',
+      PrintConv => {
+        'Off' => 'Aus',
+      },
+    },
+   'FlashReturn' => {
+      Description => 'Blitz Reflexion',
+      PrintConv => {
+        'No return detection' => 'Keine Erkennung',
+        'Return detected' => 'Reflexion erkannt',
+        'Return not detected' => 'Reflexion nicht erkannt',
+        'Subject Inside Flash Range' => 'Objekt innerhalb der Blitzreichweite',
+        'Subject Outside Flash Range' => 'Objekt ausserhalb der Blitzreichweite',
+      },
+    },
    'FlashSerialNumber' => 'Blitz-Seriennummer',
    'FlashSetting' => 'Blitzeinstellung',
@@ -2266,11 +4020,19 @@
       Description => 'Slave-Blitz-Messfeld 1',
       PrintConv => {
+        'Built-in Flash present' => 'Integrierter Blitz vorhanden',
+        'Built-in Flash present and fired' => 'Integrierter Blitz vorhanden und ausgelÃ¶st',
+        'External Flash present' => 'Externer Blitz vorhanden',
+        'External Flash present and fired' => 'Externer Blitz vorhanden und ausgelÃ¶st',
         'External, Did not fire' => 'Extern, nicht ausgelÃ¶st',
         'External, Fired' => 'Extern, ausgelÃ¶st',
         'Internal, Did not fire' => 'Intern, nicht ausgelÃ¶st',
+        'Internal, Did not fire (0x08)' => 'Intern, nicht ausgelÃ¶st',
         'Internal, Fired' => 'Intern, ausgelÃ¶st',
-        'Off' => 'Aus',
-      },
-    },
+        'No Flash present' => 'Kein Blitz vorhanden',
+        'Off' => 'Aus',
+        'Off (1)' => 'Aus (1)',
+      },
+    },
+   'FlashSyncMode' => 'Blitz-Synchronisationsmodus',
    'FlashSyncSpeed' => 'Blitzsynchronzeit',
    'FlashSyncSpeedAv' => {
@@ -2285,4 +4047,5 @@
       },
     },
+   'FlashTTLMode' => 'Blitz TTL-Modus',
    'FlashType' => {
       Description => 'Blitztyp',
@@ -2316,19 +4079,19 @@
    'FocalLength35efl' => 'Brennweite',
    'FocalLengthIn35mmFormat' => 'Brennweite in 35 mm-Kleinbildformat',
-   'FocalPlaneDiagonal' => 'Diagonale der Fokalebene',
+   'FocalPlaneDiagonal' => 'Diagonale des Sensors',
    'FocalPlaneResolutionUnit' => {
       Description => 'Einheit der SensorauflÃ¶sung',
       PrintConv => {
         'None' => 'Keine',
-        'inches' => 'Inch',
+        'inches' => 'Zoll',
         'um' => 'Âµm (Mikrometer)',
       },
     },
    'FocalPlaneXResolution' => 'SensorauflÃ¶sung horizontal',
-   'FocalPlaneXSize' => 'Breite der Fokal-Ebene',
-   'FocalPlaneXUnknown' => 'Breite der Fokal-Ebene',
+   'FocalPlaneXSize' => 'SensorgrÃ¶Ãe horizontal',
+   'FocalPlaneXUnknown' => 'SensorgrÃ¶Ãe horizontal unbekannt',
    'FocalPlaneYResolution' => 'SensorauflÃ¶sung vertikal',
-   'FocalPlaneYSize' => 'HÃ¶he der Fokal-Ebene',
-   'FocalPlaneYUnknown' => 'HÃ¶he der Fokal-Ebene',
+   'FocalPlaneYSize' => 'SensorgrÃ¶Ãe vertikal',
+   'FocalPlaneYUnknown' => 'SensorgrÃ¶Ãe vertikal unbekannt',
    'FocalType' => {
       Description => 'Objektivart',
@@ -2338,8 +4101,10 @@
       },
     },
-   'FocalUnits' => '"focal units" pro mm',
+   'FocalUnits' => 'Fokussiereinheit',
    'Focus' => {
       Description => 'SchÃ€rfeprioritÃ€t',
       PrintConv => {
+        'Auto-focus Didn\'t Lock' => 'Autofokus nicht gesperrt',
+        'Auto-focus Locked' => 'Autofokus gesperrt',
         'Manual' => 'Manuell',
       },
@@ -2364,4 +4129,10 @@
         'Continuous' => 'Serienaufnahme',
         'Manual' => 'Manuell',
+      },
+    },
+   'FocusDisplayAIServoAndMF' => {
+      PrintConv => {
+        'Disable' => 'Deaktiviert',
+        'Enable' => 'Aktiviert',
       },
     },
@@ -2369,4 +4140,5 @@
    'FocusDistanceLower' => 'Nahe Fokus-Distanz',
    'FocusDistanceUpper' => 'Entfernte Fokus-Distanz',
+   'FocusInfoVersion' => 'FokusInfo Version',
    'FocusMode' => {
       Description => 'Fokus-Modus',
@@ -2392,4 +4164,5 @@
         'Single AF' => 'Einpunkt AF',
         'Super Macro' => 'Super-Makro',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -2411,4 +4184,10 @@
       },
     },
+   'FocusModeSwitch' => {
+      Description => 'Fokus-Modus Schalter',
+      PrintConv => {
+        'Manual' => 'Manuell',
+      },
+    },
    'FocusPixel' => 'Fokus-Pixel',
    'FocusPointWrap' => {
@@ -2419,4 +4198,5 @@
       },
     },
+   'FocusPos' => 'Fokus-Position',
    'FocusPosition' => 'Fokus-Distanz',
    'FocusProcess' => {
@@ -2443,7 +4223,14 @@
       },
     },
+   'FocusStepCount' => 'Fokus-StufenzÃ€hler',
+   'FocusStepInfinity' => 'Fokus-Stufe Unendlich',
+   'FocusStepNear' => 'Fokus-Stufe Nah',
    'FocusTrackingLockOn' => {
       Description => 'SchÃ€rfenarchiv. mit Lock-On',
       PrintConv => {
+        '1 (Short)' => '5 (Kurz)',
+        '1 Short' => '1 Kurz',
+        '5 (Long)' => '5 (Lang)',
+        '5 Long' => '5 Lang',
         'Long' => 'Lang',
         'Off' => 'Aus',
@@ -2460,7 +4247,9 @@
    'FocusingScreen' => 'Mattscheibe',
    'FolderName' => 'Ordner-Name',
+   'FrameHeight' => 'BereichshÃ¶he',
    'FrameNumber' => 'Bildnummer',
    'FrameRate' => 'Bildwechselfrequenz',
    'FrameSize' => 'EinzelbildgrÃ¶Ãe',
+   'FrameWidth' => 'Bereichsbreite',
    'FreeByteCounts' => 'Anzahl Bytes des leeren Datenbereiches',
    'FreeMemoryCardImages' => 'Platz auf Speicherkarten fÃŒr',
@@ -2476,8 +4265,10 @@
       },
     },
+   'FullImageSize' => 'Volle BildgrÃ¶Ãe',
    'FunctionButton' => {
       Description => 'Funktionstaste',
       PrintConv => {
         'AF-area Mode' => 'Messfeldsteuerung',
+        'Auto Bracketing' => 'Belichtungsreihe',
         'Center AF Area' => 'AF-MessfeldgrÃ¶Ãe',
         'Center-weighted' => 'Mittenbetont',
@@ -2486,12 +4277,15 @@
         'Framing Grid' => 'Gitterlinien',
         'ISO Display' => 'ISO-Anzeige',
+        'Image Quality' => 'BildqualitÃ€t',
         'Matrix Metering' => 'Matrixmessung',
         'Spot Metering' => 'Spotmessung',
-      },
-    },
+        'White Balance' => 'WeiÃabgleich',
+      },
+    },
+   'GEImageSize' => 'GE BildgrÃ¶Ãe',
    'GIFVersion' => 'GIF-Version',
-   'GPSAltitude' => 'HÃ¶he',
+   'GPSAltitude' => 'GPS HÃ¶he',
    'GPSAltitudeRef' => {
-      Description => 'BezugshÃ¶he',
+      Description => 'GPS-HÃ¶he Bezug',
       PrintConv => {
         'Above Sea Level' => 'HÃ¶he ÃŒber Normal-Null (Meeresspiegel)',
@@ -2502,5 +4296,5 @@
    'GPSDOP' => 'Messgenauigkeit',
    'GPSDateStamp' => 'GPS Datum',
-   'GPSDateTime' => 'GPS-Zeit (Atomuhr)',
+   'GPSDateTime' => 'GPS Zeitstempel',
    'GPSDestBearing' => 'Motivrichtung',
    'GPSDestBearingRef' => {
@@ -2511,7 +4305,7 @@
       },
     },
-   'GPSDestDistance' => 'Distanz zum Ziel',
+   'GPSDestDistance' => 'GPS Zielentfernung',
    'GPSDestDistanceRef' => {
-      Description => 'Reference for distance to destination',
+      Description => 'GPS-Zielentfernung MaÃeinheit',
       PrintConv => {
         'Kilometers' => 'Kilometer',
@@ -2524,5 +4318,5 @@
       Description => 'Referenz fÃŒr die Breite des Zieles',
       PrintConv => {
-        'North' => 'Nordliche Breite',
+        'North' => 'NÃ¶rdliche Breite',
         'South' => 'SÃŒdliche Breite',
       },
@@ -2537,5 +4331,5 @@
     },
    'GPSDifferential' => {
-      Description => 'GPS-Differentialkorrektur',
+      Description => 'GPS Differentialkorrektur',
       PrintConv => {
         'Differential Corrected' => 'Differentialkorrektur angewandt',
@@ -2570,5 +4364,5 @@
    'GPSMapDatum' => 'GeodÃ€tisches Datum',
    'GPSMeasureMode' => {
-      Description => 'GPS-Messverfahren',
+      Description => 'GPS Messverfahren',
       PrintConv => {
         '2-D' => '2-Dimensionale Messung',
@@ -2592,5 +4386,5 @@
     },
    'GPSStatus' => {
-      Description => 'GPS-EmpfÃ€nger-Status',
+      Description => 'GPS-EmpfÃ€nger Status',
       PrintConv => {
         'Measurement Active' => 'Messung aktiv',
@@ -2598,5 +4392,5 @@
       },
     },
-   'GPSTimeStamp' => 'GPS-Zeit (Atomuhr)',
+   'GPSTimeStamp' => 'GPS-Zeit UTC',
    'GPSTrack' => 'Bewegungsrichtung',
    'GPSTrackRef' => {
@@ -2624,4 +4418,13 @@
       },
     },
+   'Gradation' => {
+      PrintConv => {
+        'Auto-Override' => 'Automatisch',
+        'High Key' => 'High-Key',
+        'Low Key' => 'Low-Key',
+        'User-Selected' => 'Benutzerauswahl',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'GrayResponseUnit' => {
       PrintConv => {
@@ -2634,6 +4437,9 @@
     },
    'GrayTRC' => 'Grau-Tonwertwiedergabe-Kurve',
+   'GreenAdjust' => 'GrÃŒn-Korrektur',
    'GreenMatrixColumn' => 'GrÃŒn-Matrixspalte',
    'GreenTRC' => 'GrÃŒn-Tonwertwiedergabe-Kurve',
+   'GreenX' => 'GrÃŒnpunkt X',
+   'GreenY' => 'GrÃŒnpunkt Y',
    'GridDisplay' => {
       Description => 'Gitterlinien',
@@ -2654,4 +4460,5 @@
       },
     },
+   'Grouping' => 'Gruppierung',
    'HDR' => {
       Description => 'Auto HDR',
@@ -2660,9 +4467,26 @@
       },
     },
+   'HDRImageType' => {
+      Description => 'HDR Bildtyp',
+      PrintConv => {
+        'HDR Image' => 'HDR Bild',
+        'Original Image' => 'Originalbild',
+      },
+    },
    'Headline' => 'Ãberschrift',
    'HeightResolution' => 'Vertikale BildauflÃ¶sung',
+   'HierarchicalSubject' => 'Hierarchische SchlÃŒsselwÃ¶rter',
    'HighISONoiseReduction' => {
       Description => 'RauschunterdrÃŒckung bei hoher Empfindlichkeit',
       PrintConv => {
+        '+1 (medium strong)' => '+1',
+        '+2 (strong)' => '+2 (Stark)',
+        '+3 (very strong)' => '+3',
+        '+4 (strongest)' => '+4',
+        '-1 (medium weak)' => '-1',
+        '-2 (weak)' => '-2 (Gering)',
+        '-3 (very weak)' => '-3',
+        '-4 (weakest)' => '-4 (Sehr gering)',
+        '0 (normal)' => '0 (Normal)',
         'Auto' => 'Automatisch',
         'High' => 'StÃ€rker',
@@ -2673,6 +4497,18 @@
         'Weak' => 'Gering',
         'Weakest' => 'Sehr gering',
-      },
-    },
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'HighISONoiseReduction2' => {
+      Description => 'RauschunterdrÃŒckung bei hoher Empfindlichkeit',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'Off' => 'Aus',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'HighLowKeyAdj' => 'High-/Low-Key Abstimmung',
+   'Highlight' => 'Helle Stellen',
    'HighlightTonePriority' => {
       Description => 'Tonwert PrioritÃ€t',
@@ -2694,11 +4530,46 @@
     },
    'Hue' => 'Farbton',
+   'HueAdj' => 'Farbtonkorrektur',
+   'HueAdjust' => {
+      Description => 'Farbtonkorrektur',
+      PrintConv => {
+        'Cool' => 'KÃŒhl',
+        'Off' => 'Aus',
+        'Yellow' => 'Gelb',
+      },
+    },
    'HueAdjustment' => 'Farbtonkorrektur',
    'HueSetting' => 'Farbtoneinstellung',
    'HuffmanTable' => 'Huffman Tabelle',
    'HyperfocalDistance' => 'Hyperfokale Entfernung',
-   'ICCProfileName' => 'Name des ICC Profils',
+   'ICCProfile' => 'ICC-Profil',
+   'ICCProfileName' => 'ICC-Profil Name',
+   'ICC_Profile' => 'ICC-Profil',
+   'ID3Size' => 'ID3 DatenlÃ€nge',
+   'IDCCreativeStyle' => {
+      PrintConv => {
+        'Autumn Leaves' => 'Herbstlaub',
+        'B&W' => 'Schwarz/WeiÃ',
+        'Landscape' => 'Landschaft',
+        'Night View' => 'Abendszene',
+        'Portrait' => 'PortrÃ€t',
+        'Sunset' => 'Sonnenuntergang',
+      },
+    },
+   'IDCPreviewImage' => 'IDC Vorschaubild',
+   'IDCPreviewLength' => 'IDC Vorschaubild-DatenlÃ€nge',
+   'IDCPreviewStart' => 'IDC Vorschaubild-Datenposition',
    'IPTC-NAA' => 'IPTC-NAA Metadaten',
+   'IPTCDigest' => 'IPTC Kennwert',
    'IPTCImageHeight' => 'IPTC-BildhÃ¶he',
+   'IPTCImageRotation' => {
+      Description => 'IPTC Bildausrichtung',
+      PrintConv => {
+        '0' => 'Normal',
+        '180' => '180Â° gedreht',
+        '270' => '90Â° gegen den Uhrzeigersinn',
+        '90' => '90Â° im Uhrzeigersinn',
+      },
+    },
    'IPTCImageWidth' => 'IPTC-Bildbreite',
    'IPTCPictureNumber' => 'IPTC Bildnummer',
@@ -2707,4 +4578,5 @@
    'ISO' => 'ISO-Empfindlichkeit',
    'ISO2' => 'ISO-Empfindlichkeit (2)',
+   'ISOAuto' => 'ISO-Automatik',
    'ISODisplay' => 'ISO-Anzeige',
    'ISOExpansion' => {
@@ -2731,7 +4603,9 @@
         'Auto' => 'Automatisch',
         'Manual' => 'Manuell',
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'ISOSpeedExpansion' => {
+      Description => 'ISO-Erweiterung',
       PrintConv => {
         'No' => 'Nein',
@@ -2761,4 +4635,5 @@
       },
     },
+   'ISRCNumber' => 'ISRC Nummer',
    'Illumination' => {
       Description => 'Displaybeleuchtung',
@@ -2768,4 +4643,51 @@
       },
     },
+   'Image::ExifTool::APP12::PictureInfo' => 'APP12 Bildinformation',
+   'Image::ExifTool::Canon::AFMicroAdj' => 'Canon AF Feinabstimmung',
+   'Image::ExifTool::Canon::CameraInfo1000D' => 'Canon KameraInfo 1000D',
+   'Image::ExifTool::Canon::CameraInfo1D' => 'Canon KameraInfo 1D',
+   'Image::ExifTool::Canon::CameraInfo1DX' => 'Canon KameraInfo 1DX',
+   'Image::ExifTool::Canon::CameraInfo1DmkII' => 'Canon KameraInfo 1DmkII',
+   'Image::ExifTool::Canon::CameraInfo1DmkIII' => 'Canon KameraInfo 1DmkIII',
+   'Image::ExifTool::Canon::CameraInfo1DmkIIN' => 'Canon KameraInfo 1DmkIIN',
+   'Image::ExifTool::Canon::CameraInfo1DmkIV' => 'Canon KameraInfo 1DmkIV',
+   'Image::ExifTool::Canon::CameraInfo40D' => 'Canon KameraInfo 40D',
+   'Image::ExifTool::Canon::CameraInfo450D' => 'Canon KameraInfo 450D',
+   'Image::ExifTool::Canon::CameraInfo500D' => 'Canon KameraInfo 500D',
+   'Image::ExifTool::Canon::CameraInfo50D' => 'Canon KameraInfo 50D',
+   'Image::ExifTool::Canon::CameraInfo550D' => 'Canon KameraInfo 550D',
+   'Image::ExifTool::Canon::CameraInfo5D' => 'Canon KameraInfo 5D',
+   'Image::ExifTool::Canon::CameraInfo5DmkII' => 'Canon KameraInfo 5DmkII',
+   'Image::ExifTool::Canon::CameraInfo5DmkIII' => 'Canon KameraInfo 5DmkIII',
+   'Image::ExifTool::Canon::CameraInfo600D' => 'Canon KameraInfo 600D',
+   'Image::ExifTool::Canon::CameraInfo60D' => 'Canon KameraInfo 60D',
+   'Image::ExifTool::Canon::CameraInfo650D' => 'Canon KameraInfo 650D',
+   'Image::ExifTool::Canon::CameraInfo7D' => 'Canon KameraInfo 7D',
+   'Image::ExifTool::Canon::CameraInfoPowerShot' => 'Canon KameraInfo PowerShot',
+   'Image::ExifTool::Canon::CameraInfoPowerShot2' => 'Canon KameraInfo PowerShot2',
+   'Image::ExifTool::Canon::CameraInfoUnknown32' => 'Canon KameraInfo Unbekannt32',
+   'Image::ExifTool::Canon::CropInfo' => 'Canon Ausschnitt Info',
+   'Image::ExifTool::CanonRaw::ImageFormat' => 'CanonRaw Bildformat',
+   'Image::ExifTool::DNG::OriginalRaw' => 'DNG Original RAW',
+   'Image::ExifTool::ICC_Profile::Measurement' => 'ICC_Profil Messung',
+   'Image::ExifTool::IPTC::ApplicationRecord' => 'IPTC Modell',
+   'Image::ExifTool::Jpeg2000::FileType' => 'Jpeg2000 Dateityp',
+   'Image::ExifTool::Jpeg2000::ImageHeader' => 'Jpeg2000 Bild-Header',
+   'Image::ExifTool::Kodak::CameraInfo' => 'Kodak KameraInfo',
+   'Image::ExifTool::MIE::Meta' => 'MIE Metadaten',
+   'Image::ExifTool::Minolta::CameraInfoA100' => 'Minolta KameraInfo A100',
+   'Image::ExifTool::Olympus::CameraSettings' => 'Olympus Kameraeinstellungen',
+   'Image::ExifTool::Olympus::FocusInfo' => 'Olympus FokusInfo',
+   'Image::ExifTool::Olympus::ImageProcessing' => 'Olympus Bildverarbeitung',
+   'Image::ExifTool::PNG::ImageHeader' => 'PNG Bild-Header',
+   'Image::ExifTool::PNG::PhysicalPixel' => 'PNG physikalische Pixel',
+   'Image::ExifTool::PNG::PrimaryChromaticities' => 'PNG primÃ€re ChromatizitÃ€t',
+   'Image::ExifTool::PNG::StereoImage' => 'PNG Stereobild',
+   'Image::ExifTool::PNG::TextualData' => 'PNG Textdaten',
+   'Image::ExifTool::PNG::VirtualPage' => 'PNG virtuelle Seite',
+   'Image::ExifTool::PSP::Creator' => 'PSP Ersteller',
+   'Image::ExifTool::Pentax::CameraInfo' => 'Pentax KameraInfo',
+   'Image::ExifTool::Sony::CameraInfo' => 'Sony KameraInfo',
+   'Image::ExifTool::Sony::CameraInfo2' => 'Sony KameraInfo2',
    'ImageAdjustment' => 'Bildanpassung',
    'ImageAreaOffset' => 'Bildbereichsoffset',
@@ -2774,5 +4696,5 @@
       PrintConv => {
         'Off' => 'Aus',
-        'On' => 'An',
+        'On' => 'Ein',
       },
     },
@@ -2807,6 +4729,19 @@
       },
     },
+   'ImageEffects' => {
+      PrintConv => {
+        'High Key' => 'High-Key',
+      },
+    },
+   'ImageGeneration' => {
+      Description => 'Bilderstellung',
+      PrintConv => {
+        'Original Image' => 'Originalbild',
+        'Re-developed from RAW' => 'RAW generiert',
+      },
+    },
    'ImageHeight' => 'BildhÃ¶he',
    'ImageHistory' => 'Bild-Historie',
+   'ImageLength' => 'Bild-DatenlÃ€nge',
    'ImageNumber' => 'Bildnummer',
    'ImageNumber2' => 'Bildnummer (2)',
@@ -2821,4 +4756,5 @@
       },
     },
+   'ImageProcessing' => 'Bildverarbeitung',
    'ImageProcessingVersion' => 'Bildverarbeitung Version',
    'ImageQuality' => {
@@ -2843,10 +4779,57 @@
       },
     },
+   'ImageRotation' => {
+      Description => 'Bildausrichtung',
+      PrintConv => {
+        'None' => 'Keine',
+      },
+    },
    'ImageSize' => 'BildgrÃ¶Ãe',
    'ImageStabilization' => {
       Description => 'Bildstabilisierung',
       PrintConv => {
-        'Off' => 'Aus',
-        'On' => 'Ein',
+        'Anti-Shake' => 'Verwackeln',
+        'Best Shot' => 'Beste Aufnahme',
+        'CCD Shift + High Sensitivity' => 'CCD Shift + Hohe Empfindlichkeit',
+        'Dynamic' => 'Dynamisch',
+        'Dynamic (2)' => 'Dynamisch (2)',
+        'High Sensitivity' => 'Hohe Empfindlichkeit',
+        'None' => 'Keine',
+        'Off' => 'Aus',
+        'Off (0xbf)' => 'Aus (0xbf)',
+        'Off (1)' => 'Aus (1)',
+        'Off (2)' => 'Aus (2)',
+        'On' => 'Ein',
+        'On (0x3f)' => 'Ein (0x3f)',
+        'On (2)' => 'Ein (2)',
+        'On (mode 1, continuous)' => 'Ein (Modus 1, nachfÃŒhrend)',
+        'On (mode 2, shooting only)' => 'Ein (Modus 2, Aufnahme)',
+        'On, Mode 1' => 'Ein, Modus 1',
+        'On, Mode 2' => 'Ein, Modus 2',
+        'On, Mode 3' => 'Ein, Modus 3',
+        'On, Mode 4' => 'Ein, Modus 4',
+        'Optical' => 'Optisch',
+        'Panning' => 'Schwenken',
+        'Panning (2)' => 'Schwenken (2)',
+        'Sensor-shift' => 'Sensor-Shift',
+        'Shoot Only' => 'Aufnahme',
+        'Shoot Only (2)' => 'Aufnahme (2)',
+        'Slow Shutter' => 'Kurzer VerschluÃ',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ImageStabilizationSetting' => {
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'ImageStyle' => {
+      PrintConv => {
+        'B&W' => 'Schwarz/WeiÃ',
+        'Landscape' => 'Landschaft',
+        'Night View/Portrait' => 'Abendszene/PortrÃ€t',
+        'Portrait' => 'PortrÃ€t',
+        'Sunset' => 'Sonnenuntergang',
       },
     },
@@ -2861,5 +4844,12 @@
       },
     },
-   'ImageType' => 'Bildtyp',
+   'ImageType' => {
+      Description => 'Bildtyp',
+      PrintConv => {
+        'Page' => 'Seite',
+        'Preview' => 'Vorschau',
+      },
+    },
+   'ImageUIDList' => 'Bilder UID Liste',
    'ImageUniqueID' => 'Eindeutige Bild-ID',
    'ImageWidth' => 'Bildbreite',
@@ -2880,5 +4870,45 @@
     },
    'Instructions' => 'Anweisungen',
-   'IntellectualGenre' => 'Genre',
+   'IntellectualGenre' => 'Intellektuelles Genre',
+   'IntelligentAuto' => {
+      PrintConv => {
+        'Advanced' => 'Erweitert',
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'IntelligentContrast' => {
+      Description => 'Intelligenter Kontrast',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'IntelligentD-Range' => {
+      Description => 'Intelligenter D-Bereich',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'Off' => 'Aus',
+      },
+    },
+   'IntelligentExposure' => {
+      Description => 'Intelligente Belichtung',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'Off' => 'Aus',
+      },
+    },
+   'IntelligentResolution' => {
+      Description => 'Intelligente BildauflÃ¶sung',
+      PrintConv => {
+        'Extended' => 'Erweitert',
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'Off' => 'Aus',
+      },
+    },
    'IntensityStereo' => {
       PrintConv => {
@@ -2899,4 +4929,8 @@
       },
     },
+   'InternalFlashAE1' => 'Integriertes BlitzgerÃ€t AE1',
+   'InternalFlashAE1_0' => 'Integriertes BlitzgerÃ€t AE1 0',
+   'InternalFlashAE2' => 'Integriertes BlitzgerÃ€t AE2',
+   'InternalFlashAE2_0' => 'Integriertes BlitzgerÃ€t AE2 0',
    'InternalFlashMode' => {
       Description => 'Slave-Blitz-Messfeld 2',
@@ -2928,5 +4962,5 @@
    'InternalSerialNumber' => 'Interne Seriennummer',
    'InteropIndex' => {
-      Description => 'InteroperabilitÃ€ts-Identifikation',
+      Description => 'InteroperabilitÃ€t Identifikation',
       PrintConv => {
         'R03 - DCF option file (Adobe RGB)' => 'R03: DCF Option-Format (Adobe RGB)',
@@ -2946,7 +4980,31 @@
     },
    'IntervalNumber' => 'Intervalnummer',
+   'IsCustomPictureStyle' => {
+      Description => 'Bildstil benutzerdefinert',
+      PrintConv => {
+        'No' => 'Nein',
+        'Yes' => 'Ja',
+      },
+    },
    'JFIFVersion' => 'JFIF-Version',
-   'JPEGQuality' => 'JPEG-QualitÃ€t',
-   'JobID' => 'Job-ID',
+   'JPEGDigest' => 'JPEG Kennwert',
+   'JPEGProc' => {
+      Description => 'JPEG Verfahren',
+      PrintConv => {
+        'Lossless' => 'Verlustfrei',
+      },
+    },
+   'JPEGQuality' => {
+      Description => 'BildqualitÃ€t',
+      PrintConv => {
+        'Extra Fine' => 'Extra-Fein',
+        'Fine' => 'Fein',
+        'Standard' => 'StandardqualitÃ€t',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'JPEGSize' => 'JPEG GrÃ¶Ãe',
+   'JPEGTables' => 'JPEG Tabellen',
+   'JobID' => 'Job-Kennung',
    'JpgFromRaw' => 'Jpg From Raw Bild',
    'JpgFromRawLength' => 'Jpg From Raw DatenlÃ€nge',
@@ -2954,6 +5012,6 @@
    'JpgRecordedPixels' => 'JPEG-AuflÃ¶sung',
    'Key' => 'SchlÃŒssel',
-   'Keyword' => 'StichwÃ¶rter',
-   'Keywords' => 'SchlÃŒsselwort',
+   'Keyword' => 'SchlÃŒsselwort',
+   'Keywords' => 'SchlÃŒsselwÃ¶rter',
    'KodakImageHeight' => 'Kodak-BildhÃ¶he',
    'KodakImageWidth' => 'Kodak-Bildbreite',
@@ -3004,5 +5062,6 @@
       },
     },
-   'Label' => 'Bezeichnung',
+   'Label' => 'Beschriftung',
+   'Landmark' => 'SehenswÃŒrdigkeit',
    'Language' => 'Sprache',
    'LanguageCode' => {
@@ -3014,5 +5073,15 @@
    'LanguageIdentifier' => 'Sprachkennung',
    'LastFileNumber' => 'Letzte Dateinummer',
+   'LastKeywordIPTC' => 'Letztes IPTC SchlÃŒsselwort',
+   'LastKeywordXMP' => 'Letztes XMP SchlÃŒsselwort',
+   'LateralChromaticAberration' => {
+      Description => 'Laterale Farbabweichung',
+      PrintConv => {
+        'Off' => 'Aus',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'LeafData' => 'Leaf Daten',
+   'LegacyIPTCDigest' => 'Bisheriger IPTC Kennwert',
    'Lens' => 'Objektiv',
    'Lens35efl' => 'Objektiv',
@@ -3030,6 +5099,8 @@
       },
     },
+   'LensApertureRange' => 'Objektiv Blendenbereich',
    'LensData' => 'K-Wert',
    'LensDataVersion' => 'Objektivdaten-Version',
+   'LensDistortionParams' => 'Objektiv Verzeichnungsparameter',
    'LensDriveNoAF' => {
       Description => 'SchÃ€rfensuche wenn AF unmÃ¶glich',
@@ -3046,11 +5117,36 @@
    'LensKind' => 'Objektivtyp / Version (LC0)',
    'LensMake' => 'Objektivhersteller',
+   'LensManufacturer' => 'Objektivhersteller',
+   'LensMaxApertureRange' => 'Objektiv Blendenbereich',
    'LensModel' => 'Objektiv-Typ',
+   'LensProfileDigest' => 'Kennwert des Objektivprofils',
    'LensProperties' => 'Objektivfunktionen?',
    'LensSerialNumber' => 'Objektiv-Seriennummer',
    'LensSpec' => 'Objektiv',
-   'LensType' => 'Objektivtyp',
+   'LensType' => {
+      Description => 'Objektivtyp',
+      PrintConv => {
+        'Uncoded lens' => 'Nicht kodiertes Objektiv',
+      },
+    },
+   'LevelOrientation' => {
+      Description => 'Level Ausrichtung',
+      PrintConv => {
+        'Downwards' => 'AbwÃ€rts',
+        'Horizontal; Off Level' => 'Horizontal; ohne Level',
+        'Rotate 180' => '180Â° gedreht',
+        'Rotate 180; Off Level' => '180Â° gedreht; ohne Level',
+        'Rotate 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotate 270 CW; Off Level' => '90Â° gegen den Uhrzeigersinn; ohne Level',
+        'Rotate 90 CW' => '90Â° im Uhrzeigersinn',
+        'Rotate 90 CW; Off Level' => '90Â° im Uhrzeigersinn; ohne Level',
+        'Upwards' => 'AufwÃ€rts',
+      },
+    },
+   'License' => 'Lizenz',
    'LicenseType' => {
-      PrintConv => {
+      Description => 'Lizenztyp',
+      PrintConv => {
+        'Commercial' => 'Kommerziell',
         'Unknown' => 'Unbekannt',
       },
@@ -3098,4 +5194,25 @@
       },
     },
+   'LiveViewAFAreaMode' => {
+      Description => 'Live-View AF-Modus',
+      PrintConv => {
+        'Face-Priority' => 'Gesichtserkennung',
+        'NormalArea' => 'Normaler Bereich',
+        'SubjectTracking' => 'ObjektnachfÃŒhrung',
+        'WideArea' => 'GroÃer Bereich',
+      },
+    },
+   'LiveViewAFMethod' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'LiveViewAFMode' => 'Live-View AF-Modus',
+   'LiveViewAFSetting' => {
+      Description => 'Live View AF Einstellung',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'LiveViewExposureSimulation' => {
       Description => 'Livebild-Belichtungssimulator',
@@ -3105,5 +5222,18 @@
       },
     },
+   'LiveViewFocusMode' => {
+      Description => 'Live-View Fokus-Modus',
+      PrintConv => {
+        'Manual' => 'Manuell',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'LiveViewMetering' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'LiveViewShooting' => {
+      Description => 'Live View Aufnahme',
       PrintConv => {
         'Off' => 'Aus',
@@ -3126,7 +5256,15 @@
         'Off' => 'Aus',
         'On' => 'Ein',
-      },
-    },
-   'LongFocal' => 'GrÃ¶Ãte Brennweite',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'LongExposureNoiseReduction2' => {
+      Description => 'Langzeit RauschunterdrÃŒckung 2',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+        'On (1D)' => 'Ein (1D)',
+      },
+    },
    'Luminance' => 'Luminanz',
    'LuminanceNoiseReduction' => {
@@ -3146,4 +5284,5 @@
       },
     },
+   'MB-D10BatteryType' => 'Akku-/Batterietyp',
    'MB-D80Batteries' => {
       Description => 'Akku-/Batterietyp',
@@ -3157,6 +5296,21 @@
    'MB-D80BatteryType' => 'MB-D80 Batterietyp',
    'MCUVersion' => 'MCU-Version',
+   'MD5Digest' => 'MD5 Kennwert',
    'MIEVersion' => 'MIE-Version',
    'MIMEType' => 'MIME-Typ',
+   'MPImage' => 'MP Vorschaubild',
+   'MPImageFlags' => 'MP Vorschaubild Flags',
+   'MPImageFormat' => 'MP Vorschaubild Format',
+   'MPImageLength' => 'MP Vorschaubild-DatenlÃ€nge',
+   'MPImageStart' => 'MP Vorschaubild Datenposition',
+   'MPImageType' => {
+      Description => 'MP Vorschaubild Typ',
+      PrintConv => {
+        'Large Thumbnail (VGA equivalent)' => 'Vorschaubild groÃ (VGA)',
+        'Large Thumbnail (full HD equivalent)' => 'Vorschaubild groÃ (HD)',
+        'Multi-frame Panorama' => 'Mehrbild Panorama',
+        'Undefined' => 'Nicht definiert',
+      },
+    },
    'MSStereo' => {
       PrintConv => {
@@ -3173,13 +5327,36 @@
         'On' => 'Ein',
         'Super Macro' => 'Super-Makro',
-      },
-    },
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'MacroLED' => {
+      Description => 'Makro LED',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'MacroMagnification' => 'Makro VergrÃ¶Ãerung',
    'MacroMode' => {
       Description => 'Makro-Modus',
       PrintConv => {
         'Macro' => 'Makro',
+        'Macro Zoom' => 'Makro-Zoom',
         'Off' => 'Aus',
         'On' => 'Ein',
         'Super Macro' => 'Super-Makro',
+        'Tele-Macro' => 'Tele-Makro',
+      },
+    },
+   'MagicFilter' => {
+      PrintConv => {
+        'Drawing' => 'Zeichnung',
+        'Fish Eye' => 'Fischauge',
+        'Off' => 'Aus',
+        'Reflection' => 'Reflektierung',
+        'Soft Focus' => 'Weichzeichner',
+        'Soft Focus 2' => 'Weichzeichner 2',
+        'Sparkle' => 'Perleffekt',
+        'Watercolor' => 'Wasserfarben',
       },
     },
@@ -3201,4 +5378,61 @@
    'MakeAndModel' => 'Hersteller und Modell',
    'MakerNote' => 'Hersteller-eigene Daten',
+   'MakerNoteApple' => 'Herstellerdaten Apple',
+   'MakerNoteCanon' => 'Herstellerdaten Canon',
+   'MakerNoteCasio' => 'Herstellerdaten Casio',
+   'MakerNoteCasio2' => 'Herstellerdaten Casio 2',
+   'MakerNoteFLIR' => 'Herstellerdaten FLIR',
+   'MakerNoteFujiFilm' => 'Herstellerdaten Fuji Film',
+   'MakerNoteGE' => 'Herstellerdaten GE',
+   'MakerNoteGE2' => 'Herstellerdaten GE2',
+   'MakerNoteHP' => 'Herstellerdaten HP',
+   'MakerNoteHP2' => 'Herstellerdaten HP2',
+   'MakerNoteHP4' => 'Herstellerdaten HP4',
+   'MakerNoteHP6' => 'Herstellerdaten HP6',
+   'MakerNoteHasselblad' => 'Herstellerdaten Hasselblad',
+   'MakerNoteISL' => 'Herstellerdaten ISL',
+   'MakerNoteJVC' => 'Herstellerdaten JVC',
+   'MakerNoteJVCText' => 'Herstellerdaten JVC Text',
+   'MakerNoteKodak10' => 'Herstellerdaten Kodak 10',
+   'MakerNoteKodak1a' => 'Herstellerdaten Kodak 1a',
+   'MakerNoteKodak1b' => 'Herstellerdaten Kodak 1b',
+   'MakerNoteKodak2' => 'Herstellerdaten Kodak 2',
+   'MakerNoteKodak3' => 'Herstellerdaten Kodak 3',
+   'MakerNoteKodak4' => 'Herstellerdaten Kodak 4',
+   'MakerNoteKodak5' => 'Herstellerdaten Kodak 5',
+   'MakerNoteKodak6a' => 'Herstellerdaten Kodak 6a',
+   'MakerNoteKodak6b' => 'Herstellerdaten Kodak 6b',
+   'MakerNoteKodak7' => 'Herstellerdaten Kodak 7',
+   'MakerNoteKodak8a' => 'Herstellerdaten Kodak 8a',
+   'MakerNoteKodak8b' => 'Herstellerdaten Kodak 8b',
+   'MakerNoteKodak9' => 'Herstellerdaten Kodak 9',
+   'MakerNoteKodakUnknown' => 'Herstellerdaten Kodak Unbekannt',
+   'MakerNoteKyocera' => 'Herstellerdaten Kyocera',
+   'MakerNoteLeica' => 'Herstellerdaten Leica',
+   'MakerNoteLeica2' => 'Herstellerdaten Leica 2',
+   'MakerNoteLeica3' => 'Herstellerdaten Leica 3',
+   'MakerNoteLeica4' => 'Herstellerdaten Leica 4',
+   'MakerNoteLeica5' => 'Herstellerdaten Leica 5',
+   'MakerNoteLeica6' => 'Herstellerdaten Leica 6',
+   'MakerNoteMinolta' => 'Herstellerdaten Minolta',
+   'MakerNoteMinolta2' => 'Herstellerdaten Minolta 2',
+   'MakerNoteMinolta3' => 'Herstellerdaten Minolta 3',
+   'MakerNoteNikon' => 'Herstellerdaten Nikon',
+   'MakerNoteNikon2' => 'Herstellerdaten Nikon 2',
+   'MakerNoteNikon3' => 'Herstellerdaten Nikon 3',
+   'MakerNoteOlympus' => 'Herstellerdaten Olympus',
+   'MakerNoteOlympus2' => 'Herstellerdaten Olympus 2',
+   'MakerNotePanasonic' => 'Herstellerdaten Panasonic',
+   'MakerNotePanasonic2' => 'Herstellerdaten Panasonic 2',
+   'MakerNotePentax' => 'Herstellerdaten Pentax',
+   'MakerNotePentax2' => 'Herstellerdaten Pentax 2',
+   'MakerNotePentax3' => 'Herstellerdaten Pentax 3',
+   'MakerNotePentax4' => 'Herstellerdaten Pentax 4',
+   'MakerNotePentax5' => 'Herstellerdaten Pentax 5',
+   'MakerNotePentax6' => 'Herstellerdaten Pentax 6',
+   'MakerNotePhaseOne' => 'Herstellerdaten Phase One',
+   'MakerNoteReconyx' => 'Herstellerdaten Reconyx',
+   'MakerNoteRicoh' => 'Herstellerdaten Ricoh',
+   'MakerNoteRicohText' => 'Herstellerdaten Ricoh Text',
    'MakerNoteSafety' => {
       Description => 'Sicherheit der Hersteller-Informationsdaten',
@@ -3208,8 +5442,27 @@
       },
     },
+   'MakerNoteSamsung1a' => 'Herstellerdaten Samsung 1a',
+   'MakerNoteSamsung1b' => 'Herstellerdaten Samsung 1b',
+   'MakerNoteSamsung2' => 'Herstellerdaten Samsung 2',
+   'MakerNoteSanyo' => 'Herstellerdaten Sanyo',
+   'MakerNoteSanyoC4' => 'Herstellerdaten Sanyo C4',
+   'MakerNoteSanyoPatch' => 'Herstellerdaten Sanyo Patch',
+   'MakerNoteSigma' => 'Herstellerdaten Sigma',
+   'MakerNoteSony' => 'Herstellerdaten Sony',
+   'MakerNoteSony2' => 'Herstellerdaten Sony 2',
+   'MakerNoteSony3' => 'Herstellerdaten Sony 3',
+   'MakerNoteSony4' => 'Herstellerdaten Sony 4',
+   'MakerNoteSony5' => 'Herstellerdaten Sony 5',
+   'MakerNoteSonyEricsson' => 'Herstellerdaten Sony Ericsson',
+   'MakerNoteSonySRF' => 'Herstellerdaten Sony SRF',
+   'MakerNoteType' => 'Benutzerdaten Typ',
+   'MakerNoteUnknown' => 'Herstellerdaten Unbekannt',
+   'MakerNoteUnknownBinary' => 'Herstellerdaten Unbekannt-BinÃ€r',
+   'MakerNoteUnknownText' => 'Herstellerdaten Unbekannt-Text',
    'MakerNoteVersion' => 'MakerNote-Version',
    'MakerNotes' => 'Hinweise des Herstellers',
    'ManometerPressure' => 'Gemessener Luft- bzw. Wasserdruck',
    'ManometerReading' => 'Berechnete HÃ¶he oder Tauchtiefe',
+   'ManualAFPointSelectPattern' => 'Manuelle Wahl der AF-Punkte',
    'ManualFlash' => 'Manueller Blitz',
    'ManualFlashOutput' => {
@@ -3219,10 +5472,11 @@
         'Low' => 'Gering',
         'Medium' => 'Mittel',
-        'n/a' => 'Nicht gesetzt',
-      },
-    },
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ManualFlashStrength' => 'Manuelle BlitzstÃ€rke',
    'ManualFocusDistance' => 'Manuelle Fokusdistanz',
    'ManualTv' => {
-      Description => 'Man. Tv/Av-Einst. fÃŒr M. Bel.',
+      Description => 'Manuelle Tv/Av-Einstellung fÃŒr Manuelle Belichtung',
       PrintConv => {
         'Tv=Control/Av=Main' => 'Tv=Schnelleinstellrad/Av=Haupt-Wahlrad',
@@ -3233,4 +5487,5 @@
    'Marked' => 'Markiert',
    'MasterDocumentID' => 'ID des Originaldokuments',
+   'MatrixMetering' => 'Mehrfeldmessung',
    'MaxAperture' => 'GrÃ¶Ãte Blende',
    'MaxApertureAtCurrentFocal' => 'GrÃ¶Ãte Blende bei aktueller Brennweite',
@@ -3240,6 +5495,14 @@
    'MaxContinuousRelease' => 'Max. Bildanzahl pro Serie',
    'MaxFocalLength' => 'GrÃ¶Ãte Brennweite',
+   'MaxJPEGTableIndex' => 'GrÃ¶Ãter Index JPEG Tabellen',
+   'MaxSampleValue' => 'GrÃ¶Ãter Sample Wert',
    'MeasuredEV' => 'Gemessener LW',
+   'MeasuredLV' => 'Lichtwert gemessen',
+   'MeasuredRGGB' => 'Messung RGGB',
+   'MeasuredRGGBData' => 'Messung RGGB',
+   'MeasurementBacking' => 'Basis der Messung',
+   'MeasurementFlare' => 'Messung Lichtschein',
    'MeasurementGeometry' => {
+      Description => 'Geometrie der Messung',
       PrintConv => {
         '0/45 or 45/0' => '0/45 oder 45/0',
@@ -3247,4 +5510,6 @@
       },
     },
+   'MeasurementIlluminant' => 'Messung Beleuchtung',
+   'MeasurementObserver' => 'Messung nach',
    'MediaBlackPoint' => 'Medium-Schwarzpunkt',
    'MediaWhitePoint' => 'Medium-WeiÃpunkt',
@@ -3255,5 +5520,5 @@
         'Previous' => 'Vorherige Anzeige',
         'Previous (top if power off)' => 'Vorherige (Anfang nach AUS)',
-        'Top' => 'Anfang',
+        'Top' => 'Oben',
       },
     },
@@ -3264,10 +5529,12 @@
       },
     },
+   'MetadataCreator' => 'Metadaten Ersteller',
    'MetadataDate' => 'Datum der Metadaten',
+   'MetadataID' => 'Metadaten ID',
    'Metering' => {
       Description => 'Belichtungsmessung',
       PrintConv => {
         'Center-weighted' => 'Mittenbetont',
-        'Matrix' => 'Matrixmessung',
+        'Matrix' => 'Mehrfeldmessung',
         'Spot' => 'Spotmessung',
       },
@@ -3279,4 +5546,5 @@
         'Center-weighted Average' => 'Mittenbetont',
         'Center-weighted average' => 'Mittenbetont',
+        'Default' => 'System',
         'Evaluative' => 'Mehrfeldmessung',
         'Multi-segment' => 'Multi-Segment',
@@ -3310,7 +5578,14 @@
     },
    'MinAperture' => 'Kleinste Blende',
+   'MinApertureValue' => 'Kleinste Blende',
    'MinFocalLength' => 'Kleinste Brennweite',
+   'MinSampleValue' => 'Kleinster Sample Wert',
+   'MiniatureFilterOrientation' => {
+      PrintConv => {
+        'Vertical' => 'Vertikal',
+      },
+    },
    'MinoltaCameraSettings2' => 'Kameraeinstellungen 2',
-   'MinoltaCameraSettings5D' => 'Kameraeinstellungen (A100)',
+   'MinoltaCameraSettings5D' => 'Kameraeinstellungen (5D)',
    'MinoltaCameraSettings7D' => 'Kameraeinstellungen (7D)',
    'MinoltaDate' => 'Minolta-Datum',
@@ -3325,5 +5600,5 @@
     },
    'MinoltaMakerNote' => 'Minolta-Herstellerinformationen',
-   'MinoltaModelID' => 'Minolta-Modell',
+   'MinoltaModelID' => 'Minolta-Modell ID',
    'MinoltaQuality' => {
       Description => 'Minolta-BildqualitÃ€t',
@@ -3331,4 +5606,5 @@
         'Extra Fine' => 'Extra-Fein',
         'Fine' => 'Fein',
+        'RAW+JPEG' => 'RAW + JPEG',
         'Super Fine' => 'Super-Fein',
       },
@@ -3343,6 +5619,16 @@
       },
     },
+   'ModeDialPosition' => {
+      PrintConv => {
+        'Aperture-priority AE' => 'BlendenprioritÃ€t',
+        'Manual' => 'Manuell',
+        'No Flash' => 'Kein Blitz',
+        'Program AE' => 'Programmautomatik',
+        'Shutter speed priority AE' => 'VerschluÃprioritÃ€t',
+      },
+    },
    'Model' => 'Kameramodell',
    'Model2' => 'Kameramodell (2)',
+   'ModelID' => 'Modell ID',
    'ModelingFlash' => {
       Description => 'Einstelllicht',
@@ -3352,10 +5638,17 @@
       },
     },
+   'ModifiedColorTemp' => 'GeÃ€nderte Farbtemperatur',
+   'ModifiedDigitalGain' => 'Digitale VerstÃ€rkung geÃ€ndert',
    'ModifiedPictureStyle' => {
-      PrintConv => {
+      Description => 'GeÃ€nderter Bildstil',
+      PrintConv => {
+        'Faithful' => 'NatÃŒrlich',
         'Landscape' => 'Landschaft',
         'Monochrome' => 'Monochrom',
-        'None' => 'Keine',
+        'None' => 'Keiner',
         'Portrait' => 'PortrÃ€t',
+        'User Def. 1' => 'Benutzerdefiniert 1',
+        'User Def. 2' => 'Benutzerdefiniert 2',
+        'User Def. 3' => 'Benutzerdefiniert 3',
       },
     },
@@ -3365,4 +5658,5 @@
       },
     },
+   'ModifiedSharpness' => 'SchÃ€rfe verÃ€ndert',
    'ModifiedSharpnessFreq' => {
       PrintConv => {
@@ -3370,8 +5664,10 @@
         'Highest' => 'HÃ¶chste',
         'Low' => 'Leicht',
-        'n/a' => 'Nicht gesetzt',
+        'Lowest' => 'Niedrigste',
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'ModifiedToneCurve' => {
+      Description => 'Tonwertkurve verÃ€ndert',
       PrintConv => {
         'Custom' => 'Benutzerdefiniert',
@@ -3396,5 +5692,5 @@
         'Shade' => 'Schatten',
         'Tungsten' => 'GlÃŒhbirne',
-        'Underwater' => 'Tauchen',
+        'Underwater' => 'Unterwasser',
       },
     },
@@ -3408,7 +5704,8 @@
    'MonitorOffTime' => 'Ausschaltzeit des Monitors',
    'MonochromeFilterEffect' => {
+      Description => 'Filtereffekt Monochrom',
       PrintConv => {
         'Green' => 'GrÃŒn',
-        'None' => 'Keine',
+        'None' => 'Keiner',
         'Red' => 'Rot',
         'Yellow' => 'Gelb',
@@ -3422,12 +5719,29 @@
     },
    'MonochromeToningEffect' => {
+      Description => 'TÃ¶nungseffekt Monochrom',
       PrintConv => {
         'Blue' => 'Blau',
         'Green' => 'GrÃŒn',
-        'None' => 'Keine',
+        'None' => 'Keiner',
         'Purple' => 'Lila',
       },
     },
    'Month' => 'Monat',
+   'MultiBurstImageHeight' => 'Multi-Burst BildhÃ¶he',
+   'MultiBurstImageWidth' => 'Multi-Burst Bildbreite',
+   'MultiBurstMode' => {
+      Description => 'Mehrfach-Burst Modus',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'MultiControllerWhileMetering' => {
+      Description => 'Multicontroller bei Messung',
+      PrintConv => {
+        'AF point selection' => 'AF-Punkt-Auswahl',
+        'Off' => 'Aus',
+      },
+    },
    'MultiExposure' => 'Mehrfachbelichtungsdaten',
    'MultiExposureAutoGain' => {
@@ -3452,5 +5766,15 @@
       PrintConv => {
         'Off' => 'Aus',
-        'On' => 'An',
+        'On' => 'Ein',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'MultiFunctionLock' => {
+      PrintConv => {
+        'Main dial' => 'Haupt-Wahlrad',
+        'Multi-controller' => 'Multicontroller',
+        'Off' => 'Aus',
+        'On' => 'Ein',
+        'Quick control dial' => 'Schnelleinstellrad',
       },
     },
@@ -3479,4 +5803,11 @@
       },
     },
+   'MultipleExposureMode' => {
+      PrintConv => {
+        'Off' => 'Aus',
+        'On (2 frames)' => 'Ein (2 Bilder',
+        'On (3 frames)' => 'Ein (3 Bilder',
+      },
+    },
    'MultipleExposureSet' => {
       Description => 'Mehrfachbelichtung',
@@ -3493,6 +5824,7 @@
     },
    'MyColorMode' => {
-      PrintConv => {
-        'B&W' => 'Schwarz-WeiÃ',
+      Description => 'My Color-Modus',
+      PrintConv => {
+        'B&W' => 'Schwarz/WeiÃ',
         'Custom' => 'Benutzerdefiniert',
         'Off' => 'Aus',
@@ -3505,4 +5837,10 @@
         'Off' => 'Aus',
         'On' => 'Ein',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'NEFBitDepth' => {
+      PrintConv => {
+        'n/a (JPEG)' => 'Nicht gesetzt  (JPEG)',
       },
     },
@@ -3516,14 +5854,25 @@
       },
     },
+   'NEFLinearizationTable' => 'Linearisierungstabelle',
+   'NativeDigest' => 'EXIF Kennwert',
+   'NetExposureCompensation' => 'Net Belichtungskorrektur',
+   'NewMieTag1' => 'Weiterer MIE Tag 1',
+   'NewPngTag1' => 'Weiterer PNG Tag 1',
+   'NewPngTag2' => 'Weiterer PNG Tag 2',
+   'NewPngTag3' => 'Weiterer PNG Tag 3',
+   'NewRawImageDigest' => 'Neuer RAW Image Kennwert',
    'NewsPhotoVersion' => 'IPTC-Modell-3-Version',
    'NikonCaptureData' => 'Nikon Capture-Daten',
    'NikonCaptureOutput' => 'Nikon Capture-Ausgabe',
    'NikonCaptureVersion' => 'Nikon Capture-Version',
-   'NikonICCProfile' => 'Nikon ICC-Profil-Zeiger',
+   'NikonICCProfile' => 'Nikon ICC-Profil',
    'NikonImageSize' => {
-      Description => 'BildgrÃ¶Ãe',
-      PrintConv => {
+      Description => 'Nikon BildgrÃ¶Ãe',
+      PrintConv => {
+        'Large' => 'GroÃ',
         'Large (10.0 M)' => 'GroÃ (10.0M)',
+        'Medium' => 'Mittel',
         'Medium (5.6 M)' => 'Mittel (5.6M)',
+        'Small' => 'Klein',
         'Small (2.5 M)' => 'Klein (2.5M)',
       },
@@ -3543,4 +5892,5 @@
         'Low' => 'Leicht',
         'Off' => 'Aus',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -3549,12 +5899,68 @@
       PrintConv => {
         'Auto' => 'Automatisch',
+        'High (+1)' => 'Hoch (+1)',
+        'Highest (+2)' => 'Am hÃ¶chsten (+2)',
         'Low' => 'Gering',
-        'Off' => 'Aus',
-        'On' => 'Ein',
-      },
-    },
+        'Low (-1)' => 'Niedrig (-1)',
+        'Lowest (-2)' => 'Am niedrigsten (+2)',
+        'Max' => 'Maximal',
+        'Noise Filter' => 'Rauschfilter',
+        'Noise Filter (ISO Boost)' => 'Rauschfilter (ISO Boost)',
+        'Noise Reduction' => 'Rauschreduktion',
+        'Off' => 'Aus',
+        'On' => 'Ein',
+        'Strong' => 'Stark',
+        'Weak' => 'Schwach',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'NoiseReduction2' => {
+      Description => 'RauschunterdrÃŒckung 2',
+      PrintConv => {
+        'Noise Filter' => 'Rauschfilter',
+        'Noise Filter (ISO Boost)' => 'Rauschfilter (ISO Boost)',
+        'Noise Reduction' => 'Rauschreduktion',
+      },
+    },
+   'NoiseReductionIntensity' => 'StÃ€rke RauschunterdrÃŒckung',
+   'NoiseReductionMethod' => {
+      Description => 'RauschunterdrÃŒckung Methode',
+      PrintConv => {
+        'Better Quality' => 'Bessere QualitÃ€t"',
+        'Faster' => 'Schneller',
+      },
+    },
+   'NoiseReductionMode' => {
+      Description => 'RauschunterdrÃŒckungsmodus',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
+   'NoiseReductionSharpness' => 'RauschunterdrÃŒckung SchÃ€rfe',
+   'NoiseReductionValue' => 'RauschunterdrÃŒckungswert',
    'NominalMaxAperture' => 'Nominaler AVmin',
    'NominalMinAperture' => 'Nominaler AVmax',
+   'Notes' => 'Hinweise',
    'NumAFPoints' => 'Anzahl der AF-Punkte',
+   'NumChannels' => 'Anzahl KanÃ€le',
+   'NumColors' => 'Anzahl Farben',
+   'NumFacePositions' => 'Gesichtspositionen',
+   'NumImportantColors' => 'Anzahl Hauptfarben',
+   'NumberOfFocusPoints' => {
+      Description => 'Anzahl AF-Punkte',
+      PrintConv => {
+        '11 Points' => '11 Punkte',
+        '39 Points' => '39 Punkte',
+      },
+    },
+   'NumberOfImages' => 'Anzahl Bilder',
+   'NumberOfPlanes' => 'Anzahl Ebenen',
+   'OPIProxy' => {
+      PrintConv => {
+        'Higher resolution image does not exist' => 'HÃ¶her aufgelÃ¶stes Bild nicht vorhanden',
+        'Higher resolution image exists' => 'HÃ¶her aufgelÃ¶stes Bild vorhanden',
+      },
+    },
    'ObjectAttributeReference' => 'Gattung',
    'ObjectCycle' => {
@@ -3566,8 +5972,10 @@
       },
     },
+   'ObjectDistance' => 'Objektabstand',
    'ObjectFileType' => {
+      Description => 'Objekt Dateityp',
       PrintConv => {
         'Executable file' => 'AusfÃŒhrbare Datei',
-        'None' => 'Keine',
+        'None' => 'Keiner',
         'Unknown' => 'Unbekannt',
       },
@@ -3579,5 +5987,12 @@
    'ObjectTypeReference' => 'Objekttypreferenz',
    'OffsetSchema' => 'Offset-Schema',
-   'OldSubfileType' => 'Unterdatei-Typ',
+   'OldSubfileType' => {
+      Description => 'Unterdatei-Typ',
+      PrintConv => {
+        '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',
+      },
+    },
    'OlympusImageHeight' => 'Olympus-BildhÃ¶he',
    'OlympusImageWidth' => 'Olympus-Bildbreite',
@@ -3586,10 +6001,21 @@
       PrintConv => {
         'Off' => 'Aus',
-        'On' => 'An',
-        'On (Preset)' => 'An (Preset)',
+        'On' => 'Ein',
+        'On (Preset)' => 'Ein (Preset)',
+      },
+    },
+   'OperatingSystem' => {
+      PrintConv => {
+        'unknown' => 'Unbekannt',
       },
     },
    'OpticalZoom' => 'Optischer Zoom',
    'OpticalZoomCode' => 'Optischer Zoom-Code',
+   'OpticalZoomMode' => {
+      Description => 'Optischer Zoom-Modus',
+      PrintConv => {
+        'Extended' => 'Erweitert',
+      },
+    },
    'OpticalZoomOn' => {
       PrintConv => {
@@ -3600,39 +6026,98 @@
    'Opto-ElectricConvFactor' => 'Optoelektronischer Umrechnungsfaktor',
    'OrderNumber' => 'Auftragsnummer',
+   'Organization' => 'Organisation',
    'Orientation' => {
-      Description => 'Ausrichtung des Bildes',
-      PrintConv => {
-        'Horizontal (normal)' => '0Â° (oben/links)',
+      Description => 'Ausrichtung',
+      PrintConv => {
         'Mirror horizontal' => 'Horizontal gespiegelt',
-        'Mirror horizontal and rotate 270 CW' => 'Horizontal gespiegelt und 90Â° gegen den Uhrzeigersinn gedreht',
-        'Mirror horizontal and rotate 90 CW' => 'Horizontal gespiegelt und 90Â° im Uhrzeigersinn gedreht',
+        'Mirror horizontal and rotate 270 CW' => 'Horizontal gespiegelt und 90Â° gegen den Uhrzeigersinn',
+        'Mirror horizontal and rotate 90 CW' => 'Horizontal gespiegelt und 90Â° im Uhrzeigersinn',
         'Mirror vertical' => 'Vertikal gespiegelt',
-        'Rotate 180' => '180Â° (unten/rechts)',
-        'Rotate 270 CW' => '90Â° im Uhrzeigersinn (links/unten)',
-        'Rotate 90 CW' => '90Â° gegen den Uhrzeigersinn (rechts/oben)',
+        'Rotate 180' => '180Â° gedreht',
+        'Rotate 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotate 90 CW' => '90Â° im Uhrzeigersinn',
+      },
+    },
+   'Orientation2' => {
+      Description => 'Ausrichtung 2',
+      PrintConv => {
+        'Rotate 180' => '180Â° gedreht',
+        'Rotate 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotate 90 CW' => '90Â° im Uhrzeigersinn',
       },
     },
    'OriginalFileName' => 'Original Dateiname',
+   'OriginalFileType' => 'Original Dateityp',
    'OriginalImageHeight' => 'Bildbreite Original',
    'OriginalImageWidth' => 'Bildbreite Original',
+   'OriginalRawCreator' => 'Original RAW Ersteller',
    'OriginalRawFileData' => 'Original Raw Daten',
+   'OriginalRawFileDigest' => 'Original RAW Image Kennwert',
    'OriginalRawFileName' => 'Original Raw Dateiname',
-   'OriginalTransmissionReference' => 'Jobkennung',
+   'OriginalRawFileType' => 'Original RAW Dateityp',
+   'OriginalRawImage' => 'Original RAW Bild',
+   'OriginalRawResource' => 'Original RAW Basisdaten',
+   'OriginalTHMCreator' => 'Original THM Ersteller',
+   'OriginalTHMFileType' => 'Original THM Dateityp',
+   'OriginalTHMImage' => 'Original THM Bild',
+   'OriginalTHMResource' => 'Original THM Basisdaten',
+   'OriginalTransmissionReference' => 'Anbietervermerk Verweis',
    'OriginatingProgram' => 'Erstellungsprogramm',
+   'OtherImage' => 'Other Image Vorschaubild',
+   'OtherImageLength' => 'OtherImage DatenlÃ€nge',
+   'OtherImageStart' => 'Other Image Datenposition',
    'OutputImageHeight' => 'Ausgabe-BildhÃ¶he',
    'OutputImageWidth' => 'Ausgabe-Bildbreite',
    'OutputResolution' => 'Ausgabe AuflÃ¶sung',
+   'OverlayPlanes' => 'Ãberlagerungsebenen',
    'Owner' => 'Besitzer',
    'OwnerID' => 'Besitzer-ID',
    'OwnerName' => 'Name des Besitzers',
    'PEFVersion' => 'PEF-Version',
+   'PNGWarning' => 'PNG Warnung',
    'Padding' => 'Platzhalter',
    'PageName' => 'Seitenname',
    'PageNumber' => 'Seitenummer',
    'Pages' => 'Seiten',
+   'PanOrientation' => {
+      Description => 'Pan Ausrichtung',
+      PrintConv => {
+        'Bottom to top' => 'Von Unten nach Oben',
+        'Clockwise' => 'Im Uhrzeigersinn',
+        'Counter clockwise' => 'Gegen den Uhrzeigersinn',
+        'Left to right' => 'Von Links nach Rechts',
+        'Right to left' => 'Von Rechts nach Links',
+        'Start at bottom left' => 'Links unten beginnend',
+        'Start at bottom right' => 'Rechts unten beginnend',
+        'Start at top left' => 'Links oben beginnend',
+        'Start at top right' => 'Rechts oben beginnend',
+        'Top to bottom' => 'Von Oben nach Unten',
+        '[unused]' => '[nicht verwendet]',
+      },
+    },
+   'PanasonicImageHeight' => 'Panasonic BildhÃ¶he',
+   'PanasonicImageWidth' => 'Panasonic Bildbreite',
    'PanasonicTitle' => 'Titel',
-   'PanoramaDirection' => 'Panorama-Richtung',
+   'PanoramaCropBottom' => 'Panorama Ausschnitt Unten',
+   'PanoramaCropLeft' => 'Panorama Ausschnitt Links',
+   'PanoramaCropRight' => 'Panorame Ausschnitt Rechts',
+   'PanoramaCropTop' => 'Panorama Ausschnitt Oben',
+   'PanoramaDirection' => {
+      Description => 'Panorama-Richtung',
+      PrintConv => {
+        '2x2 Matrix (Clockwise)' => '2x2 Matrix (im Uhrzeigersinn)',
+        'Bottom to Top' => 'Unten nach Oben',
+        'Left to Right' => 'Links nach Rechts',
+        'Right to Left' => 'Rechts nach Links',
+        'Top to Bottom' => 'Oben nach Unten',
+      },
+    },
    'PanoramaFrameNumber' => 'Panorama-Bild',
    'PanoramaMode' => 'Panorama Modus',
+   'PanoramaSize3D' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'PentaxImageSize' => {
       Description => 'Pentax-BildgrÃ¶Ãe',
@@ -3645,6 +6130,13 @@
       },
     },
-   'PentaxModelID' => 'Pentax-Modell',
+   'PentaxModelID' => 'Pentax-Modell ID',
    'PentaxVersion' => 'Pentax-Version',
+   'People' => 'Menschen',
+   'Permits' => {
+      PrintConv => {
+        'Distribution' => 'Verteilung',
+        'Reproduction' => 'Reproduktion',
+      },
+    },
    'PhaseDetectAF' => {
       Description => 'Auto-Fokus',
@@ -3652,5 +6144,7 @@
         'Off' => 'Aus',
         'On (11-point)' => 'Ein (11-Punkt)',
+        'On (39-point)' => 'Ein (39 Punkte)',
         'On (51-point)' => 'Ein (51-Punkt)',
+        'On (hybrid)' => 'Ein (Hybrid)',
       },
     },
@@ -3659,5 +6153,5 @@
       Description => 'Foto-Effekt',
       PrintConv => {
-        'B&W' => 'Schwarz-WeiÃ',
+        'B&W' => 'Schwarz/WeiÃ',
         'Custom' => 'Benutzerdefiniert',
         'Off' => 'Aus',
@@ -3674,5 +6168,5 @@
       Description => 'Bildeffekt-Methode',
       PrintConv => {
-        'B&W' => 'Schwarz-WeiÃ',
+        'B&W' => 'Schwarz/WeiÃ',
         'None' => 'Keine',
         'Tinted' => 'Getont',
@@ -3684,4 +6178,15 @@
         'Info Left-right, Playback Up-down' => 'Info <> / Wiedergabe',
         'Info Up-down, Playback Left-right' => 'Info / Wiedergabe <>',
+      },
+    },
+   'PhotoStyle' => {
+      Description => 'Fotostil',
+      PrintConv => {
+        'Monochrome' => 'Schwarz/WeiÃ',
+        'Natural' => 'NatÃŒrlich',
+        'Portrait' => 'PortrÃ€t',
+        'Scenery' => 'Szene',
+        'Standard or Custom' => 'Standard oder benutzerdefiniert',
+        'Vivid' => 'Lebendig',
       },
     },
@@ -3700,4 +6205,5 @@
    'PhotoshopFormat' => 'Photoshop-Format',
    'PhotoshopQuality' => 'Photoshop-QualitÃ€t',
+   'PhysicalImageSize' => 'Physikalische BildgrÃ¶Ãe',
    'PictureControl' => {
       Description => 'Bildoptimierung',
@@ -3730,4 +6236,5 @@
         'Monochrome' => 'Monochrom',
         'Natural' => 'NatÃŒrlich',
+        'Natural+' => 'NatÃŒrlich+',
         'Night Portrait' => 'NachtportrÃ€t',
         'Night Scene' => 'Nachtszene',
@@ -3752,9 +6259,11 @@
         'Auto PICT (Standard)' => 'Auto PICT (Normal)',
         'Autumn' => 'Herbst',
+        'Backlight Silhouette' => 'Hintergrundbeleuchtung Silhouette',
         'Beach' => 'Strand',
         'Beach & Snow' => 'Strand & Schnee',
         'Black & White' => 'Schwarz/WeiÃ',
         'Blue' => 'Blau',
-        'Blur Reduction' => 'Digital SR (UnschÃ€rfereduktion)',
+        'Blur Control' => 'Bildstabilisierung',
+        'Blur Reduction' => 'UnschÃ€rfereduktion',
         'Bulb' => 'Bulb-Modus',
         'Bulb, Off-Auto-Aperture' => 'Bulb (Blendenring nicht auf A)',
@@ -3765,7 +6274,9 @@
         'Digital Filter' => 'Digitalfilter',
         'Fireworks' => 'Feuerwerk',
+        'Fisheye' => 'Fischauge',
         'Flash X-Sync Speed AE' => 'Blitz X-synch. Zeit',
         'Flower' => 'Blumen',
         'Food' => 'Lebensmittel',
+        'Forest' => 'Wald',
         'Frame Composite' => 'Rahmen',
         'Green' => 'GrÃŒn',
@@ -3789,10 +6300,12 @@
         'Natural Skin Tone' => 'Nat. Hautton',
         'Night Scene' => 'Nachtszene',
+        'Night Scene HDR' => 'Nachtszene',
         'Night Scene Portrait' => 'Nacht-PortrÃ€t',
         'No Flash' => 'Kein Blitz',
-        'Pet' => 'Haustier',
+        'Pet' => 'Haustiere',
         'Pink' => 'Rosa',
         'Portrait' => 'PortrÃ€t',
-        'Program' => 'Programm',
+        'Portrait 2' => 'PortrÃ€t 2',
+        'Program' => 'Programmautomatik',
         'Program (HyP)' => 'Programmautomatik (Hyper-Programm)',
         'Program AE' => 'Programmautomatik',
@@ -3810,7 +6323,7 @@
         'Sports' => 'Sport',
         'Sunset' => 'Sonnenuntergang',
-        'Surf & Snow' => 'Surf + Schnee',
+        'Surf & Snow' => 'Surf & Schnee',
         'Synchro Sound Record' => 'Synchr. Sprachnotiz',
-        'Underwater' => 'Tauchen',
+        'Underwater' => 'Unterwasser',
         'Yellow' => 'Gelb',
       },
@@ -3837,21 +6350,37 @@
     },
    'PictureModeBWFilter' => {
+      Description => 'Motivprogramm S/W Filter',
       PrintConv => {
         'Green' => 'GrÃŒn',
         'Red' => 'Rot',
         'Yellow' => 'Gelb',
-        'n/a' => 'Nicht gesetzt',
-      },
-    },
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'PictureModeContrast' => 'Motivprogramm Kontrast',
+   'PictureModeEffect' => {
+      Description => 'Motivprogramm Effekt',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'PictureModeHue' => 'Motivprogramm Farbton',
+   'PictureModeSaturation' => 'Motivprogramm FarbsÃ€ttigung',
+   'PictureModeSharpness' => 'Motivprogramm SchÃ€rfe',
    'PictureModeTone' => {
+      Description => 'Motivprogramm Tonwert',
       PrintConv => {
         'Blue' => 'Blau',
         'Green' => 'GrÃŒn',
         'Purple' => 'Lila',
-        'n/a' => 'Nicht gesetzt',
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'PictureStyle' => {
-      PrintConv => {
+      Description => 'Bildstil',
+      PrintConv => {
+        'Custom' => 'Benutzerdefiniert',
         'Faithful' => 'NatÃŒrlich',
         'High Saturation' => 'Hohe FarbsÃ€ttigung',
@@ -3859,6 +6388,18 @@
         'Low Saturation' => 'Geringe FarbsÃ€ttigung',
         'Monochrome' => 'Monochrom',
-        'None' => 'Keine',
+        'None' => 'Keiner',
         'Portrait' => 'PortrÃ€t',
+        'Unknown?' => 'Unbekannt?',
+        'User Def. 1' => 'Benutzerdefiniert 1',
+        'User Def. 2' => 'Benutzerdefiniert 2',
+        'User Def. 3' => 'Benutzerdefiniert 3',
+      },
+    },
+   'PictureWizardMode' => {
+      PrintConv => {
+        'Forest' => 'Wald',
+        'Landscape' => 'Landschaft',
+        'Portrait' => 'PortrÃ€t',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -3870,8 +6411,14 @@
     },
    'PixelUnits' => {
+      Description => 'Pixel Einheit',
       PrintConv => {
         'Unknown' => 'Unbekannt',
-      },
-    },
+        'meters' => 'Meter',
+      },
+    },
+   'PixelsPerMeterX' => 'Pixel per Meter X',
+   'PixelsPerMeterY' => 'Pixel per Meter Y',
+   'PixelsPerUnitX' => 'Pixel pro X-Einheit',
+   'PixelsPerUnitY' => 'Pixel pro Y-Einheit',
    'PlanarConfiguration' => {
       Description => 'Bilddatenausrichtung',
@@ -3881,4 +6428,5 @@
       },
     },
+   'Planes' => 'Ebenen',
    'PostalCode' => 'Postleitzahl',
    'PowerSource' => {
@@ -3908,4 +6456,6 @@
       },
     },
+   'PresetWhiteBalanceAdj' => 'WeiÃabgleichkorrektur-Einstellung',
+   'Preview' => 'Preview-IFD-Zeiger',
    'Preview0' => 'Vorschau 0',
    'Preview1' => 'Vorschau 1',
@@ -3916,5 +6466,8 @@
       },
     },
-   'PreviewHeight' => 'Vorschaubild-HÃ¶he',
+   'PreviewCropBottom' => 'Vorschau Ausschnitt Unten',
+   'PreviewCropLeft' => 'Vorschau Ausschnitt Links',
+   'PreviewCropRight' => 'Vorschau Ausschnitt Rechts',
+   'PreviewCropTop' => 'Vorschau Ausschnitt Oben',
    'PreviewIFD' => 'Preview-IFD-Zeiger',
    'PreviewImage' => 'Vorschaubild',
@@ -3935,4 +6488,5 @@
     },
    'PreviewImageWidth' => 'Vorschaubild-Breite',
+   'PreviewPNG' => 'PNG Vorschaubild',
    'PreviewQuality' => {
       Description => 'Vorschaubild-QualitÃ€t',
@@ -3940,7 +6494,9 @@
         'Fine' => 'Fein',
         'Superfine' => 'Superfein',
-      },
-    },
-   'PreviewWidth' => 'Vorschaubild-Breite',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'PreviewSettingsDigest' => 'Kennwert der Voreinstellungen',
+   'PreviewWMF' => 'WMF Vorschaubild',
    'PrimaryAFPoint' => {
       Description => 'PrimÃ€rer AF-Punkt',
@@ -3950,13 +6506,13 @@
         'C6 (Center)' => 'C6 (Mitte)',
         'Center' => 'Mitte',
-        'Far Left' => 'Ganz links',
-        'Far Right' => 'Ganz rechts',
-        'Lower-left' => 'Unten-Links',
-        'Lower-right' => 'Unten-Rechts',
-        'Mid-left' => 'Links-Mitte',
-        'Mid-right' => 'Rechts-Mitte',
+        'Far Left' => 'Weit links',
+        'Far Right' => 'Weit rechts',
+        'Lower-left' => 'Links unten',
+        'Lower-right' => 'Rechts unten',
+        'Mid-left' => 'Links mitte',
+        'Mid-right' => 'Rechts mitte',
         'Top' => 'Oben',
-        'Upper-left' => 'Oben-Links',
-        'Upper-right' => 'Oben-Rechts',
+        'Upper-left' => 'Links oben',
+        'Upper-right' => 'Rechts oben',
       },
     },
@@ -3965,4 +6521,7 @@
    'ProcessingInfo' => 'Verarbeitungsinformationen',
    'ProcessingSoftware' => 'Verarbeitungssoftware',
+   'Producer' => 'Produzent',
+   'ProducerKeywords' => 'Hersteller SchlÃŒsselwÃ¶rter',
+   'Producers' => 'Produzent',
    'ProductID' => 'Produkt-ID',
    'ProductionCode' => 'Herstellungskennzeichen',
@@ -3983,12 +6542,27 @@
    'ProfileConnectionSpace' => 'Profil-Verbindungsfarbraum',
    'ProfileCopyright' => 'Urheberrechtsvermerk',
-   'ProfileCreator' => 'Profil-Ersteller',
+   'ProfileCreator' => 'Profilersteller',
    'ProfileDateTime' => 'Profil-Erstellungszeit',
-   'ProfileDescription' => 'Profil-Beschreibung',
-   'ProfileDescriptionML' => 'Profil-Beschreibung ML',
+   'ProfileDescription' => 'Farbprofil Name',
+   'ProfileDescriptionML' => 'Farbprofil Name mehrsprachig',
    'ProfileFileSignature' => 'Profil-Datei-Signatur',
    'ProfileID' => 'Profile-ID',
    'ProfileSequenceDesc' => 'Profilsequenz-Beschreibung',
+   'ProfileToneCurve' => 'Tonwertkurve Profil',
+   'ProfileType' => {
+      Description => 'Profiltyp',
+      PrintConv => {
+        'Group 3 FAX' => 'Gruppe 3 Fax',
+        'Unspecified' => 'Nicht bekannt',
+      },
+    },
    'ProfileVersion' => 'Profil-Version',
+   'ProgramISO' => {
+      Description => 'ISO Programm',
+      PrintConv => {
+        'Intelligent ISO' => 'ISO intelligent',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'ProgramLine' => {
       Description => 'Belichtungsprogrammtyp',
@@ -4000,7 +6574,8 @@
     },
    'ProgramMode' => {
+      Description => 'Programmmodus',
       PrintConv => {
         'Night Portrait' => 'NachtportrÃ€t',
-        'None' => 'Keine',
+        'None' => 'Keiner',
         'Portrait' => 'PortrÃ€t',
         'Sports' => 'Sport',
@@ -4010,9 +6585,15 @@
    'ProgramShift' => 'Programmverschiebung',
    'ProgramVersion' => 'Programmversion',
+   'Prohibits' => {
+      Description => 'Verbote',
+      PrintConv => {
+        'Commercial Use' => 'Kommerzielle Verwendung',
+      },
+    },
    'Protect' => 'Schutz',
    'Province-State' => 'Bundesland/Kanton',
    'Publisher' => 'Herausgeber',
    'Quality' => {
-      Description => 'BildqualitÃ€t',
+      Description => 'QualitÃ€t',
       PrintConv => {
         'Best' => 'Optimal',
@@ -4029,6 +6610,8 @@
         'Super Fine' => 'Super-Fein',
         'Superfine' => 'Superfein',
-      },
-    },
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'Quality2' => 'QualitÃ€t 2',
    'QualityMode' => {
       PrintConv => {
@@ -4036,4 +6619,5 @@
       },
     },
+   'QuickAdjust' => 'Schnelleinstellung',
    'QuickControlDialInMeter' => {
       Description => 'Schnelleinstellrad bei Messung',
@@ -4080,15 +6664,47 @@
       },
     },
+   'RawBrightnessAdj' => 'Raw Helligkeitskorrektur',
    'RawColorAdj' => {
+      Description => 'Raw Farbkorrektur',
       PrintConv => {
         'Custom' => 'Benutzerdefiniert',
-      },
-    },
-   'RawDataLength' => 'RAW DatenlÃ€nge',
-   'RawDataOffset' => 'RAW-Daten-Offset',
+        'Faithful' => 'NatÃŒrlich',
+        'Shot Settings' => 'Aufnahmeeinstellung',
+      },
+    },
+   'RawCropBottom' => 'Raw Ausschnitt Unten',
+   'RawCropLeft' => 'Raw Ausschnitt Links',
+   'RawCropRight' => 'Raw Ausschnitt Rechts',
+   'RawCropTop' => 'Raw Ausschnitt Oben',
+   'RawData' => 'Raw-Daten',
+   'RawDataByteOrder' => 'RAW Daten Bytereihenfolge',
+   'RawDataLength' => 'RAW-Daten LÃ€nge',
+   'RawDataOffset' => 'RAW-Daten Offset',
+   'RawDataUniqueID' => 'Raw-Daten eindeutige ID',
+   'RawDevArtFilter' => {
+      PrintConv => {
+        'Drawing' => 'Zeichnung',
+        'Fish Eye' => 'Fischauge',
+        'Off' => 'Aus',
+        'Reflection' => 'Reflektierung',
+        'Soft Focus' => 'Weichzeichner',
+        'Soft Focus 2' => 'Weichzeichner 2',
+        'Sparkle' => 'Perleffekt',
+        'Watercolor' => 'Wasserfarbe',
+        'Watercolor II' => 'Wasserfarbe II',
+      },
+    },
    'RawDevAutoGradation' => {
       PrintConv => {
         'Off' => 'Aus',
         'On' => 'Ein',
+      },
+    },
+   'RawDevNoiseReduction' => {
+      Description => 'RAW RauschunterdrÃŒckung',
+      PrintConv => {
+        'Noise Filter' => 'Rauschfilter',
+        'Noise Filter (ISO Boost)' => 'Rauschfilter (ISO Boost)',
+        'Noise Reduction' => 'Rauschreduktion',
       },
     },
@@ -4117,6 +6733,13 @@
       },
     },
+   'RawFile' => 'RAW Datei',
+   'RawFileName' => 'RAW Dateiname',
    'RawImageCenter' => 'RAW-Bildmitte',
+   'RawImageDigest' => 'RAW Image Kennwert',
+   'RawImageHeight' => 'Raw BildhÃ¶he',
+   'RawImageSegmentation' => 'Raw Bild Aufteilung',
    'RawImageSize' => 'RAW-BildgrÃ¶Ãe',
+   'RawImageWidth' => 'Raw Bildbreite',
+   'RawInfoVersion' => 'RawInfo Version',
    'RawJpgQuality' => {
       Description => 'RAW JPEG-QualitÃ€t',
@@ -4124,4 +6747,5 @@
         'Fine' => 'Fein',
         'Superfine' => 'Superfein',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -4142,4 +6766,13 @@
     },
    'RawMeasuredRGGB' => 'Raw Messung RGGB',
+   'RecognizedFace1Age' => 'Alter erkanntes Gesicht 1',
+   'RecognizedFace1Name' => 'Name erkanntes Gesicht 1',
+   'RecognizedFace1Position' => 'Position erkanntes Gesicht 1',
+   'RecognizedFace2Age' => 'Alter erkanntes Gesicht 2',
+   'RecognizedFace2Name' => 'Name erkanntes Gesicht 2',
+   'RecognizedFace2Position' => 'Position erkanntes Gesicht 2',
+   'RecognizedFace3Age' => 'Alter erkanntes Gesicht 3',
+   'RecognizedFace3Name' => 'Name erkanntes Gesicht 3',
+   'RecognizedFace3Position' => 'Position erkanntes Gesicht 3',
    'RecordMode' => {
       Description => 'Aufzeichnungsmodus',
@@ -4159,8 +6792,11 @@
       },
     },
+   'RedAdjust' => 'Rot-Korrektur',
    'RedBalance' => 'Farbabgleich Rot',
    'RedEyeCorrection' => {
+      Description => 'Rote-Augen-Reduzierung',
       PrintConv => {
         'Automatic' => 'Automatisch',
+        'Click on Eyes' => 'Klick auf Augen',
         'Off' => 'Aus',
       },
@@ -4174,8 +6810,11 @@
     },
    'RedMatrixColumn' => 'Rot-Matrixspalte',
+   'RedSaturation' => 'FarbsÃ€ttingung Rot',
    'RedTRC' => 'Rot-Tonwertwiedergabe-Kurve',
+   'RedX' => 'Rotpunkt X',
+   'RedY' => 'Rotpunkt Y',
    'ReductionMatrix1' => 'Reduktionsmatrix 1',
    'ReductionMatrix2' => 'Reduktionsmatrix 2',
-   'ReferenceBlackWhite' => 'Schwarz/WeiÃ-Referenzpunkte',
+   'ReferenceBlackWhite' => 'Schwarz-WeiÃ-Referenzpunkte',
    'ReferenceDate' => 'Referenzdatum',
    'ReferenceNumber' => 'Referenznummer',
@@ -4194,5 +6833,14 @@
     },
    'ReleaseDate' => 'VerÃ¶ffentlichungsdatum',
-   'ReleaseMode' => 'AuslÃ¶semodus',
+   'ReleaseMode' => {
+      Description => 'AuslÃ¶semodus',
+      PrintConv => {
+        'AE Bracketing' => 'Belichtungsreihe',
+        'Contrast Bracketing' => 'Kontrast Belichtungsreihe',
+        'High Speed Burst' => 'Aufnahme Burst',
+        'WB Bracketing' => 'WeiÃabgleich-Belichtungsreihe',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'ReleaseTime' => 'VerÃ¶ffentlichungszeit',
    'RemoteOnDuration' => 'FernauslÃ¶ser',
@@ -4226,6 +6874,5 @@
       PrintConv => {
         'None' => 'Keine',
-        'cm' => 'Pixel/cm',
-        'inches' => 'Inch',
+        'inches' => 'Zoll',
       },
     },
@@ -4233,12 +6880,16 @@
       Description => 'Bildbearbeitungsschritte',
       PrintConv => {
-        'B & W' => 'SchwarzweiÃ',
+        'B & W' => 'Schwarz/WeiÃ',
         'Color Custom' => 'Farbabgleich',
         'Cyanotype' => 'Blauton',
+        'Distortion Control' => 'Verzeichnungskontrolle',
+        'Fisheye' => 'Fischauge',
         'Image Overlay' => 'Bildmontage',
         'None' => 'Keine',
+        'Perspective Control' => 'Perspektivenkontrolle',
         'Red Eye' => 'Rote-Augen-Korrektur',
         'Sky Light' => 'Skylight',
         'Small Picture' => 'Kompaktbild',
+        'Soft Filter' => 'Weichzeichner',
         'Trim' => 'Beschneiden',
         'Warm Tone' => 'Warmer Farbton',
@@ -4246,4 +6897,12 @@
     },
    'ReverseIndicators' => 'Skalen spiegeln',
+   'ReverseShutterSpeedAperture' => {
+      PrintConv => {
+        'No' => 'Nein',
+        'Yes' => 'Ja',
+      },
+    },
+   'RevisionDate' => 'Revisionsdatum',
+   'RevisionNumber' => 'Revisionsnummer',
    'RicohDate' => 'Ricoh Datum',
    'RicohImageHeight' => 'Ricoh-BildhÃ¶he',
@@ -4253,13 +6912,11 @@
       Description => 'Ausrichtung',
       PrintConv => {
-        'Horizontal' => '0Â° (oben/links)',
-        'Horizontal (Normal)' => '0Â° (oben/links)',
-        'Horizontal (normal)' => '0Â° (oben/links)',
-        'Rotate 180' => '180Â° (unten/rechts)',
-        'Rotate 270 CW' => '90Â° im Uhrzeigersinn (links/unten)',
-        'Rotate 90 CW' => '90Â° gegen den Uhrzeigersinn (rechts/oben)',
-        'Rotated 180' => '180Â° (unten/rechts)',
-        'Rotated 270 CW' => '90Â° im Uhrzeigersinn (links/unten)',
-        'Rotated 90 CW' => '90Â° gegen den Uhrzeigersinn (rechts/oben)',
+        'Horizontal (Normal)' => 'Horizontal (normal)',
+        'Rotate 180' => '180Â° gedreht',
+        'Rotate 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotate 90 CW' => '90Â° im Uhrzeigersinn',
+        'Rotated 180' => '180Â° gedreht',
+        'Rotated 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotated 90 CW' => '90Â° im Uhrzeigersinn',
       },
     },
@@ -4267,6 +6924,7 @@
    'SPIFFVersion' => 'SPIFF-Version',
    'SRAWQuality' => {
-      PrintConv => {
-        'n/a' => 'Nicht gesetzt',
+      Description => 'SRAW QualitÃ€t',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -4314,20 +6972,104 @@
       Description => 'FarbsÃ€ttigung',
       PrintConv => {
+        '+1 (medium high)' => '+1 (Leicht erhÃ¶ht)',
+        '+2 (high)' => '+2 (Hohe FarbsÃ€ttigung)',
+        '+3 (very high)' => '+3 (Sehr hoch)',
+        '+4 (highest)' => '+4',
+        '+4 (maximum)' => '+4',
+        '-1 (medium low)' => '-1 (Leicht verringert)',
+        '-2 (low)' => '-2 (Geringe FarbsÃ€ttigung)',
+        '-3 (very low)' => '-3 (Sehr gering)',
+        '-4 (lowest)' => '-4',
+        '-4 (minimum)' => '-4',
+        '0 (normal)' => '0 (Normal)',
+        'B&W' => 'Schwarz/WeiÃ',
+        'B&W Green Filter' => 'Schwarz-WeiÃ GrÃŒnfilter',
+        'B&W Red Filter' => 'Schwarz-WeiÃ Rotfilter',
+        'B&W Sepia' => 'Schwarz-WeiÃ Sepia',
+        'B&W Yellow Filter' => 'Schwarz-WeiÃ Gelbfilter',
+        'Black & White' => 'Schwarz/WeiÃ',
         'Film Simulation' => 'Film-Simulation',
         'High' => 'Hohe FarbsÃ€ttigung',
         'Low' => 'Geringe FarbsÃ€ttigung',
-        'Med High' => 'Leicht erhÃ¶ht',
-        'Med Low' => 'Leicht verringert',
         'Medium High' => 'Mittel-Hoch',
         'Medium Low' => 'Mittel-Gering',
+        'Natural' => 'NatÃŒrlich',
         'None' => 'Nicht gesetzt',
         'None (B&W)' => 'Keine (S&W)',
-        'Normal' => 'Standard',
-        'Very High' => 'Sehr hoch',
-        'Very Low' => 'Sehr gering',
+        'Toning Effect' => 'TÃ¶nungseffekt',
+        'Vintage B&W' => 'Vintage Schwarz-WeiÃ',
+        'Vivid' => 'Lebhaft',
+      },
+    },
+   'SaturationAdj' => 'SÃ€ttigungskorrektur',
+   'SaturationAdjustmentAqua' => 'FarbsÃ€ttigung Korrektur Cyan',
+   'SaturationAdjustmentBlue' => 'FarbsÃ€ttigung Korrektur Blau',
+   'SaturationAdjustmentGreen' => 'FarbsÃ€ttigung Korrektur GrÃŒn',
+   'SaturationAdjustmentMagenta' => 'FarbsÃ€ttigung Korrektur Magenta',
+   'SaturationAdjustmentOrange' => 'FarbsÃ€ttigung Korrektur Orange',
+   'SaturationAdjustmentPurple' => 'FarbsÃ€ttigung Korrektur Lila',
+   'SaturationAdjustmentRed' => 'FarbsÃ€ttigung Korrektur Rot',
+   'SaturationAdjustmentYellow' => 'FarbsÃ€ttigung Korrektur Gelb',
+   'SaturationFaithful' => {
+      Description => 'FarbsÃ€ttigung NatÃŒrlich',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'SaturationInfo' => 'FarbsÃ€ttigung',
+   'SaturationLandscape' => {
+      Description => 'FarbsÃ€ttigung Landschaft',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SaturationMonochrome' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SaturationNeutral' => {
+      Description => 'FarbsÃ€ttigung Neutral',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SaturationPlanes' => 'SÃ€ttigungsebenen',
+   'SaturationPortrait' => {
+      Description => 'FarbsÃ€ttigung PortrÃ€t',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'SaturationSetting' => 'SÃ€ttigungseinstellung',
+   'SaturationStandard' => {
+      Description => 'FarbsÃ€ttigung Standard',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SaturationUnknown' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SaturationUserDef1' => {
+      Description => 'FarbsÃ€ttigung Benutzerdefiniert 1',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SaturationUserDef2' => {
+      Description => 'FarbsÃ€ttigung Benutzerdefiniert 2',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SaturationUserDef3' => {
+      Description => 'FarbsÃ€ttigung Benutzerdefiniert 3',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'ScaleFactor35efl' => 'Formatfaktor zu 35 mm',
    'ScanImageEnhancer' => {
@@ -4350,9 +7092,10 @@
       Description => 'Szenen-Modus',
       PrintConv => {
-        '3D Sweep Panorama' => '3D',
-        'Anti Motion Blur' => 'Anti-bewegingswaas',
+        '3D Sweep Panorama' => '3D Sweep-Panorama',
+        'Anti Motion Blur' => 'Verwackelungsschutz',
         'Aperture Priority' => 'BlendenprioritÃ€t',
         'Auto' => 'Automatisch',
         'Available Light' => 'VerfÃŒgbares Licht',
+        'Baby' => 'Kleinkind',
         'Beach' => 'Strand',
         'Beach & Snow' => 'Strand & Schnee',
@@ -4361,21 +7104,32 @@
         'Candlelight' => 'Kerzenlicht',
         'Children' => 'Kinder',
-        'Cont. Priority AE' => 'Continuvoork. AE',
+        'Color Effects' => 'Farbeffekte',
+        'Cont. Priority AE' => 'Andauernde AE PrioritÃ€t',
+        'Creative Control' => 'Kreativprogramm',
+        'Digital Filter' => 'Digitaler Filter',
         'Documents' => 'Dokumente',
         'Fireworks' => 'Feuerwerk',
-        'Handheld Night Shot' => 'Nachtopname uit hand',
+        'Food' => 'Lebensmittel',
+        'Handheld Night Shot' => 'Nachtaufnahme hÃ€ndisch',
+        'High Key' => 'High-Key',
+        'High Sensitivity' => 'Hohe Empfindlichkeit',
         'Indoor' => 'Innenaufnahme',
+        'Intelligent ISO' => 'Iso Intelligent',
         'Landscape' => 'Landschaft',
         'Landscape+Portrait' => 'Landschaft+PortrÃ€t',
+        'Low Key' => 'Low-Key',
         'Macro' => 'Makro',
         'Manual' => 'Manuell',
         'My Mode' => 'Benutzerdefiniert',
+        'Night Landscape' => 'Landschaft bei Nacht',
         'Night Portrait' => 'NachtportrÃ€t',
         'Night Scene' => 'Nachtszene',
-        'Night View/Portrait' => 'Abendszene/NachtportrÃ€t',
+        'Night Scenery' => 'Nachtszene',
+        'Night View/Portrait' => 'Abendszene/PortrÃ€t',
         'Night+Portrait' => 'Nacht+PortrÃ€t',
         'Off' => 'Aus',
+        'Pet' => 'Haustiere',
         'Portrait' => 'PortrÃ€t',
-        'Program' => 'Programm',
+        'Program' => 'Programmautomatik',
         'Self Portrait' => 'SelbstportrÃ€t',
         'Self Portrait+Self Timer' => 'SelbstportrÃ€t+SelbstauslÃ¶ser',
@@ -4384,9 +7138,13 @@
         'Sports' => 'Sport',
         'Spot' => 'Spotmessung',
-        'Standard' => '',
+        'Starry Night' => 'Sternennacht',
         'Sunset' => 'Sonnenuntergang',
         'Super Macro' => 'Super-Makro',
-        'Sweep Panorama' => 'Panorama d. beweg.',
-        'Underwater' => 'Tauchen',
+        'Sweep Panorama' => 'Sweep-Panorama',
+        'Underwater' => 'Unterwasser',
+        'Underwater Macro' => 'Unterwasser Makro',
+        'Underwater Wide1' => 'Unterwasserlandschaft',
+        'Underwater Wide2' => 'Unterwasserlandschaft 2',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -4397,11 +7155,13 @@
         'Beach' => 'Strand',
         'Candlelight' => 'Kerzenlicht',
+        'Children' => 'Kinder',
         'Fireworks' => 'Feuerwerk',
         'Landscape' => 'Landschaft',
         'Macro' => 'Makro',
         'Manual' => 'Manuell',
+        'Night Landscape' => 'Landschaft bei Nacht',
         'Night Portrait' => 'NachtportrÃ€t',
         'Portrait' => 'PortrÃ€t',
-        'Program' => 'Programm',
+        'Program' => 'Programmautomatik',
         'Shutter Priority' => 'VerschlussprioritÃ€t',
         'Snow' => 'Schnee',
@@ -4419,4 +7179,14 @@
       PrintConv => {
         'Directly photographed' => 'Direkt aufgenommenes Bild',
+      },
+    },
+   'Security' => {
+      Description => 'Sicherheit',
+      PrintConv => {
+        'Locked for annotations' => 'Gesperrt fÃŒr Anmerkungen',
+        'None' => 'Keine',
+        'Password protected' => 'Passwort geschÃŒtzt',
+        'Read-only enforced' => 'Nur Lesen - erzwungen',
+        'Read-only recommended' => 'Nur Lesen - vorgeschlagen',
       },
     },
@@ -4431,11 +7201,22 @@
       },
     },
+   'SelectAFAreaSelectMode' => {
+      Description => 'AF-Bereich Auswahlmodus',
+      PrintConv => {
+        'Disable' => 'Deaktiviert',
+        'Enable' => 'Aktiviert',
+        'Select AF-modes' => 'Wahl AF-Modus',
+      },
+    },
    'SelectableAFPoint' => {
       Description => 'WÃ€hlbares AF-Feld',
       PrintConv => {
         '11 points' => '11 Felder',
+        '19 Points, Multi-controller selectable' => '19 Punkte, wÃ€hlbar mit Multicontroller',
         '19 points' => '19 Felder',
         '45 points' => '45 Felder',
+        'Inner 9 Points, Multi-controller selectable' => 'Innere 9 Punkte, wÃ€hlbar mit Multicontroller',
         'Inner 9 points' => 'Innere 9 Felder',
+        'Outer 9 Points, Multi-controller selectable' => 'ÃuÃere 9 Punkte, wÃ€hlbar mit Multicontroller',
         'Outer 9 points' => 'ÃuÃere 9 Felder',
       },
@@ -4444,4 +7225,5 @@
       Description => 'SelbstauslÃ¶ser',
       PrintConv => {
+        '10 s / 3 pictures' => '10 s / 3 Bilder',
         'Off' => 'Aus',
         'On' => 'Ein',
@@ -4473,7 +7255,21 @@
       },
     },
+   'SensitivityType' => {
+      Description => 'Art der Empfindlichkeit',
+      PrintConv => {
+        'ISO Speed' => 'ISO Empfindlichkeit',
+        'Recommended Exposure Index' => 'Empfohlener Belichtungsindex',
+        'Recommended Exposure Index and ISO Speed' => 'Empfohlener Belichtungsindex und ISO Empfindlichkeit',
+        'Standard Output Sensitivity' => 'Standard Ausgabeempfindlichkeit',
+        'Standard Output Sensitivity and ISO Speed' => 'Standard Ausgabeempfindlichkeit und ISO Empfindlichkeit',
+        'Standard Output Sensitivity and Recommended Exposure Index' => 'Standard Ausgabeempfindlichkeit und empfohlener Belichtungsindex',
+        'Standard Output Sensitivity, Recommended Exposure Index and ISO Speed' => 'Standard Ausgabeempfindlichkeit,empfohlener Belichtungsindex und ISO Empfindlichkeit',
+        'Unknown' => 'Unbekannt',
+      },
+    },
    'SensorBlueLevel' => 'Sensor Blau-Level',
    'SensorBottomBorder' => 'Sensor unterer Rand',
    'SensorCleaning' => {
+      Description => 'Sensorreinigung',
       PrintConv => {
         'Disable' => 'Nicht mÃ¶glich',
@@ -4492,7 +7288,15 @@
    'SensorTopBorder' => 'Sensor oberer Rand',
    'SensorWidth' => 'Sensor Breite',
-   'SequenceNumber' => 'Bildsequenznummer',
+   'SequenceNumber' => {
+      Description => 'Bildsequenznummer',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'SequentialShot' => {
-      PrintConv => {
+      Description => 'Reihenaufnahme',
+      PrintConv => {
+        'Adjust Exposure' => 'Belichtungskorrektur',
+        'Best' => 'Beste',
         'None' => 'Keine',
       },
@@ -4505,5 +7309,5 @@
       PrintConv => {
         'Cross keys: AF point select' => 'Kreuztaste:AF Feld Auswahl',
-        'Set: Flash Exposure Comp' => 'SET:Blitzbe. Korr.',
+        'Set: Flash Exposure Comp' => 'SET:Blitzbelichtungskorrektur',
         'Set: Parameter' => 'SET:Parameter Ã€ndern',
         'Set: Picture Style' => 'SET:Bildstil',
@@ -4516,4 +7320,5 @@
       Description => 'SET-Taste bei Aufnahme',
       PrintConv => {
+        'Change ISO speed' => 'ISO-Wert Ã€ndern',
         'Change parameters' => 'Parameter Ã€ndern',
         'Default (no function)' => 'Normal (gesperrt)',
@@ -4528,5 +7333,5 @@
         'Normal (disabled)' => 'Normal (gesperrt)',
         'Picture style' => 'Bildstil',
-        'Quick control screen' => 'Schnelleinstell.bildschirm',
+        'Quick control screen' => 'Schnelleinstellung Bildschirm',
         'Record func. + media/folder' => 'Aufnahme-Funktion + Medium/Ordner',
         'Record movie (Live View)' => 'Movie-Aufnahme (Livebild)',
@@ -4559,4 +7364,5 @@
       },
     },
+   'Shadow' => 'Schatten',
    'Shadows' => 'Schatten',
    'ShakeReduction' => {
@@ -4568,21 +7374,43 @@
     },
    'ShakeReductionInfo' => 'Bildstabilisator',
+   'SharpenDetail' => 'SchÃ€rfungsdetail',
+   'SharpenRadius' => 'SchÃ€rfungsradius',
+   'Sharpening' => {
+      Description => 'SchÃ€rfung',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'Medium High' => 'Mittel',
+        'Off' => 'Aus',
+      },
+    },
+   'SharpeningAdj' => 'SchÃ€rfekorrektur',
    'Sharpness' => {
       Description => 'SchÃ€rfe',
       PrintConv => {
+        '+1 (medium hard)' => '+1 (Leicht erhÃ¶ht)',
+        '+2 (hard)' => '+2 (Stark)',
+        '+3 (very hard)' => '+3 (Sehr hoch)',
+        '+4 (hardest)' => '+4',
+        '+4 (maximum)' => '+4',
+        '-1 (medium soft)' => '-1 (Leicht verringert)',
+        '-2 (soft)' => '-2 (Leicht)',
+        '-3 (very soft)' => '-3 (Sehr weich)',
+        '-4 (minimum)' => '-4',
+        '-4 (softest)' => '-4',
+        '0 (normal)' => '0 (Normal)',
         'Film Simulation' => 'Film-Simulation',
         'Hard' => 'Stark',
-        'Hard2' => 'Hart2',
-        'Med Hard' => 'Leicht erhÃ¶ht',
-        'Med Soft' => 'Leicht verringert',
-        'Medium Hard' => 'Mittel-Hart',
-        'Medium Soft' => 'Mittel-Weich',
-        'Normal' => 'Standard',
-        'Sharp' => 'Weich',
+        'Sharp' => 'Hart',
         'Soft' => 'Leicht',
-        'Soft2' => 'Weich 2',
-        'Very Hard' => 'Sehr hoch',
-        'Very Soft' => 'Sehr weich',
-        'n/a' => 'Nicht gesetzt',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessAdj' => 'SchÃ€rfekorrektur',
+   'SharpnessFactor' => 'SchÃ€rfungsfaktor',
+   'SharpnessFaithful' => {
+      Description => 'SchÃ€rfe NatÃŒrlich',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -4592,8 +7420,65 @@
         'Highest' => 'HÃ¶chste',
         'Low' => 'Leicht',
-        'n/a' => 'Nicht gesetzt',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessLandscape' => {
+      Description => 'SchÃ€rfe Landschaft',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessMonochrome' => {
+      Description => 'SchÃ€rfe Monochrom',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessNeutral' => {
+      Description => 'SchÃ€rfe Neutral',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessOvershoot' => 'SchÃ€rfe GrenzwertÃŒberschreitung',
+   'SharpnessPortrait' => {
+      Description => 'SchÃ€rfe PortrÃ€t',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'SharpnessSetting' => 'SchÃ€rfeeinstellung',
+   'SharpnessStandard' => {
+      Description => 'SchÃ€rfe Standard',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessTable' => 'SchÃ€rfe Tabelle',
+   'SharpnessThreshold' => 'SchÃ€rfe Grenzwert',
+   'SharpnessUndershoot' => 'SchÃ€rfe Grenzwertunterschreitung',
+   'SharpnessUnknown' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessUserDef1' => {
+      Description => 'SchÃ€rfe Benutzerdefiniert 1',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessUserDef2' => {
+      Description => 'SchÃ€rfe Benutzerdefiniert 2',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SharpnessUserDef3' => {
+      Description => 'SchÃ€rfe Benutzerdefiniert 3',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
    'ShootingInfoDisplay' => {
       Description => 'Aufnahmeinfo-Ansicht',
@@ -4608,18 +7493,26 @@
       PrintConv => {
         'Aperture Priority' => 'BlendenprioritÃ€t',
+        'Baby' => 'Kleinkind',
         'Beach' => 'Strand',
         'Candlelight' => 'Kerzenlicht',
+        'Color Effects' => 'Farbeffekte',
         'Fireworks' => 'Feuerwerk',
+        'Food' => 'Lebensmittel',
+        'High Sensitivity' => 'Hohe Empfindlichkeit',
         'Macro' => 'Makro',
         'Manual' => 'Manuell',
         'Night Portrait' => 'NachtportrÃ€t',
+        'Night Scenery' => 'Nachtszene',
+        'Pet' => 'Haustiere',
         'Portrait' => 'PortrÃ€t',
-        'Program' => 'Programm',
+        'Program' => 'Programmautomatik',
+        'Self Portrait' => 'Selbstportait',
         'Shutter Priority' => 'VerschlussprioritÃ€t',
         'Snow' => 'Schnee',
         'Sports' => 'Sport',
         'Spot' => 'Spotmessung',
+        'Starry Night' => 'Sternennacht',
         'Sunset' => 'Sonnenuntergang',
-        'Underwater' => 'Tauchen',
+        'Underwater' => 'Unterwasser',
       },
     },
@@ -4634,6 +7527,6 @@
       },
     },
+   'ShortDescription' => 'Kurzbeschreibung',
    'ShortDocumentID' => 'Kurze Bild-ID',
-   'ShortFocal' => 'Kleinste Brennweite',
    'ShortReleaseTimeLag' => {
       Description => 'VerkÃŒrzte AuslÃ¶severzÃ¶gerung',
@@ -4648,8 +7541,8 @@
       PrintConv => {
         'AE lock/AF' => 'AE-Speicherung/AF',
-        'AE/AF, No AE lock' => 'AE/AF, keine AE-Spei.',
+        'AE/AF, No AE lock' => 'AE/AF, keine AE-Speicherung',
         'AF/AE lock' => 'AF/AE-Speicherung',
         'AF/AF lock' => 'AF/AF-Speicherung',
-        'AF/AF lock, No AE lock' => 'AF/AF-Spei.keine AE-Spei.',
+        'AF/AF lock, No AE lock' => 'AF/AF-Speicherung, keine AE-Speicherung',
       },
     },
@@ -4686,4 +7579,10 @@
       },
     },
+   'ShutterReleaseMethod' => {
+      PrintConv => {
+        'Continuous Shooting' => 'Serienaufnahme',
+        'Single Shot' => 'Einzelbild',
+      },
+    },
    'ShutterReleaseNoCFCard' => {
       Description => 'Verschlussausl. ohne Karte',
@@ -4693,5 +7592,12 @@
       },
     },
+   'ShutterReleaseTiming' => {
+      PrintConv => {
+        'Priority on focus' => 'SchÃ€rfeprioritÃ€t',
+        'Priority on shutter' => 'VerschluÃprioritÃ€t',
+      },
+    },
    'ShutterSpeed' => 'Belichtungsdauer',
+   'ShutterSpeedDisplayed' => 'Angezeigte Belichtungszeit',
    'ShutterSpeedRange' => {
       Description => 'Einstellung Blendenbereich',
@@ -4701,6 +7607,14 @@
       },
     },
+   'ShutterSpeedSetting' => 'Belichtungszeit Einstellung',
    'ShutterSpeedValue' => 'Belichtungszeit',
    'SimilarityIndex' => 'Bildgleichheits-Index',
+   'SingleFrameBracketing' => {
+      Description => 'Einzelbild-Belichtungsreihe',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+      },
+    },
    'SlaveFlashMeteringSegments' => 'Slave-Blitz-Messfeld',
    'SlideShow' => {
@@ -4717,4 +7631,5 @@
         'Off' => 'Aus',
         'On' => 'Ein',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -4723,15 +7638,50 @@
       PrintConv => {
         'Off' => 'Aus',
-        'On' => 'An',
+        'On' => 'Ein',
+      },
+    },
+   'SoftSkinEffect' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'SonyImageSize' => {
+      Description => 'Sony BildgrÃ¶Ãe',
+      PrintConv => {
+        'Large' => 'GroÃ',
+        'Large (16:9)' => 'GroÃ (16:9)',
+        'Large (3:2)' => 'GroÃ (3:2)',
+        'Medium' => 'Mittel',
+        'Medium (16:9)' => 'Mittel (16:9)',
+        'Medium (3:2)' => 'Mittel (3:2)',
+        'Small' => 'Klein',
+        'Small (16:9)' => 'Klein (16:9)',
+        'Small (3:2)' => 'Klein (3:2)',
       },
     },
    'Source' => 'Quelle',
    'SpatialFrequencyResponse' => 'Raumfrequenz-Antwort',
+   'SpecialEffectMode' => {
+      Description => 'Spezialeffekte Modus',
+      PrintConv => {
+        'Mist Removal' => 'Dunstentfernung',
+        'Off' => 'Aus',
+        'Vivid Landscape' => 'Lebende Landschaft',
+      },
+    },
    'SpecialEffectsOpticalFilter' => {
-      PrintConv => {
-        'None' => 'Keine',
+      Description => 'Spezialeffekt Filter',
+      PrintConv => {
+        'Colored' => 'Farbfilter',
+        'Diffusion' => 'Diffusionsfilter',
+        'Multi-image' => 'Mehrfachbildfilter',
+        'None' => 'Keiner',
+        'Polarizing' => 'Polarisationsfilter',
+        'Split-field' => 'Splitfilter',
+        'Star' => 'Sternenfilter',
       },
     },
    'SpecialInstructions' => 'Anweisungen',
+   'SpecialMode' => 'Spezialmodus',
    'SpectralSensitivity' => 'Spektralempfindlichkeit',
    'SpotFocusPointX' => 'Spot-Fokuspunkt X',
@@ -4752,4 +7702,5 @@
     },
    'State' => 'Bundesland/Kanton',
+   'StereoMode' => 'Stereomodus',
    'StripByteCounts' => 'Anzahl Bytes pro komprimiertem Bildabschnitt',
    'StripOffsets' => 'Bilddatenposition',
@@ -4758,11 +7709,22 @@
    'SubSecDateTimeOriginal' => 'Erstellungsdatum/-uhrzeit',
    'SubSecModifyDate' => 'Ãnderungsdatum',
-   'SubSecTime' => 'DateTime 1/100 Sekunden',
+   'SubSecTime' => 'Datum/Uhrzeit 1/100 Sekunden',
    'SubSecTimeDigitized' => 'Digitalisierungsdatum/-uhrzeit 1/100 Sekunden',
    'SubSecTimeOriginal' => 'Erstellungsdatum/-uhrzeit 1/100 Sekunden',
    'SubfileType' => {
-      Description => 'Neuer Unterdatei-Typ',
-      PrintConv => {
+      Description => 'Unterdatei-Typ',
+      PrintConv => {
+        'Alternate reduced-resolution image' => 'Alternatives Bild in reduzierter 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',
+        'TIFF-FX mixed raster content' => 'TIFF-FX gersteter Inhalt',
+        'TIFF/IT final page' => 'TIFF/IT endgÃŒltige Seite',
         'Thumbnail image' => 'Miniaturbild',
+        'Transparency mask' => 'Transparenzmaske',
+        'Transparency mask of multi-page image' => 'Transparenzmaske eines mehrseitigen Bildes',
+        'Transparency mask of reduced-resolution image' => 'Transparenzmaske eines Bildes in reduzierter AuflÃ¶sung',
+        'Transparency mask of reduced-resolution multi-page image' => 'Transparenzmaske eines mehrseitigen Bildes in reduzierter AuflÃ¶sung',
       },
     },
@@ -4772,6 +7734,7 @@
       },
     },
-   'Subject' => 'Subjekt',
+   'Subject' => 'Themen/SchlÃŒsselwÃ¶rter',
    'SubjectArea' => 'Hauptobjektposition',
+   'SubjectCode' => 'IPTC Themencode',
    'SubjectDistance' => 'Objektentfernung',
    'SubjectDistanceRange' => {
@@ -4796,4 +7759,10 @@
     },
    'SubjectReference' => 'Themencode',
+   'SubjectUnits' => {
+      PrintConv => {
+        'meters' => 'Meter',
+        'radians' => 'Winkelgrade',
+      },
+    },
    'Subsystem' => {
       PrintConv => {
@@ -4821,8 +7790,17 @@
         'Disable' => 'Nicht mÃ¶glich',
         'Enable' => 'MÃ¶glich',
+        'Only while AEL is pressed' => 'Nur wÃ€hrend AEL gedrÃŒckt',
+        'Switch with multi-controller' => 'Wechseln mit Multicontroller',
       },
     },
    'T4Options' => 'FÃŒllbits hinzugefÃŒgt',
    'T6Options' => 'T6 Optionen',
+   'T82Options' => 'T82 Option',
+   'TIFFPreview' => 'TIFF Vorschaubild',
+   'TIFF_FXExtensions' => {
+      PrintConv => {
+        'B&W JBIG2' => 'Schwarz-WeiÃ JBIG2',
+      },
+    },
    'TTL_DA_ADown' => 'Slave-Blitz-Messfeld 6',
    'TTL_DA_AUp' => 'Slave-Blitz-Messfeld 5',
@@ -4836,4 +7814,5 @@
     },
    'TargetAperture' => 'Zielblendenwert',
+   'TargetCompressionRatio' => 'Ziel-Komprimierungsrate',
    'TargetExposureTime' => 'Zielbelichtungszeit',
    'Technology' => {
@@ -4864,6 +7843,12 @@
     },
    'Teleconverter' => {
-      PrintConv => {
-        'None' => 'Keine',
+      Description => 'Telekonverter',
+      PrintConv => {
+        'None' => 'Keiner',
+      },
+    },
+   'TextEncoding' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -4894,10 +7879,21 @@
     },
    'TimeSent' => 'Absendezeit',
+   'TimeSincePowerOn' => 'Einschaltdauer',
    'TimeStamp' => 'Zeitstempel',
    'TimeStamp1' => 'Zeitstempel (1)',
+   'TimeZone' => 'Zeitzone',
+   'TimeZoneCity' => {
+      Description => 'Zeitzone Stadt',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'TimeZoneCode' => 'Zeitzonen-Code',
+   'TimeZoneInfo' => 'Zeitzonen-Info',
    'TimeZoneOffset' => 'Zeitzonen-Offset',
    'TimerFunctionButton' => {
       Description => 'Funktionstaste',
       PrintConv => {
+        'Auto Bracketing' => 'Belichtungsreihe',
         'ISO' => 'ISO-Empfindlichkeit',
         'Image Quality/Size' => 'BildqualitÃ€t/-grÃ¶Ãe',
@@ -4914,5 +7910,4 @@
       },
     },
-   'Timezone' => 'Zeitzone',
    'Title' => 'Titel',
    'ToneComp' => 'Tonwertkorrektur',
@@ -4924,5 +7919,10 @@
       },
     },
+   'ToneCurve1' => 'Tonwertkurve 1',
+   'ToneCurve2' => 'Tonwertkurve 2',
+   'ToneCurve3' => 'Tonwertkurve 3',
+   'ToneCurve4' => 'Tonwertkurve 4',
    'ToneCurveActive' => {
+      Description => 'Tonwertkurve aktiv',
       PrintConv => {
         'No' => 'Nein',
@@ -4930,16 +7930,63 @@
       },
     },
+   'ToneCurveBlue' => 'Tonwertkurve Blau',
+   'ToneCurveBlueX' => 'Tonwertkurve Blau X',
+   'ToneCurveBlueY' => 'Tonwertkurve Blau Y',
+   'ToneCurveBrightnessX' => 'Tonwertkurve Helligkeit X',
+   'ToneCurveBrightnessY' => 'Tonwertkurve Helligkeit Y',
+   'ToneCurveFileName' => 'Tonwertkurve Dateiname',
+   'ToneCurveGreen' => 'Tonwertkurve GrÃŒn',
+   'ToneCurveGreenX' => 'Tonwertkurve GrÃŒn X',
+   'ToneCurveGreenY' => 'Tonwertkurve GrÃŒn Y',
+   'ToneCurveInterpolation' => {
+      Description => 'Tonwertkurve Interpolation',
+      PrintConv => {
+        'Curve' => 'Kurve',
+        'Straight' => 'Gerade',
+      },
+    },
+   'ToneCurveMatching' => 'Tonwertkurve Ãbereinstimmung',
+   'ToneCurveMode' => {
+      Description => 'Tonwertkurve Modus',
+      PrintConv => {
+        'Luminance' => 'Luminanz',
+      },
+    },
    'ToneCurveName' => {
+      Description => 'Tonwertkurve Name',
       PrintConv => {
         'Custom' => 'Benutzerdefiniert',
-      },
-    },
+        'Medium Contrast' => 'Kontrast mittel',
+        'Strong Contrast' => 'Kontrast stark',
+      },
+    },
+   'ToneCurveName2012' => 'Tonwertkurve Name 2012',
+   'ToneCurvePV2012' => 'Tonwertkurve PV2012',
+   'ToneCurvePV2012Blue' => 'Tonwertkurve PV2012 Blau',
+   'ToneCurvePV2012Green' => 'Tonwertkurve PV2012 GrÃŒn',
+   'ToneCurvePV2012Red' => 'Tonwertkurve PV2012 Rot',
+   'ToneCurveProperty' => {
+      Description => 'Tonwertkurve Eigenschaft',
+      PrintConv => {
+        'Custom 1' => 'Benutzerdefiniert 1',
+        'Custom 2' => 'Benutzerdefiniert 2',
+        'Custom 3' => 'Benutzerdefiniert 3',
+        'Custom 4' => 'Benutzerdefiniert 4',
+        'Custom 5' => 'Benutzerdefiniert 5',
+        'Shot Settings' => 'Aufnahmeeinstellung',
+      },
+    },
+   'ToneCurveRed' => 'Tonwertkurve Rot',
+   'ToneCurveRedX' => 'Tonwertkurve Rot X',
+   'ToneCurveRedY' => 'Tonwertkurve Rot Y',
+   'ToneCurveTable' => 'Tonwertkurve Tabelle',
    'ToneCurves' => 'Ton-Kurven',
    'ToningEffect' => {
-      Description => 'TÃ¶nungs-Effekt',
-      PrintConv => {
-        'B&W' => 'Schwarz-WeiÃ',
+      Description => 'TÃ¶nungseffekt',
+      PrintConv => {
+        'B&W' => 'Schwarz/WeiÃ',
         'Blue' => 'Blau',
         'Blue-green' => 'Blau-GrÃŒn',
+        'Color' => 'Farbe',
         'Green' => 'GrÃŒn',
         'None' => 'Keiner',
@@ -4949,31 +7996,113 @@
         'Red-purple' => 'Rot-Violett',
         'Yellow' => 'Gelb',
-        'n/a' => 'Nicht gesetzt',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectFaithful' => {
+      Description => 'TÃ¶nungseffekt NatÃŒrlich',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectLandscape' => {
+      Description => 'TÃ¶nungseffekt Landschaft',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'ToningEffectMonochrome' => {
+      Description => 'TÃ¶nungseffekt Monochrom',
       PrintConv => {
         'Blue' => 'Blau',
         'Green' => 'GrÃŒn',
-        'None' => 'Keine',
+        'None' => 'Keiner',
         'Purple' => 'Lila',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectNeutral' => {
+      Description => 'TÃ¶nungseffekt Neutral',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectPortrait' => {
+      Description => 'TÃ¶nungseffekt PortrÃ€t',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectStandard' => {
+      Description => 'TÃ¶nungseffekt Standard',
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectUnknown' => {
+      Description => 'TÃ¶nungseffekt Unbekannt',
+      PrintConv => {
+        'Blue' => 'Blau',
+        'Green' => 'GrÃŒn',
+        'None' => 'Keiner',
+        'Purple' => 'Lila',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectUserDef1' => {
+      Description => 'TÃ¶nungseffekt Benutzerdefiniert 1',
+      PrintConv => {
+        'Blue' => 'Blau',
+        'Green' => 'GrÃŒn',
+        'None' => 'Keiner',
+        'Purple' => 'Lila',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectUserDef2' => {
+      Description => 'TÃ¶nungseffekt Benutzerdefiniert 2',
+      PrintConv => {
+        'Blue' => 'Blau',
+        'Green' => 'GrÃŒn',
+        'None' => 'Keiner',
+        'Purple' => 'Lila',
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'ToningEffectUserDef3' => {
+      Description => 'TÃ¶nungseffekt Benutzerdefiniert 3',
+      PrintConv => {
+        'Blue' => 'Blau',
+        'Green' => 'GrÃŒn',
+        'None' => 'Keiner',
+        'Purple' => 'Lila',
+        'n/a' => '(nicht gesetzt)',
       },
     },
    'ToningSaturation' => 'TÃ¶nungssÃ€ttigung',
    'TotalZoom' => 'Gesamtzoom',
+   'TrailerSignature' => 'Signatur des Nachspanns',
    'TransferFunction' => 'Transformationsfunktion',
+   'Transform' => {
+      Description => 'Transformation',
+      PrintConv => {
+        'Off' => 'Aus',
+        'Slim High' => 'Stark abnehmend',
+        'Slim Low' => 'Wenig abnehmend',
+        'Stretch High' => 'Stark streckend',
+        'Stretch Low' => 'Wenig streckend',
+      },
+    },
    'Transformation' => {
       PrintConv => {
-        'Horizontal (normal)' => '0Â° (oben/links)',
         'Mirror horizontal' => 'Horizontal gespiegelt',
-        'Mirror horizontal and rotate 270 CW' => 'Horizontal gespiegelt und 90Â° gegen den Uhrzeigersinn gedreht',
-        'Mirror horizontal and rotate 90 CW' => 'Horizontal gespiegelt und 90Â° im Uhrzeigersinn gedreht',
+        'Mirror horizontal and rotate 270 CW' => 'Horizontal gespiegelt und 90Â° gegen den Uhrzeigersinn',
+        'Mirror horizontal and rotate 90 CW' => 'Horizontal gespiegelt und 90Â° im Uhrzeigersinn',
         'Mirror vertical' => 'Vertikal gespiegelt',
-        'Rotate 180' => '180Â° (unten/rechts)',
-        'Rotate 270 CW' => '90Â° im Uhrzeigersinn (links/unten)',
-        'Rotate 90 CW' => '90Â° gegen den Uhrzeigersinn (rechts/oben)',
-      },
-    },
-   'TransmissionReference' => 'Ãbertragungsbezug',
+        'Rotate 180' => '180Â° gedreht',
+        'Rotate 270 CW' => '90Â° gegen den Uhrzeigersinn',
+        'Rotate 90 CW' => '90Â° im Uhrzeigersinn',
+      },
+    },
+   'TransmissionReference' => 'Anbietervermerk',
    'Trapped' => {
       PrintConv => {
@@ -4981,5 +8110,15 @@
       },
     },
+   'TravelDay' => 'Reisetag',
    'TvExposureTimeSetting' => 'Tv Belichtungszeit-Einstellung',
+   'Type' => 'Typ',
+   'TypeOfOriginal' => {
+      PrintConv => {
+        'B&W Document' => 'Schwarz-WeiÃ Dokument',
+        'B&W Print' => 'Schwarz-WeiÃ Druck',
+        'Color Document' => 'Farb Dokument',
+        'Color Print' => 'Farbdruck',
+      },
+    },
    'USMLensElectronicMF' => {
       Description => 'USM-Objektiv, elektr. MF',
@@ -5000,4 +8139,12 @@
    'UniqueDocumentID' => 'Eindeutige Bild-ID',
    'Unknown' => 'Unbekannt',
+   'UnknownInfoVersion' => 'Unbekannte Info Version',
+   'UnknownLinear' => {
+      PrintConv => {
+        'No' => 'Nein',
+        'Yes' => 'Ja',
+      },
+    },
+   'Unknown_CNDB' => 'CNDB unbekannt',
    'Unsharp1Color' => {
       PrintConv => {
@@ -5042,9 +8189,9 @@
       Description => 'Dringlichkeit',
       PrintConv => {
-        '0 (reserved)' => '0 (Reserviert fÃŒr zukÃŒnftige Verwendung)',
-        '1 (most urgent)' => '1 (sehr wichtig)',
-        '5 (normal urgency)' => '5 (normale Wichtigkeit)',
-        '8 (least urgent)' => '8 (geringe Wichtigkeit)',
-        '9 (user-defined priority)' => '9 (Reserviert fÃŒr zukÃŒnftige Verwendung)',
+        '0 (reserved)' => '0 (reserviert)',
+        '1 (most urgent)' => '1 (sehr dringend)',
+        '5 (normal urgency)' => '5 (normale Dringlichkeit)',
+        '8 (least urgent)' => '8 (geringe Dringlichkeit)',
+        '9 (user-defined priority)' => '9 (benutzerdefinierte PrioritÃ€t)',
       },
     },
@@ -5063,8 +8210,10 @@
       },
     },
-   'UsageTerms' => 'Verwendungsvorschriften',
+   'UsageTerms' => 'Nutzungsbedingungen',
    'UserComment' => 'Benutzerkommentar',
    'UserDef1PictureStyle' => {
-      PrintConv => {
+      Description => 'Bildstil Benutzerdefiniert 1',
+      PrintConv => {
+        'Faithful' => 'NatÃŒrlich',
         'Landscape' => 'Landschaft',
         'Monochrome' => 'Monochrom',
@@ -5073,5 +8222,7 @@
     },
    'UserDef2PictureStyle' => {
-      PrintConv => {
+      Description => 'Bildstil Benutzerdefiniert 2',
+      PrintConv => {
+        'Faithful' => 'NatÃŒrlich',
         'Landscape' => 'Landschaft',
         'Monochrome' => 'Monochrom',
@@ -5080,8 +8231,26 @@
     },
    'UserDef3PictureStyle' => {
-      PrintConv => {
+      Description => 'Bildstil Benutzerdefiniert 3',
+      PrintConv => {
+        'Faithful' => 'NatÃŒrlich',
         'Landscape' => 'Landschaft',
         'Monochrome' => 'Monochrom',
         'Portrait' => 'PortrÃ€t',
+      },
+    },
+   'UserFields' => 'Benutzerfelder',
+   'UserProfile' => {
+      Description => 'Benutzerprofil',
+      PrintConv => {
+        'User Profile 0 (Dynamic)' => 'Benutzerprofil 0 (dynamisch)',
+        'User Profile 1' => 'Benutzerprofil 1',
+        'User Profile 2' => 'Benutzerprofil 2',
+        'User Profile 3' => 'Benutzerprofil 3',
+      },
+    },
+   'VFDisplayIllumination' => {
+      PrintConv => {
+        'Disable' => 'Deaktiviert',
+        'Enable' => 'Aktiviert',
       },
     },
@@ -5097,6 +8266,7 @@
     },
    'ValidAFPoints' => 'GÃŒltige AF-Punkte',
+   'ValidBits' => 'Verwendete Bits',
+   'ValidPixelDepth' => 'Farbtiefe',
    'VariProgram' => 'Aufnahmeprogramm',
-   'Version' => 'PrintIM Version',
    'VibrationReduction' => {
       Description => 'Bildstabilisation',
@@ -5107,5 +8277,5 @@
         'On (2)' => 'Ein (2)',
         'On (3)' => 'Ein (3)',
-        'n/a' => 'Nicht gesetzt',
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -5122,4 +8292,14 @@
         'Off' => 'Aus',
         'On' => 'Ein',
+      },
+    },
+   'ViewfinderWarnings' => {
+      PrintConv => {
+        'ISO expansion' => 'ISO-Erweiterung',
+      },
+    },
+   'ViewingMode2' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
       },
     },
@@ -5135,4 +8315,12 @@
     },
    'VignetteControlIntensity' => 'Vignettierungskorrektur StÃ€rke',
+   'VignettingCorrection' => {
+      PrintConv => {
+        'n/a' => '(nicht gesetzt)',
+      },
+    },
+   'VirtualImageHeight' => 'Virtuelle BildhÃ¶he',
+   'VirtualImageWidth' => 'Virtuelle Bildbreite',
+   'VirtualPageUnits' => 'Virtuelle Seitenzahl',
    'VoiceMemo' => {
       PrintConv => {
@@ -5142,10 +8330,13 @@
     },
    'Volume' => 'Band',
+   'WBAdjColorTemp' => 'WeiÃabgleich Farbtemperaturkorrektur',
    'WBAdjLighting' => {
       PrintConv => {
-        'Daylight' => 'Tageslicht',
+        'Daylight (cloudy)' => 'Tageslicht (2)',
+        'Daylight (direct sunlight)' => 'Tageslicht (0)',
+        'Daylight (shade)' => 'Tageslicht (1)',
         'Flash' => 'Blitz',
         'Incandescent' => 'GlÃŒhbirne',
-        'None' => 'Keine',
+        'None' => 'Keines',
       },
     },
@@ -5159,7 +8350,9 @@
       },
     },
+   'WBBracketShotNumber' => 'WeiÃabgleich-Belichtungsreihen-Bildnummer',
    'WBBracketValueAB' => 'WeiÃabgleich AB-Belichtungsreihen-Wert',
    'WBBracketValueGM' => 'WeiÃabgleich GM-Belichtungsreihen-Wert',
    'WBFineTuneActive' => {
+      Description => 'WeiÃabgleich Feinabstimmung aktiv',
       PrintConv => {
         'No' => 'Nein',
@@ -5167,4 +8360,6 @@
       },
     },
+   'WBFineTuneSaturation' => 'WeiÃabgleich SÃ€ttigung Feinabstimmung',
+   'WBFineTuneTone' => 'WeiÃabgleich Farbton Feinabstimmung',
    'WBGreenLevel' => 'Farbabgleich GrÃŒn',
    'WBMediaImageSizeSetting' => {
@@ -5183,5 +8378,4 @@
    'WBShiftAB' => 'WeiÃabgleich AB-Korrektur',
    'WBShiftGM' => 'WeiÃabgleich GM-Korrektur',
-   'WBShiftMG' => 'WeiÃabgleich GM-Korrektur',
    'WB_GBRGLevels' => 'WeiÃabgleich GBRG-Farbverteilung',
    'WB_GLevel' => 'WeiÃabgleich G-Farbverteilung',
@@ -5214,4 +8408,5 @@
    'WB_RBLevels6600K' => 'WeiÃabgleich RB-Farbverteilung 6600K',
    'WB_RBLevels7500K' => 'WeiÃabgleich RB-Farbverteilung 7500K',
+   'WB_RBLevelsAuto' => 'WeiÃabgleich RB-Farbverteilung Automatik',
    'WB_RBLevelsCWB1' => 'WeiÃabgleich RB-Farbverteilung CWB1',
    'WB_RBLevelsCWB2' => 'WeiÃabgleich RB-Farbverteilung CWB2',
@@ -5226,4 +8421,5 @@
    'WB_RBLevelsShade' => 'WeiÃabgleich RB-Farbverteilung Schatten',
    'WB_RBLevelsTungsten' => 'WeiÃabgleich RB-Farbverteilung GlÃŒhbirne',
+   'WB_RBLevelsUsed' => 'WeiÃabgleich RB-Farbverteilung verwendet',
    'WB_RBLevelsWhiteFluorescent' => 'WeiÃabgleich RB-Farbverteilung Neonlicht universalweiÃ',
    'WB_RGBGLevels' => 'WeiÃabgleich RGBG-Farbverteilung',
@@ -5263,5 +8459,9 @@
    'WB_RGGBLevelsUnknown15' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 15',
    'WB_RGGBLevelsUnknown16' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 16',
+   'WB_RGGBLevelsUnknown17' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 17',
+   'WB_RGGBLevelsUnknown18' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 18',
+   'WB_RGGBLevelsUnknown19' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 19',
    'WB_RGGBLevelsUnknown2' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 2',
+   'WB_RGGBLevelsUnknown20' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 20',
    'WB_RGGBLevelsUnknown3' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 3',
    'WB_RGGBLevelsUnknown4' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 4',
@@ -5272,8 +8472,11 @@
    'WB_RGGBLevelsUnknown9' => 'WeiÃabgleich RGGB-Farbverteilung Unbekannt 9',
    'WCSProfiles' => 'Windows Color System-Profil',
+   'WangAnnotation' => 'Wang Anmerkung',
    'Warning' => 'Warnung',
+   'Watermark' => 'Wasserzeichen',
    'WhiteBalance' => {
       Description => 'WeiÃabgleich',
       PrintConv => {
+        'As Shot' => 'Aufnahme',
         'Auto' => 'Automatisch',
         'Black & White' => 'Schwarz/WeiÃ',
@@ -5294,4 +8497,5 @@
         'Daylight Fluorescent' => 'Neonlicht tageslichtweiÃ',
         'Flash' => 'Blitz',
+        'Flash?' => 'Blitz',
         'Fluorescent' => 'Neonlicht',
         'Incandescent' => 'GlÃŒhbirne',
@@ -5301,5 +8505,7 @@
         'Shade' => 'Schatten',
         'Tungsten' => 'GlÃŒhbirne',
-        'Underwater' => 'Tauchen',
+        'Underwater' => 'Unterwasser',
+        'Underwater 1 (Blue Water)' => 'Unterwasser 1 (blaues Wasser)',
+        'Underwater 2 (Green Water)' => 'Unterwasser 2 (grÃŒnes Wasser)',
         'Unknown' => 'Unbekannt',
         'User-Selected' => 'Benutzerdefiniert',
@@ -5323,4 +8529,5 @@
     },
    'WhiteBalanceAdj' => {
+      Description => 'WeiÃabgleich Korrektur',
       PrintConv => {
         'Auto' => 'Automatisch',
@@ -5335,9 +8542,25 @@
       },
     },
+   'WhiteBalanceAutoAdjustment' => {
+      Description => 'WeiÃabgleich automatische Abstimmung',
+      PrintConv => {
+        'Off' => 'Aus',
+        'On' => 'Ein',
+      },
+    },
    'WhiteBalanceBias' => 'WeiÃabgleich Bias',
    'WhiteBalanceBlue' => 'Farbabgleich Blau',
    'WhiteBalanceBracket' => 'WeiÃabgleichs-Belichtungsreihe',
-   'WhiteBalanceBracketing' => 'WeiÃabgleichs-Belichtungsreihe',
+   'WhiteBalanceBracketing' => {
+      Description => 'WeiÃabgleichs-Belichtungsreihe',
+      PrintConv => {
+        'High' => 'Hoch',
+        'Low' => 'Niedrig',
+        'Off' => 'Aus',
+      },
+    },
+   'WhiteBalanceComp' => 'WeiÃabgleichsausgleich',
    'WhiteBalanceFineTune' => 'WeiÃabgleichsfeineinstellung',
+   'WhiteBalanceMatching' => 'WeiÃabgleich Ãbereinstimmung',
    'WhiteBalanceMode' => {
       Description => 'WeiÃabgleich-Modus',
@@ -5374,8 +8597,16 @@
       },
     },
-   'WhiteBalanceSetting' => 'WeiÃabgleichs-Einstellung',
+   'WhiteBalanceSetting' => {
+      Description => 'WeiÃabgleichs-Einstellung',
+      PrintConv => {
+        'Color Temperature/Color Filter' => 'Farbtemperatur/Farbfilter',
+        'Custom' => 'Benutzerdefiniert',
+        'Preset' => 'Voreinstellung',
+      },
+    },
    'WhiteBalanceTable' => 'WeiÃabgleich Tabelle',
    'WhiteBalanceTemperature' => 'WeiÃabgleich Farbtemperatur',
    'WhiteBoard' => 'Whiteboard Funktion',
+   'WhiteLevel' => 'WeiÃwert',
    'WhitePoint' => 'WeiÃpunkt-ChromatizitÃ€t',
    'WhitePointX' => 'WeiÃpunkt X',
@@ -5404,15 +8635,18 @@
       PrintConv => {
         'Destination' => 'Zielort',
+        'Home' => 'Heimatort',
         'Hometown' => 'Heimatort',
       },
     },
    'Writer-Editor' => 'Verfasser der Beschreibung',
+   'Writers' => 'Schreiber',
    'XMP' => 'XMP Metadaten',
-   'XPAuthor' => 'Autor',
-   'XPComment' => 'Kommentar',
-   'XPKeywords' => 'StichwÃ¶rter',
-   'XPSubject' => 'Betreff',
-   'XPTitle' => 'Titel',
+   'XPAuthor' => 'XP Autor',
+   'XPComment' => 'XP Kommentar',
+   'XPKeywords' => 'XP SchlÃŒsselwÃ¶rter',
+   'XPSubject' => 'XP Thema',
+   'XPTitle' => 'XP Titel',
    'XResolution' => 'Horizontale BildauflÃ¶sung',
+   'XYResolution' => 'XY AuflÃ¶sung',
    'YCbCrCoefficients' => 'YCbCr-Koeffizienten',
    'YCbCrPositioning' => {
@@ -5426,4 +8660,5 @@
    'YResolution' => 'Vertikale BildauflÃ¶sung',
    'Year' => 'Jahr',
+   'ZipCompression' => 'Zip Komprimierung',
    'ZoneMatching' => {
       Description => 'Zonenabgleich',
@@ -5441,7 +8676,13 @@
       },
     },
+   'Zoom' => 'Zoom-Objektiv',
    'ZoomPos' => 'Zoom Position',
    'ZoomSourceWidth' => 'VergrÃ¶Ãerungs-UrsprungsgrÃ¶Ãe',
+   'ZoomStepCount' => 'Zoom-StufenzÃ€hler',
    'ZoomTargetWidth' => 'VergrÃ¶Ãerungs-EndgrÃ¶Ãe',
+   'ZoomedPreviewImage' => 'VergrÃ¶Ãertes Vorschaubild',
+   'ZoomedPreviewLength' => 'VergÃ¶Ãertes Vorschaubild-DatenlÃ€nge',
+   'ZoomedPreviewSize' => 'VergÃ¶Ãertes Vorschaubild-GrÃ¶Ãe',
+   'ZoomedPreviewStart' => 'VergÃ¶Ãertes Vorschaubild-Datenposition',
 );
 
@@ -5462,5 +8703,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -5469,5 +8710,6 @@
 =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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/en_ca.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/en_ca.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/en_ca.pm	(revision 34921)
@@ -12,7 +12,34 @@
 use vars qw($VERSION);
 
-$VERSION = '1.06';
+$VERSION = '1.12';
 
 %Image::ExifTool::Lang::en_ca::Translate = (
+   'AboveColor' => 'Above Colour',
+   'AdvancedFilter' => {
+      PrintConv => {
+        'Partial Color Blue' => 'Partial Colour Blue',
+        'Partial Color Green' => 'Partial Colour Green',
+        'Partial Color Orange' => 'Partial Colour Orange',
+        'Partial Color Purple' => 'Partial Colour Purple',
+        'Partial Color Red' => 'Partial Colour Red',
+        'Partial Color Yellow' => 'Partial Colour Yellow',
+        'Pop Color' => 'Pop Colour',
+      },
+    },
+   'AdvancedSceneMode' => {
+      PrintConv => {
+        'Color Select' => 'Colour Select',
+      },
+    },
+   'AllColorFlatField1' => 'All Colour Flat Field 1',
+   'AllColorFlatField2' => 'All Colour Flat Field 2',
+   'AllColorFlatField3' => 'All Colour Flat Field 3',
+   'Alpha' => {
+      PrintConv => {
+        'Alpha Exists (W color component)' => 'Alpha Exists (W colour component)',
+        'Alpha Exists (color not premultiplied)' => 'Alpha Exists (colour not premultiplied)',
+        'Alpha Exists (color premultiplied)' => 'Alpha Exists (colour premultiplied)',
+      },
+    },
    'AlternateDuotoneColors' => 'Alternate Duotone Colours',
    'AlternateSpotColors' => 'Alternate Spot Colours',
@@ -20,6 +47,31 @@
       PrintConv => {
         'Pale & Light Color' => 'Pale & Light Colour',
-      },
-    },
+        'Pale & Light Color II' => 'Pale & Light Colour II',
+        'Partial Color' => 'Partial Colour',
+        'Partial Color II' => 'Partial Colour II',
+        'Partial Color III' => 'Partial Colour III',
+        'Watercolor' => 'Watercolour',
+        'Watercolor I' => 'Watercolour I',
+        'Watercolor II' => 'Watercolour II',
+      },
+    },
+   'ArtFilterEffect' => {
+      PrintConv => {
+        'Green Color Filter' => 'Green Colour Filter',
+        'No Color Filter' => 'No Colour Filter',
+        'Orange Color Filter' => 'Orange Colour Filter',
+        'Pale & Light Color' => 'Pale & Light Colour',
+        'Pale & Light Color II' => 'Pale & Light Colour II',
+        'Partial Color' => 'Partial Colour',
+        'Partial Color II' => 'Partial Colour II',
+        'Partial Color III' => 'Partial Colour III',
+        'Red Color Filter' => 'Red Colour Filter',
+        'Watercolor' => 'Watercolour',
+        'Watercolor I' => 'Watercolour I',
+        'Watercolor II' => 'Watercolour II',
+        'Yellow Color Filter' => 'Yellow Colour Filter',
+      },
+    },
+   'AutoAFPointColorTracking' => 'Auto AF Point Colour Tracking',
    'BackgroundColor' => 'Background Colour',
    'BackgroundColorIndicator' => {
@@ -32,4 +84,10 @@
    'BackgroundColorValue' => 'Background Colour Value',
    'BasicColorImageSequence' => 'Basic Colour Image Sequence',
+   'BelowColor' => 'Below Colour',
+   'BestShotMode' => {
+      PrintConv => {
+        'Water Color' => 'Water Colour',
+      },
+    },
    'BkColor' => 'Background Colour',
    'BluePaletteColorTableData' => 'Blue Palette Colour Table Data',
@@ -52,8 +110,19 @@
    'CameraColorCalibration14' => 'Camera Colour Calibration 14',
    'CameraColorCalibration15' => 'Camera Colour Calibration 15',
+   'CameraRawColorTone' => 'Camera Raw Colour Tone',
    'CanonColorInfo1' => 'Canon Colour Info 1',
    'CanonColorInfo2' => 'Canon Colour Info 2',
    'ChromaticityColorant' => 'Chromaticity Colourant',
-   'Color' => 'Colour',
+   'CodingMethods' => {
+      PrintConv => {
+        'JBIG color' => 'JBIG colour',
+      },
+    },
+   'Color' => {
+      Description => 'Colour',
+      PrintConv => {
+        'Color' => 'Colour',
+      },
+    },
    'ColorAberrationControl' => 'Colour Aberration Control',
    'ColorAdjustment' => 'Colour Adjustment',
@@ -67,6 +136,8 @@
    'ColorBalanceRed' => 'Colour Balance Red',
    'ColorBalanceUnknown' => 'Colour Balance Unknown',
+   'ColorBalanceVersion' => 'Colour Balance Version',
    'ColorBitDepth' => 'Colour Bit Depth',
    'ColorBlur' => 'Colour Blur',
+   'ColorBlurOn' => 'Colour Blur On',
    'ColorBoostLevel' => 'Colour Boost Level',
    'ColorBoostType' => 'Colour Boost Type',
@@ -77,9 +148,14 @@
    'ColorClass' => 'Colour Class',
    'ColorCompensationFilter' => 'Colour Compensation Filter',
+   'ColorCompensationFilterCustom' => 'Colour Compensation Filter Custom',
+   'ColorCompensationFilterSet' => 'Colour Compensation Filter Set',
    'ColorComponents' => 'Colour Components',
    'ColorControl' => 'Colour Control',
    'ColorCorrection' => 'Colour Correction',
+   'ColorCreatorEffect' => 'Colour Creator Effect',
    'ColorDataVersion' => 'Colour Data Version',
+   'ColorDescriptor' => 'Colour Descriptor',
    'ColorEffect' => 'Colour Effect',
+   'ColorFieldCode' => 'Colour Field Code',
    'ColorFilter' => 'Colour Filter',
    'ColorGain' => 'Colour Gain',
@@ -88,4 +164,5 @@
    'ColorHue' => 'Colour Hue',
    'ColorImagePrintingFlag' => 'Colour Image Printing Flag',
+   'ColorLabel' => 'Colour Label',
    'ColorMap' => 'Colour Map',
    'ColorMatrix' => 'Colour Matrix',
@@ -93,11 +170,15 @@
    'ColorMatrix2' => 'Colour Matrix 2',
    'ColorMatrixA' => 'Colour Matrix A',
+   'ColorMatrixAdobeRGB' => 'Colour Matrix Adobe RGB',
    'ColorMatrixB' => 'Colour Matrix B',
    'ColorMatrixNumber' => 'Colour Matrix Number',
+   'ColorMatrixSRGB' => 'Colour Matrix sRGB',
    'ColorMode' => {
       Description => 'Colour Mode',
       PrintConv => {
+        'Indexed Color' => 'Indexed Colour',
         'Natural color' => 'Natural colour',
         'Neutral Color' => 'Neutral Colour',
+        'RGB Color' => 'RGB Colour',
         'Saturated Color' => 'Saturated Colour',
         'Vivid color' => 'Vivid colour',
@@ -107,6 +188,8 @@
    'ColorMoireReductionMode' => 'Colour Moire Reduction Mode',
    'ColorNoiseReduction' => 'Colour Noise Reduction',
+   'ColorNoiseReductionDetail' => 'Colour Noise Reduction Detail',
    'ColorNoiseReductionIntensity' => 'Colour Noise Reduction Intensity',
    'ColorNoiseReductionSharpness' => 'Colour Noise Reduction Sharpness',
+   'ColorNoiseReductionSmoothness' => 'Colour Noise Reduction Smoothness',
    'ColorObjBackType' => 'Colour Obj Back Type',
    'ColorObjName' => 'Colour Obj Name',
@@ -115,5 +198,8 @@
    'ColorPalette' => 'Colour Palette',
    'ColorPlanes' => 'Colour Planes',
+   'ColorPrimaries' => 'Colour Primaries',
    'ColorProfile' => 'Colour Profile',
+   'ColorProfileSettings' => 'Colour Profile Settings',
+   'ColorRangeLevels' => 'Colour Range Levels',
    'ColorRepresentation' => 'Colour Representation',
    'ColorReproduction' => 'Colour Reproduction',
@@ -121,12 +207,27 @@
    'ColorResponseUnit' => 'Colour Response Unit',
    'ColorSamplersResource' => 'Colour Samplers Resource',
+   'ColorSamplersResource2' => 'Colour Samplers Resource 2',
+   'ColorSaturationAdj' => 'Colour Saturation Adj',
    'ColorSequence' => 'Colour Sequence',
+   'ColorSiting' => 'Colour Siting',
    'ColorSpace' => {
       Description => 'Colour Space',
       PrintConv => {
+        'Embedded Color Profile' => 'Embedded Colour Profile',
+        'Linked Color Profile' => 'Linked Colour Profile',
         'No color space specified' => 'No colour space specified',
+        'Windows Color Space' => 'Windows Colour Space',
       },
     },
    'ColorSpaceData' => 'Colour Space Data',
+   'ColorSpecApproximation' => 'Colour Spec Approximation',
+   'ColorSpecData' => 'Colour Spec Data',
+   'ColorSpecMethod' => {
+      Description => 'Colour Spec Method',
+      PrintConv => {
+        'Vendor Color' => 'Vendor Colour',
+      },
+    },
+   'ColorSpecPrecedence' => 'Colour Spec Precedence',
    'ColorSpecification' => 'Colour Specification',
    'ColorTable' => 'Colour Table',
@@ -141,4 +242,7 @@
    'ColorTempFlashData' => 'Colour Temp Flash Data',
    'ColorTempFluorescent' => 'Colour Temp Fluorescent',
+   'ColorTempFluorescentD' => 'Colour Temp Fluorescent D',
+   'ColorTempFluorescentN' => 'Colour Temp Fluorescent N',
+   'ColorTempFluorescentW' => 'Colour Temp Fluorescent W',
    'ColorTempKelvin' => 'Colour Temp Kelvin',
    'ColorTempMeasured' => 'Colour Temp Measured',
@@ -156,6 +260,20 @@
    'ColorTempUnknown15' => 'Colour Temp Unknown 15',
    'ColorTempUnknown16' => 'Colour Temp Unknown 16',
+   'ColorTempUnknown17' => 'Colour Temp Unknown 17',
+   'ColorTempUnknown18' => 'Colour Temp Unknown 18',
+   'ColorTempUnknown19' => 'Colour Temp Unknown 19',
    'ColorTempUnknown2' => 'Colour Temp Unknown 2',
+   'ColorTempUnknown20' => 'Colour Temp Unknown 20',
+   'ColorTempUnknown21' => 'Colour Temp Unknown 21',
+   'ColorTempUnknown22' => 'Colour Temp Unknown 22',
+   'ColorTempUnknown23' => 'Colour Temp Unknown 23',
+   'ColorTempUnknown24' => 'Colour Temp Unknown 24',
+   'ColorTempUnknown25' => 'Colour Temp Unknown 25',
+   'ColorTempUnknown26' => 'Colour Temp Unknown 26',
+   'ColorTempUnknown27' => 'Colour Temp Unknown 27',
+   'ColorTempUnknown28' => 'Colour Temp Unknown 28',
+   'ColorTempUnknown29' => 'Colour Temp Unknown 29',
    'ColorTempUnknown3' => 'Colour Temp Unknown 3',
+   'ColorTempUnknown30' => 'Colour Temp Unknown 30',
    'ColorTempUnknown4' => 'Colour Temp Unknown 4',
    'ColorTempUnknown5' => 'Colour Temp Unknown 5',
@@ -166,6 +284,9 @@
    'ColorTemperature' => 'Colour Temperature',
    'ColorTemperatureAdj' => 'Colour Temperature Adj',
+   'ColorTemperatureAuto' => 'Colour Temperature Auto',
    'ColorTemperatureBG' => 'Colour Temperature BG',
+   'ColorTemperatureCustom' => 'Colour Temperature Custom',
    'ColorTemperatureRG' => 'Colour Temperature RG',
+   'ColorTemperatureSet' => 'Colour Temperature Set',
    'ColorTemperatureSetting' => {
       Description => 'Colour Temperature Setting',
@@ -176,6 +297,8 @@
    'ColorTone' => 'Colour Tone',
    'ColorToneAdj' => 'Colour Tone Adj',
+   'ColorToneAuto' => 'Colour Tone Auto',
    'ColorToneFaithful' => 'Colour Tone Faithful',
    'ColorToneLandscape' => 'Colour Tone Landscape',
+   'ColorToneMonochrome' => 'Colour Tone Monochrome',
    'ColorToneNeutral' => 'Colour Tone Neutral',
    'ColorTonePortrait' => 'Colour Tone Portrait',
@@ -206,4 +329,5 @@
    'ColorantCount' => 'Colourant Count',
    'ColorantCyan' => 'Colourant Cyan',
+   'ColorantGray' => 'Colourant Gray',
    'ColorantGreen' => 'Colourant Green',
    'ColorantL' => 'Colourant L',
@@ -214,9 +338,13 @@
    'ColorantSwatchName' => 'Colourant Swatch Name',
    'ColorantTableOut' => 'Colourant Table Out',
+   'ColorantTint' => 'Colourant Tint',
    'ColorantType' => 'Colourant Type',
    'ColorantYellow' => 'Colourant Yellow',
+   'Colorants' => 'Colourants',
+   'ColorimetricIntentImageState' => 'Colourimetric Intent Image State',
    'ColorimetricReference' => 'Colourimetric Reference',
+   'Colorimetry' => 'Colourimetry',
+   'ColorimetryCode' => 'Colourimetry Code',
    'Colors' => 'Colours',
-   'Colorspace' => 'Colourspace',
    'Compression' => {
       PrintConv => {
@@ -236,4 +364,5 @@
       },
     },
+   'CustomColorTone' => 'Custom Colour Tone',
    'D-LightingHQColorBoost' => 'D-Lighting HQ Colour Boost',
    'D-LightingHSColorBoost' => 'D-Lighting HS Colour Boost',
@@ -246,4 +375,166 @@
       },
     },
+   'DigitalFilter01' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Replace Color' => 'Replace Colour',
+        'Unicolor Bold' => 'Unicolour Bold',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter02' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter03' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter04' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter05' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter06' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter07' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter08' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter09' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter10' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter11' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter12' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter13' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter14' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter15' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter16' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter17' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter18' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter19' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter20' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
    'DisplayUnits' => {
       PrintConv => {
@@ -258,4 +549,14 @@
       },
     },
+   'EmbeddedImageColorSpace' => 'Embedded Image Colour Space',
+   'ExposureProgram' => {
+      PrintConv => {
+        'Partial Color Blue' => 'Partial Colour Blue',
+        'Partial Color Green' => 'Partial Colour Green',
+        'Partial Color Red' => 'Partial Colour Red',
+        'Partial Color Yellow' => 'Partial Colour Yellow',
+        'Pop Color' => 'Pop Colour',
+      },
+    },
    'FaithfulRawColorTone' => 'Faithful Raw Colour Tone',
    'FaxProfile' => {
@@ -266,4 +567,5 @@
     },
    'FgColor' => 'Foreground Colour',
+   'FilmColorProcess' => 'Film Colour Process',
    'FilmMode' => {
       PrintConv => {
@@ -274,6 +576,14 @@
       },
     },
+   'FlagColor' => 'Flag Colour',
    'FlashColorFilter' => 'Flash Colour Filter',
+   'FocalPlaneColorimetryEstimates' => 'Focal Plane Colourimetry Estimates',
+   'GammaColorTone' => 'Gamma Colour Tone',
    'GenOpColor' => 'Gen Op Colour',
+   'GenreID' => {
+      PrintConv => {
+        'Books|Kids|Basic Concepts|Colors' => 'Books|Kids|Basic Concepts|Colours',
+      },
+    },
    'GreenPaletteColorTableData' => 'Green Palette Colour Table Data',
    'GreenPaletteColorTableDescriptor' => 'Green Palette Colour Table Descriptor',
@@ -296,5 +606,15 @@
     },
    'ImageColorValue' => 'Image Colour Value',
+   'ImageMedium' => {
+      PrintConv => {
+        'Color hard copy' => 'Colour hard copy',
+        'Color negative' => 'Colour negative',
+        'Color reversal' => 'Colour reversal',
+      },
+    },
+   'IndexedColorTableCount' => 'Indexed Colour Table Count',
    'InterchangeColorSpace' => 'Interchange Colour Space',
+   'Isotherm1Color' => 'Isotherm 1 Colour',
+   'Isotherm2Color' => 'Isotherm 2 Colour',
    'LandscapeRawColorTone' => 'Landscape Raw Colour Tone',
    'LargeBluePaletteColorTableData' => 'Large Blue Palette Colour Table Data',
@@ -305,8 +625,25 @@
    'LargeRedPaletteColorTableData' => 'Large Red Palette Colour Table Data',
    'LargeRedPaletteColorTableDescr' => 'Large Red Palette Colour Table Descr',
+   'LayerBlendModes' => {
+      PrintConv => {
+        'Color' => 'Colour',
+        'Color Burn' => 'Colour Burn',
+        'Color Dodge' => 'Colour Dodge',
+        'Darker Color' => 'Darker Colour',
+        'Lighter Color' => 'Lighter Colour',
+      },
+    },
    'MDColorTable' => 'MD Colour Table',
+   'MDItemColorSpace' => 'MD Item Colour Space',
    'MagicFilter' => {
       PrintConv => {
         'Pale & Light Color' => 'Pale & Light Colour',
+        'Pale & Light Color II' => 'Pale & Light Colour II',
+        'Partial Color' => 'Partial Colour',
+        'Partial Color II' => 'Partial Colour II',
+        'Partial Color III' => 'Partial Colour III',
+        'Watercolor' => 'Watercolour',
+        'Watercolor I' => 'Watercolour I',
+        'Watercolor II' => 'Watercolour II',
       },
     },
@@ -320,5 +657,7 @@
     },
    'MattColor' => 'Matt Colour',
+   'MediaColor' => 'Media Colour',
    'ModifiedColorTemp' => 'Modified Colour Temp',
+   'MonochromeColor' => 'Monochrome Colour',
    'MyColorMode' => {
       Description => 'My Colour Mode',
@@ -335,6 +674,8 @@
    'NumImportantColors' => 'Num Important Colours',
    'OpColor' => 'Op Colour',
+   'OverflowColor' => 'Overflow Colour',
    'PF25ColorMatrix' => 'PF25 Colour Matrix',
    'PaletteColorTableUID' => 'Palette Colour Table UID',
+   'PaletteColors' => 'Palette Colours',
    'PhotoEffect' => {
       PrintConv => {
@@ -348,4 +689,31 @@
     },
    'Photoshop2ColorTable' => 'Photoshop 2 Colour Table',
+   'PictureEffect' => {
+      PrintConv => {
+        'Partial Color (blue)' => 'Partial Colour (blue)',
+        'Partial Color (green)' => 'Partial Colour (green)',
+        'Partial Color (red)' => 'Partial Colour (red)',
+        'Partial Color (yellow)' => 'Partial Colour (yellow)',
+        'Pop Color' => 'Pop Colour',
+        'Water Color' => 'Water Colour',
+        'Water Color 2' => 'Water Colour 2',
+      },
+    },
+   'PictureEffect2' => {
+      PrintConv => {
+        'Partial Color' => 'Partial Colour',
+        'Pop Color' => 'Pop Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'PictureIndexedColors' => 'Picture Indexed Colours',
+   'PictureMode' => {
+      PrintConv => {
+        'Color Creator' => 'Colour Creator',
+        'Color Profile 1' => 'Colour Profile 1',
+        'Color Profile 2' => 'Colour Profile 2',
+        'Color Profile 3' => 'Colour Profile 3',
+      },
+    },
    'PictureType' => {
       PrintConv => {
@@ -353,4 +721,5 @@
       },
     },
+   'PictureWizardColor' => 'Picture Wizard Colour',
    'PortraitRawColorTone' => 'Portrait Raw Colour Tone',
    'PresetWhiteBalance' => {
@@ -376,4 +745,16 @@
    'ROIDisplayColor' => 'ROI Display Colour',
    'RawColorAdj' => 'Raw Colour Adj',
+   'RawDevArtFilter' => {
+      PrintConv => {
+        'Pale & Light Color' => 'Pale & Light Colour',
+        'Pale & Light Color II' => 'Pale & Light Colour II',
+        'Partial Color' => 'Partial Colour',
+        'Partial Color II' => 'Partial Colour II',
+        'Partial Color III' => 'Partial Colour III',
+        'Watercolor' => 'Watercolour',
+        'Watercolor I' => 'Watercolour I',
+        'Watercolor II' => 'Watercolour II',
+      },
+    },
    'RawDevColorSpace' => 'Raw Dev Colour Space',
    'RawDevMemoryColorEmphasis' => 'Raw Dev Memory Colour Emphasis',
@@ -391,6 +772,9 @@
    'RedPaletteColorTableData' => 'Red Palette Colour Table Data',
    'RedPaletteColorTableDescriptor' => 'Red Palette Colour Table Descriptor',
+   'ReflectionHardcopyOrigColorimetry' => 'Reflection Hardcopy Orig Colourimetry',
+   'ReflectionPrintOutputColorimetry' => 'Reflection Print Output Colourimetry',
    'RenderingIntent' => {
       PrintConv => {
+        'Absolute Colorimetric (LCS_GM_ABS_COLORIMETRIC)' => 'Absolute Colourimetric (LCS_GM_ABS_COLORIMETRIC)',
         'ICC-Absolute Colorimetric' => 'ICC-Absolute Colourimetric',
         'Media-Relative Colorimetric' => 'Media-Relative Colourimetric',
@@ -401,4 +785,6 @@
         'Color Custom' => 'Colour Custom',
         'Color Outline' => 'Colour Outline',
+        'Color Sketch' => 'Colour Sketch',
+        'Selective Color' => 'Selective Colour',
       },
     },
@@ -410,4 +796,13 @@
       },
     },
+   'SceneBalanceAlgorithmCommand' => {
+      PrintConv => {
+        'Neutral SBA Off, Color SBA Off' => 'Neutral SBA Off, Colour SBA Off',
+        'Neutral SBA Off, Color SBA On' => 'Neutral SBA Off, Colour SBA On',
+        'Neutral SBA On, Color SBA Off' => 'Neutral SBA On, Colour SBA Off',
+        'Neutral SBA On, Color SBA On' => 'Neutral SBA On, Colour SBA On',
+      },
+    },
+   'SceneColorimetryEstimates' => 'Scene Colourimetry Estimates',
    'SceneMode' => {
       PrintConv => {
@@ -436,4 +831,5 @@
     },
    'ShutterPresentationColorCIELabVal' => 'Shutter Presentation Colour CIE Lab Val',
+   'SmartAlbumColor' => 'Smart Album Colour',
    'SpecialEffectsOpticalFilter' => {
       PrintConv => {
@@ -450,7 +846,30 @@
     },
    'SubimageColor' => 'Subimage Colour',
+   'SwatchColorantA' => 'Swatch Colourant A',
+   'SwatchColorantB' => 'Swatch Colourant B',
+   'SwatchColorantBlack' => 'Swatch Colourant Black',
+   'SwatchColorantBlue' => 'Swatch Colourant Blue',
+   'SwatchColorantCyan' => 'Swatch Colourant Cyan',
+   'SwatchColorantGray' => 'Swatch Colourant Gray',
+   'SwatchColorantGreen' => 'Swatch Colourant Green',
+   'SwatchColorantL' => 'Swatch Colourant L',
+   'SwatchColorantMagenta' => 'Swatch Colourant Magenta',
+   'SwatchColorantMode' => 'Swatch Colourant Mode',
+   'SwatchColorantRed' => 'Swatch Colourant Red',
+   'SwatchColorantSwatchName' => 'Swatch Colourant Swatch Name',
+   'SwatchColorantTint' => 'Swatch Colourant Tint',
+   'SwatchColorantType' => 'Swatch Colourant Type',
+   'SwatchColorantYellow' => 'Swatch Colourant Yellow',
+   'SwatchGroupsColorants' => 'Swatch Groups Colourants',
    'TestTarget' => {
       PrintConv => {
         'Color Chart' => 'Colour Chart',
+      },
+    },
+   'TextColor' => 'Text Colour',
+   'ToneCurveColorSpace' => 'Tone Curve Colour Space',
+   'ToningEffect' => {
+      PrintConv => {
+        'Color' => 'Colour',
       },
     },
@@ -468,8 +887,10 @@
     },
    'UltrasoundColorDataPresent' => 'Ultrasound Colour Data Present',
+   'UnderflowColor' => 'Underflow Colour',
    'Unsharp1Color' => 'Unsharp 1 Colour',
    'Unsharp2Color' => 'Unsharp 2 Colour',
    'Unsharp3Color' => 'Unsharp 3 Colour',
    'Unsharp4Color' => 'Unsharp 4 Colour',
+   'VideoAlphaPremultipleColor' => 'Video Alpha Premultiple Colour',
    'VideoAlphaPremultipleColorA' => 'Video Alpha Premultiple Colour A',
    'VideoAlphaPremultipleColorB' => 'Video Alpha Premultiple Colour B',
@@ -477,4 +898,5 @@
    'VideoAlphaPremultipleColorBlue' => 'Video Alpha Premultiple Colour Blue',
    'VideoAlphaPremultipleColorCyan' => 'Video Alpha Premultiple Colour Cyan',
+   'VideoAlphaPremultipleColorGray' => 'Video Alpha Premultiple Colour Gray',
    'VideoAlphaPremultipleColorGreen' => 'Video Alpha Premultiple Colour Green',
    'VideoAlphaPremultipleColorL' => 'Video Alpha Premultiple Colour L',
@@ -483,16 +905,39 @@
    'VideoAlphaPremultipleColorRed' => 'Video Alpha Premultiple Colour Red',
    'VideoAlphaPremultipleColorSwatchName' => 'Video Alpha Premultiple Colour Swatch Name',
+   'VideoAlphaPremultipleColorTint' => 'Video Alpha Premultiple Colour Tint',
    'VideoAlphaPremultipleColorType' => 'Video Alpha Premultiple Colour Type',
    'VideoAlphaPremultipleColorYellow' => 'Video Alpha Premultiple Colour Yellow',
+   'VideoColorKind' => 'Video Colour Kind',
    'VideoColorSpace' => 'Video Colour Space',
+   'VisualColor' => {
+      Description => 'Visual Colour',
+      PrintConv => {
+        'Color' => 'Colour',
+      },
+    },
    'WBAdjColorTemp' => 'WB Adj Colour Temp',
    'WBAdjLighting' => {
       PrintConv => {
-        'High Color Rendering Fluorescent' => 'High Colour Rendering Fluorescent',
-      },
-    },
+        'High Color Rendering Fluorescent (3700K)' => 'High Colour Rendering Fluorescent (1)',
+        'High Color Rendering Fluorescent (5000K)' => 'High Colour Rendering Fluorescent (3)',
+        'High Color Rendering Fluorescent (cool white)' => 'High Colour Rendering Fluorescent (2)',
+        'High Color Rendering Fluorescent (daylight)' => 'High Colour Rendering Fluorescent (4)',
+        'High Color Rendering Fluorescent (warm white)' => 'High Colour Rendering Fluorescent (0)',
+        'Sodium Vapor Lamps' => 'Sodium Vapour Lamps',
+        'Standard Fluorescent (high temperature mercury vapor)' => 'Standard Fluorescent (high temperature mercury vapour)',
+      },
+    },
+   'WatercolorFilter' => 'Watercolour Filter',
    'WhiteBalance' => {
       PrintConv => {
-        'Color Temperature/Color Filter' => 'Color Temperature/Colour Filter',
+        'Color Filter' => 'Colour Filter',
+        'Color Temperature' => 'Colour Temperature',
+        'Color Temperature Enhancement' => 'Colour Temperature Enhancement',
+        'Color Temperature/Color Filter' => 'Colour Temperature/Colour Filter',
+      },
+    },
+   'WhiteBalance2' => {
+      PrintConv => {
+        'Auto (Keep Warm Color Off)' => 'Auto (Keep Warm Colour Off)',
       },
     },
@@ -545,5 +990,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/en_gb.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/en_gb.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/en_gb.pm	(revision 34921)
@@ -12,7 +12,34 @@
 use vars qw($VERSION);
 
-$VERSION = '1.06';
+$VERSION = '1.13';
 
 %Image::ExifTool::Lang::en_gb::Translate = (
+   'AboveColor' => 'Above Colour',
+   'AdvancedFilter' => {
+      PrintConv => {
+        'Partial Color Blue' => 'Partial Colour Blue',
+        'Partial Color Green' => 'Partial Colour Green',
+        'Partial Color Orange' => 'Partial Colour Orange',
+        'Partial Color Purple' => 'Partial Colour Purple',
+        'Partial Color Red' => 'Partial Colour Red',
+        'Partial Color Yellow' => 'Partial Colour Yellow',
+        'Pop Color' => 'Pop Colour',
+      },
+    },
+   'AdvancedSceneMode' => {
+      PrintConv => {
+        'Color Select' => 'Colour Select',
+      },
+    },
+   'AllColorFlatField1' => 'All Colour Flat Field 1',
+   'AllColorFlatField2' => 'All Colour Flat Field 2',
+   'AllColorFlatField3' => 'All Colour Flat Field 3',
+   'Alpha' => {
+      PrintConv => {
+        'Alpha Exists (W color component)' => 'Alpha Exists (W colour component)',
+        'Alpha Exists (color not premultiplied)' => 'Alpha Exists (colour not premultiplied)',
+        'Alpha Exists (color premultiplied)' => 'Alpha Exists (colour premultiplied)',
+      },
+    },
    'AlternateDuotoneColors' => 'Alternate Duotone Colours',
    'AlternateSpotColors' => 'Alternate Spot Colours',
@@ -20,6 +47,32 @@
       PrintConv => {
         'Pale & Light Color' => 'Pale & Light Colour',
-      },
-    },
+        'Pale & Light Color II' => 'Pale & Light Colour II',
+        'Partial Color' => 'Partial Colour',
+        'Partial Color II' => 'Partial Colour II',
+        'Partial Color III' => 'Partial Colour III',
+        'Watercolor' => 'Watercolour',
+        'Watercolor I' => 'Watercolour I',
+        'Watercolor II' => 'Watercolour II',
+      },
+    },
+   'ArtFilterEffect' => {
+      PrintConv => {
+        'Green Color Filter' => 'Green Colour Filter',
+        'No Color Filter' => 'No Colour Filter',
+        'Orange Color Filter' => 'Orange Colour Filter',
+        'Pale & Light Color' => 'Pale & Light Colour',
+        'Pale & Light Color II' => 'Pale & Light Colour II',
+        'Partial Color' => 'Partial Colour',
+        'Partial Color II' => 'Partial Colour II',
+        'Partial Color III' => 'Partial Colour III',
+        'Red Color Filter' => 'Red Colour Filter',
+        'Watercolor' => 'Watercolour',
+        'Watercolor I' => 'Watercolour I',
+        'Watercolor II' => 'Watercolour II',
+        'Yellow Color Filter' => 'Yellow Colour Filter',
+      },
+    },
+   'AudioIsInitialized' => 'Audio Is Initialised',
+   'AutoAFPointColorTracking' => 'Auto AF Point Colour Tracking',
    'AutoLightingOptimizer' => 'Auto Lighting Optimiser',
    'AutoLightingOptimizerOn' => 'Auto Lighting Optimiser On',
@@ -34,4 +87,10 @@
    'BackgroundColorValue' => 'Background Colour Value',
    'BasicColorImageSequence' => 'Basic Colour Image Sequence',
+   'BelowColor' => 'Below Colour',
+   'BestShotMode' => {
+      PrintConv => {
+        'Water Color' => 'Water Colour',
+      },
+    },
    'BkColor' => 'Background Colour',
    'BluePaletteColorTableData' => 'Blue Palette Colour Table Data',
@@ -54,8 +113,19 @@
    'CameraColorCalibration14' => 'Camera Colour Calibration 14',
    'CameraColorCalibration15' => 'Camera Colour Calibration 15',
+   'CameraRawColorTone' => 'Camera Raw Colour Tone',
    'CanonColorInfo1' => 'Canon Colour Info 1',
    'CanonColorInfo2' => 'Canon Colour Info 2',
    'ChromaticityColorant' => 'Chromaticity Colourant',
-   'Color' => 'Colour',
+   'CodingMethods' => {
+      PrintConv => {
+        'JBIG color' => 'JBIG colour',
+      },
+    },
+   'Color' => {
+      Description => 'Colour',
+      PrintConv => {
+        'Color' => 'Colour',
+      },
+    },
    'ColorAberrationControl' => 'Colour Aberration Control',
    'ColorAdjustment' => 'Colour Adjustment',
@@ -69,6 +139,8 @@
    'ColorBalanceRed' => 'Colour Balance Red',
    'ColorBalanceUnknown' => 'Colour Balance Unknown',
+   'ColorBalanceVersion' => 'Colour Balance Version',
    'ColorBitDepth' => 'Colour Bit Depth',
    'ColorBlur' => 'Colour Blur',
+   'ColorBlurOn' => 'Colour Blur On',
    'ColorBoostLevel' => 'Colour Boost Level',
    'ColorBoostType' => 'Colour Boost Type',
@@ -79,9 +151,14 @@
    'ColorClass' => 'Colour Class',
    'ColorCompensationFilter' => 'Colour Compensation Filter',
+   'ColorCompensationFilterCustom' => 'Colour Compensation Filter Custom',
+   'ColorCompensationFilterSet' => 'Colour Compensation Filter Set',
    'ColorComponents' => 'Colour Components',
    'ColorControl' => 'Colour Control',
    'ColorCorrection' => 'Colour Correction',
+   'ColorCreatorEffect' => 'Colour Creator Effect',
    'ColorDataVersion' => 'Colour Data Version',
+   'ColorDescriptor' => 'Colour Descriptor',
    'ColorEffect' => 'Colour Effect',
+   'ColorFieldCode' => 'Colour Field Code',
    'ColorFilter' => 'Colour Filter',
    'ColorGain' => 'Colour Gain',
@@ -90,4 +167,5 @@
    'ColorHue' => 'Colour Hue',
    'ColorImagePrintingFlag' => 'Colour Image Printing Flag',
+   'ColorLabel' => 'Colour Label',
    'ColorMap' => 'Colour Map',
    'ColorMatrix' => 'Colour Matrix',
@@ -95,11 +173,15 @@
    'ColorMatrix2' => 'Colour Matrix 2',
    'ColorMatrixA' => 'Colour Matrix A',
+   'ColorMatrixAdobeRGB' => 'Colour Matrix Adobe RGB',
    'ColorMatrixB' => 'Colour Matrix B',
    'ColorMatrixNumber' => 'Colour Matrix Number',
+   'ColorMatrixSRGB' => 'Colour Matrix sRGB',
    'ColorMode' => {
       Description => 'Colour Mode',
       PrintConv => {
+        'Indexed Color' => 'Indexed Colour',
         'Natural color' => 'Natural colour',
         'Neutral Color' => 'Neutral Colour',
+        'RGB Color' => 'RGB Colour',
         'Saturated Color' => 'Saturated Colour',
         'Vivid color' => 'Vivid colour',
@@ -109,6 +191,8 @@
    'ColorMoireReductionMode' => 'Colour Moire Reduction Mode',
    'ColorNoiseReduction' => 'Colour Noise Reduction',
+   'ColorNoiseReductionDetail' => 'Colour Noise Reduction Detail',
    'ColorNoiseReductionIntensity' => 'Colour Noise Reduction Intensity',
    'ColorNoiseReductionSharpness' => 'Colour Noise Reduction Sharpness',
+   'ColorNoiseReductionSmoothness' => 'Colour Noise Reduction Smoothness',
    'ColorObjBackType' => 'Colour Obj Back Type',
    'ColorObjName' => 'Colour Obj Name',
@@ -117,5 +201,8 @@
    'ColorPalette' => 'Colour Palette',
    'ColorPlanes' => 'Colour Planes',
+   'ColorPrimaries' => 'Colour Primaries',
    'ColorProfile' => 'Colour Profile',
+   'ColorProfileSettings' => 'Colour Profile Settings',
+   'ColorRangeLevels' => 'Colour Range Levels',
    'ColorRepresentation' => 'Colour Representation',
    'ColorReproduction' => 'Colour Reproduction',
@@ -123,12 +210,27 @@
    'ColorResponseUnit' => 'Colour Response Unit',
    'ColorSamplersResource' => 'Colour Samplers Resource',
+   'ColorSamplersResource2' => 'Colour Samplers Resource 2',
+   'ColorSaturationAdj' => 'Colour Saturation Adj',
    'ColorSequence' => 'Colour Sequence',
+   'ColorSiting' => 'Colour Siting',
    'ColorSpace' => {
       Description => 'Colour Space',
       PrintConv => {
+        'Embedded Color Profile' => 'Embedded Colour Profile',
+        'Linked Color Profile' => 'Linked Colour Profile',
         'No color space specified' => 'No colour space specified',
+        'Windows Color Space' => 'Windows Colour Space',
       },
     },
    'ColorSpaceData' => 'Colour Space Data',
+   'ColorSpecApproximation' => 'Colour Spec Approximation',
+   'ColorSpecData' => 'Colour Spec Data',
+   'ColorSpecMethod' => {
+      Description => 'Colour Spec Method',
+      PrintConv => {
+        'Vendor Color' => 'Vendor Colour',
+      },
+    },
+   'ColorSpecPrecedence' => 'Colour Spec Precedence',
    'ColorSpecification' => 'Colour Specification',
    'ColorTable' => 'Colour Table',
@@ -143,4 +245,7 @@
    'ColorTempFlashData' => 'Colour Temp Flash Data',
    'ColorTempFluorescent' => 'Colour Temp Fluorescent',
+   'ColorTempFluorescentD' => 'Colour Temp Fluorescent D',
+   'ColorTempFluorescentN' => 'Colour Temp Fluorescent N',
+   'ColorTempFluorescentW' => 'Colour Temp Fluorescent W',
    'ColorTempKelvin' => 'Colour Temp Kelvin',
    'ColorTempMeasured' => 'Colour Temp Measured',
@@ -158,6 +263,20 @@
    'ColorTempUnknown15' => 'Colour Temp Unknown 15',
    'ColorTempUnknown16' => 'Colour Temp Unknown 16',
+   'ColorTempUnknown17' => 'Colour Temp Unknown 17',
+   'ColorTempUnknown18' => 'Colour Temp Unknown 18',
+   'ColorTempUnknown19' => 'Colour Temp Unknown 19',
    'ColorTempUnknown2' => 'Colour Temp Unknown 2',
+   'ColorTempUnknown20' => 'Colour Temp Unknown 20',
+   'ColorTempUnknown21' => 'Colour Temp Unknown 21',
+   'ColorTempUnknown22' => 'Colour Temp Unknown 22',
+   'ColorTempUnknown23' => 'Colour Temp Unknown 23',
+   'ColorTempUnknown24' => 'Colour Temp Unknown 24',
+   'ColorTempUnknown25' => 'Colour Temp Unknown 25',
+   'ColorTempUnknown26' => 'Colour Temp Unknown 26',
+   'ColorTempUnknown27' => 'Colour Temp Unknown 27',
+   'ColorTempUnknown28' => 'Colour Temp Unknown 28',
+   'ColorTempUnknown29' => 'Colour Temp Unknown 29',
    'ColorTempUnknown3' => 'Colour Temp Unknown 3',
+   'ColorTempUnknown30' => 'Colour Temp Unknown 30',
    'ColorTempUnknown4' => 'Colour Temp Unknown 4',
    'ColorTempUnknown5' => 'Colour Temp Unknown 5',
@@ -168,6 +287,9 @@
    'ColorTemperature' => 'Colour Temperature',
    'ColorTemperatureAdj' => 'Colour Temperature Adj',
+   'ColorTemperatureAuto' => 'Colour Temperature Auto',
    'ColorTemperatureBG' => 'Colour Temperature BG',
+   'ColorTemperatureCustom' => 'Colour Temperature Custom',
    'ColorTemperatureRG' => 'Colour Temperature RG',
+   'ColorTemperatureSet' => 'Colour Temperature Set',
    'ColorTemperatureSetting' => {
       Description => 'Colour Temperature Setting',
@@ -178,6 +300,8 @@
    'ColorTone' => 'Colour Tone',
    'ColorToneAdj' => 'Colour Tone Adj',
+   'ColorToneAuto' => 'Colour Tone Auto',
    'ColorToneFaithful' => 'Colour Tone Faithful',
    'ColorToneLandscape' => 'Colour Tone Landscape',
+   'ColorToneMonochrome' => 'Colour Tone Monochrome',
    'ColorToneNeutral' => 'Colour Tone Neutral',
    'ColorTonePortrait' => 'Colour Tone Portrait',
@@ -208,4 +332,5 @@
    'ColorantCount' => 'Colourant Count',
    'ColorantCyan' => 'Colourant Cyan',
+   'ColorantGray' => 'Colourant Gray',
    'ColorantGreen' => 'Colourant Green',
    'ColorantL' => 'Colourant L',
@@ -216,9 +341,13 @@
    'ColorantSwatchName' => 'Colourant Swatch Name',
    'ColorantTableOut' => 'Colourant Table Out',
+   'ColorantTint' => 'Colourant Tint',
    'ColorantType' => 'Colourant Type',
    'ColorantYellow' => 'Colourant Yellow',
+   'Colorants' => 'Colourants',
+   'ColorimetricIntentImageState' => 'Colourimetric Intent Image State',
    'ColorimetricReference' => 'Colourimetric Reference',
+   'Colorimetry' => 'Colourimetry',
+   'ColorimetryCode' => 'Colourimetry Code',
    'Colors' => 'Colours',
-   'Colorspace' => 'Colourspace',
    'Compression' => {
       PrintConv => {
@@ -238,9 +367,15 @@
       },
     },
+   'CustomColorTone' => 'Custom Colour Tone',
    'D-LightingHQColorBoost' => 'D-Lighting HQ Colour Boost',
    'D-LightingHSColorBoost' => 'D-Lighting HS Colour Boost',
+   'D-RangeOptimizerHighlight' => 'D-Range Optimiser Highlight',
+   'D-RangeOptimizerMode' => 'D-Range Optimiser Mode',
+   'D-RangeOptimizerShadow' => 'D-Range Optimiser Shadow',
+   'D-RangeOptimizerValue' => 'D-Range Optimiser Value',
    'DateTimeDigitized' => 'Date/Time Digitised',
    'DefHilite' => 'Use Default Highlight Colour',
    'DefaultImageColor' => 'Default Image Colour',
+   'DefineQuantizationTable' => 'Define Quantisation Table',
    'DeltaType' => {
       PrintConv => {
@@ -249,4 +384,166 @@
       },
     },
+   'DigitalFilter01' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Replace Color' => 'Replace Colour',
+        'Unicolor Bold' => 'Unicolour Bold',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter02' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter03' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter04' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter05' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter06' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter07' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter08' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter09' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter10' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter11' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter12' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter13' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter14' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter15' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter16' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter17' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter18' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter19' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'DigitalFilter20' => {
+      PrintConv => {
+        'Color Filter' => 'Colour Filter',
+        'Extract Color' => 'Extract Colour',
+        'Invert Color' => 'Invert Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
    'DisplayUnits' => {
       PrintConv => {
@@ -254,5 +551,21 @@
       },
     },
+   'DriveMode' => {
+      PrintConv => {
+        'D-Range Optimizer Bracketing High' => 'D-Range Optimiser Bracketing High',
+        'D-Range Optimizer Bracketing Low' => 'D-Range Optimiser Bracketing Low',
+      },
+    },
+   'DriveMode2' => {
+      PrintConv => {
+        'D-Range Optimizer Bracketing High' => 'D-Range Optimiser Bracketing High',
+        'D-Range Optimizer Bracketing Low' => 'D-Range Optimiser Bracketing Low',
+      },
+    },
    'DynamicRangeOptimizer' => 'Dynamic Range Optimiser',
+   'DynamicRangeOptimizerBracket' => 'Dynamic Range Optimiser Bracket',
+   'DynamicRangeOptimizerLevel' => 'Dynamic Range Optimiser Level',
+   'DynamicRangeOptimizerMode' => 'Dynamic Range Optimiser Mode',
+   'DynamicRangeOptimizerSetting' => 'Dynamic Range Optimiser Setting',
    'EasyMode' => {
       PrintConv => {
@@ -262,4 +575,14 @@
       },
     },
+   'EmbeddedImageColorSpace' => 'Embedded Image Colour Space',
+   'ExposureProgram' => {
+      PrintConv => {
+        'Partial Color Blue' => 'Partial Colour Blue',
+        'Partial Color Green' => 'Partial Colour Green',
+        'Partial Color Red' => 'Partial Colour Red',
+        'Partial Color Yellow' => 'Partial Colour Yellow',
+        'Pop Color' => 'Pop Colour',
+      },
+    },
    'FaithfulRawColorTone' => 'Faithful Raw Colour Tone',
    'FaxProfile' => {
@@ -276,4 +599,5 @@
       },
     },
+   'FilmColorProcess' => 'Film Colour Process',
    'FilmMode' => {
       PrintConv => {
@@ -284,6 +608,14 @@
       },
     },
+   'FlagColor' => 'Flag Colour',
    'FlashColorFilter' => 'Flash Colour Filter',
+   'FocalPlaneColorimetryEstimates' => 'Focal Plane Colourimetry Estimates',
+   'GammaColorTone' => 'Gamma Colour Tone',
    'GenOpColor' => 'Gen Op Colour',
+   'GenreID' => {
+      PrintConv => {
+        'Books|Kids|Basic Concepts|Colors' => 'Books|Kids|Basic Concepts|Colours',
+      },
+    },
    'GreenPaletteColorTableData' => 'Green Palette Colour Table Data',
    'GreenPaletteColorTableDescriptor' => 'Green Palette Colour Table Descriptor',
@@ -306,7 +638,17 @@
     },
    'ImageColorValue' => 'Image Colour Value',
+   'ImageMedium' => {
+      PrintConv => {
+        'Color hard copy' => 'Colour hard copy',
+        'Color negative' => 'Colour negative',
+        'Color reversal' => 'Colour reversal',
+      },
+    },
    'ImageOptimization' => 'Image Optimisation',
+   'IndexedColorTableCount' => 'Indexed Colour Table Count',
    'InitializedDataSize' => 'Initialised Data Size',
    'InterchangeColorSpace' => 'Interchange Colour Space',
+   'Isotherm1Color' => 'Isotherm 1 Colour',
+   'Isotherm2Color' => 'Isotherm 2 Colour',
    'LandscapeRawColorTone' => 'Landscape Raw Colour Tone',
    'LargeBluePaletteColorTableData' => 'Large Blue Palette Colour Table Data',
@@ -317,8 +659,25 @@
    'LargeRedPaletteColorTableData' => 'Large Red Palette Colour Table Data',
    'LargeRedPaletteColorTableDescr' => 'Large Red Palette Colour Table Descr',
+   'LayerBlendModes' => {
+      PrintConv => {
+        'Color' => 'Colour',
+        'Color Burn' => 'Colour Burn',
+        'Color Dodge' => 'Colour Dodge',
+        'Darker Color' => 'Darker Colour',
+        'Lighter Color' => 'Lighter Colour',
+      },
+    },
    'MDColorTable' => 'MD Colour Table',
+   'MDItemColorSpace' => 'MD Item Colour Space',
    'MagicFilter' => {
       PrintConv => {
         'Pale & Light Color' => 'Pale & Light Colour',
+        'Pale & Light Color II' => 'Pale & Light Colour II',
+        'Partial Color' => 'Partial Colour',
+        'Partial Color II' => 'Partial Colour II',
+        'Partial Color III' => 'Partial Colour III',
+        'Watercolor' => 'Watercolour',
+        'Watercolor I' => 'Watercolour I',
+        'Watercolor II' => 'Watercolour II',
       },
     },
@@ -332,5 +691,7 @@
     },
    'MattColor' => 'Matt Colour',
+   'MediaColor' => 'Media Colour',
    'ModifiedColorTemp' => 'Modified Colour Temp',
+   'MonochromeColor' => 'Monochrome Colour',
    'MyColorMode' => {
       Description => 'My Colour Mode',
@@ -347,6 +708,8 @@
    'NumImportantColors' => 'Num Important Colours',
    'OpColor' => 'Op Colour',
+   'OverflowColor' => 'Overflow Colour',
    'PF25ColorMatrix' => 'PF25 Colour Matrix',
    'PaletteColorTableUID' => 'Palette Colour Table UID',
+   'PaletteColors' => 'Palette Colours',
    'PhotoEffect' => {
       PrintConv => {
@@ -360,4 +723,36 @@
     },
    'Photoshop2ColorTable' => 'Photoshop 2 Colour Table',
+   'PhotoshopFormat' => {
+      PrintConv => {
+        'Optimized' => 'Optimised',
+      },
+    },
+   'PictureEffect' => {
+      PrintConv => {
+        'Partial Color (blue)' => 'Partial Colour (blue)',
+        'Partial Color (green)' => 'Partial Colour (green)',
+        'Partial Color (red)' => 'Partial Colour (red)',
+        'Partial Color (yellow)' => 'Partial Colour (yellow)',
+        'Pop Color' => 'Pop Colour',
+        'Water Color' => 'Water Colour',
+        'Water Color 2' => 'Water Colour 2',
+      },
+    },
+   'PictureEffect2' => {
+      PrintConv => {
+        'Partial Color' => 'Partial Colour',
+        'Pop Color' => 'Pop Colour',
+        'Water Color' => 'Water Colour',
+      },
+    },
+   'PictureIndexedColors' => 'Picture Indexed Colours',
+   'PictureMode' => {
+      PrintConv => {
+        'Color Creator' => 'Colour Creator',
+        'Color Profile 1' => 'Colour Profile 1',
+        'Color Profile 2' => 'Colour Profile 2',
+        'Color Profile 3' => 'Colour Profile 3',
+      },
+    },
    'PictureType' => {
       PrintConv => {
@@ -365,4 +760,5 @@
       },
     },
+   'PictureWizardColor' => 'Picture Wizard Colour',
    'PortraitRawColorTone' => 'Portrait Raw Colour Tone',
    'PresetWhiteBalance' => {
@@ -379,4 +775,5 @@
     },
    'PseudoColorType' => 'Pseudo Colour Type',
+   'QuantizationDefault' => 'Quantisation Default',
    'QuantizationMethod' => {
       Description => 'Quantisation Method',
@@ -389,4 +786,16 @@
    'ROIDisplayColor' => 'ROI Display Colour',
    'RawColorAdj' => 'Raw Colour Adj',
+   'RawDevArtFilter' => {
+      PrintConv => {
+        'Pale & Light Color' => 'Pale & Light Colour',
+        'Pale & Light Color II' => 'Pale & Light Colour II',
+        'Partial Color' => 'Partial Colour',
+        'Partial Color II' => 'Partial Colour II',
+        'Partial Color III' => 'Partial Colour III',
+        'Watercolor' => 'Watercolour',
+        'Watercolor I' => 'Watercolour I',
+        'Watercolor II' => 'Watercolour II',
+      },
+    },
    'RawDevColorSpace' => 'Raw Dev Colour Space',
    'RawDevMemoryColorEmphasis' => 'Raw Dev Memory Colour Emphasis',
@@ -404,6 +813,9 @@
    'RedPaletteColorTableData' => 'Red Palette Colour Table Data',
    'RedPaletteColorTableDescriptor' => 'Red Palette Colour Table Descriptor',
+   'ReflectionHardcopyOrigColorimetry' => 'Reflection Hardcopy Orig Colourimetry',
+   'ReflectionPrintOutputColorimetry' => 'Reflection Print Output Colourimetry',
    'RenderingIntent' => {
       PrintConv => {
+        'Absolute Colorimetric (LCS_GM_ABS_COLORIMETRIC)' => 'Absolute Colourimetric (LCS_GM_ABS_COLORIMETRIC)',
         'ICC-Absolute Colorimetric' => 'ICC-Absolute Colourimetric',
         'Media-Relative Colorimetric' => 'Media-Relative Colourimetric',
@@ -414,4 +826,6 @@
         'Color Custom' => 'Colour Custom',
         'Color Outline' => 'Colour Outline',
+        'Color Sketch' => 'Colour Sketch',
+        'Selective Color' => 'Selective Colour',
       },
     },
@@ -423,4 +837,13 @@
       },
     },
+   'SceneBalanceAlgorithmCommand' => {
+      PrintConv => {
+        'Neutral SBA Off, Color SBA Off' => 'Neutral SBA Off, Colour SBA Off',
+        'Neutral SBA Off, Color SBA On' => 'Neutral SBA Off, Colour SBA On',
+        'Neutral SBA On, Color SBA Off' => 'Neutral SBA On, Colour SBA Off',
+        'Neutral SBA On, Color SBA On' => 'Neutral SBA On, Colour SBA On',
+      },
+    },
+   'SceneColorimetryEstimates' => 'Scene Colourimetry Estimates',
    'SceneMode' => {
       PrintConv => {
@@ -449,4 +872,5 @@
     },
    'ShutterPresentationColorCIELabVal' => 'Shutter Presentation Colour CIE Lab Val',
+   'SmartAlbumColor' => 'Smart Album Colour',
    'SpecialEffectsOpticalFilter' => {
       PrintConv => {
@@ -464,7 +888,30 @@
     },
    'SubimageColor' => 'Subimage Colour',
+   'SwatchColorantA' => 'Swatch Colourant A',
+   'SwatchColorantB' => 'Swatch Colourant B',
+   'SwatchColorantBlack' => 'Swatch Colourant Black',
+   'SwatchColorantBlue' => 'Swatch Colourant Blue',
+   'SwatchColorantCyan' => 'Swatch Colourant Cyan',
+   'SwatchColorantGray' => 'Swatch Colourant Gray',
+   'SwatchColorantGreen' => 'Swatch Colourant Green',
+   'SwatchColorantL' => 'Swatch Colourant L',
+   'SwatchColorantMagenta' => 'Swatch Colourant Magenta',
+   'SwatchColorantMode' => 'Swatch Colourant Mode',
+   'SwatchColorantRed' => 'Swatch Colourant Red',
+   'SwatchColorantSwatchName' => 'Swatch Colourant Swatch Name',
+   'SwatchColorantTint' => 'Swatch Colourant Tint',
+   'SwatchColorantType' => 'Swatch Colourant Type',
+   'SwatchColorantYellow' => 'Swatch Colourant Yellow',
+   'SwatchGroupsColorants' => 'Swatch Groups Colourants',
    'TestTarget' => {
       PrintConv => {
         'Color Chart' => 'Colour Chart',
+      },
+    },
+   'TextColor' => 'Text Colour',
+   'ToneCurveColorSpace' => 'Tone Curve Colour Space',
+   'ToningEffect' => {
+      PrintConv => {
+        'Color' => 'Colour',
       },
     },
@@ -482,4 +929,5 @@
     },
    'UltrasoundColorDataPresent' => 'Ultrasound Colour Data Present',
+   'UnderflowColor' => 'Underflow Colour',
    'UninitializedDataSize' => 'Uninitialised Data Size',
    'Unsharp1Color' => 'Unsharp 1 Colour',
@@ -487,4 +935,5 @@
    'Unsharp3Color' => 'Unsharp 3 Colour',
    'Unsharp4Color' => 'Unsharp 4 Colour',
+   'VideoAlphaPremultipleColor' => 'Video Alpha Premultiple Colour',
    'VideoAlphaPremultipleColorA' => 'Video Alpha Premultiple Colour A',
    'VideoAlphaPremultipleColorB' => 'Video Alpha Premultiple Colour B',
@@ -492,4 +941,5 @@
    'VideoAlphaPremultipleColorBlue' => 'Video Alpha Premultiple Colour Blue',
    'VideoAlphaPremultipleColorCyan' => 'Video Alpha Premultiple Colour Cyan',
+   'VideoAlphaPremultipleColorGray' => 'Video Alpha Premultiple Colour Gray',
    'VideoAlphaPremultipleColorGreen' => 'Video Alpha Premultiple Colour Green',
    'VideoAlphaPremultipleColorL' => 'Video Alpha Premultiple Colour L',
@@ -498,16 +948,39 @@
    'VideoAlphaPremultipleColorRed' => 'Video Alpha Premultiple Colour Red',
    'VideoAlphaPremultipleColorSwatchName' => 'Video Alpha Premultiple Colour Swatch Name',
+   'VideoAlphaPremultipleColorTint' => 'Video Alpha Premultiple Colour Tint',
    'VideoAlphaPremultipleColorType' => 'Video Alpha Premultiple Colour Type',
    'VideoAlphaPremultipleColorYellow' => 'Video Alpha Premultiple Colour Yellow',
+   'VideoColorKind' => 'Video Colour Kind',
    'VideoColorSpace' => 'Video Colour Space',
+   'VisualColor' => {
+      Description => 'Visual Colour',
+      PrintConv => {
+        'Color' => 'Colour',
+      },
+    },
    'WBAdjColorTemp' => 'WB Adj Colour Temp',
    'WBAdjLighting' => {
       PrintConv => {
-        'High Color Rendering Fluorescent' => 'High Colour Rendering Fluorescent',
-      },
-    },
+        'High Color Rendering Fluorescent (3700K)' => 'High Colour Rendering Fluorescent (1)',
+        'High Color Rendering Fluorescent (5000K)' => 'High Colour Rendering Fluorescent (3)',
+        'High Color Rendering Fluorescent (cool white)' => 'High Colour Rendering Fluorescent (2)',
+        'High Color Rendering Fluorescent (daylight)' => 'High Colour Rendering Fluorescent (4)',
+        'High Color Rendering Fluorescent (warm white)' => 'High Colour Rendering Fluorescent (0)',
+        'Sodium Vapor Lamps' => 'Sodium Vapour Lamps',
+        'Standard Fluorescent (high temperature mercury vapor)' => 'Standard Fluorescent (high temperature mercury vapour)',
+      },
+    },
+   'WatercolorFilter' => 'Watercolour Filter',
    'WhiteBalance' => {
       PrintConv => {
-        'Color Temperature/Color Filter' => 'Color Temperature/Colour Filter',
+        'Color Filter' => 'Colour Filter',
+        'Color Temperature' => 'Colour Temperature',
+        'Color Temperature Enhancement' => 'Colour Temperature Enhancement',
+        'Color Temperature/Color Filter' => 'Colour Temperature/Colour Filter',
+      },
+    },
+   'WhiteBalance2' => {
+      PrintConv => {
+        'Auto (Keep Warm Color Off)' => 'Auto (Keep Warm Colour Off)',
       },
     },
@@ -560,5 +1033,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/es.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/es.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/es.pm	(revision 34921)
@@ -12,13 +12,161 @@
 use vars qw($VERSION);
 
-$VERSION = '1.06';
+$VERSION = '1.16';
 
 %Image::ExifTool::Lang::es::Translate = (
-   'AFMicroAdjActive' => {
-      PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
+   'AEAperture' => 'Aperture AE',
+   'AELock' => 'Bloqueo AE',
+   'AELockButton' => {
+      Description => 'BotÃ³n Bloqueo AE',
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'AELockButtonPlusDials' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'AEMaxAperture2' => 'Apertura mÃ¡xima AE 2',
+   'AEMinAperture' => 'Apertura mÃ­nima AE',
+   'AEProgramMode' => {
+      PrintConv => {
+        'Landscape' => 'Paisaje',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'AESetting' => {
+      PrintConv => {
+        'AE Lock' => 'Bloqueo AE',
+        'Exposure Compensation' => 'CompensaciÃ³n ExposiciÃ³n',
+      },
+    },
+   'AFAperture' => 'Apertura AF',
+   'AFAreaHeight' => 'AF Alto Ãrea',
+   'AFAreaHeights' => 'AF Alto Ãrea',
+   'AFAreaIllumination' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'AFAreaMode' => {
+      Description => 'AF Modo Ãrea',
+      PrintConv => {
+        'Face Detect AF' => 'DetecciÃ³n Caras AF',
+        'Multi-point AF or AI AF' => 'Multipunto AF o AI AF',
+        'Off (Manual Focus)' => 'Desactivado (Enfoque Manual)',
+        'Single-point AF' => 'Punto Ãºnico AF)',
+        'Zone AF' => 'Zona AF',
+      },
+    },
+   'AFAreaWidth' => 'AF Ancho Ãrea',
+   'AFAreaWidths' => 'AF Ancho Ãrea',
+   'AFAssist' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'AFImageHeight' => 'AF Alto ImÃ¡gen',
+   'AFImageWidth' => 'AF Ancho ImÃ¡gen',
    'AFMode' => 'Modo AF',
+   'AFPoint' => {
+      Description => 'Punto AF',
+      PrintConv => {
+        'Center' => 'Centro',
+        'Face Detect' => 'DetecciÃ³n Caras',
+        'Left' => 'Izquierda',
+        'None' => 'Ninguno',
+        'None (MF)' => 'Ninguno (MF)',
+        'Right' => 'Derecha',
+      },
+    },
+   'AFPointActivationArea' => {
+      Description => 'Area de ActivaciÃ³n Punto AF',
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'AFPointAreaExpansion' => {
+      Description => 'Area Expansion Punto AF',
+      PrintConv => {
+        'Disable' => 'Desactivado',
+      },
+    },
+   'AFPointAutoSelection' => 'AutoselecciÃ³n Punto AF',
+   'AFPointBrightness' => {
+      Description => 'Brillo Punto AF',
+      PrintConv => {
+        'Brighter' => 'Brillante',
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
+   'AFPointDisplayDuringFocus' => {
+      Description => 'Mostrar Punto AF durante el enfoque',
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'AFPointIllumination' => {
+      Description => 'IluminaciÃ³n de Punto AF',
+      PrintConv => {
+        'Brighter' => 'Brillante',
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'AFPointMode' => 'Modo Punto AF',
+   'AFPointPosition' => 'PosiciÃ³n Punto AF',
+   'AFPointRegistration' => 'Registro de Puntos AF',
+   'AFPointSelected' => {
+      Description => 'Punto AF Seleccionado',
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'AFPointSelected2' => 'Punto AF Seleccionado 2 ',
+   'AFPointSelection' => 'SelecciÃ³n de Punto AF',
+   'AFPointSelectionMethod' => 'MÃ©todo SelecciÃ³n Punto AF',
+   'AFPoints' => 'Punto AF',
+   'AFPointsInFocus' => {
+      Description => 'Puntos AF en foco',
+      PrintConv => {
+        'All' => 'Todo',
+        'None' => 'Ninguno',
+      },
+    },
+   'AFPointsInFocus1D' => 'Puntos AF en foco',
+   'AFPointsInFocus5D' => {
+      Description => 'Puntos AF en foco 5D',
+      PrintConv => {
+        'Bottom' => 'Abajo',
+        'Center' => 'Centro',
+        'Left' => 'Izquierda',
+        'Lower-left' => 'Inferior izquierda',
+        'Lower-right' => 'Inferior derecha',
+        'Right' => 'Derecha',
+        'Top' => 'Arriba',
+        'Upper-left' => 'Superior izquierda',
+        'Upper-right' => 'Superior derecha',
+      },
+    },
+   'AFPointsSelected' => 'Puntos AF seleccionados',
+   'AFPointsUnknown1' => {
+      PrintConv => {
+        'All' => 'Todo',
+      },
+    },
+   'AFPointsUsed' => 'Puntos AF utilizados',
+   'AIServoTrackingSensitivity' => {
+      PrintConv => {
+        'Fast' => 'RÃ¡pido',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'APEVersion' => 'VersiÃ³n APE',
    'ARMIdentifier' => 'Identificador ARM',
    'ARMVersion' => 'VersiÃ³n ARM',
@@ -29,4 +177,5 @@
       Description => 'AcciÃ³n Aconsejada',
       PrintConv => {
+        'Object Append' => 'AÃ±adir Objeto',
         'Object Kill' => 'Destruir Objecto',
         'Object Reference' => 'Referencia Objecto',
@@ -36,5 +185,42 @@
     },
    'ActiveArea' => 'Ãrea Activa',
+   'ActiveD-Lighting' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'ActiveD-LightingMode' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Off' => 'Desactivado',
+      },
+    },
+   'AddAspectRatioInfo' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'AddOriginalDecisionData' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'AdjustmentMode' => 'Modo Ajuste',
+   'AdvancedRaw' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'AdvancedSceneMode' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+        'Soft' => 'Suave',
+      },
+    },
    'Album' => 'Ãlbum',
    'AlphaByteCount' => 'NÃºmero Byte Alfa',
@@ -49,10 +235,38 @@
     },
    'AlphaOffset' => 'Offset Alfa',
+   'AmbienceSelection' => {
+      PrintConv => {
+        'Brighter' => 'Brillante',
+        'Cool' => 'FrÃ­o',
+        'Darker' => 'Oscuro',
+        'Intense' => 'Intenso',
+        'Monochrome' => 'Monocromo',
+        'Soft' => 'Suave',
+        'Standard' => 'EstÃ¡ndar',
+        'Vivid' => 'VÃ­vido',
+        'Warm' => 'CÃ¡lido',
+      },
+    },
    'AnalogBalance' => 'Balance AnalÃ³gico',
+   'Annotation' => 'AnotaciÃ³n',
+   'Annotations' => 'Anotaciones',
+   'Anti-Blur' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
    'AntiAliasStrength' => 'Potencia Relativa del Filtro Antialiasing',
-   'Aperture' => 'Abertura',
-   'ApertureValue' => 'Abertura',
+   'Aperture' => 'Apertura',
+   'ApertureRange' => 'Rango Apertura',
+   'ApertureSetting' => 'Ajustes Apertura',
+   'ApertureValue' => 'Apertura',
    'ApplicationRecordVersion' => 'VersiÃ³n Registro AplicaciÃ³n',
-   'Artist' => 'Persona que CreÃ³ la Imagen',
+   'ArtMode' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+        'Panorama' => 'Panoramica',
+      },
+    },
+   'Artist' => 'Autor',
    'AsShotICCProfile' => 'Perfil ICC Captura',
    'AsShotNeutral' => 'Captura Neutral',
@@ -65,6 +279,22 @@
       },
     },
+   'AudioChannelType' => {
+      PrintConv => {
+        'Other' => 'Otro',
+      },
+    },
+   'AudioChannels' => 'Canales Audio',
+   'AudioCodecID' => {
+      PrintConv => {
+        'Unknown -' => 'Desconocido -',
+      },
+    },
    'AudioDuration' => 'DuraciÃ³n Audio',
    'AudioOutcue' => 'Cola Audio',
+   'AudioSampleType' => {
+      PrintConv => {
+        'Other' => 'Otro',
+      },
+    },
    'AudioSamplingRate' => 'Ratio Muestreo Audio',
    'AudioSamplingResolution' => 'ResoluciÃ³n Muestreo Audio',
@@ -93,5 +323,31 @@
    'Author' => 'Autor',
    'AuthorsPosition' => 'PosiciÃ³n del Autor',
+   'AutoAperture' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'AutoBracket' => 'Auto-horquillado',
+   'AutoExposureBracketing' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'AutoFP' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'AutoLightingOptimizer' => {
+      PrintConv => {
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+        'Standard' => 'EstÃ¡ndar',
+        'Strong' => 'Fuerte',
+      },
+    },
    'AutoLightingOptimizerOn' => {
       PrintConv => {
@@ -99,11 +355,19 @@
       },
     },
+   'AutoRedEye' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'AutoRotate' => {
       PrintConv => {
-        'Rotate 180' => 'Rotar 180Â°',
-        'Rotate 270 CW' => 'Rotar 270Â° sentido reloj',
-        'Rotate 90 CW' => 'Rotar 90Â° sentido reloj',
-      },
-    },
+        'None' => 'Ninguno',
+        'Rotate 180' => 'Girado 180Â°',
+        'Rotate 270 CW' => 'Girado 270Â° sentido reloj',
+        'Rotate 90 CW' => 'Girado 90Â° sentido reloj',
+      },
+    },
+   'AverageLevel' => 'Nivel Medio',
    'BToA0' => 'B a A0',
    'BToA1' => 'B a A1',
@@ -117,20 +381,82 @@
     },
    'BadFaxLines' => 'LÃ­neas Fax Malas',
+   'BannerImageType' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'BaselineExposure' => 'ExposiciÃ³n Base',
    'BaselineNoise' => 'Ruido Base',
    'BaselineSharpness' => 'Nitidez Base',
    'BatteryLevel' => 'Nivel BaterÃ­a',
+   'BatteryState' => {
+      PrintConv => {
+        'Low' => 'Bajo',
+      },
+    },
    'BayerGreenSplit' => 'Mosaico Bayer Verde',
+   'Beep' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'BeepPitch' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
    'BestQualityScale' => 'Escala Mayor Calidad',
+   'BestShotMode' => {
+      PrintConv => {
+        'Beach' => 'Playa',
+        'Fireworks' => 'Fuegos Artificiales',
+        'Food' => 'Comida',
+        'Monochrome' => 'Monocromo',
+        'Portrait' => 'Retrato',
+        'Snow' => 'Nieve',
+        'Underwater' => 'Subacuatica',
+      },
+    },
    'BitsPerComponent' => 'Bits Por Componente',
    'BitsPerExtendedRunLength' => 'Bits Por "Run Length" Extendido',
    'BitsPerRunLength' => 'Bits Por "Run Length"',
-   'BitsPerSample' => 'NÃºmero de Bits Por Componente',
+   'BitsPerSample' => 'NÃºmero de Bits Por Muestra',
    'BlackLevel' => 'Nivel Negro',
    'BlackLevelDeltaH' => 'Nivel Negro Delta H',
    'BlackLevelDeltaV' => 'Nivel Negro Delta V',
    'BlackLevelRepeatDim' => 'DimensiÃ³n RepeticiÃ³n Nivel Negro',
+   'BleachBypassToning' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'BlocksPerFrame' => 'Bloques por Imagen',
+   'BlueBalance' => 'Balance de azules',
    'BlueMatrixColumn' => 'Columna Matriz Azul',
    'BlueTRC' => 'Curva ReproducciÃ³n Tono Azul',
+   'BlurControl' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
+   'BlurWarning' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'BodyFirmwareVersion' => 'VersiÃ³n Firmware del cuerpo de la cÃ¡mara',
+   'BracketMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
    'Brightness' => 'Brillo',
    'BrightnessValue' => 'Luminosidad',
@@ -153,21 +479,26 @@
    'CMMFlags' => 'Banderas CMM',
    'CMYKEquivalent' => 'CMYK Equivalente',
+   'CPUType' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'CalibrationDateTime' => 'Fecha y Hora CalibraciÃ³n',
    'CalibrationIlluminant1' => {
       Description => 'CalibraciÃ³n IluminaciÃ³n 1',
       PrintConv => {
-        'Cloudy' => 'Tiempo nuboso',
+        'Cloudy' => 'Tiempo Nublado',
         'Cool White Fluorescent' => 'Fluorescente blanco cÃ¡lido (W 3800 - 4500K)',
         'Day White Fluorescent' => 'Fluorescente blanco dÃ­a (N 4600 - 5500K)',
         'Daylight' => 'Luz del dÃ­a',
-        'Daylight Fluorescent' => 'Fluorescente luz del dÃ­a (D 5700 - 7100K)',
+        'Daylight Fluorescent' => 'Fluorescente luz de dÃ­a (D 5700 - 7100K)',
         'Fine Weather' => 'Buen tiempo',
         'Fluorescent' => 'Fluorescente',
         'ISO Studio Tungsten' => 'Tungsteno estudio ISO',
         'Other' => 'Otras Fuentes Luz',
-        'Shade' => 'Sombra',
-        'Standard Light A' => 'Luz estandar A',
-        'Standard Light B' => 'Luz estandar B',
-        'Standard Light C' => 'Luz estandar C',
+        'Shade' => 'SombrÃ­o',
+        'Standard Light A' => 'Luz EstÃ¡ndar A',
+        'Standard Light B' => 'Luz EstÃ¡ndar B',
+        'Standard Light C' => 'Luz EstÃ¡ndar C',
         'Tungsten (Incandescent)' => 'Tungsteno (luz incandescente)',
         'Unknown' => 'Desconocido',
@@ -179,17 +510,17 @@
       Description => 'CalibraciÃ³n IluminaciÃ³n 2',
       PrintConv => {
-        'Cloudy' => 'Tiempo nuboso',
+        'Cloudy' => 'Tiempo Nublado',
         'Cool White Fluorescent' => 'Fluorescente blanco cÃ¡lido (W 3800 - 4500K)',
         'Day White Fluorescent' => 'Fluorescente blanco dÃ­a (N 4600 - 5500K)',
         'Daylight' => 'Luz del dÃ­a',
-        'Daylight Fluorescent' => 'Fluorescente luz del dÃ­a (D 5700 - 7100K)',
+        'Daylight Fluorescent' => 'Fluorescente luz de dÃ­a (D 5700 - 7100K)',
         'Fine Weather' => 'Buen tiempo',
         'Fluorescent' => 'Fluorescente',
         'ISO Studio Tungsten' => 'Tungsteno estudio ISO',
         'Other' => 'Otras Fuentes Luz',
-        'Shade' => 'Sombra',
-        'Standard Light A' => 'Luz estandar A',
-        'Standard Light B' => 'Luz estandar B',
-        'Standard Light C' => 'Luz estandar C',
+        'Shade' => 'SombrÃ­o',
+        'Standard Light A' => 'Luz EstÃ¡ndar A',
+        'Standard Light B' => 'Luz EstÃ¡ndar B',
+        'Standard Light C' => 'Luz EstÃ¡ndar C',
         'Tungsten (Incandescent)' => 'Tungsteno (luz incandescente)',
         'Unknown' => 'Desconocido',
@@ -201,11 +532,45 @@
    'CameraCalibration2' => 'CalibraciÃ³n CÃ¡mara 2',
    'CameraCalibrationSig' => 'Firma CalibraciÃ³n CÃ¡mara',
+   'CameraISO' => 'Camara-ISO',
    'CameraOrientation' => {
-      PrintConv => {
-        'Rotate 270 CW' => 'Rotar 270Â° sentido reloj',
-        'Rotate 90 CW' => 'Rotar 90Â° sentido reloj',
+      Description => 'OrientaciÃ³n CÃ¡mara',
+      PrintConv => {
+        'Rotate 270 CW' => 'Girado 270Â° sentido reloj',
+        'Rotate 90 CW' => 'Girado 90Â° sentido reloj',
       },
     },
    'CameraSerialNumber' => 'NÃºmero Serie CÃ¡mara',
+   'CameraTemperature' => 'Temperatura CÃ¡mara',
+   'CameraType' => 'Tipo CÃ¡mara',
+   'CameraType2' => 'Tipo CÃ¡mara',
+   'CanonFileLength' => 'TamaÃ±o Archivo',
+   'CanonFlashMode' => {
+      PrintConv => {
+        'Auto' => 'AutomÃ¡tico',
+        'External flash' => 'Flash Externo',
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+        'Red-eye reduction' => 'RÃ©ducciÃ³n ojos rojos',
+        'Red-eye reduction (Auto)' => 'RÃ©ducciÃ³n ojos rojos (AutomÃ¡tico)',
+        'Red-eye reduction (On)' => 'RÃ©ducciÃ³n ojos rojos (Activado)',
+      },
+    },
+   'CanonImageSize' => {
+      PrintConv => {
+        '1280x720 Movie' => 'PelÃ­cula 1280x720',
+        '1920x1080 Movie' => 'PelÃ­cula 1920x1080',
+        '640x480 Movie' => 'PelÃ­cula 640x480',
+        'Large' => 'Ancho',
+        'Medium' => 'Medio',
+        'Medium 1' => 'Medio 1',
+        'Medium 2' => 'Medio 2',
+        'Medium 3' => 'Medio 3',
+        'Small' => 'PequeÃ±o',
+        'Small 1' => 'PequeÃ±o 1',
+        'Small 2' => 'PequeÃ±o 2',
+        'Small 3' => 'PequeÃ±o 3',
+        'Small Movie' => 'PelÃ­cula PequeÃ±a',
+      },
+    },
    'Caption-Abstract' => 'TÃ­tulo/DescripciÃ³n',
    'CaptionWriter' => 'Autor del Pie de Foto',
@@ -214,4 +579,6 @@
    'CellLength' => 'Alto Celda',
    'CellWidth' => 'Ancho Celda',
+   'Certificate' => 'Certificado',
+   'Channels' => 'Canales',
    'CharTarget' => 'Objetivo Caracter',
    'CharacterSet' => 'Conjunto de Caracteres',
@@ -219,4 +586,18 @@
    'ChromaticAdaptation' => 'AdaptaciÃ³n CromÃ¡tica',
    'Chromaticity' => 'Cromaticidad',
+   'ChrominanceNR_TIFF_JPEG' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+      },
+    },
+   'ChrominanceNoiseReduction' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+      },
+    },
    'City' => 'Ciudad',
    'ClassifyState' => 'Clasificar Estado',
@@ -224,4 +605,10 @@
    'ClipPath' => 'Camino Fragmento',
    'CodedCharacterSet' => 'Juego Caracteres Codificado',
+   'ColorAberrationControl' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'ColorAdjustment' => 'Ajuste Color',
    'ColorAdjustmentMode' => {
@@ -232,12 +619,44 @@
       },
     },
+   'ColorBalanceAdj' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'ColorBooster' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'ColorCalibrationMatrix' => 'Tabla Matriz CalibraciÃ³n Color',
    'ColorCharacterization' => 'CaracterizaciÃ³n Color',
-   'ColorFilter' => 'Filtro de Color',
+   'ColorComponents' => 'Componentes de Color',
+   'ColorEffect' => {
+      PrintConv => {
+        'Cool' => 'FrÃ­o',
+        'Warm' => 'CÃ¡lido',
+      },
+    },
+   'ColorFilter' => {
+      Description => 'Filtro de Color',
+      PrintConv => {
+        'Green' => 'Verde',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
    'ColorMap' => 'Mapa Color',
+   'ColorMatrix' => 'Matriz de Color',
    'ColorMatrix1' => 'Matriz Color 1',
    'ColorMatrix2' => 'Matriz Color 2',
+   'ColorMatrixA' => 'Matriz de Color A',
+   'ColorMatrixAdobeRGB' => 'Matriz de Color Adobe RGB',
+   'ColorMatrixB' => 'Matriz de Color B',
+   'ColorMatrixNumber' => 'NÃºmero de Matriz de Color',
+   'ColorMatrixSRGB' => 'Matriz de Color SRGB',
    'ColorMode' => {
-      Description => 'Estilo.Creativo',
+      Description => 'Modo de Color',
       PrintConv => {
         'Autumn Leaves' => 'Hojas de otoÃ±o',
@@ -248,4 +667,5 @@
         'Landscape' => 'Paisaje',
         'Light' => 'Luz',
+        'Neutral' => 'Neutro',
         'Night View' => 'Vista nocturna',
         'Night View/Portrait' => 'Retrato noct.',
@@ -253,5 +673,18 @@
         'Standard' => 'EstÃ¡ndar',
         'Sunset' => 'Puesta sol',
-        'Vivid' => 'Color vÃ­vido',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'ColorMoireReduction' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'ColorMoireReductionMode' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
       },
     },
@@ -282,13 +715,65 @@
       PrintConv => {
         'ICC Profile' => 'Perfil ICC',
+        'Monochrome' => 'Monocromo',
         'Uncalibrated' => 'Sin calibrar',
+        'Wide Gamut RGB' => 'Gamut RVB Grande',
       },
     },
    'ColorSpaceData' => 'Espacio Color Datos',
    'ColorTable' => 'Tabla Color',
+   'ColorTempAuto' => 'Temperatura Color AutomÃ¡tica',
+   'ColorTempCloudy' => 'Temperatura Color Nublado',
+   'ColorTempCustom' => 'Temperatura Color Personalizada',
+   'ColorTempCustom1' => 'Temperatura Color Personalizada 1',
+   'ColorTempCustom2' => 'Temperatura Color Personalizada 2',
+   'ColorTempDaylight' => 'Temperatura Color Luz de DÃ­a',
+   'ColorTempFlash' => 'Temperatura Color Flash',
+   'ColorTempFluorescent' => 'Temperatura Color Fluorescente',
+   'ColorTempKelvin' => 'Temperatura Color Kelvin',
+   'ColorTempMeasured' => 'Temperatura Color Medida',
+   'ColorTempShade' => 'Temperatura Color SombrÃ­o',
+   'ColorTempTungsten' => 'Temperatura Color Tungsteno',
+   'ColorTempUnknown' => 'Temperatura de Color Desconocida',
+   'ColorTempUnknown10' => 'Temperatura de Color Desconocida 10',
+   'ColorTempUnknown11' => 'Temperatura de Color Desconocida 11',
+   'ColorTempUnknown12' => 'Temperatura de Color Desconocida 12',
+   'ColorTempUnknown13' => 'Temperatura de Color Desconocida 13',
+   'ColorTempUnknown14' => 'Temperatura de Color Desconocida 14',
+   'ColorTempUnknown15' => 'Temperatura de Color Desconocida 15',
+   'ColorTempUnknown16' => 'Temperatura de Color Desconocida 16',
+   'ColorTempUnknown17' => 'Temperatura de Color Desconocida 17',
+   'ColorTempUnknown18' => 'Temperatura de Color Desconocida 18',
+   'ColorTempUnknown19' => 'Temperatura de Color Desconocida 19',
+   'ColorTempUnknown2' => 'Temperatura de Color Desconocida 2',
+   'ColorTempUnknown20' => 'Temperatura de Color Desconocida 20',
+   'ColorTempUnknown3' => 'Temperatura de Color Desconocida 3',
+   'ColorTempUnknown4' => 'Temperatura de Color Desconocida 4',
+   'ColorTempUnknown5' => 'Temperatura de Color Desconocida 5',
+   'ColorTempUnknown6' => 'Temperatura de Color Desconocida 6',
+   'ColorTempUnknown7' => 'Temperatura de Color Desconocida 7',
+   'ColorTempUnknown8' => 'Temperatura de Color Desconocida 8',
+   'ColorTempUnknown9' => 'Temperatura de Color Desconocida 9',
    'ColorTemperature' => 'Temperatura de Color',
+   'ColorTone' => {
+      Description => 'Tono de Color',
+      PrintConv => {
+        'Normal' => 'EstÃ¡ndar',
+      },
+    },
    'ColorantOrder' => 'Orden Colorante',
    'ColorantTable' => 'Tabla Colorante',
    'ColorimetricReference' => 'Referencia ColorimÃ©trica',
+   'CommandDialsChangeMainSub' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'CommandDialsMenuAndPlayback' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'CommandDialsReverseRotation' => {
       PrintConv => {
@@ -296,5 +781,21 @@
       },
     },
+   'CommanderGroupAMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'CommanderGroupBMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'CommanderInternalFlash' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
    'Comment' => 'Comentario',
+   'Compatibility' => 'Compatibilidad',
    'Compilation' => {
       PrintConv => {
@@ -302,8 +803,10 @@
       },
     },
-   'ComponentsConfiguration' => 'Significado de Cada Componente',
+   'ComponentsConfiguration' => 'ConfiguraciÃ³n de Componentes',
+   'Composer' => 'Compositor',
    'CompressedBitsPerPixel' => 'Modo CompresiÃ³n Imagen',
+   'CompressedSize' => 'TamaÃ±o Comprimido',
    'Compression' => {
-      Description => 'Esquema CompresiÃ³n',
+      Description => 'CompresiÃ³n',
       PrintConv => {
         'JPEG' => 'CompresiÃ³n JPEG',
@@ -313,4 +816,5 @@
         'Next' => 'CodificaciÃ³n NeXT 2-bit',
         'Nikon NEF Compressed' => 'CompresiÃ³n Nikon NEF',
+        'None' => 'Ninguno',
         'Pentax PEF Compressed' => 'CompresiÃ³n Pentax PEF',
         'SGILog' => 'CodificaciÃ³n Log Luminancia SGI 32-bit',
@@ -321,4 +825,15 @@
       },
     },
+   'CompressionFactor' => 'Factor de compresiÃ³n',
+   'CompressionLevel' => 'Nivel CompresiÃ³n',
+   'CompressionType' => {
+      Description => 'Tipo CompresiÃ³n',
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'CompressorName' => 'Nombre Compresor',
+   'Conductor' => 'Director',
+   'Conductors' => 'Directores',
    'ConnectionSpaceIlluminant' => 'IluminaciÃ³n Espacio ConexiÃ³n',
    'ConsecutiveBadFaxLines' => 'LÃ­neas Fax Malas Consecutivas',
@@ -326,12 +841,35 @@
    'ContentLocationCode' => 'CÃ³digo LocalizaciÃ³n Contenido',
    'ContentLocationName' => 'Nombre LocalizaciÃ³n Contenido',
+   'ContinuousBracketing' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
+   'ContinuousDrive' => {
+      PrintConv => {
+        'Continuous' => 'Continuo',
+        'Continuous, High' => 'Continuo, Alto',
+        'Continuous, Low' => 'Continuo, Bajo',
+        'Continuous, Speed Priority' => 'Continuo, Prioridad Velocidad',
+        'Movie' => 'PelÃ­cula',
+        'Single' => 'Simple',
+      },
+    },
    'Contrast' => {
       Description => 'Contraste',
       PrintConv => {
-        'High' => 'Fuerte',
-        'Low' => 'Suave',
+        'High' => 'Alto',
+        'Low' => 'Bajo',
         'Normal' => 'EstÃ¡ndar',
       },
     },
+   'ContrastMode' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
+   'ContrastSetting' => 'Ajustes de Contraste',
    'Copyright' => 'Copyright Perfil',
    'CopyrightNotice' => 'Aviso Copyright',
@@ -339,9 +877,35 @@
    'Country-PrimaryLocationCode' => 'CÃ³digo PaÃ­s ISO',
    'Country-PrimaryLocationName' => 'PaÃ­s',
+   'CountryCode' => 'CÃ³digo PaÃ­s',
    'CreateDate' => 'Fecha y Hora de Datos Digital',
    'CreationDate' => 'Fecha CreaciÃ³n',
+   'CreativeStyle' => {
+      PrintConv => {
+        'Autumn Leaves' => 'Hojas de otoÃ±o',
+        'B&W' => 'ByN',
+        'Clear' => 'Claro',
+        'Deep' => 'Profundo',
+        'Landscape' => 'Paisaje',
+        'Light' => 'Luz',
+        'Neutral' => 'Neutro',
+        'Night View/Portrait' => 'Retrato noct.',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+        'Sunset' => 'Puesta sol',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'CreativeStyleSetting' => {
+      PrintConv => {
+        'Landscape' => 'Paisaje',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
    'Creator' => 'Creador',
    'CreatorAddress' => 'Creador - DirecciÃ³n',
    'CreatorCity' => 'Creador - Ciudad',
+   'CreatorContactInfo' => 'Contacto Creador',
    'CreatorCountry' => 'Creador - PaÃ­s',
    'CreatorPostalCode' => 'Creador - CÃ³digo Postal',
@@ -356,6 +920,20 @@
       },
     },
+   'CropHeight' => 'Recorte Altura',
+   'CropLeft' => 'Recorte Izquierda',
+   'CropTop' => 'Recorte Arriba',
+   'CropWidth' => 'Recorte Anchura',
+   'CroppedImageHeight' => 'Alto ImÃ¡gen Recortada',
+   'CroppedImageLeft' => 'Izquierda ImÃ¡gen Recortada',
+   'CroppedImageTop' => 'Superior ImÃ¡gen Recortada',
+   'CroppedImageWidth' => 'Ancho ImÃ¡gen Recortada',
    'CurrentICCProfile' => 'Perfil ICC Actual',
    'CurrentPreProfileMatrix' => 'Matriz Pre Perfil Actual',
+   'Curves' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'CustomRendered' => {
       Description => 'Proceso Imagen Personalizado',
@@ -365,7 +943,20 @@
       },
     },
+   'CustomSaturation' => 'SaturaciÃ³n personalizada',
+   'D-LightingHQ' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'D-LightingHQSelected' => {
       PrintConv => {
         'Yes' => 'Si',
+      },
+    },
+   'D-LightingHS' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
       },
     },
@@ -373,13 +964,32 @@
    'DNGLensInfo' => 'Distancia Focal MÃ­nima',
    'DNGVersion' => 'VersiÃ³n DNG',
+   'DOF' => 'Profundidad de campo',
+   'Data' => 'Datos',
    'DataCompressionMethod' => 'Proveedor/Propietario Algoritmo CompresiÃ³n Datos',
+   'DataImprint' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'DataPackets' => ' Paquetes de Datos',
    'DataType' => 'Tipo Datos',
    'Date' => 'Fecha',
    'DateCreated' => 'Fecha CreaciÃ³n',
    'DateSent' => 'Fecha EnvÃ­o',
+   'DateStampMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'DateTimeDigitized' => 'Fecha y Hora Digital',
    'DateTimeOriginal' => 'Fecha y Hora de Datos Original',
    'DaylightSavings' => {
       PrintConv => {
         'Yes' => 'Si',
+      },
+    },
+   'DefaultBlackRender' => {
+      PrintConv => {
+        'None' => 'Ninguno',
       },
     },
@@ -387,4 +997,10 @@
    'DefaultCropSize' => 'TamaÃ±o Corte Defecto',
    'DefaultScale' => 'Escala por Defecto',
+   'DerivedFromMaskMarkers' => {
+      PrintConv => {
+        'All' => 'Todo',
+        'None' => 'Ninguno',
+      },
+    },
    'Description' => 'DescripciÃ³n',
    'Destination' => 'Destino',
@@ -402,5 +1018,112 @@
    'DigitalCreationDate' => 'Fecha CreaciÃ³n Digital',
    'DigitalCreationTime' => 'Hora CreaciÃ³n Digital',
-   'DigitalZoom' => 'Zoom Digital',
+   'DigitalFilter01' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter02' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter03' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter04' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter05' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter06' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter07' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter08' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter09' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter10' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter11' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter12' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter13' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter14' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter15' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter16' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter17' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter18' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter19' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalFilter20' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'DigitalSignature' => 'Firma Digital',
+   'DigitalZoom' => {
+      Description => 'Zoom Digital',
+      PrintConv => {
+        'None' => 'Ninguno',
+        'Off' => 'Desactivado',
+      },
+    },
    'DigitalZoomOn' => {
       Description => 'Zoom Digital Encendido',
@@ -412,9 +1135,45 @@
    'DigitalZoomRatio' => 'Ratio Zoom Digital',
    'Directory' => 'UbicaciÃ³n del Fichero',
+   'DistortionControl' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'DistortionCorrection' => {
+      Description => 'CorrecciÃ³n DistorsiÃ³n',
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'DistortionCorrection2' => {
+      Description => 'CorrecciÃ³n DistorsiÃ³n 2',
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'DistortionCorrectionOn' => 'CorrecciÃ³n DistorsiÃ³n Activada',
+   'DocSecurity' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'DocumentHistory' => 'Historial del Documento',
    'DocumentName' => 'Nombre Documento',
    'DocumentNotes' => 'Notas del Documento',
    'DotRange' => 'Intervalo Puntos',
-   'DriveMode' => 'Modo Entrada',
+   'DriveMode' => {
+      Description => 'Modo Entrada',
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'Duration' => 'DuraciÃ³n',
+   'DynamicRange' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
    'DynamicRangeOptimizer' => {
       Description => 'Optim.gama dinÃ¡',
@@ -430,4 +1189,61 @@
       },
     },
+   'DynamicRangeOptimizerBracket' => {
+      PrintConv => {
+        'Low' => 'Bajo',
+      },
+    },
+   'DynamicRangeOptimizerMode' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'DynamicRangeOptimizerSetting' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'EasyExposureCompensation' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'EasyMode' => {
+      PrintConv => {
+        'Beach' => 'Playa',
+        'Black & White' => 'Blanco y Negro',
+        'Digital Macro' => 'Macro digital',
+        'Easy' => 'FÃ¡cil',
+        'Fireworks' => 'Fuegos Artificiales',
+        'Fisheye Effect' => 'Efecto Ojo de Pez',
+        'Flash Off' => 'Flash Desactivado',
+        'Foliage' => 'Follaje',
+        'Gray Scale' => 'Escala de Grises',
+        'Indoor' => 'Interior',
+        'Kids & Pets' => 'NiÃ±os y Mascotas',
+        'Landscape' => 'Paisaje',
+        'Monochrome' => 'Monocromo',
+        'Neutral' => 'Neutro',
+        'Night' => 'Nocturno',
+        'Night Scene' => 'Escena Nocturna',
+        'Night Snapshot' => 'FotografÃ­a Nocturna',
+        'Nostalgic' => 'Nostalgico',
+        'Portrait' => 'Retrato',
+        'Smile' => 'Sonrisa',
+        'Snow' => 'Nieve',
+        'Sports' => 'Deportes',
+        'Sunset' => 'Puesta de sol',
+        'Surface' => 'Superficie',
+        'Underwater' => 'Subacuatica',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'EdgeNoiseReduction' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'EditStatus' => 'Estado EdiciÃ³n',
    'EditorialUpdate' => {
@@ -437,5 +1253,28 @@
       },
     },
+   'EffectiveMaxAperture' => 'Aperture MÃ¡xima Efectiva',
+   'Emphasis' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'EncodedBy' => 'Codificado por',
+   'EncodingProcess' => 'Proceso de codificaciÃ³n',
+   'EncodingSettings' => 'Ajustes de CodificaciÃ³n',
+   'EncodingTime' => 'Hora de codificaciÃ³n',
    'EndPoints' => 'Puntos Finales',
+   'EnhanceDarkTones' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'Enhancement' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Red' => 'Rojo',
+        'Underwater' => 'Subacuatica',
+      },
+    },
    'EnvelopeNumber' => 'NÃºmero Sobre',
    'EnvelopePriority' => {
@@ -450,4 +1289,7 @@
     },
    'EnvelopeRecordVersion' => 'VersiÃ³n Registro Sobre',
+   'EquipmentVersion' => 'VersiÃ³n Equipo',
+   'ErrorCorrection' => 'CorreciÃ³n Error',
+   'ErrorCorrectionType' => 'Tipo CorrecciÃ³n Error',
    'ExcursionTolerance' => {
       Description => 'Tolerancia ExcursiÃ³n',
@@ -461,4 +1303,5 @@
    'ExifImageWidth' => 'Ancho Imagen',
    'ExifOffset' => 'Puntero Exif IFD',
+   'ExifToolVersion' => 'VersiÃ³n ExifTool',
    'ExifVersion' => 'VersiÃ³n Exif',
    'ExpandFilm' => 'PelÃ­cula Expandida',
@@ -471,4 +1314,10 @@
    'ExpirationTime' => 'Hora ExpiraciÃ³n',
    'ExposureCompensation' => 'CompensaciÃ³n ExposiciÃ³n',
+   'ExposureDelayMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'ExposureIndex' => 'Ãndice ExposiciÃ³n',
    'ExposureMode' => {
@@ -478,7 +1327,15 @@
         'Auto' => 'ExposiciÃ³n automÃ¡tica',
         'Auto bracket' => 'Auto-horquillado',
+        'Beach' => 'Playa',
+        'Fireworks' => 'Fuegos Artificiales',
+        'Food' => 'Comida',
+        'Landscape' => 'Paisaje',
         'Manual' => 'ExposiciÃ³n manual',
+        'Panorama' => 'Panoramica',
+        'Portrait' => 'Retrato',
         'Program AE' => 'Programa AE',
         'Shutter speed priority AE' => 'Prioridad velocidad obturador AE',
+        'Snow' => 'Nieve',
+        'Underwater' => 'Subacuatica',
       },
     },
@@ -487,5 +1344,5 @@
       PrintConv => {
         'Action (High speed)' => 'Programa acciÃ³n (orientado a velocidad de obturaciÃ³n rÃ¡pida)',
-        'Aperture-priority AE' => 'Prioridad abertura',
+        'Aperture-priority AE' => 'Prioridad Apertura',
         'Creative (Slow speed)' => 'Programa creativo (orientado a profundidad de campo)',
         'Landscape' => 'Modo paisaje (para fotos de paisaje con el fondo en enfoque)',
@@ -497,6 +1354,18 @@
       },
     },
-   'ExposureTime' => 'Hora ExposiciÃ³n',
-   'ExposureTime2' => 'Hora ExposiciÃ³n 2',
+   'ExposureTime' => 'Tiempo de ExposiciÃ³n',
+   'ExposureTime2' => 'Tiempo de ExposiciÃ³n 2',
+   'Extender' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'ExternalFlash' => {
+      Description => 'Flash Externo',
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'ExternalFlashBounce' => {
       PrintConv => {
@@ -504,9 +1373,32 @@
       },
     },
+   'ExternalFlashMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'ExternalFlashZoom' => 'Zoom Flash Externo',
    'ExtraSamples' => 'Muestra Extra',
    'FNumber' => 'NÃºmero F',
+   'FOV' => 'Angulo de VisiÃ³n',
+   'FaceDetectArea' => 'Area detecciÃ³n caras',
+   'FaceDetectFrameSize' => 'TamaÃ±o Area detecciÃ³n caras',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (arriba/izquierda)',
+        'Rotate 180' => 'Girado 180Â°',
+        'Rotate 270 CW' => 'Girado 270Â° sentido reloj',
+        'Rotate 90 CW' => 'Girado 90Â° sentido reloj',
+      },
+    },
+   'FacesDetected' => 'Caras Detectadas',
    'FastSeek' => {
       PrintConv => {
         'Yes' => 'Si',
+      },
+    },
+   'FaxProfile' => {
+      PrintConv => {
+        'Unknown' => 'Desconocido',
       },
     },
@@ -514,7 +1406,24 @@
    'FaxRecvTime' => 'Hora RecepciÃ³n Fax',
    'FaxSubAddress' => 'SubdirecciÃ³n Fax',
+   'FileAccessDate' => 'Fecha y Hora de Acceso',
+   'FileCreateDate' => 'Fecha y Hora de CreaciÃ³n',
    'FileFormat' => 'Formato Archivo',
-   'FileModifyDate' => 'Fecha Actualizada',
+   'FileLength' => 'TamaÃ±o Archivo',
+   'FileModifyDate' => 'Fecha ActualizaciÃ³n',
    'FileName' => 'Nombre Archivo',
+   'FileNumberMemory' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'FileNumberSequence' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'FileOwner' => 'Propietario del Archivo',
+   'FilePermissions' => 'Permisos',
    'FileSize' => 'TamaÃ±o Archivo',
    'FileSource' => {
@@ -528,7 +1437,76 @@
    'FileType' => 'Tipo Archivo',
    'FileVersion' => 'VersiÃ³n Formato Archivo',
+   'Filename' => 'Nombre archivo',
    'FillOrder' => 'Orden Rellenado',
+   'FilterEffect' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+        'Off' => 'Desactivado',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'FilterEffectMonochrome' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'FilterEffectUnknown' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'FilterEffectUserDef1' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'FilterEffectUserDef2' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'FilterEffectUserDef3' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'FinderDisplayDuringExposure' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'FirmwareVersion' => 'VersiÃ³n Firmware',
    'FixtureIdentifier' => 'Identificador Marca',
+   'Flags' => {
+      PrintConv => {
+        'Comment' => 'Comentario',
+        'FileName' => 'Nombre de Archivo',
+        'Text' => 'Texto',
+      },
+    },
    'Flash' => {
       PrintConv => {
@@ -550,8 +1528,10 @@
         'No Flash' => 'Flash no disparado',
         'No flash function' => 'Sin funciÃ³n flash',
+        'Off' => 'Desactivado',
         'Off, Did not fire' => 'Flash no disparado, modo flash forzado',
         'Off, Did not fire, Return not detected' => 'Apagado, flash no disparado, retorno luz no detectado',
         'Off, No flash function' => 'Apagado, sin funciÃ³n flash',
         'Off, Red-eye reduction' => 'Apagado, modo reducciÃ³n ojos rojos',
+        'On' => 'Activado',
         'On, Did not fire' => 'Encendido, flash no disparado',
         'On, Fired' => 'Flash disparado, modo flash forzardo',
@@ -563,9 +1543,75 @@
       },
     },
+   'FlashColorFilter' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'FlashCommanderMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'FlashControlMode' => {
+      Description => 'Modo Control Flash',
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'Repeating Flash' => 'Flash Estroboscopico',
+      },
+    },
+   'FlashDevice' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'FlashEnergy' => 'EnergÃ­a Flash',
    'FlashExposureComp' => 'CompensaciÃ³n ExposiciÃ³n Flash',
+   'FlashExposureLock' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'FlashFired' => {
       PrintConv => {
         'Yes' => 'Si',
+      },
+    },
+   'FlashFocalLength' => 'Longitud Flash Flash',
+   'FlashGroupAControlMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'FlashGroupBControlMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'FlashGroupCControlMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'FlashIntensity' => {
+      Description => 'Intensidad Flash',
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
+   'FlashLevel' => {
+      PrintConv => {
+        'Low' => 'Bajo',
+      },
+    },
+   'FlashMeteringMode' => {
+      PrintConv => {
+        'External Auto' => 'Externo Automatico',
+        'External Manual' => 'Externo Manual',
+        'Off' => 'Desactivado',
       },
     },
@@ -581,4 +1627,35 @@
       },
     },
+   'FlashModel' => {
+      Description => 'Modelo Flash',
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'FlashOutput' => 'Flash Salida',
+   'FlashRemoteControl' => 'Control Remote Flash',
+   'FlashSerialNumber' => 'NÃºmero Serie Flash',
+   'FlashSource' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'FlashStatus' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'FlashType' => {
+      Description => 'Tipo Flash',
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'FlashWarning' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'FlashpixVersion' => 'VersiÃ³n Flashpix Soportado',
    'FlickerReduce' => {
@@ -607,6 +1684,34 @@
    'FocalPlaneXResolution' => 'ResoluciÃ³n X Plano Focal',
    'FocalPlaneYResolution' => 'ResoluciÃ³n Y Plano Focal',
-   'FocusMode' => 'Modo Enfoque',
+   'FocusContinuous' => {
+      PrintConv => {
+        'Continuous' => 'Continuo',
+        'Single' => 'Sencillo',
+      },
+    },
+   'FocusMode' => {
+      Description => 'Modo Enfoque',
+      PrintConv => {
+        'Continuous' => 'Continuo',
+        'Manual Focus (3)' => 'Enfoque Manual (6)',
+        'Manual Focus (6)' => 'Enfoque Manual (6)',
+        'Single' => 'Simple',
+      },
+    },
+   'FocusRange' => {
+      Description => 'Rango de Enfoque',
+      PrintConv => {
+        'Close' => 'PrÃ³ximo',
+        'Infinity' => 'Infinito',
+        'Not Known' => 'Desconocido',
+        'Very Close' => 'Muy PrÃ³ximo',
+      },
+    },
    'FocusSetting' => 'Ajuste Enfoque',
+   'FocusTrackingLockOn' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
    'ForwardMatrix1' => 'Matriz Avance 1',
    'ForwardMatrix2' => 'Matriz Avance 2',
@@ -615,4 +1720,15 @@
    'FreeByteCounts' => 'NÃºmero Bytes Libres',
    'FreeOffsets' => 'Offsets Libres',
+   'FuncButton' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'FuncButtonPlusDials' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'GEModel' => 'Modelo',
    'GPSAltitude' => 'Altitud',
    'GPSAltitudeRef' => {
@@ -626,4 +1742,5 @@
    'GPSDOP' => 'PrecisiÃ³n MediciÃ³n',
    'GPSDateStamp' => 'Fecha GPS',
+   'GPSDateTime' => 'Fecha y Hora GPS',
    'GPSDestBearing' => 'OrientaciÃ³n de Destino',
    'GPSDestBearingRef' => {
@@ -679,6 +1796,6 @@
       Description => 'Latitud Norte o Sur',
       PrintConv => {
-        'North' => 'Latitud Norte',
-        'South' => 'Latitud Sur',
+        'North' => 'Latitud norte',
+        'South' => 'Latitud sur',
       },
     },
@@ -734,5 +1851,5 @@
         'Low gain down' => 'AtenuaciÃ³n baja',
         'Low gain up' => 'Ganancia debil',
-        'None' => 'Ninguna',
+        'None' => 'Ninguno',
       },
     },
@@ -743,8 +1860,16 @@
       },
     },
+   'Genre' => {
+      Description => 'GÃ©nero',
+      PrintConv => {
+        'None' => 'Ninguno',
+        'Other' => 'Otro',
+      },
+    },
+   'GenreID' => 'ID GÃ©nero',
    'GeoTiffAsciiParams' => 'Etiqueta ParÃ¡metros Ascii Geo',
    'GeoTiffDirectory' => 'Etiqueta Directorio Clave Geo',
    'GeoTiffDoubleParams' => 'Etiqueta ParÃ¡metros Doble Geo',
-   'Gradation' => 'Impresivo',
+   'Gradation' => 'Luminosidad',
    'GrayResponseCurve' => 'Curva Respuesta Gris',
    'GrayResponseUnit' => {
@@ -761,4 +1886,10 @@
    'GreenMatrixColumn' => 'Columna Matriz Verde',
    'GreenTRC' => 'Curva ReproducciÃ³n Tono Verde',
+   'GridDisplay' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'HCUsage' => 'Uso HC',
    'HDR' => {
@@ -768,16 +1899,46 @@
       },
     },
+   'HDRSmoothing' => {
+      PrintConv => {
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+      },
+    },
    'HalftoneHints' => 'IndicaciÃ³n Medio Tono',
+   'HasAttachedImages' => 'Tiene Imagenes Adjuntas',
+   'HasAudio' => 'Tiene Audio',
+   'HasImage' => 'Tiene Imagen',
+   'HasScript' => 'Tiene Script',
+   'HasVideo' => 'Tiene Video',
    'Headline' => 'Titular',
    'HeightResolution' => 'ResoluciÃ³n Imagen Vertical',
    'HighISONoiseReduction' => {
-      Description => 'RR ISO Alta',
-      PrintConv => {
-        'High' => 'Hi',
-        'Low' => 'Lo',
-        'Off' => 'Desactivado',
+      Description => 'ReducciÃ³n Ruido ISO Alta',
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+        'Standard' => 'EstÃ¡ndar',
+        'Strong' => 'Fuerte',
+      },
+    },
+   'HighISONoiseReduction2' => {
+      PrintConv => {
+        'Low' => 'Bajo',
       },
     },
    'Highlight' => 'Realce',
+   'HighlightColorDistortReduct' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'HighlightTonePriority' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'HometownDST' => {
       PrintConv => {
@@ -786,6 +1947,21 @@
     },
    'HostComputer' => 'Ordenador Principal',
-   'Hue' => 'Tono',
+   'Hue' => {
+      Description => 'Tono',
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'HyperfocalDistance' => 'Distancia Hiperfocal',
+   'ICCProfile' => 'Perfil ICC',
    'ICC_Profile' => 'Perfil Color Entrada ICC',
+   'IDCCreativeStyle' => {
+      PrintConv => {
+        'Landscape' => 'Retrato',
+        'Neutral' => 'Neutro',
+        'Standard' => 'EstÃ¡ndar',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
    'IPTC-NAA' => 'Metadato IPTC-NAA',
    'IPTCBitsPerSample' => 'NÃºmero de Bits por Muestra',
@@ -805,4 +1981,20 @@
    'IPTCPixelWidth' => 'TamaÃ±o Pixel en DirecciÃ³n Escaneo',
    'ISO' => 'Ratio Velocidad ISO',
+   'ISOAutoParameters' => {
+      PrintConv => {
+        'Fast' => 'RÃ¡pido',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'ISOExpansion' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'ISOExpansion2' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
    'ISOSetting' => 'Ajuste ISO',
    'ISOSpeedExpansion' => {
@@ -812,5 +2004,22 @@
     },
    'IT8Header' => 'Cabecera IT8',
+   'Illumination' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'Image::ExifTool::AIFF::Comment' => 'Comentario AIFF',
+   'ImageAuthentication' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
    'ImageByteCount' => 'NÃºmero Byte Imagen',
+   'ImageColor' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
    'ImageColorIndicator' => 'Indicador Color Imagen',
    'ImageColorValue' => 'Valor Color Imagen',
@@ -826,4 +2035,20 @@
    'ImageDepth' => 'Ancho Imagen',
    'ImageDescription' => 'TÃ­tulo Imagen',
+   'ImageDustOff' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'ImageEditing' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'ImageFileFormatAsDelivered' => {
+      PrintConv => {
+        'Other' => 'Otro',
+      },
+    },
    'ImageHeight' => 'Alto Imagen',
    'ImageHistory' => 'Historia Imagen',
@@ -831,4 +2056,5 @@
    'ImageInfo' => 'Info Imagen',
    'ImageLayer' => 'Capa Imagen',
+   'ImageLength' => 'Longitud Imagen',
    'ImageNumber' => 'NÃºmero Imagen',
    'ImageOffset' => 'Offset Imagen',
@@ -841,21 +2067,108 @@
       },
     },
+   'ImageQuality' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
    'ImageResourceBlocks' => 'Bloques Recursos Imagen',
+   'ImageReview' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'ImageRotated' => {
       PrintConv => {
         'Yes' => 'Si',
+      },
+    },
+   'ImageRotation' => {
+      PrintConv => {
+        'None' => 'Ninguno',
       },
     },
    'ImageSize' => 'TamaÃ±o de la Imagen',
    'ImageSourceData' => 'Datos Fuente Imagen',
-   'ImageType' => 'Tipo Imagen',
+   'ImageStabilization' => {
+      Description => 'EstabilizaciÃ³n Imagen',
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'ImageStabilizationSetting' => 'Ajustes EstabilizaciÃ³n Imagen',
+   'ImageStyle' => {
+      PrintConv => {
+        'Landscape' => 'Paisaje',
+        'Neutral' => 'Neutro',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'ImageTone' => {
+      PrintConv => {
+        'Landscape' => 'Paisaje',
+        'Monochrome' => 'Monocromo',
+        'Portrait' => 'Retrato',
+      },
+    },
+   'ImageType' => {
+      Description => 'Tipo Imagen',
+      PrintConv => {
+        'Other' => 'Otro',
+      },
+    },
    'ImageUniqueID' => 'ID Ãnico Imagen',
    'ImageWidth' => 'Ancho Imagen',
    'Index' => 'Ãndice',
    'Indexed' => 'Indizado',
+   'IngredientsMaskMarkers' => {
+      PrintConv => {
+        'All' => 'Todo',
+        'None' => 'Ninguno',
+      },
+    },
+   'InitialKey' => 'Clave inicial',
    'InkNames' => 'Nombres Tinta',
    'InkSet' => 'Conjunto Tinta',
    'Instructions' => 'Instrucciones',
    'IntellectualGenre' => 'GÃ©nero Intelectual',
+   'IntelligentContrast' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+        'n/a' => 'No Aplica',
+      },
+    },
+   'IntelligentD-Range' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'IntelligentExposure' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'IntelligentResolution' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'IntensityStereo' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'InterchangeColorSpace' => {
       PrintConv => {
@@ -866,4 +2179,17 @@
    'IntergraphMatrix' => 'Etiqueta Matriz IntergrÃ¡fica',
    'Interlace' => 'Entrelazado',
+   'InternalFlash' => 'Flash Interno',
+   'InternalFlashAE1' => 'Flash Interno AE1',
+   'InternalFlashAE1_0' => 'Flash Interno',
+   'InternalFlashAE2' => 'Flash Interno AE2',
+   'InternalFlashAE2_0' => 'Flash Interno AE2',
+   'InternalFlashMode' => {
+      Description => 'Modo Flash Interno',
+      PrintConv => {
+        'Fired' => 'Activado',
+      },
+    },
+   'InternalFlashTable' => 'Tabla Flash Interno',
+   'InternalSerialNumber' => 'NÃºmero Serie Interno',
    'InteropIndex' => {
       Description => 'IdentificaciÃ³n Interoperabilidad',
@@ -876,4 +2202,7 @@
    'InteropOffset' => 'Etiqueta de Interoperabilidad',
    'InteropVersion' => 'VersiÃ³n Interoperabilidad',
+   'Is_Protected' => 'EstÃ¡ protegido',
+   'Is_Trusted' => 'Es de confianza',
+   'JFIFVersion' => 'VersiÃ³n JFIF',
    'JPEGACTables' => 'Tablas AC JPEG',
    'JPEGDCTables' => 'Tablas DC JPEG',
@@ -882,30 +2211,76 @@
    'JPEGProc' => 'Proc JPEG',
    'JPEGQTables' => 'Tablas Q JPEG',
+   'JPEGQuality' => {
+      Description => 'Calidad',
+      PrintConv => {
+        'Extra Fine' => 'Extrafina',
+        'Fine' => 'Fina',
+        'Standard' => 'Calidad estÃ¡ndar',
+      },
+    },
    'JPEGRestartInterval' => 'Intervalo Reinicio JPEG',
    'JPEGTables' => 'Tablas JPEG',
    'JobID' => 'ID del Trabajo',
+   'JobTitle' => 'Cargo',
    'Keyword' => 'Palabras Clave',
    'Keywords' => 'Clave',
+   'LCDIllumination' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'LCDIlluminationDuringBulb' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'LCHEditor' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'Language' => 'Idioma',
+   'LanguageCode' => {
+      PrintConv => {
+        'Neutral' => 'Neutro',
+      },
+    },
    'LanguageIdentifier' => 'Identificador Idioma',
+   'LanguageList' => 'Lista de Idiomas',
    'LeafData' => 'Datos Hoja',
    'Lens' => 'Objetivo',
-   'LensApertureRange' => 'Intervalo Abertura Objetivo',
+   'LensApertureRange' => 'Intervalo Apertura Objetivo',
+   'LensFirmwareVersion' => 'VersiÃ³n Firmware Objetivo',
+   'LensID' => 'ID Objetivo',
+   'LensIDNumber' => 'NÃºmero ID Objetivo',
    'LensInfo' => 'InformaciÃ³n del Objetivo',
+   'LensModel' => 'Modelo Objetivo',
+   'LensProperties' => 'Propiedades Objetivo',
+   'LensSerialNumber' => 'NÃºmero Serie Objetivo',
+   'LensType' => {
+      Description => 'Tipo Objetivo',
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'LightSource' => {
       Description => 'Fuente Luz',
       PrintConv => {
-        'Cloudy' => 'Tiempo nuboso',
+        'Cloudy' => 'Tiempo Nublado',
         'Cool White Fluorescent' => 'Fluorescente blanco cÃ¡lido (W 3800 - 4500K)',
         'Day White Fluorescent' => 'Fluorescente blanco dÃ­a (N 4600 - 5500K)',
         'Daylight' => 'Luz del dÃ­a',
-        'Daylight Fluorescent' => 'Fluorescente luz del dÃ­a (D 5700 - 7100K)',
+        'Daylight Fluorescent' => 'Fluorescente luz de dÃ­a (D 5700 - 7100K)',
         'Fine Weather' => 'Buen tiempo',
         'Fluorescent' => 'Fluorescente',
         'ISO Studio Tungsten' => 'Tungsteno estudio ISO',
         'Other' => 'Otras Fuentes Luz',
-        'Shade' => 'Sombra',
-        'Standard Light A' => 'Luz estandar A',
-        'Standard Light B' => 'Luz estandar B',
-        'Standard Light C' => 'Luz estandar C',
+        'Shade' => 'SombrÃ­o',
+        'Standard Light A' => 'Luz EstÃ¡ndar A',
+        'Standard Light B' => 'Luz EstÃ¡ndar B',
+        'Standard Light C' => 'Luz EstÃ¡ndar C',
         'Tungsten (Incandescent)' => 'Tungsteno (luz incandescente)',
         'Unknown' => 'Desconocido',
@@ -929,4 +2304,10 @@
       },
     },
+   'LiveViewShooting' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'LocalizedCameraModel' => 'Modelo CÃ¡mara Traducido',
    'Location' => 'LocalizaciÃ³n',
@@ -940,4 +2321,19 @@
    'LookupTable' => 'Tabla de Consulta',
    'Luminance' => 'Luminancia',
+   'LuminanceNoiseReduction' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+      },
+    },
+   'Lyrics' => 'Letras',
+   'Lyrics_Synchronised' => 'Letras Sincronizadas',
+   'MSStereo' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'Macro' => {
       PrintConv => {
@@ -945,4 +2341,11 @@
         'On' => 'Encendido',
         'View' => 'Vista',
+      },
+    },
+   'MacroMode' => 'Modo Macro',
+   'MainDialExposureComp' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
       },
     },
@@ -959,12 +2362,40 @@
     },
    'MakerNoteType' => 'Tipo Maker Note',
-   'MakerNoteVersion' => 'VersiÃ³n Maker Note',
+   'MakerNoteVersion' => 'VersiÃ³n nota Fabricante',
    'MakerNotes' => 'Notas del Fabricante',
+   'ManagedFromMaskMarkers' => {
+      PrintConv => {
+        'All' => 'Todo',
+        'None' => 'Ninguno',
+      },
+    },
+   'ManifestReferenceMaskMarkers' => {
+      PrintConv => {
+        'All' => 'Todo',
+        'None' => 'Ninguno',
+      },
+    },
+   'ManometerPressure' => 'PresiÃ³n Manometrica',
+   'ManometerReading' => 'Lectura Manometrica',
+   'ManualFlashOutput' => {
+      PrintConv => {
+        'Full' => 'Completo',
+        'Low' => 'Bajo',
+        'Medium' => 'Medio',
+        'n/a' => 'No Aplica',
+      },
+    },
    'ManualFocusDistance' => 'Distancia Enfoque Manual',
+   'Marker' => 'Marcador',
    'MaskedAreas' => 'Ãrea Oculta',
    'MasterDocumentID' => 'ID de Documento Maestro',
    'Matteing' => 'Mate',
-   'MaxAperture' => 'MÃ¡xima Abertura del Objetivo',
-   'MaxApertureValue' => 'Abertura Lente MÃ¡xima',
+   'MaxAperture' => 'MÃ¡xima Apertura del Objetivo',
+   'MaxApertureAtMaxFocal' => 'Apertura mÃ¡xima a focal mÃ¡xima',
+   'MaxApertureAtMinFocal' => 'Apertura mÃ¡xima a focal mÃ­nima',
+   'MaxApertureValue' => 'Apertura Lente MÃ¡xima',
+   'MaxFaces' => 'MÃ¡ximo caras',
+   'MaxFocalLength' => 'Longitud focal mÃ¡xima',
+   'MaxPacketSize' => 'TamaÃ±o MÃ¡ximo Paquete',
    'MaxSampleValue' => 'Valor Muestra Max',
    'MaximumDensityRange' => 'Rango Densidad Maxima',
@@ -986,6 +2417,6 @@
       Description => 'Modo MediciÃ³n',
       PrintConv => {
-        'Average' => 'Ponderado',
-        'Center-weighted average' => 'Ponderado central',
+        'Average' => 'Promedio',
+        'Center-weighted average' => 'Media ponderada al centro',
         'Multi-segment' => 'Multi-segmento',
         'Multi-spot' => 'Multi-puntual',
@@ -996,13 +2427,104 @@
       },
     },
+   'MinAperture' => 'Apertura mÃ­nima',
+   'MinFocalLength' => 'Longitud focal mÃ­nima',
+   'MinPacketSize' => 'TamaÃ±o MÃ­nimo Paquete',
    'MinSampleValue' => 'Valor Muestra Min',
+   'MinoltaQuality' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'ModeDialPosition' => {
+      PrintConv => {
+        'Panorama' => 'Panoramica',
+      },
+    },
    'Model' => 'Modelo',
    'Model2' => 'Modelo Equipamiento Entrada Imagen (2)',
+   'ModelReleaseStatus' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'ModelTiePoint' => 'Etiqueta Modelo Punto Lazo',
    'ModelTransform' => 'Etiqueta Modelo TransformaciÃ³n',
+   'ModelingFlash' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'ModifiedBy' => 'Modificado por',
+   'ModifiedPictureStyle' => {
+      PrintConv => {
+        'High Saturation' => 'SaturaciÃ³n Alta',
+        'Landscape' => 'Paisaje',
+        'Low Saturation' => 'SaturaciÃ³n Baja',
+        'Monochrome' => 'Monocromo',
+        'Neutral' => 'Neutro',
+        'None' => 'Ninguno',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'ModifiedSharpnessFreq' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'ModifiedToneCurve' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'ModifiedWhiteBalance' => {
+      PrintConv => {
+        'Underwater' => 'Subacuatica',
+      },
+    },
    'ModifyDate' => 'Fecha y Hora de Cambio del Archivo',
+   'MoireFilter' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'MonochromeFilterEffect' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
    'MonochromeLinear' => {
       PrintConv => {
         'Yes' => 'Si',
+      },
+    },
+   'MonochromeToning' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'MonochromeToningEffect' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+      },
+    },
+   'MultiExposureAutoGain' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'MultiExposureMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
       },
     },
@@ -1010,15 +2532,67 @@
       Description => 'Reduc. ruido varios fotogr.',
       PrintConv => {
-        'Off' => 'Desactivado',
-        'On' => 'Activado',
-      },
-    },
+        'None' => 'Ninguno',
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'MultipleExposureMode' => 'Modo ExposiciÃ³n MÃºltiple',
+   'MultipleExposureSet' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'Mute' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'MyColorMode' => {
+      PrintConv => {
+        'Neutral' => 'Neutro',
+        'Off' => 'Desactivado',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'NDFilter' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'NSC_Description' => 'DescripciÃ³n NSC',
+   'Name' => 'Nombre',
    'NamedColor2' => 'Color Llamado 2',
    'NativeDisplayInfo' => 'InformaciÃ³n Pantalla Nativa',
    'NewsPhotoVersion' => 'VersiÃ³n Registro Foto Noticias',
    'Noise' => 'Ruido',
-   'NoiseReduction' => 'ReducciÃ³n Ruido',
+   'NoiseFilter' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'NoiseReduction' => {
+      Description => 'ReducciÃ³n Ruido',
+      PrintConv => {
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
    'NoiseReductionApplied' => 'ReducciÃ³n Ruido Aplicada',
+   'NominalMaxAperture' => 'Apertura mÃ¡xima nominal',
+   'NominalMinAperture' => 'Apertura mÃ­nima nominal',
+   'NumAFPoints' => 'NÃºmero de Puntos AF',
+   'NumChannels' => 'NÃºmero Canales',
+   'NumColors' => 'NÃºmero de colores',
+   'NumImportantColors' => 'NÃºmero Colores Importantes',
    'NumIndexEntries' => 'NÃºmero de Entradas de Ãndice',
+   'NumSampleFrames' => 'NÃºmero de fotogramas',
+   'NumberOfFrames' => 'NÃºmero de imÃ¡genes',
    'NumberofInks' => 'NÃºmero de Tintas',
    'OPIProxy' => 'Proxy OPI',
@@ -1030,4 +2604,10 @@
         'Evening' => 'Tarde',
         'Morning' => 'MaÃ±ana',
+      },
+    },
+   'ObjectFileType' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+        'Unknown' => 'Desconocido',
       },
     },
@@ -1038,4 +2618,15 @@
    'ObjectTypeReference' => 'Referencia Tipo Objeto',
    'OffsetSchema' => 'Offset Esquema',
+   'OperatingSystem' => {
+      Description => 'Sistema Operativo',
+      PrintConv => {
+        'unknown' => 'desconocido',
+      },
+    },
+   'OpticalZoomMode' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
    'OpticalZoomOn' => {
       Description => 'Zoom Ãptico Encendido',
@@ -1054,21 +2645,69 @@
         'Mirror horizontal and rotate 90 CW' => 'Invertir horizontal y rotar 90Â° sentido reloj',
         'Mirror vertical' => 'Invertir vertical',
-        'Rotate 180' => 'Rotar 180Â°',
-        'Rotate 270 CW' => 'Rotar 270Â° sentido reloj',
-        'Rotate 90 CW' => 'Rotar 90Â° sentido reloj',
-      },
-    },
+        'Rotate 180' => 'Girado 180Â°',
+        'Rotate 270 CW' => 'Girado 270Â° sentido reloj',
+        'Rotate 90 CW' => 'Girado 90Â° sentido reloj',
+      },
+    },
+   'OriginPlatform' => {
+      PrintConv => {
+        'Other' => 'Otro',
+      },
+    },
+   'OriginalAlbumTitle' => 'TÃ­tulo Original Album',
+   'OriginalArtist' => 'Artista original',
+   'OriginalFileName' => 'Nombre archivo original',
+   'OriginalLyricist' => 'Letrista Original',
    'OriginalRawFileData' => 'Dato Archivo Raw Original',
    'OriginalRawFileDigest' => 'Cifrado Archivo Raw Original',
    'OriginalRawFileName' => 'Nombre Archivo Raw Original',
+   'OriginalReleaseYear' => 'AÃ±o VersiÃ³n Original',
    'OriginalTransmissionReference' => 'Identificador de Trabajo',
    'OriginatingProgram' => 'Programa Originario',
    'OutputResponse' => 'Respuesta Salida',
+   'Owner' => 'Propietario',
    'OwnerID' => 'ID del Propietario',
+   'OwnerName' => 'Nombre del Propietario',
+   'PF25ColorMatrix' => 'Matriz de Color PF25',
+   'PackingMethod' => {
+      PrintConv => {
+        'Best Compression' => 'Mejor CompresiÃ³n',
+        'Fast' => 'RÃ¡pido',
+        'Fastest' => 'Mas RÃ¡pido',
+        'Good Compression' => 'Buena CompresiÃ³n',
+        'Stored' => 'Almacenado',
+      },
+    },
    'Padding' => 'Margen Inferior',
    'PageName' => 'Nombre PÃ¡gina',
    'PageNumber' => 'NÃºmero PÃ¡gina',
+   'PanoramaSize3D' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'Period' => 'PerÃ­odo',
+   'PhotoEffect' => {
+      PrintConv => {
+        'B&W' => 'Blanco y Negro',
+        'Custom' => 'Personalizado',
+        'Neutral' => 'Neutro',
+        'Off' => 'Desactivado',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'PhotoEffects' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'PhotoEffectsType' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'PhotometricInterpretation' => {
-      Description => 'Esquema Pixel',
+      Description => 'InterpretaciÃ³n FotomÃ©trica',
       PrintConv => {
         'BlackIsZero' => 'Negro es cero',
@@ -1082,5 +2721,110 @@
     },
    'PhotoshopAnnotations' => 'Anotaciones Photoshop',
+   'PhotoshopFormat' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
    'PictInfo' => 'Info Imagen',
+   'Picture' => 'ImÃ¡gen',
+   'PictureControl' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'PictureControlActive' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'PictureDescription' => 'DescripciÃ³n ImÃ¡gen',
+   'PictureFinish' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+        'Portrait' => 'Retrato',
+      },
+    },
+   'PictureMode' => {
+      PrintConv => {
+        'Beach' => 'Playa',
+        'Fireworks' => 'Fuegos Artificiales',
+        'Food' => 'Comida',
+        'Green' => 'Verde',
+        'Landscape' => 'Paisaje',
+        'Panorama' => 'Panoramica',
+        'Portrait' => 'Retrato',
+        'Red' => 'Rojo',
+        'Snow' => 'Nieve',
+        'Soft' => 'Suave',
+        'Standard' => 'EstÃ¡ndar',
+        'Underwater' => 'Subacuatica',
+        'Vivid' => 'VÃ­vido',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'PictureModeBWFilter' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Neutral' => 'Neutro',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'PictureModeEffect' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'PictureModeTone' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Neutral' => 'Neutro',
+      },
+    },
+   'PictureStyle' => {
+      PrintConv => {
+        'Faithful' => 'Fiel',
+        'High Saturation' => 'SaturaciÃ³n Alta',
+        'Landscape' => 'Paisaje',
+        'Low Saturation' => 'SaturaciÃ³n Baja',
+        'Monochrome' => 'Monocromo',
+        'Neutral' => 'Neutro',
+        'None' => 'Ninguno',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'PictureType' => {
+      Description => 'Tipo ImÃ¡gen',
+      PrintConv => {
+        '32x32 PNG Icon' => 'Icono PNG 32x32',
+        'Artist' => 'Artista',
+        'Back Cover' => 'Cubierta Posterior',
+        'Composer' => 'Compositor',
+        'Conductor' => 'Director',
+        'Front Cover' => 'Cubierta Frontal',
+        'Illustration' => 'IlustraciÃ³n',
+        'Lyricist' => 'Letrista',
+        'Media' => 'Soporte',
+        'Other' => 'Otro',
+        'Other Icon' => 'Otro Icono',
+        'Performance' => 'InterpretaciÃ³n',
+        'Recording Session' => 'SesiÃ³n GrabaciÃ³n',
+      },
+    },
+   'PictureWizardMode' => {
+      PrintConv => {
+        'Cool' => 'FrÃ­o',
+        'Landscape' => 'Paisaje',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
    'PixelFormat' => 'Formato Pixel',
    'PixelIntensityRange' => 'Intervalo Intensidad Pixel',
@@ -1104,4 +2848,14 @@
    'PreviewApplicationName' => 'Nombre AplicaciÃ³n Previa',
    'PreviewApplicationVersion' => 'VersiÃ³n AplicaciÃ³n Previa',
+   'PreviewButton' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'PreviewButtonPlusDials' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'PreviewColorSpace' => {
       Description => 'Espacio Color Previa',
@@ -1111,5 +2865,5 @@
     },
    'PreviewDateTime' => 'Fecha y Hora Previa',
-   'PreviewImage' => 'Previo',
+   'PreviewImage' => 'Vista Previa',
    'PreviewImageLength' => 'Longitud Imagen Previa',
    'PreviewImageSize' => 'TamaÃ±o Imagen Previa',
@@ -1122,7 +2876,9 @@
    'PreviewSettingsDigest' => 'Cifrado ConfiguraciÃ³n Previa',
    'PreviewSettingsName' => 'Nombre ConfiguraciÃ³n Previa',
+   'PrimaryAFPoint' => 'Punto AF primario',
    'PrimaryChromaticities' => 'Cromaticidades de Colores Primarios',
    'PrimaryPlatform' => 'Plataforma Primaria',
    'ProcessingSoftware' => 'Tratamiendo de Software',
+   'Producer' => 'Productor',
    'ProductID' => 'ID Producto',
    'ProfileCMMType' => 'Tipo Perfil CMM',
@@ -1142,5 +2898,5 @@
     },
    'ProfileConnectionSpace' => 'Espacio ConexiÃ³n Perfil',
-   'ProfileCopyright' => 'Copyright Perfil',
+   'ProfileCopyright' => 'Copyright',
    'ProfileCreator' => 'Creador Perfil',
    'ProfileDateTime' => 'Fecha y Hora Perfil',
@@ -1167,6 +2923,24 @@
    'ProfileToneCurve' => 'Perfil Curva Tono',
    'ProfileVersion' => 'VersiÃ³n Perfil',
+   'ProgramMode' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+        'Portrait' => 'Retrato',
+      },
+    },
    'ProgramVersion' => 'VersiÃ³n Programa',
+   'Projects' => 'Proyectos',
+   'PromotionURL' => 'URL Promocional',
+   'PropertyReleaseStatus' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'Protect' => 'ProtecciÃ³n',
+   'ProtectionType' => 'Tipo ProtecciÃ³n',
+   'Provider' => 'Proveedor',
+   'ProviderCopyright' => 'Copyright Proveedor',
    'Province-State' => 'Provincia/Estado',
+   'Publisher' => 'Editor',
    'Quality' => {
       Description => 'Calidad',
@@ -1176,8 +2950,10 @@
         'Extra Fine' => 'Extrafina',
         'Fine' => 'Fina',
-        'Low' => 'Calidad baja',
+        'High' => 'Alto',
+        'Low' => 'Bajo',
         'Normal' => 'Calidad estÃ¡ndar',
         'RAW + JPEG' => 'RAW+JPEG',
         'Standard' => 'EstÃ¡ndar',
+        'n/a' => 'no aplica',
       },
     },
@@ -1202,10 +2978,68 @@
       },
     },
+   'RadioStationName' => 'Nombre Emisora Radio',
+   'RadioStationOwner' => 'Propietario Emisora Radio',
    'RasterPadding' => 'Relleno Trama',
    'RasterizedCaption' => 'TÃ­tulo Rasterizado',
-   'Rating' => 'ClasificaciÃ³n',
+   'Rating' => {
+      Description => 'ClasificaciÃ³n',
+      PrintConv => {
+        'none' => 'Ninguno',
+      },
+    },
    'RatingPercent' => 'ValoraciÃ³n en Porcentaje',
+   'RawCustomSaturation' => 'Raw SaturaciÃ³n personalizada',
    'RawDataUniqueID' => 'ID Ãnico Dato Raw',
+   'RawDevAutoGradation' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'RawDevNoiseReduction' => {
+      PrintConv => {
+        'Noise Filter' => 'Filtro ruido',
+        'Noise Filter (ISO Boost)' => 'Filtro ruido (ISO Boost)',
+        'Noise Reduction' => 'ReducciÃ³n ruido',
+      },
+    },
+   'RawDevPMPictureTone' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Neutral' => 'Neutro',
+      },
+    },
+   'RawDevPM_BWFilter' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Neutral' => 'Neutro',
+        'Orange' => 'Naranja',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'RawDevPictureMode' => {
+      PrintConv => {
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'RawDevSettings' => {
+      PrintConv => {
+        'Noise Reduction' => 'ReducciÃ³n ruido',
+      },
+    },
    'RawImageDigest' => 'Cifrado Imagen RAW',
+   'RawJpgSize' => {
+      PrintConv => {
+        'Medium' => 'Medio',
+        'Medium 1' => 'Medio 1 ',
+        'Medium 2' => 'Medio 2',
+        'Medium 3' => 'Medio 3',
+        'Postcard' => 'Tarjeta Postal',
+        'Small 1' => 'PequeÃ±o 1',
+        'Small 2' => 'PequeÃ±o 21',
+        'Small 3' => 'PequeÃ±o 3',
+      },
+    },
    'RecordMode' => 'Modo de GrabaciÃ³n',
    'RecordShutterRelease' => {
@@ -1214,4 +3048,22 @@
         'Press start, press stop' => 'Pulsa para iniciar, pulsa para parar',
         'Record while down' => 'Grabar mientras se pulsa',
+      },
+    },
+   'RecordedTrackNumber' => 'NÃºmero Pista grabada',
+   'RecordingMode' => {
+      PrintConv => {
+        'Panorama' => 'Panoramica',
+        'Portrait' => 'Retrato',
+      },
+    },
+   'RedEyeCorrection' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'RedEyeReduction' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
       },
     },
@@ -1243,4 +3095,16 @@
       },
     },
+   'RenditionOfMaskMarkers' => {
+      PrintConv => {
+        'All' => 'Todo',
+        'None' => 'Ninguno',
+      },
+    },
+   'ResampleParamsQuality' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
    'Resaved' => {
       Description => 'Regrabado',
@@ -1249,22 +3113,30 @@
       },
     },
+   'Reserved1' => 'Reservado 1',
+   'Resolution' => 'ResoluciÃ³n',
    'ResolutionMode' => 'Modo ResoluciÃ³n',
    'ResolutionUnit' => {
       Description => 'Unidad de ResoluciÃ³n de X e Y',
       PrintConv => {
-        'None' => 'Ninguna',
+        'None' => 'Ninguno',
         'cm' => 'PÃ­xeles/cm',
         'inches' => 'Pulgada',
       },
     },
+   'RetouchHistory' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'RevisionNumber' => 'NÃºmero RevisiÃ³n',
    'Rotation' => {
-      PrintConv => {
-        'Rotate 180' => 'Rotar 180Â°',
-        'Rotate 270 CW' => 'Rotar 270Â° sentido reloj',
-        'Rotate 90 CW' => 'Rotar 90Â° sentido reloj',
-        'Rotated 180' => 'Rotar 180Â°',
-        'Rotated 270 CW' => 'Rotar 270Â° sentido reloj',
-        'Rotated 90 CW' => 'Rotar 90Â° sentido reloj',
+      Description => 'RotaciÃ³n',
+      PrintConv => {
+        'Rotate 180' => 'Girado 180Â°',
+        'Rotate 270 CW' => 'Girado 270Â° sentido reloj',
+        'Rotate 90 CW' => 'Girado 90Â° sentido reloj',
+        'Rotated 180' => 'Girado 180Â°',
+        'Rotated 270 CW' => 'Girado 270Â° sentido reloj',
+        'Rotated 90 CW' => 'Girado 90Â° sentido reloj',
       },
     },
@@ -1273,4 +3145,9 @@
    'SMaxSampleValue' => 'Valor Muestra Max S',
    'SMinSampleValue' => 'Valor Muestra Min S',
+   'SRAWQuality' => {
+      PrintConv => {
+        'n/a' => 'No Aplica',
+      },
+    },
    'SRActive' => {
       PrintConv => {
@@ -1279,4 +3156,6 @@
     },
    'SampleFormat' => 'Formato Muestra',
+   'SampleRate' => 'Frecuencia muestreo',
+   'SampleSize' => 'TamaÃ±o muestra',
    'SampleStructure' => {
       Description => 'Estructura Muestreo',
@@ -1321,8 +3200,16 @@
       Description => 'SaturaciÃ³n',
       PrintConv => {
-        'High' => 'Alta',
-        'Low' => 'Baja',
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'None' => 'Ninguno',
         'None (B&W)' => 'Ninguna (N&B)',
         'Normal' => 'EstÃ¡ndar',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'ScanImageEnhancer' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
       },
     },
@@ -1347,5 +3234,5 @@
         'Night' => 'Escena nocturna',
         'Portrait' => 'Retrato',
-        'Standard' => 'Estandar',
+        'Standard' => 'EstÃ¡ndar',
       },
     },
@@ -1355,15 +3242,34 @@
         '3D Sweep Panorama' => '3D',
         'Anti Motion Blur' => 'Anti movimiento',
+        'Beach' => 'Playa',
         'Cont. Priority AE' => 'AE prioridad cont.',
+        'Fireworks' => 'Fuegos Artificiales',
+        'Food' => 'Comida',
         'Handheld Night Shot' => 'Toma noct. manual',
+        'Indoor' => 'Interior',
         'Landscape' => 'Paisaje',
         'Night Portrait' => 'Retrato noct.',
         'Night Scene' => 'Vista nocturna',
         'Night View/Portrait' => 'Vista/retrato nocturno',
+        'Off' => 'Desactivado',
+        'Panorama' => 'Panoramica',
         'Portrait' => 'Retrato',
+        'Snow' => 'Nieve',
         'Sports' => 'AcciÃ³n deportiva',
-        'Standard' => '',
+        'Standard' => 'EstÃ¡ndar',
         'Sunset' => 'Puesta sol',
         'Sweep Panorama' => 'Barrido panorÃ¡mico',
+        'Underwater' => 'Subacuatica',
+        'Vivid' => 'VÃ­vido',
+      },
+    },
+   'SceneModeUsed' => {
+      PrintConv => {
+        'Beach' => 'Playa',
+        'Fireworks' => 'Fuegos Artificiales',
+        'Landscape' => 'Paisaje',
+        'Panorama' => 'Panoramica',
+        'Portrait' => 'Retrato',
+        'Snow' => 'Nieve',
       },
     },
@@ -1385,4 +3291,9 @@
       },
     },
+   'Security' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'SecurityClassification' => {
       Description => 'ClasificaciÃ³n Seguridad',
@@ -1395,4 +3306,5 @@
       },
     },
+   'SelectableAFPoint' => 'Punto AF seleccionable',
    'SelfTimer' => {
       Description => 'Temporizador AutomÃ¡tico',
@@ -1417,4 +3329,9 @@
       },
     },
+   'SensitivityType' => {
+      PrintConv => {
+        'Unknown' => 'Desconocido',
+      },
+    },
    'SequenceShotInterval' => {
       Description => 'Intervalo Disparo Secuencial',
@@ -1432,5 +3349,5 @@
         'Best' => 'Mejor',
         'None' => 'Ninguno',
-        'Standard' => 'Estandar',
+        'Standard' => 'EstÃ¡ndar',
       },
     },
@@ -1438,6 +3355,24 @@
    'ServiceIdentifier' => 'Identificador Servicio',
    'ShadingCompensation' => 'CompensaciÃ³n de Sombreado',
-   'Shadow' => 'Sombra',
-   'ShadowScale' => 'Escala Sombra',
+   'ShadingCompensation2' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'Shadow' => 'SombrÃ­o',
+   'ShadowScale' => 'Escala SombrÃ­o',
+   'ShakeReduction' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'Sharpening' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
    'Sharpness' => {
       Description => 'Nitidez',
@@ -1449,6 +3384,34 @@
       },
     },
-   'ShootingMode' => 'Modo de Disparo',
+   'SharpnessFrequency' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Highest' => 'Muy Alto',
+        'Low' => 'Bajo',
+        'Lowest' => 'Mas bajo',
+        'Standard' => 'EstÃ¡ndar',
+        'n/a' => 'No Aplica',
+      },
+    },
+   'ShootingMode' => {
+      Description => 'Modo de Disparo',
+      PrintConv => {
+        'Beach' => 'Playa',
+        'Fireworks' => 'Fuegos Artificiales',
+        'Food' => 'Comida',
+        'Portrait' => 'Retrato',
+        'Snow' => 'Nieve',
+        'Underwater' => 'Subacuatica',
+      },
+    },
    'ShortDocumentID' => 'ID Corta del Documento',
+   'Shutter-AELock' => 'Disparador Bloqueo AE',
+   'ShutterCount' => 'Contador de disparos',
+   'ShutterReleaseButtonAE-L' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'ShutterReleaseNoCFCard' => {
       PrintConv => {
@@ -1456,7 +3419,14 @@
       },
     },
-   'ShutterSpeed' => 'Hora ExposiciÃ³n',
+   'ShutterSpeed' => 'Tiempo de ExposiciÃ³n',
    'ShutterSpeedValue' => 'Velocidad ObturaciÃ³n',
+   'Signature_Name' => 'Firma',
    'SimilarityIndex' => 'Ãndice de Similitudes',
+   'SingleFrameBracketing' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
    'Site' => 'Sitio',
    'SlideShow' => {
@@ -1465,12 +3435,61 @@
       },
     },
+   'SlowShutter' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'SoftSkinEffect' => {
+      PrintConv => {
+        'Low' => 'Bajo',
+      },
+    },
    'Software' => 'Programa Utilizado',
    'SoftwareVersion' => 'VersiÃ³n Software',
+   'SonyImageSize' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'SonyQuality' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
    'Source' => 'Fuente',
    'SpatialFrequencyResponse' => 'Respuesta Frecuencia Espacial',
+   'SpecialEffectsOpticalFilter' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'SpecialInstructions' => 'Instrucciones',
    'SpecialMode' => 'Modo Especial',
    'SpectralSensitivity' => 'Sensibilidad Espectral',
+   'Speed' => {
+      PrintConv => {
+        'Fast' => 'RÃ¡pido',
+      },
+    },
+   'SpotMeteringMode' => {
+      PrintConv => {
+        'AF Point' => 'Punto AF',
+        'Center' => 'Centro',
+      },
+    },
    'State' => 'Estado',
+   'StreamColor' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
+   'StreamType' => {
+      PrintConv => {
+        'Binary' => 'Binario',
+        'File Transfer' => 'Transferencia Archivo',
+      },
+    },
    'StripByteCounts' => 'Bytes por Tira Comprimida',
    'StripOffsets' => 'LocalizaciÃ³n Datos Imagen',
@@ -1481,4 +3500,9 @@
    'SubTileBlockSize' => 'TamaÃ±o Bloque Submosaico',
    'SubfileType' => 'Nuevo Tipo Subarchivo',
+   'SubimageColor' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
    'Subject' => 'Sujeto',
    'SubjectArea' => 'Zona Sujeto',
@@ -1493,5 +3517,24 @@
     },
    'SubjectLocation' => 'LocalizaciÃ³n Sujeto',
+   'SubjectProgram' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+        'Portrait' => 'Retrato',
+      },
+    },
    'SubjectReference' => 'CÃ³digo Sujeto',
+   'Subsystem' => {
+      PrintConv => {
+        'Unknown' => 'Desconocido',
+      },
+    },
+   'Subtitle' => 'Subtitulo',
+   'SubtitleDescription' => 'DescripciÃ³n Subtitulo',
+   'SuperimposedDisplay' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'SupplementalCategories' => 'CategorÃ­a Suplementaria',
    'SupplementalType' => {
@@ -1503,7 +3546,18 @@
       },
     },
+   'SweepPanoramaSize' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'SwitchToRegisteredAFPoint' => 'ConmutaciÃ³n de Punto AF registrado',
+   'SynchronizedLyricsType' => {
+      PrintConv => {
+        'Other' => 'Otro',
+      },
+    },
    'T4Options' => 'Opciones T4',
    'T6Options' => 'Opciones T6',
-   'TIFF-EPStandardID' => 'ID Estandar TIFF/EP',
+   'TIFF-EPStandardID' => 'ID EstÃ¡ndar TIFF/EP',
    'Tagged' => {
       PrintConv => {
@@ -1538,5 +3592,15 @@
       },
     },
+   'Teleconverter' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'Text' => 'Texto',
+   'TextStamp' => {
+      PrintConv => {
+        'On' => 'Activado',
+      },
+    },
    'Thresholding' => 'Umbral',
    'ThumbnailImage' => 'Miniatura',
@@ -1548,7 +3612,25 @@
    'TileWidth' => 'Ancho Elemento',
    'TimeCreated' => 'Hora CreaciÃ³n',
+   'TimeScaleParamsQuality' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+      },
+    },
    'TimeSent' => 'Hora EnvÃ­o',
+   'TimeSignature' => {
+      PrintConv => {
+        'other' => 'Otro',
+      },
+    },
+   'TimeStamp' => 'Marca de Tiempo',
+   'TimeStamp1' => 'Marca de Tiempo 1',
    'TimeZoneOffset' => 'Offset Zona Horaria',
    'Title' => 'TÃ­tulo',
+   'ToneCurve' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
    'ToneCurveActive' => {
       PrintConv => {
@@ -1556,4 +3638,56 @@
       },
     },
+   'ToningEffect' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'ToningEffectMonochrome' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+      },
+    },
+   'ToningEffectUnknown' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+      },
+    },
+   'ToningEffectUserDef1' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+      },
+    },
+   'ToningEffectUserDef2' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+      },
+    },
+   'ToningEffectUserDef3' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Ninguno',
+      },
+    },
+   'ToolName' => 'Nombre Herramienta',
+   'ToolVersion' => 'VersiÃ³n Herramienta',
+   'TotalFrames' => 'Total Imagenes',
+   'Track' => 'Pista',
+   'TrackCreateDate' => 'Fecha creaciÃ³n Track',
+   'TrackDefault' => 'Pista Defecto',
+   'TrackForced' => 'Pista Forzada',
+   'TrackHeaderVersion' => 'VersiÃ³n cabecera Pista',
+   'TrackID' => 'ID Pista',
+   'TrackName' => 'Nombre Pista',
+   'TrackNumber' => 'NÃºmero Pista',
+   'TrackType' => 'Tipo Pista',
+   'TrackUsed' => 'Pista utilizada',
+   'Tracks' => 'Pistas',
    'TransferFunction' => 'FunciÃ³n Transferencia',
    'TransferRange' => 'Intervalo Transferencia',
@@ -1565,7 +3699,7 @@
         'Mirror horizontal and rotate 90 CW' => 'Invertir horizontal y rotar 90Â° sentido reloj',
         'Mirror vertical' => 'Invertir vertical',
-        'Rotate 180' => 'Rotar 180Â°',
-        'Rotate 270 CW' => 'Rotar 270Â° sentido reloj',
-        'Rotate 90 CW' => 'Rotar 90Â° sentido reloj',
+        'Rotate 180' => 'Girado 180Â°',
+        'Rotate 270 CW' => 'Girado 270Â° sentido reloj',
+        'Rotate 90 CW' => 'Girado 90Â° sentido reloj',
       },
     },
@@ -1580,8 +3714,44 @@
       },
     },
+   'UncompressedSize' => 'TamaÃ±o Descomprimido',
    'UniqueCameraModel' => 'Modelo CÃ¡mara Unico',
    'UniqueDocumentID' => 'ID de Documento Ãnica',
+   'UniqueFileIdentifier' => 'Identificador Unico Archivo',
    'UniqueObjectName' => 'Nombre Ãnico de Objeto',
    'Unknown' => 'Desconocido',
+   'Unsharp1Color' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'Unsharp2Color' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'Unsharp3Color' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'Unsharp4Color' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Red' => 'Rojo',
+        'Yellow' => 'Amarillo',
+      },
+    },
+   'UnsharpMask' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'Urgency' => {
       Description => 'Urgencia',
@@ -1595,6 +3765,89 @@
     },
    'UserComment' => 'Comentarios Usuario',
+   'UserDef1PictureStyle' => {
+      PrintConv => {
+        'Landscape' => 'Paisaje',
+        'Monochrome' => 'Monocromo',
+        'Neutral' => 'Neutro',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'UserDef2PictureStyle' => {
+      PrintConv => {
+        'Landscape' => 'Paisaje',
+        'Monochrome' => 'Monocromo',
+        'Neutral' => 'Neutro',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'UserDef3PictureStyle' => {
+      PrintConv => {
+        'Landscape' => 'Paisaje',
+        'Monochrome' => 'Monocromo',
+        'Neutral' => 'Neutro',
+        'Portrait' => 'Retrato',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'VR_0x66' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
+   'ValidAFPoints' => 'Puntos AF validos',
    'Version' => 'VersiÃ³n PrintIM',
+   'VersionYear' => 'AÃ±o versiÃ³n',
+   'VibrationReduction' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'VideoAlphaMode' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
    'VideoCardGamma' => 'Tarjeta Video Gamma',
+   'VideoCompressor' => 'Video Compresor',
+   'VideoFieldOrder' => {
+      PrintConv => {
+        'Lower' => 'Inferior',
+        'Progressive' => 'Progresivo',
+        'Upper' => 'Superior',
+      },
+    },
+   'VideoHeight' => 'Altura Video',
+   'VideoPixelDepth' => {
+      PrintConv => {
+        '16-bit integer' => 'Entero 16-bits',
+        '24-bit integer' => 'Entero 24-bits',
+        '32-bit float' => 'Flotante 32-bits',
+        '32-bit integer' => 'Entero 32-bits',
+        '8-bit integer' => 'Entero 8-bits',
+        'Other' => 'Otro',
+      },
+    },
+   'VideoQuality' => {
+      PrintConv => {
+        'Low' => 'Bajo',
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'VideoWidth' => 'Ancho Video',
+   'ViewCompressionFactor' => 'Ver Factor de compresiÃ³n',
+   'ViewfinderWarning' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'ViewfinderWarnings' => {
+      PrintConv => {
+        'Monochrome' => 'Monocromo',
+      },
+    },
    'ViewingCondDesc' => 'DescripciÃ³n en Condiciones de VisiÃ³n',
    'ViewingCondIlluminant' => 'IluminaciÃ³n en Condiciones de VisiÃ³n',
@@ -1602,4 +3855,12 @@
    'ViewingCondSurround' => 'Entorno en Condiciones de VisiÃ³n',
    'ViewingConditions' => 'IluminaciÃ³n en Condiciones de VisiÃ³n',
+   'VignetteControl' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
    'VoiceMemo' => {
       Description => 'Notas Voz',
@@ -1609,4 +3870,14 @@
       },
     },
+   'WBAdjLighting' => {
+      PrintConv => {
+        'None' => 'Ninguno',
+      },
+    },
+   'WBBracketMode' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+      },
+    },
    'WBFineTuneActive' => {
       PrintConv => {
@@ -1616,26 +3887,40 @@
    'WCSProfiles' => 'Perfil Sistema Color Windows',
    'WhiteBalance' => {
-      Description => 'Equilibrio Blanco',
+      Description => 'Balance de Blancos',
       PrintConv => {
         'Auto' => 'AutomÃ¡tico',
         'Black & White' => 'Monocromo',
-        'Cloudy' => 'Nuboso',
+        'Cloudy' => 'Nublado',
         'Color Temperature/Color Filter' => 'Temperatura de color / Filtro de color',
         'Cool White Fluorescent' => 'Fluorescente blanco frÃ­o',
         'Custom' => 'Personalizado',
-        'Custom 1' => 'PERSONAL.1',
-        'Custom 2' => 'PERSONAL.2',
-        'Custom 3' => 'PERSONAL.3',
-        'Custom 4' => 'PERSONAL.4',
+        'Custom 1' => 'Personalizado 1',
+        'Custom 2' => 'Personalizado 2',
+        'Custom 3' => 'Personalizado 3',
+        'Custom 4' => 'Personalizado 4',
         'Day White Fluorescent' => 'Fluorescente blanco de dÃ­a',
         'Daylight' => 'Luz de dÃ­a',
-        'Daylight Fluorescent' => 'Fluorescente de luz del dÃ­a',
+        'Daylight Fluorescent' => 'Fluorescente luz de dÃ­a',
         'Fluorescent' => 'Flourescente',
         'Manual' => 'Equilibrio del blanco manual',
-        'Shade' => 'Sombra',
+        'Manual Temperature (Kelvin)' => 'Temperatura Manual (Kelvin)',
+        'Shade' => 'SombrÃ­o',
         'Tungsten' => 'Tungsteno',
+        'Underwater' => 'Subacuatica',
         'Unknown' => 'Desconocido',
         'Warm White Fluorescent' => 'Fluorescente blanco cÃ¡lido',
         'White Fluorescent' => 'Fluorescente blanco',
+      },
+    },
+   'WhiteBalanceAdj' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'WhiteBalanceBracketing' => {
+      PrintConv => {
+        'High' => 'Alto',
+        'Low' => 'Bajo',
       },
     },
@@ -1650,4 +3935,5 @@
     },
    'WidthResolution' => 'ResoluciÃ³n Imagen Horizontal',
+   'Writer' => 'Escritor',
    'Writer-Editor' => 'TÃ­tulo/DescripciÃ³n Escritor',
    'X3FillLight' => 'Luz Relleno X3',
@@ -1668,12 +3954,38 @@
    'YPosition' => 'PosiciÃ³n Y',
    'YResolution' => 'ResoluciÃ³n Imagen Vertical',
+   'Year' => 'AÃ±o',
+   'YearCreated' => 'AÃ±o CreaciÃ³n',
+   'ZipCompressedSize' => 'Zip TamaÃ±o Comprimido',
+   'ZipCompression' => {
+      Description => 'CompresiÃ³n Zip',
+      PrintConv => {
+        'None' => 'Ninguno',
+        'Reduced with compression factor 1' => 'Reducido con factor de compresiÃ³n 1',
+        'Reduced with compression factor 2' => 'Reducido con factor de compresiÃ³n 2',
+        'Reduced with compression factor 3' => 'Reducido con factor de compresiÃ³n 3',
+        'Reduced with compression factor 4' => 'Reducido con factor de compresiÃ³n 4',
+      },
+    },
+   'ZipUncompressedSize' => 'Zip TamaÃ±o Descomprimido',
    'ZoneMatching' => {
       Description => 'Zone matching',
       PrintConv => {
-        'High Key' => 'Hi',
+        'High Key' => 'Alto',
         'ISO Setting Used' => 'Desactivado',
-        'Low Key' => 'Lo',
-      },
-    },
+        'Low Key' => 'Bajo',
+      },
+    },
+   'ZoneMatchingMode' => {
+      PrintConv => {
+        'Standard' => 'EstÃ¡ndar',
+      },
+    },
+   'ZoneMatchingOn' => {
+      PrintConv => {
+        'Off' => 'Desactivado',
+        'On' => 'Activado',
+      },
+    },
+   'ZoomPos' => 'PosiciÃ³n Zoom',
 );
 
@@ -1694,5 +4006,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -1701,6 +4013,6 @@
 =head1 ACKNOWLEDGEMENTS
 
-Thanks to Jens Duttke and Santiago del BrE<iacute>o GonzE<aacute>lez for
-providing this translation.
+Thanks to Jens Duttke, Santiago del BrE<iacute>o GonzE<aacute>lez and Emilio
+Sancha for providing this translation.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/fi.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/fi.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/fi.pm	(revision 34921)
@@ -0,0 +1,2896 @@
+#------------------------------------------------------------------------------
+# File:         fi.pm
+#
+# Description:  ExifTool Finnish language translations
+#
+# Notes:        This file generated automatically by Image::ExifTool::TagInfoXML
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Lang::fi;
+
+use strict;
+use vars qw($VERSION);
+
+$VERSION = '1.04';
+
+%Image::ExifTool::Lang::fi::Translate = (
+   'AEAperture' => 'AE-aukko',
+   'AEBBracketValue' => 'AEB-haarukointiarvo',
+   'AEBXv' => 'AEB-valotuksen korjaus',
+   'AEExposureTime' => 'AE-valotusaika',
+   'AEInfo' => 'Automaattivalotustiedot',
+   'AELock' => {
+      Description => 'AE-lukitus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'AELockButton' => 'AE-lukituspainike',
+   'AEMeteringMode' => 'AE-valotuksen mittaustapa',
+   'AEMeteringSegments' => 'AE-mittaussegmentit',
+   'AEProgramMode' => 'AE-ohjelmatapa',
+   'AESetting' => 'AE-asetus',
+   'AEXv' => 'AE-valotuksen korjaus',
+   'AF-CPrioritySelection' => 'AF-C -esivalinnat',
+   'AF-OnForMB-D10' => 'AF-ON -painike (MB-D10)',
+   'AF-SPrioritySelection' => 'AF-S -esivalinnat',
+   'AFActivation' => 'AF-aktivointi',
+   'AFAdjustment' => 'AF-sÃ€Ã€tÃ¶',
+   'AFAperture' => 'AF-aukko',
+   'AFArea' => 'AF-alue',
+   'AFAreaHeight' => 'AF-alueen korkeus',
+   'AFAreaIllumination' => 'AF-alueen valaisu',
+   'AFAreaMode' => 'AF-aluetarkennus',
+   'AFAreaModeSetting' => 'AF-aluemittaustavan asetus',
+   'AFAreaWidth' => 'AF-alueen leveys',
+   'AFAreas' => 'AF-alueet',
+   'AFAssist' => 'AF-apu',
+   'AFAssistLamp' => {
+      PrintConv => {
+        'Disabled and Not Required' => 'Deaktivoitu eikÃ€ tarpeen',
+        'Disabled but Required' => 'Deaktivoitu mutta tarpeen',
+        'Enabled but Not Used' => 'Aktivoitu muttei kÃ€ytetty',
+        'Fired' => 'Lauennut',
+      },
+    },
+   'AFDefocus' => 'AF-defokus (poikkeama polttopisteestÃ€)',
+   'AFFineTune' => 'AF-hienosÃ€Ã€tÃ¶',
+   'AFImageHeight' => 'AF-kuvan korkeus',
+   'AFImageWidth' => 'AF-kuvan leveys',
+   'AFInfo' => 'Automaattitarkennustiedot',
+   'AFInfo2' => 'AF-tiedot',
+   'AFInfo2Version' => 'AF-tietojen versio',
+   'AFIntegrationTime' => 'AF-integrointiaika',
+   'AFMode' => 'AF-muoto',
+   'AFPoint' => {
+      Description => 'AF-piste',
+      PrintConv => {
+        'Bottom Center' => 'Alhaalla keskellÃ€',
+        'Bottom Left' => 'Alavasemmalla',
+        'Bottom Right' => 'Alaoikealla',
+        'Center' => 'KeskellÃ€',
+        'Center Left' => 'KeskellÃ€ vasemmalla',
+        'Center Right' => 'KeskellÃ€ oikealla',
+        'Far Left/Right of Center' => 'Kaukana vasemmalla/keskioikealla',
+        'Far Left/Right of Center/Bottom' => 'Kaukana vasemmalla/keskioikealla/alhaalla',
+        'Near Left/Right of Center' => 'Hieman vasemmalla/keskioikealla',
+        'Near Upper/Left' => 'Hieman ylhÃ€Ã€llÃ€/vasemmalla',
+        'Top Center' => 'YlhÃ€Ã€llÃ€ keskellÃ€',
+        'Top Left' => 'YlÃ€vasemmalla',
+        'Top Near-left' => 'Hieman ylÃ€vasemmalla',
+        'Top Near-right' => 'Hieman ylÃ€oikealla',
+        'Top Right' => 'YlÃ€oikealla',
+        'Upper Left' => 'YlÃ€vasemmalla',
+        'Upper Right' => 'YlÃ€oikealla',
+      },
+    },
+   'AFPointIllumination' => 'AF -pistevalaisu',
+   'AFPointMode' => 'AF-pistetapa',
+   'AFPointSelected' => {
+      Description => 'Valittu AF-piste',
+      PrintConv => {
+        'Auto' => 'Automaattinen',
+        'Automatic Tracking AF' => 'Automaattiseuranta-AF',
+        'Bottom' => 'Alas',
+        'Center' => 'Keskelle',
+        'Face Detect AF' => 'Kasvojentunnistus-AF',
+        'Fixed Center' => 'KiinteÃ€sti keskustaan',
+        'Left' => 'Vasemmalle',
+        'Lower-left' => 'Alavasemmalle',
+        'Lower-right' => 'Alaoikealle',
+        'Mid-left' => 'Keskivasemmalle',
+        'Mid-right' => 'Keskioikealle',
+        'Right' => 'Oikealle',
+        'Top' => 'YlÃ¶s',
+        'Upper-left' => 'YlÃ€vasemmalle',
+        'Upper-right' => 'YlÃ€oikealle',
+      },
+    },
+   'AFPointSelected2' => 'Valittu AF-piste 2',
+   'AFPointSelection' => 'AF-pistevalinnat',
+   'AFPoints' => 'AF-pisteet',
+   'AFPointsInFocus' => {
+      Description => 'Tarkennuksen AF-pisteet',
+      PrintConv => {
+        'Bottom-center' => 'Alakeski',
+        'Bottom-left' => 'Alavasen',
+        'Bottom-right' => 'Alaoikea',
+        'Center' => 'Keski',
+        'Fixed Center or Multiple' => 'KiinteÃ€sti keskellÃ€ tai useita',
+        'Left' => 'Vasen',
+        'None' => 'Ei yhtÃ€Ã€n',
+        'Right' => 'Oikea',
+        'Top-center' => 'YlÃ€keski',
+        'Top-left' => 'YlÃ€oikea',
+        'Top-right' => 'YlÃ€oikea',
+      },
+    },
+   'AFPointsSelected' => 'Valitut AF-pisteet',
+   'AFPointsUsed' => 'KÃ€ytetyt AF-pisteet',
+   'AFPredictor' => 'Ennakoiva AF',
+   'AFResponse' => 'KÃ€ytetty AF',
+   'AFResult' => 'AF-tulos',
+   'AFSearch' => {
+      Description => 'AF-haku',
+      PrintConv => {
+        'Not Ready' => 'Ei valmis',
+        'Ready' => 'Valmis',
+      },
+    },
+   'ARMIdentifier' => 'ARM-tunnistin',
+   'ARMVersion' => 'ARM-versio',
+   'AToB0' => 'A - B0',
+   'AToB1' => 'A - B1',
+   'AToB2' => 'A - B2',
+   'AccessoryType' => 'LisÃ€laitetyyppi',
+   'ActionAdvised' => {
+      Description => 'Suositettava toiminto',
+      PrintConv => {
+        'Object Append' => 'ObjektiliitÃ€ntÃ€',
+        'Object Kill' => 'Objektin tuhonta',
+        'Object Reference' => 'Objektiviite',
+        'Object Replace' => 'Objektin korvaus',
+        'Ojbect Append' => 'ObjektiliitÃ€ntÃ€',
+      },
+    },
+   'ActiveArea' => 'Aktiivialue',
+   'ActiveD-Lighting' => 'Aktiivinen D-Lighting',
+   'ActiveD-LightingMode' => 'Aktivoitu D-Lighting-tapa',
+   'AdjustmentMode' => 'SÃ€Ã€tÃ¶tapa',
+   'AdvancedRaw' => 'Edistynyt RAW',
+   'AdvancedSceneMode' => {
+      Description => 'Edistynyt nÃ€kymÃ€tapa',
+      PrintConv => {
+        'Auto' => 'Automaattinen',
+        'Creative' => 'Luova',
+        'Indoor/Architecture/Objects/HDR B&W' => 'SisÃ€llÃ€/arkkitehtuuri/kohteet',
+        'Normal' => 'Normaali',
+        'Outdoor/Illuminations/Flower/HDR Art' => 'Ulkona/valaistukset/kukka',
+      },
+    },
+   'AlphaByteCount' => 'Alfa-tavujen mÃ€Ã€rÃ€',
+   'AlphaChannelsNames' => 'Alfa-kanavien nimet',
+   'AlphaDataDiscard' => {
+      Description => 'Alfa-data hylÃ€tty',
+      PrintConv => {
+        'Flexbits Discarded' => 'FlexBits hylÃ€tty',
+        'Full Resolution' => 'TÃ€ysi resoluutio',
+        'HighPass Frequency Data Discarded' => 'YlipÃ€Ã€stÃ¶taajuusdata hylÃ€tty',
+        'Highpass and LowPass Frequency Data Discarded' => 'Yli- ja alipÃ€Ã€stÃ¶taajuusdata hylÃ€tty',
+      },
+    },
+   'AlphaOffset' => 'Alfa-siirtymÃ€',
+   'AnalogBalance' => 'Analoginen tasapaino',
+   'AntiAliasStrength' => 'Kameran anti-alias -suotimen suhteellinen vahvuus',
+   'Aperture' => 'Aukko',
+   'ApertureRingUse' => 'Himmenninrenkaan kÃ€yttÃ¶',
+   'ApertureValue' => 'Aukkoarvo',
+   'ApplicationRecordVersion' => 'Sovellustietueen versio',
+   'ArtFilter' => 'Taidesuodin',
+   'Artist' => 'Kuvan luonut henkilÃ¶',
+   'AsShotICCProfile' => 'Kuin kuvatessa -ICC-profiili',
+   'AsShotNeutral' => 'Kuin kuvatessa -neutraali',
+   'AsShotPreProfileMatrix' => 'Kuin kuvatessa -pre-profiilimatriisi',
+   'AsShotProfileName' => 'Kuin kuvatessa -profiilin nimi',
+   'AsShotWhiteXY' => 'Kuin kuvatessa -valkoinen X-Y',
+   'Audio' => {
+      Description => 'ÃÃ€ni',
+      PrintConv => {
+        'No' => 'Ei',
+        'Yes' => 'KyllÃ€',
+      },
+    },
+   'AudioDuration' => 'Audion kesto',
+   'AudioOutcue' => 'Audion lopetus',
+   'AudioSamplingRate' => 'Audion nÃ€ytetaajuus',
+   'AudioSamplingResolution' => 'Audion nÃ€yteresoluutio',
+   'AudioType' => {
+      Description => 'Audiotyyppi',
+      PrintConv => {
+        'Mono Actuality' => 'Aktuaalisuus (monoaudio (1 kanava))',
+        'Mono Music' => 'Musiikki, itsensÃ€ vÃ€littÃ€mÃ€ (monoaudio (1 kanava))',
+        'Mono Question and Answer Session' => 'Kysymys- ja vastausistunto (monoaudio (1 kanava))',
+        'Mono Raw Sound' => 'RaakaÃ€Ã€ni (monoaudio (1 kanava))',
+        'Mono Response to a Question' => 'Vastaus kysymykseen (monoaudio (1 kanava))',
+        'Mono Scener' => 'Kohtaus (monoaudio (1 kanava))',
+        'Mono Voicer' => 'IhmisÃ€Ã€ni (monoaudio (1 kanava))',
+        'Mono Wrap' => 'Pakkaus (monoaudio (1 kanava))',
+        'Stereo Actuality' => 'Aktuaalisuus (stereoaudio (2 kanavaa))',
+        'Stereo Music' => 'Musiikki, itsensÃ€ vÃ€littÃ€mÃ€ (stereomono (2 kanavaa))',
+        'Stereo Question and Answer Session' => 'Kysymys- ja vastausistunto (stereoaudio (2 kanavaa))',
+        'Stereo Raw Sound' => 'RaakaÃ€Ã€ni (stereoaudio (2 kanavaa))',
+        'Stereo Response to a Question' => 'Vastaus kysymykseen (stereoaudio (2 kanavaa))',
+        'Stereo Scener' => 'Kohtaus (stereoaudio (2 kanavaa))',
+        'Stereo Voicer' => 'IhmisÃ€Ã€ni (stereoaudio (2 kanavaa))',
+        'Stereo Wrap' => 'Pakkaus (stereoaudio (2 kanavaa))',
+        'Text Only' => 'Vain teksti (ei objektidataa)',
+      },
+    },
+   'Author' => 'TekijÃ€',
+   'AutoAperture' => 'Himmenninrengas A:ssa',
+   'AutoBracket' => 'Automaattihaarukointi',
+   'AutoBracketSet' => 'Haarukointisarja',
+   'AutoBracketing' => {
+      Description => 'Automaattinen haarukointi',
+      PrintConv => {
+        'No flash & flash' => 'Ei salamaa & Salama',
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'AutoBracketingSet' => 'Haarukointisarja',
+   'AutoDistortionControl' => 'Automaattinen vÃ€Ã€ristymÃ€korjaus',
+   'AutoExposureBracketing' => 'Automaattinen valotuksen haarukointi',
+   'AutoFP' => 'Automaattinen FP',
+   'AutoFocus' => {
+      Description => 'Automaattitarkennus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'AutoISO' => {
+      Description => 'Automaatti-ISO',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'AutoRedEye' => 'Automaattinen punasilmien esto',
+   'AutoRotate' => 'Automaattinen kuvankierto',
+   'AuxiliaryLens' => 'LisÃ€linssi',
+   'AvApertureSetting' => 'Av-aukkoasetus',
+   'BToA0' => 'B - A0',
+   'BToA1' => 'B - A1',
+   'BToA2' => 'B - A2',
+   'BWMode' => {
+      Description => 'M/V-muoto',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'BackgroundColor' => 'TaustavÃ€ri',
+   'BackgroundColorIndicator' => 'TaustavÃ€rin ilmaisin',
+   'BackgroundColorValue' => 'TaustavÃ€rin arvo',
+   'BadFaxLines' => 'Huonot faksirivit',
+   'BaseExposureCompensation' => 'Valotuksen perussÃ€Ã€tÃ¶',
+   'BaseISO' => 'Perus-ISO',
+   'BaselineExposure' => 'Valotuksen perusta',
+   'BaselineNoise' => 'Kohinan perusta',
+   'BaselineSharpness' => 'TerÃ€vyyden perusta',
+   'BatteryLevel' => 'Pariston varaus',
+   'BatteryOrder' => 'ParistojÃ€rjestys',
+   'BayerGreenSplit' => 'Bayer Green Split -suodin',
+   'Beep' => 'ÃÃ€nimerkki',
+   'BestQualityScale' => 'Parhaan laadun asteikko',
+   'BestShotMode' => {
+      Description => 'Parhaan kuvan tapa',
+      PrintConv => {
+        'Off' => 'Pois',
+      },
+    },
+   'BitDepth' => 'Bittisyvyys',
+   'BitsPerComponent' => 'BittejÃ€ per komponentti',
+   'BitsPerExtendedRunLength' => 'BittejÃ€ per jatkettu jakson pituus',
+   'BitsPerPixel' => 'BittejÃ€ per pikseli',
+   'BitsPerRunLength' => 'BittejÃ€ per jakson pituus',
+   'BitsPerSample' => 'BittejÃ€ per nÃ€yte',
+   'BlackLevel' => 'Mustan taso',
+   'BlackLevel2' => 'Mustan taso 2',
+   'BlackLevelDeltaH' => 'Mustan tason Delta H',
+   'BlackLevelDeltaV' => 'Mustan tason Delta V',
+   'BlackLevelRepeatDim' => 'Mustan tason toiston dimensio',
+   'BlackMaskBottomBorder' => 'Mustan maskin alareuna',
+   'BlackMaskLeftBorder' => 'Mustan maskin vasen reuna',
+   'BlackMaskRightBorder' => 'Mustan maskin oikea reuna',
+   'BlackMaskTopBorder' => 'Mustan maskin ylÃ€reuna',
+   'BlackPoint' => 'Musta piste',
+   'BlueBalance' => 'Sinitasapaino',
+   'BlueMatrixColumn' => 'Sinisen matriisin sarake',
+   'BlueTRC' => 'Sinisen toonin toistokÃ€yrÃ€',
+   'BlueX' => 'Sininen X',
+   'BlueY' => 'Sininen Y',
+   'BlurWarning' => {
+      Description => 'TÃ€rinÃ€varoitus',
+      PrintConv => {
+        'Blur Warning' => 'TÃ€rinÃ€varoitus',
+        'None' => 'Ei mitÃ€Ã€n',
+      },
+    },
+   'BodyFirmwareVersion' => 'Rungon laiteohjelmistoversio',
+   'BorderID' => 'Kehyksen ID',
+   'BorderLocation' => 'Kehyksen sijainti',
+   'BorderName' => 'Kehyksen nimi',
+   'BorderType' => 'Kehyksen tyyppi',
+   'BordersVersion' => 'Kehysten versio',
+   'BracketMode' => 'Haarukointitapa',
+   'BracketSequence' => 'HaarukointijÃ€rjestys',
+   'BracketShotNumber' => 'Haarukoinnin otosnumero',
+   'BracketStep' => 'HaarukointivÃ€li',
+   'BracketValue' => 'Haarukointiarvo',
+   'Brightness' => 'Kirkkaus',
+   'BrightnessData' => 'Kirkkausdata',
+   'BrightnessValue' => 'Kirkkausarvo',
+   'BulbDuration' => 'Aikavalotuksen kesto',
+   'BurstMode' => {
+      Description => 'Sarjatapa',
+      PrintConv => {
+        'Auto Exposure Bracketing (AEB)' => 'ÃÃ€retÃ¶n',
+        'Infinite' => 'ÃÃ€retÃ¶n',
+        'Off' => 'Pois',
+        'On' => 'Matala/korkea laatu',
+        'Unlimited' => 'Rajaton',
+      },
+    },
+   'By-line' => 'TekijÃ€',
+   'By-lineTitle' => 'TekijÃ€n ammattinimike',
+   'CCDScanMode' => {
+      Description => 'CCD-skannaustapa',
+      PrintConv => {
+        'Interlaced' => 'Lomitettu',
+        'Progressive' => 'Progressiivinen',
+      },
+    },
+   'CFALayout' => {
+      Description => 'CFA-sommitelma',
+      PrintConv => {
+        'Even columns offset down 1/2 row' => 'Horjahtanut sommitelma A: parilliset sarakkeet siirtyneet alas 1/2 riviÃ€',
+        'Even columns offset up 1/2 row' => 'Horjahtanut sommitelma B: parilliset sarakkeet osiirtyneet ylÃ¶s 1/2 riviÃ€',
+        'Even rows offset left 1/2 column' => 'Horjahtanut sommitelma D: parilliset rivit siirtyneet vasemmalle 1/2 saraketta',
+        'Even rows offset right 1/2 column' => 'Horjahtanut sommitelma C: parilliset rivit siirtyneet oikealle 1/2 saraketta',
+        'Rectangular' => 'Suorakulmainen (tai neliÃ¶mÃ€inen) sommitelma',
+      },
+    },
+   'CFAPattern' => 'CFA-kuvio',
+   'CFAPattern2' => 'CFA-kuvio 2',
+   'CFAPlaneColor' => 'CFA-tasovÃ€ri',
+   'CFARepeatPatternDim' => 'Toistuvan CFA-kuvion laajuus',
+   'CLModeShootingSpeed' => 'Hidas jatkuva kuvaus (CL)',
+   'CMContrast' => 'CM:n kontrasti',
+   'CMExposureCompensation' => 'CM:n valotuksen sÃ€Ã€tÃ¶',
+   'CMHue' => 'CM:n sÃ€vy',
+   'CMMFlags' => 'CMM-liput',
+   'CMSaturation' => 'CM:n vÃ€rikyllÃ€isyys',
+   'CMSharpness' => 'CM:n terÃ€vyys',
+   'CMWhiteBalance' => 'CM:n valkotasapaino',
+   'CMWhiteBalanceComp' => 'CM:n valkotasapainon sÃ€Ã€tÃ¶',
+   'CMWhiteBalanceGrayPoint' => 'CM:n valkotasapainon harmaapiste',
+   'CMYKEquivalent' => 'CMYK-vastaava',
+   'CPUFirmwareVersion' => 'CPU-laiteohjelmistoversio',
+   'CalibrationDateTime' => 'Kalibroinnin pÃ€ivÃ€ysaika',
+   'CalibrationIlluminant1' => {
+      Description => 'Valaistuksen kalibrointi 1',
+      PrintConv => {
+        'Unknown' => 'Tuntematon',
+      },
+    },
+   'CalibrationIlluminant2' => {
+      Description => 'Valaistuksen kalibrointi 2',
+      PrintConv => {
+        'Unknown' => 'Tuntematon',
+      },
+    },
+   'CameraCalibration1' => 'Kameran kalibrointi 1',
+   'CameraCalibration2' => 'Kameran kalibrointi 2',
+   'CameraCalibrationSig' => 'Kameran kalibrointitunniste',
+   'CameraID' => 'Kameran ID',
+   'CameraISO' => 'Kamera-ISO',
+   'CameraOwner' => 'Kameran omistaja',
+   'CameraParameters' => 'Kameran parametrit',
+   'CameraSerialNumber' => 'Kameran rungon nro',
+   'CameraSettings' => 'Kameran asetukset',
+   'CameraSettingsVersion' => 'Kamera-asetusten versio',
+   'CameraTemperature' => 'Kameran lÃ€mpÃ¶tila',
+   'CameraType' => 'Kameratyyppi',
+   'CameraType2' => 'Kameratyyppi 2',
+   'CanonAFInfo' => 'AF-info',
+   'CanonAFInfo2' => 'AF-info (2)',
+   'CanonFileInfo' => 'Tiedostoinfo',
+   'CanonFileLength' => 'Tiedoston pituus',
+   'CanonFirmwareVersion' => 'Laiteohjelmiston versio',
+   'CanonFlags' => 'Canon-liput',
+   'CanonImageType' => 'Kuvatyyppi',
+   'CanonModelID' => 'Mallin ID',
+   'Caption-Abstract' => 'Seloste/Kuvaus',
+   'CaptureConditionsPAR' => 'PAR-kuvausolosuhteet',
+   'CaptureDeviceFID' => 'Kuvauslaitteen FID',
+   'CasioImageSize' => 'Casion kuvakoko',
+   'Category' => 'Kategoria',
+   'CellLength' => 'Kennon pituus',
+   'CellWidth' => 'Kennon leveys',
+   'CenterAFArea' => 'Keskialueen AF',
+   'CharTarget' => 'Kirjainmerkin kohde',
+   'CharacterSet' => 'MerkistÃ¶',
+   'ChromaBlurRadius' => 'Kromaattisen sumeuden sÃ€de',
+   'ChromaticAdaptation' => 'Kromaattinen adaptaatio',
+   'Chromaticity' => 'Kromaattisuus',
+   'City' => 'Kaupunki',
+   'ClassifyState' => 'Luokitustila',
+   'CleanFaxData' => 'Poista faksidata',
+   'ClipPath' => 'Leikepolku',
+   'CodedCharacterSet' => 'Koodattu merkistÃ¶',
+   'ColorAberrationControl' => 'VÃ€ripoikkeaman hallinta',
+   'ColorAdjustment' => 'VÃ€rien sÃ€Ã€tÃ¶',
+   'ColorAdjustmentMode' => {
+      Description => 'VÃ€rin sÃ€Ã€tÃ¶tapa',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'ColorBalance' => 'VÃ€ritasapaino',
+   'ColorBalanceAdj' => 'VÃ€ritasapainon sÃ€Ã€tÃ¶',
+   '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',
+   'ColorBooster' => 'VÃ€ritehostus',
+   'ColorCalibrationMatrix' => 'VÃ€rien kalibrointimatriisitaulukko',
+   'ColorCharacterization' => 'VÃ€rin luonnehdinta',
+   'ColorCompensationFilter' => 'VÃ€rikorjailusuodin',
+   'ColorControl' => 'VÃ€risÃ€Ã€tÃ¶',
+   'ColorEffect' => {
+      Description => 'VÃ€riefekti',
+      PrintConv => {
+        'Black & White' => 'Musta & Valkoinen',
+        'Cool' => 'ViileÃ€',
+        'Off' => 'Pois',
+        'Sepia' => 'Seepia',
+        'Warm' => 'LÃ€mmin',
+      },
+    },
+   'ColorFilter' => {
+      Description => 'VÃ€risuodin',
+      PrintConv => {
+        'Off' => 'Pois',
+      },
+    },
+   'ColorGain' => 'VÃ€rien vahvistus',
+   'ColorHue' => 'VÃ€risÃ€vy',
+   'ColorInfo' => 'VÃ€ritiedot',
+   'ColorMap' => 'VÃ€rikartta',
+   'ColorMatrix' => 'VÃ€rimatriisi',
+   'ColorMatrix1' => 'VÃ€rimatriisi 1',
+   'ColorMatrix2' => 'VÃ€rimatriisi 2',
+   'ColorMatrixNumber' => 'VÃ€rimatriisin numero',
+   'ColorMode' => {
+      Description => 'VÃ€rimuoto',
+      PrintConv => {
+        'Autumn Leaves' => 'Syksyn lehdet',
+        'B & W' => 'M & V',
+        'B&W' => 'M&V',
+        'Black & White' => 'HeleÃ€t vÃ€rit',
+        'Chrome' => 'Kellastunut',
+        'Clear' => 'SelkeÃ€',
+        'Deep' => 'SyvÃ€',
+        'Evening' => 'Ilta',
+        'Landscape' => 'Maisema',
+        'Light' => 'Valoisa',
+        'Natural' => 'Luonnollinen',
+        'Natural color' => 'Luonnonvalo',
+        'Natural sRGB' => 'Luonnollinen sRGB',
+        'Natural+ sRGB' => 'Luonnollinen+ sRGB',
+        'Neutral' => 'Neutraali',
+        'Night Portrait' => 'YÃ¶n muotokuva',
+        'Night Scene' => 'YÃ¶nÃ€kymÃ€',
+        'Night View' => 'IltanÃ€kymÃ€',
+        'Night View/Portrait' => 'YÃ¶nÃ€kymÃ€',
+        'Normal' => 'Normaali',
+        'Off' => 'Pois',
+        'Portrait' => 'Muotokuva',
+        'Sepia' => 'Seepia',
+        'Solarization' => 'Solarisaatio',
+        'Standard' => 'Vakio',
+        'Sunset' => 'Auringonlasku',
+        'Vivid' => 'HeleÃ€t vÃ€rit',
+        'Vivid color' => 'HeleÃ€ vÃ€ri',
+      },
+    },
+   'ColorMoireReduction' => 'VÃ€rimoareen vaimennus',
+   'ColorMoireReductionMode' => 'VÃ€rimoareen vaimennustapa',
+   'ColorPalette' => 'VÃ€ripaletti',
+   'ColorProfile' => 'VÃ€riprofiili',
+   'ColorRepresentation' => 'VÃ€riesitys',
+   'ColorReproduction' => 'VÃ€rientoisto',
+   'ColorResponseUnit' => 'VÃ€rin vasteyksikkÃ¶',
+   'ColorSamplersResource' => 'VÃ€rinÃ€ytteenotinresurssit',
+   'ColorSequence' => 'VÃ€rien esitys',
+   'ColorSpace' => {
+      Description => 'VÃ€riavaruus',
+      PrintConv => {
+        'ICC Profile' => 'ICC-profiili',
+        'Uncalibrated' => 'Kalibroimaton',
+        'Wide Gamut RGB' => 'Laaja Gamut RVB',
+      },
+    },
+   'ColorTable' => 'VÃ€ritaulukko',
+   'ColorTemperature' => 'VÃ€rilÃ€mpÃ¶tila',
+   'ColorTone' => 'VÃ€risÃ€vy',
+   'ColorToneFaithful' => 'Kohdeuskollinen vÃ€risÃ€vy',
+   'ColorToneLandscape' => 'Maisemakuvan vÃ€risÃ€vy',
+   'ColorToneNeutral' => 'Neutraali vÃ€risÃ€vy',
+   'ColorTonePortrait' => 'Muotokuvan vÃ€risÃ€vy',
+   'ColorToneStandard' => 'VakiovÃ€risÃ€vy',
+   'ColorType' => 'VÃ€rityyppi',
+   'ColorantOrder' => 'VÃ€riainejÃ€rjestys',
+   'ColorantTable' => 'VÃ€riainetaulukko',
+   'ColorimetricReference' => 'Kolorimetrinen referenssi',
+   'Comment' => 'Kommentti',
+   'ComponentsConfiguration' => 'Kunkin komponentin tarkoitus',
+   'CompressedBitsPerPixel' => 'Kuvan pakkausmuoto',
+   'CompressedImageSize' => 'Pakatun kuvan koko',
+   'Compression' => 'Pakkausskeema',
+   'CompressionRatio' => 'Pakkaussuhde',
+   'ConnectionSpaceIlluminant' => 'Yhteystilan valaistus',
+   'ConsecutiveBadFaxLines' => 'PerÃ€kkÃ€iset huonot faksirivit',
+   'Contact' => 'Kontakti',
+   'ContentLocationCode' => 'SisÃ€llÃ¶n sijaintikoodi',
+   'ContentLocationName' => 'SisÃ€llÃ¶n sijaintinimi',
+   'ContinuousBracketing' => 'Jatkuva haarukointi',
+   'Contrast' => {
+      Description => 'Kontrasti',
+      PrintConv => {
+        'Film Simulation' => 'Filminsimulaatio',
+        'High' => 'Korkea',
+        'Low' => 'Matala',
+        'Medium High' => 'Korkeahko',
+        'Medium Low' => 'Matalahko',
+        'Normal' => 'Vakio',
+      },
+    },
+   'ContrastAdjustment' => 'Kontrastin sÃ€Ã€tÃ¶',
+   'ContrastCurve' => 'KontrastikÃ€yrÃ€',
+   'ContrastFaithful' => 'Kohdeuskollinen kontrasti',
+   'ContrastLandscape' => 'Maisemakuvan kontrasti',
+   'ContrastMonochrome' => 'YksivÃ€rikuvan kontrasti',
+   'ContrastNeutral' => 'Neutraali kontrasti',
+   'ContrastPortrait' => 'Muotokuvan kontrasti',
+   'ContrastSetting' => 'Kontrastiasetus',
+   'ContrastStandard' => 'Vakiokontrasti',
+   'ControlMode' => 'Ohjaustapa',
+   'ConversionLens' => {
+      Description => 'ObjektiivilisÃ€ke',
+      PrintConv => {
+        'Macro' => 'Makro',
+        'Off' => 'Pois',
+        'Telephoto' => 'Tele',
+        'Wide' => 'Laajakulma',
+      },
+    },
+   'Converter' => 'Konvertteri',
+   'Copyright' => 'Profiilin copyright',
+   'CopyrightFlag' => 'Copyright-lippu',
+   'CopyrightNotice' => 'TekijÃ€noikeusilmoitus',
+   'CoringFilter' => 'Ydinsuodin',
+   'CoringValues' => 'Ydinsuodatusarvot',
+   'Country-PrimaryLocationCode' => 'ISO-maakoodi',
+   'Country-PrimaryLocationName' => 'Maa',
+   'CreateDate' => 'Digitaalisen datan luonnin pÃ€ivÃ€ys ja aika',
+   'CreationDate' => 'LuontipÃ€ivÃ€',
+   'CreativeStyle' => {
+      Description => 'Luova tyyli',
+      PrintConv => {
+        'Autumn Leaves' => 'Syksyn lehdet',
+        'B&W' => 'M&V',
+        'Clear' => 'SelkeÃ€',
+        'Deep' => 'SyvÃ€',
+        'Landscape' => 'Maisema',
+        'Light' => 'Valoisa',
+        'Neutral' => 'Neutraali',
+        'Night View/Portrait' => 'YÃ¶nÃ€kymÃ€',
+        'Portrait' => 'Muotokuva',
+        'Sepia' => 'Seepia',
+        'Standard' => 'Vakio',
+        'Sunset' => 'Auringonlasku',
+        'Vivid' => 'HeleÃ€t vÃ€rit',
+      },
+    },
+   'CreatorAddress' => 'TekijÃ€ - Osoite',
+   'CreatorCity' => 'TekijÃ€ - Kaupunki',
+   'CreatorCountry' => 'TekijÃ€ - Maa',
+   'CreatorPostalCode' => 'TekijÃ€ - Postinumero',
+   'CreatorRegion' => 'TekijÃ€ - Valtio/Provinssi',
+   'CreatorWorkEmail' => 'TekijÃ€ - email(it)',
+   'CreatorWorkTelephone' => 'TekijÃ€ - Puhelinnumero(t)',
+   'CreatorWorkURL' => 'TekijÃ€ - Web-sivusto(t)',
+   'Credit' => 'Tarjoaja',
+   'CropBottom' => 'Rajaus alhaalta',
+   'CropData' => 'Rajausdata',
+   'CropLeft' => 'Rajaus vasemmalta',
+   'CropOutputHeight' => 'Rajaustuloksen korkeus',
+   'CropOutputPixels' => 'Rajaustulokset pikselit',
+   'CropOutputResolution' => 'Rajaustuloksen resoluutio',
+   'CropOutputScale' => 'Rajaustuloksen mittasuhteet',
+   'CropOutputWidth' => 'Rajaustuloksen leveys',
+   'CropRight' => 'Rajaus oikealta',
+   'CropScaledResolution' => 'Rajauksen skaalausresoluutio',
+   'CropSourceResolution' => 'RajauslÃ€hteen resoluutio',
+   'CropTop' => 'Rajaus ylhÃ€Ã€ltÃ€',
+   'CurrentICCProfile' => 'Nykyinen ICC-profiili',
+   'CurrentPreProfileMatrix' => 'Nykyinen pre-profiilimatriisi',
+   'Curves' => 'KÃ€yrÃ€t',
+   'Custom1' => 'Mukautus 1',
+   'Custom2' => 'Mukautus 2',
+   'Custom3' => 'Mukautus 3',
+   'Custom4' => 'Mukautus 4',
+   'CustomRendered' => {
+      Description => 'Mukautettu kuvankÃ€sittely',
+      PrintConv => {
+        'Custom' => 'Mukautettu kÃ€sittely',
+        'Normal' => 'Normaali kÃ€sittely',
+      },
+    },
+   'CustomSaturation' => 'Mukautettu vÃ€rikyllÃ€isyys',
+   'D-LightingHQColorBoost' => 'D-Lighting HQ -vÃ€ritehostus',
+   'D-LightingHQHighlight' => 'D-Lighting HQ -valoalue',
+   'D-LightingHQSelected' => 'Valittu D-Lighting HQ',
+   'D-LightingHQShadow' => 'D-Lighting HQ -varjoalue',
+   'D-LightingHSAdjustment' => 'D-Lighting HS -sÃ€Ã€tÃ¶',
+   'D-LightingHSColorBoost' => 'D-Lighting HS -vÃ€ritehostus',
+   'DECPosition' => 'DEC-sijainti',
+   'DNGBackwardVersion' => 'Edellinen DNG-versio',
+   'DNGVersion' => 'DNG-versio',
+   'DSPFirmwareVersion' => 'DSP-laiteohjelmistoversio',
+   'DataDump' => 'Datadumppi',
+   'DataImprint' => 'Datan sisÃ€llytys',
+   'DataType' => 'Mattaus',
+   'Date' => 'PÃ€ivÃ€ys',
+   'DateCreated' => 'LuontipÃ€ivÃ€ys',
+   'DateImprint' => 'PÃ€ivÃ€ysleima',
+   'DateSent' => 'LÃ€hetyspÃ€ivÃ€',
+   'DateStampMode' => 'PÃ€ivÃ€ysleiman muoto',
+   'DateTime' => 'PÃ€ivÃ€ysaika',
+   'DateTimeOriginal' => 'AlkuperÃ€isen datan luonnin pÃ€ivÃ€ys ja aika',
+   'DealerIDNumber' => 'MyyjÃ€n ID-numero',
+   'DefaultCropOrigin' => 'Oletusrajauksen alkuperÃ€',
+   'DefaultCropSize' => 'Oletusrajauskoko',
+   'DefaultScale' => 'Oletusasteikko',
+   'DelayTime' => 'Viiveaika',
+   'DeletedImageCount' => 'Poistettujen kuvien mÃ€Ã€rÃ€',
+   'Description' => 'Deskriptio',
+   'Destination' => 'Kohde',
+   'DestinationCity' => 'Kohdepaikkakunta',
+   'DestinationCityCode' => 'Kohdepaikkakoodi',
+   'DestinationDST' => {
+      Description => 'Kohteen kesÃ€aika (DST)',
+      PrintConv => {
+        'No' => 'Ei',
+        'Yes' => 'KyllÃ€',
+      },
+    },
+   'DevelopmentDynamicRange' => 'Dynamiikka-alueen kehitys',
+   'DeviceAttributes' => 'Laiteattribuutit',
+   'DeviceManufacturer' => 'Laitteen valmistaja',
+   'DeviceMfgDesc' => 'Laitteen valmistajan kuvaus',
+   'DeviceModel' => 'Laitteen malli',
+   'DeviceModelDesc' => 'Laitemallin kuvaus',
+   'DeviceSettingDescription' => 'Laiteasetusten kuvaus',
+   'DigitalCreationDate' => 'DigitalisointipÃ€ivÃ€ys',
+   'DigitalCreationTime' => 'Digitalisointiaika',
+   'DigitalDEEHighlightAdj' => 'Digitaalinen DEE -vaalean pÃ€Ã€n sÃ€Ã€tÃ¶',
+   'DigitalDEEShadowAdj' => 'Digitaalinen DEE-varjonsÃ€Ã€tÃ¶',
+   'DigitalDEEThreshold' => 'Digitaalinen DEE-kynnys',
+   'DigitalEffectsName' => 'Digitaalisten efektien nimi',
+   'DigitalEffectsType' => 'Digitaalisten efektien tyyppi',
+   'DigitalEffectsVersion' => 'Digitaalisten efektien versio',
+   'DigitalGEM' => 'Digitaalinen GEM',
+   'DigitalGain' => 'Digitaalinen vahvistus',
+   'DigitalICE' => 'Digitaalinen ICE',
+   'DigitalROC' => 'Digitaalinen ROC',
+   'DigitalZoom' => 'Digitaalinen zoom',
+   'DigitalZoomOn' => {
+      Description => 'Digitaalinen zoom',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'DigitalZoomRatio' => 'Digitaalinen zoomaussuhde',
+   'DirectoryIndex' => 'Kansioindeksi',
+   'DirectoryNumber' => 'Kansion numero',
+   'DisplayAperture' => 'Aukon nÃ€yttÃ¶',
+   'DisplayedUnitsX' => 'Vaakaresoluution yksikkÃ¶',
+   'DisplayedUnitsY' => 'Pystyresoluution yksikkÃ¶',
+   'DistortionCorrection' => 'VÃ€Ã€ristymÃ€korjaus',
+   'DocumentHistory' => 'Dokumentin historia',
+   'DocumentName' => 'Dokumentin nimi',
+   'DocumentNotes' => 'Dokumentin huomautukset',
+   'DotRange' => 'Pisteiden mÃ€Ã€rÃ€',
+   'DriveMode' => 'Kuvaustapa',
+   'DriveMode2' => 'Kuvaustapa 2',
+   'DustRemovalData' => 'PÃ¶lynpoistodata',
+   'DynamicAFArea' => 'Dynaamisen alueen AF',
+   'DynamicRange' => {
+      Description => 'Dynamiikka-alue',
+      PrintConv => {
+        'Standard' => 'Vakio',
+        'Wide' => 'Laaja',
+      },
+    },
+   'DynamicRangeExpansion' => {
+      Description => 'Dynamiikka-alueen laajennus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'DynamicRangeOptimizer' => {
+      Description => 'Dynamiikka-alueen optimointi',
+      PrintConv => {
+        'Advanced Auto' => 'Edistynyt automatiikka',
+        'Advanced Lv1' => 'Edistynyt taso 1',
+        'Advanced Lv2' => 'Edistynyt taso 2',
+        'Advanced Lv3' => 'Edistynyt taso 3',
+        'Advanced Lv4' => 'Edistynyt taso 4',
+        'Advanced Lv5' => 'Edistynyt taso 5',
+        'Off' => 'Pois',
+        'Standard' => 'Vakio',
+      },
+    },
+   'DynamicRangeSetting' => {
+      Description => 'Dynamiikka-alueen sÃ€Ã€tÃ¶',
+      PrintConv => {
+        'Film Simulation' => 'Filminsimulaatio',
+        'Standard (100%)' => 'Vakio (100%)',
+        'Wide1 (230%)' => 'Laaja 1 (230%)',
+        'Wide2 (400%)' => 'Laaja 2 (400%)',
+      },
+    },
+   'E-DialInProgram' => 'SÃ€Ã€tÃ¶kiekko ohjelmassa',
+   'EVStepInfo' => 'EV-askeltiedot',
+   'EVStepSize' => 'EV-askeleen koko',
+   'EVSteps' => 'EV-askeleet',
+   'EasyExposureCompensation' => 'Valotuksen pikakorjaus',
+   'EasyMode' => 'Helppo tapa',
+   'EdgeNoiseReduction' => 'Reunakohinan vaimennus',
+   'EditStatus' => 'Editoinnin tila',
+   'EditTagArray' => 'Muokkaa tagiryhmÃ€Ã€',
+   'EditorialUpdate' => {
+      Description => 'SisÃ€llÃ¶n pÃ€ivitys',
+      PrintConv => {
+        'Additional language' => 'LisÃ€kielet',
+      },
+    },
+   'EffectiveLV' => 'Tehollinen valoarvo (LV)',
+   'EffectiveMaxAperture' => 'Suurin tehollinen aukko',
+   'Encoder' => 'Kooderi',
+   'EncodingProcess' => 'Koodausmetodi',
+   'EndPoints' => 'Loppupisteet',
+   'EnhanceDarkTones' => 'Tummien sÃ€vyjen parantelu',
+   'Enhancement' => {
+      Description => 'Parantelu',
+      PrintConv => {
+        'Blue' => 'Sininen',
+        'Flesh Tones' => 'LihanvÃ€rinen',
+        'Green' => 'VihreÃ€',
+        'Off' => 'Pois',
+        'Red' => 'Punainen',
+      },
+    },
+   'EnhancerValues' => 'Korjainarvot',
+   'EnvelopeNumber' => 'Pakkauksen numero',
+   'EnvelopePriority' => {
+      Description => 'Pakkauksen prioriteetti',
+      PrintConv => {
+        '0 (reserved)' => '0 (varattu tulevaan kÃ€yttÃ¶Ã¶n)',
+        '1 (most urgent)' => '1 (hyvin kiireellinen)',
+        '5 (normal urgency)' => '5 (normaali kiireellisyys)',
+        '8 (least urgent)' => '8 (lievÃ€n kiireellinen)',
+        '9 (user-defined priority)' => '9 (kÃ€yttÃ€jÃ€n mÃ€Ã€rittÃ€mÃ€ prioriteetti)',
+      },
+    },
+   'EnvelopeRecordVersion' => 'Pakkaustietueen versio',
+   'EpsonImageHeight' => 'Epson-kuvan korkeus',
+   'EpsonImageWidth' => 'Epson-kuvan leveys',
+   'EpsonSoftware' => 'Epson-ohjelmisto',
+   'Equipment' => 'VÃ€lineistÃ¶n IFD-osoitin',
+   'EquipmentVersion' => 'VÃ€lineistÃ¶versio',
+   'ExcursionTolerance' => {
+      Description => 'Toleranssin ekskursio',
+      PrintConv => {
+        'Allowed' => 'Voi toteutua',
+        'Not Allowed' => 'Ei sallittu (oletus)',
+      },
+    },
+   'ExifCameraInfo' => 'Exif-kameratiedot',
+   'ExifImageHeight' => 'Kuvan korkeus',
+   'ExifImageWidth' => 'Kuvan leveys',
+   'ExifVersion' => 'Exif-versio',
+   'ExitPupilPosition' => 'LÃ€htÃ¶pupillin sijainti',
+   'ExpandFilm' => 'Filmilaajennus',
+   'ExpandFilterLens' => 'Suodinlinssilaajennus',
+   'ExpandFlashLamp' => 'Salamavalolaajennus',
+   'ExpandLens' => 'Objektiivilaajennus',
+   'ExpandScanner' => 'Skannerilaajennus',
+   'ExpandSoftware' => 'Ohjelmistolaajennus',
+   'ExpirationDate' => 'PÃ€Ã€ttymispÃ€ivÃ€ys',
+   'ExpirationTime' => 'PÃ€Ã€ttymisaika',
+   'Exposure' => 'Valotus',
+   'ExposureBracketStepSize' => 'Valotuksen haarukointivÃ€li',
+   'ExposureBracketValue' => 'Valotushaarukoinnin arvo',
+   'ExposureCompensation' => 'Valotuksen korjaus',
+   'ExposureDelayMode' => 'Valotuksen viivetila',
+   'ExposureDifference' => 'Valotusero',
+   'ExposureIndex' => 'Valotusindeksi',
+   'ExposureMode' => {
+      Description => 'Valotustapa',
+      PrintConv => {
+        'Aperture Priority' => 'Aukon esivalinta',
+        'Aperture-priority AE' => 'Aukon esivalinta AE',
+        'Auto' => 'Automaattinen',
+        'Auto bracket' => 'Automaattihaarukointi',
+        'Landscape' => 'Maisema',
+        'Manual' => 'Manuaalinen',
+        'Night Scene / Twilight' => 'YÃ¶nÃ€kymÃ€',
+        'Program' => 'Ohjelma',
+        'Program AE' => 'Ohjelma-AE',
+        'Program-shift' => 'Ohjelma-siirto',
+        'Shutter Priority' => 'Ajan esivalinta',
+        'Shutter speed priority AE' => 'Ajan esivalinta AE',
+        'n/a' => 'Ei asetettu',
+      },
+    },
+   'ExposureProgram' => {
+      Description => 'Valotusohjelma',
+      PrintConv => {
+        'Action (High speed)' => 'Toimintaohjelma (painotettu suljinnopeutta)',
+        'Aperture-priority AE' => 'Aukon esivalinta',
+        'Creative (Slow speed)' => 'Luova ohjelma (painotettu syvÃ€terÃ€vyyttÃ€)',
+        'Landscape' => 'Maisemamoodi (maisemakuviin terÃ€vÃ€llÃ€ taustalla)',
+        'Manual' => 'Manuaalinen',
+        'Not Defined' => 'Ei mÃ€Ã€ritetty',
+        'Portrait' => 'Muotokuvamoodi (lÃ€hikuviin epÃ€terÃ€vÃ€llÃ€ taustalla)',
+        'Program AE' => 'Normaali ohjelma',
+        'Shutter speed priority AE' => 'Ajan esivalinta',
+      },
+    },
+   'ExposureTime' => 'Valotusaika',
+   'ExposureTime2' => 'Valotusaika 2',
+   'ExposureWarning' => {
+      Description => 'Valotusvaroitus',
+      PrintConv => {
+        'Bad exposure' => 'Valotusvirhe',
+        'Good' => 'OK',
+      },
+    },
+   'ExtendedWBDetect' => {
+      Description => 'Laajennettu valkotas. tunnistus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'Extender' => 'Konvertteri',
+   'ExtenderFirmwareVersion' => 'Konvertterin laiteohjelmistoversio',
+   'ExtenderModel' => 'Konvertterimalli',
+   'ExtenderSerialNumber' => 'Konvertterin sarjanumero',
+   'ExternalFlash' => 'Ulkoinen salama',
+   'ExternalFlashAE1' => 'Ulkoinen salama AE 1?',
+   'ExternalFlashAE1_0' => 'Ulkoinen salama AE 1 (0)?',
+   'ExternalFlashAE2' => 'Ulkoinen salama AE 2?',
+   'ExternalFlashAE2_0' => 'Ulkoinen salama AE 2 (0)?',
+   'ExternalFlashBounce' => {
+      Description => 'Ulkoisen salaman heijastus',
+      PrintConv => {
+        'Bounce or Off' => 'Heijastus tai pois',
+        'Direct' => 'Suora',
+        'No' => 'Ei',
+        'Yes' => 'KyllÃ€',
+      },
+    },
+   'ExternalFlashExposureComp' => 'Ulkoisen salaman valotuksen sÃ€Ã€tÃ¶',
+   'ExternalFlashFlags' => 'Ulkoisen salaman liput',
+   'ExternalFlashGuideNumber' => 'Ulkoisen salaman ohjeluku?',
+   'ExternalFlashMode' => 'Ulkoisen salaman tapa',
+   'ExternalFlashZoom' => 'Ulkoisen salaman zoom',
+   'ExtraSamples' => 'LisÃ€nÃ€ytteet',
+   'FNumber' => 'Aukkoarvo',
+   'Face1Position' => 'Kasvojen 1 sijainti',
+   'Face2Position' => 'Kasvojen 2 sijainti',
+   'Face3Position' => 'Kasvojen 3 sijainti',
+   'Face4Position' => 'Kasvojen 4 sijainti',
+   'Face5Position' => 'Kasvojen 5 sijainti',
+   'Face6Position' => 'Kasvojen 6 sijainti',
+   'Face7Position' => 'Kasvojen 7 sijainti',
+   'Face8Position' => 'Kasvojen 8 sijainti',
+   'Face9Position' => 'Kasvojen 9 sijainti',
+   'FaceDetect' => 'Kasvojen tunnistus',
+   'FacePositions' => 'Kasvojen sijainnit',
+   'FacesDetected' => 'Tunnistetut kasvot',
+   'FaxRecvParams' => 'Faxin vastaanottoparametrit',
+   'FaxRecvTime' => 'Faxin vastaanottoaika',
+   'FaxSubAddress' => 'Faxin alaosoite',
+   'FileFormat' => 'Tiedostomuoto',
+   'FileIndex' => 'Tiedostoindeksi',
+   'FileInfo' => 'Tiedostoinfot',
+   'FileInfoVersion' => 'Tiedostoinfojen versio',
+   'FileName' => 'Tiedostonimi',
+   'FileNumber' => 'Tiedoston numero',
+   'FileNumberMemory' => 'Tiedostonumeromuisti',
+   'FileNumberSequence' => 'Tiedostojen numerojÃ€rjestys',
+   'FileSize' => 'Tiedoston koko',
+   'FileSource' => {
+      Description => 'Tiedoston lÃ€hde',
+      PrintConv => {
+        'Digital Camera' => 'Digitaalikamera',
+        'Film Scanner' => 'Filmiskanneri',
+        'Reflection Print Scanner' => 'Heijastava skanneri',
+      },
+    },
+   'FileType' => 'Tiedostotyyppi',
+   'Filename' => 'Tiedostonimi',
+   'FillOrder' => 'TÃ€yttÃ¶jÃ€rjestys',
+   'FilmCategory' => 'Filmiluokka',
+   'FilmGencode' => 'Filmin gencode',
+   'FilmMode' => {
+      Description => 'Filmitila',
+      PrintConv => {
+        '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)',
+        'Nostalgic' => 'Nostalginen vÃ€ri',
+        'Smooth (B&W)' => 'PehmeÃ€ (M&V)',
+        'Smooth (color)' => 'PehmeÃ€ (vÃ€ri)',
+        'Standard (B&W)' => 'Vakio (M&V)',
+        'Standard (color)' => 'Vakio (vÃ€ri)',
+        'Vibrant' => 'Eloisa vÃ€ri',
+      },
+    },
+   'FilmProductCode' => 'Filmin tuotekoodi',
+   'FilmType' => 'Filmityyppi',
+   'Filter' => 'Suodin',
+   'FilterEffect' => 'Suodinefekti',
+   'FilterEffectMonochrome' => 'YksivÃ€risuodintehoste',
+   'Firmware' => 'Laiteohjelmisto',
+   'FirmwareDate' => 'Laiteohjelmiston pÃ€ivÃ€ys',
+   'FirmwareID' => 'Laiteohjelmiston ID',
+   'FirmwareRevision' => 'Laiteohjelmiston revisio',
+   'FirmwareVersion' => 'Laiteohjelmiston versio',
+   'FixtureIdentifier' => 'Ominaisuuden tunnistin',
+   'Flash' => {
+      Description => 'Salama',
+      PrintConv => {
+        'Auto, Did not fire' => 'Salama ei lauennut, automaattimoodi',
+        'Auto, Did not fire, Red-eye reduction' => 'Automaattinen, salama ei lauennut, punasilmien esto',
+        'Auto, Fired' => 'Salama lauennut, automaattimoodi',
+        'Auto, Fired, Red-eye reduction' => 'Salama lauennut, automaattimoodi, punasilmien estomoodi',
+        'Auto, Fired, Red-eye reduction, Return detected' => 'Salama lauennut, automaattimoodi, heijastusvalo havaittu, punasilmien estomoodi',
+        'Auto, Fired, Red-eye reduction, Return not detected' => 'Salama lauennut, automaattimoodi, heijastusvaloa ei havaittu, punasilmien estomoodi',
+        'Auto, Fired, Return detected' => 'Salama lauennut, automaattimoodi. heijastusvalo havaittu',
+        'Auto, Fired, Return not detected' => 'Salama lauennut, automaattimoodi, heijastusvaloa ei havaittu',
+        'Fired' => 'Salama lauennut',
+        'Fired, Red-eye reduction' => 'Salama lauennut, punasilmien estomoodi',
+        'Fired, Red-eye reduction, Return detected' => 'Salama lauennut, punasilmien estomoodi, heijastusvalo havaittu',
+        'Fired, Red-eye reduction, Return not detected' => 'Salama lauennut, punasilmien estomoodi, heijastusvaloa ei havaittu',
+        'Fired, Return detected' => 'Strobo-salaman heijastus havaittu',
+        'Fired, Return not detected' => 'Strobo-salaman heijastusta ei havaittu',
+        'No Flash' => 'Salama ei lauennut',
+        'No flash function' => 'Ei salamatoimintoa',
+        'Off, Did not fire' => 'Salama ei lauennut, pakkosalamatila',
+        'Off, Did not fire, Return not detected' => 'Pois, salama ei lauennut, heijastusta ei havaittu',
+        'Off, No flash function' => 'Pois, ei salamatoimintoa',
+        'Off, Red-eye reduction' => 'Pois, punasilmien esto',
+        'On, Did not fire' => 'PÃ€Ã€llÃ€, salama ei lauennut',
+        'On, Fired' => 'Salama lauennut, pakkosalamatila',
+        'On, Red-eye reduction' => 'Salama lauennut, pakkosalamatila, punasilmien estomoodi',
+        'On, Red-eye reduction, Return detected' => 'Salama lauennut, pakkosalamatila, punasilmien estomoodi, heijastusvalo havaittu',
+        'On, Red-eye reduction, Return not detected' => 'Salama lauennut, pakkosalamatila, punasilmien estomoodi, heijastusvaloa ei havaittu',
+        'On, Return detected' => 'Salama lauennut, pakkosalamatila, heijastusvalo havaittu',
+        'On, Return not detected' => 'Salama lauennut, pakkosalamatila, heijastusvaloa ei havaittu',
+      },
+    },
+   'FlashActivity' => 'Salaman toiminta',
+   'FlashBias' => 'Salaman muutos',
+   'FlashChargeLevel' => 'Salaman varaustila',
+   'FlashCompensation' => 'Salaman sÃ€Ã€tÃ¶',
+   'FlashControlMode' => 'Salaman ohjaustapa',
+   'FlashDevice' => 'Salamalaite',
+   'FlashDistance' => 'SalamaetÃ€isyys',
+   'FlashEnergy' => 'Salaman teho',
+   'FlashExposureBracketValue' => 'Salamavalotuksen haarukoinnin arvo',
+   'FlashExposureComp' => 'Salaman kirkkauden sÃ€Ã€tÃ¶',
+   'FlashExposureComp2' => 'Salaman kirkkauden sÃ€Ã€tÃ¶ 2',
+   'FlashFired' => {
+      Description => 'Salama lauennut',
+      PrintConv => {
+        'No' => 'Ei',
+        'Yes' => 'KyllÃ€',
+      },
+    },
+   'FlashFirmwareVersion' => 'Salaman laiteohjelmistoversio',
+   'FlashFocalLength' => 'Salaman polttovÃ€li',
+   'FlashGuideNumber' => 'Salaman ohjeluku',
+   'FlashInfoVersion' => 'Salaman tietojen versio',
+   'FlashIntensity' => {
+      Description => 'Salaman teho',
+      PrintConv => {
+        'High' => 'Korkea',
+        'Low' => 'Matala',
+        'Normal' => 'Normaali',
+        'Strong' => 'Voimakas',
+        'Weak' => 'Heikko',
+      },
+    },
+   'FlashMetering' => 'Salamamittaus',
+   'FlashMeteringSegments' => 'Salaman mittaussegmentit',
+   'FlashMode' => {
+      Description => 'Salamatapa',
+      PrintConv => {
+        'Auto' => 'Automaattinen',
+        'Did Not Fire' => 'Ei lauennut',
+        'Disabled' => 'Deaktivoitu',
+        'Fired, Commander Mode' => 'Lauennut, pakkotapa',
+        'Fired, External' => 'Lauennut, ulkoinen',
+        'Fired, Manual' => 'Lauennut, manuaalinen',
+        'Fired, TTL Mode' => 'Lauennut, TTL-tapa',
+        'Force' => 'Pakkotapa',
+        'Not Ready' => 'Ei valmis',
+        'Off' => 'Pois (3)',
+        'On' => 'PÃ€Ã€llÃ€ (2)',
+        'Red eye' => 'Punasilmien esto',
+      },
+    },
+   'FlashModel' => {
+      Description => 'Salaman malli',
+      PrintConv => {
+        'None' => 'Ei mitÃ€Ã€n',
+      },
+    },
+   'FlashOptions' => 'Salamavalinnat',
+   'FlashOutput' => 'Salaman teho',
+   'FlashRemoteControl' => 'Salaman kaukosÃ€Ã€tÃ¶',
+   'FlashSerialNumber' => 'Salaman sarjanumero',
+   'FlashSetting' => 'Salaman asetus',
+   'FlashShutterSpeed' => 'Suljinaika salamakuvauksessa',
+   'FlashStatus' => 'Salaman tila',
+   'FlashSyncSpeed' => 'Salaman tÃ€smÃ€ysaika',
+   'FlashType' => {
+      Description => 'Salamatyyppi',
+      PrintConv => {
+        'E-System' => 'E-jÃ€rjestelmÃ€',
+        'None' => 'Ei mitÃ€Ã€n',
+        'Simple E-System' => 'Yksinkertainen E-jÃ€rjestelmÃ€',
+      },
+    },
+   'FlashWarning' => 'Salamavaroitus',
+   'FlashpixVersion' => 'Tuettu Flashpix-versio',
+   'FlickerReduce' => {
+      Description => 'VÃ€rinÃ€n vaimennus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'FlipHorizontal' => 'Kiepautus vaakatasossa',
+   'FocalLength' => 'PolttovÃ€li',
+   'FocalLengthIn35mmFormat' => 'PolttovÃ€li 35 mm filmikoolla',
+   'FocalPlaneDiagonal' => 'Polttopistetason lÃ€vistÃ€jÃ€',
+   'FocalPlaneResolutionUnit' => {
+      Description => 'Polttopistetason resoluutioyksikkÃ¶',
+      PrintConv => {
+        'None' => 'Ei mitÃ€Ã€n',
+        'inches' => 'Tuuma',
+        'um' => 'Âµm (mikrometri)',
+      },
+    },
+   'FocalPlaneXResolution' => 'Polttopistetason vaakaresoluutio',
+   'FocalPlaneXSize' => 'Polttopistetason leveys',
+   'FocalPlaneYResolution' => 'Polttopistetason pystyresoluutio',
+   'FocalPlaneYSize' => 'Polttopistetason korkeus',
+   'FocalType' => 'Objektiivityyppi',
+   'Focus' => 'Tarkennusesivalinta',
+   'FocusArea' => 'Tarkennusalue',
+   'FocusAreaSelection' => 'Tarkennusalueen valinta',
+   'FocusContinuous' => 'Jatkuva tarkennus',
+   'FocusDistance' => 'TarkennusetÃ€isyys',
+   'FocusDistanceLower' => 'LÃ€hitarkennus',
+   'FocusDistanceUpper' => 'Kaukotarkennus',
+   'FocusMode' => {
+      Description => 'Tarkennustapa',
+      PrintConv => {
+        'Auto' => 'Automaattinen',
+        'Manual' => 'Manuaalinen',
+      },
+    },
+   'FocusMode2' => 'Tarkennustapa',
+   'FocusPixel' => 'Tarkennuspikseli',
+   'FocusPosition' => 'Polttopisteen paikka',
+   'FocusProcess' => 'Tarkennusprosessi',
+   'FocusRange' => {
+      Description => 'Tarkennusalue',
+      PrintConv => {
+        'Macro' => 'Makro',
+        'Normal' => 'Normaali',
+      },
+    },
+   'FocusSetting' => 'Tarkennusasetus',
+   'FocusStepCount' => 'TarkennusaskelmÃ€Ã€rÃ€',
+   'FocusWarning' => {
+      Description => 'Tarkennusvaroitus',
+      PrintConv => {
+        'Good' => 'OK',
+        'Out of focus' => 'EpÃ€tarkka',
+      },
+    },
+   'FolderName' => 'Kansion nimi',
+   'ForwardMatrix1' => 'EteenpÃ€in-matriisi 1',
+   'ForwardMatrix2' => 'EteenpÃ€in-matriisi 2',
+   'FrameHeight' => 'Ruudun korkeus',
+   'FrameNumber' => 'Ruudun numero',
+   'FrameWidth' => 'Ruudun leveys',
+   'FreeByteCounts' => 'Vapaiden tavujen mÃ€Ã€rÃ€t',
+   'FreeMemoryCardImages' => 'Muistikortilla tilaa',
+   'FreeOffsets' => 'Vapaat siirtymÃ€t',
+   'FujiFlashMode' => {
+      Description => 'Salamatila',
+      PrintConv => {
+        'External' => 'Ulkoinen salama',
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+        'Red-eye reduction' => 'PunasilmÃ€isyyden vÃ€hennys',
+      },
+    },
+   'GEMInfo' => 'GEM-tiedot',
+   'GEModel' => 'Malli',
+   'GIFVersion' => 'GIF-versio',
+   'GPSAltitude' => 'Korkeus',
+   'GPSAltitudeRef' => {
+      Description => 'Viitekorkeus',
+      PrintConv => {
+        'Above Sea Level' => 'Merenpinnan korkeus',
+        'Below Sea Level' => 'Merenpinnan viitekorkeus (negatiivinen arvo)',
+      },
+    },
+   'GPSAreaInformation' => 'GPS-alueen nimi',
+   'GPSDOP' => 'Mittaustarkkuus',
+   'GPSDateStamp' => 'GPS-pÃ€ivÃ€ys',
+   'GPSDestBearing' => 'Kohteen suuntima',
+   'GPSDestBearingRef' => {
+      Description => 'Kohteen suuntiman viite',
+      PrintConv => {
+        'Magnetic North' => 'Magneettinen suunta',
+        'True North' => 'Todellinen suunta',
+      },
+    },
+   'GPSDestDistance' => 'EtÃ€isyys kohteeseen',
+   'GPSDestDistanceRef' => {
+      Description => 'Viite etÃ€isyydelle kohteeseen',
+      PrintConv => {
+        'Kilometers' => 'KilometriÃ€',
+        'Miles' => 'Mailia',
+        'Nautical Miles' => 'Solmua',
+      },
+    },
+   'GPSDestLatitude' => 'Kohteen leveysaste',
+   'GPSDestLatitudeRef' => {
+      Description => 'Kohteen leveysasteen viite',
+      PrintConv => {
+        'North' => 'Pohjoista leveyttÃ€',
+        'South' => 'EtelÃ€istÃ€ leveyttÃ€',
+      },
+    },
+   'GPSDestLongitude' => 'Kohteen pituusaste',
+   'GPSDestLongitudeRef' => {
+      Description => 'Kohteen pituusasteen viite',
+      PrintConv => {
+        'East' => 'ItÃ€istÃ€ pituutta',
+        'West' => 'LÃ€ntistÃ€ pituutta',
+      },
+    },
+   'GPSDifferential' => {
+      Description => 'GPS-differentiaalikorjaus',
+      PrintConv => {
+        'Differential Corrected' => 'Differentiaalikorjausta kÃ€ytetty',
+        'No Correction' => 'Mittaus ilman differentiaalikorjausta',
+      },
+    },
+   'GPSImgDirection' => 'KuvanÂŽ suunta',
+   'GPSImgDirectionRef' => {
+      Description => 'Kuvan suunnan viite',
+      PrintConv => {
+        'Magnetic North' => 'Magneettinen suunta',
+        'True North' => 'Todellinen suunta',
+      },
+    },
+   'GPSLatitude' => 'Leveysaste',
+   'GPSLatitudeRef' => {
+      Description => 'Pohjoista tai etelÃ€istÃ€ leveyttÃ€',
+      PrintConv => {
+        'North' => 'Pohjoista leveyttÃ€',
+        'South' => 'EtelÃ€istÃ€ leveyttÃ€',
+      },
+    },
+   'GPSLongitude' => 'Pituusaste',
+   'GPSLongitudeRef' => {
+      Description => 'ItÃ€istÃ€ tai lÃ€ntistÃ€ pituutta',
+      PrintConv => {
+        'East' => 'ItÃ€istÃ€ pituutta',
+        'West' => 'LÃ€ntistÃ€ pituutta',
+      },
+    },
+   'GPSMapDatum' => 'KÃ€ytetty geodeettinen karttadata',
+   'GPSMeasureMode' => {
+      Description => 'GPS-mittaustapa',
+      PrintConv => {
+        '2-Dimensional Measurement' => '2-ulotteinen mittaus',
+        '3-Dimensional Measurement' => '3-ulotteinen mittaus',
+      },
+    },
+   'GPSProcessingMethod' => 'GPS-prosessointimetodin nimi',
+   'GPSSatellites' => 'Mittaukseen kÃ€ytetyt GPS-satelliitit',
+   'GPSSpeed' => 'GPS-vastaanottimen nopeus',
+   'GPSSpeedRef' => {
+      Description => 'NopeusyksikkÃ¶',
+      PrintConv => {
+        'km/h' => 'KilometriÃ€ per tunti',
+        'knots' => 'Solmua',
+        'mph' => 'Mailia per tunti',
+      },
+    },
+   'GPSStatus' => {
+      Description => 'GPS-vastaanottimen tila',
+      PrintConv => {
+        'Measurement Active' => 'Mittaus aktiivinen',
+        'Measurement Void' => 'Mittaus virheellinen',
+      },
+    },
+   'GPSTimeStamp' => 'GPS-aika (atomikello)',
+   'GPSTrack' => 'Liikkeen suunta',
+   'GPSTrackRef' => {
+      Description => 'Liikkeen suunnan viite',
+      PrintConv => {
+        'Magnetic North' => 'Magneettinen suunta',
+        'True North' => 'Todellinen suunta',
+      },
+    },
+   'GPSVersionID' => 'GPS-tagin versio',
+   'GainBase' => 'Perusvahvistus',
+   'GainControl' => {
+      Description => 'Herkkyyden sÃ€Ã€tÃ¶',
+      PrintConv => {
+        'High gain down' => 'Suuri valoisuuden vÃ€hennys',
+        'High gain up' => 'Suuri valoisuuden lisÃ€ys',
+        'Low gain down' => 'Pieni valoisuuden vÃ€hennys',
+        'Low gain up' => 'Pieni valoisuuden lisÃ€ys',
+        'None' => 'Ei mitÃ€Ã€n',
+      },
+    },
+   'GammaCompensatedValue' => 'Kompensoidun gamman arvo',
+   'GeoTiffAsciiParams' => 'Geo-ASCII -parametrien tagi',
+   'GeoTiffDirectory' => 'Geo-avain -hakemiston tagi',
+   'GeoTiffDoubleParams' => 'Geo-kaksoisparametrien tagi',
+   'Gradation' => 'Porrastus',
+   'GrayPoint' => 'Harmaapiste',
+   'GrayResponseCurve' => 'Harmaan vastekÃ€yrÃ€',
+   'GrayResponseUnit' => {
+      Description => 'Harmaan vasteyksikkÃ¶',
+      PrintConv => {
+        '0.0001' => 'Numero edustaa yksikÃ¶n tuhannesosia',
+        '0.001' => 'Numero edustaa yksikÃ¶n sadasosia',
+        '0.1' => 'Numero edustaa yksikÃ¶n kymmenyksiÃ€',
+        '1e-05' => 'Numero edustaa yksikÃ¶n kymmenestuhannesosia',
+        '1e-06' => 'Numero edustaa yksikÃ¶n sadastuhannesosia',
+      },
+    },
+   'GrayScale' => 'Harmaa-asteikko',
+   'GrayTRC' => 'Harmaan toonin toistokÃ€yrÃ€',
+   'GreenMatrixColumn' => 'VihreÃ€n matriisin sarake',
+   'GreenTRC' => 'VihreÃ€n toonin toistokÃ€yrÃ€',
+   'GreenX' => 'VihreÃ€ X',
+   'GreenY' => 'VihreÃ€ Y',
+   'GridDisplay' => 'Ristikko',
+   'HCUsage' => 'HC-kÃ€yttÃ¶',
+   'HalftoneHints' => 'PuolisÃ€vyviitteet',
+   'Headline' => 'Otsikko',
+   'HighISONoiseReduction' => {
+      Description => 'Korkean ISO-tason kohinan vaimennus',
+      PrintConv => {
+        'High' => 'Korkea',
+        'Low' => 'Matala',
+        'Minimal' => 'Minimaalinen',
+        'Normal' => 'Normaali',
+        'Off' => 'Pois',
+      },
+    },
+   'Highlight' => 'Valoalue',
+   'HighlightData' => 'Valoalueen data',
+   'HighlightProtection' => 'Valoalueen suojaus',
+   'HometownCity' => 'Kotiseutu',
+   'HometownCityCode' => 'Kotiseutukoodi',
+   'HometownDST' => {
+      Description => 'Kotiseudun kesÃ€aika (DST)',
+      PrintConv => {
+        'No' => 'Ei',
+        'Yes' => 'KyllÃ€',
+      },
+    },
+   'HostComputer' => 'IsÃ€ntÃ€tietokone',
+   'Hue' => 'SÃ€vy',
+   'HueAdjustment' => 'VÃ€risÃ€vyn sÃ€Ã€tÃ¶',
+   'HueSetting' => 'SÃ€vyn asetus',
+   'HuffmanTable' => 'Huffman-taulukko',
+   'ICCProfile' => 'ICC-profiili',
+   'ICC_Profile' => 'ICC-syÃ¶tteen vÃ€riprofiili',
+   'IPTC-NAA' => 'IPTC-NAA -metadata',
+   'IPTCBitsPerSample' => 'Bittien mÃ€Ã€rÃ€ per nÃ€yte',
+   'IPTCData' => 'IPTC-data',
+   'IPTCDigest' => 'IPTC-yhteenveto',
+   'IPTCImageHeight' => 'Viivojen mÃ€Ã€rÃ€',
+   'IPTCImageRotation' => {
+      Description => 'Kuvan kierto',
+      PrintConv => {
+        '0' => 'Ei kiertoa',
+        '180' => '180 asteen kierto',
+        '270' => '270 asteen kierto',
+        '90' => '90 asteen kierto',
+      },
+    },
+   'IPTCImageWidth' => 'PikseleitÃ€ per viiva',
+   'IPTCPictureNumber' => 'Kuvan numero',
+   'IPTCPixelHeight' => 'Pikselikoko suorassa kulmassa skannaussuuntaan',
+   'IPTCPixelWidth' => 'Pikselikoko skannaussuunnassa',
+   'ISO' => 'ISO-herkkyys',
+   'ISOAuto' => 'Automaattinen ISO',
+   'ISODisplay' => 'ISO-nÃ€yttÃ¶',
+   'ISOExpansion' => 'ISO-laajennus',
+   'ISOFloor' => 'ISO-alaraja',
+   'ISOInfo' => 'ISO-tiedot',
+   'ISOSelection' => 'ISO-valinta',
+   'ISOSetting' => 'ISO-asetus',
+   'ISOValue' => 'ISO-arvo',
+   'IT8Header' => 'IT8-ylÃ€tunniste',
+   'Illumination' => 'NÃ€ytÃ¶n valaisu',
+   'ImageAdjustment' => 'Kuvan sÃ€Ã€tÃ¶',
+   'ImageAreaOffset' => 'Kuva-alueen siirtymÃ€',
+   'ImageAuthentication' => {
+      Description => 'Kuvan aitoustodennus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'ImageBoundary' => 'Kuvan rajat',
+   'ImageByteCount' => 'Kuvan tavumÃ€Ã€rÃ€',
+   'ImageColorIndicator' => 'Kuvan vÃ€rin ilmaisin',
+   'ImageColorValue' => 'Kuvan vÃ€rin arvo',
+   'ImageCount' => 'KuvamÃ€Ã€rÃ€',
+   'ImageData' => 'Kuvadata',
+   'ImageDataDiscard' => {
+      Description => 'Kuvadatan hylkÃ€ys',
+      PrintConv => {
+        'Flexbits Discarded' => 'FlexBits hylÃ€tty',
+        'Full Resolution' => 'TÃ€ysi resoluutio',
+        'HighPass Frequency Data Discarded' => 'YlipÃ€Ã€stÃ¶taajuusdata hylÃ€tty',
+        'Highpass and LowPass Frequency Data Discarded' => 'Yli- ja alipÃ€Ã€stÃ¶taajuusdata hylÃ€tty',
+      },
+    },
+   'ImageDataSize' => 'Kuvadatan koko',
+   'ImageDepth' => 'Kuvan syvyys',
+   'ImageDescription' => 'Kuvan otsake',
+   'ImageDustOff' => 'Kuvan pÃ¶lynpoisto',
+   'ImageEditCount' => 'Kuvan prosessointimÃ€Ã€rÃ€',
+   'ImageHeight' => 'Kuvan korkeus',
+   'ImageHistory' => 'Kuvahistoria',
+   'ImageID' => 'Kuvan ID',
+   'ImageInfo' => 'Kuvatiedot',
+   'ImageLayer' => 'Kuvataso',
+   'ImageNumber' => 'Tiedostonumero',
+   'ImageOffset' => 'Kuvan siirtrymÃ€',
+   'ImageOptimization' => 'Kuvan optimointi',
+   'ImageOrientation' => {
+      Description => 'Kuvan suunta',
+      PrintConv => {
+        'Landscape' => 'Vaakakuva',
+        'Portrait' => 'Pystykuva',
+        'Square' => 'NeliÃ¶mÃ€inen',
+      },
+    },
+   'ImagePrintStatus' => 'Kuvan tulostuksen tila',
+   'ImageProcessing' => 'Kuvan prosessointi',
+   'ImageProcessingVersion' => 'Kuvaprosessoinnin versio',
+   'ImageQuality' => 'Kuvan laatu',
+   'ImageQuality2' => 'Kuvan laatu 2',
+   'ImageReview' => 'Kuvan tarkastelu',
+   'ImageReviewTime' => 'Kuvan katseluaika',
+   'ImageRotationStatus' => 'Kuvan kierron tila',
+   'ImageSize' => 'Kuvakoko',
+   'ImageSourceData' => 'Kuvan lÃ€hdedata',
+   'ImageSourceEK' => 'EK-kuvalÃ€hde',
+   'ImageStabilization' => {
+      Description => 'Kuvanvakautus',
+      PrintConv => {
+        'Best Shot' => 'Paras kuva',
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+        'On, Mode 1' => 'PÃ€Ã€llÃ€, tapa 1',
+        'On, Mode 2' => 'PÃ€Ã€llÃ€, tapa 2',
+      },
+    },
+   'ImageTone' => {
+      Description => 'Kuvamuoto',
+      PrintConv => {
+        'Bleach Bypass' => 'Bleach bypass -esivalotus',
+        'Bright' => 'Kirkas',
+        'Landscape' => 'Maisema',
+        'Monochrome' => 'YksivÃ€rinen',
+        'Muted' => 'Vaimennettu',
+        'Natural' => 'Luonnollinen',
+        'Portrait' => 'Muotokuva',
+        'Reversal Film' => 'KÃ€Ã€ntÃ¶filmi',
+        'Vibrant' => 'Eloisa',
+      },
+    },
+   'ImageType' => 'Sivu',
+   'ImageUniqueID' => 'Kuvan uniikki ID',
+   'ImageWidth' => 'Kuvan leveys',
+   'Indexed' => 'Indeksoitu',
+   'InkNames' => 'Musteiden nimet',
+   'InkSet' => 'Mustesarja',
+   'IntellectualGenre' => 'Intellektuaalinen genre',
+   'IntelligentAuto' => 'Intelligentti automatiikka',
+   'IntergraphMatrix' => 'Intergraph-matriisi -tagi',
+   'Interlace' => 'Lomitus',
+   'InternalFlash' => {
+      Description => 'SisÃ€inen salama',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'InternalFlashAE1' => 'SisÃ€inen salama AE 1?',
+   'InternalFlashAE1_0' => 'SisÃ€inen salama AE 1 (0)?',
+   'InternalFlashAE2' => 'SisÃ€inen salama AE 2?',
+   'InternalFlashAE2_0' => 'SisÃ€inen salama AE 2 (0)?',
+   'InternalFlashMode' => 'SisÃ€isen salaman tapa',
+   'InternalFlashStrength' => 'SisÃ€isen salaman teho',
+   'InternalFlashTable' => 'SisÃ€isen salaman taulukko',
+   'InternalSerialNumber' => 'SisÃ€inen sarjanumero',
+   'InteropIndex' => {
+      Description => 'Interoperabiliteetin identifiointi',
+      PrintConv => {
+        'R03 - DCF option file (Adobe RGB)' => 'R03: DCF-valintatiedosto (Adobe RGB)',
+        'R98 - DCF basic file (sRGB)' => 'R98: DCF-perustiedosto (sRGB)',
+        'THM - DCF thumbnail file' => 'THM: DCF-nÃ€ytekuvatiedosto',
+      },
+    },
+   'InteropVersion' => 'Interoperabiliteetin versio',
+   'IntervalLength' => 'AjastusvÃ€lin pituus',
+   'IntervalMode' => 'Ajastettu kuvaustapa',
+   'IntervalNumber' => 'Ajastuksen numero',
+   'JFIFVersion' => 'JFIF-versio',
+   'JPEGACTables' => 'JPEG:n AC-taulukot',
+   'JPEGDCTables' => 'JPEG:n DC-taulukot',
+   'JPEGLosslessPredictors' => 'JPEG:n hÃ€viÃ¶ttÃ¶mÃ€t prediktorit',
+   'JPEGPointTransforms' => 'JPEG:n pistemuunnot',
+   'JPEGProc' => 'JPEG-proc',
+   'JPEGQTables' => 'JPEG:n Q-taulukot',
+   'JPEGQuality' => {
+      Description => 'JPEG-laatu',
+      PrintConv => {
+        'Extra Fine' => 'Erityishieno',
+        'Fine' => 'Hieno',
+        'Standard' => 'Normaali',
+        'n/a' => 'Ei asetettu',
+      },
+    },
+   'JPEGRestartInterval' => 'JPEG:n uudelleenaloitusvÃ€li',
+   'JPEGTables' => 'JPEG-taulukot',
+   'JobID' => 'TyÃ¶n ID',
+   'Keyword' => 'Avainsana',
+   'Keywords' => 'Avainsana',
+   'LCDIllumination' => 'LCD:n valaisu',
+   'Language' => 'Kieli',
+   'LanguageIdentifier' => 'Kielen tunnistin',
+   'LastFileNumber' => 'Viimeinen tiedostonumero',
+   'LeafData' => 'Leaf-data',
+   'Lens' => 'Objektiivi',
+   'LensApertureRange' => 'Objektiivin aukkoalue',
+   'LensDataVersion' => 'Objektiividatan versio',
+   'LensDistortionParams' => 'LinssivÃ€Ã€ristymÃ€n parametrit',
+   'LensFStops' => 'Objektiivin aukkoarvot',
+   'LensFirmwareVersion' => 'Objektiivin laiteohjelmistoversio',
+   'LensID' => 'Objektiivin ID',
+   'LensIDNumber' => 'Objektiivin ID-numero',
+   'LensInfo' => 'Objektiivin tiedot',
+   'LensSerialNumber' => 'Objektiivin sarjanumero',
+   'LensTemperature' => 'Objektiivin lÃ€mpÃ¶tila',
+   'LensType' => 'Objektiivityyppi',
+   'LightCondition' => 'Valaistusolot',
+   'LightReading' => 'Valolukema',
+   'LightSource' => {
+      Description => 'ValonlÃ€hde',
+      PrintConv => {
+        'Cloudy' => 'Pilvinen',
+        'Cool White Fluorescent' => 'ViileÃ€ valkoinen loistelamppu (W 3900 - 4500K)',
+        'Day White Fluorescent' => 'Valkoinen pÃ€ivÃ€nvaloloistelamppu (N 4600 - 5400K)',
+        'Daylight' => 'PÃ€ivÃ€nvalo',
+        'Daylight Fluorescent' => 'PÃ€ivÃ€nvaloloistelamppu (D 5700 - 7100K)',
+        'Fine Weather' => 'PilvetÃ¶n',
+        'Flash' => 'Salama',
+        'Fluorescent' => 'Loistevalo',
+        'ISO Studio Tungsten' => 'ISO studiokeinovalo (hehkulamppu)',
+        'Other' => 'Muu valonlÃ€hde',
+        'Shade' => 'Varjo',
+        'Standard Light A' => 'Standardivalo A',
+        'Standard Light B' => 'Standardivalo B',
+        'Standard Light C' => 'Standardivalo C',
+        'Tungsten (Incandescent)' => 'Keinovalo (hehkulamppu)',
+        'Unknown' => 'Tuntematon',
+        'White Fluorescent' => 'LÃ€mmin valkoinen loistelamppu (WW 3200 - 3700K)',
+      },
+    },
+   'LightSourceSpecial' => {
+      Description => 'ErikoisvalonlÃ€hde',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'LinearResponseLimit' => 'Lineaarisen vasteen raja',
+   'LinearizationTable' => 'Linearisaatiotaulukko',
+   'LiveViewAF' => 'SuoranÃ€yttÃ¶-AF',
+   'LocalizedCameraModel' => 'Lokalisoitu kameramalli',
+   'Location' => 'Sijainti',
+   'LongExposureNoiseReduction' => {
+      Description => 'Pitkien valotusten kohinan vaimennus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+        'n/a' => 'Ei asetettu',
+      },
+    },
+   'LookupTable' => 'Hakutaulukko',
+   'Luminance' => 'Luminanssi',
+   'MB-D10BatteryType' => 'MB-D10 -paristotyyppi',
+   'MB-D80Batteries' => 'MB-D80 -paristot',
+   'MCUVersion' => 'MCU-versio',
+   'Macro' => {
+      Description => 'Makro',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+        'n/a' => 'Ei asetettu',
+      },
+    },
+   'MacroMode' => {
+      Description => 'Makrotapa',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+        'Super Macro' => 'Supermakro',
+        'Tele-Macro' => 'Telemakro',
+      },
+    },
+   'Magnification' => 'Suurennus',
+   'Make' => 'Valmistaja',
+   'MakeAndModel' => 'Valmistaja ja malli',
+   'MakerNote' => 'DNG-erityistiedot',
+   'MakerNoteOffset' => 'Valmistajatietojen siirtymÃ€',
+   'MakerNoteSafety' => {
+      Description => 'Valmistatietojen turvallisuus',
+      PrintConv => {
+        'Safe' => 'Turvallinen',
+        'Unsafe' => 'Turvaton',
+      },
+    },
+   'MakerNoteType' => 'Valmistajatietojen tyyppi',
+   'MakerNoteVersion' => 'Valmistajatietojen versio',
+   'ManometerPressure' => 'Manometrin ilmaisema paine',
+   'ManualFlash' => 'Manuaalinen salama',
+   'ManualFlashOutput' => 'Salaman kÃ€sisÃ€Ã€tÃ¶',
+   'ManualFocusDistance' => 'Manuaalinen etÃ€isyydensÃ€Ã€tÃ¶',
+   'ManufactureDate' => 'ValmistuspÃ€ivÃ€ys',
+   'MaskedAreas' => 'Maskilliset alueet',
+   'MasterDocumentID' => 'AlkuperÃ€isdokumentin ID',
+   'MasterGain' => 'Yleisvahvistus',
+   'MatrixMetering' => 'Matriisimittaus',
+   'Matteing' => 'Mattaus',
+   'MaxAperture' => 'Suurin aukko',
+   'MaxApertureAtCurrentFocal' => 'Suurin aukko nykyisellÃ€ polttovÃ€lillÃ€',
+   'MaxApertureAtMaxFocal' => 'Suurin aukko pisimmÃ€llÃ€ polttovÃ€lillÃ€',
+   'MaxApertureAtMinFocal' => 'Suurin aukko lyhimmÃ€llÃ€ polttovÃ€lillÃ€',
+   'MaxApertureValue' => 'Objektiivin maksimiaukko',
+   'MaxFocalLength' => 'Pisin polttovÃ€li',
+   'MaxSampleValue' => 'NÃ€ytteen maksimiarvo',
+   'MaximumDensityRange' => 'Tiheyden maksimilaajuus',
+   'MeasuredEV' => 'Mitattu EV',
+   'MeasurementBacking' => 'Mittaustuenta',
+   'MeasurementFlare' => 'Hajavalomittaus',
+   'MeasurementGeometry' => 'Mittausgeometria',
+   'MeasurementIlluminant' => 'Valaistusmittaus',
+   'MeasurementObserver' => 'Mittauksen tarkkailija',
+   'MediaBlackPoint' => 'Median musta piste',
+   'MediaWhitePoint' => 'Median valkoinen piste',
+   'Medium' => 'Keskikokoa',
+   'MetadataNumber' => 'Metadatan mÃ€Ã€rÃ€',
+   'Metering' => 'Valonmittaus',
+   'MeteringMode' => {
+      Description => 'Valonmittaustapa',
+      PrintConv => {
+        'Average' => 'Keskiarvo',
+        'Center-weighted average' => 'Keskustapainotteinen keskiarvo',
+        'Multi-segment' => 'Monisegmenttimittaus',
+        'Multi-spot' => 'Monipiste',
+        'Other' => 'Muu',
+        'Partial' => 'Osa-alue',
+        'Pattern+AF' => 'Kuvio + AF',
+        'Spot' => 'Pistemittaus',
+        'Spot+Highlight control' => 'Pistemittaus + valoalueen sÃ€Ã€tÃ¶',
+        'Spot+Shadow control' => 'Pistemittaus + varjoalueen sÃ€Ã€tÃ¶',
+        'Unknown' => 'Tuntematon',
+      },
+    },
+   'MeteringTime' => 'Mittausaika',
+   'MinAperture' => 'Pienin aukko',
+   'MinFocalLength' => 'Lyhin polttovÃ€li',
+   'MinSampleValue' => 'NÃ€ytteen minimiarvo',
+   'MinoltaCameraSettings2' => 'Kameran asetukset 2',
+   'MinoltaCameraSettings5D' => 'Kameran asetukset (5D)',
+   'MinoltaCameraSettings7D' => 'Kamera-asetukset (7D)',
+   'MinoltaMakerNote' => 'Minolta-valmistajatiedot',
+   'MinoltaQuality' => {
+      Description => 'Kuvakoko',
+      PrintConv => {
+        'Economy' => 'Taloudellinen',
+        'Extra fine' => 'Erityishieno',
+        'Fine' => 'Hieno',
+        'Standard' => 'Normaali',
+        'Super Fine' => 'Superhieno',
+      },
+    },
+   'Model' => 'Malli',
+   'Model2' => 'KuvasyÃ¶telaitteen malli (2)',
+   'ModelAndVersion' => 'Malli ja versio',
+   'ModelID' => 'Mallin ID',
+   'ModelTiePoint' => 'Sidospistemalli-tagi',
+   'ModelTransform' => 'Muuntomalli-tagi',
+   'ModelingFlash' => 'Mallinnussalama',
+   'ModifiedDigitalGain' => 'Modifioitu digitaalinen vahvistus',
+   'ModifiedInfo' => 'Modifioidut tiedot',
+   'ModifiedParamFlag' => 'Modifioitu parametrilippu',
+   'ModifiedPictureStyle' => 'Modifioitu kuvan tyyli',
+   'ModifiedSaturation' => {
+      Description => 'Modifoitu vÃ€rikyllÃ€isyys',
+      PrintConv => {
+        'CM1 (Red Enhance)' => 'CM1 (punaisen parantelu)',
+        'CM2 (Green Enhance)' => 'CM2 (vihreÃ€n parantelu)',
+        'CM3 (Blue Enhance)' => 'CM3 (sinisen parantelu)',
+        'CM4 (Skin Tones)' => 'CM4 (ihonvÃ€rin parantelu)',
+        'Off' => 'Pois',
+      },
+    },
+   'ModifiedSensorBlueLevel' => 'Modifioitu anturin sinitaso',
+   'ModifiedSensorRedLevel' => 'Modifioitu anturin punataso',
+   'ModifiedSharpness' => 'Modifioitu terÃ€vyys',
+   'ModifiedToneCurve' => 'Modifioitu sÃ€vykÃ€yrÃ€',
+   'ModifiedWhiteBalance' => 'Modifioitu valkotasapaino',
+   'ModifiedWhiteBalanceBlue' => 'Modifioitu valkotasapainon sininen',
+   'ModifiedWhiteBalanceRed' => 'Modifioitu valkotasapainon punainen',
+   'ModifyDate' => 'Tiedostomuutoksen pÃ€ivÃ€ys ja aika',
+   'MultiExposure' => 'Monivalotusdata',
+   'MultiExposureAutoGain' => 'Monivalotuksen automaattivalotus',
+   'MultiExposureMode' => 'Monivalotustapa',
+   'MultiExposureShots' => 'Monivalotusotoksia',
+   'MultiExposureVersion' => 'Monivalotusdatan versio',
+   'MultiSample' => 'MoninÃ€yte',
+   'MultiSelector' => 'Monivalitsin',
+   'MultipleExposureSet' => 'Monivalotus',
+   'MyColorMode' => 'Oma vÃ€rimuoto',
+   'NDFilter' => 'ND-suodin',
+   'NEFLinearizationTable' => 'Linearisaatiotaulukko',
+   'NamedColor2' => 'Nimetty vÃ€ri 2',
+   'NativeDisplayInfo' => 'Paikallisen nÃ€ytÃ¶n tiedot',
+   'NativeResolutionUnit' => 'Paikallisen resoluution yksikkÃ¶',
+   'NativeXResolution' => 'Paikallinen vaakaresoluutio',
+   'NativeYResolution' => 'Paikallinen pystyresoluutio',
+   'NikonCaptureData' => 'Nikon Capture -data',
+   'NikonCaptureOffsets' => 'Nikon Capture -siirtymÃ€t',
+   'NikonCaptureOutput' => 'Nikon Capture -tuotos',
+   'NikonCaptureVersion' => 'Nikon Capture -versio',
+   'NikonICCProfile' => 'Nikon ICC-profiilin osoitin',
+   'NoMemoryCard' => 'Ei muistikorttia',
+   'Noise' => 'Kohina',
+   'NoiseFilter' => 'Kohinasuodin',
+   'NoiseReduction' => {
+      Description => 'Kohinan vÃ€hennys',
+      PrintConv => {
+        'High (+1)' => '+1 (korkea)',
+        'Highest (+2)' => '+2 (korkein)',
+        'Low' => 'Matala',
+        'Low (-1)' => '-1 (matala)',
+        'Lowest (-2)' => '-2 (matalin)',
+        'Normal' => 'Vakio',
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+        'Standard' => 'Â±0 (vakio)',
+      },
+    },
+   'NoiseReductionApplied' => 'Suoritettu kohinan vÃ€hennys',
+   'NoiseReductionData' => 'Kohinanvaimennusdata',
+   'NoiseReductionIntensity' => 'Kohinanvaimennuksen voimakkuus',
+   'NoiseReductionMethod' => 'Kohinanvaimennusmetodi',
+   'NoiseReductionSharpness' => 'Kohinanvaimennuksen terÃ€vyys',
+   'NumIndexEntries' => 'IndeksimerkintÃ¶jen mÃ€Ã€rÃ€',
+   'NumberOfChannels' => 'Kanavien mÃ€Ã€rÃ€',
+   'NumberofInks' => 'Musteiden numerot',
+   'OPIProxy' => 'OPI-vÃ€lipalvelin',
+   'ObjectAttributeReference' => 'Intellektuaalinen genre',
+   'ObjectCycle' => {
+      Description => 'Objektin sykli',
+      PrintConv => {
+        'Both Morning and Evening' => 'Molempina',
+        'Evening' => 'Iltaisin',
+        'Morning' => 'Aamuisin',
+      },
+    },
+   'ObjectDistance' => 'Kohteen etÃ€isyys',
+   'ObjectName' => 'Nimike',
+   'ObjectPreviewData' => 'Objektidatan esikatseludata',
+   'ObjectPreviewFileFormat' => 'Objektidatan esikatselun tiedostomuoto',
+   'ObjectPreviewFileVersion' => 'Objektidatan esikatselun tiedostomuodon versio',
+   'ObjectTypeReference' => 'Objektyypin viiteryhmÃ€',
+   'OffsetSchema' => 'SiirtymÃ€skeema',
+   'OlympusImageHeight' => 'Kuvan korkeus',
+   'OlympusImageWidth' => 'Kuvan leveys',
+   'OneTouchWB' => {
+      Description => 'Pikavalkotasapaino',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+        'On (Preset)' => 'PÃ€Ã€llÃ€ (esiasetus)',
+      },
+    },
+   'OpticalZoomCode' => 'Optisen zoomin koodi',
+   'OpticalZoomMode' => {
+      Description => 'Optinen zoomaustapa',
+      PrintConv => {
+        'Extended' => 'Laajennettu',
+        'Standard' => 'Vakio',
+      },
+    },
+   'OpticalZoomOn' => {
+      Description => 'Optinen zoom',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'Opto-ElectricConvFactor' => 'Optoelektrinen muuntokerroin',
+   'OrderNumber' => 'Valokuva-CD:n ostotilausnumero',
+   'Orientation' => {
+      Description => 'Kuvan suunta',
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (ylÃ€/vasen)',
+        'Mirror horizontal' => '0Â° (ylÃ€/oikea)',
+        'Mirror horizontal and rotate 270 CW' => '90Â° myÃ¶tÃ€pÃ€ivÃ€Ã€n (vasen/ylÃ€)',
+        'Mirror horizontal and rotate 90 CW' => '90Â° vastapÃ€ivÃ€Ã€n (oikea/ala)',
+        'Mirror vertical' => '180Â° (ala/vasen)',
+        'Rotate 180' => '180Â° (ala/oikea)',
+        'Rotate 270 CW' => '90Â° myÃ¶tÃ€pÃ€ivÃ€Ã€n (vasen/ala)',
+        'Rotate 90 CW' => '90Â° vastapÃ€ivÃ€Ã€n (oikea/ylÃ€)',
+      },
+    },
+   'OriginalDecisionDataOffset' => 'AlkuperÃ€isen ratkaisudatan siirtymÃ€',
+   'OriginalRawFileData' => 'Originaali raw-tiedoston data',
+   'OriginalRawFileDigest' => 'AlkuperÃ€isen raw-tiedoston tiivistelmÃ€',
+   'OriginalRawFileName' => 'Originaali raw-tiedoston nimi',
+   'OriginalTransmissionReference' => 'TehtÃ€vÃ€n tunnistin',
+   'OriginatingProgram' => 'Luontiohjelma',
+   'OutputImageHeight' => 'Tuotoskuvan korkeus',
+   'OutputImageWidth' => 'Tuotoskuvan leveys',
+   'OutputResolution' => 'Tuotoksen resoluutio',
+   'OutputResponse' => 'Tuotosvaste',
+   'OwnerID' => 'Omistajan ID',
+   'OwnerName' => 'Omistajan nimi',
+   'Padding' => 'TÃ€yte',
+   'PageName' => 'Sivun nimi',
+   'PageNumber' => 'Sivunumero',
+   'PanasonicExifVersion' => 'Panasonic-exif -versio',
+   'PanasonicRawVersion' => 'Panasonic-RAW:n versio',
+   'PanasonicTitle' => 'Otsikko',
+   'PanoramaDirection' => 'Panoraaman suunta',
+   'PanoramaMode' => 'Panoraamatapa',
+   'PentaxImageSize' => {
+      Description => 'Pentax-kuvakoko',
+      PrintConv => {
+        '2304x1728 or 2592x1944' => '2304 x 1728 tai 2592 x 1944',
+        '2560x1920 or 2304x1728' => '2560 x 1920 tai 2304 x 1728',
+        '2816x2212 or 2816x2112' => '2816 x 2212 tai 2816 x 2112',
+        '3008x2008 or 3040x2024' => '3008 x 2008 tai 3040 x 2024',
+        'Full' => 'TÃ€ysi',
+      },
+    },
+   'PentaxVersion' => 'Pentax-versio',
+   'People' => 'Ihmiset',
+   'PeripheralLighting' => 'Oheislaitevalaistus',
+   'PeripheralLightingSetting' => 'Oheislaitevalaistuksen asetus',
+   'PeripheralLightingValue' => 'Oheislaitevalaistuksen arvo',
+   'PhotoEffect' => 'Valokuvaefekti',
+   'PhotoEffects' => 'Valokuvaefektit',
+   'PhotoEffectsBlue' => 'Valokuvaefekti sininen',
+   'PhotoEffectsData' => 'Valokuvaefektidata',
+   'PhotoEffectsGreen' => 'Valokuvaefekti vihreÃ€',
+   'PhotoEffectsRed' => 'Valokuvaefekti punainen',
+   'PhotoEffectsType' => 'Valokuvaefektityyppi',
+   'PhotometricInterpretation' => {
+      Description => 'Pikseliskeema',
+      PrintConv => {
+        'BlackIsZero' => 'Musta on nolla',
+        'Color Filter Array' => 'CFA (vÃ€risuodinmatriisi)',
+        'Pixar LogL' => 'CIE Log2(L) (Log-luminanssi)',
+        'Pixar LogLuv' => 'CIE Log2(L)(u\',v\') (Log-luminanssi ja -krominanssi)',
+        'RGB Palette' => 'VÃ€ripaletti',
+        'Transparency Mask' => 'LÃ€pinÃ€kyvyysmaski',
+        'WhiteIsZero' => 'Valkoinen on nolla',
+      },
+    },
+   'PhotoshopBGRThumbnail' => 'Photoshopin BRG-nÃ€ytekuva',
+   'PhotoshopFormat' => 'Photoshop-muoto',
+   'PhotoshopQuality' => 'Photoshop-laatu',
+   'PictInfo' => 'Kuvatiedot',
+   'PictureControl' => 'Kuvan optimointi',
+   'PictureControlActive' => 'Kuvan kÃ€sittely aktivoitu',
+   'PictureControlAdjust' => 'Kuvan optimoinnin sÃ€Ã€tÃ¶',
+   'PictureControlBase' => 'Kuvan perusoptimointi',
+   'PictureControlData' => 'Kuvan kÃ€sittely',
+   'PictureControlMode' => 'Kuvan kÃ€sittelytapa',
+   'PictureControlName' => 'Kuvan optimoinnin nimi',
+   'PictureControlQuickAdjust' => 'Kuvan optimoinnin pikasÃ€Ã€tÃ¶',
+   'PictureControlVersion' => 'Kuvan optimoinnin versio',
+   'PictureFinish' => 'Kuvan viimeistely',
+   'PictureMode' => {
+      Description => 'Kuvausohjelma',
+      PrintConv => {
+        'Anti-blur' => 'EpÃ€tarkkuden vÃ€hennys',
+        'Aperture-priority AE' => 'Aukon esivalinta AE',
+        'Auto' => 'Automaattinen',
+        'Beach' => 'Hiekkaranta',
+        'Beach & Snow' => 'Hiekkaranta & Lumi',
+        'Fireworks' => 'Ilotulitus',
+        'Flower' => 'Kukka',
+        'Landscape' => 'Maisema',
+        'Macro' => 'LÃ€hikuva (Kukka)',
+        'Manual' => 'Manuaalinen',
+        'Museum' => 'Museo',
+        'Natural Light' => 'Luonnonvalo',
+        'Natural Light & Flash' => 'Luonnonvalo & Salama',
+        'Night Scene' => 'YÃ¶',
+        'Party' => 'Juhlat',
+        'Portrait' => 'Muotokuva',
+        'Program AE' => 'Automaattinen valotusohjelma',
+        'Shutter speed priority AE' => 'Ajan esivalinta AE',
+        'Snow' => 'Lumi',
+        'Sports' => 'Urheilu',
+        'Sunset' => 'Auringonlasku',
+        'Text' => 'Teksti',
+        'Underwater' => 'Veden alla',
+      },
+    },
+   'PictureMode2' => 'Kuvamuoto 2',
+   'PictureModeBWFilter' => {
+      Description => 'BW-suodin -kuvamuoto',
+      PrintConv => {
+        'Green' => 'VihreÃ€',
+        'Neutral' => 'Neutraali',
+        'Orange' => 'Oranssi',
+        'Red' => 'Punainen',
+        'Yellow' => 'Keltainen',
+        'n/a' => 'E.s.',
+      },
+    },
+   'PictureModeContrast' => 'Kontrastinen kuvamuoto',
+   'PictureModeHue' => 'SÃ€vykÃ€s kuvamuoto?',
+   'PictureModeSaturation' => 'VÃ€rikyllÃ€inen kuvamuoto',
+   'PictureModeSharpness' => 'TerÃ€vÃ€ kuvamuoto',
+   'PictureModeTone' => {
+      Description => 'Vivahteikas kuvamuoto',
+      PrintConv => {
+        'Blue' => 'Sininen',
+        'Green' => 'VihreÃ€',
+        'Neutral' => 'Neutraali',
+        'Purple' => 'Violetti',
+        'Sepia' => 'Seepia',
+        'n/a' => 'E.s.',
+      },
+    },
+   'PictureStyle' => 'Kuvan tyyli',
+   'PixelAspectRatio' => 'Pikselien kokosuhde',
+   'PixelFormat' => 'Pikseliformaatti',
+   'PixelIntensityRange' => 'Pikseli-intensiteetin alue',
+   'PixelScale' => 'Pikseliasteikkomalli-tagi',
+   'PlanarConfiguration' => {
+      Description => 'Kuvadatan jÃ€rjestys',
+      PrintConv => {
+        'Chunky' => 'Lohkoformaatti (lomitettu)',
+        'Planar' => 'Tasoformaatti',
+      },
+    },
+   'PlaybackMenusTime' => 'Toistovalikkojen aika',
+   'PowerSource' => 'VirtalÃ€hde',
+   'PreCaptureFrames' => 'Esiasetetut kehykset',
+   'Predictor' => {
+      Description => 'Prediktori',
+      PrintConv => {
+        'Horizontal differencing' => 'Horisontaalinen differointi',
+        'None' => 'Prediktioskeemaa ei kÃ€ytetty ennen koodausta',
+      },
+    },
+   'Preview' => 'Esikatselu',
+   'Preview0' => 'Esikatselu 0',
+   'Preview1' => 'Esikatselu 1',
+   'Preview2' => 'Esikatselu 2',
+   'PreviewApplicationName' => 'Sovelluksen nimen esikatselu',
+   'PreviewApplicationVersion' => 'Sovellusversion esikatselu',
+   'PreviewColorSpace' => {
+      Description => 'VÃ€riavaruuden esikatselu',
+      PrintConv => {
+        'Unknown' => 'Tuntematon',
+      },
+    },
+   'PreviewDateTime' => 'PÃ€ivÃ€yksen ja ajan esikatselu',
+   'PreviewImage' => 'Kuvan esikatselu',
+   'PreviewImageBorders' => 'Kuvan reunojen esikatselu',
+   'PreviewImageData' => 'Kuvadatan tarkastelu',
+   'PreviewImageLength' => 'Kuvan pituuden esikatselu',
+   'PreviewImageSize' => 'Kuvakoon esikatselu',
+   'PreviewImageStart' => 'Esikatselukuvan alku',
+   'PreviewImageValid' => {
+      Description => 'Kelvollinen esikatselukuva',
+      PrintConv => {
+        'No' => 'Ei',
+        'Yes' => 'KyllÃ€',
+      },
+    },
+   'PreviewSettingsDigest' => 'AsetustiivistelmÃ€n esikatselu',
+   'PreviewSettingsName' => 'Asetusten nimen esikatselu',
+   'PrimaryAFPoint' => 'Ensisijainen AF-piste',
+   'PrimaryChromaticities' => 'PÃ€Ã€vÃ€rien kromaattisuudet',
+   'PrimaryPlatform' => 'Primaari alusta',
+   'PrintQuality' => 'Tulostuslaatu',
+   'ProcessingInfo' => 'Prosessointitiedot',
+   'ProcessingSoftware' => 'Prosessointiohjelmisto',
+   'ProductID' => 'Tuotteen ID',
+   'ProfileCMMType' => 'CMM-tyypin profiili',
+   'ProfileCalibrationSig' => 'Profiilin kalibrointitunniste',
+   'ProfileClass' => 'Profiilin luokka',
+   'ProfileConnectionSpace' => 'Profiilin yhteystila',
+   'ProfileCopyright' => 'Profiilin copyright',
+   'ProfileCreator' => 'Profiilin luoja',
+   'ProfileDateTime' => 'Profiilin pÃ€ivÃ€ysaika',
+   'ProfileDescription' => 'Profiilin kuvaus',
+   'ProfileDescriptionML' => 'Monikieliprofiilin kuvaus',
+   'ProfileEmbedPolicy' => {
+      Description => 'Profiilin upotusmenetelmÃ€',
+      PrintConv => {
+        'Allow Copying' => 'Salli kopiointi',
+        'Embed if Used' => 'Upota jos kÃ€ytÃ¶ssÃ€',
+        'Never Embed' => 'ÃlÃ€ koskaan upota',
+        'No Restrictions' => 'Ei rajoituksia',
+      },
+    },
+   'ProfileFileSignature' => 'Profiilidatan tunniste',
+   'ProfileHueSatMapData1' => 'Profiilin SÃ€vy VÃ€rik. -kartan data 1',
+   'ProfileHueSatMapData2' => 'Profiilin SÃ€vy VÃ€rik. -kartan data 2',
+   'ProfileID' => 'Profiilin ID',
+   'ProfileLookTableData' => 'Profiilin hakutaulukon data',
+   'ProfileName' => 'Profiilin nimi',
+   'ProfileSequenceDesc' => 'Profiilisarjan kuvaus',
+   'ProfileToneCurve' => 'Profiilin toonin kÃ€yrÃ€',
+   'ProfileVersion' => 'Profiilin versio',
+   'ProgramISO' => 'Ohjelma-ISO',
+   'ProgramLine' => 'Valotusohjelma',
+   'ProgramMode' => 'Ohjelman muoto',
+   'ProgramShift' => 'Ohjelmasiirto',
+   'ProgramVersion' => 'Ohjelmaversio',
+   'ProgressiveScans' => 'Progressiiviset skannaukset',
+   'Province-State' => 'Provinssi/Valtio',
+   'Quality' => {
+      Description => 'Laatu',
+      PrintConv => {
+        'Best' => 'Paras',
+        'Better' => 'Parempi',
+        'Compressed RAW' => 'Pakattu RAW',
+        'Compressed RAW + JPEG' => 'Pakattu RAW + JPEG',
+        'Economy' => 'Taloudellinen',
+        'Extra Fine' => 'Erityishieno',
+        'Fine' => 'Hieno',
+        'Good' => 'HyvÃ€',
+        'Normal' => 'Normaali',
+        'Standard' => 'Vakio',
+        'Super Fine' => 'Superhieno',
+        'n/a' => 'Ei asetettu',
+      },
+    },
+   'Quality2' => 'Laatu 2',
+   'QualityMode' => {
+      Description => 'Kuvalaatu',
+      PrintConv => {
+        'Economy' => 'Taloudellinen',
+        'Fine' => 'Hieno',
+        'Normal' => 'Normaali',
+      },
+    },
+   'QuantizationMethod' => {
+      Description => 'Kvantisointimetodi',
+      PrintConv => {
+        'AP Domestic Analogue' => 'AP domestinen analogia',
+        'Color Space Specific' => 'ErityisvÃ€riavaruus',
+        'Compression Method Specific' => 'Erityispakkausmetodi',
+        'Gamma Compensated' => 'Kompensoitu gamma',
+        'IPTC Ref B' => 'IPTC ref "B"',
+        'Linear Density' => 'Lineaarinen tiheys',
+        'Linear Dot Percent' => 'Lineaarinen pisteprosentti',
+        'Linear Reflectance/Transmittance' => 'Lineaarinen heijastavuus/lÃ€pÃ€isevyys',
+      },
+    },
+   'QuickAdjust' => 'PikasÃ€Ã€tÃ¶',
+   'QuickShot' => {
+      Description => 'Pikakuvaus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'ROCInfo' => 'ROC-tiedot',
+   'RangeFinder' => 'Alue-etsin',
+   'RasterPadding' => 'RasteritÃ€yte',
+   'RasterizedCaption' => 'Rasteroitu seloste',
+   'Rating' => 'Arvostelu',
+   'RawDataOffset' => 'RAW-datan siirtymÃ€',
+   'RawDataUniqueID' => 'Raw-datan uniikki ID',
+   'RawDevColorSpace' => 'VÃ€riavaruus',
+   'RawDevContrastValue' => 'Kontrastiarvo',
+   'RawDevEditStatus' => {
+      Description => 'Editointitila',
+      PrintConv => {
+        'Edited (Landscape)' => 'Studio (maisema)',
+        'Edited (Portrait)' => 'Studio (muotokuva)',
+        'Original' => 'AlkuperÃ€inen',
+      },
+    },
+   'RawDevEngine' => {
+      Description => 'Moottori',
+      PrintConv => {
+        'Advanced High Speed' => 'Edistynyt suurnopeus',
+        'High Function' => 'HyvÃ€ suorituskyky',
+        'High Speed' => 'Suurnopeus',
+      },
+    },
+   'RawDevExposureBiasValue' => 'Valotuksen korjausarvo',
+   'RawDevGrayPoint' => 'Harmaapiste',
+   'RawDevMemoryColorEmphasis' => 'MuistivÃ€rin korostus',
+   'RawDevNoiseReduction' => 'Kohinasuodin (ISO-tehostus)',
+   'RawDevSaturationEmphasis' => 'VÃ€rikyllÃ€isyyden korostus',
+   'RawDevSettings' => 'Kohinanvaimennus',
+   'RawDevSharpnessValue' => 'Kontrastiarvo',
+   'RawDevVersion' => 'RAW-kehityksen versio',
+   'RawDevWBFineAdjustment' => 'Valkotasapainon hienosÃ€Ã€tÃ¶',
+   'RawDevWhiteBalanceValue' => 'Valkotasapainon arvo',
+   'RawImageCenter' => 'RAW-kuvan keskusta',
+   'RawImageDigest' => 'RAW-kuvan tiivistelmÃ€',
+   'RawImageHeight' => 'Kuvan korkeus',
+   'RawImageSize' => 'RAW-kuvakoko',
+   'RawImageWidth' => 'Kuvan leveys',
+   'RawInfoVersion' => 'RAW Info -versio',
+   'RecognizedFace1Age' => 'Tunnistettujen kasvojen 1 ikÃ€',
+   'RecognizedFace1Name' => 'Tunnistettujen kasvojen 1 nimi',
+   'RecognizedFace1Position' => 'Tunnistettujen kasvojen 1 sijainti',
+   'RecognizedFace2Age' => 'Tunnistettujen kasvojen 2 ikÃ€',
+   'RecognizedFace2Name' => 'Tunnistettujen kasvojen 2 nimi',
+   'RecognizedFace2Position' => 'Tunnistettujen kasvojen 2 sijainti',
+   'RecognizedFace3Age' => 'Tunnistettujen kasvojen 2 ikÃ€',
+   'RecognizedFace3Name' => 'Tunnistettujen kasvojen 3 nimi',
+   'RecognizedFace3Position' => 'Tunnistettujen kasvojen 3 sijainti',
+   'RecognizedFaceFlags' => 'Tunnistettujen kasvojen liput',
+   'RecordMode' => {
+      Description => 'Tallennustapa',
+      PrintConv => {
+        'Aperture Priority' => 'Aukon esivalinta',
+        'Best Shot' => 'Paras kuva',
+        'Manual' => 'Manuaalinen',
+        'Movie' => 'Elokuva',
+        'Movie (19)' => 'Elokuva (19)',
+        'Program AE' => 'AE-ohjelma',
+        'Shutter Priority' => 'Ajan esivalinta',
+        'YouTube Movie' => 'YouTube-elokuva',
+      },
+    },
+   'RecordShutterRelease' => {
+      Description => 'Laukaisujen tallennus',
+      PrintConv => {
+        'Press start, press stop' => 'Aloitus painaen, lopetus painaen',
+        'Record while down' => 'Tallennus laukaisin alhaalla',
+      },
+    },
+   'RecordingMode' => 'Tallennustapa',
+   'RedBalance' => 'Punatasapaino',
+   'RedEyeCorrection' => 'PunasilmÃ€korjaus',
+   'RedEyeData' => 'PunasilmÃ€data',
+   'RedMatrixColumn' => 'Punaisen matriisin sarake',
+   'RedTRC' => 'Punaisen toonin toistokÃ€yrÃ€',
+   'RedX' => 'Punainen X',
+   'RedY' => 'Punainen Y',
+   'ReductionMatrix1' => 'Reduktiomatriisi 1',
+   'ReductionMatrix2' => 'Reduktiomatriisi 2',
+   'ReferenceBlackWhite' => 'Musta ja valkoinen viitearvopari',
+   'ReferenceDate' => 'ViitepÃ€ivÃ€ys',
+   'ReferenceNumber' => 'Viitenumero',
+   'ReferenceService' => 'Viitepalvelu',
+   'RelatedImageFileFormat' => 'Kuvatiedoston muoto',
+   'RelatedImageHeight' => 'Kuvan korkeus',
+   'RelatedImageWidth' => 'Kuvan leveys',
+   'RelatedSoundFile' => 'Asiaan liittyvÃ€ audiotiedosto',
+   'ReleaseButtonToUseDial' => 'KÃ€ytÃ€ valitsinta vapauttaen painike',
+   'ReleaseDate' => 'JulkaisupÃ€ivÃ€ys',
+   'ReleaseMode' => 'Laukaisutapa',
+   'ReleaseTime' => 'Julkaisuaika',
+   'RemoteOnDuration' => 'Kaukolaukaisin',
+   'RenderingIntent' => 'MuokkausmenetelmÃ€',
+   'Resaved' => {
+      Description => 'Tallennus uudelleen',
+      PrintConv => {
+        'No' => 'Ei',
+        'Yes' => 'KyllÃ€',
+      },
+    },
+   'ResolutionMode' => 'Resoluutiomuoto',
+   'ResolutionUnit' => {
+      Description => 'X- ja Y-resoluution yksikkÃ¶',
+      PrintConv => {
+        'None' => 'Ei mitÃ€Ã€n',
+        'inches' => 'Tuuma',
+      },
+    },
+   'RetouchHistory' => 'Korjailuhistoria',
+   'ReverseIndicators' => 'KÃ€Ã€nteiset ilmaisimet',
+   'RevisionNumber' => 'Revision numero',
+   'RollGuidElements' => 'Guid-elementtien vieritys',
+   'Rotation' => {
+      Description => 'Kierto',
+      PrintConv => {
+        'Horizontal (normal)' => 'Vaakatasossa (normaali)',
+        'Rotate 270 CW' => 'Kierto 90Â° VP',
+        'Rotate 90 CW' => 'Kierto 90Â° MP',
+      },
+    },
+   'RowInterleaveFactor' => 'Rivin lomitusfaktori',
+   'RowsPerStrip' => 'Rivien mÃ€Ã€rÃ€ per strippi',
+   'SBAExposureRecord' => 'SBA-valotuksen tallennus',
+   'SBAInputImageBitDepth' => 'SBA-syÃ¶tekuvan bittisyvyys',
+   'SBAInputImageColorspace' => 'SBA-syÃ¶tekuvan vÃ€riavaruus',
+   'SMaxSampleValue' => 'S-maksimiminÃ€ytteen arvo',
+   'SMinSampleValue' => 'S-miniminÃ€ytteen arvo',
+   'SRFocalLength' => 'Vakain (SR) eri polttovÃ€leillÃ€',
+   'SRResult' => 'Kuvanvakain',
+   'SampleFormat' => 'NÃ€yteformaatti',
+   'SampleStructure' => {
+      Description => 'NÃ€ytteiden rakenne',
+      PrintConv => {
+        'CompressionDependent' => 'MÃ€Ã€ritetty pakkaustoiminnon yhteydessÃ€',
+        'Orthogonal4-2-2Sampling' => 'Toisistaan riippumattomat nÃ€ytetaajuuksin suhteessa 4:2:2:(4)',
+        'OrthogonalConstangSampling' => 'Toisistaan riippumattomat samoin suhteellisin nÃ€ytetaajuuksin kussakin komponentissa',
+      },
+    },
+   'SamplesPerPixel' => 'Komponenttien mÃ€Ã€rÃ€',
+   'SanyoQuality' => {
+      Description => 'Sanyo-laatu',
+      PrintConv => {
+        'Fine/High' => 'Hieno/korkea',
+        'Fine/Low' => 'Hieno/matala',
+        'Fine/Medium' => 'Hieno/keskilaatu',
+        'Fine/Medium High' => 'Hieno/korkeahko',
+        'Fine/Medium Low' => 'Hieno/matalahko',
+        'Fine/Super High' => 'Hieno/superkorkea',
+        'Fine/Very High' => 'Hieno/hyvin korkea',
+        'Fine/Very Low' => 'Hieno/hyvin matala',
+        'Normal/High' => 'Normaali/korkea',
+        'Normal/Low' => 'Normaali/matala',
+        'Normal/Medium' => 'Normaali/keskilaatu',
+        'Normal/Medium High' => 'Normaali/korkeahko',
+        'Normal/Medium Low' => 'Normaali/matalahko',
+        'Normal/Super High' => 'Normaali/superkorkea',
+        'Normal/Very High' => 'Normaali/hyvin korkea',
+        'Normal/Very Low' => 'Normaali/hyvin matala',
+        'Super Fine/High' => 'Superhieno/korkea',
+        'Super Fine/Low' => 'Superhieno/matala',
+        'Super Fine/Medium' => 'Superhieno/keskilaatu',
+        'Super Fine/Medium High' => 'Superhieno/korkeahko',
+        'Super Fine/Medium Low' => 'Superhieno/matalahko',
+        'Super Fine/Super High' => 'Superhieno/superkorkea',
+        'Super Fine/Very High' => 'Superhieno/hyvin korkea',
+        'Super Fine/Very Low' => 'Superhieno/hyvin matala',
+      },
+    },
+   'SanyoThumbnail' => 'Sanyo-nÃ€ytekuva',
+   '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',
+        'Medium High' => 'Korkeahko',
+        'Medium Low' => 'Matalahko',
+        'None (B&W)' => 'Ei mitÃ€Ã€n (M&V)',
+        'Normal' => 'Vakio',
+      },
+    },
+   'SaturationFaithful' => 'Kohdeuskollinen vÃ€rikyllÃ€isyys',
+   'SaturationLandscape' => 'Maisemakuvan vÃ€rikyllÃ€isyys',
+   'SaturationNeutral' => 'Neutraali vÃ€rikyllÃ€isyys',
+   'SaturationPortrait' => 'Muotokuvan vÃ€rikyllÃ€isyys',
+   'SaturationSetting' => 'VÃ€rikyllÃ€isyyden sasetus',
+   'SaturationStandard' => 'VakiovÃ€rikyllÃ€isyys',
+   'ScanImageEnhancer' => {
+      Description => 'Skannauskuvan parantelu',
+      PrintConv => {
+        'Off' => 'Pois',
+      },
+    },
+   'ScanningDirection' => {
+      Description => 'Skannaussuunta',
+      PrintConv => {
+        'Bottom-Top, L-R' => 'Alhaalta ylÃ¶s, vasemmalta oikealle',
+        'Bottom-Top, R-L' => 'Alhaalta ylÃ¶s, oikealta vasemmalle',
+        'L-R, Bottom-Top' => 'Vasemmalta oikealle, alhaalta ylÃ¶s',
+        'L-R, Top-Bottom' => 'Vasemmalta oikealle, ylhÃ€Ã€ltÃ€ alas',
+        'R-L, Bottom-Top' => 'Oikealta vasemmalle, alhaalta ylÃ¶s',
+        'R-L, Top-Bottom' => 'Oikealta vasemmalle, ylhÃ€Ã€ltÃ€ alas',
+        'Top-Bottom, L-R' => 'YlhÃ€Ã€ltÃ€ alas, vasemmalta oikealle',
+        'Top-Bottom, R-L' => 'YlhÃ€Ã€ltÃ€ alas, oikealta vasemmalle',
+      },
+    },
+   'Scene' => 'NÃ€yttÃ€mÃ¶',
+   'SceneArea' => 'NÃ€kymÃ€alue?',
+   'SceneAssist' => 'NÃ€kymÃ€-avustaja',
+   'SceneCaptureType' => {
+      Description => 'Kuvatun nÃ€kymÃ€n tyyppi',
+      PrintConv => {
+        'Landscape' => 'Maisema',
+        'Night' => 'YÃ¶nÃ€kymÃ€',
+        'Portrait' => 'Muotokuva',
+        'Standard' => 'Standardi',
+      },
+    },
+   'SceneDetect' => 'Kohtauksen tunnistus',
+   'SceneMode' => {
+      Description => 'NÃ€kymÃ€n muoto',
+      PrintConv => {
+        '2 in 1' => '2 1:ssÃ€',
+        'Auction' => 'Huutokauppa',
+        'Auto' => 'Automaattinen',
+        'Available Light' => 'Vallitseva valo',
+        'Beach' => 'Hiekkaranta',
+        'Beach & Snow' => 'Hiekkaranta&Lumi',
+        'Behind Glass' => 'Lasin takaa',
+        'Candle' => 'KynttilÃ€',
+        'Children' => 'Lapset',
+        'Cuisine' => 'Ateria',
+        'Digital Image Stabilization' => 'Digitaalinen kuvanvakautus',
+        'Documents' => 'Dokumentit',
+        'Face Portrait' => 'Kasvokuva',
+        'Fireworks' => 'Ilotulitus',
+        'Food' => 'Ateria',
+        'High Key' => 'High key -ylÃ€sÃ€vykuva',
+        'Indoor' => 'SisÃ€kuva',
+        'Landscape' => 'Maisema',
+        'Landscape+Portrait' => 'Maisema+muotokuva',
+        'Low Key' => 'Low key -alasÃ€vykuva',
+        'Macro' => 'Makro',
+        'Movie' => 'Elokuva',
+        'Museum' => 'Museo',
+        'My Mode' => 'Oma tapa',
+        'Nature Macro' => 'Luontomakro',
+        'Night Portrait' => 'YÃ¶n muotokuva',
+        'Night Scene' => 'IltanÃ€kymÃ€',
+        'Night View/Portrait' => 'IltanÃ€kymÃ€/YÃ¶n muotokuva',
+        'Night+Portrait' => 'YÃ¶+muotokuva',
+        'Normal' => 'Normaali',
+        'Panorama' => 'Panoraama',
+        'Pet' => 'Lemmikki',
+        'Portrait' => 'Muotokuva',
+        'Self Portrait' => 'Omakuva',
+        'Self Portrait+Self Timer' => 'Omakuva+itselaukaisin',
+        'Self Protrait+Timer' => 'Omakuva+itselaukaisin',
+        'Shoot & Select' => 'Kuvaa & Valitse',
+        'Shoot & Select1' => 'Kuvaus&valinta 1',
+        'Shoot & Select2' => 'Kuvaus&valinta 2',
+        'Shooting Guide' => 'Kuvausopas',
+        'Smile Shot' => 'Hymykuva',
+        'Snow' => 'Lumi',
+        'Sport' => 'Urheilu',
+        'Sports' => 'Urheilutapahtuma',
+        'Standard' => 'Vakio',
+        'Sunset' => 'Auringonlasku',
+        'Super Macro' => 'Supermakro',
+        'Text' => 'Teksti',
+        'Underwater Macro' => 'Veden alla makro',
+        'Underwater Snapshot' => 'Veden alla tilannekuva',
+        'Underwater Wide1' => 'Veden alla laaja 1',
+        'Underwater Wide2' => 'Veden alla laaja 2',
+        'Vivid' => 'HeleÃ€',
+      },
+    },
+   'SceneSelect' => {
+      Description => 'NÃ€kymÃ€n valinta',
+      PrintConv => {
+        'Lamp' => 'Lamppu',
+        'Night' => 'YÃ¶',
+        'Off' => 'Pois',
+        'Sport' => 'Urheilu',
+        'User 1' => 'KÃ€yttÃ€jÃ€ 1',
+        'User 2' => 'KÃ€yttÃ€jÃ€ 2',
+      },
+    },
+   'SceneType' => {
+      Description => 'NÃ€kymÃ€tyyppi',
+      PrintConv => {
+        'Directly photographed' => 'Suoraan otettu valokuva',
+      },
+    },
+   'SecurityClassification' => {
+      Description => 'Turvallisuusluokitus',
+      PrintConv => {
+        'Confidential' => 'Luottamuksellinen',
+        'Restricted' => 'Rajoitettu',
+        'Secret' => 'Salainen',
+        'Top Secret' => 'Huippusalainen',
+        'Unclassified' => 'Ei luokiteltu',
+      },
+    },
+   'SelfTimer' => {
+      Description => 'Itselaukaisin',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'SelfTimerMode' => 'Itselaukaisumoodi',
+   'SelfTimerShotCount' => 'Itselaukaisimen otosmÃ€Ã€rÃ€',
+   'SelfTimerTime' => 'Itselaukaisimen viive',
+   'SensingMethod' => {
+      Description => 'Mittausmetodi',
+      PrintConv => {
+        'Color sequential area' => 'PerÃ€kkÃ€isvÃ€rialueen anturi',
+        'Color sequential linear' => 'PerÃ€kkÃ€isvÃ€rien lineaarianturi',
+        'Monochrome area' => 'Monokromialueen anturi',
+        'Monochrome linear' => 'Monokromilineaarinen anturi',
+        'Not defined' => 'Ei mÃ€Ã€ritetty',
+        'One-chip color area' => 'Yhden chipin vÃ€rialueen anturi',
+        'Three-chip color area' => 'Kolmen chipin vÃ€rialueen anturi',
+        'Trilinear' => 'Trilineaarinen anturi',
+        'Two-chip color area' => 'Kahden chipin vÃ€rialueen anturi',
+      },
+    },
+   'SensitivityAdjust' => 'Herkkyyden asetus',
+   'SensitivitySteps' => 'Herkkyysaskeleet',
+   'SensorBlueLevel' => 'Anturin sinitaso',
+   'SensorBottomBorder' => 'Anturin alareuna',
+   'SensorHeight' => 'Anturin korkeus',
+   'SensorLeftBorder' => 'Anturin vasen reuna',
+   'SensorPixelSize' => 'Anturin pikselikoko',
+   'SensorRedLevel' => 'Anturin punataso',
+   'SensorRightBorder' => 'Anturin oikea reuna',
+   'SensorTemperature' => 'Anturin lÃ€mpÃ¶tila',
+   'SensorTopBorder' => 'Anturin ylÃ€reuna',
+   'SensorWidth' => 'Anturin leveys',
+   'Sequence' => 'JÃ€rjestys',
+   'SequenceNumber' => 'JÃ€rjestysnumero',
+   'SequenceShotInterval' => {
+      Description => 'Sarjakuvauksen taajuus',
+      PrintConv => {
+        '10 frames/s' => '10 ruutua/s',
+        '15 frames/s' => '15 ruutua/s',
+        '20 frames/s' => '20 ruutua/s',
+        '5 frames/s' => '5 ruutua/s',
+      },
+    },
+   'SequentialShot' => {
+      Description => 'Sarjakuvaus',
+      PrintConv => {
+        'Adjust Exposure' => 'Valotuksen sÃ€Ã€tÃ¶',
+        'Best' => 'Paras',
+        'None' => 'Ei mitÃ€Ã€n',
+        'Standard' => 'Vakio',
+      },
+    },
+   'SerialNumber' => 'Sarjanumero',
+   'SerialNumberFormat' => 'Sarjanumeron muoto',
+   'ServiceIdentifier' => 'Palvelun tunnistin',
+   'ShadingCompensation' => {
+      Description => 'Varjostumakorjaus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'Shadow' => 'Varjo',
+   'ShadowProtection' => 'Varjoalueen suojaus ',
+   'ShadowScale' => 'Varjoasteikko',
+   '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',
+        'Medium Hard' => 'Kovahko',
+        'Medium Soft' => 'PehmeÃ€hkÃ¶',
+        'Normal' => 'Vakio',
+        'Soft' => 'PehmeÃ€',
+        'Soft2' => 'PehmeÃ€ 2',
+        'n/a' => 'E.s.',
+      },
+    },
+   'SharpnessFactor' => 'TerÃ€vÃ¶intikerroin',
+   'SharpnessFaithful' => 'Kohdeuskollinen terÃ€vyys',
+   'SharpnessFreqTable' => 'TerÃ€vyyden taajuustaulukko',
+   'SharpnessFrequency' => 'TerÃ€vyystaajuus',
+   'SharpnessLandscape' => 'Maisemakuvan terÃ€vyys',
+   'SharpnessMonochrome' => 'YksivÃ€rikuvan terÃ€vyys',
+   'SharpnessNeutral' => 'Neutraali terÃ€vyys',
+   'SharpnessPortrait' => 'Muotokuvan terÃ€vyys',
+   'SharpnessSetting' => 'TerÃ€vyysasetus',
+   'SharpnessStandard' => 'VakioterÃ€vyys',
+   'SharpnessTable' => 'TerÃ€vyystaulukko',
+   'ShootingInfoDisplay' => 'Kuvaustietojen nÃ€yttÃ¶',
+   'ShootingMode' => 'IR-kauko-ohjaus',
+   'ShortDocumentID' => 'Lyhyt dokumentin ID',
+   'ShortOwnerName' => 'Omistajan lyhyt nimi',
+   'ShotInfoVersion' => 'Otostietojen versio',
+   'ShutterCount' => 'LaukaisumÃ€Ã€rÃ€',
+   'ShutterReleaseButtonAE-L' => 'Laukaisin AE-L',
+   'ShutterSpeedValue' => 'Suljinnopeuden arvo',
+   'SimilarityIndex' => 'YhtÃ€lÃ€isyysindeksi',
+   'Site' => 'Sivusto',
+   'SlaveFlashMeteringSegments' => 'Orjasalaman mittaussegmentit',
+   'SlowShutter' => 'Hidas suljin',
+   'SlowSync' => {
+      Description => 'Hidas suljin',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'Software' => 'Ohjelmisto',
+   'SoftwareVersion' => 'Ohjelmistoversio',
+   'Source' => 'LÃ€hde',
+   'SourceImageDirectory' => 'LÃ€hdekuvan kansio',
+   'SourceImageFileName' => 'LÃ€hdekuvan tiedostonimi',
+   'SourceImageVolumeName' => 'LÃ€hdekuvan taltion nimi',
+   'SpatialFrequencyResponse' => 'Spatiaalisen taajuuden vaste',
+   'SpecialInstructions' => 'Ohjeet',
+   'SpecialMode' => 'Erikoistapa',
+   'SpectralSensitivity' => 'Spektraalinen herkkyys',
+   'Sport' => 'Urheilu',
+   'SpotFocusPointX' => 'Pistetarkennuksen piste X',
+   'SpotFocusPointY' => 'Pistetarkennuksen piste Y',
+   'SpotMeteringMode' => 'Pistemittaustapa',
+   'StorageMethod' => 'Tallennusmetodi',
+   'StraightenAngle' => 'Kuvan suoristus',
+   'StripByteCounts' => 'Tavuja per pakattu strippi',
+   'StripOffsets' => 'Kuvadatan sijainti',
+   'Sub-location' => 'Sijainti',
+   'SubSecTime' => 'DateTime sekunnin murto-osina',
+   'SubSecTimeDigitized' => 'DateTimeDigitized sekunnin murto-osina',
+   'SubSecTimeOriginal' => 'DateTimeOriginal sekunnin murto-osina',
+   'SubTileBlockSize' => 'Alalaattalohkon koko',
+   'Subject' => 'Aihe',
+   'SubjectArea' => 'Kohdealue',
+   'SubjectDistance' => 'Kohteen etÃ€isyys',
+   'SubjectDistanceRange' => {
+      Description => 'Objektiivin tarkennusetÃ€isyys',
+      PrintConv => {
+        'Close' => 'LÃ€hikuva',
+        'Distant' => 'EtÃ€kuva',
+        'Macro' => 'Makro',
+        'Unknown' => 'Tuntematon',
+      },
+    },
+   'SubjectLocation' => 'Kohteen sijainti',
+   'SubjectProgram' => 'Kuvausohjelma',
+   'SubjectReference' => 'Aiheen koodi',
+   'SuperMacro' => {
+      Description => 'Supermakro',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On (1)' => 'PÃ€Ã€llÃ€ (1)',
+        'On (2)' => 'PÃ€Ã€llÃ€ (2)',
+      },
+    },
+   'SupplementalCategories' => 'TÃ€ydentÃ€vÃ€ kategoria',
+   'SupplementalType' => {
+      Description => 'LisÃ€ystyyppi',
+      PrintConv => {
+        'Main Image' => 'Ei asetettu',
+        'Rasterized Caption' => 'Rasteroitu seloste',
+        'Reduced Resolution Image' => 'Alennetun resoluution kuva',
+      },
+    },
+   'SvISOSetting' => 'Sv-ISO-asetus',
+   'T4Options' => 'LisÃ€tyt tÃ€ytebitit',
+   'T6Options' => 'T6-valinnat',
+   'TIFF-EPStandardID' => 'TIFF/EP-standardin ID',
+   'TargetAperture' => 'Tavoiteaukko',
+   'TargetExposureTime' => 'Tavoitevalotusaika',
+   'TargetPrinter' => 'Kohdetulostin',
+   'Technology' => {
+      Description => 'Teknologia',
+      PrintConv => {
+        'Digital Camera' => 'Digitaalikamera',
+        'Dye Sublimation Printer' => 'LÃ€mpÃ¶sublimaatiotulostin',
+        'Electrophotographic Printer' => 'Lasertulostin',
+        'Electrostatic Printer' => 'SÃ€hkÃ¶staattinen tulostin',
+        'Film Scanner' => 'Filmiskanneri',
+        'Film Writer' => 'Filmitulostin',
+        'Flexography' => 'Fleksografia',
+        'Gravure' => 'SyvÃ€paino',
+        'Ink Jet Printer' => 'Mustesuihkutulostin',
+        'Offset Lithography' => 'Offsetlitografia',
+        'Photo CD' => 'Valokuva-CD',
+        'Photo Image Setter' => 'Valokuvaimagesetteri',
+        'Photographic Paper Printer' => 'Valokuvapaperitulostin',
+        'Projection Television' => 'Projektiotelevisio',
+        'Reflective Scanner' => 'Heijastusskanneri',
+        'Silkscreen' => 'Silkkipaino',
+        'Thermal Wax Printer' => 'LÃ€mpÃ¶vahatulostin',
+        'Video Camera' => 'Videokamera',
+        'Video Monitor' => 'Videomonitori',
+      },
+    },
+   'Text' => 'Teksti',
+   'TextInfo' => 'Tekstitiedot',
+   'TextStamp' => {
+      Description => 'Tekstileimasin',
+      PrintConv => {
+        'Off' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'Thresholding' => 'Kynnystys',
+   'ThumbnailImage' => 'NÃ€ytekuva',
+   'ThumbnailImageValidArea' => 'NÃ€ytekuvan kelpaava alue',
+   'TileByteCounts' => 'Ruutujen tavumÃ€Ã€rÃ€t',
+   'TileDepth' => 'Ruudun syvyys',
+   'TileLength' => 'Ruudun pituus',
+   'TileOffsets' => 'RuutusiirtymÃ€t',
+   'TileWidth' => 'Otsikon leveys',
+   'Time' => 'Aika',
+   'TimeCreated' => 'Luontiaika',
+   'TimeSent' => 'LÃ€hetysaika',
+   'TimeSincePowerOn' => 'Virran pÃ€Ã€llÃ€oloaika',
+   'TimeStamp' => 'Aikaleima',
+   'TimeZone' => 'AikavyÃ¶hyke',
+   'TimeZoneOffset' => 'AikavyÃ¶hykkeen siirtymÃ€',
+   'TimerFunctionButton' => 'Ajastustoimintopainike',
+   'Title' => 'Otsikko',
+   'ToneComp' => 'SÃ€vykorjailu',
+   'ToneCurve' => 'SÃ€vykÃ€yrÃ€',
+   'ToneCurveMatching' => 'SÃ€vykÃ€yrÃ€n tÃ€smÃ€ys',
+   'ToneCurveTable' => 'SÃ€vykÃ€yrÃ€taulukko',
+   'ToneCurves' => 'SÃ€vykÃ€yrÃ€t',
+   'ToningEffect' => 'SÃ€vytysefekti',
+   'ToningEffectMonochrome' => 'YksivÃ€risÃ€vytysefekti',
+   'ToningSaturation' => 'SÃ€vykyllÃ€isyys',
+   'TransferFunction' => 'Muuntotoiminto',
+   'TransferRange' => 'Siirtonopeus',
+   'Transform' => 'Muunna',
+   'Transformation' => {
+      Description => 'Muunto',
+      PrintConv => {
+        'Mirror horizontal' => 'Peilaa vaakasuunnassa',
+        'Mirror horizontal and rotate 270 CW' => 'Peilaa vaakasuunnassa ja kierrÃ€ 270Â° myÃ¶tÃ€pÃ€ivÃ€Ã€n',
+        'Mirror horizontal and rotate 90 CW' => 'Peilaa vaakasuunnassa ja kierrÃ€ 90Â° myÃ¶tÃ€pÃ€ivÃ€Ã€n',
+        'Mirror vertical' => 'Peilaa pystysuunnassa',
+        'Rotate 180' => 'KierrÃ€ 180Â°',
+        'Rotate 270 CW' => 'KierrÃ€ 90Â° myÃ¶tÃ€pÃ€ivÃ€Ã€n',
+        'Rotate 90 CW' => 'KierrÃ€ 90Â° myÃ¶tÃ€pÃ€ivÃ€Ã€n',
+      },
+    },
+   'TransparencyIndicator' => 'LÃ€pinÃ€kyvyyden ilmaisin',
+   'TravelDay' => 'MatkapÃ€ivÃ€',
+   'TvExposureTimeSetting' => 'Tv-valotusaikaasetus',
+   'Type' => 'Tyyppi',
+   'Uncompressed' => {
+      Description => 'Pakkaamaton',
+      PrintConv => {
+        'No' => 'Ei',
+        'Yes' => 'KyllÃ€',
+      },
+    },
+   'UniqueCameraModel' => 'Uniikki kameramalli',
+   'UniqueDocumentID' => 'Uniikin dokumentin ID',
+   'Unknown' => 'Tuntematon',
+   'Unsharp1Color' => 'TerÃ€vÃ¶inti 1 -vÃ€ri',
+   'Unsharp1HaloWidth' => 'TerÃ€vÃ¶inti 1 -halolaajuus',
+   'Unsharp1Intensity' => 'TerÃ€vÃ¶inti 1 -voimakkuus',
+   'Unsharp1Threshold' => 'TerÃ€vÃ¶inti 1 -kynnys',
+   'Unsharp2Color' => 'TerÃ€vÃ¶inti 2 -vÃ€ri',
+   'Unsharp2HaloWidth' => 'TerÃ€vÃ¶inti 2 -halolaajuus',
+   'Unsharp2Intensity' => 'TerÃ€vÃ¶inti 2 -voimakkuus',
+   'Unsharp2Threshold' => 'TerÃ€vÃ¶inti 2 -kynnys',
+   'Unsharp3Color' => 'TerÃ€vÃ¶inti 3 -vÃ€ri',
+   'Unsharp3HaloWidth' => 'TerÃ€vÃ¶inti 3 -halolaajuus',
+   'Unsharp3Intensity' => 'TerÃ€vÃ¶inti 3 -voimakkuus',
+   'Unsharp3Threshold' => 'TerÃ€vÃ¶inti 3 -kynnys',
+   'Unsharp4Color' => 'TerÃ€vÃ¶inti 4 -vÃ€ri',
+   'Unsharp4HaloWidth' => 'TerÃ€vÃ¶inti 4 -halolaajuus',
+   'Unsharp4Intensity' => 'TerÃ€vÃ¶inti 4 -voimakkuus',
+   'Unsharp4Threshold' => 'TerÃ€vÃ¶inti 4 -kynnys',
+   'UnsharpCount' => 'TerÃ€vÃ¶intimÃ€Ã€rÃ€',
+   'UnsharpData' => 'TerÃ€vÃ¶intidata',
+   'UnsharpMask' => 'EpÃ€terÃ€vÃ€ maski',
+   'Urgency' => {
+      Description => 'Kiireellisyys',
+      PrintConv => {
+        '0 (reserved)' => '0 (varattu tulevaan kÃ€yttÃ¶Ã¶n)',
+        '1 (most urgent)' => '1 (hyvin kiireellinen)',
+        '5 (normal urgency)' => '5 (normaali kiirellisyys)',
+        '8 (least urgent)' => '8 (lievÃ€n kiireellinen)',
+        '9 (user-defined priority)' => '9 (varattu tulevaan kÃ€yttÃ¶Ã¶n)',
+      },
+    },
+   'UserComment' => 'KÃ€yttÃ€jÃ€n kommentti',
+   'UserSelectGroupTitle' => 'KÃ€yttÃ€jÃ€n valitseman ryhmÃ€n otsikko',
+   'VRDOffset' => 'VRD-siirtymÃ€',
+   'VRInfo' => 'Kuvanvakaimen tiedot',
+   'VRInfoVersion' => 'VR- (kuvanvakain) tietojen versio',
+   'ValidAFPoints' => 'Kelpaavat AF-pisteet',
+   'VariProgram' => 'Kuvausohjelma',
+   'Version' => 'Versio',
+   'VibrationReduction' => 'Kuvanvakautus',
+   'VideoCardGamma' => 'Grafiikkakortin gamma',
+   'ViewfinderWarning' => 'Etsinvaroitus',
+   'ViewingCondDesc' => 'Katseluolojen kuvaus',
+   'VignetteControl' => {
+      Description => 'Vinjetoinnin korjaus',
+      PrintConv => {
+        'High' => 'Korkea',
+        'Low' => 'Matala',
+        'Normal' => 'Normaali',
+        'Off' => 'Pois',
+      },
+    },
+   'VignetteControlIntensity' => 'Vinjetoinnin korjauksen voimakkuus',
+   'VoiceMemo' => {
+      Description => 'ÃÃ€nen tallennus',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'WBAdjData' => 'Valkotaspainon sÃ€Ã€tÃ¶data',
+   'WBBlueLevel' => 'Valkotas. sinisen taso',
+   'WBBracketMode' => 'Valkotasapaino-haarukointitapa',
+   'WBBracketValueAB' => 'Valkotasapainon AB-haarukointiarvo',
+   'WBBracketValueGM' => 'Valkotasapainon GM-haarukointiarvo',
+   'WBGreenLevel' => 'VihreÃ€n taso',
+   'WBMode' => {
+      Description => 'Valkotasapainotila',
+      PrintConv => {
+        'Auto' => 'Automaattinen',
+      },
+    },
+   'WBRedLevel' => 'Valkotas. punaisen taso',
+   'WBShiftAB' => 'Valkotas. sÃ€Ã€tÃ¶ keltainen/sininen',
+   'WBShiftGM' => 'Valkotas. sÃ€Ã€tÃ¶ vihreÃ€/magenta',
+   'WB_RBLevels' => 'Valkotasapaino punainen/sininen',
+   'WB_RBLevelsAuto' => 'Valkotas. RB-tasot, automatiikka',
+   'WB_RBLevelsCoolWhiteFluor' => 'Valkotas. RB-tasot, viileÃ€n valk. loistel.',
+   'WB_RBLevelsDayWhiteFluor' => 'Valkotas. RB-tasot, valk. pÃ€ivÃ€nvaloloistel.',
+   'WB_RBLevelsDaylightFluor' => 'Valkotas. RB-tasot, pÃ€ivÃ€nvaloloistel.',
+   'WB_RBLevelsEveningSunlight' => 'Valkotas. RB-tasot, ilta-aurinko',
+   'WB_RBLevelsFineWeather' => 'Valkotas. RB-tasot, kaunis sÃ€Ã€',
+   'WB_RBLevelsShade' => 'Valkotas. RB-tasot, varjo',
+   'WB_RBLevelsTungsten' => 'Valkotas. RB-tasot, hehkulamppu',
+   'WB_RBLevelsUsed' => 'KÃ€ytetyt valkotas. RB-tasot',
+   'WB_RBLevelsWhiteFluorescent' => 'Valkotas. RB-tasot, valk. loistelamppu',
+   'WB_RGGBLevelsCloudy' => 'Valkotasapainon RGGB-tasojen pilvinen',
+   'WB_RGGBLevelsDaylight' => 'Valkotasapainon RGGB-tasojen pÃ€ivÃ€nvalo',
+   'WB_RGGBLevelsFlash' => 'Valkotasapainon RGGB-tasojen salama',
+   'WB_RGGBLevelsFluorescentD' => 'Valkotasapainon RGGB-tasojen loistelamppu D',
+   'WB_RGGBLevelsFluorescentN' => 'Valkotasapainon RGGB-tasojen loistelamppu N',
+   'WB_RGGBLevelsFluorescentW' => 'Valkotasapainon RGGB-tasojen loistelamppu W',
+   'WB_RGGBLevelsShade' => 'Valkotasapainon RGGB-tasojen varjo',
+   'WB_RGGBLevelsTungsten' => 'Valkotasapainon RGGB-tasojen hehkulamppu',
+   'Watermark' => 'Vesileima',
+   'WatermarkType' => 'Vesileiman tyyppi',
+   'WhiteBalance' => {
+      Description => 'Valkotasapaino',
+      PrintConv => {
+        'Auto' => 'Automaattinen',
+        'Cloudy' => 'Pilvinen',
+        'Custom' => 'Mukautus',
+        'Custom2' => 'Mukautus 2',
+        'Custom3' => 'Mukautus 3',
+        'Custom4' => 'Mukautus 4',
+        'Day White Fluorescent' => 'Valkoinen pÃ€ivÃ€nvaloloistelamppu',
+        'Daylight' => 'Auringonvalo',
+        'Daylight Fluorescent' => 'PÃ€ivÃ€nvaloloistelamppu',
+        'Flash' => 'Salama',
+        'Incandescent' => 'Hehkulamppu',
+        'Living Room Warm White Fluorescent' => 'Asuinhuoneen lÃ€mmin valkoinen loistelamppu',
+        'Manual' => 'Manuaalinen',
+        'Warm White Fluorescent' => 'LÃ€mmin valkoinen loistelamppu',
+        'White Fluorescent' => 'Valkoinen loistelamppu',
+      },
+    },
+   'WhiteBalance2' => {
+      Description => 'Valkotasapaino',
+      PrintConv => {
+        '3000K (Tungsten light)' => '3000 K (hehkulamppu)',
+        '3600K (Tungsten light-like)' => '3600 K (hehkulamppumainen valo)',
+        '4000K (Cool white fluorescent)' => '4000 K (viileÃ€n valkoinen loistelamppu)',
+        '4500K (Neutral white fluorescent)' => '4500 K (neutraali valkoinen loistelamppu)',
+        '5300K (Fine Weather)' => '5300 K (kaunis sÃ€Ã€)',
+        '6000K (Cloudy)' => '6000 K (pilvinen)',
+        '6600K (Daylight fluorescent)' => '6600 K (pÃ€ivÃ€nvaloloistelamppu)',
+        '7500K (Fine Weather with Shade)' => '7500 K (kaunis sÃ€Ã€ ja varjoja)',
+        'Auto' => 'Automaattinen',
+        'Custom WB 1' => 'Mukautettu valkotasapaino 1',
+        'Custom WB 2' => 'Mukautettu valkotasapaino 2',
+        'Custom WB 2900K' => 'Mukautettu valkotasapaino 2900 K',
+        'Custom WB 3' => 'Mukautettu valkotasapaino 3',
+        '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Ã¶',
+   'WhiteBalanceBias' => 'Valkotasapainon korjaus',
+   'WhiteBalanceBlue' => 'Valkotasapaino sininen',
+   'WhiteBalanceBracket' => 'Valkotasapainon haarukointi',
+   'WhiteBalanceBracketing' => 'Valkotasapainohaarukointi',
+   'WhiteBalanceComp' => 'Valkotasapainon sÃ€Ã€tÃ¶',
+   'WhiteBalanceFineTune' => 'Valkotasapainon hienosÃ€Ã€tÃ¶',
+   'WhiteBalanceMatching' => 'Valkotasapainon tÃ€smÃ€ys',
+   'WhiteBalanceMode' => {
+      Description => 'Valkotasapainon muoto',
+      PrintConv => {
+        'Auto (Cloudy)' => 'Automaattinen (pilvinen)',
+        'Auto (Day White Fluorescent)' => 'Automaattinen (valkoinen pÃ€ivÃ€nvaloloistelamppu)',
+        'Auto (Daylight Fluorescent)' => 'Automaattinen (pÃ€ivÃ€nvaloloistelamppu)',
+        'Auto (Daylight)' => 'Automaattinen (auringonvalo)',
+        'Auto (Flash)' => 'Automaattinen (salama)',
+        'Auto (Shade)' => 'Automaattinen (varjo)',
+        'Auto (Tungsten)' => 'Automaattinen (hehkulamppu)',
+        'Auto (White Fluorescent)' => 'Automaattinen (valkoinen loistelamppu)',
+        'Unknown' => 'Automaattinen (ei tunnistettu)',
+        'User-Selected' => 'Itse valittu',
+      },
+    },
+   'WhiteBalanceRed' => 'Valkotasapaino punainen',
+   'WhiteBalanceSet' => 'Asetettu valkotasapaino',
+   'WhiteBalanceTable' => 'Valkotasapainotaulukko',
+   'WhiteBalanceTemperature' => 'Valkotaspainon lÃ€mpÃ¶tila',
+   'WhiteBoard' => 'Valkoinen pohja',
+   'WhiteLevel' => 'Valkoinen taso',
+   'WhitePoint' => 'Valkoinen piste',
+   'WhitePointX' => 'Valkoinen piste X',
+   'WhitePointY' => 'Valkoinen piste Y',
+   'Wide' => 'Laaja',
+   'WideFocusZone' => 'Laaja-alatarkennuksen alue',
+   'WideRange' => {
+      Description => 'Laaja alue',
+      PrintConv => {
+        'Off' => 'Pois',
+        'On' => 'PÃ€Ã€llÃ€',
+      },
+    },
+   'WorldTimeLocation' => {
+      Description => 'Maailmanaikasijainti',
+      PrintConv => {
+        'Destination' => 'Kohde',
+        'Home' => 'Koti',
+        'Hometown' => 'Kotiseutu',
+      },
+    },
+   'Writer-Editor' => 'Selosteen/Kuvatekstin kirjoittaja',
+   'X3FillLight' => 'X3-tÃ€ytevalo',
+   'XClipPathUnits' => 'X-leikepolkuyksikÃ¶t',
+   'XMP' => 'XMP-metadata',
+   'XPosition' => 'X-sijainti',
+   'XResolution' => 'Kuvan vaakaresoluutio',
+   'YCbCrCoefficients' => 'VÃ€riavaruuden muunnon matriisikertoimet',
+   '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',
+   'YResolution' => 'Kuvan pystyresoluutio',
+   'ZoneMatching' => {
+      Description => 'Yli/alivalotuksen esto',
+      PrintConv => {
+        'High Key' => 'YlÃ€sÃ€vykuva',
+        'ISO Setting Used' => 'Pois (kÃ€ytetty ISO-asetusta)',
+        'Low Key' => 'AlasÃ€vykuva',
+      },
+    },
+   'Zoom' => 'Zoom-objektiivi',
+   'ZoomSourceWidth' => 'Zoomauksen lÃ€htÃ¶koko',
+   'ZoomStepCount' => 'Zoom-askelmÃ€Ã€rÃ€',
+   'ZoomTargetWidth' => 'Zoomauksen loppukoko',
+);
+
+1;  # end
+
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Lang::fi.pm - ExifTool Finnish language translations
+
+=head1 DESCRIPTION
+
+This file is used by Image::ExifTool to generate localized tag descriptions
+and values.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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 Jarkko ME<auml>kineva for providing this
+translation.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool(3pm)|Image::ExifTool>,
+L<Image::ExifTool::TagInfoXML(3pm)|Image::ExifTool::TagInfoXML>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/fr.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/fr.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/fr.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.19';
+$VERSION = '1.34';
 
 %Image::ExifTool::Lang::fr::Translate = (
@@ -141,10 +141,4 @@
    'AFInfo2Version' => 'Version des infos AF',
    'AFIntegrationTime' => 'Temps d\'intÃ©gration AF',
-   'AFMicroAdjActive' => {
-      PrintConv => {
-        'No' => 'Non',
-        'Yes' => 'Oui',
-      },
-    },
    'AFMicroadjustment' => {
       Description => 'Micro-ajustement de l\'AF',
@@ -168,6 +162,6 @@
         'Bottom' => 'Bas',
         'Center' => 'Centre',
-        'Far Left' => 'ExtrÃšme-gauche',
-        'Far Right' => 'ExtrÃšme-droit',
+        'Far Left' => 'ExtrÃªme-gauche',
+        'Far Right' => 'ExtrÃªme-droit',
         'Left' => 'Gauche',
         'Lower-left' => 'Bas-gauche',
@@ -200,5 +194,5 @@
     },
    'AFPointAutoSelection' => {
-      Description => 'SÃ©lecition des collimateurs automatique',
+      Description => 'SÃ©lection des collimateurs automatique',
       PrintConv => {
         'Control-direct:disable/Main:disable' => 'ContrÃŽle rapide-Directe:dÃ©sactivÃ©/Principale:dÃ©sactivÃ©',
@@ -361,5 +355,5 @@
       Description => 'Sensibili. de suivi AI Servo',
       PrintConv => {
-        'Fast' => 'Schnell',
+        'Fast' => 'Rapide',
         'Medium Fast' => 'Moyenne rapide',
         'Medium Slow' => 'Moyenne lent',
@@ -379,4 +373,5 @@
       Description => 'Action conseillÃ©e',
       PrintConv => {
+        'Object Append' => 'Ajout d\'objet',
         'Object Kill' => 'Destruction d\'objet',
         'Object Reference' => 'RÃ©fÃ©rence d\'objet',
@@ -414,5 +409,5 @@
       },
     },
-   'AdditionalModelInformation' => 'Modele d\'Information additionnel',
+   'AdditionalModelInformation' => 'ModÃšle d\'Information additionnel',
    'Address' => 'Adresse',
    'AdultContentWarning' => {
@@ -425,4 +420,22 @@
         'Off' => 'DÃ©sactivÃ©',
         'On' => 'ActivÃ©',
+      },
+    },
+   'AdvancedSceneMode' => {
+      PrintConv => {
+        'Color Select' => 'DÃ©saturation partielle',
+        'Cross Process' => 'DÃ©velop. croisÃ©',
+        'Dynamic Monochrome' => 'Monochrome dynamique',
+        'Expressive' => 'Expressif',
+        'High Dynamic' => 'Dynamique haute',
+        'High Key' => 'Tons clairs',
+        'Impressive Art' => 'Impressionisme',
+        'Low Key' => 'Clair-obscur',
+        'Miniature' => 'Effet miniature',
+        'Retro' => 'RÃ©tro',
+        'Sepia' => 'SÃ©pia',
+        'Soft' => 'Mise au point douce',
+        'Star' => 'Filtre Ã©toile',
+        'Toy Effect' => 'Effet jouet',
       },
     },
@@ -554,4 +567,5 @@
     },
    'AutoFocus' => {
+      Description => 'Auto-Focus',
       PrintConv => {
         'Off' => 'DÃ©sactivÃ©',
@@ -867,8 +881,9 @@
    'CircleOfConfusion' => 'Cercle de confusion',
    'City' => 'Ville',
-   'ClassifyState' => 'Etat de classification',
+   'ClassifyState' => 'Ãtat de classification',
    'CleanFaxData' => 'DonnÃ©es de Fax propres',
    'ClipPath' => 'Chemin de rognage',
    'CodedCharacterSet' => 'Jeu de caractÃšres codÃ©',
+   'CollectionName' => 'Nom de collection',
    'ColorAberrationControl' => {
       PrintConv => {
@@ -890,4 +905,5 @@
       },
     },
+   'ColorBalanceVersion' => 'Version de la Balance des couleurs',
    'ColorBooster' => {
       PrintConv => {
@@ -1006,5 +1022,5 @@
     },
    'ColorantOrder' => 'Ordre de colorant',
-   'ColorantTable' => 'Table de colorantÃ©',
+   'ColorantTable' => 'Table de colorant',
    'ColorimetricReference' => 'RÃ©fÃ©rence colorimÃ©trique',
    'CommandDialsChangeMainSub' => {
@@ -1105,13 +1121,17 @@
       Description => 'Contraste',
       PrintConv => {
+        '+1 (medium high)' => '+1 (Assez fort)',
+        '+2 (high)' => '+2 (Forte)',
+        '+3 (very high)' => '+3 (TrÃšs fort)',
+        '-1 (medium low)' => '-1 (Assez faible)',
+        '-2 (low)' => '-2 (Faible)',
+        '-3 (very low)' => '-3 (TrÃšs faible)',
+        '0 (normal)' => '0 (Normale)',
         'High' => 'Dur',
         'Low' => 'Doux',
-        'Med High' => 'Assez fort',
-        'Med Low' => 'Assez faible',
         'Medium High' => 'Moyen Haut',
         'Medium Low' => 'Moyen Faible',
         'Normal' => 'Normale',
-        'Very High' => 'TrÃšs fort',
-        'Very Low' => 'TrÃšs faible',
+        'n/a' => 'Non Ã©tablie',
       },
     },
@@ -1148,4 +1168,5 @@
    'CreatorAddress' => 'Adresse du crÃ©ateur',
    'CreatorCity' => 'Lieu d\'Habitation du crÃ©ateur',
+   'CreatorContactInfo' => 'Contact crÃ©ateur',
    'CreatorCountry' => 'Pays du crÃ©ateur',
    'CreatorPostalCode' => 'Code postal du crÃ©ateur',
@@ -1652,4 +1673,12 @@
    'FNumber' => 'Nombre F',
    'FOV' => 'Champ de vision',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (haut/gauche)',
+        'Rotate 180' => '180Â° (bas/droit)',
+        'Rotate 270 CW' => '90Â° sens horaire (gauche/bas)',
+        'Rotate 90 CW' => '90Â° sens antihoraire (droit/haut)',
+      },
+    },
    'FastSeek' => {
       PrintConv => {
@@ -1695,4 +1724,5 @@
    'FileType' => 'Type de fichier',
    'FileVersion' => 'Version de format de fichier',
+   'Filename' => 'Nom du fichier ',
    'FillFlashAutoReduction' => {
       Description => 'Mesure E-TTL',
@@ -2075,5 +2105,5 @@
       PrintConv => {
         'Above Sea Level' => 'Au-dessus du niveau de la mer',
-        'Below Sea Level' => 'En-dessous du niveau de la mer',
+        'Below Sea Level' => 'Au-dessous du niveau de la mer',
       },
     },
@@ -2081,5 +2111,5 @@
    'GPSDOP' => 'PrÃ©cision de mesure',
    'GPSDateStamp' => 'Date GPS',
-   'GPSDateTime' => 'Heure GPS (horloge atomique)',
+   'GPSDateTime' => 'Date/heure GPS (horloge atomique)',
    'GPSDestBearing' => 'Orientation de la destination',
    'GPSDestBearingRef' => {
@@ -2095,5 +2125,5 @@
       PrintConv => {
         'Kilometers' => 'KilomÃštres',
-        'Nautical Miles' => 'Noeuds',
+        'Nautical Miles' => 'Milles marins',
       },
     },
@@ -2166,5 +2196,5 @@
       PrintConv => {
         'km/h' => 'KilomÃštres par heure',
-        'knots' => 'Noeuds',
+        'knots' => 'NÅuds',
         'mph' => 'Miles par heure',
       },
@@ -2207,5 +2237,5 @@
    'GeoTiffDirectory' => 'Tag de rÃ©pertoire de clÃ© GeoTiff',
    'GeoTiffDoubleParams' => 'Tag de paramÃštres doubles GeoTiff',
-   'Gradation' => 'Luminosite',
+   'Gradation' => 'Gradation',
    'GrayResponseCurve' => 'Courbe de rÃ©ponse du gris',
    'GrayResponseUnit' => {
@@ -2246,6 +2276,7 @@
       },
     },
-   'HalftoneHints' => 'Indications sur les demi-treintes',
+   'HalftoneHints' => 'Indications sur les demi-teintes',
    'Headline' => 'Titre principal',
+   'HierarchicalSubject' => 'Sujet hiÃ©rarchique',
    'HighISONoiseReduction' => {
       Description => 'RÃ©duction du bruit en haute sensibilitÃ© ISO',
@@ -2284,5 +2315,6 @@
    'Hue' => 'Nuance',
    'HueAdjustment' => 'Teinte',
-   'HyperfocalDistance' => 'Distanace hyperfocale',
+   'HyperfocalDistance' => 'Distance hyperfocale',
+   'ICCProfile' => 'Profil ICC',
    'ICCProfileName' => 'Nom du profil ICC',
    'ICC_Profile' => 'Profil de couleur ICC d\'entrÃ©e',
@@ -2399,4 +2431,5 @@
       },
     },
+   'ImageProcessing' => 'Retouche d\'image',
    'ImageQuality' => {
       PrintConv => {
@@ -2449,4 +2482,5 @@
    'InkSet' => 'Encrage',
    'IntellectualGenre' => 'Genre intellectuel',
+   'IntelligentAuto' => 'Mode Auto intelligent',
    'IntensityStereo' => {
       PrintConv => {
@@ -2509,5 +2543,5 @@
    'InteropOffset' => 'Indicateur d\'interfonctionnement',
    'InteropVersion' => 'Version d\'interopÃ©rabilitÃ©',
-   'IptcLastEdited' => 'Derniere edition IPTC',
+   'IptcLastEdited' => 'DerniÃšre Ã©dition IPTC',
    'JFIFVersion' => 'Version JFIF',
    'JPEGACTables' => 'Tableaux AC JPEG',
@@ -2517,4 +2551,11 @@
    'JPEGProc' => 'Proc JPEG',
    'JPEGQTables' => 'Tableaux Q JPEG',
+   'JPEGQuality' => {
+      Description => 'QualitÃ©',
+      PrintConv => {
+        'Extra Fine' => 'Extra fine',
+        'Standard' => 'Normale',
+      },
+    },
    'JPEGRestartInterval' => 'Intervalle de redÃ©marrage JPEG',
    'JPEGTables' => 'Tableaux JPEG',
@@ -2543,8 +2584,8 @@
    'LC7' => 'DonnÃ©es de condition minimale de dÃ©clenchement AF',
    'LCDDisplayAtPowerOn' => {
-      Description => 'Etat LCD lors de l\'allumage',
+      Description => 'Ãtat LCD lors de l\'allumage',
       PrintConv => {
         'Display' => 'AllumÃ©',
-        'Retain power off status' => 'Etat prÃ©cÃ©dent',
+        'Retain power off status' => 'Ãtat prÃ©cÃ©dent',
       },
     },
@@ -2586,4 +2627,6 @@
    'Language' => 'Langage',
    'LanguageIdentifier' => 'Identificateur de langue',
+   'LastKeywordIPTC' => 'Dernier mot-clÃ© IPTC',
+   'LastKeywordXMP' => 'Dernier mot-clÃ© XMP',
    'LeafData' => 'DonnÃ©es Leaf',
    'Lens' => 'Objectif ',
@@ -2615,6 +2658,8 @@
    'LensID' => 'ID Lens',
    'LensIDNumber' => 'NumÃ©ro d\'Objectif',
-   'LensInfo' => 'Infos lens',
+   'LensInfo' => 'Informations sur l\'objectif',
    'LensKind' => 'Sorte d\'objectif / version (LC0)',
+   'LensMake' => 'Fabricant d\'objectif',
+   'LensModel' => 'ModÃšle d\'objectif',
    'LensSerialNumber' => 'NumÃ©ro de sÃ©rie objectif',
    'LensType' => 'Sorte d\'objectif',
@@ -2653,5 +2698,5 @@
       },
     },
-   'LightValue' => 'Luminosite',
+   'LightValue' => 'LuminositÃ©',
    'Lightness' => 'LuminositÃ©',
    'LinearResponseLimit' => 'Limite de rÃ©ponse linÃ©aire',
@@ -2666,5 +2711,5 @@
       Description => 'Simulation d\'exposition directe',
       PrintConv => {
-        'Disable (LCD auto adjust)' => 'DÃ©sactivÃ©e (rÃ©glge Ã©cran auto)',
+        'Disable (LCD auto adjust)' => 'DÃ©sactivÃ©e (rÃ©glage Ã©cran auto)',
         'Enable (simulates exposure)' => 'ActivÃ©e (simulation exposition)',
       },
@@ -2677,5 +2722,5 @@
     },
    'LocalizedCameraModel' => 'Nom traduit de modÃšle d\'appareil',
-   'Location' => 'Ligne',
+   'Location' => 'Lieu',
    'LockMicrophoneButton' => {
       Description => 'Fonction de touche microphone',
@@ -2832,5 +2877,4 @@
         'Other' => 'Autre',
         'Partial' => 'Partielle',
-        'Spot' => 'Grain',
         'Unknown' => 'Inconnu',
       },
@@ -2868,5 +2912,5 @@
    'Model' => 'ModÃšle d\'appareil photo',
    'Model2' => 'ModÃšle d\'Ã©quipement de prise de vue (2)',
-   'ModelAge' => 'Age du modele',
+   'ModelAge' => 'Age du modÃšle',
    'ModelTiePoint' => 'Tag de lien d modÃšle',
    'ModelTransform' => 'Tag de transformation de modÃšle',
@@ -2991,4 +3035,5 @@
       },
     },
+   'NEFLinearizationTable' => 'Table de Linearization',
    'Name' => 'Nom',
    'NamedColor2' => 'Couleur nommÃ©e 2',
@@ -3092,5 +3137,5 @@
    'OtherImage' => 'Autre image',
    'OutputResponse' => 'RÃ©ponse de sortie',
-   'Owner' => 'Proprietaire',
+   'Owner' => 'PropriÃ©taire',
    'OwnerID' => 'ID du propriÃ©taire',
    'OwnerName' => 'Nom du propriÃ©taire',
@@ -3433,5 +3478,5 @@
    'ProgramVersion' => 'Version du programme',
    'Protect' => 'ProtÃ©ger',
-   'Province-State' => 'RÃ©gion / DÃ©partement',
+   'Province-State' => 'Ãtat / RÃ©gion',
    'Publisher' => 'Editeur',
    'Quality' => {
@@ -3468,4 +3513,5 @@
       },
     },
+   'QuickAdjust' => 'RÃ©glages rapides',
    'QuickControlDialInMeter' => {
       Description => 'Molette de contrÃŽle rapide en mesure',
@@ -3546,5 +3592,7 @@
    'RawImageCenter' => 'Centre Image RAW',
    'RawImageDigest' => 'Digest d\'image brute',
+   'RawImageHeight' => 'Hauteur de l\'image brute',
    'RawImageSize' => 'Taille d\'image RAW',
+   'RawImageWidth' => 'Largeur de l\'image brute',
    'RawJpgQuality' => {
       PrintConv => {
@@ -3705,12 +3753,19 @@
    'Saturation' => {
       PrintConv => {
+        '+1 (medium high)' => '+1 (Assez fort)',
+        '+2 (high)' => '+2 (Forte)',
+        '+3 (very high)' => '+3 (TrÃšs fort)',
+        '+4 (highest)' => '+4',
+        '+4 (maximum)' => '+4',
+        '-1 (medium low)' => '-1 (Assez faible)',
+        '-2 (low)' => '-2 (Faible)',
+        '-3 (very low)' => '-3 (TrÃšs faible)',
+        '-4 (lowest)' => '-4',
+        '-4 (minimum)' => '-4',
+        '0 (normal)' => '0 (Normale)',
         'High' => 'Forte',
         'Low' => 'Faible',
-        'Med High' => 'Assez forte',
-        'Med Low' => 'Assez faible',
         'None' => 'Non Ã©tablie',
         'Normal' => 'Normale',
-        'Very High' => 'TrÃšs forte',
-        'Very Low' => 'TrÃšs faible',
       },
     },
@@ -3762,5 +3817,4 @@
         'Shutter Priority' => 'PrioritÃ© vitesse',
         'Snow' => 'Neige',
-        'Standard' => '',
         'Sunset' => 'Coucher de soleil',
         'Super Macro' => 'Super macro',
@@ -3843,4 +3897,5 @@
       },
     },
+   'SensitivityType' => 'Type de sensibilitÃ©',
    'SensorCleaning' => {
       PrintConv => {
@@ -3929,11 +3984,19 @@
       Description => 'Accentuation',
       PrintConv => {
+        '+1 (medium hard)' => '+1 (Assez dure)',
+        '+2 (hard)' => '+2 (Dure)',
+        '+3 (very hard)' => '+3 (TrÃšs dure)',
+        '+4 (hardest)' => '+4',
+        '+4 (maximum)' => '+4',
+        '-1 (medium soft)' => '-1 (Assez dure)',
+        '-2 (soft)' => '-2 (Douce)',
+        '-3 (very soft)' => '-3 (TrÃšs douce)',
+        '-4 (minimum)' => '-4',
+        '-4 (softest)' => '-4',
+        '0 (normal)' => '0 (Normale)',
         'Hard' => 'Dure',
-        'Med Hard' => 'Assez dure',
-        'Med Soft' => 'Assez douce',
         'Normal' => 'Normale',
+        'Sharp' => 'Dure',
         'Soft' => 'Douce',
-        'Very Hard' => 'TrÃšs dure',
-        'Very Soft' => 'TrÃšs douce',
         'n/a' => 'Non Ã©tablie',
       },
@@ -3982,5 +4045,5 @@
    'ShortDocumentID' => 'ID court de document',
    'ShortReleaseTimeLag' => {
-      Description => 'Intertie au dÃ©clenchement rÃ©duite',
+      Description => 'Inertie au dÃ©clenchement rÃ©duite',
       PrintConv => {
         'Disable' => 'DÃ©sactivÃ©',
@@ -4003,7 +4066,7 @@
       PrintConv => {
         'AE lock/AF' => 'Verrouillage AE/Autofocus',
-        'AE/AF, No AE lock' => 'AE/AF, pad de verrou. AE',
+        'AE/AF, No AE lock' => 'AE/AF, pas de verrou. AE',
         'AF/AE lock stop' => 'Autofocus/Verrouillage AE',
-        'AF/AF lock, No AE lock' => 'AF/ver.AF, pad de verr.AE',
+        'AF/AF lock, No AE lock' => 'AF/verr.AF, pas de verr.AE',
       },
     },
@@ -4097,5 +4160,5 @@
       },
     },
-   'State' => 'Etat',
+   'State' => 'Ãtat / RÃ©gion',
    'StreamType' => {
       PrintConv => {
@@ -4189,5 +4252,5 @@
       },
     },
-   'TargetPrinter' => 'Imprimantte cible',
+   'TargetPrinter' => 'Imprimante cible',
    'Technology' => {
       Description => 'Technologie',
@@ -4231,4 +4294,6 @@
    'ThumbnailImage' => 'Vignette',
    'ThumbnailImageSize' => 'Taille des miniatures',
+   'ThumbnailLength' => 'Longueur de la vignette',
+   'ThumbnailOffset' => 'DÃ©calage de la vignette',
    'ThumbnailWidth' => 'Hauteur de la vignette',
    'TileByteCounts' => 'Nombre d\'octets d\'Ã©lÃ©ment',
@@ -4246,4 +4311,5 @@
    'TimeSent' => 'Heure d\'envoi',
    'TimeSincePowerOn' => 'Temps Ã©coulÃ© depuis la mise en marche',
+   'TimeZone' => 'Fuseau horaire',
    'TimeZoneOffset' => 'Offset de zone de date',
    'TimerLength' => {
@@ -4323,6 +4389,6 @@
         'Disable in AF mode' => 'DÃ©sactivÃ©e en mode AF',
         'Enable after one-shot AF' => 'ActivÃ©e aprÃšs AF One-Shot',
-        'Turns off after one-shot AF' => 'DÃ©brayÃ© aprÃ©s One-Shot AF',
-        'Turns on after one-shot AF' => 'ActivÃ© aprÃ©s One-Shot AF',
+        'Turns off after one-shot AF' => 'DÃ©brayÃ© aprÃšs One-Shot AF',
+        'Turns on after one-shot AF' => 'ActivÃ© aprÃšs One-Shot AF',
       },
     },
@@ -4474,10 +4540,10 @@
    'WBAdjLighting' => {
       PrintConv => {
-        'Daylight' => 'LumiÃšre du jour',
+        'Daylight (cloudy)' => 'LumiÃšre du jour (2)',
+        'Daylight (direct sunlight)' => 'LumiÃšre du jour (0)',
+        'Daylight (shade)' => 'LumiÃšre du jour (1)',
         'None' => 'Aucune',
       },
     },
-   'WBAdjustAB' => 'Ajustement Balance des Blancs bleu/jaune',
-   'WBAdjustGM' => 'Ajustement Balance des Blancs vert/magenta',
    'WBBlueLevel' => 'Niveau Bleu Balance des Blancs',
    'WBBracketMode' => {
@@ -4497,11 +4563,10 @@
       PrintConv => {
         'LCD monitor' => 'Ãcran LCD',
-        'Rear LCD panel' => 'Panneau LCD arriÃšr',
+        'Rear LCD panel' => 'Panneau LCD arriÃšre',
       },
     },
    'WBRedLevel' => 'Niveau Rouge Balance des Blancs',
-   'WBShiftAB' => 'DÃ©calage bal. blancs ambre-bleu',
-   'WBShiftGM' => 'DÃ©calage bal. blancs vert-magenta',
-   'WBShiftMG' => 'DÃ©calage bal. blancs magenta-vert',
+   'WBShiftAB' => 'DÃ©calage Balance Blancs ambre-bleu',
+   'WBShiftGM' => 'DÃ©calage Balance Blancs vert-magenta',
    'WB_GBRGLevels' => 'Niveaux BB VBRV',
    'WB_GRBGLevels' => 'Niveaux BB VRBV',
@@ -4539,5 +4604,5 @@
    'WB_RGGBLevelsFluorescentD' => 'Niveaux BB RVVB fluorescent',
    'WB_RGGBLevelsFluorescentN' => 'Niveaux BB RVVB fluo N',
-   'WB_RGGBLevelsFluorescentW' => 'Niveaux BB RVVB fluoÂ W',
+   'WB_RGGBLevelsFluorescentW' => 'Niveaux BB RVVB fluo W',
    'WB_RGGBLevelsShade' => 'Niveaux BB RVVB ombre',
    'WB_RGGBLevelsTungsten' => 'Niveaux BB RVVB tungstÃšne',
@@ -4551,5 +4616,5 @@
         'Black & White' => 'Monochrome',
         'Cloudy' => 'Temps nuageux',
-        'Color Temperature/Color Filter' => 'Temp.Couleur / Filtre couleur',
+        'Color Temperature/Color Filter' => 'Temp. Couleur / Filtre couleur',
         'Cool White Fluorescent' => 'Fluorescente type soft',
         'Custom' => 'PersonnalisÃ©e',
@@ -4687,5 +4752,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -4694,6 +4759,6 @@
 =head1 ACKNOWLEDGEMENTS
 
-Thanks to Jens Duttke, Bernard Guillotin, Jean Glasser, Jean Piquemal and
-Harry Nizard for providing this translation.
+Thanks to Jens Duttke, Bernard Guillotin, Jean Glasser, Jean Piquemal, Harry
+Nizard and Alphonse Philippe for providing this translation.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/it.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/it.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/it.pm	(revision 34921)
@@ -12,19 +12,100 @@
 use vars qw($VERSION);
 
-$VERSION = '1.07';
+$VERSION = '1.14';
 
 %Image::ExifTool::Lang::it::Translate = (
+   'A100DataOffset' => 'Offset dati A100',
+   'AAFManufacturerID' => 'ID AAF produttore',
+   'ACoordOfBottomRightCorner' => 'Una coord in basso a destra',
+   'ACoordOfTopRightCorner' => 'Una coord in alto a destra',
+   'AEAperture' => 'Apertura esposizione automatica',
+   'AEBAutoCancel' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AEBSequenceAutoCancel' => {
+      PrintConv => {
+        '-,0,+/Disabled' => '-,0,+/Disabilitato',
+        '-,0,+/Enabled' => '-,0,+/Abilitato',
+        '0,-,+/Disabled' => '0,-,+/Disabilitato',
+        '0,-,+/Enabled' => '0,-,+/Abilitato',
+      },
+    },
+   'AEExposureTime' => 'Durata esposizione automatica',
+   'AEFlags' => {
+      Description => 'Flag esposizione automatica',
+      PrintConv => {
+        'AE lock' => 'Blocco esposizione automatica',
+        'Aperture wide open' => 'Diaframma molto aperto',
+        'Flash recommended?' => 'Flash consigliato?',
+      },
+    },
+   'AELExposureIndicator' => {
+      PrintConv => {
+        'Not Indicated' => 'Non indicato',
+      },
+    },
+   'AELock' => {
+      Description => 'Blocco esposizione automatica',
+      PrintConv => {
+        'Off' => 'Spento',
+        'On' => 'Acceso',
+      },
+    },
+   'AELockButton' => {
+      Description => 'Pulsante blocco esposizione automatica',
+      PrintConv => {
+        'Flash Off' => 'Flash spento',
+        'None' => 'Nessuno',
+        'Preview' => 'Anteprima',
+        'Virtual Horizon' => 'Orizzonte virtuale',
+      },
+    },
+   'AELockButtonPlusDials' => {
+      PrintConv => {
+        'Choose Image Area' => 'Seleziona area immagine',
+        'None' => 'Nessuno',
+      },
+    },
    'AEMeteringMode' => {
       PrintConv => {
+        'Center-weighted average' => 'Media centrale ponderata',
         'Multi-segment' => 'Multi zona',
       },
     },
+   'AEMicroadjustment' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
    'AEProgramMode' => {
       PrintConv => {
+        'Kids' => 'Bambini',
         'Landscape' => 'Orizzontale',
+        'No Flash' => 'No flash',
         'Portrait' => 'Verticale',
+        'Program' => 'Programma',
+        'Sunset' => 'Tramonto',
+        'Text' => 'Testo',
+      },
+    },
+   'AESetting' => {
+      PrintConv => {
+        'Exposure Compensation' => 'Compensazione esposizione',
+      },
+    },
+   'AE_ISO' => 'ISO esposizione automatica',
+   'AFAndMeteringButtons' => {
+      PrintConv => {
+        'No function' => 'Nessuna funzione',
       },
     },
    'AFAperture' => 'Diaframma AF',
+   'AFAreaIllumination' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'AFAreaMode' => {
       Description => 'Modo AF',
@@ -33,11 +114,42 @@
         'Dynamic Area (closest subject)' => 'Area Dinamica piÃ¹ Vicina al Soggetto',
         'Group Dynamic' => 'Gruppo Dinamico',
+        'Local' => 'Locale',
+        'Off (Manual Focus)' => 'Spento (focus manuale)',
         'Single Area' => 'Area Singola',
       },
     },
+   'AFAssist' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AFDuringLiveView' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+        'Quick mode' => 'Modo veloce',
+      },
+    },
+   'AFFineTune' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AFIlluminator' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
    'AFInfo' => 'Modo AF',
-   'AFMicroAdjActive' => {
-      PrintConv => {
-        'Yes' => 'Si',
+   'AFMode' => {
+      Description => 'Modo AF',
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'AFOnAELockButtonSwitch' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
       },
     },
@@ -45,23 +157,53 @@
       Description => 'Punto AF',
       PrintConv => {
+        '(none)' => '(nessuno)',
         'Bottom' => 'Basso',
         'Center' => 'Centro',
-        'Far Left' => 'Tutto a Sinistra',
-        'Far Right' => 'Tutto a Destra',
+        'Far Left' => 'Tutto a sinistra',
+        'Far Right' => 'Tutto a destra',
         'Left' => 'Sinistra',
-        'Lower-left' => 'Inferiore Sinistro',
-        'Lower-right' => 'Inferiore Destro',
-        'Mid-left' => 'Sinistra',
-        'Mid-right' => 'Destra',
+        'Lower-left' => 'Inferiore sinistro',
+        'Lower-right' => 'Inferiore destro',
+        'Mid-left' => 'Centro/Sinistra',
+        'Mid-right' => 'Centro/Destra',
         'None' => 'Nessuno',
         'Right' => 'Destra',
+        'Right (horizontal)' => 'Destra (orizzontale)',
+        'Right (vertical)' => 'Destra (verticale)',
         'Top' => 'Alto',
-        'Upper-left' => 'Superiore Sinistro',
-        'Upper-right' => 'Superiore Destro',
+        'Upper-left' => 'Superiore sinistro',
+        'Upper-right' => 'Superiore destro',
+      },
+    },
+   'AFPointActivationArea' => {
+      PrintConv => {
+        'Expanded' => 'Espanso',
+      },
+    },
+   'AFPointAreaExpansion' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
       },
     },
    'AFPointBrightness' => {
       PrintConv => {
+        'Low' => 'Basso',
         'Normal' => 'Normale',
+      },
+    },
+   'AFPointDisplayDuringFocus' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AFPointIllumination' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AFPointMode' => {
+      PrintConv => {
+        'Fixed Center' => 'Centro fisso',
+        'Select' => 'Seleziona',
       },
     },
@@ -81,42 +223,112 @@
         'Bottom' => 'Basso',
         'Center' => 'Centro',
+        'Far Left' => 'Tutto a sinistra',
+        'Far Right' => 'Tutto a destra',
+        'Fixed Center' => 'Centro fisso',
         'Left' => 'Sinistra',
-        'Right' => 'Destra',
-        'Top' => 'Alto',
-      },
-    },
-   'AFPointSelectionMethod' => {
-      PrintConv => {
-        'Normal' => 'Normale',
-      },
-    },
-   'AFPointsInFocus' => {
-      Description => 'Punti a Fuoco',
-      PrintConv => {
-        'Bottom' => 'Basso',
-        'Center' => 'Centro',
-        'Far Left' => 'Tutto a Sinistra',
-        'Far Right' => 'Tutto a Destra',
-        'Left' => 'Sinistra',
-        'Lower-left' => 'Inferiore Sinistro',
-        'Lower-right' => 'Inferiore Destro',
         'None' => 'Nessuno',
         'Right' => 'Destra',
         'Top' => 'Alto',
-        'Upper-left' => 'Superiore Sinistro',
-        'Upper-right' => 'Superiore Destro',
-      },
-    },
-   'AFPointsUsed' => {
+      },
+    },
+   'AFPointSelected2' => {
+      PrintConv => {
+        'Center' => 'Centro',
+        'Left' => 'Sinistra',
+        'Right' => 'Destra',
+      },
+    },
+   'AFPointSelection' => {
+      PrintConv => {
+        '11 Points' => '11 punti',
+      },
+    },
+   'AFPointSelectionMethod' => {
+      PrintConv => {
+        'Normal' => 'Normale',
+      },
+    },
+   'AFPoints' => {
+      PrintConv => {
+        'Center' => 'Centro',
+        'Left' => 'Sinistra',
+        'Right' => 'Destra',
+      },
+    },
+   'AFPointsInFocus' => {
+      Description => 'Punti a fuoco',
       PrintConv => {
         'Bottom' => 'Basso',
         'Center' => 'Centro',
-        'Far Left' => 'Tutto a Sinistra',
-        'Far Right' => 'Tutto a Destra',
-        'Lower-left' => 'Inferiore Sinistro',
-        'Lower-right' => 'Inferiore Destro',
+        'Far Left' => 'Tutto a sinistra',
+        'Far Right' => 'Tutto a destra',
+        'Left' => 'Sinistra',
+        'Lower-left' => 'Inferiore sinistro',
+        'Lower-right' => 'Inferiore destro',
+        'None' => 'Nessuno',
+        'Right' => 'Destra',
         'Top' => 'Alto',
-        'Upper-left' => 'Superiore Sinistro',
-        'Upper-right' => 'Superiore Destro',
+        'Upper-left' => 'Superiore sinistro',
+        'Upper-right' => 'Superiore destro',
+      },
+    },
+   'AFPointsInFocus1D' => 'Punti a fuoco 1D',
+   'AFPointsInFocus5D' => {
+      Description => 'Punti a fuoco 5D',
+      PrintConv => {
+        'Center' => 'Centro',
+        'Left' => 'Sinistra',
+        'Right' => 'Destra',
+      },
+    },
+   'AFPointsUnknown1' => {
+      PrintConv => {
+        'Center' => 'Centro',
+        'Left' => 'Sinistra',
+        'Right' => 'Destra',
+      },
+    },
+   'AFPointsUnknown2' => {
+      PrintConv => {
+        'Center' => 'Centro',
+        'Left' => 'Sinistra',
+        'Right' => 'Destra',
+      },
+    },
+   'AFPointsUsed' => {
+      PrintConv => {
+        'Bottom' => 'Basso',
+        'Center' => 'Centro',
+        'Far Left' => 'Tutto a sinistra',
+        'Far Right' => 'Tutto a destra',
+        'Lower-left' => 'Inferiore sinistro',
+        'Lower-right' => 'Inferiore destro',
+        'Top' => 'Alto',
+        'Upper-left' => 'Superiore sinistro',
+        'Upper-right' => 'Superiore destro',
+      },
+    },
+   'AFSearch' => {
+      PrintConv => {
+        'Not Ready' => 'Non pronto',
+        'Ready' => 'Pronto',
+      },
+    },
+   'AFWithShutter' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AIServoImagePriority' => {
+      PrintConv => {
+        '1: AF, 2: Drive speed' => '1: AF, 2: drive speed',
+        '1: AF, 2: Tracking' => '1: AF, 2: puntamento',
+        '1: Release, 2: Drive speed' => '1: rilascio, 2: drive speed',
+        '1: Release, 2: Tracking' => '1: rilascio, 2: puntamento',
+      },
+    },
+   'AIServoTrackingSensitivity' => {
+      PrintConv => {
+        'Fast' => 'Veloce',
       },
     },
@@ -124,39 +336,310 @@
    'ARMIdentifier' => 'ID ARM',
    'ARMVersion' => 'Versione ARM',
+   'AToB0' => 'Da A a B0',
+   'AToB1' => 'Da A a B1',
+   'AToB2' => 'Da A a B2',
+   'AberrationCorrectionDistance' => 'Distanza della correzione di aberrazione',
+   'About' => 'Informazioni su',
+   'AbsPeakAudioFilePath' => 'Percorso file audio del picco assoluto',
+   'AbsoluteChannelDisplayScale' => 'Scala assoluta canale',
+   'Abstract' => 'Sommario',
+   'AbstractPriorCodeSequence' => 'Sequenza codice precedente astratto',
+   'AbstractPriorValue' => 'Valore codice precedente astratto',
+   'AccessDate' => 'Data di accesso',
+   'AccessionNumber' => 'Numero di adesione',
+   'AccessoryCode' => 'Codice accessorio',
+   'AccessoryType' => 'Tipo accessorio',
+   'AccountName' => 'Nome account',
+   'AccountingReferenceNumber' => 'Riferimento contabile',
+   'AcqreconRecordChecksum' => 'Checksum del record AcqRecon',
+   'AcquiredImageAreaDoseProduct' => 'Dose prodotto dell\'area acquisita',
+   'AcquisitionComments' => 'Commenti acquisizione',
+   'AcquisitionContextDescription' => 'Descrizione contesto acquisizione',
+   'AcquisitionContextSequence' => 'Sequenza contesto acquisizione',
+   'AcquisitionContrast' => 'Contrasto acquisizione',
+   'AcquisitionDate' => 'Data acquisizione',
+   'AcquisitionDateTime' => 'Data/ora acquisizione',
+   'AcquisitionDeviceProcessingCode' => 'Codice processo di acquisizione del dispositivo',
+   'AcquisitionDeviceProcessingDescr' => 'Descrizione processo di acquisizione del dispositivo',
+   'AcquisitionDeviceTypeCodeSequence' => 'Sequenza codici tipo di acquisizione del dispositivo',
+   'AcquisitionDuration' => 'Durata acquisizione',
+   'AcquisitionEndConditionData' => 'Dati condizione fine acquisizione',
+   'AcquisitionGroupLength' => 'Lunghezza gruppo di acquisizione',
+   'AcquisitionIndex' => 'Indice acquisizione',
+   'AcquisitionMatrix' => 'Matrice acquisizione',
+   'AcquisitionNumber' => 'Numero acquisizione',
+   'AcquisitionProtocolDescription' => 'Descrizione protocollo di acquisizione',
+   'AcquisitionProtocolName' => 'Nome protocollo di acquisizione',
+   'AcquisitionStartCondition' => 'Condizione iniziale acquisizione',
+   'AcquisitionStartConditionData' => 'Dati condizione iniziale acquisizione',
+   'AcquisitionTerminationCondition' => 'Condizione finale acquisizione',
+   'AcquisitionTime' => 'Ora acquisizione',
+   'AcquisitionTimeDay' => 'Ora acquisizione - Giorno',
+   'AcquisitionTimeMonth' => 'Ora acquisizione - Mese',
+   'AcquisitionTimeSynchronized' => 'Ora acquisizione sincronizzata',
+   'AcquisitionTimeYear' => 'Ora acquisizione - Anno',
+   'AcquisitionTimeYearMonth' => 'Ora acquisizione - Anno mese',
+   'AcquisitionTimeYearMonthDay' => 'Ora acquisizione - Anno mese giorno',
+   'AcquisitionType' => 'Tipo acquisizione',
+   'AcquisitionsInSeries' => 'Acquisizioni in serie',
+   'AcquisitionsInStudy' => 'Acquisizioni in esame',
+   'AcrossScanSpatialResolution' => 'Attraverso risoluzione di scansione spaziale',
    'ActionAdvised' => {
       Description => 'Azione consigliata',
       PrintConv => {
+        'Object Append' => 'Allega oggetto',
         'Object Kill' => 'Distruzione oggetto',
         'Object Reference' => 'Riferimento oggetto',
         'Object Replace' => 'Sostituzione oggetto',
-        'Ojbect Append' => 'Allega oggetto',
-      },
-    },
-   'ActiveArea' => 'Area Attiva',
+      },
+    },
+   'ActiveArea' => 'Area attiva',
    'ActiveD-Lighting' => {
-      PrintConv => {
-        'Low' => 'Leggero',
+      Description => 'D-Lighting attivo',
+      PrintConv => {
+        'Extra High' => 'Molto alto',
+        'High' => 'Alto',
+        'Low' => 'Basso',
         'Normal' => 'Normale',
+        'Off' => 'Spento',
+        'On' => 'Acceso',
       },
     },
    'ActiveD-LightingMode' => {
-      PrintConv => {
-        'Low' => 'Leggero',
+      Description => 'ModalitÃ  D-Lighting attiva',
+      PrintConv => {
+        'Extra High' => 'Molto alto',
+        'High' => 'Alto',
+        'Low' => 'Basso',
         'Normal' => 'Normale',
-      },
-    },
+        'Off' => 'Spento',
+        'Unchanged' => 'Immutato',
+      },
+    },
+   'ActiveFormatDescriptor' => 'Descrittore formato attivo',
+   'ActiveLinesperFrame' => 'Linee per quadro attuali',
+   'ActiveSamplesperLine' => 'Linee per campione attuali',
+   'ActiveSourceDiameter' => 'Diametro sorgente attuale',
+   'ActiveSourceLength' => 'Lunghezza sorgente attuale',
+   'ActiveState' => 'Stato attivo',
+   'Actor' => 'Attore',
+   'ActualCardiacTriggerDelayTime' => 'Tempo di ritardo corrente trigger cardiaco',
+   'ActualCompensation' => 'Compensazione corrente',
+   'ActualFrameDuration' => 'Durata frame attuale',
+   'ActualHumanPerformersSequence' => 'Sequenza attuale esecutori umani',
+   'ActualReceiveGainAnalog' => 'Guadagno analogico in ricezione attuale',
+   'ActualReceiveGainDigital' => 'Guadagno digitale in ricezione attuale',
+   'ActualRespiratoryTriggerDelayTime' => 'Tempo di ritardo corrente trigger respiratorio',
+   'ActualSeriesDataTimeStamp' => 'Marca temporale serie di dati attuali',
+   'Ad-ID' => 'ID Ad',
+   'AdaptiveMapFormat' => 'Formato mappa adattativa',
+   'AddAspectRatioInfo' => {
+      Description => 'Aggiunta info rapporto di aspetto',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AddIntermediateSequence' => 'Aggiunta sequenza intermedia',
+   'AddNearSequence' => 'Aggiunta sequenza vicina',
+   'AddOriginalDecisionData' => {
+      Description => 'Aggiunta dati decisione originale',
+      PrintConv => {
+        'Off' => 'Spento',
+        'On' => 'Acceso',
+      },
+    },
+   'AddOtherSequence' => 'Aggiunta altra sequenza',
+   'AddPower' => 'Aggiunta potenza',
+   'AdditionalDrugSequence' => 'Sequenza farmaci addizionali',
+   'AdditionalModelInformation' => 'Ulteriori informazioni modello',
+   'AdditionalPatientHistory' => 'Ulteriore storia del paziente',
+   'Address' => 'Indirizzo',
+   'AddressLine' => 'Linea indirizzo',
+   'AddressNameValueSets' => 'Gruppi di valori nome indirizzo',
+   'AddressSets' => 'Gruppi di indirizzi',
+   'AddressTrial' => 'Studio indirizzo',
+   'AdjustmentMode' => 'Modo adattamento',
+   'AdministrationRouteCodeSequence' => 'Sequenza codici percorso di amministrazione',
+   'AdmissionID' => 'ID ammissione',
+   'AdmittingDate' => 'Data ammissione',
+   'AdmittingDiagnosesCodeSequence' => 'Sequenza codici diagnosi ammissione',
+   'AdmittingDiagnosesDescription' => 'Descrizioni diagnosi ammissione',
+   'AdmittingTime' => 'Ora ammissione',
+   'AdobeCMType' => 'Tipo Adobe CM',
+   'AdoptedNeutral' => 'Adottato neutro',
    'AdultContentWarning' => {
-      PrintConv => {
-        'Unknown' => 'Sconosciuta',
+      Description => 'Avviso contenuto per adulti',
+      PrintConv => {
+        'Adult Content Warning Required' => 'Avviso contenuto per adulti richiesto',
+        'Not Required' => 'Non richiesto',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'AdvancedContentEncryption' => 'Crittografia avanzata del contenuto',
+   'AdvancedMutualExcl' => 'Mutua esclusione avanzata',
+   'AdvancedRaw' => {
+      Description => 'Raw avanzato',
+      PrintConv => {
+        'Off' => 'Spento',
+        'On' => 'Acceso',
+      },
+    },
+   'AdvancedSceneMode' => {
+      Description => 'Modo scena avanzato',
+      PrintConv => {
+        'Architecture' => 'Architettura',
+        'Color Select' => 'Selezione colore',
+        'Creative Macro' => 'Macro creativo',
+        'Creative Night Scenery' => 'Scenario notturno creativo',
+        'Creative Portrait' => 'Ritratto creativo',
+        'Creative Scenery' => 'Scenario creativo',
+        'Creative Sports' => 'Sport creativi',
+        'Cross Process' => 'Cross process',
+        'Dynamic Art' => 'Arte dinamica',
+        'Dynamic Monochrome' => 'Monocromatico dinamico',
+        'Elegant' => 'Elegante',
+        'Expressive' => 'Espressivo',
+        'Flower' => 'Fiore',
+        'HDR Art' => 'HDR artistico',
+        'HDR B&W' => 'HDR in bianco e nero',
+        'High Dynamic' => 'High dynamic',
+        'High Key' => 'High key',
+        'Illuminations' => 'Illuminazioni',
+        'Indoor Portrait' => 'Ritratto al chiuso',
+        'Indoor Sports' => 'Sport al chiuso',
+        'Low Key' => 'Low key',
+        'Minature' => 'Minuatura',
+        'Monochrome' => 'Monocromatico',
+        'Nature' => 'Natura',
+        'Objects' => 'Oggetti',
+        'Off' => 'Spento',
+        'Outdoor Portrait' => 'Ritratto all\'aperto',
+        'Outdoor Sports' => 'Sport all\'aperto',
+        'Pure' => 'Puro',
+        'Retro' => 'RetrÃ²',
+        'Sepia' => 'Seppia',
+        'Soft' => 'Morbido',
+        'Star' => 'Stella',
+        'Toy Effect' => 'Effetto giocattolo',
+      },
+    },
+   'AdvancedSceneType' => 'Tipo scena avanzato',
+   'AdvantageCompOverflow' => 'Overflow componente avanzato',
+   'AdvantageCompUnderflow' => 'Underflow componente avanzato',
+   'AdventRevision' => 'Revisione arrivo',
+   'AdventScale' => 'Scala arrivo',
+   'AdvertisingMaterialReference' => 'Riferimento materiale pubblicitario',
+   'Advisory' => 'Consultivo',
+   'AlbumArtistSortOrder' => 'Ordinamento album-artista',
+   'AlbumSortOrder' => 'Ordinamento album',
+   'AliasLayerMetadata' => 'Livello metadati alias',
+   'AlphaByteCount' => 'Numero byte trasparenza',
+   'AlphaDataDiscard' => {
+      Description => 'Scarto dati trasparenza',
+      PrintConv => {
+        'Flexbits Discarded' => 'Flexbit scartati',
+        'Full Resolution' => 'Risoluzione piena',
+        'HighPass Frequency Data Discarded' => 'Dati in frequenza passa-alto scartati',
+        'Highpass and LowPass Frequency Data Discarded' => 'Dati in frequenza passa-alto e passa-basso scartati',
+      },
+    },
+   'AlphaInterlace' => {
+      PrintConv => {
+        'Noninterlaced' => 'Non interlacciato',
+      },
+    },
+   'AlphaOffset' => 'Scostamento trasparenza',
+   'AlphaTransparency' => {
+      PrintConv => {
+        'Not Inverted' => 'Non invertito',
+      },
+    },
+   'AmbienceSelection' => {
+      PrintConv => {
+        'Vivid' => 'Vivace',
       },
     },
    'AnalogBalance' => 'Bilanciamento analogico',
+   'Annotation' => 'Annotazione',
+   'Annotations' => 'Annotazioni',
+   'Anti-Blur' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'AntiAliasStrength' => 'Forza antialiasing',
    'Aperture' => 'Diaframma',
-   'ApertureValue' => 'Diaframma',
+   'ApertureDisplayed' => 'Diaframma mostrato',
+   'ApertureRange' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'ApertureRingUse' => {
+      PrintConv => {
+        'Prohibited' => 'Proibito',
+      },
+    },
+   'ApertureValue' => 'Apertura diaframma',
+   'AppleStoreCountry' => {
+      PrintConv => {
+        'Italy' => 'Italia',
+        'Japan' => 'Giappone',
+        'Norway' => 'Norvegia',
+        'Portugal' => 'Portogallo',
+        'Sweden' => 'Svezia',
+        'United Kingdom' => 'Regno Unito',
+        'United States' => 'Stati Uniti',
+      },
+    },
+   'ApplicationNotes' => 'Note applicazione',
    'ApplicationRecordVersion' => 'Versione Registrazione Applicazione',
+   'ApplyShootingMeteringMode' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'ArtFilter' => {
+      PrintConv => {
+        'Fish Eye' => 'Fish-eye',
+        'Fragmented' => 'Frammentato',
+        'Gentle Sepia' => 'Seppia leggero',
+        'Off' => 'Spento',
+        'Reflection' => 'Riflessione',
+      },
+    },
+   'ArtFilterEffect' => {
+      PrintConv => {
+        'Fish Eye' => 'Fish-eye',
+        'Fragmented' => 'Frammentato',
+        'Gentle Sepia' => 'Seppia leggero',
+        'Off' => 'Spento',
+        'Reflection' => 'Riflessione',
+        'Star Light' => 'Luce stelle',
+      },
+    },
+   'ArtMode' => {
+      PrintConv => {
+        'Normal' => 'Normale',
+      },
+    },
    'Artist' => 'Persona che ha creato l\'immagine',
-   'AsShotNeutral' => 'Neutrale Come Scattato',
-   'AsShotProfileName' => 'Nome Profilo Come Scattato',
-   'AsShotWhiteXY' => 'Bilanciamento Bianco X-T Come Scattato',
+   'Artist2' => 'Artista 2',
+   'ArtistURL' => 'URL artista',
+   'AsShotICCProfile' => 'Profilo ICC allo scatto',
+   'AsShotNeutral' => 'Neutrale allo scatto',
+   'AsShotPreProfileMatrix' => 'Matrice pre-profilo allo scatto',
+   'AsShotProfileName' => 'Nome profilo allo scatto',
+   'AsShotWhiteXY' => 'Bilanciamento del bianco X-T allo scatto',
+   'AspectRatio' => 'Rapporto immagine',
+   'AspectRatioType' => {
+      Description => 'Tipo rapporto immagine',
+      PrintConv => {
+        'Fixed' => 'Fisso',
+      },
+    },
+   'AspectRatioX' => 'Rapporto immagine X',
+   'AspectRatioY' => 'Rapporto immagine Y',
    'AssistButtonFunction' => {
       PrintConv => {
@@ -164,20 +647,110 @@
       },
     },
+   'Attachments' => 'Allegati',
    'Audio' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'AudioType' => 'Tipo Audio',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'AudioAttributes' => {
+      Description => 'Attributi audio',
+      PrintConv => {
+        'Encrypted' => 'Crittografato',
+      },
+    },
+   'AudioBytes' => 'Byte audio',
+   'AudioChannelType' => 'Tipo canale audio',
+   'AudioChannels' => 'Canali audio',
+   'AudioCodec' => 'Codec audio',
+   'AudioCodecDescription' => 'Descrizione codec audio',
+   'AudioCodecID' => {
+      Description => 'ID codec audio',
+      PrintConv => {
+        'QDesign Music' => 'Musica QDesign',
+        'Unknown -' => 'Sconosciuto -',
+      },
+    },
+   'AudioCodecInfo' => 'Info codec audio',
+   'AudioCodecName' => 'Nome codec audio',
+   'AudioCompression' => 'Compressione audio',
+   'AudioCompressionAlgorithm' => 'Algoritmo di compressione audio',
+   'AudioFormat' => 'Formato audio',
+   'AudioLayer' => 'Livello audio',
+   'AudioStreamType' => {
+      PrintConv => {
+        'Reserved' => 'Riservato',
+      },
+    },
+   'AudioType' => {
+      Description => 'Tipo Audio',
+      PrintConv => {
+        'Text Only' => 'Solo testo',
+      },
+    },
    'Author' => 'Autore',
    'AuthorsPosition' => 'Posizione dell\'autore',
+   'AutoAperture' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AutoBracketModeM' => {
+      PrintConv => {
+        'Flash Only' => 'Solo flash',
+      },
+    },
+   'AutoBracketSet' => {
+      PrintConv => {
+        'Exposure' => 'Esposizione',
+        'Flash Only' => 'Solo flash',
+      },
+    },
+   'AutoBracketing' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AutoDistortionControl' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AutoExposureBracketing' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AutoFP' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AutoFocus' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'AutoISO' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'AutoLightingOptimizer' => {
       PrintConv => {
-        'Low' => 'Leggero',
+        'Enable' => 'Abilita',
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+        'Strong' => 'Forte',
+        'n/a' => 'n/d',
       },
     },
    'AutoLightingOptimizerOn' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'AutoRedEye' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
@@ -185,16 +758,41 @@
       PrintConv => {
         'None' => 'Nessuno',
-        'Rotate 180' => '180Â° (basso/destra)',
+        'Rotate 180' => 'Ruota di 180Â°',
         'Rotate 270 CW' => 'Ruota di 270Â° in senso orario',
-        'Rotate 90 CW' => '90Â° senso antiorario (destra/alto)',
-        'n/a' => 'Sconosciuta',
+        'Rotate 90 CW' => 'Ruota di 90Â° senso orario',
+        'n/a' => 'n/d',
       },
     },
    'AuxiliaryLens' => 'Obiettivo Ausiliario',
+   'AvSettingWithoutLens' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'AverageLevel' => 'Livello medio',
+   'Azimuth' => {
+      PrintConv => {
+        'NNW' => 'NNO',
+      },
+    },
+   'BWMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'BackgroundColorIndicator' => {
+      Description => 'Indicatore colore di sfondo',
+      PrintConv => {
+        'Specified Background Color' => 'Colore di sfondo specificato',
+        'Unspecified Background Color' => 'Colore di sfondo non specificato',
+      },
+    },
+   'BackgroundColorValue' => 'Valore colore di sfondo',
    'BackgroundTiling' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'BadFaxLines' => 'Linee fax non valide',
    'BannerImageType' => {
       PrintConv => {
@@ -202,11 +800,72 @@
       },
     },
-   'BatteryLevel' => 'Livello Batteria',
-   'BestQualityScale' => 'Scala QualitÃ  Migliore',
+   'BaselineExposure' => 'Esposizione di riferimento',
+   'BaselineNoise' => 'Rumore di riferimento',
+   'BaselineSharpness' => 'Nitidezza di riferimento',
+   'BatteryLevel' => 'Livello batteria',
+   'BatteryState' => {
+      PrintConv => {
+        'Low' => 'Basso',
+      },
+    },
+   'BeatsPerMinute' => 'Battiti al minuto',
+   'Beep' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+      },
+    },
+   'BeepPitch' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+      },
+    },
+   'BeepVolume' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'BestQualityScale' => 'Scala qualitÃ  migliore',
+   'BestShotMode' => {
+      PrintConv => {
+        'Children' => 'Bambini',
+        'Fireworks' => 'Fuochi artificiali',
+        'Flower' => 'Fiore',
+        'For YouTube' => 'Per YouTube',
+        'For eBay' => 'Per eBay',
+        'Off' => 'Spento',
+        'Retro' => 'RetrÃ²',
+        'Scenery' => 'Paesaggio',
+        'Short Movie' => 'Filmato breve',
+        'Text' => 'Testo',
+      },
+    },
    'BitsPerComponent' => 'Bits per componente',
-   'BitsPerSample' => 'Numero di bits per componente',
-   'BlackLevel' => 'Livello Nero',
+   'BitsPerExtendedRunLength' => 'Bit per rrun-length esteso',
+   'BitsPerRunLength' => 'Bit per rrun-length',
+   'BitsPerSample' => 'Numero di bit per componente',
+   'BlackLevel' => 'Livello del nero',
+   'BlackLevelDeltaH' => 'Livello del nero - Delta H',
+   'BlackLevelDeltaV' => 'Livello del nero - Delta V',
+   'BlackLevelRepeatDim' => 'Dim ripeti livello del nero',
+   'BleachBypassToning' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'Off' => 'Spento',
+        'Purple' => 'Porpora',
+        'Red' => 'Rosso',
+      },
+    },
+   'BlocksPerFrame' => 'Blocchi per frame',
+   'BlueBalance' => 'Bilanciamento del blu',
    'BlueMatrixColumn' => 'Colonna della Matrice Blu',
-   'BlueTRC' => 'Curva Riproduzione Tono Blu',
+   'BlueTRC' => 'Curva riproduzione tono blu',
+   'BlurControl' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+      },
+    },
    'BlurWarning' => {
       PrintConv => {
@@ -214,16 +873,109 @@
       },
     },
+   'BracketMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'BracketShotNumber' => {
+      PrintConv => {
+        '1 of 2' => '1 di 5',
+        '1 of 3' => '1 di 3',
+        '1 of 5' => '1 di 2',
+        'n/a' => 'n/d',
+      },
+    },
    'Brightness' => 'LuminositÃ ',
-   'BrightnessValue' => 'LuminositÃ ',
+   'BrightnessValue' => 'Valore di luminositÃ ',
+   'BuildDate' => 'Data compilazione',
+   'BuildVersion' => 'Versione compilazione',
+   'BurstMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ButtonFunctionControlOff' => {
+      PrintConv => {
+        'Normal (enable)' => 'Normale (abilitato)',
+      },
+    },
    'By-line' => 'Creatore',
    'By-lineTitle' => 'Titolo Creatore',
+   'CCDScanMode' => {
+      PrintConv => {
+        'Progressive' => 'Progressivo',
+      },
+    },
+   'CFALayout' => {
+      Description => 'Layout CFA',
+      PrintConv => {
+        'Even columns offset down 1/2 row' => 'Colonne pari giÃ¹ di 1/2 riga',
+        'Even columns offset up 1/2 row' => 'Colonne pari su di 1/2 riga',
+        'Even rows offset down by 1/2 row, even columns offset left by 1/2 column' => 'Righe pari giÃ¹ di 1/2 riga, colonne pari a sinistra di 1/2 colonna',
+        'Even rows offset down by 1/2 row, even columns offset right by 1/2 column' => 'Righe pari giÃ¹ di 1/2 riga, colonne pari a destra di 1/2 colonna',
+        'Even rows offset left 1/2 column' => 'Righe pari a sinistra di 1/2 colonna',
+        'Even rows offset right 1/2 column' => 'Righe pari a destra di 1/2 colonna',
+        'Even rows offset up by 1/2 row, even columns offset left by 1/2 column' => 'Righe pari su 1/2 riga, colonne pari a sinistra di 1/2 colonna',
+        'Even rows offset up by 1/2 row, even columns offset right by 1/2 column' => 'Righe pari su 1/2 riga, colonne pari a destra di 1/2 colonna',
+        'Rectangular' => 'Rettangolare',
+      },
+    },
    'CFAPattern' => 'Pattern CFA',
+   'CFAPattern2' => 'Pattern CFA 2',
+   'CFAPlaneColor' => 'Piano colori CFA',
+   'CFARepeatPatternDim' => 'Dim pattern ripetuto CFA',
+   'CHMVersion' => 'Versione CHM',
+   'CIP3DataFile' => 'File di dati CIP3',
+   'CIP3Sheet' => 'Foglio CIP3',
+   'CIP3Side' => 'Lato CIP3',
+   'CMYKEquivalent' => 'CMYK equivalente',
+   'CPUArchitecture' => 'Architettura CPU',
+   'CPUByteOrder' => {
+      Description => 'Ordine byte CPU',
+      PrintConv => {
+        'Big endian' => 'Big-endian',
+        'Little endian' => 'Little-endian',
+      },
+    },
+   'CPUCount' => 'Numero processori',
+   'CPUSubtype' => {
+      Description => 'Sottotipo CPU',
+      PrintConv => {
+        'ARM (all)' => 'ARM (tutti)',
+        'HPPA (all)' => 'HPPA (tutti)',
+        'MC680x0 (all)' => 'MC680x0 (tutti)',
+        'MC88000 (all)' => 'MC88000 (tutti)',
+        'MC98000 (all)' => 'MC98000 (tutti)',
+        'MIPS (all)' => 'MIPS (tutti)',
+        'NS32032 (all)' => 'NS32032 (tutti)',
+        'NS32032 DPC (032 CPU)' => 'NS32032 DPC (CPU 032)',
+        'NS32332 (all)' => 'NS32332 (tutti)',
+        'NS32332 DPC (032 CPU)' => 'NS32332 DPC (CPU 032)',
+        'PowerPC (all)' => 'PowerPC (tutti)',
+        'RS6000 (all)' => 'RS6000 (tutti)',
+        'RT (all)' => 'RT (tutti)',
+        'SPARC (all)' => 'SPARC (tutti)',
+        'VAX (all)' => 'VAX (tutti)',
+        'i386 (all)' => 'i386 (tutti)',
+        'i860 (all)' => 'i860 (tutti)',
+        'i860 little (all)' => 'i860 little (tutti)',
+      },
+    },
    'CPUType' => {
-      PrintConv => {
+      Description => 'Tipo CPU',
+      PrintConv => {
+        'Any' => 'Qualsiasi',
+        'Axis Communications 32-bit embedded processor' => 'Processore integrato a 32 bit Axis Communications',
         'None' => 'Nessuno',
-      },
-    },
-   'CalibrationDateTime' => 'Data e Ora della Calibrazione',
+        'S/390 (old)' => 'S/390 (precedente)',
+        'i860 big endian' => 'i860 big-endian',
+        'i860 little endian' => 'i860 little-endian',
+        'm32r (old)' => 'm32r (precedente)',
+        'v850 (old)' => 'v850 (precedente)',
+      },
+    },
+   'CalibrationDateTime' => 'Data/ora di calibrazione',
    'CalibrationIlluminant1' => {
+      Description => 'Calibration illuminazione 1',
       PrintConv => {
         'Cloudy' => 'Nuvoloso',
@@ -241,5 +993,5 @@
         'Standard Light C' => 'Luce standard C',
         'Tungsten (Incandescent)' => 'Tungsteno (luce incandescente)',
-        'Unknown' => 'Sconosciuta',
+        'Unknown' => 'Sconosciuto',
         'Warm White Fluorescent' => 'Luce fluorescente bianca calda',
         'White Fluorescent' => 'Fluorescente bianca',
@@ -247,4 +999,5 @@
     },
    'CalibrationIlluminant2' => {
+      Description => 'Calibration illuminazione 2',
       PrintConv => {
         'Cloudy' => 'Nuvoloso',
@@ -262,30 +1015,120 @@
         'Standard Light C' => 'Luce standard C',
         'Tungsten (Incandescent)' => 'Tungsteno (luce incandescente)',
-        'Unknown' => 'Sconosciuta',
+        'Unknown' => 'Sconosciuto',
         'Warm White Fluorescent' => 'Luce fluorescente bianca calda',
         'White Fluorescent' => 'Fluorescente bianca',
       },
     },
-   'CameraCalibration1' => 'Calibrazione Fotocamera 1',
-   'CameraCalibration2' => 'Calibrazione Fotocamera 2',
+   'CameraAngle' => 'Angolo fotocamera',
+   'CameraBody' => 'Corpo fotocamera',
+   'CameraByteOrder' => 'Ordine byte fotocamera',
+   'CameraCalibration1' => 'Calibrazione fotocamera 1',
+   'CameraCalibration2' => 'Calibrazione fotocamera 2',
+   'CameraCalibrationSig' => 'Segnale calibrazione fotocamera',
+   'CameraColorCalibration01' => 'Calibrazione colore fotocamera 01',
+   'CameraColorCalibration02' => 'Calibrazione colore fotocamera 02',
+   'CameraColorCalibration03' => 'Calibrazione colore fotocamera 03',
+   'CameraColorCalibration04' => 'Calibrazione colore fotocamera 04',
+   'CameraColorCalibration05' => 'Calibrazione colore fotocamera 05',
+   'CameraColorCalibration06' => 'Calibrazione colore fotocamera 06',
+   'CameraColorCalibration07' => 'Calibrazione colore fotocamera 07',
+   'CameraColorCalibration08' => 'Calibrazione colore fotocamera 08',
+   'CameraColorCalibration09' => 'Calibrazione colore fotocamera 09',
+   'CameraColorCalibration10' => 'Calibrazione colore fotocamera 10',
+   'CameraColorCalibration11' => 'Calibrazione colore fotocamera 11',
+   'CameraColorCalibration12' => 'Calibrazione colore fotocamera 12',
+   'CameraColorCalibration13' => 'Calibrazione colore fotocamera 13',
+   'CameraColorCalibration14' => 'Calibrazione colore fotocamera 14',
+   'CameraColorCalibration15' => 'Calibrazione colore fotocamera 15',
+   'CameraDateTime' => 'Data/ora fotocamera',
+   'CameraDirection' => 'Direzione fotocamera',
+   'CameraID' => 'ID fotocamera',
+   'CameraISO' => 'ISO fotocamera',
+   'CameraIdentifier' => 'Identificativo fotocamera',
+   'CameraLabel' => 'Etichetta fotocamera',
+   'CameraMaker' => 'Marca fotocamera',
+   'CameraManufacturer' => 'Produttore fotocamera',
+   'CameraModel' => 'Modello fotocamera',
+   'CameraMotion' => 'Camera motion',
+   'CameraMove' => 'Sposta fotocamera',
+   'CameraName' => 'Nome fotocamera',
+   'CameraObjBackType' => 'Nome oggetto nero fotocamera',
+   'CameraObjName' => 'Nome oggetto fotocamera',
+   'CameraObjType' => 'Tipo oggetto fotocamera',
+   'CameraObjVersion' => 'Versione oggetto fotocamera',
    'CameraOrientation' => {
-      Description => 'Orientamento dell\'immagine',
-      PrintConv => {
-        'Horizontal (normal)' => '0Â° (alto/sinistra)',
+      Description => 'Orientazione fotocamera',
+      PrintConv => {
+        'Horizontal (normal)' => 'Orizzontale (normale)',
+        'Rotate 180' => 'Ruota di 180Â°',
         'Rotate 270 CW' => 'Ruota di 270Â° in senso orario',
-        'Rotate 90 CW' => '90Â° senso antiorario (destra/alto)',
-      },
-    },
+        'Rotate 90 CW' => 'Ruota di 90Â° senso orario',
+      },
+    },
+   'CameraOwner' => 'Proprietario fotocamera',
+   'CameraParameters' => 'Parametri fotocamera',
+   'CameraProfile' => 'Profilo fotocamera',
+   'CameraProfileDigest' => 'Sommario profilo fotocamera',
+   'CameraProfileVersion' => 'Versione profilo fotocamera',
+   'CameraSerialNumber' => 'Numero di serie fotocamera',
+   'CameraSettingsVersion' => 'Versione impostazioni fotocamera',
+   'CameraTemperature' => 'Temperatura fotocamera',
+   'CameraTemperature2' => 'Temperatura fotocamera 2',
+   'CameraTemperature3' => 'Temperatura fotocamera 3',
+   'CameraTemperature4' => 'Temperatura fotocamera 4',
+   'CameraTemperature5' => 'Temperatura fotocamera 5',
+   'CameraType' => {
+      Description => 'Tipo fotocamera',
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'CameraType2' => 'Tipo fotocamera 2',
    'CanonExposureMode' => {
       PrintConv => {
         'Aperture-priority AE' => 'PrioritÃ  diaframma',
         'Manual' => 'Manuale',
-        'Shutter speed priority AE' => 'PrioritÃ  otturatore',
-      },
-    },
-   'Caption-Abstract' => 'Didascalia/Descrizione',
+        'Program AE' => 'Programma AE',
+        'Shutter speed priority AE' => 'PrioritÃ  otturatore AE',
+      },
+    },
+   'CanonFlashMode' => {
+      PrintConv => {
+        'External flash' => 'Flash esterno',
+        'Off' => 'Spento',
+        'Red-eye reduction' => 'Riduzione occhi rossi',
+        'Red-eye reduction (Auto)' => 'Riduzione occhi rossi (auto)',
+        'Red-eye reduction (On)' => 'Riduzione occhi rossi (attivo)',
+      },
+    },
+   'CanonImageSize' => {
+      PrintConv => {
+        'Postcard' => 'Cartolina',
+      },
+    },
+   'Caption-Abstract' => 'Didascalia/descrizione',
    'CaptionWriter' => 'Autore della didascalia',
-   'Categories' => 'Categorie',
+   'CardShutterLock' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'CasioQuality' => {
+      Description => 'QualitÃ  Casio',
+      PrintConv => {
+        'Normal' => 'Normale',
+      },
+    },
+   'Categories' => {
+      Description => 'Categorie',
+      PrintConv => {
+        'Events' => 'Eventi',
+        'Scenery' => 'Paesaggio',
+        'To Do' => 'Da fare',
+      },
+    },
    'Category' => 'Categoria',
+   'CellLength' => 'Lunghezza cella',
+   'CellWidth' => 'Larghezza cella',
    'CenterWeightedAreaSize' => {
       PrintConv => {
@@ -293,24 +1136,135 @@
       },
     },
-   'CharacterSet' => 'Impostazioni Carattere',
-   'ChromaticAdaptation' => 'Adattamento Cromatico',
+   'ChExtra' => 'Larghezza aggiunta per caratteri non spaziatori',
+   'Channel' => 'Canale',
+   'ChannelID' => 'ID canale',
+   'ChannelIdentificationCode' => 'Codice identificativo canale',
+   'ChannelLabel' => 'Etichetta canale',
+   'ChannelLength' => 'Lunghezza canale',
+   'ChannelMode' => 'Modo canale',
+   'ChannelNumber' => 'Numero canale',
+   'ChannelPositions' => 'Posizioni canale',
+   'ChannelStatus' => 'Stato canale',
+   'ChannelStatusMode' => 'Modo stato canale',
+   'ChannelTotalTime' => 'Tempo totale canale',
+   'ChannelWidth' => 'Larghezza canale',
+   'Channels' => 'Canali',
+   'Chapter' => 'Capitolo',
+   'ChapterPhysicalEquivalent' => {
+      PrintConv => {
+        'Session' => 'Sessione',
+        'Side' => 'Lato',
+      },
+    },
+   'ChapterProcessTime' => {
+      PrintConv => {
+        'For Duration of Chapter' => 'Per la durata del capitolo',
+      },
+    },
+   'CharacterSet' => {
+      Description => 'Set di caratteri',
+      PrintConv => {
+        'Windows, Arabic' => 'Windows, Arabo',
+        'Windows, Chinese (Simplified)' => 'Windows, Cinese semplificato',
+        'Windows, Cyrillic' => 'Windows, Cirillico',
+        'Windows, Greek' => 'Windows, Greco',
+        'Windows, Hebrew' => 'Windows, Ebraico',
+        'Windows, Japan (Shift - JIS X-0208)' => 'Windows, Giappone (Shift - JIS X-0208)',
+        'Windows, Korea (Shift - KSC 5601)' => 'Windows, Corea (Shift - KSC 5601)',
+        'Windows, Latin2 (Eastern European)' => 'Windows, Latin2 (Europa orientale)',
+        'Windows, Turkish' => 'Windows, Turco',
+      },
+    },
+   'Characters' => 'Caratteri',
+   'CharactersWithSpaces' => 'Caratteri con spazi',
+   'Children' => 'Bambini',
+   'ChromaBlurRadius' => 'Raggio sfocatura cromatica',
+   'ChromaticAberrationCorrection' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ChromaticAdaptation' => 'Adattamento cromatico',
    'Chromaticity' => 'Cromatismo',
    'ChrominanceNR_TIFF_JPEG' => {
       PrintConv => {
-        'Low' => 'Leggero',
+        'Low' => 'Basso',
+        'Off' => 'Spento',
       },
     },
    'ChrominanceNoiseReduction' => {
       PrintConv => {
-        'Low' => 'Leggero',
+        'Low' => 'Basso',
+        'Off' => 'Spento',
       },
     },
    'City' => 'CittÃ ',
    'ClassifyState' => 'Stato di Classificazione',
+   'CleanFaxData' => {
+      Description => 'Dati fax precisi',
+      PrintConv => {
+        'Clean' => 'Pulito',
+        'Regenerated' => 'Rigenerato',
+        'Unclean' => 'Sporco',
+      },
+    },
+   'ClipPath' => 'Percoso clip',
+   'CodePage' => {
+      PrintConv => {
+        'Japanese (JIS 0208-1990 and 0121-1990)' => 'Giapponese (JIS 0208-1990 e 0121-1990)',
+        'Russian/Cyrillic (KOI8-R)' => 'Russo/Cirillico (KOI8-R)',
+      },
+    },
+   'CodeSize' => 'Dimensione codice',
    'CodedCharacterSet' => 'Impostazione Caratteri Codificati',
+   'CodedContentScanningKind' => {
+      PrintConv => {
+        'Mixed' => 'Misto',
+        'Progressive' => 'Progressivo',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'CodingMethods' => {
+      Description => 'Metodi di codifica',
+      PrintConv => {
+        'Baseline JPEG' => 'Linea di base JPEG',
+        'JBIG color' => 'JBIG a colori',
+        'Modified Huffman' => 'Huffman modificato',
+        'Unspecified compression' => 'Compressione non specificata',
+      },
+    },
+   'ColorAberrationControl' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ColorAdjustmentMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'ColorBalance' => 'Bilanciamento Colore',
+   'ColorBalanceAdj' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ColorBalanceVersion' => 'Versione Bilanciamento Colore',
+   'ColorBooster' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ColorCharacterization' => 'Caratterizzazione colore',
+   'ColorClass' => {
+      PrintConv => {
+        '0 (None)' => '0 (Nessuno)',
+        '1 (Winner)' => '1 (Vincitore)',
+      },
+    },
    'ColorEffect' => {
       PrintConv => {
-        'Sepia' => 'Viraggio seppia',
+        'Off' => 'Spento',
+        'Sepia' => 'Seppia',
       },
     },
@@ -319,13 +1273,17 @@
       PrintConv => {
         'Green' => 'Verde',
+        'Off' => 'Spento',
+        'Purple' => 'Porpora',
         'Red' => 'Rosso',
+        'Sepia' => 'Seppia',
         'Yellow' => 'Giallo',
       },
     },
    'ColorHue' => 'Colore Hue',
-   'ColorMatrix1' => 'Matrice di Colore 1',
-   'ColorMatrix2' => 'Matrice di Colore 2',
+   'ColorMap' => 'Mappa colore',
+   'ColorMatrix1' => 'Matrice colore 1',
+   'ColorMatrix2' => 'Matrice colore 2',
    'ColorMode' => {
-      Description => 'Modo Colore',
+      Description => 'Modo colore',
       PrintConv => {
         'Autumn Leaves' => 'Foglie d\'autunno',
@@ -334,4 +1292,5 @@
         'Deep' => 'Cupa',
         'Evening' => 'Sera',
+        'Grayscale' => 'Scala di grigi',
         'Landscape' => 'Orizzontale',
         'Light' => 'Chiara',
@@ -340,19 +1299,45 @@
         'Night View/Portrait' => 'Rit. notturno',
         'Normal' => 'Normale',
+        'Off' => 'Spento',
         'Portrait' => 'Verticale',
+        'RGB Color' => 'Colore RGB',
+        'Saturated Color' => 'Colore saturato',
+        'Sepia' => 'Seppia',
         'Sunset' => 'Tramonto',
         'Vivid' => 'Vivace',
+        'Vivid color' => 'Colore vivace',
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorMoireReduction' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
    'ColorMoireReductionMode' => {
       PrintConv => {
-        'Low' => 'Leggero',
+        'Low' => 'Basso',
+        'Off' => 'Spento',
       },
     },
    'ColorPalette' => 'Palette di Colore',
-   'ColorRepresentation' => 'Rappresentazione del Colore',
+   'ColorProfile' => {
+      PrintConv => {
+        'Not Embedded' => 'Non incorporato',
+      },
+    },
+   'ColorRepresentation' => {
+      Description => 'Rappresentazione del Colore',
+      PrintConv => {
+        'No Image, Single Frame' => 'Nessuna immagine, quadro singolo',
+      },
+    },
+   'ColorResponseUnit' => 'UnitÃ  risposta colore',
+   'ColorSequence' => 'Sequenza colori',
    'ColorSpace' => {
       Description => 'Spazio colore',
       PrintConv => {
+        'Gray-scale' => 'Scala di grigi',
+        'Grayscale' => 'Scala di grigi',
         'ICC Profile' => 'Profilo ICC',
         'Uncalibrated' => 'Non calibrato',
@@ -360,5 +1345,21 @@
     },
    'ColorSpaceData' => 'Dati Spazio Colore',
+   'ColorSpecApproximation' => {
+      PrintConv => {
+        'Not Specified' => 'Non specificato',
+      },
+    },
+   'ColorSpecMethod' => {
+      PrintConv => {
+        'Enumerated' => 'Enumerato',
+      },
+    },
+   'ColorTable' => 'Tabella colore',
    'ColorTemperature' => 'Temperatura colore',
+   'ColorTemperatureSetting' => {
+      PrintConv => {
+        'Temperature' => 'Temperatura',
+      },
+    },
    'ColorTone' => {
       PrintConv => {
@@ -366,8 +1367,74 @@
       },
     },
-   'ColorimetricReference' => 'Riferimento Colorimetrico',
+   'ColorToneFaithful' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorToneLandscape' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorToneMonochrome' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorToneNeutral' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorTonePortrait' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorToneStandard' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorToneUnknown' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorToneUserDef1' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorToneUserDef2' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorToneUserDef3' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ColorType' => {
+      PrintConv => {
+        'Grayscale' => 'Scala di grigi',
+        'RGB with Alpha' => 'RGB con trasparenza',
+      },
+    },
+   'ColorimetricReference' => 'Riferimento colorimetrico',
+   'CommandDialsChangeMainSub' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'CommandDialsMenuAndPlayback' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'CommandDialsReverseRotation' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
       },
     },
@@ -376,4 +1443,5 @@
         'Auto Aperture' => 'Diaframma automatico',
         'Manual' => 'Manuale',
+        'Off' => 'Spento',
       },
     },
@@ -382,4 +1450,5 @@
         'Auto Aperture' => 'Diaframma automatico',
         'Manual' => 'Manuale',
+        'Off' => 'Spento',
       },
     },
@@ -387,61 +1456,260 @@
       PrintConv => {
         'Manual' => 'Manuale',
+        'Off' => 'Spento',
       },
     },
    'Comment' => 'Commento',
+   'CommentTime' => 'Ora commento',
+   'Comments' => 'Commenti',
+   'CommercialURL' => 'URL pubblicitario',
+   'CompanyName' => 'Nome azienda',
    'Compilation' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'ComponentsConfiguration' => 'Significato di ogni componente',
-   'CompressedBitsPerPixel' => 'Modo compressione immagine',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'ComponentsConfiguration' => 'Configurazione componenti',
+   'Composer' => 'Compositore',
+   'ComposerSortOrder' => 'Ordinamento compositore',
+   'CompositionAdjust' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'CompositionMode' => {
+      PrintConv => {
+        'Replace' => 'Sostituisci',
+      },
+    },
+   'Compressed' => {
+      PrintConv => {
+        'False' => 'Falso',
+      },
+    },
+   'CompressedBitsPerPixel' => 'Bit per pixel compressi',
    'Compression' => {
-      Description => 'Schema compressione',
-      PrintConv => {
+      Description => 'Compressione',
+      PrintConv => {
+        'Adobe Deflate' => 'Deflate Adobe',
+        'JBIG B&W' => 'JBIG B&N',
+        'JBIG Color' => 'JBIG a colori',
         'JPEG' => 'Compressione JPEG',
         'JPEG (old-style)' => 'JPEG (vecchio stile)',
-        'Kodak DCR Compressed' => 'Kodak DCR Compresso',
-        'Kodak KDC Compressed' => 'Kodak KDC Compresso',
-        'Next' => 'Codifica NeXT 2 bits',
-        'Nikon NEF Compressed' => 'Nikon NEF Compresso',
+        'Kodak DCR Compressed' => 'Kodak DCR compresso',
+        'Kodak KDC Compressed' => 'Kodak KDC compresso',
+        'Microsoft Document Imaging (MDI) Binary Level Codec' => 'Microsoft Document Imaging (MDI) - Codec a livello binario',
+        'Microsoft Document Imaging (MDI) Progressive Transform Codec' => 'Microsoft Document Imaging (MDI) - Codec a trasformazione progressiva',
+        'Microsoft Document Imaging (MDI) Vector' => 'Microsoft Document Imaging (MDI) - Vettore',
+        'Next' => 'Codifica NeXT',
+        'Nikon NEF Compressed' => 'Nikon NEF compresso',
         'None' => 'Nessuno',
-        'Pentax PEF Compressed' => 'Pentax PEF Compresso',
-        'Sony ARW Compressed' => 'Sony ARW Compresso',
+        'Packed RAW' => 'RAW pacchettizzato',
+        'Pentax PEF Compressed' => 'Pentax PEF compresso',
+        'RLE Encoding' => 'Codifica RLE',
+        'Samsung SRW Compressed' => 'Samsung SRW compresso',
+        'Sony ARW Compressed' => 'Sony ARW compresso',
+        'T4/Group 3 Fax' => 'Fax T4/Group 3',
+        'T6/Group 4 Fax' => 'Fax T6/Group 4',
         'Uncompressed' => 'Non compresso',
       },
     },
+   'CompressionLevel' => 'Livello di compressione',
    'CompressionType' => {
-      PrintConv => {
+      Description => 'Tipo compressione',
+      PrintConv => {
+        'Little-endian, no compression' => 'Little-endian, senza compressione',
         'None' => 'Nessuno',
       },
     },
+   'CompressorName' => 'Nome compressione',
    'ConditionalFEC' => 'Compensazione Esposizione Flash',
+   'Conductor' => 'Direttore d\'orchestra',
+   'ConsecutiveBadFaxLines' => 'Linee fax non valide consecutive',
    'Contact' => 'Contatto',
+   'ContentEncodingType' => {
+      PrintConv => {
+        'Encryption' => 'Crittografia',
+      },
+    },
+   'ContentEncryptionAlgorithm' => {
+      PrintConv => {
+        'Not Encrypted' => 'Non crittografato',
+      },
+    },
    'ContentLocationCode' => 'Codice ubicazione contenuto',
    'ContentLocationName' => 'Nome Ubicazione Contenuto',
+   'ContentSignatureAlgorithm' => {
+      PrintConv => {
+        'Not Signed' => 'Senza segno',
+      },
+    },
+   'ContentSignatureHashAlgorithm' => {
+      PrintConv => {
+        'Not Signed' => 'Senza segno',
+      },
+    },
+   'ContinuousBracketing' => {
+      PrintConv => {
+        'Low' => 'Basso',
+      },
+    },
+   'ContinuousShootingSpeed' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'ContinuousShotLimit' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
    'Contrast' => {
       Description => 'Contrasto',
       PrintConv => {
-        'High' => 'Pesante',
-        'Low' => 'Leggero',
+        'High' => 'Alto',
+        'Low' => 'Basso',
         'Normal' => 'Normale',
       },
     },
-   'ContrastCurve' => 'Curva Contrasto',
+   'ContrastCurve' => 'Curva di contrasto',
+   'ContrastDetectAF' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ContrastFaithful' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastHighlightShadowAdj' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ContrastLandscape' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastMode' => {
+      PrintConv => {
+        'Elegant (My Color)' => 'Elegante (mio colore)',
+        'Expressive' => 'Espressivo',
+        'Low' => 'Basso',
+        'Normal' => 'Normale',
+        'Nostalgic (Color Film)' => 'Nostalgico (pellicola a colori)',
+        'Retro' => 'RetrÃ²',
+        'Retro (My Color)' => 'Retro (colore personalizzato)',
+      },
+    },
+   'ContrastMonochrome' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastNeutral' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastPortrait' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastStandard' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastUnknown' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastUserDef1' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastUserDef2' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ContrastUserDef3' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ControlDialSet' => {
+      PrintConv => {
+        'Shutter Speed' => 'Tempo esposizione',
+      },
+    },
+   'ControlMode' => {
+      PrintConv => {
+        'Camera Local Control' => 'Controllo locale fotocamera',
+        'n/a' => 'n/d',
+      },
+    },
+   'ConversionLens' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Converter' => 'Convertitore',
    'Copyright' => 'Titolare del copyright',
+   'CopyrightFlag' => {
+      PrintConv => {
+        'False' => 'Falso',
+      },
+    },
    'CopyrightNotice' => 'Info Copyright',
    'CopyrightStatus' => {
       PrintConv => {
-        'Unknown' => 'Sconosciuta',
-      },
-    },
+        'Not specified' => 'Non specificato',
+        'Protected' => 'Protetto',
+        'Public Domain' => 'Pubblico dominio',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'CopyrightURL' => 'URL copyright',
    'Country' => 'Paese',
    'Country-PrimaryLocationCode' => 'Codice ISO Nazione',
    'Country-PrimaryLocationName' => 'Nazione',
-   'CreateDate' => 'Data e ora di creazione dei dati digitali',
+   'CreateDate' => 'Data di creazione',
    'CreationDate' => 'Data di creazione',
+   'CreativeStyle' => {
+      PrintConv => {
+        'Autumn Leaves' => 'Foglie d\'autunno',
+        'B&W' => 'B/N',
+        'Clear' => 'Trasparente',
+        'Deep' => 'Cupa',
+        'Landscape' => 'Orizzontale',
+        'Light' => 'Chiara',
+        'Neutral' => 'Neutra',
+        'Night View/Portrait' => 'Rit. notturno',
+        'Portrait' => 'Verticale',
+        'Sepia' => 'Seppia',
+        'Sunset' => 'Tramonto',
+        'Vivid' => 'Vivace',
+      },
+    },
+   'CreativeStyleSetting' => {
+      PrintConv => {
+        'Landscape' => 'Orizzontale',
+        'Sunset' => 'Tramonto',
+        'Vivid' => 'Vivace',
+      },
+    },
    'Creator' => 'Creatore',
    'CreatorAddress' => 'Autore - Indirizzo',
+   'CreatorAppID' => {
+      PrintConv => {
+        'Unknown' => 'Sconosciuto',
+      },
+    },
    'CreatorCity' => 'Autore - CittÃ ',
    'CreatorCountry' => 'Autore - Nazione',
@@ -452,7 +1720,12 @@
    'CreatorWorkURL' => 'Autore - Sito web',
    'Credit' => 'Fornitore',
+   'CreditLineRequired' => {
+      PrintConv => {
+        'Not Required' => 'Non richiesto',
+      },
+    },
    'CropActive' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
       },
     },
@@ -467,25 +1740,72 @@
       },
     },
+   'CrossProcess' => {
+      PrintConv => {
+        'Favorite 1' => 'Preferito 1',
+        'Favorite 2' => 'Preferito 2',
+        'Favorite 3' => 'Preferito 3',
+        'Off' => 'Spento',
+        'Random' => 'Casuale',
+      },
+    },
+   'CurrentICCProfile' => 'Profilo ICC attuale',
+   'CurrentPreProfileMatrix' => 'Matrice di pre-profilo attuale',
+   'Curves' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'CustomRendered' => {
-      Description => 'Processo immagine personale',
-      PrintConv => {
-        'Custom' => 'Processo personale',
-        'Normal' => 'Processo normale',
+      Description => 'Resa personalizzata',
+      PrintConv => {
+        'Custom' => 'Personalizzata',
+        'Normal' => 'Normale',
+      },
+    },
+   'CustomWBError' => {
+      PrintConv => {
+        'Error' => 'Errore',
+      },
+    },
+   'D-LightingHQ' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
    'D-LightingHQSelected' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'DNGBackwardVersion' => 'Versione Precedente DNG',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'D-LightingHS' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'D-RangeOptimizerMode' => {
+      PrintConv => {
+        'Manual' => 'Manuale',
+        'Off' => 'Spento',
+      },
+    },
+   'DECPosition' => {
+      PrintConv => {
+        'Exposure' => 'Esposizione',
+        'Saturation' => 'Saturazione',
+      },
+    },
+   'DNGBackwardVersion' => 'Versione precedente DNG',
+   'DNGLensInfo' => 'Informazioni lenti DNG',
+   'DNGPrivateData' => 'Dati privati DNG',
    'DNGVersion' => 'Versione DNG',
    'DataImprint' => {
       PrintConv => {
         'None' => 'Nessuno',
-      },
-    },
-   'DataType' => 'Tipo Dati',
-   'DateCreated' => 'Data di Creazione',
+        'Text' => 'Testo',
+      },
+    },
+   'DataType' => 'Tipo di dati',
+   'Date' => 'Data',
+   'DateCreated' => 'Data di creazione',
    'DateDisplayFormat' => {
       Description => 'Formato Data',
@@ -496,23 +1816,55 @@
       },
     },
+   'DateImprint' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'DateSent' => 'Data d\'invio',
-   'DateTime' => 'Data e ora di modifica del file',
-   'DateTimeOriginal' => 'Data e ora di creazione dei dati originali',
+   'DateStampMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'DateTime' => 'Data/ora',
+   'DateTimeOriginal' => 'Data/ora originale di creazione',
    'DaylightSavings' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
+        'Off' => 'Spento',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'Decode' => 'Decodifica',
+   'DefaultCropOrigin' => 'Ritaglio origine predefinito',
+   'DefaultCropSize' => 'Ritaglio dimensione predefinito',
+   'DefaultImageColor' => 'Colore immagine predefinito',
    'DefaultScale' => 'Scala predefinita',
    'DeletedImageCount' => 'Conteggio Immagini Cancellate',
+   'DeltaType' => {
+      PrintConv => {
+        'Absolute' => 'Assoluto',
+      },
+    },
    'Description' => 'Descrizione',
    'Destination' => 'Destinazione',
+   'DestinationCity' => {
+      PrintConv => {
+        'Jerusalem' => 'Gerusalemme',
+        'Lisbon' => 'Lisbona',
+        'London' => 'Londra',
+        'Milan' => 'Milano',
+        'Prague' => 'Praga',
+        'Rome' => 'Roma',
+        'Stockholm' => 'Stoccolma',
+        'Tehran' => 'Teheran',
+      },
+    },
    'DestinationDST' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
       },
     },
    'DeviceAttributes' => 'Attributi Dispositivo',
-   'DeviceManufacturer' => 'Costruttore Dispositivo',
+   'DeviceManufacturer' => 'Costruttore dispositivo',
    'DeviceMfgDesc' => 'Descrizione del Costruttore Dispositivo',
    'DeviceModel' => 'Modello Dispositivo',
@@ -522,16 +1874,228 @@
       PrintConv => {
         'Normal' => 'Normale',
-      },
-    },
-   'DigitalCreationDate' => 'Data di Creazione Digitale',
+        'Reversed' => 'Invertito',
+      },
+    },
+   'DigitalCreationDate' => 'Data di creazione digitale',
    'DigitalCreationTime' => 'Ora di Creazione Digitale',
+   'DigitalFilter01' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter02' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter03' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter04' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter05' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter06' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter07' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter08' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter09' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter10' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter11' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter12' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter13' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter14' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter15' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter16' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter17' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter18' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter19' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
+   'DigitalFilter20' => {
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Retro' => 'RetrÃ²',
+        'Shading' => 'Ombreggiatura',
+        'Starburst' => 'Esplosione stellare',
+      },
+    },
    'DigitalZoom' => {
       Description => 'Zoom Digitale',
       PrintConv => {
         'None' => 'Nessuno',
+        'Off' => 'Spento',
+      },
+    },
+   'DigitalZoomOn' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
    'DigitalZoomRatio' => 'Rapporto zoom digitale',
    'Directory' => 'Posizione file',
+   'DisplayAllAFPoints' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
    'DisplaySize' => {
       PrintConv => {
@@ -554,9 +2118,68 @@
       },
     },
+   'DistortionControl' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'DistortionCorrection' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'DistortionCorrection2' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'DjVuVersion' => 'Versione DjVu',
-   'DocumentHistory' => 'Cronologia Documento',
-   'DocumentName' => 'Nome Documento',
+   'DocSecurity' => {
+      PrintConv => {
+        'None' => 'Nessuno',
+      },
+    },
+   'DocumentHistory' => 'Cronologia documento',
+   'DocumentName' => 'Nome documento',
    'DocumentNotes' => 'Note del Documento',
-   'DriveMode' => 'ModalitÃ  esecuzione',
+   'DotRange' => 'Intervallo puntuale',
+   'DriveMode' => {
+      Description => 'ModalitÃ  esecuzione',
+      PrintConv => {
+        '10 s Timer' => 'Timer 10 s',
+        'Off' => 'Spento',
+        'Self-Timer 2 sec' => 'Autoscatto 2 sec',
+        'Self-timer' => 'Autoscatto',
+        'Self-timer (12 s)' => 'Autoscatto (12 s)',
+        'Self-timer (2 s)' => 'Autoscatto (2 s)',
+        'Self-timer 10 sec' => 'Autoscatto 10 sec',
+        'Self-timer Operation' => 'Operazione autoscatto',
+        'n/a' => 'n/d',
+      },
+    },
+   'DriveMode2' => {
+      PrintConv => {
+        'Self-timer (12 s)' => 'Autoscatto (12 s)',
+        'Self-timer (2 s)' => 'Autoscatto (2 s)',
+        'Self-timer 10 sec' => 'Autoscatto 10 sec',
+        'Self-timer 2 sec' => 'Autoscatto 2 sec',
+      },
+    },
+   'DriveModeSetting' => {
+      PrintConv => {
+        'Self-timer 10 sec' => 'Autoscatto 10 sec',
+      },
+    },
+   'DriveType' => {
+      PrintConv => {
+        'Fixed Disk' => 'Disco fisso',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'DynamicRangeExpansion' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'DynamicRangeOptimizer' => {
       Description => 'Ott.gamma din.',
@@ -569,5 +2192,26 @@
         'Advanced Lv5' => 'Liv.Avanzato 5',
         'Auto' => 'Automatico',
-        'Off' => 'Disattivata',
+        'Off' => 'Spento',
+      },
+    },
+   'DynamicRangeOptimizerBracket' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+      },
+    },
+   'DynamicRangeOptimizerMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'DynamicRangeOptimizerSetting' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'DynamicRangeSetting' => {
+      PrintConv => {
+        'Manual' => 'Manuale',
       },
     },
@@ -577,10 +2221,47 @@
       },
     },
+   'EVSteps' => {
+      PrintConv => {
+        '1/2 EV Steps' => 'Step 1/2 EV',
+        '1/3 EV Steps' => 'Step 1/3 EV',
+      },
+    },
+   'EXIFVersion' => 'Versione EXIF',
+   'EXRAuto' => {
+      PrintConv => {
+        'Manual' => 'Manuale',
+      },
+    },
+   'EasyExposureComp' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'EasyExposureCompensation' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'EasyMode' => {
       PrintConv => {
+        'Fireworks' => 'Fuochi artificiali',
+        'Fisheye Effect' => 'Effetto fish-eye',
+        'Flash Off' => 'Flash spento',
+        'Kids & Pets' => 'Bambini e animali dimestici',
         'Landscape' => 'Orizzontale',
         'Manual' => 'Manuale',
         'Night' => 'Scena notturna',
+        'Nostalgic' => 'Nostalgico',
         'Portrait' => 'Verticale',
+        'Quick Shot' => 'Scatto veloce',
+        'Sepia' => 'Seppia',
+        'Sunset' => 'Tramonto',
+        'Vivid' => 'Vivace',
+        'Zoom Blur' => 'Sfocatura zoom',
+      },
+    },
+   'EdgeNoiseReduction' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
@@ -592,19 +2273,57 @@
       },
     },
-   'EffectiveMaxAperture' => 'Diaframma Massimo Effettivo',
+   'EffectiveMaxAperture' => 'Diaframma massimo effettivo',
+   'Elevation' => 'Elevazione',
    'Emphasis' => {
       PrintConv => {
         'None' => 'Nessuno',
+        'reserved' => 'riservato',
+      },
+    },
+   'EncodedBy' => 'Codificato da',
+   'EncodedPixelsDimensions' => 'Dimensioni pixel codificati',
+   'EncodedUsing' => 'Codificato usando',
+   'EncodedWith' => 'Codificato con',
+   'Encoder' => 'Codificatore',
+   'EncoderSettings' => 'Impostazioni codificatore',
+   'EncoderVersion' => 'Versione codificatore',
+   'Encoding' => {
+      Description => 'Codifica',
+      PrintConv => {
+        'QDesign Music' => 'Musica QDesign',
+        'Unknown -' => 'Sconosciuto -',
+      },
+    },
+   'EncodingProcess' => 'Processo di codifica',
+   'EncodingScheme' => 'Schema di codifica',
+   'EncodingSettings' => 'Impostazioni di codifica',
+   'EncodingTime' => 'Durata codifica',
+   'Encryption' => 'Crittografia',
+   'EndOfItems' => 'Fine elementi',
+   'EndPoints' => 'Punti finali',
+   'EndTime' => 'Ora fine',
+   'EndUser' => 'Utente finale',
+   'EndUserID' => 'ID utente finale',
+   'EndUserName' => 'Nome utente finale',
+   'EndingPage' => 'Pagina finale',
+   'EnhanceDarkTones' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
    'Enhancement' => {
+      Description => 'Miglioramento',
       PrintConv => {
         'Green' => 'Verde',
+        'Off' => 'Spento',
         'Red' => 'Rosso',
-      },
-    },
+        'Scenery' => 'Paesaggio',
+      },
+    },
+   'EnhancementOrModificationDescription' => 'Descrizione miglioramento/modifica',
+   'EntryPoint' => 'Punto d\'ingresso',
    'EnvelopePriority' => {
       PrintConv => {
-        '0 (reserved)' => '0 (riservato per usi futuri)',
+        '0 (reserved)' => '0 (riservato)',
         '1 (most urgent)' => '1 (molto urgente)',
         '5 (normal urgency)' => '5 (urgenza normale)',
@@ -613,23 +2332,63 @@
       },
     },
+   'Error' => 'Errore',
+   'ErrorCorrection' => 'Correzione errore',
+   'ErrorCorrectionType' => 'Tipo correzione errore',
+   'EthnicGroup' => 'Gruppo etnico',
+   'Event' => 'Evento',
+   'EventAbsoluteDuration' => 'Durata assoluta evento',
+   'Events' => 'Eventi',
    'ExcursionTolerance' => {
       PrintConv => {
         'Allowed' => 'Possibile',
-        'Not Allowed' => 'Non permesso (predefinito)',
-      },
-    },
-   'ExifCameraInfo' => 'Info Exif Fotocamera',
-   'ExifImageHeight' => 'Altezza immagine',
-   'ExifImageWidth' => 'Larghezza immagine',
+        'Not Allowed' => 'Non permesso',
+      },
+    },
+   'ExecutionStatus' => 'Stato esecuzione',
+   'ExecutionStatusInfo' => 'Info stato esecuzione',
+   'ExifByteOrder' => 'Ordine dei byte Exif',
+   'ExifCameraInfo' => 'Info Exif fotocamera',
+   'ExifImageHeight' => 'Altezza immagine Exif',
+   'ExifImageWidth' => 'Larghezza immagine Exif',
+   'ExifInfo2' => 'Info 2 Exif',
    'ExifOffset' => 'Puntatore Exif IFD',
-   'ExifToolVersion' => 'Versione ExifTool',
+   'ExifToolVersion' => 'Numero versione ExifTool',
+   'ExifUnicodeByteOrder' => 'Ordine unicode dei byte Exif',
    'ExifVersion' => 'Versione Exif',
    'ExitPupilPosition' => 'Posizione pupilla d\'uscita',
-   'ExpirationDate' => 'Data Scadenza',
-   'ExpirationTime' => 'Ora Scadenza',
+   'ExpirationDate' => 'Data scadenza',
+   'ExpirationTime' => 'Ora scadenza',
+   'Expires' => 'Scade',
+   'ExposedArea' => 'Area esposta',
+   'Exposure' => 'Esposizione',
+   'Exposure2012' => 'Esposizione 2012',
    'ExposureBracketValue' => 'Valore Esposizione a Forcella',
-   'ExposureCompensation' => 'Bias esposizione',
-   'ExposureDifference' => 'Differenza Esposizione',
+   'ExposureBracketingIndicatorLast' => {
+      PrintConv => {
+        'Not Indicated' => 'Non indicato',
+      },
+    },
+   'ExposureCompensation' => 'Compensazione esposizione',
+   'ExposureCompensationMode' => 'Modo compensazione esposizione',
+   'ExposureControlMode' => 'Modo controllo esposizione',
+   'ExposureControlModeDescription' => 'Descrizione modo controllo esposizione',
+   'ExposureDelayMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ExposureDifference' => 'Differenza esposizione',
    'ExposureIndex' => 'Indice di esposizione',
+   'ExposureIndicator' => {
+      PrintConv => {
+        'Not Indicated' => 'Non indicato',
+      },
+    },
+   'ExposureLevelIncrements' => {
+      PrintConv => {
+        '1/2 Stop' => '1/2 stop',
+        '1/3 Stop' => '1/3 stop',
+      },
+    },
    'ExposureMode' => {
       Description => 'Modo esposizione',
@@ -638,13 +2397,19 @@
         'Aperture-priority AE' => 'PrioritÃ  diaframma',
         'Auto' => 'Esposizione automatica',
-        'Auto bracket' => 'Esposizione a forcella automatica',
+        'Auto bracket' => 'A forcella automatica',
+        'Fireworks' => 'Fuochi artificiali',
         'Landscape' => 'Orizzontale',
-        'Manual' => 'Esposizione manuale',
+        'Manual' => 'Manuale',
         'Portrait' => 'Verticale',
+        'Program' => 'Programma',
+        'Program AE' => 'Programma AE',
         'Shutter Priority' => 'PrioritÃ  otturatore',
-        'Shutter speed priority AE' => 'PrioritÃ  otturatore',
+        'Shutter speed priority AE' => 'PrioritÃ  otturatore AE',
+        'Sunset' => 'Tramonto',
+        'n/a' => 'n/d',
       },
     },
    'ExposureModeInManual' => {
+      Description => 'Modo esposizione in manuale',
       PrintConv => {
         'Center-weighted average' => 'Media centrale ponderata',
@@ -652,61 +2417,314 @@
       },
     },
+   'ExposureModulationType' => 'Tipo modulazione esposizione',
    'ExposureProgram' => {
       Description => 'Programma esposizione',
       PrintConv => {
-        'Action (High speed)' => 'Programma di azione',
+        'Action (High speed)' => 'Azione (alta velocitÃ )',
         'Aperture Priority' => 'PrioritÃ  diaframma',
         'Aperture-priority AE' => 'PrioritÃ  diaframma',
-        'Creative (Slow speed)' => 'Programma Creativo (basato sulla profonditÃ  di campo)',
+        'Bulb' => 'Bulbo',
+        'Creative (Slow speed)' => 'Creativo (bassa velocitÃ )',
         'Landscape' => 'Orizzontale',
         'Manual' => 'Manuale',
         'Not Defined' => 'Non definito',
         'Portrait' => 'Verticale',
-        'Program AE' => 'Programma normale',
+        'Posterization' => 'Posterizzazione',
+        'Posterization B/W' => 'Posterizzazione B&N',
+        'Program' => 'Programma',
+        'Program AE' => 'Programma AE',
+        'Retro Photo' => 'Foto retrÃ²',
         'Shutter Priority' => 'PrioritÃ  otturatore',
-        'Shutter speed priority AE' => 'PrioritÃ  otturatore',
-      },
-    },
-   'ExposureTime' => 'Tempo di esposizione',
-   'ExposureTime2' => 'Tempo di esposizione 2',
+        'Shutter speed priority AE' => 'PrioritÃ  otturatore AE',
+        'Sunset' => 'Tramonto',
+        'Sweep Panorama' => 'Panoramica ad arco',
+      },
+    },
+   'ExposureSequence' => 'Sequenza esposizione',
+   'ExposureStatus' => 'Stato esposizione',
+   'ExposureTime' => 'Tempo esposizione',
+   'ExposureTime2' => 'Tempo esposizione 2',
+   'ExposureTimeInMicroSec' => 'Tempo esposizione in microsecondi',
+   'ExposureTimeInMilliSec' => 'Tempo esposizione in millisecondi',
+   'ExposureTuning' => 'Sintonizzazione esposizione',
+   'ExposureUnknown' => 'Esposizione sconosciuta',
+   'ExposureValue' => 'Valore esposizione',
+   'ExtendedWBDetect' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Extender' => {
+      PrintConv => {
+        'None' => 'Nessuno',
+      },
+    },
+   'ExtenderStatus' => {
+      PrintConv => {
+        'Not attached' => 'Non applicabile',
+        'Removed' => 'Rimosso',
+      },
+    },
+   'ExtensionPersistence' => {
+      PrintConv => {
+        'Potentially Invalidated By Modification' => 'Potenzialmente invalidato per modifica',
+      },
+    },
+   'ExternalFlash' => {
+      Description => 'Flash esterno',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'ExternalFlashBounce' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
+        'n/a' => 'n/d',
+      },
+    },
+   'ExternalFlashExposureComp' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ExternalFlashFirmware' => {
+      PrintConv => {
+        '1.01 (SB-800 or Metz 58 AF-1)' => '1.01 (SB-800 o Metz 58 AF-1)',
+        'n/a' => 'n/d',
       },
     },
    'ExternalFlashFlags' => 'Flags Flash Esterno',
-   'ExtraSamples' => 'Campioni Extra',
+   'ExternalFlashMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ExtraFlags' => {
+      PrintConv => {
+        '(none)' => '(nessuno)',
+        'Fastest Algorithm' => 'Algoritmo piÃ¹ veloce',
+      },
+    },
+   'ExtraSamples' => {
+      Description => 'Campioni extra',
+      PrintConv => {
+        'Associated Alpha' => 'Associati alla trasparenza',
+        'Unassociated Alpha' => 'Non associati alla trasparenza',
+        'Unspecified' => 'Non specificati',
+      },
+    },
+   'EyeStartAF' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'FEMicroadjustment' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
    'FNumber' => 'Numero F',
+   'Face1Category' => {
+      PrintConv => {
+        'Family' => 'Famiglia',
+      },
+    },
+   'Face2Category' => {
+      PrintConv => {
+        'Family' => 'Famiglia',
+      },
+    },
+   'Face3Category' => {
+      PrintConv => {
+        'Family' => 'Famiglia',
+      },
+    },
+   'Face4Category' => {
+      PrintConv => {
+        'Family' => 'Famiglia',
+      },
+    },
+   'Face5Category' => {
+      PrintConv => {
+        'Family' => 'Famiglia',
+      },
+    },
+   'Face6Category' => {
+      PrintConv => {
+        'Family' => 'Famiglia',
+      },
+    },
+   'Face7Category' => {
+      PrintConv => {
+        'Family' => 'Famiglia',
+      },
+    },
+   'Face8Category' => {
+      PrintConv => {
+        'Family' => 'Famiglia',
+      },
+    },
+   'FaceDetection' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => 'Orizzontale (normale)',
+        'Rotate 180' => 'Ruota di 180Â°',
+        'Rotate 270 CW' => 'Ruota di 270Â° in senso orario',
+        'Rotate 90 CW' => 'Ruota di 90Â° senso orario',
+      },
+    },
+   'FacesDetected' => {
+      Description => 'Facce rimosse',
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'FacesRecognized' => 'Facce riconosciute',
+   'FamilyName' => 'Nome famiglia',
    'FastSeek' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'FaxNumber' => 'Numero di fax',
    'FaxProfile' => {
-      PrintConv => {
-        'Unknown' => 'Sconosciuta',
-      },
-    },
-   'FileFormat' => 'Formato File',
+      Description => 'Profilo fax',
+      PrintConv => {
+        'Extended B&W lossless, F' => 'Bianco e nero esteso senza perdita, F',
+        'Lossless JBIG B&W, J' => 'Senza perdita JBIG bianco e nero, J',
+        'Lossless color and grayscale, L' => 'Senza perdita a colori e scala di grigi, L',
+        'Lossy color and grayscale, C' => 'Con perdita a colori e scala di grigi, C',
+        'Minimal B&W lossless, S' => 'Bianco e nero minimale con perdita, S',
+        'Mixed raster content, M' => 'Contenuto raster misto, M',
+        'Multi Profiles' => 'Profili multipli',
+        'Profile T' => 'Profilo T',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'FaxRecvParams' => 'Parametri ricezione fax',
+   'FaxRecvTime' => 'Ora ricezione fax',
+   'FaxSubAddress' => 'Sotto-indirizzo fax',
+   'FileAttributes' => {
+      PrintConv => {
+        'Encrypted' => 'Crittografato',
+        'Encrypted?' => 'Crittografato?',
+        'Normal' => 'Normale',
+        'Not indexed' => 'Non indicizzato',
+        'Read-only' => 'Sola lettura',
+        'System' => 'Sistema',
+      },
+    },
+   'FileDescription' => 'Descrizione file',
+   'FileDescriptors' => 'Descrittori file',
+   'FileFlags' => {
+      Description => 'Attributi file',
+      PrintConv => {
+        'Info inferred' => 'Info desunte',
+        'Private build' => 'Compilazione privata',
+        'Special build' => 'Compilazione speciale',
+      },
+    },
+   'FileFlagsMask' => 'Maschera attributi file',
+   'FileFormat' => {
+      Description => 'Formato file',
+      PrintConv => {
+        'Ritzaus Bureau NITF version (RBNITF DTD)' => 'Versione Ritzaus Bureau NITF (RBNITF DTD)',
+      },
+    },
+   'FileFunctionFlags' => {
+      PrintConv => {
+        'Fragmented' => 'Frammentato',
+      },
+    },
+   'FileID' => 'ID file',
+   'FileIndex' => 'Indice file',
+   'FileIndex2' => 'Indice file 2',
+   'FileLength' => 'Dimensioni file',
    'FileModifyDate' => 'Data aggiornamento',
-   'FileName' => 'Nome File',
-   'FileSize' => 'Dimensione File',
+   'FileName' => 'Nome file',
+   'FileNameLength' => 'Lunghezza nome file',
+   'FileNumber' => 'Numero file',
+   'FileNumberMemory' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'FileNumberSequence' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'FileOS' => 'OS del file',
+   'FileOwner' => 'Proprietario del file',
+   'FilePermissions' => 'Permessi file',
+   'FileProfileVersion' => 'Versione profilo file',
+   'FileSecurityReport' => 'Rapporto sicurezza file',
+   'FileSequence' => 'Sequenza file',
+   'FileSetID' => 'ID gruppo file',
+   'FileSize' => 'Dimensione file',
+   'FileSizeBytes' => 'Dimensione file in byte',
    'FileSource' => {
       Description => 'Origine file',
       PrintConv => {
-        'Digital Camera' => 'Fotocamera Digitale',
-        'Film Scanner' => 'Scanner per Pellicola',
+        'Digital Camera' => 'Fotocamera digitale',
+        'Film Scanner' => 'Scanner per pellicola',
         'Reflection Print Scanner' => 'Scanner a riflessione',
-      },
-    },
-   'FileType' => 'Tipo File',
-   'FileVersion' => 'Versione Formato File',
+        'Sigma Digital Camera' => 'Fotocamera digitale Sigma',
+      },
+    },
+   'FileSubtype' => 'Sottotipo file',
+   'FileType' => 'Tipo di file',
+   'FileURL' => 'URL file',
+   'FileVersion' => 'Versione file',
+   'FileVersionNumber' => 'Numero versione file',
+   'Filename' => 'Nome file',
+   'Files' => 'File',
+   'FillFlashAutoReduction' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
    'FillOrder' => {
+      Description => 'Ordine riempimento',
       PrintConv => {
         'Normal' => 'Normale',
+        'Reversed' => 'Invertito',
+      },
+    },
+   'FilmMode' => {
+      PrintConv => {
+        'Nostalgic' => 'Nostalgico',
+        'Standard (B&W)' => 'Standard (B&N)',
+        'Standard (color)' => 'Standard (colori)',
+        'n/a' => 'n/d',
       },
     },
    'FilterEffect' => {
       Description => 'Effetto Filtro',
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Nessuno',
+        'Off' => 'Spento',
+        'Orange' => 'Arancio',
+        'Red' => 'Rosso',
+        'Yellow' => 'Giallo',
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectFaithful' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectLandscape' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectMonochrome' => {
       PrintConv => {
         'Green' => 'Verde',
@@ -715,32 +2733,100 @@
         'Red' => 'Rosso',
         'Yellow' => 'Giallo',
-        'n/a' => 'Non impostato',
-      },
-    },
-   'FilterEffectMonochrome' => {
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectNeutral' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectPortrait' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectStandard' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectUnknown' => {
       PrintConv => {
         'Green' => 'Verde',
         'None' => 'Nessuno',
-        'Orange' => 'Arancio',
         'Red' => 'Rosso',
-        'Yellow' => 'Giallo',
-      },
-    },
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectUserDef1' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Nessuno',
+        'Red' => 'Rosso',
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectUserDef2' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Nessuno',
+        'Red' => 'Rosso',
+        'n/a' => 'n/d',
+      },
+    },
+   'FilterEffectUserDef3' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Nessuno',
+        'Red' => 'Rosso',
+        'n/a' => 'n/d',
+      },
+    },
+   'FinalFrameBlocks' => 'Blocchi frame finali',
+   'FinderDisplayDuringExposure' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'FineSharpness' => {
+      PrintConv => {
+        'Normal' => 'Normale',
+        'Off' => 'Spento',
+      },
+    },
+   'FirmwareDate' => 'Data firmware',
+   'FirmwareID' => 'ID firmware',
+   'FirmwareName' => 'Nome firmware',
+   'FirmwareRevision' => 'Revisione firmware',
+   'FirmwareRevision2' => 'Revisione 2 firmware',
+   'FirmwareVersion' => 'Versione firmware',
+   'FirstChar' => 'Primo carattere',
+   'FirstObject' => 'Primo oggetto',
+   'FirstObjectID' => 'ID primo oggetto',
    'FixtureIdentifier' => 'Identificatore d\'installazione',
+   'Flags' => {
+      PrintConv => {
+        'FileName' => 'Nome file',
+        'Text' => 'Testo',
+      },
+    },
    'Flash' => {
       PrintConv => {
-        'Auto, Did not fire' => 'Flash non emesso, modo auto',
-        'Auto, Fired' => 'Flash emesso, modo auto',
-        'Auto, Fired, Red-eye reduction' => '"Attivato (flash automatico, riduzione occhi rossi)"',
-        'Auto, Fired, Red-eye reduction, Return detected' => '"Attivato (flash automatico, riduzione occhi rossi, rilevato riflesso)"',
-        'Auto, Fired, Return detected' => 'Flash emesso, modo auto, luce di ritorno rilevata',
-        'Auto, Fired, Return not detected' => 'Flash emesso, modo auto, luce di ritorno non rilevata',
+        'Auto, Did not fire' => 'Auto, flash non emesso',
+        'Auto, Did not fire, Red-eye reduction' => 'Auto, flash non emesso, riduzione occhi rossi',
+        'Auto, Fired' => 'Auto, flash emesso',
+        'Auto, Fired, Red-eye reduction' => 'Auto, flash emesso, riduzione occhi rossi',
+        'Auto, Fired, Red-eye reduction, Return detected' => 'Auto, flash emesso, riduzione occhi rossi, luce di ritorno rilevata',
+        'Auto, Fired, Red-eye reduction, Return not detected' => 'Auto, flash emesso, riduzione occhi rossi, luce di ritorno non rilevata',
+        'Auto, Fired, Return detected' => 'Auto, flash emesso, luce di ritorno rilevata',
+        'Auto, Fired, Return not detected' => 'Auto, flash emesso, luce di ritorno non rilevata',
         'Did not fire' => 'Flash non emesso',
-        'Fired' => 'Flash emesso',
-        'Fired, Red-eye reduction' => 'Flash emesso, modo riduzione occhi rossi',
-        'Fired, Red-eye reduction, Return detected' => 'Flash emesso, modo riduzione occhi rossi, luce di ritorno rilevata',
-        'Fired, Red-eye reduction, Return not detected' => 'Flash emesso, modo riduzione occhi rossi, luce di ritorno non rilevata',
-        'Fired, Return detected' => 'Luce di ritorno rilevata',
-        'Fired, Return not detected' => 'Luce di ritorno non rilevata',
+        'Fired' => 'Emesso',
+        'Fired, Red-eye reduction' => 'Emesso, riduzione occhi rossi',
+        'Fired, Red-eye reduction, Return detected' => 'Emesso, riduzione occhi rossi, ritorno rilevato',
+        'Fired, Red-eye reduction, Return not detected' => 'Emesso, riduzione occhi rossi, ritorno non rilevato',
+        'Fired, Return detected' => 'Emesso, ritorno rilevato',
+        'Fired, Return not detected' => 'Emesso, ritorno non rilevato',
+        'Flash Fired' => 'Flash emesso',
         'No Flash' => 'Flash non emesso',
         'No flash function' => 'Nessuna funzione flash',
@@ -749,15 +2835,46 @@
         'Off, Did not fire, Return not detected' => 'Off, Non emesso. Luce di ritorno non rilevata',
         'Off, No flash function' => 'Off, Nessuna funzione flash',
+        'Off, Red-eye reduction' => 'Disattivato, riduzione occhi rossi',
         'On' => 'Flash emesso, modalitÃ  flash forzata',
-        'On, Did not fire' => 'On, flash non emesso',
-        'On, Fired' => 'Flash emesso, modalitÃ  flash forzata',
-        'On, Red-eye reduction' => 'Flash emesso, modalitÃ  forzata, modo riduzione occhi rossi',
-        'On, Red-eye reduction, Return detected' => '"Attivato (flash schiarimento, riduzione occhi rossi, rilevato riflesso)"',
-        'On, Return detected' => 'Flash emesso, modalitÃ  flash forzata, luce di ritorno rilevata',
-        'On, Return not detected' => 'Flash emesso, modalitÃ  flash forzata, luce di ritorno non rilevata',
-      },
-    },
-   'FlashCommanderMode' => 'Modo Commander',
-   'FlashCompensation' => 'Compensazionee Flash',
+        'On, Did not fire' => 'Attivato, non emesso',
+        'On, Fired' => 'Attivato, emesso',
+        'On, Red-eye reduction' => 'Attivato, riiduzione occhi rossi',
+        'On, Red-eye reduction, Return detected' => 'Attivato, riiduzione occhi rossi, ritorno rilevato',
+        'On, Red-eye reduction, Return not detected' => 'Attivato, riiduzione occhi rossi, ritorno non rilevato',
+        'On, Return detected' => 'Attivato, ritorno rilevato',
+        'On, Return not detected' => 'Attivato, ritorno non rilevato',
+      },
+    },
+   'FlashBits' => {
+      PrintConv => {
+        'External' => 'Esterno',
+        'Manual' => 'Manuale',
+      },
+    },
+   'FlashButtonFunction' => {
+      PrintConv => {
+        'ISO speed' => 'VelocitÃ  ISO',
+      },
+    },
+   'FlashColorFilter' => {
+      PrintConv => {
+        'None' => 'Nessuno',
+        'Red' => 'Rosso',
+      },
+    },
+   'FlashCommanderMode' => {
+      Description => 'Modo Commander',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'FlashCompensation' => 'Compensazione flash',
+   'FlashControl' => 'Controllo flash',
+   'FlashControlBuilt-in' => {
+      PrintConv => {
+        'Manual' => 'Manuale',
+        'Repeating Flash' => 'Ripetizione flash',
+      },
+    },
    'FlashControlMode' => {
       Description => 'Modo Controllo Flash',
@@ -765,9 +2882,11 @@
         'Auto Aperture' => 'Diaframma automatico',
         'Manual' => 'Manuale',
-        'Repeating Flash' => 'Ripetizione Flash',
+        'Off' => 'Spento',
+        'Repeating Flash' => 'Ripetizione flash',
       },
     },
    'FlashDevice' => {
       PrintConv => {
+        'External' => 'Esterno',
         'None' => 'Nessuno',
       },
@@ -776,10 +2895,45 @@
    'FlashExposureBracketValue' => 'Valore Esposizione a Forcella Flash',
    'FlashExposureComp' => 'Compensazione Esposizione Flash',
+   'FlashExposureIndicator' => {
+      PrintConv => {
+        'Not Indicated' => 'Non indicato',
+      },
+    },
+   'FlashExposureIndicatorLast' => {
+      PrintConv => {
+        'Not Indicated' => 'Non indicato',
+      },
+    },
+   'FlashExposureIndicatorNext' => {
+      PrintConv => {
+        'Not Indicated' => 'Non indicato',
+      },
+    },
+   'FlashExposureLock' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'FlashFired' => {
-      PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'FlashFocalLength' => 'Lunghezza Focale Flash',
+      Description => 'Flash emesso',
+      PrintConv => {
+        'External' => 'Esterno',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'FlashFiring' => 'Emissione flash',
+   'FlashFirmwareVersion' => 'Versione firmware flash',
+   'FlashFocalLength' => 'Lunghezza focale flash',
+   'FlashFunction' => {
+      Description => 'Funzione flash',
+      PrintConv => {
+        'Manual' => 'Manuale',
+      },
+    },
+   'FlashGNDistance' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
    'FlashGroupAControlMode' => {
       Description => 'Gruppo A Modo Controllo Flash',
@@ -787,5 +2941,6 @@
         'Auto Aperture' => 'Diaframma automatico',
         'Manual' => 'Manuale',
-        'Repeating Flash' => 'Ripetizione Flash',
+        'Off' => 'Spento',
+        'Repeating Flash' => 'Ripetizione flash',
       },
     },
@@ -795,5 +2950,6 @@
         'Auto Aperture' => 'Diaframma automatico',
         'Manual' => 'Manuale',
-        'Repeating Flash' => 'Ripetizione Flash',
+        'Off' => 'Spento',
+        'Repeating Flash' => 'Ripetizione flash',
       },
     },
@@ -802,5 +2958,6 @@
       PrintConv => {
         'Manual' => 'Manuale',
-        'Repeating Flash' => 'Ripetizione Flash',
+        'Off' => 'Spento',
+        'Repeating Flash' => 'Ripetizione flash',
       },
     },
@@ -808,21 +2965,46 @@
    'FlashIntensity' => {
       PrintConv => {
+        'Low' => 'Basso',
         'Normal' => 'Normale',
+        'Strong' => 'Forte',
+      },
+    },
+   'FlashLevel' => {
+      Description => 'Livello flash',
+      PrintConv => {
+        'Low' => 'Basso',
+        'Normal' => 'Normale',
+      },
+    },
+   'FlashMeteringMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
    'FlashMode' => {
-      Description => 'Modo Flash',
-      PrintConv => {
-        'Did Not Fire' => 'Non Emesso',
+      Description => 'Modo flash',
+      PrintConv => {
+        'Did Not Fire' => 'Non emesso',
         'Fired, Commander Mode' => 'Emesso, ModalitÃ  Commander',
         'Fired, External' => 'Emesso Esterno',
         'Fired, Manual' => 'Emesso, Manuale',
         'Fired, TTL Mode' => 'Emesso, ModalitÃ  TTL',
+        'Flash Off' => 'Flash spento',
         'Normal' => 'Normale',
+        'Not Ready' => 'Non pronto',
+        'Off' => 'Spento',
+        'Off, Did not fire' => 'Spendo, non emesso',
+        'Off?' => 'Spento?',
+        'Red eye' => 'Occhi rossi',
+        'Red-Eye' => 'Occhi rossi',
+        'Red-Eye?' => 'Occhi rossi?',
+        'Red-eye' => 'Occhi rossi',
+        'Red-eye Reduction' => 'Riduzione occhi rossi',
+        'Red-eye reduction' => 'Riduzione occhi rossi',
         'Unknown' => 'Sconosciuta',
       },
     },
    'FlashModel' => {
-      Description => 'Modello Flash',
+      Description => 'Modello flash',
       PrintConv => {
         'None' => 'Nessuno',
@@ -830,38 +3012,104 @@
     },
    'FlashOptions' => {
+      Description => 'Opzioni flash',
       PrintConv => {
         'Normal' => 'Normale',
+        'Red-eye reduction' => 'Riduzione occhi rossi',
       },
     },
    'FlashOptions2' => {
+      Description => 'Opzioni 2 flash',
       PrintConv => {
         'Normal' => 'Normale',
-      },
-    },
-   'FlashSetting' => 'Impostazione Flash',
+        'Red-eye reduction' => 'Riduzione occhi rossi',
+      },
+    },
+   'FlashRemoteControl' => {
+      Description => 'Telecomando flash',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'FlashReturn' => 'Ritorno flash',
+   'FlashSerialNumber' => 'Numero di serie del flash',
+   'FlashSetting' => 'Impostazione flash',
+   'FlashSource' => {
+      Description => 'Fonte flash',
+      PrintConv => {
+        'External' => 'Esterno',
+        'None' => 'Nessuno',
+      },
+    },
+   'FlashStatus' => {
+      Description => 'Stato flash',
+      PrintConv => {
+        'Off' => 'Spento',
+        'Off (1)' => 'Spento (1)',
+      },
+    },
+   'FlashSyncSpeed' => {
+      PrintConv => {
+        '1/250 s (auto FP)' => '1/250 s (piano focale auto)',
+        '1/320 s (auto FP)' => '1/320 s (piano focale auto)',
+      },
+    },
+   'FlashSyncSpeedAv' => {
+      PrintConv => {
+        '1/200 Fixed' => '1/200 fisso',
+        '1/200-1/60 Auto' => '1/200-1/60 auto',
+        '1/250 Fixed' => '1/250 fisso',
+        '1/250-1/60 Auto' => '1/250-1/60 auto',
+        '1/300 Fixed' => '1/300 fisso',
+        '1/300-1/60 Auto' => '1/300-1/60 auto',
+      },
+    },
    'FlashType' => {
-      Description => 'Tipo Flash',
-      PrintConv => {
+      Description => 'Tipo di flash',
+      PrintConv => {
+        'External' => 'Esterno',
         'None' => 'Nessuno',
-      },
-    },
-   'FlashpixVersion' => 'Versione Flashpix supportata',
+        'Off' => 'Spento',
+      },
+    },
+   'FlashVersion' => 'Versione del flash',
+   'FlashWarning' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'FlashpixVersion' => 'Versione Flashpix',
+   'FlickerReduce' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'FlipHorizontal' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'FocalLength' => 'Lunghezza focale obiettivo',
-   'FocalLength35efl' => 'Lunghezza focale obiettivo',
-   'FocalLengthIn35mmFormat' => 'Lunghezza focale in 35 mm',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'FocalLength' => 'Lunghezza focale',
+   'FocalLength35efl' => 'Lunghezza focale',
+   'FocalLength35mm' => 'Lunghezza focale 35mm',
+   'FocalLengthIn35mmFormat' => 'Lunghezza focale in formato 35mm',
+   'FocalPlaneDiagonal' => 'Diagonale piano focale',
    'FocalPlaneResolutionUnit' => {
       Description => 'UnitÃ  risoluzione piano focale',
       PrintConv => {
         'None' => 'Nessuno',
-        'inches' => 'Pollici',
+        'inches' => 'pollici',
       },
     },
    'FocalPlaneXResolution' => 'Risoluzione X del piano focale',
+   'FocalPlaneXSize' => 'Dimensione X del piano focale',
+   'FocalPlaneXUnknown' => 'X del piano focale sconisciuta',
    'FocalPlaneYResolution' => 'Risoluzione Y del piano focale',
+   'FocalPlaneYSize' => 'Dimensione Y del piano focale',
+   'FocalPlaneYUnknown' => 'Y del piano focale sconisciuta',
+   'FocalType' => {
+      PrintConv => {
+        'Fixed' => 'Fisso',
+      },
+    },
    'Focus' => {
       PrintConv => {
@@ -874,14 +3122,20 @@
       },
     },
-   'FocusDistance' => 'Distanza Fuoco',
+   'FocusDisplayAIServoAndMF' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'FocusDistance' => 'Distanza fuoco',
    'FocusMode' => {
-      Description => 'ModalitÃ  Messa a Fuoco',
+      Description => 'ModalitÃ  messa a fuoco',
       PrintConv => {
         'Manual' => 'Manuale',
         'Normal' => 'Normale',
+        'n/a' => 'n/d',
       },
     },
    'FocusMode2' => {
-      Description => 'ModalitÃ  Messa a Fuoco 2',
+      Description => 'ModalitÃ  messa a fuoco 2',
       PrintConv => {
         'Manual' => 'Manuale',
@@ -893,46 +3147,131 @@
       },
     },
-   'FocusPosition' => 'Posizione Fuoco',
+   'FocusModeSwitch' => {
+      PrintConv => {
+        'Manual' => 'Manuale',
+      },
+    },
+   'FocusPos' => 'Posizione fuoco',
+   'FocusPosition' => 'Posizione fuoco',
    'FocusRange' => {
       PrintConv => {
         'Manual' => 'Manuale',
         'Normal' => 'Normale',
+        'Not Known' => 'Sconosciuto',
+        'Very Close' => 'Molto vicino',
+      },
+    },
+   'FocusStatus' => {
+      PrintConv => {
+        'Failed' => 'Fallito',
+        'Not confirmed' => 'Non confermato',
       },
     },
    'FocusTrackingLockOn' => {
       PrintConv => {
+        '1 (Short)' => '1 (Breve)',
+        '1 Short' => '1 breve',
         'Normal' => 'Normale',
-      },
-    },
+        'Off' => 'Spento',
+        'Short' => 'Breve',
+      },
+    },
+   'FontFamily' => {
+      Description => 'Tipo di carattere',
+      PrintConv => {
+        'Swiss' => 'Svizzera',
+      },
+    },
+   'FontFileName' => 'Nome file carattere',
+   'FontName' => 'Nome carattere',
+   'FontSize' => 'Dimensioni carattere',
+   'FontSubfamily' => 'Sottotipo di carattere',
+   'FontSubfamilyID' => 'ID sottotipo di carattere',
+   'FontType' => 'Tipo di carattere',
+   'FontVersion' => 'Versione carattere',
+   'FontWeight' => 'Peso carattere',
+   'Fonts' => 'Caratteri',
+   'For' => 'Per',
+   'Format' => 'Formato',
+   'ForwardMatrix1' => 'Matrice predittiva 1',
+   'ForwardMatrix2' => 'Matrice predittiva 2',
    'FrameRate' => 'Frequenza fotogramma',
    'FrameSize' => 'Dimensioni fotogrammi',
+   'FreeByteCounts' => 'Byte disponibili',
+   'FreeOffsets' => 'Offset disponibili',
+   'FujiFlashMode' => {
+      PrintConv => {
+        'External' => 'Esterno',
+        'Off' => 'Spento',
+        'Red-eye reduction' => 'Riduzione occhi rossi',
+      },
+    },
+   'FuncButton' => {
+      PrintConv => {
+        'Flash Off' => 'Flash spento',
+        'None' => 'Nessuno',
+        'Preview' => 'Anteprima',
+        'Virtual Horizon' => 'Orizzonte virtuale',
+      },
+    },
+   'FuncButtonPlusDials' => {
+      PrintConv => {
+        'Choose Image Area' => 'Seleziona area immagine',
+        'None' => 'Nessuno',
+      },
+    },
+   'FunctionButton' => {
+      PrintConv => {
+        'Flash Off' => 'Flash spento',
+      },
+    },
+   'GDALMetadata' => 'Metadati GDAL',
+   'GDALNoData' => 'Nessun dato GDAL',
    'GIFVersion' => 'Versione GIF',
-   'GPSAltitude' => 'Altitudine',
+   'GPSAltitude' => 'Altitudine GPS',
    'GPSAltitudeRef' => {
-      Description => 'Riferimento Altitudine',
-      PrintConv => {
-        'Above Sea Level' => 'Livello del mare',
-        'Below Sea Level' => 'Riferimento livello del mare (valore negativo)',
-      },
-    },
-   'GPSAreaInformation' => 'Nome dell\'area GPS',
-   'GPSDOP' => 'Precisione di misurazione',
+      Description => 'Riferimento altitudine GPS',
+      PrintConv => {
+        'Above Sea Level' => 'Sul livello del mare',
+        'Below Sea Level' => 'Sotto il livello del mare',
+      },
+    },
+   'GPSAreaInformation' => 'Informazioni area GPS',
+   'GPSDOP' => 'Precisione misurazione GPS',
    'GPSDateStamp' => 'Data GPS',
    'GPSDateTime' => 'Ora GPS (orologio atomico)',
-   'GPSDestBearing' => 'Direzione di destinazione',
-   'GPSDestBearingRef' => 'Riferimento per direzione di destinazione',
-   'GPSDestDistance' => 'Distanza di destinazione',
+   'GPSDestBearing' => 'Direzione destinazione GPS',
+   'GPSDestBearingRef' => {
+      Description => 'Riferimento direzione destinazione GPS',
+      PrintConv => {
+        'Magnetic North' => 'Nord magnetico',
+        'True North' => 'Nord geografico',
+      },
+    },
+   'GPSDestDistance' => 'Distanza destinazione GPS',
    'GPSDestDistanceRef' => {
-      Description => 'Riferimento per distanza di destinazione',
+      Description => 'Riferimento distanza destinazione GPS',
       PrintConv => {
         'Kilometers' => 'Chilometri',
         'Miles' => 'Miglia',
-        'Nautical Miles' => 'Nodi',
-      },
-    },
-   'GPSDestLatitude' => 'Latitudine di destinazione',
-   'GPSDestLatitudeRef' => 'Riferimento per latitudine di destinazione',
-   'GPSDestLongitude' => 'Longitudine di destinazione',
-   'GPSDestLongitudeRef' => 'Riferimento per longitudine di destinazione',
+        'Nautical Miles' => 'Miglia nautiche',
+      },
+    },
+   'GPSDestLatitude' => 'Latitudine destinazione GPS',
+   'GPSDestLatitudeRef' => {
+      Description => 'Riferimento latitudine destinazione GPS',
+      PrintConv => {
+        'North' => 'Nord',
+        'South' => 'Sud',
+      },
+    },
+   'GPSDestLongitude' => 'Longitudine destinazione GPS',
+   'GPSDestLongitudeRef' => {
+      Description => 'Riferimento per longitudine di destinazione',
+      PrintConv => {
+        'East' => 'Est',
+        'West' => 'Ovest',
+      },
+    },
    'GPSDifferential' => {
       Description => 'Correzione differenziale GPS',
@@ -942,6 +3281,13 @@
       },
     },
+   'GPSHPositioningError' => 'Errore posizionamento orizzontale GPS',
    'GPSImgDirection' => 'Direzione di immagine',
-   'GPSImgDirectionRef' => 'Riferimento per direzione di immagine',
+   'GPSImgDirectionRef' => {
+      Description => 'Riferimento per direzione di immagine',
+      PrintConv => {
+        'Magnetic North' => 'Nord magnetico',
+        'True North' => 'Nord geografico',
+      },
+    },
    'GPSInfo' => 'Puntatore GPS Info IFD',
    'GPSLatitude' => 'Latitudine',
@@ -965,4 +3311,5 @@
       Description => 'ModalitÃ  misurazione GPS',
       PrintConv => {
+        '2-Dimensional Measurement' => 'Misurazione 2D',
         '3-Dimensional Measurement' => 'Misurazione tridimensionale',
       },
@@ -996,4 +3343,9 @@
     },
    'GPSVersionID' => 'Versione tag GPS',
+   'GTModelType' => {
+      PrintConv => {
+        'Projected' => 'Proiettato',
+      },
+    },
    'GainControl' => {
       Description => 'Controllo di Guadagno',
@@ -1009,13 +3361,150 @@
    'Gapless' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'Gradation' => 'Ottimizzaz.',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'Genre' => {
+      Description => 'Genere',
+      PrintConv => {
+        'Acapella' => 'A cappella',
+        'Acid Jazz' => 'Acid jazz',
+        'Acid Punk' => 'Acid punk',
+        'Acoustic' => 'Acustica',
+        'Ambient' => 'Ambientale',
+        'Avantgarde' => 'Avanguardia',
+        'Ballad' => 'Ballata',
+        'Bass' => 'Basso',
+        'Big Band' => 'Big band',
+        'Black Metal' => 'Black metal',
+        'Booty Bass' => 'Basso booty',
+        'Celtic' => 'Celtica',
+        'Chamber Music' => 'Musica da camera',
+        'Chorus' => 'Coro',
+        'Christian Gangsta' => 'Gangsta cristiano',
+        'Christian Rap' => 'Rap cristiano',
+        'Christian Rock' => 'Rock cristiano',
+        'Classic Rock' => 'Rock classico',
+        'Classical' => 'Classica',
+        'Club-House' => 'Club-house',
+        'Comedy' => 'Commedia',
+        'Contemporary C' => 'C contemporaneo',
+        'Country' => 'Nazione',
+        'Cover' => 'Copertina',
+        'Dance Hall' => 'Dance hall',
+        'Death Metal' => 'Death metal',
+        'Drum & Bass' => 'Batteria e basso',
+        'Drum Solo' => 'Batteria solo',
+        'Duet' => 'Duetto',
+        'Easy Listening' => 'Easy listening',
+        'Electronic' => 'Elettronica',
+        'Ethnic' => 'Etnica',
+        'Euro-House' => 'Euro-house',
+        'Euro-Techno' => 'Euro-techno',
+        'Fast Fusion' => 'Fast fusion',
+        'Folk-Rock' => 'Folk-rock',
+        'Game' => 'Gioco',
+        'Gothic' => 'Gotica',
+        'Gothic Rock' => 'Rock gotico',
+        'Hard Rock' => 'Hard rock',
+        'Heavy Metal' => 'Heavy metal',
+        'Hip-Hop' => 'Hip-hop',
+        'Humour' => 'Umoristica',
+        'Instrumental' => 'Strumentale',
+        'Instrumental Pop' => 'Pop strumentale',
+        'Instrumental Rock' => 'Rock strumentale',
+        'Jazz+Funk' => 'Jazz+funk',
+        'Latin' => 'Latina',
+        'Lo-Fi' => 'Lo-fi',
+        'Meditative' => 'Medidativa',
+        'National Folk' => 'Folklore nazionale',
+        'Native American' => 'Nativi americani',
+        'New Age' => 'New age',
+        'New Wave' => 'New wave',
+        'Noise' => 'Rumore',
+        'None' => 'Nessuno',
+        'Oldies' => 'Vecchi successi',
+        'Other' => 'Altro',
+        'Polsk Punk' => 'Punk polacco',
+        'Pop-Folk' => 'Pop-folk',
+        'Pop/Funk' => 'Pop/funk',
+        'Porn Groove' => 'Porn groove',
+        'Power Ballad' => 'Power ballad',
+        'Progressive Rock' => 'Progressive rock',
+        'Psychadelic' => 'Psichedelica',
+        'Psychedelic Rock' => 'Rock psichedelica',
+        'Punk Rock' => 'Punk rock',
+        'Retro' => 'RetrÃ²',
+        'Rhythmic Soul' => 'Rhythmic soul',
+        'Rock & Roll' => 'Rock & roll',
+        'Satire' => 'Satira',
+        'Slow Jam' => 'Slow jam',
+        'Slow Rock' => 'Slow rock',
+        'Sound Clip' => 'Clip sonora',
+        'Soundtrack' => 'Colonna sonora',
+        'Southern Rock' => 'Southern rock',
+        'Speech' => 'Parlato',
+        'Symphonic Rock' => 'Rock sinfonico',
+        'Symphony' => 'Sinfonia',
+        'Techno-Industrial' => 'Techno-industrial',
+        'Terror' => 'Terrore',
+        'Thrash Metal' => 'Thrash metal',
+        'Tribal' => 'Tribale',
+        'Trip-Hop' => 'Trip-hop',
+      },
+    },
+   'GenreID' => 'ID genere',
+   'GeoTiffAsciiParams' => 'Parametri Geo Tiff Ascii',
+   'GeoTiffDirectory' => 'Cartella Geo Tiff',
+   'GeoTiffDoubleParams' => 'Parametri Geo Tiff Double',
+   'GeogGeodeticDatum' => {
+      PrintConv => {
+        'Lisbon' => 'Lisbona',
+        'Stockholm 1938' => 'Stoccolma 1938',
+      },
+    },
+   'GeogPrimeMeridian' => {
+      PrintConv => {
+        'Lisbon' => 'Lisbona',
+        'Rome' => 'Roma',
+        'Stockholm' => 'Stoccolma',
+      },
+    },
+   'GeographicType' => {
+      PrintConv => {
+        'Greek' => 'Greco',
+        'Lisbon' => 'Lisbona',
+        'Stockholm 1938' => 'Stoccolma 1938',
+      },
+    },
+   'Gradation' => {
+      Description => 'Ottimizzaz.',
+      PrintConv => {
+        'Normal' => 'Normale',
+        'n/a' => 'n/d',
+      },
+    },
    'GrayResponseCurve' => 'Curva di risposta Grigio',
-   'GrayResponseUnit' => 'UnitÃ  di risposta Grigio',
+   'GrayResponseUnit' => {
+      Description => 'UnitÃ  di risposta Grigio',
+      PrintConv => {
+        '1e-05' => '1e-005',
+        '1e-06' => '1e-006',
+      },
+    },
    'GrayTRC' => 'Curva Riproduzione Tono Grigio',
    'GreenMatrixColumn' => 'Colonna della Matrice Verde',
    'GreenTRC' => 'Curva Riproduziozne Tono Verde',
+   'GridDisplay' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Grouping' => 'Raggruppamento',
+   'HCUsage' => {
+      Description => 'Uso HC',
+      PrintConv => {
+        'Line Art' => 'Line art',
+      },
+    },
    'HDR' => {
       Description => 'HDR auto',
@@ -1024,5 +3513,17 @@
       },
     },
+   'HDRSetting' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'HalftoneHints' => 'Suggerimenti mezzi toni',
+   'HandlerType' => {
+      PrintConv => {
+        'Text' => 'Testo',
+      },
+    },
    'Headline' => 'Intestazione',
+   'HeightResolution' => 'Risoluzione altezza',
    'HighISONoiseReduction' => {
       Description => 'Riduzione Rumore High ISO',
@@ -1033,13 +3534,63 @@
         'Normal' => 'Normale',
         'Off' => 'Disattivata',
+        'Strong' => 'Forte',
+        'n/a' => 'n/d',
+      },
+    },
+   'HighSpeedSync' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'HighlightTonePriority' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+        'Off' => 'Spento',
+      },
+    },
+   'HometownCity' => {
+      PrintConv => {
+        'Jerusalem' => 'Gerusalemme',
+        'Lisbon' => 'Lisbona',
+        'London' => 'Londra',
+        'Milan' => 'Milano',
+        'Prague' => 'Praga',
+        'Rome' => 'Roma',
+        'Stockholm' => 'Stoccolma',
+        'Tehran' => 'Teheran',
       },
     },
    'HometownDST' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'Hue' => 'TonalitÃ ',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'HostComputer' => 'Computer ospite',
+   'HotKey' => {
+      PrintConv => {
+        '(none)' => '(nessuno)',
+      },
+    },
+   'Hue' => {
+      Description => 'TonalitÃ ',
+      PrintConv => {
+        'None' => 'Nessuno',
+        'Normal' => 'Normale',
+      },
+    },
    'HueAdjustment' => 'Regolazione Hue',
+   'ICCProfile' => 'Profili ICC',
+   'IDCCreativeStyle' => {
+      PrintConv => {
+        'Camera Setting' => 'Impostazioni fotocamera',
+        'Landscape' => 'Orizzontale',
+        'Light' => 'Chiara',
+        'Real' => 'Reale',
+        'Sepia' => 'Seppia',
+        'Sunset' => 'Tramonto',
+        'Vivid' => 'Vivace',
+      },
+    },
+   'INGRReserved' => 'Riseervato a INGR',
    'IPTC-NAA' => 'Metadati IPTC-NAA',
    'IPTCBitsPerSample' => 'Numero di Bits per Campione',
@@ -1057,26 +3608,178 @@
    'IPTCPictureNumber' => 'Numero Immagine',
    'ISO' => 'SensibilitÃ  ISO',
+   'ISOAuto' => {
+      Description => 'ISO auto',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ISOAutoParameters' => {
+      Description => 'Parametri ISO auto',
+      PrintConv => {
+        'Fast' => 'Veloce',
+      },
+    },
+   'ISODisplay' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ISOExpansion' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ISOExpansion2' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'ISOInfo' => 'Info ISO',
    'ISOSelection' => 'Selezione ISO',
+   'ISOSensitivityStep' => 'Passo sensibilitÃ  ISO',
    'ISOSetting' => {
       Description => 'Impostazione ISO',
       PrintConv => {
+        '100 (Low)' => '100 (basso)',
         'Manual' => 'Manuale',
-      },
-    },
+        'n/a' => 'n/d',
+      },
+    },
+   'ISOSpeed' => 'VelocitÃ  ISO',
    'ISOSpeedExpansion' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'ISOSpeedIncrements' => {
+      PrintConv => {
+        '1 Stop' => '1 stop',
+        '1/3 Stop' => '1/3 stop',
+      },
+    },
+   'ISOSpeedLatitudeyyy' => 'VelocitÃ  ISO - Latitudine yyy',
+   'ISOSpeedLatitudezzz' => 'VelocitÃ  ISO - Latitudine zzz',
+   'ISOSpeedRange' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'ISOValue' => 'Valore ISO',
+   'IT8Header' => 'Intestazione IT8',
+   'Illumination' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Image::ExifTool::AIFF::Comment' => 'Commento AIFF',
+   'Image::ExifTool::EXE::CHM' => 'EXE CHM',
+   'Image::ExifTool::EXE::ELF' => 'EXE ELF',
+   'Image::ExifTool::EXE::MachO' => 'EXE MachO',
+   'Image::ExifTool::EXE::Main' => 'EXE',
+   'Image::ExifTool::EXE::PEF' => 'EXE PEF',
+   'Image::ExifTool::EXE::PEString' => 'EXE PEString',
+   'Image::ExifTool::EXE::PEVersion' => 'EXE PEVersion',
+   'Image::ExifTool::Exif::Main' => 'Exif',
+   'Image::ExifTool::FLAC::Main' => 'FLAC',
+   'Image::ExifTool::Flash::Main' => 'Flash',
+   'Image::ExifTool::Flash::Video' => 'Video flash',
+   'Image::ExifTool::FlashPix::Main' => 'FlashPix',
+   'Image::ExifTool::Font::Main' => 'Carattere',
+   'Image::ExifTool::Font::Name' => 'Nome carattere',
+   'Image::ExifTool::Font::PFM' => 'Carattere PFM',
+   'Image::ExifTool::GPS::Main' => 'GPS',
+   'Image::ExifTool::ID3::Private' => 'ID3 privato',
+   'Image::ExifTool::ID3::v1' => 'ID3 v1',
+   'Image::ExifTool::ID3::v1_Enh' => 'ID3 v1_Enh',
+   'Image::ExifTool::ID3::v2_2' => 'ID3 v2_2',
+   'Image::ExifTool::ID3::v2_3' => 'ID3 v2_3',
+   'Image::ExifTool::ID3::v2_4' => 'ID3 v2_4',
+   'Image::ExifTool::ITC::Main' => 'ITC',
+   'Image::ExifTool::JFIF::Main' => 'JFIF',
+   'Image::ExifTool::Kodak::DcMD' => 'Kodak DcMD',
+   'Image::ExifTool::Kodak::Free' => 'Kodak Free',
+   'Image::ExifTool::Kodak::KDC_IFD' => 'KDC_IFD Kodak',
+   'Image::ExifTool::Kodak::Main' => 'Kodak',
+   'Image::ExifTool::Microsoft::Stitch' => 'Microsoft Stitch',
+   'Image::ExifTool::Olympus::AVI' => 'AVI Olympus',
+   'Image::ExifTool::Olympus::Main' => 'Olympus',
+   'Image::ExifTool::PSP::Creator' => 'Creatore PSP',
+   'Image::ExifTool::PSP::Image' => 'Immagine PSP',
+   'Image::ExifTool::PSP::Main' => 'PSP',
+   'Image::ExifTool::PanasonicRaw::Main' => 'PanasonicRaw',
+   'Image::ExifTool::PostScript::Main' => 'PostScript',
+   'Image::ExifTool::PrintIM::Main' => 'PrintIM',
+   'Image::ExifTool::Qualcomm::Main' => 'Qualcomm',
+   'Image::ExifTool::QuickTime::Main' => 'QuickTime',
+   'Image::ExifTool::RIFF::Main' => 'RIFF',
+   'Image::ExifTool::Radiance::Main' => 'Radianza',
+   'Image::ExifTool::Rawzor::Main' => 'Rawzor',
+   'Image::ExifTool::Real::AudioV3' => 'Real AudioV3',
+   'Image::ExifTool::Real::AudioV4' => 'Real AudioV4',
+   'Image::ExifTool::Real::AudioV5' => 'Real AudioV5',
+   'Image::ExifTool::Ricoh::AVI' => 'AVI Ricoh',
+   'Image::ExifTool::Ricoh::FaceInfo' => 'FaceInfo Ricoh',
+   'Image::ExifTool::Ricoh::FirmwareInfo' => 'Info firmware Ricoh',
+   'Image::ExifTool::Ricoh::ImageInfo' => 'Info immagine Ricoh',
+   'Image::ExifTool::Ricoh::Main' => 'Ricoh',
+   'Image::ExifTool::Ricoh::RMETA' => 'RMETA Ricoh',
+   'Image::ExifTool::Ricoh::SerialInfo' => 'Info seriale Ricoh',
+   'Image::ExifTool::Ricoh::Subdir' => 'Sotto-cartella Ricoh',
+   'Image::ExifTool::Ricoh::Text' => 'Testo Ricoh',
+   'Image::ExifTool::Samsung::INFO' => 'Samsung INFO',
+   'Image::ExifTool::Samsung::MP4' => 'Samsung MP4',
+   'Image::ExifTool::Samsung::PictureWizard' => 'Samsung PictureWizard',
+   'Image::ExifTool::Sanyo::Main' => 'Sanyo',
+   'Image::ExifTool::Sigma::Main' => 'Sigma',
    'ImageAdjustment' => 'Regolazione Immagine',
+   'ImageAlterationConstraints' => {
+      PrintConv => {
+        'No Merging' => 'Nessuna fusione',
+      },
+    },
+   'ImageAuthentication' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ImageByteCount' => 'Numero di byte dell\'immagine',
+   'ImageColorIndicator' => {
+      Description => 'Indicazione colore dell\'immagine',
+      PrintConv => {
+        'Specified Image Color' => 'Colore immagine specificato',
+        'Unspecified Image Color' => 'Colore immagine non specificato',
+      },
+    },
+   'ImageColorValue' => 'Valore colore dell\'immagine',
    'ImageCount' => 'Conteggio Immagini',
+   'ImageDataDiscard' => {
+      Description => 'Dati scartati dell\'immagine',
+      PrintConv => {
+        'Flexbits Discarded' => 'Flexbit scartati',
+        'Full Resolution' => 'Risoluzione completa',
+        'HighPass Frequency Data Discarded' => 'Dati in frequenza passa-alto scartati',
+        'Highpass and LowPass Frequency Data Discarded' => 'Dati in frequenza passa-alto e passa-basso scartati',
+      },
+    },
    'ImageDataSize' => 'Dimensione Dati Immagine',
    'ImageDepth' => 'ProfonditÃ  Immagine',
    'ImageDescription' => 'Descrizione Immagine',
+   'ImageDustOff' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ImageEditing' => {
+      PrintConv => {
+        'None' => 'Nessuno',
+        'Resized' => 'Ridimensionato',
+      },
+    },
    'ImageHeight' => 'Altezza immagine',
    'ImageHistory' => 'Cronologia immagine',
    'ImageID' => 'ID Immagine',
+   'ImageLayer' => 'Livello immagine',
    'ImageNumber' => 'Numero immagine',
+   'ImageOffset' => 'Offset immagine',
    'ImageOptimization' => 'Ottimizzazione Immagine',
    'ImageOrientation' => {
@@ -1094,23 +3797,140 @@
       },
     },
+   'ImageReview' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'ImageRotated' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'ImageRotation' => {
+      PrintConv => {
+        'None' => 'Nessuno',
       },
     },
    'ImageSize' => 'Dimensioni immagini',
-   'ImageStabilization' => 'Stabilizzazione Immagine',
+   'ImageSourceData' => 'Dati origine immagine',
+   'ImageStabilization' => {
+      Description => 'Stabilizzazione Immagine',
+      PrintConv => {
+        'Off' => 'Spento',
+        'Off (1)' => 'Spento (1)',
+        'Off (2)' => 'Spento (2)',
+        'n/a' => 'n/d',
+      },
+    },
+   'ImageStabilizationSetting' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ImageStyle' => {
+      PrintConv => {
+        'Landscape' => 'Orizzontale',
+        'Sunset' => 'Tramonto',
+        'Vivid' => 'Vivace',
+      },
+    },
    'ImageTone' => {
       PrintConv => {
         'Landscape' => 'Orizzontale',
         'Portrait' => 'Verticale',
-      },
-    },
-   'ImageType' => 'Tipo Immagine',
+        'Radiant' => 'Radiante',
+      },
+    },
+   'ImageType' => {
+      Description => 'Tipo immagine',
+      PrintConv => {
+        'Page' => 'Pagina',
+        'Preview' => 'Anteprima',
+      },
+    },
    'ImageUniqueID' => 'ID unico immagine',
+   'ImageVersion' => 'Versione immagine',
    'ImageWidth' => 'Larghezza immagine',
    'Index' => 'Indice',
+   'Indexable' => {
+      PrintConv => {
+        'False' => 'Falso',
+      },
+    },
+   'Indexed' => {
+      Description => 'Indicizzato',
+      PrintConv => {
+        'Indexed' => 'Indicizzato',
+        'Not indexed' => 'Non indicizzato',
+      },
+    },
+   'InfraredIlluminator' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'InitialDisplayEffect' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'InitialKey' => 'Chiave iniziale',
+   'InitializedDataSize' => 'Dimensione dati inizializzati',
+   'InkNames' => 'Nomi inchiostri',
+   'InkSet' => {
+      Description => 'Gruppo inchiostri',
+      PrintConv => {
+        'Not CMYK' => 'Non CMYK',
+      },
+    },
    'Instructions' => 'Istruzioni',
    'IntellectualGenre' => 'Genere Intellettuale',
+   'IntelligentAuto' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'IntelligentContrast' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'IntelligentD-Range' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+      },
+    },
+   'IntelligentExposure' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+      },
+    },
+   'IntelligentResolution' => {
+      PrintConv => {
+        'Extended' => 'Esteso',
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+      },
+    },
+   'IntensityStereo' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Interlace' => {
+      Description => 'Interlacciamento',
+      PrintConv => {
+        'Noninterlaced' => 'Non interlacciato',
+        'Progressive' => 'Progressivo',
+      },
+    },
+   'InterleavedField' => {
+      PrintConv => {
+        'Even' => 'Pari',
+      },
+    },
    'InternalFlash' => {
       PrintConv => {
@@ -1118,35 +3938,233 @@
         'Manual' => 'Manuale',
         'No' => 'Flash non emesso',
-        'Repeating Flash' => 'Ripetizione Flash',
-      },
-    },
+        'Off' => 'Spento',
+        'Repeating Flash' => 'Ripetizione flash',
+      },
+    },
+   'InternalName' => 'Nome interno',
+   'InternetRadioStationName' => 'Nome stazione radio internet',
+   'InternetRadioStationOwner' => 'Proprietario stazione radio internet',
+   'InternetRadioStationURL' => 'URL stazione radio internet',
    'InteropIndex' => {
       Description => 'Identificazione interoperativitÃ ',
       PrintConv => {
-        'R98 - DCF basic file (sRGB)' => 'R98: File base DCF (sRGB)',
+        'R03 - DCF option file (Adobe RGB)' => 'R03 - file opzioni DCF (Adobe RGB)',
+        'R98 - DCF basic file (sRGB)' => 'R98 - file base DCF (sRGB)',
+        'THM - DCF thumbnail file' => 'File miniatura THM - DCF',
       },
     },
    'InteropOffset' => 'Etichetta interoperativitÃ ',
    'InteropVersion' => 'Versione interoperativitÃ ',
+   'InterpretedBy' => 'Interpetrato da',
+   'InvolvedPeople' => 'Persone coinvolte',
+   'Italic' => 'Corsivo',
    'JFIFVersion' => 'Versione JFIF',
-   'JPEGTables' => 'Tavole JPEG',
-   'JobID' => 'ID Lavoro',
-   'Keyword' => 'Parole Chiave',
-   'Keywords' => 'Parala Chiave',
-   'LanguageIdentifier' => 'ID Linguaggio',
+   'JPEGACTables' => 'Tabelle JPEGAC',
+   'JPEGDCTables' => 'Tabelle JPEGDC',
+   'JPEGLosslessPredictors' => 'Predittori JPEG senza perdita',
+   'JPEGPointTransforms' => 'Trasformazioni puntiali JPEG',
+   'JPEGProc' => {
+      Description => 'Proc JPEG',
+      PrintConv => {
+        'Baseline' => 'Linea di base',
+        'Lossless' => 'Senza perdita',
+      },
+    },
+   'JPEGQTables' => 'Tabelle JPEGQ',
+   'JPEGQuality' => {
+      Description => 'QualitÃ ',
+      PrintConv => {
+        'Extra Fine' => 'Extra fine',
+        'Standard' => 'Normale',
+        'n/a' => 'n/d',
+      },
+    },
+   'JPEGRestartInterval' => 'Intervallo riavvio JPEG',
+   'JPEGTables' => 'Tabelle JPEG',
+   'JobID' => 'ID processo',
+   'JobName' => 'Nome processo',
+   'JobRef' => 'Rif processo',
+   'JobStatus' => 'Stato processo',
+   'JpgFromRaw' => 'JPG da raw',
+   'JpgFromRawLength' => 'Lunghezza JPG da raw',
+   'JpgFromRawStart' => 'Inizio JPG da raw',
+   'Keyword' => 'Parola chiave',
+   'KeywordInfo' => 'Info parola chiave',
+   'Keywords' => 'Parole chiave',
+   'Kinds' => 'Tipi',
+   'LCDIllumination' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'LCDIlluminationDuringBulb' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'LCHEditor' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Language' => 'Lingua',
+   'LanguageCode' => {
+      Description => 'Codice lingua',
+      PrintConv => {
+        'Albanian' => 'Albanese',
+        'Arabic' => 'Arabo',
+        'Armenian' => 'Armeno',
+        'Azeri' => 'Azero',
+        'Basque' => 'Basco',
+        'Belarusian' => 'Bielorusso',
+        'Breton' => 'Bretone',
+        'Bulgarian' => 'Bulgaro',
+        'Catalan' => 'Catalano',
+        'Chinese (Simplified)' => 'Cinese (semplificato)',
+        'Chinese (Traditional)' => 'Cinese (tradizionale)',
+        'Croato-Serbian (Latin)' => 'Serbo-croato (alfabeto latino)',
+        'Czech' => 'Ceco',
+        'Danish' => 'Danese',
+        'Dutch' => 'Olandese',
+        'Dutch (Belgian)' => 'Olandese (Belgio)',
+        'English (Australian)' => 'Inglese (Australia)',
+        'English (British)' => 'Inglese (Gran Bretagna)',
+        'English (Canadian)' => 'Inglese (Canada)',
+        'English (U.S.)' => 'Inglese (U.S.A.)',
+        'Estonian' => 'Estone',
+        'Farsi' => 'Persiano',
+        'Finnish' => 'Finlandese',
+        'French' => 'Francese',
+        'French (Belgian)' => 'Francese (Belgio)',
+        'French (Canadian)' => 'Francese (Canada)',
+        'French (Swiss)' => 'Francese (Svizzera)',
+        'Gaelic' => 'Gaelico',
+        'Galician' => 'Galiziano',
+        'Georgian' => 'Georgiano',
+        'German' => 'Tedesco',
+        'German (Austrian)' => 'Tedesco (Austria)',
+        'German (Swiss)' => 'Tedesco (Svizzera)',
+        'Greek' => 'Greco',
+        'Hebrew' => 'Ebraico',
+        'Hungarian' => 'Ungherese',
+        'Icelandic' => 'Islandese',
+        'Indonesian' => 'Indonesiano',
+        'Invariant' => 'Invariante',
+        'Italian' => 'Italiano',
+        'Italian (Swiss)' => 'Italiano (Svizzera)',
+        'Japanese' => 'Giapponese',
+        'Kazak' => 'Kazako',
+        'Korean' => 'Coreano',
+        'Kyrgyz' => 'Kirghizo',
+        'Latvian' => 'Lettone',
+        'Lithuanian' => 'Lituano',
+        'Macedonian' => 'Macedone',
+        'Mongolian' => 'Mongolo',
+        'Nepali' => 'Nepalese',
+        'Neutral' => 'Neutrale',
+        'Neutral 2' => 'Neutrale 2',
+        'Norwegian (Bokml)' => 'Norvegese (BokmÃ¥l)',
+        'Norwegian (Nynorsk)' => 'Norvegese (Nynorsk)',
+        'Polish' => 'Polacco',
+        'Portuguese' => 'Portogese',
+        'Portuguese (Brazilian)' => 'Portoghese (Brasile)',
+        'Process default' => 'Predefinita del processo',
+        'Rhaeto-Romanic' => 'Reto-romanico',
+        'Romanian' => 'Rumeno',
+        'Russian' => 'Russo',
+        'Sanskrit' => 'Sanscrito',
+        'Serbo-Croatian (Cyrillic)' => 'Serbo-croato (cirillico)',
+        'Slovak' => 'Slovacco',
+        'Slovenian' => 'Sloveno',
+        'Spanish (Castilian)' => 'Spagnolo (Castiglia)',
+        'Spanish (Mexican)' => 'Spagnolo (Messico)',
+        'Spanish (Modern)' => 'Spagnolo moderno',
+        'Swedish' => 'Svedese',
+        'Syriac' => 'Siriaco',
+        'Turkish' => 'Turco',
+        'Ukrainian' => 'Ucraino',
+        'Uzbek' => 'Usbeco',
+        'Vietnamese' => 'Vietnamita',
+        'Welsh' => 'Gallese',
+      },
+    },
+   'LanguageIdentifier' => 'Identificativo lingua',
+   'LanguageList' => 'Lista lingue',
+   'LanguageName' => 'Nome lingua',
+   'LateralChromaticAberration' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'Layout' => {
+      PrintConv => {
+        'Tiles' => 'Tasselli',
+      },
+    },
+   'LegalCopyright' => 'Copyright legali',
+   'LegalTrademarks' => 'Marchi legali',
+   'Length' => 'Durata',
    'Lens' => 'Obiettivo',
    'Lens35efl' => 'Obiettivo',
    'LensDataVersion' => 'Versione Dati Obiettivo',
    'LensFStops' => 'F-Stops Obiettivo',
-   'LensID' => 'Obiettivo Utilizzato',
+   'LensID' => {
+      Description => 'Obiettivo Utilizzato',
+      PrintConv => {
+        'Ricoh Lens A16 24-85mm F3.5-5.5' => 'Obiettivo Ricoh A16 24-85mm F3.5-5.5',
+        'Ricoh Lens P10 28-300mm F3.5-5.6 VC' => 'Obiettivo Ricoh P10 28-300mm F3.5-5.6 VC',
+        'Ricoh Lens S10 24-70mm F2.5-4.4 VC' => 'Obiettivo Ricoh S10 24-70mm F2.5-4.4 VC',
+      },
+    },
    'LensIDNumber' => 'Numero ID Obiettivo',
-   'LensInfo' => 'Informazioni su lente',
+   'LensInfo' => 'Informazioni obiettivo',
+   'LensMake' => 'Marca obiettivo',
+   'LensModel' => 'Modello obiettivo',
+   'LensSerialNumber' => 'Numero di serie obiettivo',
+   'LensShutterLock' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'LensSpec' => 'Obiettivo',
-   'LensType' => 'Tipo Obiettivo',
+   'LensType' => {
+      Description => 'Tipo obiettivo',
+      PrintConv => {
+        '02 Standard Zoom 5-15mm F2.8-4.5' => '02 Zoom standard 5-15mm F2.8-4.5',
+        '04 Toy Lens Wide 6.3mm F7.1' => '04 Grandangolare toy 6.3mm F7.1',
+        '05 Toy Lens Telephoto 18mm F8' => '05 Teleobiettivo toy 18mm F8',
+        '1.4x Teleconverter' => 'Moltiplicatore di focale 1.4x',
+        'None' => 'Nessuno',
+        'Sigma 100-300mm F4 EX (APO (D) or D IF)' => 'Sigma 100-300mm F4 EX (APO (D) o D IF)',
+      },
+    },
+   'LevelGaugePitch' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'LevelGaugeRoll' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'LevelOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => 'Orizzontale',
+        'Rotate 180' => 'Ruota di 180Â°',
+        'Rotate 270 CW' => 'Ruota di 270Â° in senso orario',
+        'Rotate 90 CW' => 'Ruota di 90Â° senso orario',
+      },
+    },
+   'License' => 'Licenza',
+   'LicenseID' => 'ID licenza',
    'LicenseType' => {
       PrintConv => {
-        'Unknown' => 'Sconosciuta',
-      },
-    },
+        'Public Domain' => 'Pubblico dominio',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'LightCondition' => 'Condizione luce',
    'LightSource' => {
       Description => 'Sorgente di luce',
@@ -1157,4 +4175,5 @@
         'Daylight' => 'Luce del giorno',
         'Daylight Fluorescent' => 'Fluorescente a luce del giorno',
+        'Evening Sunlight' => 'Luce solare serale',
         'Fine Weather' => 'Bel tempo',
         'Fluorescent' => 'Fluorescente',
@@ -1166,24 +4185,93 @@
         'Standard Light C' => 'Luce standard C',
         'Tungsten (Incandescent)' => 'Tungsteno (luce incandescente)',
-        'Unknown' => 'Sconosciuta',
+        'Unknown' => 'Sconosciuto',
         'Warm White Fluorescent' => 'Luce fluorescente bianca calda',
         'White Fluorescent' => 'Fluorescente bianca',
       },
     },
+   'LightSourceSpecial' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'LightingMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'Lightness' => 'Luce',
+   'Line' => 'Linea',
+   'LineOrder' => {
+      PrintConv => {
+        'Random Y' => 'Casuale Y',
+      },
+    },
+   'LinearResponseLimit' => 'Limite risposta lineare',
+   'LinearizationTable' => 'Tabella di linearizzazione',
+   'Lines' => 'Linee',
+   'LinkAEToAFPoint' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'LinkerVersion' => 'Versione linker',
    'Lit' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'LocalizedCameraModel' => 'Modello Fotocamera Localizzato',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'LiveViewAFMethod' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'LiveViewAFSetting' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'LiveViewFocusMode' => {
+      PrintConv => {
+        'Manual' => 'Manuale',
+        'n/a' => 'n/d',
+      },
+    },
+   'LiveViewMetering' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'LiveViewShooting' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'LocalDeltaType' => {
+      PrintConv => {
+        'Absolute' => 'Assoluto',
+      },
+    },
+   'LocalizedCameraModel' => 'Modello fotocamera localizzato',
    'Location' => 'LocalitÃ ',
+   'LocationKind' => 'Tipo localitÃ ',
+   'LocationName' => 'Nome localitÃ ',
+   'LocationNote' => 'Note localitÃ ',
+   'LongDescription' => 'Descrizione estesa',
    'LongExposureNoiseReduction' => {
-      Description => 'Espos.lunga NR',
-      PrintConv => {
-        'Off' => 'Disattivata',
+      Description => 'Espososizione lunga riduzione rumore',
+      PrintConv => {
+        'Off' => 'Spento',
+        'Off (65535)' => 'Spento (65535)',
         'On' => 'Attivata',
-      },
-    },
+        'n/a' => 'n/d',
+      },
+    },
+   'LongExposureNoiseReduction2' => {
+      Description => 'Espososizione lunga riduzione rumore 2',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'LongText' => 'Testo lungo',
    'LoopStyle' => {
       PrintConv => {
@@ -1193,13 +4281,59 @@
    'LuminanceNoiseReduction' => {
       PrintConv => {
-        'Low' => 'Leggero',
-      },
-    },
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+      },
+    },
+   'Lyricist' => 'Paroliere',
+   'Lyrics' => 'Testo',
    'MCUVersion' => 'Versione MCU',
+   'MDColorTable' => 'Tabella colori MD',
+   'MDFileTag' => 'Tag file MD',
+   'MDFileUnits' => 'UnitÃ  file MD',
+   'MDLabName' => 'Nome lab MD',
+   'MDPrepDate' => 'Data prep MD',
+   'MDPrepTime' => 'Ora prep MD',
+   'MDSampleInfo' => 'Info campione MD',
+   'MDScalePixel' => 'Scala pixel MD',
    'MIEVersion' => 'Versione MIE',
+   'MIMEType' => 'Tipo mime',
+   'MIMETypeOfEncapsulatedDocument' => 'Tipo mime del documento incapsulato',
+   'MSDocumentText' => 'Testo documento MS',
+   'MSDocumentTextPosition' => 'Posizione testo documento MS',
+   'MSPropertySetStorage' => 'Gruppo di memoria proprietÃ  MS',
+   'MSStereo' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'MachineType' => {
+      Description => 'Tipo macchina',
+      PrintConv => {
+        'ARM little endian' => 'ARM little-endian',
+        'Alpha AXP (old)' => 'Alpha AXP (precedente)',
+        'EFI Byte Code' => 'Byte code EFI',
+        'Intel 386 or later, and compatibles' => 'Intel 386 o successivo e compatibili',
+        'MIPS little endian (R4000)' => 'MIPS little-endian (R4000)',
+        'MIPS little endian WCI v2' => 'MIPS little-endian WCI v2',
+        'MIPS with FPU' => 'MIPS con FPU',
+        'MIPS16 with FPU' => 'MIPS16 con FPU',
+        'Mitsubishi M32R little endian' => 'Mitsubishi M32R little-endian',
+        'Motorola 68000 series' => 'Serie Motorola 68000',
+        'PowerPC little endian' => 'PowerPC little-endian',
+        'PowerPC with floating point support' => 'PowerPC con supporto numeri in in virgola mobile',
+        'clr pure MSIL' => 'clr con MSIL puro',
+      },
+    },
    'Macro' => {
       PrintConv => {
         'Manual' => 'Manuale',
         'Normal' => 'Normale',
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'MacroLED' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
@@ -1207,4 +4341,19 @@
       PrintConv => {
         'Normal' => 'Normale',
+        'Off' => 'Spento',
+      },
+    },
+   'MagicFilter' => {
+      PrintConv => {
+        'Fish Eye' => 'Fish-eye',
+        'Fragmented' => 'Frammentato',
+        'Gentle Sepia' => 'Seppia leggero',
+        'Off' => 'Spento',
+        'Reflection' => 'Riflessione',
+      },
+    },
+   'MainDialExposureComp' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
@@ -1212,22 +4361,110 @@
    'MakeAndModel' => 'Marca e Modello',
    'MakerNote' => 'Dati DNG Privati',
+   'MakerNoteCanon' => 'Note marca Canon',
+   'MakerNoteCasio' => 'Note marca Casio',
+   'MakerNoteCasio2' => 'Note marca Casio 2',
+   'MakerNoteFujiFilm' => 'Note marca Fuji Film',
+   'MakerNoteGE' => 'Note marca GE',
+   'MakerNoteGE2' => 'Note marca GE2',
+   'MakerNoteHP' => 'Note marca HP',
+   'MakerNoteHP2' => 'Note marca HP2',
+   'MakerNoteHP4' => 'Note marca HP4',
+   'MakerNoteHP6' => 'Note marca HP6',
+   'MakerNoteHasselblad' => 'Note marca Hasselblad',
+   'MakerNoteISL' => 'Note marca ISL',
+   'MakerNoteJVC' => 'Note marca JVC',
+   'MakerNoteJVCText' => 'Note marca JVC - Testo',
+   'MakerNoteKodak10' => 'Note marca Kodak 10',
+   'MakerNoteKodak1a' => 'Note marca Kodak 1a',
+   'MakerNoteKodak1b' => 'Note marca Kodak 1b',
+   'MakerNoteKodak2' => 'Note marca Kodak 2',
+   'MakerNoteKodak3' => 'Note marca Kodak 3',
+   'MakerNoteKodak4' => 'Note marca Kodak 4',
+   'MakerNoteKodak5' => 'Note marca Kodak 5',
+   'MakerNoteKodak6a' => 'Note marca Kodak 6a',
+   'MakerNoteKodak6b' => 'Note marca Kodak 6b',
+   'MakerNoteKodak7' => 'Note marca Kodak 7',
+   'MakerNoteKodak8a' => 'Note marca Kodak 8a',
+   'MakerNoteKodak8b' => 'Note marca Kodak 8b',
+   'MakerNoteKodak9' => 'Note marca Kodak 9',
+   'MakerNoteKodakUnknown' => 'Note marca Kodak sconosciuta',
+   'MakerNoteKyocera' => 'Note marca Kyocera',
+   'MakerNoteLeica' => 'Note marca Leica',
+   'MakerNoteLeica2' => 'Note marca Leica 2',
+   'MakerNoteLeica3' => 'Note marca Leica 3',
+   'MakerNoteLeica4' => 'Note marca Leica 4',
+   'MakerNoteLeica5' => 'Note marca Leica 5',
+   'MakerNoteLeica6' => 'Note marca Leica 6',
+   'MakerNoteMinolta' => 'Note marca Minolta',
+   'MakerNoteMinolta2' => 'Note marca Minolta 2',
+   'MakerNoteMinolta3' => 'Note marca Minolta 3',
+   'MakerNoteNikon' => 'Note marca Nikon',
+   'MakerNoteNikon2' => 'Note marca Nikon 2',
+   'MakerNoteNikon3' => 'Note marca Nikon 3',
+   'MakerNoteOlympus' => 'Note marca Olympus',
+   'MakerNoteOlympus2' => 'Note marca Olympus 2',
+   'MakerNotePanasonic' => 'Note marca Panasonic',
+   'MakerNotePanasonic2' => 'Note marca Panasonic 2',
+   'MakerNotePentax' => 'Note marca Pentax',
+   'MakerNotePentax2' => 'Note marca Pentax 2',
+   'MakerNotePentax3' => 'Note marca Pentax 3',
+   'MakerNotePentax4' => 'Note marca Pentax 4',
+   'MakerNotePentax5' => 'Note marca Pentax 5',
+   'MakerNotePentax6' => 'Note marca Pentax 6',
+   'MakerNotePhaseOne' => 'Note marca Phase One',
+   'MakerNoteReconyx' => 'Note marca Reconyx',
+   'MakerNoteRicoh' => 'Note marca Ricoh',
+   'MakerNoteRicohText' => 'Note marca Ricoh - Testo',
+   'MakerNoteSafety' => {
+      Description => 'Note marca Safety',
+      PrintConv => {
+        'Safe' => 'Sicuro',
+        'Unsafe' => 'Non sicuro',
+      },
+    },
+   'MakerNoteSamsung1a' => 'Note marca Samsung 1a',
+   'MakerNoteSamsung1b' => 'Note marca Samsung 1b',
+   'MakerNoteSamsung2' => 'Note marca Samsung 2',
+   'MakerNoteSanyo' => 'Note marca Sanyo',
+   'MakerNoteSanyoC4' => 'Note marca Sanyo C4',
+   'MakerNoteSanyoPatch' => 'Note marca Sanyo Patch',
+   'MakerNoteSigma' => 'Note marca Sigma',
+   'MakerNoteSony' => 'Note marca Sony',
+   'MakerNoteSony2' => 'Note marca Sony 2',
+   'MakerNoteSony3' => 'Note marca Sony 3',
+   'MakerNoteSony4' => 'Note marca Sony 4',
+   'MakerNoteSonyEricsson' => 'Note marca Sony Ericsson',
+   'MakerNoteSonySRF' => 'Note marca Sony SRF',
+   'MakerNoteUnknown' => 'Note marca sconosciuta',
+   'MakerNoteUnknownText' => 'Note marca sconosciuta - Testo',
    'MakerNoteVersion' => 'Note Versione Costruttore',
    'MakerNotes' => 'Note produttore',
    'ManualFlashOutput' => {
       PrintConv => {
-        'Low' => 'Leggero',
+        'Low' => 'Basso',
+        'n/a' => 'n/d',
       },
     },
    'ManualFocusDistance' => 'Messa a Fuoco Manuale',
+   'MarkerID' => 'ID marker',
+   'MaskedAreas' => 'Aree mascherate',
    'MasterDocumentID' => 'ID Documento Principale',
+   'Matteing' => 'Opacizzazione',
    'MaxAperture' => 'Massima apertura delle lenti',
-   'MaxApertureAtMaxFocal' => 'Diaframma Massimo alla Focale Massima',
-   'MaxApertureAtMinFocal' => 'Diaframma Massimo alla Focale Minima',
+   'MaxApertureAtMaxFocal' => 'Diaframma massimo alla focale massima',
+   'MaxApertureAtMinFocal' => 'Diaframma massimo alla focale minima',
    'MaxApertureValue' => 'Diaframma massimo obiettivo',
-   'MaxFocalLength' => 'Lunghezza Focale Massima',
+   'MaxFocalLength' => 'Lunghezza focale massima',
+   'MaxSampleValue' => 'Massimo valore campioni',
+   'MeasurementGeometry' => {
+      PrintConv => {
+        '0/45 or 45/0' => '0/45 o 45/0',
+        '0/d or d/0' => '0/d o d/0',
+      },
+    },
    'MediaBlackPoint' => 'Media Punto Nero',
    'MediaType' => {
       PrintConv => {
-        'Normal' => 'Normale',
+        'Normal (Music)' => 'Normale (musica)',
       },
     },
@@ -1244,18 +4481,20 @@
     },
    'MeteringMode' => {
-      Description => 'ModalitÃ  misurazione esposimetrica',
+      Description => 'ModalitÃ  misurazione',
       PrintConv => {
         'Average' => 'Media',
+        'Center-weighted Average' => 'Media centrale ponderata',
         'Center-weighted average' => 'Media centrale ponderata',
-        'Multi-segment' => 'Multi zona',
-        'Multi-spot' => 'Multipunto',
+        'Multi-segment' => 'Multi-zona',
+        'Multi-spot' => 'Multi-punto',
         'Other' => 'Altro',
         'Partial' => 'Parziale',
         'Spot' => 'Punto',
-        'Unknown' => 'Sconosciuta',
+        'Unknown' => 'Sconosciuto',
       },
     },
    'MeteringMode2' => {
       PrintConv => {
+        'Center-weighted average' => 'Media centrale ponderata',
         'Multi-segment' => 'Multi zona',
       },
@@ -1263,8 +4502,21 @@
    'MeteringMode3' => {
       PrintConv => {
+        'Center-weighted average' => 'Media centrale ponderata',
         'Multi-segment' => 'Multi zona',
       },
     },
-   'MinFocalLength' => 'Lunghezza Focale Minima',
+   'MeteringTime' => {
+      PrintConv => {
+        'No Limit' => 'Nessun limite',
+      },
+    },
+   'MinFocalLength' => 'Lunghezza focale minima',
+   'MinSampleValue' => 'Minimo valore campioni',
+   'MiniatureFilterOrientation' => {
+      PrintConv => {
+        'Horizontal' => 'Orizzontale',
+        'Vertical' => 'Verticale',
+      },
+    },
    'MinoltaQuality' => {
       Description => 'QualitÃ ',
@@ -1273,5 +4525,23 @@
       },
     },
-   'Model' => 'Modello Fotocamera',
+   'MirrorLockup' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'ModeNumber' => 'Numero modo',
+   'Model' => 'Nome modello fotocamera',
+   'Model2' => 'Modello 2',
+   'ModelReleaseStatus' => {
+      PrintConv => {
+        'None' => 'Nessuno',
+        'Not Applicable' => 'Non applicabile',
+      },
+    },
+   'ModelingFlash' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'ModifiedPictureStyle' => {
       PrintConv => {
@@ -1281,7 +4551,13 @@
       },
     },
+   'ModifiedSaturation' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'ModifiedSharpnessFreq' => {
       PrintConv => {
-        'Low' => 'Leggero',
+        'Low' => 'Basso',
+        'n/a' => 'n/d',
       },
     },
@@ -1301,5 +4577,16 @@
       },
     },
-   'ModifyDate' => 'Data e ora di modifica del file',
+   'ModifyDate' => 'Data modifica',
+   'MoireFilter' => {
+      Description => 'Filtro moire',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'MonitorDisplayOff' => {
+      PrintConv => {
+        'Manual' => 'Manuale',
+      },
+    },
    'MonochromeFilterEffect' => {
       PrintConv => {
@@ -1313,5 +4600,10 @@
    'MonochromeLinear' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'MonochromeToning' => {
+      PrintConv => {
+        'None' => 'Nessuno',
       },
     },
@@ -1320,9 +4612,31 @@
         'Green' => 'Verde',
         'None' => 'Nessuno',
+        'Purple' => 'Porpora',
+        'Sepia' => 'Seppia',
+      },
+    },
+   'MultiBurstMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'MultiControllerWhileMetering' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
    'MultiExposure' => 'Dati Esposizione Multipla',
-   'MultiExposureAutoGain' => 'Guadagno Automatico Esposizione Multipla',
-   'MultiExposureMode' => 'Modo Esposizione Multipla',
+   'MultiExposureAutoGain' => {
+      Description => 'Guadagno Automatico Esposizione Multipla',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'MultiExposureMode' => {
+      Description => 'Modo Esposizione Multipla',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'MultiExposureShots' => 'Scatti Esposizione Multipla',
    'MultiExposureVersion' => 'Versione Dati Esposizione Multipla',
@@ -1330,6 +4644,80 @@
       Description => 'Riduz. distur. su piÃ¹ fotogr.',
       PrintConv => {
-        'Off' => 'Disattivata',
+        'None' => 'Nessuno',
+        'Off' => 'Spento',
         'On' => 'Attivata',
+        'n/a' => 'n/d',
+      },
+    },
+   'MultiFunctionLock' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'MultiProfiles' => {
+      Description => 'Profili multipli',
+      PrintConv => {
+        'JBIG2 Profile M' => 'JBIG2 TIFF FX',
+        'N Layer Profile M' => 'Livello N profilo M',
+        'Profile C' => 'Profilo C',
+        'Profile F' => 'Profilo F',
+        'Profile J' => 'Profilo J',
+        'Profile L' => 'Profilo L',
+        'Profile M' => 'Profilo M',
+        'Profile S' => 'Profilo S',
+        'Profile T' => 'Profilo T',
+        'Resolution/Image Width' => 'Risoluzione/larghezza immagine',
+        'Shared Data' => 'Dati condivisi',
+      },
+    },
+   'MultiSelectorLiveView' => {
+      PrintConv => {
+        'Not Used' => 'Non usato',
+        'Reset' => 'Reimposta',
+        'Zoom On/Off' => 'Zoon sÃ¬/no',
+      },
+    },
+   'MultiSelectorPlaybackMode' => {
+      PrintConv => {
+        'Choose Folder' => 'Seleziona cartella',
+        'Thumbnail On/Off' => 'Thumbnail sÃ¬/no',
+        'Zoom On/Off' => 'Zoon sÃ¬/no',
+      },
+    },
+   'MultiSelectorShootMode' => {
+      PrintConv => {
+        'Not Used' => 'Non usato',
+      },
+    },
+   'MultipleExposureMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'MultipleExposureSet' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'MusicCDIdentifier' => 'Identificativo CD musicale',
+   'MusicianCredits' => 'Info sul musicista',
+   'Mute' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'MyColorMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'Sepia' => 'Seppia',
+        'Vivid' => 'Vivace',
+        'Vivid Blue' => 'Blu vivace',
+        'Vivid Green' => 'Verde vivace',
+      },
+    },
+   'NDFilter' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
       },
     },
@@ -1341,24 +4729,88 @@
       },
     },
+   'Name' => 'Nome',
    'NamedColor2' => 'Colore Chiamato 2',
    'NativeDisplayInfo' => 'Info Display Nativo',
+   'NeutralDensityFilter' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'NikonCaptureData' => 'Dati Nikon Capture',
    'NikonCaptureVersion' => 'Versione Nikon Capture',
+   'NoMemoryCard' => 'Scheda di memoria assente',
    'Noise' => 'Rumore',
    'NoiseFilter' => {
-      PrintConv => {
-        'Low' => 'Leggero',
-      },
-    },
+      Description => 'Filtro rumore',
+      PrintConv => {
+        'Low' => 'Basso',
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'NoiseProfile' => 'Profilo rumore',
    'NoiseReduction' => {
-      Description => 'Riduzione Rumore',
-      PrintConv => {
+      Description => 'Riduzione rumore',
+      PrintConv => {
+        'Low' => 'Basso',
+        'Low (-1)' => 'Basso (-1)',
+        'Noise Filter' => 'Filtro rumore',
+        'Noise Reduction' => 'Riduzione rumore',
         'Normal' => 'Normale',
-      },
-    },
-   'NoiseReductionApplied' => 'Riduzione Rumore Applicata',
+        'Off' => 'Spento',
+        'Strong' => 'Forte',
+        'n/a' => 'n/d',
+      },
+    },
+   'NoiseReduction2' => {
+      Description => 'Riduzione rumore 2',
+      PrintConv => {
+        'Noise Filter' => 'Filtro rumore',
+        'Noise Reduction' => 'Riduzione rumore',
+      },
+    },
+   'NoiseReductionApplied' => 'Riduzione rumore applicata',
+   'NoiseReductionIntensity' => 'IntensitÃ  riduzione rumore',
+   'NoiseReductionMethod' => {
+      Description => 'Metodo riduzione rumore',
+      PrintConv => {
+        'Faster' => 'PiÃ¹ veloce',
+      },
+    },
+   'NoiseReductionMode' => {
+      Description => 'Modo riduzione rumore',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'NoiseReductionValue' => 'Valore riduzione rumore',
+   'Notes' => 'Note',
+   'Now' => 'Adesso',
+   'NumChannels' => 'Numero canali',
+   'NumSampleFrames' => 'Numero fotogrammi campionamento',
+   'NumberOfFocusPoints' => {
+      PrintConv => {
+        '11 Points' => '11 punti',
+      },
+    },
+   'NumberofInks' => 'Numero di inchiostri',
+   'OKButton' => {
+      PrintConv => {
+        'Not Used' => 'Non usato',
+        'Off' => 'Spento',
+      },
+    },
+   'OPIProxy' => {
+      Description => 'Proxy OPI',
+      PrintConv => {
+        'Higher resolution image does not exist' => 'Immagine a risoluzione maggiore non esistente',
+        'Higher resolution image exists' => 'Immagine a risoluzione maggiore esistente',
+      },
+    },
+   'OSVersion' => 'Versione OS',
+   'Object' => 'Oggetto',
    'ObjectAttributeReference' => 'Genere intellettuale',
    'ObjectCycle' => {
-      Description => 'Ciclo Oggetto',
+      Description => 'Ciclo oggetto',
       PrintConv => {
         'Both Morning and Evening' => 'Entrambi',
@@ -1368,64 +4820,255 @@
     },
    'ObjectFileType' => {
-      PrintConv => {
+      Description => 'Tipo file oggetto',
+      PrintConv => {
+        'Core file' => 'File core',
+        'Demand paged executable' => 'Eseguibile paginato a richiesta',
+        'Dynamic link editor' => 'Editor con collegamenti dinamici',
+        'Dynamic link library' => 'Libreria a collegamento dinamico',
+        'Dynamically bound bundle' => 'Pacchetto incorporato dinamicamente',
+        'Dynamically bound shared library' => 'Libreria condivisa collegata dinamicamente',
+        'Executable application' => 'Applicazione eseguibile',
+        'Executable file' => 'File eseguibile',
+        'Fixed VM shared library' => 'Libreria fissa VM condivisa',
+        'Font' => 'Carattere',
         'None' => 'Nessuno',
-        'Unknown' => 'Sconosciuta',
+        'Preloaded executable' => 'Eseguibile precaricato',
+        'Relocatable file' => 'File rilocabile',
+        'Relocatable object' => 'Oggetto rilocabile',
+        'Shared library stub for static linking' => 'Stub libreria condivisa per il collegamenti statici',
+        'Shared object file' => 'File con oggetti condivisi',
+        'Static library' => 'Libreria statica',
+        'Unknown' => 'Sconosciuto',
       },
     },
    'ObjectName' => 'Titolo',
+   'ObjectPreviewFileFormat' => {
+      PrintConv => {
+        'Ritzaus Bureau NITF version (RBNITF DTD)' => 'Versione Ritzaus Bureau NITF (RBNITF DTD)',
+      },
+    },
    'ObjectTypeReference' => 'Riferimento Tipo Oggetto',
    'OffsetSchema' => 'Schema Offset',
-   'OldSubfileType' => 'Tipo subfile',
+   'OldSubfileType' => {
+      Description => 'Vecchio tipo sotto-file',
+      PrintConv => {
+        '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',
+      },
+    },
+   'OneTouchWB' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'OpEndPic' => 'Fine immagine',
+   'OpcodeList1' => 'Lista opcode 1',
+   'OpcodeList2' => 'Lista opcode 2',
+   'OpcodeList3' => 'Lista opcode 3',
+   'OpticalZoomMode' => {
+      PrintConv => {
+        'Extended' => 'Esteso',
+      },
+    },
+   'OpticalZoomOn' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'Opto-ElectricConvFactor' => 'Fattore di conversione optoelettrica',
    'Orientation' => {
-      Description => 'Orientamento dell\'immagine',
-      PrintConv => {
-        'Horizontal (normal)' => '0Â° (alto/sinistra)',
-        'Mirror horizontal' => 'Rifletti in orizzontale',
-        'Mirror horizontal and rotate 270 CW' => 'Rifletti in orizzontale e ruota di 270Â° in senso orario',
-        'Mirror horizontal and rotate 90 CW' => 'Rifletti in orizzontale e ruota di 90Â° in senso orario',
-        'Mirror vertical' => 'Rifletti in verticale',
-        'Rotate 180' => '180Â° (basso/destra)',
+      Description => 'Orientamento',
+      PrintConv => {
+        'Horizontal (normal)' => 'Orizzontale (normale)',
+        'Mirror horizontal' => 'Rifletti orizzontalmente',
+        'Mirror horizontal and rotate 270 CW' => 'Rifletti orizzontalmente e ruota di 270Â° in senso orario',
+        'Mirror horizontal and rotate 90 CW' => 'Rifletti orizzontalmente e ruota di 90Â° in senso orario',
+        'Mirror vertical' => 'Rifletti verticalmente',
+        'Rotate 180' => 'Ruota di 180Â°',
         'Rotate 270 CW' => 'Ruota di 270Â° in senso orario',
-        'Rotate 90 CW' => '90Â° senso antiorario (destra/alto)',
-      },
-    },
+        'Rotate 90 CW' => 'Ruota di 90Â° senso orario',
+        'Tiled' => 'Tassellato',
+      },
+    },
+   'Origin' => 'Origine',
+   'OriginCode' => 'Codice origine',
+   'OriginPlatform' => {
+      Description => 'Piattaforma origine',
+      PrintConv => {
+        'Print' => 'Stampa',
+      },
+    },
+   'OriginalAlbum' => 'Album originale',
+   'OriginalAlbumTitle' => 'Titolo album originale',
+   'OriginalArtist' => 'Artista originale',
+   'OriginalFileName' => 'Nome file originale',
+   'OriginalLyricist' => 'Paroliere originale',
+   'OriginalMedia' => {
+      PrintConv => {
+        'False' => 'Falso',
+      },
+    },
+   'OriginalRawFileData' => 'Dati file raw originale',
+   'OriginalRawFileDigest' => 'Sommario file raw originale',
+   'OriginalRawFileName' => 'Nome file raw originale',
+   'OriginalReleaseTime' => 'Ora di rilascio originale',
+   'OriginalReleaseYear' => 'Anno di rilascio originale',
    'OriginalTransmissionReference' => 'ID Lavoro',
    'OriginatingProgram' => 'Programma d\'origine',
+   'OtherCodecDescription' => 'Descrizione altro codec',
+   'OtherCodecName' => 'Nome altro codec',
+   'OtherImageLength' => 'Altra lunghezza immagine',
+   'OtherImageStart' => 'Altro inizio immagine',
    'OwnerID' => 'ID proprietario',
+   'OwnerName' => 'Nome proprietario',
    'PEFVersion' => 'Versione PEF',
-   'PageName' => 'Nome Pagina',
-   'PageNumber' => 'Numero Pagina',
+   'PEType' => 'Tipo PE',
+   'PackingMethod' => {
+      PrintConv => {
+        'Fast' => 'Veloce',
+        'Fastest' => 'Massimamente veloce',
+        'Normal' => 'Normale',
+      },
+    },
+   'PageName' => 'Nome pagina',
+   'PageNumber' => 'Numero pagina',
+   'PanOrientation' => {
+      PrintConv => {
+        '[unused]' => '[non usato]',
+      },
+    },
+   'PanasonicRawVersion' => 'Versione raw Panasonic',
+   'PanasonicTitle' => 'Titolo Panasonic',
+   'PanasonicTitle2' => 'Titolo Panasonic 2',
+   'PanoramaSize3D' => {
+      Description => 'Dimensione panomara 3D',
+      PrintConv => {
+        'Wide' => 'Ampio',
+        'n/a' => 'n/d',
+      },
+    },
+   'PartOfSet' => 'Parte del gruppo',
+   'PaymentURL' => 'URL pagamento',
+   'PeakValue' => 'Valore di picco',
+   'PerformerSortOrder' => 'Ordinamento interprete',
+   'PeripheralLighting' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'PeripheralLightingSetting' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'PhaseDetectAF' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'PhotoEffect' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'Sepia' => 'Seppia',
+        'Vivid' => 'Vivace',
+      },
+    },
+   'PhotoEffects' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'PhotoEffectsType' => {
       PrintConv => {
         'None' => 'Nessuno',
+        'Sepia' => 'Seppia',
+        'Tinted' => 'Tinteggiato',
+      },
+    },
+   'PhotoInfoPlayback' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
    'PhotometricInterpretation' => {
-      Description => 'Composizione del pixel',
+      Description => 'Interpretazione fotometrica',
       PrintConv => {
         'BlackIsZero' => 'Nero Ãš zero',
+        'Color Filter Array' => 'Array filtro colore',
+        'Linear Raw' => 'Raw lineare',
+        'Pixar LogL' => 'Pixar LogLuv',
+        'Pixar LogLuv' => 'Pixar LogL',
+        'RGB Palette' => 'Tavolozza RGB',
+        'Transparency Mask' => 'Maschera trasparenza',
         'WhiteIsZero' => 'Bianco Ãš zero',
       },
     },
+   'PhotoshopFormat' => {
+      PrintConv => {
+        'Progressive' => 'Progressivo',
+      },
+    },
+   'Picture' => 'Immagine',
+   'PictureControl' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'PictureControlActive' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'PictureControlAdjust' => {
       PrintConv => {
         'Default Settings' => 'Impostazioni Predefinite',
-        'Full Control' => 'Controllo Totale',
-        'Quick Adjust' => 'Regolazione Rapida',
+        'Full Control' => 'Controllo completo',
+        'Quick Adjust' => 'Regolazione rapida',
+      },
+    },
+   'PictureDescription' => 'Descrizione immagine',
+   'PictureEffect' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'Posterization' => 'Posterizzazione',
+        'Posterization B/W' => 'Posterizzazione B&N',
+        'Retro Photo' => 'Foto retrÃ²',
       },
     },
    'PictureFinish' => {
       PrintConv => {
+        'Evening Scene' => 'Scena serale',
         'Portrait' => 'Verticale',
       },
     },
+   'PictureFormat' => 'Formato immagine',
+   'PictureMIMEType' => 'MIME type immagine',
    'PictureMode' => {
       PrintConv => {
+        '1/2 EV steps' => 'Step 1/2 EV',
+        '1/3 EV steps' => 'Step 1/3 EV',
         'Aperture-priority AE' => 'PrioritÃ  diaframma',
+        'Fireworks' => 'Fuochi artificiali',
+        'Fisheye' => 'Fish-eye',
+        'Flower' => 'Fiore',
+        'Forest' => 'Foresta',
+        'Green' => 'Verde',
+        'Kids' => 'Bambini',
         'Landscape' => 'Orizzontale',
         'Manual' => 'Manuale',
+        'No Flash' => 'No flash',
         'Portrait' => 'Verticale',
-        'Shutter speed priority AE' => 'PrioritÃ  otturatore',
+        'Program' => 'Programma',
+        'Program (HyP)' => 'Programma (HyP)',
+        'Program AE' => 'Programma AE',
+        'Purple' => 'Porpora',
+        'Quick Macro' => 'Macro veloce',
+        'Red' => 'Rosso',
+        'Sepia' => 'Seppia',
+        'Shutter speed priority AE' => 'PrioritÃ  otturatore AE',
+        'Sunset' => 'Tramonto',
+        'Text' => 'Testo',
+        'Vivid' => 'Vivace',
       },
     },
@@ -1434,4 +5077,6 @@
         'Aperture Priority' => 'PrioritÃ  diaframma',
         'Manual' => 'Manuale',
+        'Program AE' => 'Programma AE',
+        'Scene Mode' => 'Modo scena',
         'Shutter Speed Priority' => 'PrioritÃ  otturatore',
       },
@@ -1443,4 +5088,11 @@
         'Red' => 'Rosso',
         'Yellow' => 'Giallo',
+        'n/a' => 'n/d',
+      },
+    },
+   'PictureModeEffect' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'n/a' => 'n/d',
       },
     },
@@ -1448,4 +5100,7 @@
       PrintConv => {
         'Green' => 'Verde',
+        'Purple' => 'Porpora',
+        'Sepia' => 'Seppia',
+        'n/a' => 'n/d',
       },
     },
@@ -1457,64 +5112,238 @@
       },
     },
-   'PixelFormat' => 'Formato-Pixel',
+   'PictureType' => {
+      Description => 'Tipo immagine',
+      PrintConv => {
+        '32x32 PNG Icon' => 'Icona PNG 32x32',
+        'Artist' => 'Artista',
+        'Back Cover' => 'Retrocopertina',
+        'Band Logo' => 'Logo band',
+        'Bright(ly) Colored Fish' => 'Pesci dai vivaci colori',
+        'Capture from Movie or Video' => 'Acquisizione da film o video',
+        'Composer' => 'Compositore',
+        'Conductor' => 'Direttore d\'orchestra',
+        'Front Cover' => 'Copertina',
+        'Illustration' => 'Illustrazione',
+        'Lead Artist' => 'Artista principale',
+        'Leaflet' => 'Volantino',
+        'Lyricist' => 'Paroliere',
+        'Other' => 'Altro',
+        'Other Icon' => 'Altra icona',
+        'Performance' => 'Interpretazione',
+        'Publisher Logo' => 'Logo editore',
+        'Recording Session' => 'Sessione registrazione',
+        'Recording Studio or Location' => 'Studio/luogo registrazione',
+      },
+    },
+   'PictureWizardMode' => {
+      PrintConv => {
+        'Forest' => 'Foresta',
+        'Landscape' => 'Orizzontale',
+        'Retro' => 'RetrÃ²',
+        'Vivid' => 'Vivace',
+        'n/a' => 'n/d',
+      },
+    },
+   'PixelFormat' => {
+      Description => 'Formato pixel',
+      PrintConv => {
+        '112-bit 6 Channels Alpha' => '112-bit 6 canali trasparenza',
+        '112-bit 7 Channels' => '112-bit 7 canali',
+        '128-bit 7 Channels Alpha' => '128-bit 7 canali trasparenza',
+        '128-bit 8 Channels' => '128-bit 8 canali',
+        '128-bit PRGBA Float' => '128-bit PRGBA virgola mobile',
+        '128-bit RGB Float' => '128-bit RGB virgola mobile',
+        '128-bit RGBA Fixed Point' => '128-bit RGBA virgola fissa',
+        '128-bit RGBA Float' => '128-bit RGBA virgola mobile',
+        '144-bit 8 Channels Alpha' => '144-bit 8 canali trasparenza',
+        '16-bit Gray' => '16-bit grigio',
+        '16-bit Gray Half' => '16-bit grigio metÃ ',
+        '24-bit 3 Channels' => '24-bit 3 canali',
+        '32-bit 3 Channels Alpha' => '32-bit 3 canali trasparenza',
+        '32-bit 4 Channels' => '32-bit 4 canali',
+        '32-bit Gray Fixed Point' => '32-bit punto grigio virgola fissa',
+        '32-bit Gray Float' => '32-bit punto grigio virgola mobile',
+        '40-bit 4 Channels Alpha' => '40-bit 4 canali trasparenza',
+        '40-bit 5 Channels' => '40-bit 5 canali',
+        '40-bit CMYK Alpha' => '40-bit CMYK trasparenza',
+        '48-bit 3 Channels' => '48-bit 3 canali',
+        '48-bit 5 Channels Alpha' => '48-bit 5 canali trasparenza',
+        '48-bit 6 Channels' => '48-bit 6 canali',
+        '48-bit RGB Fixed Point' => '48-bit RGB virgola fissa',
+        '48-bit RGB Half' => '48-bit RGB metÃ ',
+        '56-bit 6 Channels Alpha' => '56-bit 6 canali trasparenza',
+        '56-bit 7 Channels' => '56-bit 7 canali',
+        '64-bit 3 Channels Alpha' => '64-bit 3 canali trasparenza',
+        '64-bit 4 Channels' => '64-bit 4 canali',
+        '64-bit 7 Channels Alpha' => '64-bit 7 canali trasparenza',
+        '64-bit 8 Channels' => '64-bit 8 canali',
+        '64-bit RGBA Fixed Point' => '64-bit RGBA virgola fissa',
+        '64-bit RGBA Half' => '64-bit RGBA mezzi toni',
+        '72-bit 8 Channels Alpha' => '72-bit 8 canali trasparenza',
+        '8-bit Gray' => '8-bit grigio',
+        '80-bit 4 Channels Alpha' => '80-bit 4 canali trasparenza',
+        '80-bit 5 Channels' => '80-bit 5 canali',
+        '80-bit CMYK Alpha' => '80-bit CMYK trasparenza',
+        '96-bit 5 Channels Alpha' => '96-bit 5 canali trasparenza',
+        '96-bit 6 Channels' => '96-bit 6 canali',
+        '96-bit RGB Fixed Point' => '96-bit RGB virgola fissa',
+        'Black & White' => 'Bianco e nero',
+      },
+    },
+   'PixelIntensityRange' => 'Intervallo intensitÃ  pixel',
+   'PixelMagicJBIGOptions' => 'Opzioni Pixel Magic JBIG',
+   'PixelScale' => 'Scala pixel',
    'PixelUnits' => {
       PrintConv => {
-        'Unknown' => 'Sconosciuta',
+        'Unknown' => 'Sconosciuto',
       },
     },
    'PlanarConfiguration' => {
-      Description => 'Regolazione Dati Immagine',
-      PrintConv => {
-        'Chunky' => 'Formato spezzettato',
-        'Planar' => 'Formato planare',
-      },
-    },
+      Description => 'Configurazione planare',
+      PrintConv => {
+        'Chunky' => 'Spezzettato',
+        'Planar' => 'Planare',
+      },
+    },
+   'PlayCounter' => 'Conteggio esecuzioni',
+   'PlayGap' => {
+      PrintConv => {
+        'No Gap' => 'Nessun salto',
+      },
+    },
+   'PlaylistDelay' => 'Attesa playlist',
+   'PortraitRefiner' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Position' => 'Posizione',
+   'PostScriptFontName' => 'Nome carattere PostScript',
+   'PostprocessingFunction' => 'Funzione post-processamento',
+   'PowerSource' => 'Fonte alimentazione',
+   'PowerUpTime' => 'Ora accensione',
+   'Predictor' => {
+      Description => 'Predittore',
+      PrintConv => {
+        'Horizontal differencing' => 'Differenziazione orizzontale',
+        'None' => 'Nessuno',
+      },
+    },
+   'PredictorColumns' => 'Colonne predittore',
+   'PredictorConstants' => 'Costanti predittore',
+   'PredictorRows' => 'Righe predittore',
+   'PreferredFamily' => 'Famiglia preferita',
+   'PreferredSubfamily' => 'Sotto-famiglia preferita',
+   'PreferredVolume' => 'Volume preferito',
+   'Prefs' => 'Preferenze',
+   'PresetWhiteBalance' => {
+      PrintConv => {
+        'Camera Setting' => 'Impostazioni fotocamera',
+        'Fluorescent' => 'Fluorescente',
+        'Shade' => 'Ombrato',
+      },
+    },
+   'PrevFileName' => 'Nome file precedente',
+   'PrevSize' => 'Dimensione precedente',
+   'PrevUID' => 'UID precedente',
+   'Preview' => 'Anteprima',
    'Preview0' => 'Anteprima 0 ',
    'Preview1' => 'Anteprima 1 ',
    'Preview2' => 'Anteprima 2',
-   'PreviewApplicationName' => 'Anteprima Nome Applicazione',
-   'PreviewApplicationVersion' => 'Anteprima Versione Applicazione',
+   'PreviewApplicationName' => 'Nome applicazione anteprima ',
+   'PreviewApplicationVersion' => 'Versione applicazione anteprima ',
+   'PreviewButton' => {
+      Description => 'Pulsante anteprima',
+      PrintConv => {
+        'Flash Off' => 'Flash spento',
+        'None' => 'Nessuno',
+        'Preview' => 'Anteprima',
+        'Virtual Horizon' => 'Orizzonte virtuale',
+      },
+    },
+   'PreviewButtonPlusDials' => {
+      PrintConv => {
+        'Choose Image Area' => 'Seleziona area immagine',
+        'None' => 'Nessuno',
+      },
+    },
    'PreviewColorSpace' => {
-      Description => 'Anteprima Spazio Colore',
-      PrintConv => {
-        'Unknown' => 'Sconosciuta',
-      },
-    },
-   'PreviewDateTime' => 'Anteprima Data Ora',
+      Description => 'Spazio colore anteprima',
+      PrintConv => {
+        'Gray Gamma 2.2' => 'Gamma grigio 2.2',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'PreviewDate' => 'Data anteprima',
+   'PreviewDateTime' => 'Data ora anteprima',
+   'PreviewDuration' => 'Durata anteprima',
    'PreviewIFD' => 'Anteprima Puntatore IFD',
-   'PreviewImage' => 'Anteprima',
+   'PreviewImage' => 'Immagine anteprima',
+   'PreviewImageBorders' => 'Bordi immagine anteprima',
+   'PreviewImageData' => 'Altezza immagine anteprima',
+   'PreviewImageHeight' => 'Altezza immagine anteprima',
+   'PreviewImageLength' => 'Lunghezza immagine anteprima',
+   'PreviewImageName' => 'Nome immagine anteprima',
+   'PreviewImageSize' => 'Dimensioni immagine anteprima',
+   'PreviewImageStart' => 'Inizio immagine anteprima',
+   'PreviewImageType' => 'Tipo immagine anteprima',
    'PreviewImageValid' => {
-      PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
+      Description => 'Immagine anteprima valida',
+      PrintConv => {
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'PreviewImageWidth' => 'Larghezza immagine anteprima',
+   'PreviewInfo' => 'Info anteprima',
    'PreviewQuality' => {
+      Description => 'QualtiÃ  anteprima',
       PrintConv => {
         'Normal' => 'Normale',
       },
     },
-   'PreviewSettingsName' => 'Anteprima Nome Impostazioni',
+   'PreviewSettingsDigest' => 'Sommario impostazioni anteprima',
+   'PreviewSettingsName' => 'Nome impostazioni anteprima',
    'PrimaryAFPoint' => {
       PrintConv => {
+        '(none)' => '(nessuno)',
         'Bottom' => 'Basso',
         'C6 (Center)' => 'C6 (Centro)',
         'Center' => 'Centro',
-        'Far Left' => 'Tutto a Sinistra',
-        'Far Right' => 'Tutto a Destra',
-        'Lower-left' => 'Inferiore Sinistro',
-        'Lower-right' => 'Inferiore Destro',
-        'Mid-left' => 'Sinistra',
-        'Mid-right' => 'Destra',
+        'Far Left' => 'Tutto a sinistra',
+        'Far Right' => 'Tutto a destra',
+        'Lower-left' => 'Inferiore sinistro',
+        'Lower-right' => 'Inferiore destro',
+        'Mid-left' => 'Centro/sinistra',
+        'Mid-right' => 'Centro/destra',
         'Top' => 'Alto',
-        'Upper-left' => 'Superiore Sinistro',
-        'Upper-right' => 'Superiore Destro',
+        'Upper-left' => 'Superiore sinistro',
+        'Upper-right' => 'Superiore destro',
       },
     },
    'PrimaryChromaticities' => 'Cromatismo dei colori primari',
    'PrimaryPlatform' => 'Piattaforma primaria',
-   'ProductID' => 'ID Prodotto',
-   'ProfileCMMType' => 'Tipo Profilo CMM',
+   'PrintIM' => 'Stampa Image Matching',
+   'PrintIMVersion' => 'Versione PrintIM',
+   'PrintPriority' => 'PrioritÃ  stampa',
+   'PrintQuality' => 'QualitÃ  stampa',
+   'PrintScale' => 'Scala stampa',
+   'PrinterName' => 'Nome stampante',
+   'Priority' => 'PrioritÃ ',
+   'PrivateBuild' => 'Compilazione privata',
+   'ProcessingSoftware' => 'Software di elaborazione',
+   'ProducedNotice' => 'Note prodotte',
+   'Product' => 'Prodotto',
+   'ProductDescription' => 'Descrizione prodotto',
+   'ProductID' => 'ID prodotto',
+   'ProductName' => 'Nome prodotto',
+   'ProductVersion' => 'Versione prodotto',
+   'ProductVersionNumber' => 'Numero di versione prodotto',
+   'Profession' => 'Professione',
+   'Profile' => 'Profilo',
+   'ProfileAndLevel' => 'Profilo e livello',
+   'ProfileCMMType' => 'Tipo profilo CMM',
+   'ProfileCalibrationSig' => 'Segn calibrazione profilo',
    'ProfileClass' => {
-      Description => 'Classe Profilo',
+      Description => 'Classe profilo',
       PrintConv => {
         'Abstract Profile' => 'Profilo Astratto',
@@ -1528,21 +5357,42 @@
       },
     },
-   'ProfileConnectionSpace' => 'Profilo Spazio Connessione',
-   'ProfileCopyright' => 'Copyright del Profilo',
-   'ProfileCreator' => 'Autore Profilo',
-   'ProfileDateTime' => 'Data Ora Profilo',
+   'ProfileConnectionSpace' => 'Spazio connessione profilo',
+   'ProfileCopyright' => 'Copyright profilo',
+   'ProfileCreator' => 'Autore profilo',
+   'ProfileDateTime' => 'Data/ora profilo',
    'ProfileDescription' => 'Descrizione del Profilo',
    'ProfileDescriptionML' => 'Descrizione profilo multilinguaggio.',
    'ProfileEmbedPolicy' => {
+      Description => 'Politica incorporamento profilo',
       PrintConv => {
         'Allow Copying' => 'Permetti la copia',
+        'Embed if Used' => 'Incorpora se usato',
+        'Never Embed' => 'Non incorporare mai',
         'No Restrictions' => 'Nessuna restrizione',
       },
     },
-   'ProfileFileSignature' => 'Firma File Profilo',
-   'ProfileID' => 'ID Profilo',
-   'ProfileName' => 'Nome Profilo',
+   'ProfileFileSignature' => 'Firma file profilo',
+   'ProfileID' => {
+      Description => 'ID profilo',
+      PrintConv => {
+        'Not Specified' => 'Non specificato',
+      },
+    },
+   'ProfileName' => 'Nome profilo',
    'ProfileSequenceDesc' => 'Descrizione della Sequenza del Profilo',
-   'ProfileVersion' => 'Versione Profilo',
+   'ProfileType' => {
+      Description => 'Tipo profilo',
+      PrintConv => {
+        'Unspecified' => 'Non specificato',
+      },
+    },
+   'ProfileVersion' => 'Versione profilo',
+   'ProgID' => 'ID programma',
+   'ProgramISO' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ProgramKind' => 'Tipo di programma',
    'ProgramLine' => {
       PrintConv => {
@@ -1551,34 +5401,798 @@
     },
    'ProgramMode' => {
+      Description => 'Modo programma',
       PrintConv => {
         'None' => 'Nessuno',
         'Portrait' => 'Verticale',
-      },
-    },
-   'ProgramVersion' => 'Versione Programma',
+        'Sunset' => 'Tramonto',
+        'Text' => 'Testo',
+      },
+    },
+   'ProgramName' => 'Nome programma',
+   'ProgramNumber' => 'Numero programma',
+   'ProgramVersion' => 'Versione programma',
+   'ProgrammingGroupKind' => 'Tipo gruppo programmazione',
+   'ProgrammingGroupTitle' => 'Titolo gruppo programmazione',
+   'ProgressiveScans' => 'Scansioni progressive',
+   'Project' => 'Progetto',
+   'ProjectName' => 'Nome progetto',
+   'ProjectNumber' => 'Numero progetto',
+   'ProjectRef' => 'Rif progetto',
+   'ProjectSet' => 'Set progetto',
+   'ProjectedCSType' => {
+      Description => 'Tipo CS proiettato',
+      PrintConv => {
+        'ETRS89 Poland CS2000 zone 5' => 'ETRS89 Poland CS2000 zona 5',
+        'ETRS89 Poland CS2000 zone 7' => 'ETRS89 Poland CS2000 zona 7',
+        'ETRS89 Poland CS2000 zone 8' => 'ETRS89 Poland CS2000 zona 8',
+        'PSAD56 UTM zone 17S' => 'PSAD56 UTM zona 17S',
+        'PSAD56 UTM zone 18N' => 'PSAD56 UTM zona 18N',
+        'PSAD56 UTM zone 18S' => 'PSAD56 UTM zona 18S',
+        'PSAD56 UTM zone 19N' => 'PSAD56 UTM zona 19N',
+        'PSAD56 UTM zone 19S' => 'PSAD56 UTM zona 19S',
+        'PSAD56 UTM zone 20N' => 'PSAD56 UTM zona 20N',
+        'PSAD56 UTM zone 20S' => 'PSAD56 UTM zona 20S',
+        'PSAD56 UTM zone 21N' => 'PSAD56 UTM zona 21N',
+        'Pulkovo Gauss zone 10' => 'Pulkovo Gauss zona 10',
+        'Pulkovo Gauss zone 11' => 'Pulkovo Gauss zona 11',
+        'Pulkovo Gauss zone 12' => 'Pulkovo Gauss zona 12',
+        'Pulkovo Gauss zone 13' => 'Pulkovo Gauss zona 13',
+        'Pulkovo Gauss zone 14' => 'Pulkovo Gauss zona 14',
+        'Pulkovo Gauss zone 15' => 'Pulkovo Gauss zona 15',
+        'Pulkovo Gauss zone 16' => 'Pulkovo Gauss zona 16',
+        'Pulkovo Gauss zone 17' => 'Pulkovo Gauss zona 17',
+        'Pulkovo Gauss zone 18' => 'Pulkovo Gauss zona 18',
+        'Pulkovo Gauss zone 19' => 'Pulkovo Gauss zona 19',
+        'Pulkovo Gauss zone 20' => 'Pulkovo Gauss zona 20',
+        'Pulkovo Gauss zone 21' => 'Pulkovo Gauss zona 21',
+        'Pulkovo Gauss zone 22' => 'Pulkovo Gauss zona 22',
+        'Pulkovo Gauss zone 23' => 'Pulkovo Gauss zona 23',
+        'Pulkovo Gauss zone 24' => 'Pulkovo Gauss zona 24',
+        'Pulkovo Gauss zone 25' => 'Pulkovo Gauss zona 25',
+        'Pulkovo Gauss zone 26' => 'Pulkovo Gauss zona 26',
+        'Pulkovo Gauss zone 27' => 'Pulkovo Gauss zona 27',
+        'Pulkovo Gauss zone 28' => 'Pulkovo Gauss zona 28',
+        'Pulkovo Gauss zone 29' => 'Pulkovo Gauss zona 29',
+        'Pulkovo Gauss zone 30' => 'Pulkovo Gauss zona 30',
+        'Pulkovo Gauss zone 31' => 'Pulkovo Gauss zona 31',
+        'Pulkovo Gauss zone 32' => 'Pulkovo Gauss zona 32',
+        'Pulkovo Gauss zone 4' => 'Pulkovo Gauss zona 4',
+        'Pulkovo Gauss zone 5' => 'Pulkovo Gauss zona 5',
+        'Pulkovo Gauss zone 6' => 'Pulkovo Gauss zona 6',
+        'Pulkovo Gauss zone 7' => 'Pulkovo Gauss zona 7',
+        'Pulkovo Gauss zone 8' => 'Pulkovo Gauss zona 8',
+        'Pulkovo Gauss zone 9' => 'Pulkovo Gauss zona 9',
+        'Sudan UTM zone 35N' => 'Sudan UTM zona 35N',
+        'Sudan UTM zone 36N' => 'Sudan UTM zona 36N',
+      },
+    },
+   'Projection' => 'Proiezione',
+   'ProjectionAlgorithm' => 'Algoritmo proiezione',
+   'ProjectionAngle' => 'Angolo proiezione',
+   'Projects' => 'Progetti',
+   'Properties' => 'ProprietÃ ',
+   'PropertyReleaseStatus' => {
+      PrintConv => {
+        'None' => 'Nessuno',
+        'Not Applicable' => 'Non applicabile',
+      },
+    },
+   'Protect' => 'Proteggi',
+   'Protected' => 'Protetto',
+   'ProtocolName' => 'Nome protocollo',
    'Province-State' => 'Provincia/Stato',
+   'PublicationDate' => 'Data pubblicazione',
+   'PublicationName' => 'Nome pubblicazione',
+   'PublicationSets' => 'Set pupplicazione',
+   'Publisher' => 'Editore',
+   'PublisherURL' => 'URL editore',
+   'PurchaseDate' => 'Data acquisto',
+   'PurchaserAccountName' => 'Nome account acquirente',
+   'PurchaserAccountNumber' => 'Numero account acquirente',
+   'PurchaserIdentificationKind' => 'Tipo identificazione acquirente',
+   'PurchaserIdentificationValue' => 'Valore identificazione acquirente',
+   'PurchasingDepartment' => 'Reparto acquirente',
+   'PurchasingOrganizationName' => 'Nome organizzazione acquirente',
+   'Purpose' => 'Scopo',
+   'PurposeOfReferenceCodeSequence' => 'Scopo sequenza codici riferimento',
+   'PyramidLevels' => 'Livelli piramite',
    'Quality' => {
       Description => 'QualitÃ ',
       PrintConv => {
-        'Compressed RAW' => 'cRAW',
-        'Compressed RAW + JPEG' => 'cRAW+JPEG',
+        'Compressed RAW' => 'RAW compresso',
+        'Compressed RAW + JPEG' => 'RAW+JPEG compresso',
         'Extra Fine' => 'Extra fine',
-        'Low' => 'Leggero',
+        'Low' => 'Basso',
         'Normal' => 'Normale',
         'RAW + JPEG' => 'RAW+JPEG',
-      },
-    },
+        'n/a' => 'n/d',
+      },
+    },
+   'QualityControlImage' => 'Immagine controllo qualitÃ ',
+   'QualityFlag' => 'Indicatore qualitÃ ',
    'QualityMode' => {
+      Description => 'Modo qualitÃ ',
       PrintConv => {
         'Normal' => 'Normale',
       },
     },
+   'Quantity' => 'QuantitÃ ',
+   'QuantitySequence' => 'Sequenza quantitÃ ',
+   'QuantizationDefault' => 'Default quantizzazione',
+   'QuantizationMethod' => 'Metodo quantizzazione',
+   'QueueStatus' => 'Stato coda',
+   'QuickAdjust' => 'Regolazione rapida',
+   'QuickControlDialInMeter' => {
+      PrintConv => {
+        'ISO speed' => 'VelocitÃ  ISO',
+      },
+    },
+   'QuickEdit' => 'Modifica velote',
+   'QuickMaskInfo' => 'Info maschera veloce',
+   'QuickShot' => {
+      Description => 'Scatto veloce',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'R2ABlueCtbl00' => 'R2 A blu Stbl 30',
+   'R2ABlueCtbl01' => 'R2 A blu Stbl 29',
+   'R2ABlueCtbl02' => 'R2 A blu Stbl 28',
+   'R2ABlueCtbl03' => 'R2 A blu Stbl 27',
+   'R2ABlueCtbl04' => 'R2 A blu Stbl 26',
+   'R2ABlueCtbl05' => 'R2 A blu Stbl 25',
+   'R2ABlueCtbl06' => 'R2 A blu Stbl 24',
+   'R2ABlueCtbl07' => 'R2 A blu Stbl 23',
+   'R2ABlueCtbl08' => 'R2 A blu Stbl 22',
+   'R2ABlueCtbl09' => 'R2 A blu Stbl 21',
+   'R2ABlueCtbl10' => 'R2 A blu Stbl 20',
+   'R2ABlueCtbl11' => 'R2 A blu Stbl 19',
+   'R2ABlueCtbl12' => 'R2 A blu Stbl 18',
+   'R2ABlueCtbl13' => 'R2 A blu Stbl 17',
+   'R2ABlueCtbl14' => 'R2 A blu Stbl 16',
+   'R2ABlueCtbl15' => 'R2 A blu Stbl 15',
+   'R2ABlueCtbl16' => 'R2 A blu Stbl 14',
+   'R2ABlueCtbl17' => 'R2 A blu Stbl 13',
+   'R2ABlueCtbl18' => 'R2 A blu Stbl 12',
+   'R2ABlueCtbl19' => 'R2 A blu Stbl 11',
+   'R2ABlueCtbl20' => 'R2 A blu Stbl 10',
+   'R2ABlueCtbl21' => 'R2 A blu Stbl 09',
+   'R2ABlueCtbl22' => 'R2 A blu Stbl 08',
+   'R2ABlueCtbl23' => 'R2 A blu Stbl 07',
+   'R2ABlueCtbl24' => 'R2 A blu Stbl 06',
+   'R2ABlueCtbl25' => 'R2 A blu Stbl 05',
+   'R2ABlueCtbl26' => 'R2 A blu Stbl 04',
+   'R2ABlueCtbl27' => 'R2 A blu Stbl 03',
+   'R2ABlueCtbl28' => 'R2 A blu Stbl 02',
+   'R2ABlueCtbl29' => 'R2 A blu Stbl 01',
+   'R2ABlueCtbl30' => 'R2 A blu Stbl 00',
+   'R2ABlueCtbl31' => 'R2 A blu Ctbl 31',
+   'R2ABlueStbl00' => 'R2 A blu Ctbl 30',
+   'R2ABlueStbl01' => 'R2 A blu Ctbl 29',
+   'R2ABlueStbl02' => 'R2 A blu Ctbl 28',
+   'R2ABlueStbl03' => 'R2 A blu Ctbl 27',
+   'R2ABlueStbl04' => 'R2 A blu Ctbl 26',
+   'R2ABlueStbl05' => 'R2 A blu Ctbl 25',
+   'R2ABlueStbl06' => 'R2 A blu Ctbl 24',
+   'R2ABlueStbl07' => 'R2 A blu Ctbl 23',
+   'R2ABlueStbl08' => 'R2 A blu Ctbl 22',
+   'R2ABlueStbl09' => 'R2 A blu Ctbl 21',
+   'R2ABlueStbl10' => 'R2 A blu Ctbl 20',
+   'R2ABlueStbl11' => 'R2 A blu Ctbl 19',
+   'R2ABlueStbl12' => 'R2 A blu Ctbl 18',
+   'R2ABlueStbl13' => 'R2 A blu Ctbl 17',
+   'R2ABlueStbl14' => 'R2 A blu Ctbl 16',
+   'R2ABlueStbl15' => 'R2 A blu Ctbl 15',
+   'R2ABlueStbl16' => 'R2 A blu Ctbl 14',
+   'R2ABlueStbl17' => 'R2 A blu Ctbl 13',
+   'R2ABlueStbl18' => 'R2 A blu Ctbl 12',
+   'R2ABlueStbl19' => 'R2 A blu Ctbl 11',
+   'R2ABlueStbl20' => 'R2 A blu Ctbl 10',
+   'R2ABlueStbl21' => 'R2 A blu Ctbl 09',
+   'R2ABlueStbl22' => 'R2 A blu Ctbl 08',
+   'R2ABlueStbl23' => 'R2 A blu Ctbl 07',
+   'R2ABlueStbl24' => 'R2 A blu Ctbl 06',
+   'R2ABlueStbl25' => 'R2 A blu Ctbl 05',
+   'R2ABlueStbl26' => 'R2 A blu Ctbl 04',
+   'R2ABlueStbl27' => 'R2 A blu Ctbl 03',
+   'R2ABlueStbl28' => 'R2 A blu Ctbl 02',
+   'R2ABlueStbl29' => 'R2 A blu Ctbl 01',
+   'R2ABlueStbl30' => 'R2 A blu Ctbl 00',
+   'R2ABlueStbl31' => 'R2 A blu Stbl 31',
+   'R2AGreenCtbl00' => 'R2 A verde Ctbl 00',
+   'R2AGreenCtbl01' => 'R2 A verde Ctbl 01',
+   'R2AGreenCtbl02' => 'R2 A verde Ctbl 02',
+   'R2AGreenCtbl03' => 'R2 A verde Ctbl 03',
+   'R2AGreenCtbl04' => 'R2 A verde Ctbl 04',
+   'R2AGreenCtbl05' => 'R2 A verde Ctbl 05',
+   'R2AGreenCtbl06' => 'R2 A verde Ctbl 06',
+   'R2AGreenCtbl07' => 'R2 A verde Ctbl 07',
+   'R2AGreenCtbl08' => 'R2 A verde Ctbl 08',
+   'R2AGreenCtbl09' => 'R2 A verde Ctbl 09',
+   'R2AGreenCtbl10' => 'R2 A verde Ctbl 10',
+   'R2AGreenCtbl11' => 'R2 A verde Ctbl 11',
+   'R2AGreenCtbl12' => 'R2 A verde Ctbl 12',
+   'R2AGreenCtbl13' => 'R2 A verde Ctbl 13',
+   'R2AGreenCtbl14' => 'R2 A verde Ctbl 14',
+   'R2AGreenCtbl15' => 'R2 A verde Ctbl 15',
+   'R2AGreenCtbl16' => 'R2 A verde Ctbl 16',
+   'R2AGreenCtbl17' => 'R2 A verde Ctbl 17',
+   'R2AGreenCtbl18' => 'R2 A verde Ctbl 18',
+   'R2AGreenCtbl19' => 'R2 A verde Ctbl 19',
+   'R2AGreenCtbl20' => 'R2 A verde Ctbl 20',
+   'R2AGreenCtbl21' => 'R2 A verde Ctbl 21',
+   'R2AGreenCtbl22' => 'R2 A verde Ctbl 22',
+   'R2AGreenCtbl23' => 'R2 A verde Ctbl 23',
+   'R2AGreenCtbl24' => 'R2 A verde Ctbl 24',
+   'R2AGreenCtbl25' => 'R2 A verde Ctbl 25',
+   'R2AGreenCtbl26' => 'R2 A verde Ctbl 26',
+   'R2AGreenCtbl27' => 'R2 A verde Ctbl 27',
+   'R2AGreenCtbl28' => 'R2 A verde Ctbl 28',
+   'R2AGreenCtbl29' => 'R2 A verde Ctbl 29',
+   'R2AGreenCtbl30' => 'R2 A verde Ctbl 30',
+   'R2AGreenCtbl31' => 'R2 A verde Ctbl 31',
+   'R2AGreenStbl00' => 'R2 A verde Stbl 00',
+   'R2AGreenStbl01' => 'R2 A verde Stbl 01',
+   'R2AGreenStbl02' => 'R2 A verde Stbl 02',
+   'R2AGreenStbl03' => 'R2 A verde Stbl 03',
+   'R2AGreenStbl04' => 'R2 A verde Stbl 04',
+   'R2AGreenStbl05' => 'R2 A verde Stbl 05',
+   'R2AGreenStbl06' => 'R2 A verde Stbl 06',
+   'R2AGreenStbl07' => 'R2 A verde Stbl 07',
+   'R2AGreenStbl08' => 'R2 A verde Stbl 08',
+   'R2AGreenStbl09' => 'R2 A verde Stbl 09',
+   'R2AGreenStbl10' => 'R2 A verde Stbl 10',
+   'R2AGreenStbl11' => 'R2 A verde Stbl 11',
+   'R2AGreenStbl12' => 'R2 A verde Stbl 12',
+   'R2AGreenStbl13' => 'R2 A verde Stbl 13',
+   'R2AGreenStbl14' => 'R2 A verde Stbl 14',
+   'R2AGreenStbl15' => 'R2 A verde Stbl 15',
+   'R2AGreenStbl16' => 'R2 A verde Stbl 16',
+   'R2AGreenStbl17' => 'R2 A verde Stbl 17',
+   'R2AGreenStbl18' => 'R2 A verde Stbl 18',
+   'R2AGreenStbl19' => 'R2 A verde Stbl 19',
+   'R2AGreenStbl20' => 'R2 A verde Stbl 20',
+   'R2AGreenStbl21' => 'R2 A verde Stbl 21',
+   'R2AGreenStbl22' => 'R2 A verde Stbl 22',
+   'R2AGreenStbl23' => 'R2 A verde Stbl 23',
+   'R2AGreenStbl24' => 'R2 A verde Stbl 24',
+   'R2AGreenStbl25' => 'R2 A verde Stbl 25',
+   'R2AGreenStbl26' => 'R2 A verde Stbl 26',
+   'R2AGreenStbl27' => 'R2 A verde Stbl 27',
+   'R2AGreenStbl28' => 'R2 A verde Stbl 28',
+   'R2AGreenStbl29' => 'R2 A verde Stbl 29',
+   'R2AGreenStbl30' => 'R2 A verde Stbl 30',
+   'R2AGreenStbl31' => 'R2 A verde Stbl 31',
+   'R2AHeight' => 'R2 A altezza',
+   'R2AIntervals' => 'R2 A intervalli',
+   'R2ARedCtbl00' => 'R2 A rosso Ctbl 00',
+   'R2ARedCtbl01' => 'R2 A rosso Ctbl 01',
+   'R2ARedCtbl02' => 'R2 A rosso Ctbl 02',
+   'R2ARedCtbl03' => 'R2 A rosso Ctbl 03',
+   'R2ARedCtbl04' => 'R2 A rosso Ctbl 04',
+   'R2ARedCtbl05' => 'R2 A rosso Ctbl 05',
+   'R2ARedCtbl06' => 'R2 A rosso Ctbl 06',
+   'R2ARedCtbl07' => 'R2 A rosso Ctbl 07',
+   'R2ARedCtbl08' => 'R2 A rosso Ctbl 08',
+   'R2ARedCtbl09' => 'R2 A rosso Ctbl 09',
+   'R2ARedCtbl10' => 'R2 A rosso Ctbl 10',
+   'R2ARedCtbl11' => 'R2 A rosso Ctbl 11',
+   'R2ARedCtbl12' => 'R2 A rosso Ctbl 12',
+   'R2ARedCtbl13' => 'R2 A rosso Ctbl 13',
+   'R2ARedCtbl14' => 'R2 A rosso Ctbl 14',
+   'R2ARedCtbl15' => 'R2 A rosso Ctbl 15',
+   'R2ARedCtbl16' => 'R2 A rosso Ctbl 16',
+   'R2ARedCtbl17' => 'R2 A rosso Ctbl 17',
+   'R2ARedCtbl18' => 'R2 A rosso Ctbl 18',
+   'R2ARedCtbl19' => 'R2 A rosso Ctbl 19',
+   'R2ARedCtbl20' => 'R2 A rosso Ctbl 20',
+   'R2ARedCtbl21' => 'R2 A rosso Ctbl 21',
+   'R2ARedCtbl22' => 'R2 A rosso Ctbl 22',
+   'R2ARedCtbl23' => 'R2 A rosso Ctbl 23',
+   'R2ARedCtbl24' => 'R2 A rosso Ctbl 24',
+   'R2ARedCtbl25' => 'R2 A rosso Ctbl 25',
+   'R2ARedCtbl26' => 'R2 A rosso Ctbl 26',
+   'R2ARedCtbl27' => 'R2 A rosso Ctbl 27',
+   'R2ARedCtbl28' => 'R2 A rosso Ctbl 28',
+   'R2ARedCtbl29' => 'R2 A rosso Ctbl 29',
+   'R2ARedCtbl30' => 'R2 A rosso Ctbl 30',
+   'R2ARedCtbl31' => 'R2 A rosso Ctbl 31',
+   'R2ARedStbl00' => 'R2 A rosso Stbl 00',
+   'R2ARedStbl01' => 'R2 A rosso Stbl 01',
+   'R2ARedStbl02' => 'R2 A rosso Stbl 02',
+   'R2ARedStbl03' => 'R2 A rosso Stbl 03',
+   'R2ARedStbl04' => 'R2 A rosso Stbl 04',
+   'R2ARedStbl05' => 'R2 A rosso Stbl 05',
+   'R2ARedStbl06' => 'R2 A rosso Stbl 06',
+   'R2ARedStbl07' => 'R2 A rosso Stbl 07',
+   'R2ARedStbl08' => 'R2 A rosso Stbl 08',
+   'R2ARedStbl09' => 'R2 A rosso Stbl 09',
+   'R2ARedStbl10' => 'R2 A rosso Stbl 10',
+   'R2ARedStbl11' => 'R2 A rosso Stbl 11',
+   'R2ARedStbl12' => 'R2 A rosso Stbl 12',
+   'R2ARedStbl13' => 'R2 A rosso Stbl 13',
+   'R2ARedStbl14' => 'R2 A rosso Stbl 14',
+   'R2ARedStbl15' => 'R2 A rosso Stbl 15',
+   'R2ARedStbl16' => 'R2 A rosso Stbl 16',
+   'R2ARedStbl17' => 'R2 A rosso Stbl 17',
+   'R2ARedStbl18' => 'R2 A rosso Stbl 18',
+   'R2ARedStbl19' => 'R2 A rosso Stbl 19',
+   'R2ARedStbl20' => 'R2 A rosso Stbl 20',
+   'R2ARedStbl21' => 'R2 A rosso Stbl 21',
+   'R2ARedStbl22' => 'R2 A rosso Stbl 22',
+   'R2ARedStbl23' => 'R2 A rosso Stbl 23',
+   'R2ARedStbl24' => 'R2 A rosso Stbl 24',
+   'R2ARedStbl25' => 'R2 A rosso Stbl 25',
+   'R2ARedStbl26' => 'R2 A rosso Stbl 26',
+   'R2ARedStbl27' => 'R2 A rosso Stbl 27',
+   'R2ARedStbl28' => 'R2 A rosso Stbl 28',
+   'R2ARedStbl29' => 'R2 A rosso Stbl 29',
+   'R2ARedStbl30' => 'R2 A rosso Stbl 30',
+   'R2ARedStbl31' => 'R2 A rosso Stbl 31',
+   'R2AWidth' => 'R2 A larghezza',
+   'R2D65BlueCtbl00' => 'R2 D65 blu Ctbl 00',
+   'R2D65BlueCtbl01' => 'R2 D65 blu Ctbl 01',
+   'R2D65BlueCtbl02' => 'R2 D65 blu Ctbl 02',
+   'R2D65BlueCtbl03' => 'R2 D65 blu Ctbl 03',
+   'R2D65BlueCtbl04' => 'R2 D65 blu Ctbl 04',
+   'R2D65BlueCtbl05' => 'R2 D65 blu Ctbl 05',
+   'R2D65BlueCtbl06' => 'R2 D65 blu Ctbl 06',
+   'R2D65BlueCtbl07' => 'R2 D65 blu Ctbl 07',
+   'R2D65BlueCtbl08' => 'R2 D65 blu Ctbl 08',
+   'R2D65BlueCtbl09' => 'R2 D65 blu Ctbl 09',
+   'R2D65BlueCtbl10' => 'R2 D65 blu Ctbl 10',
+   'R2D65BlueCtbl11' => 'R2 D65 blu Ctbl 11',
+   'R2D65BlueCtbl12' => 'R2 D65 blu Ctbl 12',
+   'R2D65BlueCtbl13' => 'R2 D65 blu Ctbl 13',
+   'R2D65BlueCtbl14' => 'R2 D65 blu Ctbl 14',
+   'R2D65BlueCtbl15' => 'R2 D65 blu Ctbl 15',
+   'R2D65BlueCtbl16' => 'R2 D65 blu Ctbl 16',
+   'R2D65BlueCtbl17' => 'R2 D65 blu Ctbl 17',
+   'R2D65BlueCtbl18' => 'R2 D65 blu Ctbl 18',
+   'R2D65BlueCtbl19' => 'R2 D65 blu Ctbl 19',
+   'R2D65BlueCtbl20' => 'R2 D65 blu Ctbl 20',
+   'R2D65BlueCtbl21' => 'R2 D65 blu Ctbl 21',
+   'R2D65BlueCtbl22' => 'R2 D65 blu Ctbl 22',
+   'R2D65BlueCtbl23' => 'R2 D65 blu Ctbl 23',
+   'R2D65BlueCtbl24' => 'R2 D65 blu Ctbl 24',
+   'R2D65BlueCtbl25' => 'R2 D65 blu Ctbl 25',
+   'R2D65BlueCtbl26' => 'R2 D65 blu Ctbl 26',
+   'R2D65BlueCtbl27' => 'R2 D65 blu Ctbl 27',
+   'R2D65BlueCtbl28' => 'R2 D65 blu Ctbl 28',
+   'R2D65BlueCtbl29' => 'R2 D65 blu Ctbl 29',
+   'R2D65BlueCtbl30' => 'R2 D65 blu Ctbl 30',
+   'R2D65BlueCtbl31' => 'R2 D65 blu Ctbl 31',
+   'R2D65BlueStbl00' => 'R2 D65 blu Stbl 00',
+   'R2D65BlueStbl01' => 'R2 D65 blu Stbl 01',
+   'R2D65BlueStbl02' => 'R2 D65 blu Stbl 02',
+   'R2D65BlueStbl03' => 'R2 D65 blu Stbl 03',
+   'R2D65BlueStbl04' => 'R2 D65 blu Stbl 04',
+   'R2D65BlueStbl05' => 'R2 D65 blu Stbl 05',
+   'R2D65BlueStbl06' => 'R2 D65 blu Stbl 06',
+   'R2D65BlueStbl07' => 'R2 D65 blu Stbl 07',
+   'R2D65BlueStbl08' => 'R2 D65 blu Stbl 08',
+   'R2D65BlueStbl09' => 'R2 D65 blu Stbl 09',
+   'R2D65BlueStbl10' => 'R2 D65 blu Stbl 10',
+   'R2D65BlueStbl11' => 'R2 D65 blu Stbl 11',
+   'R2D65BlueStbl12' => 'R2 D65 blu Stbl 12',
+   'R2D65BlueStbl13' => 'R2 D65 blu Stbl 13',
+   'R2D65BlueStbl14' => 'R2 D65 blu Stbl 14',
+   'R2D65BlueStbl15' => 'R2 D65 blu Stbl 15',
+   'R2D65BlueStbl16' => 'R2 D65 blu Stbl 16',
+   'R2D65BlueStbl17' => 'R2 D65 blu Stbl 17',
+   'R2D65BlueStbl18' => 'R2 D65 blu Stbl 18',
+   'R2D65BlueStbl19' => 'R2 D65 blu Stbl 19',
+   'R2D65BlueStbl20' => 'R2 D65 blu Stbl 20',
+   'R2D65BlueStbl21' => 'R2 D65 blu Stbl 21',
+   'R2D65BlueStbl22' => 'R2 D65 blu Stbl 22',
+   'R2D65BlueStbl23' => 'R2 D65 blu Stbl 23',
+   'R2D65BlueStbl24' => 'R2 D65 blu Stbl 24',
+   'R2D65BlueStbl25' => 'R2 D65 blu Stbl 25',
+   'R2D65BlueStbl26' => 'R2 D65 blu Stbl 26',
+   'R2D65BlueStbl27' => 'R2 D65 blu Stbl 27',
+   'R2D65BlueStbl28' => 'R2 D65 blu Stbl 28',
+   'R2D65BlueStbl29' => 'R2 D65 blu Stbl 29',
+   'R2D65BlueStbl30' => 'R2 D65 blu Stbl 30',
+   'R2D65BlueStbl31' => 'R2 D65 blu Stbl 31',
+   'R2D65GreenCtbl00' => 'R2 D65 verde Ctbl 00',
+   'R2D65GreenCtbl01' => 'R2 D65 verde Ctbl 01',
+   'R2D65GreenCtbl02' => 'R2 D65 verde Ctbl 02',
+   'R2D65GreenCtbl03' => 'R2 D65 verde Ctbl 03',
+   'R2D65GreenCtbl04' => 'R2 D65 verde Ctbl 04',
+   'R2D65GreenCtbl05' => 'R2 D65 verde Ctbl 05',
+   'R2D65GreenCtbl06' => 'R2 D65 verde Ctbl 06',
+   'R2D65GreenCtbl07' => 'R2 D65 verde Ctbl 07',
+   'R2D65GreenCtbl08' => 'R2 D65 verde Ctbl 08',
+   'R2D65GreenCtbl09' => 'R2 D65 verde Ctbl 09',
+   'R2D65GreenCtbl10' => 'R2 D65 verde Ctbl 10',
+   'R2D65GreenCtbl11' => 'R2 D65 verde Ctbl 11',
+   'R2D65GreenCtbl12' => 'R2 D65 verde Ctbl 12',
+   'R2D65GreenCtbl13' => 'R2 D65 verde Ctbl 13',
+   'R2D65GreenCtbl14' => 'R2 D65 verde Ctbl 14',
+   'R2D65GreenCtbl15' => 'R2 D65 verde Ctbl 15',
+   'R2D65GreenCtbl16' => 'R2 D65 verde Ctbl 16',
+   'R2D65GreenCtbl17' => 'R2 D65 verde Ctbl 17',
+   'R2D65GreenCtbl18' => 'R2 D65 verde Ctbl 18',
+   'R2D65GreenCtbl19' => 'R2 D65 verde Ctbl 19',
+   'R2D65GreenCtbl20' => 'R2 D65 verde Ctbl 20',
+   'R2D65GreenCtbl21' => 'R2 D65 verde Ctbl 21',
+   'R2D65GreenCtbl22' => 'R2 D65 verde Ctbl 22',
+   'R2D65GreenCtbl23' => 'R2 D65 verde Ctbl 23',
+   'R2D65GreenCtbl24' => 'R2 D65 verde Ctbl 24',
+   'R2D65GreenCtbl25' => 'R2 D65 verde Ctbl 25',
+   'R2D65GreenCtbl26' => 'R2 D65 verde Ctbl 26',
+   'R2D65GreenCtbl27' => 'R2 D65 verde Ctbl 27',
+   'R2D65GreenCtbl28' => 'R2 D65 verde Ctbl 28',
+   'R2D65GreenCtbl29' => 'R2 D65 verde Ctbl 29',
+   'R2D65GreenCtbl30' => 'R2 D65 verde Ctbl 30',
+   'R2D65GreenCtbl31' => 'R2 D65 verde Ctbl 31',
+   'R2D65GreenStbl00' => 'R2 D65 verde Stbl 00',
+   'R2D65GreenStbl01' => 'R2 D65 verde Stbl 01',
+   'R2D65GreenStbl02' => 'R2 D65 verde Stbl 02',
+   'R2D65GreenStbl03' => 'R2 D65 verde Stbl 03',
+   'R2D65GreenStbl04' => 'R2 D65 verde Stbl 04',
+   'R2D65GreenStbl05' => 'R2 D65 verde Stbl 05',
+   'R2D65GreenStbl06' => 'R2 D65 verde Stbl 06',
+   'R2D65GreenStbl07' => 'R2 D65 verde Stbl 07',
+   'R2D65GreenStbl08' => 'R2 D65 verde Stbl 08',
+   'R2D65GreenStbl09' => 'R2 D65 verde Stbl 09',
+   'R2D65GreenStbl10' => 'R2 D65 verde Stbl 10',
+   'R2D65GreenStbl11' => 'R2 D65 verde Stbl 11',
+   'R2D65GreenStbl12' => 'R2 D65 verde Stbl 12',
+   'R2D65GreenStbl13' => 'R2 D65 verde Stbl 13',
+   'R2D65GreenStbl14' => 'R2 D65 verde Stbl 14',
+   'R2D65GreenStbl15' => 'R2 D65 verde Stbl 15',
+   'R2D65GreenStbl16' => 'R2 D65 verde Stbl 16',
+   'R2D65GreenStbl17' => 'R2 D65 verde Stbl 17',
+   'R2D65GreenStbl18' => 'R2 D65 verde Stbl 18',
+   'R2D65GreenStbl19' => 'R2 D65 verde Stbl 19',
+   'R2D65GreenStbl20' => 'R2 D65 verde Stbl 20',
+   'R2D65GreenStbl21' => 'R2 D65 verde Stbl 21',
+   'R2D65GreenStbl22' => 'R2 D65 verde Stbl 22',
+   'R2D65GreenStbl23' => 'R2 D65 verde Stbl 23',
+   'R2D65GreenStbl24' => 'R2 D65 verde Stbl 24',
+   'R2D65GreenStbl25' => 'R2 D65 verde Stbl 25',
+   'R2D65GreenStbl26' => 'R2 D65 verde Stbl 26',
+   'R2D65GreenStbl27' => 'R2 D65 verde Stbl 27',
+   'R2D65GreenStbl28' => 'R2 D65 verde Stbl 28',
+   'R2D65GreenStbl29' => 'R2 D65 verde Stbl 29',
+   'R2D65GreenStbl30' => 'R2 D65 verde Stbl 30',
+   'R2D65GreenStbl31' => 'R2 D65 verde Stbl 31',
+   'R2D65Height' => 'R2 D65 altezza',
+   'R2D65Intervals' => 'R2 D65 intervalli',
+   'R2D65RedCtbl00' => 'R2 D65 rosso Ctbl 00',
+   'R2D65RedCtbl01' => 'R2 D65 rosso Ctbl 01',
+   'R2D65RedCtbl02' => 'R2 D65 rosso Ctbl 02',
+   'R2D65RedCtbl03' => 'R2 D65 rosso Ctbl 03',
+   'R2D65RedCtbl04' => 'R2 D65 rosso Ctbl 04',
+   'R2D65RedCtbl05' => 'R2 D65 rosso Ctbl 05',
+   'R2D65RedCtbl06' => 'R2 D65 rosso Ctbl 06',
+   'R2D65RedCtbl07' => 'R2 D65 rosso Ctbl 07',
+   'R2D65RedCtbl08' => 'R2 D65 rosso Ctbl 08',
+   'R2D65RedCtbl09' => 'R2 D65 rosso Ctbl 09',
+   'R2D65RedCtbl10' => 'R2 D65 rosso Ctbl 10',
+   'R2D65RedCtbl11' => 'R2 D65 rosso Ctbl 11',
+   'R2D65RedCtbl12' => 'R2 D65 rosso Ctbl 12',
+   'R2D65RedCtbl13' => 'R2 D65 rosso Ctbl 13',
+   'R2D65RedCtbl14' => 'R2 D65 rosso Ctbl 14',
+   'R2D65RedCtbl15' => 'R2 D65 rosso Ctbl 15',
+   'R2D65RedCtbl16' => 'R2 D65 rosso Ctbl 16',
+   'R2D65RedCtbl17' => 'R2 D65 rosso Ctbl 17',
+   'R2D65RedCtbl18' => 'R2 D65 rosso Ctbl 18',
+   'R2D65RedCtbl19' => 'R2 D65 rosso Ctbl 19',
+   'R2D65RedCtbl20' => 'R2 D65 rosso Ctbl 20',
+   'R2D65RedCtbl21' => 'R2 D65 rosso Ctbl 21',
+   'R2D65RedCtbl22' => 'R2 D65 rosso Ctbl 22',
+   'R2D65RedCtbl23' => 'R2 D65 rosso Ctbl 23',
+   'R2D65RedCtbl24' => 'R2 D65 rosso Ctbl 24',
+   'R2D65RedCtbl25' => 'R2 D65 rosso Ctbl 25',
+   'R2D65RedCtbl26' => 'R2 D65 rosso Ctbl 26',
+   'R2D65RedCtbl27' => 'R2 D65 rosso Ctbl 27',
+   'R2D65RedCtbl28' => 'R2 D65 rosso Ctbl 28',
+   'R2D65RedCtbl29' => 'R2 D65 rosso Ctbl 29',
+   'R2D65RedCtbl30' => 'R2 D65 rosso Ctbl 30',
+   'R2D65RedCtbl31' => 'R2 D65 rosso Ctbl 31',
+   'R2D65RedStbl00' => 'R2 D65 rosso Stbl 00',
+   'R2D65RedStbl01' => 'R2 D65 rosso Stbl 01',
+   'R2D65RedStbl02' => 'R2 D65 rosso Stbl 02',
+   'R2D65RedStbl03' => 'R2 D65 rosso Stbl 03',
+   'R2D65RedStbl04' => 'R2 D65 rosso Stbl 04',
+   'R2D65RedStbl05' => 'R2 D65 rosso Stbl 05',
+   'R2D65RedStbl06' => 'R2 D65 rosso Stbl 06',
+   'R2D65RedStbl07' => 'R2 D65 rosso Stbl 07',
+   'R2D65RedStbl08' => 'R2 D65 rosso Stbl 08',
+   'R2D65RedStbl09' => 'R2 D65 rosso Stbl 09',
+   'R2D65RedStbl10' => 'R2 D65 rosso Stbl 10',
+   'R2D65RedStbl11' => 'R2 D65 rosso Stbl 11',
+   'R2D65RedStbl12' => 'R2 D65 rosso Stbl 12',
+   'R2D65RedStbl13' => 'R2 D65 rosso Stbl 13',
+   'R2D65RedStbl14' => 'R2 D65 rosso Stbl 14',
+   'R2D65RedStbl15' => 'R2 D65 rosso Stbl 15',
+   'R2D65RedStbl16' => 'R2 D65 rosso Stbl 16',
+   'R2D65RedStbl17' => 'R2 D65 rosso Stbl 17',
+   'R2D65RedStbl18' => 'R2 D65 rosso Stbl 18',
+   'R2D65RedStbl19' => 'R2 D65 rosso Stbl 19',
+   'R2D65RedStbl20' => 'R2 D65 rosso Stbl 20',
+   'R2D65RedStbl21' => 'R2 D65 rosso Stbl 21',
+   'R2D65RedStbl22' => 'R2 D65 rosso Stbl 22',
+   'R2D65RedStbl23' => 'R2 D65 rosso Stbl 23',
+   'R2D65RedStbl24' => 'R2 D65 rosso Stbl 24',
+   'R2D65RedStbl25' => 'R2 D65 rosso Stbl 25',
+   'R2D65RedStbl26' => 'R2 D65 rosso Stbl 26',
+   'R2D65RedStbl27' => 'R2 D65 rosso Stbl 27',
+   'R2D65RedStbl28' => 'R2 D65 rosso Stbl 28',
+   'R2D65RedStbl29' => 'R2 D65 rosso Stbl 29',
+   'R2D65RedStbl30' => 'R2 D65 rosso Stbl 30',
+   'R2D65RedStbl31' => 'R2 D65 rosso Stbl 31',
+   'R2D65Width' => 'R2 D65 larghezza',
+   'R2TL84BlueCtbl00' => 'R2 TL84 blu Ctbl 00',
+   'R2TL84BlueCtbl01' => 'R2 TL84 blu Ctbl 01',
+   'R2TL84BlueCtbl02' => 'R2 TL84 blu Ctbl 02',
+   'R2TL84BlueCtbl03' => 'R2 TL84 blu Ctbl 03',
+   'R2TL84BlueCtbl04' => 'R2 TL84 blu Ctbl 04',
+   'R2TL84BlueCtbl05' => 'R2 TL84 blu Ctbl 05',
+   'R2TL84BlueCtbl06' => 'R2 TL84 blu Ctbl 06',
+   'R2TL84BlueCtbl07' => 'R2 TL84 blu Ctbl 07',
+   'R2TL84BlueCtbl08' => 'R2 TL84 blu Ctbl 08',
+   'R2TL84BlueCtbl09' => 'R2 TL84 blu Ctbl 09',
+   'R2TL84BlueCtbl10' => 'R2 TL84 blu Ctbl 10',
+   'R2TL84BlueCtbl11' => 'R2 TL84 blu Ctbl 11',
+   'R2TL84BlueCtbl12' => 'R2 TL84 blu Ctbl 12',
+   'R2TL84BlueCtbl13' => 'R2 TL84 blu Ctbl 13',
+   'R2TL84BlueCtbl14' => 'R2 TL84 blu Ctbl 14',
+   'R2TL84BlueCtbl15' => 'R2 TL84 blu Ctbl 15',
+   'R2TL84BlueCtbl16' => 'R2 TL84 blu Ctbl 16',
+   'R2TL84BlueCtbl17' => 'R2 TL84 blu Ctbl 17',
+   'R2TL84BlueCtbl18' => 'R2 TL84 blu Ctbl 18',
+   'R2TL84BlueCtbl19' => 'R2 TL84 blu Ctbl 19',
+   'R2TL84BlueCtbl20' => 'R2 TL84 blu Ctbl 20',
+   'R2TL84BlueCtbl21' => 'R2 TL84 blu Ctbl 21',
+   'R2TL84BlueCtbl22' => 'R2 TL84 blu Ctbl 22',
+   'R2TL84BlueCtbl23' => 'R2 TL84 blu Ctbl 23',
+   'R2TL84BlueCtbl24' => 'R2 TL84 blu Ctbl 24',
+   'R2TL84BlueCtbl25' => 'R2 TL84 blu Ctbl 25',
+   'R2TL84BlueCtbl26' => 'R2 TL84 blu Ctbl 26',
+   'R2TL84BlueCtbl27' => 'R2 TL84 blu Ctbl 27',
+   'R2TL84BlueCtbl28' => 'R2 TL84 blu Ctbl 28',
+   'R2TL84BlueCtbl29' => 'R2 TL84 blu Ctbl 29',
+   'R2TL84BlueCtbl30' => 'R2 TL84 blu Ctbl 30',
+   'R2TL84BlueCtbl31' => 'R2 TL84 blu Ctbl 31',
+   'R2TL84BlueStbl00' => 'R2 TL84 blu Stbl 00',
+   'R2TL84BlueStbl01' => 'R2 TL84 blu Stbl 01',
+   'R2TL84BlueStbl02' => 'R2 TL84 blu Stbl 02',
+   'R2TL84BlueStbl03' => 'R2 TL84 blu Stbl 03',
+   'R2TL84BlueStbl04' => 'R2 TL84 blu Stbl 04',
+   'R2TL84BlueStbl05' => 'R2 TL84 blu Stbl 05',
+   'R2TL84BlueStbl06' => 'R2 TL84 blu Stbl 06',
+   'R2TL84BlueStbl07' => 'R2 TL84 blu Stbl 07',
+   'R2TL84BlueStbl08' => 'R2 TL84 blu Stbl 08',
+   'R2TL84BlueStbl09' => 'R2 TL84 blu Stbl 09',
+   'R2TL84BlueStbl10' => 'R2 TL84 blu Stbl 10',
+   'R2TL84BlueStbl11' => 'R2 TL84 blu Stbl 11',
+   'R2TL84BlueStbl12' => 'R2 TL84 blu Stbl 12',
+   'R2TL84BlueStbl13' => 'R2 TL84 blu Stbl 13',
+   'R2TL84BlueStbl14' => 'R2 TL84 blu Stbl 14',
+   'R2TL84BlueStbl15' => 'R2 TL84 blu Stbl 15',
+   'R2TL84BlueStbl16' => 'R2 TL84 blu Stbl 16',
+   'R2TL84BlueStbl17' => 'R2 TL84 blu Stbl 17',
+   'R2TL84BlueStbl18' => 'R2 TL84 blu Stbl 18',
+   'R2TL84BlueStbl19' => 'R2 TL84 blu Stbl 19',
+   'R2TL84BlueStbl20' => 'R2 TL84 blu Stbl 20',
+   'R2TL84BlueStbl21' => 'R2 TL84 blu Stbl 21',
+   'R2TL84BlueStbl22' => 'R2 TL84 blu Stbl 22',
+   'R2TL84BlueStbl23' => 'R2 TL84 blu Stbl 23',
+   'R2TL84BlueStbl24' => 'R2 TL84 blu Stbl 24',
+   'R2TL84BlueStbl25' => 'R2 TL84 blu Stbl 25',
+   'R2TL84BlueStbl26' => 'R2 TL84 blu Stbl 26',
+   'R2TL84BlueStbl27' => 'R2 TL84 blu Stbl 27',
+   'R2TL84BlueStbl28' => 'R2 TL84 blu Stbl 28',
+   'R2TL84BlueStbl29' => 'R2 TL84 blu Stbl 29',
+   'R2TL84BlueStbl30' => 'R2 TL84 blu Stbl 30',
+   'R2TL84BlueStbl31' => 'R2 TL84 blu Stbl 31',
+   'R2TL84GreenCtbl00' => 'R2 TL84 verde Ctbl 00',
+   'R2TL84GreenCtbl01' => 'R2 TL84 verde Ctbl 01',
+   'R2TL84GreenCtbl02' => 'R2 TL84 verde Ctbl 02',
+   'R2TL84GreenCtbl03' => 'R2 TL84 verde Ctbl 03',
+   'R2TL84GreenCtbl04' => 'R2 TL84 verde Ctbl 04',
+   'R2TL84GreenCtbl05' => 'R2 TL84 verde Ctbl 05',
+   'R2TL84GreenCtbl06' => 'R2 TL84 verde Ctbl 06',
+   'R2TL84GreenCtbl07' => 'R2 TL84 verde Ctbl 07',
+   'R2TL84GreenCtbl08' => 'R2 TL84 verde Ctbl 08',
+   'R2TL84GreenCtbl09' => 'R2 TL84 verde Ctbl 09',
+   'R2TL84GreenCtbl10' => 'R2 TL84 verde Ctbl 10',
+   'R2TL84GreenCtbl11' => 'R2 TL84 verde Ctbl 11',
+   'R2TL84GreenCtbl12' => 'R2 TL84 verde Ctbl 12',
+   'R2TL84GreenCtbl13' => 'R2 TL84 verde Ctbl 13',
+   'R2TL84GreenCtbl14' => 'R2 TL84 verde Ctbl 14',
+   'R2TL84GreenCtbl15' => 'R2 TL84 verde Ctbl 15',
+   'R2TL84GreenCtbl16' => 'R2 TL84 verde Ctbl 16',
+   'R2TL84GreenCtbl17' => 'R2 TL84 verde Ctbl 17',
+   'R2TL84GreenCtbl18' => 'R2 TL84 verde Ctbl 18',
+   'R2TL84GreenCtbl19' => 'R2 TL84 verde Ctbl 19',
+   'R2TL84GreenCtbl20' => 'R2 TL84 verde Ctbl 20',
+   'R2TL84GreenCtbl21' => 'R2 TL84 verde Ctbl 21',
+   'R2TL84GreenCtbl22' => 'R2 TL84 verde Ctbl 22',
+   'R2TL84GreenCtbl23' => 'R2 TL84 verde Ctbl 23',
+   'R2TL84GreenCtbl24' => 'R2 TL84 verde Ctbl 24',
+   'R2TL84GreenCtbl25' => 'R2 TL84 verde Ctbl 25',
+   'R2TL84GreenCtbl26' => 'R2 TL84 verde Ctbl 26',
+   'R2TL84GreenCtbl27' => 'R2 TL84 verde Ctbl 27',
+   'R2TL84GreenCtbl28' => 'R2 TL84 verde Ctbl 28',
+   'R2TL84GreenCtbl29' => 'R2 TL84 verde Ctbl 29',
+   'R2TL84GreenCtbl30' => 'R2 TL84 verde Ctbl 30',
+   'R2TL84GreenCtbl31' => 'R2 TL84 verde Ctbl 31',
+   'R2TL84GreenStbl00' => 'R2 TL84 verde Stbl 00',
+   'R2TL84GreenStbl01' => 'R2 TL84 verde Stbl 01',
+   'R2TL84GreenStbl02' => 'R2 TL84 verde Stbl 02',
+   'R2TL84GreenStbl03' => 'R2 TL84 verde Stbl 03',
+   'R2TL84GreenStbl04' => 'R2 TL84 verde Stbl 04',
+   'R2TL84GreenStbl05' => 'R2 TL84 verde Stbl 05',
+   'R2TL84GreenStbl06' => 'R2 TL84 verde Stbl 06',
+   'R2TL84GreenStbl07' => 'R2 TL84 verde Stbl 07',
+   'R2TL84GreenStbl08' => 'R2 TL84 verde Stbl 08',
+   'R2TL84GreenStbl09' => 'R2 TL84 verde Stbl 09',
+   'R2TL84GreenStbl10' => 'R2 TL84 verde Stbl 10',
+   'R2TL84GreenStbl11' => 'R2 TL84 verde Stbl 11',
+   'R2TL84GreenStbl12' => 'R2 TL84 verde Stbl 12',
+   'R2TL84GreenStbl13' => 'R2 TL84 verde Stbl 13',
+   'R2TL84GreenStbl14' => 'R2 TL84 verde Stbl 14',
+   'R2TL84GreenStbl15' => 'R2 TL84 verde Stbl 15',
+   'R2TL84GreenStbl16' => 'R2 TL84 verde Stbl 16',
+   'R2TL84GreenStbl17' => 'R2 TL84 verde Stbl 17',
+   'R2TL84GreenStbl18' => 'R2 TL84 verde Stbl 18',
+   'R2TL84GreenStbl19' => 'R2 TL84 verde Stbl 19',
+   'R2TL84GreenStbl20' => 'R2 TL84 verde Stbl 20',
+   'R2TL84GreenStbl21' => 'R2 TL84 verde Stbl 21',
+   'R2TL84GreenStbl22' => 'R2 TL84 verde Stbl 22',
+   'R2TL84GreenStbl23' => 'R2 TL84 verde Stbl 23',
+   'R2TL84GreenStbl24' => 'R2 TL84 verde Stbl 24',
+   'R2TL84GreenStbl25' => 'R2 TL84 verde Stbl 25',
+   'R2TL84GreenStbl26' => 'R2 TL84 verde Stbl 26',
+   'R2TL84GreenStbl27' => 'R2 TL84 verde Stbl 27',
+   'R2TL84GreenStbl28' => 'R2 TL84 verde Stbl 28',
+   'R2TL84GreenStbl29' => 'R2 TL84 verde Stbl 29',
+   'R2TL84GreenStbl30' => 'R2 TL84 verde Stbl 30',
+   'R2TL84GreenStbl31' => 'R2 TL84 verde Stbl 31',
+   'R2TL84Height' => 'R2 TL84 altezza',
+   'R2TL84Intervals' => 'R2 TL84 intervalli',
+   'R2TL84RedCtbl00' => 'R2 TL84 rosso Ctbl 00',
+   'R2TL84RedCtbl01' => 'R2 TL84 rosso Ctbl 01',
+   'R2TL84RedCtbl02' => 'R2 TL84 rosso Ctbl 02',
+   'R2TL84RedCtbl03' => 'R2 TL84 rosso Ctbl 03',
+   'R2TL84RedCtbl04' => 'R2 TL84 rosso Ctbl 04',
+   'R2TL84RedCtbl05' => 'R2 TL84 rosso Ctbl 05',
+   'R2TL84RedCtbl06' => 'R2 TL84 rosso Ctbl 06',
+   'R2TL84RedCtbl07' => 'R2 TL84 rosso Ctbl 07',
+   'R2TL84RedCtbl08' => 'R2 TL84 rosso Ctbl 08',
+   'R2TL84RedCtbl09' => 'R2 TL84 rosso Ctbl 09',
+   'R2TL84RedCtbl10' => 'R2 TL84 rosso Ctbl 10',
+   'R2TL84RedCtbl11' => 'R2 TL84 rosso Ctbl 11',
+   'R2TL84RedCtbl12' => 'R2 TL84 rosso Ctbl 12',
+   'R2TL84RedCtbl13' => 'R2 TL84 rosso Ctbl 13',
+   'R2TL84RedCtbl14' => 'R2 TL84 rosso Ctbl 14',
+   'R2TL84RedCtbl15' => 'R2 TL84 rosso Ctbl 15',
+   'R2TL84RedCtbl16' => 'R2 TL84 rosso Ctbl 16',
+   'R2TL84RedCtbl17' => 'R2 TL84 rosso Ctbl 17',
+   'R2TL84RedCtbl18' => 'R2 TL84 rosso Ctbl 18',
+   'R2TL84RedCtbl19' => 'R2 TL84 rosso Ctbl 19',
+   'R2TL84RedCtbl20' => 'R2 TL84 rosso Ctbl 20',
+   'R2TL84RedCtbl21' => 'R2 TL84 rosso Ctbl 21',
+   'R2TL84RedCtbl22' => 'R2 TL84 rosso Ctbl 22',
+   'R2TL84RedCtbl23' => 'R2 TL84 rosso Ctbl 23',
+   'R2TL84RedCtbl24' => 'R2 TL84 rosso Ctbl 24',
+   'R2TL84RedCtbl25' => 'R2 TL84 rosso Ctbl 25',
+   'R2TL84RedCtbl26' => 'R2 TL84 rosso Ctbl 26',
+   'R2TL84RedCtbl27' => 'R2 TL84 rosso Ctbl 27',
+   'R2TL84RedCtbl28' => 'R2 TL84 rosso Ctbl 28',
+   'R2TL84RedCtbl29' => 'R2 TL84 rosso Ctbl 29',
+   'R2TL84RedCtbl30' => 'R2 TL84 rosso Ctbl 30',
+   'R2TL84RedCtbl31' => 'R2 TL84 rosso Ctbl 31',
+   'R2TL84RedStbl00' => 'R2 TL84 rosso Stbl 00',
+   'R2TL84RedStbl01' => 'R2 TL84 rosso Stbl 01',
+   'R2TL84RedStbl02' => 'R2 TL84 rosso Stbl 02',
+   'R2TL84RedStbl03' => 'R2 TL84 rosso Stbl 03',
+   'R2TL84RedStbl04' => 'R2 TL84 rosso Stbl 04',
+   'R2TL84RedStbl05' => 'R2 TL84 rosso Stbl 05',
+   'R2TL84RedStbl06' => 'R2 TL84 rosso Stbl 06',
+   'R2TL84RedStbl07' => 'R2 TL84 rosso Stbl 07',
+   'R2TL84RedStbl08' => 'R2 TL84 rosso Stbl 08',
+   'R2TL84RedStbl09' => 'R2 TL84 rosso Stbl 09',
+   'R2TL84RedStbl10' => 'R2 TL84 rosso Stbl 10',
+   'R2TL84RedStbl11' => 'R2 TL84 rosso Stbl 11',
+   'R2TL84RedStbl12' => 'R2 TL84 rosso Stbl 12',
+   'R2TL84RedStbl13' => 'R2 TL84 rosso Stbl 13',
+   'R2TL84RedStbl14' => 'R2 TL84 rosso Stbl 14',
+   'R2TL84RedStbl15' => 'R2 TL84 rosso Stbl 15',
+   'R2TL84RedStbl16' => 'R2 TL84 rosso Stbl 16',
+   'R2TL84RedStbl17' => 'R2 TL84 rosso Stbl 17',
+   'R2TL84RedStbl18' => 'R2 TL84 rosso Stbl 18',
+   'R2TL84RedStbl19' => 'R2 TL84 rosso Stbl 19',
+   'R2TL84RedStbl20' => 'R2 TL84 rosso Stbl 20',
+   'R2TL84RedStbl21' => 'R2 TL84 rosso Stbl 21',
+   'R2TL84RedStbl22' => 'R2 TL84 rosso Stbl 22',
+   'R2TL84RedStbl23' => 'R2 TL84 rosso Stbl 23',
+   'R2TL84RedStbl24' => 'R2 TL84 rosso Stbl 24',
+   'R2TL84RedStbl25' => 'R2 TL84 rosso Stbl 25',
+   'R2TL84RedStbl26' => 'R2 TL84 rosso Stbl 26',
+   'R2TL84RedStbl27' => 'R2 TL84 rosso Stbl 27',
+   'R2TL84RedStbl28' => 'R2 TL84 rosso Stbl 28',
+   'R2TL84RedStbl29' => 'R2 TL84 rosso Stbl 29',
+   'R2TL84RedStbl30' => 'R2 TL84 rosso Stbl 30',
+   'R2TL84RedStbl31' => 'R2 TL84 rosso Stbl 31',
+   'R2TL84Width' => 'R2 TL84 larghezza',
    'RAFVersion' => 'Versione RAF',
-   'RasterizedCaption' => 'Didascalia Rasterizzata',
-   'Rating' => 'Valutazione',
-   'RatingPercent' => 'Valutazione in percentuale',
+   'RGBCurveLimits' => 'Limiti curva RGB',
+   'RGBCurvePoints' => 'Punti curva RGB',
+   'RadialPosition' => 'Posizione radiale',
+   'RandomIndexMetadata' => 'Indice casuale metadati',
+   'RandomIndexMetadataV10' => 'Indice casuale metadati V10',
+   'RangeFinder' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'RasterPadding' => {
+      PrintConv => {
+        'Long Sector' => 'Settore lungo',
+        'Long Word' => 'Parola lunga',
+        'Sector' => 'Settore',
+        'Word' => 'Parola',
+      },
+    },
+   'RasterizedCaption' => 'Didascalia rasterizzata',
+   'Rating' => {
+      Description => 'Valutazione',
+      PrintConv => {
+        'Explicit' => 'Esplicito',
+      },
+    },
+   'RatingPercent' => 'Valutazione percentuale',
+   'RawAndJpgRecording' => {
+      Description => 'Registrazione raw e jpg',
+      PrintConv => {
+        'Off' => 'Spento',
+        'RAW (DNG, Best)' => 'RAW (DNG, migliore)',
+        'RAW (DNG, Better)' => 'RAW (DNG, piÃ¹ buona)',
+        'RAW (DNG, Good)' => 'RAW (DNG, buona)',
+        'RAW (PEF, Best)' => 'RAW (PEF, migliore)',
+        'RAW (PEF, Better)' => 'RAW (PEF, piÃ¹ buona)',
+        'RAW (PEF, Good)' => 'RAW (PEF, buona)',
+        'RAW+JPEG (DNG, Best)' => 'RAW+JPEG (DNG, migliore)',
+        'RAW+JPEG (DNG, Better)' => 'RAW+JPEG (DNG, piÃ¹ buona)',
+        'RAW+JPEG (DNG, Good)' => 'RAW+JPEG (DNG, buona)',
+        'RAW+JPEG (PEF, Best)' => 'RAW+JPEG (PEF, migliore)',
+        'RAW+JPEG (PEF, Better)' => 'RAW+JPEG (PEF, piÃ¹ buona)',
+        'RAW+JPEG (PEF, Good)' => 'RAW+JPEG (PEF, buona)',
+      },
+    },
+   'RawColorAdj' => {
+      PrintConv => {
+        'Shot Settings' => 'Impostazioni scatto',
+      },
+    },
+   'RawDataOffset' => 'Offset dati raw',
+   'RawDataUniqueID' => 'ID unico dati raw',
+   'RawDepth' => 'ProfonditÃ  raw',
+   'RawDevAutoGradation' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'RawDevEditStatus' => {
+      PrintConv => {
+        'Original' => 'Originale',
+      },
+    },
+   'RawDevNoiseReduction' => {
+      PrintConv => {
+        'Noise Filter' => 'Filtro rumore',
+        'Noise Reduction' => 'Riduzione rumore',
+      },
+    },
    'RawDevPMPictureTone' => {
       PrintConv => {
         'Green' => 'Verde',
+        'Purple' => 'Porpora',
+        'Sepia' => 'Seppia',
       },
     },
@@ -1591,8 +6205,47 @@
       },
     },
-   'RawImageCenter' => 'Centro Immagine RAW',
+   'RawDevPictureMode' => {
+      PrintConv => {
+        'Sepia' => 'Seppia',
+        'Vivid' => 'Vivace',
+      },
+    },
+   'RawDevSettings' => {
+      PrintConv => {
+        'Noise Reduction' => 'Riduzione rumore',
+        'Saturation' => 'Saturazione',
+        'Sharpness' => 'Nitidezza',
+      },
+    },
+   'RawFile' => 'File raw',
+   'RawFileName' => 'Nome file raw',
+   'RawImageCenter' => 'Centro immagine raw',
+   'RawImageDigest' => 'Sommario file raw',
+   'RawImageFullSize' => 'Dimensione finale immagine raw',
+   'RawImageHeight' => 'Altezza immagine raw',
+   'RawImageMode' => 'Modo immagine raw',
+   'RawImageSegmentation' => 'Segmentazione file raw',
+   'RawImageSize' => 'Dimensione immagine raw',
+   'RawImageWidth' => 'Larghezza immagine raw',
+   'RawInfoVersion' => 'Info versione raw',
+   'RawJpgHeight' => 'Altezza jpg raw',
    'RawJpgQuality' => {
+      Description => 'QualitÃ  jpg raw',
       PrintConv => {
         'Normal' => 'Normale',
+      },
+    },
+   'RawJpgSize' => {
+      Description => 'Dimensione jpg raw',
+      PrintConv => {
+        'Postcard' => 'Cartolina',
+      },
+    },
+   'RawJpgWidth' => 'Larghezza jpg raw',
+   'ReadStatus' => 'Stato lettura',
+   'RecommendedExposureIndex' => 'Indice esposizione raccomandato',
+   'RecordDisplay' => {
+      PrintConv => {
+        'Horizontal' => 'Orizzontale',
       },
     },
@@ -1602,8 +6255,18 @@
         'Aperture Priority' => 'PrioritÃ  diaframma',
         'Manual' => 'Manuale',
+        'Program AE' => 'Programma AE',
         'Shutter Priority' => 'PrioritÃ  otturatore',
       },
     },
+   'RecordShutterRelease' => {
+      PrintConv => {
+        'Press start, press stop' => 'Premi start, premi stop',
+      },
+    },
+   'RecordedFormat' => 'Formato registrato',
+   'RecordingDates' => 'Date registrazioni',
+   'RecordingLabelName' => 'Nome etichetta registrazione',
    'RecordingMode' => {
+      Description => 'Modo registrazione',
       PrintConv => {
         'Landscape' => 'Orizzontale',
@@ -1612,23 +6275,79 @@
       },
     },
-   'RedMatrixColumn' => 'Colonna della Matrice Rossa',
-   'RedTRC' => 'Curva Riproduzione Tono Rosso',
-   'ReductionMatrix1' => 'Matrice di Riduzione 1',
-   'ReductionMatrix2' => 'Matrice di Riduzione 2',
+   'RecordingTime' => 'Tempo registrazione',
+   'RedAdjust' => 'Correzione rosso',
+   'RedBalance' => 'Bilanciamento del rosso',
+   'RedCurveLimits' => 'Limiti curva rosso',
+   'RedCurvePoints' => 'Punti curva rosso',
+   'RedEyeCorrection' => {
+      Description => 'Correzione occhi rossi',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'RedEyeInfo' => 'Info occhi rossi',
+   'RedEyeReduction' => {
+      Description => 'Riduzione occhi rossi',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'RedGain' => 'Guadagno rosso',
+   'RedHue' => 'Tinta rosso',
+   'RedMatrixColumn' => 'Colonna matrice rosso',
+   'RedPaletteColorTableData' => 'Dati tabella tavolozza colori rosso',
+   'RedPaletteColorTableDescriptor' => 'Descrittore tabella tavolozza colori rosso',
+   'RedPrimary' => 'Rosso primario',
+   'RedSample' => 'Campione rosso',
+   'RedSaturation' => 'Saturazione rosso',
+   'RedTRC' => 'Curva riproduzione tono rosso',
+   'ReductionMatrix1' => 'Matrice di riduzione 1',
+   'ReductionMatrix2' => 'Matrice di riduzione 2',
+   'Reference' => 'Riferimento',
+   'Reference1' => 'Riferimento 1',
+   'Reference2' => 'Riferimento 2',
+   'Reference3' => 'Riferimento 3',
+   'Reference4' => 'Riferimento 4',
+   'Reference5' => 'Riferimento 5',
+   'Reference6' => 'Riferimento 6',
    'ReferenceBlackWhite' => 'Coppia valori riferimento di bianco e nero',
-   'ReferenceDate' => 'Data di Riferimento',
-   'ReferenceNumber' => 'Numero di Riferimento',
-   'ReferenceService' => 'Riferimento Servizio',
+   'ReferenceBlock' => 'Blocco di riferimento',
+   'ReferenceChannels' => 'Canali di riferimento',
+   'ReferenceCoordinates' => 'Coordinate di riferimento',
+   'ReferenceDate' => 'Data di riferimento',
+   'ReferenceNumber' => 'Numero di riferimento',
+   'ReferencePixelPhysicalValueX' => 'Valore fisico valore X pixel di riferimento',
+   'ReferencePixelPhysicalValueY' => 'Valore fisico valore Y pixel di riferimento',
+   'ReferencePixelX0' => 'Pixel X0 di riferimento',
+   'ReferencePixelY0' => 'Pixel Y0 di riferimento',
+   'ReferencePriority' => 'PrioritÃ  riferimento',
+   'ReferenceService' => 'Riferimento di servizio',
+   'ReferenceToRecordedSound' => 'Riferimento a suono registrato',
+   'ReferenceVirtual' => 'Riferimento virtuale',
+   'Refresh' => 'Aggiorna',
+   'RegionCode' => 'Codice regione',
+   'RegionInfo' => 'Info regione',
+   'RegionList' => 'Elenco regioni',
+   'RegionName' => 'Nome regione',
+   'RegionOfResidence' => 'Regione di residenza',
    'RelatedImageFileFormat' => 'Formato file immagine correlato',
    'RelatedImageHeight' => 'Numero delle righe dei dati immagine',
    'RelatedImageWidth' => 'Larghezza immagine correlata',
    'RelatedSoundFile' => 'File audio relativo',
+   'Relation' => 'Relazione',
+   'RelativeVolumeAdjustment' => 'Correzione relativa volume',
    'ReleaseButtonToUseDial' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'ReleaseDate' => 'Data di Rilascio',
-   'ReleaseTime' => 'Ora di Rilascio',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'ReleaseDate' => 'Data di rilascio',
+   'ReleaseMode' => {
+      PrintConv => {
+        'Normal' => 'Normale',
+        'n/a' => 'n/d',
+      },
+    },
+   'ReleaseTime' => 'Ora di rilascio',
    'RenderingIntent' => {
       PrintConv => {
@@ -1639,77 +6358,225 @@
       },
     },
-   'ResampleParamsQuality' => {
-      PrintConv => {
-        'Low' => 'Leggero',
-      },
-    },
+   'RenderingType3D' => 'Tipo resa 3D',
+   'RepeatingFlashCount' => 'Conteggio ripetizione flash',
+   'RepeatingFlashOutput' => 'Uscita ripetizione flash',
+   'RepeatingFlashRate' => 'Frequenza ripetizione flash',
+   'ReplyTo' => 'Rispondi a',
    'Resaved' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'Reserved' => 'Riservato',
+   'Reserved1' => 'Riservato 1',
+   'Resolution' => 'Risoluzione',
+   'ResolutionMode' => 'Modo risoluzione',
    'ResolutionUnit' => {
-      Description => 'UnitÃ  di risoluzione in X e Y',
+      Description => 'UnitÃ  risoluzione',
       PrintConv => {
         'None' => 'Nessuno',
-        'cm' => 'Pixel/cm',
         'inches' => 'Pollici',
       },
     },
+   'ResonantNucleus' => 'Nucleo risonante',
+   'ResourceID' => 'ID risorsa',
+   'ResourceType' => 'Tipo risorsa',
+   'Resources' => 'Risorse',
+   'ResourcesNeeded' => 'Risorse richieste',
+   'Restrictions' => 'Restrizioni',
+   'ResultsID' => 'ID risultati',
    'RetouchHistory' => {
-      Description => 'Cronologia Ritocco',
-      PrintConv => {
+      Description => 'Cronologia ritocco',
+      PrintConv => {
+        'Fisheye' => 'Fish-eye',
         'None' => 'Nessuno',
-      },
-    },
+        'Quick Retouch' => 'Ritocco veloce',
+        'Red Eye' => 'Occhi rossi',
+        'Red Intensifier' => 'Intensificatore rosso',
+        'Resize' => 'Ridimensione',
+        'Sepia' => 'Seppia',
+        'Straighten' => 'Raddrizza',
+      },
+    },
+   'RetouchInfo' => 'Info ritocco',
+   'Reuse' => {
+      Description => 'Riutilizza',
+      PrintConv => {
+        'Not Applicable' => 'Non applicabile',
+      },
+    },
+   'ReverseIndicators' => 'Inverti indicatori',
+   'ReversedByteOrder' => 'Ordine byte invertito',
+   'Revision' => 'Revisione',
+   'RevisionDate' => 'Data revisione',
    'RevisionNumber' => 'Numero revisione',
+   'RicohDate' => 'Data Ricoh',
+   'RicohImageHeight' => 'Altezza immagine Ricoh',
+   'RicohImageWidth' => 'Larghezza immagine Ricoh',
+   'RicohRDC2' => 'RDC2 Ricoh',
+   'RightAscension' => 'Ascensione retta',
+   'Robots' => 'Robot',
+   'RoleName' => 'Nome ruolo',
+   'RoomNumber' => 'Numero stanza',
+   'RoomOrSuiteName' => 'Numero stanza/suite',
+   'RootFormatVersion' => 'Versione formato radice',
    'Rotation' => {
-      Description => 'Orientanento Fotocamera',
-      PrintConv => {
-        'Horizontal' => '0Â° (alto/sinistra)',
-        'Horizontal (Normal)' => '0Â° (alto/sinistra)',
-        'Horizontal (normal)' => '0Â° (alto/sinistra)',
-        'Rotate 180' => '180Â° (basso/destra)',
+      Description => 'Rotazione',
+      PrintConv => {
+        'Horizontal' => 'Orizzontale',
+        'Horizontal (Normal)' => 'Orizzontale (normale)',
+        'Horizontal (normal)' => 'Orizzontale (normale)',
+        'Rotate 180' => 'Ruota di 180Â°',
         'Rotate 270 CW' => 'Ruota di 270Â° in senso orario',
-        'Rotate 90 CW' => '90Â° senso antiorario (destra/alto)',
-        'Rotated 180' => '180Â° (basso/destra)',
-        'Rotated 270 CW' => 'Ruota di 270Â° in senso orario',
-        'Rotated 90 CW' => '90Â° senso antiorario (destra/alto)',
-      },
-    },
-   'RowsPerStrip' => 'Numero righe per striscia',
+        'Rotate 90 CW' => 'Ruota di 90Â° senso orario',
+        'Rotated 180' => 'Ruotato di 180Â°',
+        'Rotated 270 CW' => 'Ruotato di 270Â° in senso orario',
+        'Rotated 90 CW' => 'Ruotato di 90Â° in senso orario',
+      },
+    },
+   'RotationAngle' => 'Angolo rotazione',
+   'RotationDirection' => 'Direzione rotazione',
+   'RowsPerStrip' => 'Righe per striscia',
+   'RunWindow' => {
+      PrintConv => {
+        'Normal' => 'Normale',
+        'Restore' => 'Ripristina',
+      },
+    },
+   'SEMInfo' => 'Info SEM',
    'SPIFFVersion' => 'Versione SPIFF',
+   'SRAWQuality' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
    'SRActive' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'SRGBRendering' => {
+      PrintConv => {
+        'Saturation' => 'Saturazione',
+      },
+    },
+   'SRResult' => {
+      PrintConv => {
+        'Not ready' => 'Non pronto',
       },
     },
    'SVGVersion' => 'Versione SVG',
+   'SafetyShiftInAvOrTv' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'SampleBits' => 'Bit campione',
    'SampleFormat' => {
-      PrintConv => {
-        'Float' => 'Virgola Mobile',
+      Description => 'Formato campioni',
+      PrintConv => {
+        'Complex float' => 'Virgola mobile immaginario',
+        'Complex int' => 'Intero immaginario',
+        'Float' => 'Virgola mobile',
+        'Signed' => 'Con segno',
         'Undefined' => 'Non definito',
-      },
-    },
-   'SamplesPerPixel' => 'Numero dei componenti',
+        'Unsigned' => 'Senza segno',
+      },
+    },
+   'SampleIndex' => 'Indice campione',
+   'SampleRate' => 'Frequenza campionamento',
+   'SampleRate2' => 'Frequenza campionamento 2',
+   'SampleSize' => 'Dimensione campione',
+   'SampleSizes' => 'Dimensioni campione',
+   'SampleStructure' => 'Struttura d\'esempio',
+   'SampleText' => 'Testo d\'esempio',
+   'SamplesPerPixel' => 'Campioni per pixel',
+   'SamplesPerPixelUsed' => 'Campioni per pixel',
+   'SamplingFrequency' => 'Frequenza campionamento',
    'Saturation' => {
       Description => 'Saturazione',
       PrintConv => {
-        'High' => 'Saturazione massima',
-        'Low' => 'Saturazione minima',
+        'High' => 'Alta',
+        'Low' => 'Basso',
+        'None' => 'Nessuno',
+        'None (B&W)' => 'Nessuno (B&N)',
         'Normal' => 'Normale',
+        'Vivid' => 'Vivace',
+      },
+    },
+   'SaturationAdj' => 'Correzione saturazione',
+   'SaturationFaithful' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationLandscape' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationMonochrome' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationNeutral' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationPortrait' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationStandard' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationUnknown' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationUserDef1' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationUserDef2' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SaturationUserDef3' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ScanImageEnhancer' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ScanningDirection' => {
+      PrintConv => {
+        'R-L, Bottom-Top' => 'D-S, basso-alto',
+        'R-L, Top-Bottom' => 'D-S, alto-basso',
       },
     },
    'Scene' => 'Scena',
+   'SceneArea' => 'Area scena',
    'SceneCaptureType' => {
-      Description => 'Tipo di cattura scena',
+      Description => 'Tipo cattura scena',
       PrintConv => {
         'Landscape' => 'Orizzontale',
-        'Night' => 'Scena notturna',
+        'Night' => 'Notte',
         'Portrait' => 'Verticale',
       },
     },
    'SceneMode' => {
-      Description => 'Modo Scena',
+      Description => 'Modo scena',
       PrintConv => {
         '3D Sweep Panorama' => '3D',
@@ -1717,5 +6584,7 @@
         'Aperture Priority' => 'PrioritÃ  diaframma',
         'Auto' => 'Automatico',
+        'Children' => 'Bambini',
         'Cont. Priority AE' => 'AE prior. avan.cont.',
+        'Fireworks' => 'Fuochi artificiali',
         'Handheld Night Shot' => 'Foto nott. senza trepp.',
         'Landscape' => 'Orizzontale',
@@ -1725,25 +6594,37 @@
         'Night View/Portrait' => 'Visione/Ritratto notturni',
         'Normal' => 'Normale',
+        'Off' => 'Spento',
         'Portrait' => 'Verticale',
+        'Program' => 'Programma',
+        'Scenery' => 'Paesaggio',
         'Shutter Priority' => 'PrioritÃ  otturatore',
         'Sports' => 'Evento sportivo',
-        'Standard' => '',
         'Sunset' => 'Tramonto',
         'Sweep Panorama' => 'Panoramica ad arco',
+        'Text' => 'Testo',
+        'Vivid' => 'Vivace',
+        'n/a' => 'n/d',
       },
     },
    'SceneModeUsed' => {
-      Description => 'Modo Scena',
+      Description => 'Modo scena usato',
       PrintConv => {
         'Aperture Priority' => 'PrioritÃ  diaframma',
+        'Children' => 'Bambini',
+        'Fireworks' => 'Fuochi artificiali',
         'Landscape' => 'Orizzontale',
         'Manual' => 'Manuale',
         'Portrait' => 'Verticale',
+        'Program' => 'Programma',
         'Shutter Priority' => 'PrioritÃ  otturatore',
-      },
-    },
+        'Sunset' => 'Tramonto',
+        'Text' => 'Testo',
+      },
+    },
+   'SceneNumber' => 'Numero scena',
    'SceneSelect' => {
       PrintConv => {
         'Night' => 'Scena notturna',
+        'Off' => 'Spento',
       },
     },
@@ -1754,6 +6635,20 @@
       },
     },
+   'School' => 'Scuola',
+   'ScreenTips' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Section' => 'Sezione',
+   'SectorSize' => 'Dimensione settore',
+   'Security' => {
+      Description => 'Sicurezza',
+      PrintConv => {
+        'None' => 'Nessuno',
+      },
+    },
    'SecurityClassification' => {
-      Description => 'Classificazione die sicurezza',
+      Description => 'Classificazione sicurezza',
       PrintConv => {
         'Confidential' => 'Confidenziale',
@@ -1764,18 +6659,91 @@
       },
     },
+   'SelectAFAreaSelectMode' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'SelectableAFPoint' => {
+      PrintConv => {
+        '11 points' => '11 punti',
+      },
+    },
+   'Selected' => 'Selezionato',
+   'SelfTimer' => {
+      Description => 'Autoscatto',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'SelfTimer2' => 'Autoscatto 2',
+   'SelfTimerInterval' => 'Intervallo autoscatto',
    'SelfTimerMode' => 'Modo autoscatto',
+   'SelfTimerTime' => 'Tempo autoscatto',
+   'SenderAddress' => 'Indirizzo mittente',
+   'SenderName' => 'Nome mittente',
    'SensingMethod' => {
-      Description => 'Metodo di misurazione esposimetrica',
-      PrintConv => {
-        'Color sequential area' => 'Sensore area sequenziale a colori',
-        'Color sequential linear' => 'Sensore lineare sequenziale a colori',
+      Description => 'Metodo misurazione esposimetrica',
+      PrintConv => {
+        'Color sequential area' => 'Area sequenziale a colori',
+        'Color sequential linear' => 'Lineare sequenziale a colori',
         'Not defined' => 'Non definito',
         'One-chip color area' => 'Sensore area a colori a un chip',
         'Three-chip color area' => 'Sensore area a colori a tre chip',
-        'Trilinear' => 'Sensore trilineare',
+        'Trilinear' => 'Trilineare',
         'Two-chip color area' => 'Sensore area a colori a due chip',
       },
     },
-   'SensorPixelSize' => 'Dimensione Pixel Sensore',
+   'Sensitivity' => 'SensibilitÃ ',
+   'SensitivityCalibrated' => 'SensibilitÃ  calibrata',
+   'SensitivitySteps' => {
+      Description => 'Passi sensibilitÃ ',
+      PrintConv => {
+        '1 EV Steps' => 'Step 1 EV',
+      },
+    },
+   'SensitivityType' => {
+      Description => 'Tipo sensibilitÃ ',
+      PrintConv => {
+        'ISO Speed' => 'VelocitÃ  ISO',
+        'Recommended Exposure Index' => 'Indice esposizione raccomandato',
+        'Recommended Exposure Index and ISO Speed' => 'Indice esposizione raccomandato e velocitÃ  ISO',
+        'Standard Output Sensitivity' => 'SensibilitÃ  predefinita uscita',
+        'Standard Output Sensitivity and ISO Speed' => 'SensibilitÃ  predefinita uscita e velocitÃ  ISO',
+        'Standard Output Sensitivity and Recommended Exposure Index' => 'SensibilitÃ  predefinita uscita e indice esposizione consigliato',
+        'Standard Output Sensitivity, Recommended Exposure Index and ISO Speed' => 'SensibilitÃ  predefinita uscita, indice esposizione consigliato e velocitÃ  ISO',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'SensorAreas' => 'Aree sensore',
+   'SensorCleaning' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'SensorHeight' => 'Altezza sensore',
+   'SensorID' => 'ID sensore',
+   'SensorLeftBorder' => 'Bordo sinistro sensore',
+   'SensorMode' => 'Modo sensore',
+   'SensorPixelSize' => 'Dimensione pixel sensore',
+   'SensorRedLevel' => 'Livello rosso sensore',
+   'SensorSize' => 'Dimensione sensore',
+   'SensorTemperature' => 'Temperatura sensore',
+   'SensorTopBorder' => 'Bordo superiore sensore',
+   'SensorType' => 'Tipo sensore',
+   'SensorTypeCode' => 'Codice tipo sensore',
+   'SensorWidth' => 'Larghezza sensore',
+   'Sequence' => 'Sequenza',
+   'SequenceName' => 'Nome sequenza',
+   'SequenceNumber' => {
+      Description => 'Numero sequenza',
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SequenceShotInterval' => {
+      PrintConv => {
+        '10 frames/s' => '10 frame/s',
+      },
+    },
    'SequentialShot' => {
       PrintConv => {
@@ -1783,6 +6751,15 @@
       },
     },
-   'SerialNumber' => 'Numero di Serie',
-   'ServiceIdentifier' => 'ID Servizio',
+   'SerialNumber' => 'Numero di serie',
+   'SerialNumberFormat' => {
+      Description => 'Formato numero di serie',
+      PrintConv => {
+        'Format 1' => 'Formato 1',
+        'Format 2' => 'Formato 2',
+      },
+    },
+   'ServiceID' => 'ID servizio',
+   'ServiceIdentifier' => 'Identificativo servizio',
+   'ServiceOrganizationName' => 'Nome organizzazione servizio',
    'SetButtonCrossKeysFunc' => {
       PrintConv => {
@@ -1790,31 +6767,164 @@
       },
     },
-   'ShadingCompensation' => 'Compensazione ombreggiatura',
+   'SetButtonWhenShooting' => {
+      PrintConv => {
+        'Change ISO speed' => 'Cambia velocitÃ  ISO',
+        'Change parameters' => 'Cambia parametri',
+        'ISO speed' => 'VelocitÃ  ISO',
+        'Normal (disabled)' => 'Normale (disabilitato)',
+        'White balance' => 'Bilanciamento del bianco',
+      },
+    },
+   'SetCookie' => 'Imposta cookie',
+   'SetFunctionWhenShooting' => {
+      PrintConv => {
+        'Change Parameters' => 'Cambia parametri',
+      },
+    },
+   'SetInfo' => 'Imposta info',
+   'SetSubtitle' => 'Imposta sottotitoli',
+   'ShadingCompensation' => {
+      Description => 'Compensazione ombreggiatura',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ShadingCompensation2' => {
+      Description => 'Compensazione ombreggiatura 2',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Shadow' => 'Ombra',
+   'ShadowCorrection' => {
+      PrintConv => {
+        'Normal' => 'Normale',
+        'Off' => 'Spento',
+        'Strong' => 'Forte',
+      },
+    },
+   'ShadowScale' => 'Scala ombre',
+   'Shadows' => 'Ombre',
+   'ShakeReduction' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'Off (4)' => 'Spento (4)',
+      },
+    },
+   'SharedData' => 'Dati condivisi',
+   'Sharpening' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'Normal' => 'Normale',
+        'Off' => 'Spento',
+      },
+    },
    'Sharpness' => {
       Description => 'Nitidezza',
       PrintConv => {
-        'Hard' => 'Pesante',
+        'Hard' => 'Forte',
         'Normal' => 'Normale',
         'Soft' => 'Leggera',
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessFaithful' => {
+      PrintConv => {
+        'n/a' => 'n/d',
       },
     },
    'SharpnessFrequency' => {
       PrintConv => {
-        'Low' => 'Leggero',
+        'Low' => 'Basso',
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessLandscape' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessMonochrome' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessNeutral' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessPortrait' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessStandard' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessUnknown' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessUserDef1' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessUserDef2' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'SharpnessUserDef3' => {
+      PrintConv => {
+        'n/a' => 'n/d',
       },
     },
    'ShootingMode' => {
-      Description => 'ModalitÃ  Scatto',
+      Description => 'Modo scatto',
       PrintConv => {
         'Aperture Priority' => 'PrioritÃ  diaframma',
+        'Fireworks' => 'Fuochi artificiali',
         'Manual' => 'Manuale',
         'Normal' => 'Normale',
         'Portrait' => 'Verticale',
+        'Program' => 'Programma',
+        'Scenery' => 'Paesaggio',
         'Shutter Priority' => 'PrioritÃ  otturatore',
-      },
-    },
-   'ShortDocumentID' => 'ID Documento Breve',
-   'ShotInfoVersion' => 'Info Versione Scatto',
-   'ShutterCount' => 'Conteggio Scatti',
+        'Sunset' => 'Tramonto',
+      },
+    },
+   'ShootingModeSetting' => {
+      Description => 'Impostazione modo scatto',
+      PrintConv => {
+        'Self-timer' => 'Autoscatto',
+      },
+    },
+   'ShortComment' => 'Commento breve',
+   'ShortDescription' => 'Descrizione breve',
+   'ShortDocumentID' => 'ID documento breve',
+   'ShortReleaseTimeLag' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'ShotComment' => 'Commento scatto',
+   'ShotCommentKind' => 'Tipo commento scatto',
+   'ShotDate' => 'Data scatto',
+   'ShotDay' => 'Giorno scatto',
+   'ShotDescription' => 'Descrizione scatto',
+   'ShotDuration' => 'Durata scatto',
+   'ShotInfoVersion' => 'Info versione scatto',
+   'ShotList' => 'Elenco scatti',
+   'ShotLocation' => 'Posizione scatto',
+   'ShotLocationSets' => 'Insiemi posizione scatto',
+   'ShotName' => 'Nome scatto',
+   'ShotNumber' => 'Numero scatto',
+   'ShotSize' => 'Dimensione scatto',
+   'ShutterCount' => 'Conteggio scatti',
    'ShutterMode' => {
       PrintConv => {
@@ -1822,15 +6932,34 @@
       },
     },
+   'ShutterReleaseButtonAE-L' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'ShutterReleaseNoCFCard' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'ShutterSpeed' => 'Tempo di esposizione',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'ShutterSpeed' => 'Tempo esposizione',
+   'ShutterSpeedRange' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
    'ShutterSpeedValue' => 'VelocitÃ  otturatore',
+   'SideNumber' => 'Numero lato',
+   'Sidebars' => 'Barre laterali',
    'SimilarityIndex' => 'Indice di Somiglianza',
+   'SingleFrameBracketing' => {
+      PrintConv => {
+        'Low' => 'Basso',
+      },
+    },
+   'Site' => 'Sito',
+   'Size' => 'Dimensioni',
    'SlideShow' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
       },
     },
@@ -1838,16 +6967,60 @@
       PrintConv => {
         'None' => 'Nessuno',
-      },
-    },
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'SlowSync' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'SmartRange' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'SmileShutter' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Smoothness' => 'Arrotondamento',
    'Software' => 'Software utilizzato',
    'Source' => 'Origine',
+   'SourceTitle' => 'Titolo fonte',
+   'SourceTrackID' => 'ID traccia fonte',
+   'SourceTrackIDs' => 'ID traccia fonte',
+   'SourceType' => 'Tipo fonte',
+   'SourceURL' => 'URL fonte',
+   'SourceValue' => 'Valore fonte',
    'SpatialFrequencyResponse' => 'Risposta in frequenza spaziale',
+   'SpecialBuild' => 'Compilazione speciale',
+   'SpecialEffectMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'SpecialEffectSetting' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'SpecialEffectsOpticalFilter' => {
       PrintConv => {
         'None' => 'Nessuno',
+        'Star' => 'Stella',
       },
     },
    'SpecialInstructions' => 'Istruzioni',
    'SpectralSensitivity' => 'SensibilitÃ  spettro',
+   'Speed' => {
+      Description => 'VelocitÃ ',
+      PrintConv => {
+        'Fast' => 'Veloce',
+        'Medium' => 'Medio',
+        'Slow' => 'Lento',
+      },
+    },
    'SpotMeteringMode' => {
       PrintConv => {
@@ -1855,37 +7028,113 @@
       },
     },
+   'StandardOutputSensitivity' => 'SensibilitÃ  predefinita uscita',
+   'StartTime' => 'Ora inizio',
    'State' => 'Stato',
-   'StripByteCounts' => 'Byte per striscia compressa',
-   'StripOffsets' => 'Ubicazione dati immagine',
+   'StorageMethod' => {
+      PrintConv => {
+        'Linear' => 'Lineare',
+      },
+    },
+   'StreamType' => {
+      PrintConv => {
+        'File Transfer' => 'Trasferimento file',
+        'Text' => 'Testo',
+      },
+    },
+   'StretchMode' => {
+      PrintConv => {
+        'Fixed length' => 'Lunghezza fissa',
+      },
+    },
+   'StripByteCounts' => 'Byte per striscia',
+   'StripOffsets' => 'Offset striscia',
+   'StripRowCounts' => 'Numero righe striscia',
    'Sub-location' => 'LocalitÃ ',
-   'SubSecCreateDate' => 'Data e ora di creazione dei dati digitali',
-   'SubSecDateTimeOriginal' => 'Data e ora di creazione dei dati originali',
-   'SubSecModifyDate' => 'Data e ora di modifica del file',
-   'SubSecTime' => 'Frazioni di secondo di DataTime',
-   'SubSecTimeDigitized' => 'Sottosecondi DataOraDigitalizzate',
-   'SubSecTimeOriginal' => 'Sottosecondi DataOraOriginali',
-   'SubfileType' => 'Nuovo tipo subfile',
+   'SubSecCreateDate' => 'Data di creazione',
+   'SubSecDateTimeOriginal' => 'Data/ora originali',
+   'SubSecModifyDate' => 'Data modifica',
+   'SubSecTime' => 'Sottosecondi ora',
+   'SubSecTimeDigitized' => 'Sottosecondi ora digitalizzazione',
+   'SubSecTimeOriginal' => 'Sottosecondi ora originale',
+   'SubTileBlockSize' => 'Dimensione blocco sotto-tasselli',
+   'SubfileType' => {
+      Description => 'Tipo sotto-file',
+      PrintConv => {
+        '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',
+        'TIFF-FX mixed raster content' => 'Contenuto raster misto TIFF-FX',
+        'TIFF/IT final page' => 'Pagina finale TIFF/IT',
+        'Thumbnail image' => 'Miniatura',
+        'Transparency mask' => 'Maschera trasparenza',
+        'Transparency mask of multi-page image' => 'Maschera trasparenza di immagine multi-pagina',
+        'Transparency mask of reduced-resolution image' => 'Maschera trasparenza di immagine a risoluzione ridotta',
+        'Transparency mask of reduced-resolution multi-page image' => 'Maschera trasparenza di immagine multi-pagina a risoluzione ridotta',
+        'invalid' => 'non valido',
+      },
+    },
+   'SubimageColor' => {
+      PrintConv => {
+        'RGB (uncalibrated)' => 'RGB (non calibrato)',
+        'RGB with Opacity' => 'RGB con opacitÃ ',
+        'RGB with Opacity (uncalibrated)' => 'RGB con opacitÃ  (non calibrato)',
+      },
+    },
    'Subject' => 'Soggetto',
    'SubjectArea' => 'Area soggetto',
-   'SubjectDistance' => 'Distanza dal soggetto',
+   'SubjectCode' => 'Codice sottetto',
+   'SubjectDistance' => 'Distanza soggetto',
    'SubjectDistanceRange' => {
-      Description => 'Rapporto distanza soggetto',
-      PrintConv => {
-        'Close' => 'Distanza ravvicinata',
-        'Distant' => 'Vista da lontano',
-        'Unknown' => 'Sconosciuta',
-      },
-    },
-   'SubjectLocation' => 'Area soggetto',
+      Description => 'Intervallo distanza soggetto',
+      PrintConv => {
+        'Close' => 'Vicino',
+        'Distant' => 'Lontano',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'SubjectLocation' => 'Posizione soggetto',
+   'SubjectName' => 'Nome soggetto',
    'SubjectProgram' => {
       PrintConv => {
         'None' => 'Nessuno',
         'Portrait' => 'Verticale',
+        'Sunset' => 'Tramonto',
+        'Text' => 'Testo',
       },
     },
    'SubjectReference' => 'Codice Soggetto',
+   'SubjectUnits' => {
+      PrintConv => {
+        'radians' => 'Radianti',
+      },
+    },
    'Subsystem' => {
-      PrintConv => {
-        'Unknown' => 'Sconosciuta',
+      Description => 'Sottosistema',
+      PrintConv => {
+        'EFI ROM' => 'ROM EFI',
+        'EFI application' => 'Applicazione EFI',
+        'EFI boot service' => 'Servizio di avvio EFI',
+        'EFI runtime driver' => 'Driver a runtine EFI',
+        'Native' => 'Nativo',
+        'OS/2 command line' => 'Linea di comando OS/2',
+        'POSIX command line' => 'Linea di comando POSIX',
+        'Unknown' => 'Sconosciuto',
+        'Windows command line' => 'Linea di comando Windows',
+      },
+    },
+   'SubsystemVersion' => 'Versione sottosistema',
+   'Subtitle' => 'Sottotitolo',
+   'Suffix' => 'Suffisso',
+   'SuggestedPalette' => 'Tavolozza suggerita',
+   'Summary' => 'Sommario',
+   'SuperMacro' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'SuperimposedDisplay' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
@@ -1898,11 +7147,65 @@
       },
     },
-   'T4Options' => 'Non compresso',
-   'T6Options' => 'Opzioni T6',
+   'SurroundMode' => {
+      PrintConv => {
+        'Not Dolby surround' => 'Non Dolby surround',
+        'Not indicated' => 'Non indicato',
+      },
+    },
+   'SweepPanoramaDirection' => {
+      Description => 'Direzione panoramica ad arco',
+      PrintConv => {
+        'Left' => 'Sinistra',
+        'Right' => 'Destra',
+      },
+    },
+   'SweepPanoramaSize' => 'Dimensione panoramica ad arco',
+   'SwitchToRegisteredAFPoint' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'SynchronizedLyricText' => 'Testo sincronizzato',
+   'SystemNameOrNumber' => 'Nome/numero sistema',
+   'T4Options' => {
+      Description => 'Opzioni T4',
+      PrintConv => {
+        '2-Dimensional encoding' => 'Codifica 2D',
+        'Fill bits added' => 'Bit di riempimento aggiunti',
+        'Uncompressed' => 'Non compresso',
+      },
+    },
+   'T6Options' => {
+      Description => 'Opzioni T6',
+      PrintConv => {
+        'Uncompressed' => 'Non compresso',
+      },
+    },
+   'T82Options' => 'Opzioni T82',
+   'T88Options' => 'Opzioni T88',
+   'TIFFPreview' => 'Anteprima TIFF',
+   'TIFFSummary' => 'Sommario TIFF',
+   'TIFF_FXExtensions' => {
+      Description => 'Estensioni TIFF FX',
+      PrintConv => {
+        'B&W JBIG2' => 'JBIG2 bianco e nero',
+        'JBIG2 Profile M' => 'JBIG2 TIFF FX',
+        'N Layer Profile M' => 'Livello N profilo M',
+        'Resolution/Image Width' => 'Risoluzione/larghezza immagine',
+        'Shared Data' => 'Dati condivisi',
+      },
+    },
    'Tagged' => {
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'TaggingTime' => 'Ora tag',
+   'TargetDeltaType' => {
+      PrintConv => {
+        'Absolute' => 'Assoluto',
+      },
+    },
+   'TargetPrinter' => 'Stampante di destinazione',
    'Technology' => {
       Description => 'Tecnologia',
@@ -1919,6 +7222,6 @@
         'Passive Matrix Display' => 'Display a Matrice passiva',
         'Photographic Paper Printer' => 'Stampante per Carta Fotografica',
-        'Projection Television' => 'Proiettore Televisivo',
-        'Reflective Scanner' => 'Scanner a Riflessione',
+        'Projection Television' => 'Proiettore televisivo',
+        'Reflective Scanner' => 'Scanner a riflessione',
         'Thermal Wax Printer' => 'Stampante Thermal Wax',
       },
@@ -1929,15 +7232,109 @@
       },
     },
-   'Thresholding' => 'Soglia',
+   'Temperature' => 'Temperatura',
+   'Template' => 'Modello',
+   'TermsOfUse' => 'Termini di utilizzo',
+   'TestTarget' => {
+      PrintConv => {
+        'Grayscale' => 'Scala di grigi',
+      },
+    },
+   'Text' => 'Testo',
+   'TextColor' => 'Colore testo',
+   'TextComments' => 'Testo commenti',
+   'TextEncoding' => {
+      Description => 'Codifica testo',
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'TextFace' => {
+      Description => 'Aspetto testo',
+      PrintConv => {
+        'Extend' => 'Estendi',
+        'Italic' => 'Corsivo',
+        'Shadow' => 'Ombra',
+      },
+    },
+   'TextFont' => {
+      Description => 'Carattere testo',
+      PrintConv => {
+        'System' => 'Sistema',
+      },
+    },
+   'TextLayers' => 'Livelli testo',
+   'TextSize' => 'Dimenione testo',
+   'TextStamp' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'TextString' => 'Stringa testo',
+   'TextValue' => 'Valore testo',
+   'Thresholding' => {
+      Description => 'Soglia',
+      PrintConv => {
+        'No dithering or halftoning' => 'Nessun dithering o resa a mezzi toni',
+        'Randomized dither' => 'Dither casuale',
+      },
+    },
+   'ThumbnailFileName' => 'Nome file miniatura',
+   'ThumbnailFormat' => 'Formato miniatura',
+   'ThumbnailHeight' => 'Miniatura',
    'ThumbnailImage' => 'Miniatura',
-   'ThumbnailImageSize' => 'Dimensione delle miniature',
+   'ThumbnailImageName' => 'Nome miniatura',
+   'ThumbnailImageSize' => 'Dimensione miniatura',
+   'ThumbnailImageType' => 'Tipo miniatura',
+   'ThumbnailImageValidArea' => 'Area valida miniatura',
+   'ThumbnailLength' => 'Dimensioni miniatura',
+   'ThumbnailOffset' => 'Offset miniatura',
+   'ThumbnailWidth' => 'Larghezza miniatura',
+   'Thumbnails' => 'Miniature',
+   'TileByteCounts' => 'Byte tassello',
+   'TileDepth' => 'ProfonditÃ  tassello',
+   'TileLength' => 'Lunghezza tassello',
+   'TileOffsets' => 'Offset tasselli',
+   'TileWidth' => 'Larghezza tassello',
+   'Tiles' => 'Tasselli',
+   'Time' => 'Ora',
    'TimeCreated' => 'Ora di Creazione',
-   'TimeScaleParamsQuality' => {
-      PrintConv => {
-        'Low' => 'Leggero',
-      },
-    },
    'TimeSent' => 'Ora d\'invio',
+   'TimeStamp' => 'Marcatura oraria',
+   'TimeStamp1' => 'Marcatura oraria 1',
+   'TimeZone' => 'Fuso orario',
+   'TimeZoneCity' => {
+      Description => 'CittÃ  fuso orario',
+      PrintConv => {
+        'London' => 'Londra',
+        'Tehran' => 'Teheran',
+        'n/a' => 'n/d',
+      },
+    },
+   'TimeZoneCode' => 'Codice fuso orario',
+   'TimeZoneInfo' => 'Info fuso orario',
+   'TimeZoneOffset' => 'Scostamento fuso orario',
+   'TimerFunctionButton' => {
+      PrintConv => {
+        'Self-timer' => 'Autoscatto',
+        'Shooting Mode' => 'Modo scatto',
+        'White Balance' => 'Bilanciamento del bianco',
+      },
+    },
+   'TimerLength' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'Tint' => 'Tinta',
    'Title' => 'Titolo',
+   'Title2' => 'Titolo 2',
+   'TitleKind' => 'Tipo titolo',
+   'TitleLen' => 'Lungh titolo',
+   'TitleNum' => 'Num titolo',
+   'TitleOfParts' => 'Titolo parti',
+   'TitleSortOrder' => 'Ordinamento titolo',
+   'TitlesOfParts' => 'Titoli parti',
+   'TitlesSets' => 'Insiemi di titoli',
+   'ToDoTitle' => 'Titolo da fare',
    'ToneComp' => 'Compensazione Tono',
    'ToneCurve' => {
@@ -1948,5 +7345,17 @@
    'ToneCurveActive' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'ToneCurveName' => {
+      PrintConv => {
+        'Linear' => 'Lineare',
+        'Strong Contrast' => 'Contrasto elevato',
+      },
+    },
+   'ToneCurveProperty' => {
+      PrintConv => {
+        'Linear' => 'Lineare',
+        'Shot Settings' => 'Impostazioni scatto',
       },
     },
@@ -1956,9 +7365,21 @@
         'Green' => 'Verde',
         'None' => 'Nessuno',
-        'Purple-blue' => 'Viola-Blu',
+        'Purple' => 'Porpora',
+        'Purple-blue' => 'Porpora-blu',
         'Red' => 'Rosso',
-        'Red-purple' => 'Rosso-Viola',
+        'Red-purple' => 'Rosso-porpora',
+        'Sepia' => 'Seppia',
         'Yellow' => 'Giallo',
-        'n/a' => 'Non impostato',
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectFaithful' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectLandscape' => {
+      PrintConv => {
+        'n/a' => 'n/d',
       },
     },
@@ -1967,23 +7388,120 @@
         'Green' => 'Verde',
         'None' => 'Nessuno',
+        'Purple' => 'Porpora',
+        'Sepia' => 'Seppia',
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectNeutral' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectPortrait' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectStandard' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectUnknown' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Nessuno',
+        'Purple' => 'Porpora',
+        'Sepia' => 'Seppia',
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectUserDef1' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Nessuno',
+        'Purple' => 'Porpora',
+        'Sepia' => 'Seppia',
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectUserDef2' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Nessuno',
+        'Purple' => 'Porpora',
+        'Sepia' => 'Seppia',
+        'n/a' => 'n/d',
+      },
+    },
+   'ToningEffectUserDef3' => {
+      PrintConv => {
+        'Green' => 'Verde',
+        'None' => 'Nessuno',
+        'Purple' => 'Porpora',
+        'Sepia' => 'Seppia',
+        'n/a' => 'n/d',
+      },
+    },
+   'ToolName' => 'Nome strumento',
+   'ToolVersion' => 'Versione strumento',
+   'TotalFrames' => 'Frame totali',
+   'Track' => 'Traccia',
+   'TrackProperty' => {
+      PrintConv => {
+        'Read only' => 'Sola lettura',
       },
     },
    'TransferFunction' => 'Funzione di trasferimento',
+   'TransferRange' => 'Intervallo di trasferimento',
+   'Transform' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'Transformation' => {
-      PrintConv => {
-        'Horizontal (normal)' => '0Â° (alto/sinistra)',
-        'Mirror horizontal' => 'Rifletti in orizzontale',
-        'Mirror horizontal and rotate 270 CW' => 'Rifletti in orizzontale e ruota di 270Â° in senso orario',
-        'Mirror horizontal and rotate 90 CW' => 'Rifletti in orizzontale e ruota di 90Â° in senso orario',
-        'Mirror vertical' => 'Rifletti in verticale',
-        'Rotate 180' => '180Â° (basso/destra)',
+      Description => 'Trasformazione',
+      PrintConv => {
+        'Horizontal (normal)' => 'Orizzontale (normale)',
+        'Mirror horizontal' => 'Rifletti orizzontalmente',
+        'Mirror horizontal and rotate 270 CW' => 'Rifletti orizzontalmente e ruota di 270Â° in senso orario',
+        'Mirror horizontal and rotate 90 CW' => 'Rifletti orizzontalmente e ruota di 90Â° in senso orario',
+        'Mirror vertical' => 'Rifletti verticalmente',
+        'Rotate 180' => 'Ruota di 180Â°',
         'Rotate 270 CW' => 'Ruota di 270Â° in senso orario',
-        'Rotate 90 CW' => '90Â° senso antiorario (destra/alto)',
+        'Rotate 90 CW' => 'Ruota di 90Â° senso orario',
       },
     },
    'TransmissionReference' => 'Riferimento trasmissione',
+   'TransparencyIndicator' => 'Indicatore trasparenza',
+   'TrapIndicator' => 'Indicatore trap',
    'Trapped' => {
       PrintConv => {
-        'Unknown' => 'Sconosciuta',
+        'False' => 'Falso',
+        'Unknown' => 'Sconosciuto',
+      },
+    },
+   'TungstenAWB' => {
+      PrintConv => {
+        'Strong Correction' => 'Correzione elevata',
+      },
+    },
+   'TxFace' => 'Stile carattere testo',
+   'TxFont' => 'Numero carattere',
+   'TxSize' => 'Dimenione testo',
+   'UIC1Tag' => 'Tag UIC1',
+   'UIC2Tag' => 'Tag UIC2',
+   'UIC3Tag' => 'Tag UIC3',
+   'UIC4Tag' => 'Tag UIC4',
+   'USPTOOriginalContentType' => {
+      PrintConv => {
+        'Color' => 'Colore',
+        'Grayscale' => 'Scala di grigi',
+        'Text or Drawing' => 'Testo o disegno',
+      },
+    },
+   'UV-IRFilterCorrection' => {
+      PrintConv => {
+        'Not Active' => 'Non attivo',
       },
     },
@@ -1991,9 +7509,11 @@
       Description => 'Non compresso',
       PrintConv => {
-        'Yes' => 'Si',
-      },
-    },
-   'UniqueCameraModel' => 'Nome Unico Modello Fotocamera',
+        'Yes' => 'SÃ¬',
+      },
+    },
+   'UninitializedDataSize' => 'Dimensione dati non inizializzati',
+   'UniqueCameraModel' => 'Modello unico fotocamera',
    'UniqueDocumentID' => 'ID Unico del Documento',
+   'Units' => 'UnitÃ ',
    'Unknown' => 'Sconosciuto',
    'Unsharp1Color' => {
@@ -2025,8 +7545,13 @@
       },
     },
+   'UnsharpMask' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'Urgency' => {
       Description => 'Urgenza',
       PrintConv => {
-        '0 (reserved)' => '0 (riservato per usi futuri)',
+        '0 (reserved)' => '0 (riservato)',
         '1 (most urgent)' => '1 (molto urgente)',
         '5 (normal urgency)' => '5 (urgenza normale)',
@@ -2035,4 +7560,19 @@
       },
     },
+   'UsableMeteringModes' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'UsableShootingModes' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'UserAccess' => {
+      PrintConv => {
+        'Print' => 'Stampa',
+      },
+    },
    'UserComment' => 'Commento utente',
    'UserDef1PictureStyle' => {
@@ -2052,4 +7592,11 @@
         'Landscape' => 'Orizzontale',
         'Portrait' => 'Verticale',
+      },
+    },
+   'UserDefinedText' => 'Testo personalizzato',
+   'UserDefinedURL' => 'URL personalizzato',
+   'VFDisplayIllumination' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
       },
     },
@@ -2057,27 +7604,134 @@
    'VRInfo' => 'Info Riduzione Vibrazione',
    'VRInfoVersion' => 'Info Versione VR',
-   'Version' => 'Versione',
-   'VibrationReduction' => 'Riduzione Vibrazione',
+   'VR_0x66' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'Value' => 'Valore',
+   'VariousModes' => 'Modi vari',
+   'VariousModes2' => 'Modi vari 2',
+   'Version' => 'Numero versione immagine',
+   'Version2' => 'Versione 2',
+   'VersionBF' => 'Versione BF',
+   'VersionCreateDate' => 'Data creazione versione',
+   'VersionID' => 'ID versione',
+   'VersionIdentifier' => 'Identificativo versione',
+   'VersionInfo' => 'Info versione',
+   'VersionModifyDate' => 'Data modifica versione',
+   'VersionNumber' => 'Numero versione',
+   'VersionNumberString' => 'Stringa numero versione',
+   'VersionTitle' => 'Titolo versione',
+   'VersionYear' => 'Anno versione',
+   'Versions' => 'Versioni',
+   'VerticalCSType' => {
+      PrintConv => {
+        'Caspian Sea' => 'Mar Caspio',
+        'WGS 84 ellipsoid' => 'Ellissoide WGS 84',
+      },
+    },
+   'VerticalUnits' => 'UnitÃ  verticali',
+   'VibrationReduction' => {
+      Description => 'Riduzione vibrazione',
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'VideoAlphaMode' => {
+      PrintConv => {
+        'None' => 'Nessuno',
+      },
+    },
+   'VideoAttributes' => {
+      PrintConv => {
+        'Encrypted' => 'Crittografato',
+      },
+    },
+   'VideoBitrate' => 'Bitrate video',
    'VideoCardGamma' => 'Gamma della Scheda Video',
+   'VideoCodec' => 'Codec video',
+   'VideoCodecDescription' => 'Descrizione codec video',
+   'VideoCodecID' => 'ID codec video',
+   'VideoCodecInfo' => 'Info codec video',
+   'VideoCodecName' => 'Nome codec video',
+   'VideoFieldOrder' => {
+      PrintConv => {
+        'Progressive' => 'Progressivo',
+      },
+    },
+   'VideoQuality' => {
+      PrintConv => {
+        'Low' => 'Basso',
+      },
+    },
+   'VideoScanType' => {
+      PrintConv => {
+        'Progressive' => 'Progressivo',
+      },
+    },
+   'VideoStreamType' => {
+      PrintConv => {
+        'Reserved' => 'Riservato',
+      },
+    },
+   'ViewInfoDuringExposure' => {
+      PrintConv => {
+        'Enable' => 'Abilita',
+      },
+    },
+   'ViewfinderWarning' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'ViewingCondDesc' => 'Descrizione Condizioni di Visualizzazione',
+   'ViewingMode2' => {
+      PrintConv => {
+        'n/a' => 'n/d',
+      },
+    },
    'VignetteControl' => {
       PrintConv => {
+        'Low' => 'Basso',
         'Normal' => 'Normale',
+        'Off' => 'Spento',
+      },
+    },
+   'VignettingCorrection' => {
+      PrintConv => {
+        'Off' => 'Spento',
+        'n/a' => 'n/d',
+      },
+    },
+   'VirtualImageHeight' => 'Altezza immagine virtuale',
+   'VirtualImageWidth' => 'Larghezza immagine virtuale',
+   'VirtualPageUnits' => 'UnitÃ  pagina virtuale',
+   'VoiceMemo' => {
+      PrintConv => {
+        'Off' => 'Spento',
       },
     },
    'WBAdjLighting' => {
       PrintConv => {
-        'Daylight' => 'Luce del giorno',
+        'Daylight (cloudy)' => 'Luce del giorno (2)',
+        'Daylight (direct sunlight)' => 'Luce del giorno (0)',
+        'Daylight (shade)' => 'Luce del giorno (1)',
         'None' => 'Nessuno',
       },
     },
+   'WBBracketMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
    'WBFineTuneActive' => {
       PrintConv => {
-        'Yes' => 'Si',
+        'Yes' => 'SÃ¬',
       },
     },
    'WCSProfiles' => 'Profilo Windows Color System',
    'WhiteBalance' => {
-      Description => 'Bilanciamento del Bianco',
+      Description => 'Bilanciamento del bianco',
       PrintConv => {
         'Auto' => 'Equilibrio del bianco automatico',
@@ -2098,16 +7752,32 @@
         'Shade' => 'Ombrato',
         'Tungsten' => 'Tungsteno (luce incandescente)',
-        'Unknown' => 'Sconosciuta',
+        'Unknown' => 'Sconosciuto',
         'Warm White Fluorescent' => 'Luce fluorescente bianca calda',
         'White Fluorescent' => 'Fluorescente bianca',
       },
     },
+   'WhiteBalance2' => 'Bilanciamento del bianco 2',
    'WhiteBalanceAdj' => {
+      Description => 'Adattamento bilanciamento bianco',
       PrintConv => {
         'Cloudy' => 'Nuvoloso',
         'Daylight' => 'Luce del giorno',
         'Fluorescent' => 'Fluorescente',
+        'Off' => 'Spento',
         'Shade' => 'Ombrato',
+        'Shot Settings' => 'Impostazioni scatto',
         'Tungsten' => 'Tungsteno (luce incandescente)',
+      },
+    },
+   'WhiteBalanceAutoAdjustment' => {
+      Description => 'Adattamento automatico bilanciamento bianco',
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'WhiteBalanceBracketing' => {
+      PrintConv => {
+        'Low' => 'Basso',
+        'Off' => 'Spento',
       },
     },
@@ -2115,5 +7785,5 @@
    'WhiteBalanceMode' => {
       PrintConv => {
-        'Unknown' => 'Sconosciuta',
+        'Unknown' => 'Sconosciuto',
       },
     },
@@ -2129,12 +7799,41 @@
       },
     },
-   'WhiteLevel' => 'Livello Bianco',
-   'WhitePoint' => 'Cromatismo del punto bianco',
+   'WhiteBalanceSetting' => {
+      PrintConv => {
+        'Fluorescent (+1)' => 'Fluorescente (+1)',
+        'Fluorescent (+2)' => 'Fluorescente (+2)',
+        'Fluorescent (+3)' => 'Fluorescente (+3)',
+        'Fluorescent (-1)' => 'Fluorescente (-1)',
+        'Fluorescent (-2)' => 'Fluorescente (-2)',
+        'Fluorescent (-3)' => 'Fluorescente (-3)',
+        'Fluorescent (0)' => 'Fluorescente (0)',
+        'Shade (+1)' => 'Ombrato (+1)',
+        'Shade (+2)' => 'Ombrato (+2)',
+        'Shade (+3)' => 'Ombrato (+3)',
+        'Shade (-1)' => 'Ombrato (-1)',
+        'Shade (-2)' => 'Ombrato (-2)',
+        'Shade (-3)' => 'Ombrato (-3)',
+        'Shade (0)' => 'Ombrato (0)',
+      },
+    },
+   'WhiteLevel' => 'Livello bianco',
+   'WhitePoint' => 'Punto bianco',
+   'WideRange' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'WidthResolution' => 'Risoluzione larghezza',
    'Writer-Editor' => 'Autore Didascalia/Descrizione',
+   'XMethod' => {
+      PrintConv => {
+        'No Magnification' => 'Nessun ingrandimento',
+      },
+    },
    'XPAuthor' => 'Autore',
-   'XPComment' => 'Commento',
-   'XPKeywords' => 'Parole Chiave',
-   'XPSubject' => 'Soggetto',
-   'XPTitle' => 'Titolo',
+   'XPComment' => 'Commento XP',
+   'XPKeywords' => 'Parole chiave XP',
+   'XPSubject' => 'Soggetto XP',
+   'XPTitle' => 'Titolo XP',
    'XPosition' => 'Posizione X',
    'XResolution' => 'Risoluzione orizzontale immagine',
@@ -2148,14 +7847,43 @@
     },
    'YCbCrSubSampling' => 'Indice sottocampionamento da Y a C',
+   'YMethod' => {
+      PrintConv => {
+        'No Magnification' => 'Nessun ingrandimento',
+      },
+    },
    'YPosition' => 'Posizione Y',
    'YResolution' => 'Risoluzione verticale immagine',
+   'Year' => 'Anno',
+   'ZipCompression' => {
+      PrintConv => {
+        'None' => 'Nessuno',
+        'Reduced with compression factor 1' => 'Ridotto con fattore compressione 1',
+        'Reduced with compression factor 2' => 'Ridotto con fattore compressione 2',
+        'Reduced with compression factor 3' => 'Ridotto con fattore compressione 3',
+        'Reduced with compression factor 4' => 'Ridotto con fattore compressione 4',
+      },
+    },
    'ZoneMatching' => {
       Description => 'Adeguamento zona',
       PrintConv => {
         'High Key' => 'Hi',
-        'ISO Setting Used' => 'Disattivata',
+        'ISO Setting Used' => 'Impostazione ISO usata',
         'Low Key' => 'Lo',
       },
     },
+   'ZoneMatchingMode' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ZoneMatchingOn' => {
+      PrintConv => {
+        'Off' => 'Spento',
+      },
+    },
+   'ZoomCenter' => 'Centro zoom',
+   'ZoomFactor' => 'Fattore di zoom',
+   'ZoomPos' => 'Posizione zoom',
+   'iTunesU' => 'ITunes U',
 );
 
@@ -2176,5 +7904,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -2183,6 +7911,6 @@
 =head1 ACKNOWLEDGEMENTS
 
-Thanks to Jens Duttke, Ferdinando Agovino and Emilio Dati for providing this
-translation.
+Thanks to Jens Duttke, Ferdinando Agovino, Emilio Dati and Michele Locati
+for providing this translation.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ja.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ja.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ja.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.17';
+$VERSION = '1.25';
 
 %Image::ExifTool::Lang::ja::Translate = (
@@ -238,10 +238,4 @@
 å ±ããŒãžã§ã³',
    'AFIntegrationTime' => 'AFéç©æé',
-   'AFMicroAdjActive' => {
-      PrintConv => {
-        'No' => 'ããã',
-        'Yes' => 'ã¯ã',
-      },
-    },
    'AFMicroadjustment' => {
       Description => 'AFãã€ã¯ã­ã¢ãžã£ã¹ãã¡ã³ã',
@@ -676,4 +670,5 @@
       },
     },
+   'AutoBracketingSet' => 'ãªãŒããã©ã±ããèš­å®',
    'AutoExposureBracketing' => {
       Description => 'ãã©ãã·ã¥ãã€ã¢ã¹',
@@ -804,5 +799,10 @@
     },
    'BestQualityScale' => 'é«åè³ªã¹ã±ãŒã«',
-   'BestShotMode' => 'ãã¹ãã·ã§ããã¢ãŒã',
+   'BestShotMode' => {
+      Description => 'ãã¹ãã·ã§ããã¢ãŒã',
+      PrintConv => {
+        'Off' => 'ãªã',
+      },
+    },
    'BitDepth' => 'ãããæ·±åºŠ',
    'BitsPerComponent' => 'ã³ã³ããŒãã³ããããããã',
@@ -860,4 +860,5 @@
       Description => 'ãã©ã¹ãã¢ãŒã',
       PrintConv => {
+        'Auto Exposure Bracketing (AEB)' => 'ç¡é',
         'Infinite' => 'ç¡é',
         'Off' => 'ãªã',
@@ -1199,8 +1200,11 @@
         'Clear' => 'ã¯ãªã¢ãŒ',
         'Deep' => 'ãã£ãŒã',
+        'Evening' => 'å€çŒã',
         'Landscape' => 'é¢šæ¯',
         'Light' => 'ã©ã€ã',
         'Natural' => 'ããã¥ã©ã«',
         'Natural color' => 'ããã¥ã©ã«ã«ã©ãŒ',
+        'Natural sRGB' => 'ããã¥ã©ã« sRGB',
+        'Natural+ sRGB' => 'ããã¥ã©ã«+ sRGB',
         'Neutral' => 'ãã¥ãŒãã©ã«',
         'Night Portrait' => 'äººç©å€æ¯',
@@ -1248,4 +1252,5 @@
       Description => 'è²ç©ºé',
       PrintConv => {
+        'ICC Profile' => 'ICCãã­ãã£ãŒã«',
         'Monochrome' => 'ã¢ãããŒã³',
         'Uncalibrated' => 'æªèª¿æŽ',
@@ -1356,5 +1361,5 @@
       PrintConv => {
         'JPEG' => 'JPEGå§çž®ç',
-        'JPEG (old-style)' => 'JPEG(å€ãåœ¢åŒ)',
+        'JPEG (old-style)' => 'JPEG (å€ãåœ¢åŒ)',
         'None' => 'ç¡ã',
         'Uncompressed' => 'éå§çž®',
@@ -1404,14 +1409,17 @@
       Description => 'ã³ã³ãã©ã¹ã',
       PrintConv => {
+        '+1 (medium high)' => '+1 (å°ãé«ã)',
+        '+2 (high)' => '+2 (ããŒã)',
+        '+3 (very high)' => '+3 (ããªãé«ã)',
+        '-1 (medium low)' => '-1 (å°ãäœã)',
+        '-2 (low)' => '-2 (ãœãã)',
+        '-3 (very low)' => '-3 (ããªãäœã)',
+        '0 (normal)' => '0 (ã¹ã¿ã³ããŒã)',
         'Film Simulation' => 'ãã£ã«ã ã·ãã¥ã¬ãŒã·ã§ã³',
         'High' => 'ããŒã',
         'Low' => 'ãœãã',
-        'Med High' => 'å°ãé«ã',
-        'Med Low' => 'å°ãäœã',
         'Medium High' => 'å°ãé«ã',
         'Medium Low' => 'å°ãäœã',
         'Normal' => 'ã¹ã¿ã³ããŒã',
-        'Very High' => 'ããªãé«ã',
-        'Very Low' => 'ããªãäœã',
       },
     },
@@ -1458,10 +1466,34 @@
    'Country-PrimaryLocationCode' => 'ISOåœã³ãŒã',
    'Country-PrimaryLocationName' => 'åœ',
+   'CountryCode' => 'æ®åœ±åœã³ãŒã',
    'CreateDate' => 'ããžã¿ã«ããŒã¿äœææ¥æ',
    'CreationDate' => 'äœææ¥æ',
+   'CreativeStyle' => {
+      Description => 'ã¯ãªãšã€ãã£ãã¹ã¿ã€ã«',
+      PrintConv => {
+        'Autumn' => 'ç§',
+        'Autumn Leaves' => 'çŽ
+è',
+        'B&W' => 'çœé»',
+        'Clear' => 'ã¯ãªã¢ãŒ',
+        'Deep' => 'ãã£ãŒã',
+        'Landscape' => 'é¢šæ¯',
+        'Light' => 'ã©ã€ã',
+        'Neutral' => 'ãã¥ãŒãã©ã«',
+        'Night View/Portrait' => 'å€æ¯/å€æ¯ããŒãã¬ãŒã',
+        'Portrait' => 'ããŒãã¬ãŒã',
+        'Sepia' => 'ã»ãã¢',
+        'Standard' => 'ã¹ã¿ã³ããŒã',
+        'Sunset' => 'å€æ¥',
+        'Vivid' => 'ãããã',
+      },
+    },
    'Creator' => 'è£œäœè
 ',
    'CreatorAddress' => 'ã¯ãªãšãŒã¿ãŒã-ãäœæ',
    'CreatorCity' => 'ã¯ãªãšãŒã¿ãŒã-ãè¡',
+   'CreatorContactInfo' => 'äœæè
+ã®ã³ã³ ã¿ã¯ãå
+',
    'CreatorCountry' => 'ã¯ãªãšãŒã¿ãŒã-ãåœ',
    'CreatorPostalCode' => 'ã¯ãªãšãŒã¿ãŒã-ãéµäŸ¿çªå·',
@@ -1495,4 +1527,6 @@
    'Custom1' => 'ã«ã¹ã¿ã 1',
    'Custom2' => 'ã«ã¹ã¿ã 2',
+   'Custom3' => 'ã«ã¹ã¿ã 3',
+   'Custom4' => 'ã«ã¹ã¿ã 4',
    'CustomRendered' => {
       Description => 'ã«ã¹ã¿ã ç»ååŠç',
@@ -1641,4 +1675,5 @@
     },
    'DistortionCorrection' => {
+      Description => 'æ­ªæ²ä¿®æ­£',
       PrintConv => {
         'Off' => 'ãªã',
@@ -1869,4 +1904,5 @@
 ',
    'EpsonSoftware' => 'ãšããœã³ãœãããŠã§ã¢',
+   'Equipment' => 'ã€ã¯ã€ããã¡ã³ãIFDãã€ã³ã¿ãŒ',
    'EquipmentVersion' => 'ã€ã¯ã€ããã¡ã³ãããŒãžã§ã³',
    'ExcursionTolerance' => 'æ¯å¹
@@ -1950,4 +1986,5 @@
         'Shutter speed priority AE' => 'ã·ã£ãã¿ãŒåªå
 ',
+        'n/a' => 'æªèš­å®',
       },
     },
@@ -2068,4 +2105,5 @@
    'Face7Position' => 'é¡7äœçœ®',
    'Face8Position' => 'é¡8äœçœ®',
+   'Face9Position' => 'é¡9äœçœ®',
    'FaceDetect' => {
       Description => 'é¡èªè­',
@@ -2077,4 +2115,12 @@
    'FaceDetectArea' => 'é¡ãšãªã¢',
    'FaceDetectFrameSize' => 'ãã¬ãŒã ãµã€ãº',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => 'æ°Žå¹³ïŒæšæºïŒ',
+        'Rotate 180' => '180åºŠåè»¢',
+        'Rotate 270 CW' => '270åºŠåè»¢ CW',
+        'Rotate 90 CW' => '90åºŠåè»¢ CW',
+      },
+    },
    'FacesDetected' => 'é¡èªè­',
    'FastSeek' => {
@@ -2126,4 +2172,5 @@
    'FileType' => 'ãã¡ã€ã«ã¿ã€ã',
    'FileVersion' => 'ãã¡ã€ã«åœ¢åŒããŒãžã§ã³',
+   'Filename' => 'ãã¡ã€ã«å',
    'FillFlashAutoReduction' => {
       Description => 'æ¥äž­ã·ã³ã¯ã­ã»ã¹ãã­ãé²åºèªåäœæžå¶åŸ¡',
@@ -2314,4 +2361,5 @@
    'FlashExposureBracketValue' => 'ãã©ãã·ã¥é²åºãã©ã±ããå€',
    'FlashExposureComp' => 'ãã©ãã·ã¥é²åºè£æ­£',
+   'FlashExposureComp2' => 'ãã©ãã·ã¥é²åºè£æ­£',
    'FlashExposureCompSet' => 'ã¹ãã­ãé²åºè£æ­£èš­å®',
    'FlashExposureLock' => {
@@ -2489,4 +2537,5 @@
     },
    'FlashOutput' => 'ãã©ãã·ã¥åºå',
+   'FlashRemoteControl' => 'ãã©ãã·ã¥ãªã¢ãŒãã³ã³ãã­ãŒã«',
    'FlashSerialNumber' => 'ãã©ãã·ã¥ã·ãªã¢ã«çªå·',
    'FlashSetting' => 'ãã©ãã·ã¥èš­å®',
@@ -2691,7 +2740,10 @@
    'ForwardMatrix1' => 'åè¡å1',
    'ForwardMatrix2' => 'åè¡å2',
+   'FrameHeight' => 'ãã¬ãŒã é«',
    'FrameNumber' => 'ãã¬ãŒã çªå·',
    'FrameRate' => 'ãã¬ãŒã ã¬ãŒã',
    'FrameSize' => 'ãã¬ãŒã ãµã€ãº',
+   'FrameWidth' => 'ãã¬ãŒã å¹
+',
    'FreeByteCounts' => 'ããªãŒãã€ãæ°',
    'FreeMemoryCardImages' => 'ããªãŒã¡ã¢ãªãŒã«ãŒãã€ã¡ãŒãž',
@@ -2726,4 +2778,5 @@
    'GEMInfo' => 'GEMæ
 å ±',
+   'GEModel' => 'ã¢ãã«',
    'GIFVersion' => 'GIFããŒãžã§ã³',
    'GPSAltitude' => 'é«åºŠ',
@@ -2883,4 +2936,5 @@
    'GeoTiffDoubleParams' => 'ãžãªããã«èš­å®ã¿ã°',
    'Gradation' => 'ã°ã©ããŒã·ã§ã³',
+   'GrayPoint' => 'ã°ã¬ãŒãã€ã³ã',
    'GrayResponseCurve' => 'ã°ã¬ãŒåå¿æ²ç·',
    'GrayResponseUnit' => {
@@ -2894,4 +2948,5 @@
       },
     },
+   'GrayScale' => 'ã°ã¬ãŒã¹ã±ãŒã«',
    'GrayTRC' => 'ç°è²èª¿å¢æ®æ²ç·',
    'GreenMatrixColumn' => 'ç·è²ãããªãã¯ã¹å',
@@ -2921,4 +2976,7 @@
       Description => 'é«æåºŠãã€ãºãªãã¯ã·ã§ã³',
       PrintConv => {
+        '+2 (strong)' => '+2 (åŒ·)',
+        '-2 (weak)' => '-2 (åŒ±)',
+        '-4 (weakest)' => '-4 (åŸ®åŒ±)',
         'Auto' => 'ãªãŒã',
         'High' => 'é«ã',
@@ -2958,4 +3016,5 @@
    'HueAdjustment' => 'è²çžèª¿æŽ',
    'HueSetting' => 'è²çžèš­å®',
+   'ICCProfile' => 'ICCãã­ãã£ãŒã«',
    'ICC_Profile' => 'ICCå
 ¥åè²ãã­ãã£ãŒã«',
@@ -2971,4 +3030,5 @@
    'ISO' => 'ISOã¹ããŒãã¬ãŒã',
    'ISO2' => 'ISOïŒ2ïŒ',
+   'ISOAuto' => 'ISOãªãŒã',
    'ISODisplay' => 'ISOè¡šç€º',
    'ISOExpansion' => {
@@ -3096,4 +3156,5 @@
       },
     },
+   'ImageProcessing' => 'ã€ã¡ãŒãžåŠç',
    'ImageProcessingVersion' => 'ç»ååŠçããŒãžã§ã³',
    'ImageQuality' => {
@@ -3172,4 +3233,5 @@
    'Instructions' => 'è©³çŽ°',
    'IntellectualGenre' => 'ã€ã³ããªãžã£ã³ã«',
+   'IntelligentAuto' => 'ã€ã³ããªãžã§ã³ããªãŒã',
    'IntensityStereo' => {
       PrintConv => {
@@ -3259,5 +3321,13 @@
    'JPEGProc' => 'JPEGåŠç',
    'JPEGQTables' => 'JPEG Q ããŒãã«',
-   'JPEGQuality' => 'JPEGãåè³ª',
+   'JPEGQuality' => {
+      Description => 'JPEGãåè³ª',
+      PrintConv => {
+        'Extra Fine' => 'ãšã¯ã¹ãã©ãã¡ã€ã³',
+        'Fine' => 'ãã¡ã€ã³',
+        'Standard' => 'ããŒãã«',
+        'n/a' => 'æªèš­å®',
+      },
+    },
    'JPEGRestartInterval' => 'JPEGåééé',
    'JPEGTables' => 'JPEGããŒãã«',
@@ -3446,7 +3516,7 @@
         'Off' => 'ãªã',
         'On' => 'ãªã³',
-      },
-    },
-   'LongFocal' => 'æé·çŠç¹',
+        'n/a' => 'æªèš­å®',
+      },
+    },
    'LookupTable' => 'ã«ãã¯ã¢ããããŒãã«',
    'LoopStyle' => {
@@ -3464,4 +3534,5 @@
     },
    'MB-D10Batteries' => 'MB-D10é»æºã¿ã€ã',
+   'MB-D10BatteryType' => 'MB-D10é»æºã¿ã€ã',
    'MB-D80Batteries' => 'MB-D80ããããªãŒ',
    'MIEVersion' => 'MIEããŒãžã§ã³',
@@ -3482,4 +3553,5 @@
         'On' => 'ãªã³',
         'Super Macro' => 'ã¹ãŒããŒãã¯ã­',
+        'n/a' => 'æªèš­å®',
       },
     },
@@ -3546,4 +3618,6 @@
    'MasterDocumentID' => 'ãã¹ã¿ææžID',
    'MasterGain' => 'ãã¹ã¿ãŒã²ã€ã³',
+   'MatrixMetering' => 'åå²æž¬å
+',
    'Matteing' => 'ãããã³ã°',
    'MaxAperture' => 'æå€§çµã',
@@ -3675,4 +3749,5 @@
    'Model2' => 'ç»åå
 ¥åæ©åšã¢ãã«(2)',
+   'ModelID' => 'ã¢ãã«ID',
    'ModelTiePoint' => 'ã¢ãã«ææãã€ã³ãã¿ã°',
    'ModelTransform' => 'ã¢ãã«å€åã¿ã°',
@@ -3855,4 +3930,5 @@
     },
    'MyColorMode' => {
+      Description => 'ãã€ã«ã©ãŒã¢ãŒã',
       PrintConv => {
         'B&W' => 'çœé»',
@@ -3889,4 +3965,5 @@
       },
     },
+   'NEFLinearizationTable' => 'ç·åœ¢åè¡š',
    'NamedColor2' => 'è²åç§°2',
    'NativeDisplayInfo' => 'ãã€ãã£ããã£ã¹ãã¬ã€æ
@@ -4015,4 +4092,6 @@
    'PentaxModelID' => 'ãã³ã¿ãã¯ã¹ã¢ãã«',
    'PentaxVersion' => 'ãã³ã¿ãã¯ã¹ããŒãžã§ã³',
+   'People' => 'äººã
+',
    'PhaseDetectAF' => {
       Description => 'ãªãŒããã©ãŒã«ã¹',
@@ -4314,4 +4393,5 @@
    'PreCaptureFrames' => 'ãã¬ã­ã£ããã£ãŒãã¬ãŒã ',
    'Predictor' => 'ææš',
+   'Preview' => 'ãã¬ãã¥ãŒIFDãã€ã³ã¿ãŒ',
    'Preview0' => 'ãã¬ãã¥ãŒ0',
    'Preview1' => 'ãã¬ãã¥ãŒ1',
@@ -4456,6 +4536,8 @@
         'RAW + JPEG' => 'RAW+JPEG',
         'Standard' => 'ã¹ã¿ã³ããŒã',
-      },
-    },
+        'n/a' => 'æªèš­å®',
+      },
+    },
+   'Quality2' => 'åè³ª',
    'QualityMode' => {
       Description => 'åè³ªã¢ãŒã',
@@ -4467,4 +4549,5 @@
     },
    'QuantizationMethod' => 'éå­åæ¹æ³',
+   'QuickAdjust' => 'ã¯ã€ãã¯èª¿æŽ',
    'QuickControlDialInMeter' => {
       Description => 'æž¬å
@@ -4576,6 +4659,9 @@
    'RawImageCenter' => 'RAWã€ã¡ãŒãžã»ã³ã¿ãŒ',
    'RawImageDigest' => 'RAWã€ã¡ãŒãžèŠçŽ',
+   'RawImageHeight' => 'ã€ã¡ãŒãžé«ã',
    'RawImageSegmentation' => 'RAWã€ã¡ãŒãžéšåçªå·',
    'RawImageSize' => 'RAWã€ã¡ãŒãžãµã€ãº',
+   'RawImageWidth' => 'ã€ã¡ãŒãžå¹
+',
    'RawInfoVersion' => 'RAWæ
 å ±ããŒãžã§ã³',
@@ -4779,9 +4865,19 @@
       Description => 'åœ©åºŠ',
       PrintConv => {
+        '+1 (medium high)' => '+1 (å°ãé«ã)',
+        '+2 (high)' => '+2 (ããŒã)',
+        '+3 (very high)' => '+3 (ããªãé«ã)',
+        '+4 (highest)' => '+4',
+        '+4 (maximum)' => '+4',
+        '-1 (medium low)' => '-1 (å°ãäœã)',
+        '-2 (low)' => '-2 (ãœãã)',
+        '-3 (very low)' => '-3 (ããªãäœã)',
+        '-4 (lowest)' => '-4',
+        '-4 (minimum)' => '-4',
+        '0 (normal)' => '0 (ã¹ã¿ã³ããŒã)',
+        'B&W' => 'é»ïŒçœ',
         'Film Simulation' => 'ãã£ã«ã ã·ãã¥ã¬ãŒã·ã§ã³',
         'High' => 'é«ãåœ©åºŠ',
         'Low' => 'äœãåœ©åºŠ',
-        'Med High' => 'å°ãé«ã',
-        'Med Low' => 'å°ãäœã',
         'Medium High' => 'å°ãé«ã',
         'Medium Low' => 'å°ãäœã',
@@ -4789,6 +4885,4 @@
         'None (B&W)' => 'ç¡ãïŒé»ïŒçœïŒ',
         'Normal' => 'æšæº',
-        'Very High' => 'ããªãé«ã',
-        'Very Low' => 'ããªãäœã',
       },
     },
@@ -5025,4 +5119,5 @@
    'SensorWidth' => 'ã»ã³ãµãŒå¹
 ',
+   'Sequence' => 'ã·ãŒã±ã³ã¹',
    'SequenceNumber' => 'ã·ãŒã±ã³ã¹çªå·',
    'SequenceShotInterval' => 'ã·ãŒã±ã³ã¹ã·ã§ããã€ã³ã¿ãŒãã«',
@@ -5111,9 +5206,18 @@
       Description => 'ã·ã£ãŒããã¹',
       PrintConv => {
+        '+1 (medium hard)' => '+1 (å°ãããŒã)',
+        '+2 (hard)' => '+2 (ããŒã)',
+        '+3 (very hard)' => '+3 (ããªãããŒã)',
+        '+4 (hardest)' => '+4',
+        '+4 (maximum)' => '+4',
+        '-1 (medium soft)' => '-1 (ããã«ãœãã)',
+        '-2 (soft)' => '-2 (ãœãã)',
+        '-3 (very soft)' => '-3 (ããªããœãã)',
+        '-4 (minimum)' => '-4',
+        '-4 (softest)' => '-4',
+        '0 (normal)' => '0 (ããŒãã«)',
         'Film Simulation' => 'ãã£ã«ã ã·ãã¥ã¬ãŒã·ã§ã³',
         'Hard' => 'ããŒã',
         'Hard2' => 'ããŒã2',
-        'Med Hard' => 'å°ãããŒã',
-        'Med Soft' => 'å°ããœãã',
         'Medium Hard' => 'ããã«ããŒã',
         'Medium Soft' => 'ããã«ãœãã',
@@ -5122,6 +5226,4 @@
         'Soft' => 'ãœãã',
         'Soft2' => 'ãœãã2',
-        'Very Hard' => 'ããªãããŒã',
-        'Very Soft' => 'ããªããœãã',
         'n/a' => 'è©²åœç¡ã',
       },
@@ -5211,5 +5313,4 @@
     },
    'ShortDocumentID' => 'ç­ææžID',
-   'ShortFocal' => 'æç­çŠç¹',
    'ShortOwnerName' => 'ç­ããªãŒããŒå',
    'ShortReleaseTimeLag' => {
@@ -5327,4 +5428,5 @@
    'SpecialMode' => 'ã¹ãã·ã£ã«ã¢ãŒã',
    'SpectralSensitivity' => 'ã¹ãã¯ãã«æåºŠ',
+   'Sport' => 'ã¹ããŒã',
    'SpotFocusPointX' => 'ã¹ããããã©ãŒã«ã¹ãã€ã³ãX',
    'SpotFocusPointY' => 'ã¹ããããã©ãŒã«ã¹ãã€ã³ãY',
@@ -5369,4 +5471,5 @@
    'Subject' => 'ãµããžã§ã¯ã',
    'SubjectArea' => 'å¯Ÿè±¡é å',
+   'SubjectCode' => 'ãµããžã§ã¯ãã³ãŒã',
    'SubjectDistance' => 'å¯Ÿè±¡è·é¢',
    'SubjectDistanceRange' => {
@@ -5501,4 +5604,5 @@
    'TimeStamp' => 'ã¿ã€ã ã¹ã¿ã³ã',
    'TimeStamp1' => 'ã¿ã€ã ã¹ã¿ã³ã1',
+   'TimeZone' => 'ã¿ã€ã ãŸãŒã³',
    'TimeZoneOffset' => 'ã¿ã€ã ãŸãŒã³ãªãã»ãã',
    'TimerFunctionButton' => {
@@ -5519,5 +5623,4 @@
       },
     },
-   'Timezone' => 'ã¿ã€ã ãŸãŒã³',
    'Title' => 'ã¿ã€ãã«',
    'ToneComp' => 'ããŒã³è£æ­£',
@@ -5818,10 +5921,28 @@
 ',
         'Flash' => 'ã¹ãã­ã',
-        'High Color Rendering Fluorescent' => 'ãã€ã«ã©ãŒã¬ã³ããªã³ã°èå
-ç¯',
+        'High Color Rendering Fluorescent (3700K)' => 'ãã€ã«ã©ãŒã¬ã³ããªã³ã°èå
+ç¯ (1)',
+        'High Color Rendering Fluorescent (5000K)' => 'ãã€ã«ã©ãŒã¬ã³ããªã³ã°èå
+ç¯ (3)',
+        'High Color Rendering Fluorescent (cool white)' => 'ãã€ã«ã©ãŒã¬ã³ããªã³ã°èå
+ç¯ (2)',
+        'High Color Rendering Fluorescent (daylight)' => 'ãã€ã«ã©ãŒã¬ã³ããªã³ã°èå
+ç¯ (4)',
+        'High Color Rendering Fluorescent (warm white)' => 'ãã€ã«ã©ãŒã¬ã³ããªã³ã°èå
+ç¯ (0)',
         'Incandescent' => 'é»ç',
         'None' => 'ç¡ã',
-        'Standard Fluorescent' => 'æšæºèå
-ç¯',
+        'Standard Fluorescent (3700K)' => 'æšæºèå
+ç¯ (1)',
+        'Standard Fluorescent (5000K)' => 'æšæºèå
+ç¯ (3)',
+        'Standard Fluorescent (6500K)' => 'æšæºèå
+ç¯ (4)',
+        'Standard Fluorescent (cool white)' => 'æšæºèå
+ç¯ (2)',
+        'Standard Fluorescent (high temperature mercury vapor)' => 'æšæºèå
+ç¯ (5)',
+        'Standard Fluorescent (warm white)' => 'æšæºèå
+ç¯ (0)',
       },
     },
@@ -5836,6 +5957,4 @@
     },
    'WBAdjTemperature' => 'ãã¯ã€ããã©ã³ã¹èª¿æŽãè²æž©åºŠ',
-   'WBAdjustAB' => 'ãã¯ã€ããã©ã³ã¹èª¿æŽA/B',
-   'WBAdjustGM' => 'ãã¯ã€ããã©ã³ã¹èª¿æŽG/M',
    'WBBlueLevel' => 'ãã¯ã€ããã©ã³ã¹éã¬ãã«',
    'WBBracketMode' => {
@@ -5872,5 +5991,4 @@
    'WBShiftAB' => 'WB ABè£æ­£',
    'WBShiftGM' => 'WB GMè£æ­£',
-   'WBShiftMG' => 'WB GMè£æ­£',
    'WB_GBRGLevels' => 'WB GBRG ã¬ãã«',
    'WB_GRBGLevels' => 'WB GRBG ã¬ãã«',
@@ -6006,4 +6124,8 @@
         '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',
       },
     },
@@ -6138,4 +6260,5 @@
       },
     },
+   'Zoom' => 'ãºãŒã ',
    'ZoomSourceWidth' => 'ãºãŒã ãœãŒã¹å¹
 ',
@@ -6161,5 +6284,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ko.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ko.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ko.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.04';
+$VERSION = '1.07';
 
 %Image::ExifTool::Lang::ko::Translate = (
@@ -109,4 +109,5 @@
    'AFInfo2' => 'AF ì ë³Ž',
    'AFInfo2Version' => 'AF ì ë³Ž ë²ì ',
+   'AFMode' => 'AF ëªšë',
    'AFPoint' => {
       Description => 'AF í¬ìžíž',
@@ -268,4 +269,6 @@
       },
     },
+   'AutoBracketingSet' => 'ìë ëžëŒìŒí
+ ì€ì ',
    'AutoExposureBracketing' => {
       PrintConv => {
@@ -349,41 +352,4 @@
    'CFAPattern' => 'CFA íšíŽ',
    'CLModeShootingSpeed' => 'CL ëªšë ìŽ¬ì ìë',
-   'CanonExposureMode' => {
-      PrintConv => {
-        'Manual' => 'ìë',
-      },
-    },
-   'CanonFlashMode' => {
-      PrintConv => {
-        'Auto' => 'ìë',
-        'Off' => 'êºŒì§',
-        'On' => 'ìŒì§',
-      },
-    },
-   'Caption-Abstract' => 'ì ëª©/ì€ëª
-',
-   'CaptionWriter' => 'ìº¡ì
- ìì±ì',
-   'Categories' => 'ë²ì£Œ',
-   'Category' => 'ë²ì£Œ',
-   'CenterAFArea' => {
-      Description => 'ì€ì ìŽì  ìì­',
-      PrintConv => {
-        'Normal Zone' => 'ìŒë° ìì­',
-        'Wide Zone' => 'ììŽë ìì­',
-      },
-    },
-   'CenterWeightedAreaSize' => 'ì€ì ì€ì  ìì­',
-   'ChrominanceNR_TIFF_JPEG' => {
-      PrintConv => {
-        'Off' => 'êºŒì§',
-      },
-    },
-   'ChrominanceNoiseReduction' => {
-      PrintConv => {
-        'Off' => 'êºŒì§',
-      },
-    },
-   'City' => 'ëì',
    'CalibrationIlluminant1' => {
       PrintConv => {
@@ -442,4 +408,41 @@
       },
     },
+   'CanonExposureMode' => {
+      PrintConv => {
+        'Manual' => 'ìë',
+      },
+    },
+   'CanonFlashMode' => {
+      PrintConv => {
+        'Auto' => 'ìë',
+        'Off' => 'êºŒì§',
+        'On' => 'ìŒì§',
+      },
+    },
+   'Caption-Abstract' => 'ì ëª©/ì€ëª
+',
+   'CaptionWriter' => 'ìº¡ì
+ ìì±ì',
+   'Categories' => 'ë²ì£Œ',
+   'Category' => 'ë²ì£Œ',
+   'CenterAFArea' => {
+      Description => 'ì€ì ìŽì  ìì­',
+      PrintConv => {
+        'Normal Zone' => 'ìŒë° ìì­',
+        'Wide Zone' => 'ììŽë ìì­',
+      },
+    },
+   'CenterWeightedAreaSize' => 'ì€ì ì€ì  ìì­',
+   'ChrominanceNR_TIFF_JPEG' => {
+      PrintConv => {
+        'Off' => 'êºŒì§',
+      },
+    },
+   'ChrominanceNoiseReduction' => {
+      PrintConv => {
+        'Off' => 'êºŒì§',
+      },
+    },
+   'City' => 'ëì',
    'CodedCharacterSet' => 'ìœëë ìºëŠ­í° ìžíž',
    'ColorAberrationControl' => {
@@ -456,4 +459,5 @@
       },
     },
+   'ColorBalanceVersion' => 'ì»¬ë¬ ë°žë°ì€ ë²ì ',
    'ColorBooster' => {
       PrintConv => {
@@ -865,4 +869,12 @@
     },
    'FNumber' => 'F ì«ì',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (ììªœ/ì¢ìž¡)',
+        'Rotate 180' => '180Â° (ìë/ì°ìž¡)',
+        'Rotate 270 CW' => '90Â° ìê³ë°©í¥ (ì¢ìž¡/ìë)',
+        'Rotate 90 CW' => '90Â° ë°ìê³ë°©í¥ (ì°ìž¡/ììªœ)',
+      },
+    },
    'FileFormat' => 'íì',
    'FileInfo' => 'íìŒ ì ë³Ž',
@@ -896,4 +908,6 @@
     },
    'FileType' => 'íìŒíì',
+   'Filename' => 'íìŒëª
+',
    'FilmType' => 'íëŠ íì',
    'Filter' => {
@@ -1232,4 +1246,5 @@
       Description => 'GPS ìž¡ì  ëªšë',
       PrintConv => {
+        '2-Dimensional Measurement' => '2-ì°šì ìž¡ë(íë©Ž ìž¡ë)',
         '3-Dimensional Measurement' => '3ì°šì ìž¡ì ',
       },
@@ -1312,4 +1327,5 @@
    'HueAdjustment' => 'ìì¡°',
    'ISO' => 'ISO ìë',
+   'ISOAuto' => 'ìë ISO',
    'ISODisplay' => 'ISO íì',
    'ISOExpansion' => {
@@ -1422,4 +1438,12 @@
    'InteropOffset' => 'ìíž ìŽì©ì± íê·ž',
    'InteropVersion' => 'ìíž ìŽì©ì± ë²ì ',
+   'JPEGQuality' => {
+      Description => 'íì§',
+      PrintConv => {
+        'Extra Fine' => 'ìì€ížëŒ íìž',
+        'Fine' => 'íìž',
+        'Standard' => 'íì€íì§',
+      },
+    },
    'Keyword' => 'í€ìë',
    'Keywords' => 'í€ìë',
@@ -1506,4 +1530,5 @@
     },
    'MB-D10Batteries' => 'MB-D10 ë°°í°ëŠ¬ íì',
+   'MB-D10BatteryType' => 'MB-D10 ë°°í°ëŠ¬ íì',
    'MB-D80Batteries' => {
       Description => 'MB-D80 ë°°í°ëŠ¬',
@@ -1548,4 +1573,5 @@
    'ManualFlashOutput' => 'ëŽì¥ íëì ìë ì¶ë ¥',
    'ManualFocusDistance' => 'ìë ìŽì  ê±°ëŠ¬',
+   'MatrixMetering' => 'ë©í° íšíŽ ìž¡êŽ',
    'MaxAperture' => 'ìµë ë ìŠ ì¡°ëŠ¬ê°',
    'MaxApertureAtMaxFocal' => 'ìµë ìŽì êžžìŽìì ìµë ì¡°ëŠ¬ê°',
@@ -1723,4 +1749,5 @@
       },
     },
+   'NEFLinearizationTable' => 'ì íëí',
    'NikonCaptureData' => 'Nikon Capture ë°ìŽí°',
    'NikonCaptureVersion' => 'Nikon Capture ë²ì ',
@@ -1870,4 +1897,5 @@
       },
     },
+   'Preview' => 'IFD í¬ìží° ë¯žëŠ¬ë³Žêž°',
    'PreviewIFD' => 'IFD í¬ìží° ë¯žëŠ¬ë³Žêž°',
    'PrimaryAFPoint' => {
@@ -1903,4 +1931,5 @@
       },
     },
+   'QuickAdjust' => 'ë¹ ë¥ž ì¡°ì ',
    'RawDevAutoGradation' => {
       PrintConv => {
@@ -2046,5 +2075,4 @@
         'Sports' => 'ì€í¬ìž  ì¡ì
 ',
-        'Standard' => '',
         'Sunset' => 'ìììŽ¬ì',
         'Sweep Panorama' => 'ì€ìí íë
@@ -2223,4 +2251,5 @@
    'ThumbnailImage' => 'ì¶ì ê·žëŠŒ',
    'ThumbnailImageSize' => 'ê°€ë¬ëŠ¬ í¬êž°',
+   'TimeZone' => 'íì€ ìê°ë',
    'TimerFunctionButton' => {
       Description => 'Fn ë²íŒ',
@@ -2234,5 +2263,4 @@
       },
     },
-   'Timezone' => 'íì€ ìê°ë',
    'Title' => 'ì ëª©',
    'ToneComp' => 'ê³ì¡° ë³Žì ',
@@ -2447,5 +2475,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/nl.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/nl.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/nl.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.07';
+$VERSION = '1.12';
 
 %Image::ExifTool::Lang::nl::Translate = (
@@ -120,10 +120,4 @@
       },
     },
-   'AFMicroAdjActive' => {
-      PrintConv => {
-        'No' => 'Nee',
-        'Yes' => 'Ja',
-      },
-    },
    'AFPoint' => {
       PrintConv => {
@@ -208,4 +202,5 @@
       Description => 'Actie advies',
       PrintConv => {
+        'Object Append' => 'Object toevoegen',
         'Object Kill' => 'Object verwijderen',
         'Object Reference' => 'Object referentie',
@@ -342,4 +337,5 @@
       },
     },
+   'AutoBracketingSet' => 'Inst. voor auto bracketing',
    'AutoExposureBracketing' => {
       PrintConv => {
@@ -349,4 +345,5 @@
     },
    'AutoFP' => {
+      Description => 'Auto FP',
       PrintConv => {
         'Off' => 'Uit',
@@ -1006,5 +1003,5 @@
         'Landscape' => 'Landschap',
         'Manual' => 'Handmatig',
-        'Night' => 'Nachtszene',
+        'Night' => 'Nachtscene',
         'Portrait' => 'Portret',
       },
@@ -1160,4 +1157,12 @@
    'ExtraSamples' => 'Extra componenten',
    'FNumber' => 'F waarde',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (boven/links)',
+        'Rotate 180' => '180Â° (onder/rechts)',
+        'Rotate 270 CW' => 'Draai 270Â° met de klok mee',
+        'Rotate 90 CW' => '90Â° tegen de klok in (rechts/boven)',
+      },
+    },
    'FastSeek' => {
       PrintConv => {
@@ -1201,4 +1206,5 @@
    'FileType' => 'Bestandtype',
    'FileVersion' => 'Fileformaat versie',
+   'Filename' => 'Bestandnaam',
    'FillOrder' => {
       Description => 'Vul volgorde',
@@ -1519,5 +1525,5 @@
       Description => 'Referentie voor de afstand tot de bestemming',
       PrintConv => {
-        'Miles' => 'Meilen',
+        'Miles' => 'Mijlen',
         'Nautical Miles' => 'Knopen',
       },
@@ -1527,5 +1533,5 @@
       Description => 'Referentie voor de breedte van het doel',
       PrintConv => {
-        'North' => 'Nordelijke breedte',
+        'North' => 'Noordelijke breedte',
         'South' => 'Zuidelijke breedte',
       },
@@ -1536,5 +1542,5 @@
       PrintConv => {
         'East' => 'Oostelijke lengte',
-        'West' => 'Westlijke Lengte',
+        'West' => 'Westlijke lengte',
       },
     },
@@ -1591,5 +1597,5 @@
         'km/h' => 'Kilometer per uur',
         'knots' => 'Knopen',
-        'mph' => 'Meilen per uur',
+        'mph' => 'Mijl per uur',
       },
     },
@@ -1680,6 +1686,8 @@
     },
    'Hue' => 'Kleurtoon',
+   'ICCProfile' => 'ICC Profiel',
    'IPTC-NAA' => 'IPTC-NAA metadata',
    'ISO' => 'ISO gevoeligheid',
+   'ISOAuto' => 'ISO auto',
    'ISODisplay' => 'ISO-weergave',
    'ISOExpansion' => {
@@ -1847,4 +1855,12 @@
    'InteropVersion' => 'Interoperabiliteits versie',
    'JFIFVersion' => 'JFIF versie',
+   'JPEGQuality' => {
+      Description => 'Beeldkwaliteit',
+      PrintConv => {
+        'Extra Fine' => 'Extra fijn',
+        'Fine' => 'Fijn',
+        'Standard' => 'Normaal',
+      },
+    },
    'JobID' => 'ID van baan',
    'Keyword' => 'Trefwoorden',
@@ -1941,4 +1957,5 @@
     },
    'MB-D10Batteries' => 'MB-D10 batterijen',
+   'MB-D10BatteryType' => 'MB-D10 batterijen',
    'MB-D80Batteries' => 'MB-D80 batterijen',
    'MIEVersion' => 'MIE versie',
@@ -1982,4 +1999,5 @@
     },
    'MasterDocumentID' => 'ID van hoofddocument',
+   'MatrixMetering' => 'Matrixmeting',
    'MaxAperture' => 'Maximale lensopening',
    'MaxApertureValue' => 'Grootste diafragma',
@@ -2597,5 +2615,5 @@
       PrintConv => {
         'Landscape' => 'Landschap',
-        'Night' => 'Nachtszene',
+        'Night' => 'Nachtscene',
         'Portrait' => 'Portret',
         'Standard' => 'Standaard',
@@ -2637,5 +2655,5 @@
    'SceneSelect' => {
       PrintConv => {
-        'Night' => 'Nachtszene',
+        'Night' => 'Nachtscene',
         'Off' => 'Uit',
       },
@@ -2879,5 +2897,5 @@
         'Photo CD' => 'Photo-CD',
         'Photo Image Setter' => 'Fotofilmbelichter',
-        'Photographic Paper Printer' => 'Photopapier printer',
+        'Photographic Paper Printer' => 'Fotopapier printer',
         'Projection Television' => 'Projectietelevisie',
         'Reflective Scanner' => 'Reflectieve Scanner',
@@ -3044,5 +3062,7 @@
    'WBAdjLighting' => {
       PrintConv => {
-        'Daylight' => 'Daglicht',
+        'Daylight (cloudy)' => 'Daglicht (2)',
+        'Daylight (direct sunlight)' => 'Daglicht (0)',
+        'Daylight (shade)' => 'Daglicht (1)',
         'Flash' => 'Flits',
         'None' => 'Geen',
@@ -3188,5 +3208,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -3195,6 +3215,6 @@
 =head1 ACKNOWLEDGEMENTS
 
-Thanks to Jens Duttke, Peter Moonen and Herman Beld for providing this
-translation.
+Thanks to Jens Duttke, Peter Moonen, Herman Beld and Peter van der Laan for
+providing this translation.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/pl.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/pl.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/pl.pm	(revision 34921)
@@ -12,7 +12,26 @@
 use vars qw($VERSION);
 
-$VERSION = '1.04';
+$VERSION = '1.12';
 
 %Image::ExifTool::Lang::pl::Translate = (
+   'A100DataOffset' => 'PrzesuniÄcie danych A100',
+   'AEAperture' => 'Priorytet AE',
+   'AEExposureTime' => 'Czas ekspozycji AE',
+   'AEInfo' => 'Informacja o automatycznej ekspozycji',
+   'AELock' => {
+      Description => 'Blokada AE',
+      PrintConv => {
+        'Off' => 'WyÅÄ
+czona',
+        'On' => 'WÅÄ
+czona',
+      },
+    },
+   'AEMeteringMode' => 'Tryb pomiaru AE',
+   'AEMeteringSegments' => 'Segmenty pomiaru AE',
+   'AEProgramMode' => 'Tryb programu AE',
+   'AFAdjustment' => 'Korekta AF',
+   'AFInfo' => 'Informacje autofocusa',
+   'AFIntegrationTime' => 'Czas integracji AF',
    'AFPoint' => {
       PrintConv => {
@@ -20,14 +39,54 @@
       },
     },
+   'AFPointMode' => 'Tryb Autofokusa',
+   'AFPointSelected' => {
+      Description => 'Wybrany punkt AF',
+      PrintConv => {
+        'Auto' => 'Automatyczny',
+        'Automatic Tracking AF' => 'ÅledzÄ
+cy AF',
+        'Bottom' => 'Dolny',
+        'Center' => 'Centralny',
+        'Face Detect AF' => 'Wykrywanie twarzy',
+        'Fixed Center' => 'Centralny',
+        'Left' => 'Lewy',
+        'Lower-left' => 'Dolny-lewy',
+        'Lower-right' => 'Dolny-prawy',
+        'Mid-left' => 'Årodek-lewy',
+        'Mid-right' => 'Årodek-prawy',
+        'Right' => 'Prawy',
+        'Top' => 'GÃ³rny',
+        'Upper-left' => 'GÃ³rny-lewy',
+        'Upper-right' => 'GÃ³rny-prawy',
+      },
+    },
+   'AFPointSelected2' => 'Wybrany punkt autofokusa 2',
    'AFPointsInFocus' => {
-      PrintConv => {
-        'None' => 'Brak',
-      },
-    },
+      Description => 'Punkty AF w ostroÅci',
+      PrintConv => {
+        'Bottom-center' => 'Dolny-centralny',
+        'Bottom-left' => 'Dolny-lewy',
+        'Bottom-right' => 'Dolny-prawy',
+        'Center' => 'Centralny',
+        'Fixed Center or Multiple' => 'Centralny lub wiele',
+        'Left' => 'Lewy',
+        'None' => 'Brak',
+        'Right' => 'Prawy',
+        'Top-center' => 'GÃ³rny-centralny',
+        'Top-left' => 'GÃ³rny-lewy',
+        'Top-right' => 'GÃ³rny-prawy',
+      },
+    },
+   'AFPointsSelected' => 'Wybrane punkty AF',
+   'AFPredictor' => 'PrzewidujÄ
+cy AF',
    'Aperture' => 'PrzysÅona',
+   'ApertureRingUse' => 'UÅŒycie pierÅcienia przysÅony',
    'ApertureValue' => 'PrzysÅona',
    'Artist' => 'Artysta',
    'Author' => 'Autor',
    'AuthorsPosition' => 'Pozycja autora',
+   'AutoAperture' => 'Automatyczna przysÅona',
+   'AutoBracketing' => 'Bracketing automatyczny',
    'AutoRotate' => {
       PrintConv => {
@@ -38,4 +97,6 @@
       },
     },
+   'AvApertureSetting' => 'Ustawienia priorytetu przysÅony Av',
+   'BadFaxLines' => 'Uszkodzone wiersze transmisji Fax',
    'BannerImageType' => {
       PrintConv => {
@@ -43,5 +104,8 @@
       },
     },
+   'BaseExposureCompensation' => 'Podstawowa kompensacja ekspozycji',
    'BitsPerSample' => 'Liczba bitÃ³w na skÅadnik',
+   'BlackPoint' => 'Punkt czerni',
+   'BlueBalance' => 'Balans niebieskiego',
    'BlurWarning' => {
       PrintConv => {
@@ -49,8 +113,10 @@
       },
     },
+   'BracketShotNumber' => 'IloÅÄ zdjÄÄ w bracketingu',
    'Brightness' => 'JasnoÅÄ',
    'By-line' => 'Autor',
    'CFAPattern' => 'Wzorzec CFA',
    'CMMFlags' => 'Flagi CMM',
+   'CPUFirmwareVersion' => 'Wersja firmware CPU',
    'CPUType' => {
       PrintConv => {
@@ -70,5 +136,5 @@
         'Fluorescent' => 'Jarzeniowy',
         'ISO Studio Tungsten' => 'ISO dla studyjnych lamp ÅŒarowych',
-        'Other' => 'inne ÅºrÃ³dÅo ÅwiatÅa',
+        'Other' => 'Inne ÅºrÃ³dÅo ÅwiatÅa',
         'Shade' => 'CieÅ',
         'Standard Light A' => 'Standardowe ÅwiatÅo A',
@@ -92,5 +158,5 @@
         'Fluorescent' => 'Jarzeniowy',
         'ISO Studio Tungsten' => 'ISO dla studyjnych lamp ÅŒarowych',
-        'Other' => 'inne ÅºrÃ³dÅo ÅwiatÅa',
+        'Other' => 'Inne ÅºrÃ³dÅo ÅwiatÅa',
         'Shade' => 'CieÅ',
         'Standard Light A' => 'Standardowe ÅwiatÅo A',
@@ -110,10 +176,38 @@
       },
     },
+   'CameraSettings' => 'Ustawienia aparatu',
+   'CameraTemperature' => 'Temperatura aparatu',
    'Caption-Abstract' => 'Podpis',
    'CaptionWriter' => 'Autor podpisu',
    'Categories' => 'Kategorie',
    'Category' => 'Kategorie',
+   'CellLength' => 'DÅugoÅÄ komÃ³rki',
+   'CellWidth' => 'SzerokoÅÄ komÃ³rki',
    'City' => 'Miasto',
+   'CleanFaxData' => {
+      Description => 'Poprawne wiersze transmisji Fax',
+      PrintConv => {
+        'Clean' => 'Dobry',
+        'Regenerated' => 'Ponowiony',
+        'Unclean' => 'Niedobry',
+      },
+    },
+   'ClipPath' => 'ÅcieÅŒka obciÄcia',
+   'CodingMethods' => {
+      Description => 'Metody kompresji',
+      PrintConv => {
+        'Baseline JPEG' => 'JPEG podstawowa',
+        'JBIG color' => 'JBIG kolor',
+        'Modified Huffman' => 'Huffmana zmodyfikowana',
+        'Modified MR' => 'Zmodyfikowany MR',
+        'Modified Read' => 'Zmodyfikowany odczyt',
+        'Unspecified compression' => 'Nie podane',
+      },
+    },
    'ColorFilter' => 'Filtr kolorowy',
+   'ColorInfo' => 'Informacje o kolorze',
+   'ColorMap' => 'Mapa kolorÃ³w',
+   'ColorMatrix1' => 'Macierz kolorÃ³w 1',
+   'ColorMatrix2' => 'Macierz kolorÃ³w 2',
    'ColorSpace' => {
       Description => 'Informacja o przestrzeni barwowej',
@@ -131,4 +225,6 @@
       PrintConv => {
         'Epson ERF Compressed' => 'Skompresowany Epson ERF',
+        'JBIG B&W' => 'JBIG Czarno BiaÅy',
+        'JBIG Color' => 'JBIG Kolorowy',
         'JPEG' => 'Kompresja JPEG',
         'JPEG (old-style)' => 'JPEG (w starym stylu)',
@@ -138,7 +234,9 @@
         'Nikon NEF Compressed' => 'Skompresowany Nikon NEF',
         'None' => 'Brak',
+        'Packed RAW' => 'Spakowany RAW',
         'Pentax PEF Compressed' => 'Skompresowany Pentax PEF',
         'SGILog' => 'Kodowanie 32-bitowe SGI Log Luminance',
         'SGILog24' => 'Kodowanie 24-bitowe SGI Log Luminance',
+        'Samsung SRW Compressed' => 'Skompresowany Samsung SRW',
         'Sony ARW Compressed' => 'Skompresowany Sony ARW',
         'Thunderscan' => 'Kodowanie 4-bitowe ThunderScan',
@@ -151,4 +249,5 @@
       },
     },
+   'ConsecutiveBadFaxLines' => 'Sekwencja uszkodzonych wierszy transmisji Fax',
    'Contrast' => {
       Description => 'Kontrast',
@@ -185,4 +284,6 @@
    'DNGBackwardVersion' => 'Poprzednia wersja DNG',
    'DNGVersion' => 'Wersja DNG',
+   'DSPFirmwareVersion' => 'Wersja firmware DSP',
+   'DataDump' => 'Zrzut danych?',
    'DataImprint' => {
       PrintConv => {
@@ -190,8 +291,21 @@
       },
     },
+   'DataType' => 'Typ daty',
+   'Date' => 'Data',
    'DateCreated' => 'Data utworzenia',
    'DateSent' => 'WysÅano datÄ',
    'DateTimeOriginal' => 'Pierwotna data i godzina',
+   'Decode' => 'Zdekodowany',
+   'DefaultImageColor' => 'DomyÅlny kolor w obrazie',
    'Description' => 'Opis',
+   'DestinationCity' => 'Miasto przeznaczenia',
+   'DestinationCityCode' => 'Kod miasta przeznaczenia',
+   'DestinationDST' => {
+      Description => 'Czas letni miasta przeznaczenia',
+      PrintConv => {
+        'No' => 'Nie',
+        'Yes' => 'Tak',
+      },
+    },
    'DeviceAttributes' => 'Atrybuty urzÄ
 dzenia',
@@ -220,6 +334,21 @@
       },
     },
+   'DocumentName' => 'Nazwa dokumentu',
    'DriveMode' => 'Tryb przesuwu',
+   'DriveMode2' => 'Tryb zdjÄÄ 2',
    'Duration' => 'Czas',
+   'DynamicRangeExpansion' => {
+      Description => 'Rozszerzenie zakresu dynamiki',
+      PrintConv => {
+        'Off' => 'WyÅÄ
+czone',
+        'On' => 'WÅÄ
+czone',
+      },
+    },
+   'E-DialInProgram' => 'Program E-Dial',
+   'EVStepInfo' => 'Informacja o krokach EV',
+   'EVSteps' => 'Krok EV',
+   'EffectiveLV' => 'Efektywne LV',
    'Emphasis' => {
       PrintConv => {
@@ -240,4 +369,5 @@
    'ExifOffset' => 'WskaÅºnik Exif IFD',
    'ExifVersion' => 'Wersja Exif',
+   'ExposureBracketStepSize' => 'Krok bracketingu ekspozycji',
    'ExposureCompensation' => 'RÃ³ÅŒnica ekspozycji',
    'ExposureIndex' => 'WskaÅºnik ekspozycji',
@@ -264,5 +394,29 @@
     },
    'ExposureTime' => 'Czas ekspozycji',
+   'ExternalFlashExposureComp' => 'Kompensacja ekspozycji zewnetrznej lampy',
+   'ExternalFlashGuideNumber' => 'Liczba przewodnia lampy zewnÄtrznej',
+   'ExternalFlashMode' => 'Tryb lampy zewnÄtrznej',
    'FNumber' => 'PrzysÅona',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (gÃ³ra/lewo)',
+        'Rotate 180' => '180Â° (dÃ³Å/prawo)',
+        'Rotate 270 CW' => '90Â° CW (lewo/dÃ³Å)',
+        'Rotate 90 CW' => '90Â° CCW (prawo/gÃ³ra)',
+      },
+    },
+   'FaxProfile' => {
+      Description => 'Profil faxu (rodzaj zawartoÅci)',
+      PrintConv => {
+        'Extended B&W lossless, F' => 'Rozszerzony cz.b. bezstratny, F',
+        'Lossless JBIG B&W, J' => 'Bezstratny JBIG cz.b., J',
+        'Lossless color and grayscale, L' => 'Bezstratne kolor i skala szaroÅci, L',
+        'Lossy color and grayscale, C' => 'Stratne kolor i skala szaroÅci, C',
+        'Minimal B&W lossless, S' => 'Minimalny cz.b. bezstratny, S',
+        'Mixed raster content, M' => 'Raster â zawartoÅÄ mieszana, M',
+        'Multi Profiles' => 'Wiele profili',
+        'Unknown' => 'Nieznany',
+      },
+    },
    'FileFormat' => 'Format',
    'FileModifyDate' => 'Data aktualizacji',
@@ -278,4 +432,12 @@
     },
    'FileType' => 'Typ pliku',
+   'Filename' => 'Nazwa pliku',
+   'FillOrder' => {
+      Description => 'KolejnoÅÄ wypeÅniania',
+      PrintConv => {
+        'Normal' => 'Normalna',
+        'Reversed' => 'ZajÄte',
+      },
+    },
    'FilterEffectMonochrome' => {
       PrintConv => {
@@ -326,4 +488,6 @@
    'FlashEnergy' => 'SiÅa lampy bÅyskowej',
    'FlashExposureComp' => 'Kompensacja lampy',
+   'FlashMeteringSegments' => 'Segmenty pomiaru bÅysku',
+   'FlashMode' => 'Tryb lampy',
    'FlashModel' => {
       PrintConv => {
@@ -331,4 +495,6 @@
       },
     },
+   'FlashOptions' => 'Opcje lampy',
+   'FlashStatus' => 'Stan lampy',
    'FlashType' => {
       PrintConv => {
@@ -351,8 +517,12 @@
    'FocalPlaneYResolution' => 'RozdzielczoÅÄ w pÅaszczyÅºnie ogniskowej - oÅ y',
    'FocusMode' => 'Tryb ostrzenia',
+   'FocusMode2' => 'Tryb Autofokusa 2',
+   'FrameNumber' => 'Numer zdjÄcia',
    'FrameRate' => 'CzÄstotliwoÅÄ zmiany kadrÃ³w',
    'FrameSize' => 'WielkoÅÄ kadru',
    'FreeByteCounts' => 'Liczba wolnych bajtÃ³w',
    'FreeOffsets' => 'Wolne offsety',
+   'GDALMetadata' => 'Metadane GDAL',
+   'GDALNoData' => 'Brak danych GDAL',
    'GPSAltitude' => 'WysokoÅÄ',
    'GPSAltitudeRef' => {
@@ -381,4 +551,6 @@
       },
     },
+   'GPSHPositioningError' => 'BÅÄ
+d poziomy wyznaczenia pozycji',
    'GPSImgDirection' => 'Kierunek obrazu',
    'GPSImgDirectionRef' => 'WartoÅÄ odniesienia dla kierunku obrazu',
@@ -447,19 +619,98 @@
    'Genre' => 'Gatunek',
    'Gradation' => 'Gradacja',
+   'GrayResponseCurve' => 'Krzywa odpowiedzi SzaroÅci',
+   'GrayResponseUnit' => 'WielkoÅÄ jednostki dla krzywej odpowiedzi szaroÅci',
+   'HalftoneHints' => 'PÃ³Åtony',
    'Headline' => 'NagÅÃ³wek',
+   'HighISONoiseReduction' => 'Redukcja szumu przy wysokim ISO',
+   'HometownCity' => 'Miasto domowe',
+   'HometownCityCode' => 'Kod miasta domowego',
+   'HometownDST' => {
+      Description => 'Czas letni miasta domowego',
+      PrintConv => {
+        'No' => 'Nie',
+        'Yes' => 'Tak',
+      },
+    },
+   'HostComputer' => 'Komputer uÅŒyty do wygenerowania obrazu',
    'Hue' => 'Barwa',
+   'ICCProfile' => 'Profil ICC',
    'ISO' => 'CzuÅoÅÄ ISO',
+   'ISOFloor' => 'Minimalne ISO',
+   'ISOSetting' => 'Ustawienia ISO',
+   'ImageAreaOffset' => 'PrzesuniÄcie obszaru obrazu',
+   'ImageDescription' => 'Opis obrazu',
+   'ImageEditCount' => 'Licznik przetworzonych zdjÄÄ',
    'ImageHeight' => 'WysokoÅÄ obrazu',
+   'ImageID' => 'Identyfikator obrazu',
+   'ImageProcessing' => 'Przetwarzanie obrazu',
    'ImageSize' => 'Rozmiar zdjÄcia',
+   'ImageTone' => {
+      Description => 'OdcieÅ zdjÄcia',
+      PrintConv => {
+        'Bright' => 'Jasny',
+        'Landscape' => 'Krajobraz',
+        'Monochrome' => 'Monochromatyczny',
+        'Natural' => 'Naturalny',
+        'Portrait' => 'Portret',
+      },
+    },
+   'ImageType' => {
+      Description => 'Rodzaj obrazu',
+      PrintConv => {
+        'Page' => 'Strona',
+      },
+    },
    'ImageUniqueID' => 'Unikalny kod ID zdjÄcia',
    'ImageWidth' => 'SzerokoÅÄ obrazu',
    'Index' => 'Indeks',
+   'Indexed' => {
+      Description => 'Indeksowane',
+      PrintConv => {
+        'Indexed' => 'Indeksowane',
+        'Not indexed' => 'Nie indeksowane',
+      },
+    },
+   'InkNames' => 'Nazwy tuszy',
+   'InkSet' => {
+      Description => 'Zestaw tuszy',
+      PrintConv => {
+        'Not CMYK' => 'Nie CMYK',
+      },
+    },
    'Instructions' => 'Instrukcje',
-   'InteropIndex' => 'Identyfikacja wzajemnej zgodnoÅci',
+   'InternalFlashMode' => 'Tryb wewnÄtrznej lampy',
+   'InternalFlashStrength' => 'Moc wewnÄtrznej lampy',
+   'InteropIndex' => {
+      Description => 'Identyfikacja wzajemnej zgodnoÅci',
+      PrintConv => {
+        'R03 - DCF option file (Adobe RGB)' => 'R03: Plik pomocniczy DCF (Adobe RGB)',
+        'R98 - DCF basic file (sRGB)' => 'R98: Plik zasadniczy DCF (sRGB)',
+        'THM - DCF thumbnail file' => 'THM: Plik miniatury DCF',
+      },
+    },
    'InteropOffset' => 'Znacznik wzajemnej zgodnoÅci',
    'InteropVersion' => 'Wersja wzajemnej zgodnoÅci',
+   'JPEGProc' => {
+      PrintConv => {
+        'Baseline' => 'JPEG Podstawowy',
+        'Lossless' => 'Bezstratny',
+      },
+    },
+   'JPEGQuality' => {
+      Description => 'JakoÅÄ',
+      PrintConv => {
+        'Standard' => 'Standardowa jakoÅÄ',
+      },
+    },
+   'JPEGRestartInterval' => 'JPEG odstÄp restartÃ³w',
    'Keywords' => 'SÅowa kluczowe',
    'Lens' => 'Obiektyw',
+   'LensID' => 'ID obiektywu',
    'LensInfo' => 'Informacja o obiektywie',
+   'LensMake' => 'Producent obiektywu',
+   'LensModel' => 'Model obiektywu',
+   'LensSerialNumber' => 'Numer seryjny obiektywu',
+   'LightReading' => 'Pomiar ÅwiatÅa',
    'LightSource' => {
       Description => 'Å¹rÃ³dÅo ÅwiatÅa',
@@ -475,5 +726,5 @@
         'Fluorescent' => 'Jarzeniowy',
         'ISO Studio Tungsten' => 'ISO dla studyjnych lamp ÅŒarowych',
-        'Other' => 'inne ÅºrÃ³dÅo ÅwiatÅa',
+        'Other' => 'Inne ÅºrÃ³dÅo ÅwiatÅa',
         'Shade' => 'CieÅ',
         'Standard Light A' => 'Standardowe ÅwiatÅo A',
@@ -489,4 +740,5 @@
    'Location' => 'Miejsce',
    'Luminance' => 'Luminancja',
+   'Macro' => 'Makro',
    'Make' => 'Producent',
    'MakeAndModel' => 'Producent i model',
@@ -494,4 +746,5 @@
    'MakerNotes' => 'Dane producenta',
    'MaxAperture' => 'Maks. przysÅona obiektywu',
+   'MaxSampleValue' => 'Maksymalny rozmiar prÃ³bki',
    'MeasurementGeometry' => {
       Description => 'Geometria pomiaru',
@@ -510,5 +763,5 @@
         'Multi-segment' => 'WzÃ³r',
         'Multi-spot' => 'Wielopunktowy',
-        'Other' => 'inne',
+        'Other' => 'Inne',
         'Partial' => 'CzÄÅciowy',
         'Spot' => 'Punktowy',
@@ -516,4 +769,6 @@
       },
     },
+   'MinSampleValue' => 'Minimalny rozmiar prÃ³bki',
+   'ModeNumber' => 'Numer trybu',
    'Model' => 'Aparat',
    'ModifiedPictureStyle' => {
@@ -533,4 +788,5 @@
       },
     },
+   'MultipleExposureSet' => 'Wielokrotna ekspozycja',
    'NEFCompression' => {
       PrintConv => {
@@ -539,8 +795,26 @@
     },
    'NativeDisplayInfo' => 'Informacja o natywnym(?) wyÅwietlaczu',
-   'NoiseReduction' => 'Redukcja szumÃ³w',
+   'Noise' => 'Szumy',
+   'NoiseReduction' => {
+      Description => 'Redukcja szumÃ³w',
+      PrintConv => {
+        'Off' => 'WyÅÄ
+czona',
+        'On' => 'WÅÄ
+czona',
+      },
+    },
+   'NumberofInks' => 'Liczba tuszy',
    'ObjectFileType' => {
       PrintConv => {
         'None' => 'Brak',
+      },
+    },
+   'OldSubfileType' => {
+      Description => 'Stary typ podsekcji',
+      PrintConv => {
+        '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',
       },
     },
@@ -559,4 +833,18 @@
       },
     },
+   'OwnerName' => 'Nazwa wÅaÅciciela',
+   'PageName' => 'Nazwa strony',
+   'PageNumber' => 'Numer strony',
+   'PentaxImageSize' => {
+      Description => 'Rozmiar obrazu Pentax\'a',
+      PrintConv => {
+        '2304x1728 or 2592x1944' => '2304 x 1728 lub 2592 x 1944',
+        '2560x1920 or 2304x1728' => '2560 x 1920 lub 2304 x 1728',
+        '2816x2212 or 2816x2112' => '2816 x 2212 lub 2816 x 2112',
+        '3008x2008 or 3040x2024' => '3008 x 2008 lub 3040 x 2024',
+        'Full' => 'PeÅny',
+      },
+    },
+   'PentaxVersion' => 'Wersja Pentax\'a',
    'PhotoEffectsType' => {
       PrintConv => {
@@ -576,7 +864,23 @@
       },
     },
+   'PictureMode' => 'Tryb obrazu',
+   'PictureMode2' => 'Tryb obrazu 2',
    'PictureStyle' => {
       PrintConv => {
         'None' => 'Brak',
+      },
+    },
+   'PixelFormat' => {
+      Description => 'Format zapisu koloru',
+      PrintConv => {
+        '128-bit PRGBA Float' => '128-bitÃ³w PRGBA (zapis zmienno przecinkowy)',
+        '128-bit RGB Float' => '128-bitÃ³w RGB (zapis zmienno przecinkowy)',
+        '128-bit RGBA Float' => '128-bitÃ³w RGBA (zapis zmienno przecinkowy)',
+        '16-bit Gray' => '16-bitÃ³w SzaroÅÄ',
+        '32-bit Gray Float' => '32-bity SzaroÅÄ (zapis zmienno przecinkowy)',
+        '48-bit RGB Fixed Point' => '48-bitÃ³w RGB (zapis staÅopozycyjny)',
+        '8-bit Gray' => '8-bitÃ³w SzaroÅÄ',
+        '96-bit RGB Fixed Point' => '96-bitÃ³w RGB (zapis staÅopozycyjny)',
+        'Black & White' => 'Czarno BiaÅy',
       },
     },
@@ -586,4 +890,12 @@
         'Chunky' => 'Format "chunky" (z przeplotem)',
         'Planar' => 'Format "planar"',
+      },
+    },
+   'PowerSource' => 'Zasilanie',
+   'Predictor' => {
+      Description => 'Przelicznik',
+      PrintConv => {
+        'Horizontal differencing' => 'W oparciu o rÃ³ÅŒnicÄ w poziomie',
+        'None' => 'Bez przelicznika',
       },
     },
@@ -601,5 +913,17 @@
    'PreviewImage' => 'PodglÄ
 d',
+   'PreviewImageBorders' => 'Ramka podglÄ
+du',
+   'PreviewImageData' => 'Dane podglÄ
+du obrazu',
+   'PreviewImageLength' => 'DÅugoÅÄ miniatury z podglÄ
+dem',
+   'PreviewImageSize' => 'Rozmiar podglÄ
+du',
+   'PreviewImageStart' => 'PoczÄ
+tek miniatury z podglÄ
+dem',
    'PrimaryChromaticities' => 'TonalnoÅÄ kolorÃ³w podstawowych',
+   'ProcessingSoftware' => 'Oprogramowanie wykorzystane do przetwarzania',
    'ProductID' => 'ID produktu',
    'ProfileCMMType' => 'Typ profilu CMM',
@@ -626,5 +950,12 @@
    'ProfileDescriptionML' => 'WielojÄzyczny opis profilu.',
    'ProfileSequenceDesc' => 'Opis sekwencji profilu',
+   'ProfileType' => {
+      Description => 'Typ profilu',
+      PrintConv => {
+        'Unspecified' => 'Nie podany',
+      },
+    },
    'ProfileVersion' => 'Wersja profilu',
+   'ProgramLine' => 'Linia programu',
    'ProgramMode' => {
       PrintConv => {
@@ -634,10 +965,18 @@
    'Province-State' => 'Region',
    'Quality' => {
-      PrintConv => {
+      Description => 'JakoÅÄ',
+      PrintConv => {
+        'Best' => 'Najlepsza',
+        'Better' => 'Lepsza',
+        'Good' => 'Dobra',
         'Low' => 'Niska jakoÅÄ',
         'Normal' => 'Standardowa jakoÅÄ',
       },
     },
+   'Rating' => 'Ocena',
+   'RatingPercent' => 'Ocena procentowo',
+   'RawImageSize' => 'Rozmiar obrazu RAW',
    'RecordMode' => 'Tryb zapisu',
+   'RedBalance' => 'Balans czerwonego',
    'RedMatrixColumn' => 'Kolumna matrycy czerwieni',
    'RedTRC' => 'Krzywa reprodukcji czerwieni',
@@ -665,4 +1004,5 @@
     },
    'Rotation' => {
+      Description => 'ObrÃ³t',
       PrintConv => {
         'Horizontal' => '0Â° (gÃ³ra/lewo)',
@@ -678,4 +1018,15 @@
     },
    'RowsPerStrip' => 'Liczba rzÄdÃ³w w pasku',
+   'SRFocalLength' => 'DÅugoÅÄ fokalna SR',
+   'SRResult' => 'Stabilizacja obrazu',
+   'SampleFormat' => {
+      Description => 'Format prÃ³bki',
+      PrintConv => {
+        'Float' => 'Zmienno przecinkowa',
+        'Signed' => 'CaÅkowita ze znakiem',
+        'Undefined' => 'Nie podano',
+        'Unsigned' => 'CaÅkowita bez znaku',
+      },
+    },
    'SamplesPerPixel' => 'Liczba skÅadnikÃ³w',
    'Saturation' => {
@@ -697,4 +1048,5 @@
     },
    'SceneMode' => {
+      Description => 'Tryby tematyczne',
       PrintConv => {
         'Sunset' => 'ZachÃ³d sÅoÅca',
@@ -718,4 +1070,6 @@
       },
     },
+   'SensitivityAdjust' => 'Regulacja czuÅoÅci',
+   'SensitivitySteps' => 'Krok ustawienia czuÅoÅci',
    'SequentialShot' => {
       PrintConv => {
@@ -735,6 +1089,8 @@
     },
    'ShootingMode' => 'Tryb fotografowania',
+   'ShutterCount' => 'Licznik migawki',
    'ShutterSpeed' => 'Czas ekspozycji',
    'ShutterSpeedValue' => 'PrÄdkoÅÄ migawki',
+   'SlaveFlashMeteringSegments' => 'Segmenty pomiarowe lampy podrzÄdnej',
    'SlowShutter' => {
       PrintConv => {
@@ -757,4 +1113,19 @@
    'SubSecTimeDigitized' => '"Cyfrowa data i godzina, subsekundy"',
    'SubSecTimeOriginal' => '"Pierwotna data i godzina, sub-sekundy"',
+   'SubfileType' => {
+      Description => 'Typ podsekcji',
+      PrintConv => {
+        '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',
+        'TIFF/IT final page' => 'Ostatnia strona TIFF/IT',
+        'Transparency mask' => 'Maska przezroczystoÅci',
+        'Transparency mask of multi-page image' => 'Maska przezroczystoÅci obrazu wielostronicowego',
+        'Transparency mask of reduced-resolution image' => 'Maska przezroczystoÅci obrazu o zredukowanej rozdzielczoÅci',
+        'Transparency mask of reduced-resolution multi-page image' => 'Maska przezroczystoÅci obrazu wielostronicowego o zredukowanej rozdzielczoÅci',
+        'invalid' => 'BÅÄdny',
+      },
+    },
    'SubjectArea' => 'Obszar obiektu',
    'SubjectDistance' => 'OdlegÅoÅÄ od obiektu',
@@ -774,4 +1145,11 @@
     },
    'SupplementalCategories' => 'Kategorie dodatkowe',
+   'SvISOSetting' => 'Ustawienia ISO Sv',
+   'T6Options' => {
+      PrintConv => {
+        'Uncompressed' => 'Nieskompresowany',
+      },
+    },
+   'TargetPrinter' => 'Docelowa drukarka',
    'Technology' => {
       Description => 'Technologia',
@@ -803,7 +1181,16 @@
       },
     },
+   'Text' => 'Tekst',
+   'Thresholding' => 'Progowanie',
    'ThumbnailImage' => 'Miniatura',
    'ThumbnailImageSize' => 'Rozmiar miniaturki',
+   'TileByteCounts' => 'Liczba bajtÃ³w na kafelek',
+   'TileLength' => 'WysokoÅÄ kafelka',
+   'TileOffsets' => 'PrzesuniÄcie kafelkÃ³w',
+   'TileWidth' => 'SzerokoÅÄ kafelka',
+   'Time' => 'Czas',
    'Title' => 'TytuÅ',
+   'ToneCurve' => 'Krzywa barwy',
+   'ToneCurves' => 'Krzywe barwy',
    'ToningEffectMonochrome' => {
       PrintConv => {
@@ -814,4 +1201,5 @@
    'TransferFunction' => 'Funkcja transferu',
    'Transformation' => {
+      Description => 'PrzeksztaÅcenie',
       PrintConv => {
         'Horizontal (normal)' => '0Â° (gÃ³ra/lewo)',
@@ -826,8 +1214,11 @@
     },
    'TransmissionReference' => 'OdnoÅnik transmisji',
+   'TvExposureTimeSetting' => 'Ustawienia czasu ekspozycji TV',
+   'Uncompressed' => 'Nieskompresowany',
    'UniqueCameraModel' => 'Unikatowy model aparatu',
    'Unknown' => 'Nieznany',
    'Urgency' => 'Priorytet',
    'UserComment' => 'Komentarz uÅŒytkownika',
+   'VersionYear' => 'Rok wersji',
    'VideoCardGamma' => 'Gamma karty graficznej',
    'WBAdjLighting' => {
@@ -836,4 +1227,12 @@
       },
     },
+   'WB_RGGBLevelsCloudy' => 'Poziomy WB RGGB - zachmurzenie ',
+   'WB_RGGBLevelsDaylight' => 'Poziomy WB RGGB - ÅwiatÅo dzienne ',
+   'WB_RGGBLevelsFlash' => 'Poziomy WB RGGB - lampa bÅyskowa ',
+   'WB_RGGBLevelsFluorescentD' => 'Poziomy WB RGGB - ÅwiatÅo fluorescencyjne ',
+   'WB_RGGBLevelsFluorescentN' => 'Poziomy WB RGGB - ÅwiatÅo fluorescencyjne N ',
+   'WB_RGGBLevelsFluorescentW' => 'Poziomy WB RGGB - ÅwiatÅo fluorescencyjne W ',
+   'WB_RGGBLevelsShade' => 'Poziomy WB RGGB - cieÅ ',
+   'WB_RGGBLevelsTungsten' => 'Poziomy WB RGGB - ÅwiatÅo ÅŒarowe ',
    'WhiteBalance' => {
       Description => 'Balans bieli',
@@ -856,6 +1255,31 @@
       },
     },
+   'WhiteBalanceMode' => {
+      Description => 'Tryb balansu bieli',
+      PrintConv => {
+        'Auto (Cloudy)' => 'Automatyczny (zachmurzenie)',
+        'Auto (Day White Fluorescent)' => 'Automatyczny (biaÅe fluorescencyjne ÅwiatÅo dzienne)',
+        'Auto (Daylight Fluorescent)' => 'Automatyczny (fluorescencyjne ÅwiatÅo dzienne)',
+        'Auto (Daylight)' => 'Automatyczny (ÅwiatÅo dzienne)',
+        'Auto (Flash)' => 'Automatyczny (lampa bÅyskowa)',
+        'Auto (Shade)' => 'Automatyczny (cieÅ)',
+        'Auto (Tungsten)' => 'Automatyczny (ÅwiatÅo ÅŒarowe)',
+        'Auto (White Fluorescent)' => 'Automatyczny (biaÅe ÅwiatÅo fluorescencyjne)',
+        'Unknown' => 'Automatyczny (nie wykryty)',
+        'User-Selected' => 'UÅŒytkownika',
+      },
+    },
+   'WhiteBalanceSet' => 'Ustawienie balansu bieli',
    'WhitePoint' => 'ChromatycznoÅÄ biaÅego punktu',
+   'WorldTimeLocation' => {
+      Description => 'Miejsca czasu Åwiatowego',
+      PrintConv => {
+        'Destination' => 'Przeznaczenie',
+        'Hometown' => 'Miasto domowe',
+      },
+    },
    'Writer-Editor' => 'Autor podpisu',
+   'XClipPathUnits' => 'Jednostki wzdÅuÅŒ osi X dla ÅcieÅŒki obciÄcia',
+   'XPosition' => 'WspÃ³ÅrzÄdna X',
    'XResolution' => 'RozdzielczoÅÄ obrazu w poziomie',
    'YCbCrCoefficients' => 'WspÃ³Åczynniki matrycy transformacji przestrzeni barwowej',
@@ -868,4 +1292,6 @@
     },
    'YCbCrSubSampling' => 'WspÃ³Åczynnik podprÃ³bkowania(?) Y do C',
+   'YClipPathUnits' => 'Jednostki wzdÅuÅŒ osi Y dla ÅcieÅŒki obciÄcia',
+   'YPosition' => 'WspÃ³ÅrzÄdna Y',
    'YResolution' => 'RozdzielczoÅÄ obrazu w pionie',
    'Year' => 'Rok',
@@ -888,5 +1314,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -895,5 +1321,6 @@
 =head1 ACKNOWLEDGEMENTS
 
-Thanks to Jens Duttke and Przemyslaw Sulek for providing this translation.
+Thanks to Jens Duttke, Przemyslaw Sulek and Kacper Perschke for providing
+this translation.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ru.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ru.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/ru.pm	(revision 34921)
@@ -12,106 +12,735 @@
 use vars qw($VERSION);
 
-$VERSION = '1.02';
+$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',
-      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' => 'ÐÑÑÐŒÐŸÑÐ³ÐŸÐ»ÑÐœÐŸÐµ (ÐžÐ»Ðž ÐºÐ²Ð°ÐŽÑÐ°ÑÐœÐŸÐµ) ÑÐ°ÑÐ¿ÐŸÐ»ÐŸÐ¶ÐµÐœÐžÐµ ÑÐ»ÐµÐŒÐµÐœÑÐŸÐ²',
-      },
-    },
-   'CFAPattern' => '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 => {
+        '[Blue,Green][Green,Red]' => '[Ð¡ÐžÐœÐžÐ¹, ÐÐµÐ»ÐµÐœÑÐ¹][ÐÐµÐ»ÐµÐœÑÐ¹, ÐÑÐ°ÑÐœÑÐ¹]',
+        '[Green,Blue][Red,Green]' => '[ÐÐµÐ»ÐµÐœÑÐ¹, Ð¡ÐžÐœÐžÐ¹][ÐÑÐ°ÑÐœÑÐ¹, ÐÐµÐ»ÐµÐœÑÐ¹]',
+        '[Green,Red][Blue,Green]' => '[ÐÐµÐ»ÐµÐœÑÐ¹, ÐÑÐ°ÑÐœÑÐ¹][Ð¡ÐžÐœÐžÐ¹, ÐÐµÐ»ÐµÐœÑÐ¹]',
+        '[Red,Green][Green,Blue]' => '[ÐÑÐ°ÑÐœÑÐ¹, ÐÐµÐ»ÐµÐœÑÐ¹][ÐÐµÐ»ÐµÐœÑÐ¹, Ð¡ÐžÐœÐžÐ¹]',
+      },
+    },
+   'CacheControl' => 'ÐÐŸÐœÑÑÐŸÐ»Ñ ÐºÐµÑÐžÑÐŸÐ²Ð°ÐœÐžÑ',
+   'CacheVersion' => 'ÐÐµÑÑÐžÑ ÐºÑÑÐ°',
+   'CalendarColor' => 'ÐŠÐ²ÐµÑ ÐºÐ°Ð»ÐµÐœÐŽÐ°ÑÑ',
+   'CalendarDescription' => 'ÐÐ¿ÐžÑÐ°ÐœÐžÐµ ÐºÐ°Ð»ÐµÐœÐŽÐ°ÑÑ',
+   'CalendarID' => 'ID ÐºÐ°Ð»ÐµÐœÐŽÐ°ÑÑ',
+   'CalendarName' => 'ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐºÐ°Ð»ÐµÐœÐŽÐ°ÑÑ',
+   'CalendarScale' => 'ÐÐ°Ð»ÐµÐœÐŽÐ°ÑÐœÐ°Ñ ÑÐžÑÑÐµÐŒÐ°',
+   'CalibratedFocalLength' => 'ÐÑÐºÐ°Ð»ÐžÑÐ±ÑÐŸÐ²Ð°ÐœÐœÐŸÐµ ÑÐŸÐºÑÑÐœÐŸÐµ ÑÐ°ÑÑÑÐŸÑÐœÐžÐµ',
+   'CalibratedOpticalCenterX' => 'ÐÑÐºÐ°Ð»ÐžÑÐ±ÑÐŸÐ²Ð°ÐœÐœÑÐ¹ ÐŸÐ¿ÑÐžÑÐµÑÐºÐžÐ¹ ÑÐµÐœÑÑ Ð¿ÐŸ X',
+   'CalibratedOpticalCenterY' => 'ÐÑÐºÐ°Ð»ÐžÑÐ±ÑÐŸÐ²Ð°ÐœÐœÑÐ¹ ÐŸÐ¿ÑÐžÑÐµÑÐºÐžÐ¹ ÑÐµÐœÑÑ Ð¿ÐŸ Y',
    'CalibrationIlluminant1' => {
-      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)',
+      Description => 'ÐÐ°Ð»ÐžÐ±ÑÐŸÐ²ÐŸÑÐœÐŸÐµ ÐŸÑÐ²ÐµÑÐµÐœÐžÐµ 1',
+      PrintConv => {
+        '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',
-      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)',
-      },
-    },
-   'CameraCalibration1' => 'ÐÐ°Ð»ÐžÐ±ÑÐŸÐ²ÐŸÑÐœÐ°Ñ ÐŒÐ°ÑÑÐžÑÐ° ÑÐŸÑÐŸÐ°Ð¿Ð¿Ð°ÑÐ°ÑÐ° â1',
-   'CameraCalibration2' => 'ÐÐ°Ð»ÐžÐ±ÑÐŸÐ²ÐŸÑÐœÐ°Ñ ÐŒÐ°ÑÑÐžÑÐ° ÑÐŸÑÐŸÐ°Ð¿Ð¿Ð°ÑÐ°ÑÐ° â2',
-   'CameraCalibrationSig' => 'Ð¡ÐžÐ³ÐœÐ°ÑÑÑÐ° ÐºÐ°Ð»ÐžÐ±ÑÐŸÐ²ÐºÐž ÑÐŸÑÐŸÐ°Ð¿Ð¿Ð°ÑÐ°ÑÐ°',
-   'CameraSerialNumber' => 'Ð¡ÐµÑÐžÐ¹ÐœÑÐ¹ ÐœÐŸÐŒÐµÑ ÑÐŸÑÐŸÐ°Ð¿Ð¿Ð°ÑÐ°ÑÐ°',
-   'Caption-Abstract' => 'ÐÐŸÐŽÐ¿ÐžÑÑ',
+      Description => 'ÐÐ°Ð»ÐžÐ±ÑÐŸÐ²ÐŸÑÐœÐŸÐµ ÐŸÑÐ²ÐµÑÐµÐœÐžÐµ 2',
+      PrintConv => {
+        '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Â° Ð¿ÐŸ ÑÐ°ÑÐŸÐ²ÐŸÐ¹ ÑÑÑÐµÐ»ÐºÐµ',
+      },
+    },
+   '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 => {
@@ -120,217 +749,1467 @@
     },
    '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 => 'ÐÐ°ÐœÐœÑÐµ ÐŸ ÑÐ²ÐµÑÐŸÐ²ÐŸÐ¹ ÑÑÐµÐŽÐµ',
-      PrintConv => {
-        'ICC Profile' => 'ÐÑÐŸÑÐžÐ»Ñ ICC',
-        'Uncalibrated' => 'ÐÐµ ÐºÐ°Ð»ÐžÐ±ÑÐŸÐ²Ð°ÐœÐœÑÐ¹',
-      },
-    },
+      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 => {
+        '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 => 'Ð¡Ñ
-ÐµÐŒÐ° ÑÐ¶Ð°ÑÐžÑ',
-      PrintConv => {
+      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' => 'Ð¡ÑÐ°ÐœÐŽÐ°ÑÑ',
-      },
-    },
-   'Copyright' => 'ÐÐ»Ð°ÐŽÐµÐ»ÐµÑ ÐºÐŸÐ¿ÐžÑÐ°Ð¹ÑÐ°',
-   'CopyrightNotice' => 'Ð£Ð²ÐµÐŽÐŸÐŒÐ»ÐµÐœÐžÐµ ÐŸÐ± Ð°Ð²ÑÐŸÑÑÐºÐžÑ
- Ð¿ÑÐ°Ð²Ð°Ñ
+        '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' => 'ÐÐµ ÑÐºÐ°Ð·Ð°ÐœÐŸ',
+      },
+    },
+   'CountInfo' => 'ÐÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸ Ð¿ÐŸÐŽÑÑÑÐµ',
+   'Country' => 'Ð¡ÑÑÐ°ÐœÐ°',
+   'Country-PrimaryLocationCode' => 'ÐÐŸÐŽ ÑÑÑÐ°ÐœÑ',
+   'Country-PrimaryLocationName' => 'Ð¡ÑÑÐ°ÐœÐ°',
+   'CountryCode' => 'ÐÐŸÐŽ ÑÑÑÐ°ÐœÑ',
+   'CoverArt' => 'ÐÐ±Ð»ÐŸÐ¶ÐºÐ°',
+   'CoverArtMIMEType' => 'MIME ÑÐžÐ¿ ÐŸÐ±Ð»ÐŸÐ¶ÐºÐž',
+   'CoverArtType' => 'Ð¢ÐžÐ¿ ÐŸÐ±Ð»ÐŸÐ¶ÐºÐž',
+   'Coverage' => 'ÐÑ
+Ð²Ð°Ñ',
+   'CreateDate' => 'ÐÐ°ÑÐ° ÐŸÑÐžÑÑÐŸÐ²ÐºÐž',
+   'CreatedBy' => 'Ð¡ÐŸÐ·ÐŽÐ°Ðœ',
+   'CreationDate' => 'ÐÐ°ÑÐ° ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ',
+   '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' => 'ÐÑÑ
+ÐŸÐŽÐœÐ°Ñ Ð²ÑÑÐŸÑÐ° ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð² Ð¿ÐžÐºÑÐµÐ»ÑÑ
 ',
-   'Country' => 'Ð¡ÑÑÐ°ÐœÐ°',
-   'Country-PrimaryLocationName' => 'Ð¡ÑÑÐ°ÐœÐ°',
-   'CreateDate' => 'ÐÐ°ÑÐ° ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ',
-   'CreationDate' => 'ÐÐ°ÑÐ° ÑÐŸÐ·ÐŽÐ°ÐœÐžÑ',
-   'Credit' => 'Ð€Ð°ÐŒÐžÐ»ÐžÑ',
-   'CurrentICCProfile' => 'Ð¢ÐµÐºÑÑÐžÐ¹ ICC Ð¿ÑÐŸÑÐžÐ»Ñ',
-   'CurrentPreProfileMatrix' => 'Ð¢ÐµÐºÑÑÐ°Ñ Ð¿ÑÐµÐŽÐ²Ð°ÑÐžÑÐµÐ»ÑÐœÐ°Ñ ÑÐ²ÐµÑÐŸÐ²Ð°Ñ ÐŒÐ°ÑÑÐžÑÐ°',
+   '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 => 'ÐÐ±ÑÐ°Ð±ÐŸÑÐºÐ° ÑÐœÐžÐŒÐºÐŸÐ² Ð¿ÐŸ Ð¿ÐµÑÑÐŸÐœÐ°Ð»ÑÐœÑÐŒ ÐœÐ°ÑÑÑÐŸÐ¹ÐºÐ°ÐŒ',
-      PrintConv => {
-        'Custom' => '"ÐÑÐŸÑÐµÑÑ, ÐœÐ°ÑÑÑÐŸÐµÐœÐœÑÐ¹ Ð¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÐµÐŒ"',
-        'Normal' => 'ÐÐŸÑÐŒÐ°Ð»ÑÐœÑÐ¹ Ð¿ÑÐŸÑÐµÑÑ',
-      },
-    },
+      Description => 'ÐÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÑÑÐºÐžÐ¹ ÑÐµÐœÐŽÐµÑÐžÐœÐ³',
+      PrintConv => {
+        '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' => 'Ð¡ÑÐ°ÐœÐŽÐ°ÑÑÐœÐŸÐµ',
-      },
-    },
-   'ExifImageHeight' => 'ÐÐŸÐ¿ÑÑÑÐžÐŒÐ°Ñ Ð²ÑÑÐŸÑÐ° ÑÐœÐžÐŒÐºÐ°',
-   'ExifImageWidth' => 'ÐÐŸÐ¿ÑÑÑÐžÐŒÐ°Ñ ÑÐžÑÐžÐœÐ° ÑÐœÐžÐŒÐºÐ°',
-   'ExifOffset' => 'Exif IFD ÑÐºÐ°Ð·Ð°ÑÐµÐ»Ñ',
-   'ExifVersion' => 'Exif Ð²ÐµÑÑÐžÑ',
-   'ExposureCompensation' => '"Ð­ÐºÑÐ¿ÐŸÐ·ÐžÑÐžÑ, ÐºÐ°Ð»ÐžÐ±ÑÐŸÐ²ÐºÐ°"',
-   'ExposureIndex' => '"Ð­ÐºÑÐ¿ÐŸÐ·ÐžÑÐžÑ, Ð¿ÐŸÐºÐ°Ð·Ð°ÑÐµÐ»Ñ"',
+      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',
+      },
+    },
+   '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 => 'Ð­ÐºÑÐ¿ÐŸÐ·ÐžÑÐžÑ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐœÐ°Ñ',
-      PrintConv => {
-        'Action (High speed)' => 'Ð­ÐºÑÐµÐœ/Ð±ÐŸÐµÐ²ÐžÐº',
-        'Aperture-priority AE' => 'ÐÑÐžÐŸÑÐžÑÐµÑ ÐŽÐžÐ°ÑÑÐ°Ð³ÐŒÑ',
-        'Bulb' => 'ÐÐ°ÐŒÐ¿Ð°',
-        'Creative (Slow speed)' => 'Ð¢Ð²ÐŸÑÑÐµÑÐºÐ°Ñ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÐ°',
+      Description => 'ÐÑÐŸÐ³ÑÐ°ÐŒÐŒÐ° ÑÐºÑÐ¿ÐŸÐ·ÐžÑÐžÐž',
+      PrintConv => {
+        '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' => 'ÐÐžÐ°ÑÑÐ°Ð³ÐŒÐ°',
-   'FileFormat' => 'Ð€ÐŸÑÐŒÐ°Ñ',
-   'FileModifyDate' => 'ÐÐ°ÑÐ° ÐŸÐ±ÐœÐŸÐ²Ð»ÐµÐœÐžÑ',
-   'FileName' => 'ÐÐŒÑ ÑÐ°Ð¹Ð»Ð°',
+   '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' => 'DSC',
-        'Film Scanner' => 'Ð¡ÐºÐ°ÐœÐœÐµÑ Ð¿ÑÐŸÑÐ²ÐµÑÐžÐ²Ð°ÑÑÐµÐ³ÐŸ ÑÐžÐ¿Ð°',
-        'Reflection Print Scanner' => 'Ð¡ÐºÐ°ÐœÐœÐµÑ ÐŸÑÑÐ°Ð¶Ð°ÑÑÐµÐ³ÐŸ ÑÐžÐ¿Ð°',
+        '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, Fired' => 'ÐÐºÐ». (Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐ°Ñ Ð²ÑÐ¿ÑÑÐºÐ°)',
-        'Auto, Fired, Red-eye reduction' => '"ÐÐºÐ». (Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐ°Ñ Ð²ÑÐ¿ÑÑÐºÐ°, ÑÐœÐžÐ¶ÐµÐœÐžÐµ ÑÑÑÐµÐºÑÐ° Â«ÐºÑÐ°ÑÐœÑÑ
- Ð³Ð»Ð°Ð·Â»)"',
-        'Auto, Fired, Red-eye reduction, Return detected' => '"ÐÐºÐ». (Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐ°Ñ Ð²ÑÐ¿ÑÑÐºÐ°, ÑÐœÐžÐ¶ÐµÐœÐžÐµ ÑÑÑÐµÐºÑÐ° Â«ÐºÑÐ°ÑÐœÑÑ
- Ð³Ð»Ð°Ð·Â», ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ ÐŸÑÑÐ°Ð¶ÐµÐœÐœÐŸÐ³ÐŸ Ð»ÑÑÐ°)"',
-        'Auto, Fired, Return detected' => '"ÐÐºÐ». (Ð°Ð²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐ°Ñ Ð²ÑÐ¿ÑÑÐºÐ°, ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ ÐŸÑÑÐ°Ð¶ÐµÐœÐœÐŸÐ³ÐŸ Ð»ÑÑÐ°)"',
+      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, Return detected' => 'ÐÐºÐ». (ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ ÐŸÑÑÐ°Ð¶ÐµÐœÐœÐŸÐ³ÐŸ Ð»ÑÑÐ°)',
-        'No Flash' => 'ÐÐµÑ ÑÑÐœÐºÑÐžÐž Ð²ÑÐ¿ÑÑÐºÐž',
-        'On, Fired' => 'ÐÐºÐ». (Ð¿ÑÐžÐœÑÐŽÐžÑÐµÐ»ÑÐœÐ°Ñ)',
-        'On, Red-eye reduction' => '"ÐÐºÐ». (Ð¿ÑÐžÐœÑÐŽÐžÑÐµÐ»ÑÐœÐ°Ñ, ÑÐœÐžÐ¶ÐµÐœÐžÐµ ÑÑÑÐµÐºÑÐ° Â«ÐºÑÐ°ÑÐœÑÑ
- Ð³Ð»Ð°Ð·Â»)"',
-        'On, Red-eye reduction, Return detected' => '"ÐÐºÐ». (Ð¿ÑÐžÐœÑÐŽÐžÑÐµÐ»ÑÐœÐ°Ñ, ÑÐœÐžÐ¶ÐµÐœÐžÐµ ÑÑÑÐµÐºÑÐ° Â«ÐºÑÐ°ÑÐœÑÑ
- Ð³Ð»Ð°Ð·Â», ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ ÐŸÑÑÐ°Ð¶ÐµÐœÐœÐŸÐ³ÐŸ Ð»ÑÑÐ°)"',
-        'On, Return detected' => '"ÐÐºÐ». (Ð¿ÑÐžÐœÑÐŽÐžÑÐµÐ»ÑÐœÐ°Ñ, ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÑ ÐŸÑÑÐ°Ð¶ÐµÐœÐœÐŸÐ³ÐŸ Ð»ÑÑÐ°)"',
-      },
-    },
+        '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' => 'ÐÐŸÑÑÐµÐºÑÐžÑ Ð²ÑÐ¿ÑÑÐºÐž',
-   'FlashpixVersion' => 'ÐÐŸÐŽÐŽÐµÑÐ¶ÐžÐ²Ð°ÐµÐŒÐ°Ñ Ð²ÐµÑÑÐžÑ Flashpix',
+   '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' => 'Ð€ÐŸÐºÑÑÐœÐŸÐµ ÑÐ°ÑÑÑÐŸÑÐœÐžÐµ (Ð¿ÑÐžÐ²ÐµÐŽÐµÐœÐŸ Ðº 35 ÐŒÐŒ)',
-   'FocalLengthIn35mmFormat' => 'Ð€ÐŸÐºÑÑÐœÐŸÐµ ÑÐ°ÑÑÑÐŸÑÐœÐžÐµ ÐŽÐ»Ñ 35-ÐŒÐŒ ÑÐŸÑÐŸÐ¿Ð»ÐµÐœÐºÐž',
+   'FocalLength35efl' => 'Ð€ÐŸÐºÑÑÐœÐŸÐµ ÑÐ°ÑÑÑÐŸÑÐœÐžÐµ',
+   'FocalLengthIn35mmFormat' => 'Ð€ÐŸÐºÑÑÐœÐŸÐµ ÑÐ°ÑÑÑÐŸÑÐœÐžÐµ ÐŽÐ»Ñ 35-ÐŒÐŒ ÑÐŸÑÐŒÐ°ÑÐ°',
    'FocalPlaneResolutionUnit' => {
-      Description => 'Ð­Ð»ÐµÐŒÐµÐœÑ ÑÐ°Ð·ÑÐµÑÐµÐœÐžÑ Ð² ÑÐŸÐºÐ°Ð»ÑÐœÐŸÐ¹ Ð¿Ð»ÐŸÑÐºÐŸÑÑÐž',
-      PrintConv => {
-        'inches' => 'ÐŽÑÐ¹ÐŒ',
+      Description => 'ÐÐŽÐžÐœÐžÑÑ ÑÐ°Ð·ÑÐµÑÐµÐœÐžÑ Ð² ÑÐŸÐºÐ°Ð»ÑÐœÐŸÐ¹ Ð¿Ð»ÐŸÑÐºÐŸÑÑÐž',
+      PrintConv => {
+        'None' => 'ÐÐµ ÑÐºÐ°Ð·Ð°ÐœÐŸ',
+        'cm' => 'ÑÐŒ',
+        'inches' => 'ÐŽÑÐ¹ÐŒÑ',
+        'mm' => 'ÐŒÐŒ',
+        'um' => 'ÐŒÐºÐŒ',
       },
     },
    'FocalPlaneXResolution' => 'Ð Ð°Ð·ÑÐµÑÐµÐœÐžÐµ Ð² ÑÐŸÐºÐ°Ð»ÑÐœÐŸÐ¹ Ð¿Ð»ÐŸÑÐºÐŸÑÑÐž Ð¿ÐŸ X',
    'FocalPlaneYResolution' => 'Ð Ð°Ð·ÑÐµÑÐµÐœÐžÐµ Ð² ÑÐŸÐºÐ°Ð»ÑÐœÐŸÐ¹ Ð¿Ð»ÐŸÑÐºÐŸÑÑÐž Ð¿ÐŸ Y',
-   'FocusMode' => 'Ð€ÐŸÐºÑÑÐžÑÐŸÐ²ÐºÐ°',
-   'ForwardMatrix1' => 'ÐÑÑÐŒÐ°Ñ ÐŒÐ°ÑÑÐžÑÐ° â1',
-   'ForwardMatrix2' => 'ÐÑÑÐŒÐ°Ñ ÐŒÐ°ÑÑÐžÑÐ° â2',
-   'FrameRate' => 'ÐÐ»ÐŸÑÐœÐŸÑÑÑ ÐºÐ°ÐŽÑÐŸÐ²',
-   'FrameSize' => '"ÐÐ°ÐŽÑ, ÑÐ°Ð·ÐŒÐµÑ"',
-   'GPSAltitude' => 'ÐÑÑÐŸÑÐ°',
+   '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 => 'ÐÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐžÐµ Ð¿ÐŸ Ð²ÑÑÐŸÑÐµ',
-      PrintConv => {
-        'Above Sea Level' => 'Ð£ÑÐŸÐ²ÐµÐœÑ ÐŒÐŸÑÑ',
-        'Below Sea Level' => 'ÐÐ¿ÐŸÑÐœÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÑÑÐŸÐ²ÐœÑ ÐŒÐŸÑÑ (ÐœÐµÐ³Ð°ÑÐžÐ²ÐœÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ)',
-      },
-    },
-   'GPSAreaInformation' => 'ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐŸÐ±Ð»Ð°ÑÑÐž GPS',
-   'GPSDOP' => 'Ð¢ÐŸÑÐœÐŸÑÑÑ ÐžÐ·ÐŒÐµÑÐµÐœÐžÑ',
-   'GPSDateStamp' => 'ÐÐ°ÑÐ° GPS',
-   'GPSDestBearing' => 'ÐÐ·ÐžÐŒÑÑ Ð¿ÑÐœÐºÑÐ° ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ',
-   'GPSDestBearingRef' => 'ÐÐ¿ÐŸÑÐœÐ°Ñ Ð²ÐµÐ»ÐžÑÐžÐœÐ° ÐŽÐ»Ñ Ð°Ð·ÐžÐŒÑÑÐ° Ð¿ÑÐœÐºÑÐ° ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ',
-   'GPSDestDistance' => 'Ð Ð°ÑÑÑÐŸÑÐœÐžÐµ ÐŽÐŸ Ð¿ÑÐœÐºÑÐ° ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ',
-   'GPSDestDistanceRef' => 'ÐÐ¿ÐŸÑÐœÐ°Ñ Ð²ÐµÐ»ÐžÑÐžÐœÐ° ÑÐ°ÑÑÑÐŸÑÐœÐžÑ ÐŽÐŸ Ð¿ÑÐœÐºÑÐ° ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ',
-   'GPSDestLatitude' => 'ÐšÐžÑÐŸÑÐ° Ð¿ÑÐœÐºÑÐ° ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ',
-   'GPSDestLatitudeRef' => 'ÐÐ¿ÐŸÑÐœÐ°Ñ Ð²ÐµÐ»ÐžÑÐžÐœÐ° ÐŽÐ»Ñ ÑÐžÑÐŸÑÑ Ð¿ÑÐœÐºÑÐ° ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ',
-   'GPSDestLongitude' => 'ÐÐŸÐ»Ð³ÐŸÑÐ° Ð¿ÑÐœÐºÑÐ° ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ',
-   'GPSDestLongitudeRef' => 'ÐÐ¿ÐŸÑÐœÐ°Ñ Ð²ÐµÐ»ÐžÑÐžÐœÐ° ÐŽÐ»Ñ ÐŽÐŸÐ»Ð³ÐŸÑÑ Ð¿ÑÐœÐºÑÐ° ÐœÐ°Ð·ÐœÐ°ÑÐµÐœÐžÑ',
-   'GPSDifferential' => {
-      Description => 'ÐÐžÑÑÐµÑÐµÐœÑÐžÐ°Ð»ÑÐœÐ°Ñ ÐºÐŸÑÑÐµÐºÑÐžÑ GPS',
-      PrintConv => {
-        'Differential Corrected' => 'ÐÐžÑÑÐµÑÐµÐœÑÐžÐ°Ð»ÑÐœÐ°Ñ ÐºÐŸÑÑÐµÐºÑÐžÑ Ð¿ÑÐžÐŒÐµÐœÐµÐœÐ°',
-        'No Correction' => 'ÐÐ·ÐŒÐµÑÐµÐœÐžÐµ Ð±ÐµÐ· ÐŽÐžÑÑÐµÑÐµÐœÑÐžÐ°Ð»ÑÐœÐŸÐ¹ ÐºÐŸÑÑÐµÐºÑÐžÐž',
-      },
-    },
-   'GPSImgDirection' => 'ÐÐ°Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ',
-   'GPSImgDirectionRef' => 'ÐÐ¿ÐŸÑÐœÐ°Ñ Ð²ÐµÐ»ÐžÑÐžÐœÐ° ÐŽÐ»Ñ ÐœÐ°Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ',
-   'GPSInfo' => 'IFD ÑÐºÐ°Ð·Ð°ÑÐµÐ»Ñ ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž GPS',
-   'GPSLatitude' => 'ÐšÐžÑÐŸÑÐ°',
-   'GPSLatitudeRef' => {
-      Description => 'Ð¡ÐµÐ²ÐµÑÐœÐ°Ñ ÐžÐ»Ðž ÑÐ¶ÐœÐ°Ñ ÑÐžÑÐŸÑÐ°',
+      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' => 'Ð¡ÐµÐ²ÐµÑÐœÐ°Ñ ÑÐžÑÐŸÑÐ°',
@@ -338,7 +2217,7 @@
       },
     },
-   'GPSLongitude' => 'ÐÐŸÐ»Ð³ÐŸÑÐ°',
-   'GPSLongitudeRef' => {
-      Description => 'ÐÐŸÑÑÐŸÑÐœÐ°Ñ ÐžÐ»Ðž Ð·Ð°Ð¿Ð°ÐŽÐœÐ°Ñ ÐŽÐŸÐ»Ð³ÐŸÑÐ°',
+   'GPSDestLongitude' => 'GPS â ÐÐŸÐ»Ð³ÐŸÑÐ° ÐŸÐ±ÑÐµÐºÑÐ° ÑÑÑÐŒÐºÐž',
+   'GPSDestLongitudeRef' => {
+      Description => 'GPS â ÐÐœÐŽÐµÐºÑ ÐŽÐŸÐ»Ð³ÐŸÑÑ ÐŸÐ±ÑÐµÐºÑÐ° ÑÑÑÐŒÐºÐž',
       PrintConv => {
         'East' => 'ÐÐŸÑÑÐŸÑÐœÐ°Ñ ÐŽÐŸÐ»Ð³ÐŸÑÐ°',
@@ -346,42 +2225,87 @@
       },
     },
-   'GPSMapDatum' => 'ÐÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÑ ÐŽÐ°ÐœÐœÑÐµ Ð³ÐµÐŸÐŽÐµÐ·ÐžÑÐµÑÐºÐžÑ
- ÐžÑÑÐ»ÐµÐŽÐŸÐ²Ð°ÐœÐžÐ¹',
+   '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',
-      PrintConv => {
-        '3-Dimensional Measurement' => '3-ÐŒÐµÑÐœÐŸÐµ ÐžÐ·ÐŒÐµÑÐµÐœÐžÐµ',
-      },
-    },
-   'GPSProcessingMethod' => 'ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐŒÐµÑÐŸÐŽÐ° ÐŸÐ±ÑÐ°Ð±ÐŸÑÐºÐž GPS',
-   'GPSSatellites' => '"Ð¡Ð¿ÑÑÐœÐžÐºÐž GPS, ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÐŒÑÐµ ÐŽÐ»Ñ ÐžÐ·ÐŒÐµÑÐµÐœÐžÑ"',
-   'GPSSpeed' => 'Ð¡ÐºÐŸÑÐŸÑÑÑ GPS-ÑÑÑÑÐŸÐ¹ÑÑÐ²Ð°',
+      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 => 'Ð¡ÐºÐŸÑÐŸÑÑÐœÐŸÐ¹ ÑÐ»ÐµÐŒÐµÐœÑ',
-      PrintConv => {
-        'km/h' => 'ÐÐžÐ»ÐŸÐŒÐµÑÑÑ Ð² ÑÐ°Ñ',
+      Description => 'GPS â ÐÐŽÐžÐœÐžÑÑ ÐžÐ·ÐŒÐµÑÐµÐœÐžÑ ÑÐºÐŸÑÐŸÑÑÐž',
+      PrintConv => {
+        'km/h' => 'ÐÐŒ/Ñ',
         'knots' => 'Ð£Ð·Ð»Ñ',
-        'mph' => 'ÐÐžÐ»Ðž Ð² ÑÐ°Ñ',
-      },
-    },
+        'mph' => 'ÐÐžÐ»Ñ/Ñ',
+      },
+    },
+   'GPSSpeedX' => 'GPS â Ð¡ÐºÐŸÑÐŸÑÑÑ Ð¿ÐŸ X',
+   'GPSSpeedY' => 'GPS â Ð¡ÐºÐŸÑÐŸÑÑÑ Ð¿ÐŸ Y',
+   'GPSSpeedZ' => 'GPS â Ð¡ÐºÐŸÑÐŸÑÑÑ Ð¿ÐŸ Z',
    'GPSStatus' => {
-      Description => 'Ð¡ÐŸÑÑÐŸÑÐœÐžÐµ GPS-ÑÑÑÑÐŸÐ¹ÑÑÐ²Ð°',
-      PrintConv => {
-        'Measurement Active' => 'ÐÑÐŸÐžÐ·Ð²ÐŸÐŽÐžÑÑÑ ÐžÐ·ÐŒÐµÑÐµÐœÐžÐµ',
-        'Measurement Void' => 'ÐÐ·Ð°ÐžÐŒÐœÐ°Ñ ÑÐŸÐ²ÐŒÐµÑÑÐžÐŒÐŸÑÑÑ ÐžÐ·ÐŒÐµÑÐµÐœÐžÐ¹',
-      },
-    },
-   'GPSTimeStamp' => 'GPS-Ð²ÑÐµÐŒÑ (Ð°ÑÐŸÐŒÐœÑÐµ ÑÐ°ÑÑ)',
-   'GPSTrack' => 'ÐÐ°Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÐŽÐ²ÐžÐ¶ÐµÐœÐžÑ',
+      Description => 'GPS â Ð¡ÐŸÑÑÐŸÑÐœÐžÐµ Ð¿ÑÐžÑÐŒÐœÐžÐºÐ° Ð²ÐŸ Ð²ÑÐµÐŒÑ ÑÑÑÐŒÐºÐž',
+      PrintConv => {
+        'Measurement Active' => 'ÐÐŸÐŸÑÐŽÐžÐœÐ°ÑÑ Ð°ÐºÑÑÐ°Ð»ÑÐœÑÐµ',
+        'Measurement Void' => 'ÐÐºÑÑÐ°Ð»ÑÐœÑÑ
+ ÐºÐŸÐŸÑÐŽÐžÐœÐ°Ñ ÐœÐµÑÑ',
+      },
+    },
+   'GPSTimeStamp' => 'GPS â ÐÑÐµÐŒÑ Ð·Ð°Ð¿ÐžÑÐ°ÐœÐœÑÑ
+ ÐºÐŸÐŸÑÐŽÐžÐœÐ°Ñ',
+   'GPSTrack' => 'GPS â Ð¢ÑÐµÐº',
+   'GPSTrackRaw' => 'GPS â Ð¢ÑÐµÐº â Raw',
    'GPSTrackRef' => {
-      Description => 'ÐÐ¿ÐŸÑÐœÐ°Ñ Ð²ÐµÐ»ÐžÑÐžÐœÐ° ÐœÐ°Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÑ ÐŽÐ²ÐžÐ¶ÐµÐœÐžÑ',
-      PrintConv => {
-        'Magnetic North' => 'ÐÐ°Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÐŒÐ°Ð³ÐœÐžÑÐœÐŸÐ¹ ÑÑÑÐµÐ»ÐºÐž',
-        'True North' => 'ÐÑÑÐžÐœÐœÐŸÐµ ÐœÐ°Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ',
-      },
-    },
-   'GPSVersionID' => 'ÐÐµÑÑÐžÑ GPS-ÑÑÐ³Ð°',
+      Description => 'GPS â ÐÑÐžÐµÐœÑÐžÑ ÐœÐ°Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÑ',
+      PrintConv => {
+        'Magnetic North' => 'ÐÐ° ÐŒÐ°Ð³ÐœÐžÑÐœÑÐ¹ ÑÐµÐ²ÐµÑÐœÑÐ¹ Ð¿ÐŸÐ»ÑÑ',
+        'True North' => 'ÐÐ° Ð³ÐµÐŸÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÐ¹ ÑÐµÐ²ÐµÑÐœÑÐ¹ Ð¿ÐŸÐ»ÑÑ',
+      },
+    },
+   'GPSVersionID' => 'GPS â ÐÐµÑÑÐžÑ ÑÐµÐ³ÐŸÐ²',
    'GainControl' => {
-      Description => 'Ð£Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÑÐ°Ð³ÐŸÐŒ',
+      Description => 'Ð£Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ ÑÑÐžÐ»ÐµÐœÐžÐµÐŒ',
       PrintConv => {
         'High gain down' => 'Ð¡ Ð±ÐŸÐ»ÑÑÐžÐŒ ÑÐ°Ð³ÐŸÐŒ Ð²ÐœÐžÐ·',
@@ -391,81 +2315,1329 @@
         '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' => 'ÐÐµÑ',
       },
     },
-   'Gamma' => 'ÐÐ°ÐŒÐŒÐ°',
-   'Gradation' => 'ÐÐ¿ÐµÑÐ°ÑÐ»ÑÑÑ.ÑÐµÐ¶ÐžÐŒ',
-   'HDR' => {
-      Description => 'ÐÐ²ÑÐŸ HDR',
-      PrintConv => {
-        'Off' => 'ÐÑÐºÐ»ÑÑÐµÐœÐŸ',
-      },
-    },
-   'Headline' => 'ÐÐ°Ð³ÐŸÐ»ÐŸÐ²ÐŸÐº',
-   'HighISONoiseReduction' => {
-      Description => 'NR Ð²ÑÑÐŸÐºÐŸÐ³ÐŸ ISO',
-      PrintConv => {
-        'Auto' => 'ÐÐ²ÑÐŸ',
-        'High' => 'Hi',
-        'Low' => 'Lo',
-        'Normal' => 'ÐÐŸÑÐŒÐ°Ð»ÑÐœÐ°Ñ',
-        'Off' => 'ÐÑÐºÐ»ÑÑÐµÐœÐŸ',
-      },
-    },
-   'Hue' => 'ÐÑÑÐµÐœÐŸÐº',
-   'ISO' => 'ÐÐœÐ°ÑÐµÐœÐžÐµ ISO',
-   'ImageHeight' => 'ÐÑÑÐŸÑÐ° ÑÐœÐžÐŒÐºÐ°',
-   'ImageSize' => '"Ð¡ÐœÐžÐŒÐŸÐº, ÑÐ°Ð·ÐŒÐµÑ"',
-   'ImageUniqueID' => 'Ð£ÐœÐžÐºÐ°Ð»ÑÐœÑÐ¹ ID-ÐºÐŸÐŽ ÑÐœÐžÐŒÐºÐ°',
-   'ImageWidth' => 'ÐšÐžÑÐžÐœÐ° ÑÐœÐžÐŒÐºÐ°',
+   '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' => 'ÐÐœÑÑÑÑÐºÑÐžÐž',
-   'InteropIndex' => 'ÐÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐžÑ Ð²Ð·Ð°ÐžÐŒÐœÐŸÐ¹ ÑÐŸÐ²ÐŒÐµÑÑÐžÐŒÐŸÑÑÐž',
-   'InteropOffset' => 'Ð¢ÑÐ³ Ð²Ð·Ð°ÐžÐŒÐœÐŸÐ¹ ÑÐŸÐ²ÐŒÐµÑÑÐžÐŒÐŸÑÑÐž',
-   'InteropVersion' => 'ÐÐµÑÑÐžÑ Ð²Ð·Ð°ÐžÐŒÐœÐŸÐ¹ ÑÐŸÐ²ÐŒÐµÑÑÐžÐŒÐŸÑÑÐž',
+   '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' => 'ÐÐ±ÑÐµÐºÑÐžÐ²',
-   'LensInfo' => 'ÐÐœÑÐŸÑÐŒÐ°ÑÐžÑ ÐŸÐ± ÐŸÐ±ÑÐµÐºÑÐžÐ²Ðµ',
+   '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' => 'ÐÐ±Ð»Ð°ÑÐœÐŸÑÑÑ',
-        'Cool White Fluorescent' => 'Ð€Ð»ÑÐŸÑÐµÑÑÐµÐœÑÐœÑÐ¹ Ð±ÐµÐ»ÑÐ¹ Ñ
-ÐŸÐ»ÐŸÐŽÐœÑÐ¹ (W 3800 - 4500K)',
-        'Day White Fluorescent' => 'Ð€Ð»ÑÐŸÑÐµÑÑÐµÐœÑÐœÑÐ¹ Ð±ÐµÐ»ÑÐ¹ ÐŽÐœÐµÐ²ÐœÐŸÐ¹',
-        'Daylight' => 'ÐÐœÐµÐ²ÐœÐŸÐ¹ ÑÐ²ÐµÑ',
-        'Daylight Fluorescent' => 'Ð€Ð»ÑÐŸÑÐµÑÑÐµÐœÑÐœÑÐ¹ Ð±ÐµÐ»ÑÐ¹ ÐŽÐœÐµÐ²ÐœÐŸÐ³ÐŸ ÑÐ²ÐµÑÐ° (D 5700 - 7100K)',
-        'Fine Weather' => 'Ð¯ÑÐœÐ°Ñ Ð¿ÐŸÐ³ÐŸÐŽÐ°',
-        'Flash' => 'ÐÑÐ¿ÑÑÐºÐ°',
-        'Fluorescent' => 'Ð€Ð»ÑÐŸÑÐµÑÑÐµÐœÑÐœÑÐ¹',
+      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' => 'Ð¢ÐµÐœÑ',
+        'Other' => 'ÐÑÑÐ³ÐŸÐ¹ ÐžÑÑÐŸÑÐœÐžÐº ÑÐ²ÐµÑÐ°',
+        'Shade' => 'Ð¢ÐµÐœÑ (7500 Ð)',
         '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)',
-      },
-    },
+        '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' => 'Ð¢Ð°Ð±Ð»ÐžÑÐ° Ð»ÐžÐœÐµÐ°ÑÐžÐ·Ð°ÑÐžÐž',
-   'LocalizedCameraModel' => 'ÐÐŸÐºÐ°Ð»ÐžÐ·ÐŸÐ²Ð°ÐœÐœÐŸÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐŸÑÐŸÐ°Ð¿Ð¿Ð°ÑÐ°ÑÐ°',
-   'Location' => 'ÐÐµÑÑÐŸ ÑÑÐµÐŒÐºÐž',
+   'Linearized' => {
+      Description => 'ÐÐžÐœÐµÐ°ÑÐžÐ·Ð°ÑÐžÑ',
+      PrintConv => {
+        'No' => 'ÐÐµÑ',
+        'Yes' => 'ÐÐ°',
+      },
+    },
+   'Lines' => 'Ð¡ÑÑÐŸÐº',
+   'LinkedProfileName' => 'ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ Ð¿ÑÐŸÑÐžÐ»Ñ',
+   'LithostratigraphicTerms' => 'ÐÐžÑÐŸÑÑÑÐ°ÑÐžÐ³ÑÐ°ÑÐžÑÐµÑÐºÐžÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÑ Ð¿ÐŸÑÐŸÐŽ',
+   'LivingSpecimen' => 'ÐÐžÐ²ÐŸÐ¹ ÐŸÐ±ÑÐ°Ð·ÐµÑ',
+   'LivingSpecimenMaterialSampleID' => 'ÐÐžÐ²ÐŸÐ¹ ÐŸÐ±ÑÐ°Ð·ÐµÑ â ID ÐŸÐ±ÑÐ°Ð·ÑÐ° ÐŒÐ°ÑÐµÑÐžÐ°Ð»Ð°',
+   'LocalBasePath' => 'ÐÐŸÐºÐ°Ð»ÑÐœÑÐ¹ Ð±Ð°Ð·ÐŸÐ²ÑÐ¹ Ð¿ÑÑÑ',
+   'LocalCaption' => 'ÐÐ¿ÐžÑÐ°ÐœÐžÐµ ÐŒÐµÑÑÐ°',
+   'LocalDefaultAlarm' => 'ÐÐŸÐºÐ°Ð»ÑÐœÑÐ¹ ÑÐžÐ³ÐœÐ°Ð» Ð¿ÐŸ-ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ',
+   'LocalPositionNED' => 'ÐÐŸÐºÐ°Ð»ÑÐœÐ°Ñ Ð¿ÐŸÐ·ÐžÑÐžÑ NED',
+   'LocalizedCameraModel' => 'ÐÐŸÐºÐ°Ð»ÐžÐ·ÐŸÐ²Ð°ÐœÐœÐŸÐµ ÐœÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐŒÐŸÐŽÐµÐ»Ðž ÐºÐ°ÐŒÐµÑÑ',
+   'Location' => 'ÐÐµÑÑÐŸÐ¿ÐŸÐ»ÐŸÐ¶ÐµÐœÐžÐµ',
+   'Logo' => 'ÐÐŸÐ³ÐŸÑÐžÐ¿',
    'LongExposureNoiseReduction' => {
-      Description => 'NR ÐŽÐŸÐ»Ð³ÐŸÐ¹ ÑÐºÑÐ¿.',
-      PrintConv => {
-        'Off' => 'ÐÑÐºÐ»ÑÑÐµÐœÐŸ',
+      Description => 'ÐšÑÐŒÐŸÐ¿ÐŸÐŽÐ°Ð²Ð»ÐµÐœÐžÐµ Ð¿ÑÐž ÐŽÐ»ÐžÑÐµÐ»ÑÐœÐŸÐ¹ Ð²ÑÐŽÐµÑÐ¶ÐºÐµ',
+      PrintConv => {
+        'Auto' => 'ÐÐ²ÑÐŸÐŒÐ°ÑÐžÑÐµÑÐºÐŸÐµ',
+        'Off' => 'ÐÐµ Ð²ÐºÐ»ÑÑÐµÐœÐŸ',
         'On' => 'ÐÐºÐ»ÑÑÐµÐœÐŸ',
       },
     },
-   'Make' => 'ÐÐ·Ð³ÐŸÑÐŸÐ²ÐžÑÐµÐ»Ñ',
+   '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 => 'ÐÐµÐ·ÐŸÐ¿Ð°ÑÐœÐŸÑÑÑ Â«Ð¿ÑÐžÐŒÐµÑÐ°ÐœÐžÐ¹ Ð¿ÑÐŸÐžÐ·Ð²ÐŸÐŽÐžÑÐµÐ»ÑÂ»',
+      Description => 'ÐÑÐžÐŒÐµÑÐ°ÐœÐžÑ Ð±ÐµÐ·ÐŸÐ¿Ð°ÑÐœÐŸÑÑÐž',
       PrintConv => {
         'Safe' => 'ÐÐµÐ·ÐŸÐ¿Ð°ÑÐœÐŸ',
@@ -473,89 +3645,1056 @@
       },
     },
+   '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' => 'ÐÐ°ÐœÐœÑÐµ Ð¿ÑÐŸÐžÐ·Ð²ÐŸÐŽÐžÑÐµÐ»ÐµÐ¹',
-   'MaskedAreas' => 'ÐÐµÐ°ÐºÑÐžÐ²ÐœÑÐµ ÐŸÐ±Ð»Ð°ÑÑÐž',
-   'MaxAperture' => 'ÐÐ°ÐºÑ. ÐŽÐžÐ°ÑÑÐ°Ð³ÐŒÐ° ÐŸÐ±ÑÐµÐºÑÐžÐ²Ð°',
+   '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' => 'ÐÑÑÐ³ÐŸÐµ',
+        'Average' => 'Ð£ÑÑÐµÐŽÐœÑÐœÐœÑÐ¹',
+        'Center-weighted average' => 'ÐŠÐµÐœÑÑÐ°Ð»ÑÐœÐŸ-Ð²Ð·Ð²ÐµÑÐµÐœÐœÑÐ¹',
+        'Multi-segment' => 'ÐÑÐµÐœÐŸÑÐœÑÐ¹/ÐÐœÐŸÐ³ÐŸÐ·ÐŸÐœÐœÑÐ¹',
+        'Multi-spot' => 'ÐÐœÐŸÐ³ÐŸÑÐŸÑÐµÑÐœÑÐ¹',
+        'Other' => 'ÐÑÑÐ³ÐŸÐ¹',
         'Partial' => 'Ð§Ð°ÑÑÐžÑÐœÑÐ¹',
         'Spot' => 'Ð¢ÐŸÑÐµÑÐœÑÐ¹',
-        'Unknown' => 'ÐœÐµÐžÐ·Ð²ÐµÑÑÐœÐŸ',
-      },
-    },
-   'Model' => 'ÐÐ°ÐŒÐµÑÐ°',
-   'ModifyDate' => '"Ð€Ð°Ð¹Ð», ÐžÐ·ÐŒÐµÐœÐžÑÑ ÐŽÐ°ÑÑ Ðž Ð²ÑÐµÐŒÑ"',
+        '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' => 'ÐÑÐºÐ»ÑÑÐµÐœÐŸ',
+      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)' => 'ÐÐŸÐ»ÐŸÐ¶ÐžÑÐµÐ»ÑÐœÐŸÐµ ÐœÐ°Ð¿ÑÐ°Ð²Ð»ÐµÐœÐžÐµ',
+        '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Â° Ð¿ÐŸ ÑÐ°ÑÐŸÐ²ÐŸÐ¹ ÑÑÑÐµÐ»ÐºÐµ',
       },
     },
-   'OriginalRawFileData' => 'ÐÑÑ
-ÐŸÐŽÐœÑÐµ ÐŽÐ°ÐœÐœÑÐµ raw-ÑÐ°Ð¹Ð»Ð°',
-   'OriginalRawFileDigest' => 'Ð¡ÐžÐ³ÐœÐ°ÑÑÑÐ° ÐžÑÑ
-ÐŸÐŽÐœÐŸÐ³ÐŸ Raw-ÑÐ°Ð¹Ð»Ð°',
-   'OriginalRawFileName' => 'ÐÑÑ
-ÐŸÐŽÐœÐŸÐµ ÐžÐŒÑ Raw-ÑÐ°Ð¹Ð»Ð°',
-   'PhotometricInterpretation' => 'Ð¡ÐŸÑÑÐ°Ð² Ð¿ÐžÐºÑÐµÐ»Ð°',
+   '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' => 'ÐºÑÑÐ¿ÐœÑÐ¹ ÑÐŸÑÐŒÐ°Ñ',
-        'Planar' => 'Ð¿Ð»Ð°ÐœÐ°ÑÐœÑÐ¹ ÑÐŸÑÐŒÐ°Ñ',
-      },
-    },
-   'PreviewApplicationName' => 'ÐÐŒÑ Ð¿ÑÐžÐ»ÐŸÐ¶ÐµÐœÐžÑ Ð¿ÑÐµÐŽÐ¿ÑÐŸÑÐŒÐŸÑÑÐ°',
-   'PreviewApplicationVersion' => 'ÐÐµÑÑÐžÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ Ð¿ÑÐµÐŽÐ¿ÑÐŸÑÐŒÐŸÑÑÐ°',
+      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 => 'ÐŠÐ²ÐµÑÐŸÐ²ÐŸÐµ Ð¿ÑÐŸÑÑÑÐ°ÐœÑÑÐ²ÐŸ Ð¿ÑÐµÐŽÐ¿ÑÐŸÑÐŒÐŸÑÑÐ°',
+      Description => 'Ð€Ð°Ð¹Ð» Ð¿ÑÐµÐŽÐ¿ÑÐŸÑÐŒÐŸÑÑÐ° â ÐŠÐ²ÐµÑÐŸÐ²ÐŸÐµ Ð¿ÑÐŸÑÑÑÐ°ÐœÑÑÐ²ÐŸ',
       PrintConv => {
         'Unknown' => 'ÐÐµÐžÐ·Ð²ÐµÑÑÐœÐŸ',
       },
     },
-   'PreviewDateTime' => 'ÐÐ°ÑÐ° Ðž Ð²ÑÐµÐŒÑ Ð¿ÑÐµÐŽÐ¿ÑÐŸÑÐŒÐŸÑÑÐ°',
-   'PreviewSettingsDigest' => 'Ð¡ÐžÐ³ÐœÐ°ÑÑÑÐ° ÐœÐ°ÑÑÑÐŸÐµÐº Ð¿ÑÐµÐŽÐ¿ÑÐŸÑÐŒÐŸÑÑÐ°',
-   'PreviewSettingsName' => 'ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ ÐœÐ°ÑÑÑÐŸÐµÐº Ð¿ÑÐµÐŽÐ¿ÑÐŸÑÐŒÐŸÑÑÐ°',
-   'PrimaryChromaticities' => 'Ð¢ÐŸÐœÐ°Ð»ÑÐœÐŸÑÑÑ ÐŸÑÐœÐŸÐ²ÐœÑÑ
+   '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' => 'ÐÐ²ÑÐŸÑÑÐºÐžÐµ Ð¿ÑÐ°Ð²Ð° Ð¿ÑÐŸÑÐžÐ»Ñ',
+   'ProfileCopyright' => 'ÐÐ²ÑÐŸÑÑÐºÐŸÐµ Ð¿ÑÐ°Ð²ÐŸ Ð¿ÑÐŸÑÐžÐ»Ñ',
+   'ProfileDataOffset' => 'Ð¡ÐŒÐµÑÐµÐœÐžÐµ ÐŽÐ°ÐœÐœÑÑ
+ Ð¿ÑÐŸÑÐžÐ»Ñ',
    'ProfileEmbedPolicy' => {
       Description => 'ÐÐŸÐ»ÐžÑÐžÐºÐ° Ð²ÐœÐµÐŽÑÐµÐœÐžÑ Ð¿ÑÐŸÑÐžÐ»Ñ',
       PrintConv => {
         'Allow Copying' => 'Ð Ð°Ð·ÑÐµÑÐµÐœÐŸ ÐºÐŸÐ¿ÐžÑÐŸÐ²Ð°ÐœÐžÐµ',
-        'Embed if Used' => 'ÐÐœÐµÐŽÑÐžÑÑ ÐµÑÐ»Ðž ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ðœ',
+        'Embed if Used' => 'ÐÐœÐµÐŽÑÐžÑÑ ÐµÑÐ»Ðž ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ',
         'Never Embed' => 'ÐÐžÐºÐŸÐ³ÐŽÐ° ÐœÐµ Ð²ÐœÐµÐŽÑÑÑÑ',
-        'No Restrictions' => 'ÐÐµÑ ÐŸÐ³ÑÐ°ÐœÐžÑÐµÐœÐžÐ¹',
-      },
-    },
-   'ProfileHueSatMapData1' => 'ÐÐ°ÐœÑÐµ ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐŸÑÑÐµÐœÐºÐ°/ÐœÐ°ÑÑÑÐµÐœÐœÐŸÑÑÐž â1',
-   'ProfileHueSatMapData2' => 'ÐÐ°ÐœÑÐµ ÐŸÑÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ ÐŸÑÑÐµÐœÐºÐ°/ÐœÐ°ÑÑÑÐµÐœÐœÐŸÑÑÐž â2',
-   'ProfileHueSatMapDims' => 'ÐÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÐŸÐ±ÑÐ°Ð·ÑÐŸÐ² ÐŸÑÑÐµÐœÐºÐŸÐ²',
-   'ProfileLookTableData' => 'ÐÐ°ÐœÐœÑÐµ ÑÐ°Ð±Ð»ÐžÑÑ Ð¿ÑÐŸÑÐŒÐŸÑÑÐ°',
-   'ProfileLookTableDims' => 'ÐÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÐŸÐ±ÑÐ°Ð·ÑÐŸÐ² ÐŸÑÑÐµÐœÐºÐŸÐ²',
-   'ProfileName' => 'ÐÐŒÑ Ð¿ÑÐŸÑÐžÐ»Ñ',
-   'ProfileToneCurve' => 'ÐÑÐžÐ²Ð°Ñ ÑÑÐŸÐºÑÑÐž Ð¿ÑÐŸÑÐžÐ»Ñ',
+        'No Restrictions' => 'ÐÐµÐ· ÐŸÐ³ÑÐ°ÐœÐžÑÐµÐœÐžÐ¹',
+      },
+    },
+   'ProfileHueSatMapData1' => 'ÐÑÐŸÑÐžÐ»Ñ â ÐÐ°ÑÑÐ° ÐŸÑÑÐµÐœÐºÐŸÐ²/ÐœÐ°ÑÑÑÐµÐœÐœÐŸÑÑÐž â ÐÐ°ÐœÐœÑÐµ 1',
+   'ProfileHueSatMapData2' => 'ÐÑÐŸÑÐžÐ»Ñ â ÐÐ°ÑÑÐ° ÐŸÑÑÐµÐœÐºÐŸÐ²/ÐœÐ°ÑÑÑÐµÐœÐœÐŸÑÑÐž â ÐÐ°ÐœÐœÑÐµ 2',
+   'ProfileHueSatMapDims' => 'ÐÑÐŸÑÐžÐ»Ñ â ÐÐ°ÑÑÐ° ÐŸÑÑÐµÐœÐºÐŸÐ²/ÐœÐ°ÑÑÑÐµÐœÐœÐŸÑÑÐž â ÐÐ°ÑÐµÐŒÐœÐµÐœÐžÐµ',
+   'ProfileHueSatMapEncoding' => {
+      Description => 'ÐÑÐŸÑÐžÐ»Ñ â ÐÐ°ÑÑÐ° ÐŸÑÑÐµÐœÐºÐŸÐ²/ÐœÐ°ÑÑÑÐµÐœÐœÐŸÑÑÐž â ÐÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ',
+      PrintConv => {
+        'Linear' => 'ÐÐžÐœÐµÐ¹ÐœÐŸÐµ',
+      },
+    },
+   'ProfileLookTableData' => 'ÐÑÐŸÑÐžÐ»Ñ â Ð¢Ð°Ð±Ð»ÐžÑÐ° Ð¿ÐŸÐŽÑÑÐ°ÐœÐŸÐ²ÐºÐž â ÐÐ°ÐœÐœÑÐµ',
+   'ProfileLookTableDims' => 'ÐÑÐŸÑÐžÐ»Ñ â Ð¢Ð°Ð±Ð»ÐžÑÐ° Ð¿ÐŸÐŽÑÑÐ°ÐœÐŸÐ²ÐºÐž â ÐÐ°ÑÐµÐŒÐœÐµÐœÐžÐµ',
+   'ProfileLookTableEncoding' => {
+      Description => 'ÐÑÐŸÑÐžÐ»Ñ â Ð¢Ð°Ð±Ð»ÐžÑÐ° Ð¿ÐŸÐŽÑÑÐ°ÐœÐŸÐ²ÐºÐž â ÐÐŸÐŽÐžÑÐŸÐ²Ð°ÐœÐžÐµ',
+      PrintConv => {
+        'Linear' => 'ÐÐžÐœÐµÐ¹ÐœÐŸÐµ',
+      },
+    },
+   'ProfileName' => 'ÐÐ°Ð·Ð²Ð°ÐœÐžÐµ Ð¿ÑÐŸÑÐžÐ»Ñ',
+   'ProfileSize' => 'Ð Ð°Ð·ÐŒÐµÑ Ð¿ÑÐŸÑÐžÐ»Ñ',
+   'ProfileToneCurve' => 'ÐÑÐŸÑÐžÐ»Ñ â Ð¢ÐŸÐœÐŸÐ²Ð°Ñ ÐºÑÐžÐ²Ð°Ñ',
+   'ProfileType' => {
+      Description => 'Ð¢ÐžÐ¿ Ð¿ÑÐŸÑÐžÐ»Ñ',
+      PrintConv => {
+        'Unspecified' => 'ÐÐµ ÑÐºÐ°Ð·Ð°Ðœ',
+      },
+    },
+   'ProgID' => 'ID Ð¿ÑÐžÐ»ÐŸÐ¶ÐµÐœÐžÑ',
+   'ProgramID' => 'ID Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ',
+   'ProgramMode' => {
+      Description => 'Ð ÐµÐ¶ÐžÐŒ Ð¿ÑÐŸÐ³ÑÐ°ÐŒÐŒÑ',
+      PrintConv => {
+        'Night Portrait' => 'ÐÐŸÑÐœÐŸÐ¹ Ð¿ÐŸÑÑÑÐµÑ',
+        'None' => 'ÐÑÑÑÑÑÑÐ²ÑÐµÑ',
+        'Portrait' => 'ÐÐŸÑÑÑÐµÑ',
+        'Sports' => 'Ð¡Ð¿ÐŸÑÑ',
+        'Sunset' => 'ÐÐ°ÐºÐ°Ñ',
+        'Text' => 'Ð¢ÐµÐºÑÑ',
+      },
+    },
+   'ProgramVersion' => 'ÐÐµÑÑÐžÑ Ð¿ÑÐžÐ»ÐŸÐ¶ÐµÐœÐžÑ',
+   'ProgressiveScans' => {
+      Description => 'ÐÑÐŸÐ³ÑÐµÑÑÐžÐ²ÐœÐŸÐµ ÑÐºÐ°ÐœÐžÑÐŸÐ²Ð°ÐœÐžÐµ',
+      PrintConv => {
+        '3 Scans' => '3 Ð¿ÑÐŸÑ
+ÐŸÐŽÐ°',
+        '4 Scans' => '4 Ð¿ÑÐŸÑ
+ÐŸÐŽÐ°',
+        '5 Scans' => '5 Ð¿ÑÐŸÑ
+ÐŸÐŽÐŸÐ²',
+      },
+    },
+   'Project' => 'ÐÑÐŸÐµÐºÑ',
+   'ProjectionType' => 'Ð¢ÐžÐ¿ Ð¿ÑÐŸÐµÐºÑÐžÐž',
+   'PropertyReleaseID' => 'ID ÑÐ²ÐŸÐ¹ÑÑÐ² ÑÐµÐ»ÐžÐ·Ð°',
+   'PropertyReleaseStatus' => {
+      Description => 'Ð¡ÑÐ°ÑÑÑ ÑÐ²ÐŸÐ¹ÑÑÐ² ÑÐµÐ»ÐžÐ·Ð°',
+      PrintConv => {
+        'Limited or Incomplete Property Releases' => 'ÐÐ³ÑÐ°ÐœÐžÑÐµÐœÐœÑÐµ ÐžÐ»Ðž ÐœÐµÐ¿ÐŸÐ»ÐœÑÐµ ÑÐµÐ»ÐžÐ·Ñ',
+        'None' => 'ÐÐµ ÐŸÐ±ÐŸÐ·ÐœÐ°ÑÐµÐœÐŸ',
+        'Not Applicable' => 'ÐÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÑÐµÑÑÑ',
+        'Unlimited Property Releases' => 'ÐÐµÐŸÐ³ÑÐ°ÐœÐžÑÐµÐœÐœÑÐµ ÑÐµÐ»ÐžÐ·Ñ ÑÐ²ÐŸÐ¹ÑÑÐ²',
+      },
+    },
+   'Protect' => 'ÐÐ°ÑÐžÑÐ°',
+   'Provider' => 'ÐÐŸÑÑÐ°Ð²ÑÐžÐº',
+   'ProviderCopyright' => 'ÐÐŸÑÑÐ°Ð²ÑÐžÐº â ÐÐ²ÑÐŸÑÑÐºÐŸÐµ Ð¿ÑÐ°Ð²ÐŸ',
+   'ProviderRating' => 'ÐÑÐŸÐ²Ð°Ð¹ÐŽÐµÑ â Ð ÐµÐ¹ÑÐžÐœÐ³',
    'Province-State' => 'ÐÐ±Ð»Ð°ÑÑÑ/ÑÐ°Ð¹ÐŸÐœ',
+   'PublishDate' => 'ÐÐ°ÑÐ° Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐž',
+   'PublishDateStart' => 'ÐÐ°ÑÐ° ÐœÐ°ÑÐ°Ð»Ð° Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐž',
+   'Publisher' => 'ÐÐ·ÐŽÐ°ÑÐµÐ»Ñ',
+   'PublisherLimit' => 'ÐÐ³ÑÐ°ÐœÐžÑÐµÐœÐžÑ ÐžÐ·ÐŽÐ°ÑÐµÐ»Ñ',
+   'PxShiftPeriphEdgeNR' => {
+      PrintConv => {
+        'Off' => 'ÐÐµ Ð²ÐºÐ»ÑÑÑÐœ',
+        'On' => 'ÐÐºÐ»ÑÑÐµÐœ',
+      },
+    },
+   'PyramidLevels' => 'Ð£ÑÐŸÐ²ÐœÐž Ð¿ÐžÑÐ°ÐŒÐžÐŽÑ',
    'Quality' => {
-      Description => 'ÐÐ°ÑÐµÑÑÐ²ÐŸ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ',
-      PrintConv => {
+      Description => 'ÐÐ°ÑÐµÑÑÐ²ÐŸ',
+      PrintConv => {
+        '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',
@@ -567,42 +4706,429 @@
         'RAW + JPEG' => 'RAW+JPEG',
         'Standard' => 'Ð¡ÑÐ°ÐœÐŽÐ°ÑÑÐœÐŸÐµ',
-      },
-    },
-   'RawDataUniqueID' => 'Ð£ÐœÐžÐºÐ°Ð»ÑÐœÑÐ¹ ÐžÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ ÑÐ°Ð¹Ð»Ð°',
-   'RawImageDigest' => 'Ð¡ÐžÐ³ÐœÐ°ÑÑÑÐ° RAW-ÑÐ°Ð¹Ð»Ð°',
+        'Unstable/Experimental' => 'ÐÐµÑÑÐ°Ð±ÐžÐ»ÑÐœÐŸÐµ/Ð­ÐºÑÐ¿ÐµÑÐžÐŒÐµÐœÑÐ°Ð»ÑÐœÐŸÐµ',
+      },
+    },
+   'QuantizationMethod' => {
+      Description => 'ÐÐµÑÐŸÐŽ ÐºÐ²Ð°ÐœÑÐŸÐ²Ð°ÐœÐžÑ',
+      PrintConv => {
+        'Color Space Specific' => 'Ð¡Ð¿ÐµÑÐžÑÐžÑÐœÐŸÐµ ÑÐ²ÐµÑÐŸÐ²ÐŸÐµ Ð¿ÑÐŸÑÑÑÐ°ÐœÑÑÐ²ÐŸ',
+        'Compression Method Specific' => 'Ð¡Ð¿ÐµÑÐžÑÐžÑÐœÑÐ¹ ÐŒÐµÑÐŸÐŽ ÑÐ¶Ð°ÑÐžÑ',
+        'Gamma Compensated' => 'ÐÐŸÐŒÐ¿ÐµÐœÑÐ°ÑÐžÑ Ð³Ð°ÐŒÐŒÑ',
+        'Linear Density' => 'ÐÐžÐœÐµÐ¹ÐœÐ°Ñ Ð¿Ð»ÐŸÑÐœÐŸÑÑÑ',
+        'Linear Reflectance/Transmittance' => 'ÐÐžÐœÐµÐ¹ÐœÐŸÐµ ÐÑÑÐ°Ð¶ÐµÐœÐžÐµ/ÐÑÐŸÐ¿ÑÑÐºÐ°ÐœÐžÐµ',
+      },
+    },
+   'QuickEdit' => 'ÐÑÑÑÑÐŸÐµ ÑÐµÐŽÐ°ÐºÑÐžÑÐŸÐ²Ð°ÐœÐžÐµ',
+   'QuickMaskInfo' => 'Ð¡Ð²ÐµÐŽÐµÐœÐžÑ ÐŸ Ð±ÑÑÑÑÐŸÐ¹ ÐŒÐ°ÑÐºÐµ',
+   'QuickShot' => {
+      Description => 'ÐÑÑÑÑÑÐ¹ ÑÐœÐžÐŒÐŸÐº',
+      PrintConv => {
+        'Off' => 'ÐÐµ Ð²ÐºÐ»ÑÑÑÐœ',
+        'On' => 'ÐÐºÐ»ÑÑÐµÐœ',
+      },
+    },
+   'RAFVersion' => 'ÐÐµÑÑÐžÑ RAF',
+   'RGBCurves' => 'ÐÑÐžÐ²ÑÐµ RGB',
+   'ROIDescription' => 'ÐÐ¿ÐžÑÐ°ÐœÐžÐµ ROI',
+   'RPP' => 'Raw Photo Processor (RPP)',
+   'RasterPadding' => {
+      Description => 'Ð Ð°ÑÑÑÐŸÐ²ÐŸÐµ Ð·Ð°Ð¿ÐŸÐ»ÐœÐµÐœÐžÐµ',
+      PrintConv => {
+        'Byte' => 'ÐÐ°Ð¹Ñ',
+        'Long Sector' => 'ÐÐ»ÐžÐœÐœÑÐ¹ ÑÐµÐºÑÐŸÑ',
+        'Long Word' => 'ÐÐ»ÐžÐœÐœÐŸÐµ ÑÐ»ÐŸÐ²ÐŸ',
+        'Sector' => 'Ð¡ÐµÐºÑÐŸÑ',
+        'Word' => 'Ð¡Ð»ÐŸÐ²ÐŸ',
+      },
+    },
+   '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' => 'Ð ÐµÐ¶ÐžÐŒ Ð·Ð°Ð¿ÐžÑÐž',
-   'ReductionMatrix1' => 'ÐÐ°ÑÑÐžÑÐ° ÑÐµÐŽÑÐºÑÐžÐž â1',
+   'RecordOwnerInstitutionCode' => 'ÐÑÐ³Ð°ÐœÐžÐ·Ð°ÑÐžÑ-Ð²Ð»Ð°ÐŽÐµÐ»ÐµÑ ÐŸÐ±ÑÐ°Ð·ÑÐ° ÐžÐ»Ðž ÐžÐœÑÐŸÑÐŒÐ°ÑÐžÐž',
+   'RecordShutterRelease' => {
+      Description => 'Ð¡Ð¿ÑÑÐº Ð·Ð°ÑÐ²ÐŸÑÐ° Ð¿ÑÐž Ð·Ð°Ð¿ÐžÑÐž',
+      PrintConv => {
+        'Press start, press stop' => 'ÐÐ°Ð¶Ð°ÑÑ Â«Ð¡ÑÐ°ÑÑÂ», ÐœÐ°Ð¶Ð°ÑÑ Â«Ð¡ÑÐŸÐ¿Â»',
+        'Record while down' => 'ÐÐ°Ð¿ÐžÑÑ Ð¿ÐŸÐºÐ° ÐœÐ°Ð¶Ð°ÑÐ° ÐºÐœÐŸÐ¿ÐºÐ°',
+      },
+    },
+   'RecurrenceDateTimes' => 'ÐÐ°ÑÐ°/ÐÑÐµÐŒÑ Ð¿ÐŸÐ²ÑÐŸÑÐµÐœÐžÑ ÑÐŸÐ±ÑÑÐžÑ',
+   'RecurrenceID' => 'ID Ð¿ÐŸÐ²ÑÐŸÑÑÑÑÐµÐ³ÐŸÑÑ ÑÐŸÐ±ÑÑÐžÑ',
+   'RecurrenceRule' => 'ÐÑÐ°Ð²ÐžÐ»ÐŸ Ð¿ÐŸÐ²ÑÐŸÑÐµÐœÐžÑ',
+   'RedBalance' => 'ÐÐ°Ð»Ð°ÐœÑ ÐºÑÐ°ÑÐœÐŸÐ³ÐŸ',
+   'RedBlueFlatField' => 'ÐÐŸÑÑÐµÐºÑÐžÑ Ð¿Ð»ÐŸÑÐºÐŸÐ³ÐŸ Ð¿ÐŸÐ»Ñ â ÐÑÐ°ÑÐœÑÐ¹ Ðž Ð¡ÐžÐœÐžÐ¹',
+   'RedEndpoint' => 'ÐÐŸÐœÐµÑÐœÐ°Ñ ÑÐŸÑÐºÐ° ÐÑÐ°ÑÐœÐŸÐ³ÐŸ',
+   'RedEyeReduction' => {
+      Description => 'Ð£ÐŒÐµÐœÑÑÐµÐœÐžÐµ ÑÑÑÐµÐºÑÐ° ÐºÑÐ°ÑÐœÑÑ
+ Ð³Ð»Ð°Ð·',
+      PrintConv => {
+        'Off' => 'ÐÐµ Ð²ÐºÐ»ÑÑÐµÐœÐŸ',
+        'On' => 'ÐÐºÐ»ÑÑÐµÐœÐŸ',
+      },
+    },
+   'RedMask' => 'ÐÐ°ÑÐºÐ° ÐÑÐ°ÑÐœÐŸÐ³ÐŸ',
+   'RedPrimary' => 'ÐÑÐœÐŸÐ²ÐœÐŸÐ¹ ÐºÑÐ°ÑÐœÑÐ¹',
+   'RedX' => 'ÐÑÐ°ÑÐœÑÐ¹ Ð¿ÐŸ X',
+   'RedY' => 'ÐÑÐ°ÑÐœÑÐ¹ Ð¿ÐŸ Y',
+   'RedcodeVersion' => 'ÐÐµÑÑÐžÑ Redcode',
+   'ReductionMatrix1' => 'ÐÐ°ÑÑÐžÑÐ° ÑÐµÐŽÑÐºÑÐžÐž 1',
    'ReductionMatrix2' => 'ÐÐ°ÑÑÐžÑÐ° ÑÐµÐŽÑÐºÑÐžÐž 2',
-   'ReferenceBlackWhite' => 'ÐÐ°ÑÐ° ÐŸÐ¿ÐŸÑÐœÑÑ
- Ð·ÐœÐ°ÑÐµÐœÐžÐ¹ ÑÐµÑÐœÐŸÐ³ÐŸ Ðž Ð±ÐµÐ»ÐŸÐ³ÐŸ',
-   'RelatedImageFileFormat' => 'Ð€ÐŸÑÐŒÐ°Ñ ÑÐ°Ð¹Ð»Ð° ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐœÐžÐŒÐºÐ°',
-   'RelatedImageHeight' => 'ÐÐ»ÐžÐœÐ° ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐœÐžÐŒÐºÐ°',
-   'RelatedImageWidth' => 'ÐšÐžÑÐžÐœÐ° ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐœÐžÐŒÐºÐ°',
-   'RelatedSoundFile' => 'Ð¡Ð²ÑÐ·Ð°ÐœÐœÑÐ¹ Ð°ÑÐŽÐžÐŸ-ÑÐ°Ð¹Ð»',
+   '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 => {
+        'Evaluated, Not Used' => 'Ð£ÑÐžÑÑÐ²Ð°Ð»ÑÑ, ÐœÐŸ ÐœÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ð»ÑÑ',
+        'Evaluated, Used' => 'Ð£ÑÐžÑÑÐ²Ð°Ð»ÑÑ Ðž ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ð»ÑÑ',
+        'Not Evaluated, Not Used' => 'ÐÐµ ÑÑÐžÑÑÐ²Ð°Ð»ÑÑ Ðž ÐœÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°Ð»ÑÑ',
+      },
+    },
+   '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 => {
+        'BarCode' => 'ÐšÑÑÐžÑ
+ÐºÐŸÐŽ',
+        'Face' => 'ÐÐžÑÐŸ',
+        'Focus' => 'Ð€ÐŸÐºÑÑ',
+        'Pet' => 'ÐÐžÐ²ÐŸÑÐœÐŸÐµ',
+      },
+    },
+   'RegionXformTackPoint' => 'Ð¢ÐŸÑÐºÐž-ÐŒÐŸÐŽÐžÑÐžÐºÐ°ÑÐŸÑÑ ÐŸÐ±Ð»Ð°ÑÑÐž Ð¿ÑÐµÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÑ Xform',
+   'RelatedImageFileFormat' => 'Ð€ÐŸÑÐŒÐ°Ñ ÑÐ°Ð¹Ð»Ð° ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ',
+   'RelatedImageHeight' => 'ÐÑÑÐŸÑÐ° ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ',
+   'RelatedImageWidth' => 'ÐšÐžÑÐžÐœÐ° ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ',
+   'RelatedResourceID' => 'ID ÑÐ²ÑÐ·Ð°ÐœÐœÐŸÐ³ÐŸ ÑÐµÑÑÑÑÐ°',
+   'RelatedSoundFile' => 'Ð¡Ð²ÑÐ·Ð°ÐœÐœÑÐ¹ Ð°ÑÐŽÐžÐŸÑÐ°Ð¹Ð»',
+   'RelatedTo' => 'ÐÑÐœÐŸÑÐžÑÑÑ Ðº',
+   'Relation' => 'Ð¡ÑÑÐ»ÐºÐ° ÐœÐ° ÑÐ²ÑÐ·Ð°ÐœÐœÑÐ¹ ÑÐµÑÑÑÑ',
+   'RelationshipAccordingTo' => 'Ð¡Ð²ÑÐ·Ñ ÐŒÐµÐ¶ÐŽÑ ÑÐµÑÑÑÑÐ°ÐŒÐž ÑÐŸÐ·ÐŽÐ°Ð»',
+   'RelationshipEstablishedDate' => 'ÐÐ°ÑÐ° ÑÐ²ÑÐ·Ðž ÐŒÐµÐ¶ÐŽÑ ÑÐµÑÑÑÑÐ°ÐŒÐž',
+   'RelationshipOfResource' => 'Ð¡Ð²ÑÐ·Ñ ÑÐµÑÑÑÑÐŸÐ²',
+   'RelationshipRemarks' => 'ÐÐŸÐŒÐŒÐµÐœÑÐ°ÑÐžÐž Ðº ÑÐ²ÑÐ·Ðž ÑÐµÑÑÑÑÐŸÐ²',
+   'RelativeAltitude' => 'ÐÑÐœÐŸÑÐžÑÐµÐ»ÑÐœÐ°Ñ Ð²ÑÑÐŸÑÐ°',
+   'RelativePath' => 'ÐÑÐœÐŸÑÐžÑÐµÐ»ÑÐœÑÐ¹ Ð¿ÑÑÑ',
+   'ReleaseDate' => 'ÐÐ°ÑÐ° Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐž',
+   'ReleaseTime' => 'ÐÑÐµÐŒÑ Ð¿ÑÐ±Ð»ÐžÐºÐ°ÑÐžÐž',
+   'RemoveHistoryDuplicates' => 'Ð£ÐŽÐ°Ð»ÐžÑÑ ÐžÑÑÐŸÑÐžÑ ÐŽÑÐ±Ð»ÐžÐºÐ°ÑÐŸÐ²',
+   'RenderingIntent' => {
+      Description => 'ÐÐµÑÐŸÐŽÑ ÑÐ²ÐµÑÐŸÐ²ÐŸÐ³ÐŸ Ð¿ÑÐµÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÑ',
+      PrintConv => {
+        '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)',
+      },
+    },
+   'RenderingTransform' => 'ÐÑÐµÐŸÐ±ÑÐ°Ð·ÐŸÐ²Ð°ÐœÐžÐµ ÑÐ²ÐµÑÐ°',
+   'RentalExpirationDate' => 'ÐÐ°ÑÐ° ÐŸÐºÐŸÐœÑÐ°ÐœÐžÑ Ð°ÑÐµÐœÐŽÑ',
+   'RentalFlag' => 'Ð€Ð»Ð°Ð³ Ð°ÑÐµÐœÐŽÑ',
+   'Repeat' => 'ÐÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ Ð¿ÐŸÐ²ÑÐŸÑÐŸÐ²',
+   'ReplayGainAlbumGain' => 'Replay Gain â ÐÐŸÑÑÐµÐºÑÐžÑ Ð³ÑÐŸÐŒÐºÐŸÑÑÐž Ð°Ð»ÑÐ±ÐŸÐŒÐ°',
+   'ReplayGainAlbumPeak' => 'Replay Gain â ÐÐžÐºÐŸÐ²ÑÐ¹ ÑÑÐŸÐ²ÐµÐœÑ Ð°Ð»ÑÐ±ÐŸÐŒÐ°',
+   'ReplayGainTrackGain' => 'Replay Gain â ÐÐŸÑÑÐµÐºÑÐžÑ Ð³ÑÐŸÐŒÐºÐŸÑÑÐž ÑÑÐµÐºÐ°',
+   'ReplayGainTrackPeak' => 'Replay Gain â ÐÐžÐºÐŸÐ²ÑÐ¹ ÑÑÐŸÐ²ÐµÐœÑ ÑÑÐµÐºÐ°',
+   'ReplyTo' => 'E-Mail Ð²ÐµÐ±ÐŒÐ°ÑÑÐµÑÐ°',
+   'RepresentativeDisparityFar' => 'Ð ÐµÐ¿ÑÐµÐ·ÐµÐœÑÐ°ÑÐžÐ²ÐœÐ°Ñ ÐœÐµÑÐŸÐ³Ð»Ð°ÑÐŸÐ²Ð°ÐœÐœÐŸÑÑÑ â ÐÐŽÐ°Ð»Ðž',
+   'RepresentativeDisparityNear' => 'Ð ÐµÐ¿ÑÐµÐ·ÐµÐœÑÐ°ÑÐžÐ²ÐœÐ°Ñ ÐœÐµÑÐŸÐ³Ð»Ð°ÑÐŸÐ²Ð°ÐœÐœÐŸÑÑÑ â Ð ÑÐŽÐŸÐŒ',
+   'RepresentativeImage' => {
+      Description => 'Ð ÐµÐ¿ÑÐµÐ·ÐµÐœÑÐ°ÑÐžÐ²ÐœÐŸÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÐµ',
+      PrintConv => {
+        'Left Viewpoint' => 'ÐÐµÐ²Ð°Ñ ÑÐŸÑÐºÐ° Ð¿ÑÐŸÑÐŒÐŸÑÑÐ°',
+        'Right Viewpoint' => 'ÐÑÐ°Ð²Ð°Ñ ÑÐŸÑÐºÐ° Ð¿ÑÐŸÑÐŒÐŸÑÑÐ°',
+      },
+    },
+   'RequestID' => 'ID Ð·Ð°Ð¿ÑÑÐ°',
+   'RequestStatus' => 'Ð¡ÑÐ°ÑÑÑ Ð·Ð°Ð¿ÑÐŸÑÐ°',
+   'Resaved' => {
+      Description => 'ÐÐŸÐ²ÑÐŸÑÐœÐŸÐµ ÑÐŸÑ
+ÑÐ°ÐœÐµÐœÐžÐµ',
+      PrintConv => {
+        'No' => 'ÐÐµÑ',
+        'Yes' => 'ÐÐ°',
+      },
+    },
+   'Reserved5' => 'ÐÐ°ÑÐµÐ·ÐµÑÐ²ÐžÑÐŸÐ²Ð°ÐœÐŸ 5',
+   'Resolution' => 'Ð Ð°Ð·ÑÐµÑÐµÐœÐžÐµ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ',
    'ResolutionUnit' => {
-      Description => 'Ð­Ð»ÐµÐŒÐµÐœÑ ÑÐ°Ð·ÑÐµÑÐµÐœÐžÑ Ð¿ÐŸ X Ðž Y',
-      PrintConv => {
-        'cm' => 'ÑÐ°ÐœÑÐžÐŒÐµÑÑÑ',
+      Description => 'ÐÐŽÐžÐœÐžÑÑ ÑÐ°Ð·ÑÐµÑÐµÐœÐžÑ Ð¿ÐŸ X Ðž Y',
+      PrintConv => {
+        'None' => 'ÐÐµ ÑÐºÐ°Ð·Ð°ÐœÑ',
+        'cm' => 'ÑÐŒ',
         'inches' => 'ÐŽÑÐ¹ÐŒÑ',
       },
     },
-   'RowInterleaveFactor' => 'ÐšÐžÑÐžÐœÐ° ÑÐµÑÐµÐŽÐŸÐ²Ð°ÐœÐžÑ ÑÑÑÐŸÐº',
-   'RowsPerStrip' => 'Ð§ÐžÑÐ»ÐŸ ÑÑÐŽÐŸÐ² Ð² Ð¿ÐŸÐ»ÐŸÑÐµ',
-   'SamplesPerPixel' => 'ÐÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÐŸÐ²',
+   'ResourceCount' => 'ÐÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÑÐµÑÑÑÑÐŸÐ²',
+   'ResourceForkSize' => 'Ð Ð°Ð·ÐŒÐµÑ ÑÐ°Ð·Ð²ÐµÑÐ²Ð»ÐµÐœÐžÑ ÑÐµÑÑÑÑÐ°',
+   'ResourceID' => 'ID ÑÐµÑÑÑÑÐ°',
+   'ResourceRelationship' => 'Ð¡Ð²ÑÐ·Ðž ÑÐµÑÑÑÑÐŸÐ²',
+   'ResourceRelationshipID' => 'ID ÑÐ²ÑÐ·Ðž ÐŒÐµÐ¶ÐŽÑ ÑÐµÑÑÑÑÐ°ÐŒÐž',
+   'ResourceType' => 'Ð¢ÐžÐ¿ ÑÐµÑÑÑÑÐ°',
+   'Resources' => 'Ð ÐµÑÑÑÑÑ',
+   'RetailPrice' => 'Ð ÐŸÐ·ÐœÐžÑÐœÐ°Ñ ÑÐµÐœÐ°',
+   'RetailPriceCurrency' => 'ÐÐ°Ð»ÑÑÐ° ÑÐŸÐ·ÐœÐžÑÐœÐŸÐ¹ ÑÐµÐœÑ',
+   'Reuse' => {
+      Description => 'ÐÐŸÐ²ÑÐŸÑÐœÐŸÐµ ÐžÑÐ¿ÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÐœÐžÐµ',
+      PrintConv => {
+        'Not Applicable' => 'ÐÐ°Ð¿ÑÐµÑÐµÐœÐŸ',
+        'Repeat Use' => 'Ð Ð°Ð·ÑÐµÑÐµÐœÐŸ',
+      },
+    },
+   '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 => {
+        'Has been rounded' => 'ÐÐºÑÑÐ³Ð»ÐµÐœÐœÐŸÐµ Ð²ÑÐµÐŒÑ',
+        'Indefinite' => 'ÐÐµÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÐœÐœÐŸÐµ Ð²ÑÐµÐŒÑ',
+        'Negative infinity' => 'ÐÐžÐœÑÑ Ð±ÐµÑÐºÐŸÐœÐµÑÐœÐŸÑÑÑ',
+        'Positive infinity' => 'ÐÐ»ÑÑ Ð±ÐµÑÐºÐŸÐœÐµÑÐœÐŸÑÑÑ',
+        'Valid' => 'ÐÐµÐ¹ÑÑÐ²ÐžÑÐµÐ»ÑÐœÐŸÐµ Ð²ÑÐµÐŒÑ',
+      },
+    },
+   'RunTimeScale' => 'ÐÑÐµÐŒÑ Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÑ â ÐšÐºÐ°Ð»Ð° Ð²ÑÐµÐŒÐµÐœÐž',
+   'RunTimeSincePowerUp' => 'ÐÑÐµÐŒÑ ÑÐ°Ð±ÐŸÑÑ Ñ ÐŒÐŸÐŒÐµÐœÑÐ° Ð²ÐºÐ»ÑÑÐµÐœÐžÑ',
+   'RunTimeValue' => 'ÐÑÐµÐŒÑ Ð²ÑÐ¿ÐŸÐ»ÐœÐµÐœÐžÑ â ÐÐœÐ°ÑÐµÐœÐžÐµ',
+   'RunWindow' => {
+      Description => 'ÐÐ°Ð¿ÑÑÑÐžÑÑ ÐŸÐºÐœÐŸ',
+      PrintConv => {
+        'Hide' => 'Ð¡ÐºÑÑÑÑÐ¹',
+        'Minimized' => 'ÐÐžÐœÐžÐŒÐžÐ·ÐžÑÐŸÐ²Ð°ÑÑ',
+        'Normal' => 'ÐÐ±ÑÑÐœÑÐ¹',
+        'Restore' => 'ÐÐŸÑÑÑÐ°ÐœÐŸÐ²ÐžÑÑ',
+        'Show' => 'ÐÐŸÐºÐ°Ð·ÑÐ²Ð°ÑÑ',
+        'Show Default' => 'ÐÑÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ Ð¿ÐŸ-ÑÐŒÐŸÐ»ÑÐ°ÐœÐžÑ',
+        'Show Maximized' => 'ÐÑÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ ÑÐ°Ð·Ð²ÑÑÐœÑÑÑÐŒ',
+        'Show Minimized' => 'ÐÑÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ ÑÐ²ÐµÑÐœÑÑÑÐŒ',
+        'Show Minimized No Activate' => 'ÐÑÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ ÑÐ²ÐµÑÐœÑÑÑÐŒ Ðž ÐœÐµ Ð°ÐºÑÐžÐ²Ð²ÐœÑÐŒ',
+        'Show No Activate' => 'ÐÑÐŸÐ±ÑÐ°Ð¶Ð°ÑÑ',
+      },
+    },
+   'SEMInfo' => 'SEM â ÐÐ¿ÐžÑÐ°ÐœÐžÐµ',
+   'SIUnits' => 'ÐÐŽÐžÐœÐžÑÑ SI',
+   'SMaxSampleValue' => 'ÐÐ°ÐºÑÐžÐŒÐ°Ð»ÑÐœÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÐ°',
+   'SMinSampleValue' => 'ÐÐžÐœÐžÐŒÐ°Ð»ÑÐœÐŸÐµ Ð·ÐœÐ°ÑÐµÐœÐžÐµ ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÐ°',
+   'SRGBRendering' => {
+      Description => 'SRGB-ÑÐµÐœÐŽÐµÑÐžÐœÐ³',
+      PrintConv => {
+        'Absolute Colorimetric' => 'ÐÐ±ÑÐŸÐ»ÑÑÐœÐŸ ÐºÐŸÐ»ÐŸÑÐžÐŒÐµÑÑÐžÑÐµÑÐºÐžÐ¹',
+        'Perceptual' => 'ÐÐµÑÑÐµÐ¿ÑÐžÐŸÐœÐœÑÐ¹',
+        'Relative Colorimetric' => 'ÐÑÐœÐŸÑÐžÑÐµÐ»ÑÐœÐŸ ÐºÐŸÐ»ÐŸÑÐžÐŒÐµÑÑÐžÑÐµÑÐºÐžÐ¹',
+        'Saturation' => 'ÐÐ°ÑÑÑÐµÐœÐœÑÐ¹',
+      },
+    },
+   'SRawType' => 'Ð¢ÐžÐ¿ SRaw',
+   'SampleFlag' => 'Ð€Ð»Ð°Ð³ ÐŸÐ±ÑÐ°Ð·ÑÐ°',
+   'SampleFormat' => {
+      Description => 'Ð€ÐŸÑÐŒÐ°Ñ ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÐ°',
+      PrintConv => {
+        'Complex float' => 'ÐÐŸÐŒÐ¿Ð»ÐµÐºÑÐœÑÐµ ÐŽÐ°ÐœÐœÑÐµ Ñ Ð¿Ð»Ð°Ð²Ð°ÑÑÐµÐ¹ ÑÐŸÑÐºÐŸÐ¹ IEEE',
+        'Complex int' => 'ÐÐŸÐŒÐ¿Ð»ÐµÐºÑÐœÑÐµ ÑÐµÐ»ÑÐµ ÐŽÐ°ÐœÐœÑÐµ',
+        'Float' => 'ÐÐ°ÐœÐœÑÐµ Ñ Ð¿Ð»Ð°Ð²Ð°ÑÑÐµÐ¹ ÑÐŸÑÐºÐŸÐ¹ IEEE',
+        'Signed' => 'ÐŠÐµÐ»ÐŸÑÐžÑÐ»ÐµÐœÐœÑÐµ ÐŽÐ°ÐœÐœÑÐµ ÑÐŸ Ð·ÐœÐ°ÐºÐŸÐŒ',
+        'Undefined' => 'ÐÐµÐŸÐ¿ÑÐµÐŽÐµÐ»ÐµÐœÐœÑÐ¹ ÑÐŸÑÐŒÐ°Ñ ÐŽÐ°ÐœÐœÑÑ
+',
+        'Unsigned' => 'ÐÐµÐ·Ð·ÐœÐ°ÐºÐŸÐ²ÑÐµ ÑÐµÐ»ÐŸÑÐžÑÐ»ÐµÐœÐœÑÐµ ÐŽÐ°ÐœÐœÑÐµ',
+      },
+    },
+   'SampleRate' => 'Ð§Ð°ÑÑÐŸÑÐ° ÐŽÐžÑÐºÑÐµÑÐžÐ·Ð°ÑÐžÐž',
+   'SampleRate2' => 'Ð§Ð°ÑÑÐŸÑÐ° ÐŽÐžÑÐºÑÐµÑÐžÐ·Ð°ÑÐžÐž 2',
+   'SampleSize' => 'Ð Ð°Ð·ÐŒÐµÑ',
+   'SampleStructure' => {
+      Description => 'Ð¡ÑÑÑÐºÑÑÑÐ° ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÐ°',
+      PrintConv => {
+        'CompressionDependent' => 'ÐÐ°Ð²ÐžÑÐžÐŒÐ°Ñ ÐŸÑ ÑÐ¶Ð°ÑÐžÑ',
+        'Orthogonal4-2-2Sampling' => 'ÐÑÑÐŸÐ³ÐŸÐœÐ°Ð»ÑÐœÐ°Ñ Ñ ÑÐ°ÑÑÐŸÑÐ°ÐŒÐž ÐŽÐžÑÐºÑÐµÑÐžÐ·Ð°ÑÐžÐž Ð² ÑÐŸÐŸÑÐœÐŸÑÐµÐœÐžÐž 4: 2: 2: (4)',
+        'OrthogonalConstangSampling' => 'ÐÑÑÐŸÐ³ÐŸÐœÐ°Ð»ÑÐœÐ°Ñ Ñ ÑÐµÐŒÐž Ð¶Ðµ ÐŸÑÐœÐŸÑÐžÑÐµÐ»ÑÐœÑÐŒÐž ÑÐ°ÑÑÐŸÑÐ°ÐŒÐž ÐŽÐžÑÐºÑÐµÑÐžÐ·Ð°ÑÐžÐž Ð² ÐºÐ°Ð¶ÐŽÐŸÐŒ ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÐµ',
+      },
+    },
+   'SampleText' => 'ÐÑÐžÐŒÐµÑ ÑÐµÐºÑÑÐ°',
+   'SamplesPerPixel' => 'ÐÐŸÐ»ÐžÑÐµÑÑÐ²ÐŸ ÐºÐŸÐŒÐ¿ÐŸÐœÐµÐœÑÐŸÐ² ÐœÐ° Ð¿ÐžÐºÑÐµÐ»Ñ',
+   'SamsungRawByteOrder' => 'Samsung RAW â ÐÐŸÑÑÐŽÐŸÐº Ð±Ð°Ð¹ÑÐŸÐ²',
+   'SamsungRawPointersLength' => 'Samsung RAW â ÐÐ»ÐžÐœÐ° ÑÐºÐ°Ð·Ð°ÑÐµÐ»ÐµÐ¹',
+   'SamsungRawPointersOffset' => 'Samsung RAW â Ð¡ÐŒÐµÑÐµÐœÐžÐµ ÑÐºÐ°Ð·Ð°ÑÐµÐ»ÐµÐ¹',
+   'SamsungRawUnknown' => 'Samsung RAW â ÐÐµÐžÐ·Ð²ÐµÑÑÐœÐŸ',
+   'SanyoQuality' => {
+      Description => 'Sanyo â ÐÐ°ÑÐµÑÑÐ²ÐŸ',
+      PrintConv => {
+        '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' => 'ÐÑÑÑÐµÐµ/ÐÑÐµÐœÑ ÐœÐžÐ·ÐºÐŸÐµ',
+      },
+    },
+   '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' => 'Ð¡ÑÐ°ÐœÐŽÐ°ÑÑÐœÑÐ¹ ÑÐµÐ¶ÐžÐŒ',
       },
     },
@@ -611,8 +5137,8 @@
       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' => 'ÐÐ°ÐºÑÐŸÑÑÑÐŒÐºÐ°',
@@ -622,85 +5148,788 @@
         'Portrait' => 'ÐÐŸÑÑÑÐµÑ',
         'Sports' => 'Ð¡Ð¿ÐŸÑÑÐžÐ²ÐœÑÐµ ÑÑÐµÐœÑ',
-        'Standard' => '',
         'Sunset' => 'ÐÐ°ÐºÐ°Ñ',
         'Sweep Panorama' => 'ÐÐ°ÐœÐŸÑÐ°ÐŒÐœÑÐ¹ ÐŸÐ±Ð·ÐŸÑ',
       },
     },
+   'SceneSelect' => {
+      Description => 'ÐÑÐ±ÐŸÑ ÑÑÐµÐœÑ',
+      PrintConv => {
+        'Lamp' => 'ÐÐ°ÐŒÐ¿Ð°',
+        'Night' => 'ÐÐŸÑÑ',
+        'Off' => 'ÐÐµ Ð·Ð°ÐŽÐµÐ¹ÑÑÐ²ÐŸÐ²Ð°Ðœ',
+        'Sport' => 'Ð¡Ð¿ÐŸÑÑ',
+        'User 1' => 'ÐÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÑÑÐºÐ°Ñ 1',
+        'User 2' => 'ÐÐŸÐ»ÑÐ·ÐŸÐ²Ð°ÑÐµÐ»ÑÑÐºÐ°Ñ 2',
+      },
+    },
    'SceneType' => {
-      Description => 'Ð¢ÐžÐ¿ ÑÑÐ¶ÐµÑÐ°',
-      PrintConv => {
-        'Directly photographed' => 'ÐÐµÐ¿ÐŸÑÑÐµÐŽÑÑÐ²ÐµÐœÐœÐŸ Ð¿ÐŸÐ»ÑÑÐµÐœÐœÑÐ¹ ÑÐœÐžÐŒÐŸÐº',
-      },
-    },
+      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 => {
+        'Off' => 'ÐÐµ Ð·Ð°ÐŽÐµÐ¹ÑÑÐ²ÐŸÐ²Ð°Ðœ',
+        'On' => 'ÐÐºÐ»ÑÑÐµÐœ',
+      },
+    },
+   'SelfTimerMode' => 'Ð ÐµÐ¶ÐžÐŒ ÑÐ°Ð¹ÐŒÐµÑÐ° ÑÐ¿ÑÑÐºÐ° Ð·Ð°ÑÐ²ÐŸÑÐ°',
    'SensingMethod' => {
-      Description => 'ÐÐµÑÐŸÐŽ ÑÐµÐ³ÐžÑÑÑÐ°ÑÐžÐž',
-      PrintConv => {
-        'Color sequential area' => 'ÐÐŸÑÐ»ÐµÐŽÐŸÐ²Ð°ÑÐµÐ»ÑÐœÑÐ¹ ÑÐµÐœÑÐŸÑ ÑÐ²ÐµÑÐŸÐ²ÐŸÐ¹ ÐŸÐ±Ð»Ð°ÑÑÐž',
-        'Color sequential linear' => 'ÐÐŸÑÐ»ÐµÐŽÐŸÐ²Ð°ÑÐµÐ»ÑÐœÑÐ¹ Ð»ÐžÐœÐµÐ¹ÐœÑÐ¹ ÑÐ²ÐµÑÐŸÐ²ÐŸÐ¹ ÑÐµÐœÑÐŸÑ',
-        'One-chip color area' => 'ÐÐŽÐœÐŸÐ¿ÑÐŸÑÐµÑÑÐŸÑÐœÑÐ¹ ÑÐµÐœÑÐŸÑ ÑÐ²ÐµÑÐŸÐ²ÐŸÐ¹ ÐŸÐ±Ð»Ð°ÑÑÐž',
+      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' => 'ÐÐ²ÑÑ
-Ð¿ÑÐŸÑÐµÑÑÐŸÑÐœÑÐ¹ ÑÐµÐœÑÐŸÑ ÑÐ²ÐµÑÐŸÐ²ÐŸÐ¹ ÐŸÐ±Ð»Ð°ÑÑÐž',
-      },
-    },
-   'SerialNumber' => 'ID-ÐºÐŸÐŽ ÑÐŸÑÐŸÐºÐ°ÐŒÐµÑÑ',
+ÑÐžÐ¿ÐŸÐ²ÑÐ¹ ÑÐ²ÐµÑÐœÐŸÐ¹ ÑÐµÐœÑÐŸÑ',
+      },
+    },
+   '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 => {
+        'Adjust Exposure' => 'ÐÐŸ ÑÐŽÐ²ÐžÐ³Ñ ÑÐºÑÐ¿ÐŸÐ·ÐžÑÐžÐž',
+        'Best' => 'ÐÑÑÑÐžÐ¹ ÑÐœÐžÐŒÐŸÐº',
+        'None' => 'ÐÐµÑ',
+        'Standard' => 'Ð¡ÑÐ°ÐœÐŽÐ°ÑÑÐœÐ°Ñ',
+      },
+    },
+   'SerialNumber' => 'Ð¡ÐµÑÐžÐ¹ÐœÑÐ¹ ÐœÐŸÐŒÐµÑ ÐºÐ°ÐŒÐµÑÑ',
+   'Series' => 'Ð¡ÐµÑÐžÑ',
+   'SeriesDateTime' => 'ÐÐ°ÑÐ° ÑÐµÑÐžÐž',
+   'SeriesDescription' => 'ÐÐ¿ÐžÑÐ°ÐœÐžÐµ ÑÑÐžÐž',
+   'SeriesModality' => 'ÐÐŸÐŽÐ°Ð»ÑÐœÐŸÑÑÑ ÑÐµÑÐžÐž',
+   'SeriesNumber' => 'ÐÐŸÐŒÐµÑ ÑÐµÑÐžÐž',
+   'ServiceID' => 'ID ÑÐµÑÐ²ÐžÑÐ°',
+   'ServiceIdentifier' => 'ÐÐŽÐµÐœÑÐžÑÐžÐºÐ°ÑÐŸÑ Ð¿ÐŸÑÑÐ°Ð²ÑÐžÐºÐ° Ðž Ð¿ÑÐŸÐŽÑÐºÑÐ°',
+   'SetCookie' => 'ÐÐ°ÑÑÑÐŸÐ¹ÐºÐž cookie',
    'ShadingCompensation' => 'Ð£ÑÑÑÐ°ÐœÐµÐœÐžÐµ ÑÐµÐœÐµÐ¹',
    'ShadowScale' => 'ÐÐžÐ°Ð¿Ð°Ð·ÐŸÐœ ÑÐµÐœÐµÐ¹',
+   'Shadows' => 'Ð¢ÐµÐœÐž',
+   'ShadowsAdj' => 'Ð ÐµÐ³ÑÐ»ÐžÑÐŸÐ²ÐºÐ° ÑÐµÐœÐµÐ¹',
+   'SharedData' => 'ÐÐ±ÑÐžÐµ ÐŽÐ°ÐœÐœÑÐµ',
    'Sharpness' => {
       Description => 'Ð ÐµÐ·ÐºÐŸÑÑÑ',
       PrintConv => {
-        'Hard' => 'Ð ÐµÐ·ÐºÐžÐ¹',
-        'Normal' => 'Ð¡ÑÐ°ÐœÐŽÐ°ÑÑÐœÑÐ¹',
-        'Soft' => 'ÐÑÐ³ÐºÐžÐ¹',
-      },
-    },
-   'ShootingMode' => 'Ð ÐµÐ¶ÐžÐŒ ÑÑÐµÐŒÐºÐž',
-   'ShutterSpeed' => 'ÐÑÐŽÐµÑÐ¶ÐºÐ°',
-   'ShutterSpeedValue' => 'ÐÑÐŽÐµÑÐ¶ÐºÐ°',
-   'Software' => 'ÐÐŒÑ Ðž Ð²ÐµÑÑÐžÑ ÐÐ',
+        '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',
+      },
+    },
+   '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 => 'ÐÐžÐ°Ð¿Ð°Ð·ÐŸÐœ ÑÐ°ÑÑÑÐŸÑÐœÐžÐ¹ ÐŽÐŸ ÐŸÐ±ÑÐµÐºÑÐ°',
-      PrintConv => {
-        'Close' => 'ÐÑÑÐ¿ÐœÑÐ¹ Ð¿Ð»Ð°Ðœ',
-        'Distant' => 'Ð£ÐŽÐ°Ð»ÐµÐœÐœÑÐ¹ Ð¿Ð»Ð°Ðœ',
-        'Macro' => 'ÐÐ°ÐºÑÐŸ',
+      Description => 'Ð Ð°ÑÑÑÐŸÑÐœÐžÐµ ÐŽÐŸ ÑÐœÐžÐŒÐ°ÐµÐŒÐŸÐ³ÐŸ ÐŸÐ±ÑÐµÐºÑÐ°',
+      PrintConv => {
+        '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' => 'Ð€Ð»ÑÐŸÑÐµÑÑÐµÐœÑÐœÑÐ¹ Ð±ÐµÐ»ÑÐ¹ Ñ
 ÐŸÐ»ÐŸÐŽÐœÑÐ¹',
@@ -715,5 +5944,5 @@
         'Flash' => 'ÐÑÐ¿ÑÑÐºÐ°',
         'Fluorescent' => 'Ð€Ð»ÑÐŸÑÐµÑÑÐµÐœÑÐœÑÐ¹',
-        'Manual' => 'Ð ÑÑÐœÐ°Ñ ÐœÐ°ÑÑÑÐŸÐ¹ÐºÐ° Ð±Ð°Ð»Ð°ÐœÑÐ° Ð±ÐµÐ»ÐŸÐ³ÐŸ',
+        'Manual' => 'Ð ÑÑÐœÐŸÐ¹',
         'Shade' => 'Ð¢ÐµÐœÑ',
         'Tungsten' => 'ÐÐ°ÐŒÐ¿Ð° ÐœÐ°ÐºÐ°Ð»ÐžÐ²Ð°ÐœÐžÑ',
@@ -723,28 +5952,119 @@
       },
     },
+   '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',
-      PrintConv => {
-        'Centered' => 'ÑÐµÐœÑÑÐŸÐ²Ð°ÐœÐœÑÐ¹',
-        'Co-sited' => 'ÑÐŸÐ²Ð¿Ð°ÐŽÐ°ÑÑÐžÐ¹ Ð¿ÐŸ ÐŒÐµÑÑÑ',
-      },
-    },
-   'YCbCrSubSampling' => 'ÐÐŸÑÑÑÐžÑÐžÐµÐœÑ ÑÑÐ±ÐŽÐžÑÐºÑÐµÑÐžÐ·Ð°ÑÐžÐž Y Ðž C',
+      Description => 'ÐÐŸÐ»ÐŸÐ¶ÐµÐœÐžÐµ ÑÐŸÑÐºÐž, ÐŸÐ¿ÑÐµÐŽÐµÐ»ÑÑÑÐµÐ¹ ÑÐ²ÐµÑ Ð² Y Cb Cr',
+      PrintConv => {
+        'Centered' => 'ÐŠÐµÐœÑÑÐŸÐ²Ð°ÐœÐœÑÐ¹',
+        'Co-sited' => 'Ð¡ÐŸÐ²ÐŒÐµÑÑÐžÐŒÑÐ¹',
+      },
+    },
+   '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 => 'Ð¡ÐŸÐŸÑÐ²ÐµÑÑÑÐ²ÐžÐµ ÐŸÐ±Ð»Ð°ÑÑÐµÐ¹',
-      PrintConv => {
-        'High Key' => 'Hi',
-        'ISO Setting Used' => 'ÐÑÐºÐ»ÑÑÐµÐœÐŸ',
-        'Low Key' => 'Lo',
-      },
-    },
+      Description => 'Ð¡ÐŸÐ³Ð»Ð°ÑÐŸÐ²Ð°ÐœÐžÐµ Ð·ÐŸÐœ',
+      PrintConv => {
+        'High Key' => 'Ð Ð²ÑÑÐŸÐºÐŸÐŒ ÐºÐ»ÑÑÐµ',
+        'ISO Setting Used' => 'ÐÑÐ¿ÐŸÐ»ÑÐ·ÑÑÑÑÑ Ð¿Ð°ÑÐ°ÐŒÐµÑÑÑ ISO',
+        'Low Key' => 'Ð ÐœÐžÐ·ÐºÐŸÐŒ ÐºÐ»ÑÑÐµ',
+      },
+    },
+   'Zoom' => 'ÐÑÐŒ',
+   'ZoomPos' => 'ÐÐŸÐ·ÐžÑÐžÑ Ð·ÑÐŒÐ°',
+   'ZoomedPreviewImage' => 'Ð£Ð²ÐµÐ»ÐžÑÐµÐœÐœÑÐ¹ Ð¿ÑÐµÐŽÐ¿ÑÐŸÑÐŒÐŸÑÑ ÐžÐ·ÐŸÐ±ÑÐ°Ð¶ÐµÐœÐžÑ',
+   'iTunesMediaType' => 'Ð¢ÐžÐ¿ iTunes ÐŒÐµÐŽÐžÐ°',
 );
 
 1;  # end
-
 
 __END__
@@ -761,5 +6081,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -768,6 +6088,6 @@
 =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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/sv.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/sv.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/sv.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.03';
+$VERSION = '1.05';
 
 %Image::ExifTool::Lang::sv::Translate = (
@@ -35,5 +35,5 @@
         'Fluorescent' => 'LysrÃ¶rsbelysning',
         'ISO Studio Tungsten' => 'ISO tungsten studiobelysning',
-        'Other' => 'annan ljuskÃ€lla',
+        'Other' => 'Annan ljuskÃ€lla',
         'Shade' => 'Skugga',
         'Standard Light A' => 'Standardljus A',
@@ -41,5 +41,5 @@
         'Standard Light C' => 'Standardljus C',
         'Tungsten (Incandescent)' => 'Tungsten',
-        'Unknown' => 'okÃ€nt',
+        'Unknown' => 'OkÃ€nt',
         'Warm White Fluorescent' => 'Varmt vitt fluorescerande (L 2600 - 3250k)',
         'White Fluorescent' => 'Vit lysrÃ¶rsbelysning (WW 3250 - 3800 k)',
@@ -57,5 +57,5 @@
         'Fluorescent' => 'LysrÃ¶rsbelysning',
         'ISO Studio Tungsten' => 'ISO tungsten studiobelysning',
-        'Other' => 'annan ljuskÃ€lla',
+        'Other' => 'Annan ljuskÃ€lla',
         'Shade' => 'Skugga',
         'Standard Light A' => 'Standardljus A',
@@ -63,5 +63,5 @@
         'Standard Light C' => 'Standardljus C',
         'Tungsten (Incandescent)' => 'Tungsten',
-        'Unknown' => 'okÃ€nt',
+        'Unknown' => 'OkÃ€nt',
         'Warm White Fluorescent' => 'Varmt vitt fluorescerande (L 2600 - 3250k)',
         'White Fluorescent' => 'Vit lysrÃ¶rsbelysning (WW 3250 - 3800 k)',
@@ -106,5 +106,5 @@
       PrintConv => {
         'JPEG' => 'JPEG-komprimering',
-        'Uncompressed' => 'ingen komprimering',
+        'Uncompressed' => 'Ingen komprimering',
       },
     },
@@ -180,4 +180,10 @@
    'ExposureTime' => 'Exponeringstid',
    'FNumber' => 'BlÃ€ndare',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => 'Positiv riktning',
+        'Rotate 90 CW' => 'Rotera 90Â° medurs',
+      },
+    },
    'FileFormat' => 'Format',
    'FileModifyDate' => 'Uppdateringsdatum',
@@ -193,4 +199,5 @@
     },
    'FileType' => 'Filtyp',
+   'Filename' => 'Filnamn',
    'Flash' => {
       Description => 'Blixt',
@@ -345,4 +352,5 @@
     },
    'Hue' => 'Nyans',
+   'ICCProfile' => 'ICC profil',
    'ISO' => 'ISO vÃ€rde',
    'ImageHeight' => 'BildhÃ¶jd',
@@ -355,4 +363,12 @@
    'InteropOffset' => 'Interoperability tag',
    'InteropVersion' => 'Interoperability Version',
+   'JPEGQuality' => {
+      Description => 'Bildkvalitet',
+      PrintConv => {
+        'Extra Fine' => 'Extra fin',
+        'Fine' => 'Fin',
+        'Standard' => 'Standardkvalitet',
+      },
+    },
    'Keywords' => 'Nyckelord',
    'Lens' => 'Objektiv',
@@ -370,5 +386,5 @@
         'Fluorescent' => 'LysrÃ¶rsbelysning',
         'ISO Studio Tungsten' => 'ISO tungsten studiobelysning',
-        'Other' => 'annan ljuskÃ€lla',
+        'Other' => 'Annan ljuskÃ€lla',
         'Shade' => 'Skugga',
         'Standard Light A' => 'Standardljus A',
@@ -376,5 +392,5 @@
         'Standard Light C' => 'Standardljus C',
         'Tungsten (Incandescent)' => 'Tungsten',
-        'Unknown' => 'okÃ€nt',
+        'Unknown' => 'OkÃ€nt',
         'Warm White Fluorescent' => 'Varmt vitt fluorescerande (L 2600 - 3250k)',
         'White Fluorescent' => 'Vit lysrÃ¶rsbelysning (WW 3250 - 3800 k)',
@@ -400,7 +416,7 @@
         'Multi-segment' => 'MÃ¶nster',
         'Multi-spot' => 'MultiSpot',
-        'Other' => 'annat',
+        'Other' => 'Annat',
         'Partial' => 'Delvis',
-        'Unknown' => 'okÃ€nt',
+        'Unknown' => 'OkÃ€nt',
       },
     },
@@ -491,5 +507,4 @@
         'Portrait' => 'PortrÃ€tt',
         'Sports' => 'SporthÃ€ndelse',
-        'Standard' => '',
         'Sunset' => 'SolnedgÃ¥ng',
         'Sweep Panorama' => 'Panorering',
@@ -576,5 +591,5 @@
         'Shade' => 'Skugga',
         'Tungsten' => 'GlÃ¶dlampa',
-        'Unknown' => 'okÃ€nt',
+        'Unknown' => 'OkÃ€nt',
         'Warm White Fluorescent' => 'Varmt vitt fluorescerande',
         'White Fluorescent' => 'Vit lysrÃ¶rsbelysning',
@@ -587,6 +602,5 @@
       Description => 'Y- och C-placering',
       PrintConv => {
-        'Centered' => 'centrerad',
-        'Co-sited' => 'co-sited',
+        'Centered' => 'Centrerad',
       },
     },
@@ -618,5 +632,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/tr.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/tr.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/tr.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.02';
+$VERSION = '1.05';
 
 %Image::ExifTool::Lang::tr::Translate = (
@@ -36,5 +36,5 @@
         'Fluorescent' => 'Floresan',
         'ISO Studio Tungsten' => 'ISO stÃŒdyo tungsten',
-        'Other' => 'diÄer Ä±ÅÄ±k kaynaÄÄ±',
+        'Other' => 'DiÄer Ä±ÅÄ±k kaynaÄÄ±',
         'Shade' => 'GÃ¶lge',
         'Standard Light A' => 'Standard IÅÄ±k A',
@@ -42,5 +42,5 @@
         'Standard Light C' => 'Standard IÅÄ±k C',
         'Tungsten (Incandescent)' => 'Tungsten',
-        'Unknown' => 'bilinmeyen',
+        'Unknown' => 'Bilinmeyen',
         'White Fluorescent' => 'Beyaz floresan (WW 3250 - 3800K)',
       },
@@ -57,5 +57,5 @@
         'Fluorescent' => 'Floresan',
         'ISO Studio Tungsten' => 'ISO stÃŒdyo tungsten',
-        'Other' => 'diÄer Ä±ÅÄ±k kaynaÄÄ±',
+        'Other' => 'DiÄer Ä±ÅÄ±k kaynaÄÄ±',
         'Shade' => 'GÃ¶lge',
         'Standard Light A' => 'Standard IÅÄ±k A',
@@ -63,5 +63,5 @@
         'Standard Light C' => 'Standard IÅÄ±k C',
         'Tungsten (Incandescent)' => 'Tungsten',
-        'Unknown' => 'bilinmeyen',
+        'Unknown' => 'Bilinmeyen',
         'White Fluorescent' => 'Beyaz floresan (WW 3250 - 3800K)',
       },
@@ -87,5 +87,5 @@
       PrintConv => {
         'JPEG' => 'JPEG SÄ±kÄ±ÅtÄ±rma',
-        'Uncompressed' => 'sÄ±kÄ±ÅtÄ±rÄ±lmamÄ±Å',
+        'Uncompressed' => 'SÄ±kÄ±ÅtÄ±rÄ±lmamÄ±Å',
       },
     },
@@ -149,4 +149,10 @@
    'ExposureTime' => 'Poz sÃŒresi',
    'FNumber' => 'AÃ§Ä±klÄ±k',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => 'Pozitif yÃ¶n',
+        'Rotate 90 CW' => 'Saat yÃ¶nÃŒnde 90Â° dÃ¶ndÃŒr',
+      },
+    },
    'FileFormat' => 'Format',
    'FileModifyDate' => 'GÃŒncellenen Tarih',
@@ -162,4 +168,5 @@
     },
    'FileType' => 'Dosya tÃŒrÃŒ',
+   'Filename' => 'Dosya adÄ±',
    'Flash' => {
       Description => 'FlaÅ',
@@ -291,4 +298,5 @@
    'Headline' => 'BaÅlÄ±k',
    'Hue' => 'Renk',
+   'ICCProfile' => 'ICC Profili',
    'ISO' => 'ISO deÄeri',
    'ImageHeight' => 'Ä°maj yÃŒksekliÄi',
@@ -301,4 +309,9 @@
    'InteropOffset' => 'Interoperabilite etiketi',
    'InteropVersion' => 'Interoperabilite SÃŒrÃŒmÃŒ',
+   'JPEGQuality' => {
+      PrintConv => {
+        'Standard' => 'Standart Kalite',
+      },
+    },
    'Keywords' => 'Anahtar sÃ¶zcÃŒkler',
    'Lens' => 'Objektif',
@@ -316,5 +329,5 @@
         'Fluorescent' => 'Floresan',
         'ISO Studio Tungsten' => 'ISO stÃŒdyo tungsten',
-        'Other' => 'diÄer Ä±ÅÄ±k kaynaÄÄ±',
+        'Other' => 'DiÄer Ä±ÅÄ±k kaynaÄÄ±',
         'Shade' => 'GÃ¶lge',
         'Standard Light A' => 'Standard IÅÄ±k A',
@@ -322,5 +335,5 @@
         'Standard Light C' => 'Standard IÅÄ±k C',
         'Tungsten (Incandescent)' => 'Tungsten',
-        'Unknown' => 'bilinmeyen',
+        'Unknown' => 'Bilinmeyen',
         'White Fluorescent' => 'Beyaz floresan (WW 3250 - 3800K)',
       },
@@ -338,7 +351,7 @@
         'Multi-segment' => 'Desen',
         'Multi-spot' => 'Multispot',
-        'Other' => 'diÄer',
+        'Other' => 'DiÄer',
         'Partial' => 'KÄ±smen',
-        'Unknown' => 'bilinmeyen',
+        'Unknown' => 'Bilinmeyen',
       },
     },
@@ -487,13 +500,15 @@
    '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',
       PrintConv => {
-        'Centered' => 'ortalanmÄ±Å',
-        'Co-sited' => 'birlikte-konumlanmÄ±Å',
+        'Centered' => 'OrtalanmÄ±Å',
+        'Co-sited' => 'Birlikte-konumlanmÄ±Å',
       },
     },
    'YCbCrSubSampling' => 'Y den C\'ye alt Ã¶rnekleme oranÄ±',
+   'YResolution' => 'Y Ã§Ã¶zÃŒnÃŒrlÃŒÄÃŒ',
 );
 
@@ -514,5 +529,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/zh_cn.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/zh_cn.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/zh_cn.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.05';
+$VERSION = '1.08';
 
 %Image::ExifTool::Lang::zh_cn::Translate = (
@@ -133,8 +133,8 @@
         'Tungsten (Incandescent)' => 'çœçœç¯',
         'Unknown' => 'æªç¥',
+        'Warm White Fluorescent' => 'æçœè§å
+ç¯ïŒL2600-3250KïŒ',
         'White Fluorescent' => 'çœè²è§å
 ç¯ïŒWW3250-3800KïŒ',
-        'Warm White Fluorescent' => 'æçœè§å
-ç¯ïŒL2600-3250KïŒ',
       },
     },
@@ -170,8 +170,8 @@
         'Tungsten (Incandescent)' => 'çœçœç¯',
         'Unknown' => 'æªç¥',
+        'Warm White Fluorescent' => 'æçœè§å
+ç¯ïŒL2600-3250KïŒ',
         'White Fluorescent' => 'çœè²è§å
 ç¯ïŒWW3250-3800KïŒ',
-        'Warm White Fluorescent' => 'æçœè§å
-ç¯ïŒL2600-3250KïŒ',
       },
     },
@@ -395,4 +395,5 @@
         'Shutter speed priority AE' => 'å¿«éšäŒå
 ',
+        'n/a' => 'æªè®Ÿçœ®',
       },
     },
@@ -436,4 +437,12 @@
    'FNumber' => 'å
 åæ°',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (äž/å·Š)',
+        'Rotate 180' => '180Â° (åº/å³)',
+        'Rotate 270 CW' => '90Â° CW (å·Š/åº)',
+        'Rotate 90 CW' => '90Â° CCW (å³/äž)',
+      },
+    },
    'FaxProfile' => {
       PrintConv => {
@@ -740,4 +749,5 @@
     },
    'Hue' => 'è²çž',
+   'ICCProfile' => 'ICC è§è',
    'IPTC-NAA' => 'IPTC-NAA å
 æ°æ®',
@@ -780,4 +790,14 @@
    'InteropVersion' => 'äºçšçæ¬',
    'JFIFVersion' => 'JFIF çæ¬',
+   'JPEGQuality' => {
+      Description => 'åŸåèŽšé',
+      PrintConv => {
+        'Extra Fine' => 'è¶
+ç²Ÿç»',
+        'Fine' => 'ç²Ÿç»',
+        'Standard' => 'æ åç»èŽš',
+        'n/a' => 'æªè®Ÿçœ®',
+      },
+    },
    'Keyword' => 'å
 ³é®è¯',
@@ -825,8 +845,8 @@
         'Tungsten (Incandescent)' => 'çœçœç¯',
         'Unknown' => 'æªç¥',
+        'Warm White Fluorescent' => 'æçœè§å
+ç¯ïŒL2600-3250KïŒ',
         'White Fluorescent' => 'çœè²è§å
 ç¯ïŒWW3250-3800KïŒ',
-        'Warm White Fluorescent' => 'æçœè§å
-ç¯ïŒL2600-3250KïŒ',
       },
     },
@@ -840,4 +860,5 @@
 ³',
         'On' => 'åŒ',
+        'n/a' => 'æªè®Ÿçœ®',
       },
     },
@@ -846,4 +867,5 @@
       PrintConv => {
         'Manual' => 'æåš',
+        'n/a' => 'æªè®Ÿçœ®',
       },
     },
@@ -1042,4 +1064,5 @@
         'RAW + JPEG' => 'RAW+JPEG',
         'Standard' => 'æ å',
+        'n/a' => 'æªè®Ÿçœ®',
       },
     },
@@ -1150,5 +1173,4 @@
 ',
         'Sports' => 'è¿åšæš¡åŒ',
-        'Standard' => '',
         'Sunset' => 'å€é³',
         'Sweep Panorama' => 'æ«æå
@@ -1341,6 +1363,10 @@
    'WBAdjLighting' => {
       PrintConv => {
-        'Daylight' => 'å€ªé³å
-',
+        'Daylight (direct sunlight)' => 'å€ªé³å
+ (0)',
+        'Daylight (shade)' => 'å€ªé³å
+ (1)',
+        'Daylight (cloudy)' => 'å€ªé³å
+ (2)',
         'Flash' => 'éªå
 ',
@@ -1383,7 +1409,7 @@
         'Tungsten' => 'çœçœç¯',
         'Unknown' => 'æªç¥',
+        'Warm White Fluorescent' => 'æçœè§å
+ç¯',
         'White Fluorescent' => 'çœè²è§å
-ç¯',
-        'Warm White Fluorescent' => 'æçœè§å
 ç¯',
       },
@@ -1473,5 +1499,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/zh_tw.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/zh_tw.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lang/zh_tw.pm	(revision 34921)
@@ -12,5 +12,5 @@
 use vars qw($VERSION);
 
-$VERSION = '1.04';
+$VERSION = '1.06';
 
 %Image::ExifTool::Lang::zh_tw::Translate = (
@@ -272,4 +272,12 @@
    'FNumber' => 'å
 å',
+   'FaceOrientation' => {
+      PrintConv => {
+        'Horizontal (normal)' => '0Â° (é ç«¯/å·Šé)',
+        'Rotate 180' => '180Â° (åºéš/å³é)',
+        'Rotate 270 CW' => '90Â° CW (å·Šé/åºéš)',
+        'Rotate 90 CW' => '90Â° CCW (å³é/é ç«¯)',
+      },
+    },
    'FaxRecvParams' => 'å³çæ¥æ¶åæž',
    'FaxRecvTime' => 'å³çæ¥æ¶æé',
@@ -288,4 +296,5 @@
     },
    'FileType' => 'æªæ¡æ ŒåŒ',
+   'Filename' => 'æªæ¡åçš±',
    'FillOrder' => 'å¡«å¯«èšå®',
    'Flash' => {
@@ -547,4 +556,5 @@
    'HostComputer' => 'äž»æ©',
    'Hue' => 'è²çž',
+   'ICCProfile' => 'ICC è²åœ©èš­å®æª',
    'IPTC-NAA' => 'IPTC-NAA å
 è³æ',
@@ -563,4 +573,13 @@
    'InteropOffset' => 'äºçšæšèš',
    'InteropVersion' => 'äºéæ§çæ¬',
+   'JPEGQuality' => {
+      Description => 'åœ±ååè³ª',
+      PrintConv => {
+        'Extra Fine' => 'è¶
+ç²ŸçŽ°',
+        'Fine' => 'ç²ŸçŽ°',
+        'Standard' => 'æšæºåè³ª',
+      },
+    },
    'Keyword' => 'ééµå­',
    'Keywords' => 'ééµå­',
@@ -774,5 +793,4 @@
         'Portrait' => 'èå',
         'Sports' => 'éåå Žé¢',
-        'Standard' => '',
         'Sunset' => 'å€éœ',
         'Sweep Panorama' => 'å
@@ -944,5 +962,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Leaf.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Leaf.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Leaf.pm	(revision 34921)
@@ -14,5 +14,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.03';
+$VERSION = '1.07';
 
 sub ProcessLeaf($$$);
@@ -48,4 +48,5 @@
     JPEG_preview_data => {
         %Image::ExifTool::previewImageTagInfo,
+        Groups => { 2 => 'Preview' },
     },
     JPEG_preview_info => 'PreviewInfo',
@@ -74,5 +75,5 @@
         Name => 'BackSerial',
         Description => 'Back Serial Number',
-        PrintConv => '$val =~ s/ .*//; $val',
+        PrintConv => '$val =~ s/ .*//s; $val',
     },
     image_offset => { Format => 'int16u' },
@@ -111,5 +112,5 @@
         Name => 'CaptureSerial',
         Description => 'Capture Serial Number',
-        PrintConv => '$val =~ s/ .*//; $val',
+        PrintConv => '$val =~ s/ .*//s; $val',
     },
     CaptProf_image_offset       => {},
@@ -340,7 +341,8 @@
     NOTES => q{
         Leaf writes a TIFF-format sub-IFD inside IFD0 of a MOS image.  No tags in
-        this sub-IFD are currently known, except for tag 0x8606 which really
-        shouldn't be here anyway (so it doesn't appear in the table below) because
-        it duplicates a reference to the same data of tag 0x8606 in IFD0.
+        this sub-IFD are currently known, except for tags 0x8602 and 0x8606 which
+        really shouldn't be here anyway (so they don't appear in the table below)
+        because they duplicate references to the same data from tags with the same
+        ID in IFD0.
     },
 );
@@ -395,15 +397,15 @@
 sub ProcessLeaf($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart} || 0;
     my $dirLen = $$dirInfo{DirLen} || $$dirInfo{DataLen} - $dirStart;
     my $dirEnd = $dirStart + $dirLen;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $pos = $dirStart;
     my $hdrLen = 52;    # header length for PKTS information
     my $success;
 
-    $verbose and $exifTool->VerboseDir('Leaf');
+    $verbose and $et->VerboseDir('Leaf');
     for (;;) {
         last if $pos + $hdrLen > $dirEnd;
@@ -414,11 +416,11 @@
         $pos += $hdrLen;
         if ($pos + $size > $dirEnd) {
-            $exifTool->Warn('Truncated Leaf data');
+            $et->Warn('Truncated Leaf data');
             last;
         }
         my $tag = substr($header, 8, 40);
-        $tag =~ s/\0.*//;
+        $tag =~ s/\0.*//s;
         next unless $tag;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         # generate tag info for unknown tags
         my $val;
@@ -438,5 +440,5 @@
                 };
             } elsif ($tagTablePtr ne \%Image::ExifTool::Leaf::Main or
-                     $exifTool->Options('Unknown'))
+                     $et->Options('Unknown'))
             {
                 $tagInfo = {
@@ -448,8 +450,8 @@
                 $$tagInfo{Unknown} = 1 if $tagTablePtr eq \%Image::ExifTool::Leaf::Main;
             }
-            $tagInfo and Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            $tagInfo and AddTagToTable($tagTablePtr, $tag, $tagInfo);
         }
         if ($verbose) {
-            $exifTool->VerboseInfo($tag, $tagInfo,
+            $et->VerboseInfo($tag, $tagInfo,
                 Table   => $tagTablePtr,
                 Value   => $val,
@@ -470,14 +472,14 @@
                 );
                 my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
-                $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
+                $et->ProcessDirectory(\%subdirInfo, $subTable);
             } else {
                 $val =~ tr/\n/ /;   # translate newlines to spaces
                 $val =~ s/\0+$//;   # remove null terminators
-                $exifTool->FoundTag($tagInfo, $val);
+                $et->FoundTag($tagInfo, $val);
             }
         }
         $pos += $size;
     }
-    $success or $exifTool->Warn('Bad format Leaf data');
+    $success or $et->Warn('Bad format Leaf data');
     return $success;
 }
@@ -503,5 +505,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lytro.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lytro.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Lytro.pm	(revision 34921)
@@ -0,0 +1,214 @@
+#------------------------------------------------------------------------------
+# File:         Lytro.pm
+#
+# Description:  Read Lytro LFP files
+#
+# Revisions:    2014-07-17 - P. Harvey Created
+#
+# References:   1) http://optics.miloush.net/lytro/TheFileFormat.aspx
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Lytro;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Import;
+
+$VERSION = '1.03';
+
+sub ExtractTags($$$);
+
+# Lytro LFP tags (ref PH)
+%Image::ExifTool::Lytro::Main = (
+    GROUPS => { 2 => 'Camera' },
+    VARS => { NO_ID => 1 },
+    NOTES => q{
+        Tag definitions for Lytro Light Field Picture (LFP) files.  ExifTool
+        extracts the full JSON metadata blocks, as well as breaking them down into
+        individual tags.  All available tags are extracted from the JSON metadata,
+        even if they don't appear in the table below.
+    },
+    JSONMetadata => {
+        Notes => 'the full JSON-format metadata blocks',
+        Binary => 1,
+        List => 1,
+    },
+    EmbeddedImage => {
+        Notes => 'JPEG image embedded in LFP files written by Lytro Desktop',
+        Groups => { 2 => 'Preview' },
+        Binary => 1,
+    },
+    Type                => { Name => 'CameraType' },
+    CameraMake          => { Name => 'Make' },
+    CameraModel         => { Name => 'Model', Description => 'Camera Model Name' },
+    CameraSerialNumber  => { Name => 'SerialNumber'},
+    CameraFirmware      => { Name => 'FirmwareVersion'},
+    DevicesAccelerometerSampleArrayTime => { Name => 'AccelerometerTime'},
+    DevicesAccelerometerSampleArrayX    => { Name => 'AccelerometerX'},
+    DevicesAccelerometerSampleArrayY    => { Name => 'AccelerometerY'},
+    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)',
+    },
+    DevicesLensFNumber => {
+        Name => 'FNumber',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+    },
+    DevicesLensFocalLength => {
+        Name => 'FocalLength',
+        ValueConv => '$val * 1000', # convert from metres to mm
+        PrintConv => 'sprintf("%.1f mm",$val)',
+    },
+    DevicesLensTemperature => {
+        Name => 'LensTemperature',
+        PrintConv => 'sprintf("%.1f C",$val)',
+    },
+    DevicesSocTemperature => {
+        Name => 'SocTemperature',
+        PrintConv => 'sprintf("%.1f C",$val)',
+    },
+    DevicesShutterFrameExposureDuration => {
+        Name => 'FrameExposureTime',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    DevicesShutterPixelExposureDuration => {
+        Name => 'ExposureTime',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    DevicesSensorPixelPitch => {
+        Name => 'FocalPlaneXResolution',
+        Notes => 'Y resolution is the same as X resolution',
+        ValueConv => '25.4 / $val / 1000',  # convert from metres to pixels/inch
+    },
+    DevicesSensorSensorSerial   => { Name => 'SensorSerialNumber'},
+    DevicesSensorIso            => { Name => 'ISO' },
+    ImageLimitExposureBias      => { Groups => { 2 => 'Image' }, PrintConv => 'sprintf("%+.1f", $val)' },
+    ImageModulationExposureBias => { Groups => { 2 => 'Image' }, PrintConv => 'sprintf("%+.1f", $val)' },
+    ImageOrientation => {
+        Name => 'Orientation',
+        Groups => { 2 => 'Image' },
+        PrintConv => {
+            1 => 'Horizontal (normal)',
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# Extract tags from a parsed JSON hash
+# Inputs: 0) ExifTool ref, 1) tag hash ref, 2) base tag name
+sub ExtractTags($$$)
+{
+    my ($et, $meta, $parent) = @_;
+    ref $meta eq 'HASH' or $et->Warn('Invalid LFP metadata'), return;
+    my ($key, $val, $name, $tagTablePtr);
+    foreach $key (sort keys %$meta) {
+        my $tag = $parent . ucfirst($key);
+        foreach $val (ref $$meta{$key} eq 'ARRAY' ? @{$$meta{$key}} : $$meta{$key}) {
+            ref $val eq 'HASH' and ExtractTags($et, $val, $tag), next;
+            $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::Lytro::Main');
+            unless ($$tagTablePtr{$tag}) {
+                ($name = $tag) =~ s/[^-_a-zA-Z0-9](.?)/\U$1/g;
+                $name =~ s/ParametersVendorContentComLytroTags//;
+                my %tagInfo;
+                $tagInfo{Groups} = { 2 => 'Image' } unless $name =~ s/^Devices//;
+                $tagInfo{List} = 1 if ref $$meta{$key} eq 'ARRAY';
+                $tagInfo{Name} = $name;
+                my $str = $tag eq $name ? '' : " as $name";
+                $et->VPrint(0, "  [adding $tag$str]\n");
+                AddTagToTable($tagTablePtr, $tag, \%tagInfo);
+            }
+            $et->HandleTag($tagTablePtr, $tag, $val);
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
+# Process segments from a Lytro LFP image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid Lytro image
+sub ProcessLFP($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $et->Options('Verbose');
+    my ($buff, $id);
+
+    # validate the Lytro file header
+    return 0 unless $raf->Read($buff, 16) == 16 and $buff =~ /^\x89LFP\x0d\x0a\x1a\x0a/;
+    $et->SetFileType();   # set the FileType tag
+    SetByteOrder('MM');
+    my $tagTablePtr = GetTagTable('Image::ExifTool::Lytro::Main');
+    while ($raf->Read($buff, 16) == 16) {
+        $buff =~ /^\x89LF/ or $et->Warn('LFP format error'), last;
+        my $size = Get32u(\$buff, 12);
+        $size & 0x80000000 and $et->Warn('Invalid LFP segment size'), last;
+        $raf->Read($id, 80) == 80 or $et->Warn('Truncated LFP segment'), last;  # ignore the sha1
+        if ($verbose) {
+            $id =~ s/\0.*//s;
+            $et->VPrint(0, substr($buff,1,3), " segment ($size bytes, $id)\n");
+        }
+        if ($size > 20000000) {
+            $raf->Seek($size, 1) or $et->Warn('Seek error in LFP file'), last;
+        } else {
+            $raf->Read($buff,$size) == $size or $et->Warn('Truncated LFP data'), last;
+            $et->VerboseDump(\$buff, Addr=>$raf->Tell()-$size);
+            if ($buff =~ /^\{\s+"/) { # JSON metadata?
+                pos($buff) = 0;
+                $et->HandleTag($tagTablePtr, 'JSONMetadata', $buff);
+                my $meta = Image::ExifTool::Import::ReadJSONObject(undef, \$buff);
+                ExtractTags($et, $meta, '');
+            } elsif ($buff =~ /^\xff\xd8\xff/) { # embedded JPEG image?
+                $et->HandleTag($tagTablePtr, 'EmbeddedImage', $buff);
+            }
+        }
+        # skip padding if necessary
+        my $pad = 16 - ($size % 16);
+        $raf->Seek($pad, 1) if $pad != 16;
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Lytro - Read Lytro LFP files
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to read metadata
+from Lytro Light Field Picture (LFP) files.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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://optics.miloush.net/lytro/TheFileFormat.aspx>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Lytro Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/M2TS.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/M2TS.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/M2TS.pm	(revision 34921)
@@ -32,5 +32,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.08';
+$VERSION = '1.18';
 
 # program map table "stream_type" lookup (ref 6/1)
@@ -234,9 +234,9 @@
 sub ParseAC3Audio($$)
 {
-    my ($exifTool, $dataPt) = @_;
+    my ($et, $dataPt) = @_;
     if ($$dataPt =~ /\x0b\x77..(.)/sg) {
         my $sampleRate = ord($1) >> 6;
         my $tagTablePtr = GetTagTable('Image::ExifTool::M2TS::AC3');
-        $exifTool->HandleTag($tagTablePtr, AudioSampleRate => $sampleRate);
+        $et->HandleTag($tagTablePtr, AudioSampleRate => $sampleRate);
     }
 }
@@ -250,12 +250,12 @@
 sub ParseAC3Descriptor($$)
 {
-    my ($exifTool, $dataPt) = @_;
+    my ($et, $dataPt) = @_;
     return if length $$dataPt < 3;
     my @v = unpack('C3', $$dataPt);
     my $tagTablePtr = GetTagTable('Image::ExifTool::M2TS::AC3');
-    # $exifTool->HandleTag($tagTablePtr, 'AudioSampleRate', $v[0] >> 5);
-    $exifTool->HandleTag($tagTablePtr, 'AudioBitrate', $v[1] >> 2);
-    $exifTool->HandleTag($tagTablePtr, 'SurroundMode', $v[1] & 0x03);
-    $exifTool->HandleTag($tagTablePtr, 'AudioChannels', ($v[2] >> 1) & 0x0f);
+    # $et->HandleTag($tagTablePtr, 'AudioSampleRate', $v[0] >> 5);
+    $et->HandleTag($tagTablePtr, 'AudioBitrate', $v[1] >> 2);
+    $et->HandleTag($tagTablePtr, 'SurroundMode', $v[1] & 0x03);
+    $et->HandleTag($tagTablePtr, 'AudioChannels', ($v[2] >> 1) & 0x0f);
     # don't (yet) decode any more (language codes, etc)
 }
@@ -263,5 +263,5 @@
 #------------------------------------------------------------------------------
 # Parse PID stream data
-# Inputs: 0) Exiftool ref, 1) PID number, 2) PID type, 3) PID name, 4) data ref
+# Inputs: 0) ExifTool ref, 1) PID number, 2) PID type, 3) PID name, 4) data ref
 # Returns: 0=stream parsed OK,
 #          1=stream parsed but we want to parse more of these,
@@ -269,14 +269,12 @@
 sub ParsePID($$$$$)
 {
-    my ($exifTool, $pid, $type, $pidName, $dataPt) = @_;
+    my ($et, $pid, $type, $pidName, $dataPt) = @_;
     # can't parse until we know the type (Program Map Table may be later in the stream)
-    return -1 unless defined $type;   
-    my $verbose = $exifTool->Options('Verbose');
+    return -1 unless defined $type;
+    my $verbose = $et->Options('Verbose');
     if ($verbose > 1) {
-        my $out = $exifTool->Options('TextOut');
+        my $out = $et->Options('TextOut');
         printf $out "Parsing stream 0x%.4x (%s)\n", $pid, $pidName;
-        my %parms = ( Out => $out );
-        $parms{MaxLen} = 96 if $verbose < 4;
-        Image::ExifTool::HexDump($dataPt, undef, %parms) if $verbose > 2;
+        $et->VerboseDump($dataPt);
     }
     my $more = 0;
@@ -284,18 +282,22 @@
         # MPEG-1/MPEG-2 Video
         require Image::ExifTool::MPEG;
-        Image::ExifTool::MPEG::ParseMPEGAudioVideo($exifTool, $dataPt);
+        Image::ExifTool::MPEG::ParseMPEGAudioVideo($et, $dataPt);
     } elsif ($type == 0x03 or $type == 0x04) {
         # MPEG-1/MPEG-2 Audio
         require Image::ExifTool::MPEG;
-        Image::ExifTool::MPEG::ParseMPEGAudio($exifTool, $dataPt);
+        Image::ExifTool::MPEG::ParseMPEGAudio($et, $dataPt);
     } elsif ($type == 0x1b) {
         # H.264 Video
         require Image::ExifTool::H264;
-        $more = Image::ExifTool::H264::ParseH264Video($exifTool, $dataPt);
+        $more = Image::ExifTool::H264::ParseH264Video($et, $dataPt);
         # force parsing additional H264 frames with ExtractEmbedded option
-        $more = 1 if $exifTool->Options('ExtractEmbedded');
+        if ($$et{OPTIONS}{ExtractEmbedded}) {
+            $more = 1;
+        } elsif (not $$et{OPTIONS}{Validate}) {
+            $et->WarnOnce('The ExtractEmbedded option may find more tags in the video data',3);
+        }
     } elsif ($type == 0x81 or $type == 0x87 or $type == 0x91) {
         # AC-3 audio
-        ParseAC3Audio($exifTool, $dataPt);
+        ParseAC3Audio($et, $dataPt);
     }
     return $more;
@@ -308,11 +310,11 @@
 sub ProcessM2TS($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my ($buff, $plen, $i, $j, $fileType, $eof);
-    my (%pmt, %pidType, %didPID, %data, %sectLen);
-    my ($startTime, $endTime, $backScan, $maxBack);
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my ($buff, $pLen, $upkPrefix, $j, $fileType, $eof);
+    my (%pmt, %pidType, %data, %sectLen);
+    my ($startTime, $endTime, $fwdTime, $backScan, $maxBack);
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
 
     # read first packet
@@ -321,12 +323,21 @@
     return 0 unless $buff =~ /^(....)?\x47/s;
     unless ($1) {
-        $plen = 188;        # no timecode
+        $pLen = 188;        # no timecode
         $fileType = 'M2T';  # (just as a way to tell there is no timecode)
+        $upkPrefix = 'N';
     } else {
-        $plen = 192; # 188-byte transport packet + leading 4-byte timecode (ref 4)
-    }
-    $exifTool->SetFileType($fileType);
+        $pLen = 192; # 188-byte transport packet + leading 4-byte timecode (ref 4)
+        $upkPrefix = 'x4N';
+    }
+    my $prePos = $pLen - 188;       # byte position of packet prefix
+    my $readSize = 64 * $pLen;      # size of our read buffer
+    $raf->Seek(0,0);                # rewind to start
+    $raf->Read($buff, $readSize) >= $pLen * 4 or return 0;  # require at least 4 packets
+    # validate the sync byte in the next 3 packets
+    for ($j=1; $j<4; ++$j) {
+        return 0 unless substr($buff, $prePos + $pLen * $j, 1) eq 'G'; # (0x47)
+    }
+    $et->SetFileType($fileType);
     SetByteOrder('MM');
-    $raf->Seek(0,0);        # rewind to start
     my $tagTablePtr = GetTagTable('Image::ExifTool::M2TS::Main');
 
@@ -338,41 +349,67 @@
         0x1fff => 'Null Packet',
     );
-    my %needPID = ( 0x00 => 1 );    # lookup for stream PID's that we still need to parse
+    my %didPID = ( 1 => 0, 2 => 0, 0x1fff => 0 );
+    my %needPID = ( 0 => 1 );       # lookup for stream PID's that we still need to parse
+    my $pEnd = 0;
 
     # parse packets from MPEG-2 Transport Stream
-    for ($i=0; ; ++$i) {
+    for (;;) {
 
         unless (%needPID) {
             last unless defined $startTime;
-            # seek backwards to find last PCR
-            if (defined $backScan) {
-                last if defined $endTime;
-                $backScan -= $plen;
-                last if $backScan < $maxBack;
-            } else {
+            # reconfigure to seek backwards for last PCR
+            unless (defined $backScan) {
+                my $saveTime = $endTime;
                 undef $endTime;
-                last if $exifTool->Options('FastScan');
-                $verbose and print "[Starting backscan for last PCR]\n";
-                # calculate position of last complete packet
-                my $fwdPos = $raf->Tell();
+                last if $et->Options('FastScan');
+                $verbose and print $out "[Starting backscan for last PCR]\n";
+                # remember how far we got when reading forward through the file
+                my $fwdPos = $raf->Tell() - length($buff) + $pEnd;
+                # determine the position of the last packet relative to the EOF
                 $raf->Seek(0, 2) or last;
                 my $fsize = $raf->Tell();
-                my $nPack = int($fsize / $plen);
-                $backScan = ($nPack - 1) * $plen - $fsize;
+                $backScan = int($fsize / $pLen) * $pLen - $fsize;
                 # set limit on how far back we will go
                 $maxBack = $fwdPos - $fsize;
-                $maxBack = -256000 if $maxBack < -256000;
-            }
-            $raf->Seek($backScan, 2) or last;
-        }
-        # read the next packet
-        $raf->Read($buff, $plen) == $plen or $eof = 1, last;
+                # scan back a maximum of 512k (have seen last PCR at -276k)
+                my $nMax = int(512000 / $pLen);     # max packets to backscan
+                if ($nMax < int(-$maxBack / $pLen)) {
+                    $maxBack = $backScan - $nMax * $pLen;
+                } else {
+                    # use this time if none found in all remaining packets
+                    $fwdTime = $saveTime;
+                }
+                $pEnd = 0;
+            }
+        }
+        my $pos;
+        # read more if necessary
+        if (defined $backScan) {
+            last if defined $endTime;
+            $pos = $pEnd = $pEnd - 2 * $pLen;   # step back to previous packet
+            if ($pos < 0) {
+                # read another buffer from end of file
+                last if $backScan <= $maxBack;
+                my $buffLen = $backScan - $maxBack;
+                $buffLen = $readSize if $buffLen > $readSize;
+                $backScan -= $buffLen;
+                $raf->Seek($backScan, 2) or last;
+                $raf->Read($buff, $buffLen) == $buffLen or last;
+                $pos = $pEnd = $buffLen - $pLen;
+            }
+        } else {
+            $pos = $pEnd;
+            if ($pos + $pLen > length $buff) {
+                $raf->Read($buff, $readSize) >= $pLen or $eof = 1, last;
+                $pos = $pEnd = 0;
+            }
+        }
+        $pEnd += $pLen;
         # decode the packet prefix
-        my $pos = length($buff) - 188;
-        my $prefix = Get32u(\$buff, $pos);
-        $pos += 4;
+        $pos += $prePos;
+        my $prefix = unpack("x${pos}N", $buff); # (use unpack instead of Get32u for speed)
         # validate sync byte
-        unless (($prefix & 0xff000000) >> 24 == 0x47) {
-            $exifTool->Warn('Synchronization error') unless defined $backScan;
+        unless (($prefix & 0xff000000) == 0x47000000) {
+            $et->Warn('M2TS synchronization error') unless defined $backScan;
             last;
         }
@@ -387,16 +424,18 @@
 
         if ($verbose > 1) {
+            my $i = ($raf->Tell() - length($buff) + $pEnd) / $pLen - 1;
             print  $out "Transport packet $i:\n";
-            Image::ExifTool::HexDump(\$buff, undef, Addr => $i * $plen, Out => $out) if $verbose > 2;
+            $et->VerboseDump(\$buff, Len => $pLen, Addr => $i * $pLen, Start => $pos - $prePos);
             my $str = $pidName{$pid} ? " ($pidName{$pid})" : '';
-            printf $out "  Timecode:   0x%.4x\n", Get32u(\$buff, 0) if $plen == 192;
+            printf $out "  Timecode:   0x%.4x\n", Get32u(\$buff, $pos - $prePos) if $pLen == 192;
             printf $out "  Packet ID:  0x%.4x$str\n", $pid;
             printf $out "  Start Flag: %s\n", $payload_unit_start_indicator ? 'Yes' : 'No';
         }
 
+        $pos += 4;
         # handle adaptation field
         if ($adaptation_field_exists) {
             my $len = Get8u(\$buff, $pos++);
-            $pos + $len > $plen and $exifTool->Warn('Invalid adaptation field length'), last;
+            $pos + $len > $pEnd and $et->Warn('Invalid adaptation field length'), last;
             # read PCR value for calculation of Duration
             if ($len > 6) {
@@ -424,31 +463,34 @@
         {
             # must interpret pointer field if payload_unit_start_indicator is set
+            my $buf2;
             if ($payload_unit_start_indicator) {
                 # skip to start of section
                 my $pointer_field = Get8u(\$buff, $pos);
                 $pos += 1 + $pointer_field;
-                $pos >= $plen and $exifTool->Warn('Bad pointer field'), last;
+                $pos >= $pEnd and $et->Warn('Bad pointer field'), last;
+                $buf2 = substr($buff, $pEnd-$pLen, $pLen);
+                $pos -= $pEnd - $pLen;
             } else {
                 # not the start of a section
                 next unless $sectLen{$pid};
                 my $more = $sectLen{$pid} - length($data{$pid});
-                my $size = length($buff) - $pos;
+                my $size = $pLen - $pos;
                 $size = $more if $size > $more;
                 $data{$pid} .= substr($buff, $pos, $size);
                 next unless $size == $more;
-                # we have the complete section now, so put back into $buff for parsing
-                $buff = $data{$pid};
+                # we have the complete section now, so put into $buf2 for parsing
+                $buf2 = $data{$pid};
                 $pos = 0;
                 delete $data{$pid};
                 delete $sectLen{$pid};
             }
-            my $slen = length($buff);   # section length
-            $pos + 8 > $slen and $exifTool->Warn("Truncated payload"), last;
+            my $slen = length($buf2);   # section length
+            $pos + 8 > $slen and $et->Warn('Truncated payload'), last;
             # validate table ID
-            my $table_id = Get8u(\$buff, $pos);
+            my $table_id = Get8u(\$buf2, $pos);
             my $name = ($tableID{$table_id} || sprintf('Unknown (0x%x)',$table_id)) . ' Table';
             my $expectedID = $pid ? 0x02 : 0x00;
             unless ($table_id == $expectedID) {
-                $verbose > 1 and printf $out "  (skipping $name)\n";
+                $verbose > 1 and print $out "  (skipping $name)\n";
                 delete $needPID{$pid};
                 $didPID{$pid} = 1;
@@ -456,17 +498,17 @@
             }
             # validate section syntax indicator for parsed tables (PAT, PMT)
-            my $section_syntax_indicator = Get8u(\$buff, $pos + 1) & 0xc0;
-            $section_syntax_indicator == 0x80 or $exifTool->Warn("Bad $name"), last;
-            my $section_length = Get16u(\$buff, $pos + 1) & 0x0fff;
-            $section_length > 1021 and $exifTool->Warn("Invalid $name length"), last;
+            my $section_syntax_indicator = Get8u(\$buf2, $pos + 1) & 0xc0;
+            $section_syntax_indicator == 0x80 or $et->Warn("Bad $name"), last;
+            my $section_length = Get16u(\$buf2, $pos + 1) & 0x0fff;
+            $section_length > 1021 and $et->Warn("Invalid $name length"), last;
             if ($slen < $section_length + 3) { # (3 bytes for table_id + section_length)
                 # must wait until we have the full section
-                $data{$pid} = substr($buff, $pos);
+                $data{$pid} = substr($buf2, $pos);
                 $sectLen{$pid} = $section_length + 3;
                 next;
             }
-            my $program_number = Get16u(\$buff, $pos + 3);
-            my $section_number = Get8u(\$buff, $pos + 6);
-            my $last_section_number = Get8u(\$buff, $pos + 7);
+            my $program_number = Get16u(\$buf2, $pos + 3);
+            my $section_number = Get8u(\$buf2, $pos + 6);
+            my $last_section_number = Get8u(\$buf2, $pos + 7);
             if ($verbose > 1) {
                 print  $out "  $name length: $section_length\n";
@@ -481,34 +523,30 @@
                 # decode PAT (Program Association Table)
                 while ($pos <= $end - 4) {
-                    my $program_number = Get16u(\$buff, $pos);
-                    my $program_map_PID = Get16u(\$buff, $pos + 2) & 0x1fff;
+                    my $program_number = Get16u(\$buf2, $pos);
+                    my $program_map_PID = Get16u(\$buf2, $pos + 2) & 0x1fff;
                     $pmt{$program_map_PID} = $program_number; # save our PMT PID's
-                    if (not $pidName{$program_map_PID} or $verbose > 1) {
-                        my $str = "Program $program_number Map";
-                        $pidName{$program_map_PID} = $str;
-                        $needPID{$program_map_PID} = 1 unless $didPID{$program_map_PID};
-                        $verbose and printf $out "  PID(0x%.4x) --> $str\n", $program_map_PID;
-                    }
+                    my $str = "Program $program_number Map";
+                    $pidName{$program_map_PID} = $str;
+                    $needPID{$program_map_PID} = 1 unless $didPID{$program_map_PID};
+                    $verbose and printf $out "  PID(0x%.4x) --> $str\n", $program_map_PID;
                     $pos += 4;
                 }
             } else {
                 # decode PMT (Program Map Table)
-                $pos + 4 > $slen and $exifTool->Warn('Truncated PMT'), last;
-                my $pcr_pid = Get16u(\$buff, $pos) & 0x1fff;
-                my $program_info_length = Get16u(\$buff, $pos + 2) & 0x0fff;
-                if (not $pidName{$pcr_pid} or $verbose > 1) {
-                    my $str = "Program $program_number Clock Reference";
-                    $pidName{$pcr_pid} = $str;
-                    $verbose and printf $out "  PID(0x%.4x) --> $str\n", $pcr_pid;
-                }
+                $pos + 4 > $slen and $et->Warn('Truncated PMT'), last;
+                my $pcr_pid = Get16u(\$buf2, $pos) & 0x1fff;
+                my $program_info_length = Get16u(\$buf2, $pos + 2) & 0x0fff;
+                my $str = "Program $program_number Clock Reference";
+                $pidName{$pcr_pid} = $str;
+                $verbose and printf $out "  PID(0x%.4x) --> $str\n", $pcr_pid;
                 $pos += 4;
-                $pos + $program_info_length > $slen and $exifTool->Warn('Truncated program info'), last;
+                $pos + $program_info_length > $slen and $et->Warn('Truncated program info'), last;
                 # dump program information descriptors if verbose
                 if ($verbose > 1) { for ($j=0; $j<$program_info_length-2; ) {
-                    my $descriptor_tag = Get8u(\$buff, $pos + $j);
-                    my $descriptor_length = Get8u(\$buff, $pos + $j + 1);
+                    my $descriptor_tag = Get8u(\$buf2, $pos + $j);
+                    my $descriptor_length = Get8u(\$buf2, $pos + $j + 1);
                     $j += 2;
                     last if $j + $descriptor_length > $program_info_length;
-                    my $desc = substr($buff, $pos+$j, $descriptor_length);
+                    my $desc = substr($buf2, $pos+$j, $descriptor_length);
                     $j += $descriptor_length;
                     $desc =~ s/([\x00-\x1f\x80-\xff])/sprintf("\\x%.2x",ord $1)/eg;
@@ -517,31 +555,31 @@
                 $pos += $program_info_length; # skip descriptors (for now)
                 while ($pos <= $end - 5) {
-                    my $stream_type = Get8u(\$buff, $pos);
-                    my $elementary_pid = Get16u(\$buff, $pos + 1) & 0x1fff;
-                    my $es_info_length = Get16u(\$buff, $pos + 3) & 0x0fff;
-                    if (not $pidName{$elementary_pid} or $verbose > 1) {
-                        my $str = $streamType{$stream_type};
-                        $str or $str = ($stream_type < 0x7f ? 'Reserved' : 'Private');
-                        $str = sprintf('%s (0x%.2x)', $str, $stream_type);
-                        $str = "Program $program_number $str";
-                        # save PID type and name string
-                        $pidName{$elementary_pid} = $str;
-                        $pidType{$elementary_pid} = $stream_type;
-                        $verbose and printf $out "  PID(0x%.4x) --> $str\n", $elementary_pid;
-                        if ($str =~ /(Audio|Video)/) {
-                            $exifTool->HandleTag($tagTablePtr, $1 . 'StreamType', $stream_type);
-                            # we want to parse all Audio and Video streams
-                            $needPID{$elementary_pid} = 1 unless $didPID{$elementary_pid};
+                    my $stream_type = Get8u(\$buf2, $pos);
+                    my $elementary_pid = Get16u(\$buf2, $pos + 1) & 0x1fff;
+                    my $es_info_length = Get16u(\$buf2, $pos + 3) & 0x0fff;
+                    my $str = $streamType{$stream_type};
+                    $str or $str = ($stream_type < 0x7f ? 'Reserved' : 'Private');
+                    $str = sprintf('%s (0x%.2x)', $str, $stream_type);
+                    $str = "Program $program_number $str";
+                    $verbose and printf $out "  PID(0x%.4x) --> $str\n", $elementary_pid;
+                    if ($str =~ /(Audio|Video)/) {
+                        unless ($pidName{$elementary_pid}) {
+                            $et->HandleTag($tagTablePtr, $1 . 'StreamType', $stream_type)
                         }
+                        # we want to parse all Audio and Video streams
+                        $needPID{$elementary_pid} = 1 unless $didPID{$elementary_pid};
                     }
+                    # save PID type and name string
+                    $pidName{$elementary_pid} = $str;
+                    $pidType{$elementary_pid} = $stream_type;
                     $pos += 5;
-                    $pos + $es_info_length > $slen and $exifTool->Warn('Trunacted ES info'), $pos = $end, last;
+                    $pos + $es_info_length > $slen and $et->Warn('Truncated ES info'), $pos = $end, last;
                     # parse elementary stream descriptors
                     for ($j=0; $j<$es_info_length-2; ) {
-                        my $descriptor_tag = Get8u(\$buff, $pos + $j);
-                        my $descriptor_length = Get8u(\$buff, $pos + $j + 1);
+                        my $descriptor_tag = Get8u(\$buf2, $pos + $j);
+                        my $descriptor_length = Get8u(\$buf2, $pos + $j + 1);
                         $j += 2;
                         last if $j + $descriptor_length > $es_info_length;
-                        my $desc = substr($buff, $pos+$j, $descriptor_length);
+                        my $desc = substr($buf2, $pos+$j, $descriptor_length);
                         $j += $descriptor_length;
                         if ($verbose > 1) {
@@ -553,5 +591,5 @@
                         unless ($didPID{$pid}) {
                             if ($descriptor_tag == 0x81) {  # AC-3
-                                ParseAC3Descriptor($exifTool, \$desc);
+                                ParseAC3Descriptor($et, \$desc);
                             }
                         }
@@ -560,14 +598,13 @@
                 }
             }
-            $pos = $end + 4; # skip CRC
-        } elsif ($pid == 1) {       # conditional access table
-        } elsif ($pid == 2) {       # transport stream description table
-        } elsif ($pid == 0x1fff) {  # null packet
-        } elsif (not $didPID{$pid}) {
+            # $pos = $end + 4; # skip CRC
+
+        } elsif (not defined $didPID{$pid}) {
+
             # save data from the start of each elementary stream
             if ($payload_unit_start_indicator) {
                 if (defined $data{$pid}) {
                     # we must have a whole section, so parse now
-                    my $more = ParsePID($exifTool, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
+                    my $more = ParsePID($et, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
                     # start fresh even if we couldn't process this PID yet
                     delete $data{$pid};
@@ -581,5 +618,5 @@
                 }
                 # check for a PES header
-                next if $pos + 6 > $plen;
+                next if $pos + 6 > $pEnd;
                 my $start_code = Get32u(\$buff, $pos);
                 next unless ($start_code & 0xffffff00) == 0x00000100;
@@ -592,18 +629,18 @@
                 $pos += 6;
                 unless ($noSyntax{$stream_id}) {
-                    next if $pos + 3 > $plen;
+                    next if $pos + 3 > $pEnd;
                     # validate PES syntax
                     my $syntax = Get8u(\$buff, $pos) & 0xc0;
-                    $syntax == 0x80 or $exifTool->Warn('Bad PES syntax'), next;
+                    $syntax == 0x80 or $et->Warn('Bad PES syntax'), next;
                     # skip PES header
                     my $pes_header_data_length = Get8u(\$buff, $pos + 2);
                     $pos += 3 + $pes_header_data_length;
-                    next if $pos >= $plen;
+                    next if $pos >= $pEnd;
                 }
-                $data{$pid} = substr($buff, $pos);
+                $data{$pid} = substr($buff, $pos, $pEnd-$pos);
             } else {
                 next unless defined $data{$pid};
                 # accumulate data for each elementary stream
-                $data{$pid} .= substr($buff, $pos);
+                $data{$pid} .= substr($buff, $pos, $pEnd-$pos);
             }
             # save only the first 256 bytes of most streams, except for
@@ -611,5 +648,5 @@
             my $saveLen = (not $pidType{$pid} or $pidType{$pid} == 0x1b) ? 1024 : 256;
             if (length($data{$pid}) >= $saveLen) {
-                my $more = ParsePID($exifTool, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
+                my $more = ParsePID($et, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
                 next if $more < 0;  # wait for program map table (hopefully not too long)
                 delete $data{$pid};
@@ -629,7 +666,8 @@
 
     # calculate Duration if available
-    if (defined $startTime and defined $endTime and $startTime != $endTime) {
+    $endTime = $fwdTime unless defined $endTime;
+    if (defined $startTime and defined $endTime) {
         $endTime += 0x80000000 * 1200 if $startTime > $endTime; # handle 33-bit wrap
-        $exifTool->HandleTag($tagTablePtr, 'Duration', $endTime - $startTime);
+        $et->HandleTag($tagTablePtr, 'Duration', $endTime - $startTime);
     }
 
@@ -651,5 +689,5 @@
     my $pid;
     foreach $pid (sort keys %data) {
-        ParsePID($exifTool, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
+        ParsePID($et, $pid, $pidType{$pid}, $pidName{$pid}, \$data{$pid});
         delete $data{$pid};
     }
@@ -677,5 +715,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIE.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIE.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIE.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool::GPS;
 
-$VERSION = '1.34';
+$VERSION = '1.48';
 
 sub ProcessMIE($$);
@@ -144,5 +144,5 @@
         C<TAG-xx_YY>, where C<TAG> is the tag name, C<xx> is a 2-character lower
         case ISO 639-1 language code, and C<YY> is a 2-character upper case ISO
-        3166-1 alpha 2 country code (ie. C<Title-en_US>).  But as usual, the user
+        3166-1 alpha 2 country code (eg. C<Title-en_US>).  But as usual, the user
         interface is case-insensitive, and ExifTool will write the correct case to
         the file.
@@ -150,6 +150,12 @@
         3) Some numerical MIE tags allow units of measurement to be specified.  For
         these tags, units may be added in brackets immediately following the value
-        (ie. C<55(mi/h)>).  If no units are specified, the default units are
+        (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 L<Compress|../ExifTool.html#Compress> (-z)
+        option is used and Compress::Zlib is available.
+
+        See L<https://exiftool.org/MIE1.1-20070121.pdf> for the official MIE
+        specification.
     },
    '0Type' => {
@@ -296,5 +302,5 @@
     Copyright   => { Groups => { 2 => 'Author' } },
     CreateDate  => { Groups => { 2 => 'Time' }, %dateInfo },
-    EMail       => { Groups => { 2 => 'Author' } },
+    EMail       => { Name => 'Email', Groups => { 2 => 'Author' } },
     Keywords    => { List => 1 },
     ModifyDate  => { Groups => { 2 => 'Time' }, %dateInfo },
@@ -464,4 +470,5 @@
     data => {
         Name => 'FullSizeImage',
+        Groups => { 2 => 'Preview' },
         %binaryConv,
         RawConv => '$self->ValidateImage(\$val,$tag)',
@@ -486,4 +493,5 @@
     data => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         %binaryConv,
         RawConv => '$self->ValidateImage(\$val,$tag)',
@@ -508,4 +516,5 @@
     data => {
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
         %binaryConv,
         RawConv => '$self->ValidateImage(\$val,$tag)',
@@ -565,5 +574,5 @@
         Writable => 'rational64u',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => '$val',
     },
     Flash => {
@@ -782,5 +791,5 @@
 #------------------------------------------------------------------------------
 # Get localized version of tagInfo hash
-# Inputs: 0) tagInfo hash ref, 1) locale code (ie. "en_CA")
+# Inputs: 0) tagInfo hash ref, 1) locale code (eg. "en_CA")
 # Returns: new tagInfo hash ref, or undef if invalid
 sub GetLangInfo($$)
@@ -803,5 +812,5 @@
 {
     unless (defined $hasZlib) {
-        $hasZlib = eval 'require Compress::Zlib';
+        $hasZlib = eval { require Compress::Zlib };
         unless ($hasZlib) {
             $hasZlib = 0;
@@ -827,11 +836,11 @@
 # 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
+#         4) valid data length relative to offset, 5) returned rational ref
 # Returns: converted value, or undefined if data isn't there
 #          or list of values in list context
 # Notes: all string formats are converted to UTF8
-sub ReadMIEValue($$$$$)
+sub ReadMIEValue($$$$$;$)
 {
-    my ($dataPt, $offset, $format, $count, $size) = @_;
+    my ($dataPt, $offset, $format, $count, $size, $ratPt) = @_;
     my $val;
     if ($format =~ /^(utf(8|16|32)|string)/) {
@@ -860,5 +869,5 @@
     } else {
         $format = 'undef' if $format eq 'free'; # read 'free' as 'undef'
-        return ReadValue($dataPt, $offset, $format, $count, $size);
+        return ReadValue($dataPt, $offset, $format, $count, $size, $ratPt);
     }
     return $val;
@@ -871,5 +880,5 @@
 sub CheckMIE($$$)
 {
-    my ($exifTool, $tagInfo, $valPtr) = @_;
+    my ($et, $tagInfo, $valPtr) = @_;
     my $format = $$tagInfo{Writable} || $tagInfo->{Table}->{WRITABLE};
     my $err;
@@ -888,9 +897,9 @@
         return 'Units not supported';
     } else {
-        if ($format eq 'string' and $exifTool->{OPTIONS}->{Charset} ne 'UTF8' and
+        if ($format eq 'string' and $$et{OPTIONS}{Charset} ne 'UTF8' and
             $$valPtr =~ /[\x80-\xff]/)
         {
             # convert from Charset to UTF-8
-            $$valPtr = $exifTool->Encode($$valPtr,'UTF8');
+            $$valPtr = $et->Encode($$valPtr,'UTF8');
         }
         $err = Image::ExifTool::CheckValue($valPtr, $format, $$tagInfo{Count});
@@ -905,12 +914,12 @@
 sub WriteMIEGroup($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $outfile = $$dirInfo{OutFile};
     my $dirName = $$dirInfo{DirName};
     my $toWrite = $$dirInfo{ToWrite} || '';
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
-    my $optCompress = $exifTool->Options('Compress');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $optCompress = $et->Options('Compress');
+    my $out = $et->Options('TextOut');
     my ($msg, $err, $ok, $sync, $delGroup);
     my $tag = '';
@@ -919,5 +928,5 @@
     # count each MIE directory found and make name for this specific instance
     my ($grp1, %isWriting);
-    my $cnt = $exifTool->{MIE_COUNT};
+    my $cnt = $$et{MIE_COUNT};
     my $grp = $tagTablePtr->{GROUPS}->{1};
     my $n = $$cnt{'MIE-Main'} || 0;
@@ -928,24 +937,24 @@
         ($grp1 = $grp) =~ s/MIE-/MIE$n-/;
         my $m = $$cnt{$grp1} = ($$cnt{$grp1} || 0) + 1;
-        $isWriting{"$grp$m"} = 1;   # ie. 'MIE-Doc2'
-        $isWriting{$grp1} = 1;      # ie. 'MIE1-Doc'
+        $isWriting{"$grp$m"} = 1;   # eg. 'MIE-Doc2'
+        $isWriting{$grp1} = 1;      # eg. 'MIE1-Doc'
         $grp1 .= $m;
     }
     # build lookup for all valid group names for this MIE group
-    $isWriting{$grp} = 1;           # ie. 'MIE-Doc'
-    $isWriting{$grp1} = 1;          # ie. 'MIE1-Doc2'
-    $isWriting{"MIE$n"} = 1;        # ie. 'MIE1'
+    $isWriting{$grp} = 1;           # eg. 'MIE-Doc'
+    $isWriting{$grp1} = 1;          # eg. 'MIE1-Doc2'
+    $isWriting{"MIE$n"} = 1;        # eg. 'MIE1'
 
     # determine if we are deleting this group
-    if (%{$exifTool->{DEL_GROUP}}) {
-        $delGroup = 1 if $exifTool->{DEL_GROUP}->{MIE} or
-                         $exifTool->{DEL_GROUP}->{$grp} or
-                         $exifTool->{DEL_GROUP}->{$grp1} or
-                         $exifTool->{DEL_GROUP}->{"MIE$n"};
+    if (%{$$et{DEL_GROUP}}) {
+        $delGroup = 1 if $$et{DEL_GROUP}{MIE} or
+                         $$et{DEL_GROUP}{$grp} or
+                         $$et{DEL_GROUP}{$grp1} or
+                         $$et{DEL_GROUP}{"MIE$n"};
     }
 
     # prepare lookups and lists for writing
-    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
-    my ($addDirs, $editDirs) = $exifTool->GetAddDirHash($tagTablePtr, $dirName);
+    my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
+    my ($addDirs, $editDirs) = $et->GetAddDirHash($tagTablePtr, $dirName);
     my @editTags = sort keys %$newTags, keys %$editDirs;
     $verbose and print $out $raf ? 'Writing' : 'Creating', " $grp1:\n";
@@ -972,5 +981,5 @@
                 $raf->Read($tag, $tagLen) == $tagLen or last;
                 $oldHdr .= $tag;    # add tag to element header
-                $exifTool->Warn("MIE tag '$tag' out of sequence") if $tag lt $lastTag;
+                $et->Warn("MIE tag '${tag}' out of sequence") if $tag lt $lastTag;
                 # separate units from tag name if they exist
                 $units = $1 if $tag =~ s/\((.*)\)$//;
@@ -993,11 +1002,11 @@
             }
             # 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";
                 }
-                ++$exifTool->{CHANGED} if $delGroup;
+                ++$$et{CHANGED} if $delGroup;
                 next;
             }
@@ -1020,5 +1029,5 @@
                 my $subTablePtr = GetTagTable($newInfo->{SubDirectory}->{TagTable});
                 unless ($subTablePtr) {
-                    $exifTool->Warn("No tag table for $newTag $$newInfo{Name}");
+                    $et->Warn("No tag table for $newTag $$newInfo{Name}");
                     next;
                 }
@@ -1030,10 +1039,10 @@
                     # make sure that either both or neither old and new tags are MIE groups
                     if ($isMieGroup xor ($format & 0xf3) == 0x10) {
-                        $exifTool->Warn("Tag '$tag' not expected type");
+                        $et->Warn("Tag '${tag}' not expected type");
                         next;   # don't write our new tag
                     }
                     # uncompress existing directory into $oldVal since we are editing it
                     if ($format & 0x04) {
-                        last unless HasZlib($exifTool, 'edit');
+                        last unless HasZlib($et, 'edit');
                         $raf->Read($oldVal, $valLen) == $valLen or last MieElement;
                         my $stat;
@@ -1080,6 +1089,6 @@
                     $subdirInfo{Parent} = $dirName;
                     # don't compress elements of an already compressed group
-                    $subdirInfo{IsCompressed} = 1;
-                    $msg = WriteMIEGroup($exifTool, \%subdirInfo, $subTablePtr);
+                    $subdirInfo{IsCompressed} = $$dirInfo{IsCompressed} || $compress;
+                    $msg = WriteMIEGroup($et, \%subdirInfo, $subTablePtr);
                     last MieElement if $msg;
                     # message is defined but empty if nothing was written
@@ -1091,4 +1100,8 @@
                         $toWrite = '';
                         next;
+                    } elsif (length($newVal) <= 4) {    # terminator only?
+                        $verbose and print $out "Deleted compressed $grp1 (empty)\n";
+                        next MieElement if $newTag eq $tag; # deleting the directory
+                        next;       # not creating the new directory
                     }
                     $writable = 'undef';
@@ -1104,5 +1117,5 @@
                             DataLen => $valLen,
                             DirName => $$newInfo{Name},
-                            DataPos => $raf->Tell() - $valLen,
+                            DataPos => $$dirInfo{IsCompressed} ? undef : $raf->Tell() - $valLen,
                             DirStart=> 0,
                             DirLen  => $valLen,
@@ -1110,7 +1123,8 @@
                         # write Compact subdirectories if we will compress the data
                         if (($compress or $optCompress or $$dirInfo{IsCompressed}) and
-                            eval 'require Compress::Zlib')
+                            eval { require Compress::Zlib })
                         {
                             $subdirInfo{Compact} = 1;
+                            $subdirInfo{ReadOnly} = 1;  # because XMP is not writable in place
                         }
                     }
@@ -1118,6 +1132,6 @@
                     my $writeProc = $newInfo->{SubDirectory}->{WriteProc};
                     # reset processed lookup to avoid errors in case of multiple EXIF blocks
-                    $exifTool->{PROCESSED} = { };
-                    $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTablePtr, $writeProc);
+                    $$et{PROCESSED} = { };
+                    $newVal = $et->WriteDirectory(\%subdirInfo, $subTablePtr, $writeProc);
                     if (defined $newVal) {
                         if ($newVal eq '') {
@@ -1136,5 +1150,5 @@
                 # get the new tag information
                 $newInfo = $$newTags{$newTag};
-                my $nvHash = $exifTool->GetNewValueHash($newInfo);
+                my $nvHash = $et->GetNewValueHash($newInfo);
                 my @newVals;
 
@@ -1148,7 +1162,8 @@
                     my $isList = $$newInfo{List};
                     if ($isList) {
+                        last if $$nvHash{CreateOnly};
                         $isOverwriting = -1;    # force processing list elements individually
                     } else {
-                        $isOverwriting = Image::ExifTool::IsOverwriting($nvHash);
+                        $isOverwriting = $et->IsOverwriting($nvHash);
                         last unless $isOverwriting;
                     }
@@ -1156,5 +1171,5 @@
                     if ($isOverwriting < 0 or $verbose > 1) {
                         # check to be sure we can uncompress the value if necessary
-                        HasZlib($exifTool, 'edit') or last if $format & 0x04;
+                        HasZlib($et, 'edit') or last if $format & 0x04;
                         # read the old value
                         $raf->Read($oldVal, $valLen) == $valLen or last MieElement;
@@ -1187,10 +1202,10 @@
                                 # keep any list items that we aren't overwriting
                                 foreach $v (@vals) {
-                                    next if Image::ExifTool::IsOverwriting($nvHash, $v);
+                                    next if $et->IsOverwriting($nvHash, $v);
                                     push @newVals, $v;
                                 }
                             } else {
                                 # test to see if we really want to overwrite the value
-                                $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val);
+                                $isOverwriting = $et->IsOverwriting($nvHash, $val);
                             }
                         }
@@ -1203,8 +1218,8 @@
                         if ($verbose > 1) {
                             $val .= "($units)" if defined $units;
-                            $exifTool->VerboseValue("- $grp1:$$newInfo{Name}", $val);
+                            $et->VerboseValue("- $grp1:$$newInfo{Name}", $val);
                         }
                         $deletedTag = $tag;     # remember that we deleted this tag
-                        ++$exifTool->{CHANGED}; # we deleted the old value
+                        ++$$et{CHANGED}; # we deleted the old value
                     } else {
                         if (defined $oldVal) {
@@ -1217,4 +1232,5 @@
                         Write($outfile, $toWrite, $oldHdr, $oldVal) or $err = 1;
                         $toWrite = '';
+                        next MieElement;
                     }
                     unless (@newVals) {
@@ -1226,9 +1242,9 @@
                     # write new value if creating, or if List and list existed, or
                     # if tag was previously deleted
-                    next unless Image::ExifTool::IsCreating($nvHash) or
+                    next unless $$nvHash{IsCreating} or
                         ($newTag eq $lastTag and ($$newInfo{List} or $deletedTag eq $lastTag));
                 }
                 # get the new value to write (undef to delete)
-                push @newVals, Image::ExifTool::GetNewValues($nvHash);
+                push @newVals, $et->GetNewValue($nvHash);
                 next unless @newVals;
                 $writable = $$newInfo{Writable} || $$tagTablePtr{WRITABLE};
@@ -1257,5 +1273,5 @@
                 $newFormat = $mieCode{$writable};
                 unless (defined $newFormat) {
-                    $msg = "Bad format '$writable' for $$newInfo{Name}";
+                    $msg = "Bad format '${writable}' for $$newInfo{Name}";
                     next MieElement;
                 }
@@ -1283,5 +1299,5 @@
                 if ($writable !~ /^(utf|string|undef)/) {
                     my $val3 = WriteValue($$valPt, $writable, $$newInfo{Count});
-                    defined $val3 or $exifTool->Warn("Error writing $newTag"), last;
+                    defined $val3 or $et->Warn("Error writing $newTag"), last;
                     $valPt = \$val3;
                 }
@@ -1289,5 +1305,5 @@
                 # compress value before writing if required
                 if (($compress or $optCompress) and not $$dirInfo{IsCompressed} and
-                    HasZlib($exifTool, 'write'))
+                    HasZlib($et, 'write'))
                 {
                     my $deflate = Compress::Zlib::deflateInit();
@@ -1310,5 +1326,5 @@
                         }
                     } else {
-                        $exifTool->Warn("Error deflating $newTag (written uncompressed)");
+                        $et->Warn("Error deflating $newTag (written uncompressed)");
                     }
                 }
@@ -1324,5 +1340,5 @@
                     $len = 254;
                 } else {
-                    $exifTool->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
                 }
@@ -1333,6 +1349,6 @@
                 # we changed a tag unless just editing a subdirectory
                 unless ($$editDirs{$newTag}) {
-                    $exifTool->VerboseValue("+ $grp1:$$newInfo{Name}", $newVal);
-                    ++$exifTool->{CHANGED};
+                    $et->VerboseValue("+ $grp1:$$newInfo{Name}", $newVal);
+                    ++$$et{CHANGED};
                 }
                 last;   # didn't want to loop anyway
@@ -1368,5 +1384,5 @@
         if ($format == 0x10 or $format == 0x18) {
             my ($subTablePtr, $dirName);
-            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
             if ($tagInfo and $$tagInfo{SubDirectory}) {
                 $dirName = $tagInfo->{SubDirectory}->{DirName};
@@ -1387,5 +1403,5 @@
             my $oldOrder = GetByteOrder();
             SetByteOrder($format & 0x08 ? 'II' : 'MM');
-            $msg = WriteMIEGroup($exifTool, \%subdirInfo, $subTablePtr);
+            $msg = WriteMIEGroup($et, \%subdirInfo, $subTablePtr);
             SetByteOrder($oldOrder);
             last if $msg;
@@ -1425,15 +1441,15 @@
 sub ProcessMIEGroup($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
-    my $notUTF8 = ($exifTool->{OPTIONS}->{Charset} ne 'UTF8');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
+    my $notUTF8 = ($$et{OPTIONS}{Charset} ne 'UTF8');
     my ($msg, $buff, $ok, $oldIndent, $mime);
     my $lastTag = '';
 
-    # get group 1 names: $grp doesn't have numbers (ie. 'MIE-Doc'),
-    # and $grp1 does (ie. 'MIE1-Doc1')
-    my $cnt = $exifTool->{MIE_COUNT};
+    # get group 1 names: $grp doesn't have numbers (eg. 'MIE-Doc'),
+    # and $grp1 does (eg. 'MIE1-Doc1')
+    my $cnt = $$et{MIE_COUNT};
     my $grp1 = $tagTablePtr->{GROUPS}->{1};
     my $n = $$cnt{'MIE-Main'} || 0;
@@ -1447,10 +1463,10 @@
     }
     # set group1 name for all tags extracted from this group
-    $exifTool->{SET_GROUP1} = $grp1;
+    $$et{SET_GROUP1} = $grp1;
 
     if ($verbose) {
-        $oldIndent = $exifTool->{INDENT};
-        $exifTool->{INDENT} .= '| ';
-        $exifTool->VerboseDir($grp1);
+        $oldIndent = $$et{INDENT};
+        $$et{INDENT} .= '| ';
+        $et->VerboseDir($grp1);
     }
     my $wasCompressed = $$dirInfo{WasCompressed};
@@ -1466,5 +1482,5 @@
         if ($tagLen) {
             $raf->Read($tag, $tagLen) == $tagLen or last;
-            $exifTool->Warn("MIE tag '$tag' out of sequence") if $tag lt $lastTag;
+            $et->Warn("MIE tag '${tag}' out of sequence") if $tag lt $lastTag;
             $lastTag = $tag;
             # separate units from tag name if they exist
@@ -1496,5 +1512,5 @@
         my ($tagInfo, $value);
         while ($format != 0x80) {
-            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
             last if $tagInfo;
             # extract tags with locale code
@@ -1502,9 +1518,9 @@
                 if ($tag =~ /^(\w+)-([a-z]{2}_[A-Z]{2})$/) {
                     my ($baseTag, $langCode) = ($1, $2);
-                    $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $baseTag);
+                    $tagInfo = $et->GetTagInfo($tagTablePtr, $baseTag);
                     $tagInfo = GetLangInfo($tagInfo, $langCode) if $tagInfo;
                     last if $tagInfo;
                 } else {
-                    $exifTool->Warn('Invalid MIE tag name');
+                    $et->Warn('Invalid MIE tag name');
                     last;
                 }
@@ -1516,5 +1532,5 @@
                 PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
             };
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
             last;
         }
@@ -1526,12 +1542,12 @@
             if ($format & 0x04) {
                 if ($verbose) {
-                    print $out "$$exifTool{INDENT}\[Tag '$tag' $valLen bytes compressed]\n";
+                    print $out "$$et{INDENT}\[Tag '${tag}' $valLen bytes compressed]\n";
                 }
-                next unless HasZlib($exifTool, 'decode');
+                next unless HasZlib($et, 'decode');
                 my $stat;
                 my $inflate = Compress::Zlib::inflateInit();
                 $inflate and ($value, $stat) = $inflate->inflate($value);
                 unless ($inflate and $stat == Compress::Zlib::Z_STREAM_END()) {
-                    $exifTool->Warn("Error inflating $tag");
+                    $et->Warn("Error inflating $tag");
                     next;
                 }
@@ -1554,5 +1570,5 @@
             if ($verbose) {
                 my $order = ', byte order ' . GetByteOrder();
-                $exifTool->VerboseInfo($tag, $tagInfo, Size => $valLen, Extra => $order);
+                $et->VerboseInfo($tag, $tagInfo, Size => $valLen, Extra => $order);
             }
             my %subdirInfo = (
@@ -1563,19 +1579,20 @@
             );
             # read from uncompressed data instead if necessary
-            $subdirInfo{RAF} = new File::RandomAccess(\$value) if $format & 0x04;
+            $subdirInfo{RAF} = new File::RandomAccess(\$value) if $valLen;
 
             my $oldOrder = GetByteOrder();
             SetByteOrder($format & 0x08 ? 'II' : 'MM');
-            $msg = ProcessMIEGroup($exifTool, \%subdirInfo, $subTablePtr);
+            $msg = ProcessMIEGroup($et, \%subdirInfo, $subTablePtr);
             SetByteOrder($oldOrder);
-            $exifTool->{SET_GROUP1} = $grp1;    # restore this group1 name
+            $$et{SET_GROUP1} = $grp1;    # restore this group1 name
             last if $msg;
         } else {
             # process MIE data format types
             if ($tagInfo) {
+                my $rational;
                 # extract tag value
-                my $val = ReadMIEValue(\$value, 0, $formatStr, undef, $valLen);
+                my $val = ReadMIEValue(\$value, 0, $formatStr, undef, $valLen, \$rational);
                 unless (defined $val) {
-                    $exifTool->Warn("Error reading $tag value");
+                    $et->Warn("Error reading $tag value");
                     $val = '<err>';
                 }
@@ -1588,7 +1605,7 @@
                         $count = $valLen / $s;
                     }
-                    $exifTool->VerboseInfo($lastTag, $tagInfo,
+                    $et->VerboseInfo($lastTag, $tagInfo,
                         DataPt  => \$value,
-                        DataPos => $raf->Tell() - $valLen,
+                        DataPos => $wasCompressed ? undef : $raf->Tell() - $valLen,
                         Size    => $valLen,
                         Format  => $formatStr,
@@ -1610,20 +1627,20 @@
                     # set DataPos and Base for uncompressed information only
                     unless ($wasCompressed) {
-                        $subdirInfo{DataPos} = $raf->Tell() - $valLen;
+                        $subdirInfo{DataPos} = 0; # (relative to Base)
                         $subdirInfo{Base}    = $raf->Tell() - $valLen;
                     }
                     # reset PROCESSED lookup for each MIE directory
                     # (there is no possibility of double-processing a MIE directory)
-                    $exifTool->{PROCESSED} = { };
+                    $$et{PROCESSED} = { };
                     my $processProc = $tagInfo->{SubDirectory}->{ProcessProc};
-                    delete $exifTool->{SET_GROUP1};
-                    delete $exifTool->{NO_LIST};
-                    $exifTool->ProcessDirectory(\%subdirInfo, $subTablePtr, $processProc);
-                    $exifTool->{SET_GROUP1} = $grp1;
-                    $exifTool->{NO_LIST} = 1;
+                    delete $$et{SET_GROUP1};
+                    delete $$et{NO_LIST};
+                    $et->ProcessDirectory(\%subdirInfo, $subTablePtr, $processProc);
+                    $$et{SET_GROUP1} = $grp1;
+                    $$et{NO_LIST} = 1;
                 } else {
                     # convert to specified character set if necessary
                     if ($notUTF8 and $formatStr =~ /^(utf|string)/) {
-                        $val = $exifTool->Decode($val, 'UTF8');
+                        $val = $et->Decode($val, 'UTF8');
                     }
                     if ($formatStr =~ /_list$/) {
@@ -1637,18 +1654,19 @@
                         $val .= "($units)" if defined $units;
                     }
-                    $exifTool->FoundTag($tagInfo, $val);
+                    my $key = $et->FoundTag($tagInfo, $val);
+                    $$et{RATIONAL}{$key} = $rational if defined $rational and defined $key;
                 }
             } else {
                 # skip over unknown information or free bytes
                 $raf->Seek($valLen, 1) or $msg = 'Seek error', last;
-                $verbose and $exifTool->VerboseInfo($tag, undef, Size => $valLen);
+                $verbose and $et->VerboseInfo($tag, undef, Size => $valLen);
             }
         }
     }
     # modify MIME type if necessary
-    $mime and not $$dirInfo{Parent} and $exifTool->ModifyMimeType($mime);
+    $mime and not $$dirInfo{Parent} and $et->ModifyMimeType($mime);
 
     $ok or $msg or $msg = 'Unexpected end of file';
-    $verbose and $exifTool->{INDENT} = $oldIndent;
+    $verbose and $$et{INDENT} = $oldIndent;
     return $msg;
 }
@@ -1661,6 +1679,6 @@
 sub ProcessMIE($$)
 {
-    my ($exifTool, $dirInfo) = @_;
-    return 1 unless defined $exifTool;
+    my ($et, $dirInfo) = @_;
+    return 1 unless defined $et;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
@@ -1699,11 +1717,11 @@
         $$dirInfo{DataPos} = $pos;
         $$dirInfo{DirLen} = $end - $pos;
-        if ($outfile and $exifTool->{DEL_GROUP}->{MIE}) {
+        if ($outfile and $$et{DEL_GROUP}{MIE}) {
             # delete the trailer
-            $exifTool->VPrint(0,"  Deleting MIE trailer\n");
-            ++$exifTool->{CHANGED};
+            $et->VPrint(0,"  Deleting MIE trailer\n");
+            ++$$et{CHANGED};
             return 1;
-        } elsif ($exifTool->Options('Verbose') or $exifTool->{HTML_DUMP}) {
-            $exifTool->DumpTrailer($dirInfo);
+        } elsif ($et->Options('Verbose') or $$et{HTML_DUMP}) {
+            $et->DumpTrailer($dirInfo);
         }
     }
@@ -1716,5 +1734,5 @@
         if ($num == 8) {
             # verify file identifier
-            if ($buff =~ /^~(\x10|\x18)\x04(.)0MIE/) {
+            if ($buff =~ /^~(\x10|\x18)\x04(.)0MIE/s) {
                 SetByteOrder($1 eq "\x10" ? 'MM' : 'II');
                 my $len = ord($2);
@@ -1740,5 +1758,5 @@
             $buff = ''; # start from nothing
             # set byte order according to preferences
-            $exifTool->SetPreferredByteOrder();
+            $et->SetPreferredByteOrder();
             $isCreating = 1;
         }
@@ -1746,7 +1764,7 @@
             last if $$dirInfo{Trailer}; # allow other trailers after MIE
             if ($outfile) {
-                $exifTool->Error($msg);
+                $et->Error($msg);
             } else {
-                $exifTool->Warn($msg);
+                $et->Warn($msg);
             }
             last;
@@ -1755,7 +1773,7 @@
         unless ($numDocs) {
             # this is a valid MIE file (unless a trailer on another file)
-            $exifTool->SetFileType();
-            $exifTool->{NO_LIST} = 1;   # handle lists ourself
-            $exifTool->{MIE_COUNT} = { };
+            $et->SetFileType();
+            $$et{NO_LIST} = 1;   # handle lists ourself
+            $$et{MIE_COUNT} = { };
             undef $hasZlib;
         }
@@ -1784,9 +1802,9 @@
             #  to another type of image, but this is OK because we are done writing
             #  the other format by the time we start writing the trailer)
-            $exifTool->InitWriteDirs(\%mieMap, 'MIE');
+            $et->InitWriteDirs(\%mieMap, 'MIE');
             $subdirInfo{ToWrite} = '~' . MIEGroupFormat(1) . "\x04\xfe0MIE\0\0\0\0";
-            $msg = WriteMIEGroup($exifTool, \%subdirInfo, $tagTablePtr);
+            $msg = WriteMIEGroup($et, \%subdirInfo, $tagTablePtr);
             if ($msg) {
-                $exifTool->Error($msg);
+                $et->Error($msg);
                 $err = 1;
                 last;
@@ -1795,14 +1813,14 @@
             }
         } else {
-            $msg = ProcessMIEGroup($exifTool, \%subdirInfo, $tagTablePtr);
+            $msg = ProcessMIEGroup($et, \%subdirInfo, $tagTablePtr);
             if ($msg) {
-                $exifTool->Warn($msg);
+                $et->Warn($msg);
                 last;
             }
         }
     }
-    delete $exifTool->{NO_LIST};
-    delete $exifTool->{MIE_COUNT};
-    delete $exifTool->{SET_GROUP1};
+    delete $$et{NO_LIST};
+    delete $$et{MIE_COUNT};
+    delete $$et{SET_GROUP1};
     return $err ? -1 : 1;
 }
@@ -1852,5 +1870,5 @@
  12) Relocatable data elements (ie. no fixed offsets).
  13) Binary meta information (+7) with variable byte order (+3).
- 14) Mandatory tags not required (an unecessary complication).
+ 14) Mandatory tags not required (an unnecessary complication).
  15) Append information to end of file without editing.
 
@@ -2059,5 +2077,5 @@
 
 The TagName of a string element may have an 6-character suffix to indicate a
-specific locale. (ie. "Title-en_US", or "Keywords-de_DE").
+specific locale. (eg. "Title-en_US", or "Keywords-de_DE").
 
 =item 3.
@@ -2088,5 +2106,5 @@
 order byte is always the first byte if big-endian, and the eighth byte if
 little-endian.  This means that some swapping is always necessary for these
-values on systems where the byte order differs from the word order (ie. some
+values on systems where the byte order differs from the word order (eg. some
 ARM systems), regardless of the endian-ness of the stored values.
 
@@ -2096,5 +2114,5 @@
 comes first regardless of the byte ordering.  In a signed rational value,
 only the numerator is signed.  The denominator of all rational values is
-unsigned (ie. a signed 64-bit rational of 0x80000000/0x80000000 evaluates to
+unsigned (eg. a signed 64-bit rational of 0x80000000/0x80000000 evaluates to
 -1, not +1).
 
@@ -2102,5 +2120,5 @@
 
 32-bit fixed point values are converted to floating point by treating them
-as an integer and dividing by an appropriate value.  ie)
+as an integer and dividing by an appropriate value.  eg)
 
     16-bit fixed value = 16-bit integer value / 256.0
@@ -2151,5 +2169,5 @@
 upper case.  The underline ("_") is provided to allow separation of two
 acronyms or two numbers, but it shouldn't be used unless necessary.  No
-separation is necessary between an acronym and a word (ie. "ISOSetting").
+separation is necessary between an acronym and a word (eg. "ISOSetting").
 
 All TagNames should start with an uppercase letter.  An exception to this
@@ -2163,5 +2181,5 @@
 following format:  The first character is a dash ('-'), followed by a
 2-character lower case ISO 639-1 language code, then an underline ('_'), and
-ending with a 2-character upper case ISO 3166-1 alpha 2 country code.  (ie.
+ending with a 2-character upper case ISO 3166-1 alpha 2 country code.  (eg.
 "-en_US", "-en_GB", "-de_DE" or "-fr_FR".  Note that "GB", and not "UK" is
 the code for Great Britain, although "UK" should be recognized for
@@ -2174,5 +2192,5 @@
 The units string is stored in brackets at the end of the tag name, and is
 composed of zero or more ASCII characters in the range 0x21 to 0x7d,
-excluding the bracket characters 0x28 and 0x29.  (ie. "Resolution(/cm)" or
+excluding the bracket characters 0x28 and 0x29.  (eg. "Resolution(/cm)" or
 "SpecificHeat(J/kg.K)".)  See L<Image::ExifTool::MIEUnits> for details. Unit
 strings are not localized, and may not be used in combination with localized
@@ -2367,8 +2385,8 @@
 Integer and floating point numbers may be represented in binary or string
 form.  In string form, integers are a series of digits with an optional
-leading sign (ie. "[+|-]DDDDDD"), and multiple values are separated by a
-single space character (ie. "23 128 -32").  Floating point numbers are
+leading sign (eg. "[+|-]DDDDDD"), and multiple values are separated by a
+single space character (eg. "23 128 -32").  Floating point numbers are
 similar but may also contain a decimal point and/or a signed exponent with a
-leading 'e' character (ie. "[+|-]DD[.DDDDDD][e(+|-)EEE]").  The string "inf"
+leading 'e' character (eg. "[+|-]DD[.DDDDDD][e(+|-)EEE]").  The string "inf"
 is used to represent infinity.  One advantage of numerical strings is that
 they can have an arbitrarily high precision because the possible number of
@@ -2418,5 +2436,5 @@
 Historically, a limit of 2GB may be imposed by some systems.  However,
 8-byte data lengths should be supported by all applications provided the
-value doesn't exceed the system limit.  (ie. For systems with a 2GB limit,
+value doesn't exceed the system limit.  (eg. For systems with a 2GB limit,
 8-byte data lengths should be supported if the upper 17 bits are all zero.)
 If a data length above the system limit is encountered, it may be necessary
@@ -2511,5 +2529,5 @@
 =head1 REVISIONS
 
-  2010-04-05 - Fixed ÒFormat SizeÓ Note 7 to give the correct number of bits
+  2010-04-05 - Fixed "Format Size" Note 7 to give the correct number of bits
                in the example rational value
   2007-01-21 - Specified LF character (0x0a) for text newline sequence
@@ -2527,5 +2545,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -2537,5 +2555,5 @@
 =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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIEUnits.pod
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIEUnits.pod	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIEUnits.pod	(revision 34921)
@@ -7,5 +7,5 @@
 
 The MIE format allows units of measurement to be specified in brackets at
-the end of a MIE tag name (ie. "Volume(m3)"). This document describes the
+the end of a MIE tag name (eg. "Volume(m3)"). This document describes the
 standard MIE units abbreviations.
 
@@ -19,11 +19,11 @@
 words may be separated with a hyphen ('-').
 
-Exponents should be positive, and require no separator (ie. "m2" for square
-meters).  L<Prefixes|/PREFIXES> may be added to the standard units (ie.
+Exponents should be positive, and require no separator (eg. "m2" for square
+meters).  L<Prefixes|/PREFIXES> may be added to the standard units (eg.
 "cm") except when the resulting name conflicts with another standard unit.
 
 Multiplication is indicated by '.', and division by '/'.  Reciprocal units
 (ie. the multiplicative inverse) are obtained through division rather than
-the use of negative exponents (ie. "/in", not "in-1").  In MIE units,
+the use of negative exponents (eg. "/in", not "in-1").  In MIE units,
 multiplication has precedence over division, so everything to the right of a
 '/' is in the denominator.  (See L</EXAMPLES> for a few examples.)
@@ -357,5 +357,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIFF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIFF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MIFF.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.05';
+$VERSION = '1.07';
 
 # MIFF chunks
@@ -32,5 +32,5 @@
     class => 'Class',
     colors => 'Colors',
-    colorspace => 'Colorspace',
+    colorspace => 'ColorSpace',
     columns => 'ImageWidth',
     compression => 'Compression',
@@ -104,7 +104,7 @@
 sub ProcessMIFF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->{OPTIONS}->{Verbose};
+    my $verbose = $$et{OPTIONS}{Verbose};
     my ($hdr, $buff);
 
@@ -113,5 +113,5 @@
     return 0 unless $raf->Read($hdr, 14) == 14;
     return 0 unless $hdr eq 'id=ImageMagick';
-    $exifTool->SetFileType();   # set the FileType tag
+    $et->SetFileType();   # set the FileType tag
 
     # set end-of-line character sequence to read to end of the TEXT
@@ -154,13 +154,13 @@
             } else {
                 # something we don't recognize -- stop parsing here
-                $exifTool->Warn('Unrecognized MIFF data');
+                $et->Warn('Unrecognized MIFF data');
                 last;
             }
-            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+            my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
             unless ($tagInfo) {
                 $tagInfo = { Name => $tag };
-                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
-            }
-            $verbose and $exifTool->VerboseInfo($tag, $tagInfo,
+                AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            }
+            $verbose and $et->VerboseInfo($tag, $tagInfo,
                 Table  => $tagTablePtr,
                 DataPt => \$val,
@@ -170,5 +170,5 @@
                 push @profiles, [$1, $val];
             } else {
-                $exifTool->FoundTag($tagInfo, $val);
+                $et->FoundTag($tagInfo, $val);
             }
         }
@@ -179,9 +179,9 @@
         my ($type, $len) = @{$_};
         unless ($len =~ /^\d+$/) {
-            $exifTool->Warn("Invalid length for $type profile");
+            $et->Warn("Invalid length for $type profile");
             last;   # don't try to read the rest
         }
         unless ($raf->Read($buff, $len) == $len) {
-            $exifTool->Warn("Error reading $type profile ($len bytes)");
+            $et->Warn("Error reading $type profile ($len bytes)");
             next;
         }
@@ -198,10 +198,10 @@
             # ICC Profile information
             my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
-            $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         } elsif ($type eq 'iptc') {
             if ($buff =~ /^8BIM/) {
                 # Photoshop information
                 my $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Main');
-                $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
             }
         # I haven't seen 'exif' or 'xmp' profile types yet, but I have seen them
@@ -216,5 +216,5 @@
                 # (this may be wrong, but I can't see where the PNG stores this information)
                 $dirInfo{Base} = 12; # this is the usual value
-                $processed = $exifTool->ProcessTIFF(\%dirInfo);
+                $processed = $et->ProcessTIFF(\%dirInfo);
             } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) {
                 # APP1 XMP
@@ -223,12 +223,12 @@
                 $dirInfo{DirStart} += $hdrLen;
                 $dirInfo{DirLen} -= $hdrLen;
-                $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+                $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
             }
         }
         unless ($processed) {
-            $exifTool->Warn("Unknown MIFF $type profile data");
+            $et->Warn("Unknown MIFF $type profile data");
             if ($verbose) {
-                $exifTool->VerboseDir($type, 0, $len);
-                $exifTool->VerboseDump(\$buff);
+                $et->VerboseDir($type, 0, $len);
+                $et->VerboseDump(\$buff);
             }
          }
@@ -256,5 +256,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MNG.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MNG.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MNG.pm	(revision 34921)
@@ -662,5 +662,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MOI.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MOI.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MOI.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPC.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPC.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPC.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool::FLAC;
 
-$VERSION = '1.00';
+$VERSION = '1.01';
 
 # MPC metadata blocks
@@ -79,10 +79,10 @@
 sub ProcessMPC($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
 
     # must first check for leading ID3 information
-    unless ($exifTool->{DoneID3}) {
+    unless ($$et{DoneID3}) {
         require Image::ExifTool::ID3;
-        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
+        Image::ExifTool::ID3::ProcessID3($et, $dirInfo) and return 1;
     }
     my $raf = $$dirInfo{RAF};
@@ -92,5 +92,5 @@
     $raf->Read($buff, 32) == 32 and $buff =~ /^MP\+(.)/s or return 0;
     my $vers = ord($1) & 0x0f;
-    $exifTool->SetFileType();
+    $et->SetFileType();
 
     # extract audio information (currently only from version 7 MPC files)
@@ -98,18 +98,18 @@
         SetByteOrder('II');
         my $pos = $raf->Tell() - 32;
-        if ($exifTool->Options('Verbose')) {
-            $exifTool->VPrint(0, "MPC Header (32 bytes):\n");
-            $exifTool->VerboseDump(\$buff, DataPos => $pos);
+        if ($et->Options('Verbose')) {
+            $et->VPrint(0, "MPC Header (32 bytes):\n");
+            $et->VerboseDump(\$buff, DataPos => $pos);
         }
         my $tagTablePtr = GetTagTable('Image::ExifTool::MPC::Main');
         my %dirInfo = ( DataPt => \$buff, DataPos => $pos );
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
     } else {
-        $exifTool->Warn('Audio info not currently extracted from this version MPC file');
+        $et->Warn('Audio info currently not extracted from this version MPC file');
     }
 
     # process APE trailer if it exists
     require Image::ExifTool::APE;
-    Image::ExifTool::APE::ProcessAPE($exifTool, $dirInfo);
+    Image::ExifTool::APE::ProcessAPE($et, $dirInfo);
 
     return 1;
@@ -135,5 +135,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPEG.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPEG.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPEG.pm	(revision 34921)
@@ -19,5 +19,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.13';
+$VERSION = '1.16';
 
 %Image::ExifTool::MPEG::Audio = (
@@ -370,5 +370,4 @@
         Name => 'LameStereoMode',
         Mask => 0x1c,
-        ValueConv => '$val >> 2',
         PrintConv => {
             0 => 'Mono',
@@ -442,5 +441,5 @@
 sub ProcessFrameHeader($$@)
 {
-    my ($exifTool, $tagTablePtr, @data) = @_;
+    my ($et, $tagTablePtr, @data) = @_;
     my $tag;
     foreach $tag (sort keys %$tagTablePtr) {
@@ -454,5 +453,5 @@
         }
         my $val = ($word >> (31 + 32*$index - $b2)) & $mask;
-        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+        $et->HandleTag($tagTablePtr, $tag, $val);
     }
 }
@@ -461,10 +460,11 @@
 # Read MPEG audio frame header
 # Inputs: 0) ExifTool object reference, 1) Reference to audio data
+#         2) flag set if we are trying to recognized MP3 file only
 # Returns: 1 on success, 0 if no audio header was found
-sub ParseMPEGAudio($$)
+sub ParseMPEGAudio($$;$)
 {
-    my ($exifTool, $buffPt) = @_;
+    my ($et, $buffPt, $mp3) = @_;
     my ($word, $pos);
-    my $ext = $$exifTool{FILE_EXT} || '';
+    my $ext = $$et{FILE_EXT} || '';
 
     for (;;) {
@@ -482,5 +482,6 @@
             ($word & 0x00f000) == 0x00f000 or   # 1111 is a bad bitrate index
             ($word & 0x000c00) == 0x000c00 or   # 11 is a reserved sampling frequency
-            ($word & 0x000003) == 0x000002)     # 10 is a reserved emphasis
+            ($word & 0x000003) == 0x000002 or   # 10 is a reserved emphasis
+            (($mp3 and ($word & 0x060000) != 0x020000))) # must be layer 3 for MP3
         {
             # give up easily unless this really should be an MP3 file
@@ -493,11 +494,11 @@
     }
     # set file type if not done already
-    $exifTool->SetFileType();
+    $et->SetFileType();
 
     my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Audio');
-    ProcessFrameHeader($exifTool, $tagTablePtr, $word);
+    ProcessFrameHeader($et, $tagTablePtr, $word);
 
     # extract the VBR information (ref MP3::Info)
-    my ($v, $m) = ($$exifTool{MPEG_Vers}, $$exifTool{MPEG_Mode});
+    my ($v, $m) = ($$et{MPEG_Vers}, $$et{MPEG_Mode});
     while (defined $v and defined $m) {
         my $len = length $$buffPt;
@@ -513,10 +514,10 @@
         if ($flags & 0x01) {    # VBRFrames
             last if $pos + 4 > $len;
-            $exifTool->HandleTag($xingTable, 1, unpack("x${pos}N", $$buffPt)) if $isVBR;
+            $et->HandleTag($xingTable, 1, unpack("x${pos}N", $$buffPt)) if $isVBR;
             $pos += 4;
         }
         if ($flags & 0x02) {    # VBRBytes
             last if $pos + 4 > $len;
-            $exifTool->HandleTag($xingTable, 2, unpack("x${pos}N", $$buffPt)) if $isVBR;
+            $et->HandleTag($xingTable, 2, unpack("x${pos}N", $$buffPt)) if $isVBR;
             $pos += 4;
         }
@@ -529,5 +530,5 @@
             last if $pos + 4 > $len;
             $vbrScale = unpack("x${pos}N", $$buffPt);
-            $exifTool->HandleTag($xingTable, 3, $vbrScale) if $isVBR;
+            $et->HandleTag($xingTable, 3, $vbrScale) if $isVBR;
             $pos += 4;
         }
@@ -551,5 +552,5 @@
                     last;
                 }
-                $exifTool->HandleTag($xingTable, 4, $lib);
+                $et->HandleTag($xingTable, 4, $lib);
                 last;
             }
@@ -559,8 +560,8 @@
         my $enc = substr($$buffPt, $pos, 9);
         if ($enc ge 'LAME3.90') {
-            $exifTool->HandleTag($xingTable, 4, $enc);
+            $et->HandleTag($xingTable, 4, $enc);
             if ($vbrScale <= 100) {
-                $exifTool->HandleTag($xingTable, 5, int((100 - $vbrScale) / 10));
-                $exifTool->HandleTag($xingTable, 6, (100 - $vbrScale) % 10);
+                $et->HandleTag($xingTable, 5, int((100 - $vbrScale) / 10));
+                $et->HandleTag($xingTable, 6, (100 - $vbrScale) % 10);
             }
             my %dirInfo = (
@@ -570,10 +571,10 @@
             );
             my $subTablePtr = GetTagTable('Image::ExifTool::MPEG::Lame');
-            $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $subTablePtr);
         } else {
-            $exifTool->HandleTag($xingTable, 4, substr($$buffPt, $pos, 20));
+            $et->HandleTag($xingTable, 4, substr($$buffPt, $pos, 20));
         }
         last;   # (didn't want to loop anyway)
-	}
+    }
 
     return 1;
@@ -586,5 +587,5 @@
 sub ProcessMPEGVideo($$)
 {
-    my ($exifTool, $buffPt) = @_;
+    my ($et, $buffPt) = @_;
 
     return 0 unless length $$buffPt >= 4;
@@ -599,8 +600,8 @@
     }
     # set file type if not done already
-    $exifTool->SetFileType('MPEG') unless $exifTool->{VALUE}->{FileType};
+    $et->SetFileType('MPEG') unless $$et{VALUE}{FileType};
 
     my $tagTablePtr = GetTagTable('Image::ExifTool::MPEG::Video');
-    ProcessFrameHeader($exifTool, $tagTablePtr, $w1, $w2);
+    ProcessFrameHeader($et, $tagTablePtr, $w1, $w2);
     return 1;
 }
@@ -626,20 +627,20 @@
 sub ParseMPEGAudioVideo($$)
 {
-    my ($exifTool, $buffPt) = @_;
+    my ($et, $buffPt) = @_;
     my (%found, $didHdr);
     my $rtnVal = 0;
     my %proc = ( audio => \&ParseMPEGAudio, video => \&ProcessMPEGVideo );
 
-    delete $exifTool->{AudioBitrate};
-    delete $exifTool->{VideoBitrate};
+    delete $$et{AudioBitrate};
+    delete $$et{VideoBitrate};
 
     while ($$buffPt =~ /\0\0\x01(\xb3|\xc0)/g) {
         my $type = $1 eq "\xb3" ? 'video' : 'audio';
         unless ($didHdr) {
-            # make sure we didn't miss an audio frame sync before this (ie. MP3 file)
+            # make sure we didn't miss an audio frame sync before this (eg. MP3 file)
             # (the last byte of the 4-byte MP3 audio frame header word may be zero,
             # but the 2nd last must be non-zero, so we need only check to pos-3)
             my $buff = substr($$buffPt, 0, pos($$buffPt) - 3);
-            $found{audio} = 1 if ParseMPEGAudio($exifTool, \$buff);
+            $found{audio} = 1 if ParseMPEGAudio($et, \$buff);
             $didHdr = 1;
         }
@@ -650,5 +651,5 @@
         my $dat = substr($$buffPt, pos($$buffPt), $len);
         # process MPEG audio or video
-        if (&{$proc{$type}}($exifTool, \$dat)) {
+        if (&{$proc{$type}}($et, \$dat)) {
             $rtnVal = 1;
             $found{$type} = 1;
@@ -666,5 +667,5 @@
 sub ProcessMPEG($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -672,10 +673,10 @@
     $raf->Read($buff, 4) == 4 or return 0;
     return 0 unless $buff =~ /^\0\0\x01[\xb0-\xbf]/;
-    $exifTool->SetFileType();
+    $et->SetFileType();
 
     $raf->Seek(0,0);
     $raf->Read($buff, 65536*4) or return 0;
 
-    return ParseMPEGAudioVideo($exifTool, \$buff);
+    return ParseMPEGAudioVideo($et, \$buff);
 }
 
@@ -704,5 +705,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MPF.pm	(revision 34921)
@@ -6,5 +6,5 @@
 # Revisions:    06/12/2009 - P. Harvey Created
 #
-# References:   1) http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-007_E.pdf
+# References:   1) http://www.cipa.jp/std/documents/e/DC-007_E.pdf
 #------------------------------------------------------------------------------
 
@@ -16,16 +16,19 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.05';
+$VERSION = '1.14';
 
 sub ProcessMPImageList($$$);
 
-# Tags found in MPF APP2 segment in JPEG images
+# Tags found in APP2 MPF segment in JPEG images
 %Image::ExifTool::MPF::Main = (
     GROUPS => { 0 => 'MPF', 1 => 'MPF0', 2 => 'Image'},
     NOTES => q{
         These tags are part of the CIPA Multi-Picture Format specification, and are
-        found in the APP2 "MPF" segment of JPEG images.  See
-        L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-007_E.pdf> for the
-        official specification.
+        found in the APP2 "MPF" segment of JPEG images.  MPImage data referenced
+        from this segment is stored as a JPEG trailer.  The MPF tags are not
+        writable, however the MPF segment may be deleted as a group (with "MPF:All")
+        but then the JPEG trailer should also be deleted (with "Trailer:All").  See
+        L<https://web.archive.org/web/20190713230858/http://www.cipa.jp/std/documents/e/DC-007_E.pdf>
+        for the official specification.
     },
     0xb000 => 'MPFVersion',
@@ -70,5 +73,5 @@
             },
         ],
-    },          
+    },
     0xb202 => 'PanOverlapH',
     0xb203 => 'PanOverlapV',
@@ -95,5 +98,5 @@
         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.
     },
@@ -103,7 +106,7 @@
         Mask => 0xf8000000,
         PrintConv => { BITMASK => {
-            29 => 'Representative image',
-            30 => 'Dependent child image',
-            31 => 'Dependent parent image',
+            2 => 'Representative image',
+            3 => 'Dependent child image',
+            4 => 'Dependent parent image',
         }},
     },
@@ -152,5 +155,5 @@
 # extract MP Images as composite tags
 %Image::ExifTool::MPF::Composite = (
-    GROUPS => { 2 => 'Image' },
+    GROUPS => { 2 => 'Preview' },
     MPImage => {
         Require => {
@@ -161,5 +164,5 @@
         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.
         },
@@ -167,4 +170,5 @@
         RawConv => q{
             require Image::ExifTool::MPF;
+            @grps = $self->GetGroup($$val{0});  # set groups from input tag
             Image::ExifTool::MPF::ExtractMPImages($self);
         },
@@ -181,16 +185,16 @@
 sub ExtractMPImages($)
 {
-    my $exifTool = shift;
-    my $ee = $exifTool->Options('ExtractEmbedded');
-    my $saveBinary = $exifTool->Options('Binary');
+    my $et = shift;
+    my $ee = $et->Options('ExtractEmbedded');
+    my $saveBinary = $et->Options('Binary');
     my ($i, $didPreview, $xtra);
 
     for ($i=1; $xtra or not defined $xtra; ++$i) {
         # run through MP images in the same order they were extracted
-        $xtra = defined $$exifTool{VALUE}{"MPImageStart ($i)"} ? " ($i)" : '';
-        my $off = $exifTool->GetValue("MPImageStart$xtra");
-        my $len = $exifTool->GetValue("MPImageLength$xtra");
+        $xtra = defined $$et{VALUE}{"MPImageStart ($i)"} ? " ($i)" : '';
+        my $off = $et->GetValue("MPImageStart$xtra", 'ValueConv');
+        my $len = $et->GetValue("MPImageLength$xtra", 'ValueConv');
         if ($off and $len) {
-            my $type = $exifTool->GetValue("MPImageType$xtra", 'ValueConv');
+            my $type = $et->GetValue("MPImageType$xtra", 'ValueConv');
             my $tag = "MPImage$i";
             # store first "Large Thumbnail" as a PreviewImage
@@ -199,25 +203,23 @@
                 $didPreview = 1;
             }
-            $exifTool->Options('Binary', 1) if $ee;
-            my $val = Image::ExifTool::Exif::ExtractImage($exifTool, $off, $len, $tag);
-            $exifTool->Options('Binary', $saveBinary) if $ee;
+            $et->Options('Binary', 1) if $ee;
+            my $val = Image::ExifTool::Exif::ExtractImage($et, $off, $len, $tag);
+            $et->Options('Binary', $saveBinary) if $ee;
             next unless defined $val;
             unless ($Image::ExifTool::Extra{$tag}) {
-                Image::ExifTool::AddTagToTable(\%Image::ExifTool::Extra, $tag, {
+                AddTagToTable(\%Image::ExifTool::Extra, $tag, {
                     Name => $tag,
-                    Groups => { 0 => 'Composite', 1 => 'Composite', 2 => 'Image'},
+                    Groups => { 0 => 'Composite', 1 => 'Composite', 2 => 'Preview'},
                 });
             }
-            my $key = $exifTool->FoundTag($tag, $val);
-            # set groups for PreviewImage
-            if ($tag eq 'PreviewImage') {
-                $exifTool->SetGroup($key, 'Composite', 0);
-                $exifTool->SetGroup($key, 'Composite');
-            }
+            my $key = $et->FoundTag($tag, $val, $et->GetGroup("MPImageStart$xtra"));
             # extract information from MP images if ExtractEmbedded option used
             if ($ee) {
-                $$exifTool{DOC_NUM} = $i;
-                $exifTool->ExtractInfo($val, { ReEntry => 1 });
-                delete $$exifTool{DOC_NUM};
+                my $oldBase = $$et{BASE};
+                $$et{BASE} = $off;
+                $$et{DOC_NUM} = $i;
+                $et->ExtractInfo($val, { ReEntry => 1 });
+                delete $$et{DOC_NUM};
+                $$et{BASE} = $oldBase;
             }
         }
@@ -232,15 +234,15 @@
 sub ProcessMPImageList($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $num = int($$dirInfo{DirLen} / 16); # (16 bytes per MP Entry)
     $$dirInfo{DirLen} = 16;
     my ($i, $success);
-    my $oldG1 = $$exifTool{SET_GROUP1};
+    my $oldG1 = $$et{SET_GROUP1};
     for ($i=0; $i<$num; ++$i) {
-        $$exifTool{SET_GROUP1} = '+' . ($i + 1);
-        $success = $exifTool->ProcessBinaryData($dirInfo, $tagTablePtr);
+        $$et{SET_GROUP1} = '+' . ($i + 1);
+        $success = $et->ProcessBinaryData($dirInfo, $tagTablePtr);
         $$dirInfo{DirStart} += 16;
     }
-    $$exifTool{SET_GROUP1} = $oldG1;
+    $$et{SET_GROUP1} = $oldG1;
     return $success;
 }
@@ -265,5 +267,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -274,5 +276,5 @@
 =over 4
 
-=item L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-007_E.pdf>
+=item L<http://www.cipa.jp/std/documents/e/DC-007_E.pdf>
 
 =back
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MWG.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MWG.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MWG.pm	(revision 34921)
@@ -15,10 +15,7 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
-
-$VERSION = '1.08';
-
-# enable MWG strict mode by default
-# (causes non-standard EXIF, IPTC and XMP to be ignored)
-$Image::ExifTool::MWG::strict = 1 unless defined $Image::ExifTool::MWG::strict;
+use Image::ExifTool::XMP;
+
+$VERSION = '1.24';
 
 sub RecoverTruncatedIPTC($$$);
@@ -27,22 +24,18 @@
 sub OverwriteStringList($$$$);
 
+my $mwgLoaded;  # flag set if we alreaded Load()ed the MWG tags
+
 # MWG Composite tags
 %Image::ExifTool::MWG::Composite = (
     GROUPS => { 0 => 'Composite', 1 => 'MWG', 2 => 'Image' },
     VARS => { NO_ID => 1 },
+    WRITE_PROC => \&Image::ExifTool::DummyWriteProc,
     NOTES => q{
-        The Metadata Working Group (MWG) recommendations provide a set of rules to
-        allow certain overlapping EXIF, IPTC and XMP tags to be reconciled when
-        reading, and synchronized when writing.  The ExifTool MWG module is designed
-        to aid in the implementation of these recommendations.  (See
-        L<http://www.metadataworkinggroup.org/> for the complete MWG technical
-        specifications.)
-
         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
-        when the MWG module is loaded.  The MWG module is loaded automatically by
-        the exiftool application if MWG is specified as a group for any tag on the
-        command line, or manually with the C<-use MWG> option.  Via the API, the MWG
-        module is loaded with "C<use Image::ExifTool::MWG>".
+        when explicitly loaded, but this is done automatically by the exiftool
+        application if MWG is specified as a group for any tag on the command line,
+        or manually with the C<-use MWG> option.  Via the API, the MWG Composite
+        tags are loaded by calling "C<Image::ExifTool::MWG::Load()>".
 
         When reading, the value of each MWG tag is B<Derived From> the specified
@@ -59,10 +52,16 @@
         tag is generated when non-standard metadata is encountered.  This feature
         may be disabled by setting C<$Image::ExifTool::MWG::strict = 0> in the
-        ExifTool config file (or from your Perl script when using the API).  Note
+        L<ExifTool config file|../config.html> (or from your Perl script when using the API).  Note
         that the behaviour when writing is not changed:  ExifTool always creates new
         records only in the standard location, but writes new tags to any
         EXIF/IPTC/XMP records that exist.
 
-        A complication of the specification is that although the MWG:Creator
+        Contrary to the EXIF specification, the MWG recommends that EXIF "ASCII"
+        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
+        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
         (EXIF:Artist) is only a simple string.  To resolve this discrepancy the MWG
@@ -80,5 +79,5 @@
             3 => 'IPTCDigest',
         },
-        ValueConv => q{
+        RawConv => q{
             return $val[1] if not defined $val[2] or (defined $val[1] and
                              (not defined $val[3] or $val[2] eq $val[3]));
@@ -88,5 +87,5 @@
         WriteCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)',
         WriteAlso  => {
-            # only write Keywords if IPTC exists (ie. set EditGroup option)
+            # only write Keywords if IPTC exists (eg. set EditGroup option)
             'IPTC:Keywords'  => '$opts{EditGroup} = 1; $val',
             'XMP-dc:Subject' => '$val',
@@ -102,5 +101,5 @@
             4 => 'IPTCDigest',
         },
-        ValueConv => q{
+        RawConv => q{
             return $val[0] if defined $val[0] and $val[0] !~ /^ *$/;
             return $val[2] if not defined $val[3] or (defined $val[2] and
@@ -119,9 +118,10 @@
         Description => 'Date/Time Original',
         Groups => { 2 => 'Time' },
-        Notes => '"creation date of the intellectual content being shown" - MWG',
-        Writable => 1,
-        Desire => {
-            0 => 'EXIF:DateTimeOriginal',
-            1 => 'EXIF:SubSecTimeOriginal',
+        Notes => '"specifies when a photo was taken" - MWG',
+        Writable => 1,
+        Shift => 0, # don't shift this tag
+        Desire => {
+            0 => 'Composite:SubSecDateTimeOriginal',
+            1 => 'EXIF:DateTimeOriginal',
             2 => 'IPTC:DateCreated',
             3 => 'IPTC:TimeCreated',
@@ -130,8 +130,14 @@
             6 => 'IPTCDigest',
         },
+        # must check for validity in RawConv to avoid hiding a same-named tag,
+        # but IPTC dates use a ValueConv so we need to derive the value there
+        RawConv => q{
+            (defined $val[0] or defined $val[1] or $val[2] or
+            (defined $val[4] and (not defined $val[5] or not defined $val[6]
+            or $val[5] eq $val[6]))) ? $val : undef
+        },
         ValueConv => q{
-            if (defined $val[0] and $val[0] !~ /^[: ]*$/) {
-                return ($val[1] and $val[1] !~ /^ *$/) ? "$val[0].$val[1]" : $val[0];
-            }
+            return $val[0] if defined $val[0] and $val[0] !~ /^[: ]*$/;
+            return $val[1] if defined $val[1] and $val[1] !~ /^[: ]*$/;
             return $val[4] if not defined $val[5] or (defined $val[4] and
                              (not defined $val[6] or $val[5] eq $val[6]));
@@ -146,18 +152,18 @@
             # set EXIF date/time values according to PrintConv option instead
             # of defaulting to Type=ValueConv to allow reformatting to be applied
-            'EXIF:DateTimeOriginal'     => 'delete $opts{Type}; $val',
-            'EXIF:SubSecTimeOriginal'   => 'delete $opts{Type}; $val',
-            'IPTC:DateCreated'          => '$opts{EditGroup} = 1; $val',
-            'IPTC:TimeCreated'          => '$opts{EditGroup} = 1; $val',
-            'XMP-photoshop:DateCreated' => '$val',
+            'Composite:SubSecDateTimeOriginal'  => 'delete $opts{Type}; $val',
+            'IPTC:DateCreated'                  => '$opts{EditGroup} = 1; $val',
+            'IPTC:TimeCreated'                  => '$opts{EditGroup} = 1; $val',
+            'XMP-photoshop:DateCreated'         => '$val',
         },
     },
     CreateDate => {
         Groups => { 2 => 'Time' },
-        Notes => '"creation date of the digital representation" - MWG',
-        Writable => 1,
-        Desire => {
-            0 => 'EXIF:CreateDate',
-            1 => 'EXIF:SubSecTimeDigitized',
+        Notes => '"specifies when an image was digitized" - MWG',
+        Writable => 1,
+        Shift => 0, # don't shift this tag
+        Desire => {
+            0 => 'Composite:SubSecCreateDate',
+            1 => 'EXIF:CreateDate',
             2 => 'IPTC:DigitalCreationDate',
             3 => 'IPTC:DigitalCreationTime',
@@ -166,8 +172,12 @@
             6 => 'IPTCDigest',
         },
+        RawConv => q{
+            (defined $val[0] or defined $val[1] or $val[2] or
+            (defined $val[4] and (not defined $val[5] or not defined $val[6]
+            or $val[5] eq $val[6]))) ? $val : undef
+        },
         ValueConv => q{
-            if (defined $val[0] and $val[0] !~ /^[: ]*$/) {
-                return ($val[1] and $val[1] !~ /^ *$/) ? "$val[0].$val[1]" : $val[0];
-            }
+            return $val[0] if defined $val[0] and $val[0] !~ /^[: ]*$/;
+            return $val[1] if defined $val[1] and $val[1] !~ /^[: ]*$/;
             return $val[4] if not defined $val[5] or (defined $val[4] and
                              (not defined $val[6] or $val[5] eq $val[6]));
@@ -180,26 +190,25 @@
         WriteCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)',
         WriteAlso  => {
-            'EXIF:CreateDate'          => 'delete $opts{Type}; $val',
-            'EXIF:SubSecTimeDigitized' => 'delete $opts{Type}; $val',
-            'IPTC:DigitalCreationDate' => '$opts{EditGroup} = 1; $val',
-            'IPTC:DigitalCreationTime' => '$opts{EditGroup} = 1; $val',
-            'XMP-xmp:CreateDate'       => '$val',
+            'Composite:SubSecCreateDate' => 'delete $opts{Type}; $val',
+            'IPTC:DigitalCreationDate'   => '$opts{EditGroup} = 1; $val',
+            'IPTC:DigitalCreationTime'   => '$opts{EditGroup} = 1; $val',
+            'XMP-xmp:CreateDate'         => '$val',
         },
     },
     ModifyDate => {
         Groups => { 2 => 'Time' },
-        Notes => '"modification date of the digital image file" - MWG',
-        Writable => 1,
-        Desire => {
-            0 => 'EXIF:ModifyDate',
-            1 => 'EXIF:SubSecTime',
+        Notes => '"specifies when a file was modified by the user" - MWG',
+        Writable => 1,
+        Shift => 0, # don't shift this tag
+        Desire => {
+            0 => 'Composite:SubSecModifyDate',
+            1 => 'EXIF:ModifyDate',
             2 => 'XMP-xmp:ModifyDate',
             3 => 'CurrentIPTCDigest',
             4 => 'IPTCDigest',
         },
-        ValueConv => q{
-            if (defined $val[0] and $val[0] !~ /^[: ]*$/) {
-                return ($val[1] and $val[1] !~ /^ *$/) ? "$val[0].$val[1]" : $val[0];
-            }
+        RawConv => q{
+            return $val[0] if defined $val[0] and $val[0] !~ /^[: ]*$/;
+            return $val[1] if defined $val[1] and $val[1] !~ /^[: ]*$/;
             return $val[2] if not defined $val[3] or not defined $val[4] or $val[3] eq $val[4];
             return undef;
@@ -212,7 +221,6 @@
         WriteCheck => '""',
         WriteAlso  => {
-            'EXIF:ModifyDate'    => 'delete $opts{Type}; $val',
-            'EXIF:SubSecTime'    => 'delete $opts{Type}; $val',
-            'XMP-xmp:ModifyDate' => '$val',
+            'Composite:SubSecModifyDate' => 'delete $opts{Type}; $val',
+            'XMP-xmp:ModifyDate'         => '$val',
         },
     },
@@ -248,5 +256,5 @@
             4 => 'IPTCDigest',
         },
-        ValueConv => q{
+        RawConv => q{
             return $val[0] if defined $val[0] and $val[0] !~ /^ *$/;
             return $val[2] if not defined $val[3] or (defined $val[2] and
@@ -257,5 +265,14 @@
         WriteCheck => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)',
         WriteAlso  => {
-            'EXIF:Copyright'       => '$val',
+            'EXIF:Copyright' => q{
+                # encode if necessary (not automatic because Format is 'undef')
+                my $enc = $self->Options('CharsetEXIF');
+                if ($enc) {
+                    my $v = $val;
+                    $self->Encode($v,$enc);
+                    return $v;
+                }
+                return $val;
+            },
             'IPTC:CopyrightNotice' => '$opts{EditGroup} = 1; $val',
             'XMP-dc:Rights'        => '$val',
@@ -272,5 +289,5 @@
             4 => 'IPTCDigest',
         },
-        ValueConv => q{
+        RawConv => q{
             return $val[0] if defined $val[0] and $val[0] !~ /^ *$/;
             return $val[2] if not defined $val[3] or (defined $val[2] and
@@ -292,11 +309,13 @@
             0 => 'IPTC:Country-PrimaryLocationName', # (64-character limit)
             1 => 'XMP-photoshop:Country',
-            2 => 'CurrentIPTCDigest',
-            3 => 'IPTCDigest',
-        },
-        ValueConv => q{
-            return $val[1] if not defined $val[2] or (defined $val[1] and
-                             (not defined $val[3] or $val[2] eq $val[3]));
-            return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $val[1], 64);
+            2 => 'XMP-iptcExt:LocationShownCountryName',
+            3 => 'CurrentIPTCDigest',
+            4 => 'IPTCDigest',
+        },
+        RawConv => q{
+            my $xmpVal = $val[2] || $val[1];
+            return $xmpVal if not defined $val[3] or (defined $xmpVal and
+                             (not defined $val[4] or $val[3] eq $val[4]));
+            return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $xmpVal, 64);
         },
         DelCheck   => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)',
@@ -304,5 +323,6 @@
         WriteAlso  => {
             'IPTC:Country-PrimaryLocationName' => '$opts{EditGroup} = 1; $val',
-            'XMP-photoshop:Country'            => '$val',
+            'XMP-photoshop:Country'            => '$val', # (legacy)
+            'XMP-iptcExt:LocationShownCountryName' => '$val',
         },
     },
@@ -313,11 +333,13 @@
             0 => 'IPTC:Province-State', # (32-character limit)
             1 => 'XMP-photoshop:State',
-            2 => 'CurrentIPTCDigest',
-            3 => 'IPTCDigest',
-        },
-        ValueConv => q{
-            return $val[1] if not defined $val[2] or (defined $val[1] and
-                             (not defined $val[3] or $val[2] eq $val[3]));
-            return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $val[1], 32);
+            2 => 'XMP-iptcExt:LocationShownProvinceState',
+            3 => 'CurrentIPTCDigest',
+            4 => 'IPTCDigest',
+        },
+        RawConv => q{
+            my $xmpVal = $val[2] || $val[1];
+            return $xmpVal if not defined $val[3] or (defined $xmpVal and
+                             (not defined $val[4] or $val[3] eq $val[4]));
+            return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $xmpVal, 32);
         },
         DelCheck   => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)',
@@ -325,5 +347,6 @@
         WriteAlso  => {
             'IPTC:Province-State' => '$opts{EditGroup} = 1; $val',
-            'XMP-photoshop:State' => '$val',
+            'XMP-photoshop:State' => '$val', # (legacy)
+            'XMP-iptcExt:LocationShownProvinceState' => '$val',
         },
     },
@@ -334,11 +357,13 @@
             0 => 'IPTC:City', # (32-character limit)
             1 => 'XMP-photoshop:City',
-            2 => 'CurrentIPTCDigest',
-            3 => 'IPTCDigest',
-        },
-        ValueConv => q{
-            return $val[1] if not defined $val[2] or (defined $val[1] and
-                             (not defined $val[3] or $val[2] eq $val[3]));
-            return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $val[1], 32);
+            2 => 'XMP-iptcExt:LocationShownCity',
+            3 => 'CurrentIPTCDigest',
+            4 => 'IPTCDigest',
+        },
+        RawConv => q{
+            my $xmpVal = $val[2] || $val[1];
+            return $xmpVal if not defined $val[3] or (defined $xmpVal and
+                             (not defined $val[4] or $val[3] eq $val[4]));
+            return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $xmpVal, 32);
         },
         DelCheck   => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)',
@@ -346,5 +371,6 @@
         WriteAlso  => {
             'IPTC:City'          => '$opts{EditGroup} = 1; $val',
-            'XMP-photoshop:City' => '$val',
+            'XMP-photoshop:City' => '$val', # (legacy)
+            'XMP-iptcExt:LocationShownCity' => '$val',
         },
     },
@@ -355,11 +381,13 @@
             0 => 'IPTC:Sub-location', # (32-character limit)
             1 => 'XMP-iptcCore:Location',
-            2 => 'CurrentIPTCDigest',
-            3 => 'IPTCDigest',
-        },
-        ValueConv => q{
-            return $val[1] if not defined $val[2] or (defined $val[1] and
-                             (not defined $val[3] or $val[2] eq $val[3]));
-            return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $val[1], 32);
+            2 => 'XMP-iptcExt:LocationShownSublocation',
+            3 => 'CurrentIPTCDigest',
+            4 => 'IPTCDigest',
+        },
+        RawConv => q{
+            my $xmpVal = $val[2] || $val[1];
+            return $xmpVal if not defined $val[3] or (defined $xmpVal and
+                             (not defined $val[4] or $val[3] eq $val[4]));
+            return Image::ExifTool::MWG::RecoverTruncatedIPTC($val[0], $xmpVal, 32);
         },
         DelCheck   => 'Image::ExifTool::MWG::ReconcileIPTCDigest($self)',
@@ -367,10 +395,161 @@
         WriteAlso  => {
             'IPTC:Sub-location'     => '$opts{EditGroup} = 1; $val',
-            'XMP-iptcCore:Location' => '$val',
+            'XMP-iptcCore:Location' => '$val', # (legacy)
+            'XMP-iptcExt:LocationShownSublocation' => '$val',
         },
     },
 );
 
-unless ($Image::ExifTool::documentOnly) {
+# MWG XMP structures
+my %sExtensions = (
+    STRUCT_NAME => 'MWG Extensions',
+    NAMESPACE   => undef, # variable namespace
+    NOTES => q{
+        This structure may contain any top-level XMP tags, but none have been
+        pre-defined in ExifTool.  Since no flattened tags have been pre-defined,
+        RegionExtensions is writable only as a structure (eg.
+        C<{xmp-dc:creator=me,rating=5}>).  Fields for this structure are identified
+        using the standard ExifTool tag name (with optional leading group name,
+        and/or trailing language code, and/or trailing C<#> symbol to disable print
+        conversion).
+    },
+);
+my %sRegionStruct = (
+    STRUCT_NAME => 'MWG RegionStruct',
+    NAMESPACE   => 'mwg-rs',
+    Area => { Struct => \%Image::ExifTool::XMP::sArea },
+    Type => {
+        PrintConv => {
+            Face => 'Face',
+            Pet => 'Pet',
+            Focus => 'Focus',
+            BarCode => 'BarCode',
+        },
+    },
+    Name        => { },
+    Description => { },
+    FocusUsage  => {
+        PrintConv => {
+            EvaluatedUsed => 'Evaluated, Used',
+            EvaluatedNotUsed => 'Evaluated, Not Used',
+            NotEvaluatedNotUsed => 'Not Evaluated, Not Used',
+        },
+    },
+    BarCodeValue=> { },
+    Extensions  => { Struct => \%sExtensions },
+    Rotation    => { # (observed in LR6 XMP)
+        Writable => 'real',
+        Notes => 'not part of MWG 2.0 spec',
+    },
+    seeAlso => { Namespace => 'rdfs', Resource => 1 },
+);
+my %sKeywordStruct;
+%sKeywordStruct = (
+    STRUCT_NAME => 'MWG KeywordStruct',
+    NAMESPACE   => 'mwg-kw',
+    Keyword   => { },
+    Applied   => { Writable => 'boolean' },
+    Children  => { Struct => \%sKeywordStruct, List => 'Bag' },
+);
+
+# MWG 2.0 XMP region namespace tags
+%Image::ExifTool::MWG::Regions = (
+    %Image::ExifTool::XMP::xmpTableDefaults,
+    GROUPS => { 0 => 'XMP', 1 => 'XMP-mwg-rs', 2 => 'Image' },
+    NAMESPACE => 'mwg-rs',
+    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<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/>
+        for the official specification.
+    },
+    Regions => {
+        Name => 'RegionInfo',
+        FlatName => 'Region',
+        Struct => {
+            STRUCT_NAME => 'MWG RegionInfo',
+            NAMESPACE   => 'mwg-rs',
+            RegionList => {
+                FlatName => 'Region',
+                Struct => \%sRegionStruct,
+                List => 'Bag',
+            },
+            AppliedToDimensions => { Struct => \%Image::ExifTool::XMP::sDimensions },
+        },
+    },
+    RegionsRegionList => { Flat => 1, Name => 'RegionList' },
+);
+
+# MWG 2.0 XMP hierarchical keyword namespace tags
+%Image::ExifTool::MWG::Keywords = (
+    %Image::ExifTool::XMP::xmpTableDefaults,
+    GROUPS => { 0 => 'XMP', 1 => 'XMP-mwg-kw', 2 => 'Image' },
+    NAMESPACE => 'mwg-kw',
+    NOTES => q{
+        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<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 => {
+        Name => 'KeywordInfo',
+        Struct => {
+            STRUCT_NAME => 'MWG KeywordInfo',
+            NAMESPACE   => 'mwg-kw',
+            Hierarchy => { Struct => \%sKeywordStruct, List => 'Bag' },
+        },
+    },
+    KeywordsHierarchy => { Name => 'HierarchicalKeywords', Flat => 1 },
+    KeywordsHierarchyKeyword  => { Name => 'HierarchicalKeywords1', Flat => 1 },
+    KeywordsHierarchyApplied  => { Name => 'HierarchicalKeywords1Applied', Flat => 1 },
+    KeywordsHierarchyChildren => { Name => 'HierarchicalKeywords1Children', Flat => 1 },
+    KeywordsHierarchyChildrenKeyword  => { Name => 'HierarchicalKeywords2', Flat => 1 },
+    KeywordsHierarchyChildrenApplied  => { Name => 'HierarchicalKeywords2Applied', Flat => 1 },
+    KeywordsHierarchyChildrenChildren => { Name => 'HierarchicalKeywords2Children', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenKeyword  => { Name => 'HierarchicalKeywords3', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenApplied  => { Name => 'HierarchicalKeywords3Applied', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenChildren => { Name => 'HierarchicalKeywords3Children', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenChildrenKeyword  => { Name => 'HierarchicalKeywords4', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenChildrenApplied  => { Name => 'HierarchicalKeywords4Applied', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenChildrenChildren => { Name => 'HierarchicalKeywords4Children', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenChildrenChildrenKeyword  => { Name => 'HierarchicalKeywords5', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenChildrenChildrenApplied  => { Name => 'HierarchicalKeywords5Applied', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenChildrenChildrenChildren => { Name => 'HierarchicalKeywords5Children', Flat => 1, NoSubStruct => 1 }, # break infinite recursion
+    KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenKeyword => { Name => 'HierarchicalKeywords6', Flat => 1 },
+    KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenApplied => { Name => 'HierarchicalKeywords6Applied', Flat => 1 },
+);
+
+# MWG 2.0 XMP collections namespace tags
+%Image::ExifTool::MWG::Collections = (
+    %Image::ExifTool::XMP::xmpTableDefaults,
+    GROUPS => { 0 => 'XMP', 1 => 'XMP-mwg-coll', 2 => 'Image' },
+    NAMESPACE => 'mwg-coll',
+    NOTES => q{
+        Collections metadata defined by the MWG 2.0 specification.  See
+        L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/>
+        for the official specification.
+    },
+    Collections => {
+        FlatName => '',
+        List => 'Bag',
+        Struct => {
+            STRUCT_NAME => 'MWG CollectionInfo',
+            NAMESPACE   => 'mwg-coll',
+            CollectionName => { },
+            CollectionURI  => { },
+        },
+    },
+);
+
+
+#------------------------------------------------------------------------------
+# Load the MWG Composite tags
+sub Load()
+{
+    return if $mwgLoaded;
+
     # add our composite tags
     Image::ExifTool::AddCompositeTags('Image::ExifTool::MWG');
@@ -379,12 +558,16 @@
     Image::ExifTool::AddTagsToLookup(\%Image::ExifTool::MWG::Composite,
                                      'Image::ExifTool::Composite');
-}
-
-# modify EXIF:Artist to behave as a List-type tag
-{
+
+    # modify EXIF:Artist to behave as a list-type tag
     my $artist = $Image::ExifTool::Exif::Main{0x13b};
     $$artist{List} = 1;
     $$artist{IsOverwriting} = \&OverwriteStringList;
     $$artist{RawConv} = \&StringToList;
+
+    # enable MWG strict mode if not set already
+    # (causes non-standard EXIF, IPTC and XMP to be ignored)
+    $Image::ExifTool::MWG::strict = 1 unless defined $Image::ExifTool::MWG::strict;
+
+    $mwgLoaded = 1;
 }
 
@@ -414,5 +597,5 @@
 sub StringToList($$)
 {
-    my ($str, $exifTool) = @_;
+    my ($str, $et) = @_;
     my (@vals, $inQuotes);
     my @t = split '; ', $str, -1;
@@ -433,5 +616,5 @@
         }
     }
-    $exifTool->Warn('Incorrectly quoted MWG string-list value') if $inQuotes;
+    $et->Warn('Incorrectly quoted MWG string-list value') if $inQuotes;
     return @vals > 1 ? \@vals : $vals[0];
 }
@@ -439,5 +622,5 @@
 #------------------------------------------------------------------------------
 # Handle logic for overwriting EXIF string-type list tag
-# Inputs: 0) new value hash ref, 1) new value hash ref,
+# Inputs: 0) ExifTool ref, 1) new value hash ref,
 #         2) old string value (or undef if it didn't exist), 3) new value ref
 # Returns: 1 and sets the new value for the tag
@@ -445,9 +628,17 @@
 {
     local $_;
-    my ($exifTool, $nvHash, $val, $newValuePt) = @_;
+    my ($et, $nvHash, $val, $newValuePt) = @_;
     my (@new, $delIndex);
+    my $writeMode = $et->Options('WriteMode');
+    if ($writeMode ne 'wcg') {
+        if (defined $val) {
+            $writeMode =~ /w/i or return 0;
+        } else {
+            $writeMode =~ /c/i or return 0;
+        }
+    }
     if ($$nvHash{DelValue} and defined $val) {
         # preserve specified old values
-        my $old = StringToList($val, $exifTool);
+        my $old = StringToList($val, $et);
         my @old = ref $old eq 'ARRAY' ? @$old : $old;
         if (@{$$nvHash{DelValue}}) {
@@ -485,15 +676,15 @@
 sub ReconcileIPTCDigest($)
 {
-    my $exifTool = shift;
+    my $et = shift;
 
     # set new value for IPTCDigest if not done already
     unless ($Image::ExifTool::Photoshop::iptcDigestInfo and
-            $exifTool->{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo})
+            $$et{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo})
     {
         # write new IPTCDigest only if it doesn't exist or
         # is the same as the digest of the original IPTC
         my @a; # (capture warning messages)
-        @a = $exifTool->SetNewValue('Photoshop:IPTCDigest', 'old', Protected => 1, DelValue => 1);
-        @a = $exifTool->SetNewValue('Photoshop:IPTCDigest', 'new', Protected => 1);
+        @a = $et->SetNewValue('Photoshop:IPTCDigest', 'old', Protected => 1, DelValue => 1);
+        @a = $et->SetNewValue('Photoshop:IPTCDigest', 'new', Protected => 1);
     }
     return '';
@@ -516,5 +707,5 @@
         }
         return \@vals;
-    } elsif (defined $iptc and length $iptc == $limit) {    
+    } elsif (defined $iptc and length $iptc == $limit) {
         $xmp = $$xmp[0] if ref $xmp;    # take first element of list
         return $xmp if length $xmp > $limit and $iptc eq substr($xmp, 0, $limit);
@@ -533,6 +724,10 @@
 =head1 SYNOPSIS
 
-    # enable MWG tags (strict mode enabled by default)
+    # enable MWG Composite tags
     use Image::ExifTool::MWG;
+    Image::ExifTool::MWG::Load();
+
+    # enable MWG strict mode
+    $Image::ExifTool::MWG::strict = 1;
 
     # disable MWG strict mode
@@ -541,21 +736,26 @@
 =head1 DESCRIPTION
 
-The MWG module contains tag definitions which are designed to simplify
-implementation of the Metadata Working Group guidelines.  These special MWG
-composite tags are enabled simply by loading this module:
+The MWG module contains Composite tag definitions which are designed to
+simplify implementation of the Metadata Working Group guidelines.  These
+special MWG Composite tags are enabled by calling the Load() method:
 
     use Image::ExifTool::MWG;
-
-When the MWG module is loaded, "strict MWG conformance" is enabled by
-default.  In this mode, ExifTool will generate a Warning tag instead of
-extracting EXIF, IPTC and XMP from non-standard locations.  The strict mode
-may be disabled by setting the MWG "strict" flag to zero (either before or
-after loading the MWG module):
+    Image::ExifTool::MWG::Load();
+
+By default, loading the MWG Composite tags enables "strict MWG conformance"
+unless previously enabled or disabled by the user.  In this mode, ExifTool
+will generate a Warning instead of extracting EXIF, IPTC and XMP from
+non-standard locations.  The strict mode may be disabled or enabled at any
+time by setting the MWG "strict" flag to 0 or 1.  eg)
 
     $Image::ExifTool::MWG::strict = 0;
 
+This module also contains the MWG XMP tags which are loaded automatically by
+ExifTool as required, and are independent of the MWG Composite tags which
+must be loaded explicitly as described above.
+
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MXF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MXF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MXF.pm	(revision 34921)
@@ -37,6 +37,7 @@
 use vars qw($VERSION);
 use Image::ExifTool qw(:DataAccess :Utils);
-
-$VERSION = '1.02';
+use Image::ExifTool::GPS;
+
+$VERSION = '1.08';
 
 sub ProcessPrimer($$$);
@@ -58,5 +59,4 @@
     Lat => 1,       Timestamp => 1,
     Length => 1,    UID => 1,
-           
 );
 
@@ -79,14 +79,13 @@
 my %geoLat = (
     Groups => { 2 => 'Location' },
-    PrintConv => 'require Image::ExifTool::GPS; Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
 );
 my %geoLon = (
     Groups => { 2 => 'Location' },
-    PrintConv => 'require Image::ExifTool::GPS; Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
 );
 my %geoLatLon = (
     Groups => { 2 => 'Location' },
     PrintConv => q{
-        require Image::ExifTool::GPS;
         my ($lat, $lon) = split ' ', $val;
         $lat = Image::ExifTool::GPS::ToDMS($self, $lat, 1, 'N');
@@ -118,6 +117,5 @@
 %Image::ExifTool::MXF::Main = (
     GROUPS => { 2 => 'Video' },
-    PROCESS_PROC => 0,  # set this to zero to omit tags from lookup (way too many!)
-    VARS => { NO_ID => 1 }, # tag ID's are too bulky for documentation
+    VARS => { NO_LOOKUP => 1, NO_ID => 1 }, # tag ID's are too bulky
     NOTES => q{
         Tags extracted from Material Exchange Format files.  Tag ID's are not listed
@@ -268,6 +266,6 @@
   # '060e2b34.0101.0101.02080000.00000000' => { Name => 'Security', Type => 'Node' },
   # '060e2b34.0101.0101.02080100.00000000' => { Name => 'SystemAccess', Type => 'Node' },
-    '060e2b34.0101.0101.02080101.00000000' => { Name => 'Username', Format => 'string' },
-    '060e2b34.0101.0101.02080101.01000000' => { Name => 'Username', Type => 'UTF-16' },
+    '060e2b34.0101.0101.02080101.00000000' => { Name => 'UserName', Format => 'string' },
+    '060e2b34.0101.0101.02080101.01000000' => { Name => 'UserName', Type => 'UTF-16' },
     '060e2b34.0101.0101.02080102.00000000' => { Name => 'Password', Format => 'string' },
     '060e2b34.0101.0101.02080102.01000000' => { Name => 'Password', Type => 'UTF-16' },
@@ -456,5 +454,5 @@
     '060e2b34.0101.0101.04010502.02000000' => { Name => 'ImageWidth', Format => 'int32u' }, # (renamed from StoredWidth)
   # '060e2b34.0101.0101.04010503.00000000' => { Name => 'DigitalQuantizationAndLevelParameters', Type => 'Node' },
-    '060e2b34.0101.0101.04010503.01000000' => { Name => 'BitsperPixel', Format => 'int8u' },
+    '060e2b34.0101.0101.04010503.01000000' => { Name => 'BitsPerPixel', Format => 'int8u' },
     '060e2b34.0101.0101.04010503.02000000' => { Name => 'RoundingMethodCode', Format => 'string' },
     '060e2b34.0101.0101.04010503.03000000' => { Name => 'BlackReferenceLevel', Format => 'int32u' },
@@ -785,5 +783,5 @@
     '060e2b34.0101.0101.07012001.10030100' => { Name => 'TelephoneNumber', Format => 'string' },
     '060e2b34.0101.0101.07012001.10030200' => { Name => 'FaxNumber', Format => 'string' },
-    '060e2b34.0101.0101.07012001.10030300' => { Name => 'E-MailAddress', Format => 'string' },
+    '060e2b34.0101.0101.07012001.10030300' => { Name => 'E-mailAddress', Format => 'string' },
   # '060e2b34.0101.0101.07012002.00000000' => { Name => 'PlaceDescriptions', Type => 'Node' },
     '060e2b34.0101.0101.07012002.01000000' => { Name => 'SettingDescription', Format => 'string' },
@@ -808,6 +806,6 @@
     '060e2b34.0101.0101.07020102.04010000' => { Name => 'TimecodeEndDateTime', Type => 'UILSBF', Unknown => 1, Groups => { 2 => 'Time' } },
   # '060e2b34.0101.0101.07020102.05000000' => { Name => 'MaterialOccurrenceTrueDateTime', Type => 'Node' },
-    '060e2b34.0101.0101.07020102.05010000' => { Name => 'UTCLastModifyDate', Format => 'string' },
-    '060e2b34.0101.0101.07020102.05020000' => { Name => 'LocalLastModifyDate', Format => 'string' },
+    '060e2b34.0101.0101.07020102.05010000' => { Name => 'UTCLastModifyDate', Format => 'string', Groups => { 2 => 'Time' } },
+    '060e2b34.0101.0101.07020102.05020000' => { Name => 'LocalLastModifyDate', Format => 'string', Groups => { 2 => 'Time' } },
   # '060e2b34.0101.0101.07020102.06000000' => { Name => 'MaterialOccurrenceTimeAddress', Type => 'Node' },
     '060e2b34.0101.0101.07020102.06010000' => { Name => 'TimecodeLastModifyDate', Type => 'UILSBF', Unknown => 1, Groups => { 2 => 'Time' } },
@@ -845,5 +843,5 @@
     '060e2b34.0101.0101.07020110.01020000' => { Name => 'TimecodeCreationDateTime', Type => 'UILSBF', Unknown => 1, Groups => { 2 => 'Time' } },
   # '060e2b34.0101.0101.07020110.02000000' => { Name => 'ModifyDate', Type => 'Node' },
-    '060e2b34.0101.0101.07020110.02010000' => { Name => 'LocalModifyDate', Format => 'string' },
+    '060e2b34.0101.0101.07020110.02010000' => { Name => 'LocalModifyDate', Format => 'string', Groups => { 2 => 'Time' } },
     '060e2b34.0101.0101.07020110.02020000' => { Name => 'TimecodeModifyDate', Type => 'UILSBF', Unknown => 1, Groups => { 2 => 'Time' } },
   # '060e2b34.0101.0101.07020200.00000000' => { Name => 'Durations', Type => 'Node' },
@@ -1062,5 +1060,5 @@
     '060e2b34.0101.0102.04010401.01000000' => { Name => 'AnalogVideoSystemName', Type => 'VideoSignalType', Unknown => 1 },
     '060e2b34.0101.0102.04010501.10000000' => { Name => 'VerticalSub-sampling', Format => 'int32u' },
-    '060e2b34.0101.0102.04010503.01010000' => { Name => 'BitsperPixel', Format => 'int32u' },
+    '060e2b34.0101.0102.04010503.01010000' => { Name => 'BitsPerPixel', Format => 'int32u' },
     '060e2b34.0101.0102.04010503.05000000' => { Name => 'ColorRangeLevels', Format => 'int32u' },
     '060e2b34.0101.0102.04010503.06000000' => { Name => 'PixelLayout', Type => 'RGBALayout', Unknown => 1 },
@@ -1357,5 +1355,5 @@
     '060e2b34.0101.0103.02080203.00000000' => { Name => 'ClassifiedBy', Format => 'string' },
     '060e2b34.0101.0103.02080204.00000000' => { Name => 'ClassificationReason', Format => 'string' },
-    '060e2b34.0101.0103.02080205.00000000' => { Name => 'DeclassificationDate', Format => 'string' },
+    '060e2b34.0101.0103.02080205.00000000' => { Name => 'DeclassificationDate', Format => 'string', Groups => { 2 => 'Time' } },
     '060e2b34.0101.0103.02080206.00000000' => { Name => 'DerivedFrom', Format => 'string' },
     '060e2b34.0101.0103.02080207.00000000' => { Name => 'ClassificationComment', Format => 'string' },
@@ -1367,5 +1365,5 @@
     '060e2b34.0101.0103.02300101.01000000' => { Name => 'NatureOfPersonality', Type => 'UTF-16' },
     '060e2b34.0101.0103.02300102.01010000' => { Name => 'ContributionStatus', Type => 'UTF-16' },
-    '060e2b34.0101.0103.02300103.01010000' => { Name => 'SupportorAdministrationStatus', Type => 'UTF-16' },
+    '060e2b34.0101.0103.02300103.01010000' => { Name => 'SupportOrAdministrationStatus', Type => 'UTF-16' },
     '060e2b34.0101.0103.02300201.01000000' => { Name => 'OrganizationKind', Type => 'UTF-16' },
     '060e2b34.0101.0103.02300202.01010000' => { Name => 'ProductionOrganizationRole', Type => 'UTF-16' },
@@ -1525,5 +1523,5 @@
     '060e2b34.0101.0103.07012001.10030101' => { Name => 'TelephoneNumber', Type => 'UTF-16' },
     '060e2b34.0101.0103.07012001.10030201' => { Name => 'FaxNumber', Type => 'UTF-16' },
-    '060e2b34.0101.0103.07012001.10030301' => { Name => 'E-MailAddress', Type => 'UTF-16' },
+    '060e2b34.0101.0103.07012001.10030301' => { Name => 'E-mailAddress', Type => 'UTF-16' },
     '060e2b34.0101.0103.07012002.01010000' => { Name => 'SettingDescription', Type => 'UTF-16' },
     '060e2b34.0101.0103.07020101.01050000' => { Name => 'POSIXMicroseconds', Format => 'int64u' },
@@ -2418,5 +2416,5 @@
 );
 
-# header information 
+# header information
 %Image::ExifTool::MXF::Header = (
     GROUPS => { 2 => 'Video' },
@@ -2479,10 +2477,10 @@
 sub ReadMXFValue($$$)
 {
-    my ($exifTool, $val, $type) = @_;
+    my ($et, $val, $type) = @_;
     my $len = length($val);
     local $_;
 
     if ($type eq 'UTF-16') {
-        $val = $exifTool->Decode($val, 'UCS2'); # (until we handle UTF-16 properly)
+        $val = $et->Decode($val, 'UCS2'); # (until we handle UTF-16 properly)
     } elsif ($type eq 'ProductVersion') {
         my @a = unpack('n*', $val);
@@ -2528,5 +2526,5 @@
         my ($count, $size) = unpack('NN', $val);
         # validate data length
-        $len == 8 + $count * $size or $exifTool->WarnOnce("Bad array or batch size");
+        $len == 8 + $count * $size or $et->WarnOnce("Bad array or batch size");
         my ($i, @a);
         for ($i=0; $i<$count; ++$i) {
@@ -2538,5 +2536,5 @@
             $_ = join('-', unpack('H8H4H4H4H12', $_)) foreach @a;
         } elsif ($type eq 'BatchOfUL' or $type =~ /^WeakReference/) {
-            $_ = ReadMXFValue($exifTool, $_, 'UL') foreach @a;
+            $_ = ReadMXFValue($et, $_, 'UL') foreach @a;
         }
         $val = \@a;
@@ -2571,5 +2569,5 @@
 sub ProcessPrimer($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $end = $$dirInfo{DirLen};
@@ -2578,7 +2576,7 @@
     my $size = Get32u($dataPt, 4);
     return 0 unless $size >= 18;
-    $exifTool->VerboseDir('MXF Primer', $count);
-    my $verbose = $exifTool->Options('Verbose');
-    my $primer = $$exifTool{MXFInfo}{Primer};
+    $et->VerboseDir('MXF Primer', $count);
+    my $verbose = $et->Options('Verbose');
+    my $primer = $$et{MXFInfo}{Primer};
     my $pos = 8;
     my $i;
@@ -2594,5 +2592,5 @@
         my $indx = $i . ')';
         $indx .= ' ' if length($indx) < 3;
-        $exifTool->VPrint(0, sprintf("  | $indx 0x%.4x => '$global'\n", $local));
+        $et->VPrint(0, sprintf("  | $indx 0x%.4x => '${global}'\n", $local));
     }
     return 1;
@@ -2605,14 +2603,14 @@
 sub ProcessLocalSet($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     local $_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos};
     my $end = $$dirInfo{DirLen};
-    my $mxfInfo = $$exifTool{MXFInfo};
+    my $mxfInfo = $$et{MXFInfo};
     my $primer = $$mxfInfo{Primer};
     my (@strongRef, @groups, $instance, $editRate, $trackID, $langCode, $textLang);
 
-    $exifTool->VerboseDir('MXF LocalSet', undef, $end);
+    $et->VerboseDir('MXF LocalSet', undef, $end);
 
     # loop through all tags in this local set
@@ -2629,5 +2627,5 @@
         } else {
             $tag = $loc;
-          # $exifTool->WarnOnce('Missing local key for at least one tag');
+          # $et->WarnOnce('Missing local key for at least one tag');
             $extra = ', NOT IN PRIMER!';
         }
@@ -2637,5 +2635,5 @@
             $type = $$tagInfo{Type};
             if ($type and $knownType{$type}) {
-                $val = ReadMXFValue($exifTool, substr($$dataPt, $pos, $len), $type);
+                $val = ReadMXFValue($et, substr($$dataPt, $pos, $len), $type);
                 push @strongRef, (ref $val ? @$val : $val) if $type =~ /^StrongReference/;
                 # remember instance UID of this local set
@@ -2651,10 +2649,10 @@
         }
         # get tagInfo ref the standard way to handle Unknown tags
-        $tagInfo = $langInfo || $exifTool->GetTagInfo($tagTablePtr, $tag);
+        $tagInfo = $langInfo || $et->GetTagInfo($tagTablePtr, $tag);
         # set Binary flag to extract all unknown-format tags as Binary data
         if ($tagInfo and $$tagInfo{Unknown} and not defined $$tagInfo{Binary}) {
             $$tagInfo{Binary} = not ($$tagInfo{Format} or ($type and $knownType{$type}));
         }
-        my $key = $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        my $key = $et->HandleTag($tagTablePtr, $tag, $val,
             Extra       => $extra,
             TagInfo     => $tagInfo,
@@ -2670,5 +2668,5 @@
         # (necessary because we don't have all the information we need
         #  to do this on the fly when the file is parsed linearly)
-        push @groups, $$exifTool{TAG_EXTRA}{$key};
+        push @groups, $$et{TAG_EXTRA}{$key};
         next unless $tagInfo;
         my $name = $$tagInfo{Name};
@@ -2676,9 +2674,9 @@
             $$mxfInfo{FixDuration}{$key} = 1;
         } elsif ($$tagInfo{LanguageCode}) {
-            $langCode = $$exifTool{VALUE}{$key};
+            $langCode = $$et{VALUE}{$key};
         } elsif ($name eq 'EditRate') {
-            $editRate = $$exifTool{VALUE}{$key};
+            $editRate = $$et{VALUE}{$key};
         } elsif ($name =~ /TrackID$/) {
-            $trackID = $$exifTool{VALUE}{$key};
+            $trackID = $$et{VALUE}{$key};
             unless ($$mxfInfo{Group1}{$trackID}) {
                 # save lookup to convert TrackID to our group 1 name
@@ -2702,5 +2700,5 @@
         # save instance UID's in groups hash (used to remove duplicates later)
         $$_{UID} = $instance foreach @groups;
-        $$objInfo{Name} = $$exifTool{DIR_NAME};
+        $$objInfo{Name} = $$et{DIR_NAME};
         $$objInfo{TrackID} = $trackID if defined $trackID;
         $$objInfo{EditRate} = $editRate if $editRate;
@@ -2720,5 +2718,5 @@
         }
         # save instance UID's of Preface's
-        push @{$$mxfInfo{Preface}}, $instance if $$exifTool{DIR_NAME} eq 'Preface';
+        push @{$$mxfInfo{Preface}}, $instance if $$et{DIR_NAME} eq 'Preface';
     }
     return 1;
@@ -2785,8 +2783,8 @@
 sub ConvertDurations($$)
 {
-    my ($exifTool, $mxfInfo) = @_;
-    my $valueHash = $$exifTool{VALUE};
-    my $infoHash = $$exifTool{TAG_INFO};
-    my $tagExtra = $$exifTool{TAG_EXTRA};
+    my ($et, $mxfInfo) = @_;
+    my $valueHash = $$et{VALUE};
+    my $infoHash = $$et{TAG_INFO};
+    my $tagExtra = $$et{TAG_EXTRA};
     my $editHash = $$mxfInfo{EditRate};
     my ($tag, $key, $i);
@@ -2809,8 +2807,8 @@
 sub ProcessMXF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
-    my $unknown = $exifTool->Options('Unknown');
+    my $verbose = $et->Options('Verbose');
+    my $unknown = $et->Options('Unknown');
     my ($buff, $preface, $n, $headerEnd, $footerPos);
 
@@ -2820,7 +2818,7 @@
     my $start = pos($buff) - 11;
 
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('MM');
-    $raf->Seek($start, 0) or $exifTool->Warn('Seek error'), return 1;
+    $raf->Seek($start, 0) or $et->Warn('Seek error'), return 1;
     my $tagTablePtr = GetTagTable('Image::ExifTool::MXF::Main');
 
@@ -2835,8 +2833,8 @@
         Preface => [ ],     # instance UID's for all Preface objects
     );
-    $$exifTool{MXFInfo} = \%mxfInfo;
+    $$et{MXFInfo} = \%mxfInfo;
 
     # set group 1 name for all tags (so we can overwrite with track number later)
-    $$exifTool{SET_GROUP1} = 'MXF';
+    $$et{SET_GROUP1} = 'MXF';
 
     for (;;) {
@@ -2849,5 +2847,5 @@
             # skip directly to footer if possible
             if ($footerPos and $footerPos > $pos and (not $verbose or not $unknown)) {
-                $exifTool->VPrint(0, "[Skipping to footer. Use Unknown option to parse body partitions]\n");
+                $et->VPrint(0, "[Skipping to footer. Use Unknown option to parse body partitions]\n");
                 $raf->Seek($footerPos, 0) or last;
                 $pos = $footerPos;
@@ -2878,5 +2876,5 @@
             my $name = $1 eq '0d' ? 'UserOrganizationPublicUse' : 'Experimental';
             $tagInfo = { Name => $name, %localSet };
-            Image::ExifTool::AddTagToTable($tagTablePtr, $ul, $tagInfo);
+            AddTagToTable($tagTablePtr, $ul, $tagInfo);
         }
         my ($val, $dataPt);
@@ -2895,5 +2893,5 @@
             $dataPt = \$buff;
             my $type = $$tagInfo{Type};
-            $val = ReadMXFValue($exifTool, $buff, $type) if $type and $knownType{$type};
+            $val = ReadMXFValue($et, $buff, $type) if $type and $knownType{$type};
         } elsif (($tagInfo and (not $$tagInfo{Unknown} or $unknown)) or $verbose) {
             if ($tagInfo) {
@@ -2922,5 +2920,5 @@
             next;
         }
-        $exifTool->HandleTag($tagTablePtr, $ul, $val,
+        $et->HandleTag($tagTablePtr, $ul, $val,
             TagInfo     => $tagInfo,
             DataPt      => $dataPt,
@@ -2932,14 +2930,14 @@
     # walk entire MXF object tree to fix family 1 group names
     my ($pathInfo, $tag, %did, %bestDur);
-    $pathInfo = { Path => [ 'MXF' ] } if $exifTool->Options('SavePath');
+    $pathInfo = { Path => [ 'MXF' ] } if $et->Options('SavePath');
     foreach $preface (@{$mxfInfo{Preface}}) {
         SetGroups(\%mxfInfo, $preface, $pathInfo);
     }
     # convert Duration values to seconds based on the appropriate EditRate
-    ConvertDurations($exifTool, \%mxfInfo);
+    ConvertDurations($et, \%mxfInfo);
 
     # remove tags to keep only the one from the most recent instance of the object
-    my $tagExtra = $$exifTool{TAG_EXTRA};
-    my $fileOrder = $$exifTool{FILE_ORDER};
+    my $tagExtra = $$et{TAG_EXTRA};
+    my $fileOrder = $$et{FILE_ORDER};
     # also determine our best Duration value
     if ($mxfInfo{BestDuration}) {
@@ -2954,11 +2952,11 @@
         my $utag = "$1 $instance";      # instance-specific tag name
         if ($did{$utag}) {
-            Image::ExifTool::DeleteTag($exifTool, $tag); # delete the duplicate
+            Image::ExifTool::DeleteTag($et, $tag); # delete the duplicate
         } else {
             $did{$utag} = 1;
             if ($bestDur{$utag}) {
                 # save best duration value
-                my $val = $$exifTool{VALUE}{$tag};
-                $exifTool->HandleTag($tagTablePtr, '060e2b34.0101.0102.07020201.01030000', $val);
+                my $val = $$et{VALUE}{$tag};
+                $et->HandleTag($tagTablePtr, '060e2b34.0101.0102.07020201.01030000', $val);
             }
         }
@@ -2966,6 +2964,6 @@
 
     # clean up and return
-    delete $$exifTool{SET_GROUP1};
-    delete $$exifTool{MXFInfo};
+    delete $$et{SET_GROUP1};
+    delete $$et{MXFInfo};
     return 1;
 }
@@ -2990,5 +2988,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MacOS.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MacOS.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MacOS.pm	(revision 34921)
@@ -0,0 +1,735 @@
+#------------------------------------------------------------------------------
+# File:         MacOS.pm
+#
+# Description:  Read/write MacOS system tags
+#
+# Revisions:    2017/03/01 - P. Harvey Created
+#               2020/10/13 - PH Added ability to read MacOS "._" files
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::MacOS;
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.11';
+
+sub MDItemLocalTime($);
+sub ProcessATTR($$$);
+
+my %mdDateInfo = (
+    ValueConv => \&MDItemLocalTime,
+    PrintConv => '$self->ConvertDateTime($val)',
+);
+
+# Information decoded from Mac OS sidecar files
+%Image::ExifTool::MacOS::Main = (
+    GROUPS => { 0 => 'File', 1 => 'MacOS' },
+    NOTES => q{
+        Note that on some filesystems, MacOS creates sidecar files with names that
+        begin with "._".  ExifTool will read these files if specified, and extract
+        the information listed in the following table without the need for extra
+        options, but these files are not writable directly.
+    },
+    2 => {
+        Name => 'RSRC',
+        SubDirectory => { TagTable => 'Image::ExifTool::RSRC::Main' },
+    },
+    9 => {
+        Name => 'ATTR',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::MacOS::XAttr',
+            ProcessProc => \&ProcessATTR,
+        },
+    },
+);
+
+# "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.
+        And they extracted by default from MacOS "._" files when reading
+        these files directly.
+    },
+    '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/\| $//;
+}
+
+        
+#------------------------------------------------------------------------------
+# Read MacOS XAttr value
+# Inputs: 0) ExifTool object ref, 1) file name
+sub ReadXAttrValue($$$$)
+{
+    my ($et, $tagTablePtr, $tag, $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)) {
+            return undef if ref $dirInfo{Value} eq 'HASH';
+            $val = $dirInfo{Value}
+        } else {
+            $et->Warn("Error decoding $$tagTablePtr{$tag}{Name}");
+            return undef;
+        }
+    }
+    if (not ref $val and ($val =~ /\0/ or length($val) > 200) or $tag eq 'XAttrMDLabel') {
+        my $buff = $val;
+        $val = \$buff;
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Read MacOS extended attribute tags using 'xattr' utility
+# 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) {
+            $val = ReadXAttrValue($et, $tagTablePtr, $tag, $val);
+            $et->HandleTag($tagTablePtr, $tag, $val) if defined $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};
+}
+
+#------------------------------------------------------------------------------
+# Read ATTR metadata from "._" file
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Return: 1 on success
+# (ref https://www.swiftforensics.com/2018/11/the-dot-underscore-file-format.html)
+sub ProcessATTR($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $dataLen = length $$dataPt;
+
+    $dataLen >= 58 and $$dataPt =~ /^.{34}ATTR/s or $et->Warn('Invalid ATTR header'), return 0;
+    my $entries = Get32u($dataPt, 66);
+    $et->VerboseDir('ATTR', $entries);
+    # (Note: The RAF is not in $dirInfo because it would break RSRC reading --
+    # the RSCR block uses relative offsets, while the ATTR block uses absolute! grrr!)
+    my $raf = $$et{RAF};
+    my $pos = 70;       # first entry is after ATTR header
+    my $i;
+    for ($i=0; $i<$entries; ++$i) {
+        $pos + 12 > $dataLen and $et->Warn('Truncated ATTR entry'), last;
+        my $off = Get32u($dataPt, $pos);
+        my $len = Get32u($dataPt, $pos + 4);
+        my $n = Get8u($dataPt, $pos + 10);  # number of characters in tag name
+        $pos + 11 + $n > $dataLen and $et->Warn('Truncated ATTR name'), last;
+        $off -= $dataPos;       # convert to relative offset (grrr!)
+        $off < 0 or $off > $dataLen and $et->Warn('Invalid ATTR offset'), last;
+        my $tag = substr($$dataPt, $pos + 11, $n);
+        $tag =~ s/\0+$//;       # remove null terminator
+        # remove random ID after kMDLabel in tag ID
+        $tag =~ s/^com.apple.metadata:kMDLabel_.*/com.apple.metadata:kMDLabel/s;
+        $off + $len > $dataLen and $et->Warn('Truncated ATTR value'), last;
+        my $val = ReadXAttrValue($et, $tagTablePtr, $tag, substr($$dataPt, $off, $len));
+        $et->HandleTag($tagTablePtr, $tag, $val,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Start   => $off,
+            Size    => $len,
+        ) if defined $val;
+        $pos += (11 + $n + 3) & -4; # step to next entry (on even 4-byte boundary)
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Read information from a MacOS "._" sidecar file
+# Inputs: 0) ExifTool ref, 1) dirInfo ref
+# Returns: 1 on success, 0 if this wasn't a valid "._" file
+# (ref https://www.swiftforensics.com/2018/11/the-dot-underscore-file-format.html)
+sub ProcessMacOS($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my ($hdr, $buff, $i);
+
+    return 0 unless $raf->Read($hdr, 26) == 26 and $hdr =~ /^\0\x05\x16\x07\0(.)\0\0Mac OS X        /s;
+    my $ver = ord $1;
+    # (extension may be anything, so just echo back the incoming file extension if it exists)
+    $et->SetFileType(undef, undef, $$et{FILE_EXT});
+    $ver == 2 or $et->Warn("Unsupported file version $ver"), return 1;
+    SetByteOrder('MM');
+    my $tagTablePtr = GetTagTable('Image::ExifTool::MacOS::Main');
+    my $entries = Get16u(\$hdr, 0x18);
+    $et->VerboseDir('MacOS', $entries);
+    $raf->Read($hdr, $entries * 12) == $entries * 12 or $et->Warn('Truncated header'), return 1;
+    for ($i=0; $i<$entries; ++$i) {
+        my $pos = $i * 12;
+        my $tag = Get32u(\$hdr, $pos);
+        my $off = Get32u(\$hdr, $pos + 4);
+        my $len = Get32u(\$hdr, $pos + 8);
+        $len > 100000000 and $et->Warn('Record size too large'), last;
+        $raf->Seek($off,0) and $raf->Read($buff,$len) == $len or $et->Warn('Truncated record'), last;
+        $et->HandleTag($tagTablePtr, $tag, undef, DataPt => \$buff, DataPos => $off, Index => $i);
+    }
+    return 1;
+}
+
+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.  It also reads metadata directly from the MacOS "_."
+sidecar files that are used on some filesystems to store file attributes. 
+Writable tags use "xattr", "setfile" or "osascript" for writing.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MakerNotes.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MakerNotes.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MakerNotes.pm	(revision 34921)
@@ -18,8 +18,9 @@
 sub ProcessCanon($$$);
 sub ProcessGE2($$$);
+sub ProcessKodakPatch($$$);
 sub WriteUnknownOrPreview($$$);
 sub FixLeicaBase($$;$);
 
-$VERSION = '1.66';
+$VERSION = '2.10';
 
 my $debug;          # set to 1 to enable debugging code
@@ -32,5 +33,28 @@
 # - 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/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Apple::Main',
+            Start => '$valuePtr + 14',
+            Base => '$start - 14',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        # this maker notes starts with a standard TIFF header at offset 0x0a
+        # (must check Nikon signature first because Nikon Capture NX can generate
+        #  NEF images containing Nikon maker notes from JPEG images of any camera model)
+        Name => 'MakerNoteNikon',
+        Condition => '$$valPt=~/^Nikon\x00\x02/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::Main',
+            Start => '$valuePtr + 18',
+            Base => '$start - 8',
+            ByteOrder => 'Unknown',
+        },
+    },
     {
         Name => 'MakerNoteCanon',
@@ -64,4 +88,23 @@
             ByteOrder => 'Unknown',
             FixBase => 1, # necessary for AVI and MOV videos
+        },
+    },
+    {
+        Name => 'MakerNoteDJI',
+        Condition => '$$self{Make} eq "DJI" and $$valPt !~ /^...\@AMBA/s',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::DJI::Main',
+            Start => '$valuePtr',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteFLIR',
+        # (starts with IFD, Make is 'FLIR Systems AB' or 'FLIR Systems')
+        Condition => '$$self{Make} =~ /^FLIR Systems/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FLIR::Main',
+            Start => '$valuePtr',
+            ByteOrder => 'Unknown',
         },
     },
@@ -109,4 +152,18 @@
        },
     },
+    {
+        Name => 'MakerNoteHasselblad',
+        Condition => '$$self{Make} eq "Hasselblad"',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Unknown::Main',
+            ByteOrder => 'Unknown',
+            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)
@@ -310,4 +367,22 @@
     {
         Name => 'MakerNoteKodak8b',
+        # these maker notes have an extra 2 bytes after the entry count
+        # (this is handled by the patch).  Also, the IFD uses a Format 13,
+        # which is some 2-byte format (not Float, as decoded by ExifTool)
+        # - written by the PixPro AZ251, AZ361, AZ262, AZ521
+        Condition => q{
+            $$self{Make}=~/Kodak/i and
+            $$valPt =~ /^MM\0\x2a\0\0\0\x08\0.\0\0/
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type8',
+            ProcessProc => \&ProcessKodakPatch,
+            ByteOrder => 'BigEndian',
+            Start => '$valuePtr + 8',
+            Base => '$start - 8',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak8c',
         # TIFF-format maker notes
         Condition => q{
@@ -347,4 +422,36 @@
             ByteOrder => 'Unknown',
             Start => '$valuePtr + 2',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak11',
+        # these maker notes have a 4-byte entry count
+        # - written by the PixPro S-1 (Note: Make is "JK Imaging, Ltd.", so check Model for "Kodak")
+        Condition => q{
+            $$self{Model}=~/(Kodak|PixPro)/i and
+            $$valPt =~ /^II\x2a\0\x08\0\0\0.\0\0\0/s
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type11',
+            ProcessProc => \&ProcessKodakPatch,
+            ByteOrder => 'LittleEndian',
+            Start => '$valuePtr + 8',
+            Base => '$start - 8',
+        },
+    },
+    {
+        Name => 'MakerNoteKodak12',
+        # these maker notes have a 4-byte entry count
+        # - written by the PixPro AZ901 (Note: Make is "JK Imaging, Ltd.", so check Model for "Kodak")
+        Condition => q{
+            $$self{Model}=~/(Kodak|PixPro)/i and
+            $$valPt =~ /^MM\0\x2a\0\0\0\x08\0\0\0./s
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Kodak::Type11',
+            ProcessProc => \&ProcessKodakPatch,
+            ByteOrder => 'BigEndian',
+            Start => '$valuePtr + 8',
+            Base => '$start - 8',
         },
     },
@@ -404,10 +511,9 @@
     },
     {
-        # this maker notes starts with a standard TIFF header at offset 0x0a
-        Name => 'MakerNoteNikon',
-        Condition => '$$self{Make}=~/^NIKON/i and $$valPt=~/^Nikon\x00\x02/',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Nikon::Main',
-            Start => '$valuePtr + 18',
+        Name => 'MakerNoteMotorola',
+        Condition => '$$valPt=~/^MOT\0/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Motorola::Main',
+            Start => '$valuePtr + 8',
             Base => '$start - 8',
             ByteOrder => 'Unknown',
@@ -417,5 +523,5 @@
         # older Nikon maker notes
         Name => 'MakerNoteNikon2',
-        Condition => '$$self{Make}=~/^NIKON/ and $$valPt=~/^Nikon\x00\x01/',
+        Condition => '$$valPt=~/^Nikon\x00\x01/',
         SubDirectory => {
             TagTable => 'Image::ExifTool::Nikon::Type2',
@@ -431,4 +537,13 @@
             TagTable => 'Image::ExifTool::Nikon::Main',
             ByteOrder => 'Unknown', # most are little-endian, but D1 is big
+        },
+    },
+    {
+        Name => 'MakerNoteNintendo',
+        # (starts with an IFD)
+        Condition => '$$self{Make} eq "Nintendo"',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nintendo::Main',
+            ByteOrder => 'Unknown',
         },
     },
@@ -485,5 +600,8 @@
         Name => 'MakerNoteLeica3', # used by the R8 and R9
         # (starts with IFD)
-        Condition => '$$self{Make} =~ /^Leica Camera AG/ and $$valPt !~ /^LEICA/ and $$self{Model} ne "S2"',
+        Condition => q{
+            $$self{Make} =~ /^Leica Camera AG/ and $$valPt !~ /^LEICA/ and
+            $$self{Model} ne "S2" and $$self{Model} ne "LEICA M (Typ 240)"
+        },
         SubDirectory => {
             TagTable => 'Image::ExifTool::Panasonic::Leica3',
@@ -493,6 +611,6 @@
     },
     {
-        Name => 'MakerNoteLeica4', # used by the M9
-        # (M9 starts with "LEICA0\x03\0")
+        Name => 'MakerNoteLeica4', # used by the M9/M-Monochrom
+        # (M9 and M Monochrom start with "LEICA0\x03\0")
         Condition => '$$self{Make} =~ /^Leica Camera AG/ and $$valPt =~ /^LEICA0/',
         SubDirectory => {
@@ -504,7 +622,12 @@
     },
     {
-        Name => 'MakerNoteLeica5', # used by the X1
+        Name => 'MakerNoteLeica5', # used by the X1/X2/X VARIO/T/X-U
         # (X1 starts with "LEICA\0\x01\0", Make is "LEICA CAMERA AG")
-        Condition => '$$valPt =~ /^LEICA\0\x01\0/',
+        # (X2 starts with "LEICA\0\x05\0", Make is "LEICA CAMERA AG")
+        # (X VARIO starts with "LEICA\0\x04\0", Make is "LEICA CAMERA AG")
+        # (T (Typ 701) starts with "LEICA\0\0x6", Make is "LEICA CAMERA AG")
+        # (X (Typ 113) starts with "LEICA\0\0x7", Make is "LEICA CAMERA AG")
+        # (X-U (Typ 113) starts with "LEICA\0\x10\0", Make is "LEICA CAMERA AG")
+        Condition => '$$valPt =~ /^LEICA\0[\x01\x04\x05\x06\x07\x10\x1a]\0/',
         SubDirectory => {
             TagTable => 'Image::ExifTool::Panasonic::Leica5',
@@ -515,9 +638,15 @@
     },
     {
-        Name => 'MakerNoteLeica6', # used by the S2 (CAUTION: this tag name is special cased in the code)
-        # (S2 starts with "LEICA\0\x02\xff", Make is "LEICA CAMERA AG",
-        #  but maker notes aren't loaded at the time this is tested)
-        Condition => '$$self{Model} eq "S2"',
+        Name => 'MakerNoteLeica6', # used by the S2, M (Typ 240) and S (Typ 006)
+        # (starts with "LEICA\0\x02\xff", Make is "Leica Camera AG", but test the
+        # model names separately because the maker notes data may not be loaded
+        # at the time this is tested if they are in a JPEG trailer.  Also, this
+        # header is used by the M Monochrom (Type 246), with different offsets.)
+        Condition => q{
+            ($$self{Make} eq 'Leica Camera AG' and ($$self{Model} eq 'S2' or
+            $$self{Model} eq 'LEICA M (Typ 240)' or $$self{Model} eq 'LEICA S (Typ 006)'))
+        },
         DataTag => 'LeicaTrailer',  # (generates fixup name for this tag)
+        LeicaTrailer => 1, # flag to special-case this tag in the Exif code
         SubDirectory => {
             TagTable => 'Image::ExifTool::Panasonic::Leica6',
@@ -527,5 +656,5 @@
             # as a JPEG trailer -- this case is handled by ProcessLeicaTrailer in
             # Panasonic.pm, and any "Base" defined here is ignored for this case.
-            # ExifTool may also create S2 maker notes inside the APP1 segment when
+            # ExifTool may also create S2/M maker notes inside the APP1 segment when
             # copying from other files, and for this the normal EXIF offsets are used,
             # Base should not be defined!
@@ -533,7 +662,50 @@
     },
     {
+        Name => 'MakerNoteLeica7', # used by the M Monochrom (Typ 246)
+        # (starts with "LEICA\0\x02\xff", Make is "Leica Camera AG")
+        Condition => '$$valPt =~ /^LEICA\0\x02\xff/',
+        DataTag => 'LeicaTrailer',  # (generates fixup name for this tag)
+        LeicaTrailer => 1, # flag to special-case this tag in the Exif code
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Panasonic::Leica6',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'Unknown',
+            Base => '-$base',  # uses absolute file offsets (not based on TIFF header offset)
+        },
+    },
+    {
+        Name => 'MakerNoteLeica8', # used by the Q (Type 116)
+        # (Q (Typ 116) starts with "LEICA\0\x08\0", Make is "LEICA CAMERA AG")
+        # (SL (Typ 601) and CL start with "LEICA\0\x09\0", Make is "LEICA CAMERA AG")
+        Condition => '$$valPt =~ /^LEICA\0[\x08\x09]\0/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Panasonic::Leica5',
+            Start => '$valuePtr + 8',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteLeica9', # used by the M10/S
+        # (M10 and S start with "LEICA0\x02\0")
+        Condition => '$$self{Make} =~ /^Leica Camera AG/ and $$valPt =~ /^LEICA\0\x02\0/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Panasonic::Leica9',
+            Start => '$valuePtr + 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',
+        },
+    },
+    {
         Name => 'MakerNotePanasonic',
         # (starts with "Panasonic\0")
-        Condition => '$$valPt=~/^Panasonic/',
+        Condition => '$$valPt=~/^Panasonic/ and $$self{Model} ne "DC-FT7"',
         SubDirectory => {
             TagTable => 'Image::ExifTool::Panasonic::Main',
@@ -549,4 +721,15 @@
             TagTable => 'Image::ExifTool::Panasonic::Type2',
             ByteOrder => 'LittleEndian',
+        },
+    },
+    {
+        Name => 'MakerNotePanasonic3', # (DC-FT7)
+        # (starts with "Panasonic\0")
+        Condition => '$$valPt=~/^Panasonic/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Panasonic::Main',
+            Start => '$valuePtr + 12',
+            Base => 12, # crazy!
+            ByteOrder => 'Unknown',
         },
     },
@@ -609,4 +792,5 @@
         Name => 'MakerNotePentax5',
         # (starts with "PENTAX \0")
+        # used by cameras such as the Q, Optio S1, RS1500 and WG-1
         Condition => '$$valPt=~/^PENTAX \0/',
         SubDirectory => {
@@ -618,4 +802,15 @@
     },
     {
+        Name => 'MakerNotePentax6',
+        # (starts with "S1\0\0\0\0\0\0\x0c\0\0\0")
+        Condition => '$$valPt=~/^S1\0{6}\x0c\0{3}/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::S1',
+            Start => '$valuePtr + 12',
+            Base => '$start - 12',
+            ByteOrder => 'Unknown',
+        },
+    },
+    {
         Name => 'MakerNotePhaseOne',
         # Starts with: 'IIIITwaR' or 'IIIICwaR' (have seen both written by P25)
@@ -627,11 +822,14 @@
         },
         NotIFD => 1,
-        Binary => 1,
-        PutFirst => 1, # place immediately after TIFF header
-        Notes => 'the raw image data in PhaseOne IIQ images',
+        IsPhaseOne => 1,    # flag to rebuild these differently
+        SubDirectory => { TagTable => 'Image::ExifTool::PhaseOne::Main' },
+        PutFirst => 1,      # place immediately after TIFF header
     },
     {
         Name => 'MakerNoteReconyx',
-        Condition => '$$valPt =~ /^\x01\xf1[\x02\x03]\x00/',
+        Condition => q{
+            $$valPt =~ /^\x01\xf1([\x02\x03]\x00)?/ and
+            ($1 or $$self{Make} eq "RECONYX")
+        },
         SubDirectory => {
             TagTable => 'Image::ExifTool::Reconyx::Main',
@@ -640,11 +838,61 @@
     },
     {
+        Name => 'MakerNoteReconyx2',
+        Condition => '$$valPt =~ /^RECONYXUF\0/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Reconyx::Type2',
+            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)
-        Condition => '$$self{Make}=~/^RICOH/ and $$valPt=~/^(Ricoh|      )/i',
+        Condition => q{
+            $$self{Make} =~ /^(PENTAX )?RICOH/ and
+            $$valPt =~ /^(Ricoh|      |MM\0\x2a|II\x2a\0)/i and
+            $$valPt !~ /^(MM\0\x2a\0\0\0\x08\0.\0\0|II\x2a\0\x08\0\0\0.\0\0\0)/s and
+            $$self{Model} ne 'RICOH WG-M1'
+        },
         SubDirectory => {
             TagTable => 'Image::ExifTool::Ricoh::Main',
             Start => '$valuePtr + 8',
             ByteOrder => 'Unknown',
+        },
+    },
+    {
+        Name => 'MakerNoteRicoh2',
+        # (the Ricoh HZ15 starts with "MM\0\x2a" and the Pentax XG-1 starts with "II\x2a\0",
+        # but an extra 2 bytes of padding after the IFD entry count prevents these from
+        # being processed as a standard IFD.  Note that the offsets for the HZ15 are all
+        # zeros, but they seem to be mostly OK for the XG-1)
+        Condition => q{
+            $$self{Make} =~ /^(PENTAX )?RICOH/ and ($$self{Model} eq 'RICOH WG-M1' or
+            $$valPt =~ /^(MM\0\x2a\0\0\0\x08\0.\0\0|II\x2a\0\x08\0\0\0.\0\0\0)/s)
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Ricoh::Type2',
+            Start => '$valuePtr + 8',
+            Base => '$start - 8',
+            ByteOrder => 'Unknown',
+            ProcessProc => \&ProcessKodakPatch,
         },
     },
@@ -670,12 +918,12 @@
         Condition => '$$valPt =~ /^STMN\d{3}/',
         SubDirectory => {
-            TagTable => 'Image::ExifTool::Samsung::Type1',
+            TagTable => 'Image::ExifTool::Samsung::Main',
         },
     },
     {
         Name => 'MakerNoteSamsung2',
-        # Samsung EXIF-format maker notes
-        Condition => q{
-            $$self{Make} eq 'SAMSUNG' and ($$self{TIFF_TYPE} eq 'SRW' or
+        # Samsung EXIF-format maker notes (
+        Condition => q{
+            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)
         },
@@ -726,6 +974,10 @@
     {
         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',
@@ -738,5 +990,7 @@
         Name => 'MakerNoteSony',
         # (starts with "SONY DSC \0" or "SONY CAM \0")
-        Condition => '$$self{Make}=~/^SONY/ and $$valPt=~/^SONY (DSC|CAM)/',
+        # (TF1 starts with "\0\0SONY PIC\0")
+        # (Hasselblad models start with "VHAB     \0")
+        Condition => '$$valPt=~/^(SONY (DSC|CAM|MOBILE)|\0\0SONY PIC\0|VHAB     \0)/',
         SubDirectory => {
             TagTable => 'Image::ExifTool::Sony::Main',
@@ -748,5 +1002,5 @@
         Name => 'MakerNoteSony2',
         # (starts with "SONY PI\0" -- DSC-S650/S700/S750)
-        Condition => '$$self{Make}=~/^SONY/ and $$valPt=~/^SONY PI\0/ and $$self{OlympusCAMER}=1',
+        Condition => '$$valPt=~/^SONY PI\0/ and $$self{OlympusCAMER}=1',
         SubDirectory => {
             TagTable => 'Image::ExifTool::Olympus::Main',
@@ -758,5 +1012,5 @@
         Name => 'MakerNoteSony3',
         # (starts with "PREMI\0" -- DSC-S45/S500)
-        Condition => '$$self{Make}=~/^SONY/ and $$valPt=~/^(PREMI)\0/ and $$self{OlympusCAMER}=1',
+        Condition => '$$valPt=~/^(PREMI)\0/ and $$self{OlympusCAMER}=1',
         SubDirectory => {
             TagTable => 'Image::ExifTool::Olympus::Main',
@@ -766,6 +1020,16 @@
     },
     {
-        Name => 'MakerNoteSony4', # used in SR2 and ARW images
+        Name => 'MakerNoteSony4',
+        # (starts with "SONY PIC\0" -- DSC-H200/J20/W370/W510, MHS-TS20)
+        Condition => '$$valPt=~/^SONY PIC\0/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::PIC' },
+    },
+    {
+        Name => 'MakerNoteSony5', # used in SR2 and ARW images
         Condition => '$$self{Make}=~/^SONY/ and $$valPt!~/^\x01\x00/',
+        Condition => q{
+            ($$self{Make}=~/^SONY/ or ($$self{Make}=~/^HASSELBLAD/ and
+            $$self{Model}=~/^(HV|Stellar|Lusso|Lunar)/)) and $$valPt!~/^\x01\x00/
+        },
         SubDirectory => {
             TagTable => 'Image::ExifTool::Sony::Main',
@@ -802,4 +1066,11 @@
     },
     {
+        Name => 'MakerNoteUnknownBinary',
+        # "LSI1\0" - SilverFast
+        Condition => '$$valPt =~ /^LSI1\0/',
+        Notes => 'unknown binary maker notes',
+        Binary => 1,
+    },
+    {
         Name => 'MakerNoteUnknown',
         PossiblePreview => 1,
@@ -818,4 +1089,5 @@
 foreach $tagInfo (@Image::ExifTool::MakerNotes::Main) {
     $$tagInfo{Writable} = 'undef';
+    $$tagInfo{Format} = 'undef', # (make sure we don't convert this when reading)
     $$tagInfo{WriteGroup} = 'ExifIFD';
     $$tagInfo{Groups} = { 1 => 'MakerNotes' };
@@ -835,8 +1107,8 @@
 sub GetMakerNoteOffset($)
 {
-    my $exifTool = shift;
+    my $et = shift;
     # figure out where we expect the value data based on camera type
-    my $make = $exifTool->{Make};
-    my $model = $exifTool->{Model};
+    my $make = $$et{Make};
+    my $model = $$et{Model};
     my ($relative, @offsets);
 
@@ -855,5 +1127,5 @@
         # except some models like the EX-S770,Z65,Z70,Z75 and Z700 which use 16,
         # and the EX-Z35 which uses 2 (grrrr...)
-        push @offsets, $$exifTool{FILE_TYPE} =~ /^(RIFF|MOV)$/ ? 0 : (4, 16, 2);
+        push @offsets, $$et{FILE_TYPE} =~ /^(RIFF|MOV)$/ ? 0 : (4, 16, 2);
     } elsif ($make =~ /^(General Imaging Co.|GEDSC IMAGING CORP.)/i) {
         push @offsets, 0;
@@ -863,5 +1135,9 @@
         if ($model eq 'S2') {
             # lots of empty space before first value in S2 images
-            push @offsets, 4, ($$exifTool{FILE_TYPE} eq 'JPEG' ? 286 : 274);
+            push @offsets, 4, ($$et{FILE_TYPE} eq 'JPEG' ? 286 : 274);
+        } elsif ($model eq 'LEICA M MONOCHROM (Typ 246)') {
+            push @offsets, 4, 130;
+        } elsif ($model eq 'LEICA M (Typ 240)') {
+            push @offsets, 4, 118;
         } elsif ($model =~ /^(R8|R9|M8)\b/) {
             push @offsets, 6;
@@ -879,10 +1155,14 @@
         push @offsets, 0;
     } elsif ($make =~ /^SONY/) {
-        # DSLR and "PREMI" models use an offset of 4
-        if ($model =~ /DSLR/ or $$exifTool{OlympusCAMER}) {
+        # earlier DSLR and "PREMI" models use an offset of 4
+        if ($model =~ /^(DSLR-.*|SLT-A(33|35|55V)|NEX-(3|5|C3|VG10E))$/ or
+            $$et{OlympusCAMER})
+        {
             push @offsets, 4;
         } else {
             push @offsets, 0;
         }
+    } elsif ($$et{TIFF_TYPE} eq 'SRW' and $make eq 'SAMSUNG' and $model eq 'EK-GN120') {
+        push @offsets, 40;  # patch to read most of the maker notes, but breaks PreviewIFD
     } elsif ($make eq 'FUJIFILM') {
         # some models have offset of 6, so allow that too (A345,A350,A360,A370)
@@ -961,5 +1241,5 @@
 {
     local $_;
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     # don't fix base if fixing offsets individually or if we don't want to fix them
     return 0 if $$dirInfo{FixOffsets} or $$dirInfo{NoFixBase};
@@ -970,5 +1250,5 @@
     my $entryBased = $$dirInfo{EntryBased};
     my $dirName = $$dirInfo{DirName};
-    my $fixBase = $exifTool->Options('FixBase');
+    my $fixBase = $et->Options('FixBase');
     my $setBase = (defined $fixBase and $fixBase ne '') ? 1 : 0;
     my ($fix, $fixedBy, %tagPtr);
@@ -982,5 +1262,5 @@
 # handle special case of Canon maker notes with TIFF footer containing original offset
 #
-    if ($$exifTool{Make} =~ /^Canon/ and $$dirInfo{DirLen} > 8) {
+    if ($$et{Make} =~ /^Canon/ and $$dirInfo{DirLen} > 8) {
         my $footerPos = $dirStart + $$dirInfo{DirLen} - 8;
         my $footer = substr($$dataPt, $footerPos, 8);
@@ -1004,9 +1284,9 @@
                 # (allow for possible padding byte, although I have never seen this)
                 if (not $endDiff or $endDiff == 1) {
-                    $exifTool->Warn('Canon maker note footer may be invalid (ignored)',1);
+                    $et->Warn('Canon maker note footer may be invalid (ignored)',1);
                     return 0;
                 }
             }
-            $exifTool->Warn("Adjusted $dirName base by $fix",1);
+            $et->Warn("Adjusted $dirName base by $fix",1);
             $$dirInfo{FixedBy} = $fix;
             $$dirInfo{Base} += $fix;
@@ -1023,7 +1303,7 @@
     my $ifdLen = 2 + 12 * Get16u($$dirInfo{DataPt}, $dirStart);
     my $ifdEnd = $dirStart + $ifdLen;
-    my ($relative, @offsets) = GetMakerNoteOffset($exifTool);
+    my ($relative, @offsets) = GetMakerNoteOffset($et);
     my $makeDiff = $offsets[0];
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my ($diff, $shift);
 
@@ -1066,12 +1346,12 @@
         # which have been correcting for individual entry position
         $entryBased = 1;
-        $verbose and $exifTool->Warn("$dirName offsets are entry-based",1);
+        $verbose and $et->Warn("$dirName offsets are entry-based",1);
     } else {
         # calculate offset difference from end of IFD to first value
         $diff = ($minPt - $dataPos) - $ifdEnd;
         $shift = 0;
-        $countOverlap and $exifTool->Warn("Overlapping $dirName values",1);
+        $countOverlap and $et->Warn("Overlapping $dirName values",1);
         if ($entryBased) {
-            $exifTool->Warn("$dirName offsets do NOT look entry-based",1);
+            $et->Warn("$dirName offsets do NOT look entry-based",1);
             undef $entryBased;
             undef $relative;
@@ -1087,6 +1367,7 @@
             return 0 if $diff >=0 and $diff <= 24;
         }
-        # (used for testing to extract differences)
-        # $exifTool->FoundTag('Diff', $diff);
+        # ******** (used for testing to extract differences) ********
+        # $et->FoundTag('Diff', $diff);
+        # $et->FoundTag('MakeDiff',$makeDiff);
     }
 #
@@ -1147,5 +1428,5 @@
         # print warning unless difference looks reasonable
         if ($diff < 0 or $diff > 16 or ($diff & 0x01)) {
-            $exifTool->Warn("Possibly incorrect maker notes offsets (fix by $fix?)",1);
+            $et->Warn("Possibly incorrect maker notes offsets (fix by $fix?)",1);
         }
         # don't do the fix (but we already adjusted base if entry-based)
@@ -1153,5 +1434,5 @@
     }
     if (defined $fixedBy) {
-        $exifTool->Warn("Adjusted $dirName base by $fixedBy",1);
+        $et->Warn("Adjusted $dirName base by $fixedBy",1);
         $$dirInfo{FixedBy} = $fixedBy;
     }
@@ -1171,10 +1452,10 @@
 sub LocateIFD($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart} || 0;
     # (ignore MakerNotes DirLen since sometimes this is incorrect)
     my $size = $$dirInfo{DataLen} - $dirStart;
-    my $dirLen = $$dirInfo{DirLen} || $size;
+    my $dirLen = defined $$dirInfo{DirLen} ? $$dirInfo{DirLen} : $size;
     my $tagInfo = $$dirInfo{TagInfo};
     my $ifdOffsetPos;
@@ -1191,5 +1472,5 @@
     if ($tagInfo and $$tagInfo{SubDirectory}) {
         my $subdir = $$tagInfo{SubDirectory};
-        unless ($$subdir{ProcessProc} and 
+        unless ($$subdir{ProcessProc} and
                ($$subdir{ProcessProc} eq \&ProcessUnknown or
                 $$subdir{ProcessProc} eq \&ProcessUnknownOrPreview))
@@ -1220,5 +1501,5 @@
                         my $oldStart = $$dirInfo{DirStart};
                         $$dirInfo{DirStart} = $newStart;
-                        FixLeicaBase($exifTool, $dirInfo);
+                        FixLeicaBase($et, $dirInfo);
                         $$dirInfo{DirStart} = $oldStart;
                     }
@@ -1298,9 +1579,19 @@
                 my $format = Get16u($dataPt, $entry+2);
                 my $count = Get32u($dataPt, $entry+4);
-                # allow everything to be zero if not first entry
-                # because some manufacturers pad with null entries
-                next unless $format or $count or $index == 0;
-                # patch for Canon EOS 40D firmware 1.0.4 bug: allow zero format for last entry
-                next if $format==0 and $index==$num-1 and $$exifTool{Model}=~/EOS 40D/;
+                unless ($format) {
+                    # patch for buggy Samsung NX200 JPEG MakerNotes entry count
+                    if ($num == 23 and $index == 21 and $$et{Make} eq 'SAMSUNG') {
+                        Set16u(21, $dataPt, $pos);  # really 21 IFD entries!
+                        $et->Warn('Fixed incorrect Makernote entry count', 1);
+                        last;
+                    }
+                    # allow everything to be zero if not first entry
+                    # because some manufacturers pad with null entries
+                    next unless $count or $index == 0;
+                    # patch for Canon EOS 40D firmware 1.0.4 bug: allow zero format for last entry
+                    next if $index==$num-1 and $$et{Model}=~/EOS 40D/;
+                }
+                # patch for Sony cameras like the DSC-P10 that have invalid MakerNote entries
+                next if $num == 12 and $$et{Make} eq 'SONY' and $index >= 8;
                 # (would like to verify tag ID, but some manufactures don't
                 #  sort entries in order of tag ID so we don't have much of
@@ -1334,5 +1625,5 @@
 sub FixLeicaBase($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart} || 0;
@@ -1351,5 +1642,5 @@
     my $success = 1;
     if ($tagTablePtr) {
-        $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+        $success = Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
     }
     return $success;
@@ -1362,8 +1653,8 @@
 sub ProcessCanon($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     # identify Canon MakerNote footer in HtmlDump
     # (this code moved from FixBase so it also works for Adobe MakN in DNG images)
-    if ($$exifTool{HTML_DUMP} and $$dirInfo{DirLen} > 8) {
+    if ($$et{HTML_DUMP} and $$dirInfo{DirLen} > 8) {
         my $dataPos = $$dirInfo{DataPos};
         my $dirStart = $$dirInfo{DirStart} || 0;
@@ -1378,9 +1669,9 @@
             }
             my $filePos = ($$dirInfo{Base} || 0) + $dataPos + $footerPos;
-            $exifTool->HDump($filePos, 8, '[Canon MakerNotes footer]', $str);
+            $et->HDump($filePos, 8, '[Canon MakerNotes footer]', $str);
         }
     }
     # process as normal
-    return Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+    return Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
 }
 
@@ -1391,5 +1682,5 @@
 sub ProcessGE2($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt} or return 0;
     my $dirStart = $$dirInfo{DirStart} || 0;
@@ -1398,5 +1689,25 @@
     # always have 25 entries, so write the entry count manually
     Set16u(25, $dataPt, $dirStart);
-    return Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+    return Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
+}
+
+#------------------------------------------------------------------------------
+# Process broken Kodak type 8b maker notes
+# Inputs: 0) ExifTool object ref, 1) DirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessKodakPatch($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt} or return 0;
+    my $dirStart = $$dirInfo{DirStart} || 0;
+
+    # these maker notes have an 2 extra null bytes either before or after the entry count,
+    # so fix this by making a 2-byte entry count just before the first IFD entry
+    return 0 unless $$dirInfo{DirLen} >= 4;
+    my $t1 = Get16u($dataPt,$dirStart);
+    my $t2 = Get16u($dataPt,$dirStart+2);
+    Set16u($t1 || $t2, $dataPt, $dirStart+2);
+    $$dirInfo{DirStart} += 2;
+    return Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
 }
 
@@ -1407,5 +1718,5 @@
 sub ProcessUnknownOrPreview($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
@@ -1413,13 +1724,13 @@
     # check to see if this is a preview image
     if ($dirLen > 6 and substr($$dataPt, $dirStart, 3) eq "\xff\xd8\xff") {
-        $exifTool->VerboseDir('PreviewImage');
-        if ($$exifTool{HTML_DUMP}) {
+        $et->VerboseDir('PreviewImage');
+        if ($$et{HTML_DUMP}) {
             my $pos = $$dirInfo{DataPos} + $$dirInfo{Base} + $dirStart;
-            $exifTool->HDump($pos, $dirLen, '(MakerNotes:PreviewImage data)', "Size: $dirLen bytes")
-        }
-        $exifTool->FoundTag('PreviewImage', substr($$dataPt, $dirStart, $dirLen));
+            $et->HDump($pos, $dirLen, '(MakerNotes:PreviewImage data)', "Size: $dirLen bytes")
+        }
+        $et->FoundTag('PreviewImage', substr($$dataPt, $dirStart, $dirLen));
         return 1;
     }
-    return ProcessUnknown($exifTool, $dirInfo, $tagTablePtr);
+    return ProcessUnknown($et, $dirInfo, $tagTablePtr);
 }
 
@@ -1430,5 +1741,5 @@
 sub WriteUnknownOrPreview($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
@@ -1437,12 +1748,12 @@
     # check to see if this is a preview image
     if ($dirLen > 6 and substr($$dataPt, $dirStart, 3) eq "\xff\xd8\xff") {
-        if ($$exifTool{NEW_VALUE}{$Image::ExifTool::Extra{PreviewImage}}) {
+        if ($$et{NEW_VALUE}{$Image::ExifTool::Extra{PreviewImage}}) {
             # write or delete new preview (if deleted, it can't currently be added back again)
-            $newVal = $exifTool->GetNewValues('PreviewImage') || '';
-            if ($exifTool->Options('Verbose') > 1) {
-                $exifTool->VerboseValue("- MakerNotes:PreviewImage", substr($$dataPt, $dirStart, $dirLen));
-                $exifTool->VerboseValue("+ MakerNotes:PreviewImage", $newVal) if $newVal;
+            $newVal = $et->GetNewValue('PreviewImage') || '';
+            if ($et->Options('Verbose') > 1) {
+                $et->VerboseValue("- MakerNotes:PreviewImage", substr($$dataPt, $dirStart, $dirLen));
+                $et->VerboseValue("+ MakerNotes:PreviewImage", $newVal) if $newVal;
             }
-            ++$$exifTool{CHANGED};
+            ++$$et{CHANGED};
         } else {
             $newVal = substr($$dataPt, $dirStart, $dirLen);
@@ -1450,5 +1761,5 @@
     } else {
         # rewrite MakerNote IFD
-        $newVal = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
+        $newVal = Image::ExifTool::Exif::WriteExif($et, $dirInfo, $tagTablePtr);
     }
     return $newVal;
@@ -1461,21 +1772,21 @@
 sub ProcessUnknown($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $success = 0;
 
-    my $loc = LocateIFD($exifTool, $dirInfo);
+    my $loc = LocateIFD($et, $dirInfo);
     if (defined $loc) {
-        $exifTool->{UnknownByteOrder} = GetByteOrder();
-        if ($exifTool->Options('Verbose') > 1) {
-            my $out = $exifTool->Options('TextOut');
-            my $indent = $exifTool->{INDENT};
+        $$et{UnknownByteOrder} = GetByteOrder();
+        if ($et->Options('Verbose') > 1) {
+            my $out = $et->Options('TextOut');
+            my $indent = $$et{INDENT};
             $indent =~ s/\| $/  /;
             printf $out "${indent}Found IFD at offset 0x%.4x in maker notes:\n",
                     $$dirInfo{DirStart} + $$dirInfo{DataPos} + $$dirInfo{Base};
         }
-        $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+        $success = Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
     } else {
-        $exifTool->{UnknownByteOrder} = ''; # indicates we tried but didn't set byte order
-        $exifTool->Warn("Unrecognized $$dirInfo{DirName}", 1);
+        $$et{UnknownByteOrder} = ''; # indicates we tried but didn't set byte order
+        $et->Warn("Unrecognized $$dirInfo{DirName}", 1);
     }
     return $success;
@@ -1502,5 +1813,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Matroska.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Matroska.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Matroska.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.04';
+$VERSION = '1.10';
 
 my %noYes = ( 0 => 'No', 1 => 'Yes' );
@@ -24,9 +24,10 @@
 %Image::ExifTool::Matroska::Main = (
     GROUPS => { 2 => 'Video' },
+    VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
     NOTES => q{
         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.
@@ -151,5 +152,5 @@
     },
     0x67 => {
-        Name => 'Timecode',
+        Name => 'TimeCode',
         Format => 'unsigned',
         Unknown => 1,
@@ -221,4 +222,6 @@
     0x2e => {
         Name => 'TrackEntry',
+        # reset TrackType member at the start of each track
+        Condition => 'delete $$self{TrackType}; 1',
         SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Main' },
     },
@@ -632,4 +635,46 @@
     0x487 => { Name => 'TagString',         Format => 'utf8' },
     0x485 => { Name => 'TagBinary',         Binary => 1 },
+#
+# Spherical Video V2 (untested)
+#
+    0x7670 => {
+        Name => 'Projection',
+        SubDirectory => { TagTable => 'Image::ExifTool::Matroska::Projection' },
+    },
+);
+
+# Spherical video v2 projection tags (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md)
+%Image::ExifTool::Matroska::Projection = (
+    GROUPS => { 2 => 'Video' },
+    VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
+    NOTES => q{
+        Projection tags defined by the Spherical Video V2 specification.  See
+        L<https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md>
+        for the specification.
+    },
+    0x7671 => {
+        Name => 'ProjectionType',
+        Format => 'unsigned',
+        DataMember => 'ProjectionType',
+        RawConv => '$$self{ProjectionType} = $val',
+        PrintConv => {
+            0 => 'Rectangular',
+            1 => 'Equirectangular',
+            2 => 'Cubemap',
+            3 => 'Mesh',
+        },
+    },
+    0x7672 => [{
+        Name => 'EquirectangularProj',
+        Condition => '$$self{ProjectionType} == 1',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::equi' },
+    },{
+        Name => 'CubemapProj',
+        Condition => '$$self{ProjectionType} == 2',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::cbmp' },
+    }],
+    0x7673 => { Name => 'ProjectionPosYaw',   Format => 'float' },
+    0x7674 => { Name => 'ProjectionPosPitch', Format => 'float' },
+    0x7675 => { Name => 'ProjectionPosRoll',  Format => 'float' },
 );
 
@@ -673,5 +718,5 @@
 sub ProcessMKV($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $buf2, @dirEnd, $trackIndent, %trackTypes);
@@ -688,14 +733,14 @@
     my $hlen = GetVInt($buff, $pos);
     return 0 unless $hlen and $hlen > 0;
-    $pos + $hlen > $dataLen and $exifTool->Warn('Truncated Matroska header'), return 1;
-    $exifTool->SetFileType();
+    $pos + $hlen > $dataLen and $et->Warn('Truncated Matroska header'), return 1;
+    $et->SetFileType();
     SetByteOrder('MM');
     my $tagTablePtr = GetTagTable('Image::ExifTool::Matroska::Main');
 
     # set flag to process entire file (otherwise we stop at the first Cluster)
-    my $verbose = $exifTool->Options('Verbose');
-    my $processAll = ($verbose or $exifTool->Options('Unknown') > 1);
-    $$exifTool{TrackTypes} = \%trackTypes;  # store Track types reference
-    my $oldIndent = $$exifTool{INDENT};
+    my $verbose = $et->Options('Verbose');
+    my $processAll = ($verbose or $et->Options('Unknown') > 1);
+    $$et{TrackTypes} = \%trackTypes;  # store Track types reference
+    my $oldIndent = $$et{INDENT};
     my $chapterNum = 0;
 
@@ -705,6 +750,6 @@
             pop @dirEnd;
             # use INDENT to decide whether or not we are done this Track element
-            delete $$exifTool{SET_GROUP1} if $trackIndent and $trackIndent eq $$exifTool{INDENT};
-            $$exifTool{INDENT} = substr($$exifTool{INDENT}, 0, -2);
+            delete $$et{SET_GROUP1} if $trackIndent and $trackIndent eq $$et{INDENT};
+            $$et{INDENT} = substr($$et{INDENT}, 0, -2);
         }
         # read more if we are getting close to the end of our buffer
@@ -724,5 +769,5 @@
         $size < 0 and $unknownSize = 1, $size = 1e20;
         if (@dirEnd and $pos + $dataPos + $size > $dirEnd[-1][0]) {
-            $exifTool->Warn("Invalid or corrupted $dirEnd[-1][1] master element");
+            $et->Warn("Invalid or corrupted $dirEnd[-1][1] master element");
             $pos = $dirEnd[-1][0] - $dataPos;
             if ($pos < 0 or $pos > $dataLen) {
@@ -735,15 +780,15 @@
             next;
         }
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         # just fall through into the contained EBML elements
         if ($tagInfo and $$tagInfo{SubDirectory}) {
             # stop processing at first cluster unless we are in verbose mode
             last if $$tagInfo{Name} eq 'Cluster' and not $processAll;
-            $$exifTool{INDENT} .= '| ';
-            $exifTool->VerboseDir($$tagTablePtr{$tag}{Name}, undef, $size);
+            $$et{INDENT} .= '| ';
+            $et->VerboseDir($$tagTablePtr{$tag}{Name}, undef, $size);
             push @dirEnd, [ $pos + $dataPos + $size, $$tagInfo{Name} ];
             if ($$tagInfo{Name} eq 'ChapterAtom') {
-                $$exifTool{SET_GROUP1} = 'Chapter' . (++$chapterNum);
-                $trackIndent = $$exifTool{INDENT};
+                $$et{SET_GROUP1} = 'Chapter' . (++$chapterNum);
+                $trackIndent = $$et{INDENT};
             }
             next;
@@ -756,5 +801,5 @@
             if (not $tagInfo or $more > 10000000) {
                 # don't try to skip very large blocks unless LargeFileSupport is enabled
-                last if $more > 0x80000000 and not $exifTool->Options('LargeFileSupport');
+                last if $more >= 0x80000000 and not $et->Options('LargeFileSupport');
                 $raf->Seek($more, 1) or last;
                 $buff = '';
@@ -786,5 +831,5 @@
             if ($fmt eq 'string' or $fmt eq 'utf8') {
                 ($val = substr($buff, $pos, $size)) =~ s/\0.*//s;
-                $val = $exifTool->Decode($val, 'UTF8') if $fmt eq 'utf8';
+                $val = $et->Decode($val, 'UTF8') if $fmt eq 'utf8';
             } elsif ($fmt eq 'float') {
                 if ($size == 4) {
@@ -793,5 +838,5 @@
                     $val = GetDouble(\$buff, $pos);
                 } else {
-                    $exifTool->Warn("Illegal float size ($size)");
+                    $et->Warn("Illegal float size ($size)");
                 }
             } else {
@@ -821,6 +866,6 @@
             # set group1 to Track/Chapter number
             if ($$tagInfo{Name} eq 'TrackNumber') {
-                $$exifTool{SET_GROUP1} = 'Track' . $val;
-                $trackIndent = $$exifTool{INDENT};
+                $$et{SET_GROUP1} = 'Track' . $val;
+                $trackIndent = $$et{INDENT};
             }
         }
@@ -832,18 +877,18 @@
         );
         if ($$tagInfo{NoSave}) {
-            $exifTool->VerboseInfo($tag, $tagInfo, Value => $val, %parms) if $verbose;
+            $et->VerboseInfo($tag, $tagInfo, Value => $val, %parms) if $verbose;
         } else {
-            $exifTool->HandleTag($tagTablePtr, $tag, $val, %parms);
+            $et->HandleTag($tagTablePtr, $tag, $val, %parms);
         }
         $pos += $size;  # step to next element
     }
-    $$exifTool{INDENT} = $oldIndent;
-    delete $$exifTool{SET_GROUP1};
+    $$et{INDENT} = $oldIndent;
+    delete $$et{SET_GROUP1};
     # override file type if necessary based on existing track types
     unless ($trackTypes{0x01} or $trackTypes{0x03}) {   # video or complex?
         if ($trackTypes{0x02}) {                        # audio?
-            $exifTool->OverrideFileType('MKA');
+            $et->OverrideFileType('MKA');
         } elsif ($trackTypes{0x11}) {                   # subtitle?
-            $exifTool->OverrideFileType('MKS');
+            $et->OverrideFileType('MKS');
         }
     }
@@ -870,5 +915,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -889,3 +934,2 @@
 
 =cut
-
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Microsoft.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Microsoft.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Microsoft.pm	(revision 34921)
@@ -5,4 +5,5 @@
 #
 # Revisions:    2010/10/01 - P. Harvey Created
+#               2011/10/05 - PH Added ProcessXtra()
 #
 # References:   1) http://research.microsoft.com/en-us/um/redmond/groups/ivm/hdview/hdmetadataspec.htm
@@ -13,7 +14,10 @@
 use strict;
 use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::XMP;
 
-$VERSION = '1.03';
+$VERSION = '1.20';
+
+sub ProcessXtra($$$);
 
 # tags written by Microsoft HDView (ref 1)
@@ -71,6 +75,6 @@
         Microsoft Photo 1.0 schema XMP tags.  This is likely not a complete list,
         but represents tags which have been observed in sample images.  The actual
-        namespace prefix is "MicrosoftPhoto", but ExifTool shortens this to
-        "XMP-microsoft" in the family 1 group name.
+        namespace prefix is "MicrosoftPhoto", but ExifTool shortens this in the
+        family 1 group name.
     },
     CameraSerialNumber => { },
@@ -81,12 +85,15 @@
     LastKeywordXMP     => { List => 'Bag' },
     LensManufacturer   => { },
-    LensModel          => { },
+    LensModel          => { Avoid => 1 },
     Rating => {
         Name => 'RatingPercent',
         Notes => q{
-            normal Rating values of 1,2,3,4 and 5 stars correspond to RatingPercent
+            XMP-xmp:Rating values of 1,2,3,4 and 5 stars correspond to RatingPercent
             values of 1,25,50,75 and 99 respectively
         },
     },
+    CreatorAppId             => { Name => 'CreatorAppID' },
+    CreatorOpenWithUIOptions => { },
+    ItemSubType              => { },
 );
 
@@ -122,12 +129,30 @@
     PanoramicStitchTheta0 => { Writable => 'real' },
     PanoramicStitchTheta1 => { Writable => 'real' },
+    WhiteBalance0         => { Writable => 'real' },
+    WhiteBalance1         => { Writable => 'real' },
+    WhiteBalance2         => { Writable => 'real' },
+    Brightness            => { Avoid => 1 },
+    Contrast              => { Avoid => 1 },
+    CameraModelID         => { Avoid => 1 },
+    ExposureCompensation  => { Avoid => 1 },
+    PipelineVersion       => { },
+    StreamType            => { },
 );
 
 # Microsoft Photo 1.2 schema properties (MP) (ref PH)
+# (also ref http://msdn.microsoft.com/en-us/library/windows/desktop/ee719905(v=vs.85).aspx)
 my %sRegions = (
-    STRUCT_NAME => 'Regions',
+    STRUCT_NAME => 'Microsoft Regions',
     NAMESPACE   => 'MPReg',
-    Rectangle => { },
+    NOTES => q{
+        Note that PersonLiveIdCID element is called PersonLiveCID according to the
+        Microsoft specification, but in practice their software actually writes
+        PersonLiveIdCID, so ExifTool uses this too.
+    },
+    Rectangle         => { },
     PersonDisplayName => { },
+    PersonEmailDigest => { },
+    PersonLiveIdCID   => { },  # (see https://exiftool.org/forum/index.php?topic=4274.msg20368#msg20368)
+    PersonSourceID    => { },
 );
 %Image::ExifTool::Microsoft::MP = (
@@ -143,19 +168,701 @@
         Name => 'RegionInfoMP',
         Struct => {
-            STRUCT_NAME => 'RegionInfoMP',
+            STRUCT_NAME => 'Microsoft RegionInfo',
             NAMESPACE   => 'MPRI',
             Regions   => { Struct => \%sRegions, List => 'Bag' },
+            DateRegionsValid => {
+                Writable => 'date',
+                Shift => 'Time',
+                Groups => { 2 => 'Time'},
+                PrintConv => '$self->ConvertDateTime($val)',
+                PrintConvInv => '$self->InverseDateTime($val,undef,1)',
+            },
         },
     },
-    RegionInfoRegionsRectangle => {
-        Name => 'RegionRectangle',
-        Flat => 1,
-    },
-    RegionInfoRegionsPersonDisplayName => {
-        Name => 'RegionPersonDisplayName',
-        Flat => 1,
-    },
+    # remove "MP" from tag name (was added only to avoid conflict with XMP-mwg-rs:RegionInfo)
+    RegionInfoRegions                  => { Flat => 1, Name => 'RegionInfoRegions' },
+    RegionInfoDateRegionsValid         => { Flat => 1, Name => 'RegionInfoDateRegionsValid' },
+    # shorten flattened Regions tag names to make them easier to use
+    RegionInfoRegionsRectangle         => { Flat => 1, Name => 'RegionRectangle' },
+    RegionInfoRegionsPersonDisplayName => { Flat => 1, Name => 'RegionPersonDisplayName' },
+    RegionInfoRegionsPersonEmailDigest => { Flat => 1, Name => 'RegionPersonEmailDigest' },
+    RegionInfoRegionsPersonLiveIdCID   => { Flat => 1, Name => 'RegionPersonLiveIdCID' },
+    RegionInfoRegionsPersonSourceID    => { Flat => 1, Name => 'RegionPersonSourceID' },
 );
 
+# Xtra tags written in MP4 files written by Microsoft Windows Media Player
+# (ref http://msdn.microsoft.com/en-us/library/windows/desktop/dd562330(v=VS.85).aspx)
+# Note: These tags are closely related to tags in Image::ExifTool::ASF::ExtendedDescr
+#       and Image::ExifTool::WTV::Metadata
+%Image::ExifTool::Microsoft::Xtra = (
+    PROCESS_PROC => \&ProcessXtra,
+    GROUPS => { 0 => 'QuickTime', 2 => 'Video' },
+    VARS => { NO_ID => 1 },
+    NOTES => q{
+        Tags extracted from the Microsoft "Xtra" atom of QuickTime videos.  Tag ID's
+        are not shown because some are unruly GUID's.
+    },
+    Abstract                    => { },
+    AcquisitionTime             => { Groups => { 2 => 'Time' } },
+    AcquisitionTimeDay          => { Groups => { 2 => 'Time' } },
+    AcquisitionTimeMonth        => { Groups => { 2 => 'Time' } },
+    AcquisitionTimeYear         => { Groups => { 2 => 'Time' } },
+    AcquisitionTimeYearMonth    => { Groups => { 2 => 'Time' } },
+    AcquisitionTimeYearMonthDay => { Groups => { 2 => 'Time' } },
+    AlbumArtistSortOrder        => { },
+    AlbumID                     => { },
+    AlbumIDAlbumArtist          => { },
+    AlbumTitleSortOrder         => { },
+    AlternateSourceURL          => { },
+    AudioBitrate                => { },
+    AudioFormat                 => { },
+    Author                      => { Groups => { 2 => 'Author' } },
+    AuthorSortOrder             => { },
+    AverageLevel                => { },
+    Bitrate                     => { },
+    BuyNow                      => { },
+    BuyTickets                  => { },
+    CallLetters                 => { },
+    CameraManufacturer          => { },
+    CameraModel                 => { },
+    CDTrackEnabled              => { },
+    Channels                    => { },
+    chapterNum                  => { },
+    Comment                     => { },
+    ContentDistributorDuration  => { },
+    Copyright                   => { Groups => { 2 => 'Author' } },
+    Count                       => { },
+    CurrentBitrate              => { },
+    Description                 => { },
+    DisplayArtist               => { },
+    DLNAServerUDN               => { },
+    DLNASourceURI               => { },
+    DRMKeyID                    => { },
+    DRMIndividualizedVersion    => { },
+    DTCPIPHost                  => { },
+    DTCPIPPort                  => { },
+    Duration                    => { },
+    DVDID                       => { },
+    Event                       => { },
+    FileSize                    => { },
+    FileType                    => { },
+    FourCC                      => { },
+    FormatTag                   => { },
+    FrameRate                   => { },
+    Frequency                   => { },
+    IsNetworkFeed               => { },
+    Is_Protected                => 'IsProtected',
+    IsVBR                       => { },
+    LeadPerformer               => { },
+    LibraryID                   => { },
+    LibraryName                 => { },
+    Location                    => { },
+    MediaContentTypes           => { },
+    MediaType                   => { },
+    ModifiedBy                  => { },
+    MoreInfo                    => { },
+    PartOfSet                   => { },
+    PeakValue                   => { },
+    PixelAspectRatioX           => { },
+    PixelAspectRatioY           => { },
+    PlaylistIndex               => { },
+    Provider                    => { },
+    ProviderLogoURL             => { },
+    ProviderURL                 => { },
+    RadioBand                   => { },
+    RadioFormat                 => { },
+    RatingOrg                   => { },
+    RecordingTime               => { Groups => { 2 => 'Time' } },
+    RecordingTimeDay            => { Groups => { 2 => 'Time' } },
+    RecordingTimeMonth          => { Groups => { 2 => 'Time' } },
+    RecordingTimeYear           => { Groups => { 2 => 'Time' } },
+    RecordingTimeYearMonth      => { Groups => { 2 => 'Time' } },
+    RecordingTimeYearMonthDay   => { Groups => { 2 => 'Time' } },
+    ReleaseDate                 => { Groups => { 2 => 'Time' } },
+    ReleaseDateDay              => { Groups => { 2 => 'Time' } },
+    ReleaseDateMonth            => { Groups => { 2 => 'Time' } },
+    ReleaseDateYear             => { Groups => { 2 => 'Time' } },
+    ReleaseDateYearMonth        => { Groups => { 2 => 'Time' } },
+    ReleaseDateYearMonthDay     => { Groups => { 2 => 'Time' } },
+    RequestState                => { },
+    ShadowFilePath              => { },
+    SourceURL                   => { },
+    Subject                     => { },
+    SyncState                   => { },
+    Sync01                      => { },
+    Sync02                      => { },
+    Sync03                      => { },
+    Sync04                      => { },
+    Sync05                      => { },
+    Sync06                      => { },
+    Sync07                      => { },
+    Sync08                      => { },
+    Sync09                      => { },
+    Sync10                      => { },
+    Sync11                      => { },
+    Sync12                      => { },
+    Sync13                      => { },
+    Sync14                      => { },
+    Sync15                      => { },
+    Sync16                      => { },
+    SyncOnly                    => { },
+    Temporary                   => { },
+    Title                       => { },
+    titleNum                    => { },
+    TitleSortOrder              => { },
+    TotalDuration               => { },
+    TrackingID                  => { },
+    UserCustom1                 => { },
+    UserCustom2                 => { },
+    UserEffectiveRating         => { },
+    UserLastPlayedTime          => { },
+    UserPlayCount               => { },
+    UserPlaycountAfternoon      => { },
+    UserPlaycountEvening        => { },
+    UserPlaycountMorning        => { },
+    UserPlaycountNight          => { },
+    UserPlaycountWeekday        => { },
+    UserPlaycountWeekend        => { },
+    UserRating                  => { },
+    UserServiceRating           => { },
+    VideoBitrate                => { },
+    VideoFormat                 => { },
+    'WM/AlbumArtist'            => 'AlbumArtist',
+    'WM/AlbumCoverURL'          => 'AlbumCoverURL',
+    'WM/AlbumTitle'             => 'AlbumTitle',
+    'WM/BeatsPerMinute'         => 'BeatsPerMinute',
+    'WM/Category'               => 'Category',
+    'WM/Composer'               => 'Composer',
+    'WM/Conductor'              => 'Conductor',
+    'WM/ContentDistributor'     => 'ContentDistributor',
+    'WM/ContentDistributorType' => 'ContentDistributorType',
+    'WM/ContentGroupDescription'=> 'ContentGroupDescription',
+    'WM/Director'               => 'Director',
+    'WM/EncodingTime'           => {
+        Name => 'EncodingTime',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    'WM/Genre'                  => 'Genre',
+    'WM/GenreID'                => 'GenreID',
+    'WM/InitialKey'             => 'InitialKey',
+    'WM/Language'               => 'Language',
+    'WM/Lyrics'                 => 'Lyrics',
+    'WM/MCDI'                   => 'MCDI',
+    'WM/MediaClassPrimaryID'    => {
+        Name => 'MediaClassPrimaryID',
+        PrintConv => { #http://msdn.microsoft.com/en-us/library/windows/desktop/dd757960(v=vs.85).aspx
+            'D1607DBC-E323-4BE2-86A1-48A42A28441E' => 'Music',
+            'DB9830BD-3AB3-4FAB-8A37-1A995F7FF74B' => 'Video',
+            '01CD0F29-DA4E-4157-897B-6275D50C4F11' => 'Audio (not music)',
+            'FCF24A76-9A57-4036-990D-E35DD8B244E1' => 'Other (not audio or video)',
+        },
+    },
+    'WM/MediaClassSecondaryID' => {
+        Name => 'MediaClassSecondaryID',
+        PrintConv => { #http://msdn.microsoft.com/en-us/library/windows/desktop/dd757960(v=vs.85).aspx
+            'E0236BEB-C281-4EDE-A36D-7AF76A3D45B5' => 'Audio Book',
+            '3A172A13-2BD9-4831-835B-114F6A95943F' => 'Spoken Word',
+            '6677DB9B-E5A0-4063-A1AD-ACEB52840CF1' => 'Audio News',
+            '1B824A67-3F80-4E3E-9CDE-F7361B0F5F1B' => 'Talk Show',
+            '1FE2E091-4E1E-40CE-B22D-348C732E0B10' => 'Video News',
+            'D6DE1D88-C77C-4593-BFBC-9C61E8C373E3' => 'Web-based Video',
+            '00033368-5009-4AC3-A820-5D2D09A4E7C1' => 'Sound Clip from Game',
+            'F24FF731-96FC-4D0F-A2F5-5A3483682B1A' => 'Song from Game',
+            'E3E689E2-BA8C-4330-96DF-A0EEEFFA6876' => 'Music Video',
+            'B76628F4-300D-443D-9CB5-01C285109DAF' => 'Home Movie',
+            'A9B87FC9-BD47-4BF0-AC4F-655B89F7D868' => 'Feature Film',
+            'BA7F258A-62F7-47A9-B21F-4651C42A000E' => 'TV Show',
+            '44051B5B-B103-4B5C-92AB-93060A9463F0' => 'Corporate Video',
+            '0B710218-8C0C-475E-AF73-4C41C0C8F8CE' => 'Home Video from Pictures',
+            '00000000-0000-0000-0000-000000000000' => 'Unknown Content', #PH
+        },
+    },
+    'WM/MediaOriginalBroadcastDateTime' => {
+        Name => 'MediaOriginalBroadcastDateTime',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    'WM/MediaOriginalChannel'   => 'MediaOriginalChannel',
+    'WM/MediaStationName'       => 'MediaStationName',
+    'WM/Mood'                   => 'Mood',
+    'WM/OriginalAlbumTitle'     => 'OriginalAlbumTitle',
+    'WM/OriginalArtist'         => 'OriginalArtist',
+    'WM/OriginalLyricist'       => 'OriginalLyricist',
+    'WM/ParentalRating'         => 'ParentalRating',
+    'WM/PartOfSet'              => 'PartOfSet',
+    'WM/Period'                 => 'Period',
+    'WM/Producer'               => 'Producer',
+    'WM/ProtectionType'         => 'ProtectionType',
+    'WM/Provider'               => 'Provider',
+    'WM/ProviderRating'         => 'ProviderRating',
+    'WM/ProviderStyle'          => 'ProviderStyle',
+    'WM/Publisher'              => 'Publisher',
+    'WM/SharedUserRating'       => 'SharedUserRating',
+    'WM/SubscriptionContentID'  => 'SubscriptionContentID',
+    'WM/SubTitle'               => 'Subtitle',
+    'WM/SubTitleDescription'    => 'SubtitleDescription',
+    'WM/TrackNumber'            => 'TrackNumber',
+    'WM/UniqueFileIdentifier'   => 'UniqueFileIdentifier',
+    'WM/VideoFrameRate'         => 'VideoFrameRate',
+    'WM/VideoHeight'            => 'VideoHeight',
+    'WM/VideoWidth'             => 'VideoWidth',
+    'WM/WMCollectionGroupID'    => 'WMCollectionGroupID',
+    'WM/WMCollectionID'         => 'WMCollectionID',
+    'WM/WMContentID'            => 'WMContentID',
+    'WM/WMShadowFileSourceDRMType' => 'WMShadowFileSourceDRMType',
+    'WM/WMShadowFileSourceFileType' => 'WMShadowFileSourceFileType',
+    'WM/Writer'                 => 'Writer',
+    'WM/Year'                   => { Name => 'Year', Groups => { 2 => 'Time' } },
+
+    # I can't find documentation for the following tags in videos,
+    # but the tag ID's correspond to Microsoft property GUID+ID's
+    # References:
+    #  http://msdn.microsoft.com/en-us/library/cc251929%28v=prot.10%29.aspx
+    #  http://multi-rename-script.googlecode.com/svn-history/r4/trunk/plugins/ShellDetails/ShellDetails.ini
+    # I have observed only 1 so far:
+    '{2CBAA8F5-D81F-47CA-B17A-F8D822300131} 100' => {
+        Name => 'DateAcquired',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    # the following have not yet been observed...
+    '{B725F130-47EF-101A-A5F1-02608C9EEBAC} 10'    => 'Name',
+    '{B725F130-47EF-101A-A5F1-02608C9EEBAC} 12'    => 'Size',
+    '{B725F130-47EF-101A-A5F1-02608C9EEBAC} 4'     => 'Type',
+    '{B725F130-47EF-101A-A5F1-02608C9EEBAC} 14'    => {
+        Name => 'DateModified',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{B725F130-47EF-101A-A5F1-02608C9EEBAC} 15'    => {
+        Name => 'DateCreated',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{B725F130-47EF-101A-A5F1-02608C9EEBAC} 16'    => {
+        Name => 'DateAccessed',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{B725F130-47EF-101A-A5F1-02608C9EEBAC} 13'    => 'Attributes',
+    '{D8C3986F-813B-449C-845D-87B95D674ADE} 2'     => 'Status',
+    '{9B174B34-40FF-11D2-A27E-00C04FC30871} 4'     => 'Owner',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 4'     => {
+        Name => 'Author',
+        Groups => { 2 => 'Author' },
+    },
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 2'     => 'Title',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 3'     => 'Subject',
+    '{D5CDD502-2E9C-101B-9397-08002B2CF9AE} 2'     => 'Category',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 14'    => 'Pages',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 6'     => 'Comments',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 11'    => {
+        Name => 'Copyright',
+        Groups => { 2 => 'Author' },
+    },
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 2'     => 'Artist',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 4'     => 'AlbumTitle',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 5'     => {
+        Name => 'Year',
+        Groups => { 2 => 'Time' },
+    },
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 7'     => 'TrackNumber',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 11'    => 'Genre',
+    '{64440490-4C8B-11D1-8B70-080036B11A03} 3'     => 'Duration',
+    '{64440490-4C8B-11D1-8B70-080036B11A03} 4'     => 'Bitrate',
+    '{AEAC19E4-89AE-4508-B9B7-BB867ABEE2ED} 2'     => 'Protected',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 272'   => 'CameraModel',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 36867' => {
+        Name => 'DatePictureTaken',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{6444048F-4C8B-11D1-8B70-080036B11A03} 13'    => 'Dimensions',
+    '{6444048F-4C8B-11D1-8B70-080036B11A03} 3'     => 'Untitled0',
+    '{6444048F-4C8B-11D1-8B70-080036B11A03} 4'     => 'Untitled1',
+    '{6D748DE2-8D38-4CC3-AC60-F009B057C557} 2'     => 'EpisodeName',
+    '{6D748DE2-8D38-4CC3-AC60-F009B057C557} 3'     => 'ProgramDescription',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 12'    => 'Untitled2',
+    '{64440490-4C8B-11D1-8B70-080036B11A03} 6'     => 'AudioSampleSize',
+    '{64440490-4C8B-11D1-8B70-080036B11A03} 5'     => 'AudioSampleRate',
+    '{64440490-4C8B-11D1-8B70-080036B11A03} 7'     => 'Channels',
+    '{D5CDD502-2E9C-101B-9397-08002B2CF9AE} 15'    => 'Company',
+    '{0CEF7D53-FA64-11D1-A203-0000F81FEDEE} 3'     => 'Description',
+    '{0CEF7D53-FA64-11D1-A203-0000F81FEDEE} 4'     => 'FileVersion',
+    '{0CEF7D53-FA64-11D1-A203-0000F81FEDEE} 7'     => 'ProductName',
+    '{0CEF7D53-FA64-11D1-A203-0000F81FEDEE} 8'     => 'ProductVersion',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 5'     => 'Keywords',
+    '{28636AA6-953D-11D2-B5D6-00C04FD918D0} 11'    => 'Type',
+    '{6D24888F-4718-4BDA-AFED-EA0FB4386CD8} 100'   => 'OfflineStatus',
+    '{A94688B6-7D9F-4570-A648-E3DFC0AB2B3F} 100'   => 'OfflineAvailability',
+    '{28636AA6-953D-11D2-B5D6-00C04FD918D0} 9'     => 'PerceivedType',
+    '{1E3EE840-BC2B-476C-8237-2ACD1A839B22} 3'     => 'Kinds',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 36'    => 'Conductors',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 9'     => 'Rating',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 271'   => 'CameraMaker',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 18'    => 'ProgramName',
+    '{293CA35A-09AA-4DD2-B180-1FE245728A52} 100'   => 'Duration',
+    '{BFEE9149-E3E2-49A7-A862-C05988145CEC} 100'   => 'IsOnline',
+    '{315B9C8D-80A9-4EF9-AE16-8E746DA51D70} 100'   => 'IsRecurring',
+    '{F6272D18-CECC-40B1-B26A-3911717AA7BD} 100'   => 'Location',
+    '{D55BAE5A-3892-417A-A649-C6AC5AAAEAB3} 100'   => 'OptionalAttendeeAddresses',
+    '{09429607-582D-437F-84C3-DE93A2B24C3C} 100'   => 'OptionalAttendees',
+    '{744C8242-4DF5-456C-AB9E-014EFB9021E3} 100'   => 'OrganizerAddress',
+    '{AAA660F9-9865-458E-B484-01BC7FE3973E} 100'   => 'OrganizerName',
+    '{72FC5BA4-24F9-4011-9F3F-ADD27AFAD818} 100'   => 'ReminderTime',
+    '{0BA7D6C3-568D-4159-AB91-781A91FB71E5} 100'   => 'RequiredAttendeeAddresses',
+    '{B33AF30B-F552-4584-936C-CB93E5CDA29F} 100'   => 'RequiredAttendees',
+    '{00F58A38-C54B-4C40-8696-97235980EAE1} 100'   => 'Resources',
+    '{5BF396D4-5EB2-466F-BDE9-2FB3F2361D6E} 100'   => 'Free-busyStatus',
+    '{9B174B35-40FF-11D2-A27E-00C04FC30871} 3'     => 'TotalSize',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 9'     => 'AccountName',
+    '{28636AA6-953D-11D2-B5D6-00C04FD918D0} 5'     => 'Computer',
+    '{9AD5BADB-CEA7-4470-A03D-B84E51B9949E} 100'   => 'Anniversary',
+    '{CD102C9C-5540-4A88-A6F6-64E4981C8CD1} 100'   => 'AssistantsName',
+    '{9A93244D-A7AD-4FF8-9B99-45EE4CC09AF6} 100'   => 'AssistantsPhone',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 47'    => 'Birthday',
+    '{730FB6DD-CF7C-426B-A03F-BD166CC9EE24} 100'   => 'BusinessAddress',
+    '{402B5934-EC5A-48C3-93E6-85E86A2D934E} 100'   => 'BusinessCity',
+    '{B0B87314-FCF6-4FEB-8DFF-A50DA6AF561C} 100'   => 'BusinessCountry-Region',
+    '{BC4E71CE-17F9-48D5-BEE9-021DF0EA5409} 100'   => 'BusinessPOBox',
+    '{E1D4A09E-D758-4CD1-B6EC-34A8B5A73F80} 100'   => 'BusinessPostalCode',
+    '{446F787F-10C4-41CB-A6C4-4D0343551597} 100'   => 'BusinessStateOrProvince',
+    '{DDD1460F-C0BF-4553-8CE4-10433C908FB0} 100'   => 'BusinessStreet',
+    '{91EFF6F3-2E27-42CA-933E-7C999FBE310B} 100'   => 'BusinessFax',
+    '{56310920-2491-4919-99CE-EADB06FAFDB2} 100'   => 'BusinessHomePage',
+    '{6A15E5A0-0A1E-4CD7-BB8C-D2F1B0C929BC} 100'   => 'BusinessPhone',
+    '{BF53D1C3-49E0-4F7F-8567-5A821D8AC542} 100'   => 'CallbackNumber',
+    '{8FDC6DEA-B929-412B-BA90-397A257465FE} 100'   => 'CarPhone',
+    '{D4729704-8EF1-43EF-9024-2BD381187FD5} 100'   => 'Children',
+    '{8589E481-6040-473D-B171-7FA89C2708ED} 100'   => 'CompanyMainPhone',
+    '{FC9F7306-FF8F-4D49-9FB6-3FFE5C0951EC} 100'   => 'Department',
+    '{F8FA7FA3-D12B-4785-8A4E-691A94F7A3E7} 100'   => 'E-mailAddress',
+    '{38965063-EDC8-4268-8491-B7723172CF29} 100'   => 'E-mail2',
+    '{644D37B4-E1B3-4BAD-B099-7E7C04966ACA} 100'   => 'E-mail3',
+    '{84D8F337-981D-44B3-9615-C7596DBA17E3} 100'   => 'E-mailList',
+    '{CC6F4F24-6083-4BD4-8754-674D0DE87AB8} 100'   => 'E-mailDisplayName',
+    '{F1A24AA7-9CA7-40F6-89EC-97DEF9FFE8DB} 100'   => 'FileAs',
+    '{14977844-6B49-4AAD-A714-A4513BF60460} 100'   => 'FirstName',
+    '{635E9051-50A5-4BA2-B9DB-4ED056C77296} 100'   => 'FullName',
+    '{3C8CEE58-D4F0-4CF9-B756-4E5D24447BCD} 100'   => 'Gender',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 70'    => 'GivenName',
+    '{5DC2253F-5E11-4ADF-9CFE-910DD01E3E70} 100'   => 'Hobbies',
+    '{98F98354-617A-46B8-8560-5B1B64BF1F89} 100'   => 'HomeAddress',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 65'    => 'HomeCity',
+    '{08A65AA1-F4C9-43DD-9DDF-A33D8E7EAD85} 100'   => 'HomeCountry-Region',
+    '{7B9F6399-0A3F-4B12-89BD-4ADC51C918AF} 100'   => 'HomePOBox',
+    '{8AFCC170-8A46-4B53-9EEE-90BAE7151E62} 100'   => 'HomePostalCode',
+    '{C89A23D0-7D6D-4EB8-87D4-776A82D493E5} 100'   => 'HomeStateOrProvince',
+    '{0ADEF160-DB3F-4308-9A21-06237B16FA2A} 100'   => 'HomeStreet',
+    '{660E04D6-81AB-4977-A09F-82313113AB26} 100'   => 'HomeFax',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 20'    => 'HomePhone',
+    '{D68DBD8A-3374-4B81-9972-3EC30682DB3D} 100'   => 'IMAddresses',
+    '{F3D8F40D-50CB-44A2-9718-40CB9119495D} 100'   => 'Initials',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 6'     => 'JobTitle',
+    '{97B0AD89-DF49-49CC-834E-660974FD755B} 100'   => 'Label',
+    '{8F367200-C270-457C-B1D4-E07C5BCD90C7} 100'   => 'LastName',
+    '{C0AC206A-827E-4650-95AE-77E2BB74FCC9} 100'   => 'MailingAddress',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 71'    => 'MiddleName',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 35'    => 'CellPhone',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 74'    => 'Nickname',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 7'     => 'OfficeLocation',
+    '{508161FA-313B-43D5-83A1-C1ACCF68622C} 100'   => 'OtherAddress',
+    '{6E682923-7F7B-4F0C-A337-CFCA296687BF} 100'   => 'OtherCity',
+    '{8F167568-0AAE-4322-8ED9-6055B7B0E398} 100'   => 'OtherCountry-Region',
+    '{8B26EA41-058F-43F6-AECC-4035681CE977} 100'   => 'OtherPOBox',
+    '{95C656C1-2ABF-4148-9ED3-9EC602E3B7CD} 100'   => 'OtherPostalCode',
+    '{71B377D6-E570-425F-A170-809FAE73E54E} 100'   => 'OtherStateOrProvince',
+    '{FF962609-B7D6-4999-862D-95180D529AEA} 100'   => 'OtherStreet',
+    '{D6304E01-F8F5-4F45-8B15-D024A6296789} 100'   => 'Pager',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 69'    => 'PersonalTitle',
+    '{C8EA94F0-A9E3-4969-A94B-9C62A95324E0} 100'   => 'City',
+    '{E53D799D-0F3F-466E-B2FF-74634A3CB7A4} 100'   => 'Country-Region',
+    '{DE5EF3C7-46E1-484E-9999-62C5308394C1} 100'   => 'POBox',
+    '{18BBD425-ECFD-46EF-B612-7B4A6034EDA0} 100'   => 'PostalCode',
+    '{F1176DFE-7138-4640-8B4C-AE375DC70A6D} 100'   => 'StateOrProvince',
+    '{63C25B20-96BE-488F-8788-C09C407AD812} 100'   => 'Street',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 48'    => 'PrimaryE-mail',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 25'    => 'PrimaryPhone',
+    '{7268AF55-1CE4-4F6E-A41F-B6E4EF10E4A9} 100'   => 'Profession',
+    '{9D2408B6-3167-422B-82B0-F583B7A7CFE3} 100'   => 'Spouse',
+    '{176DC63C-2688-4E89-8143-A347800F25E9} 73'    => 'Suffix',
+    '{AAF16BAC-2B55-45E6-9F6D-415EB94910DF} 100'   => 'TTY-TTDPhone',
+    '{C554493C-C1F7-40C1-A76C-EF8C0614003E} 100'   => 'Telex',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 18'    => 'Webpage',
+    '{D5CDD502-2E9C-101B-9397-08002B2CF9AE} 27'    => 'Status',
+    '{D5CDD502-2E9C-101B-9397-08002B2CF9AE} 26'    => 'ContentType',
+    '{43F8D7B7-A444-4F87-9383-52271C9B915C} 100'   => {
+        Name => 'DateArchived',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{72FAB781-ACDA-43E5-B155-B2434F85E678} 100'   => {
+        Name => 'DateCompleted',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 18258' => {
+        Name => 'DateImported',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{276D7BB0-5B34-4FB0-AA4B-158ED12A1809} 100'   => 'ClientID',
+    '{F334115E-DA1B-4509-9B3D-119504DC7ABB} 100'   => 'Contributors',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 11'    => 'LastPrinted',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 13'    => {
+        Name => 'DateLastSaved',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{1E005EE6-BF27-428B-B01C-79676ACD2870} 100'   => 'Division',
+    '{E08805C8-E395-40DF-80D2-54F0D6C43154} 100'   => 'DocumentID',
+    '{D5CDD502-2E9C-101B-9397-08002B2CF9AE} 7'     => 'Slides',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 10'    => 'TotalEditingTime',
+    '{F29F85E0-4FF9-1068-AB91-08002B27B3D9} 15'    => 'WordCount',
+    '{3F8472B5-E0AF-4DB2-8071-C53FE76AE7CE} 100'   => 'DueDate',
+    '{C75FAA05-96FD-49E7-9CB4-9F601082D553} 100'   => 'EndDate',
+    '{28636AA6-953D-11D2-B5D6-00C04FD918D0} 12'    => 'FileCount',
+    '{41CF5AE0-F75A-4806-BD87-59C7D9248EB9} 100'   => 'WindowsFileName',
+    '{67DF94DE-0CA7-4D6F-B792-053A3E4F03CF} 100'   => 'FlagColor',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 12'    => 'FlagStatus',
+    '{9B174B35-40FF-11D2-A27E-00C04FC30871} 2'     => 'SpaceFree',
+    '{6444048F-4C8B-11D1-8B70-080036B11A03} 7'     => 'BitDepth',
+    '{6444048F-4C8B-11D1-8B70-080036B11A03} 5'     => 'HorizontalResolution',
+    '{6444048F-4C8B-11D1-8B70-080036B11A03} 6'     => 'VerticalResolution',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 11'    => 'Importance',
+    '{F23F425C-71A1-4FA8-922F-678EA4A60408} 100'   => 'IsAttachment',
+    '{5CDA5FC8-33EE-4FF3-9094-AE7BD8868C4D} 100'   => 'IsDeleted',
+    '{5DA84765-E3FF-4278-86B0-A27967FBDD03} 100'   => 'HasFlag',
+    '{A6F360D2-55F9-48DE-B909-620E090A647C} 100'   => 'IsCompleted',
+    '{346C8BD1-2E6A-4C45-89A4-61B78E8E700F} 100'   => 'Incomplete',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 10'    => 'ReadStatus',
+    '{EF884C5B-2BFE-41BB-AAE5-76EEDF4F9902} 100'   => 'Shared',
+    '{D0A04F0A-462A-48A4-BB2F-3706E88DBD7D} 100'   => {
+        Name => 'Creator',
+        Groups => { 2 => 'Author' },
+    },
+    '{F7DB74B4-4287-4103-AFBA-F1B13DCD75CF} 100'   => {
+        Name => 'Date',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{B725F130-47EF-101A-A5F1-02608C9EEBAC} 2'     => 'FolderName',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 6'     => 'FolderPath',
+    '{DABD30ED-0043-4789-A7F8-D013A4736622} 100'   => 'Folder',
+    '{D4D0AA16-9948-41A4-AA85-D97FF9646993} 100'   => 'Participants',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 7'     => 'Path',
+    '{DEA7C82C-1D89-4A66-9427-A4E3DEBABCB1} 100'   => 'ContactNames',
+    '{95BEB1FC-326D-4644-B396-CD3ED90E6DDF} 100'   => 'EntryType',
+    '{D5CDD502-2E9C-101B-9397-08002B2CF9AE} 28'    => 'Language',
+    '{5CBF2787-48CF-4208-B90E-EE5E5D420294} 23'    => {
+        Name => 'DateVisited',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{5CBF2787-48CF-4208-B90E-EE5E5D420294} 21'    => 'Description',
+    '{B9B4B3FC-2B51-4A42-B5D8-324146AFCF25} 3'     => 'LinkStatus',
+    '{B9B4B3FC-2B51-4A42-B5D8-324146AFCF25} 2'     => 'LinkTarget',
+    '{5CBF2787-48CF-4208-B90E-EE5E5D420294} 2'     => 'URL',
+    '{2E4B640D-5019-46D8-8881-55414CC5CAA0} 100'   => 'MediaCreated',
+    '{DE41CC29-6971-4290-B472-F59F2E2F31E2} 100'   => {
+        Name => 'DateReleased',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 36'    => 'EncodedBy',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 22'    => 'Producers',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 30'    => 'Publisher',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 38'    => 'Subtitle',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 34'    => 'UserWebURL',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 23'    => 'Writers',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 21'    => 'Attachments',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 2'     => 'BccAddresses',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 3'     => 'BccNames',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 4'     => 'CcAddresses',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 5'     => 'CcNames',
+    '{DC8F80BD-AF1E-4289-85B6-3DFC1B493992} 100'   => 'ConversationID',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 20'    => {
+        Name => 'DateReceived',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 19'    => {
+        Name => 'DateSent',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 13'    => 'FromAddresses',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 14'    => 'FromNames',
+    '{9C1FCF74-2D97-41BA-B4AE-CB2E3661A6E4} 8'     => 'HasAttachments',
+    '{0BE1C8E7-1981-4676-AE14-FDD78F05A6E7} 100'   => 'SenderAddress',
+    '{0DA41CFA-D224-4A18-AE2F-596158DB4B3A} 100'   => 'SenderName',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 15'    => 'Store',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 16'    => 'ToAddresses',
+    '{BCCC8A3C-8CEF-42E5-9B1C-C69079398BC7} 100'   => 'ToDoTitle',
+    '{E3E0584C-B788-4A5A-BB20-7F5A44C9ACDD} 17'    => 'ToNames',
+    '{FDF84370-031A-4ADD-9E91-0D775F1C6605} 100'   => 'Mileage',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 13'    => 'AlbumArtist',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 35'    => 'Beats-per-minute',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 19'    => 'Composers',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 34'    => 'InitialKey',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 39'    => 'Mood',
+    '{56A3372E-CE9C-11D2-9F0E-006097C686F6} 37'    => 'PartOfSet',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 31'    => 'Period',
+    '{4776CAFA-BCE4-4CB1-A23E-265E76D8EB11} 100'   => 'Color',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 21'    => 'ParentalRating',
+    '{10984E0A-F9F2-4321-B7EF-BAF195AF4319} 100'   => 'ParentalRatingReason',
+    '{9B174B35-40FF-11D2-A27E-00C04FC30871} 5'     => 'SpaceUsed',
+    '{D35F743A-EB2E-47F2-A286-844132CB1427} 100'   => 'ExifVersion',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 18248' => 'Event',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 37380' => 'ExposureBias',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 34850' => 'ExposureProgram',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 33434' => 'ExposureTime',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 33437' => 'F-stop',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 37385' => 'FlashMode',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 37386' => 'FocalLength',
+    '{A0E74609-B84D-4F49-B860-462BD9971F98} 100'   => 'FocalLength35mm',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 34855' => 'ISOSpeed',
+    '{E6DDCAF7-29C5-4F0A-9A68-D19412EC7090} 100'   => 'LensMaker',
+    '{E1277516-2B5F-4869-89B1-2E585BD38B7A} 100'   => 'LensModel',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 37384' => 'LightSource',
+    '{08F6D7C2-E3F2-44FC-AF1E-5AA5C81A2D3E} 100'   => 'MaxAperture',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 37383' => 'MeteringMode',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 274'   => 'Orientation',
+    '{6D217F6D-3F6A-4825-B470-5F03CA2FBE9B} 100'   => 'ProgramMode',
+    '{49237325-A95A-4F67-B211-816B2D45D2E0} 100'   => 'Saturation',
+    '{14B81DA1-0135-4D31-96D9-6CBFC9671A99} 37382' => 'SubjectDistance',
+    '{EE3D3D8A-5381-4CFA-B13B-AAF66B5F4EC9} 100'   => 'WhiteBalance',
+    '{9C1FCF74-2D97-41BA-B4AE-CB2E3661A6E4} 5'     => 'Priority',
+    '{39A7F922-477C-48DE-8BC8-B28441E342E3} 100'   => 'Project',
+    '{6D748DE2-8D38-4CC3-AC60-F009B057C557} 7'     => 'ChannelNumber',
+    '{6D748DE2-8D38-4CC3-AC60-F009B057C557} 12'    => 'ClosedCaptioning',
+    '{6D748DE2-8D38-4CC3-AC60-F009B057C557} 13'    => 'Rerun',
+    '{6D748DE2-8D38-4CC3-AC60-F009B057C557} 14'    => 'SAP',
+    '{4684FE97-8765-4842-9C13-F006447B178C} 100'   => 'BroadcastDate',
+    '{A5477F61-7A82-4ECA-9DDE-98B69B2479B3} 100'   => 'RecordingTime',
+    '{6D748DE2-8D38-4CC3-AC60-F009B057C557} 5'     => 'StationCallSign',
+    '{1B5439E7-EBA1-4AF8-BDD7-7AF1D4549493} 100'   => 'StationName',
+    '{560C36C0-503A-11CF-BAA1-00004C752A9A} 2'     => 'AutoSummary',
+    '{560C36C0-503A-11CF-BAA1-00004C752A9A} 3'     => 'Summary',
+    '{49691C90-7E17-101A-A91C-08002B2ECDA9} 3'     => 'SearchRanking',
+    '{F8D3F6AC-4874-42CB-BE59-AB454B30716A} 100'   => 'Sensitivity',
+    '{EF884C5B-2BFE-41BB-AAE5-76EEDF4F9902} 200'   => 'SharedWith',
+    '{668CDFA5-7A1B-4323-AE4B-E527393A1D81} 100'   => 'Source',
+    '{48FD6EC8-8A12-4CDF-A03E-4EC5A511EDDE} 100'   => 'StartDate',
+    '{D37D52C6-261C-4303-82B3-08B926AC6F12} 100'   => 'BillingInformation',
+    '{084D8A0A-E6D5-40DE-BF1F-C8820E7C877C} 100'   => 'Complete',
+    '{08C7CC5F-60F2-4494-AD75-55E3E0B5ADD0} 100'   => 'TaskOwner',
+    '{28636AA6-953D-11D2-B5D6-00C04FD918D0} 14'    => 'TotalFileSize',
+    '{0CEF7D53-FA64-11D1-A203-0000F81FEDEE} 9'     => 'LegalTrademarks',
+    '{64440491-4C8B-11D1-8B70-080036B11A03} 10'    => 'VideoCompression',
+    '{64440492-4C8B-11D1-8B70-080036B11A03} 20'    => 'Directors',
+    '{64440491-4C8B-11D1-8B70-080036B11A03} 8'     => 'DataRate',
+    '{64440491-4C8B-11D1-8B70-080036B11A03} 4'     => 'FrameHeight',
+    '{64440491-4C8B-11D1-8B70-080036B11A03} 6'     => 'FrameRate',
+    '{64440491-4C8B-11D1-8B70-080036B11A03} 3'     => 'FrameWidth',
+    '{64440491-4C8B-11D1-8B70-080036B11A03} 43'    => 'TotalBitrate',
+);
+
+#------------------------------------------------------------------------------
+# Extract information from Xtra MP4 atom
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+# Reference: http://code.google.com/p/mp4v2/ [since removed from trunk]
+sub ProcessXtra($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{Base} || 0;
+    my $dataLen = $$dirInfo{DataLen};
+    my $pos = 0;
+    $et->VerboseDir('Xtra', 0, $dataLen);
+    for (;;) {
+        last if $pos + 4 > $dataLen;
+        my $size = Get32u($dataPt, $pos); # (includes $size word)
+        last if $size < 8 or $pos + $size > $dataLen;
+        my $tagLen = Get32u($dataPt, $pos + 4);
+        last if $tagLen + 18 > $size;
+        my $tag = substr($$dataPt, $pos + 8, $tagLen);
+        # (version flags according to the reference, but looks more like a count - PH)
+        my $count = Get32u($dataPt, $pos + $tagLen + 8);
+        my ($i, $valPos, $valLen, $valType, $val, $format, @vals);
+        # point to start of first value (after 4-byte length and 2-byte type)
+        $valPos = $pos + $tagLen + 18;
+        for ($i=0; ;) {
+            # (stored value includes size of $valLen and $valType, so subtract 6)
+            $valLen  = Get32u($dataPt, $valPos - 6) - 6;
+            my $more = $pos + $size - $valPos - $valLen;
+            last if $more < 0;
+            $valType = Get16u($dataPt, $valPos - 2);
+            $val = substr($$dataPt, $valPos, $valLen);
+            # Note: all dumb Microsoft values are little-endian inside a big-endian-format file
+            SetByteOrder('II');
+            if ($valType == 8) {
+                $format = 'Unicode';
+                $val = $et->Decode($val, 'UCS2');
+            } elsif ($valType == 19 and $valLen == 8) {
+                $format = 'int64u';
+                $val = Get64u(\$val, 0);
+            } elsif ($valType == 21 and $valLen == 8) {
+                $format = 'date';
+                $val = Get64u(\$val, 0);
+                # convert time from 100 ns intervals since Jan 1, 1601
+                $val = $val * 1e-7 - 11644473600 if $val;
+                # (the Nikon S100 uses UTC timezone, same as ASF - PH)
+                $val = Image::ExifTool::ConvertUnixTime($val) . 'Z';
+            } elsif ($valType == 72 and $valLen == 16) {
+                $format = 'GUID';
+                $val = uc unpack('H*',pack('NnnNN',unpack('VvvNN',$val)));
+                $val =~ s/(.{8})(.{4})(.{4})(.{4})/$1-$2-$3-$4-/;
+            } elsif ($valType == 65 && $valLen > 4) { #PH (empirical)
+                $format = 'variant';
+                require Image::ExifTool::FlashPix;
+                my $vPos = $valPos; # (necessary because ReadFPXValue updates this)
+                # read entry as a VT_VARIANT (use FlashPix module for this)
+                $val = Image::ExifTool::FlashPix::ReadFPXValue($et, $dataPt, $vPos,
+                       Image::ExifTool::FlashPix::VT_VARIANT(), $valPos+$valLen, 1);
+            } else {
+                $format = "Unknown($valType)";
+            }
+            SetByteOrder('MM'); # back to native QuickTime byte ordering
+            last if ++$i >= $count or $more < 6;
+            push @vals, $val;
+            undef $val;
+            $valPos += $valLen + 6; # step to next value
+        }
+        if (@vals) {
+            push @vals, $val if defined $val;
+            $val = \@vals;
+            $valPos = $pos + $tagLen + 18;
+            $valLen = $size - 18 - $tagLen;
+        }
+        if ($tagLen > 0 and $valLen > 0) {
+            my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+            unless ($tagInfo) {
+                # generate tag information for unrecognized tags
+                my $name = $tag;
+                $name =~ s{^WM/}{};
+              # $name =~ tr/-_A-Za-z0-9//dc;
+                if ($name =~ /^[-\w]+$/) {
+                    $tagInfo = { Name => ucfirst($name) };
+                    AddTagToTable($tagTablePtr, $tag, $tagInfo);
+                    $et->VPrint(0, $$et{INDENT}, "[adding Microsoft:$tag]\n");
+                }
+            }
+            $et->HandleTag($tagTablePtr, $tag, $val,
+                TagInfo => $tagInfo,
+                DataPt  => $dataPt,
+                DataPos => $dataPos,
+                Start   => $valPos,
+                Size    => $valLen,
+                Format  => $format,
+                Extra   => " count=$count type=$valType",
+            );
+        }
+        $pos += $size;  # step to next entry
+    }
+    return 1;
+}
 
 1;  # end
@@ -178,5 +885,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Minolta.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Minolta.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Minolta.pm	(revision 34921)
@@ -10,5 +10,4 @@
 #               2) Jay Al-Saadi private communication (testing with A2)
 #               3) Shingo Noguchi, PhotoXP (http://www.daifukuya.com/photoxp/)
-#               4) Niels Kristian Bech Jensen private communication
 #               5) http://www.cybercom.net/~dcoffin/dcraw/
 #               6) Pedro Corte-Real private communication
@@ -33,5 +32,12 @@
 #              23) Marcin Krol private communication
 #              24) http://cpanforum.com/threads/12291
+#              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) 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
+#              NJ) Niels Kristian Bech Jensen private communication
 #------------------------------------------------------------------------------
 
@@ -39,9 +45,134 @@
 
 use strict;
-use vars qw($VERSION %minoltaLensTypes %minoltaColorMode %sonyColorMode %minoltaSceneMode);
+use vars qw($VERSION %minoltaLensTypes %minoltaTeleconverters %minoltaColorMode
+            %sonyColorMode %minoltaSceneMode %afStatusInfo %metabonesID);
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
 
-$VERSION = '1.76';
+$VERSION = '2.87';
+
+# Full list of product codes for Sony-compatible Minolta lenses
+# (ref http://www.kb.sony.com/selfservice/documentLink.do?externalId=C1000570)
+# NOTE: Unfortunately, these product codes sometimes do not match the first 4
+#       digits of the lens ID
+# 2578 AF 16mm F2.8 FISH-EYE
+# 2579 AF 20mm F2.8
+# 2641 AF 20mm F2.8 NEW
+# 2566 AF 24mm F2.8
+# 2642 AF 24mm F2.8 NEW
+# 2596 AF 28mm F2
+# 2668 AF 28mm F2 NEW
+# 2557 AF 28mm F2.8
+# 2591 AF 35mm F1.4 G
+# 2666 AF 35mm F1.4 G NEW
+# 2597 AF 35mm F2
+# 2667 AF 35mm F2 NEW
+# 2562 AF 50mm F1.4
+# 2662 AF 50mm F1.4 NEW
+# 2550 AF 50mm F1.7
+# 2613 AF 50mm F1.7 NEW
+# 2592 AF 85mm F1.4
+# 2629 AF 85mm F1.4 G
+# 2677 AF 85mm F1.4 G (D)
+# 2689 AF 85mm F1.4 G (D) Limited
+# 2598 AF 100mm F2
+# 2648 AF 100mm F2.8 SOFT
+# 2556 AF 135mm F2.8
+# 2656 STF 135mm F2.8 [T4.5]
+# 2593 AF APO 20 0mm F2.8
+# 2612 High Speed AF APO 200mm F2.8 G
+# 2563 AF APO 300mm F2.8
+# 2608 High Speed AF APO 300mm F2.8 G
+# 2674 AF APO 300mm F2.8 G(D) SSM
+# 2640 AF APO 300mm F4 G
+# 2651 AF APO 400mm F4.5 G
+# 2572 AF REFLEX 500mm F8
+# 2565 AF APO 600mm F4
+# 2609 High Speed AF APO 600mm F4 G
+# 2564 AF MACRO 50mm F2.8
+# 2638 AF MACRO 50mm F2.8 NEW
+# 2675 AF MACRO 50mm F2.8 (D)
+# 2646 AF MACRO 50mm F3.5
+# 2581 AF MACRO 100mm F2.8
+# 2639 AF MACRO 100mm F2.8 NEW
+# 2676 AF MACRO 100mm F2.8 (D)
+# 2658 AF APO TE LE MACRO 200mm F4 G
+# 2594 AF MACRO ZOOM 1x-3x F1.7-2.8
+# 2695 AF 17-35mm F2.8-4 (D)
+# 2654 AF 17-35mm F3.5 G
+# 2657 AF 20-35mm F3.5-4.5
+# 2558 AF 24-50mm F4
+# 2632 AF 24-50mm F4 NEW
+# 2636 AF 24-85mm F3.5-4.5
+# 2660 AF 24-85mm F3.5-4.5 NEW
+# 2672 AF 24-105mm F3.5-4.5 (D)
+# 2620 AF 28-70mm F2.8 G
+# 2696 AF 28-75mm F2.8 (D)
+# 2659 AF 28-80mm F3.5-5.6
+# 2670 AF 28-80mm F3.5-5.6 II
+# 2683 AF 28-80mm F3.5-5.6 (D)
+# 2633 AF 28-80mm F4-5.6
+# 2552 AF 28-85mm F3.5-4.5
+# 2586 AF 28-85mm F3.5-4.5 NEW
+# 2692 AF 28-100mm F3.5-5.6 (D)
+# 2635 AF 28-105mm F3.5-4.5
+# 2661 AF 28-105mm F3.5-4.5 NEW
+# 2553 AF 28-135mm F4-4.5
+# 2551 AF 35-70mm F4
+# 2643 AF 35-70mm F3.5-4.5
+# 2652 AF 35-70mm F3.5-4.5 NEW
+# 2605 AF 35-80mm F4-5.6
+# 2671 AF 35-80mm F4.5-5.6 II
+# 2554 AF 35-105mm F3.5-4.5
+# 2585 AF 35-105mm F3.5-4.5
+# 2682 AF APO 70-200mm F2.8 G (D) SSM
+# 2588 AF 70-210mm F4.5-5.6
+# 2555 AF 70-210mm F4
+# 2634 AF 70-210mm F4.5-5.6 NEW
+# 2669 AF 70-210mm F4.5-5.6 II
+# 2561 AF 75-300mm F4.5-5.6
+# 2649 AF 75-300mm F4.5-5.6 NEW
+# 2665 AF 75-300mm F4.5-5.6 II
+# 2684 AF 75-300mm F4.5-5.6 (D)
+# 2589 AF APO 80-200mm F2.8
+# 2628 High-Speed AF APO 80-200mm F2.8 G
+# 2604 AF 80-200mm F4.5-5.6
+# 2560 AF 100-200mm F4.5
+# 2606 AF 100-300mm F4.5-5.6
+# 2631 AF APO 100-300mm F4.5-5.6
+# 2681 AF APO 100-300mm F4.5-5.6 (D)
+# 2644 AF APO 100-400mm F4.5-6.7
+# 2618 AF Xi 28-80mm F4-5.6
+# 2615 AF Xi 28-105mm F3.5-4.5
+# 2624 AF PZ 35-80mm F4-5.6
+# 2616 AF Xi 35-200mm F4.5-5.6
+# 2619 AF Xi 80-200mm F4.5-5.6
+# 2621 AF Xi 100-300mm F4.5-5.6
+# 2698 AF DT 11-18mm F4.5-5.6 (D)
+# 2697 AF DT 18-70mm F3.5-5.6 (D)
+# 2699 AF DT 18-200mm F3.5-6.3 (D)
+# 2590 1.4x TELE CONVERTER APO
+# 2601 2x TELE CONVERTER APO
+# 2610 1.4x TELE CONVERTER APO II
+# 2611 2x TELE CONVERTER APO II
+# 2687 1.4x TELE CONVERTER APO (D)
+# 2688 2x TELE CONVERTER APO (D)
+
+# high bytes in Sony LensID's identifying Metabones adapters and high bytes of Canon LensID's
+%metabonesID = (
+    # 0xef00 is used by Metabones, Fotodiox, Sigma and Viltrox adapters (JR)
+    0xef00 => \ 'Canon EF Adapter',         # with Canon LensID 0x00xx
+    0xf000 => 0xef00,                       # with Canon LensID 0x01xx
+    0xf100 => 0xef00,                       # with Canon LensID 0x02xx
+    0xff00 => 0xef00,                       # with Canon LensID 0x10xx
+    0x7700 => \ 'Metabones Speed Booster',  # with Canon LensID 0x00xx
+    0x7800 => 0x7700,                       # with Canon LensID 0x01xx
+    0x7900 => 0x7700,                       # with Canon LensID 0x02xx
+    0x8700 => 0x7700,                       # with Canon LensID 0x10xx
+    0xbc00 => \ 'Metabones Speed Booster Ultra', # with Canon LensID 0x00xx
+    0xbd00 => 0xbc00,                       # with Canon LensID 0x01xx
+    0xbe00 => 0xbc00,                       # with Canon LensID 0x02xx
+    0xcc00 => 0xbc00,                       # with Canon LensID 0x10xx
+);
 
 # lens ID numbers (ref 3)
@@ -49,13 +180,36 @@
 %minoltaLensTypes = (
     Notes => q{
-        Decimal values differentiate lenses which would otherwise have the same
-        LensType, and are used by the Composite LensID tag when attempting to
-        identify the specific lens model.  "New" or "II" appear in brackets if the
-        original version of the lens has the same LensType.
+        Decimal values have been added to differentiate lenses which would otherwise
+        have the same LensType, and are used by the Composite LensID tag when
+        attempting to identify the specific lens model.  "New" or "II" appear in
+        brackets if the original version of the lens has the same LensType.  Special
+        logic is employed to identify the attached lens when a Metabones Canon EF
+        adapter is used.
+    },
+    OTHER => sub {
+        my ($val, $inv) = @_;
+        return undef if $inv;
+        my $id = $val & 0xff00;
+        # Note: Metabones Smart Adapter firmware versions before 31 kill
+        # the high byte for 2-byte Canon LensType values, so the reported lens
+        # will be incorrect for these
+        my $mb = $metabonesID{$id};
+        if ($mb) {
+            ref $mb or $id = $mb, $mb = $metabonesID{$id};
+            require Image::ExifTool::Canon;
+            my $lens = $Image::ExifTool::Canon::canonLensTypes{$val - $id};
+            return "$lens + $$mb" if $lens;
+        } elsif ($val >= 0x4900) { # test for Sigma MC-11 SA-E adapter with Sigma SA-mount lens
+            require Image::ExifTool::Sigma;
+            my $lens = $Image::ExifTool::Sigma::sigmaLensTypes{$val - 0x4900};
+            return "$lens + MC-11 SA-E" if $lens;
+        }
+        return undef;
     },
     0 => 'Minolta AF 28-85mm F3.5-4.5 New', # New added (ref 13/18)
-    1 => 'Minolta AF 80-200mm F2.8 HS-APO G',
+    1 => 'Minolta AF 80-200mm F2.8 HS-APO G', # white
     2 => 'Minolta AF 28-70mm F2.8 G',
     3 => 'Minolta AF 28-80mm F4-5.6',
+    4 => 'Minolta AF 85mm F1.4G', #exiv2 0.23
     5 => 'Minolta AF 35-70mm F3.5-4.5 [II]', # (original and II, ref 13)
     6 => 'Minolta AF 24-85mm F3.5-4.5 [New]', # (original and New, ref 13)
@@ -77,23 +231,32 @@
     19 => 'Minolta AF 35mm F1.4 G', # G added (ref 18), but not New as per ref 13
     20 => 'Minolta/Sony 135mm F2.8 [T4.5] STF',
+    # 20 => 'Sony 135mm F2.8 [T4.5] STF (SAL135F28)', (ref JR)
     22 => 'Minolta AF 35-80mm F4-5.6 II', # II added (ref 13)
     23 => 'Minolta AF 200mm F4 Macro APO G',
     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.3 => 'Sigma 20-40mm F2.8 EX DG Aspherical IF', #JD
+    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 20-40mm F2.8 EX DG Aspherical IF', #22
-    24.6 => 'Tamron SP AF 28-75mm F2.8 XR Di (IF) Macro', #JD
+    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
     25.3 => 'Sigma 20mm F1.8 EX DG Aspherical RF', #19
-    25.4 => 'Sigma 30mm F1.4 DG EX', #21
+    25.4 => 'Sigma 30mm F1.4 EX DC', #21/27
+    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 (SAL-100M28)' (ref 18)
-    28.1 => 'Tamron SP AF 90mm F2.8 Di Macro', #JD
+    # 28 => 'Sony 100mm F2.8 Macro (SAL100M28)', (ref 18/JR)
+    28.1 => 'Tamron SP AF 90mm F2.8 Di Macro', #JD (Model 272E)
+    28.2 => 'Tamron SP AF 180mm F3.5 Di LD [IF] Macro', #27 (Model B01) ("SP" moved - ref JR)
     29 => 'Minolta/Sony AF 75-300mm F4.5-5.6 (D)', # Sony added (ref 13)
+    # 29 => 'Sony 75-300mm F4.5-5.6 (SAL75300)', (ref JR)
     30 => 'Minolta AF 28-80mm F3.5-5.6 (D) or Sigma Lens',
     30.1 => 'Sigma AF 10-20mm F4-5.6 EX DC', #JD
@@ -102,68 +265,138 @@
     30.4 => 'Sigma 55-200mm F4-5.6 DC', #JD
     31 => 'Minolta/Sony AF 50mm F2.8 Macro (D) or F3.5',
+    # 31 => 'Sony 50mm F2.8 Macro (SAL50M28)', (ref JR)
     31.1 => 'Minolta/Sony AF 50mm F3.5 Macro',
     32 => 'Minolta/Sony AF 300mm F2.8 G or 1.5x Teleconverter', #13/18
-    # 32 => 'Minolta AF 300mm F2.8 G (D) SSM' (ref 13)
-    # 32 => 'Sony 300mm F2.8 G (SAL-300F28G)' (ref 18)
+    # 32 => 'Minolta AF 300mm F2.8 APO G (D) SSM', (ref 13) ("APO" added - ref JR)
+    # 32 => 'Sony 300mm F2.8 G (SAL300F28G)', (ref 18/JR)
     33 => 'Minolta/Sony AF 70-200mm F2.8 G',
-    # 33 => 'Minolta AF 70-200mm F2.8 G (D) SSM' (ref 13)
+    # 33 => 'Sony 70-200mm F2.8 G (SAL70200G)', (ref JR)
+    # 33 => 'Minolta AF 70-200mm F2.8 APO G (D) SSM' (ref 13) ("APO" added - ref JR)
     35 => 'Minolta AF 85mm F1.4 G (D) Limited',
     36 => 'Minolta AF 28-100mm F3.5-5.6 (D)',
     38 => 'Minolta AF 17-35mm F2.8-4 (D)', # (Konica Minolta, ref 13)
     39 => 'Minolta AF 28-75mm F2.8 (D)', # (Konica Minolta, ref 13)
-    40 => 'Minolta/Sony AF DT 18-70mm F3.5-5.6 (D) or 18-200m F3.5-6.3', # (Konica Minolta, ref 13)
-    40.1 => 'Sony AF DT 18-200mm F3.5-6.3', #11
+    40 => 'Minolta/Sony AF DT 18-70mm F3.5-5.6 (D)', # (Konica Minolta, ref 13)
+    # 40 => 'Sony DT 18-70mm F3.5-5.6 (SAL1870)', (ref JR)
+    #40.1 => 'Sony AF DT 18-200mm F3.5-6.3', #11 (anomaly? - PH)
     41 => 'Minolta/Sony AF DT 11-18mm F4.5-5.6 (D) or Tamron Lens', # (Konica Minolta, ref 13)
-    41.1 => 'Tamron SP AF 11-18mm F4.5-5.6 Di II LD Aspherical IF', #JD
+    # 41 => 'Sony DT 11-18mm F4.5-5.6 (SAL1118)', (ref JR)
+    41.1 => 'Tamron SP AF 11-18mm F4.5-5.6 Di II LD Aspherical IF', #JD (Model A13)
     42 => 'Minolta/Sony AF DT 18-200mm F3.5-6.3 (D)', # Sony added (ref 13) (Konica Minolta, ref 13)
-    43 => 'Sony 35mm F1.4 G (SAL-35F14G)', # changed from Minolta to Sony (ref 13/18) (but ref 11 shows both!)
-    44 => 'Sony 50mm F1.4 (SAL-50F14)', # changed from Minolta to Sony (ref 13/18)
-    45 => 'Carl Zeiss Planar T* 85mm F1.4 ZA',
-    46 => 'Carl Zeiss Vario-Sonnar T* DT 16-80mm F3.5-4.5 ZA',
-    47 => 'Carl Zeiss Sonnar T* 135mm F1.8 ZA',
-    48 => 'Carl Zeiss Vario-Sonnar T* 24-70mm F2.8 ZA SSM (SAL-2470Z)', #11
-    49 => 'Sony AF DT 55-200mm F4-5.6', #JD
-    50 => 'Sony AF DT 18-250mm F3.5-6.3', #11
-    51 => 'Sony AF DT 16-105mm F3.5-5.6 or 55-200mm F4-5.5', #11
-    51.1 => 'Sony AF DT 55-200mm F4-5.5', #11
-    52 => 'Sony 70-300mm F4.5-5.6 G SSM', #JD
-    53 => 'Sony AF 70-400mm F4-5.6 G SSM (SAL-70400G)', #17 (/w correction by Stephen Bishop)
-    54 => 'Carl Zeiss Vario-Sonnar T* 16-35mm F2.8 ZA SSM (SAL-1635Z)', #17
-    55 => 'Sony DT 18-55mm F3.5-5.6 SAM (SAL-1855)', #PH
-    56 => 'Sony AF DT 55-200mm F4-5.6 SAM', #22
-    57 => 'Sony AF DT 50mm F1.8 SAM', #22
-    58 => 'Sony AF DT 30mm F2.8 SAM Macro', #22
-    59 => 'Sony 28-75/2.8 SAM', #21
-    60 => 'Carl Zeiss Distagon T* 24mm F2 SSM', #17
-    61 => 'Sony 85mm F2.8 SAM (SAL-85F28)', #17
-    62 => 'Sony DT 35mm F1.8 SAM (SAL-35F18)', #PH
+    # 42 => 'Sony DT 18-200mm F3.5-6.3 (SAL18200)', (ref JR)
+    43 => 'Sony 35mm F1.4 G (SAL35F14G)', # changed from Minolta to Sony (ref 13/18/JR) (but ref 11 shows both!)
+    44 => 'Sony 50mm F1.4 (SAL50F14)', # changed from Minolta to Sony (ref 13/18/JR)
+    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 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)
+    53 => 'Sony 70-400mm F4-5.6 G SSM (SAL70400G)', #17(/w correction by Stephen Bishop)/JR
+    54 => 'Carl Zeiss Vario-Sonnar T* 16-35mm F2.8 ZA SSM (SAL1635Z) or ZA SSM II', #17/JR
+    54.1 => 'Carl Zeiss Vario-Sonnar T* 16-35mm F2.8 ZA SSM II (SAL1635Z2)', #JR
+    55 => 'Sony DT 18-55mm F3.5-5.6 SAM (SAL1855) or SAM II', #PH
+    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 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
+    59 => 'Sony 28-75mm F2.8 SAM (SAL2875)', #21/JR
+    60 => 'Carl Zeiss Distagon T* 24mm F2 ZA SSM (SAL24F20Z)', #17/JR
+    61 => 'Sony 85mm F2.8 SAM (SAL85F28)', #17/JR
+    62 => 'Sony DT 35mm F1.8 SAM (SAL35F18)', #PH/JR
+    63 => 'Sony DT 16-50mm F2.8 SSM (SAL1650)', #17/JR
+    64 => 'Sony 500mm F4 G SSM (SAL500F40G)', #29
+    65 => 'Sony DT 18-135mm F3.5-5.6 SAM (SAL18135)', #JR
+    66 => 'Sony 300mm F2.8 G SSM II (SAL300F28G2)', #29
+    67 => 'Sony 70-200mm F2.8 G SSM II (SAL70200G2)', #JR
+    68 => 'Sony DT 55-300mm F4.5-5.6 SAM (SAL55300)', #29
+    69 => 'Sony 70-400mm F4-5.6 G SSM II (SAL70400G2)', #JR
+    70 => 'Carl Zeiss Planar T* 50mm F1.4 ZA SSM (SAL50F14Z)', #JR
     128 => 'Tamron or Sigma Lens (128)',
-    128.1 => 'Tamron 18-200mm F3.5-6.3',
-    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
-    128.5 => 'Tamron SP AF 17-35mm F2.8-4 Di LD Aspherical IF', #JD
-    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.1 => 'Tamron AF 18-200mm F3.5-6.3 XR Di II LD Aspherical [IF] Macro', #JR (Model A14)
+    # 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',
+    # (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.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.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
-    131 => 'Tamron 20-40mm F2.7-3.5 SP Aspherical IF', #23
+    131 => 'Tamron 20-40mm F2.7-3.5 SP Aspherical IF', #23 (Model 266D)
     135 => 'Vivitar 28-210mm F3.5-5.6', #16
     136 => 'Tokina EMZ M100 AF 100mm F3.5', #JD
     137 => 'Cosina 70-210mm F2.8-4 AF', #11
     138 => 'Soligor 19-35mm F3.5-4.5', #11
-    142 => 'Voigtlander 70-300mm F4.5-5.6', #JD
+    139 => 'Tokina AF 28-300mm F4-6.3', #IB
+    # (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) (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)
+    215 => 'Tamron SP 15-30mm F2.8 Di USD', #JR (Model A012)
+    216 => 'Tamron SP 45mm F1.8 Di USD', #forum8320 (F013)
+    217 => 'Tamron SP 35mm F1.8 Di USD', #forum8320 (F012)
+    218 => 'Tamron SP 90mm F2.8 Di Macro 1:1 USD (F017)', #JR (Model F017)
+    220 => 'Tamron SP 150-600mm F5-6.3 Di USD G2', #forum8846 (Model A022)
+    224 => 'Tamron SP 90mm F2.8 Di Macro 1:1 USD (F004)', #JR (Model F004)
     255 => 'Tamron Lens (255)',
-    255.1 => 'Tamron SP AF 17-50mm F2.8 XR Di II LD Aspherical',
-    255.2 => 'Tamron AF 18-250mm F3.5-6.3 XR Di II LD', #JD
-    255.3 => 'Tamron AF 55-200mm F4-5.6 Di II',
-    255.4 => 'Tamron AF 70-300mm F4-5.6 Di LD MACRO 1:2',
-    255.5 => 'Tamron SP AF 200-500mm F5.0-6.3 Di LD IF',
-    255.6 => 'Tamron SP AF 10-24mm F3.5-4.5 Di II LD Aspherical IF', #22
-    255.7 => 'Tamron SP AF 70-200mm F2.8 Di LD IF Macro', #22
-    255.8 => 'Tamron SP AF 28-75mm F2.8 XR Di LD Aspherical IF', #24
+    255.1 => 'Tamron SP AF 17-50mm F2.8 XR Di II LD Aspherical', # (Model A16)
+    255.2 => 'Tamron AF 18-250mm F3.5-6.3 XR Di II LD', #JD (Model A18?)
+ #? 225.2 => 'Tamron AF 18-250mm F3.5-6.3 Di II LD Aspherical [IF] Macro', #JR (Model A18)
+    255.3 => 'Tamron AF 55-200mm F4-5.6 Di II LD Macro', # (Model A15) (added "LD Macro", ref 23)
+    255.4 => 'Tamron AF 70-300mm F4-5.6 Di LD Macro 1:2', # (Model A17)
+    255.5 => 'Tamron SP AF 200-500mm F5.0-6.3 Di LD IF', # (Model A08)
+    255.6 => 'Tamron SP AF 10-24mm F3.5-4.5 Di II LD Aspherical IF', #22 (Model B001)
+    255.7 => 'Tamron SP AF 70-200mm F2.8 Di LD IF Macro', #22 (Model A001)
+    255.8 => 'Tamron SP AF 28-75mm F2.8 XR Di LD Aspherical IF', #24 (Model A09)
+    255.9 => 'Tamron AF 90-300mm F4.5-5.6 Telemacro', #Fredrik Agert
+    18688 => 'Sigma MC-11 SA-E Mount Converter with not-supported Sigma lens',
+    # The MC-11 SA-E Mount Converter uses this 18688 offset for not-supported SIGMA mount lenses.
+    # The MC-11 EF-E Mount Converter uses the 61184 offset for not-supported CANON mount lenses, as also used by Metabones.
+    # Both MC-11 SA-E and EF-E Mount Converters use the 504xx LensType2 values for supported SA-mount or EF-mount Sigma lenses.
     25501 => 'Minolta AF 50mm F1.7', #7
     25511 => 'Minolta AF 35-70mm F4 or Other Lens',
@@ -172,4 +405,5 @@
     25511.3 => 'Sigma M-AF 70-200mm F2.8 EX Aspherical', #12
     25511.4 => 'Quantaray M-AF 35-80mm F4-5.6', #JD
+    25511.5 => 'Tokina 28-70mm F2.8-4.5 AF', #IB
     25521 => 'Minolta AF 28-85mm F3.5-4.5 or Other Lens', # not New (ref 18)
     25521.1 => 'Tokina 19-35mm F3.5-4.5', #3
@@ -177,10 +411,14 @@
     25521.3 => 'Tokina 80-400mm F4.5-5.6 AT-X AF II 840', #JD
     25521.4 => 'Tokina AF PRO 28-80mm F2.8 AT-X 280', #JD
-    25521.5 => 'Tokina AT-X PRO II AF 28-70mm F2.6-2.8 270', #24
-    25521.6 => 'Tamron AF 19-35mm F3.5-4.5', #JD
+    25521.5 => 'Tokina AT-X PRO [II] AF 28-70mm F2.6-2.8 270', #24 (original + II versions)
+    25521.6 => 'Tamron AF 19-35mm F3.5-4.5', #JD (Model A10)
     25521.7 => 'Angenieux AF 28-70mm F2.6', #JD
-    25531 => 'Minolta AF 28-135mm F4-4.5 or Sigma Lens',
+    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 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',
@@ -190,9 +428,9 @@
     25561 => 'Minolta AF 135mm F2.8',
     25571 => 'Minolta/Sony AF 28mm F2.8', # Sony added (ref 18)
-    # 25571 => 'Sony 28mm F2.8 (SAL-28F28)' (ref 18)
+    # 25571 => 'Sony 28mm F2.8 (SAL28F28)', (ref 18/JR)
     25581 => 'Minolta AF 24-50mm F4',
     25601 => 'Minolta AF 100-200mm F4.5',
     25611 => 'Minolta AF 75-300mm F4.5-5.6 or Sigma Lens', #13
-    25611.1 => 'Sigma 70-300mm F4-5.6 DL Macro', #12
+    25611.1 => 'Sigma 70-300mm F4-5.6 DL Macro', #12 (also DG version ref 27, and APO version ref JR)
     25611.2 => 'Sigma 300mm F4 APO Macro', #3/7
     25611.3 => 'Sigma AF 500mm F4.5 APO', #JD
@@ -201,39 +439,55 @@
     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', #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)
     25631 => 'Minolta AF 300mm F2.8 APO or Sigma Lens', # changed G to APO (ref 13)
     25631.1 => 'Sigma AF 50-500mm F4-6.3 EX DG APO', #JD
-    25631.2 => 'Sigma AF 170-500mm F5-6.3 APO Aspherical', #JD
+    25631.2 => 'Sigma AF 170-500mm F5-6.3 APO Aspherical', #JD (also DG version, ref 27)
     25631.3 => 'Sigma AF 500mm F4.5 EX DG APO', #JD
     25631.4 => 'Sigma 400mm F5.6 APO', #22
     25641 => 'Minolta AF 50mm F2.8 Macro or Sigma Lens',
     25641.1 => 'Sigma 50mm F2.8 EX Macro', #11
-    25651 => 'Minolta AF 600mm F4',
-    25661 => 'Minolta AF 24mm F2.8',
+    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', #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)
-    # 25781 => 'Sony 16mm F2.8 Fisheye (SAL-16F28)' (ref 18)
+    # 25781 => 'Sony 16mm F2.8 Fisheye (SAL16F28)', (ref 18/JR)
     25781.1 => 'Sigma 8mm F4 EX [DG] Fisheye',
     25781.2 => 'Sigma 14mm F3.5',
     25781.3 => 'Sigma 15mm F2.8 Fisheye', #JD (writes 16mm to EXIF)
-    25791 => 'Minolta/Sony AF 20mm F2.8', # Sony added (ref 11)
+    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', #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 => 'Tamron 90mm F2.8 Macro',
+    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',
-    25858.1 => 'Tamron 24-135mm F3.5-5.6',
+    25858.1 => 'Tamron 24-135mm F3.5-5.6', # (Model 190D)
     25881 => 'Minolta AF 70-210mm F3.5-4.5',
-    25891 => 'Minolta AF 80-200mm F2.8 APO or Tokina Lens',
+    25891 => 'Minolta AF 80-200mm F2.8 APO or Tokina Lens', # black
     25891.1 => 'Tokina 80-200mm F2.8',
+    # 25901 - Note: only get this with older 1.4x and lenses with 5-digit LensTypes (ref 27)
+    # 25901 - also "Minolta AF 200mm F2.8 HS-APO G + Minolta AF 1.4x APO"
+    25901 => 'Minolta AF 200mm F2.8 G APO + Minolta AF 1.4x APO or Other Lens + 1.4x', #26
+    25901.1 => 'Minolta AF 600mm F4 HS-APO G + Minolta AF 1.4x APO', #27
     25911 => 'Minolta AF 35mm F1.4', #(from Sony list) (not G as per ref 13)
     25921 => 'Minolta AF 85mm F1.4 G (D)',
-    25931 => 'Minolta AF 200mm F2.8 G APO',
+    25931 => 'Minolta AF 200mm F2.8 APO', # (not "G", see 26121 - ref JR)
     25941 => 'Minolta AF 3x-1x F1.7-2.8 Macro',
     25961 => 'Minolta AF 28mm F2',
     25971 => 'Minolta AF 35mm F2 [New]', #13
     25981 => 'Minolta AF 100mm F2',
+    # 26011 - Note: only get this with older 2x and lenses with 5-digit LensTypes (ref 27)
+    # 26011 - also "Minolta AF 200mm F2.8 HS-APO G + Minolta AF 2x APO"
+    26011 => 'Minolta AF 200mm F2.8 G APO + Minolta AF 2x APO or Other Lens + 2x', #26
+    26011.1 => 'Minolta AF 600mm F4 HS-APO G + Minolta AF 2x APO', #27
     26041 => 'Minolta AF 80-200mm F4.5-5.6',
     26051 => 'Minolta AF 35-80mm F4-5.6', #(from Sony list)
@@ -251,7 +505,7 @@
     26211 => 'Minolta AF 100-300mm F4.5-5.6 xi', # xi, not Power Zoom (ref 13/18)
     26241 => 'Minolta AF 35-80mm F4-5.6 Power Zoom',
-    26281 => 'Minolta AF 80-200mm F2.8 G', #11
+    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',
@@ -264,5 +518,11 @@
     26681 => 'Minolta AF 28mm F2 New',
     26721 => 'Minolta AF 24-105mm F3.5-4.5 (D)', #11
+    # 30464: newer firmware versions of the Speed Booster report type 30464 (=0x7700)
+    # - 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
     45741.1 => 'Tamron SP AF 90mm F2.5', #JD
@@ -271,13 +531,41 @@
     45751 => '1.4x Teleconverter', #18
     45851 => 'Tamron SP AF 300mm F2.8 LD IF', #11
+    45861 => 'Tamron SP AF 35-105mm F2.8 LD Aspherical IF', #Fredrik Agert
+    45871 => 'Tamron AF 70-210mm F2.8 SP LD', #Fabio Suprani
+    # 48128: the Speed Booster Ultra appears to report type 48128 (=0xbc00)
+    # - this is the base to which the Canon LensType is added
+    48128 => 'Metabones Canon EF Speed Booster Ultra', #JR (to this, add Canon LensType)
+    # 61184: older firmware versions of both the Speed Booster and the Smart Adapter
+    # report type 61184 (=0xef00), and add only the lower byte of the Canon LensType (ref JR).
+    # For newer firmware versions this is only used by the Smart Adapter, and
+    # the full Canon LensType code is added - PH
+    # the metabones adapter translates Canon L -> G, II -> II, USM -> SSM, IS -> OSS (ref JR)
+    # This offset is used by Metabones, Fotodiox, Sigma MC-11 EF-E and Viltrox Canon EF adapters.
+    61184 => 'Canon EF Adapter', #JR (to this, add Canon LensType)
+    # 65280 = 0xff00
+    65280 => 'Sigma 16mm F2.8 Filtermatic Fisheye', #IB
     # all M42-type lenses give a value of 65535 (and FocalLength=0, FNumber=1)
-    65535 => 'T-Mount or Other Lens or no lens', #JD
-    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
+    65535 => 'E-Mount, T-Mount, Other Lens or no lens', #JD/JR
+   '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 = (
+    0x00 => 'None',
+    0x04 => 'Minolta/Sony AF 1.4x APO (D) (0x04)', # (Andy Johnson, A77 APO and APO D)
+    0x05 => 'Minolta/Sony AF 2x APO (D) (0x05)', # (Andy Johnson, A77 APO D)
+    0x48 => 'Minolta/Sony AF 2x APO (D)',
+    # 0x48 => 'Sony 2x Teleconverter (SAL20TC)', (ref JR)
+    0x50 => 'Minolta AF 2x APO II',
+    0x60 => 'Minolta AF 2x APO',#26
+    0x88 => 'Minolta/Sony AF 1.4x APO (D)',
+    # 0x88 => 'Sony 1.4x Teleconverter (SAL14TC)', (ref JR)
+    0x90 => 'Minolta AF 1.4x APO II',
+    0xa0 => 'Minolta AF 1.4x APO',#26
 );
 
@@ -310,4 +598,13 @@
     7 => 'Adobe RGB',
     12 => 'Neutral', # Sony
+    13 => 'Clear', #JR (NC)
+    14 => 'Deep', #JR
+    15 => 'Light', #JR (NC)
+    16 => 'Autumn Leaves', #JR (NC)
+    17 => 'Sepia', #JR
+    18 => 'FL', #JR (7SM3)
+    19 => 'Vivid 2', #JR (7SM3)
+    20 => 'IN', #JR (7SM3)
+    21 => 'SH', #JR (7SM3)
     100 => 'Neutral', #JD
     101 => 'Clear', #JD
@@ -316,5 +613,6 @@
     104 => 'Night View', #JD
     105 => 'Autumn Leaves', #JD
-    0xffffffff => 'n/a', #PH
+    255 => 'Off', #JR (new for ILCE-7SM3, July 2020)
+   0xffffffff => 'n/a', #PH
 );
 
@@ -330,5 +628,5 @@
     8 => 'Macro',
     9 => 'Super Macro',
-    16 => 'Auto',
+    16 => 'Auto', # (RX100 'Intelligent Auto' - PH)
     17 => 'Night View/Portrait',
     18 => 'Sweep Panorama', #PH (SLT-A55V)
@@ -338,5 +636,27 @@
     22 => 'Auto+',
     23 => '3D Sweep Panorama', #PH (SLT-A55V)
+    24 => 'Superior Auto', #28
+    25 => 'High Sensitivity', #28
+    26 => 'Fireworks', #28
+    27 => 'Food', #28
+    28 => 'Pet', #28
+    33 => 'HDR', #JR
     0xffff => 'n/a', #PH
+);
+
+# tag information for AFStatus tags (ref 20)
+%afStatusInfo = (
+    Format => 'int16s',
+    # 0=in focus, -32768=out of focus, -ve=front focus, +ve=back focus
+    PrintConvColumns => 2,
+    PrintConv => {
+        0 => 'In Focus',
+        -32768 => 'Out of Focus',
+        OTHER => sub {
+            my ($val, $inv) = @_;
+            $inv and $val =~ /([-+]?\d+)/, return $1;
+            return $val < 0 ? "Front Focus ($val)" : "Back Focus (+$val)";
+        },
+    },
 );
 
@@ -403,15 +723,32 @@
         },
     },
+    0x0010 => { #20 (count: 256)
+        Name => 'CameraInfoA100',
+        Condition => '$$self{Model} eq "DSLR-A100"',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Minolta::CameraInfoA100',
+            ByteOrder => 'LittleEndian',
+        },
+    },
     # it appears that image stabilization is on if this tag exists (ref 2),
     # but it is an 8kB binary data block!
-    0x0018 => {
-        Name => 'ImageStabilization',
-        Condition => '$self->{Model} =~ /^DiMAGE (A1|A2|X1)$/',
-        Notes => q{
-            a block of binary data which exists in DiMAGE A2 (and A1/X1?) images only if
-            image stabilization is enabled
-        },
-        ValueConv => '"On"',
-    },
+    0x0018 => [
+        {
+            Name => 'ISInfoA100',
+            Condition => '$self->{Model} eq "DSLR-A100"',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Minolta::ISInfoA100',
+                ByteOrder => 'BigEndian',
+            },
+        },{
+            Name => 'ImageStabilization',
+            Condition => '$self->{Model} =~ /^DiMAGE (A1|A2|X1)$/',
+            Notes => q{
+                a block of binary data which exists in DiMAGE A2 (and A1/X1?) images only if
+                image stabilization is enabled
+            },
+            ValueConv => '"On"',
+        },
+    ],
     0x0020 => {
         Name => 'WBInfoA100',
@@ -430,4 +767,5 @@
         # JPEG preview found in DiMAGE 7 images
         %Image::ExifTool::previewImageTagInfo,
+        Groups => { 2 => 'Preview' },
         Permanent => 1,     # don't add this to a file
     },
@@ -438,4 +776,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
         # Note: Sony also uses this tag in A100 ARW images, but it points
@@ -447,4 +786,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -472,5 +812,5 @@
         Name => 'MinoltaQuality',
         Writable => 'int32u',
-        # PrintConv strings conform with Minolta reference manual (ref 4)
+        # PrintConv strings conform with Minolta reference manual (ref NJ)
         # (note that Minolta calls an uncompressed TIFF image "Super fine")
         PrintConv => {
@@ -492,5 +832,5 @@
             Notes => 'quality for DiMAGE A2/7Hi',
             Priority => 0, # lower priority because this doesn't work for A200
-            PrintConv => { #4
+            PrintConv => { #NJ
                 0 => 'Raw',
                 1 => 'Super Fine',
@@ -525,11 +865,5 @@
         Writable => 'int32u',
         PrintHex => 1,
-        PrintConv => {
-            0x00 => 'None',
-            0x48 => 'Minolta AF 2x APO (D)',
-            0x50 => 'Minolta AF 2x APO II',
-            0x88 => 'Minolta AF 1.4x APO (D)',
-            0x90 => 'Minolta AF 1.4x APO II',
-        },
+        PrintConv => \%minoltaTeleconverters,
     },
     0x0107 => { #8
@@ -563,4 +897,5 @@
         Writable => 'int32u',
         SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
         PrintConv => \%minoltaLensTypes,
     },
@@ -646,5 +981,5 @@
         information may not be as reliable as it should be.  Because of this, tags
         in the following tables are set to lower priority to prevent them from
-        superceding the values of same-named tags in other locations when duplicate
+        superseding the values of same-named tags in other locations when duplicate
         tags are disabled.
     },
@@ -686,5 +1021,5 @@
     5 => {
         Name => 'MinoltaQuality',
-        PrintConv => { #4
+        PrintConv => { #NJ
             0 => 'Raw',
             1 => 'Super Fine',
@@ -1068,15 +1403,18 @@
     0x10 => {
         Name => 'AFPoints',
-        PrintConv => { BITMASK => {
-            0 => 'Center',
-            1 => 'Top',
-            2 => 'Top-Right',
-            3 => 'Right',
-            4 => 'Bottom-Right',
-            5 => 'Bottom',
-            6 => 'Bottom-Left',
-            7 => 'Left',
-            8 => 'Top-Left',
-        } },
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => {
+                0 => 'Center',
+                1 => 'Top',
+                2 => 'Top-right',
+                3 => 'Right',
+                4 => 'Bottom-right',
+                5 => 'Bottom',
+                6 => 'Bottom-left',
+                7 => 'Left',
+                8 => 'Top-left',
+            },
+        },
     },
     0x15 => {
@@ -1408,4 +1746,120 @@
         Name => 'ImageStabilization',
         PrintConv => \%offOn,
+    },
+);
+
+# Camera settings used by the Sony DSLR-A100 (ref 20)
+%Image::ExifTool::Minolta::CameraInfoA100 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'Camera information for the Sony DSLR-A100.',
+    WRITABLE => 1,
+    PRIORITY => 0, # may not be as reliable as other information
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    0x01 => { #PH
+        Name => 'AFSensorActive',
+        PrintConv => {
+            0 => 'Top-right',
+            1 => 'Bottom-right',
+            2 => 'Bottom',
+            3 => 'Middle Horizontal',
+            4 => 'Center Vertical',
+            5 => 'Top',
+            6 => 'Top-left',
+            7 => 'Bottom-left',
+        },
+    },
+    0x02 => {
+        Name => 'AFStatusActiveSensor',
+        %afStatusInfo,
+        Notes => q{
+            the focus status at shutter release.  May not reflect the status after
+            focusing if the image is focused then recomposed
+        },
+    },
+    0x04 => { Name => 'AFStatusTop-right',      %afStatusInfo },
+    0x06 => { Name => 'AFStatusBottom-right',   %afStatusInfo },
+    0x08 => { Name => 'AFStatusBottom',         %afStatusInfo },
+    0x0a => {
+        Name => 'AFStatusMiddleHorizontal',
+        %afStatusInfo,
+        Notes => q{
+            any of the three horizontal sensors at the middle of the focus frame: Left,
+            Center or Right
+        },
+    },
+    0x0c => { Name => 'AFStatusCenterVertical', %afStatusInfo },
+    0x0e => { Name => 'AFStatusTop',            %afStatusInfo },
+    0x10 => { Name => 'AFStatusTop-left',       %afStatusInfo },
+    0x12 => { Name => 'AFStatusBottom-left',    %afStatusInfo },
+    0x14 => {
+        Name => 'FocusLocked',
+        # (Focus can be locked in all modes other than Manual and Continuous,
+        # and the latter can be overridden by pushing the Spot AF button)
+        PrintConv => {
+            0 => 'Manual Focus',
+            4 => 'No',
+            16 => 'Continuous Focus',
+            64 => 'Yes',
+        },
+    },
+    0x15 => {
+        Name => 'AFPoint',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Center',
+            2 => 'Top',
+            3 => 'Top-right',
+            4 => 'Right',
+            5 => 'Bottom-right',
+            6 => 'Bottom',
+            7 => 'Bottom-left',
+            8 => 'Left',
+            9 => 'Top-left',
+        },
+    },
+    0x16 => {
+        Name => 'AFMode',
+        PrintConv => {
+            0 => 'DMF',
+            1 => 'AF-S',
+            2 => 'AF-C',
+            3 => 'AF-A',
+        },
+    },
+    0x2d => { Name => 'AFStatusLeft',            %afStatusInfo },
+    0x2f => { Name => 'AFStatusCenterHorizontal',%afStatusInfo },
+    0x31 => { Name => 'AFStatusRight',           %afStatusInfo },
+    0x33 => {
+        Name => 'AFAreaMode',
+        PrintConv => {
+            0 => 'Wide',
+            1 => 'Local',
+            2 => 'Spot',
+        },
+    },
+);
+
+# 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,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    NOTES => 'Image stabilization information for the Sony DSLR-A100.',
+    WRITABLE => 1,
+    PRIORITY => 0, # may not be as reliable as other information
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    0 => {
+        Name => 'ImageStabilization',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0x0000 => 'Off',
+            0x2784 => 'On',
+        },
     },
 );
@@ -1452,23 +1906,23 @@
     },
     0x06 => { #20
-        Name => 'ManualExposureTime',
-        Notes => 'the most recent exposure time set manually by the user',
-        ValueConv => '$val ? 2 ** ((48-$val)/8) : $val',
-        ValueConvInv => '$val ? 48 - 8*log($val)/log(2) : $val',
+        Name => 'ShutterSpeedSetting',
+        Notes => 'used only in M and S exposure modes',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
         PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
         PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
     },
     0x07 => { #20
-        Name => 'ManualFNumber',
-        Notes => 'the most recent aperture set manually by the user',
-        ValueConv => '2 ** (($val-8)/16)',
-        ValueConvInv => '8 + 16*log($val)/log(2)',
-        PrintConv => 'sprintf("%.1f",$val)',
+        Name => 'ApertureSetting',
+        Notes => 'used only in M and A exposure modes',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
         PrintConvInv => '$val',
     },
     0x08 => { #20
         Name => 'ExposureTime',
-        ValueConv => '$val ? 2 ** ((48-$val)/8) : $val',
-        ValueConvInv => '$val ? 48 - 8*log($val)/log(2) : $val',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
         PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
         PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
@@ -1476,22 +1930,23 @@
     0x09 => { #15/20
         Name => 'FNumber',
-        ValueConv => '2 ** (($val / 8 - 1) / 2)',
-        ValueConvInv => '$val>0 ? (2*log($val)/log(2)+1) * 8 : undef',
-        PrintConv => 'sprintf("%.1f",$val)',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
         PrintConvInv => '$val',
     },
     0x0a => { #20
-        Name => 'DriveMode2',
-        PrintConv => {
-            0 => 'Self-timer 10 sec',
-            1 => 'Continuous',
-            4 => 'Self-timer 2 sec',
-            5 => 'Single Frame',
-            8 => 'White Balance Bracketing Low',
-            9 => 'White Balance Bracketing High',
-            770 => 'Single-frame Bracketing Low',
-            771 => 'Continous Bracketing Low',
-            1794 => 'Single-frame Bracketing High',
-            1795 => 'Continuous Bracketing High',
+        Name => 'DriveMode2', # (one of these is probably DriveModeSetting like Sony - PH)
+        PrintHex => 1,
+        PrintConv => {
+            0x000 => 'Self-timer 10 sec',
+            0x001 => 'Continuous',
+            0x302 => 'Single-frame Bracketing Low',
+            0x702 => 'Single-frame Bracketing High',
+            0x303 => 'Continous Bracketing Low',
+            0x703 => 'Continuous Bracketing High',
+            0x004 => 'Self-timer 2 sec',
+            0x005 => 'Single Frame',
+            0x008 => 'White Balance Bracketing Low',
+            0x009 => 'White Balance Bracketing High',
         },
     },
@@ -1522,15 +1977,16 @@
     },
     0x0d => { #20
-        Name => 'LocalAFAreaPoint',
+        Name => 'AFPointSelected', # (v8.88: renamed from LocalAFAreaPoint)
+        # (9-point centre-cross AF system, ref JR)
         PrintConv => {
             1 => 'Center',
             2 => 'Top',
-            3 => 'Top-Right',
+            3 => 'Top-right',
             4 => 'Right',
-            5 => 'Bottom-Right',
+            5 => 'Bottom-right',
             6 => 'Bottom',
-            7 => 'Bottom-Left',
+            7 => 'Bottom-left',
             8 => 'Left',
-            9 => 'Top-Left',
+            9 => 'Top-left',
         },
     },
@@ -1553,5 +2009,5 @@
     },
     0x10 => { #20
-        Name => 'FlashExposureCompSetting',
+        Name => 'FlashExposureCompSet',
         Description => 'Flash Exposure Comp. Setting',
         # (may differ from FlashExposureComp for flash bracketing shots)
@@ -1618,4 +2074,5 @@
         PrintConv => {
             0 => 'sRGB',
+            2 => 'B&W', #PH (A100)
             5 => 'Adobe RGB',
         },
@@ -1981,5 +2438,5 @@
     },
     0x60 => { #20
-        Name => 'BatteryLevel',
+        Name => 'BatteryState',
         PrintConv => {
             3 => 'Very Low',
@@ -2000,28 +2457,298 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     FIRST_ENTRY => 0,
-    0x96  => { Name => 'WB_RGBLevels',          Format => 'int16u[3]' },
-    0xae  => { Name => 'WB_GBRGLevels',         Format => 'int16u[4]' },
-    0x304 => { Name => 'WB_RBPresetFlash',      Format => 'int16u[2]' },
-    0x308 => { Name => 'WB_RBPresetCoolWhiteF', Format => 'int16u[2]' },
-    0x3e8 => { Name => 'WB_RBPresetTungsten',   Format => 'int16u[2]' },
-    0x3ec => { Name => 'WB_RBPresetDaylight',   Format => 'int16u[2]' },
-    0x3f0 => { Name => 'WB_RBPresetCloudy',     Format => 'int16u[2]' },
-    0x3f4 => { Name => 'WB_RBPresetFlash',      Format => 'int16u[2]' },
-    0x3fc => {
-        Name => 'WB_RedPresetsFluorescent',
+    PRIORITY => 0,
+    0x0e => {
+        Name => 'DriveMode',
+        PrintConv => {
+            0 => 'Self-timer 10 sec',
+            1 => 'Continuous',
+            2 => 'Single-frame Exposure Bracketing',
+            3 => 'Continuous Exposure Bracketing',
+            4 => 'Self-Timer 2 sec',
+            5 => 'Single Frame',
+            8 => 'White Balance Bracketing Low',
+            9 => 'White Balance Bracketing High',
+        },
+    },
+    0x10 => {
+        Name => 'Rotation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 270 CW',
+            2 => 'Rotate 90 CW',
+        },
+    },
+    0x14 => {
+        Name => 'ImageStabilizationSetting',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x15 => {
+        Name => 'DynamicRangeOptimizerMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Standard',
+            2 => 'Advanced',
+        },
+    },
+    0x2a => {
+        Name => 'ExposureCompensationMode',
+        PrintConv => {
+            0 => 'Ambient and Flash',
+            1 => 'Ambient Only',
+        },
+    },
+    0x2b => 'WBBracketShotNumber',
+    0x2c => {
+        Name => 'WhiteBalanceBracketing',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    0x2d => 'ExposureBracketShotNumber',
+    0x31 => {
+        Name => 'FlashFunction',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0x0000 => 'No flash',
+            0x0300 => 'Built-in flash',
+            # (the following refers to an external flash)
+            0x1205 => 'Manual',
+            0x120e => 'Strobe',
+            #0x122e => ?
+            0x128e => 'Fill flash, Pre-flash TTL',
+            0x12ae => 'Bounce flash',
+            0x140e => 'Rear sync, ADI',
+            0x148e => 'Fill flash, ADI',
+            0x1580 => 'Wireless',
+            # 0x17ae => ?
+            0x178e => 'HSS',
+        },
+    },
+    0x34 => {
+        Name => 'ExposureMode',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0x0000 => 'Program',
+            0x0001 => 'Aperture Priority',
+            0x0002 => 'Shutter Priority',
+            0x0003 => 'Manual',
+            0x0004 => 'Auto',
+            0x0005 => 'Program Shift A',
+            0x0006 => 'Program Shift S',
+            0x1013 => 'Portrait',
+            0x1023 => 'Sports',
+            0x1033 => 'Sunset',
+            0x1043 => 'Night View/Portrait',
+            0x1053 => 'Landscape',
+            0x1083 => 'Macro',
+        },
+    },
+    0x36 => {
+        Name => 'ColorMode',
+        Format => 'int16u',
+        PrintConv => {
+            0x00 => 'Standard',
+            0x01 => 'Vivid',
+            0x02 => 'Portrait',
+            0x03 => 'Landscape',
+            0x04 => 'Sunset',
+            0x05 => 'Night View',
+            0x07 => 'B&W',
+            0x08 => 'Adobe RGB',
+        },
+    },
+    0x38 => {
+        Name => 'AverageLV',
+        Format => 'int16u',
+        Notes => 'arithmetic mean of the readings from the 40 honeycomb segments',
+        ValueConv => '($val-106)/8',
+        ValueConvInv => '$val * 8 + 106',
+    },
+    # 0x3a - int16u: Approx FocusDistance in metres (0x0f50=inf)
+    0x3c => {
+        Name => 'FrameNumber',
+        # Numbers > 1 appear in continuous and continuous bracketing drive modes,
+        # as well as WB bracketing.
+    },
+    0x96  => { Name => 'WB_RGBLevels',              Format => 'int16u[3]' },
+    0xae  => { Name => 'WB_GBRGLevels',             Format => 'int16u[4]' },
+    0xc0  => {
+        Name => 'WB_RedLevelsTungsten',
+        Notes => '7 values for adjustments of -3 through +3',
+        Format => 'int16u[7]',
+    },
+    0xce  => { Name => 'WB_BlueLevelsTungsten',     Format => 'int16u[7]' },
+    0xdc  => { Name => 'WB_RedLevelsDaylight',      Format => 'int16u[7]' },
+    0xea  => { Name => 'WB_BlueLevelsDaylight',     Format => 'int16u[7]' },
+    0xf8  => { Name => 'WB_RedLevelsCloudy',        Format => 'int16u[7]' },
+    0x106 => { Name => 'WB_BlueLevelsCloudy',       Format => 'int16u[7]' },
+    0x114 => { Name => 'WB_RedLevelsFlash',         Format => 'int16u[7]' },
+    0x122 => { Name => 'WB_BlueLevelsFlash',        Format => 'int16u[7]' },
+    0x14c => {
+        Name => 'WB_RedLevelsFluorescent',
         Format => 'int16u[7]',
         Notes => q{
-            white balance red presets for fluorescent -2 through +4.  -2=Fluorescent,
+            white balance red presets for fluorescent -2 through +4:  -2=Fluorescent,
             -1=WhiteFluorescent, 0=CoolWhiteFluorescent, +1=DayWhiteFluorescent and
             +3=DaylightFluorescent
         },
     },
-    0x40a => {
-        Name => 'WB_BluePresetsFluorescent',
-        Format => 'int16u[7]',
-        Notes => 'white balance blue presets for fluorescent -2 through +4',
-    },
-    0x418 => { Name => 'WB_RBPresetShade',                 Format => 'int16u[2]' },
-    0x424 => { Name => 'WB_RBPresetCustom',                Format => 'int16u[2]' },
+    0x15a => { Name => 'WB_BlueLevelsFluorescent',  Format => 'int16u[7]' },
+    0x168 => { Name => 'WB_RedLevelsShade',         Format => 'int16u[7]' },
+    0x176 => { Name => 'WB_BlueLevelsShade',        Format => 'int16u[7]' },
+    0x188 => { Name => 'WB_RedLevel6500K',          Format => 'int16u' },
+    0x18a => { Name => 'WB_BlueLevel6500K',         Format => 'int16u' },
+    0x18c => { Name => 'WB_RedLevelCustom',         Format => 'int16u' },
+    0x18e => { Name => 'WB_BlueLevelCustom',        Format => 'int16u' },
+    0x198 => { Name => 'WB_RedLevel3500K',          Format => 'int16u' },
+    0x19a => { Name => 'WB_BlueLevel3500K',         Format => 'int16u' },
+    0x1be => {
+        Name => 'WB_RedLevelsKelvin',
+        Format => 'int16u[75]',
+        Notes => 'values for 2500-9900 K, in increments of 100 K',
+    },
+    0x254 => { Name => 'WB_BlueLevelsKelvin',       Format => 'int16u[75]' },
+    0x304 => { Name => 'WB_RBLevelsFlash',          Format => 'int16u[2]' },
+    0x308 => { Name => 'WB_RBLevelsCoolWhiteF',     Format => 'int16u[2]' },
+    0x3e8 => { Name => 'WB_RBLevelsTungsten',       Format => 'int16u[2]' },
+    0x3ec => { Name => 'WB_RBLevelsDaylight',       Format => 'int16u[2]' },
+    0x3f0 => { Name => 'WB_RBLevelsCloudy',         Format => 'int16u[2]' },
+    0x3f4 => { Name => 'WB_RBLevelsFlash',          Format => 'int16u[2]' },
+    0x3fc => { Name => 'WB_RedLevelsFluorescent',   Format => 'int16u[7]' },
+    0x40a => { Name => 'WB_BlueLevelsFluorescent',  Format => 'int16u[7]' },
+    0x418 => { Name => 'WB_RBLevelsShade',          Format => 'int16u[2]' },
+    0x420 => { Name => 'WB_RBLevels6500K',          Format => 'int16u[2]' },
+    0x424 => { Name => 'WB_RBLevelsCustom',         Format => 'int16u[2]' },
+    0x430 => { Name => 'WB_RBLevels3500K',          Format => 'int16u[2]' },
+    0x528 => { Name => 'WB_RBLevelsDaylight',       Format => 'int16u[2]' },
+    0x546 => { Name => 'WB_RGBLevels',              Format => 'int16u[3]' },
+    0x628 => {
+        Name => 'AEMeteringSegments',
+        Format => 'int8u[40]',
+        Notes => q{
+            metering values from the 40 honeycomb segments, converted to LV.  The first
+            value is for the outer cell, then the values are given row by row, from top
+            to bottom, with each row scanned left-to-right.  The 21st value is the
+            middle cell, which gives the spot metering
+        },
+        ValueConv    => sub { join ' ', map( { ($_ - 106) / 8 } split(' ',$_[0]) ) },
+        ValueConvInv => sub { join ' ', map( { int($_ * 8 + 106.5) } split(' ',$_[0]) ) },
+    },
+    0x690 => {
+        Name => 'MeasuredLV',
+        Notes => 'measured light value based on MeteringMode',
+        ValueConv => '($val-106)/8',
+        ValueConvInv => '$val * 8 + 106',
+    },
+    0x691 => {
+        Name => 'BrightnessValue',
+        ValueConv => '($val-106)/8',
+        ValueConvInv => '$val * 8 + 106',
+    },
+    # 0x87f - int8u: 33mm Equivalent magnification (FocusDistance = (1.5 * $val + 1) * FocalLength) (255=inf)
+    0x104c => { # (9600 bytes: 4 sets of 40x30 int16u values in the range 0-8191)
+        Name => 'TiffMeteringImage',
+        Format => 'undef[9600]',
+        Notes => q{
+            13-bit RBGG (?) 40x30 pixels, presumably metering info, converted to a 16-bit
+            TIFF image;
+        },
+        ValueConv => sub {
+            my ($val, $et) = @_;
+            return undef unless length $val >= 9600;
+            return \ "Binary data 7404 bytes" unless $et->Options('Binary');
+            my @dat = unpack('n*', $val);  # for Big-endian
+            # TIFF header for a 16-bit RGB 10dpi 40x30 image
+            $val = Image::ExifTool::MakeTiffHeader(40,30,3,16,10);
+            # re-order data to RGB pixels
+            my ($i, @val);
+            for ($i=0; $i<40*30; ++$i) {
+                # data is 13-bit (max 8191), shift left to fill 16 bits
+                # (typically, this gives a very dark image since the data should
+                # really be anti-logged to convert from EV to perceived brightness)
+#                 push @val, $dat[$i]<<3, $dat[$i+2400]<<3, $dat[$i+1200]<<3;
+                push @val, int(5041.1*log($dat[$i]+1)/log(2)), int(5041.1*log($dat[$i+2400]+1)/log(2)), int(5041.1*log($dat[$i+1200]+1)/log(2));
+            }
+            $val .= pack('v*', @val);   # add TIFF strip data
+            return \$val;
+        },
+    },
+    0x49b8 => {
+        Name => 'ExposureTime',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x49ba => {
+        Name => 'ISO',
+        ValueConv => '2 ** (($val-48)/8) * 100',
+        ValueConvInv => '48 + 8*log($val/100)/log(2)',
+        PrintConv => 'int($val + 0.5)',
+        PrintConvInv => '$val',
+    },
+    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)
+        Name => 'FocusDistance',
+        ValueConv => '2**(($val-126)/16)',
+        ValueConvInv => 'log($val)/log(2)*16+126',
+        PrintConv => '$val > 266 ? "inf" : sprintf("%.2f m", $val)',
+        PrintConvInv => '$val=~s/ ?m//; $val=~/inf/i ? 267 : $val',
+    },
+    0x49bd => {
+        Name => 'LensType',
+        Format => 'int16uRev',
+        SeparateTable => 1,
+        ValueConvInv => 'int($val)', # (must truncate decimal part)
+        PrintConv => \%minoltaLensTypes,
+    },
+    0x49c0 => {
+        Name => 'ExposureCompensation', # (in exposure bracketing, this is the actual value used)
+        Format => 'int8s',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x49c1 => {
+        Name => 'FlashExposureComp',
+        Description => 'Flash Exposure Compensation',
+        Format => 'int8s',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x49c2 => {
+        Name => 'ImageStabilization',
+        PrintConv => \%offOn,
+    },
+    0x49c3 => {
+        Name => 'BrightnessValue',
+        ValueConv => '($val-106)/8',
+        ValueConvInv => '$val * 8 + 106',
+    },
+    0x49c5 => {
+        Name => 'MaxAperture',
+        ValueConv => '2 ** (($val-8)/16)',
+        ValueConvInv => '8 + 16*log($val)/log(2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    # 0x49c6 - gives focal length using same formula as 0x49bb
+    0x49c7 => {
+        Name => 'FNumber',
+        ValueConv => '2 ** (($val-8)/16)',
+        ValueConvInv => '8 + 16*log($val)/log(2)',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
     0x49dc => {
         Name => 'InternalSerialNumber',
@@ -2166,5 +2893,5 @@
     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;
@@ -2202,5 +2929,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -2221,6 +2948,7 @@
 Thanks to Jay Al-Saadi, Niels Kristian Bech Jensen, Shingo Noguchi, Pedro
 Corte-Real, Jeffery Small, Jens Duttke,  Thomas Kassner, Mladen Sever, Olaf
-Ulrich, Lukasz Stelmach and Igal Milchtaich for the information they
-provided, and for everyone who helped with the LensType list.
+Ulrich, Lukasz Stelmach, Igal Milchtaich, Jos Roost and Michael Reitinger
+for the information they provided, and for everyone who helped with the
+LensType list.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MinoltaRaw.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MinoltaRaw.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/MinoltaRaw.pm	(revision 34921)
@@ -18,5 +18,5 @@
 use Image::ExifTool::Minolta;
 
-$VERSION = '1.12';
+$VERSION = '1.16';
 
 sub ProcessMRW($$;$);
@@ -60,8 +60,10 @@
     WRITABLE => 1,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0 ],
     FIRST_ENTRY => 0,
     0 => {
         Name => 'FirmwareID',
         Format => 'string[8]',
+        RawConv => '$$self{MinoltaPRD} = 1 if $$self{FILE_TYPE} eq "MRW"; $val',  # used in decoding RIF info
     },
     8 => {
@@ -101,4 +103,5 @@
         Format => 'int8u',
         PrintConv => {
+            # 0 - seen in some Sony A850 ARW images
             1 => 'RGGB',
             4 => 'GBRG',
@@ -186,5 +189,6 @@
                 my ($val, $inv) = @_;
                 return int(2 ** (($val-48)/8) * 100 + 0.5) unless $inv;
-                return 48 + 8*log($val/100)/log(2) if Image::ExifTool::IsFloat($val);
+                # (must check for zero below in inverse conversion)
+                return 48 + 8*log($val/100)/log(2) if Image::ExifTool::IsFloat($val) and $val != 0;
                 return undef;
             },
@@ -213,8 +217,8 @@
         },
     ],
-    # NOTE: some of these WB_RBLevels may apply to other models too...
+    # NOTE: WB_RBLevels up to Custom also apply to Minolta models which write PRD info (ref IB)
     8  => { #3
         Name => 'WB_RBLevelsTungsten',
-        Condition => '$$self{Model} eq "DSLR-A100"',
+        Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
         Format => 'int16u[2]',
         Notes => 'these WB_RBLevels currently decoded only for the Sony A100',
@@ -222,27 +226,26 @@
     12 => { #3
         Name => 'WB_RBLevelsDaylight',
-        Condition => '$$self{Model} eq "DSLR-A100"',
+        Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
         Format => 'int16u[2]',
     },
     16 => { #3
         Name => 'WB_RBLevelsCloudy',
-        Condition => '$$self{Model} eq "DSLR-A100"',
+        Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
         Format => 'int16u[2]',
     },
     20 => { #3
         Name => 'WB_RBLevelsCoolWhiteF',
-        Condition => '$$self{Model} eq "DSLR-A100"',
+        Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
         Format => 'int16u[2]',
     },
     24 => { #3
         Name => 'WB_RBLevelsFlash',
-        Condition => '$$self{Model} eq "DSLR-A100"',
+        Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
         Format => 'int16u[2]',
     },
     28 => { #3
-        Name => 'WB_RBLevelsUnknown',
-        Condition => '$$self{Model} eq "DSLR-A100"',
-        Format => 'int16u[2]',
-        Unknown => 1,
+        Name => 'WB_RBLevelsCustom', #IB
+        Condition => '$$self{Model} eq "DSLR-A100" or $$self{MinoltaPRD}',
+        Format => 'int16u[2]',
     },
     32 => { #3
@@ -308,5 +311,5 @@
     76 => { #3
         Name => 'ColorTemperature',
-        Condition => '$$self{Make} =~ /^SONY/ and $$self{Model} eq "DSLR-A100"',
+        Condition => '$$self{Model} eq "DSLR-A100"',
         Notes => 'A100',
         ValueConv => '$val * 100',
@@ -317,10 +320,10 @@
     77 => { #3
         Name => 'ColorFilter',
-        Condition => '$$self{Make} =~ /^SONY/ and $$self{Model} eq "DSLR-A100"',
+        Condition => '$$self{Model} eq "DSLR-A100"',
         Notes => 'A100',
     },
     78 => { #3
         Name => 'ColorTemperature',
-        Condition => '$$self{Make} =~ /^SONY/ and $$self{Model} =~ /^DSLR-A(200|700)$/',
+        Condition => '$$self{Model} =~ /^DSLR-A(200|700)$/',
         Notes => 'A200 and A700',
         ValueConv => '$val * 100',
@@ -331,6 +334,13 @@
     79 => { #3
         Name => 'ColorFilter',
-        Condition => '$$self{Make} =~ /^SONY/ and $$self{Model} =~ /^DSLR-A(200|700)$/',
+        Condition => '$$self{Model} =~ /^DSLR-A(200|700)$/',
         Notes => 'A200 and A700',
+    },
+    80 => { #3
+        Name => 'RawDataLength',
+        Condition => '$$self{Model} eq "DSLR-A100"',
+        Format => 'int32u',
+        Notes => 'A100',
+        Writable => 0,
     },
 );
@@ -362,14 +372,14 @@
 
 #------------------------------------------------------------------------------
-# Write MRW directory (ie. in ARW images)
+# Write MRW directory (eg. in ARW images)
 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
 # Returns: new MRW data or undef on error
 sub WriteMRW($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;      # allow dummy access
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;      # allow dummy access
     my $buff = '';
     $$dirInfo{OutFile} = \$buff;
-    ProcessMRW($exifTool, $dirInfo, $tagTablePtr) > 0 or undef $buff;
+    ProcessMRW($et, $dirInfo, $tagTablePtr) > 0 or undef $buff;
     return $buff;
 }
@@ -382,9 +392,9 @@
 sub ProcessMRW($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     my ($data, $err, $outBuff);
 
@@ -401,8 +411,8 @@
     my $hdr = "\0MR$1";
     SetByteOrder($1 . $1);
-    $exifTool->SetFileType();
+    $et->SetFileType();
     $tagTablePtr = GetTagTable('Image::ExifTool::MinoltaRaw::Main');
     if ($outfile) {
-        $exifTool->InitWriteDirs('TIFF'); # use same write dirs as TIFF
+        $et->InitWriteDirs('TIFF'); # use same write dirs as TIFF
         $outBuff = '';
     }
@@ -418,16 +428,16 @@
         my $len = Get32u(\$data, 4);
         if ($verbose) {
-            print $out "MRW ",$exifTool->Printable($tag)," segment ($len bytes):\n";
+            print $out "MRW ",$et->Printable($tag)," segment ($len bytes):\n";
             if ($verbose > 2) {
                 $raf->Read($data,$len) == $len and $raf->Seek($pos,0) or $err = 1, last;
-                $exifTool->VerboseDump(\$data);
+                $et->VerboseDump(\$data);
             }
         }
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($tagInfo and $$tagInfo{SubDirectory}) {
             my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
             my $buff;
             # save shift for values stored with wrong base offset
-            $$exifTool{MRW_WrongBase} = -($raf->Tell());
+            $$et{MRW_WrongBase} = -($raf->Tell());
             $raf->Read($buff, $len) == $len or $err = 1, last;
             my %subdirInfo = (
@@ -443,5 +453,5 @@
             if ($outfile) {
                 my $writeProc = $tagInfo->{SubDirectory}->{WriteProc};
-                my $val = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
+                my $val = $et->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
                 if (defined $val and length $val) {
                     # pad to an even 4 bytes (can't hurt, and it seems to be the standard)
@@ -453,5 +463,5 @@
             } else {
                 my $processProc = $tagInfo->{SubDirectory}->{ProcessProc};
-                $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
+                $et->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
             }
         } elsif ($outfile) {
@@ -477,7 +487,7 @@
         # Sony IDC utility corrupts MRWInfo when writing ARW images,
         # so make this a minor error for these images
-        $err and $exifTool->Error("MRW format error", $$exifTool{TIFF_TYPE} eq 'ARW');
+        $err and $et->Error("MRW format error", $$et{TIFF_TYPE} eq 'ARW');
     } else {
-        $err and $exifTool->Warn("MRW format error");
+        $err and $et->Warn("MRW format error");
     }
     return $rtnVal;
@@ -503,5 +513,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Motorola.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Motorola.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Motorola.pm	(revision 34921)
@@ -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-2021, 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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Nikon.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Nikon.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Nikon.pm	(revision 34921)
@@ -38,10 +38,19 @@
 #              23) Alexandre Naaman private communication (D3)
 #              24) Geert De Soete private communication
-#              25) Niels Kristian private communication
 #              26) Bozi (http://www.cpanforum.com/posts/8983)
 #              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) https://exiftool.org/forum/index.php/topic,3833.30.html
+#              31) Michael Relt private communication
+#              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
 #------------------------------------------------------------------------------
 
@@ -49,9 +58,10 @@
 
 use strict;
-use vars qw($VERSION);
+use vars qw($VERSION %nikonLensIDs %nikonTextEncoding);
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
-
-$VERSION = '2.47';
+use Image::ExifTool::GPS;
+
+$VERSION = '3.93';
 
 sub LensIDConv($$$);
@@ -60,16 +70,19 @@
 sub FormatString($);
 sub ProcessNikonCaptureEditVersions($$$);
+sub PrintAFPoints($$);
+sub PrintAFPointsInv($$);
+sub PrintAFPointsGrid($$);
+sub PrintAFPointsGridInv($$$);
+sub GetAFPointGrid($$;$);
 
 # nikon lens ID numbers (ref 8/11)
-my %nikonLensIDs = (
+%nikonLensIDs = (
     Notes => q{
         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).
     },
@@ -79,4 +92,5 @@
     # (hex digits must be uppercase in keys below)
     '01 58 50 50 14 14 02 00' => 'AF Nikkor 50mm f/1.8',
+    '01 58 50 50 14 14 05 00' => 'AF Nikkor 50mm f/1.8',
     '02 42 44 5C 2A 34 02 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5',
     '02 42 44 5C 2A 34 08 00' => 'AF Zoom-Nikkor 35-70mm f/3.3-4.5',
@@ -96,4 +110,5 @@
     '10 48 8E 8E 30 30 08 00' => 'AF Nikkor 300mm f/4 IF-ED',
     '11 48 44 5C 24 24 08 00' => 'AF Zoom-Nikkor 35-70mm f/2.8',
+    '11 48 44 5C 24 24 15 00' => 'AF Zoom-Nikkor 35-70mm f/2.8', #Jakob Dettner
     '12 48 5C 81 30 3C 09 00' => 'AF Nikkor 70-210mm f/4-5.6',
     '13 42 37 50 2A 34 0B 00' => 'AF Zoom-Nikkor 24-50mm f/3.3-4.5',
@@ -115,4 +130,5 @@
     '24 48 60 80 24 24 1A 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED',
     '25 48 44 5C 24 24 1B 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D',
+    '25 48 44 5C 24 24 3A 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D',
     '25 48 44 5C 24 24 52 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D',
     '26 40 3C 5C 2C 34 1C 02' => 'AF Zoom-Nikkor 28-70mm f/3.5-4.5D',
@@ -149,5 +165,5 @@
     '3A 40 3C 5C 2C 34 39 02' => 'AF Zoom-Nikkor 28-70mm f/3.5-4.5D',
     '3B 48 44 5C 24 24 3A 02' => 'AF Zoom-Nikkor 35-70mm f/2.8D N',
-    '3C 48 60 80 24 24 3B 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED', #25
+    '3C 48 60 80 24 24 3B 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED', #NJ
     '3D 3C 44 60 30 3C 3E 02' => 'AF Zoom-Nikkor 35-80mm f/4-5.6D',
     '3E 48 3C 3C 24 24 3D 02' => 'AF Nikkor 28mm f/2.8D',
@@ -181,4 +197,5 @@
     '53 48 60 80 24 24 60 02' => 'AF Zoom-Nikkor 80-200mm f/2.8D ED',
     '54 44 5C 7C 34 3C 58 02' => 'AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED',
+    '54 44 5C 7C 34 3C 61 02' => 'AF Zoom-Micro Nikkor 70-180mm f/4.5-5.6D ED',
     '56 48 5C 8E 30 3C 5A 02' => 'AF Zoom-Nikkor 70-300mm f/4-5.6D ED',
     '59 48 98 98 24 24 5D 02' => 'AF-S Nikkor 400mm f/2.8D IF-ED',
@@ -223,4 +240,12 @@
     '89 3C 53 80 30 3C 8B 06' => 'AF-S DX Zoom-Nikkor 55-200mm f/4-5.6G ED',
     '8A 54 6A 6A 24 24 8C 0E' => 'AF-S VR Micro-Nikkor 105mm f/2.8G IF-ED', #10
+    # when the TC-20 III 2x teleconverter is used with the above lens, the following have been observed:
+    # 8A 4D 6A 6A 24 24 8C 0E
+    # 8A 4E 6A 6A 24 24 8C 0E
+    # 8A 50 6A 6A 24 24 8C 0E
+    # 8A 51 6A 6A 24 24 8C 0E
+    # 8A 52 6A 6A 24 24 8C 0E
+    # 8A 53 6A 6A 24 24 8C 0E
+    # 8A 54 6A 6A 24 24 8C 0E (same as without the TC)
     '8B 40 2D 80 2C 3C 8D 0E' => 'AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED',
     '8B 40 2D 80 2C 3C FD 0E' => 'AF-S DX VR Zoom-Nikkor 18-200mm f/3.5-5.6G IF-ED [II]', #20
@@ -252,12 +277,69 @@
     'A4 54 37 37 0C 0C A6 06' => 'AF-S Nikkor 24mm f/1.4G ED',
     '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 VR Nikkor 300mm f/2.8G IF-ED II',
+    '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', #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 VR Nikkor 55-300mm 4.5-5.6G ED',
+    'AC 38 53 8E 34 3C AE 0E' => 'AF-S DX Nikkor 55-300mm f/4.5-5.6G ED VR',
+    'AD 3C 2D 8E 2C 3C AF 0E' => 'AF-S DX Nikkor 18-300mm f/3.5-5.6G ED VR',
     'AE 54 62 62 0C 0C B0 06' => 'AF-S Nikkor 85mm f/1.4G',
     'AF 54 44 44 0C 0C B1 06' => 'AF-S Nikkor 35mm f/1.4G',
     'B0 4C 50 50 14 14 B2 06' => 'AF-S Nikkor 50mm f/1.8G',
+    'B1 48 48 48 24 24 B3 06' => 'AF-S DX Micro Nikkor 40mm f/2.8G', #27
+    'B2 48 5C 80 30 30 B4 0E' => 'AF-S Nikkor 70-200mm f/4G ED VR', #35
+    'B3 4C 62 62 14 14 B5 06' => 'AF-S Nikkor 85mm f/1.8G',
+    'B4 40 37 62 2C 34 B6 0E' => 'AF-S Zoom-Nikkor 24-85mm f/3.5-4.5G IF-ED VR', #30
+    'B5 4C 3C 3C 14 14 B7 06' => 'AF-S Nikkor 28mm f/1.8G', #30
+    'B6 3C B0 B0 3C 3C B8 0E' => 'AF-S VR Nikkor 800mm f/5.6E FL ED',
+    'B6 3C B0 B0 3C 3C B8 4E' => 'AF-S VR Nikkor 800mm f/5.6E FL ED', #PH
+    'B7 44 60 98 34 3C B9 0E' => 'AF-S Nikkor 80-400mm f/4.5-5.6G ED VR',
+    'B8 40 2D 44 2C 34 BA 06' => 'AF-S Nikkor 18-35mm f/3.5-4.5G ED',
+    'A0 40 2D 74 2C 3C BB 0E' => 'AF-S DX Nikkor 18-140mm f/3.5-5.6G ED VR', #PH
+    'A1 54 55 55 0C 0C BC 06' => 'AF-S Nikkor 58mm f/1.4G', #IB
+    'A1 48 6E 8E 24 24 DB 4E' => 'AF-S Nikkor 120-300mm f/2.8E FL ED SR VR', #28
+    'A2 40 2D 53 2C 3C BD 0E' => 'AF-S DX Nikkor 18-55mm f/3.5-5.6G VR II',
+    'A4 40 2D 8E 2C 40 BF 0E' => 'AF-S DX Nikkor 18-300mm f/3.5-6.3G ED VR',
+    'A5 4C 44 44 14 14 C0 06' => 'AF-S Nikkor 35mm f/1.8G ED', #35 ("ED" ref 11)
+    'A6 48 98 98 24 24 C1 0E' => 'AF-S Nikkor 400mm f/2.8E FL ED VR',
+    'A7 3C 53 80 30 3C C2 0E' => 'AF-S DX Nikkor 55-200mm f/4-5.6G ED VR II', #IB
+    'A8 48 8E 8E 30 30 C3 4E' => 'AF-S Nikkor 300mm f/4E PF ED VR', #35
+    'A8 48 8E 8E 30 30 C3 0E' => 'AF-S Nikkor 300mm f/4E PF ED VR', #30
+    'A9 4C 31 31 14 14 C4 06' => 'AF-S Nikkor 20mm f/1.8G ED', #30
+    'AA 48 37 5C 24 24 C5 4E' => 'AF-S Nikkor 24-70mm f/2.8E ED VR',
+    'AA 48 37 5C 24 24 C5 0E' => 'AF-S Nikkor 24-70mm f/2.8E ED VR',
+    'AB 3C A0 A0 30 30 C6 4E' => 'AF-S Nikkor 500mm f/4E FL ED VR',
+    'AC 3C A6 A6 30 30 C7 4E' => 'AF-S Nikkor 600mm f/4E FL ED VR', #PH
+    'AD 48 28 60 24 30 C8 4E' => 'AF-S DX Nikkor 16-80mm f/2.8-4E ED VR',
+    'AD 48 28 60 24 30 C8 0E' => 'AF-S DX Nikkor 16-80mm f/2.8-4E ED VR', #PH
+    'AE 3C 80 A0 3C 3C C9 4E' => 'AF-S Nikkor 200-500mm f/5.6E ED VR', #PH
+    'AE 3C 80 A0 3C 3C C9 0E' => 'AF-S Nikkor 200-500mm f/5.6E ED VR',
+    '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',
+    'A4 48 5C 80 24 24 CF 0E' => 'AF-S Nikkor 70-200mm f/2.8E FL ED VR',
+    'A5 54 6A 6A 0C 0C D0 46' => 'AF-S Nikkor 105mm f/1.4E ED', #IB
+    'A5 54 6A 6A 0C 0C D0 06' => 'AF-S Nikkor 105mm f/1.4E ED', #IB
+    'A6 48 2F 2F 30 30 D1 46' => 'PC Nikkor 19mm f/4E ED',
+    'A6 48 2F 2F 30 30 D1 06' => 'PC Nikkor 19mm f/4E ED',
+    'A7 40 11 26 2C 34 D2 46' => 'AF-S Fisheye Nikkor 8-15mm f/3.5-4.5E ED',
+    'A7 40 11 26 2C 34 D2 06' => 'AF-S Fisheye Nikkor 8-15mm f/3.5-4.5E ED',
+    'A8 38 18 30 34 3C D3 8E' => 'AF-P DX Nikkor 10-20mm f/4.5-5.6G VR', #Yang You pvt communication
+    'A8 38 18 30 34 3C D3 0E' => 'AF-P DX Nikkor 10-20mm f/4.5-5.6G VR',
+    'A9 48 7C 98 30 30 D4 4E' => 'AF-S Nikkor 180-400mm f/4E TC1.4 FL ED VR', #IB
+    'A9 48 7C 98 30 30 D4 0E' => 'AF-S Nikkor 180-400mm f/4E TC1.4 FL ED VR',
+    'AA 48 88 A4 3C 3C D5 4E' => 'AF-S Nikkor 180-400mm f/4E TC1.4 FL ED VR + 1.4x TC', #IB
+    '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',
+    'AD 3C A0 A0 3C 3C D8 4E' => 'AF-S Nikkor 500mm f/5.6E PF ED VR',
     '01 00 00 00 00 00 02 00' => 'TC-16A',
     '01 00 00 00 00 00 08 00' => 'TC-16A',
@@ -268,9 +350,13 @@
     '26 48 11 11 30 30 1C 02' => 'Sigma 8mm F4 EX Circular Fisheye',
     '79 40 11 11 2C 2C 1C 06' => 'Sigma 8mm F3.5 EX Circular Fisheye', #JD
+    'DB 40 11 11 2C 2C 1C 06' => 'Sigma 8mm F3.5 EX DG Circular Fisheye', #30
     'DC 48 19 19 24 24 4B 06' => 'Sigma 10mm F2.8 EX DC HSM Fisheye',
+    'C2 4C 24 24 14 14 4B 06' => 'Sigma 14mm F1.8 DG HSM | A', #IB
+    '48 48 24 24 24 24 4B 02' => 'Sigma 14mm F2.8 EX Aspherical HSM',
     '02 3F 24 24 2C 2C 02 00' => 'Sigma 14mm F3.5',
-    '48 48 24 24 24 24 4B 02' => 'Sigma 14mm F2.8 EX Aspherical HSM',
     '26 48 27 27 24 24 1C 02' => 'Sigma 15mm F2.8 EX Diagonal Fisheye',
+    'EA 48 27 27 24 24 1C 02' => 'Sigma 15mm F2.8 EX Diagonal Fisheye', #30
     '26 58 31 31 14 14 1C 02' => 'Sigma 20mm F1.8 EX DG Aspherical RF',
+    '79 54 31 31 0C 0C 4B 06' => 'Sigma 20mm F1.4 DG HSM | A', #Rolf Probst
     '26 58 37 37 14 14 1C 02' => 'Sigma 24mm F1.8 EX DG Aspherical Macro',
     'E1 58 37 37 14 14 1C 02' => 'Sigma 24mm F1.8 EX DG Aspherical Macro',
@@ -279,16 +365,25 @@
     '48 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM',
     'F8 54 3E 3E 0C 0C 4B 06' => 'Sigma 30mm F1.4 EX DC HSM', #JD
+    '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', #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',
-    '02 48 65 65 24 24 02 00' => 'Sigma 90mm F2.8 Macro',
+    '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',
-    '48 48 76 76 24 24 4B 06' => 'Sigma 150mm F2.8 EX DG APO Macro HSM',
-    'F5 48 76 76 24 24 4B 06' => 'Sigma 150mm F2.8 EX DG APO Macro HSM', #24
-    '48 4C 7C 7C 2C 2C 4B 02' => 'Sigma 180mm F3.5 EX DG Macro',
+    '97 48 6A 6A 24 24 4B 0E' => 'Sigma Macro 105mm F2.8 EX DG OS HSM',
+    '48 48 76 76 24 24 4B 06' => 'Sigma APO Macro 150mm F2.8 EX DG HSM',
+    'F5 48 76 76 24 24 4B 06' => 'Sigma APO Macro 150mm F2.8 EX DG HSM', #24
+    '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
@@ -308,13 +403,20 @@
     '48 38 1F 37 34 3C 4B 06' => 'Sigma 12-24mm F4.5-5.6 EX DG Aspherical HSM',
     'F0 38 1F 37 34 3C 4B 06' => 'Sigma 12-24mm F4.5-5.6 EX DG Aspherical HSM',
+    '96 38 1F 37 34 3C 4B 06' => 'Sigma 12-24mm F4.5-5.6 II DG HSM', #Jurgen Sahlberg
+    'C1 48 24 37 24 24 4B 46' => 'Sigma 14-24mm F2.8 DG HSM | A', #30
     '26 40 27 3F 2C 34 1C 02' => 'Sigma 15-30mm F3.5-4.5 EX DG Aspherical DF',
     '48 48 2B 44 24 30 4B 06' => 'Sigma 17-35mm F2.8-4 EX DG  Aspherical HSM',
     '26 54 2B 44 24 30 1C 02' => 'Sigma 17-35mm F2.8-4 EX Aspherical',
+    '9D 48 2B 50 24 24 4B 0E' => 'Sigma 17-50mm F2.8 EX DC OS HSM',
+    '8F 48 2B 50 24 24 4B 0E' => 'Sigma 17-50mm F2.8 EX DC OS HSM', #http://dev.exiv2.org/boards/3/topics/1747
     '7A 47 2B 5C 24 34 4B 06' => 'Sigma 17-70mm F2.8-4.5 DC Macro Asp. IF HSM',
     '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',
-    '26 40 2D 44 2B 34 1C 02' => 'Sigma 18-35 F3.5-4.5 Aspherical',
+    '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', #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',
-    '7F 48 2D 50 24 24 1C 06' => 'Sigma 18-50mm F2.8 EX DC Macro', #25
+    '7F 48 2D 50 24 24 1C 06' => 'Sigma 18-50mm F2.8 EX DC Macro', #NJ
     '7A 48 2D 50 24 24 4B 06' => 'Sigma 18-50mm F2.8 EX DC Macro',
     'F6 48 2D 50 24 24 4B 06' => 'Sigma 18-50mm F2.8 EX DC Macro',
@@ -325,19 +427,44 @@
     'CD 3D 2D 70 2E 3C 4B 0E' => 'Sigma 18-125mm F3.8-5.6 DC OS HSM',
     '26 40 2D 80 2C 40 1C 06' => 'Sigma 18-200mm F3.5-6.3 DC',
+    'FF 40 2D 80 2C 40 4B 06' => 'Sigma 18-200mm F3.5-6.3 DC', #30
     '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
+  # '92 2C 2D 88 2C 40 4B 0E' (250mm)
+  # '92 2B 2D 88 2C 40 4B 0E' (210mm)
+  # '92 2C 2D 88 2C 40 4B 0E' (185mm)
+  # '92 2D 2D 88 2C 40 4B 0E' (155mm)
+  # '92 2E 2D 88 2C 40 4B 0E' (130mm)
+  # '92 2F 2D 88 2C 40 4B 0E' (105mm)
+  # '92 30 2D 88 2C 40 4B 0E' (90mm)
+  # '92 32 2D 88 2C 40 4B 0E' (75mm)
+  # '92 33 2D 88 2C 40 4B 0E' (62mm)
+  # '92 35 2D 88 2C 40 4B 0E' (52mm)
+  # '92 37 2D 88 2C 40 4B 0E' (44mm)
+  # '92 39 2D 88 2C 40 4B 0E' (38mm)
+  # '92 3A 2D 88 2C 40 4B 0E' (32mm)
+  # '92 3E 2D 88 2C 40 4B 0E' (22mm)
+  # '92 40 2D 88 2C 40 4B 0E' (18mm)
     '26 48 31 49 24 24 1C 02' => 'Sigma 20-40mm F2.8',
+    '7B 48 37 44 18 18 4B 06' => 'Sigma 24-35mm F2.0 DG HSM | A', #30
+    '02 3A 37 50 31 3D 02 00' => 'Sigma 24-50mm F4-5.6 UC',
     '26 48 37 56 24 24 1C 02' => 'Sigma 24-60mm F2.8 EX DG',
     'B6 48 37 56 24 24 1C 02' => 'Sigma 24-60mm F2.8 EX DG',
     'A6 48 37 5C 24 24 4B 06' => 'Sigma 24-70mm F2.8 IF EX DG HSM', #JD
+    'C9 48 37 5C 24 24 4B 4E' => 'Sigma 24-70mm F2.8 DG OS HSM | A', #30
     '26 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro',
     '67 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro',
     'E9 54 37 5C 24 24 1C 02' => 'Sigma 24-70mm F2.8 EX DG Macro',
     '26 40 37 5C 2C 3C 1C 02' => 'Sigma 24-70mm F3.5-5.6 Aspherical HF',
+    '8A 3C 37 6A 30 30 4B 0E' => 'Sigma 24-105mm F4 DG OS HSM', #IB
     '26 54 37 73 24 34 1C 02' => 'Sigma 24-135mm F2.8-4.5',
     '02 46 3C 5C 25 25 02 00' => 'Sigma 28-70mm F2.8',
     '26 54 3C 5C 24 24 1C 02' => 'Sigma 28-70mm F2.8 EX',
     '26 48 3C 5C 24 24 1C 06' => 'Sigma 28-70mm F2.8 EX DG',
+    '79 48 3C 5C 24 24 1C 06' => 'Sigma 28-70mm F2.8 EX DG', #30 ("D" removed)
     '26 48 3C 5C 24 30 1C 02' => 'Sigma 28-70mm F2.8-4 DG',
     '02 3F 3C 5C 2D 35 02 00' => 'Sigma 28-70mm F3.5-4.5 UC',
@@ -350,10 +477,12 @@
     '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',
+    'CC 4C 50 68 14 14 4B 06' => 'Sigma 50-100mm F1.8 DC HSM | A', #30
     '7A 47 50 76 24 24 4B 06' => 'Sigma 50-150mm F2.8 EX APO DC HSM',
     'FD 47 50 76 24 24 4B 06' => 'Sigma 50-150mm F2.8 EX APO DC HSM II',
+    '98 48 50 76 24 24 4B 0E' => 'Sigma 50-150mm F2.8 EX APO DC OS HSM', #30
     '48 3C 50 A0 30 40 4B 02' => 'Sigma 50-500mm F4-6.3 EX APO RF HSM',
     '9F 37 50 A0 34 40 4B 0E' => 'Sigma 50-500mm F4.5-6.3 DG OS HSM', #16
@@ -365,4 +494,5 @@
     '9C 48 5C 80 24 24 4B 0E' => 'Sigma 70-200mm F2.8 EX DG OS HSM', #Rolando Ruzic
     '02 46 5C 82 25 25 02 00' => 'Sigma 70-210mm F2.8 APO', #JD
+    '02 40 5C 82 2C 35 02 00' => 'Sigma APO 70-210mm F3.5-4.5',
     '26 3C 5C 82 30 3C 1C 02' => 'Sigma 70-210mm F4-5.6 UC-II',
     '26 3C 5C 8E 30 3C 1C 02' => 'Sigma 70-300mm F4-5.6 DG Macro',
@@ -373,18 +503,29 @@
     '02 3A 5E 8E 32 3D 02 00' => 'Sigma 75-300mm F4.0-5.6',
     '77 44 61 98 34 3C 7B 0E' => 'Sigma 80-400mm F4.5-5.6 EX OS',
-    '48 48 68 8E 30 30 4B 02' => 'Sigma 100-300mm F4 EX IF HSM',
+    '77 44 60 98 34 3C 7B 0E' => 'Sigma 80-400mm F4.5-5.6 APO DG D OS',
+    '48 48 68 8E 30 30 4B 02' => 'Sigma APO 100-300mm F4 EX IF HSM',
     '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',
     '26 44 73 98 34 3C 1C 02' => 'Sigma 135-400mm F4.5-5.6 APO Aspherical',
     'CE 34 76 A0 38 40 4B 0E' => 'Sigma 150-500mm F5-6.3 DG OS APO HSM', #JD
+    '81 34 76 A6 38 40 4B 0E' => 'Sigma 150-600mm F5-6.3 DG OS HSM | S', #Jaap Voets
+    '82 34 76 A6 38 40 4B 0E' => 'Sigma 150-600mm F5-6.3 DG OS HSM | C',
+    'C4 4C 73 73 14 14 4B 46' => 'Sigma 135mm F1.8 DG HSM | A', #forum3833
     '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)',
@@ -393,29 +534,47 @@
     'F8 55 64 64 24 24 84 06' => 'Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)',
     'F8 54 64 64 24 24 DF 06' => 'Tamron SP AF 90mm f/2.8 Di Macro 1:1 (272NII)',
+    'FE 54 64 64 24 24 DF 0E' => 'Tamron SP 90mm f/2.8 Di VC USD Macro 1:1 (F004)', #Jurgen Sahlberg
+    'E4 54 64 64 24 24 DF 0E' => 'Tamron SP 90mm f/2.8 Di VC USD Macro 1:1 (F017)', #Rolf Probst
     '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)',
     '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
+    '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
+    '7C 54 2B 50 24 24 00 06' => 'Tamron SP AF 17-50mm f/2.8 XR Di II LD Aspherical (IF) (A16)', #PH (https://github.com/Exiv2/exiv2/issues/1155)
     '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)', #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)', #25
+    '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 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 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)',
     '0E 4A 31 48 23 2D 0E 02' => 'Tamron SP AF 20-40mm f/2.7-3.5 (166D)',
+    'FE 48 37 5C 24 24 DF 0E' => 'Tamron SP 24-70mm f/2.8 Di VC USD (A007)', #24
+    'CE 47 37 5C 25 25 DF 4E' => 'Tamron SP 24-70mm f/2.8 Di VC USD G2 (A032)', #forum9110
     '45 41 37 72 2C 3C 48 02' => 'Tamron SP AF 24-135mm f/3.5-5.6 AD Aspherical (IF) Macro (190D)',
     '33 54 3C 5E 24 24 62 02' => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09)',
     'FA 54 3C 5E 24 24 84 06' => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09NII)', #JD
+    'FA 54 3C 5E 24 24 DF 06' => 'Tamron SP AF 28-75mm f/2.8 XR Di LD Aspherical (IF) Macro (A09NII)',
     '10 3D 3C 60 2C 3C D2 02' => 'Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)',
     '45 3D 3C 60 2C 3C 48 02' => 'Tamron AF 28-80mm f/3.5-5.6 Aspherical (177D)',
     '00 48 3C 6A 24 24 00 02' => 'Tamron SP AF 28-105mm f/2.8 LD Aspherical IF (176D)',
+    '4D 3E 3C 80 2E 3C 62 02' => 'Tamron AF 28-200mm f/3.8-5.6 XR Aspherical (IF) Macro (A03N)',
     '0B 3E 3D 7F 2F 3D 0E 00' => 'Tamron AF 28-200mm f/3.8-5.6 (71D)',
     '0B 3E 3D 7F 2F 3D 0E 02' => 'Tamron AF 28-200mm f/3.8-5.6D (171D)',
@@ -424,11 +583,19 @@
     '4D 41 3C 8E 2C 40 62 02' => 'Tamron AF 28-300mm f/3.5-6.3 XR LD Aspherical (IF) (185D)',
     'F9 40 3C 8E 2C 40 40 0E' => 'Tamron AF 28-300mm f/3.5-6.3 XR Di VC LD Aspherical (IF) Macro (A20)',
+    'C9 3C 44 76 25 31 DF 4E' => 'Tamron 35-150mm f/2.8-4 Di VC OSD (A043)', #30
     '00 47 53 80 30 3C 00 06' => 'Tamron AF 55-200mm f/4-5.6 Di II LD (A15)',
     'F7 53 5C 80 24 24 84 06' => 'Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)',
     'FE 53 5C 80 24 24 84 06' => 'Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)',
-    '69 48 5C 8E 30 3C 6F 02' => 'Tamron AF 70-300mm f/4-5.6 LD Macro 1:2 (772D)',
+    'F7 53 5C 80 24 24 40 06' => 'Tamron SP AF 70-200mm f/2.8 Di LD (IF) Macro (A001)',
+  # 'FE 54 5C 80 24 24 DF 0E' => 'Tamron SP AF 70-200mm f/2.8 Di VC USD (A009)',
+    'FE 54 5C 80 24 24 DF 0E' => 'Tamron SP 70-200mm f/2.8 Di VC USD (A009)', #NJ
+    'E2 47 5C 80 24 24 DF 4E' => 'Tamron SP 70-200mm f/2.8 Di VC USD G2 (A025)', #forum9549
+    '69 48 5C 8E 30 3C 6F 02' => 'Tamron AF 70-300mm f/4-5.6 LD Macro 1:2 (572D/772D)',
     '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 (A17)', #JD
+    '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)',
     '00 3E 80 A0 38 3F 00 02' => 'Tamron SP AF 200-500mm f/5-6.3 Di LD (IF) (A08)',
@@ -437,18 +604,24 @@
     '00 40 2B 2B 2C 2C 00 02' => 'Tokina AT-X 17 AF PRO (AF 17mm f/3.5)',
     '00 47 44 44 24 24 00 06' => 'Tokina AT-X M35 PRO DX (AF 35mm f/2.8 Macro)',
-    '00 54 68 68 24 24 00 02' => 'Tokina AT-X M100 PRO D (AF 100mm f/2.8 Macro)',
+    '00 54 68 68 24 24 00 02' => 'Tokina AT-X M100 AF PRO D (AF 100mm f/2.8 Macro)',
     '27 48 8E 8E 30 30 1D 02' => 'Tokina AT-X 304 AF (AF 300mm f/4.0)',
     '00 54 8E 8E 24 24 00 02' => 'Tokina AT-X 300 AF PRO (AF 300mm f/2.8)',
     '12 3B 98 98 3D 3D 09 00' => 'Tokina AT-X 400 AF SD (AF 400mm f/5.6)',
-    '00 40 18 2B 2C 34 00 06' => 'Tokina AT-X 107 DX Fisheye (AF 10-17mm f/3.5-4.5)',
+    '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)',
+    '7A 3C 1F 3C 30 30 7E 06' => 'Tokina AT-X 12-28 PRO DX (AF 12-28mm f/4)',
     '00 48 29 3C 24 24 00 06' => 'Tokina AT-X 16-28 AF PRO FX (AF 16-28mm f/2.8)',
     '00 48 29 50 24 24 00 06' => 'Tokina AT-X 165 PRO DX (AF 16-50mm f/2.8)',
     '00 40 2A 72 2C 3C 00 06' => 'Tokina AT-X 16.5-135 DX (AF 16.5-135mm F3.5-5.6)',
+    '00 3C 2B 44 30 30 00 06' => 'Tokina AT-X 17-35 F4 PRO FX (AF 17-35mm f/4)',
     '2F 40 30 44 2C 34 29 02.2' => 'Tokina AF 193 (AF 19-35mm f/3.5-4.5)',
     '2F 48 30 44 24 24 29 02.2' => 'Tokina AT-X 235 AF PRO (AF 20-35mm f/2.8)',
     '2F 40 30 44 2C 34 29 02.1' => 'Tokina AF 235 II (AF 20-35mm f/3.5-4.5)',
+    '00 48 37 5C 24 24 00 06' => 'Tokina AT-X 24-70 F2.8 PRO FX (AF 24-70mm f/2.8)',
     '00 40 37 80 2C 3C 00 02' => 'Tokina AT-X 242 AF (AF 24-200mm f/3.5-5.6)',
     '25 48 3C 5C 24 24 1B 02.1' => 'Tokina AT-X 270 AF PRO II (AF 28-70mm f/2.6-2.8)',
@@ -460,4 +633,6 @@
     '25 44 44 8E 34 42 1B 02' => 'Tokina AF 353 (AF 35-300mm f/4.5-6.7)',
     '00 48 50 72 24 24 00 06' => 'Tokina AT-X 535 PRO DX (AF 50-135mm f/2.8)',
+    '00 3C 5C 80 30 30 00 0E' => 'Tokina AT-X 70-200 F4 FX VCM-S (AF 70-200mm f/4)',
+    '00 48 5C 80 30 30 00 0E' => 'Tokina AT-X 70-200 F4 FX VCM-S (AF 70-200mm f/4)',
     '12 44 5E 8E 34 3C 09 00' => 'Tokina AF 730 (AF 75-300mm F4.5-5.6)',
     '14 54 60 80 24 24 0B 00' => 'Tokina AT-X 828 AF (AF 80-200mm f/2.8)',
@@ -474,23 +649,50 @@
     '12 3B 68 8D 3D 43 09 02' => 'Cosina AF Zoom 100-300mm F5.6-6.7 MC Macro',
 #
+    '12 38 69 97 35 42 09 02' => 'Promaster Spectrum 7 100-400mm F4.5-6.7',
+#
     '00 40 31 31 2C 2C 00 00' => 'Voigtlander Color Skopar 20mm F3.5 SLII Aspherical',
+    '00 48 3C 3C 24 24 00 00' => 'Voigtlander Color Skopar 28mm F2.8 SL II',
     '00 54 48 48 18 18 00 00' => 'Voigtlander Ultron 40mm F2 SLII Aspherical',
     '00 54 55 55 0C 0C 00 00' => 'Voigtlander Nokton 58mm F1.4 SLII',
     '00 40 64 64 2C 2C 00 00' => 'Voigtlander APO-Lanthar 90mm F3.5 SLII Close Focus',
 #
-    '00 40 2D 2D 2C 2C 00 00' => 'Carl Zeiss Distagon T* 3,5/18 ZF.2',
-    '00 48 32 32 24 24 00 00' => 'Carl Zeiss Distagon T* 2,8/21 ZF.2',
+    '00 40 2D 2D 2C 2C 00 00' => 'Carl Zeiss Distagon T* 3.5/18 ZF.2',
+    '00 48 27 27 24 24 00 00' => 'Carl Zeiss Distagon T* 2.8/15 ZF.2', #MykytaKozlov
+    '00 48 32 32 24 24 00 00' => 'Carl Zeiss Distagon T* 2.8/21 ZF.2',
+    '00 54 38 38 18 18 00 00' => 'Carl Zeiss Distagon T* 2/25 ZF.2',
     '00 54 3C 3C 18 18 00 00' => 'Carl Zeiss Distagon T* 2/28 ZF.2',
+    '00 54 44 44 0C 0C 00 00' => 'Carl Zeiss Distagon T* 1.4/35 ZF.2',
     '00 54 44 44 18 18 00 00' => 'Carl Zeiss Distagon T* 2/35 ZF.2',
-    '00 54 50 50 0C 0C 00 00' => 'Carl Zeiss Planar T* 1,4/50 ZF.2',
+    '00 54 50 50 0C 0C 00 00' => 'Carl Zeiss Planar T* 1.4/50 ZF.2',
     '00 54 50 50 18 18 00 00' => 'Carl Zeiss Makro-Planar T* 2/50 ZF.2',
-    '00 54 62 62 0C 0C 00 00' => 'Carl Zeiss Planar T* 1,4/85 ZF.2',
+    '00 54 62 62 0C 0C 00 00' => 'Carl Zeiss Planar T* 1.4/85 ZF.2',
     '00 54 68 68 18 18 00 00' => 'Carl Zeiss Makro-Planar T* 2/100 ZF.2',
+    '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',
+    '55 54 62 62 0C 0C 00 00' => 'Zeiss Milvus 85mm f/1.4', #IB
+    '56 54 68 68 18 18 00 00' => 'Zeiss Milvus 100mm f/2 Macro',
 #
     '00 54 56 56 30 30 00 00' => 'Coastal Optical Systems 60mm 1:4 UV-VIS-IR Macro Apo',
 #
-    '4A 48 24 24 24 0C 4D 02' => 'Samyang AE 14mm f/2.8 ED AS IF UMC', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,3150.0.html
+    'BF 4E 26 26 1E 1E 01 04' => 'Irix 15mm f/2.4 Firefly', #30
+    'BF 3C 1B 1B 30 30 01 04' => 'Irix 11mm f/4 Firefly', #30
+#
+    '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', #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',
@@ -499,14 +701,29 @@
     '03 43 5C 81 35 35 02 00' => 'Soligor AF C/D Zoom UMCS 70-210mm 1:4.5',
     '12 4A 5C 81 31 3D 09 00' => 'Soligor AF C/D Auto Zoom+Macro 70-210mm 1:4-5.6 UMCS',
+    '12 36 69 97 35 42 09 00' => 'Soligor AF Zoom 100-400mm 1:4.5-6.7 MC',
 #
     '00 00 00 00 00 00 00 01' => 'Manual Lens No CPU',
 #
+    '00 00 48 48 53 53 00 01' => 'Loreo 40mm F11-22 3D Lens in a Cap 9005', #PH
     '00 47 10 10 24 24 00 00' => 'Fisheye Nikkor 8mm f/2.8 AiS',
-    '00 54 44 44 0C 0C 00 00' => 'Nikkor 35mm f/1.4 AiS',
+    '00 47 3C 3C 24 24 00 00' => 'Nikkor 28mm f/2.8 AiS', #35
+  # '00 54 44 44 0C 0C 00 00' => 'Nikkor 35mm f/1.4 AiS', comment out in favour of Zeiss with same ID because this lens is rare (requires CPU upgrade)
+    '00 57 50 50 14 14 00 00' => 'Nikkor 50mm f/1.8 AI', #35
     '00 48 50 50 18 18 00 00' => 'Nikkor H 50mm f/2',
-    '00 58 64 64 20 20 00 00' => 'Soligor C/D Macro MC 90mm f/2.5',
     '00 48 68 68 24 24 00 00' => 'Series E 100mm f/2.8',
     '00 4C 6A 6A 20 20 00 00' => 'Nikkor 105mm f/2.5 AiS',
     '00 48 80 80 30 30 00 00' => 'Nikkor 200mm f/4 AiS',
+    '00 40 11 11 2C 2C 00 00' => 'Samyang 8mm f/3.5 Fish-Eye',
+    '00 58 64 64 20 20 00 00' => 'Soligor C/D Macro MC 90mm f/2.5',
+    '4A 58 30 30 14 0C 4D 02' => 'Rokinon 20mm f/1.8 ED AS UMC', #30
+);
+
+# text encoding used in LocationInfo (ref PH)
+%nikonTextEncoding = (
+    0 => 'n/a',
+    1 => 'UTF8',
+    # UTF16 is a guess here: it could also be Unicode or JIS,
+    # but I chose UTF16 due to the similarity with the QuickTime stringEncoding
+    2 => 'UTF16',
 );
 
@@ -525,4 +742,6 @@
     '5 1' => '5.01 (SB-900)',
     '5 2' => '5.02 (SB-900)',
+    '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) = @_;
@@ -535,14 +754,14 @@
 # flash Guide Number (GN) distance settings (ref 28)
 my %flashGNDistance = (
-    0 => 0,         19 => '2.8 m',
-    1 => '0.1 m',   20 => '3.2 m',
-    2 => '0.2 m',   21 => '3.6 m',
-    3 => '0.3 m',   22 => '4.0 m',
-    4 => '0.4 m',   23 => '4.5 m',
-    5 => '0.5 m',   24 => '5.0 m',
-    6 => '0.6 m',   25 => '5.6 m',
-    7 => '0.7 m',   26 => '6.3 m',
-    8 => '0.8 m',   27 => '7.1 m',
-    9 => '0.9 m',   28 => '8.0 m',
+     0 => 0,        19 => '2.8 m',
+     1 => '0.1 m',  20 => '3.2 m',
+     2 => '0.2 m',  21 => '3.6 m',
+     3 => '0.3 m',  22 => '4.0 m',
+     4 => '0.4 m',  23 => '4.5 m',
+     5 => '0.5 m',  24 => '5.0 m',
+     6 => '0.6 m',  25 => '5.6 m',
+     7 => '0.7 m',  26 => '6.3 m',
+     8 => '0.8 m',  27 => '7.1 m',
+     9 => '0.9 m',  28 => '8.0 m',
     10 => '1.0 m',  29 => '9.0 m',
     11 => '1.1 m',  30 => '10.0 m',
@@ -554,4 +773,17 @@
     17 => '2.2 m',  36 => '20.0 m',
     18 => '2.5 m',  255 => 'n/a',
+);
+
+# flash color filter values (ref 28)
+my %flashColorFilter = (
+    0x00 => 'None',
+    1 => 'FL-GL1 or SZ-2FL Fluorescent', # (green) (SZ model ref PH)
+    2 => 'FL-GL2',
+    9 => 'TN-A1 or SZ-2TN Incandescent', # (orange) (SZ model ref PH)
+    10 => 'TN-A2',
+    65 => 'Red',
+    66 => 'Blue',
+    67 => 'Yellow',
+    68 => 'Amber',
 );
 
@@ -569,12 +801,12 @@
 
 my %retouchValues = ( #PH
-    0 => 'None',
-    3 => 'B & W',
-    4 => 'Sepia',
-    5 => 'Trim',
-    6 => 'Small Picture',
-    7 => 'D-Lighting',
-    8 => 'Red Eye',
-    9 => 'Cyanotype',
+     0 => 'None',
+     3 => 'B & W',
+     4 => 'Sepia',
+     5 => 'Trim',
+     6 => 'Small Picture',
+     7 => 'D-Lighting',
+     8 => 'Red Eye',
+     9 => 'Cyanotype',
     10 => 'Sky Light',
     11 => 'Warm Tone',
@@ -593,5 +825,225 @@
     30 => 'Color Outline',
     31 => 'Soft Filter',
+    32 => 'Resize', #31
     33 => 'Miniature Effect',
+    34 => 'Skin Softening', # (S9200)
+    35 => 'Selected Frame', #31 (frame exported from MOV)
+    37 => 'Color Sketch', #31
+    38 => 'Selective Color', # (S9200)
+    39 => 'Glamour', # (S3500)
+    40 => 'Drawing', # (S9200)
+    44 => 'Pop', # (S3500)
+    45 => 'Toy Camera Effect 1', # (S3500)
+    46 => 'Toy Camera Effect 2', # (S3500)
+    47 => 'Cross Process (red)', # (S3500)
+    48 => 'Cross Process (blue)', # (S3500)
+    49 => 'Cross Process (green)', # (S3500)
+    50 => 'Cross Process (yellow)', # (S3500)
+    51 => 'Super Vivid', # (S3500)
+    52 => 'High-contrast Monochrome', # (S3500)
+    53 => 'High Key', # (S3500)
+    54 => 'Low Key', # (S3500)
+);
+
+# AF point indices for models with 51 focus points, eg. D3 (ref JD/PH)
+#        A1  A2  A3  A4  A5  A6  A7  A8  A9
+#    B1  B2  B3  B4  B5  B6  B7  B8  B9  B10  B11
+#    C1  C2  C3  C4  C5  C6  C7  C8  C9  C10  C11
+#    D1  D2  D3  D4  D5  D6  D7  D8  D9  D10  D11
+#        E1  E2  E3  E4  E5  E6  E7  E8  E9
+my %afPoints51 = (
+     1 => 'C6', 11 => 'C5', 21 => 'C9', 31 => 'C11',41 => 'A2', 51 => 'D1',
+     2 => 'B6', 12 => 'B5', 22 => 'B9', 32 => 'B11',42 => 'D3',
+     3 => 'A5', 13 => 'A4', 23 => 'A8', 33 => 'D11',43 => 'E2',
+     4 => 'D6', 14 => 'D5', 24 => 'D9', 34 => 'C4', 44 => 'C2',
+     5 => 'E5', 15 => 'E4', 25 => 'E8', 35 => 'B4', 45 => 'B2',
+     6 => 'C7', 16 => 'C8', 26 => 'C10',36 => 'A3', 46 => 'A1',
+     7 => 'B7', 17 => 'B8', 27 => 'B10',37 => 'D4', 47 => 'D2',
+     8 => 'A6', 18 => 'A7', 28 => 'A9', 38 => 'E3', 48 => 'E1',
+     9 => 'D7', 19 => 'D8', 29 => 'D10',39 => 'C3', 49 => 'C1',
+    10 => 'E6', 20 => 'E7', 30 => 'E9', 40 => 'B3', 50 => 'B1',
+);
+
+# AF point indices for models with 39 focus points, eg. D7000 (ref 29)
+#                    A1  A2  A3
+#    B1  B2  B3  B4  B5  B6  B7  B8  B9  B10  B11
+#    C1  C2  C3  C4  C5  C6  C7  C8  C9  C10  C11
+#    D1  D2  D3  D4  D5  D6  D7  D8  D9  D10  D11
+#                    E1  E2  E3
+my %afPoints39 = (
+     1 => 'C6', 11 => 'C5', 21 => 'D9', 31 => 'C3',
+     2 => 'B6', 12 => 'B5', 22 => 'C10',32 => 'B3',
+     3 => 'A2', 13 => 'A1', 23 => 'B10',33 => 'D3',
+     4 => 'D6', 14 => 'D5', 24 => 'D10',34 => 'C2',
+     5 => 'E2', 15 => 'E1', 25 => 'C11',35 => 'B2',
+     6 => 'C7', 16 => 'C8', 26 => 'B11',36 => 'D2',
+     7 => 'B7', 17 => 'B8', 27 => 'D11',37 => 'C1',
+     8 => 'A3', 18 => 'D8', 28 => 'C4', 38 => 'B1',
+     9 => 'D7', 19 => 'C9', 29 => 'B4', 39 => 'D1',
+    10 => 'E3', 20 => 'B9', 30 => 'D4',
+);
+
+# AF point indices for models with 105 focus points, eg. D6 (ref 28)
+# - 7 rows (A-G) with 15 columns (1-15), center is D8
+my %afPoints105 = (
+     1 => 'D8',  28 => 'G7',  55 => 'F13', 82 => 'E4',
+     2 => 'C8',  29 => 'D6',  56 => 'G13', 83 => 'F4',
+     3 => 'B8',  30 => 'C6',  57 => 'D14', 84 => 'G4',
+     4 => 'A8',  31 => 'B6',  58 => 'C14', 85 => 'D3',
+     5 => 'E8',  32 => 'A6',  59 => 'B14', 86 => 'C3',
+     6 => 'F8',  33 => 'E6',  60 => 'A14', 87 => 'B3',
+     7 => 'G8',  34 => 'F6',  61 => 'E14', 88 => 'A3',
+     8 => 'D9',  35 => 'G6',  62 => 'F14', 89 => 'E3',
+     9 => 'C9',  36 => 'D11', 63 => 'G14', 90 => 'F3',
+    10 => 'B9',  37 => 'C11', 64 => 'D15', 91 => 'G3',
+    11 => 'A9',  38 => 'B11', 65 => 'C15', 92 => 'D2',
+    12 => 'E9',  39 => 'A11', 66 => 'B15', 93 => 'C2',
+    13 => 'F9',  40 => 'E11', 67 => 'A15', 94 => 'B2',
+    14 => 'G9',  41 => 'F11', 68 => 'E15', 95 => 'A2',
+    15 => 'D10', 42 => 'G11', 69 => 'F15', 96 => 'E2',
+    16 => 'C10', 43 => 'D12', 70 => 'G15', 97 => 'F2',
+    17 => 'B10', 44 => 'C12', 71 => 'D5',  98 => 'G2',
+    18 => 'A10', 45 => 'B12', 72 => 'C5',  99 => 'D1',
+    19 => 'E10', 46 => 'A12', 73 => 'B5', 100 => 'C1',
+    20 => 'F10', 47 => 'E12', 74 => 'A5', 101 => 'B1',
+    21 => 'G10', 48 => 'F12', 75 => 'E5', 102 => 'A1',
+    22 => 'D7',  49 => 'G12', 76 => 'F5', 103 => 'E1',
+    23 => 'C7',  50 => 'D13', 77 => 'G5', 104 => 'F1',
+    24 => 'B7',  51 => 'C13', 78 => 'D4', 105 => 'G1',
+    25 => 'A7',  52 => 'B13', 79 => 'C4',
+    26 => 'E7',  53 => 'A13', 80 => 'B4',
+    27 => 'F7',  54 => 'E13', 81 => 'A4',
+);
+
+# AF point indices for models with 135 focus points, eg. 1J1 (ref PH)
+# - 9 rows (A-I) with 15 columns (1-15), center is E8
+# - odd columns, columns 2 and 14, and the remaining corner points are
+#   not used in 41-point mode
+my %afPoints135 = (
+     1 => 'E8', 28 => 'E10', 55 => 'E13',  82 => 'E6', 109 => 'E3',
+     2 => 'D8', 29 => 'D10', 56 => 'D13',  83 => 'D6', 110 => 'D3',
+     3 => 'C8', 30 => 'C10', 57 => 'C13',  84 => 'C6', 111 => 'C3',
+     4 => 'B8', 31 => 'B10', 58 => 'B13',  85 => 'B6', 112 => 'B3',
+     5 => 'A8', 32 => 'A10', 59 => 'A13',  86 => 'A6', 113 => 'A3',
+     6 => 'F8', 33 => 'F10', 60 => 'F13',  87 => 'F6', 114 => 'F3',
+     7 => 'G8', 34 => 'G10', 61 => 'G13',  88 => 'G6', 115 => 'G3',
+     8 => 'H8', 35 => 'H10', 62 => 'H13',  89 => 'H6', 116 => 'H3',
+     9 => 'I8', 36 => 'I10', 63 => 'I13',  90 => 'I6', 117 => 'I3',
+    10 => 'E9', 37 => 'E11', 64 => 'E14',  91 => 'E5', 118 => 'E2',
+    11 => 'D9', 38 => 'D11', 65 => 'D14',  92 => 'D5', 119 => 'D2',
+    12 => 'C9', 39 => 'C11', 66 => 'C14',  93 => 'C5', 120 => 'C2',
+    13 => 'B9', 40 => 'B11', 67 => 'B14',  94 => 'B5', 121 => 'B2',
+    14 => 'A9', 41 => 'A11', 68 => 'A14',  95 => 'A5', 122 => 'A2',
+    15 => 'F9', 42 => 'F11', 69 => 'F14',  96 => 'F5', 123 => 'F2',
+    16 => 'G9', 43 => 'G11', 70 => 'G14',  97 => 'G5', 124 => 'G2',
+    17 => 'H9', 44 => 'H11', 71 => 'H14',  98 => 'H5', 125 => 'H2',
+    18 => 'I9', 45 => 'I11', 72 => 'I14',  99 => 'I5', 126 => 'I2',
+    19 => 'E7', 46 => 'E12', 73 => 'E15', 100 => 'E4', 127 => 'E1',
+    20 => 'D7', 47 => 'D12', 74 => 'D15', 101 => 'D4', 128 => 'D1',
+    21 => 'C7', 48 => 'C12', 75 => 'C15', 102 => 'C4', 129 => 'C1',
+    22 => 'B7', 49 => 'B12', 76 => 'B15', 103 => 'B4', 130 => 'B1',
+    23 => 'A7', 50 => 'A12', 77 => 'A15', 104 => 'A4', 131 => 'A1',
+    24 => 'F7', 51 => 'F12', 78 => 'F15', 105 => 'F4', 132 => 'F1',
+    25 => 'G7', 52 => 'G12', 79 => 'G15', 106 => 'G4', 133 => 'G1',
+    26 => 'H7', 53 => 'H12', 80 => 'H15', 107 => 'H4', 134 => 'H1',
+    27 => 'I7', 54 => 'I12', 81 => 'I15', 108 => 'I4', 135 => 'I1',
+);
+
+# AF point indices for models with 153 focus points, eg. D5,D500 (ref PH)
+# - 9 rows (A-I) with 17 columns (1-17), center is E9
+# - 55 of these are selectable cross points (odd rows and columns 1,3,4,6,7,9,11,12,14,15,17)
+my %afPoints153 = (
+     1 => 'E9',  32 => 'A8',  63 => 'I13',  94 => 'B17', 125 => 'H4',
+     2 => 'D9',  33 => 'F8',  64 => 'E14',  95 => 'A17', 126 => 'I4',
+     3 => 'C9',  34 => 'G8',  65 => 'D14',  96 => 'F17', 127 => 'E3',
+     4 => 'B9',  35 => 'H8',  66 => 'C14',  97 => 'G17', 128 => 'D3',
+     5 => 'A9',  36 => 'I8',  67 => 'B14',  98 => 'H17', 129 => 'C3',
+     6 => 'F9',  37 => 'E7',  68 => 'A14',  99 => 'I17', 130 => 'B3',
+     7 => 'G9',  38 => 'D7',  69 => 'F14', 100 => 'E6',  131 => 'A3',
+     8 => 'H9',  39 => 'C7',  70 => 'G14', 101 => 'D6',  132 => 'F3',
+     9 => 'I9',  40 => 'B7',  71 => 'H14', 102 => 'C6',  133 => 'G3',
+    10 => 'E10', 41 => 'A7',  72 => 'I14', 103 => 'B6',  134 => 'H3',
+    11 => 'D10', 42 => 'F7',  73 => 'E15', 104 => 'A6',  135 => 'I3',
+    12 => 'C10', 43 => 'G7',  74 => 'D15', 105 => 'F6',  136 => 'E2',
+    13 => 'B10', 44 => 'H7',  75 => 'C15', 106 => 'G6',  137 => 'D2',
+    14 => 'A10', 45 => 'I7',  76 => 'B15', 107 => 'H6',  138 => 'C2',
+    15 => 'F10', 46 => 'E12', 77 => 'A15', 108 => 'I6',  139 => 'B2',
+    16 => 'G10', 47 => 'D12', 78 => 'F15', 109 => 'E5',  140 => 'A2',
+    17 => 'H10', 48 => 'C12', 79 => 'G15', 110 => 'D5',  141 => 'F2',
+    18 => 'I10', 49 => 'B12', 80 => 'H15', 111 => 'C5',  142 => 'G2',
+    19 => 'E11', 50 => 'A12', 81 => 'I15', 112 => 'B5',  143 => 'H2',
+    20 => 'D11', 51 => 'F12', 82 => 'E16', 113 => 'A5',  144 => 'I2',
+    21 => 'C11', 52 => 'G12', 83 => 'D16', 114 => 'F5',  145 => 'E1',
+    22 => 'B11', 53 => 'H12', 84 => 'C16', 115 => 'G5',  146 => 'D1',
+    23 => 'A11', 54 => 'I12', 85 => 'B16', 116 => 'H5',  147 => 'C1',
+    24 => 'F11', 55 => 'E13', 86 => 'A16', 117 => 'I5',  148 => 'B1',
+    25 => 'G11', 56 => 'D13', 87 => 'F16', 118 => 'E4',  149 => 'A1',
+    26 => 'H11', 57 => 'C13', 88 => 'G16', 119 => 'D4',  150 => 'F1',
+    27 => 'I11', 58 => 'B13', 89 => 'H16', 120 => 'C4',  151 => 'G1',
+    28 => 'E8',  59 => 'A13', 90 => 'I16', 121 => 'B4',  152 => 'H1',
+    29 => 'D8',  60 => 'F13', 91 => 'E17', 122 => 'A4',  153 => 'I1',
+    30 => 'C8',  61 => 'G13', 92 => 'D17', 123 => 'F4',
+    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', # (1.5x)
+    3 => '5:4 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) = @_;
+        return undef if $inv;
+        my @a = split ' ', $val;
+        return "Unknown ($val)" unless @a == 7;
+        $a[0] = $$conv{$a[0]} || "Unknown ($a[0])";
+        return "$a[0] ($a[1]x$a[2] cropped to $a[3]x$a[4] at pixel $a[5],$a[6])";
+    },
 );
 
@@ -646,5 +1098,10 @@
     0x0005 => { Name => 'WhiteBalance', Writable => 'string' },
     0x0006 => { Name => 'Sharpness',    Writable => 'string' },
-    0x0007 => { Name => 'FocusMode',    Writable => 'string' },
+    0x0007 => {
+        Name => 'FocusMode',
+        DataMember => 'FocusMode',
+        Writable => 'string',
+        RawConv => '$$self{FocusMode} = $val',
+    },
     # FlashSetting (better named FlashSyncMode, ref 28) values:
     #   "Normal", "Slow", "Rear Slow", "RED-EYE", "RED-EYE SLOW"
@@ -656,6 +1113,6 @@
     #   no flash: ""
     0x0009 => { Name => 'FlashType',    Writable => 'string' }, #2 (count varies by model - PH)
-    # 0x000a - rational values: 5.6 to 9.283 - found in coolpix models - PH
-    #          (not correlated with any LV or scale factor)
+    # 0x000a - rational values: 5.6 to 9.33 - found in Coolpix models - PH
+    #          (seems constant for a given camera model, but not correlated with scale factor)
     0x000b => { #2
         Name => 'WhiteBalanceFineTune',
@@ -712,5 +1169,9 @@
         Writable => 'undef',
         Count => 4,
-        Notes => 'may be set even if flash does not fire',
+        # (includes the built-in compensation for FlashType "Built-in,TTL&Comdr.")
+        Notes => q{
+            may be set even if flash does not fire.  Does not include the effect of
+            flash bracketing.
+        },
         ValueConv => 'my ($a,$b,$c)=unpack("c3",$val); $c ? $a*($b/$c) : 0',
         ValueConvInv => q{
@@ -738,12 +1199,22 @@
             },
         },
-        { #PH
+        { #IB
             Name => 'NRWData',
-            Condition => '$$valPt =~ /^NRW/', # starts with "NRW 0100"
-            Notes => 'large unknown block in NRW images, not copied to JPEG images',
-            # 'Drop' because not found in JPEG images (too large for APP1 anyway)
-            Flags => [ 'Unknown', 'Binary', 'Drop' ],
+            Condition => '$$valPt =~ /^NRW 0100/',
+            Drop => 1,  # 'Drop' because it is large and not found in JPEG images
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalanceB',
+            },
+        },
+        { #IB
+            Name => 'NRWData',
+            Condition => '$$valPt =~ /^NRW /',
+            Drop => 1,  # 'Drop' because it is large and not found in JPEG images
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalanceC',
+            },
         },
     ],
+    # 0x0015 - string[8]: "AUTO   "
     # D70 Image boundary?? top x,y bot-right x,y
     0x0016 => { #2
@@ -790,10 +1261,5 @@
         Writable => 'int16u',
         Count => 7,
-        PrintConv => q{
-            my @a = split ' ', $val;
-            return "Unknown ($val)" unless @a == 7;
-            $a[0] = $a[0] ? "On" : "Off";
-            return "$a[0] ($a[1]x$a[2] cropped to $a[3]x$a[4] at pixel $a[5],$a[6])";
-        }
+        PrintConv => \%cropHiSpeed,
     },
     0x001c => { #28 (D3 "the application of CSb6 to the selected metering mode")
@@ -811,4 +1277,6 @@
     0x001d => { #4
         Name => 'SerialNumber',
+        # Note: this has been known to change even if the serial number on the body
+        # stays the same if some parts of the camera were replaced by Nikon service
         Writable => 'string',
         Protected => 1,
@@ -849,14 +1317,41 @@
             5 => 'High',
             7 => 'Extra High', #10
+            8 => 'Extra High 1', #PH
+            9 => 'Extra High 2', #PH
+            10 => 'Extra High 3', #PH
+            11 => 'Extra High 4', #PH
             0xffff => 'Auto', #10
         },
     },
-    0x0023 => { #PH (D300, but also found in D3,D3S,D3X,D90,D300S,D700,D3000,D5000)
-        Name => 'PictureControlData',
-        Writable => 'undef',
-        Permanent => 0,
-        Binary => 1,
-        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl' },
-    },
+    0x0023 => [
+        { #PH (D300, but also found in D3,D3S,D3X,D90,D300S,D700,D3000,D5000)
+            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
         Name => 'WorldTime',
@@ -870,5 +1365,5 @@
         SubDirectory => {
             TagTable => 'Image::ExifTool::Nikon::ISOInfo',
-            ByteOrder => 'BigEndian', #(NC)
+            ByteOrder => 'BigEndian',
         },
     },
@@ -887,5 +1382,4 @@
         SubDirectory => {
             TagTable => 'Image::ExifTool::Nikon::DistortInfo',
-            ByteOrder => 'BigEndian', #(NC)
         },
     },
@@ -897,4 +1391,5 @@
         },
     },
+    # 0x2d - "512 0 0","512 3 10","512 1 14",...
     0x0032 => { #PH
         Name => 'UnknownInfo2',
@@ -903,4 +1398,60 @@
             ByteOrder => 'BigEndian', #(NC)
         },
+    },
+    0x0034 => { #forum9646
+        Name => 'ShutterMode',
+        Writable => 'int16u',
+        PrintConv => {
+             0 => 'Mechanical',
+             16 => 'Electronic',
+           # 33 => ? seen for 1J2
+             48 => 'Electronic Front Curtain',
+             64 => 'Electronic (Movie)', #JanSkoda (Z6II)
+             80 => 'Auto (Mechanical)', #JanSkoda (Z6II)
+             81 => 'Auto (Electronic Front Curtain)', #JanSkoda (Z6II)
+        },
+    },
+    0x0035 => { #32
+        Name => 'HDRInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::HDRInfo' },
+    },
+    0x0037 => { #XavierJubier
+        Name => 'MechanicalShutterCount',
+        Writable => 'int32u',
+    },
+    0x0039 => {
+        Name => 'LocationInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LocationInfo' },
+    },
+    0x003d => { #IB
+        Name => 'BlackLevel',
+        Writable => 'int16u',
+        Count => 4,
+        # (may need to divide by 4 for some images, eg. D3300/D5300, 12 bit - ref IB)
+    },
+    0x003e => { #28
+        Name => 'ImageSizeRAW',
+        PrintConv => {
+             1 => 'Large',
+             2 => 'Medium',
+             3 => 'Small',
+        },
+    },
+    0x0045 => { #IB
+        Name => 'CropArea',
+        Notes => 'left, top, width, height',
+        Writable => 'int16u',
+        Count => 4,
+    },
+    0x004e => { #28
+        Name => 'NikonSettings',
+        Writable => 'undef',
+        Permanent => 0,
+        Flags => [ 'Binary', 'Protected' ],
+        SubDirectory => { TagTable => 'Image::ExifTool::NikonSettings::Main' },
+    },
+    0x004f => { #IB (D850)
+        Name => 'ColorTemperatureAuto',
+        Writable => 'int16u',
     },
     0x0080 => { Name => 'ImageAdjustment',  Writable => 'string' },
@@ -911,4 +1462,6 @@
         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,
             {
@@ -917,14 +1470,26 @@
                 2 => 'G',
                 3 => 'VR',
+                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;
         ],
@@ -956,4 +1521,5 @@
             8 => 'Fired, Commander Mode',
             9 => 'Fired, TTL Mode',
+            18 => 'LED Light', #G.F. (movie LED light)
         },
     },
@@ -986,4 +1552,18 @@
         # slows down your drive operation to 50% (1.5fps max not 3fps).  But no
         # longer does !$val alone indicate single-frame operation. - TC, D70
+        # The following comments are from Warren Hatch:
+        # Bits 4,6,8 indicate bracketing mode.
+        #  - all 0's => Bracketing Off
+        #  - bit 4 on with bits 6,8 off => Exposure Bracketing On
+        #  - bits 4,6 on => WB bracketing On
+        #  - 4,8 on => ADL Bracketing On
+        # Bit 2 gives tethered status:  Off=>Not Tethered; On=Tethered.
+        #  - that this simply indicates a camera is connected via a cord to a PC
+        #    (doesn't necessarily mean that the shutter was tripped by the computer)
+        # Bits 0,1,3,7,9 relate to how the shutter is tripped in concert with the
+        #  Release Mode dial [although I cannot cause bit 7 to flip with any of my gear and
+        #  I suspect it is no longer used for the D500].  Regardless, the ReleaseMode tag
+        #  offers a superior decoding of this information for the D4s, D810 and D500.
+        # Bit 5 indicates whether or not AutoISO is enabled.
         PrintConv => q[
             $_ = '';
@@ -997,8 +1577,10 @@
                 1 => 'Delay',
                 2 => 'PC Control',
+                3 => 'Self-timer', #forum6281 (NC)
                 4 => 'Exposure Bracketing',
                 5 => $$self{Model}=~/D70\b/ ? 'Unused LE-NR Slowdown' : 'Auto ISO',
                 6 => 'White-Balance Bracketing',
                 7 => 'IR Control',
+                8 => 'D-Lighting Bracketing', #forum6281 (NC)
             });
         ],
@@ -1018,7 +1600,9 @@
     0x008c => {
         Name => 'ContrastCurve', #JD
-        Writable => 0,
-        Binary => 1,
-    },
+        Writable => 'undef',
+        Flags => [ 'Binary', 'Protected', 'Drop' ], # (drop because not found in Nikon JPEG's)
+    },
+    # ColorHue: MODE1/MODE1a=sRGB, MODE2=Adobe RGB, MODE3a=more saturated sRGB
+    # --> should really be called ColorSpace or ColorMode, but that would conflict with other tags
     0x008d => { Name => 'ColorHue' ,        Writable => 'string' }, #2
     # SceneMode takes on the following values: PORTRAIT, PARTY/INDOOR, NIGHT PORTRAIT,
@@ -1046,5 +1630,5 @@
                 TagTable => 'Image::ExifTool::Nikon::ShotInfoD80',
                 DecryptStart => 4,
-                DecryptLen => 764,
+                DecryptLen => 765,
                 # (Capture NX can change the makernote byte order, but this stays big-endian)
                 ByteOrder => 'BigEndian',
@@ -1097,5 +1681,5 @@
                 TagTable => 'Image::ExifTool::Nikon::ShotInfoD3S',
                 DecryptStart => 4,
-                DecryptLen => 0x2e6,
+                DecryptLen => 0x2e9,
                 ByteOrder => 'BigEndian',
             },
@@ -1134,4 +1718,5 @@
             },
         },
+        # 0225 - D600
         { #29 (D700 firmware version 1.02f)
             Condition => '$$valPt =~ /^0212/ and $count == 5312',
@@ -1139,6 +1724,4 @@
             SubDirectory => {
                 TagTable => 'Image::ExifTool::Nikon::ShotInfoD700',
-                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
-                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
                 DecryptStart => 4,
                 DecryptLen => 0x358,
@@ -1146,4 +1729,39 @@
             },
         },
+        { #PH (D800 firmware 1.01a)
+            Condition => '$$valPt =~ /^0222/',
+            Name => 'ShotInfoD800',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD800',
+                DecryptStart => 4,
+                DecryptLen => 0x720,
+                ByteOrder => 'BigEndian',
+            },
+        },
+        { #28 (D810 firmware 1.01)
+            Condition => '$$valPt =~ /^0233/',
+            Name => 'ShotInfoD810',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD810',
+                DecryptStart => 4,
+                DecryptLen => 0x36f4 + 12,
+                DecryptMore => 'Get32u(\$data, 0x84) + 12',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        { #28 (D850 firmware 1.00b)
+            Condition => '$$valPt =~ /^0243/',
+            Name => 'ShotInfoD850',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD850',
+                DecryptStart => 4,
+                DecryptLen => 0x2efb + 12,
+                DecryptMore => 'Get32u(\$data, 0xa0) + 12',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        # 0217 - D3000
+        # 0219 - D3100
+        # 0224 - D3200
         { #PH
             Condition => '$$valPt =~ /^0215/ and $count == 6745',
@@ -1156,4 +1774,24 @@
             },
         },
+        { #PH
+            Condition => '$$valPt =~ /^0221/ and $count == 8902',
+            Name => 'ShotInfoD5100',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD5100',
+                DecryptStart => 4,
+                DecryptLen => 0x430,
+                ByteOrder => 'BigEndian',
+            },
+        },
+        { #PH
+            Condition => '$$valPt =~ /^0226/ and $count == 11587',
+            Name => 'ShotInfoD5200',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD5200',
+                DecryptStart => 4,
+                DecryptLen => 0xd00,
+                ByteOrder => 'BigEndian',
+            },
+        },
         { #29 (D7000 firmware version 1.01b)
             Condition => '$$valPt =~ /^0220/',
@@ -1161,6 +1799,4 @@
             SubDirectory => {
                 TagTable => 'Image::ExifTool::Nikon::ShotInfoD7000',
-                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
-                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
                 DecryptStart => 4,
                 DecryptLen => 0x448,
@@ -1168,6 +1804,78 @@
             },
         },
-        {
-            Condition => '$$valPt =~ /^02/',
+        { # (D4 firmware version 1.00g)
+            Condition => '$$valPt =~ /^0223/',
+            Name => 'ShotInfoD4',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD4',
+                DecryptStart => 4,
+                DecryptLen => 0x789,
+                ByteOrder => 'BigEndian',
+            },
+        },
+        { # (D4S firmware version 1.00d and 1.01a)
+            Condition => '$$valPt =~ /^0231/',
+            Name => 'ShotInfoD4S',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD4S',
+                DecryptStart => 4,
+                DecryptLen => 0x3697,
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        { #28 (D5 firmware version 1.10a)
+            Condition => '$$valPt =~ /^0238/',
+            Name => 'ShotInfoD5',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD500',
+                DecryptStart => 4,
+                DecryptLen => 0x2c24 + 12,
+                DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        { # (D500 firmware version 1.00)
+            Condition => '$$valPt =~ /^0239/',
+            Name => 'ShotInfoD500',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD500',
+                DecryptStart => 4,
+                DecryptLen => 0x2cb2 + 4,
+                DecryptMore => 'Get32u(\$data, 0xa8) + 0x2ea5 - 0x2c90',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        { # (D6 firmware version 1.00, ref 28)
+            Condition => '$$valPt =~ /^0246/',
+            Name => 'ShotInfoD6',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD6',
+                DecryptStart => 4,
+                DecryptLen => 0xc21a + 12,
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        { # (D610 firmware version 1.00)
+            Condition => '$$valPt =~ /^0232/',
+            Name => 'ShotInfoD610',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoD610',
+                DecryptStart => 4,
+                DecryptLen => 0x7ff,
+                ByteOrder => 'BigEndian',
+            },
+        },
+        { # (Z6_2 firmware version 1.00 and Z7_2 firmware versions 1.00 & 1.01, ref 28)
+            Condition => '$$valPt =~ /^0800/ or $$valPt =~ /^0803/',
+            Name => 'ShotInfoZ7_2',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ShotInfoZ7_2',
+                DecryptStart => 4,
+                DecryptLen => 0xce32 + 12,
+                ByteOrder => 'LittleEndian',
+            },
+        },
+        { # D7100=0227, Z6/Z7=0800
+            Condition => '$$valPt =~ /^0[28]/',
             Name => 'ShotInfo02xx',
             SubDirectory => {
@@ -1202,17 +1910,23 @@
             3 => 'Lossless',
             4 => 'Lossy (type 2)',
-        },
-    },
-    0x0094 => { Name => 'Saturation',       Writable => 'int16s' },
-    0x0095 => { Name => 'NoiseReduction',   Writable => 'string' },
+            5 => 'Striped packed 12 bits', #IB
+            6 => 'Uncompressed (reduced to 12 bit)', #IB
+            7 => 'Unpacked 12 bits', #IB (padded to 16)
+            8 => 'Small', #IB
+            9 => 'Packed 12 bits', #IB (2 pixels in 3 bytes)
+            10 => 'Packed 14 bits', #28 (4 pixels in 7 bytes, eg. D6 uncompressed 14 bit)
+        },
+    },
+    0x0094 => { Name => 'SaturationAdj',    Writable => 'int16s' },
+    0x0095 => { Name => 'NoiseReduction',   Writable => 'string' }, # ("Off" or "FPNR"=long exposure NR)
     0x0096 => {
-        Name => 'LinearizationTable', # same table as DNG LinearizationTable (ref JD)
-        Writable => 0,
-        Binary => 1,
+        Name => 'NEFLinearizationTable', # same table as DNG LinearizationTable (ref JD)
+        Writable => 'undef',
+        Flags => [ 'Binary', 'Protected' ],
     },
     0x0097 => [ #4
         # (NOTE: these are byte-swapped by NX when byte order changes)
         {
-            Condition => '$$valPt =~ /^0100/', # (D100)
+            Condition => '$$valPt =~ /^0100/', # (D100 and Coolpix models)
             Name => 'ColorBalance0100',
             SubDirectory => {
@@ -1230,5 +1944,5 @@
         },
         {
-            Condition => '$$valPt =~ /^0103/', # (D70)
+            Condition => '$$valPt =~ /^0103/', # (D70/D70s)
             Name => 'ColorBalance0103',
             # D70:  at file offset 'tag-value + base + 20', 4 16 bits numbers,
@@ -1251,6 +1965,6 @@
             },
         },
-        {
-            Condition => '$$valPt =~ /^0209/', # (D3)
+        {   # (D3/D3X/D300/D700=0209,D300S=0212,D3S=0214)
+            Condition => '$$valPt =~ /^02(09|12|14)/',
             Name => 'ColorBalance0209',
             SubDirectory => {
@@ -1259,9 +1973,9 @@
                 WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
                 DecryptStart => 284,
-                DecryptLen => 18, # don't need to decrypt it all
+                DecryptLen => 18, # 324 bytes encrypted, but don't need to decrypt it all
                 DirOffset => 10,
             },
         },
-        {   # (D2X=0204,D2Hs=0206,D200=0207,D40=0208)
+        {   # (D2X/D2Xs=0204,D2Hs=0206,D200=0207,D40/D40X/D80=0208,D60=0210)
             Condition => '$$valPt =~ /^02(\d{2})/ and $1 < 11',
             Name => 'ColorBalance02',
@@ -1271,11 +1985,68 @@
                 WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
                 DecryptStart => 284,
-                DecryptLen => 14, # 324 bytes encrypted, but don't need to decrypt it all
+                DecryptLen => 14, # don't need to decrypt it all
                 DirOffset => 6,
             },
         },
-        {   # (D90/D5000=0211,D300S=0212,D3000=0213,D3S=0214,D3100=0215,D7000/D5100=0216)
+        {
+            Condition => '$$valPt =~ /^0211/', # (D90/D5000)
+            Name => 'ColorBalance0211',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 284,
+                DecryptLen => 24, # don't need to decrypt it all
+                DirOffset => 16,
+            },
+        },
+        {
+            Condition => '$$valPt =~ /^0213/', # (D3000)
+            Name => 'ColorBalance0213',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalance2',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 284,
+                DecryptLen => 18, # don't need to decrypt it all
+                DirOffset => 10,
+            },
+        },
+        {   # (D3100=0215,D7000/D5100=0216,D4/D600/D800/D800E/D3200=0217)
+            Condition => '$$valPt =~ /^021[567]/',
+            Name => 'ColorBalance0215',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalance4',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 284,
+                DecryptLen => 12, # don't need to decrypt it all
+                DirOffset => 4,
+            },
+        },
+        {   # (D5200/D7100=0218, D5300=0219, D610/Df=0220, D3300=0221, CoolpixA=0601)
+            Name => 'ColorBalanceUnknown02',
+            Condition => '$$valPt =~ /^0[26]/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 284,
+                DecryptLen => 10, # (arbitrary)
+            },
+        },
+        {   # (1J1/1J2/1V1=0400, 1V2=0401, 1J3/1S1=0402, 1AW1=0403, Z6/Z7=0800)
+            Name => 'ColorBalanceUnknown04',
+            Condition => '$$valPt =~ /^0[48]/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 4,
+                DecryptLen => 10, # (arbitrary)
+            },
+        },
+        {
+            # (CoolpixP7700/P7800=0500, CoolpixP330/P520=0502)
             Name => 'ColorBalanceUnknown',
-            Writable => 0,
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::ColorBalanceUnknown' },
         },
     ],
@@ -1316,7 +2087,51 @@
         },
         {
+            Condition => '$$valPt =~ /^040[01]/', # 0=1J1/1V1, 1=1J2
+            Name => 'LensData0400',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::LensData0400',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 4,
+            },
+        },
+        {
+            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 =~ /^080[01]/', # 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,
             },
         },
@@ -1340,6 +2155,20 @@
         # Landscape Assist:LANDSCAPE,SCENIC VIEW,ARCHITECTURE,GROUP RIGHT,GROUP LEFT
         # Sports Assist:   SPORTS,SPORT SPECTATOR,SPORT COMPOSITE
+        # P7100 has test modes: - PH
+        #  CREATIVE MONOCHROME,PAINTING,CROSS PROCESS,SOFT,NOSTALGIC SEPIA,
+        #  HIGH KEY,LOW KEY,SELECTIVE COLOR,ZOOM EXPOSURE EXP.,DEFOCUS DURING
         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
@@ -1386,7 +2215,11 @@
         Writable => 'int32u',
         Protected => 1,
+        PrintConv => '$val == 4294965247 ? "n/a" : $val',
+        PrintConvInv => '$val eq "n/a" ? 4294965247 : $val',
         Notes => q{
-            this value is used as a key to decrypt other information -- writing this tag
-            causes the other information to be re-encrypted with the new key
+            includes both mechanical and electronic shutter activations for models with
+            this feature.  This value is used as a key to decrypt other information, and
+            writing this tag causes the other information to be re-encrypted with the
+            new key
         },
     },
@@ -1404,11 +2237,22 @@
         {
             Name => 'FlashInfo0103',
-            Condition => '$$valPt =~ /^0103/',
+            # (0104 for D7000, 0105 for D800)
+            Condition => '$$valPt =~ /^010[345]/',
             SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0103' },
         },
-        { #29 (D7000, NC)
-            Name => 'FlashInfo0104',
-            Condition => '$$valPt =~ /^0104/',
-            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0103' },
+        {
+            Name => 'FlashInfo0106', # (Df, D610, D3300, D5300, D7100, Coolpix A)
+            Condition => '$$valPt =~ /^0106/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0106' },
+        },
+        {
+            Name => 'FlashInfo0107', # (0107 for D4S/D750/D810/D5500/D7200, 0108 for D5/D500/D3400)
+            Condition => '$$valPt =~ /^010[78]/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0107' },
+        },
+         {
+            Name => 'FlashInfo0300', # (Z7_2)
+            Condition => '$$valPt =~ /^0300/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0300' },
         },
         {
@@ -1422,9 +2266,22 @@
     0x00ac => { Name => 'ImageStabilization',Writable=> 'string' }, #14
     0x00ad => { Name => 'AFResponse',       Writable => 'string' }, #14
-    0x00b0 => { #PH
+    0x00b0 => [{ #PH
         Name => 'MultiExposure',
         Condition => '$$valPt =~ /^0100/',
-        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::MultiExposure' },
-    },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::MultiExposure',
+            # Note: this endianness varies with model, but Nikon software may change
+            # metadata endianness (although it is unknown how it affects this record),
+            # so for now don't specify ByteOrder although it may be wrong if the
+            # file is rewritten by Nikon software --> see comments for FileInfo
+        },
+    },{
+        Name => 'MultiExposure',
+        Condition => '$$valPt =~ /^0101/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::MultiExposure',
+            ByteOrder => 'LittleEndian',
+        },
+    }],
     0x00b1 => { #14/PH/JD (D80)
         Name => 'HighISONoiseReduction',
@@ -1434,9 +2291,11 @@
             1 => 'Minimal', # for high ISO (>800) when setting is "Off"
             2 => 'Low',     # Low,Normal,High take effect for ISO > 400
+            3 => 'Medium Low',
             4 => 'Normal',
+            5 => 'Medium High',
             6 => 'High',
         },
     },
-    # 0x00b2 (string: 'Normal', 0xc3's, 0xff's or 0x20's)
+    # 0x00b2 (string: "NORMAL  ", 0xc3's, 0xff's or 0x20's)
     0x00b3 => { #14
         Name => 'ToningEffect',
@@ -1469,7 +2328,32 @@
     0x00b7 => { #JD
         Name => 'AFInfo2',
+        # (this structure may be byte swapped when rewritten by CaptureNX)
         SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AFInfo2' },
     },
-    0x00b8 => { #PH
+    0x00b8 => [{ #PH
+        Name => 'FileInfo',
+        # unfortunately, some newer models write this as little-endian
+        # (and CaptureNX can change the byte order of the maker notes,
+        #  but leaves this structure unchanged)
+        # - it will be an ongoing pain to keep this list of models up-to-date,
+        #   so if only one ordering yields valid DirectoryNumber and FileNumber values,
+        #   use it, otherwise default to a-priori knowledge of the camera model
+        #   (assume that a valid DirectoryNumber is 100-999, and a valid FileNumber
+        #   is 0000-9999, although I have some samples with a DirectoryNumber of 99)
+        Condition => q{
+            if (length($$valPt) >= 0) {
+                my ($dir, $file) = unpack('x6vv', $$valPt);
+                my $littleEndian = ($dir >= 100 and $dir <= 999 and $file <= 9999);
+                ($dir, $file) = unpack('x6nn', $$valPt);
+                my $bigEndian = ($dir >= 100 and $dir <= 999 and $file <= 9999);
+                return $littleEndian if $littleEndian xor $bigEndian;
+            }
+            return $$self{Model} =~ /^NIKON (D4S|D750|D810|D3300|D5200|D5300|D5500|D7100)$/;
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::FileInfo',
+            ByteOrder => 'LittleEndian',
+        },
+    },{
         Name => 'FileInfo',
         SubDirectory => {
@@ -1477,5 +2361,5 @@
             ByteOrder => 'BigEndian',
         },
-    },
+    }],
     0x00b9 => { #28
         Name => 'AFTune',
@@ -1483,10 +2367,22 @@
     },
     # 0x00ba - custom curve data? (ref 28?) (only in NEF images)
+    0x00bb => { #forum6281
+        Name => 'RetouchInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::RetouchInfo' },
+    },
+    # 0x00bc - NEFThumbnail? (forum6281)
     0x00bd => { #PH (P6000)
         Name => 'PictureControlData',
         Writable => 'undef',
         Permanent => 0,
-        Binary => 1,
+        Flags => [ 'Binary', 'Protected' ],
         SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl' },
+    },
+    0x00c3 => {
+        Name => 'BarometerInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::BarometerInfo',
+            # (little-endian in II EXIF, big-endian in MOV)
+        },
     },
     0x0e00 => {
@@ -1505,6 +2401,6 @@
         Writable => 'undef',
         Permanent => 0,
-        Drop => 1, # (may be too large for JPEG images)
-        Binary => 1,
+        # (Drop because may be too large for JPEG images)
+        Flags => [ 'Binary', 'Protected', 'Drop' ],
         Notes => q{
             this data is dropped when copying Nikon MakerNotes since it may be too large
@@ -1521,9 +2417,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',
@@ -1541,9 +2440,9 @@
         },
     },
-    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
         },
@@ -1561,11 +2460,9 @@
         Writable => 'undef',
         Permanent => 0,
-        Binary => 1,
-        Drop => 1,
+        Flags => [ 'Binary', 'Protected', 'Drop' ],
     }],
     0x0e1d => { #JD
         Name => 'NikonICCProfile',
-        Binary => 1,
-        Protected => 1,
+        Flags => [ 'Binary', 'Protected' ],
         Writable => 'undef', # must be defined here so tag will be extracted if specified
         WriteCheck => q{
@@ -1582,5 +2479,5 @@
         Writable => 'undef',
         Permanent => 0,
-        Binary => 1,
+        Flags => [ 'Binary', 'Protected' ],
         SubDirectory => {
             TagTable => 'Image::ExifTool::Nikon::CaptureOutput',
@@ -1596,4 +2493,5 @@
             '0 0 0 0' => 'n/a (JPEG)',
             '8 8 8 0' => '8 x 3', # TIFF RGB
+            '16 16 16 0' => '16 x 3', # TIFF 16-bit RGB
             '12 0 0 0' => 12,
             '14 0 0 0' => 14,
@@ -1683,10 +2581,20 @@
         Name => 'VibrationReduction',
         PrintConv => {
+            0 => 'n/a', # (1V1 with a non-VR lens)
             1 => 'On',
             2 => 'Off',
         },
     },
-    # 5 - values: 0, 1, 2
-    # 6 and 7 - values: 0
+    # 5 - values: 0, 1 (VR On), 2 (VR Off)
+    6 => {
+        Name => 'VRMode',
+        PrintConv => {
+            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
 );
 
@@ -1804,4 +2712,5 @@
     # Neutral2   03 c2 01 00 02 ff 80 7f 81 00 7f ff ff ff (custom)
     # (note that up to 9 different custom picture controls can be stored)
+    # --> bytes 44 and 45 are swapped if CaptureNX changes the byte order
     #
     48 => { #21
@@ -1897,4 +2806,5 @@
             0x89 => 'Red-purple',
             0xff => 'n/a',
+            # 0x04 - seen for D810 (PH)
         },
     },
@@ -1911,4 +2821,299 @@
 );
 
+# Picture Control information V2 (ref 28)
+%Image::ExifTool::Nikon::PictureControl2 = (
+    %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,
+    },
+    4 => {
+        Name => 'PictureControlName',
+        Format => 'string[20]',
+        # make lower case with a leading capital for each word
+        PrintConv => \&FormatString,
+        PrintConvInv => 'uc($val)',
+    },
+    24 => {
+        Name => 'PictureControlBase',
+        Format => 'string[20]',
+        PrintConv => \&FormatString,
+        PrintConvInv => 'uc($val)',
+    },
+    # beginning at byte 44, there is some interesting information.
+    # here are the observed bytes for each PictureControlMode:
+    #            44 45 46 47 48 49 50 51 52 53 54 55 56 57
+    # STANDARD   00 01 00 00 00 80 83 80 80 80 80 ff ff ff
+    # NEUTRAL    03 c2 00 00 00 ff 82 80 80 80 80 ff ff ff
+    # VIVID      00 c3 00 00 00 80 84 80 80 80 80 ff ff ff
+    # MONOCHROME 06 4d 00 01 02 ff 82 80 80 ff ff 80 80 ff
+    # Neutral2   03 c2 01 00 02 ff 80 7f 81 00 7f ff ff ff (custom)
+    # (note that up to 9 different custom picture controls can be stored)
+    # --> bytes 44 and 45 are swapped if CaptureNX changes the byte order
+    #
+    48 => { #21
+        Name => 'PictureControlAdjust',
+        PrintConv => {
+            0 => 'Default Settings',
+            1 => 'Quick Adjust',
+            2 => 'Full Control',
+        },
+    },
+    49 => {
+        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 => {
+        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',
+            1 => 'Quick Adjust',
+            2 => 'Full Control',
+        },
+    },
+    55 => { # (NC)
+        Name => 'PictureControlQuickAdjust',
+        DelValue => 0xff,
+        ValueConv => '$val - 0x80',
+        ValueConvInv => '$val + 0x80',
+        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val)',
+        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val)',
+    },
+    57 => {
+        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)',
+    },
+    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',
+        ValueConvInv => '$val + 0x80',
+        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)',
+        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv2($val,4)',
+    },
+    63 => {
+        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)',
+    },
+    65 => { #21
+        Name => 'Brightness',
+        ValueConv => '$val - 0x80',
+        ValueConvInv => '$val + 0x80',
+        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,undef,"%.2f",4)',
+        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)',
+    },
+    67 => {
+        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)',
+    },
+    69 => {
+        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)',
+    },
+    71 => { # (NC)
+        Name => 'FilterEffect',
+        DelValue => 0xff,
+        PrintHex => 1,
+        PrintConv => {
+            0x80 => 'Off',
+            0x81 => 'Yellow',
+            0x82 => 'Orange',
+            0x83 => 'Red',
+            0x84 => 'Green',
+            0xff => 'n/a',
+        },
+    },
+    72 => { # (NC)
+        Name => 'ToningEffect',
+        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',
+        },
+    },
+    73 => { # (NC)
+        Name => 'ToningSaturation',
+        DelValue => 0xff,
+        ValueConv => '$val - 0x80',
+        ValueConvInv => '$val + 0x80',
+        PrintConv => 'Image::ExifTool::Nikon::PrintPC($val,"None","%.2f",4)',
+        PrintConvInv => 'Image::ExifTool::Nikon::PrintPCInv($val,4)',
+
+    },
+);
+
+# 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 = (
@@ -1916,5 +3121,5 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Time' },
     0 => {
-        Name => 'Timezone',
+        Name => 'TimeZone',
         Format => 'int16s',
         PrintConv => q{
@@ -1960,4 +3165,49 @@
     4 => {
         Name => 'ISOExpansion',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0x000 => 'Off',
+            0x101 => 'Hi 0.3',
+            0x102 => 'Hi 0.5',
+            0x103 => 'Hi 0.7',
+            0x104 => 'Hi 1.0',
+            0x105 => 'Hi 1.3', # (Hi 1.3-1.7 may be possible with future models)
+            0x106 => 'Hi 1.5',
+            0x107 => 'Hi 1.7',
+            0x108 => 'Hi 2.0', #(NC) - D3 should have this mode
+            0x109 => 'Hi 2.3', #IB
+            0x10a => 'Hi 2.5', #IB
+            0x10b => 'Hi 2.7', #IB
+            0x10c => 'Hi 3.0', #IB
+            0x10d => 'Hi 3.3', #IB
+            0x10e => 'Hi 3.5', #IB
+            0x10f => 'Hi 3.7', #IB
+            0x110 => 'Hi 4.0', #IB
+            0x111 => 'Hi 4.3', #IB
+            0x112 => 'Hi 4.5', #IB
+            0x113 => 'Hi 4.7', #IB
+            0x114 => 'Hi 5.0', #IB
+            0x201 => 'Lo 0.3',
+            0x202 => 'Lo 0.5',
+            0x203 => 'Lo 0.7',
+            0x204 => 'Lo 1.0',
+        },
+    },
+    # bytes 6-11 same as 0-4 in my samples (why is this duplicated?)
+    6 => {
+        Name => 'ISO2',
+        Notes => 'val = 100 * 2**(raw/12-5)',
+        ValueConv => '100*exp(($val/12-5)*log(2))',
+        ValueConvInv => '(log($val/100)/log(2)+5)*12',
+        PrintConv => 'int($val + 0.5)',
+        PrintConvInv => '$val',
+    },
+    # 7 - 0x01
+    # 8 - 0x0c (probably the ISO divisor above)
+    # 9 - 0x00
+    10 => {
+        Name => 'ISOExpansion2',
         Format => 'int16u',
         PrintHex => 1,
@@ -1979,37 +3229,4 @@
         },
     },
-    # bytes 6-11 same as 0-4 in my samples (why is this duplicated?)
-    6 => {
-        Name => 'ISO2',
-        Notes => 'val = 100 * 2**(raw/12-5)',
-        ValueConv => '100*exp(($val/12-5)*log(2))',
-        ValueConvInv => '(log($val/100)/log(2)+5)*12',
-        PrintConv => 'int($val + 0.5)',
-        PrintConvInv => '$val',
-    },
-    # 7 - 0x01
-    # 8 - 0x0c (probably the ISO divisor above)
-    # 9 - 0x00
-    10 => {
-        Name => 'ISOExpansion2',
-        Format => 'int16u',
-        PrintHex => 1,
-        PrintConvColumns => 2,
-        PrintConv => {
-            0x000 => 'Off',
-            0x101 => 'Hi 0.3',
-            0x102 => 'Hi 0.5',
-            0x103 => 'Hi 0.7',
-            0x104 => 'Hi 1.0',
-            0x105 => 'Hi 1.3', # (Hi 1.3-1.7 may be possible with future models)
-            0x106 => 'Hi 1.5',
-            0x107 => 'Hi 1.7',
-            0x108 => 'Hi 2.0', #(NC) - D3 should have this mode
-            0x201 => 'Lo 0.3',
-            0x202 => 'Lo 0.5',
-            0x203 => 'Lo 0.7',
-            0x204 => 'Lo 1.0',
-        },
-    },
     # bytes 12-13: 00 00
 );
@@ -2019,4 +3236,5 @@
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     0 => {
         Name => 'DistortionVersion',
@@ -2027,5 +3245,9 @@
     4 => {
         Name => 'AutoDistortionControl',
-        PrintConv => \%offOn,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (underwater)', # (1AW1)
+        },
     },
 );
@@ -2043,4 +3265,5 @@
         Unknown => 1,
     },
+    # (bytes 6/7 and 8/9 are swapped if CaptureNX changes the byte order)
 );
 
@@ -2057,4 +3280,5 @@
         Unknown => 1,
     },
+    # (byte 4 may be changed from 1 to 0 when rewritten by CaptureNX)
 );
 
@@ -2090,4 +3314,5 @@
             9 => 'Far Left',
             10 => 'Far Right',
+            # (have also seen values of 11 and 12 when AFPointsInFocus is "(none)" - PH S3500)
         },
     },
@@ -2097,4 +3322,5 @@
         PrintConvColumns => 2,
         PrintConv => {
+            0 => '(none)',
             0x7ff => 'All 11 Points',
             BITMASK => {
@@ -2119,5 +3345,5 @@
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    DATAMEMBER => [ 4, 6 ],
+    DATAMEMBER => [ 0, 4, 6 ],
     NOTES => "These tags are written by Nikon DSLR's which have the live view feature.",
     # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
@@ -2126,9 +3352,14 @@
         Format => 'undef[4]',
         Writable => 0,
+        RawConv => '$$self{AFInfo2Version} = $val',
     },
     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 => [
@@ -2151,4 +3382,21 @@
                 11 => 'Dynamic Area (wide)', #PH
                 12 => 'Dynamic Area (wide, 3D-tracking)', #PH
+                13 => 'Group Area', #PH
+                14 => 'Dynamic Area (25 points)', #PH
+                15 => 'Dynamic Area (72 points)', #PH
+                16 => 'Group Area (HL)', #28
+                17 => 'Group Area (VL)', #28
+                18 => 'Dynamic Area (49 points)', #28
+                128 => 'Single', #PH (1J1,1J2,1J3,1J4,1S1,1S2,1V2,1V3)
+                129 => 'Auto (41 points)', #PH (1J1,1J2,1J3,1J4,1S1,1S2,1V1,1V2,1V3,AW1)
+                130 => 'Subject Tracking (41 points)', #PH (1J1,1J4,1J3)
+                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)
             },
         },
@@ -2165,4 +3413,20 @@
                 3 => 'Contrast-detect (face priority)', # (ViewNX)
                 4 => 'Contrast-detect (subject tracking)', # (ViewNX)
+                128 => 'Single', #PH (1V3)
+                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)
+                194 => 'Dynamic', #PH (Z7)
+                195 => 'Wide (S)', #PH (Z7)
+                196 => 'Wide (L)', #PH (Z7)
+                197 => 'Auto', #PH (Z7)
+                198 => 'Auto (People)', #28 (Z7)    #if no faces are detected, will record as 'Auto'.  Camera setting recorded in AFAreaMode field in the MakerNotes area
+                199 => 'Auto (Animal)', #28 (Z7)    #if no animals are detected, will record as 'Auto'.  Camera setting recorded in AFAreaMode field in the MakerNotes area
+                200 => 'Normal-area AF', #28 (D6)
+                201 => 'Wide-area AF', #28 (D6)
+                202 => 'Face-priority AF', #28 (D6)
+                203 => 'Subject-tracking AF', #28 (D6)
             },
         },
@@ -2173,8 +3437,15 @@
         RawConv => '$$self{PhaseDetectAF} = $val',
         PrintConv => {
+            # [observed AFAreaMode values in square brackets for each PhaseDetectAF value]
             0 => 'Off',
             1 => 'On (51-point)', #PH
             2 => 'On (11-point)', #PH
             3 => 'On (39-point)', #29 (D7000)
+            4 => 'On (73-point)', #PH (1J1[128/129],1J2[128/129/135],1J3/1S1/1V2[128/129/131],1V1[129],AW1[129/131])
+            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
+            9 => 'On (105-point)', #28 (D6)
         },
     },
@@ -2182,39 +3453,20 @@
         { #PH/JD
             Name => 'PrimaryAFPoint',
-            Condition => '$$self{PhaseDetectAF} < 2',
-            Notes => 'models with 51-point AF: D3, D3S, D3X, D300, D300S and D700',
+            # PrimaryAFPoint may only be valid for PhaseDetect - certainly true on the D6, possibly other bodies? (ref 28)
+            Condition => '$$self{PhaseDetectAF} < 2 and $$self{AFInfo2Version} ne "0301"',
+            Notes => q{
+                models with 51-point AF -- 5 rows (A-E) and 11 columns (1-11): D3, D3S, D3X,
+                D4, D4S, D300, D300S, D700, D800, D800e and D810
+            },
             PrintConvColumns => 5,
             PrintConv => {
-                0 => '(none)',      26 => 'C10',
-                1 => 'C6 (Center)', 27 => 'B10',
-                2 => 'B6',          28 => 'A9',
-                3 => 'A5',          29 => 'D10',
-                4 => 'D6',          30 => 'E9',
-                5 => 'E5',          31 => 'C11',
-                6 => 'C7',          32 => 'B11',
-                7 => 'B7',          33 => 'D11',
-                8 => 'A6',          34 => 'C4',
-                9 => 'D7',          35 => 'B4',
-                10 => 'E6',         36 => 'A3',
-                11 => 'C5',         37 => 'D4',
-                12 => 'B5',         38 => 'E3',
-                13 => 'A4',         39 => 'C3',
-                14 => 'D5',         40 => 'B3',
-                15 => 'E4',         41 => 'A2',
-                16 => 'C8',         42 => 'D3',
-                17 => 'B8',         43 => 'E2',
-                18 => 'A7',         44 => 'C2',
-                19 => 'D8',         45 => 'B2',
-                20 => 'E7',         46 => 'A1',
-                21 => 'C9',         47 => 'D2',
-                22 => 'B9',         48 => 'E1',
-                23 => 'A8',         49 => 'C1',
-                24 => 'D9',         50 => 'B1',
-                25 => 'E8',         51 => 'D1',
+                0 => '(none)',
+                %afPoints51,
+                1 => 'C6 (Center)', # (add " (Center)" to central point)
             },
         },
         { #10
             Name => 'PrimaryAFPoint',
-            Notes => 'models with 11-point AF: D90, D3000 and D5000',
+            Notes => 'models with 11-point AF: D90, D3000, D3100, D5000 and D5100',
             Condition => '$$self{PhaseDetectAF} == 2',
             PrintConvColumns => 2,
@@ -2237,33 +3489,94 @@
             Name => 'PrimaryAFPoint',
             Condition => '$$self{PhaseDetectAF} == 3',
-            Notes => 'models with 39-point AF: D7000 (not verified)',
+            Notes => 'models with 39-point AF: D600 and D7000',
             PrintConvColumns => 5,
             PrintConv => {
-                0 => '(none)',      22 => 'C10',
-                1 => 'C6 (Center)', 23 => 'B10',
-                2 => 'B6',          24 => 'D10',
-                3 => 'A2',          25 => 'C11',
-                4 => 'D6',          26 => 'B11',
-                5 => 'E2',          27 => 'D11',
-                6 => 'C7',          28 => 'C4',
-                7 => 'B7',          29 => 'B4',
-                8 => 'A3',          30 => 'D4',
-                9 => 'D7',          31 => 'C3',
-                10 => 'E3',         32 => 'B3',
-                11 => 'C5',         33 => 'D3',
-                12 => 'B5',         34 => 'C2',
-                13 => 'A1',         35 => 'B2',
-                14 => 'D5',         36 => 'D2',
-                15 => 'E1',         37 => 'C1',
-                16 => 'C8',         38 => 'B1',
-                17 => 'B8',         39 => 'D1',
-                18 => 'D8',
-                19 => 'C9',
-                20 => 'B9',
-                21 => 'D9',
+                0 => '(none)',
+                %afPoints39,
+                1 => 'C6 (Center)', # (add " (Center)" to central point)
+            },
+        },
+        { #PH
+            Name => 'PrimaryAFPoint',
+            Condition => '$$self{PhaseDetectAF} == 4',
+            Notes => 'Nikon 1 models with older 135-point AF and 73-point phase-detect AF',
+            PrintConvColumns => 5,
+            PrintConv => {
+                0 => '(none)',
+                %afPoints135,
+                1 => 'E8 (Center)', # (add " (Center)" to central point)
+            },
+        },
+        { #PH (NC)
+            Name => 'PrimaryAFPoint',
+            Condition => '$$self{PhaseDetectAF} == 5',
+            Notes => q{
+                Nikon 1 models with newer 135-point AF and 73-point phase-detect AF -- 9
+                rows (B-J) and 15 columns (1-15), inside a grid of 11 rows by 15 columns.
+                The points are numbered sequentially, with F8 at the center
+            },
+            PrintConv => {
+                0 => '(none)',
+                82 => 'F8 (Center)',
+                OTHER => sub {
+                    my ($val, $inv) = @_;
+                    return GetAFPointGrid($val, 15, $inv);
+                },
+            },
+        },
+        { #PH
+            Name => 'PrimaryAFPoint',
+            Condition => '$$self{PhaseDetectAF} == 6',
+            Notes => q{
+                Nikon 1 models with 171-point AF and 105-point phase-detect AF -- 9 rows
+                (B-J) and 19 columns (2-20), inside a grid of 11 rows by 21 columns.  The
+                points are numbered sequentially, with F11 at the center
+            },
+            PrintConv => {
+                0 => '(none)',
+                #22 => 'B2 (Top-left)',
+                #40 => 'B20 (Top-right)',
+                115 => 'F11 (Center)',
+                #190 => 'J2 (Bottom-left)',
+                #208 => 'J20 (Bottom-right)',
+                OTHER => sub {
+                    my ($val, $inv) = @_;
+                    return GetAFPointGrid($val, 21, $inv);
+                },
+            },
+        },
+        { #PH
+            Name => 'PrimaryAFPoint',
+            Condition => '$$self{PhaseDetectAF} == 7 and $$self{AFInfo2Version} eq "0100"',
+            Notes => q{
+                Nikon models with 153-point AF -- 9 rows (A-I) and 17 columns (1-17): D5,
+                D500 and D850
+            },
+            PrintConvColumns => 5,
+            PrintConv => {
+                0 => '(none)',
+                %afPoints153,
+                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"',
             Notes => 'future models?...',
             PrintConv => {
@@ -2276,11 +3589,14 @@
         { #JD/PH
             Name => 'AFPointsUsed',
-            Condition => '$$self{PhaseDetectAF} < 2',
+            Condition => '$$self{PhaseDetectAF} < 2 and $$self{AFInfo2Version} ne "0301"',
             Notes => q{
-                models with 51-point AF -- 5 rows: A1-9, B1-11, C1-11, D1-11, E1-9, center
+                models with 51-point AF -- 5 rows: A1-9, B1-11, C1-11, D1-11, E1-9.  Center
                 point is C6
             },
             Format => 'undef[7]',
-            PrintConv => 'Image::ExifTool::Nikon::PrintAFPointsD3($val)',
+            ValueConv => 'join(" ", unpack("H2"x7, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            PrintConv => sub { PrintAFPoints(shift, \%afPoints51); },
+            PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints51); },
         },
         { #10
@@ -2294,4 +3610,5 @@
             PrintConvColumns => 2,
             PrintConv => {
+                0 => '(none)',
                 0x7ff => 'All 11 Points',
                 BITMASK => {
@@ -2310,19 +3627,110 @@
             },
         },
-        { #29
+        { #29/PH
             Name => 'AFPointsUsed',
             Condition => '$$self{PhaseDetectAF} == 3',
-            Notes => 'models with 39-point AF: D7000 (not decoded)',
+            Notes => q{
+                models with 39-point AF -- 5 rows: A1-3, B1-11, C1-11, D1-11, E1-3.  Center
+                point is C6
+            },
+            Format => 'undef[5]',
+            ValueConv => 'join(" ", unpack("H2"x5, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            PrintConv => sub { PrintAFPoints(shift, \%afPoints39); },
+            PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints39); },
+        },
+        { #PH (1AW1,1J1,1J2,1J3,1S1,1V1,1V2)
+            Name => 'AFPointsUsed',
+            Condition => '$$self{PhaseDetectAF} == 4',
+            Notes => q{
+                older models with 135-point AF -- 9 rows (A-I) and 15 columns (1-15).
+                Center point is E8.  The odd-numbered columns, columns 2 and 14, and the
+                remaining corner points are not used for 41-point AF mode
+            },
+            Format => 'undef[17]',
+            ValueConv => 'join(" ", unpack("H2"x17, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            PrintConv => sub { PrintAFPoints(shift, \%afPoints135); },
+            PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints135); },
+        },
+        { #PH (1S2)
+            Name => 'AFPointsUsed',
+            Condition => '$$self{PhaseDetectAF} == 5',
+            Notes => q{
+                newer models with 135-point AF -- 9 rows (B-J) and 15 columns (1-15). Center
+                point is F8
+            },
+            Format => 'undef[21]',
+            ValueConv => 'join(" ", unpack("H2"x21, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            PrintConv => sub { PrintAFPointsGrid(shift, 15); },
+            PrintConvInv => sub { PrintAFPointsGridInv(shift, 15, 21); },
+        },
+        { #PH (1J4,1V3)
+            Name => 'AFPointsUsed',
+            Condition => '$$self{PhaseDetectAF} == 6',
+            Notes => q{
+                models with 171-point AF -- 9 rows (B-J) and 19 columns (2-20).  Center
+                point is F10
+            },
+            Format => 'undef[29]',
+            ValueConv => 'join(" ", unpack("H2"x29, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            PrintConv => sub { PrintAFPointsGrid(shift, 21); },
+            PrintConvInv => sub { PrintAFPointsGridInv(shift, 21, 29); },
+        },
+        { #PH (D5,D500)
+            Name => 'AFPointsUsed',
+            Condition => '$$self{PhaseDetectAF} == 7',
+            Notes => q{
+                models with 153-point AF -- 9 rows (A-I) and 17 columns (1-17). Center
+                point is E9
+            },
+            Format => 'undef[20]',
+            ValueConv => 'join(" ", unpack("H2"x20, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            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',
+            # version 301 uses a separate field at offset 0x0a for this tag (ref 28)
+            Condition =>  '$$self{AFInfo2Version} ne "0301"',
             Format => 'undef[7]',
-            PrintConv => '$_=unpack("H*",$val); "Unknown (".join(" ", /(..)/g).")"',
-        },
-        {
+            ValueConv => 'join(" ", unpack("H2"x7, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            PrintConv => '"Unknown ($val)"',
+            PrintConvInv => '$val=~s/Unknown \\((.*)\\)/$1/; $val',
+        },
+    ],
+    0x0a => { #28 (D6) in any of the 3 Group modes on the D6, the points specify the outer boundaries of the focus point area; otherwise the tag value is consistent with other Nikon bodies
             Name => 'AFPointsUsed',
-            Format => 'undef[7]',
-            PrintConv => '$_=unpack("H*",$val); "Unknown (".join(" ", /(..)/g).")"',
-        },
-    ],
+        Condition => '$$self{AFInfo2Version} eq "0301"  and $$self{PhaseDetectAF} == 9',
+        Notes => q{
+            models with 105-point AF -- 7 rows (A-G) and 15 columns (1-15). Center
+            point is D8
+        },
+        Format => 'undef[14]',
+        ValueConv => 'join(" ", unpack("H2"x14, $val))',
+        ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+        PrintConv => sub { PrintAFPoints(shift, \%afPoints105); },
+        PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints105); },
+    },
     0x10 => { #PH (D90 and D5000)
         Name => 'AFImageWidth',
+        Condition => '$$self{AFInfo2Version} eq "0100"',
         Format => 'int16u',
         RawConv => '$val ? $val : undef',
@@ -2331,4 +3739,5 @@
     0x12 => { #PH
         Name => 'AFImageHeight',
+        Condition => '$$self{AFInfo2Version} eq "0100"',
         Format => 'int16u',
         RawConv => '$val ? $val : undef',
@@ -2336,4 +3745,5 @@
     0x14 => { #PH
         Name => 'AFAreaXPosition',
+        Condition => '$$self{AFInfo2Version} eq "0100"',
         Notes => 'center of AF area in AFImage coordinates',
         Format => 'int16u',
@@ -2342,4 +3752,5 @@
     0x16 => { #PH
         Name => 'AFAreaYPosition',
+        Condition => '$$self{AFInfo2Version} eq "0100"',
         Format => 'int16u',
         RawConv => '$val ? $val : undef',
@@ -2350,4 +3761,5 @@
     0x18 => { #PH
         Name => 'AFAreaWidth',
+        Condition => '$$self{AFInfo2Version} eq "0100"',
         Format => 'int16u',
         Notes => 'size of AF area in AFImage coordinates',
@@ -2356,12 +3768,190 @@
     0x1a => { #PH
         Name => 'AFAreaHeight',
+        Condition => '$$self{AFInfo2Version} eq "0100"',
         Format => 'int16u',
         RawConv => '$val ? $val : undef',
     },
-    0x1c => { #PH
+    0x1c => [
+        { #PH
+            Name => 'ContrastDetectAFInFocus',
+            Condition => '$$self{AFInfo2Version} eq "0100"',
+            PrintConv => { 0 => 'No', 1 => 'Yes' },
+        },{ #PH (D500, see forum11190)
+            Name => 'AFPointsSelected',
+            Condition => '$$self{AFInfo2Version} eq "0101" and $$self{PhaseDetectAF} == 7',
+            Format => 'undef[20]',
+            ValueConv => 'join(" ", unpack("H2"x20, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            PrintConv => sub { PrintAFPoints(shift, \%afPoints153); },
+            PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints153); },
+        },
+    ],
+    # 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 => q{
+            $$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
+            $$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} =~ /^0301/
+        },
+        Format => 'int16u',
+    },
+    0x2f => { #28 (Z7)   Still photography range 1-17 for the 493 point Z7 (arranged in a 29x17 grid. Center at x=16, y=10).
+        Name => 'AFFocusPointXPosition',
+        Condition => q{
+            $$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
+            $$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} =~ /^0301/
+        },
+        PrintConv => sub { my ($val) = @_; PrintAFPointsLeftRight($val, 29 ); },
+    },
+    0x30 => [
+        { #PH (Z7)
+            Name => 'AFAreaYPosition',
+            Condition => q{
+                $$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
+                $$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} =~ /^0301/
+            },
+            Format => 'int16u',
+        },{ #PH (D500, see forum11190)
+            Name => 'AFPointsInFocus',
+            Condition => '$$self{AFInfo2Version} eq "0101" and $$self{PhaseDetectAF} == 7',
+            Notes => 'AF points in focus at the time time image was captured',
+            Format => 'undef[20]',
+            ValueConv => 'join(" ", unpack("H2"x20, $val))',
+            ValueConvInv => '$val=~tr/ //d; pack("H*",$val)',
+            PrintConv => sub { PrintAFPoints(shift, \%afPoints153); },
+            PrintConvInv => sub { PrintAFPointsInv(shift, \%afPoints153); },
+        },
+    ],
+    0x31 => { #28 (Z7)
+        Name => 'AFFocusPointYPosition',
+        Condition => q{
+            $$self{ContrastDetectAF} == 2 and $$self{AFInfo2Version} =~ /^03/ or
+            $$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} =~ /^0301/
+        },
+        PrintConv => sub { my ($val) = @_; PrintAFPointsUpDown($val, 17 ); },
+    },
+    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',
+    },
+    0x38 => { #28
+        Name => 'PrimaryAFPoint',
+        Condition => '$$self{PhaseDetectAF} == 9 and $$self{AFInfo2Version} =~ /^03/',
+        Notes => q{
+            Nikon models with 105-point AF -- 7 rows (A-G) and 15 columns (1-15): D6
+        },
+        PrintConvColumns => 5,
+        PrintConv => {
+            0 => '(none)',
+            %afPoints105,
+            1 => 'D8 (Center)',
+        },
+    },
+    0x44 => [
+        {
+            Name => 'PrimaryAFPoint',
+            Condition => '$$self{PhaseDetectAF} == 7 and $$self{AFInfo2Version} eq "0101"',
+            PrintConvColumns => 5,
+            PrintConv => {
+                0 => '(none)',
+                %afPoints153,
+                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',
+            },
+        },
+    ],
+    0x46 => {
+        Name => 'AFImageWidth',
+        Condition => '$$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} eq "0101"',
+        Format => 'int16u',
+        RawConv => '$val ? $val : undef',
+        Notes => 'this and the following tags are valid only for contrast-detect AF',
+    },
+    0x48 => {
+        Name => 'AFImageHeight',
+        Condition => '$$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} eq "0101"',
+        Format => 'int16u',
+        RawConv => '$val ? $val : undef',
+    },
+    0x4a => {
+        Name => 'AFAreaXPosition',
+        Condition => '$$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} eq "0101"',
+        Notes => 'center of AF area in AFImage coordinates',
+        Format => 'int16u',
+        RawConv => '$val ? $val : undef',
+    },
+    0x4c => {
+        Name => 'AFAreaYPosition',
+        Condition => '$$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} eq "0101"',
+        Format => 'int16u',
+        RawConv => '$val ? $val : undef',
+    },
+    0x4e => {
+        Name => 'AFAreaWidth',
+        Condition => '$$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} eq "0101"',
+        Format => 'int16u',
+        Notes => 'size of AF area in AFImage coordinates',
+        RawConv => '$val ? $val : undef',
+    },
+    0x50 => {
+        Name => 'AFAreaHeight',
+        Condition => '$$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} eq "0101"',
+        Format => 'int16u',
+        RawConv => '$val ? $val : undef',
+    },
+    0x52 => {
         Name => 'ContrastDetectAFInFocus',
+        Condition => '$$self{ContrastDetectAF} == 1 and $$self{AFInfo2Version} eq "0101"',
         PrintConv => { 0 => 'No', 1 => 'Yes' },
     },
-    # 0x1d - always zero (with or without live view)
 );
 
@@ -2377,4 +3967,5 @@
             1 => 'On (1)',
             2 => 'On (2)',
+            3 => 'On (Zoom)', #28
         },
     },
@@ -2386,4 +3977,5 @@
     },
     2 => {
+        # when AFFineTune = 3 (indicating a zoom lens), this Tag stores the tuning adjustment for the wide end of the zoom range (ref 28)
         Name => 'AFFineTuneAdj',
         Priority => 0, # so other value takes priority if it exists
@@ -2393,4 +3985,35 @@
         PrintConvInv => '$val',
     },
+    3 => {
+        Name => 'AFFineTuneAdjTele',
+        # should probably insert a Condition that restricts this to AFFineTune = 3 (ref 28)
+        Notes => 'only valid for zoom lenses (ie, AFTune=3)',
+        Format => 'int8s',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+);
+
+# Nikon NEF processing information (ref forum6281)
+%Image::ExifTool::Nikon::RetouchInfo = (
+    %binaryDataAttrs,
+    FORMAT => 'int8s',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0 ],
+    0 => {
+        Name => 'RetouchInfoVersion',
+        Format => 'undef[4]',
+        Writable => 0,
+        RawConv => '$$self{RetouchInfoVersion} = $val',
+    },
+    # 4 - RetouchExposureComp (+$val/6 or -$val/6?)
+    5 => {
+        Name => 'RetouchNEFProcessing',
+        Condition => '$$self{RetouchInfoVersion} ge "0200"',
+        PrintConv => {
+            -1 => 'Off',
+            1 => 'On',
+        },
+    },
 );
 
@@ -2399,4 +4022,5 @@
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    FORMAT => 'int16u',
     0 => {
         Name => 'FileInfoVersion',
@@ -2404,16 +4028,33 @@
         Writable => 0,
     },
-    6 => {
+    2 => 'MemoryCardNumber',
+    3 => {
         Name => 'DirectoryNumber',
-        Format => 'int16u',
         PrintConv => 'sprintf("%.3d", $val)',
         PrintConvInv => '$val',
     },
-    8 => {
+    4 => {
         Name => 'FileNumber',
-        Format => 'int16u',
         PrintConv => 'sprintf("%.4d", $val)',
         PrintConvInv => '$val',
     },
+);
+
+# ref PH
+%Image::ExifTool::Nikon::BarometerInfo = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Location' },
+    0 => {
+        Name => 'BarometerInfoVersion',
+        Format => 'undef[4]',
+        Writable => 0,
+    },
+    6 => {
+        Name => 'Altitude',
+        Format => 'int32s',
+        PrintConv => '"$val m"', # (always stored as metres)
+        PrintConvInv => '$val=~s/\s*m$//; $val',
+    },
+    # 10: int16u - values: 0 (display in metres?), 18 (display in feet?)
 );
 
@@ -2422,4 +4063,6 @@
     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',
@@ -2439,21 +4082,110 @@
 );
 
-# ref 4
+# ref IB
 %Image::ExifTool::Nikon::ColorBalanceA = (
     %binaryDataAttrs,
     FORMAT => 'int16u',
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    624 => {
-        Name => 'RedBalance',
-        ValueConv => '$val / 256',
-        ValueConvInv => '$val * 256',
+    624 => { #4
+        Name => 'WB_RBLevels',
+        Notes => 'as shot', #IB
+        Format => 'int16u[2]',
         Protected => 1,
     },
-    625 => {
-        Name => 'BlueBalance',
-        ValueConv => '$val / 256',
-        ValueConvInv => '$val * 256',
+    626 => {
+        Name => 'WB_RBLevelsAuto',
+        Format => 'int16u[2]',
         Protected => 1,
     },
+    628 => {
+        Name => 'WB_RBLevelsDaylight',
+        Notes => 'red/blue levels for 0,+3,+2,+1,-1,-2,-3',
+        Format => 'int16u[14]',
+        Protected => 1,
+    },
+    642 => {
+        Name => 'WB_RBLevelsIncandescent',
+        Format => 'int16u[14]',
+        Protected => 1,
+    },
+    656 => {
+        Name => 'WB_RBLevelsFluorescent',
+        Format => 'int16u[6]',
+        Notes => 'red/blue levels for fluorescent W,N,D',
+        Protected => 1,
+    },
+    662 => {
+        Name => 'WB_RBLevelsCloudy',
+        Format => 'int16u[14]',
+        Protected => 1,
+    },
+    676 => {
+        Name => 'WB_RBLevelsFlash',
+        Format => 'int16u[14]',
+        Protected => 1,
+    },
+    690 => {
+        Name => 'WB_RBLevelsShade',
+        Condition => '$$self{Model} ne "E8700"',
+        Notes => 'not valid for E8700',
+        Format => 'int16u[14]',
+        Protected => 1,
+    },
+);
+
+my %nrwLevels = (
+    Format => 'int32u[4]',
+    Protected => 1,
+    ValueConv => 'my @a=split " ",$val;$a[0]*=2;$a[3]*=2;"@a"',
+    ValueConvInv => 'my @a=split " ",$val;$a[0]/=2;$a[3]/=2;"@a"',
+);
+
+# (ref IB)
+%Image::ExifTool::Nikon::ColorBalanceB = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Color balance tags used by the P6000.',
+    0x0004 => {
+        Name => 'ColorBalanceVersion',
+        Format => 'undef[4]',
+    },
+    0x13e8 => { Name => 'WB_RGGBLevels',            %nrwLevels },
+    0x13f8 => { Name => 'WB_RGGBLevelsDaylight',    %nrwLevels },
+    0x1408 => { Name => 'WB_RGGBLevelsCloudy',      %nrwLevels },
+    0x1428 => { Name => 'WB_RGGBLevelsTungsten',    %nrwLevels },
+    0x1438 => { Name => 'WB_RGGBLevelsFluorescentW',%nrwLevels },
+    0x1448 => { Name => 'WB_RGGBLevelsFlash',       %nrwLevels },
+    0x1468 => { Name => 'WB_RGGBLevelsCustom',      %nrwLevels, Notes => 'all zero if preset WB not used' },
+    0x1478 => { Name => 'WB_RGGBLevelsAuto',        %nrwLevels },
+);
+
+# (ref IB)
+%Image::ExifTool::Nikon::ColorBalanceC = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 4 ],
+    NOTES => 'Color balance tags used by the P1000, P7000, P7100 and B700.',
+    0x0004 => {
+        Name => 'ColorBalanceVersion',
+        Format => 'undef[4]',
+        RawConv => '$$self{ColorBalanceVersion} = $val',
+    },
+    0x0020 => { Name => 'BlackLevel', Format => 'int16u' },
+    0x0038 => { Name => 'WB_RGGBLevels',            %nrwLevels },
+    0x004c => { Name => 'WB_RGGBLevelsDaylight',    %nrwLevels },
+    0x0060 => { Name => 'WB_RGGBLevelsCloudy',      %nrwLevels },
+    0x0074 => {
+        Name => 'WB_RGGBLevelsShade',
+        Condition => '$$self{ColorBalanceVersion} ge "0104"',
+        Notes => 'valid only for some models',
+        %nrwLevels,
+    },
+    0x0088 => { Name => 'WB_RGGBLevelsTungsten',    %nrwLevels },
+    0x009c => { Name => 'WB_RGGBLevelsFluorescentW',%nrwLevels },
+    0x00b0 => { Name => 'WB_RGGBLevelsFluorescentN',%nrwLevels },
+    0x00c4 => { Name => 'WB_RGGBLevelsFluorescentD',%nrwLevels },
+    0x00d8 => { Name => 'WB_RGGBLevelsHTMercury',   %nrwLevels },
+    0x0100 => { Name => 'WB_RGGBLevelsCustom',      %nrwLevels, Notes => 'all zero if preset WB not used' },
+    0x0114 => { Name => 'WB_RGGBLevelsAuto',        %nrwLevels },
 );
 
@@ -2504,4 +4236,13 @@
         Format => 'int16u[4]',
         Protected => 1,
+    },
+);
+
+%Image::ExifTool::Nikon::ColorBalanceUnknown = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'ColorBalanceVersion',
+        Format => 'undef[4]',
     },
 );
@@ -2557,4 +4298,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -2565,4 +4307,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -2629,5 +4372,5 @@
         %nikonApertureConversions,
     },
-    0x0c => 'MCUVersion', #8
+    0x0c => 'MCUVersion', #8 (MCU = Micro Controller Unit)
 );
 
@@ -2669,5 +4412,5 @@
     0x09 => { #8/9
         # With older AF lenses this does not work... (ref 13)
-        # ie) AF Nikkor 50mm f/1.4 => 48 (0x30)
+        # eg) AF Nikkor 50mm f/1.4 => 48 (0x30)
         # AF Zoom-Nikkor 35-105mm f/3.5-4.5 => @35mm => 15 (0x0f), @105mm => 141 (0x8d)
         Notes => 'this focus distance is approximate, and not very accurate for some lenses',
@@ -2710,5 +4453,5 @@
         %nikonApertureConversions,
     },
-    0x11 => 'MCUVersion', #8
+    0x11 => 'MCUVersion', #8 (MCU = Micro Controller Unit)
     0x12 => { #8
         Name => 'EffectiveMaxAperture',
@@ -2755,5 +4498,5 @@
     0x0a => { #8/9
         # With older AF lenses this does not work... (ref 13)
-        # ie) AF Nikkor 50mm f/1.4 => 48 (0x30)
+        # eg) AF Nikkor 50mm f/1.4 => 48 (0x30)
         # AF Zoom-Nikkor 35-105mm f/3.5-4.5 => @35mm => 15 (0x0f), @105mm => 141 (0x8d)
         Notes => 'this focus distance is approximate, and not very accurate for some lenses',
@@ -2796,8 +4539,222 @@
         %nikonApertureConversions,
     },
-    0x12 => 'MCUVersion', #8
+    0x12 => 'MCUVersion', #8 (MCU = Micro Controller Unit)
     0x13 => { #8
         Name => 'EffectiveMaxAperture',
         %nikonApertureConversions,
+    },
+);
+
+# Nikon lens data version 0400 (note: needs decrypting) (ref PH)
+%Image::ExifTool::Nikon::LensData0400 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Tags extracted from the encrypted lens data of the Nikon 1J1/1V1/1J2.',
+    0x00 => {
+        Name => 'LensDataVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x18a => { #PH
+        Name => 'LensModel',
+        Format => 'string[64]',
+    },
+);
+
+# 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
+            16 => 'Nikkor Z 70-200mm f/2.8 VR S', #IB
+            17 => 'Nikkor Z 20mm f/1.8 S', #IB
+            18 => 'Nikkor Z 24-200mm f/4-6.3 VR', #IB
+            21 => 'Nikkor Z 50mm f/1.2 S', #IB
+            22 => 'Nikkor Z 24-50mm f/4-6.3', #IB
+            23 => 'Nikkor Z 14-24mm f/2.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',
     },
 );
@@ -2892,4 +4849,5 @@
         },
     },
+    # 0xac - int16u[600] TiffMeteringImage1: 30x20 image (ShotInfoVersion 0800, ref JR)
     0x157 => { #JD
         Name => 'ShutterCount',
@@ -2922,4 +4880,12 @@
     },
     # 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)
 );
 
@@ -2948,8 +4914,5 @@
         Name => 'VibrationReduction',
         Mask => 0x08,
-        PrintConv => {
-            0x00 => 'Off',
-            0x08 => 'On',
-        },
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     729 => { #JD
@@ -2989,8 +4952,8 @@
         Mask => 0x07,
         PrintConv => {
-            0x00 => 'Horizontal',
-            0x01 => 'Rotated 270 CW',
-            0x02 => 'Rotated 90 CW',
-            0x03 => 'Rotated 180',
+            0 => 'Horizontal',
+            1 => 'Rotate 270 CW',
+            2 => 'Rotate 90 CW',
+            3 => 'Rotate 180',
         },
     },
@@ -2999,6 +4962,6 @@
         Mask => 0x18,
         PrintConv => {
-            0x00 => 'Off',
-            0x18 => 'On',
+            0 => 'Off',
+            3 => 'On',
         },
     },
@@ -3007,6 +4970,6 @@
         Mask => 0xe0,
         PrintConv => { BITMASK => {
-            6 => 'Internal',
-            7 => 'External',
+            1 => 'Internal',
+            2 => 'External',
         }},
     },
@@ -3015,7 +4978,7 @@
         Mask => 0xf0,
         PrintConv => {
-            0x00 => 'Large (10.0 M)',
-            0x10 => 'Medium (5.6 M)',
-            0x20 => 'Small (2.5 M)',
+            0 => 'Large (10.0 M)',
+            1 => 'Medium (5.6 M)',
+            2 => 'Small (2.5 M)',
         },
     },
@@ -3040,5 +5003,5 @@
         },
     },
-    # note: DecryptLen currently set to 764
+    # note: DecryptLen currently set to 765
 );
 
@@ -3124,7 +5087,7 @@
         Mask => 0x18,
         PrintConv => {
-            0x00 => 'Large',
-            0x08 => 'Medium',
-            0x10 => 'Small',
+            0 => 'Large',
+            1 => 'Medium',
+            2 => 'Small',
         },
     },
@@ -3203,5 +5166,5 @@
     0x27f => {
         Name => 'ShutterCount',
-        Condition => '$$self{FirmwareVersion} =~ /^2.0[012]/',
+        Condition => '$$self{FirmwareVersion} =~ /^2.0/',
         Notes => 'firmware 2.00, 2.01 and 2.02',
         Format => 'int32u',
@@ -3212,7 +5175,7 @@
         Mask => 0x18,
         PrintConv => {
-            0x00 => 'Large',
-            0x08 => 'Medium',
-            0x10 => 'Small',
+            0 => 'Large',
+            1 => 'Medium',
+            2 => 'Small',
         },
     },
@@ -3341,10 +5304,10 @@
     0x2ce => { #(NC)
         Name => 'CustomSettingsD3S',
-        Format => 'undef[24]',
+        Format => 'undef[27]',
         SubDirectory => {
             TagTable => 'Image::ExifTool::NikonCustom::SettingsD3',
         },
     },
-    # note: DecryptLen currently set to 0x2e6
+    # note: DecryptLen currently set to 0x2e9
 );
 
@@ -3448,4 +5411,5 @@
     CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     VARS => { ID_LABEL => 'Index' },
+    DATAMEMBER => [ 4 ],
     IS_SUBDIR => [ 802 ],
     WRITABLE => 1,
@@ -3463,6 +5427,8 @@
     0x04 => { #PH
         Name => 'FirmwareVersion',
+        DataMember => 'FirmwareVersion',
         Format => 'string[5]',
         Writable => 0,
+        RawConv => '$$self{FirmwareVersion} = $val',
     },
     613 => {
@@ -3478,6 +5444,58 @@
         Priority => 0,
     },
-    732 => {
+    732 => [{
         Name => 'AFFineTuneAdj',
+        Condition => '$$self{FirmwareVersion} eq "1.10B"',
+        Notes => 'firmware version 1.10B',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConvColumns => 3,
+        # thanks to Michael Tapes for the samples to decode this!...
+        PrintConv => {
+            0xe03e => '+20',
+            0xc83e => '+19',
+            0xb03e => '+18',
+            0x983e => '+17',
+            0x803e => '+16',
+            0x683e => '+15',
+            0x503e => '+14',
+            0x383e => '+13',
+            0x203e => '+12',
+            0x083e => '+11',
+            0xe03d => '+10',
+            0xb03d => '+9',
+            0x803d => '+8',
+            0x503d => '+7',
+            0x203d => '+6',
+            0xe03c => '+5',
+            0x803c => '+4',
+            0x203c => '+3',
+            0x803b => '+2',
+            0x803a => '+1',
+            0x0000 => '0',
+            0x80c6 => '-1',
+            0x80c5 => '-2',
+            0x20c4 => '-3',
+            0x80c4 => '-4',
+            0xe0c4 => '-5',
+            0x20c3 => '-6',
+            0x50c3 => '-7',
+            0x80c3 => '-8',
+            0xb0c3 => '-9',
+            0xe0c3 => '-10',
+            0x08c2 => '-11',
+            0x20c2 => '-12',
+            0x38c2 => '-13',
+            0x50c2 => '-14',
+            0x68c2 => '-15',
+            0x80c2 => '-16',
+            0x98c2 => '-17',
+            0xb0c2 => '-18',
+            0xc8c2 => '-19',
+            0xe0c2 => '-20',
+        },
+    },{
+        Name => 'AFFineTuneAdj',
+        Notes => 'other versions',
         Format => 'int16u',
         PrintHex => 1,
@@ -3527,5 +5545,5 @@
             0x90c2 => '-20',
         },
-    },
+    }],
     802 => {
         Name => 'CustomSettingsD300',
@@ -3676,4 +5694,77 @@
 );
 
+# shot information for the D5100 firmware 1.00f (encrypted) - ref PH
+%Image::ExifTool::Nikon::ShotInfoD5100 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    IS_SUBDIR => [ 0x407 ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+    },
+    0x321 => {
+        Name => 'ShutterCount',
+        Format => 'int32u',
+        Priority => 0,
+    },
+    0x407 => {
+        Name => 'CustomSettingsD5100',
+        Format => 'undef[34]',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCustom::SettingsD5100',
+        },
+    },
+    # note: DecryptLen currently set to 0x430
+);
+
+# shot information for the D5200 firmware 1.00 (encrypted) - ref PH
+%Image::ExifTool::Nikon::ShotInfoD5200 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    IS_SUBDIR => [ 0xcd5 ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+    },
+    # 0x101 - 2=VR Off, 3=VR On
+    # 0x13d - 0=VR On, 1=VR Off
+    0xbd8 => {
+        Name => 'ShutterCount',
+        Format => 'int32u',
+        Priority => 0,
+    },
+    # 0xcd2 - 12=VR Off, 15=VR On
+    0xcd5 => {
+        Name => 'CustomSettingsD5200',
+        Format => 'undef[34]',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCustom::SettingsD5200',
+        },
+    },
+    # note: DecryptLen currently set to 0xd00
+);
+
 # shot information for the D7000 firmware 1.01d (encrypted) - ref 29
 %Image::ExifTool::Nikon::ShotInfoD7000 = (
@@ -3721,4 +5812,1619 @@
 );
 
+# shot information for the D800 firmware 1.01a (encrypted) - ref PH
+%Image::ExifTool::Nikon::ShotInfoD800 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    IS_SUBDIR => [ 0x6ec ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are extracted from encrypted data in images from the D800.',
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+    },
+    0x4c0 => {
+        Name => 'RepeatingFlashOutputExternal',
+        ValueConv => '2 ** (-$val/6)',
+        ValueConvInv => '$val > 0 ? -6*log($val)/log(2) : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x4c2 => {
+        Name => 'RepeatingFlashRateExternal',
+        DelValue => 0,
+        RawConv => '$val || undef',
+        PrintConv => '"$val Hz"',
+        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
+    },
+    0x4c3 => {
+        Name => 'RepeatingFlashCountExternal',
+        DelValue => 0,
+        RawConv => '$val || undef',
+    },
+    0x4d2 => {
+        Name => 'FlashExposureComp2',
+        Notes => 'includes the effect of flash bracketing',
+        Format => 'int8s',
+        ValueConv => '-$val/6',
+        ValueConvInv => '-6 * $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    # 0x4d4 - FEC again, doesn't include bracketing this time (internal?)
+# (not fully decoded, and duplicated in custom settings)
+#    0x4d9 => {
+#        Name => 'FlashControlBuilt-in',
+#        PrintConv => {
+#            1 => 'TTL',
+#            6 => 'Manual',
+#            7 => 'Repeating Flash',
+#        },
+#    },
+    0x4da => {
+        Name => 'RepeatingFlashRateBuilt-in',
+        DelValue => 0,
+        RawConv => '$val || undef',
+        PrintConv => '"$val Hz"',
+        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
+    },
+    0x4db => {
+        Name => 'RepeatingFlashCountBuilt-in',
+        DelValue => 0,
+        RawConv => '$val || undef',
+    },
+#    1294.1 => { # (0x4dc)
+#        Name => 'FlashModeBuilt-in',
+#        Mask => 0x0f,
+#        PrintConv => {
+#            0 => 'Front-curtain Sync',
+#            1 => 'Red-eye Reduction',
+#            2 => 'Redy-eye Reduction with Slow Sync',
+#            3 => 'Slow Sync',
+#            4 => 'Rear-curtain Sync',
+#            5 => 'Rear-curtain Sync 2', # got this in P exposure mode
+#        },
+#    },
+#    1294.2 => { # (0x4dc)
+#        Name => 'ExposureMode2',
+#        Mask => 0xf0,
+#        PrintConv => {
+#            0 => 'Program',
+#            1 => 'Aperture Priority',
+#            3 => 'Manual',
+#        },
+#    },
+    # 0x511 - related to FlashSyncSpeed
+    0x51c => 'SequenceNumber',
+    # 0x4ba+0x63 - interesting
+    # 0x4ba+0x68 - general downward trend
+    # 0x4ba+0x7b - FlashControlBuilt-in: 8=TTL, 72=Manual
+# (not reliable)
+#    1346.1 => { # (0x542)
+#        Name => 'RepeatingFlashOutputBuilt-in',
+#        DelValue => 112,
+#        Mask => 0xfc,
+#        RawConv => '$val == 0x1c ? undef : 2 ** ($val/3-7)',
+#        ValueConvInv => '$val > 0 ? (log($val)/log(2)+7)*3 : 0',
+#        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+#        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+#    },
+    0x5fb => {
+        Name => 'ShutterCount',
+        Format => 'int32u',
+    },
+    0x6ec => {
+        Name => 'CustomSettingsD800',
+        Format => 'undef[48]',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCustom::SettingsD800',
+        },
+    },
+    # note: DecryptLen currently set to 0x720
+);
+
+# shot information for the D5 firmware 1.10a and D500 firmware 1.01 (encrypted) - ref 28
+%Image::ExifTool::Nikon::ShotInfoD500 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    DATAMEMBER => [ 0x04, 0x10, 0x14, 0x2c, 0x50, 0x58, 0xa0, 0xa8, 0xb0,
+                    0x07b0, 0x086c, 0x0e7c, 0x0eea, 0x2c23, 0x2c8f ],
+    IS_SUBDIR => [ 0x0eeb ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are extracted from encrypted data in images from the D5 and D500.',
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        DataMember => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+        RawConv => '$$self{FirmwareVersion} = $val',
+    },
+    0x10 => {
+        Name => 'RotationInfoOffset',
+        DataMember => 'RotationInfoOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{RotationInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
+    },
+    0x14 => {
+        Name => 'JPGInfoOffset',
+        DataMember => 'JPGInfoOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{JPGInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
+    },
+    0x2c => {
+        Name => 'BracketingInfoOffset',
+        DataMember => 'BracketingInfoOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{BracketingInfoOffset} = $val || 0x10000000; undef', # (ignore if 0)
+    },
+    0x50 => {
+        Name => 'ShootingMenuOffset',
+        DataMember => 'ShootingMenuOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{ShootingMenuOffset} = $val || 0x10000000; undef', # (ignore if 0)
+    },
+    0x58 => {
+        Name => 'CustomSettingsOffset',
+        DataMember => 'CustomSettingsOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef', # (ignore if 0)
+    },
+    0xa0 => {
+        Name => 'OrientationOffset',
+        DataMember => 'OrientationOffset',
+        Format => 'int32u',
+        Writable => 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
+# for various image types according to the offset table above
+#
+### 0xb0 - RotationInfo start
+    0xb0 => {
+        Name => 'Hook1',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of Rotation data
+        Hook => '$varSize = $$self{RotationInfoOffset} - 0xb0',
+    },
+    0xca => {
+        Name => 'Rotation',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Horizontal',
+            1 => 'Rotate 270 CW',
+            2 => 'Rotate 90 CW',
+            3 => 'Rotate 180',
+        },
+    },
+    0x05e2 => {
+        Name => 'FlickerReductionIndicator',
+        Mask => 0x01,
+        PrintConv => { 0 => 'On', 1 => 'Off' },
+    },
+### 0x07b0 - JPEGInfo start
+    0x07b0 => {
+        Name => 'Hook2',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of Shooting Menu data
+        Hook => '$varSize = $$self{JPGInfoOffset} - 0x07b0',
+    },
+    0x07d4 => {
+        Name => 'JPGCompression',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'Size Priority',
+            1 => 'Optimal Quality',
+        },
+    },
+### 0x0830 - ? start
+### 0x086c - BracketingInfo start
+    0x086c => {
+        Name => 'Hook3',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of Shooting Menu data
+        Hook => '$varSize = $$self{BracketingInfoOffset} - 0x086c',
+    },
+    0x087b => {
+        Name => 'AEBracketingSteps',
+        Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0x00 => 'AE Bracketing Disabled',
+            0x20 => 'AE Bracketing Disabled',
+            0x30 => 'AE Bracketing Disabled',
+            0x40 => 'AE Bracketing Disabled',
+            0x50 => 'AE Bracketing Disabled',
+            0x81 => '+3F0.3',
+            0x82 => '-3F0.3',
+            0x83 => '+2F0.3',
+            0x84 => '-2F0.3',
+            0x85 => '3F0.3',
+            0x86 => '5F0.3',
+            0x87 => '7F0.3',
+            0x88 => '9F0.3',
+            0x91 => '+3F0.5',
+            0x92 => '-3F0.5',
+            0x93 => '+2F0.5',
+            0x94 => '-2F0.5',
+            0x95 => '3F0.5',
+            0x96 => '5F0.5',
+            0x97 => '7F0.5',
+            0x98 => '9F0.5',
+            0xa1 => '+3F0.7',
+            0xa2 => '-3F0.7',
+            0xa3 => '+2F0.7',
+            0xa4 => '-2F0.7',
+            0xa5 => '3F0.7',
+            0xa6 => '5F0.7',
+            0xa7 => '7F0.7',
+            0xa8 => '9F0.7',
+            0xb1 => '+3F1',
+            0xb2 => '-3F1',
+            0xb3 => '+2F1',
+            0xb4 => '-2F1',
+            0xb5 => '3F1',
+            0xb6 => '5F1',
+            0xb7 => '7F1',
+            0xb8 => '9F1',
+            0xc1 => '+3F2',
+            0xc2 => '-3F2',
+            0xc3 => '+2F2',
+            0xc4 => '-2F2',
+            0xc5 => '3F2',
+            0xc6 => '5F2',
+            0xd1 => '+3F3',
+            0xd2 => '-3F3',
+            0xd3 => '+2F3',
+            0xd4 => '-2F3',
+            0xd5 => '3F3',
+            0xd6 => '5F3',
+        },
+    },
+    0x087c => {
+        Name => 'WBBracketingSteps',
+        Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0x00 => 'WB Bracketing Disabled',
+            0x01 => 'b3F 1',
+            0x02 => 'A3F 1',
+            0x03 => 'b2F 1',
+            0x04 => 'A2F 1',
+            0x05 => '3F 1',
+            0x06 => '5F 1',
+            0x07 => '7F 1',
+            0x08 => '9F 1',
+            0x10 => '0F 2',
+            0x11 => 'b3F 2',
+            0x12 => 'A3F 2',
+            0x13 => 'b2F 2',
+            0x14 => 'A2F 2',
+            0x15 => '3F 2',
+            0x16 => '5F 2',
+            0x17 => '7F 2',
+            0x18 => '9F 2',
+            0x20 => '0F 3',
+            0x21 => 'b3F 3',
+            0x22 => 'A3F 3',
+            0x23 => 'b2F 3',
+            0x24 => 'A2F 3',
+            0x25 => '3F 3',
+            0x26 => '5F 3',
+            0x27 => '7F 3',
+            0x28 => '9F 3',
+            0x22 => 'A3F 3',
+            0x23 => 'b2F 3',
+            0x24 => 'A2F 3',
+            0x25 => '3F 3',
+            0x26 => '5F 3',
+            0x27 => '7F 3',
+            0x28 => '9F 3',
+        },
+    },
+    0x0883 => {
+        Name => 'ADLBracketingStep',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Normal',
+            3 => 'High',
+            4 => 'Extra High',
+            8 => 'Auto',
+        },
+    },
+    0x0884 => {
+        Name => 'ADLBracketingType',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'Off',
+            1 => '2 Shots',
+            2 => '3 Shots',
+            3 => '4 Shots',
+            4 => '5 Shots',
+        },
+    },
+### 0x0887 - ? start
+### 0x089f - ? start
+### 0x0929 - ? start
+### 0x09c9 - ? start
+### 0x0ac5 - ? start
+### 0x0bc1 - ? start
+### 0x0cbd - ? start
+### 0x0d98 - ? start
+### 0x0e7d - ShootingMenuOffset start
+    0x0e7c => {
+        Name => 'Hook4',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of Shooting Menu data
+        Hook => '$varSize = $$self{ShootingMenuOffset} - 0x0e7d',
+    },
+    0x0e7d => {
+        Name => 'PhotoShootingMenuBank',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'A',
+            1 => 'B',
+            2 => 'C',
+            3 => 'D',
+        },
+    },
+    0x0e7f => {
+        Name => 'PrimarySlot',
+        Condition => '$$self{Model} =~ /\bD500\b/',
+        Notes => 'D500 only',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'XQD Card',
+            1 => 'SD Card',
+        },
+    },
+    0x0e81 => {
+        Name => 'ISOAutoShutterTime',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => '1/4000 s',
+            1 => '1/3200 s',
+            2 => '1/2500 s',
+            3 => '1/2000 s',
+            4 => '1/1600 s',
+            5 => '1/1250 s',
+            6 => '1/1000 s',
+            7 => '1/800 s',
+            8 => '1/640 s',
+            9 => '1/500 s',
+            10 => '1/400 s',
+            11 => '1/320 s',
+            12 => '1/250 s',
+            13 => '1/200 s',
+            14 => '1/160 s',
+            15 => '1/125 s',
+            16 => '1/100 s',
+            17 => '1/80 s',
+            18 => '1/60 s',
+            19 => '1/50 s',
+            20 => '1/40 s',
+            21 => '1/30 s',
+            22 => '1/15 s',
+            23 => '1/8 s',
+            24 => '1/4 s',
+            25 => '1/2 s',
+            26 => '1 s',
+            27 => '2 s',
+            28 => '4 s',
+            29 => '8 s',
+            30 => '15 s',
+            31 => '30 s',
+            32 => 'Auto (Slowest)',
+            33 => 'Auto (Slower)',
+            34 => 'Auto',
+            35 => 'Auto (Faster)',
+            36 => 'Auto (Fastest)',
+        },
+    },
+    0x0e82 => {
+        Name => 'ISOAutoHiLimit',
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConv => {
+            0x24 => 'ISO 200',
+            0x26 => 'ISO 250',
+            0x27 => 'ISO 280',
+            0x28 => 'ISO 320',
+            0x2a => 'ISO 400',
+            0x2c => 'ISO 500',
+            0x2d => 'ISO 560',
+            0x2e => 'ISO 640',
+            0x30 => 'ISO 800',
+            0x32 => 'ISO 1000',
+            0x33 => 'ISO 1100',
+            0x34 => 'ISO 1250',
+            0x36 => 'ISO 1600',
+            0x38 => 'ISO 2000',
+            0x39 => 'ISO 2200',
+            0x3a => 'ISO 2500',
+            0x3c => 'ISO 3200',
+            0x3e => 'ISO 4000',
+            0x3f => 'ISO 4500',
+            0x40 => 'ISO 5000',
+            0x42 => 'ISO 6400',
+            0x44 => 'ISO 8000',
+            0x45 => 'ISO 9000',
+            0x46 => 'ISO 10000',
+            0x48 => 'ISO 12800',
+            0x4a => 'ISO 16000',
+            0x4b => 'ISO 18000',
+            0x4c => 'ISO 20000',
+            0x4e => 'ISO 25600',
+            0x50 => 'ISO 32000',
+            0x51 => 'ISO 36000',
+            0x52 => 'ISO 40000',
+            0x54 => 'ISO 51200',
+            0x56 => 'ISO Hi 0.3',
+            0x57 => 'ISO Hi 0.5',
+            0x58 => 'ISO Hi 0.7',
+            0x5a => 'ISO Hi 1.0',
+            0x60 => 'ISO Hi 2.0',
+            0x66 => 'ISO Hi 3.0',
+            0x6c => 'ISO Hi 4.0',
+            0x72 => 'ISO Hi 5.0',
+        },
+    },
+    0x0e84 => {
+        Name => 'FlickerReduction',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Enable',
+            1 => 'Disable',
+        },
+    },
+    3716.1 => { # (0x0e84)
+        Name => 'PhotoShootingMenuBankImageArea',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'FX (36x24)',
+            1 => 'DX (24x16)',
+            2 => '5:4 (30x24)',
+            3 => '1.2x (30x20)',
+            4 => '1.3x (18x12)',
+        },
+    },
+### 0x0ec4 - ? start
+### 0x0eeb - CustomSettings start
+    0x0eea => {
+        Name => 'Hook5',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of CustomSettings data
+        Hook => '$varSize = $$self{CustomSettingsOffset} - 0x0eeb',
+    },
+    0x0eeb => [{
+        Name => 'CustomSettingsD5',
+        Condition => '$$self{Model} =~ /\bD5\b/',
+        Format => 'undef[90]',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCustom::SettingsD5',
+        },
+    },{
+        Name => 'CustomSettingsD500',
+        Format => 'undef[90]',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCustom::SettingsD500',
+        },
+    }],
+#    0x0f68 => {  #this decode works, but involves more bits than should be necessary
+#        Name => 'ShutterTrigger',
+#        Mask => 0xff,
+#        PrintConv => {
+#           0 => 'Timer',
+#           15 => 'Cable Release/Remote',
+#           195 => 'Shutter Button',
+#       },
+#   },
+### 0x2c24 - OrientationInfo start (D5 firmware 1.10b)
+    0x2c23 => {
+        Name => 'Hook6',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of OrientationInfo data
+        Hook => '$varSize = $$self{OrientationOffset} - 0x2c24',
+    },
+    0x2c24 => {
+        Name => 'RollAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of clockwise camera roll',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x2c28 => {
+        Name => 'PitchAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of upward camera tilt',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x2c2c => {
+        Name => 'YawAngle',
+        Format => 'fixed32u',
+        Notes => 'the camera yaw angle when shooting in portrait orientation',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+### 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,
+    #    PrintConv => {
+    #        0 => 'On',
+    #        1 => 'Off',
+    #    },
+    #},
+    # (may not be reliable and is found elsewhere)
+    #0x2ea2 => {
+    #    Name => 'Rotation',
+    #    Condition => '$$self{Model} =~ /\bD500\b/',
+    #    Notes => 'D500 firmware 1.1x',
+    #    Mask => 0x30,
+    #    PrintConv => {
+    #        0 => 'Horizontal',
+    #        1 => 'Rotate 270 CW',
+    #        2 => 'Rotate 90 CW',
+    #        3 => 'Rotate 180',
+    #    },
+    #},
+    0x2ea4 => { #PH
+        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 D6 firmware 1.00 (encrypted) - ref 28
+%Image::ExifTool::Nikon::ShotInfoD6 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    DATAMEMBER => [ 0x9c, 0xc219 ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are extracted from encrypted data in images from the D6.',
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x24 => {
+        Name => 'NumberOffsets', # (number of entries in offset table.  offsets are from start of ShotInfo data)
+        DataMember => 'NumberOffsets',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+    },
+    0x9c => {
+        Name => 'OrientationOffset',
+        DataMember => 'OrientationOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
+    },
+### 0xc21a - OrientationInfo start (D6 firmware 1.00)
+    0xc219 => {
+        Name => 'Hook1',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of OrientationInfo data
+        Hook => '$varSize = $$self{OrientationOffset} - 0xc21a',
+    },
+
+    0xc21a => {
+        Name => 'RollAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of clockwise camera roll',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0xc21e => {
+        Name => 'PitchAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of upward camera tilt',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0xc222 => {
+        Name => 'YawAngle',
+        Format => 'fixed32u',
+        Notes => 'the camera yaw angle when shooting in portrait orientation',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    # note: DecryptLen currently set to 0xc21a + 12
+);
+
+# shot information for the D610 firmware 1.00 (encrypted) - ref PH
+%Image::ExifTool::Nikon::ShotInfoD610 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    IS_SUBDIR => [ 0x07cf ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are extracted from encrypted data in images from the D610.',
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+    },
+    0x07cf => {
+        Name => 'CustomSettingsD610',
+        Format => 'undef[48]',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCustom::SettingsD610',
+        },
+    },
+    # note: DecryptLen currently set to 0x7ff
+);
+
+# shot information for the D810 firmware 1.00(PH)/1.01 (encrypted) - ref 28
+%Image::ExifTool::Nikon::ShotInfoD810 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    DATAMEMBER => [ 0x04, 0x24, 0x38, 0x40, 0x84, 0x01d0, 0x175e, 0x185d, 0x18ab ],
+    IS_SUBDIR => [ 0x18ab ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    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]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        DataMember => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+        RawConv => '$$self{FirmwareVersion} = $val',
+    },
+    # 0x0c - number of entries in offset table (= 0x21)
+    # 0x10 - int32u[val 0x0c]: offset table
+    0x24 => {
+        Name => 'BracketingOffset',
+        DataMember => 'BracketingOffset',
+        Format => 'int32u',
+        Writable => 0,
+        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,
+        Hidden => 1,
+        RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
+    },
+    0x84 => {
+        Name => 'OrientationOffset',
+        DataMember => 'OrientationOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
+    },
+    0x01d0 => {
+        Name => 'SecondarySlotFunction',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Overflow',
+            2 => 'Backup',
+            3 => 'NEF Primary + JPG Secondary',
+        },
+        Hook => '$varSize = $$self{BracketingOffset} - 0x1747',
+    },
+    0x1756 => {
+        Name => 'AEBracketingSteps',
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0x00 => 'AE Bracketing Disabled',
+            0x20 => 'AE Bracketing Disabled',
+            0x30 => 'AE Bracketing Disabled',
+            0x40 => 'AE Bracketing Disabled',
+            0x50 => 'AE Bracketing Disabled',
+            0x81 => '+3F0.3',
+            0x82 => '-3F0.3',
+            0x83 => '+2F0.3',
+            0x84 => '-2F0.3',
+            0x85 => '3F0.3',
+            0x86 => '5F0.3',
+            0x87 => '7F0.3',
+            0x88 => '9F0.3',
+            0x91 => '+3F0.5',
+            0x92 => '-3F0.5',
+            0x93 => '+2F0.5',
+            0x94 => '-2F0.5',
+            0x95 => '3F0.5',
+            0x96 => '5F0.5',
+            0x97 => '7F0.5',
+            0x98 => '9F0.5',
+            0xa1 => '+3F0.7',
+            0xa2 => '-3F0.7',
+            0xa3 => '+2F0.7',
+            0xa4 => '-2F0.7',
+            0xa5 => '3F0.7',
+            0xa6 => '5F0.7',
+            0xa7 => '7F0.7',
+            0xa8 => '9F0.7',
+            0xb1 => '+3F1',
+            0xb2 => '-3F1',
+            0xb3 => '+2F1',
+            0xb4 => '-2F1',
+            0xb5 => '3F1',
+            0xb6 => '5F1',
+            0xb7 => '7F1',
+            0xb8 => '9F1',
+            0xc1 => '+3F2',
+            0xc2 => '-3F2',
+            0xc3 => '+2F2',
+            0xc4 => '-2F2',
+            0xc5 => '3F2',
+            0xc6 => '5F2',
+            0xd1 => '+3F3',
+            0xd2 => '-3F3',
+            0xd3 => '+2F3',
+            0xd4 => '-2F3',
+            0xd5 => '3F3',
+            0xd6 => '5F3',
+        },
+    },
+    0x1757 => {
+        Name => 'WBBracketingSteps',
+        Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0x00 => 'WB Bracketing Disabled',
+            0x01 => 'b3F 1',
+            0x02 => 'A3F 1',
+            0x03 => 'b2F 1',
+            0x04 => 'A2F 1',
+            0x05 => '3F 1',
+            0x06 => '5F 1',
+            0x07 => '7F 1',
+            0x08 => '9F 1',
+            0x10 => '0F 2',
+            0x11 => 'b3F 2',
+            0x12 => 'A3F 2',
+            0x13 => 'b2F 2',
+            0x14 => 'A2F 2',
+            0x15 => '3F 2',
+            0x16 => '5F 2',
+            0x17 => '7F 2',
+            0x18 => '9F 2',
+            0x20 => '0F 3',
+            0x21 => 'b3F 3',
+            0x22 => 'A3F 3',
+            0x23 => 'b2F 3',
+            0x24 => 'A2F 3',
+            0x25 => '3F 3',
+            0x26 => '5F 3',
+            0x27 => '7F 3',
+            0x28 => '9F 3',
+            0x22 => 'A3F 3',
+            0x23 => 'b2F 3',
+            0x24 => 'A2F 3',
+            0x25 => '3F 3',
+            0x26 => '5F 3',
+            0x27 => '7F 3',
+            0x28 => '9F 3',
+        },
+    },
+    0x175e => {
+        Name => 'NikonMeteringMode',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Matrix',
+            1 => 'Center',
+            2 => 'Spot',
+            3 => 'Highlight'
+        },
+        Hook => '$varSize = $$self{ISOAutoOffset} - 0x1858',
+    },
+    0x185c => {
+        Name => 'ISOAutoShutterTime',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => '1/4000 s',
+            1 => '1/3200 s',
+            2 => '1/2500 s',
+            3 => '1/2000 s',
+            4 => '1/1600 s',
+            5 => '1/1250 s',
+            6 => '1/1000 s',
+            7 => '1/800 s',
+            8 => '1/640 s',
+            9 => '1/500 s',
+            10 => '1/400 s',
+            11 => '1/320 s',
+            12 => '1/250 s',
+            13 => '1/200 s',
+            14 => '1/160 s',
+            15 => '1/125 s',
+            16 => '1/100 s',
+            17 => '1/80 s',
+            18 => '1/60 s',
+            19 => '1/50 s',
+            20 => '1/40 s',
+            21 => '1/30 s',
+            22 => '1/15 s',
+            23 => '1/8 s',
+            24 => '1/4 s',
+            25 => '1/2 s',
+            26 => '1 s',
+            27 => '2 s',
+            28 => '4 s',
+            29 => '8 s',
+            30 => '15 s',
+            31 => '30 s',
+            32 => 'Auto (Slowest)',
+            33 => 'Auto (Slower)',
+            34 => 'Auto',
+            35 => 'Auto (Faster)',
+            36 => 'Auto (Fastest)',
+        },
+    },
+    0x185d => {
+        Name => 'ISOAutoHiLimit',
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConv => {
+            0x24 => 'ISO 200',
+            0x26 => 'ISO 250',
+            0x27 => 'ISO 280',
+            0x28 => 'ISO 320',
+            0x2a => 'ISO 400',
+            0x2c => 'ISO 500',
+            0x2d => 'ISO 560',
+            0x2e => 'ISO 640',
+            0x30 => 'ISO 800',
+            0x32 => 'ISO 1000',
+            0x33 => 'ISO 1100',
+            0x34 => 'ISO 1250',
+            0x36 => 'ISO 1600',
+            0x38 => 'ISO 2000',
+            0x39 => 'ISO 2200',
+            0x3a => 'ISO 2500',
+            0x3c => 'ISO 3200',
+            0x3e => 'ISO 4000',
+            0x3f => 'ISO 4500',
+            0x40 => 'ISO 5000',
+            0x42 => 'ISO 6400',
+            0x44 => 'ISO 8000',
+            0x45 => 'ISO 9000',
+            0x46 => 'ISO 10000',
+            0x48 => 'ISO 12800',
+            0x4a => 'ISO 16000',
+            0x4b => 'ISO 18000',
+            0x4c => 'ISO 20000',
+            0x4e => 'ISO 25600',
+            0x50 => 'ISO 32000',
+            0x51 => 'ISO 36000',
+            0x52 => 'ISO 40000',
+            0x54 => 'ISO 51200',
+            0x56 => 'ISO Hi 0.3',
+            0x57 => 'ISO Hi 0.5',
+            0x58 => 'ISO Hi 0.7',
+            0x5a => 'ISO Hi 1.0',
+            0x60 => 'ISO Hi 2.0',
+            0x66 => 'ISO Hi 3.0',
+            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',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of clockwise camera roll',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x36f8 => {
+        Name => 'PitchAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of upward camera tilt',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x36fc => {
+        Name => 'YawAngle',
+        Format => 'fixed32u',
+        Notes => 'the camera yaw angle when shooting in portrait orientation',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    # note: DecryptLen currently set to OrientationOffset + 12
+
+    # (moves around too much and doesn't fit cleanly in the offset table)
+    #0x38be => {
+    #    Name => 'Rotation',
+    #    Condition => '$$self{FirmwareVersion} =~ /^1.0/',
+    #    Mask => 0x30,
+    #    PrintConv => {
+    #        0 => 'Horizontal',
+    #        1 => 'Rotate 270 CW',
+    #        2 => 'Rotate 90 CW',
+    #        3 => 'Rotate 180',
+    #    },
+    #},
+);
+
+# shot information for the D850 firmware 1.00b (encrypted) - ref 28
+%Image::ExifTool::Nikon::ShotInfoD850 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    DATAMEMBER => [ 0x04, 0x58, 0xa0, 0x0fbf, 0x2efa ],
+    IS_SUBDIR => [ 0x1038 ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are extracted from encrypted data in images from the D850.',
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        DataMember => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+        RawConv => '$$self{FirmwareVersion} = $val',
+    },
+    0x58 => {
+        Name => 'CustomSettingsOffset', # (relative offset from start of ShotInfo data)
+        DataMember => 'CustomSettingsOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{CustomSettingsOffset} = $val || 0x10000000; undef',
+    },
+    0xa0 => {
+        Name => 'OrientationOffset',
+        DataMember => 'OrientationOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef',
+    },
+    0x0791 => {
+        Name => 'PhotoShootingMenuBankImageArea',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'FX (36x24)',
+            1 => 'DX (24x16)',
+            2 => '5:4 (30x24)',
+            3 => '1.2x (30x20)',
+            4 => '1:1 (24x24)',
+        },
+    },
+    0x0fbd => {
+        Name => 'PhotoShootingMenuBank',
+        Condition => '$$self{FILE_TYPE} eq "JPEG"',
+        Notes => 'valid for JPEG images only',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'A',
+            1 => 'B',
+            2 => 'C',
+            3 => 'D',
+        },
+    },
+    0x0fbf => {
+        Name => 'PrimarySlot',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'XQD Card',
+            1 => 'SD Card',
+        },
+        Hook => '$varSize = $$self{CustomSettingsOffset} - 0x1038',
+    },
+    0x1038 => {
+        Name => 'CustomSettingsD850',
+        Format => 'undef[90]',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::NikonCustom::SettingsD850',
+        },
+    },
+### 0x2efb - OrientationInfo start (D850 firmware 1.01a)
+    0x2efa => {
+        Name => 'Hook1',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of OrientationInfo data
+        Hook => '$varSize = $$self{OrientationOffset} - 0x2efb',
+    },
+    0x2efb => { #28
+        Name => 'RollAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of clockwise camera roll',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x2eff => { #28
+        Name => 'PitchAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of upward camera tilt',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x2f03 => { #28
+        Name => 'YawAngle',
+        Format => 'fixed32u',
+        Notes => 'the camera yaw angle when shooting in portrait orientation',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    # note: DecryptLen currently set to 0x2f07
+);
+# shot information for the D4 firmware 1.00g (ref PH)
+%Image::ExifTool::Nikon::ShotInfoD4 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    IS_SUBDIR => [ 0x0751 ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        These tags are extracted from encrypted data in images from the D4.
+    },
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+    },
+    0x0751 => { #PH (NC)
+        Name => 'CustomSettingsD4',
+        # (seems to work for 1.00g and 1.02b)
+        Format => 'undef[56]',
+        SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsD4' },
+    },
+    # note: DecryptLen currently set to 0x789
+);
+
+# shot information for the D4S firmware 1.01a (ref 28, encrypted)
+%Image::ExifTool::Nikon::ShotInfoD4S = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    DATAMEMBER => [ 4 ],
+    IS_SUBDIR => [ 0x189d, 0x193d ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        These tags are extracted from encrypted data in images from the D4S.
+    },
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        DataMember => 'FirmwareVersion',
+        Format => 'string[5]',
+        Writable => 0,
+        RawConv => '$$self{FirmwareVersion} = $val',
+    },
+    0x01d0 => {
+        Name => 'SecondarySlotFunction',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Overflow',
+            2 => 'Backup',
+            3 => 'NEF Primary + JPG Secondary',
+        },
+    },
+    0x174c => {
+        Name => 'AEBracketingSteps',
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0x00 => 'AE Bracketing Disabled',
+            0x20 => 'AE Bracketing Disabled',
+            0x30 => 'AE Bracketing Disabled',
+            0x40 => 'AE Bracketing Disabled',
+            0x50 => 'AE Bracketing Disabled',
+            0x81 => '+3F0.3',
+            0x82 => '-3F0.3',
+            0x83 => '+2F0.3',
+            0x84 => '-2F0.3',
+            0x85 => '3F0.3',
+            0x86 => '5F0.3',
+            0x87 => '7F0.3',
+            0x88 => '9F0.3',
+            0x91 => '+3F0.5',
+            0x92 => '-3F0.5',
+            0x93 => '+2F0.5',
+            0x94 => '-2F0.5',
+            0x95 => '3F0.5',
+            0x96 => '5F0.5',
+            0x97 => '7F0.5',
+            0x98 => '9F0.5',
+            0xa1 => '+3F0.7',
+            0xa2 => '-3F0.7',
+            0xa3 => '+2F0.7',
+            0xa4 => '-2F0.7',
+            0xa5 => '3F0.7',
+            0xa6 => '5F0.7',
+            0xa7 => '7F0.7',
+            0xa8 => '9F0.7',
+            0xb1 => '+3F1',
+            0xb2 => '-3F1',
+            0xb3 => '+2F1',
+            0xb4 => '-2F1',
+            0xb5 => '3F1',
+            0xb6 => '5F1',
+            0xb7 => '7F1',
+            0xb8 => '9F1',
+            0xc1 => '+3F2',
+            0xc2 => '-3F2',
+            0xc3 => '+2F2',
+            0xc4 => '-2F2',
+            0xc5 => '3F2',
+            0xc6 => '5F2',
+            0xd1 => '+3F3',
+            0xd2 => '-3F3',
+            0xd3 => '+2F3',
+            0xd4 => '-2F3',
+            0xd5 => '3F3',
+            0xd6 => '5F3',
+        },
+    },
+    0x174d => {
+        Name => 'WBBracketingSteps',
+        Condition => '$$self{FILE_TYPE} ne "TIFF"', # (covers NEF and TIFF)
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0x00 => 'WB Bracketing Disabled',
+            0x01 => 'b3F 1',
+            0x02 => 'A3F 1',
+            0x03 => 'b2F 1',
+            0x04 => 'A2F 1',
+            0x05 => '3F 1',
+            0x06 => '5F 1',
+            0x07 => '7F 1',
+            0x08 => '9F 1',
+            0x10 => '0F 2',
+            0x11 => 'b3F 2',
+            0x12 => 'A3F 2',
+            0x13 => 'b2F 2',
+            0x14 => 'A2F 2',
+            0x15 => '3F 2',
+            0x16 => '5F 2',
+            0x17 => '7F 2',
+            0x18 => '9F 2',
+            0x20 => '0F 3',
+            0x21 => 'b3F 3',
+            0x22 => 'A3F 3',
+            0x23 => 'b2F 3',
+            0x24 => 'A2F 3',
+            0x25 => '3F 3',
+            0x26 => '5F 3',
+            0x27 => '7F 3',
+            0x28 => '9F 3',
+            0x22 => 'A3F 3',
+            0x23 => 'b2F 3',
+            0x24 => 'A2F 3',
+            0x25 => '3F 3',
+            0x26 => '5F 3',
+            0x27 => '7F 3',
+            0x28 => '9F 3',
+        },
+    },
+    0x184d => {
+        Name => 'ReleaseMode',
+        Mask => 0xff,
+        PrintConv => {
+            0 => 'Single Frame',
+            1 => 'Continuous High Speed',
+            3 => 'Continuous Low Speed',
+            4 => 'Timer',
+            32 => 'Mirror-Up',
+            64 => 'Quiet',
+        },
+    },
+    0x189d => { #PH (NC)
+        Name => 'CustomSettingsD4S',
+        Condition => '$$self{FirmwareVersion} =~ /^1.00/',
+        Notes => 'firmware version 1.00',
+        Format => 'undef[56]',
+        SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsD4' },
+    },
+    0x18c2 => { # CSf1-c (no idea why it is so far away from the rest of the settings)
+        Name => 'MultiSelectorLiveViewMode',
+        Groups => { 1 => 'NikonCustom' },
+        Condition => '$$self{FirmwareVersion} !~ /^1.00/',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Reset',
+            1 => 'Zoom',
+            3 => 'None',
+        },
+    },
+    0x18ea => {
+        Name => 'ISOAutoShutterTime',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => '1/4000 s',
+            1 => '1/3200 s',
+            2 => '1/2500 s',
+            3 => '1/2000 s',
+            4 => '1/1600 s',
+            5 => '1/1250 s',
+            6 => '1/1000 s',
+            7 => '1/800 s',
+            8 => '1/640 s',
+            9 => '1/500 s',
+            10 => '1/400 s',
+            11 => '1/320 s',
+            12 => '1/250 s',
+            13 => '1/200 s',
+            14 => '1/160 s',
+            15 => '1/125 s',
+            16 => '1/100 s',
+            17 => '1/80 s',
+            18 => '1/60 s',
+            19 => '1/50 s',
+            20 => '1/40 s',
+            21 => '1/30 s',
+            22 => '1/15 s',
+            23 => '1/8 s',
+            24 => '1/4 s',
+            25 => '1/2 s',
+            26 => '1 s',
+            27 => '2 s',
+            28 => '4 s',
+            29 => '8 s',
+            30 => '15 s',
+            31 => '30 s',
+            32 => 'Auto (Slowest)',
+            33 => 'Auto (Slower)',
+            34 => 'Auto',
+            35 => 'Auto (Faster)',
+            36 => 'Auto (Fastest)',
+        },
+    },
+    0x18eb => {
+        Name => 'ISOAutoHiLimit',
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConv => {
+            0x24 => 'ISO 200',
+            0x26 => 'ISO 250',
+            0x27 => 'ISO 280',
+            0x28 => 'ISO 320',
+            0x2a => 'ISO 400',
+            0x2c => 'ISO 500',
+            0x2d => 'ISO 560',
+            0x2e => 'ISO 640',
+            0x30 => 'ISO 800',
+            0x32 => 'ISO 1000',
+            0x33 => 'ISO 1100',
+            0x34 => 'ISO 1250',
+            0x36 => 'ISO 1600',
+            0x38 => 'ISO 2000',
+            0x39 => 'ISO 2200',
+            0x3a => 'ISO 2500',
+            0x3c => 'ISO 3200',
+            0x3e => 'ISO 4000',
+            0x3f => 'ISO 4500',
+            0x40 => 'ISO 5000',
+            0x42 => 'ISO 6400',
+            0x44 => 'ISO 8000',
+            0x45 => 'ISO 9000',
+            0x46 => 'ISO 10000',
+            0x48 => 'ISO 12800',
+            0x4a => 'ISO 16000',
+            0x4b => 'ISO 18000',
+            0x4c => 'ISO 20000',
+            0x4e => 'ISO 25600',
+            0x50 => 'ISO 32000',
+            0x51 => 'ISO 36000',
+            0x52 => 'ISO 40000',
+            0x54 => 'ISO 51200',
+            0x56 => 'ISO Hi 0.3',
+            0x57 => 'ISO Hi 0.5',
+            0x58 => 'ISO Hi 0.7',
+            0x5a => 'ISO Hi 1.0',
+            0x60 => 'ISO Hi 2.0',
+            0x66 => 'ISO Hi 3.0',
+            0x6c => 'ISO Hi 4.0',
+            0x72 => 'ISO Hi 5.0',
+        },
+    },
+    0x193d => {
+        Name => 'CustomSettingsD4S',
+        Condition => '$$self{FirmwareVersion} !~ /^1.00/',
+        Notes => 'firmware version 1.01',
+        Format => 'undef[56]',
+        SubDirectory => { TagTable => 'Image::ExifTool::NikonCustom::SettingsD4' },
+    },
+#    0x1978 => {        #this decode works, but involves more bits than should be necessary
+#        Name => 'ShutterTrigger',
+#        Mask => 0xff,
+#        PrintConv => {
+#           0 => 'Timer',
+#           15 => 'Cable Release/Remote',
+#           195 => 'Shutter Button',
+#       },
+#   },
+    0x350b => {
+        Name => 'RollAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of clockwise camera roll',
+        ValueConv => '$val < 180 ? -$val : 360 - $val',
+        ValueConvInv => '$val <= 0 ? -$val : 360 - $val',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x350f => {
+        Name => 'PitchAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of upward camera tilt',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x3513 => {
+        Name => 'YawAngle',
+        Format => 'fixed32u',
+        Notes => 'the camera yaw angle when shooting in portrait orientation',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x3693 => {
+        Name => 'Rotation',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Horizontal',
+            1 => 'Rotate 270 CW',
+            2 => 'Rotate 90 CW',
+            3 => 'Rotate 180',
+        },
+    },
+    # note: DecryptLen currently set to 0x3697
+);
+
+# shot information for the Z7_2 firmware 1.00 (encrypted) - ref 28
+%Image::ExifTool::Nikon::ShotInfoZ7_2 = (
+    PROCESS_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    WRITE_PROC => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    VARS => { ID_LABEL => 'Index' },
+    DATAMEMBER => [ 0x04, 0x0e, 0x18, 0x98, 0xce31 ],
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are extracted from encrypted data in images from the Z7_2.',
+    0x00 => {
+        Name => 'ShotInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    0x04 => {
+        Name => 'FirmwareVersion',
+        DataMember => 'FirmwareVersion',
+        Format => 'string[8]',
+        Writable => 0,
+        RawConv => '$$self{FirmwareVersion} = $val',
+    },
+    0x0E => {
+        Name => 'FirmwareVersion2',
+        Format => 'string[8]',
+        Writable => 0,
+        RawConv => '$$self{FirmwareVersion2} = $val',
+        Hidden => 1,
+    },
+    0x18 => {
+        Name => 'FirmwareVersion3',
+        Format => 'string[8]',
+        Writable => 0,
+        RawConv => '$$self{FirmwareVersion3} = $val',
+        Hidden => 1,
+    },
+    0x24 => {
+        Name => 'NumberOffsets', #number of entries in offset table.  offsets are from start of ShotInfo data.
+        DataMember => 'NumberOffsets',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+    },
+    0x98 => {
+        Name => 'OrientationOffset',
+        DataMember => 'OrientationOffset',
+        Format => 'int32u',
+        Writable => 0,
+        Hidden => 1,
+        RawConv => '$$self{OrientationOffset} = $val || 0x10000000; undef', # (ignore if 0)
+    },
+
+### 0xce32 - OrientationInfo start (Z7_2 firmware 1.00)
+    0xce31 => {
+        Name => 'Hook1',
+        Hidden => 1,
+        RawConv => 'undef',
+        # account for variable location of OrientationInfo data
+        Hook => '$varSize = $$self{OrientationOffset} - 0xce32',
+    },
+
+    0xce32 => {
+        Name => 'RollAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of clockwise camera roll',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0xce36 => {
+        Name => 'PitchAngle',
+        Format => 'fixed32u',
+        Notes => 'converted to degrees of upward camera tilt',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+    0xce3a => {
+        Name => 'YawAngle',
+        Format => 'fixed32u',
+        Notes => 'the camera yaw angle when shooting in portrait orientation',
+        ValueConv => '$val <= 180 ? $val : $val - 360',
+        ValueConvInv => '$val >= 0 ? $val : $val + 360',
+        PrintConv => 'sprintf("%.1f", $val)',
+        PrintConvInv => '$val',
+    },
+     #note: DecryptLen currently set to 0xce32 + 12
+);
+
 # Flash information (ref JD)
 %Image::ExifTool::Nikon::FlashInfo0100 = (
@@ -3753,18 +7459,17 @@
     8 => {
         Name => 'ExternalFlashFlags',
-        PrintConv => { BITMASK => {
-            0 => 'Fired', #28
-            2 => 'Bounce Flash', #PH
-            4 => 'Wide Flash Adapter',
-            5 => 'Dome Diffuser', #28
-        }},
+        PrintConv => { 0 => '(none)',
+            BITMASK => {
+                0 => 'Fired', #28
+                2 => 'Bounce Flash', #PH
+                4 => 'Wide Flash Adapter',
+                5 => 'Dome Diffuser', #28
+            },
+        },
     },
     9.1 => {
         Name => 'FlashCommanderMode',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'Off',
-            0x80 => 'On',
-        },
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     9.2 => {
@@ -3912,8 +7617,5 @@
         Name => 'FlashCommanderMode',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'Off',
-            0x80 => 'On',
-        },
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     9.2 => {
@@ -3982,6 +7684,4 @@
         DataMember => 'FlashGroupBControlMode',
         RawConv => '$$self{FlashGroupBControlMode} = $val',
-        ValueConv => '$val >> 4',
-        ValueConvInv => '$val << 4',
         PrintConv => \%flashControlMode,
         SeparateTable => 'FlashControlMode',
@@ -4053,4 +7753,5 @@
 
 # Flash information for D90 and D700 (ref PH)
+# - confirmed in detail for D800 (0105) - PH
 %Image::ExifTool::Nikon::FlashInfo0103 = (
     %binaryDataAttrs,
@@ -4058,6 +7759,7 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     NOTES => q{
-        These tags are used by the D3 (firmware 2.x), D3X, D3S, D90, D300 (firmware
-        1.10), D300S, D700, D3000 and D5000.
+        These tags are used by the D3 (firmware 2.x), D3X, D3S, D4, D90, D300
+        (firmware 1.10), D300S, D600, D700, D800, D3000, D3100, D3200, D5000, D5100,
+        D5200, D7000.
     },
     # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
@@ -4094,8 +7796,5 @@
         Name => 'FlashCommanderMode',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'Off',
-            0x80 => 'On',
-        },
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     9.2 => {
@@ -4151,15 +7850,6 @@
     16 => { #28
         Name => 'FlashColorFilter',
-        PrintConv => {
-            0x00 => 'None',
-            1 => 'FL-GL1',
-            2 => 'FL-GL2',
-            9 => 'TN-A1',
-            10 => 'TN-A2',
-            65 => 'Red',
-            66 => 'Blue',
-            67 => 'Yellow',
-            68 => 'Amber',
-        },
+        SeparateTable => 1,
+        PrintConv => \%flashColorFilter,
     },
     17.1 => {
@@ -4178,6 +7868,4 @@
         DataMember => 'FlashGroupBControlMode',
         RawConv => '$$self{FlashGroupBControlMode} = $val',
-        ValueConv => '$val >> 4',
-        ValueConvInv => '$val << 4',
         PrintConv => \%flashControlMode,
         SeparateTable => 'FlashControlMode',
@@ -4192,5 +7880,5 @@
         SeparateTable => 'FlashControlMode',
     },
-    19 => [
+    0x13 => [
         {
             Name => 'FlashGroupAOutput',
@@ -4210,5 +7898,5 @@
         },
     ],
-    20 => [
+    0x14 => [
         {
             Name => 'FlashGroupBOutput',
@@ -4228,5 +7916,5 @@
         },
     ],
-    21 => [ #PH
+    0x15 => [ #PH
         {
             Name => 'FlashGroupCOutput',
@@ -4246,6 +7934,427 @@
         },
     ],
-);
-
+    0x1b => { #PH
+        Name => 'ExternalFlashCompensation',
+        Format => 'int8s',
+        Priority => 0,
+        ValueConv => '-$val/6',
+        ValueConvInv => '-6 * $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x1d => { #PH
+        Name => 'FlashExposureComp3',
+        Format => 'int8s',
+        # (does not include the built-in compensation for FlashType "Built-in,TTL&Comdr.")
+        Notes => 'does not include the effect of flash bracketing',
+        Priority => 0,
+        ValueConv => '-$val/6',
+        ValueConvInv => '-6 * $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x27 => { #PH (same as ShotInfoD800 0x4d2 but also valid for repeating flash)
+        Name => 'FlashExposureComp4',
+        Format => 'int8s',
+        Notes => 'includes the effect of flash bracketing.  Valid for repeating flash',
+        Priority => 0,
+        ValueConv => '-$val/6',
+        ValueConvInv => '-6 * $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    # 0x2b - related to flash power (PH, D800, 96=full,62=1/4,2=1/128)
+);
+
+# Flash information for the D7100 (ref PH)
+# (this is VERY similar to FlashInfo0107, but there are a few differences that
+#  would need to be resolved if these two definitions were to be combined)
+%Image::ExifTool::Nikon::FlashInfo0106 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 9.2, 17.1, 18.1, 18.2 ],
+    NOTES => 'These tags are used by the Df, D610, D3300, D5300, D7100 and Coolpix A.',
+    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
+    0 => {
+        Name => 'FlashInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    4 => {
+        Name => 'FlashSource',
+        PrintConv => {
+            0 => 'None',
+            1 => 'External',
+            2 => 'Internal',
+        },
+    },
+    6 => {
+        Format => 'int8u[2]',
+        Name => 'ExternalFlashFirmware',
+        SeparateTable => 'FlashFirmware',
+        PrintConv => \%flashFirmware,
+    },
+    8 => {
+        Name => 'ExternalFlashFlags',
+        PrintConv => { BITMASK => {
+            0 => 'Fired',
+            2 => 'Bounce Flash',
+            4 => 'Wide Flash Adapter',
+            5 => 'Dome Diffuser', # (NC, not true for the SB-910 anyway)
+          # 7 - ? (set for SB-910 when an advanced option is used, eg. diff pattern)
+        }},
+    },
+    9.1 => { # (NC)
+        Name => 'FlashCommanderMode',
+        Mask => 0x80,
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    9.2 => {
+        Name => 'FlashControlMode',
+        Mask => 0x7f,
+        DataMember => 'FlashControlMode',
+        RawConv => '$$self{FlashControlMode} = $val',
+        PrintConv => \%flashControlMode,
+        SeparateTable => 'FlashControlMode',
+    },
+  # 10 - similar to 0x27 but zero sometimes when I don't think it should be
+    12 => {
+        Name => 'FlashFocalLength',
+        Notes => 'only valid if flash pattern is "Standard Illumination"',
+        RawConv => '($val and $val != 255) ? $val : undef',
+        PrintConv => '"$val mm"',
+        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
+    },
+    13 => {
+        Name => 'RepeatingFlashRate',
+        RawConv => '($val and $val != 255) ? $val : undef',
+        PrintConv => '"$val Hz"',
+        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
+    },
+    14 => {
+        Name => 'RepeatingFlashCount',
+        RawConv => '($val and $val != 255) ? $val : undef',
+    },
+    15 => { # (NC)
+        Name => 'FlashGNDistance',
+        SeparateTable => 1,
+        PrintConv => \%flashGNDistance,
+    },
+    16 => {
+        Name => 'FlashColorFilter',
+        SeparateTable => 1,
+        PrintConv => \%flashColorFilter,
+    },
+    17.1 => {
+        Name => 'FlashGroupAControlMode',
+        Mask => 0x0f,
+        DataMember => 'FlashGroupAControlMode',
+        RawConv => '$$self{FlashGroupAControlMode} = $val',
+        PrintConv => \%flashControlMode,
+        SeparateTable => 'FlashControlMode',
+    },
+    18.1 => {
+        Name => 'FlashGroupBControlMode',
+        Mask => 0xf0,
+        DataMember => 'FlashGroupBControlMode',
+        RawConv => '$$self{FlashGroupBControlMode} = $val',
+        PrintConv => \%flashControlMode,
+        SeparateTable => 'FlashControlMode',
+    },
+    18.2 => {
+        Name => 'FlashGroupCControlMode',
+        Mask => 0x0f,
+        DataMember => 'FlashGroupCControlMode',
+        RawConv => '$$self{FlashGroupCControlMode} = $val',
+        PrintConv => \%flashControlMode,
+        SeparateTable => 'FlashControlMode',
+    },
+  # 0x13 - same as 0x28 but not zero when flash group A is Off
+  # 0x14 - same as 0x29 but not zero when flash group B is Off
+  # 0x15 - same as 0x2a but not zero when flash group B is Off
+  # 0x1a - changes with illumination pattern (0=normal,1=narrow,2=wide), but other values seen
+  # 0x26 - changes when diffuser is used
+    0x27 => [
+        {
+            Name => 'FlashOutput',
+            Condition => '$$self{FlashControlMode} >= 0x06',
+            ValueConv => '2 ** (-$val/6)',
+            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
+            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
+            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
+        },
+        {
+            Name => 'FlashCompensation',
+            Format => 'int8s',
+            Priority => 0,
+            ValueConv => '-$val/6',
+            ValueConvInv => '-6 * $val',
+            PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+            PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        },
+    ],
+    0x28 => [
+        {
+            Name => 'FlashGroupAOutput',
+            Condition => '$$self{FlashGroupAControlMode} >= 0x06',
+            ValueConv => '2 ** (-$val/6)',
+            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
+            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
+            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
+        },
+        {
+            Name => 'FlashGroupACompensation',
+            Format => 'int8s',
+            ValueConv => '-$val/6',
+            ValueConvInv => '-6 * $val',
+            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+            PrintConvInv => '$val',
+        },
+    ],
+    0x29 => [
+        {
+            Name => 'FlashGroupBOutput',
+            Condition => '$$self{FlashGroupBControlMode} >= 0x60',
+            ValueConv => '2 ** (-$val/6)',
+            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
+            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
+            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
+        },
+        {
+            Name => 'FlashGroupBCompensation',
+            Format => 'int8s',
+            ValueConv => '-$val/6',
+            ValueConvInv => '-6 * $val',
+            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+            PrintConvInv => '$val',
+        },
+    ],
+    0x2a => [
+        {
+            Name => 'FlashGroupCOutput',
+            Condition => '$$self{FlashGroupCControlMode} >= 0x06',
+            ValueConv => '2 ** (-$val/6)',
+            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
+            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
+            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
+        },
+        {
+            Name => 'FlashGroupCCompensation',
+            Format => 'int8s',
+            ValueConv => '-$val/6',
+            ValueConvInv => '-6 * $val',
+            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+            PrintConvInv => '$val',
+        },
+    ],
+);
+
+# Flash information for the D4S/D750/D810/D5500/D7200 (0107)
+# and D5/D500/D850/D3400 (0108) (ref 28)
+%Image::ExifTool::Nikon::FlashInfo0107 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 17.1, 18.1, 18.2 ],
+    NOTES => q{
+        These tags are used by the D4S, D750, D810, D5500, D7200 (FlashInfoVersion
+        0107) and the D5, D500, D850 and D3400 (FlashInfoVersion 0108).
+    },
+    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
+    0 => {
+        Name => 'FlashInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    4 => {
+        Name => 'FlashSource',
+        PrintConv => {
+            0 => 'None',
+            1 => 'External',
+            2 => 'Internal',
+        },
+    },
+    6 => {
+        Format => 'int8u[2]',
+        Name => 'ExternalFlashFirmware',
+        SeparateTable => 'FlashFirmware',
+        PrintConv => \%flashFirmware,
+    },
+    8.1 => {
+        Name => 'ExternalFlashZoomOverride',
+        Mask => 0x80,
+        Notes => 'indicates that the user has overridden the flash zoom distance',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    8.2 => {
+        Name => 'ExternalFlashStatus',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'Flash Not Attached',
+            1 => 'Flash Attached',
+        },
+    },
+    9.1 => {
+        Name => 'ExternalFlashReadyState',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Ready',
+            6 => 'Not Ready',
+        },
+    },
+    10 => {
+        Name => 'FlashCompensation',
+        # this is the compensation from the camera (0x0012) for "Built-in" FlashType, or
+        # the compensation from the external unit (0x0017) for "Optional" FlashType - PH
+        Format => 'int8s',
+        Priority => 0,
+        ValueConv => '-$val/6',
+        ValueConvInv => '-6 * $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    12 => {
+        Name => 'FlashFocalLength',
+        Notes => 'only valid if flash pattern is "Standard Illumination"',
+        RawConv => '($val and $val != 255) ? $val : undef',
+        PrintConv => '"$val mm"',
+        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
+    },
+    13 => {
+        Name => 'RepeatingFlashRate',
+        RawConv => '($val and $val != 255) ? $val : undef',
+        PrintConv => '"$val Hz"',
+        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
+    },
+    14 => {
+        Name => 'RepeatingFlashCount',
+        RawConv => '($val and $val != 255) ? $val : undef',
+    },
+    15 => {
+        Name => 'FlashGNDistance',
+        SeparateTable => 1,
+        PrintConv => \%flashGNDistance,
+    },
+    17.1 => { #PH
+        Name => 'FlashGroupAControlMode',
+        Mask => 0x0f,
+        Notes => 'note: group A tags may apply to the built-in flash settings for some models',
+        DataMember => 'FlashGroupAControlMode',
+        RawConv => '$$self{FlashGroupAControlMode} = $val',
+        PrintConv => \%flashControlMode,
+        SeparateTable => 'FlashControlMode',
+    },
+    18.1 => { #PH
+        Name => 'FlashGroupBControlMode',
+        Mask => 0xf0,
+        Notes => 'note: group B tags may apply to group A settings for some models',
+        DataMember => 'FlashGroupBControlMode',
+        RawConv => '$$self{FlashGroupBControlMode} = $val',
+        PrintConv => \%flashControlMode,
+        SeparateTable => 'FlashControlMode',
+    },
+    18.2 => { #PH
+        Name => 'FlashGroupCControlMode',
+        Mask => 0x0f,
+        Notes => 'note: group C tags may apply to group B settings for some models',
+        DataMember => 'FlashGroupCControlMode',
+        RawConv => '$$self{FlashGroupCControlMode} = $val',
+        PrintConv => \%flashControlMode,
+        SeparateTable => 'FlashControlMode',
+    },
+    # 0x13 - very similar to 0x28
+    # 0x18 or 0x19 may indicate flash illumination pattern (Standard, Center-weighted, Even)
+    0x28 => [ #PH
+        {
+            Name => 'FlashGroupAOutput',
+            Condition => '$$self{FlashGroupAControlMode} >= 0x06',
+            ValueConv => '2 ** (-$val/6)',
+            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
+            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
+            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
+        },
+        {
+            Name => 'FlashGroupACompensation',
+            Format => 'int8s',
+            ValueConv => '-$val/6',
+            ValueConvInv => '-6 * $val',
+            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+            PrintConvInv => '$val',
+        },
+    ],
+    0x29 => [ #PH
+        {
+            Name => 'FlashGroupBOutput',
+            Condition => '$$self{FlashGroupBControlMode} >= 0x60',
+            ValueConv => '2 ** (-$val/6)',
+            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
+            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
+            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
+        },
+        {
+            Name => 'FlashGroupBCompensation',
+            Format => 'int8s',
+            ValueConv => '-$val/6',
+            ValueConvInv => '-6 * $val',
+            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+            PrintConvInv => '$val',
+        },
+    ],
+    0x2a => [ #PH
+        {
+            Name => 'FlashGroupCOutput',
+            Condition => '$$self{FlashGroupCControlMode} >= 0x06',
+            ValueConv => '2 ** (-$val/6)',
+            ValueConvInv => '$val>0 ? -6*log($val)/log(2) : 0',
+            PrintConv => '$val>0.99 ? "Full" : sprintf("%.0f%%",$val*100)',
+            PrintConvInv => '$val=~/(\d+)/ ? $1/100 : 1',
+        },
+        {
+            Name => 'FlashGroupCCompensation',
+            Format => 'int8s',
+            ValueConv => '-$val/6',
+            ValueConvInv => '-6 * $val',
+            PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+            PrintConvInv => '$val',
+        },
+    ],
+);
+
+# Flash information for the Z7_2 (ref 28)
+# (likey similar to FlashInfo010 and FlashInfo0108 with addition of support for radio controlled units such as the SB-5000?
+%Image::ExifTool::Nikon::FlashInfo0300 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'FlashInfoVersion',
+        Format => 'string[4]',
+        Writable => 0,
+    },
+    4 => {
+        Name => 'FlashSource',
+        PrintConv => {
+            0 => 'None',
+            1 => 'External',
+            2 => 'Internal',
+        },
+    },
+    6 => {
+        Format => 'int8u[2]',
+        Name => 'ExternalFlashFirmware',
+        SeparateTable => 'FlashFirmware',
+        PrintConv => \%flashFirmware,
+    },
+    27 => {
+        Name => 'FlashCompensation',
+        # this is the compensation from the camera (0x0012) for "Built-in" FlashType, or
+        # the compensation from the external unit (0x0017) for "Optional" FlashType - PH
+        Format => 'int8s',
+        Priority => 0,
+        ValueConv => '-$val/6',
+        ValueConvInv => '-6 * $val',
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+);
 # Unknown Flash information
 %Image::ExifTool::Nikon::FlashInfoUnknown = (
@@ -4264,5 +8373,4 @@
     FORMAT => 'int32u',
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
     0 => {
         Name => 'MultiExposureVersion',
@@ -4276,4 +8384,5 @@
             1 => 'Multiple Exposure',
             2 => 'Image Overlay',
+            3 => 'HDR', #31
         },
     },
@@ -4283,4 +8392,108 @@
         PrintConv => \%offOn,
     },
+);
+
+# HDR information (ref 32)
+%Image::ExifTool::Nikon::HDRInfo = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    # NOTE: Must set ByteOrder in SubDirectory if any multi-byte integer tags added
+    0 => {
+        Name => 'HDRInfoVersion',
+        Format => 'string[4]',
+    },
+    4 => {
+        Name => 'HDR',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            48 => 'Auto', #PH (NC)
+        },
+    },
+    5 => {
+        Name => 'HDRLevel',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1 EV',
+            2 => '2 EV',
+            3 => '3 EV',
+            # 5 - seen for 1J4
+            255 => 'n/a', #PH
+        },
+    },
+    6 => {
+        Name => 'HDRSmoothing',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Normal',
+            2 => 'Low',
+            3 => 'High',
+            48 => 'Auto', #PH (NC)
+            255 => 'n/a', #PH
+        },
+    },
+    7 => { #PH (P330, HDRInfoVersion=0101)
+        Name => 'HDRLevel2',
+        PrintConv => {
+            0 => 'Auto',
+            1 => '1 EV',
+            2 => '2 EV',
+            3 => '3 EV',
+            255 => 'n/a',
+        },
+    },
+);
+
+# location information (ref PH)
+%Image::ExifTool::Nikon::LocationInfo = (
+    %binaryDataAttrs,
+    DATAMEMBER => [ 4 ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Location' },
+    NOTES => 'Tags written by some Nikon GPS-equipped cameras like the AW100.',
+    0 => {
+        Name => 'LocationInfoVersion',
+        Format => 'undef[4]',
+    },
+    4 => {
+        Name => 'TextEncoding',
+        DataMember => 'TextEncoding',
+        RawConv => q{
+            $$self{TextEncoding} = $Image::ExifTool::Nikon::nikonTextEncoding{$val} if $val;
+            return $val;
+        },
+        PrintConv => \%Image::ExifTool::Nikon::nikonTextEncoding,
+    },
+    # (the CountryCode and Location tag names chosen to correspond with XMP::iptcCore)
+    5 => {
+        Name => 'CountryCode',
+        Format => 'undef[3]',
+        ValueConv => '$val=~s/\0.*//s; $val', # truncate at null
+        ValueConvInv => '$val',
+    },
+    8 => 'POILevel', #forum5782
+    9 => {
+        Name => 'Location',
+        Format => 'undef[70]',
+        RawConv    => '$$self{TextEncoding} ? $self->Decode($val,$$self{TextEncoding},"MM") : $val',
+        RawConvInv => '$$self{TextEncoding} ? $self->Encode($val,$$self{TextEncoding},"MM") : $val',
+    },
+);
+
+# 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]
 );
 
@@ -4358,4 +8571,5 @@
     ncth => {
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
         Binary => 1,
     },
@@ -4366,4 +8580,5 @@
     ncvw => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         RawConv => 'length($val) ? $val : undef',
         Binary => 1,
@@ -4542,6 +8757,6 @@
     GROUPS => { 0 => 'MakerNotes', 1 => 'Nikon', 2 => 'Video' },
     NOTES => q{
-        Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some
-        Nikon cameras such as the Coolpix S8000.
+        Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from
+        various Nikon models.
     },
     NCHD => {
@@ -4558,7 +8773,43 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Nikon::NCTG' },
     },
-    NCTH => { Name => 'ThumbnailImage', Format => 'undef', Binary => 1 },
-    NCVW => { Name => 'PreviewImage',   Format => 'undef', Binary => 1 },
-    # NCDB - 0 bytes long, or 4 null bytes
+    NCTH => {
+        Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef',
+        Binary => 1,
+    },
+    NCVW => {
+        Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef',
+        Binary => 1,
+    },
+    NCDB => { # (often 0 bytes long, or 4 null bytes)
+        Name => 'NikonNCDB',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::NCDB' },
+    },
+    NCM1 => {
+        Name => 'PreviewImage1',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef',
+        Binary => 1,
+        RawConv => 'length $val ? $val : undef',
+    },
+    NCM2 => { #PH (guess - have only seen 0 bytes)
+        Name => 'PreviewImage2',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef',
+        Binary => 1,
+        RawConv => 'length $val ? $val : undef',
+    },
+);
+
+# Nikon NCDB tags from MOV videos (ref PH)
+%Image::ExifTool::Nikon::NCDB = (
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Nikon', 2 => 'Video' },
+    # the following probably contain encrypted data -- look into decryping these!
+    # OP01 - 320 bytes, starts with "0200" (D600,D610,D810,D3200,D5200)
+    #      - 638 bytes, starts with "0200" (D7100)
+    # OP02 - 2048 bytes, starts with "0200" (D810)
 );
 
@@ -4597,4 +8848,10 @@
         PrintConv => 'int($val * 1000 + 0.5) / 1000',
     },
+    # 0x17 - rational62u: same value as FrameRate
+    # 0x18 - int16u: 1, 2
+    0x19 => {
+        Name => 'TimeZone',
+        Groups => { 2 => 'Time' },
+    },
     # 0x21 - int16u: 1, 2
     0x22 => {
@@ -4606,6 +8863,6 @@
         Groups => { 2 => 'Video' },
     },
-    # 0x24 - int16u: 2
-    # 0x31 - int16u: 1, 2
+    # 0x24 - int16u: 1, 2
+    # 0x31 - int16u: 0, 1, 2
     0x32 => { #(guess)
         Name => 'AudioChannels',
@@ -4620,4 +8877,169 @@
         Groups => { 2 => 'Audio' },
     },
+    # 0x101 - int16u[4]: "160 120 1280 720", "160 120 3840 2160"
+    # 0x102 - int16u[8]: "640 360 0 0 0 0 0 0", "640 360 1920 1080 0 0 0 0"
+    # 0x1001 - int16s: 0
+    0x1002 => {
+        Name => 'NikonDateTime', #?
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    # 0x1011 - int32u: 0
+    # 0x1012 - int32u: 0
+    0x1013 => { #HayoBaan
+        Name => 'ElectronicVR',
+        PrintConv => \%offOn,
+    },
+    # 0x1014 - int16u: 1
+    # 0x1021 - int32u[32]: all zeros
+#
+# 0x110**** tags correspond to 0x**** tags in Exif::Main
+#
+    0x110829a => { #34
+        Name => 'ExposureTime',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x110829d => { #34
+        Name => 'FNumber',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+    },
+    0x1108822 => {
+        Name => 'ExposureProgram',
+        PrintConv => {
+            0 => 'Not Defined',
+            1 => 'Manual',
+            2 => 'Program AE',
+            3 => 'Aperture-priority AE',
+            4 => 'Shutter speed priority AE',
+            5 => 'Creative (Slow speed)',
+            6 => 'Action (High speed)',
+            7 => 'Portrait',
+            8 => 'Landscape',
+          # 9 => 'Bulb', # (non-standard Canon value)
+        },
+    },
+    0x1109204 => {
+        Name => 'ExposureCompensation',
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+    },
+    0x1109207 => {
+        Name => 'MeteringMode',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'Average',
+            2 => 'Center-weighted average',
+            3 => 'Spot',
+            4 => 'Multi-spot',
+            5 => 'Multi-segment',
+            6 => 'Partial',
+            255 => 'Other',
+        },
+    },
+    0x110920a => { #34
+        Name => 'FocalLength',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+    },
+    0x110a431 => 'SerialNumber',
+    0x110a432 => {
+        Name => 'LensInfo',
+        PrintConv => \&Image::ExifTool::Exif::PrintLensInfo,
+    },
+    0x110a433 => 'LensMake',
+    0x110a434 => 'LensModel',
+    0x110a435 => 'LensSerialNumber',
+#
+# 0x120**** tags correspond to 0x**** tags in GPS::Main
+#
+    0x1200000 => {
+        Name => 'GPSVersionID',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => '$val =~ tr/ /./; $val',
+    },
+    0x1200001 => {
+        Name => 'GPSLatitudeRef',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            N => 'North',
+            S => 'South',
+        },
+    },
+    0x1200002 => {
+        Name => 'GPSLatitude',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        ValueConv => q{
+            require Image::ExifTool::GPS;
+            Image::ExifTool::GPS::ToDegrees($val);
+        },
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+    },
+    0x1200003 => {
+        Name => 'GPSLongitudeRef',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            E => 'East',
+            W => 'West',
+        },
+    },
+    0x1200004 => {
+        Name => 'GPSLongitude',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        ValueConv => q{
+            require Image::ExifTool::GPS;
+            Image::ExifTool::GPS::ToDegrees($val);
+        },
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+    },
+    0x1200005 => {
+        Name => 'GPSAltitudeRef',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            0 => 'Above Sea Level',
+            1 => 'Below Sea Level',
+        },
+    },
+    0x1200006 => {
+        Name => 'GPSAltitude',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
+    },
+    0x1200007 => {
+        Name => 'GPSTimeStamp',
+        Groups => { 1 => 'GPS', 2 => 'Time' },
+        ValueConv => q{
+            require Image::ExifTool::GPS;
+            Image::ExifTool::GPS::ConvertTimeStamp($val);
+        },
+        PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)',
+    },
+    0x1200008 => {
+        Name => 'GPSSatellites',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+    },
+    0x1200010 => {
+        Name => 'GPSImgDirectionRef',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            M => 'Magnetic North',
+            T => 'True North',
+        },
+    },
+    0x1200011 => {
+        Name => 'GPSImgDirection',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+    },
+    0x1200012 => {
+        Name => 'GPSMapDatum',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+    },
+    0x120001d => {
+        Name => 'GPSDateStamp',
+        Groups => { 1 => 'GPS', 2 => 'Time' },
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+    },
+#
+# 0x200**** tags correspond to 0x**** tags in Nikon::Main
+# (must be duplicated here so tagInfo "Table" entry will point to correct table.
+#  Also there would be a problem with the PRINT_CONV from the Main table)
+#
     0x2000001 => {
         Name => 'MakerNoteVersion',
@@ -4625,5 +9047,12 @@
     },
     0x2000005 => 'WhiteBalance',
+    0x2000007 => { Name => 'FocusMode',    Writable => 'string' }, #34
     0x200000b => 'WhiteBalanceFineTune',
+    0x200001b => {
+        Name => 'CropHiSpeed',
+        Writable => 'int16u',
+        Count => 7,
+        PrintConv => \%cropHiSpeed,
+    },
     0x200001e => {
         Name => 'ColorSpace',
@@ -4633,17 +9062,91 @@
         },
     },
-    0x2000023 => {
-        Name => 'PictureControlData',
-        Binary => 1,
-        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::PictureControl' },
-    },
+    0x200001f => {
+        Name => 'VRInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::VRInfo' },
+    },
+    0x2000022 => {
+        Name => 'ActiveD-Lighting',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            3 => 'Normal',
+            5 => 'High',
+            7 => 'Extra High',
+            8 => 'Extra High 1',
+            9 => 'Extra High 2',
+            10 => 'Extra High 3',
+            11 => 'Extra High 4',
+            0xffff => 'Auto',
+        },
+    },
+    0x2000023 => [
+        { #PH (D300, but also found in D3,D3S,D3X,D90,D300S,D700,D3000,D5000)
+            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 => {
         Name => 'WorldTime',
         SubDirectory => { TagTable => 'Image::ExifTool::Nikon::WorldTime' },
     },
-    0x2000032 => {
+    0x2000025 => { #34
+        Name => 'ISOInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::ISOInfo',
+            ByteOrder => 'BigEndian', # (BigEndian even for D810, which is a little-endian camera)
+        },
+    },
+    0x200002a => { #23 (this tag added with D3 firmware 1.10 -- also written by Nikon utilities)
+        Name => 'VignetteControl',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            3 => 'Normal',
+            5 => 'High',
+        },
+    },
+    0x200002c => {
         Name => 'UnknownInfo',
         SubDirectory => { TagTable => 'Image::ExifTool::Nikon::UnknownInfo' },
     },
+    # 0x200002d - int16u[3]: "512 0 0"
+    0x2000032 => {
+        Name => 'UnknownInfo2',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::UnknownInfo2' },
+    },
+    0x2000039 => {
+        Name => 'LocationInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LocationInfo' },
+    },
+    # 0x200003f - rational64s[2]: "0 0"
+    # 0x2000042 - undef[6]: "0100\x03\0"
+    # 0x2000043 - undef[12]: all zeros
     0x2000083 => {
         Name => 'LensType',
@@ -4655,7 +9158,14 @@
                 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 $_;
         ],
     },
@@ -4665,4 +9175,166 @@
         PrintConv => \&Image::ExifTool::Exif::PrintLensInfo,
     },
+    0x2000087 => {
+        Name => 'FlashMode',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Did Not Fire',
+            1 => 'Fired, Manual', #14
+            3 => 'Not Ready', #28
+            7 => 'Fired, External', #14
+            8 => 'Fired, Commander Mode',
+            9 => 'Fired, TTL Mode',
+            18 => 'LED Light', #G.F. (movie LED light)
+        },
+    },
+    0x2000098 => [
+        { #8
+            Condition => '$$valPt =~ /^0100/', # D100, D1X - PH
+            Name => 'LensData0100',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensData00' },
+        },
+        { #8
+            Condition => '$$valPt =~ /^0101/', # D70, D70s - PH
+            Name => 'LensData0101',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::LensData01' },
+        },
+        # note: this information is encrypted if the version is 02xx
+        { #8
+            # 0201 - D200, D2Hs, D2X and D2Xs
+            # 0202 - D40, D40X and D80
+            # 0203 - D300
+            Condition => '$$valPt =~ /^020[1-3]/',
+            Name => 'LensData0201',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::LensData01',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 4,
+            },
+        },
+        { #PH
+            Condition => '$$valPt =~ /^0204/', # D90, D7000
+            Name => 'LensData0204',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::LensData0204',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 4,
+            },
+        },
+        {
+            Condition => '$$valPt =~ /^040[01]/', # 0=1J1/1V1, 1=1J2
+            Name => 'LensData0400',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Nikon::LensData0400',
+                ProcessProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                WriteProc => \&Image::ExifTool::Nikon::ProcessNikonEncrypted,
+                DecryptStart => 4,
+            },
+        },
+        {
+            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 =~ /^080[01]/', # 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,
+            },
+        },
+    ],
+    0x20000a7 => { # Number of shots taken by camera so far (ref 2)
+        Name => 'ShutterCount',
+        PrintConv => '$val == 4294965247 ? "n/a" : $val',
+    },
+    0x20000a8 => [
+        {
+            Name => 'FlashInfo0100',
+            Condition => '$$valPt =~ /^010[01]/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0100' },
+        },
+        {
+            Name => 'FlashInfo0102',
+            Condition => '$$valPt =~ /^0102/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0102' },
+        },
+        {
+            Name => 'FlashInfo0103',
+            # (0104 for D7000, 0105 for D800)
+            Condition => '$$valPt =~ /^010[345]/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0103' },
+        },
+        {
+            Name => 'FlashInfo0106', # (0106 for D7100)
+            Condition => '$$valPt =~ /^0106/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0106' },
+        },
+        {
+            Name => 'FlashInfo0107', # (0107 for D4S/D750/D810/D5500/D7200, 0108 for D5/D500/D3400)
+            Condition => '$$valPt =~ /^010[78]/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfo0107' },
+        },
+        {
+            Name => 'FlashInfoUnknown',
+            SubDirectory => { TagTable => 'Image::ExifTool::Nikon::FlashInfoUnknown' },
+        },
+    ],
+    0x20000ab => { Name => 'VariProgram', Writable => 'string' }, #2 (scene mode for DSLR's - PH)
+    0x20000b1 => { #34
+        Name => 'HighISONoiseReduction',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Minimal', # for high ISO (>800) when setting is "Off"
+            2 => 'Low',     # Low,Normal,High take effect for ISO > 400
+            3 => 'Medium Low',
+            4 => 'Normal',
+            5 => 'Medium High',
+            6 => 'High',
+        },
+    },
+    0x20000b7 => {
+        Name => 'AFInfo2',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::AFInfo2' },
+    },
+    # 0x20000c0 - undef[8]
+    0x20000c3 => {
+        Name => 'BarometerInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::BarometerInfo',
+            # (little-endian in II EXIF, big-endian in MOV)
+        },
+    },
 );
 
@@ -4671,5 +9343,4 @@
     GROUPS => { 2 => 'Camera' },
     LensSpec => {
-        Description => 'Lens',
         Require => {
             0 => 'Nikon:Lens',
@@ -4692,5 +9363,5 @@
         },
         # construct lens ID string as per ref 11
-        ValueConv => 'uc(join(" ",(unpack("H*",pack("C*",@raw)) =~ /../g)))',
+        ValueConv => 'sprintf("%.2X"." %.2X"x7, @raw)',
         PrintConv => \%nikonLensIDs,
     },
@@ -4714,9 +9385,9 @@
 sub ProcessNikonAVI($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart} || 0;
     my $dirEnd = $pos + $$dirInfo{DirLen};
-    $exifTool->VerboseDir($dirInfo, undef, $$dirInfo{DirLen});
+    $et->VerboseDir($dirInfo, undef, $$dirInfo{DirLen});
     SetByteOrder('II');
     while ($pos + 4 <= $dirEnd) {
@@ -4725,5 +9396,5 @@
         $pos += 4;
         last if $pos + $size > $dirEnd;
-        $exifTool->HandleTag($tagTablePtr, $tag, undef,
+        $et->HandleTag($tagTablePtr, $tag, undef,
             DataPt => $dataPt,
             Start  => $pos,
@@ -4734,40 +9405,138 @@
     return 1;
 }
+
 #------------------------------------------------------------------------------
-# Print D3/D300 AF points (similar to Canon::PrintAFPoints1D)
-# Inputs: 0) value to convert (undef[7])
-# Focus point pattern:
-#        A1  A2  A3  A4  A5  A6  A7  A8  A9
-#    B1  B2  B3  B4  B5  B6  B7  B8  B9  B10  B11
-#    C1  C2  C3  C4  C5  C6  C7  C8  C9  C10  C11
-#    D1  D2  D3  D4  D5  D6  D7  D8  D9  D10  D11
-#        E1  E2  E3  E4  E5  E6  E7  E8  E9
-sub PrintAFPointsD3($)
+# Print conversion for Nikon AF points
+# Inputs: 0) value to convert (as a string of hex bytes),
+#         1) lookup for AF point bit number (starting at 1)
+sub PrintAFPoints($$)
 {
-    my $val = shift;
-    return 'Unknown' unless length $val == 7;
-    # list of byte/bit positions for each focus point (upper/lower nibble)
-    my @focusPts = (
-             0x55,0x50,0x43,0x14,0x02,0x07,0x21,0x26,0x33,
-        0x61,0x54,0x47,0x42,0x13,0x01,0x06,0x20,0x25,0x32,0x37,
-        0x60,0x53,0x46,0x41,0x12,0x00,0x05,0x17,0x24,0x31,0x36,
-        0x62,0x56,0x51,0x44,0x15,0x03,0x10,0x22,0x27,0x34,0x40,
-             0x57,0x52,0x45,0x16,0x04,0x11,0x23,0x30,0x35
-    );
-    my ($focusPt, @points);
-    my @dat = unpack('C*', $val);
-    my @cols = (9,11,11,11,9);
-    my $cols = shift @cols;
-    my ($row, $col) = ('A', 1);
-    foreach $focusPt (@focusPts) {
-        push @points, $row . $col if $dat[$focusPt >> 4] & (0x01 << ($focusPt & 0x0f));
-        if (++$col > $cols) {
-            $cols = shift @cols;
-            $col = 1;
-            ++$row;
+    my ($val, $afPoints) = @_;
+    my ($i, $j, @points);
+    $val =~ tr/ //d;    # remove spaces from hex string
+    my @dat = unpack 'C*', pack 'H*', $val; # convert to array of bytes
+    # loop through all bytes to find active AF points
+    for ($i=0; $i<=@dat; ++$i) {
+        next unless $dat[$i];
+        for ($j=0; $j<8; ++$j) {
+            next unless $dat[$i] & (1 << $j);
+            my $point = $$afPoints{$i*8 + $j + 1};
+            push @points, $point if defined $point;
         }
     }
     return '(none)' unless @points;
-    return join(',',@points);
+    # sort the points and return as comma-separated string
+    return join ',', sort {
+        return $a cmp $b if length($a) == length($b);
+        return substr($a,0,1).'0'.substr($a,1,1) cmp $b if length($a) == 2;
+        return $a cmp substr($b,0,1).'0'.substr($b,1,1);
+    } @points;
+}
+
+#------------------------------------------------------------------------------
+# Inverse print conversion for AF points
+# Inputs: 0) AF point string, 1) AF point lookup
+# Returns: AF point data as a string of hex bytes
+sub PrintAFPointsInv($$)
+{
+    my ($val, $afPoints) = @_;
+    my @points = ($val =~ /[A-Za-z]\d+/g);
+    my $size = int((scalar(keys %$afPoints) + 7) / 8);
+    my @dat = (0) x $size;
+    if (@points) {
+        my (%bitNum, $point);
+        $bitNum{$$afPoints{$_}} = $_ foreach keys %$afPoints; # build reverse lookup
+        foreach $point (@points) {
+            my $bitNum = $bitNum{uc $point} or next;
+            my $byte = int(($bitNum - 1) / 8);
+            $dat[$byte] |= (1 << (($bitNum - 1) % 8));
+        }
+    }
+    return join(" ", unpack("H2"x$size, pack('C*', @dat)));
+}
+
+#------------------------------------------------------------------------------
+# Get AF point name for grid-type AF
+# Inputs: 0) AF point number, 1) number of columns, 2) true for inverse conversion
+# Returns: AF point name, or undef
+sub GetAFPointGrid($$;$)
+{
+    my ($val, $ncol, $inv) = @_;
+    if ($inv) {
+        return undef unless $val =~ /^([A-J])(\d+)$/i;
+        return (ord(uc($1))-65) * $ncol + $2 - 1;
+    } else {
+        my $row = int(($val + 0.5) / $ncol);
+        my $col = $val - $ncol * $row + 1;
+        return chr(65+$row) . $col;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Print conversion for grid-type AF points
+# Inputs: 0) value to convert (as a string of hex bytes),
+#         1) number of columns in grid
+sub PrintAFPointsGrid($$)
+{
+    my ($val, $ncol) = @_;
+    my ($i, $j, @points);
+    $val =~ tr/ //d;    # remove spaces from hex string
+    my @dat = unpack 'C*', pack 'H*', $val; # convert to array of bytes
+    # loop through all bytes to find active AF points
+    for ($i=0; $i<@dat; ++$i) {
+        next unless $dat[$i];
+        for ($j=0; $j<8; ++$j) {
+            next unless $dat[$i] & (1 << $j);
+            my $point = GetAFPointGrid($i*8 + $j, $ncol);
+            push @points, $point if defined $point;
+        }
+    }
+    return '(none)' unless @points;
+    return join ',', @points;   # return as comma-separated string
+}
+
+#------------------------------------------------------------------------------
+# Inverse print conversion for AF points
+# Inputs: 0) AF point string, 1) number of columns, 2) size of data
+# Returns: AF point data as a string of hex bytes
+sub PrintAFPointsGridInv($$$)
+{
+    my ($val, $ncol, $size) = @_;
+    my @points = ($val =~ /[A-Za-z]\d+/g);
+    my @dat = (0) x $size;
+    foreach (@points) {
+        my $n = GetAFPointGrid($_, $ncol, 1);
+        next unless defined $n;
+        my $byte = int($n / 8);
+        next if $byte > $size;
+        $dat[$byte] |= (1 << ($n - $byte * 8));
+    }
+    return join(" ", unpack("H2"x$size, pack('C*', @dat)));
+}
+
+#------------------------------------------------------------------------------
+# Print conversion for relative Left/Right AF points (ref 28)
+# Inputs: 0) column, 1) number of columns
+# Returns: AF point data as a string (e.g. '2L' or 'C' or '3R')
+sub PrintAFPointsLeftRight($$)
+{
+    my ($col, $ncol) = @_;
+    my $center = 1 + ($ncol + 1)/2;
+    return 'C' if $col == $center;
+    return sprintf('%d', $center - $col) . 'L of Center' if $col < $center;
+    return sprintf('%d', $col - $center) . 'R of Center' if $col > $center;
+}
+
+#------------------------------------------------------------------------------
+# Print conversion for relative Up/Down AF points (ref 28)
+# Inputs: 0) column, 1) number of columns
+# Returns: AF point data as a string (e.g. '2U' or 'C' or '3D')
+sub PrintAFPointsUpDown($$)
+{
+    my ($row, $nrow) = @_;
+    my $center = 1 + ($nrow + 1)/2;
+    return 'C' if $row == $center;
+    return sprintf('%d', $center - $row) . 'U from Center' if $row < $center;
+    return sprintf('%d', $row - $center) . 'D from Center' if $row > $center;
 }
 
@@ -4776,9 +9545,9 @@
 # Inputs: 0) value (with 0x80 subtracted),
 #         1) 'Normal' (0 value) string (default 'Normal')
-#         2) format string for numbers (default '%+d')
+#         2) format string for numbers (default '%+d'), 3) v2 divisor
 # Returns: PrintConv value
-sub PrintPC($;$$)
+sub PrintPC($;$$$)
 {
-    my ($val, $norm, $fmt) = @_;
+    my ($val, $norm, $fmt, $div) = @_;
     return $norm || 'Normal' if $val == 0;
     return 'n/a'             if $val == 0x7f;
@@ -4786,16 +9555,16 @@
     # -127 = custom curve created in Camera Control Pro (show as "User" by D3) - ref 28
     return 'User'            if $val == -127; #28
-    return sprintf($fmt || '%+d', $val);
+    return sprintf($fmt || '%+d', $val / ($div || 1));
 }
 
 #------------------------------------------------------------------------------
 # Inverse of PrintPC
-# Inputs: 0) PrintConv value (after subracting 0x80 from raw value)
+# Inputs: 0) PrintConv value (after subracting 0x80 from raw value), 1) v2 divisor
 # Returns: unconverted value
 # Notes: raw values: 0=Auto, 1=User, 0xff=n/a, ... 0x7f=-1, 0x80=0, 0x81=1, ...
-sub PrintPCInv($)
+sub PrintPCInv($;$)
 {
-    my $val = shift;
-    return $val if $val =~ /^[-+]?\d+$/;
+    my ($val, $div) = @_;
+    return $val * ($div || 1) if $val =~ /^[-+]?\d+(\.\d+)?$/;
     return 0x7f if $val =~ /n\/a/i;
     return -128 if $val =~ /auto/i;
@@ -4825,9 +9594,25 @@
         return join(' or ', @vals);
     }
-    my $regex = $val;
-    # Sigma has been changing the LensID on some new lenses
-    $regex =~ s/^\w+/../;
-    my @ids = sort grep /^$regex$/, keys %$conv;
-    return "Unknown ($val) $$conv{$ids[0]} ?" if @ids;
+    # 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+/.. ../;  # 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 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;
 }
@@ -4854,5 +9639,5 @@
                 # patch for a number of models that write improper string
                 # terminator for ImageStabilization (VR-OFF, VR-ON)
-                $str =~ s/  +.$//
+                $str =~ s/  +.$//s;
             }
             if ($str =~ s/\b([A-Z])([A-Z]*[AEIOUY][A-Z]*)/$1\L$2/g) {
@@ -4901,5 +9686,5 @@
 );
 
-# decrypt Nikon data block (ref 4)
+# Decrypt Nikon data block (ref 4)
 # Inputs: 0) reference to data block, 1) serial number key, 2) shutter count key
 #         4) optional start offset (default 0)
@@ -4912,5 +9697,6 @@
 
     $start or $start = 0;
-    $len = length($$dataPt) - $start if not defined $len or $len > length($$dataPt) - $start;
+    my $maxLen = length($$dataPt) - $start;
+    $len = $maxLen if not defined $len or $len > $maxLen;
     return $$dataPt if $len <= 0;
     my $key = 0;
@@ -4939,8 +9725,8 @@
 sub SerialKey($$)
 {
-    my ($exifTool, $serial) = @_;
+    my ($et, $serial) = @_;
     # use serial number as key if integral
     return $serial if not defined $serial or $serial =~ /^\d+$/;
-    return 0x22 if $$exifTool{Model} =~ /\bD50$/; # D50 (ref 8)
+    return 0x22 if $$et{Model} =~ /\bD50$/; # D50 (ref 8)
     return 0x60; # D200 (ref 10), D40X (ref PH), etc
 }
@@ -4952,34 +9738,48 @@
 sub ProcessNikonMOV($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos};
-    my $pos = $$dirInfo{DirStart};
-    my $end = $pos + $$dirInfo{DirLen};
-    $exifTool->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) {
-            $exifTool->Warn(sprintf("Unknown format ($fmt) for $$dirInfo{DirName} tag 0x%x",$tag));
-            last;
+    my %needTags = ( 0x110a431 => 0, 0x20000a7 => undef );  # needed for decryption
+    $et->VerboseDir($$dirInfo{DirName}, 0, $$dirInfo{DirLen});
+    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 $size = $count * $Image::ExifTool::Exif::formatSize[$fmt];
-        if ($pos + $size > $end) {
-            $exifTool->Warn(sprintf("Truncated data for $$dirInfo{DirName} tag 0x%x",$tag));
-            last;
-        }
-        my $val = ReadValue($dataPt, $pos, $fmtStr, $count, $size);
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
-            DataPt  => $dataPt,
-            DataPos => $dataPos,
-            Format  => $fmtStr,
-            Start   => $pos,
-            Size    => $size,
-        );
-        $pos += $size;  # is this padded to an even offset????
     }
     return 1;
@@ -4992,46 +9792,53 @@
 sub ProcessNikonEncrypted($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access
-    my $serial = $$exifTool{NikonSerialKey};
-    my $count = $$exifTool{NikonCountKey};
-    unless (defined $serial and defined $count) {
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access
+    my $serial = $$et{NikonSerialKey};
+    my $count = $$et{NikonCountKey};
+    unless (defined $serial and defined $count and $serial =~ /^\d+$/ and $count =~ /^\d+$/) {
         if (defined $serial or defined $count) {
-            my $missing = defined $serial ? 'ShutterCount' : 'SerialNumber';
-            $exifTool->Warn("Can't decrypt Nikon information (no $missing key)");
+            my $msg;
+            if (defined $serial and defined $count) {
+                $msg = $serial =~ /^\d+$/ ? 'invalid ShutterCount' : 'invalid SerialNumber';
+            } else {
+                $msg = defined $serial ? 'no ShutterCount' : 'no SerialNumber';
+            }
+            $et->Warn("Can't decrypt Nikon information ($msg key)");
         }
-        delete $$exifTool{NikonSerialKey};
-        delete $$exifTool{NikonCountKey};
+        delete $$et{NikonSerialKey};
+        delete $$et{NikonCountKey};
         return 0;
     }
-    my $verbose = $$dirInfo{IsWriting} ? 0 : $exifTool->Options('Verbose');
+    my $verbose = $$dirInfo{IsWriting} ? 0 : $et->Options('Verbose');
     my $tagInfo = $$dirInfo{TagInfo};
-    my $data = substr(${$$dirInfo{DataPt}}, $$dirInfo{DirStart}, $$dirInfo{DirLen});
-
-    my ($start, $len, $offset, $byteOrder, $recrypt, $newSerial, $newCount);
+    my $dirStart = $$dirInfo{DirStart};
+    my $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen});
+
+    my ($start, $len, $more, $offset, $byteOrder, $recrypt, $newSerial, $newCount);
 
     # must re-encrypt when writing if serial number or shutter count changes
     if ($$dirInfo{IsWriting}) {
-        if ($$exifTool{NewNikonSerialKey}) {
-            $newSerial = $$exifTool{NewNikonSerialKey};
+        if ($$et{NewNikonSerialKey}) {
+            $newSerial = $$et{NewNikonSerialKey};
             $recrypt = 1;
         }
-        if ($$exifTool{NewNikonCountKey}) {
-            $newCount = $$exifTool{NewNikonCountKey};
+        if ($$et{NewNikonCountKey}) {
+            $newCount = $$et{NewNikonCountKey};
             $recrypt = 1;
         }
     }
     if ($tagInfo and $$tagInfo{SubDirectory}) {
-        $start = $tagInfo->{SubDirectory}->{DecryptStart};
+        $start = $$tagInfo{SubDirectory}{DecryptStart};
         # may decrypt only part of the information to save time
-        if ($verbose < 3 and $exifTool->Options('Unknown') < 2 and not $recrypt) {
-            $len = $tagInfo->{SubDirectory}->{DecryptLen};
+        if ($verbose < 3 and $et->Options('Unknown') < 2 and not $recrypt) {
+            $len = $$tagInfo{SubDirectory}{DecryptLen};
+            $more = $$tagInfo{SubDirectory}{DecryptMore};
         }
-        $offset = $tagInfo->{SubDirectory}->{DirOffset};
-        $byteOrder = $tagInfo->{SubDirectory}->{ByteOrder};
+        $offset = $$tagInfo{SubDirectory}{DirOffset};
+        $byteOrder = $$tagInfo{SubDirectory}{ByteOrder};
     }
     $start or $start = 0;
     if (defined $offset) {
-        # offset, if specified, is releative to start of encrypted data
+        # offset, if specified, is relative to start of encrypted data
         $offset += $start;
     } else {
@@ -5040,13 +9847,32 @@
     my $maxLen = length($data) - $start;
     # decrypt all the data unless DecryptLen is given
-    $len = $maxLen unless $len and $len <= $maxLen;
+    unless ($len and $len < $maxLen) {
+        $len = $maxLen;
+        undef $more;    # (can't decrypt more than this)
+    }
 
     $data = Decrypt(\$data, $serial, $count, $start, $len);
 
+    # set appropriate byte ordering before evaluating DecryptMore
+    my $oldOrder = GetByteOrder();
+    SetByteOrder($byteOrder) if $byteOrder;
+
+    if ($more) {
+        #### eval DecryptMore ($data)
+        my $moreLen = eval $more;
+        $moreLen = $maxLen if $moreLen > $maxLen;
+        # re-decrypt with new length
+        if ($len < $moreLen) {
+            $len = $moreLen;
+            $data = substr(${$$dirInfo{DataPt}}, $dirStart, $$dirInfo{DirLen});
+            $data = Decrypt(\$data, $serial, $count, $start, $len);
+        }
+    }
     if ($verbose > 2) {
-        $exifTool->VerboseDir("Decrypted $$tagInfo{Name}");
-        $exifTool->VerboseDump(\$data,
-            Prefix  => $exifTool->{INDENT} . '  ',
-            DataPos => $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base} || 0),
+        $et->VerboseDir("Decrypted $$tagInfo{Name}");
+        $et->VerboseDump(\$data,
+            Prefix  => $$et{INDENT} . '  ',
+            # (remove this because it is useful to have decrypted offsets start at 0)
+            #DataPos => $dirStart + $$dirInfo{DataPos} + ($$dirInfo{Base} || 0),
         );
     }
@@ -5057,20 +9883,18 @@
         DirLen   => length($data) - $offset,
         DirName  => $$dirInfo{DirName},
-        DataPos  => $$dirInfo{DataPos} + $$dirInfo{DirStart},
+        DataPos  => $$dirInfo{DataPos} + $dirStart,
         Base     => $$dirInfo{Base},
     );
     my $rtnVal;
-    my $oldOrder = GetByteOrder();
-    SetByteOrder($byteOrder) if $byteOrder;
     if ($$dirInfo{IsWriting}) {
-        my $changed = $$exifTool{CHANGED};
-        $rtnVal = $exifTool->WriteBinaryData(\%subdirInfo, $tagTablePtr);
+        my $changed = $$et{CHANGED};
+        $rtnVal = $et->WriteBinaryData(\%subdirInfo, $tagTablePtr);
         # must re-encrypt if serial number or shutter count changes
         if ($recrypt) {
             $serial = $newSerial if defined $newSerial;
             $count = $newCount if defined $newCount;
-            ++$$exifTool{CHANGED};
+            ++$$et{CHANGED};
         }
-        if ($changed == $$exifTool{CHANGED}) {
+        if ($changed == $$et{CHANGED}) {
             undef $rtnVal;  # nothing changed so use original data
         } else {
@@ -5081,5 +9905,5 @@
         }
     } else {
-        $rtnVal = $exifTool->ProcessBinaryData(\%subdirInfo, $tagTablePtr);
+        $rtnVal = $et->ProcessBinaryData(\%subdirInfo, $tagTablePtr);
     }
     SetByteOrder($oldOrder);
@@ -5093,5 +9917,5 @@
 sub PrescanExif($$$)
 {
-    my ($exifTool, $dirInfo, $tagHash) = @_;
+    my ($et, $dirInfo, $tagHash) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos} || 0;
@@ -5122,10 +9946,8 @@
         $dirStart = 0;
     }
-    # loop through necessary IFD entries
-    my ($lastTag) = sort { $b <=> $a } keys %$tagHash; # (reverse sort)
+    # loop through Nikon MakerNote IFD entries
     for ($index=0; $index<$numEntries; ++$index) {
         my $entry = $dirStart + 2 + 12 * $index;
         my $tagID = Get16u($dataPt, $entry);
-        last if $tagID > $lastTag;  # (assuming tags are in order)
         next unless exists $$tagHash{$tagID};   # only extract required tags
         my $format = Get16u($dataPt, $entry+2);
@@ -5159,11 +9981,11 @@
 sub ProcessNikonCaptureEditVersions($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     require Image::ExifTool::NikonCapture;
-    return Image::ExifTool::NikonCapture::ProcessNikonCaptureEditVersions($exifTool, $dirInfo, $tagTablePtr);
+    return Image::ExifTool::NikonCapture::ProcessNikonCaptureEditVersions($et, $dirInfo, $tagTablePtr);
 }
 
 #------------------------------------------------------------------------------
-# process Nikon Capture Offsets IFD (ref PH)
+# Process Nikon Capture Offsets IFD (ref PH)
 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
 # Returns: 1 on success
@@ -5171,5 +9993,5 @@
 sub ProcessNikonCaptureOffsets($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
@@ -5179,6 +10001,6 @@
     my $count = Get16u($dataPt, $dirStart);
     return 0 unless $count and $count * 12 + 2 <= $dirLen;
-    if ($exifTool->Options('Verbose')) {
-        $exifTool->VerboseDir('NikonCaptureOffsets', $count);
+    if ($et->Options('Verbose')) {
+        $et->VerboseDir('NikonCaptureOffsets', $count);
     }
     my $index;
@@ -5187,5 +10009,5 @@
         my $tagID = Get32u($dataPt, $pos);
         my $value = Get32u($dataPt, $pos + 4);
-        $exifTool->HandleTag($tagTablePtr, $tagID, $value,
+        $et->HandleTag($tagTablePtr, $tagID, $value,
             Index  => $index,
             DataPt => $dataPt,
@@ -5198,5 +10020,5 @@
 
 #------------------------------------------------------------------------------
-# Read/write Nikon Makernotes directory
+# Read/write Nikon MakerNotes directory
 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
 # Returns: 1 on success, otherwise returns 0 and sets a Warning when reading
@@ -5204,12 +10026,12 @@
 sub ProcessNikon($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access
 
     # pre-scan IFD to get SerialNumber (0x001d) and ShutterCount (0x00a7) for use in decryption
     my %needTags = ( 0x001d => 0, 0x00a7 => undef );
-    PrescanExif($exifTool, $dirInfo, \%needTags);
-    $$exifTool{NikonSerialKey} = SerialKey($exifTool, $needTags{0x001d});
-    $$exifTool{NikonCountKey} = $needTags{0x00a7};
+    PrescanExif($et, $dirInfo, \%needTags);
+    $$et{NikonSerialKey} = SerialKey($et, $needTags{0x001d});
+    $$et{NikonCountKey} = $needTags{0x00a7};
 
     # process Nikon makernotes
@@ -5217,16 +10039,16 @@
     if ($$dirInfo{IsWriting}) {
         # get new decryptino keys if they are being changed
-        my $serial = $exifTool->GetNewValues($Image::ExifTool::Nikon::Main{0x001d});
-        my $count = $exifTool->GetNewValues($Image::ExifTool::Nikon::Main{0x00a7});
-        $$exifTool{NewNikonSerialKey} = SerialKey($exifTool, $serial);
-        $$exifTool{NewNikonCountKey} = $count;
-        $rtnVal = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
-        delete $$exifTool{NewNikonSerialKey};
-        delete $$exifTool{NewNikonCountKey};
+        my $serial = $et->GetNewValue($Image::ExifTool::Nikon::Main{0x001d});
+        my $count = $et->GetNewValue($Image::ExifTool::Nikon::Main{0x00a7});
+        $$et{NewNikonSerialKey} = SerialKey($et, $serial);
+        $$et{NewNikonCountKey} = $count;
+        $rtnVal = Image::ExifTool::Exif::WriteExif($et, $dirInfo, $tagTablePtr);
+        delete $$et{NewNikonSerialKey};
+        delete $$et{NewNikonCountKey};
     } else {
-        $rtnVal = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+        $rtnVal = Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
     }
-    delete $$exifTool{NikonSerialKey};
-    delete $$exifTool{NikonCountKey};
+    delete $$et{NikonSerialKey};
+    delete $$et{NikonCountKey};
     return $rtnVal;
 }
@@ -5251,5 +10073,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -5271,4 +10093,6 @@
 
 =item L<http://www.wohlberg.net/public/software/photo/nstiffexif/>
+
+=item (...plus lots of testing with Best Buy store demos!)
 
 =back
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonCapture.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonCapture.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonCapture.pm	(revision 34921)
@@ -9,4 +9,5 @@
 #
 # References:   1) http://www.cybercom.net/~dcoffin/dcraw/
+#               IB) Iliah Borg private communication (LibRaw)
 #------------------------------------------------------------------------------
 
@@ -18,5 +19,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.07';
+$VERSION = '1.14';
 
 sub ProcessNikonCapture($$$);
@@ -94,4 +95,9 @@
     },
     # 0x3e726567 added when I rotated by 90 degrees
+    0x416391c6 => {
+        Name => 'QuickFix',
+        Writable => 'int8u',
+        PrintConv => \%offOn,
+    },
     0x56a54260 => {
         Name => 'Exposure',
@@ -166,4 +172,5 @@
         },
     },
+  # 0x88f55e48 - related to QuickFix
     0x890ff591 => {
         Name => 'D-LightingHQData',
@@ -184,5 +191,5 @@
         },
     },
-  # 0xa7264a72, 0x88f55e48 and 0x416391c6 all change from 0 to 1 when QuickFix is turned on
+  # 0xa7264a72 - related to QuickFix
     0xab5eca5e => {
         Name => 'PhotoEffects',
@@ -347,21 +354,38 @@
             2 => 'Recorded Value',
             3 => 'Use Temperature',
-            4 => 'Calculate Automatically'
-        },
-    },
-    0x14 => {
-        Name => 'WBAdjLightingSubtype',
-        # this varies for different lighting types
-        # (ie. for Daylight, this is 0 => 'Direct', 1 => 'Shade', 2 => 'Cloudy')
-    },
-    0x15 => {
+            4 => 'Calculate Automatically',
+            5 => 'Auto2', #IB
+            6 => 'Underwater', #IB
+            7 => 'Auto1',
+        },
+    },
+    0x14 => { #IB
         Name => 'WBAdjLighting',
+        Format => 'int16u',
+        PrintHex => 1,
         PrintConv => {
-            0 => 'None',
-            1 => 'Incandescent',
-            2 => 'Daylight',
-            3 => 'Standard Fluorescent',
-            4 => 'High Color Rendering Fluorescent',
-            5 => 'Flash',
+            0x000 => 'None',
+            0x100 => 'Incandescent',
+            0x200 => 'Daylight (direct sunlight)',
+            0x201 => 'Daylight (shade)',
+            0x202 => 'Daylight (cloudy)',
+            0x300 => 'Standard Fluorescent (warm white)',
+            0x301 => 'Standard Fluorescent (3700K)',
+            0x302 => 'Standard Fluorescent (cool white)',
+            0x303 => 'Standard Fluorescent (5000K)',
+            0x304 => 'Standard Fluorescent (daylight)',
+            0x305 => 'Standard Fluorescent (high temperature mercury vapor)',
+            0x400 => 'High Color Rendering Fluorescent (warm white)',
+            0x401 => 'High Color Rendering Fluorescent (3700K)',
+            0x402 => 'High Color Rendering Fluorescent (cool white)',
+            0x403 => 'High Color Rendering Fluorescent (5000K)',
+            0x404 => 'High Color Rendering Fluorescent (daylight)',
+            0x500 => 'Flash',
+            0x501 => 'Flash (FL-G1 filter)',
+            0x502 => 'Flash (FL-G2 filter)',
+            0x503 => 'Flash (TN-A1 filter)',
+            0x504 => 'Flash (TN-A2 filter)',
+            0x600 => 'Sodium Vapor Lamps',
+            # 0x1002 => seen for WBAdjMode modes of Underwater and Calculate Automatically
         },
     },
@@ -462,4 +486,5 @@
             0 => 'Faster',
             1 => 'Better Quality',
+            2 => 'Better Quality 2013',
         },
     },
@@ -640,5 +665,5 @@
         Format => 'double',
         PrintConv => 'sprintf("%.4f", $val)',
-        PrintConvInvn => '$val',
+        PrintConvInv => '$val',
     },
     0x24 => {
@@ -655,4 +680,6 @@
             4 => 'High',
             6 => 'Extra High',
+            7 => 'Extra High 1',
+            8 => 'Extra High 2',
         },
     },
@@ -679,9 +706,9 @@
 sub WriteNikonCapture($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
 
     # no need to edit this information unless necessary
-    unless ($exifTool->{EDIT_DIRS}->{MakerNotes} or $exifTool->{EDIT_DIRS}->{IPTC}) {
+    unless ($$et{EDIT_DIRS}{MakerNotes} or $$et{EDIT_DIRS}{IPTC}) {
         return undef;
     }
@@ -690,5 +717,5 @@
     my $dirLen = $$dirInfo{DirLen};
     if ($dirLen < 22) {
-        $exifTool->Warn('Short Nikon Capture Data',1);
+        $et->Warn('Short Nikon Capture Data',1);
         return undef;
     }
@@ -696,9 +723,9 @@
     SetByteOrder('II');
     my $tagID = Get32u($dataPt, $dirStart);
-    # sometimes size includes 18 header bytes, and other times it doesn't (ie. ViewNX 2.1.1)
+    # sometimes size includes 18 header bytes, and other times it doesn't (eg. ViewNX 2.1.1)
     my $size = Get32u($dataPt, $dirStart + 18);
-    my $pad = $dirLen - $size - 18; 
+    my $pad = $dirLen - $size - 18;
     unless ($tagID == 0x7a86a940 and ($pad >= 0 or $pad == -18)) {
-        $exifTool->Warn('Unrecognized Nikon Capture Data header');
+        $et->Warn('Unrecognized Nikon Capture Data header');
         return undef;
     }
@@ -712,5 +739,5 @@
     my $outBuff = '';
     my $pos;
-    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+    my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
     my $dirEnd = $dirStart + $dirLen;
 
@@ -720,5 +747,5 @@
         $size = Get32u($dataPt, $pos + 18) - 4;
         last if $size < 0 or $pos + 22 + $size > $dirEnd;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
         if ($tagInfo) {
             my $newVal;
@@ -732,23 +759,23 @@
                 my $subTable = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
                 # ignore minor errors in IPTC since there is typically trailing garbage
-                my $oldSetting = $exifTool->Options('IgnoreMinorErrors');
-                $$tagInfo{Name} =~ /IPTC/ and $exifTool->Options(IgnoreMinorErrors => 1);
+                my $oldSetting = $et->Options('IgnoreMinorErrors');
+                $$tagInfo{Name} =~ /IPTC/ and $et->Options(IgnoreMinorErrors => 1);
                 # rewrite the directory
-                $newVal = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
+                $newVal = $et->WriteDirectory(\%subdirInfo, $subTable);
                 # restore our original options
-                $exifTool->Options(IgnoreMinorErrors => $oldSetting);
+                $et->Options(IgnoreMinorErrors => $oldSetting);
             } elsif ($$newTags{$tagID}) {
                 # get new value for this tag if we are writing it
                 my $format = $$tagInfo{Format} || $$tagInfo{Writable};
                 my $oldVal = ReadValue($dataPt,$pos+22,$format,1,$size);
-                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-                if (Image::ExifTool::IsOverwriting($nvHash, $oldVal)) {
-                    my $val = $exifTool->GetNewValues($tagInfo);
+                my $nvHash = $et->GetNewValueHash($tagInfo);
+                if ($et->IsOverwriting($nvHash, $oldVal)) {
+                    my $val = $et->GetNewValue($tagInfo);
                     $newVal = WriteValue($val, $$tagInfo{Writable}) if defined $val;
                     if (defined $newVal and length $newVal) {
-                        ++$exifTool->{CHANGED};
+                        ++$$et{CHANGED};
                     } else {
                         undef $newVal;
-                        $exifTool->Warn("Can't delete $$tagInfo{Name}");
+                        $et->Warn("Can't delete $$tagInfo{Name}");
                     }
                 }
@@ -772,5 +799,5 @@
             $outBuff .= substr($$dataPt, $pos, 4);
         } else {
-            $exifTool->Warn('Nikon Capture Data improperly terminated',1);
+            $et->Warn('Nikon Capture Data improperly terminated',1);
             return undef;
         }
@@ -788,15 +815,15 @@
 sub ProcessNikonCaptureEditVersions($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
     my $dirLen = $$dirInfo{DirLen};
     my $dirEnd = $dirStart + $dirLen;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     SetByteOrder('II');
     return 0 unless $dirLen > 4;
     my $num = Get32u($dataPt, $dirStart);
     my $pos = $dirStart + 4;
-    $verbose and $exifTool->VerboseDir('NikonCaptureEditVersions', $num);
+    $verbose and $et->VerboseDir('NikonCaptureEditVersions', $num);
     while ($num) {
         last if $pos + 4 > $dirEnd;
@@ -810,10 +837,10 @@
             DirLen   => $len,
         );
-        $$exifTool{DOC_NUM} = ++$$exifTool{DOC_COUNT};
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         --$num;
         $pos += $len + 4;
     }
-    delete $$exifTool{DOC_NUM};
+    delete $$et{DOC_NUM};
     return 1;
 }
@@ -825,13 +852,13 @@
 sub ProcessNikonCapture($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
     my $dirLen = $$dirInfo{DirLen};
     my $dirEnd = $dirStart + $dirLen;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $success = 0;
     SetByteOrder('II');
-    $verbose and $exifTool->VerboseDir('NikonCapture', 0, $dirLen);
+    $verbose and $et->VerboseDir('NikonCapture', 0, $dirLen);
     my $pos;
     for ($pos=$dirStart+22; $pos+22<$dirEnd; ) {
@@ -840,5 +867,5 @@
         $pos += 22;
         last if $size < 0 or $pos + $size > $dirEnd;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
         if ($tagInfo or $verbose) {
             my ($format, $value);
@@ -860,8 +887,10 @@
                 $value = substr($$dataPt, $pos, $size);
             }
-            $exifTool->HandleTag($tagTablePtr, $tagID, $value,
-                DataPt => $dataPt,
-                Start  => $pos,
-                Size   => $size,
+            $et->HandleTag($tagTablePtr, $tagID, $value,
+                DataPt  => $dataPt,
+                DataPos => $$dirInfo{DataPos},
+                Base    => $$dirInfo{Base},
+                Start   => $pos,
+                Size    => $size,
             ) and $success = 1;
         }
@@ -890,5 +919,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonCustom.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonCustom.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonCustom.pm	(revision 34921)
@@ -16,5 +16,9 @@
 use vars qw($VERSION);
 
-$VERSION = '1.06';
+$VERSION = '1.17';
+
+my %offOn = ( 0 => 'Off', 1 => 'On' );
+my %onOff = ( 0 => 'On', 1 => 'Off' );
+my %noYes = ( 0 => 'No', 1 => 'Yes' );
 
 # custom settings for the D80 (encrypted) - ref JD
@@ -30,16 +34,10 @@
         Name => 'Beep',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'On',
-            0x80 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     0.2 => { # CS4
         Name => 'AFAssist',
         Mask => 0x40,
-        PrintConv => {
-            0x00 => 'On',
-            0x40 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     0.3 => { # CS5
@@ -47,6 +45,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Release Locked',
-            0x20 => 'Enable Release',
+            0 => 'Release Locked',
+            1 => 'Enable Release',
         },
     },
@@ -54,24 +52,15 @@
         Name => 'ImageReview',
         Mask => 0x10,
-        PrintConv => {
-            0x00 => 'On',
-            0x10 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     0.5 => { # CS17
         Name => 'Illumination',
         Mask => 0x08,
-        PrintConv => {
-            0x00 => 'Off',
-            0x08 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     0.6 => { # CS11
         Name => 'MainDialExposureComp',
         Mask => 0x04,
-        PrintConv => {
-            0x00 => 'Off',
-            0x04 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     0.7 => { # CS10
@@ -79,6 +68,6 @@
         Mask => 0x01,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x01 => '1/2 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
         },
     },
@@ -86,8 +75,5 @@
         Name => 'AutoISO',
         Mask => 0x40,
-        PrintConv => {
-            0x00 => 'Off',
-            0x40 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     1.2 => { # CS7-a
@@ -95,8 +81,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 200,
-            0x10 => 400,
-            0x20 => 800,
-            0x30 => 1600,
+            0 => 200,
+            1 => 400,
+            2 => 800,
+            3 => 1600,
         },
     },
@@ -106,15 +92,15 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '1/125 s',
-            0x01 => '1/100 s',
-            0x02 => '1/80 s',
-            0x03 => '1/60 s',
-            0x04 => '1/40 s',
-            0x05 => '1/30 s',
-            0x06 => '1/15 s',
-            0x07 => '1/8 s',
-            0x08 => '1/4 s',
-            0x09 => '1/2 s',
-            0x0a => '1 s',
+            0 => '1/125 s',
+            1 => '1/100 s',
+            2 => '1/80 s',
+            3 => '1/60 s',
+            4 => '1/40 s',
+            5 => '1/30 s',
+            6 => '1/15 s',
+            7 => '1/8 s',
+            8 => '1/4 s',
+            9 => '1/2 s',
+            10 => '1 s',
         },
     },
@@ -123,8 +109,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'AE & Flash',
-            0x40 => 'AE Only',
-            0x80 => 'Flash Only',
-            0xc0 => 'WB Bracketing',
+            0 => 'AE & Flash',
+            1 => 'AE Only',
+            2 => 'Flash Only',
+            3 => 'WB Bracketing',
         },
     },
@@ -133,6 +119,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => '0,-,+',
-            0x20 => '-,0,+',
+            0 => '0,-,+',
+            1 => '-,0,+',
         },
     },
@@ -141,10 +127,10 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '5 s',
-            0x20 => '10 s',
-            0x40 => '20 s',
-            0x60 => '1 min',
-            0x80 => '5 min',
-            0xa0 => '10 min',
+            0 => '5 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -153,10 +139,10 @@
         Mask => 0x1c,
         PrintConv => {
-            0x00 => '4 s',
-            0x04 => '6 s',
-            0x08 => '8 s',
-            0x0c => '16 s',
-            0x10 => '30 s',
-            0x14 => '30 min',
+            0 => '4 s',
+            1 => '6 s',
+            2 => '8 s',
+            3 => '16 s',
+            4 => '30 s',
+            5 => '30 min',
         },
     },
@@ -165,8 +151,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => '2 s',
-            0x01 => '5 s',
-            0x02 => '10 s',
-            0x03 => '20 s',
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
         },
     },
@@ -175,15 +161,15 @@
         Mask => 0x1e,
         PrintConv => {
-            0x00 => 'AE/AF Lock',
-            0x02 => 'AE Lock Only',
-            0x04 => 'AF Lock Only',
-            0x06 => 'AE Lock (hold)',
-            0x08 => 'AF-ON',
-            0x0a => 'FV Lock',
-            0x0c => 'Focus Area Selection',
-            0x0e => 'AE-L/AF-L/AF Area',
-            0x10 => 'AE-L/AF Area',
-            0x12 => 'AF-L/AF Area',
-            0x14 => 'AF-ON/AF Area',
+            0 => 'AE/AF Lock',
+            1 => 'AE Lock Only',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (hold)',
+            4 => 'AF-ON',
+            5 => 'FV Lock',
+            6 => 'Focus Area Selection',
+            7 => 'AE-L/AF-L/AF Area',
+            8 => 'AE-L/AF Area',
+            9 => 'AF-L/AF Area',
+            10 => 'AF-ON/AF Area',
         },
     },
@@ -191,8 +177,5 @@
         Name => 'AELock',
         Mask => 0x01,
-        PrintConv => {
-            0x00 => 'Off',
-            0x01 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     4.3 => { # CS30
@@ -200,8 +183,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => '1 min',
-            0x40 => '5 min',
-            0x80 => '10 min',
-            0xc0 => '15 min',
+            0 => '1 min',
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
         },
     },
@@ -210,6 +193,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => 'Standard (Main Shutter, Sub Aperture)',
-            0x80 => 'Reversed (Main Aperture, Sub Shutter)',
+            0 => 'Standard (Main Shutter, Sub Aperture)',
+            1 => 'Reversed (Main Aperture, Sub Shutter)',
         },
     },
@@ -218,13 +201,13 @@
         Mask => 0x78,
         PrintConv => {
-            0x00 => 'ISO Display',
-            0x08 => 'Framing Grid',
-            0x10 => 'AF-area Mode',
-            0x18 => 'Center AF Area',
-            0x20 => 'FV Lock',
-            0x28 => 'Flash Off',
-            0x30 => 'Matrix Metering',
-            0x38 => 'Center-weighted',
-            0x40 => 'Spot Metering',
+            0 => 'ISO Display',
+            1 => 'Framing Grid',
+            2 => 'AF-area Mode',
+            3 => 'Center AF Area',
+            4 => 'FV Lock',
+            5 => 'Flash Off',
+            6 => 'Matrix Metering',
+            7 => 'Center-weighted',
+            8 => 'Spot Metering',
         },
     },
@@ -232,16 +215,10 @@
         Name => 'GridDisplay',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'Off',
-            0x80 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     6.2 => { # CS9
         Name => 'ViewfinderWarning',
         Mask => 0x40,
-        PrintConv => {
-            0x00 => 'On',
-            0x40 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     6.3 => { # CS12
@@ -249,7 +226,7 @@
         Mask => 0x0c,
         PrintConv => {
-            0x00 => '6 mm',
-            0x04 => '8 mm',
-            0x08 => '10 mm',
+            0 => '6 mm',
+            1 => '8 mm',
+            2 => '10 mm',
         },
     },
@@ -257,8 +234,5 @@
         Name => 'ExposureDelayMode',
         Mask => 0x20,
-        PrintConv => {
-            0x00 => 'Off',
-            0x20 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     6.5 => { # CS32
@@ -266,8 +240,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'LR6 (AA Alkaline)',
-            0x01 => 'HR6 (AA Ni-MH)',
-            0x02 => 'FR6 (AA Lithium)',
-            0x03 => 'ZR6 (AA Ni-Mg)',
+            0 => 'LR6 (AA Alkaline)',
+            1 => 'HR6 (AA Ni-MH)',
+            2 => 'FR6 (AA Lithium)',
+            3 => 'ZR6 (AA Ni-Mg)',
         },
     },
@@ -275,14 +249,11 @@
         Name => 'FlashWarning',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'On',
-            0x80 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     7.2 => { # CS24
         Name => 'FlashShutterSpeed',
         Mask => 0x78,
-        ValueConv => '2 ** (($val >> 3) - 6)',
-        ValueConvInv => '$val>0 ? int(log($val)/log(2)+6+0.5) << 3 : 0',
+        ValueConv => '2 ** ($val - 6)',
+        ValueConvInv => '$val>0 ? int(log($val)/log(2)+6+0.5) : 0',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -291,16 +262,10 @@
         Name => 'AutoFP',
         Mask => 0x04,
-        PrintConv => {
-            0x00 => 'Off',
-            0x04 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     7.4 => { # CS26
         Name => 'ModelingFlash',
         Mask => 0x02,
-        PrintConv => {
-            0x00 => 'Off',
-            0x02 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     8.1 => { # CS22
@@ -308,8 +273,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'TTL',
-            0x40 => 'Manual',
-            0x80 => 'Repeating Flash',
-            0xc0 => 'Commander Mode',
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Repeating Flash',
+            3 => 'Commander Mode',
         },
     },
@@ -328,6 +293,6 @@
         Name => 'RepeatingFlashOutput',
         Mask => 0x70,
-        ValueConv => '2 ** (-($val>>4)-2)',
-        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5)<<4 : 0',
+        ValueConv => '2 ** (-$val-2)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5) : 0',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -342,6 +307,6 @@
         Name => 'RepeatingFlashRate',
         Mask => 0xf0,
-        ValueConv => 'my $v=($val>>4); $v < 10 ? $v + 1 : 10 * ($v - 8)',
-        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5) << 4',
+        ValueConv => '$val < 10 ? $val + 1 : 10 * ($val - 8)',
+        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5)',
         PrintConv => '"$val Hz"',
         PrintConvInv => '$val=~/(\d+)/; $1 || 0',
@@ -357,7 +322,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'TTL',
-            0x40 => 'Manual',
-            0x80 => 'Off',
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Off',
         },
     },
@@ -366,8 +331,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'TTL',
-            0x10 => 'Auto Aperture',
-            0x20 => 'Manual',
-            0x30 => 'Off',
+            0 => 'TTL',
+            1 => 'Auto Aperture',
+            2 => 'Manual',
+            3 => 'Off',
         },
     },
@@ -376,8 +341,8 @@
         Mask => 0x0c,
         PrintConv => {
-            0x00 => 'TTL',
-            0x04 => 'Auto Aperture',
-            0x08 => 'Manual',
-            0x0c => 'Off',
+            0 => 'TTL',
+            1 => 'Auto Aperture',
+            2 => 'Manual',
+            3 => 'Off',
         },
     },
@@ -393,6 +358,6 @@
         Name => 'CommanderInternalManualOutput',
         Mask => 0xe0,
-        ValueConv => '2 ** (-($val>>5))',
-        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)+0.5) << 5 : 0',
+        ValueConv => '2 ** (-$val)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)+0.5) : 0',
         PrintConv => q{
             return 'Full' if $val > 0.99;
@@ -412,6 +377,6 @@
         Name => 'CommanderGroupAManualOutput',
         Mask => 0xe0,
-        ValueConv => '2 ** (-($val>>5))',
-        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)+0.5) << 5 : 0',
+        ValueConv => '2 ** (-$val)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)+0.5) : 0',
         PrintConv => q{
             return 'Full' if $val > 0.99;
@@ -431,6 +396,6 @@
         Name => 'CommanderGroupBManualOutput',
         Mask => 0xe0,
-        ValueConv => '2 ** (-($val>>5))',
-        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)+0.5) << 5 : 0',
+        ValueConv => '2 ** (-$val)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)+0.5) : 0',
         PrintConv => q{
             return 'Full' if $val > 0.99;
@@ -443,6 +408,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => 'Normal Zone',
-            0x80 => 'Wide Zone',
+            0 => 'Normal Zone',
+            1 => 'Wide Zone',
         },
     },
@@ -451,6 +416,6 @@
         Mask => 0x04,
         PrintConv => {
-            0x00 => 'No Wrap',
-            0x04 => 'Wrap',
+            0 => 'No Wrap',
+            1 => 'Wrap',
         },
     },
@@ -459,7 +424,7 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'Auto',
-            0x01 => 'Off',
-            0x02 => 'On',
+            0 => 'Auto',
+            1 => 'Off',
+            2 => 'On',
         },
     },
@@ -468,7 +433,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Single Area',
-            0x40 => 'Dynamic Area',
-            0x80 => 'Auto-area',
+            0 => 'Single Area',
+            1 => 'Dynamic Area',
+            2 => 'Auto-area',
         },
     },
@@ -487,16 +452,10 @@
         Name => 'Beep',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'On',
-            0x80 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     0.2 => { # CS9
         Name => 'AFAssist',
         Mask => 0x40,
-        PrintConv => {
-            0x00 => 'On',
-            0x40 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     0.3 => { # CS6
@@ -504,6 +463,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Release Locked',
-            0x20 => 'Enable Release',
+            0 => 'Release Locked',
+            1 => 'Enable Release',
         },
     },
@@ -511,16 +470,10 @@
         Name => 'ImageReview',
         Mask => 0x10,
-        PrintConv => {
-            0x00 => 'On',
-            0x10 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     1.1 => { # CS10-a
         Name => 'AutoISO',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'Off',
-            0x80 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     1.2 => { # CS10-b
@@ -528,7 +481,7 @@
         Mask => 0x30,
         PrintConv => {
-            0x10 => 400,
-            0x20 => 800,
-            0x30 => 1600,
+            1 => 400,
+            2 => 800,
+            3 => 1600,
         },
     },
@@ -538,12 +491,12 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '1/125 s',
-            0x01 => '1/60 s',
-            0x02 => '1/30 s',
-            0x03 => '1/15 s',
-            0x04 => '1/8 s',
-            0x05 => '1/4 s',
-            0x06 => '1/2 s',
-            0x07 => '1 s',
+            0 => '1/125 s',
+            1 => '1/60 s',
+            2 => '1/30 s',
+            3 => '1/15 s',
+            4 => '1/8 s',
+            5 => '1/4 s',
+            6 => '1/2 s',
+            7 => '1 s',
         },
     },
@@ -552,9 +505,9 @@
         Mask => 0x07,
         PrintConv => {
-            0x00 => '4 s',
-            0x01 => '8 s',
-            0x02 => '20 s',
-            0x03 => '1 min',
-            0x04 => '10 min',
+            0 => '4 s',
+            1 => '8 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '10 min',
         },
     },
@@ -563,9 +516,9 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '4 s',
-            0x20 => '8 s',
-            0x40 => '20 s',
-            0x60 => '1 min',
-            0x80 => '10 min',
+            0 => '4 s',
+            1 => '8 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '10 min',
         },
     },
@@ -574,9 +527,9 @@
         Mask => 0x1c,
         PrintConv => {
-            0x00 => '4 s',
-            0x04 => '8 s',
-            0x08 => '20 s',
-            0x0c => '1 min',
-            0x10 => '30 min',
+            0 => '4 s',
+            1 => '8 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '30 min',
         },
     },
@@ -585,8 +538,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => '2 s',
-            0x01 => '5 s',
-            0x02 => '10 s',
-            0x03 => '20 s',
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
         },
     },
@@ -595,8 +548,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => '1 min',
-            0x40 => '5 min',
-            0x80 => '10 min',
-            0xc0 => '15 min',
+            0 => '1 min',
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
         },
     },
@@ -605,9 +558,9 @@
         Mask => 0x0e,
         PrintConv => {
-            0x00 => 'AE/AF Lock',
-            0x02 => 'AE Lock Only',
-            0x04 => 'AF Lock Only',
-            0x06 => 'AE Lock (hold)',
-            0x08 => 'AF-ON',
+            0 => 'AE/AF Lock',
+            1 => 'AE Lock Only',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (hold)',
+            4 => 'AF-ON',
         },
     },
@@ -615,8 +568,5 @@
         Name => 'AELock',
         Mask => 0x01,
-        PrintConv => {
-            0x00 => 'Off',
-            0x01 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     5.1 => { # CS4
@@ -624,9 +574,9 @@
         Mask => 0x70,
         PrintConv => {
-            0x00 => 'Single Frame',
-            0x10 => 'Continuous',
-            0x20 => 'Self-timer',
-            0x30 => 'Delayed Remote',
-            0x40 => 'Quick-response Remote',
+            0 => 'Single Frame',
+            1 => 'Continuous',
+            2 => 'Self-timer',
+            3 => 'Delayed Remote',
+            4 => 'Quick-response Remote',
         },
     },
@@ -635,9 +585,9 @@
         Mask => 0x07,
         PrintConv => {
-            0x00 => 'Shooting Mode',
-            0x01 => 'Image Quality/Size',
-            0x02 => 'ISO',
-            0x03 => 'White Balance',
-            0x04 => 'Self-timer',
+            0 => 'Shooting Mode',
+            1 => 'Image Quality/Size',
+            2 => 'ISO',
+            3 => 'White Balance',
+            4 => 'Self-timer',
         },
     },
@@ -646,7 +596,7 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'Matrix',
-            0x01 => 'Center-weighted',
-            0x02 => 'Spot',
+            0 => 'Matrix',
+            1 => 'Center-weighted',
+            2 => 'Spot',
         },
     },
@@ -655,6 +605,6 @@
         Mask => 0x10,
         PrintConv => {
-            0x00 => 'TTL',
-            0x10 => 'Manual',
+            0 => 'TTL',
+            1 => 'Manual',
         },
     },
@@ -683,8 +633,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Manual',
-            0x40 => 'AF-S',
-            0x80 => 'AF-C',
-            0xc0 => 'AF-A',
+            0 => 'Manual',
+            1 => 'AF-S',
+            2 => 'AF-C',
+            3 => 'AF-A',
         },
     },
@@ -694,7 +644,7 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'Single Area',
-            0x10 => 'Dynamic Area',
-            0x20 => 'Closest Subject',
+            0 => 'Single Area',
+            1 => 'Dynamic Area',
+            2 => 'Closest Subject',
         },
     }
@@ -724,6 +674,6 @@
         Mask => 0x08,
         PrintConv => {
-            0x00 => 'LCD Backlight',
-            0x08 => 'LCD Backlight and Shooting Information',
+            0 => 'LCD Backlight',
+            1 => 'LCD Backlight and Shooting Information',
         },
     },
@@ -732,8 +682,8 @@
         Mask => 0x60,
         PrintConv => {
-            0x00 => 'Single Area',
-            0x20 => 'Dynamic Area',
-            0x40 => 'Auto-area',
-            0x60 => '3D-tracking (11 points)',
+            0 => 'Single Area',
+            1 => 'Dynamic Area',
+            2 => 'Auto-area',
+            3 => '3D-tracking (11 points)',
         },
     },
@@ -742,6 +692,6 @@
         Mask => 0x10,
         PrintConv => {
-            0x00 => 'Normal Zone',
-            0x10 => 'Wide Zone',
+            0 => 'Normal Zone',
+            1 => 'Wide Zone',
         },
     },
@@ -749,5 +699,5 @@
         Name => 'AFAssist',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     2.4 => { # CSa4
@@ -755,7 +705,7 @@
         Mask => 0x06,
         PrintConv => {
-            0x00 => 'Auto',
-            0x02 => 'On',
-            0x04 => 'Off',
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
         },
     },
@@ -764,6 +714,6 @@
         Mask => 0x08,
         PrintConv => {
-            0x00 => 'No Wrap',
-            0x08 => 'Wrap',
+            0 => 'No Wrap',
+            1 => 'Wrap',
         },
     },
@@ -772,11 +722,11 @@
         Mask => 0x1c,
         PrintConv => {
-            0x00 => 'AE Lock Only',
-            0x04 => 'AF Lock Only',
-            0x08 => 'AE Lock (hold)',
-            0x0c => 'AF-On',
-            0x10 => 'FV Lock',
-            0x14 => 'Focus Point Selection',
-            0x1c => 'AE/AF Lock',
+            0 => 'AE Lock Only',
+            1 => 'AF Lock Only',
+            2 => 'AE Lock (hold)',
+            3 => 'AF-On',
+            4 => 'FV Lock',
+            5 => 'Focus Point Selection',
+            7 => 'AE/AF Lock',
         },
     },
@@ -785,8 +735,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'LR6 (AA alkaline)',
-            0x01 => 'HR6 (AA Ni-MH)',
-            0x02 => 'FR6 (AA lithium)',
-            0x03 => 'ZR6 (AA Ni-Mn)',
+            0 => 'LR6 (AA alkaline)',
+            1 => 'HR6 (AA Ni-MH)',
+            2 => 'FR6 (AA lithium)',
+            3 => 'ZR6 (AA Ni-Mn)',
         },
     },
@@ -794,13 +744,10 @@
         Name => 'Beep',
         Mask => 0x40,
-        PrintConv => {
-            0x40 => 'On',
-            0x00 => 'Off',
-        },
+        PrintConv => \%offOn,
     },
     4.2 => { # CSd2
         Name => 'GridDisplay',
         Mask => 0x02,
-        PrintConv => { 0x00 => 'Off', 0x02 => 'On' },
+        PrintConv => \%offOn,
     },
     4.3 => { # CSd3
@@ -808,7 +755,7 @@
         Mask => 0x0c,
         PrintConv => {
-            0x00 => 'Show ISO/Easy ISO',
-            0x04 => 'Show ISO Sensitivity',
-            0x0c => 'Show Frame Count',
+            0 => 'Show ISO/Easy ISO',
+            1 => 'Show ISO Sensitivity',
+            3 => 'Show Frame Count',
         },
     },
@@ -816,5 +763,5 @@
         Name => 'ViewfinderWarning',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     4.5 => { # CSf6
@@ -822,6 +769,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Release Locked',
-            0x20 => 'Enable Release',
+            0 => 'Release Locked',
+            1 => 'Enable Release',
         },
     },
@@ -829,10 +776,10 @@
         Name => 'ScreenTips',
         Mask => 0x04,
-        PrintConv => { 0x00 => 'Off', 0x04 => 'On' },
+        PrintConv => \%offOn,
     },
     5.2 => { # CSd7
         Name => 'FileNumberSequence',
         Mask => 0x08,
-        PrintConv => { 0x00 => 'On', 0x08 => 'Off' },
+        PrintConv => \%onOff,
     },
     5.3 => { # CSd8
@@ -840,7 +787,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Auto',
-            0x80 => 'Manual (dark on light)',
-            0xc0 => 'Manual (light on dark)',
+            0 => 'Auto',
+            2 => 'Manual (dark on light)',
+            3 => 'Manual (light on dark)',
         },
     },
@@ -848,10 +795,10 @@
         Name => 'LCDIllumination',
         Mask => 0x20,
-        PrintConv => { 0x00 => 'Off', 0x20 => 'On' },
+        PrintConv => \%offOn,
     },
     6.1 => { # CSb2
         Name => 'EasyExposureComp',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'Off', 0x01 => 'On' },
+        PrintConv => \%offOn,
     },
     6.2 => { # CSf7
@@ -859,6 +806,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => '+ 0 -',
-            0x80 => '- 0 +',
+            0 => '+ 0 -',
+            1 => '- 0 +',
         },
     },
@@ -867,6 +814,6 @@
         Mask => 0x40,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x40 => '1/2 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
         },
     },
@@ -875,7 +822,7 @@
         Mask => 0x60,
         PrintConv => {
-            0x00 => '6 mm',
-            0x20 => '8 mm',
-            0x40 => '10 mm',
+            0 => '6 mm',
+            1 => '8 mm',
+            2 => '10 mm',
         },
     },
@@ -884,5 +831,5 @@
         Mask => 0x0f,
         ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
-        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5)) & 0x0f',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
         PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -891,6 +838,6 @@
         Name => 'FineTuneOptCenterWeighted',
         Mask => 0xf0,
-        ValueConv => '($val > 0x70 ? $val - 0x100 : $val) / 0x60',
-        ValueConvInv => '(int($val*6+($val>0?0.5:-0.5))<<4) & 0xf0',
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
         PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -900,5 +847,5 @@
         Mask => 0x0f,
         ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
-        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5)) & 0x0f',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
         PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -913,8 +860,5 @@
         Name => 'ExposureDelayMode',
         Mask => 0x40,
-        PrintConv => {
-            0x00 => 'Off',
-            0x40 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     13.1 => { # CSe4
@@ -922,9 +866,9 @@
         Mask => 0xe0, #(NC)
         PrintConv => {
-            0x00 => 'AE & Flash', # default
-            0x20 => 'AE Only',
-            0x40 => 'Flash Only', #(NC)
-            0x60 => 'WB Bracketing', #(NC)
-            0x80 => 'Active D-Lighting', #(NC)
+            0 => 'AE & Flash', # default
+            1 => 'AE Only',
+            2 => 'Flash Only', #(NC)
+            3 => 'WB Bracketing', #(NC)
+            4 => 'Active D-Lighting', #(NC)
         },
     },
@@ -933,6 +877,6 @@
         Mask => 0x10,
         PrintConv => {
-            0x00 => '0,-,+',
-            0x10 => '-,0,+',
+            0 => '0,-,+',
+            1 => '-,0,+',
         },
     },
@@ -941,14 +885,14 @@
         Mask => 0x78,
         PrintConv => {
-            0x08 => 'Framing Grid',
-            0x10 => 'AF-area Mode',
-            0x18 => 'Center Focus Point',
-            0x20 => 'FV Lock', # default
-            0x28 => 'Flash Off',
-            0x30 => 'Matrix Metering',
-            0x38 => 'Center-weighted Metering',
-            0x40 => 'Spot Metering',
-            0x48 => 'My Menu Top',
-            0x50 => '+ NEF (RAW)',
+            1 => 'Framing Grid',
+            2 => 'AF-area Mode',
+            3 => 'Center Focus Point',
+            4 => 'FV Lock', # default
+            5 => 'Flash Off',
+            6 => 'Matrix Metering',
+            7 => 'Center-weighted Metering',
+            8 => 'Spot Metering',
+            9 => 'My Menu Top',
+            10 => '+ NEF (RAW)',
         },
     },
@@ -957,8 +901,8 @@
         Mask => 0x18,
         PrintConv => {
-            0x08 => 'Select Center Focus Point',
-            0x10 => 'Highlight Active Focus Point',
-            0x18 => 'Not Used', #(NC)
-            0x00 => 'Not Used', #(NC)
+            1 => 'Select Center Focus Point',
+            2 => 'Highlight Active Focus Point',
+            3 => 'Not Used', #(NC)
+            0 => 'Not Used', #(NC)
         },
     },
@@ -967,10 +911,10 @@
         Mask => 0x38,
         PrintConv => {
-            0x00 => 'AE/AF Lock',
-            0x08 => 'AE Lock Only',
-            0x10 => 'AF Lock Only', #(NC)
-            0x18 => 'AE Lock (hold)', #(NC)
-            0x20 => 'AF-ON', #(NC)
-            0x28 => 'FV Lock', #(NC)
+            0 => 'AE/AF Lock',
+            1 => 'AE Lock Only',
+            2 => 'AF Lock Only', #(NC)
+            3 => 'AE Lock (hold)', #(NC)
+            4 => 'AF-ON', #(NC)
+            5 => 'FV Lock', #(NC)
         },
     },
@@ -978,10 +922,10 @@
         Name => 'CommandDialsReverseRotation',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'No', 0x80 => 'Yes' },
+        PrintConv => \%noYes,
     },
     18.2 => { # CSc1
         Name => 'ShutterReleaseButtonAE-L',
         Mask => 0x02,
-        PrintConv => { 0x00 => 'Off', 0x02 => 'On' },
+        PrintConv => \%offOn,
     },
     19.1 => { # CSc2
@@ -990,13 +934,13 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '4 s',
-            0x10 => '6 s', # default
-            0x20 => '8 s',
-            0x30 => '16 s',
-            0x40 => '30 s',
-            0x50 => '1 min',
-            0x60 => '5 min',
-            0x70 => '10 min',
-            0x80 => '30 min',
+            0 => '4 s',
+            1 => '6 s', # default
+            2 => '8 s',
+            3 => '16 s',
+            4 => '30 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+            8 => '30 min',
         },
     },
@@ -1005,8 +949,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => '1 min',
-            0x01 => '5 min',
-            0x02 => '10 min',
-            0x03 => '15 min',
+            0 => '1 min',
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
         },
     },
@@ -1015,8 +959,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => '2 s',
-            0x40 => '5 s',
-            0x80 => '10 s', # default
-            0xc0 => '20 s',
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s', # default
+            3 => '20 s',
         },
     },
@@ -1024,6 +968,4 @@
         Name => 'SelfTimerShotCount',
         Mask => 0x1e,
-        ValueConv => '$val >> 1',
-        ValueConvInv => '$val << 1',
     },
     21.1 => { # CSc4-a
@@ -1031,10 +973,10 @@
         Mask => 0x1c,
         PrintConv => {
-            0x00 => '4 s',
-            0x04 => '10 s', # default
-            0x08 => '20 s',
-            0x0c => '1 min',
-            0x10 => '5 min',
-            0x14 => '10 min',
+            0 => '4 s',
+            1 => '10 s', # default
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -1043,10 +985,10 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '4 s', # default
-            0x20 => '10 s',
-            0x40 => '20 s',
-            0x60 => '1 min',
-            0x80 => '5 min',
-            0xa0 => '10 min',
+            0 => '4 s', # default
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -1055,10 +997,10 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '4 s',
-            0x20 => '10 s',
-            0x40 => '20 s', # default
-            0x60 => '1 min',
-            0x80 => '5 min',
-            0xa0 => '10 min',
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s', # default
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -1067,10 +1009,10 @@
         Mask => 0x1c,
         PrintConv => {
-            0x00 => '4 s',
-            0x04 => '10 s', # default
-            0x08 => '20 s',
-            0x0c => '1 min',
-            0x10 => '5 min',
-            0x14 => '10 min',
+            0 => '4 s',
+            1 => '10 s', # default
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -1080,16 +1022,16 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '1/60 s', # default
-            0x01 => '1/30 s',
-            0x02 => '1/15 s',
-            0x03 => '1/8 s',
-            0x04 => '1/4 s',
-            0x05 => '1/2 s',
-            0x06 => '1 s',
-            0x07 => '2 s',
-            0x08 => '4 s',
-            0x09 => '8 s',
-            0x0a => '15 s',
-            0x0b => '30 s',
+            0 => '1/60 s', # default
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
         },
     },
@@ -1098,8 +1040,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'TTL',
-            0x40 => 'Manual',
-            0x80 => 'Repeating Flash',
-            0xc0 => 'Commander Mode',
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Repeating Flash',
+            3 => 'Commander Mode',
         },
     },
@@ -1118,6 +1060,6 @@
         Name => 'RepeatingFlashOutput',
         Mask => 0x70,
-        ValueConv => '2 ** (-($val>>4)-2)',
-        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5)<<4 : 0',
+        ValueConv => '2 ** (-$val-2)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5) : 0',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -1132,6 +1074,6 @@
         Name => 'RepeatingFlashRate',
         Mask => 0xf0,
-        ValueConv => 'my $v=($val>>4); $v < 10 ? $v + 1 : 10 * ($v - 8)',
-        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5) << 4',
+        ValueConv => '$val < 10 ? $val + 1 : 10 * ($val - 8)',
+        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5)',
         PrintConv => '"$val Hz"',
         PrintConvInv => '$val=~/(\d+)/; $1 || 0',
@@ -1140,8 +1082,5 @@
         Name => 'FlashWarning',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'On',
-            0x80 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     31.2 => { # CSe2-ea
@@ -1156,13 +1095,10 @@
         Name => 'ModelingFlash',
         Mask => 0x20,
-        PrintConv => { 0x00 => 'On', 0x20 => 'Off' },
+        PrintConv => \%onOff,
     },
     31.4 => { # CSe5
         Name => 'AutoFP',
         Mask => 0x40,
-        PrintConv => {
-            0x00 => 'Off',
-            0x40 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     32.1 => { # CSe2-eb
@@ -1186,7 +1122,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Face Priority', #(NC)
-            0x40 => 'Wide Area',
-            0x80 => 'Normal Area',
+            0 => 'Face Priority', #(NC)
+            1 => 'Wide Area',
+            2 => 'Normal Area',
         },
     },
@@ -1221,5 +1157,5 @@
         Notes => '"No" if any custom setting for this bank was changed from the default',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'Yes', 0x80 => 'No' },
+        PrintConv => { 0 => 'Yes', 1 => 'No' },
     },
     1.1 => { # CSa1
@@ -1227,7 +1163,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Release',
-            0x40 => 'Release + Focus',
-            0x80 => 'Focus',
+            0 => 'Release',
+            1 => 'Release + Focus',
+            2 => 'Focus',
         },
     },
@@ -1236,6 +1172,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Focus',
-            0x20 => 'Release',
+            0 => 'Focus',
+            1 => 'Release',
         },
     },
@@ -1244,6 +1180,6 @@
         Mask => 0x10,
         PrintConv => {
-            0x00 => '51 Points',
-            0x10 => '11 Points',
+            0 => '51 Points',
+            1 => '11 Points',
         },
     },
@@ -1252,8 +1188,8 @@
         Mask => 0x0c,
         PrintConv => {
-            0x00 => '9 Points',
-            0x04 => '21 Points',
-            0x08 => '51 Points',
-            0x0c => '51 Points (3D-tracking)',
+            0 => '9 Points',
+            1 => '21 Points',
+            2 => '51 Points',
+            3 => '51 Points (3D-tracking)',
         },
     },
@@ -1264,8 +1200,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'Long',
-            0x01 => 'Normal',
-            0x02 => 'Short',
-            0x03 => 'Off',
+            0 => 'Long',
+            1 => 'Normal',
+            2 => 'Short',
+            3 => 'Off',
         },
     },
@@ -1274,6 +1210,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => 'Shutter/AF-On',
-            0x80 => 'AF-On Only',
+            0 => 'Shutter/AF-On',
+            1 => 'AF-On Only',
         },
     },
@@ -1282,6 +1218,6 @@
         Mask => 0x08,
         PrintConv => {
-            0x00 => 'No Wrap',
-            0x08 => 'Wrap',
+            0 => 'No Wrap',
+            1 => 'Wrap',
         },
     },
@@ -1292,9 +1228,9 @@
             Notes => 'D3',
             Mask => 0x60,
-            PrintConv => { 
-                0x00 => 'On in Continuous Shooting and Manual Focusing',
-                0x20 => 'On During Manual Focusing',
-                0x40 => 'On in Continuous Shooting Modes',
-                0x60 => 'Off',
+            PrintConv => {
+                0 => 'On in Continuous Shooting and Manual Focusing',
+                1 => 'On During Manual Focusing',
+                2 => 'On in Continuous Shooting Modes',
+                3 => 'Off',
             },
         },
@@ -1304,7 +1240,7 @@
             Mask => 0x06,
             PrintConv => {
-                0x00 => 'Auto',
-                0x02 => 'Off',
-                0x04 => 'On',
+                0 => 'Auto',
+                1 => 'Off',
+                2 => 'On',
             },
         },
@@ -1316,8 +1252,8 @@
         Mask => 0x06,
         PrintConv => {
-            0x00 => 'Low',
-            0x02 => 'Normal',
-            0x04 => 'High',
-            0x06 => 'Extra High',
+            0 => 'Low',
+            1 => 'Normal',
+            2 => 'High',
+            3 => 'Extra High',
         },
     },
@@ -1327,5 +1263,5 @@
         Notes => 'D300 only',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     3.1 => { # CSa9 (D3)
@@ -1349,11 +1285,11 @@
         Mask => 0x70,
         PrintConv => {
-            0x00 => 'AF On',
-            0x10 => 'AE/AF Lock',
-            0x20 => 'AE Lock Only',
-            0x30 => 'AE Lock (reset on release)',
-            0x40 => 'AE Lock (hold)',
-            0x50 => 'AF Lock Only',
-            0x70 => 'Same as AF On',
+            0 => 'AF On',
+            1 => 'AE/AF Lock',
+            2 => 'AE Lock Only',
+            3 => 'AE Lock (reset on release)',
+            4 => 'AE Lock (hold)',
+            5 => 'AF Lock Only',
+            7 => 'Same as AF On',
         },
     },
@@ -1364,11 +1300,11 @@
         Mask => 0x70,
         PrintConv => {
-            0x00 => 'AF-On',
-            0x10 => 'AE/AF Lock',
-            0x20 => 'AE Lock Only',
-            0x30 => 'AE Lock (reset on release)',
-            0x40 => 'AE Lock (hold)',
-            0x50 => 'AF Lock Only',
-            0x60 => 'Same as FUNC Button',
+            0 => 'AF-On',
+            1 => 'AE/AF Lock',
+            2 => 'AE Lock Only',
+            3 => 'AE Lock (reset on release)',
+            4 => 'AE Lock (hold)',
+            5 => 'AF Lock Only',
+            6 => 'Same as FUNC Button',
         },
     },
@@ -1379,10 +1315,10 @@
         Mask => 0x07,
         PrintConv => {
-            0x00 => '5 (Long)',
-            0x01 => '4',
-            0x02 => '3 (Normal)',
-            0x03 => '2',
-            0x04 => '1 (Short)',
-            0x05 => 'Off',
+            0 => '5 (Long)',
+            1 => '4',
+            2 => '3 (Normal)',
+            3 => '2',
+            4 => '1 (Short)',
+            5 => 'Off',
         },
     },
@@ -1393,6 +1329,6 @@
         Mask => 0x08,
         PrintConv => {
-            0x00 => 'Auto Bracketing',
-            0x08 => 'Multiple Exposure',
+            0 => 'Auto Bracketing',
+            1 => 'Multiple Exposure',
         },
     },
@@ -1403,8 +1339,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Reset',
-            0x40 => 'Zoom On/Off',
-            0x80 => 'Start Movie Recording',
-            0xc0 => 'Not Used',
+            0 => 'Reset',
+            1 => 'Zoom On/Off',
+            2 => 'Start Movie Recording',
+            3 => 'Not Used',
         },
     },
@@ -1415,7 +1351,7 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'Low Magnification',
-            0x10 => 'Medium Magnification',
-            0x20 => 'High Magnification',
+            0 => 'Low Magnification',
+            1 => 'Medium Magnification',
+            2 => 'High Magnification',
         },
     },
@@ -1424,7 +1360,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x40 => '1/2 EV',
-            0x80 => '1 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
         },
     },
@@ -1433,7 +1369,7 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x10 => '1/2 EV',
-            0x20 => '1 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
         },
     },
@@ -1442,7 +1378,7 @@
         Mask => 0x0c,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x04 => '1/2 EV',
-            0x08 => '1 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
         },
     },
@@ -1451,7 +1387,7 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'Off',
-            0x01 => 'On',
-            0x02 => 'On (auto reset)',
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (auto reset)',
         },
     },
@@ -1463,9 +1399,9 @@
             Mask => 0xe0,
             PrintConv => {
-                0x00 => '8 mm',
-                0x20 => '12 mm',
-                0x40 => '15 mm',
-                0x60 => '20 mm',
-                0x80 => 'Average',
+                0 => '8 mm',
+                1 => '12 mm',
+                2 => '15 mm',
+                3 => '20 mm',
+                4 => 'Average',
             },
         },
@@ -1475,9 +1411,9 @@
             Mask => 0xe0,
             PrintConv => {
-                0x00 => '6 mm',
-                0x20 => '8 mm',
-                0x40 => '10 mm',
-                0x60 => '13 mm',
-                0x80 => 'Average',
+                0 => '6 mm',
+                1 => '8 mm',
+                2 => '10 mm',
+                3 => '13 mm',
+                4 => 'Average',
             },
         },
@@ -1487,5 +1423,5 @@
         Mask => 0x0f,
         ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
-        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5)) & 0x0f',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
         PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -1494,6 +1430,6 @@
         Name => 'FineTuneOptMatrixMetering',
         Mask => 0xf0,
-        ValueConv => '($val > 0x70 ? $val - 0x100 : $val) / 0x60',
-        ValueConvInv => '(int($val*6+($val>0?0.5:-0.5))<<4) & 0xf0',
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
         PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -1503,5 +1439,5 @@
         Mask => 0x0f,
         ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
-        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5)) & 0x0f',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
         PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -1511,7 +1447,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Select Center Focus Point',
-            0x40 => 'Highlight Active Focus Point',
-            0x80 => 'Not Used',
+            0 => 'Select Center Focus Point',
+            1 => 'Highlight Active Focus Point',
+            2 => 'Not Used',
         },
     },
@@ -1522,8 +1458,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'Thumbnail On/Off',
-            0x10 => 'View Histograms',
-            0x20 => 'Zoom On/Off',
-            0x30 => 'Choose Folder',
+            0 => 'Thumbnail On/Off',
+            1 => 'View Histograms',
+            2 => 'Zoom On/Off',
+            3 => 'Choose Folder',
         },
     },
@@ -1535,7 +1471,7 @@
             Mask => 0x0c,
             PrintConv => { #1
-                0x00 => 'High Magnification',
-                0x04 => 'Medium Magnification',
-                0x08 => 'Low Magnification',
+                0 => 'High Magnification',
+                1 => 'Medium Magnification',
+                2 => 'Low Magnification',
             },
         },
@@ -1545,7 +1481,7 @@
             Mask => 0x0c,
             PrintConv => { #JD
-                0x00 => 'Low Magnification',
-                0x04 => 'Medium Magnification',
-                0x08 => 'High Magnification',
+                0 => 'Low Magnification',
+                1 => 'Medium Magnification',
+                2 => 'High Magnification',
             },
         },
@@ -1555,6 +1491,6 @@
         Mask => 0x01,
         PrintConv => {
-            0x00 => 'Do Nothing',
-            0x01 => 'Reset Meter-off Delay',
+            0 => 'Do Nothing',
+            1 => 'Reset Meter-off Delay',
         },
     },
@@ -1562,5 +1498,5 @@
         Name => 'ExposureDelayMode',
         Mask => 0x40,
-        PrintConv => { 0x00 => 'Off', 0x40 => 'On' },
+        PrintConv => \%offOn,
     },
     10.2 => { # CSd4 (D300), CDs5 (D300S), CSd2-a (D3)
@@ -1576,7 +1512,7 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => '9 fps',
-            0x10 => '10 fps',
-            0x20 => '11 fps',
+            0 => '9 fps',
+            1 => '10 fps',
+            2 => '11 fps',
         },
     },
@@ -1589,6 +1525,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => '+ 0 -',
-            0x20 => '- 0 +',
+            0 => '+ 0 -',
+            1 => '- 0 +',
         },
     },
@@ -1599,5 +1535,5 @@
             Notes => 'D3',
             Mask => 0x02,
-            PrintConv => { 0x00 => 'On', 0x02 => 'Off' },
+            PrintConv => \%onOff,
         },
         {
@@ -1605,5 +1541,5 @@
             Notes => 'D300',
             Mask => 0x08,
-            PrintConv => { 0x00 => 'On', 0x08 => 'Off' },
+            PrintConv => \%onOff,
         },
     ],
@@ -1614,6 +1550,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => 'ISO',
-            0x80 => 'Exposures Remaining',
+            0 => 'ISO',
+            1 => 'Exposures Remaining',
         },
     },
@@ -1624,6 +1560,6 @@
         Mask => 0x40,
         PrintConv => {
-            0x00 => 'Frame Count',
-            0x40 => 'Exposures Remaining',
+            0 => 'Frame Count',
+            1 => 'Exposures Remaining',
         },
     },
@@ -1634,6 +1570,6 @@
         Mask => 0x04,
         PrintConv => {
-            0x00 => 'MB-D10 First',
-            0x04 => 'Camera Battery First',
+            0 => 'MB-D10 First',
+            1 => 'Camera Battery First',
         },
     },
@@ -1644,8 +1580,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'LR6 (AA alkaline)',
-            0x01 => 'HR6 (AA Ni-MH)',
-            0x02 => 'FR6 (AA lithium)',
-            0x03 => 'ZR6 (AA Ni-Mn)',
+            0 => 'LR6 (AA alkaline)',
+            1 => 'HR6 (AA Ni-MH)',
+            2 => 'FR6 (AA lithium)',
+            3 => 'ZR6 (AA Ni-Mn)',
         },
     },
@@ -1654,8 +1590,5 @@
         Condition => '$$self{Model} =~ /(D3S|D300S)\b/',
         Mask => 0x10,
-        PrintConv => {
-            0x00 => 'On',
-            0x10 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     13.1 => { # CSd1
@@ -1663,7 +1596,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'High',
-            0x40 => 'Low',
-            0x80 => 'Off',
+            0 => 'High',
+            1 => 'Low',
+            2 => 'Off',
         },
     },
@@ -1672,8 +1605,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'Auto', #JD (D300)
-            0x10 => 'Auto', #1 (D3)
-            0x20 => 'Manual (dark on light)',
-            0x30 => 'Manual (light on dark)',
+            0 => 'Auto', #JD (D300)
+            1 => 'Auto', #1 (D3)
+            2 => 'Manual (dark on light)',
+            3 => 'Manual (light on dark)',
         },
     },
@@ -1683,5 +1616,5 @@
         Notes => 'D300 only',
         Mask => 0x02,
-        PrintConv => { 0x00 => 'Off', 0x02 => 'On' },
+        PrintConv => \%offOn,
     },
     13.4 => { # CSd3 (D300)
@@ -1690,5 +1623,5 @@
         Notes => 'D300 only',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     13.5 => { # CSf1-b (D3S) (ref 1)
@@ -1698,7 +1631,7 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'Thumbnail On/Off',
-            0x01 => 'View Histograms',
-            0x02 => 'Zoom On/Off',
+            0 => 'Thumbnail On/Off',
+            1 => 'View Histograms',
+            2 => 'Zoom On/Off',
         },
     },
@@ -1710,21 +1643,21 @@
             Mask => 0xf8,
             PrintConv => {
-                0x00 => 'None',
-                0x08 => 'Preview',
-                0x10 => 'FV Lock',
-                0x18 => 'AE/AF Lock',
-                0x20 => 'AE Lock Only',
-                0x28 => 'AE Lock (reset on release)',
-                0x30 => 'AE Lock (hold)',
-                0x38 => 'AF Lock Only',
-                0x40 => 'Flash Off',
-                0x48 => 'Bracketing Burst',
-                0x50 => 'Matrix Metering',
-                0x58 => 'Center-weighted Metering',
-                0x60 => 'Spot Metering',
-                0x68 => 'Virtual Horizon',
-                # 0x70 not used
-                0x78 => 'Playback',
-                0x80 => 'My Menu Top',
+                0 => 'None',
+                1 => 'Preview',
+                2 => 'FV Lock',
+                3 => 'AE/AF Lock',
+                4 => 'AE Lock Only',
+                5 => 'AE Lock (reset on release)',
+                6 => 'AE Lock (hold)',
+                7 => 'AF Lock Only',
+                8 => 'Flash Off',
+                9 => 'Bracketing Burst',
+                10 => 'Matrix Metering',
+                11 => 'Center-weighted Metering',
+                12 => 'Spot Metering',
+                13 => 'Virtual Horizon',
+                # 14 not used
+                15 => 'Playback',
+                16 => 'My Menu Top',
             },
         },
@@ -1734,21 +1667,21 @@
             Mask => 0xf8,
             PrintConv => {
-                0x00 => 'None',
-                0x08 => 'Preview',
-                0x10 => 'FV Lock',
-                0x18 => 'AE/AF Lock',
-                0x20 => 'AE Lock Only',
-                0x28 => 'AE Lock (reset on release)',
-                0x30 => 'AE Lock (hold)',
-                0x38 => 'AF Lock Only',
-                # 0x40 not used
-                0x48 => 'Flash Off',
-                0x50 => 'Bracketing Burst',
-                0x58 => 'Matrix Metering',
-                0x60 => 'Center-weighted Metering',
-                0x68 => 'Spot Metering',
-                0x70 => 'Playback', #PH (guess)
-                0x78 => 'My Menu Top', #PH (guess)
-                0x80 => '+ NEF (RAW)', #PH (guess)
+                0 => 'None',
+                1 => 'Preview',
+                2 => 'FV Lock',
+                3 => 'AE/AF Lock',
+                4 => 'AE Lock Only',
+                5 => 'AE Lock (reset on release)',
+                6 => 'AE Lock (hold)',
+                7 => 'AF Lock Only',
+                # 8 not used
+                9 => 'Flash Off',
+                10 => 'Bracketing Burst',
+                11 => 'Matrix Metering',
+                12 => 'Center-weighted Metering',
+                13 => 'Spot Metering',
+                14 => 'Playback', #PH (guess)
+                15 => 'My Menu Top', #PH (guess)
+                16 => '+ NEF (RAW)', #PH (guess)
             },
         },
@@ -1791,21 +1724,21 @@
             Mask => 0xf8,
             PrintConv => {
-                0x00 => 'None',
-                0x08 => 'Preview',
-                0x10 => 'FV Lock',
-                0x18 => 'AE/AF Lock',
-                0x20 => 'AE Lock Only',
-                0x28 => 'AE Lock (reset on release)',
-                0x30 => 'AE Lock (hold)',
-                0x38 => 'AF Lock Only',
-                0x40 => 'Flash Off',
-                0x48 => 'Bracketing Burst',
-                0x50 => 'Matrix Metering',
-                0x58 => 'Center-weighted Metering',
-                0x60 => 'Spot Metering',
-                0x68 => 'Virtual Horizon',
-                # 0x70 not used
-                0x78 => 'Playback',
-                0x80 => 'My Menu Top',
+                0 => 'None',
+                1 => 'Preview',
+                2 => 'FV Lock',
+                3 => 'AE/AF Lock',
+                4 => 'AE Lock Only',
+                5 => 'AE Lock (reset on release)',
+                6 => 'AE Lock (hold)',
+                7 => 'AF Lock Only',
+                8 => 'Flash Off',
+                9 => 'Bracketing Burst',
+                10 => 'Matrix Metering',
+                11 => 'Center-weighted Metering',
+                12 => 'Spot Metering',
+                13 => 'Virtual Horizon',
+                # 14 not used
+                15 => 'Playback',
+                16 => 'My Menu Top',
             },
         },
@@ -1815,21 +1748,21 @@
             Mask => 0xf8,
             PrintConv => {
-                0x00 => 'None',
-                0x08 => 'Preview',
-                0x10 => 'FV Lock',
-                0x18 => 'AE/AF Lock',
-                0x20 => 'AE Lock Only',
-                0x28 => 'AE Lock (reset on release)',
-                0x30 => 'AE Lock (hold)',
-                0x38 => 'AF Lock Only',
-                # 0x40 not used
-                0x48 => 'Flash Off',
-                0x50 => 'Bracketing Burst',
-                0x58 => 'Matrix Metering',
-                0x60 => 'Center-weighted Metering',
-                0x68 => 'Spot Metering',
-                0x70 => 'Playback', #PH (guess)
-                0x78 => 'My Menu Top', #PH (guess)
-                0x80 => '+ NEF (RAW)', #PH (guess)
+                0 => 'None',
+                1 => 'Preview',
+                2 => 'FV Lock',
+                3 => 'AE/AF Lock',
+                4 => 'AE Lock Only',
+                5 => 'AE Lock (reset on release)',
+                6 => 'AE Lock (hold)',
+                7 => 'AF Lock Only',
+                # 8 not used
+                9 => 'Flash Off',
+                10 => 'Bracketing Burst',
+                11 => 'Matrix Metering',
+                12 => 'Center-weighted Metering',
+                13 => 'Spot Metering',
+                14 => 'Playback', #PH (guess)
+                15 => 'My Menu Top', #PH (guess)
+                16 => '+ NEF (RAW)', #PH (guess)
             },
         },
@@ -1872,21 +1805,21 @@
             Mask => 0xf8,
             PrintConv => {
-                0x00 => 'None',
-                0x08 => 'Preview',
-                0x10 => 'FV Lock',
-                0x18 => 'AE/AF Lock',
-                0x20 => 'AE Lock Only',
-                0x28 => 'AE Lock (reset on release)',
-                0x30 => 'AE Lock (hold)',
-                0x38 => 'AF Lock Only',
-                0x40 => 'Flash Off',
-                0x48 => 'Bracketing Burst',
-                0x50 => 'Matrix Metering',
-                0x58 => 'Center-weighted Metering',
-                0x60 => 'Spot Metering',
-                0x68 => 'Virtual Horizon',
-                0x70 => 'AF On', # (AE-L/AF-L button only)
-                0x78 => 'Playback',
-                0x80 => 'My Menu Top',
+                0 => 'None',
+                1 => 'Preview',
+                2 => 'FV Lock',
+                3 => 'AE/AF Lock',
+                4 => 'AE Lock Only',
+                5 => 'AE Lock (reset on release)',
+                6 => 'AE Lock (hold)',
+                7 => 'AF Lock Only',
+                8 => 'Flash Off',
+                9 => 'Bracketing Burst',
+                10 => 'Matrix Metering',
+                11 => 'Center-weighted Metering',
+                12 => 'Spot Metering',
+                13 => 'Virtual Horizon',
+                14 => 'AF On', # (AE-L/AF-L button only)
+                15 => 'Playback',
+                16 => 'My Menu Top',
             },
         },
@@ -1896,21 +1829,21 @@
             Mask => 0xf8,
             PrintConv => {
-                0x00 => 'None',
-                0x08 => 'Preview',
-                0x10 => 'FV Lock',
-                0x18 => 'AE/AF Lock',
-                0x20 => 'AE Lock Only',
-                0x28 => 'AE Lock (reset on release)',
-                0x30 => 'AE Lock (hold)',
-                0x38 => 'AF Lock Only',
-                0x40 => 'AF On', # (AE-L/AF-L button only)
-                0x48 => 'Flash Off',
-                0x50 => 'Bracketing Burst',
-                0x58 => 'Matrix Metering',
-                0x60 => 'Center-weighted Metering',
-                0x68 => 'Spot Metering',
-                0x70 => 'Playback', #PH (guess)
-                0x78 => 'My Menu Top', #PH (guess)
-                0x80 => '+ NEF (RAW)', #PH (guess)
+                0 => 'None',
+                1 => 'Preview',
+                2 => 'FV Lock',
+                3 => 'AE/AF Lock',
+                4 => 'AE Lock Only',
+                5 => 'AE Lock (reset on release)',
+                6 => 'AE Lock (hold)',
+                7 => 'AF Lock Only',
+                8 => 'AF On', # (AE-L/AF-L button only)
+                9 => 'Flash Off',
+                10 => 'Bracketing Burst',
+                11 => 'Matrix Metering',
+                12 => 'Center-weighted Metering',
+                13 => 'Spot Metering',
+                14 => 'Playback', #PH (guess)
+                15 => 'My Menu Top', #PH (guess)
+                16 => '+ NEF (RAW)', #PH (guess)
             },
         },
@@ -1949,10 +1882,10 @@
         Name => 'CommandDialsReverseRotation',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'No', 0x80 => 'Yes' },
+        PrintConv => \%noYes,
     },
     17.2 => { # CSf7-b, CSf8-b (D3S,D300S)
         Name => 'CommandDialsChangeMainSub',
         Mask => 0x40,
-        PrintConv => { 0x00 => 'Off', 0x40 => 'On' },
+        PrintConv => \%offOn,
     },
     17.3 => { # CSf7-c, CSf8-c (D3S,D300S)
@@ -1960,6 +1893,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Sub-command Dial',
-            0x20 => 'Aperture Ring',
+            0 => 'Sub-command Dial',
+            1 => 'Aperture Ring',
         },
     },
@@ -1967,10 +1900,10 @@
         Name => 'CommandDialsMenuAndPlayback',
         Mask => 0x10,
-        PrintConv => { 0x00 => 'Off', 0x10 => 'On' },
+        PrintConv => \%offOn,
     },
     17.5 => { # CSd8 (D300,D3S), CSd9 (D300S), CSd7 (D3)
         Name => 'LCDIllumination',
         Mask => 0x08,
-        PrintConv => { 0x00 => 'Off', 0x08 => 'On' },
+        PrintConv => \%offOn,
     },
     17.6 => { # CSf3, CSf4 (D300S)
@@ -1978,6 +1911,6 @@
         Mask => 0x04,
         PrintConv => {
-            0x00 => 'Info Up-down, Playback Left-right',
-            0x04 => 'Info Left-right, Playback Up-down',
+            0 => 'Info Up-down, Playback Left-right',
+            1 => 'Info Left-right, Playback Up-down',
         },
     },
@@ -1985,10 +1918,10 @@
         Name => 'ShutterReleaseButtonAE-L',
         Mask => 0x02,
-        PrintConv => { 0x00 => 'Off', 0x02 => 'On' },
+        PrintConv => \%offOn,
     },
     17.8 => { # CSf8, CSf9 (D3S,D300S)
         Name => 'ReleaseButtonToUseDial',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'No', 0x01 => 'Yes' },
+        PrintConv => \%noYes,
     },
     18.1 => { # CSc3
@@ -1996,8 +1929,8 @@
         Mask => 0x18,
         PrintConv => {
-            0x00 => '2 s',
-            0x08 => '5 s',
-            0x10 => '10 s',
-            0x18 => '20 s',
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
         },
     },
@@ -2005,13 +1938,12 @@
         Name => 'MonitorOffTime',
         # NOTE: The D3S and D300S have separate settings for Playback,
-        # Image Review, Menus, and Information Display times, but these
-        # have not yet been decoded - PH
+        # Image Review, Menus, and Information Display times
         Mask => 0x07,
         PrintConv => {
-            0x00 => '10 s',
-            0x01 => '20 s',
-            0x02 => '1 min',
-            0x03 => '5 min',
-            0x04 => '10 min',
+            0 => '10 s',
+            1 => '20 s',
+            2 => '1 min',
+            3 => '5 min',
+            4 => '10 min',
         },
     },
@@ -2023,12 +1955,12 @@
             Mask => 0xe0,
             PrintConv => {
-                0x00 => '1/250 s (auto FP)',
-                0x20 => '1/250 s',
-                0x40 => '1/200 s',
-                0x60 => '1/160 s',
-                0x80 => '1/125 s',
-                0xa0 => '1/100 s',
-                0xc0 => '1/80 s',
-                0xe0 => '1/60 s',
+                0 => '1/250 s (auto FP)',
+                1 => '1/250 s',
+                2 => '1/200 s',
+                3 => '1/160 s',
+                4 => '1/125 s',
+                5 => '1/100 s',
+                6 => '1/80 s',
+                7 => '1/60 s',
             },
         },
@@ -2038,13 +1970,13 @@
             Mask => 0xf0,
             PrintConv => {
-                0x00 => '1/320 s (auto FP)',
-                0x10 => '1/250 s (auto FP)',
-                0x20 => '1/250 s',
-                0x30 => '1/200 s',
-                0x40 => '1/160 s',
-                0x50 => '1/125 s',
-                0x60 => '1/100 s',
-                0x70 => '1/80 s',
-                0x80 => '1/60 s',
+                0 => '1/320 s (auto FP)',
+                1 => '1/250 s (auto FP)',
+                2 => '1/250 s',
+                3 => '1/200 s',
+                4 => '1/160 s',
+                5 => '1/125 s',
+                6 => '1/100 s',
+                7 => '1/80 s',
+                8 => '1/60 s',
             },
         },
@@ -2055,51 +1987,86 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '1/60 s',
-            0x01 => '1/30 s',
-            0x02 => '1/15 s',
-            0x03 => '1/8 s',
-            0x04 => '1/4 s',
-            0x05 => '1/2 s',
-            0x06 => '1 s',
-            0x07 => '2 s',
-            0x08 => '4 s',
-            0x09 => '8 s',
-            0x0a => '15 s',
-            0x0b => '30 s',
-        },
-    },
-    21.1 => { # CSe5 (D300), CSe4 (D3)
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
+        },
+    },
+    21.1 => [{ # CSe5 (D300), CSe4 (D3)
         Name => 'AutoBracketSet',
+        Condition => '$$self{Model} !~ /(D3S|D300S)\b/',
+        Notes => 'D3 and D300',
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'AE & Flash',
-            0x40 => 'AE Only',
-            0x80 => 'Flash Only',
-            0xc0 => 'WB Bracketing',
-            # NOTE: D3S/D300S have an "ADL Bracketing" setting not decoded - PH
-        },
-    },
-    21.2 => { # CSe6 (D300), CSe5 (D3)
+            0 => 'AE & Flash',
+            1 => 'AE Only',
+            2 => 'Flash Only',
+            3 => 'WB Bracketing',
+        },
+    },{ # CSe4 (D3S) (NC for D300S)
+        Name => 'AutoBracketSet',
+        Notes => 'D3S and D300S',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'AE & Flash',
+            1 => 'AE Only',
+            2 => 'Flash Only',
+            3 => 'WB Bracketing',
+            # D3S/D300S have an "ADL Bracketing" setting - PH
+            4 => 'ADL Bracketing',
+        },
+    }],
+    21.2 => [{ # CSe6 (D300), CSe5 (D3)
         Name => 'AutoBracketModeM',
+        Condition => '$$self{Model} !~ /(D3S|D300S)\b/',
+        Notes => 'D3 and D300',
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'Flash/Speed',
-            0x10 => 'Flash/Speed/Aperture',
-            0x20 => 'Flash/Aperture',
-            0x30 => 'Flash Only',
-        },
-    },
-    21.3 => { # CSe7 (D300), CSe6 (D3)
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
+        },
+    },{ # CSe5 (D3S)
+        Name => 'AutoBracketModeM',
+        Notes => 'D3S and D300S',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
+        },
+    }],
+    21.3 => [{ # CSe7 (D300), CSe6 (D3)
         Name => 'AutoBracketOrder',
+        Condition => '$$self{Model} !~ /(D3S|D300S)\b/',
+        Notes => 'D3 and D300',
         Mask => 0x08,
         PrintConv => {
-            0x00 => '0,-,+',
-            0x08 => '-,0,+',
-        },
-    },
+            0 => '0,-,+',
+            1 => '-,0,+',
+        },
+    },{ # CSe6 (D3S)
+        Name => 'AutoBracketOrder',
+        Notes => 'D3S and D300S',
+        Mask => 0x04,
+        PrintConv => {
+            0 => '0,-,+',
+            1 => '-,0,+',
+        },
+    }],
     21.4 => { # CSe4 (D300), CSe3 (D3)
         Name => 'ModelingFlash',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     22.1 => { # CSf9, CSf10 (D3S,D300S)
@@ -2107,6 +2074,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => 'Release Locked',
-            0x80 => 'Enable Release',
+            0 => 'Release Locked',
+            1 => 'Enable Release',
         },
     },
@@ -2116,14 +2083,14 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '4 s',
-            0x01 => '6 s',
-            0x02 => '8 s',
-            0x03 => '16 s',
-            0x04 => '30 s',
-            0x05 => '1 min',
-            0x06 => '5 min',
-            0x07 => '10 min',
-            0x08 => '30 min',
-            0x09 => 'No Limit',
+            0 => '4 s',
+            1 => '6 s',
+            2 => '8 s',
+            3 => '16 s',
+            4 => '30 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+            8 => '30 min',
+            9 => 'No Limit',
         },
     },
@@ -2132,8 +2099,56 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'TTL',
-            0x40 => 'Manual',
-            0x80 => 'Repeating Flash',
-            0xc0 => 'Commander Mode',
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Repeating Flash',
+            3 => 'Commander Mode',
+        },
+    },
+    25.1 => { #1 CSc4-d (D3S)
+        Name => 'ImageReviewTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    25.2 => { #1 CSc4-a (D3S)
+        Name => 'PlaybackMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    26.1 => { #1 CSc4-b (D3S)
+        Name => 'MenuMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    26.2 => { #1 CSc4-c (D3S)
+        Name => 'ShootingInfoMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -2164,5 +2179,5 @@
         Notes => '"No" if any custom setting for this bank was changed from the default',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'Yes', 0x80 => 'No' },
+        PrintConv => { 0 => 'Yes', 1 => 'No' },
     },
     1.1 => { # CSa1
@@ -2170,7 +2185,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Release',
-            0x40 => 'Release + Focus',
-            0x80 => 'Focus',
+            0 => 'Release',
+            1 => 'Release + Focus',
+            2 => 'Focus',
         },
     },
@@ -2179,6 +2194,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Focus',
-            0x20 => 'Release',
+            0 => 'Focus',
+            1 => 'Release',
         },
     },
@@ -2187,6 +2202,6 @@
         Mask => 0x10,
         PrintConv => {
-            0x00 => '51 Points',
-            0x10 => '11 Points',
+            0 => '51 Points',
+            1 => '11 Points',
         },
     },
@@ -2195,8 +2210,8 @@
         Mask => 0x0c,
         PrintConv => {
-            0x00 => '9 Points',
-            0x04 => '21 Points',
-            0x08 => '51 Points',
-            0x0c => '51 Points (3D-tracking)',
+            0 => '9 Points',
+            1 => '21 Points',
+            2 => '51 Points',
+            3 => '51 Points (3D-tracking)',
         },
     },
@@ -2205,6 +2220,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => 'Shutter/AF-On',
-            0x80 => 'AF-On Only',
+            0 => 'Shutter/AF-On',
+            1 => 'AF-On Only',
         },
     },
@@ -2213,6 +2228,6 @@
         Mask => 0x08,
         PrintConv => {
-            0x00 => 'No Wrap',
-            0x08 => 'Wrap',
+            0 => 'No Wrap',
+            1 => 'Wrap',
         },
     },
@@ -2221,7 +2236,7 @@
         Mask => 0x06,
         PrintConv => {
-            0x00 => 'Auto',
-            0x02 => 'Off',
-            0x04 => 'On',
+            0 => 'Auto',
+            1 => 'Off',
+            2 => 'On',
         },
     },
@@ -2229,5 +2244,5 @@
         Name => 'AFAssist',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     3.1 => { # CSa4
@@ -2235,10 +2250,10 @@
         Mask => 0x07,
         PrintConv => {
-            0x00 => '3 Normal',
-            0x01 => '4',
-            0x02 => '5 Long',
-            0x03 => '2',
-            0x04 => '1 Short',
-            0x05 => 'Off',
+            0 => '3 Normal',
+            1 => '4',
+            2 => '5 Long',
+            3 => '2',
+            4 => '1 Short',
+            5 => 'Off',
         },
     },
@@ -2247,11 +2262,11 @@
         Mask => 0x70,
         PrintConv => {
-            0x00 => 'AF-On',
-            0x10 => 'AE/AF Lock',
-            0x20 => 'AE Lock Only',
-            0x30 => 'AE Lock (reset on release)',
-            0x40 => 'AE Lock (hold)',
-            0x50 => 'AF Lock Only',
-            0x60 => 'Same as FUNC Button',
+            0 => 'AF-On',
+            1 => 'AE/AF Lock',
+            2 => 'AE Lock Only',
+            3 => 'AE Lock (reset on release)',
+            4 => 'AE Lock (hold)',
+            5 => 'AF Lock Only',
+            6 => 'Same as FUNC Button',
         },
     },
@@ -2260,7 +2275,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x40 => '1/2 EV',
-            0x80 => '1 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
         },
     },
@@ -2269,7 +2284,7 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x10 => '1/2 EV',
-            0x20 => '1 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
         },
     },
@@ -2278,7 +2293,7 @@
         Mask => 0x0c,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x04 => '1/2 EV',
-            0x08 => '1 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
         },
     },
@@ -2287,7 +2302,7 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'Off',
-            0x01 => 'On',
-            0x02 => 'On (auto reset)',
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (auto reset)',
         },
     },
@@ -2296,9 +2311,9 @@
         Mask => 0x70,
         PrintConv => {
-            0x00 => '8 mm',
-            0x10 => '12 mm',
-            0x20 => '15 mm',
-            0x30 => '20 mm',
-            0x40 => 'Average',
+            0 => '8 mm',
+            1 => '12 mm',
+            2 => '15 mm',
+            3 => '20 mm',
+            4 => 'Average',
         },
     },
@@ -2306,6 +2321,6 @@
         Name => 'FineTuneOptMatrixMetering',
         Mask => 0xf0,
-        ValueConv => '($val > 0x70 ? $val - 0x100 : $val) / 0x60',
-        ValueConvInv => '(int($val*6+($val>0?0.5:-0.5))<<4) & 0xf0',
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
         PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -2315,5 +2330,5 @@
         Mask => 0x0f,
         ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
-        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5)) & 0x0f',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
         PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -2322,5 +2337,5 @@
         Name => 'ShutterReleaseButtonAE-L',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'Off', 0x80 => 'On' },
+        PrintConv => \%offOn,
     },
     7.2 => { # CSc3
@@ -2328,8 +2343,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => '2 s',
-            0x10 => '5 s',
-            0x20 => '10 s',
-            0x30 => '20 s',
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
         },
     },
@@ -2339,14 +2354,14 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '4 s',
-            0x01 => '6 s',
-            0x02 => '8 s',
-            0x03 => '16 s',
-            0x04 => '30 s',
-            0x05 => '1 min',
-            0x06 => '5 min',
-            0x07 => '10 min',
-            0x08 => '30 min',
-            0x09 => 'No Limit',
+            0 => '4 s',
+            1 => '6 s',
+            2 => '8 s',
+            3 => '16 s',
+            4 => '30 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+            8 => '30 min',
+            9 => 'No Limit',
         },
     },
@@ -2355,10 +2370,10 @@
         Mask => 0x38,
         PrintConv => {
-            0x00 => '4 s',
-            0x08 => '10 s',
-            0x10 => '20 s',
-            0x18 => '1 min',
-            0x20 => '5 min',
-            0x28 => '10 min',
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -2367,10 +2382,10 @@
         Mask => 0x07,
         PrintConv => {
-            0x00 => '4 s',
-            0x01 => '10 s',
-            0x02 => '20 s',
-            0x03 => '1 min',
-            0x04 => '5 min',
-            0x05 => '10 min',
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -2379,10 +2394,10 @@
         Mask => 0x38,
         PrintConv => {
-            0x00 => '4 s',
-            0x08 => '10 s',
-            0x10 => '20 s',
-            0x18 => '1 min',
-            0x20 => '5 min',
-            0x28 => '10 min',
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -2391,10 +2406,10 @@
         Mask => 0x07,
         PrintConv => {
-            0x00 => '4 s',
-            0x01 => '10 s',
-            0x02 => '20 s',
-            0x03 => '1 min',
-            0x04 => '5 min',
-            0x05 => '10 min',
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -2403,7 +2418,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'High',
-            0x40 => 'Low',
-            0x80 => 'Off',
+            0 => 'High',
+            1 => 'Low',
+            2 => 'Off',
         },
     },
@@ -2412,8 +2427,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'Auto', #JD (D300)
-            0x10 => 'Auto', #1 (D3)
-            0x20 => 'Manual (dark on light)',
-            0x30 => 'Manual (light on dark)',
+            0 => 'Auto', #JD (D300)
+            1 => 'Auto', #1 (D3)
+            2 => 'Manual (dark on light)',
+            3 => 'Manual (light on dark)',
         },
     },
@@ -2421,20 +2436,20 @@
         Name => 'LCDIllumination',
         Mask => 0x08,
-        PrintConv => { 0x00 => 'Off', 0x08 => 'On' },
+        PrintConv => \%offOn,
     },
     10.4 => { # CSd9
         Name => 'ExposureDelayMode',
         Mask => 0x04,
-        PrintConv => { 0x00 => 'Off', 0x04 => 'On' },
+        PrintConv => \%offOn,
     },
     10.5 => { # CSd2
         Name => 'GridDisplay',
         Mask => 0x02,
-        PrintConv => { 0x00 => 'Off', 0x02 => 'On' },
+        PrintConv => \%offOn,
     },
     11.1 => { # CSd6
         Name => 'FileNumberSequence',
         Mask => 0x40,
-        PrintConv => { 0x00 => 'On', 0x40 => 'Off' },
+        PrintConv => \%onOff,
     },
     11.2 => { # CSd4
@@ -2451,5 +2466,5 @@
         Name => 'ScreenTips',
         Mask => 0x08,
-        PrintConv => { 0x08 => 'On', 0x00 => 'Off' },
+        PrintConv => \%onOff,
     },
     13.2 => { # CSd11
@@ -2457,6 +2472,6 @@
         Mask => 0x04,
         PrintConv => {
-            0x00 => 'MB-D10 First',
-            0x04 => 'Camera Battery First',
+            0 => 'MB-D10 First',
+            1 => 'Camera Battery First',
         },
     },
@@ -2465,8 +2480,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'LR6 (AA alkaline)',
-            0x01 => 'HR6 (AA Ni-MH)',
-            0x02 => 'FR6 (AA lithium)',
-            0x03 => 'ZR6 (AA Ni-Mn)',
+            0 => 'LR6 (AA alkaline)',
+            1 => 'HR6 (AA Ni-MH)',
+            2 => 'FR6 (AA lithium)',
+            3 => 'ZR6 (AA Ni-Mn)',
         },
     },
@@ -2475,13 +2490,13 @@
         Mask => 0xf0,
         PrintConv => {
-            0x00 => '1/320 s (auto FP)',
-            0x10 => '1/250 s (auto FP)',
-            0x20 => '1/250 s',
-            0x30 => '1/200 s',
-            0x40 => '1/160 s',
-            0x50 => '1/125 s',
-            0x60 => '1/100 s',
-            0x70 => '1/80 s',
-            0x80 => '1/60 s',
+            0 => '1/320 s (auto FP)',
+            1 => '1/250 s (auto FP)',
+            2 => '1/250 s',
+            3 => '1/200 s',
+            4 => '1/160 s',
+            5 => '1/125 s',
+            6 => '1/100 s',
+            7 => '1/80 s',
+            8 => '1/60 s',
        },
     },
@@ -2491,16 +2506,16 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '1/60 s',
-            0x01 => '1/30 s',
-            0x02 => '1/15 s',
-            0x03 => '1/8 s',
-            0x04 => '1/4 s',
-            0x05 => '1/2 s',
-            0x06 => '1 s',
-            0x07 => '2 s',
-            0x08 => '4 s',
-            0x09 => '8 s',
-            0x0a => '15 s',
-            0x0b => '30 s',
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
         },
     },
@@ -2510,15 +2525,15 @@
         #      does not decode the detail settings.
         Mask => 0xc0,
-        RawConv => '$$self{FlashControlBuiltin} = $val & 0xc0',
-        PrintConv => {
-            0x00 => 'TTL',
-            0x40 => 'Manual',
-            0x80 => 'Repeating Flash',
-            0xc0 => 'Commander Mode',
+        RawConv => '$$self{FlashControlBuiltin} = $val',
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Repeating Flash',
+            3 => 'Commander Mode',
         },
     },
     16.2 => { # CSe3-b
         Name => 'ManualFlashOutput',
-        Condition => '$$self{FlashControlBuiltin} == 0x40',
+        Condition => '$$self{FlashControlBuiltin} == 1',
         Mask => 0x1f,
         ValueConv => '2 ** (-$val/3)',
@@ -2532,8 +2547,8 @@
     17.1 => { # CSe3-ca
         Name => 'RepeatingFlashOutput',
-        Condition => '$$self{FlashControlBuiltin} == 0x80',
+        Condition => '$$self{FlashControlBuiltin} == 2',
         Mask => 0x70,
-        ValueConv => '2 ** (-($val>>4)-2)',
-        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5)<<4 : 0',
+        ValueConv => '2 ** (-$val-2)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5) : 0',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -2541,5 +2556,5 @@
     17.2 => { # CSe3-cb
         Name => 'RepeatingFlashCount',
-        Condition => '$$self{FlashControlBuiltin} == 0x80',
+        Condition => '$$self{FlashControlBuiltin} == 2',
         Mask => 0x0f,
         ValueConv => '$val < 10 ? $val + 1 : 5 * ($val - 7)',
@@ -2548,8 +2563,8 @@
     18.1 => { # CSe3-cc (NC)
         Name => 'RepeatingFlashRate',
-        Condition => '$$self{FlashControlBuiltin} == 0x80',
+        Condition => '$$self{FlashControlBuiltin} == 2',
         Mask => 0xf0,
-        ValueConv => 'my $v=($val>>4); $v < 10 ? $v + 1 : 10 * ($v - 8)',
-        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5) << 4',
+        ValueConv => '$val < 10 ? $val + 1 : 10 * ($val - 8)',
+        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5)',
         PrintConv => '"$val Hz"',
         PrintConvInv => '$val=~/(\d+)/; $1 || 0',
@@ -2557,16 +2572,16 @@
     18.2 => { # CSe3-dd
         Name => 'CommanderInternalTTLChannel',
-        Condition => '$$self{FlashControlBuiltin} == 0xc0',
+        Condition => '$$self{FlashControlBuiltin} == 3',
         Mask => 0x03,
         PrintConv => {
-            0x00 => '1 ch',
-            0x01 => '2 ch',
-            0x02 => '3 ch',
-            0x03 => '4 ch',
+            0 => '1 ch',
+            1 => '2 ch',
+            2 => '3 ch',
+            3 => '4 ch',
         },
     },
     20.1 => { # CSe3-da
         Name => 'CommanderInternalTTLCompBuiltin',
-        Condition => '$$self{FlashControlBuiltin} == 0xc0',
+        Condition => '$$self{FlashControlBuiltin} == 3',
         Mask => 0x1f,
         ValueConv => '($val - 9) / 3',
@@ -2577,5 +2592,5 @@
     21.1 => { # CSe3-db
         Name => 'CommanderInternalTTLCompGroupA',
-        Condition => '$$self{FlashControlBuiltin} == 0xc0',
+        Condition => '$$self{FlashControlBuiltin} == 3',
         Mask => 0x1f,
         ValueConv => '($val - 9) / 3',
@@ -2586,5 +2601,5 @@
     22.1 => { # CSe3-dc
         Name => 'CommanderInternalTTLCompGroupB',
-        Condition => '$$self{FlashControlBuiltin} == 0xc0',
+        Condition => '$$self{FlashControlBuiltin} == 3',
         Mask => 0x1f,
         ValueConv => '($val - 9) / 3',
@@ -2597,8 +2612,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'AE & Flash',
-            0x40 => 'AE Only',
-            0x80 => 'Flash Only',
-            0xc0 => 'WB Bracketing',
+            0 => 'AE & Flash',
+            1 => 'AE Only',
+            2 => 'Flash Only',
+            3 => 'WB Bracketing',
         },
     },
@@ -2607,8 +2622,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'Flash/Speed',
-            0x10 => 'Flash/Speed/Aperture',
-            0x20 => 'Flash/Aperture',
-            0x30 => 'Flash Only',
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
         },
     },
@@ -2617,6 +2632,6 @@
         Mask => 0x08,
         PrintConv => {
-            0x00 => '0,-,+',
-            0x08 => '-,0,+',
+            0 => '0,-,+',
+            1 => '-,0,+',
         },
     },
@@ -2624,5 +2639,5 @@
         Name => 'ModelingFlash',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     27.1 => { # CSf2-a
@@ -2630,7 +2645,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Select Center Focus Point',
-            0x40 => 'Highlight Active Focus Point',
-            0x80 => 'Not Used',
+            0 => 'Select Center Focus Point',
+            1 => 'Highlight Active Focus Point',
+            2 => 'Not Used',
         },
     },
@@ -2639,8 +2654,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => 'Thumbnail On/Off',
-            0x10 => 'View Histograms',
-            0x20 => 'Zoom On/Off',
-            0x30 => 'Choose Folder',
+            0 => 'Thumbnail On/Off',
+            1 => 'View Histograms',
+            2 => 'Zoom On/Off',
+            3 => 'Choose Folder',
         },
     },
@@ -2649,7 +2664,7 @@
         Mask => 0x0c,
         PrintConv => { #1
-            0x00 => 'Low Magnification',
-            0x04 => 'Medium Magnification',
-            0x08 => 'High Magnification',
+            0 => 'Low Magnification',
+            1 => 'Medium Magnification',
+            2 => 'High Magnification',
         },
     },
@@ -2658,6 +2673,6 @@
         Mask => 0x01,
         PrintConv => {
-            0x00 => 'Do Nothing',
-            0x01 => 'Reset Meter-off Delay',
+            0 => 'Do Nothing',
+            1 => 'Reset Meter-off Delay',
         },
     },
@@ -2666,22 +2681,22 @@
         Mask => 0xf8,
         PrintConv => {
-            0x00 => 'None',
-            0x08 => 'Preview',
-            0x10 => 'FV Lock',
-            0x18 => 'AE/AF Lock',
-            0x20 => 'AE Lock Only',
-            0x28 => 'AE Lock (reset on release)',
-            0x30 => 'AE Lock (hold)',
-            0x38 => 'AF Lock Only',
-            # 0x40 not used
-            0x48 => 'Flash Off',
-            0x50 => 'Bracketing Burst',
-            0x58 => 'Matrix Metering',
-            0x60 => 'Center-weighted Metering',
-            0x68 => 'Spot Metering',
-            0x70 => 'My Menu Top',
-            0x78 => 'Live View',
-            0x80 => '+ NEF (RAW)',
-            0x88 => 'Virtual Horizon',
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            # 8 not used
+            9 => 'Flash Off',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'My Menu Top',
+            15 => 'Live View',
+            16 => '+ NEF (RAW)',
+            17 => 'Virtual Horizon',
         },
     },
@@ -2690,22 +2705,22 @@
         Mask => 0xf8,
         PrintConv => {
-            0x00 => 'None',
-            0x08 => 'Preview',
-            0x10 => 'FV Lock',
-            0x18 => 'AE/AF Lock',
-            0x20 => 'AE Lock Only',
-            0x28 => 'AE Lock (reset on release)',
-            0x30 => 'AE Lock (hold)',
-            0x38 => 'AF Lock Only',
-            0x40 => 'AF-ON',
-            0x48 => 'Flash Off',
-            0x50 => 'Bracketing Burst',
-            0x58 => 'Matrix Metering',
-            0x60 => 'Center-weighted Metering',
-            0x68 => 'Spot Metering',
-            0x70 => 'My Menu Top',
-            0x78 => 'Live View',
-            0x80 => '+ NEF (RAW)',
-            0x88 => 'Virtual Horizon',
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-ON',
+            9 => 'Flash Off',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'My Menu Top',
+            15 => 'Live View',
+            16 => '+ NEF (RAW)',
+            17 => 'Virtual Horizon',
         },
     },
@@ -2715,22 +2730,22 @@
         Mask => 0xf8,
         PrintConv => {
-            0x00 => 'None',
-            0x08 => 'Preview',
-            0x10 => 'FV Lock',
-            0x18 => 'AE/AF Lock',
-            0x20 => 'AE Lock Only',
-            0x28 => 'AE Lock (reset on release)',
-            0x30 => 'AE Lock (hold)',
-            0x38 => 'AF Lock Only',
-            0x40 => 'AF-ON',
-            0x48 => 'Flash Off',
-            0x50 => 'Bracketing Burst',
-            0x58 => 'Matrix Metering',
-            0x60 => 'Center-weighted Metering',
-            0x68 => 'Spot Metering',
-            0x70 => 'My Menu Top',
-            0x78 => 'Live View',
-            0x80 => '+ NEF (RAW)',
-            0x88 => 'Virtual Horizon',
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-ON',
+            9 => 'Flash Off',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'My Menu Top',
+            15 => 'Live View',
+            16 => '+ NEF (RAW)',
+            17 => 'Virtual Horizon',
         },
     },
@@ -2739,12 +2754,12 @@
         Mask => 0x70,
         PrintConv => {
-            0x00 => 'None',
-            0x10 => 'Choose Image Area',
-            0x20 => 'One Step Speed/Aperture',
-            0x30 => 'Choose Non-CPU Lens Number',
-            # n/a  0x40 => 'Focus Point Selection',
-            0x50 => 'Auto bracketing',
-            0x60 => 'Dynamic AF Area',
-            0x70 => 'Shutter speed & Aperture lock',
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'One Step Speed/Aperture',
+            3 => 'Choose Non-CPU Lens Number',
+            # n/a  4 => 'Focus Point Selection',
+            5 => 'Auto bracketing',
+            6 => 'Dynamic AF Area',
+            7 => 'Shutter speed & Aperture lock',
         },
     },
@@ -2753,12 +2768,12 @@
         Mask => 0x07,
         PrintConv => {
-            0x00 => 'None',
-            0x01 => 'Choose Image Area',
-            0x02 => 'One Step Speed/Aperture',
-            0x03 => 'Choose Non-CPU Lens Number',
-            # n/a  0x04 => 'Focus Point Selection',
-            0x05 => 'Auto bracketing',
-            0x06 => 'Dynamic AF Area',
-            0x07 => 'Shutter speed & Aperture lock',
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'One Step Speed/Aperture',
+            3 => 'Choose Non-CPU Lens Number',
+            # n/a  4 => 'Focus Point Selection',
+            5 => 'Auto bracketing',
+            6 => 'Dynamic AF Area',
+            7 => 'Shutter speed & Aperture lock',
         },
     },
@@ -2766,13 +2781,13 @@
         Name => 'AELockButtonPlusDials',
         Mask => 0x70,
-        PrintConv => {
-            0x00 => 'None',
-            0x10 => 'Choose Image Area',
-            0x20 => 'One Step Speed/Aperture',
-            0x30 => 'Choose Non-CPU Lens Number',
-            # n/a  0x40 => 'Focus Point Selection',
-            0x50 => 'Auto bracketing',
-            0x60 => 'Dynamic AF Area',
-            0x70 => 'Shutter speed & Aperture lock',
+        Prinonv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'One Step Speed/Aperture',
+            3 => 'Choose Non-CPU Lens Number',
+            # n/a  4 => 'Focus Point Selection',
+            5 => 'Auto bracketing',
+            6 => 'Dynamic AF Area',
+            7 => 'Shutter speed & Aperture lock',
         },
     },
@@ -2780,10 +2795,10 @@
         Name => 'CommandDialsReverseRotation',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'No', 0x80 => 'Yes' },
+        PrintConv => \%noYes,
     },
     33.2 => { # CSf9-b
         Name => 'CommandDialsChangeMainSub',
         Mask => 0x40,
-        PrintConv => { 0x00 => 'Off', 0x40 => 'On' },
+        PrintConv => \%offOn,
     },
     33.3 => { # CSf9-c
@@ -2791,6 +2806,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Sub-command Dial',
-            0x20 => 'Aperture Ring',
+            0 => 'Sub-command Dial',
+            1 => 'Aperture Ring',
         },
     },
@@ -2798,5 +2813,5 @@
         Name => 'CommandDialsMenuAndPlayback',
         Mask => 0x10,
-        PrintConv => { 0x00 => 'Off', 0x10 => 'On' },
+        PrintConv => \%offOn,
     },
     33.5 => { # CSf12
@@ -2804,6 +2819,6 @@
         Mask => 0x08,
         PrintConv => {
-            0x00 => '+ 0 -',
-            0x08 => '- 0 +',
+            0 => '+ 0 -',
+            1 => '- 0 +',
         },
     },
@@ -2811,5 +2826,5 @@
         Name => 'PhotoInfoPlayback',
         Mask => 0x04,
-        PrintConv => { 0x00 => 'Off', 0x04 => 'On' },
+        PrintConv => \%offOn,
     },
     33.7 => { # CSf11
@@ -2817,6 +2832,6 @@
         Mask => 0x02,
         PrintConv => {
-            0x00 => 'Release Locked',
-            0x02 => 'Enable Release',
+            0 => 'Release Locked',
+            1 => 'Enable Release',
         },
     },
@@ -2824,5 +2839,4456 @@
         Name => 'ReleaseButtonToUseDial',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'No', 0x01 => 'Yes' },
+        PrintConv => \%noYes,
+    },
+);
+
+# D800 custom settings (ref PH)
+%Image::ExifTool::NikonCustom::SettingsD800 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    DATAMEMBER => [ 23.1 ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D800 and D800E.',
+    12.1 => { # CSe5
+        Name => 'AutoBracketingSet',
+        Mask => 0xe0, #(NC)
+        PrintConv => {
+            0 => 'AE & Flash', # default
+            1 => 'AE Only', #(NC)
+            2 => 'Flash Only',
+            3 => 'WB Bracketing', #(NC)
+            4 => 'Active D-Lighting', #(NC)
+        },
+    },
+    12.2 => { # CSe7
+        Name => 'AutoBracketOrder',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '0,-,+',
+            1 => '-,0,+',
+        },
+    },
+    12.3 => { # CSe6
+        Name => 'AutoBracketingMode',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
+        },
+    },
+    # 21 - 100 (MaxContinuousRelease?)
+    22.1 => { # CSe1
+        Name => 'FlashSyncSpeed',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => '1/320 s (auto FP)',
+            1 => '1/250 s (auto FP)',
+            2 => '1/250 s',
+            3 => '1/200 s',
+            4 => '1/160 s',
+            5 => '1/125 s',
+            6 => '1/100 s',
+            7 => '1/80 s',
+            8 => '1/60 s',
+       },
+    },
+    22.2 => { # CSe2
+        Name => 'FlashShutterSpeed',
+        Mask => 0x0f,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
+        },
+    },
+    23.1 => { # CSe3
+        Name => 'FlashControlBuilt-in',
+        Mask => 0xc0,
+        RawConv => '$$self{FlashControlBuiltin} = $val',
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Repeating Flash',
+            3 => 'Commander Mode',
+        },
+    },
+    23.2 => { # CSe3-b
+        Name => 'ManualFlashOutput',
+        Condition => '$$self{FlashControlBuiltin} == 1',
+        Mask => 0x1f,
+        ValueConv => '2 ** (-$val/3)',
+        ValueConvInv => '$val > 0 ? -3*log($val)/log(2) : 0',
+        PrintConv => q{
+            return 'Full' if $val > 0.99;
+            Image::ExifTool::Exif::PrintExposureTime($val);
+        },
+        PrintConvInv => '$val=~/F/i ? 1 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    24.1 => { # CSe3-ca
+        Name => 'RepeatingFlashOutput',
+        Condition => '$$self{FlashControlBuiltin} == 2',
+        Mask => 0x70,
+        ValueConv => '2 ** (-$val-2)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5) : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    24.2 => { # CSe3-cb
+        Name => 'RepeatingFlashCount',
+        Condition => '$$self{FlashControlBuiltin} == 2',
+        Mask => 0x0f,
+        ValueConv => '$val < 10 ? $val + 1 : 5 * ($val - 7)',
+        ValueConvInv => '$val <= 10 ? $val - 1 : $val / 5 + 7',
+    },
+    25.1 => { # CSe3-cc
+        Name => 'RepeatingFlashRate',
+        Condition => '$$self{FlashControlBuiltin} == 2',
+        Mask => 0xf0,
+        ValueConv => '$val < 10 ? $val + 1 : 10 * ($val - 8)',
+        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5)',
+        PrintConv => '"$val Hz"',
+        PrintConvInv => '$val=~/(\d+)/; $1 || 0',
+    },
+    25.2 => { # CSe3
+        Name => 'CommanderChannel',
+        Mask => 0x03,
+        ValueConv => '$val + 1',
+        ValueConvInv => '$val - 1',
+    },
+    27.1 => { # CSe3
+        Name => 'CommanderInternalFlash',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Off',
+        },
+    },
+    27.2 => { # CSe3
+        Name => 'CommanderInternalManualOutput',
+        Mask => 0x1f,
+        ValueConv => '2 ** (-$val/3)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2) * 3 + 0.5): 0',
+        PrintConv => q{
+            return 'Full' if $val > 0.99;
+            Image::ExifTool::Exif::PrintExposureTime($val);
+        },
+        PrintConvInv => '$val=~/F/i ? 1 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    28.1 => { # CSe3
+        Name => 'CommanderGroupAMode',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Auto Aperture',
+            2 => 'Manual',
+            3 => 'Off',
+        },
+    },
+    28.2 => { # CSe3
+        Name => 'CommanderGroupAManualOutput',
+        Mask => 0x1f,
+        ValueConv => '2 ** (-$val/3)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2) * 3 + 0.5): 0',
+        PrintConv => q{
+            return 'Full' if $val > 0.99;
+            Image::ExifTool::Exif::PrintExposureTime($val);
+        },
+        PrintConvInv => '$val=~/F/i ? 1 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    29.1 => { # CSe3
+        Name => 'CommanderGroupBMode',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Auto Aperture',
+            2 => 'Manual',
+            3 => 'Off',
+        },
+    },
+    29.2 => { # CSe3
+        Name => 'CommanderGroupBManualOutput',
+        Mask => 0x1f,
+        ValueConv => '2 ** (-$val/3)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2) * 3 + 0.5): 0',
+        PrintConv => q{
+            return 'Full' if $val > 0.99;
+            Image::ExifTool::Exif::PrintExposureTime($val);
+        },
+        PrintConvInv => '$val=~/F/i ? 1 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    30.1 => { # CSe4
+        Name => 'ModelingFlash',
+        Mask => 0x20,
+        PrintConv => \%onOff,
+    },
+    30.2 => { # CSe3
+        Name => 'CommanderInternalTTLComp',
+        Mask => 0x1f,
+        ValueConv => '($val - 9) / 3',
+        ValueConvInv => '$val * 3 + 9',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    31.1 => { # CSe3
+        Name => 'CommanderGroupA_TTL-AAComp',
+        Mask => 0x1f,
+        ValueConv => '($val - 9) / 3',
+        ValueConvInv => '$val * 3 + 9',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    32.1 => { # CSe3
+        Name => 'CommanderGroupB_TTL-AAComp',
+        Mask => 0x1f,
+        ValueConv => '($val - 9) / 3',
+        ValueConvInv => '$val * 3 + 9',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    # 47 - related to flash
+);
+
+# D5 custom settings (ref 1)
+%Image::ExifTool::NikonCustom::SettingsD5 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D5.',
+    0.1 => {
+        Name => 'CustomSettingsBank',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'A',
+            1 => 'B',
+            2 => 'C',
+            3 => 'D',
+        },
+    },
+    1.1 => { # CSa1
+        Name => 'AF-CPrioritySelection',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Release + Focus',
+            2 => 'Focus',
+            3 => 'Focus + Release',
+        },
+    },
+    1.2 => { # CSa2
+        Name => 'AF-SPrioritySelection',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Focus',
+            1 => 'Release',
+        },
+    },
+    1.3 => { # CSa6
+        Name => 'NumberOfFocusPoints',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '55 Points',
+            1 => '15 Points',
+        },
+    },
+    1.4 => { # CSa4
+        Name => 'Three-DTrackingFaceDetection',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    1.5 => { # CSa3-a
+        Name => 'BlockShotAFResponse',
+        Mask => 0x07,
+        #values 1-5
+    },
+    2.1 => { # CSa11
+        Name => 'FocusPointWrap',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'No Wrap',
+            1 => 'Wrap',
+        },
+    },
+    2.2 => { # CSa12-d
+        Name => 'AFPointBrightness',
+        Mask => 0x06,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
+    4.1 => { # CSd3
+        Name => 'ISODisplay',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'Show ISO Sensitivity',
+            1 => 'Show Frame Count',
+        },
+    },
+    4.2 => { # CSd8
+        Name => 'GridDisplay',
+        Mask => 0x02,
+        PrintConv => \%onOff,
+    },
+    5.1 => { # CSd9
+        Name => 'LCDIllumination',
+        Mask => 0x20,
+        PrintConv => \%offOn,
+    },
+    5.2 => { # CSd6
+        Name => 'ElectronicFront-CurtainShutter',
+        Mask => 0x08,
+        PrintConv => \%offOn,
+    },
+    6.1 => { # CSf7
+        Name => 'ReverseIndicators',
+        Mask => 0x80,
+        PrintConv => {
+            0 => '+ 0 -',
+            1 => '- 0 +',
+        },
+    },
+    6.2 => { # CSf4-a
+        Name => 'CommandDialsReverseRotation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'No',
+            1 => 'Shutter Speed & Aperture',
+            2 => 'Exposure Compensation',
+            3 => 'Exposure Compensation, Shutter Speed & Aperture',
+        },
+    },
+    6.3 => { # CSb4
+        Name => 'EasyExposureCompensation',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (auto reset)',
+        },
+    },
+    7.1 => { # CSb2
+        Name => 'ExposureControlStepSize',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.2 => { # CSb1
+        Name => 'ISOStepSize',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.3 => { # CSb3
+        Name => 'ExposureCompStepSize',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    8.1 => { # CSb6
+        Name => 'CenterWeightedAreaSize',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '8 mm',
+            1 => '12 mm',
+            2 => '15 mm',
+            3 => '20 mm',
+            4 => 'Average',
+        },
+    },
+    8.2 => { # CSb7-a
+        Name => 'FineTuneOptMatrixMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.1 => { # CSb7-b
+        Name => 'FineTuneOptCenterWeighted',
+        Mask => 0xf0,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.2 => { # CSb7-c
+        Name => 'FineTuneOptSpotMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    10.1 => { # CSf2-a
+        Name => 'MultiSelectorShootMode',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'Select Center Focus Point (Reset)',
+            1 => 'Zoom On/Off',  # this is the documented (and actual) default value, but the choice does not appear on the camera menu
+            2 => 'Preset Focus Point (Pre)',
+            4 => 'Not Used (None)',
+        },
+    },
+#    10.2 => { # CSf2-b             # moved from the D500 position to Nikon_ShotInfoD5_0x0ab1 with the Mask and PrintConv as specified below.  Further research required.
+#        Name => 'MultiSelectorPlaybackMode',
+#        Mask => 0x70,
+#        PrintConv => {
+#            0 => 'Zoom On/Off',
+#            1 => 'Choose Folder',
+#            6 => 'Thumbnail On/Off',
+#            7 => 'View Histograms',
+#        },
+#    },
+    10.3 => { # CSf5
+        Name => 'MultiSelector',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'Do Nothing',
+            1 => 'Reset Meter-off Delay',
+        },
+    },
+    11.1 => { # CSd5
+        Name => 'ExposureDelayMode',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Off',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    11.2 => { # CSd1
+        Name => 'CLModeShootingSpeed',
+        Mask => 0x0f,
+        PrintConv => '"$val fps"',
+        PrintConvInv => '$val=~s/\s*fps//i; $val',
+    },
+    12.1 => { # CSd2
+        Name => 'MaxContinuousRelease',
+        # values: 1-100
+    },
+    13.1 => { # CSe7
+        Name => 'AutoBracketOrder',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '0,-,+',
+            1 => '-,0,+',
+        },
+    },
+    13.2 => { # CSe6
+        Name => 'AutoBracketModeM',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
+        },
+    },
+    14.1 => { # CSf1-c
+        Name => 'Func1Button',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+        },
+    },
+    15.1 => { # CSf1-a
+        Name => 'PreviewButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+        },
+    },
+    16.1 => { # CSf1-p
+        Name => 'AssignBktButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Auto Bracketing',
+            1 => 'Multiple Exposure',
+            2 => 'HDR (high dynamic range)',
+            3 => 'None',
+        },
+    },
+    18.1 => { # CSf4-b
+        Name => 'CommandDialsChangeMainSub',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'Autofocus Off, Exposure Off',
+            1 => 'Autofocus Off, Exposure On',
+            2 => 'Autofocus Off, Exposure On (Mode A)',
+            4 => 'Autofocus On, Exposure Off',
+            5 => 'Autofocus On, Exposure On',
+            6 => 'Autofocus On, Exposure On (Mode A)',
+        },
+    },
+    18.2 => { # CSf4-d
+        Name => 'CommandDialsMenuAndPlayback',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'On',
+            1 => 'Off',
+            2 => 'On (Image Review Excluded)',
+        },
+    },
+    18.3 => { # CSf4-c
+        Name => 'CommandDialsApertureSetting',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Sub-command Dial',
+            1 => 'Aperture Ring',
+        },
+    },
+    18.4 => { # CSf6
+        Name => 'ReleaseButtonToUseDial',
+        Mask => 0x01,
+        PrintConv => \%noYes,
+    },
+    19.1 => { # CSc2
+        Name => 'StandbyTimer',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '6 s',
+            3 => '10 s',
+            5 => '30 s',
+            6 => '1 min',
+            7 => '5 min',
+            8 => '10 min',
+            9 => '30 min',
+            10 => 'No Limit',
+        },
+    },
+    20.1 => { # CSc3-a
+        Name => 'SelfTimerTime',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
+        },
+    },
+    20.2 => { # CSc3-c
+        Name => 'SelfTimerShotInterval',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '0.5 s',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    20.3 => { # CSc3-b
+        Name => 'SelfTimerShotCount',
+        Mask => 0x0f,
+    },
+    21.1 => { # CSc4-d
+        Name => 'ImageReviewMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '4 s',
+            3 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    21.2 => { # CSc4-e
+        Name => 'LiveViewMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
+            4 => '20 min',
+            5 => '30 min',
+            6 => 'No Limit',
+        },
+    },
+    22.1 => { # CSc4-b
+        Name => 'MenuMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            2 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    22.2 => { # CSc4-c
+        Name => 'ShootingInfoMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '4 s',
+            2 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    23.1 => { # CSe1
+        Name => 'FlashSyncSpeed',
+        Mask => 0xf0,
+        PrintConv => {
+            2 => '1/250 s (auto FP)',
+            3 => '1/250 s',
+            5 => '1/200 s',
+            6 => '1/160 s',
+            7 => '1/125 s',
+            8 => '1/100 s',
+            9 => '1/80 s',
+            10 => '1/60 s',
+        },
+    },
+    23.2 => { # CSe2
+        Name => 'FlashShutterSpeed',
+        Mask => 0x0f,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
+        },
+    },
+    31.1 => { # CSe5
+        Name => 'ModelingFlash',
+        Mask => 0x20,
+        PrintConv => \%onOff,
+    },
+    36.1 => { # CSc4-a
+        Name => 'PlaybackMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    37.1 => { # CSf2-c
+        Name => 'MultiSelectorLiveView',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Reset',
+            1 => 'Zoom',
+            3 => 'Not Used',
+        },
+    },
+    38.1 => { # CSf3-a
+        Name => 'ShutterSpeedLock',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    38.2 => { # CSf3-b
+        Name => 'ApertureLock',
+        Mask => 0x40,
+        PrintConv => \%offOn,
+    },
+    38.3 => { # CSg1-h
+        Name => 'MovieShutterButton',
+        Mask => 0x10,
+        PrintConv => {
+            0 => 'Take Photo',
+            1 => 'Record Movies',
+        },
+    },
+    38.4 => { # CSe3
+        Name => 'FlashExposureCompArea',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Entire Frame',
+            1 => 'Background Only',
+        },
+    },
+    38.5 => { # CSe4
+        Name => 'AutoFlashISOSensitivity',
+        Mask => 0x02,
+        PrintConv => {
+            0 => 'Subject and Background',
+            1 => 'Subject Only',
+        },
+    },
+    41.1 => { # CSg1-c
+        Name => 'MovieFunc1Button',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'None',
+            2 => 'Power Aperture (close)',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            11 => 'Exposure Compensation -',
+        },
+    },
+    41.2 => { # CSg1-a
+        Name => 'MoviePreviewButton',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Power Aperture (open)',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            10 => 'Exposure Compensation +',
+        },
+    },
+    42.1 => { # CSf1-d
+        Name => 'Func1ButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    43.1 => { # CSf1-b
+        Name => 'PreviewButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',    # new with D500
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    45.1 => { # CSf1-q
+        Name => 'AssignMovieRecordButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            7 => 'Photo Shooting Menu Bank',
+            11 => 'Exposure Mode',
+        },
+    },
+    46.1 => { # CSb7-d
+        Name => 'FineTuneOptHighlightWeighted',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    47.1 => { # CSa12-b
+        Name => 'DynamicAreaAFDisplay',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    47.2 => { # CSa12-a
+        Name => 'AFPointIllumination',
+        Mask => 0x40,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On During Manual Focusing',
+        },
+    },
+    47.3 => { # CSa7
+        Name => 'StoreByOrientation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Focus Point',
+            2 => 'Focus Point and AF-area Mode',
+        },
+    },
+    48.1 => { # CSb5
+        Name => 'MatrixMetering',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Face Detection On',
+            1 => 'Face Detection Off',
+        },
+    },
+    48.2 => { # CSf8
+        Name => 'LiveViewButtonOptions',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Enable',
+            1 => 'Enable (Standby Timer Active)',    # new with D500
+            2 => 'Disable',
+        },
+    },
+    48.3 => { # CSa10
+        Name => 'AFModeRestrictions',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'No Restrictions',
+            1 => 'AF-C',
+            2 => 'AF-S',
+        },
+    },
+    49.1 => { # CSa9
+        Name => 'LimitAFAreaModeSelection',
+        Mask => 0x7e,
+        PrintConv => {
+            0 => 'No Restrictions',
+            BITMASK => {
+                0 => 'Auto-area',
+                1 => 'Group-area',
+                2 => '3D-tracking',
+                3 => 'Dynamic area (153 points)',
+                4 => 'Dynamic area (72 points)',
+                5 => 'Dynamic area (25 points)',
+            },
+        },
+    },
+    52.1 => { # CSf1-r
+        Name => 'LensFocusFunctionButtons',
+        Mask => 0x3f,
+        PrintConv => {
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            24 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+        },
+    },
+    66.1 => { # CSf1-o
+        Name => 'VerticalMultiSelector',
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConv => {
+            0x00 => 'Same as Multi-Selector with Info(U/D) & Playback(R/L)',
+            0x08 => 'Same as Multi-Selector with Info(R/L) & Playback(U/D)',
+            0x80 => 'Focus Point Selection',
+        },
+    },
+    67.1 => { # CSf1-g
+        Name => 'VerticalFuncButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'Reset Focus Point',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            23 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            54 => 'Highlight Active Focus Point',
+        },
+    },
+    68.1 => { # CSf1-h
+        Name => 'VerticalFuncPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',
+            8 => 'Exposure Delay Mode',
+            10 => 'ISO Sensitivity',
+            11 => 'Exposure Mode',
+            12 => 'Exposure Compensation',
+            13 => 'Metering',
+        },
+    },
+    70.1 => { # CSf1-j
+        Name => 'AF-OnButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+        },
+    },
+    71.1 => { # CSf1-k
+        Name => 'SubSelector',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Focus Point Selection',
+            1 => 'Same as MultiSelector',
+        },
+    },
+    72.1 => { # CSf1-l
+        Name => 'SubSelectorCenter',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'Reset Focus Point',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            23 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            54 => 'Highlight Active Focus Point',
+        },
+    },
+    73.1 => { # CSf1-m
+        Name => 'SubSelectorPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            4 => 'Choose Non-CPU Lens Number',
+            7 => 'Photo Shooting Menu Bank',
+        },
+    },
+    74.1 => { # CSg1-f
+        Name => 'AssignMovieSubselector',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'None',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            5 => 'AE/AF Lock',
+            6 => 'AE Lock (Only)',
+            7 => 'AE Lock (Hold)',
+            8 => 'AF Lock (Only)',
+        },
+    },
+    75.1 => { # CSg1-d
+        Name => 'AssignMovieFunc1ButtonPlusDials',
+        Mask => 0x10,
+        PrintConv => {
+            0  => 'None',
+            1  => 'Choose Image Area',
+        },
+    },
+    75.2 => { # CSg1-b
+        Name => 'AssignMoviePreviewButtonPlusDials',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (DX/1.3x)',
+        },
+    },
+    76.1 => { # CSg1-g
+        Name => 'AssignMovieSubselectorPlusDials',
+        Mask => 0x10,
+        PrintConv => {
+            0  => 'None',
+            1  => 'Choose Image Area',
+        },
+    },
+    77.1 => { # CSd4
+        Name => 'SyncReleaseMode',              # new with D500
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'No Sync',
+            1 => 'Sync',
+        },
+    },
+    78.1 => { # CSa5
+        Name => 'Three-DTrackingWatchArea',     # new with D500
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Wide',
+            1 => 'Normal',
+        },
+    },
+    78.2 => { # CSa3-b
+        Name => 'SubjectMotion',
+        Mask => 0x60,
+        PrintConv => {
+            0 => 'Steady',
+            1 => 'Middle',
+            2 => 'Erratic',
+        },
+    },
+    78.3 => { # CSa8
+        Name => 'AFActivation',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'Shutter/AF-On',
+            1 => 'AF-On Only',
+        },
+    },
+    78.4 => { # CSc1
+        Name => 'ShutterReleaseButtonAE-L',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On (Half Press)',
+            2 => 'On (Burst Mode)'
+        },
+    },
+    79.1 => { # CSf1-n
+        Name => 'VerticalAFOnButton',
+        Mask => 0x7f,
+        PrintConv => {
+            0 => 'None',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            100 => 'Same as AF-On',
+        },
+    },
+    80.1 => { # CSf1-e
+        Name => 'Func2Button',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+        },
+    },
+    81.1 => { # CSf1-f
+        Name => 'Func2ButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    82.1 => { # CSg1-e
+        Name => 'AssignMovieFunc2Button',
+        Mask => 0x70,
+        PrintConv => {
+            0 => 'None',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+        },
+    },
+    83.1 => { # CSf1-i
+        Name => 'Func3Button',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Voice Memo',
+            2 => 'Rating',
+            3 => 'Connect To Network',
+        },
+    },
+);
+
+# D500 custom settings (ref 1)
+%Image::ExifTool::NikonCustom::SettingsD500 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D500.',
+    0.1 => {
+        Name => 'CustomSettingsBank',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'A',
+            1 => 'B',
+            2 => 'C',
+            3 => 'D',
+        },
+    },
+    1.1 => { # CSa1
+        Name => 'AF-CPrioritySelection',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Release + Focus',
+            2 => 'Focus',
+            3 => 'Focus + Release',
+        },
+    },
+    1.2 => { # CSa2
+        Name => 'AF-SPrioritySelection',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Focus',
+            1 => 'Release',
+        },
+    },
+    1.3 => { # CSa6
+        Name => 'NumberOfFocusPoints',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '55 Points',
+            1 => '15 Points',
+        },
+    },
+    1.4 => { # CSa4
+        Name => 'Three-DTrackingFaceDetection',
+        Mask => 0x08,
+        PrintConv => \%offOn,
+    },
+    1.5 => { # CSa3-a
+        Name => 'BlockShotAFResponse',
+        Mask => 0x07,
+        #values 1-5
+    },
+    2.1 => { # CSa11
+        Name => 'FocusPointWrap',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'No Wrap',
+            1 => 'Wrap',
+        },
+    },
+    2.2 => { # CSa12-c
+        Name => 'AFPointBrightness',
+        Mask => 0x06,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
+    4.1 => { # CSd3
+        Name => 'ISODisplay',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'Show ISO Sensitivity',
+            1 => 'Show Frame Count',
+        },
+    },
+    4.2 => { # CSd8
+        Name => 'GridDisplay',
+        Mask => 0x02,
+        PrintConv => \%onOff,
+    },
+    5.1 => { # CSd9
+        Name => 'LCDIllumination',
+        Mask => 0x20,
+        PrintConv => \%offOn,
+    },
+    5.2 => { # CSd6
+        Name => 'ElectronicFront-CurtainShutter',
+        Mask => 0x08,
+        PrintConv => \%offOn,
+    },
+    6.1 => { # CSf7
+        Name => 'ReverseIndicators',
+        Mask => 0x80,
+        PrintConv => {
+            0 => '+ 0 -',
+            1 => '- 0 +',
+        },
+    },
+    6.2 => { # CSf4-a
+        Name => 'CommandDialsReverseRotation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'No',
+            1 => 'Shutter Speed & Aperture',
+            2 => 'Exposure Compensation',
+            3 => 'Exposure Compensation, Shutter Speed & Aperture',
+        },
+    },
+    6.3 => { # CSb4
+        Name => 'EasyExposureCompensation',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (auto reset)',
+        },
+    },
+    7.1 => { # CSb2
+        Name => 'ExposureControlStepSize',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.2 => { # CSb1
+        Name => 'ISOStepSize',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.3 => { # CSb3
+        Name => 'ExposureCompStepSize',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    8.1 => { # CSb6
+        Name => 'CenterWeightedAreaSize',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '6 mm',
+            1 => '8 mm',
+            2 => '10 mm',
+            3 => '13 mm',
+            4 => 'Average',
+        },
+    },
+    8.2 => { # CSb7-a
+        Name => 'FineTuneOptMatrixMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.1 => { # CSb7-b
+        Name => 'FineTuneOptCenterWeighted',
+        Mask => 0xf0,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.2 => { # CSb7-c
+        Name => 'FineTuneOptSpotMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    10.1 => { # CSf2-a
+        Name => 'MultiSelectorShootMode',
+        Mask => 0xe0,                       #same offset and settings as D810 but with a different decoding
+        PrintConv => {
+            0 => 'Select Center Focus Point (Reset)',
+            2 => 'Preset Focus Point (Pre)',
+            3 => 'Highlight Active Focus Point',
+            4 => 'Not Used (None)',
+        },
+    },
+    10.2 => { # CSf2-b                      #same offset and settings as D810 but with a different decoding
+        Name => 'MultiSelectorPlaybackMode',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Thumbnail On/Off',
+            1 => 'View Histograms',
+            2 => 'Zoom On/Off',
+            3 => 'Choose Folder',
+        },
+    },
+    10.3 => { # CSf5
+        Name => 'MultiSelector',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'Do Nothing',
+            1 => 'Reset Meter-off Delay',
+        },
+    },
+    11.1 => { # CSd5
+        Name => 'ExposureDelayMode',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Off',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    11.2 => { # CSd1
+        Name => 'CLModeShootingSpeed',
+        Mask => 0x0f,
+        PrintConv => '"$val fps"',
+        PrintConvInv => '$val=~s/\s*fps//i; $val',
+    },
+    12.1 => { # CSd2
+        Name => 'MaxContinuousRelease',
+        # values: 1-100
+    },
+    13.1 => { # CSe7
+        Name => 'AutoBracketOrder',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '0,-,+',
+            1 => '-,0,+',
+        },
+    },
+    13.2 => { # CSe6
+        Name => 'AutoBracketModeM',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
+        },
+    },
+    14.1 => { # CSf1-c
+        Name => 'Func1Button',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+        },
+    },
+    15.1 => { # CSf1-a
+        Name => 'PreviewButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+#           21 => 'Disable Synchronized Release',   # removed with D500
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',                         # new with D500
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',         # new with D500
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',         # new with D500
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',        # new with D500
+            40 => 'AF-Area Mode (Group Area AF)',                  # new with D500
+            41 => 'AF-Area Mode (Auto Area AF)',                   # new with D500
+            42 => 'AF-Area Mode + AF-On (Single)',                 # new with D500
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)', # new with D500
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)', # new with D500
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',# new with D500
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',          # new with D500
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',           # new with D500
+            49 => 'Sync Release (Master Only)',                    # new with D500
+            50 => 'Sync Release (Remote Only)',                    # new with D500
+        },
+    },
+    16.1 => { # CSf1-j
+        Name => 'AssignBktButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Auto Bracketing',
+            1 => 'Multiple Exposure',
+            2 => 'HDR (high dynamic range)',
+            3 => 'None',
+        },
+    },
+    18.1 => { # CSf4-b
+        Name => 'CommandDialsChangeMainSub',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'Autofocus Off, Exposure Off',
+            1 => 'Autofocus Off, Exposure On',
+            2 => 'Autofocus Off, Exposure On (Mode A)',
+            4 => 'Autofocus On, Exposure Off',
+            5 => 'Autofocus On, Exposure On',
+            6 => 'Autofocus On, Exposure On (Mode A)',
+        },
+    },
+    18.2 => { # CSf4-d
+        Name => 'CommandDialsMenuAndPlayback',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'On',
+            1 => 'Off',
+            2 => 'On (Image Review Excluded)',
+        },
+    },
+    18.3 => { # CSf4-c
+        Name => 'CommandDialsApertureSetting',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Sub-command Dial',
+            1 => 'Aperture Ring',
+        },
+    },
+    18.4 => { # CSf6
+        Name => 'ReleaseButtonToUseDial',
+        Mask => 0x01,
+        PrintConv => \%noYes,
+    },
+    19.1 => { # CSc2
+        Name => 'StandbyTimer',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '6 s',
+            3 => '10 s',
+            5 => '30 s',
+            6 => '1 min',
+            7 => '5 min',
+            8 => '10 min',
+            9 => '30 min',
+            10 => 'No Limit',
+        },
+    },
+    20.1 => { # CSc3-a
+        Name => 'SelfTimerTime',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
+        },
+    },
+    20.2 => { # CSc3-c
+        Name => 'SelfTimerShotInterval',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '0.5 s',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    20.3 => { # CSc3-b
+        Name => 'SelfTimerShotCount',
+        Mask => 0x0f,
+    },
+    21.1 => { # CSc4-d
+        Name => 'ImageReviewMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '4 s',
+            3 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    21.2 => { # CSc4-e
+        Name => 'LiveViewMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
+            4 => '20 min',
+            5 => '30 min',
+            6 => 'No Limit',
+        },
+    },
+    22.1 => { # CSc4-b
+        Name => 'MenuMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            2 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    22.2 => { # CSc4-c
+        Name => 'ShootingInfoMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '4 s',
+            2 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    23.1 => { # CSe1
+        Name => 'FlashSyncSpeed',
+        Mask => 0xf0,
+        PrintConv => {
+            2 => '1/250 s (auto FP)',
+            3 => '1/250 s',
+            5 => '1/200 s',
+            6 => '1/160 s',
+            7 => '1/125 s',
+            8 => '1/100 s',
+            9 => '1/80 s',
+            10 => '1/60 s',
+        },
+    },
+    23.2 => { # CSe2
+        Name => 'FlashShutterSpeed',
+        Mask => 0x0f,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
+        },
+    },
+    31.1 => { # CSe5
+        Name => 'ModelingFlash',
+        Mask => 0x20,
+        PrintConv => \%onOff,
+    },
+    36.1 => { # CSc4-a
+        Name => 'PlaybackMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    37.1 => { # CSf2-c
+        Name => 'MultiSelectorLiveView',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Reset',
+            1 => 'Zoom',
+            3 => 'Not Used',
+        },
+    },
+    38.1 => { # CSf3-a
+        Name => 'ShutterSpeedLock',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    38.2 => { # CSf3-b
+        Name => 'ApertureLock',
+        Mask => 0x40,
+        PrintConv => \%offOn,
+    },
+    38.3 => { # CSg1-h
+        Name => 'MovieShutterButton',
+        Mask => 0x10,
+        PrintConv => {
+            0 => 'Take Photo',
+            1 => 'Record Movies',
+        },
+    },
+    38.4 => { # CSe3
+        Name => 'FlashExposureCompArea',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Entire Frame',
+            1 => 'Background Only',
+        },
+    },
+    38.5 => { # CSe4
+        Name => 'AutoFlashISOSensitivity',
+        Mask => 0x02,
+        PrintConv => {
+            0 => 'Subject and Background',
+            1 => 'Subject Only',
+        },
+    },
+    41.1 => { # CSg1-c
+        Name => 'MovieFunc1Button',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'None',
+            2 => 'Power Aperture (close)',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            11 => 'Exposure Compensation -',
+        },
+    },
+    41.2 => { # CSg1-a
+        Name => 'MoviePreviewButton',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Power Aperture (open)',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            10 => 'Exposure Compensation +',
+        },
+    },
+    42.1 => { # CSf1-d
+        Name => 'Func1ButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (DX/1.3x)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    43.1 => { # CSf1-b
+        Name => 'PreviewButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (DX/1.3x)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',    # new with D500
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    45.1 => { # CSf1-k
+        Name => 'AssignMovieRecordButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (DX/1.3x)',
+            2 => 'Shutter Speed & Aperture Lock',
+            7 => 'Photo Shooting Menu Bank',
+            11 => 'Exposure Mode',
+        },
+    },
+    46.1 => { # CSb7-d
+        Name => 'FineTuneOptHighlightWeighted',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    47.1 => { # CSa12-b
+        Name => 'DynamicAreaAFDisplay',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    47.2 => { # CSa12-a
+        Name => 'AFPointIllumination',
+        Mask => 0x40,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On During Manual Focusing',
+        },
+    },
+    47.3 => { # CSa7
+        Name => 'StoreByOrientation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Focus Point',
+            2 => 'Focus Point and AF-area Mode',
+        },
+    },
+    47.4 => { # CSa12-c
+        Name => 'GroupAreaAFIllumination',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Squares',
+            1 => 'Dots',
+        },
+    },
+    48.1 => { # CSb5
+        Name => 'MatrixMetering',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Face Detection On',
+            1 => 'Face Detection Off',
+        },
+    },
+    48.2 => { # CSf8
+        Name => 'LiveViewButtonOptions',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Enable',
+            1 => 'Enable (Standby Timer Active)',    # new with D500
+            2 => 'Disable',
+        },
+    },
+    48.3 => { # CSa10
+        Name => 'AFModeRestrictions',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'No Restrictions',
+            1 => 'AF-C',
+            2 => 'AF-S',
+        },
+    },
+    49.1 => { # CSa9
+        Name => 'LimitAFAreaModeSelection',
+        Mask => 0x7e,
+        PrintConv => {
+            0 => 'No Restrictions',
+            BITMASK => {
+                0 => 'Auto-area',
+                1 => 'Group-area',
+                2 => '3D-tracking',
+                3 => 'Dynamic area (153 points)',
+                4 => 'Dynamic area (72 points)',
+                5 => 'Dynamic area (25 points)',
+            },
+        },
+    },
+    52.1 => { # CSf1-l
+        Name => 'LensFocusFunctionButtons',
+        Mask => 0x3f,
+        PrintConv => {
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            24 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+        },
+    },
+    66.1 => { # CSf10-d
+        Name => 'VerticalMultiSelector',
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConv => {
+            0x00 => 'Same as Multi-Selector with Info(U/D) & Playback(R/L)',
+            0x08 => 'Same as Multi-Selector with Info(R/L) & Playback(U/D)',
+            0x80 => 'Focus Point Selection',
+        },
+    },
+    67.1 => { # CSf10-a
+        Name => 'AssignMB-D17FuncButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'Reset Focus Point',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            23 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            54 => 'Highlight Active Focus Point',
+        },
+    },
+    68.1 => { # CSf10-b
+        Name => 'AssignMB-D17FuncButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (DX/1.3x)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',
+            8 => 'Exposure Delay Mode',
+            10 => 'ISO Sensitivity',
+            11 => 'Exposure Mode',
+            12 => 'Exposure Compensation',
+            13 => 'Metering Mode',
+        },
+    },
+    70.1 => { # CSf1-f
+        Name => 'AF-OnButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+        },
+    },
+    71.1 => { # CSf1-g
+        Name => 'SubSelector',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Focus Point Selection',
+            1 => 'Same as MultiSelector',
+        },
+    },
+    72.1 => { # CSf1-h
+        Name => 'SubSelectorCenter',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'Reset Focus Point',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            23 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            54 => 'Highlight Active Focus Point',
+        },
+    },
+    73.1 => { # CSf1-i
+        Name => 'SubSelectorPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (DX/1.3x)',
+            2 => 'Shutter Speed & Aperture Lock',
+            4 => 'Choose Non-CPU Lens Number',
+            7 => 'Photo Shooting Menu Bank',
+        },
+    },
+    74.1 => { # CSg1-f
+        Name => 'AssignMovieSubselector',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'None',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            5 => 'AE/AF Lock',
+            6 => 'AE Lock (Only)',
+            7 => 'AE Lock (Hold)',
+            8 => 'AF Lock (Only)',
+        },
+    },
+    75.1 => { # CSg1-d
+        Name => 'AssignMovieFunc1ButtonPlusDials',
+        Mask => 0x10,
+        PrintConv => {
+            0  => 'None',
+            1  => 'Choose Image Area (DX/1.3x)',
+        },
+    },
+    75.2 => { # CSg1-b
+        Name => 'AssignMoviePreviewButtonPlusDials',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (DX/1.3x)',
+        },
+    },
+    76.1 => { # CSg1-g
+        Name => 'AssignMovieSubselectorPlusDials',
+        Mask => 0x10,
+        PrintConv => {
+            0  => 'None',
+            1  => 'Choose Image Area (DX/1.3x)',
+        },
+    },
+    77.1 => { # CSd4
+        Name => 'SyncReleaseMode',          # new with D500
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'No Sync',
+            1 => 'Sync',
+        },
+    },
+    78.1 => { # CSa5
+        Name => 'Three-DTrackingWatchArea', # new with D500
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Wide',
+            1 => 'Normal',
+        },
+    },
+    78.2 => { # CSa3-b
+        Name => 'SubjectMotion',
+        Mask => 0x60,
+        PrintConv => {
+            0 => 'Steady',
+            1 => 'Middle',
+            2 => 'Erratic',
+        },
+    },
+    78.3 => { # CSa8
+        Name => 'AFActivation',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'Shutter/AF-On',
+            1 => 'AF-On Only',
+        },
+    },
+    78.4 => { # CSc1
+        Name => 'ShutterReleaseButtonAE-L',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On (Half Press)',
+            2 => 'On (Burst Mode)'
+        },
+    },
+    79.1 => { # CSf10-c
+        Name => 'AssignMB-D17AF-OnButton',
+        Mask => 0x7f,
+        PrintConv => {
+            0 => 'None',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 152 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 152 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            100 => 'Same as Camera AF-On Button',
+        },
+    },
+    80.1 => { # CSf1-e
+        Name => 'Func2Button',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            15 => 'My Menu Top Item',
+            20 => 'My Menu',
+            55 => 'Rating',
+        },
+    },
+    82.1 => { # CSg1-e
+        Name => 'AssignMovieFunc2Button',
+        Mask => 0x70,
+        PrintConv => {
+            0 => 'None',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+        },
+    },
+);
+
+# D610 custom settings (ref forum6942)
+%Image::ExifTool::NikonCustom::SettingsD610 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D610.',
+    0.1 => { #CSa1
+        Name => 'AF-CPrioritySelection',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Focus',
+        },
+    },
+    0.2 => { #CSa2
+        Name => 'AF-SPrioritySelection',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Focus',
+        },
+    },
+    0.3 => { # CSa6
+        Name => 'NumberOfFocusPoints',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '39 Points',
+            1 => '11 Points',
+        },
+    },
+    0.4 => { # CSa3
+        Name => 'FocusTrackingLockOn',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Off',
+            1 => '1 Short',
+            2 => '2',
+            3 => '3 Normal',
+            4 => '4',
+            5 => '5 Long',
+        },
+    },
+    1.1 => { # CSa5
+        Name => 'FocusPointWrap',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'No Wrap',
+            1 => 'Wrap',
+        },
+    },
+    1.2 => { # CSa4
+        Name => 'AFPointIllumination',
+        Mask => 0x06,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
+    1.3 => { # CSa7
+        Name => 'AFAssist',
+        Mask => 0x01,
+        PrintConv => \%onOff,
+    },
+    5.1 => { # CSb3
+        Name => 'EasyExposureCompensation',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On Auto Reset',
+        },
+    },
+    6.1 => { # CSb2
+        Name => 'ExposureControlStep',
+        Mask => 0x40,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+        },
+    },
+    6.2 => { # CSb1
+        Name => 'ISOSensitivityStep',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+        },
+    },
+    7.1 => { # CSb4
+        Name => 'CenterWeightedAreaSize',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '8 mm',
+            1 => '12 mm',
+            2 => '15 mm',
+            3 => '20 mm',
+            4 => 'Average',
+        },
+    },
+    7.2 => { # CSb5-a
+        Name => 'FineTuneOptMatrixMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    8.1 => { # CSb5-b
+        Name => 'FineTuneOptCenterWeighted',
+        Mask => 0xf0,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    8.2 => { # CSb5-c
+        Name => 'FineTuneOptSpotMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    17.1 => { # CSc1
+        Name => 'ShutterReleaseButtonAE-L',
+        Mask => 0x02,
+        PrintConv => \%offOn,
+    },
+    18.1 => { # CSc2
+        Name => 'StandbyTimer',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '6 s',
+            2 => '10 s',
+            3 => '30 s',
+            4 => '1 min',
+            5 => '5 min',
+            6 => '10 min',
+            7 => '30 min',
+            8 => 'No Limit',
+        },
+    },
+    18.2 => { # CSc5
+        Name => 'RemoteOnDuration',
+        Mask => 0x03,
+        PrintConv => {
+            0 => '1 min',
+            1 => '5 min',
+            2 => '10 min',
+            3 => '20 min',
+        },
+    },
+    19.1 => { # CSc3-a
+        Name => 'SelfTimerTime',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
+        },
+    },
+    19.2 => { # CSc3-c
+        Name => 'SelfTimerShotInterval',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '0.5 s',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    19.3 => { # CSc3-b
+        Name => 'SelfTimerShotCount',
+        Mask => 0x0f,
+    },
+    20.1 => { # CSc4-d
+        Name => 'ImageReviewMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '4 s',
+            2 => '10 s',
+            3 => '20 s',
+            4 => '1 min',
+            5 => '5 min',
+            6 => '10 min',
+        },
+    },
+    20.2 => { # CSc4-e
+        Name => 'LiveViewMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '5 min',
+            1 => '10 min',
+            2 => '15 min',
+            3 => '20 min',
+            4 => '30 min',
+            5 => 'No Limit',
+        },
+    },
+    21.1 => { # CSc4-b
+        Name => 'MenuMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s', # default
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    21.2 => { # CSc4-c
+        Name => 'ShootingInfoMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s', # default
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    35.1 => { # CSc4-a
+        Name => 'PlaybackMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+);
+
+# D810 custom settings (ref 1)
+%Image::ExifTool::NikonCustom::SettingsD810 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    DATAMEMBER => [ 24.1 ],
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D810.',
+    0.1 => { # CSf1
+        Name => 'LightSwitch',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'LCD Backlight',
+            1 => 'LCD Backlight and Shooting Information',
+        },
+    },
+    0.2 => {
+        Name => 'CustomSettingsBank',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'A',
+            1 => 'B',
+            2 => 'C',
+            3 => 'D',
+        },
+    },
+    1.1 => { #CSa1
+        Name => 'AF-CPrioritySelection',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Release + Focus',
+            2 => 'Focus',
+        },
+    },
+    1.2 => { # CSa2
+        Name => 'AF-SPrioritySelection',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Focus',
+            1 => 'Release',
+        },
+    },
+    1.3 => { # CSa7
+        Name => 'AFPointSelection',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '51 Points',
+            1 => '11 Points',
+        },
+    },
+    1.4 => { # CSa3
+        Name => 'FocusTrackingLockOn',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Off',
+            1 => '1 (Short)',
+            2 => '2',
+            3 => '3 (Normal)',
+            4 => '4',
+            5 => '5 (Long)',
+        },
+    },
+    2.1 => { # CSa4
+        Name => 'AFActivation',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Shutter/AF-On',
+            1 => 'AF-On Only',
+        },
+    },
+    2.2 => { # CSa7
+        Name => 'FocusPointWrap',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'No Wrap',
+            1 => 'Wrap',
+        },
+    },
+    2.3 => { # CSa6
+        Name => 'AFPointBrightness',
+        Mask => 0x06,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
+    2.4 => { # CSa10
+        Name => 'AFAssist',
+        Mask => 0x01,
+        PrintConv => \%onOff,
+    },
+    3.1 => { # CSd13
+        Name => 'BatteryOrder',
+        Mask => 0x40,
+        PrintConv => {
+            0 => 'MB-D12 First',
+            1 => 'Camera Battery First',
+        },
+    },
+    3.2 => { # CSd12
+        Name => 'MB-D12BatteryType',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'LR6 (AA alkaline)',
+            1 => 'HR6 (AA Ni-MH)',
+            2 => 'FR6 (AA lithium)',
+        },
+    },
+    4.1 => { # CSd1-b
+        Name => 'Pitch',
+        Mask => 0x40,
+        PrintConv => { 0 => 'High', 1 => 'Low' },
+    },
+    4.2 => { # CSf11
+        Name => 'NoMemoryCard',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Release Locked',
+            1 => 'Enable Release',
+        },
+    },
+    4.3 => { # CSd8
+        Name => 'ISODisplay',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Show ISO/Easy ISO',
+            1 => 'Show ISO Sensitivity',
+            3 => 'Show Frame Count',
+        },
+    },
+    4.4 => { # CSd7
+        Name => 'GridDisplay',
+        Mask => 0x02,
+        PrintConv => \%onOff,
+    },
+    5.1 => { # CSd10
+        Name => 'ShootingInfoDisplay',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Not Set', # observed on a new camera prior to applying a setting for the first time
+            1 => 'Auto',
+            2 => 'Manual (dark on light)',
+            3 => 'Manual (light on dark)',
+        },
+    },
+    5.2 => { # CSd11
+        Name => 'LCDIllumination',
+        Mask => 0x20,
+        PrintConv => \%offOn,
+    },
+    5.3 => { # CSd5
+        Name => 'ElectronicFront-CurtainShutter',
+        Mask => 0x08,
+        PrintConv => \%offOn,
+    },
+    5.4 => { # CSd9
+        Name => 'ScreenTips',
+        Mask => 0x04,
+        PrintConv => \%offOn,
+    },
+    5.5 => { # CSd1-a
+        Name => 'Beep',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Medium',
+            3 => 'High',
+        },
+    },
+    6.1 => { # CSf12
+        Name => 'ReverseIndicators',
+        Mask => 0x80,
+        PrintConv => {
+            0 => '+ 0 -',
+            1 => '- 0 +',
+        },
+    },
+    6.2 => { # CSf9-a
+        Name => 'CommandDialsReverseRotation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'No',
+            1 => 'Shutter Speed & Aperture',
+            2 => 'Exposure Compensation',
+            3 => 'Exposure Compensation, Shutter Speed & Aperture',
+        },
+    },
+    6.3 => { # CSb4
+        Name => 'EasyExposureCompensation',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (auto reset)',
+        },
+    },
+    7.1 => { # CSb2
+        Name => 'ExposureControlStepSize',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.2 => { # CSb1
+        Name => 'ISOStepSize',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.3 => { # CSb3
+        Name => 'ExposureCompStepSize',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    8.1 => { # CSb6
+        Name => 'CenterWeightedAreaSize',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '8 mm',
+            1 => '12 mm',
+            2 => '15 mm',
+            3 => '20 mm',
+            4 => 'Average',
+        },
+    },
+    8.2 => { # CSb7-a
+        Name => 'FineTuneOptMatrixMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.1 => { # CSb7-b
+        Name => 'FineTuneOptCenterWeighted',
+        Mask => 0xf0,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.2 => { # CSb7-c
+        Name => 'FineTuneOptSpotMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    10.1 => { # CSf2-a
+        Name => 'MultiSelectorShootMode',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Select Center Focus Point (Reset)',
+            1 => 'Highlight Active Focus Point',
+            2 => 'Preset Focus Point (Pre)',
+            3 => 'Not Used (None)',
+        },
+    },
+    10.2 => { # CSf2-b
+        Name => 'MultiSelectorPlaybackMode',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Thumbnail On/Off',
+            1 => 'View Histograms',
+            2 => 'Zoom On/Off',
+            3 => 'Choose Folder',
+        },
+    },
+    10.3 => { # CSf3
+        Name => 'MultiSelector',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'Do Nothing',
+            1 => 'Reset Meter-off Delay',
+        },
+    },
+    11.1 => { # CSd4
+        Name => 'ExposureDelayMode',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Off',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    11.2 => { # CSd2
+        Name => 'CLModeShootingSpeed',
+        Mask => 0x0f,
+        PrintConv => '"$val fps"',
+        PrintConvInv => '$val=~s/\s*fps//i; $val',
+    },
+    12.1 => { # CSd3
+        Name => 'MaxContinuousRelease',
+        # values: 1-100
+    },
+    13.1 => { # CSe6
+        Name => 'AutoBracketSet',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'AE & Flash',
+            1 => 'AE Only',
+            2 => 'Flash Only',
+            3 => 'WB Bracketing',
+            4 => 'Active D-Lighting',
+        },
+    },
+    13.2 => { # CSe8
+        Name => 'AutoBracketOrder',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '0,-,+',
+            1 => '-,0,+',
+        },
+    },
+    13.3 => { # CSe7
+        Name => 'AutoBracketModeM',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
+        },
+    },
+    14.1 => { # CSf4-a
+        Name => 'FuncButton',
+        Mask => 0x1f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display', # values 19 and 20 are swapped from the D4s encodings
+            20 => 'My Menu',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',    # new value with D810
+        },
+    },
+    15.1 => { # CSf5-a
+        Name => 'PreviewButton',
+        Mask => 0x1f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display', # values 19 and 20 are swapped from the D4s encodings
+            20 => 'My Menu',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',        # new value with D810
+        },
+    },
+    16.1 => { # CSf8
+        Name => 'AssignBktButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Auto Bracketing',
+            1 => 'Multiple Exposure',
+            2 => 'HDR (high dynamic range)',
+            3 => 'None',
+        },
+    },
+    17.1 => { # CSf6-a
+        Name => 'AELockButton',
+        Mask => 0x1f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display', # values 19 and 20 are swapped from the D4s encodings
+            20 => 'My Menu',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',        # new value with D810
+        },
+    },
+    18.1 => { # CSf9-b
+        Name => 'CommandDialsChangeMainSub',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'Autofocus Off, Exposure Off',
+            1 => 'Autofocus Off, Exposure On',
+            2 => 'Autofocus Off, Exposure On (Mode A)',
+            4 => 'Autofocus On, Exposure Off',
+            5 => 'Autofocus On, Exposure On',
+            6 => 'Autofocus On, Exposure On (Mode A)',
+        },
+    },
+    18.2 => { # CSf9-d
+        Name => 'CommandDialsMenuAndPlayback',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'On',
+            1 => 'Off',
+            2 => 'On (Image Review Excluded)',
+        },
+    },
+    18.3 => { # CSf9-c
+        Name => 'CommandDialsApertureSetting',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Sub-command Dial',
+            1 => 'Aperture Ring',
+        },
+    },
+    18.4 => { # CSc1
+        Name => 'ShutterReleaseButtonAE-L',
+        Mask => 0x02,
+        PrintConv => \%offOn,
+    },
+    18.5 => { # CSf10
+        Name => 'ReleaseButtonToUseDial',
+        Mask => 0x01,
+        PrintConv => \%noYes,
+    },
+    19.1 => { # CSc2
+        Name => 'StandbyTimer',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '6 s',
+            3 => '10 s',
+            5 => '30 s',
+            6 => '1 min',
+            7 => '5 min',
+            8 => '10 min',
+            9 => '30 min',
+            10 => 'No Limit', #1
+        },
+    },
+    20.1 => { # CSc3-a
+        Name => 'SelfTimerTime',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
+        },
+    },
+    20.2 => { # CSc3-c
+        Name => 'SelfTimerShotInterval',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '0.5 s',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    20.3 => { # CSc3-b
+        Name => 'SelfTimerShotCount',
+        Mask => 0x0f,
+    },
+    21.1 => { # CSc4-d
+        Name => 'ImageReviewMonitorOffTime',  # note: decode changed from D4s
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '4 s',
+            3 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    21.2 => { # CSc4-e                        # note: decode changed from D4s
+        Name => 'LiveViewMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
+            4 => '20 min',
+            5 => '30 min',
+            6 => 'No Limit',
+        },
+    },
+    22.1 => { # CSc4-b                        # note: decode changed from D4s
+        Name => 'MenuMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            2 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    22.2 => { # CSc4-c                        # note: decode changed from D4s
+        Name => 'ShootingInfoMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '4 s',
+            2 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    23.1 => { # CSe1
+        Name => 'FlashSyncSpeed',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => '1/320 s (auto FP)',
+            2 => '1/250 s (auto FP)',
+            3 => '1/250 s',
+            5 => '1/200 s',
+            6 => '1/160 s',
+            7 => '1/125 s',
+            8 => '1/100 s',
+            9 => '1/80 s',
+            10 => '1/60 s',
+        },
+    },
+    23.2 => { # CSe2
+        Name => 'FlashShutterSpeed',
+        Mask => 0x0f,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
+        },
+    },
+    24.1 => { # CSe3
+        Name => 'FlashControlBuilt-in',
+        Mask => 0xc0,
+        RawConv => '$$self{FlashControlBuiltin} = $val',
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Repeating Flash',
+            3 => 'Commander Mode',
+        },
+    },
+    31.1 => { # CSe5
+        Name => 'ModelingFlash',
+        Mask => 0x20,
+        PrintConv => \%onOff,
+    },
+    36.1 => { # CSc4-a
+        Name => 'PlaybackMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    37.1 => { # CSf2-c
+        Name => 'MultiSelectorLiveView',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Reset',
+            1 => 'Zoom',
+            3 => 'Not Used',
+        },
+    },
+    38.1 => { # CSf7-a
+        Name => 'ShutterSpeedLock',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    38.2 => { # CSf7-b
+        Name => 'ApertureLock',
+        Mask => 0x40,
+        PrintConv => \%offOn,
+    },
+    38.3 => { # CSg4
+        Name => 'MovieShutterButton',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Take Photo',
+            1 => 'Record Movies',
+        },
+    },
+    38.4 => { # CSe4
+        Name => 'FlashExposureCompArea',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Entire frame',
+            1 => 'Background only',
+        },
+    },
+    40.1 => { # CSg3
+        Name => 'MovieAELockButtonAssignment',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            5 => 'AE/AF Lock',
+            6 => 'AE Lock Only',
+            7 => 'AE Lock (hold)',
+            8 => 'AF Lock Only',
+        },
+    },
+    41.1 => { # CSg1
+        Name => 'MovieFunctionButton',
+        Mask => 0x70,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Power Aperture (open)', # bit '02' is also toggled on for this setting
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+        },
+    },
+    41.2 => { # CSg2
+        Name => 'MoviePreviewButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'None',
+            2 => 'Power Aperture (open)', # bit '10' is also toggled on for this setting
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+        },
+    },
+    42.1 => { # CSf4-b
+        Name => 'FuncButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    43.1 => { # CSf5-b
+        Name => 'PreviewButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    44.1 => { # CSf6-b
+        Name => 'AELockButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            4 => 'Choose Non-CPU Lens Number',
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    45.1 => { # CSf13
+        Name => 'AssignMovieRecordButton',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            9 => 'White Balance',
+            10 => 'ISO Sensitivity',
+        },
+    },
+    46.1 => { # CSb7-d
+        Name => 'FineTuneOptHighlightWeighted',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    47.1 => { # CSa5-b
+        Name => 'DynamicAreaAFDisplay',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    47.2 => { # CSa5-a              # moved with D810
+        Name => 'AFPointIllumination',
+        Mask => 0x40,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On During Manual Focusing',
+        },
+    },
+    47.3 => { # CSa9
+        Name => 'StoreByOrientation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Focus Point',
+            2 => 'Focus Point and AF-area mode',
+        },
+    },
+    47.4 => { # CSa5-c
+        Name => 'GroupAreaAFIllumination',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Squares',      # moved with D810
+            1 => 'Dots',
+        },
+    },
+    48.1 => { # CSb5
+        Name => 'MatrixMetering',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Face Detection On',
+            1 => 'Face Detection Off',
+        },
+    },
+    48.2 => { # CSf14
+        Name => 'LiveViewButtonOptions',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Enable',
+            2 => 'Disable',
+        },
+    },
+    48.3 => { # CSa12
+        Name => 'AFModeRestrictions',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'No Restrictions',
+            1 => 'AF-C',
+            2 => 'AF-S',
+        },
+    },
+    49.1 => { # CSa11
+        Name => 'LimitAFAreaModeSelection',
+        Mask => 0x7e,
+        PrintConv => {
+            0 => 'No Restrictions',
+            BITMASK => {
+                0 => 'Auto-area',
+                1 => 'Group-area',
+                2 => '3D-tracking',
+                3 => 'Dynamic area (51 points)',
+                4 => 'Dynamic area (21 points)',
+                5 => 'Dynamic area (9 points)',
+            },
+        },
+    },
+    50.1 => { # CSf15
+        Name => 'AF-OnForMB-D12',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'AE/AF Lock',
+            1 => 'AE Lock Only',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (hold)',
+            4 => 'AE Lock (reset)',
+            5 => 'AF-On',
+            6 => 'FV Lock',
+            7 => 'Same As Fn Button',
+        },
+    },
+    51.1 => { # CSf16
+        Name => 'AssignRemoteFnButton',
+        Mask => 0x1f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            16 => '+NEF(RAW)',
+            25 => 'Live View',
+            26 => 'Flash Disable/Enable',
+        },
+    },
+    52.1 => { # CSf17
+        Name => 'LensFocusFunctionButtons',
+        Mask => 0x3f,
+        PrintConv => {
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            7 => 'AF Lock Only',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            24 => 'Preset focus Point',
+            26 => 'Flash Disable/Enable',
+            32 => 'AF-Area Mode:  Single-point AF',
+            33 => 'AF-Area Mode: Dynamic-area AF (9 points)',
+            34 => 'AF-Area Mode: Dynamic-area AF (21 points)',
+            35 => 'AF-Area Mode: Dynamic-area AF (51 points)',
+            36 => 'AF-Area Mode: Group-area AF',
+            37 => 'AF-Area Mode: Auto area AF',
+        },
+    },
+);
+
+# D850 custom settings (ref 1)
+%Image::ExifTool::NikonCustom::SettingsD850 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D850.',
+    0.2 => {
+        Name => 'CustomSettingsBank',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'A',
+            1 => 'B',
+            2 => 'C',
+            3 => 'D',
+        },
+    },
+    1.1 => { #CSa1
+        Name => 'AF-CPrioritySelection',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Release + Focus',
+            2 => 'Focus',
+            3 => 'Focus + Release',
+        },
+    },
+    1.2 => { # CSa2
+        Name => 'AF-SPrioritySelection',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Focus',
+            1 => 'Release',
+        },
+    },
+    1.3 => { # CSa6
+        Name => 'AFPointSelection',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '55 Points',
+            1 => '15 Points',
+        },
+    },
+    1.4 => { # CSa4
+        Name => 'Three-DTrackingFaceDetection',
+        Mask => 0x08,
+        PrintConv => \%offOn,
+    },
+    1.5 => { # CSa3-a
+        Name => 'BlockShotAFResponse',
+        Mask => 0x07,
+        PrintConv => {
+            1 => '1 (Quick)',
+            2 => '2',
+            3 => '3 (Normal)',
+            4 => '4',
+            5 => '5 (Delay)',
+        },
+    },
+    2.1 => { # CSa11
+        Name => 'FocusPointWrap',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'No Wrap',
+            1 => 'Wrap',
+        },
+    },
+    2.2 => { # CSa12-a
+        Name => 'AFPointBrightness',
+        Mask => 0x06,
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
+    4.1 => { # CSd3
+        Name => 'ISODisplay',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'Show ISO Sensitivity',
+            1 => 'Show Frame Count',
+        },
+    },
+    4.2 => { # CSd9
+        Name => 'GridDisplay',
+        Mask => 0x02,
+        PrintConv => \%onOff,
+    },
+    5.1 => { # CSd10
+        Name => 'LCDIllumination',
+        Mask => 0x20,
+        PrintConv => \%offOn,
+    },
+    5.2 => { # CSd6
+        Name => 'ElectronicFront-CurtainShutter',
+        Mask => 0x08,
+        PrintConv => \%offOn,
+    },
+    6.1 => { # CSf7
+        Name => 'ReverseIndicators',
+        Mask => 0x80,
+        PrintConv => {
+            0 => '+ 0 -',
+            1 => '- 0 +',
+        },
+    },
+    6.2 => { # CSf4-a
+        Name => 'CommandDialsReverseRotation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'No',
+            1 => 'Shutter Speed & Aperture',
+            2 => 'Exposure Compensation',
+            3 => 'Exposure Compensation, Shutter Speed & Aperture',
+        },
+    },
+    6.3 => { # CSb4
+        Name => 'EasyExposureCompensation',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (Auto Reset)',
+        },
+    },
+    7.1 => { # CSb2
+        Name => 'ExposureControlStepSize',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.2 => { # CSb1
+        Name => 'ISOStepSize',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.3 => { # CSb3
+        Name => 'ExposureCompStepSize',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    8.1 => { # CSb6
+        Name => 'CenterWeightedAreaSize',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '8 mm',
+            1 => '12 mm',
+            2 => '15 mm',
+            3 => '20 mm',
+            4 => 'Average',
+        },
+    },
+    8.2 => { # CSb7-a
+        Name => 'FineTuneOptMatrixMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.1 => { # CSb7-b
+        Name => 'FineTuneOptCenterWeighted',
+        Mask => 0xf0,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.2 => { # CSb7-c
+        Name => 'FineTuneOptSpotMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    10.1 => { # CSf2-a
+        Name => 'MultiSelectorShootMode',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'Select Center Focus Point (Reset)',
+            2 => 'Preset Focus Point (Pre)',
+            3 => 'Highlight Active Focus Point',
+            4 => 'Not Used (None)',
+        },
+    },
+    10.2 => { # CSf2-b
+        Name => 'MultiSelectorPlaybackMode',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Thumbnail On/Off',
+            1 => 'View Histograms',
+            2 => 'Zoom On/Off',
+            3 => 'Choose Folder',
+        },
+    },
+    10.3 => { # CSf5
+        Name => 'MultiSelector',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'Do Nothing',
+            1 => 'Reset Meter-off Delay',
+        },
+    },
+    11.1 => { # CSd5
+        Name => 'ExposureDelayMode',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'Off',
+            1 => '0.2 s',          #new with the D850
+            2 => '0.5 s',          #new with the D850
+            3 => '1 s',
+            4 => '2 s',
+            5 => '3 s',
+        },
+    },
+    11.2 => { # CSd1
+        Name => 'CLModeShootingSpeed',
+        Mask => 0x0f,
+        PrintConv => '"$val fps"',
+        PrintConvInv => '$val=~s/\s*fps//i; $val',
+    },
+    12.1 => { # CSd2
+        Name => 'MaxContinuousRelease',
+        # values: 1-100
+    },
+    13.1 => { # CSe7
+        Name => 'AutoBracketOrder',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '0,-,+',
+            1 => '-,0,+',
+        },
+    },
+    13.2 => { # CSe6
+        Name => 'AutoBracketModeM',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
+        },
+    },
+    14.1 => { # CSf1-c
+        Name => 'Func1Button',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 153 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 153 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            56 => 'AF-Area Mode (Dynamic Area 9 Points)',
+            57 => 'AF-Area Mode + AF-On (Dynamic Area 9 Points)',
+        },
+    },
+    15.1 => { # CSf1-a
+        Name => 'PreviewButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 153 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 153 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            56 => 'AF-Area Mode (Dynamic Area 9 Points)',
+            57 => 'AF-Area Mode + AF-On (Dynamic Area 9 Points)',
+        },
+    },
+    16.1 => { # CSf1-j
+        Name => 'AssignBktButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Auto Bracketing',
+            1 => 'Multiple Exposure',
+            2 => 'HDR (high dynamic range)',
+            3 => 'None',
+        },
+    },
+    18.1 => { # CSf4-b
+        Name => 'CommandDialsChangeMainSub',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'Autofocus Off, Exposure Off',
+            1 => 'Autofocus Off, Exposure On',
+            2 => 'Autofocus Off, Exposure On (Mode A)',
+            4 => 'Autofocus On, Exposure Off',
+            5 => 'Autofocus On, Exposure On',
+            6 => 'Autofocus On, Exposure On (Mode A)',
+        },
+    },
+    18.2 => { # CSf4-d
+        Name => 'CommandDialsMenuAndPlayback',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'On',
+            1 => 'Off',
+            2 => 'On (Image Review Excluded)',
+        },
+    },
+    18.3 => { # CSf4-c
+        Name => 'CommandDialsApertureSetting',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Sub-command Dial',
+            1 => 'Aperture Ring',
+        },
+    },
+    18.4 => { # CSf6
+        Name => 'ReleaseButtonToUseDial',
+        Mask => 0x01,
+        PrintConv => \%noYes,
+    },
+    19.1 => { # CSc2
+        Name => 'StandbyTimer',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '6 s',
+            3 => '10 s',
+            5 => '30 s',
+            6 => '1 min',
+            7 => '5 min',
+            8 => '10 min',
+            9 => '30 min',
+            10 => 'No Limit',
+        },
+    },
+    20.1 => { # CSc3-a
+        Name => 'SelfTimerTime',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
+        },
+    },
+    20.2 => { # CSc3-c
+        Name => 'SelfTimerShotInterval',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '0.5 s',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    20.3 => { # CSc3-b
+        Name => 'SelfTimerShotCount',
+        Mask => 0x0f,
+    },
+    21.1 => { # CSc4-d
+        Name => 'ImageReviewMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '4 s',
+            3 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    21.2 => { # CSc4-e
+        Name => 'LiveViewMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
+            4 => '20 min',
+            5 => '30 min',
+            6 => 'No Limit',
+        },
+    },
+    22.1 => { # CSc4-b
+        Name => 'MenuMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            2 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    22.2 => { # CSc4-c
+        Name => 'ShootingInfoMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '4 s',
+            2 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    23.1 => { # CSe1
+        Name => 'FlashSyncSpeed',
+        Mask => 0xf0,
+        PrintConv => {
+            2 => '1/250 s (auto FP)',
+            3 => '1/250 s',
+            5 => '1/200 s',
+            6 => '1/160 s',
+            7 => '1/125 s',
+            8 => '1/100 s',
+            9 => '1/80 s',
+            10 => '1/60 s',
+        },
+    },
+    23.2 => { # CSe2
+        Name => 'FlashShutterSpeed',
+        Mask => 0x0f,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
+        },
+    },
+    31.1 => { # CSe5
+        Name => 'ModelingFlash',
+        Mask => 0x20,
+        PrintConv => \%onOff,
+    },
+    36.1 => { # CSc4-a
+        Name => 'PlaybackMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    37.1 => { # CSf2-c
+        Name => 'MultiSelectorLiveView',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Reset',
+            1 => 'Zoom',
+            3 => 'Not Used',
+        },
+    },
+    38.1 => { # CSf3-a
+        Name => 'ShutterSpeedLock',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    38.2 => { # CSf3-b
+        Name => 'ApertureLock',
+        Mask => 0x40,
+        PrintConv => \%offOn,
+    },
+    38.3 => { # CSg1-h
+        Name => 'MovieShutterButton',
+        Mask => 0x10,
+        PrintConv => {
+            0 => 'Take Photo',
+            1 => 'Record Movies',
+        },
+    },
+    38.4 => { # CSe3
+        Name => 'FlashExposureCompArea',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Entire Frame',
+            1 => 'Background Only',
+        },
+    },
+    38.5 => { # CSe4
+        Name => 'AutoFlashISOSensitivity',
+        Mask => 0x02,
+        PrintConv => {
+            0 => 'Subject and Background',
+            1 => 'Subject Only',
+        },
+    },
+    41.1 => { # CSg1-c
+        Name => 'MovieFunc1Button',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'None',
+            2 => 'Power Aperture (close)',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            11 => 'Exposure Compensation -',
+        },
+    },
+    41.2 => { # CSg1-a
+        Name => 'MoviePreviewButton',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Power Aperture (open)',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            10 => 'Exposure Compensation +',
+        },
+    },
+    42.1 => { # CSf1-d
+        Name => 'Func1ButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    43.1 => { # CSf1-b
+        Name => 'PreviewButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',
+            8 => 'Exposure Delay Mode',
+        },
+    },
+    45.1 => { # CSf1-k
+        Name => 'AssignMovieRecordButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            7 => 'Photo Shooting Menu Bank',
+            11 => 'Exposure Mode',
+        },
+    },
+    46.1 => { # CSb7-d
+        Name => 'FineTuneOptHighlightWeighted',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    47.1 => { # CSa12-c
+        Name => 'DynamicAreaAFDisplay',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    47.2 => { # CSa12-b
+        Name => 'AFPointIllumination',
+        Mask => 0x40,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On During Manual Focusing',
+        },
+    },
+    47.3 => { # CSa7
+        Name => 'StoreByOrientation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Focus Point',
+            2 => 'Focus Point and AF-area Mode',
+        },
+    },
+    48.1 => { # CSb5
+        Name => 'MatrixMetering',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Face Detection On',
+            1 => 'Face Detection Off',
+        },
+    },
+    48.2 => { # CSf8
+        Name => 'LiveViewButtonOptions',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Enable',
+            1 => 'Enable (Standby Timer Active)',
+            2 => 'Disable',
+        },
+    },
+    48.3 => { # CSa10
+        Name => 'AFModeRestrictions',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'No Restrictions',
+            1 => 'AF-C',
+            2 => 'AF-S',
+        },
+    },
+    49.1 => { # CSa9
+        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 => {
+                0 => 'Auto-area',
+                1 => 'Group-area',
+                2 => '3D-tracking',
+                3 => 'Dynamic area (153 points)',
+                4 => 'Dynamic area (72 points)',
+                5 => 'Dynamic area (25 points)',
+          },
+        },
+    },
+    52.1 => { # CSf1-l
+        Name => 'LensFocusFunctionButtons',
+        Mask => 0x3f,
+        PrintConv => {
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            24 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 153 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 153 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            56 => 'AF-Area Mode (Dynamic Area 9 Points)',
+            57 => 'AF-Area Mode + AF-On (Dynamic Area 9 Points)',
+        },
+    },
+    66.1 => { # CSf10-d
+        Name => 'VerticalMultiSelector',
+        Mask => 0xff,
+        PrintHex => 1,
+        PrintConv => {
+            0x00 => 'Same as Multi-Selector with Info(U/D) & Playback(R/L)',
+            0x08 => 'Same as Multi-Selector with Info(R/L) & Playback(U/D)',
+            0x80 => 'Focus Point Selection',
+        },
+    },
+    67.1 => { # CSf10-a
+        Name => 'AssignMB-D18FuncButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'Reset Focus Point',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            23 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 153 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 153 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            54 => 'Highlight Active Focus Point',
+            56 => 'AF-Area Mode (Dynamic Area 9 Points)',
+            57 => 'AF-Area Mode + AF-On (Dynamic Area 9 Points)',
+        },
+    },
+    68.1 => { # CSf10-b
+        Name => 'AssignMB-D18FuncButtonPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            7 => 'Photo Shooting Menu Bank',
+            8 => 'Exposure Delay Mode',
+            10 => 'ISO Sensitivity',
+            11 => 'Exposure Mode',
+            12 => 'Exposure Compensation',
+            13 => 'Metering Mode',
+        },
+    },
+    70.1 => { # CSf1-f
+        Name => 'AF-OnButton',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 153 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 153 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            56 => 'AF-Area Mode (Dynamic Area 9 Points)',
+            57 => 'AF-Area Mode + AF-On (Dynamic Area 9 Points)',
+        },
+    },
+    71.1 => { # CSf1-g
+        Name => 'SubSelector',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Focus Point Selection',
+            1 => 'Same as MultiSelector',
+        },
+    },
+    72.1 => { # CSf1-h
+        Name => 'SubSelectorCenter',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'Reset Focus Point',
+            19 => 'Grid Display',
+            20 => 'My Menu',
+            22 => 'Remote Release Only',
+            23 => 'Preset Focus Point',
+            26 => 'Flash Disable/Enable',
+            27 => 'Highlight-weighted Metering',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 153 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 153 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            49 => 'Sync Release (Master Only)',
+            50 => 'Sync Release (Remote Only)',
+            54 => 'Highlight Active Focus Point',
+            56 => 'AF-Area Mode (Dynamic Area 9 Points)',
+            57 => 'AF-Area Mode + AF-On (Dynamic Area 9 Points)',
+        },
+    },
+    73.1 => { # CSf1-i
+        Name => 'SubSelectorPlusDials',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+            2 => 'Shutter Speed & Aperture Lock',
+            4 => 'Choose Non-CPU Lens Number',
+            7 => 'Photo Shooting Menu Bank',
+        },
+    },
+    74.1 => { # CSg1-f
+        Name => 'AssignMovieSubselector',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'None',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+            5 => 'AE/AF Lock',
+            6 => 'AE Lock (Only)',
+            7 => 'AE Lock (Hold)',
+            8 => 'AF Lock (Only)',
+        },
+    },
+    75.1 => { # CSg1-d
+        Name => 'AssignMovieFunc1ButtonPlusDials',
+        Mask => 0x10,
+        PrintConv => {
+            0  => 'None',
+            1  => 'Choose Image Area',
+        },
+    },
+    75.2 => { # CSg1-b
+        Name => 'AssignMoviePreviewButtonPlusDials',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+        },
+    },
+    76.1 => { # CSg1-g
+        Name => 'AssignMovieSubselectorPlusDials',
+        Mask => 0x10,
+        PrintConv => {
+            0  => 'None',
+            1  => 'Choose Image Area',
+        },
+    },
+    77.1 => { # CSd4
+        Name => 'SyncReleaseMode',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'No Sync',
+            1 => 'Sync',
+        },
+    },
+    77.2 => { # CSd11 (new with D850)
+        Name => 'ContinuousModeLiveView',
+        Mask => 0x40,
+        PrintConv => \%offOn,
+    },
+    78.1 => { # CSa5
+        Name => 'Three-DTrackingWatchArea',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Wide',
+            1 => 'Normal',
+        },
+    },
+    78.2 => { # CSa3-b
+        Name => 'SubjectMotion',
+        Mask => 0x60,
+        PrintConv => {
+            0 => 'Steady',
+            1 => 'Middle',
+            2 => 'Erratic',
+        },
+    },
+    78.3 => { # CSa8
+        Name => 'AFActivation',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'Shutter/AF-On',
+            1 => 'AF-On Only',
+        },
+    },
+    78.4 => { # CSc1
+        Name => 'ShutterReleaseButtonAE-L',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On (Half Press)',
+            2 => 'On (Burst Mode)'
+        },
+    },
+    79.1 => { # CSf10-c
+        Name => 'AssignMB-D18AF-OnButton',
+        Mask => 0x7f,
+        PrintConv => {
+            0 => 'None',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            36 => 'AF-Area Mode (Single)',
+            37 => 'AF-Area Mode (Dynamic Area 25 Points)',
+            38 => 'AF-Area Mode (Dynamic Area 72 Points)',
+            39 => 'AF-Area Mode (Dynamic Area 153 Points)',
+            40 => 'AF-Area Mode (Group Area AF)',
+            41 => 'AF-Area Mode (Auto Area AF)',
+            42 => 'AF-Area Mode + AF-On (Single)',
+            43 => 'AF-Area Mode + AF-On (Dynamic Area 25 Points)',
+            44 => 'AF-Area Mode + AF-On (Dynamic Area 72 Points)',
+            45 => 'AF-Area Mode + AF-On (Dynamic Area 153 Points)',
+            46 => 'AF-Area Mode + AF-On (Group Area AF)',
+            47 => 'AF-Area Mode + AF-On (Auto Area AF)',
+            56 => 'AF-Area Mode (Dynamic Area 9 Points)',
+            57 => 'AF-Area Mode + AF-On (Dynamic Area 9 Points)',
+            100 => 'Same as Camera AF-On Button',
+        },
+    },
+    80.1 => { # CSf1-e
+        Name => 'Func2Button',
+        Mask => 0x3f,
+        PrintConv => {
+            0 => 'None',
+            15 => 'My Menu Top Item',
+            20 => 'My Menu',
+            55 => 'Rating',
+        },
+    },
+    82.1 => { # CSg1-e
+        Name => 'AssignMovieFunc2Button',
+        Mask => 0x70,
+        PrintConv => {
+            0 => 'None',
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+        },
     },
 );
@@ -2843,8 +7309,8 @@
         Mask => 0x60,
         PrintConv => {
-            0x00 => 'Single Area',
-            0x20 => 'Dynamic Area',
-            0x40 => 'Auto-area',
-            0x60 => '3D-tracking (11 points)',
+            0 => 'Single Area',
+            1 => 'Dynamic Area',
+            2 => 'Auto-area',
+            3 => '3D-tracking (11 points)',
         },
     },
@@ -2852,8 +7318,5 @@
         Name => 'AFAssist',
         Mask => 0x01,
-        PrintConv => {
-            0 => 'On',
-            1 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     2.1 => { # CSd1
@@ -2861,7 +7324,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Off',
-            0x40 => 'Low',
-            0x80 => 'High',
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'High',
         },
     },
@@ -2869,16 +7332,10 @@
         Name => 'GridDisplay',
         Mask => 0x02,
-        PrintConv => {
-            0x00 => 'On',
-            0x02 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     2.3 => { # CSd3
         Name => 'ISODisplay',
         Mask => 0x08,
-        PrintConv => {
-            0x08 => 'Off',
-            0x00 => 'On',
-        },
+        PrintConv => \%onOff,
     },
     2.4 => { # CSf4
@@ -2886,6 +7343,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Release Locked',
-            0x20 => 'Enable Release',
+            0 => 'Release Locked',
+            1 => 'Enable Release',
         },
     },
@@ -2893,18 +7350,15 @@
         Name => 'FileNumberSequence',
         Mask => 0x08,
-        PrintConv => { 0x00 => 'On', 0x08 => 'Off' },
+        PrintConv => \%onOff,
     },
     4.1 => { # CSa4
         Name => 'RangeFinder',
         Mask => 0x10,
-        PrintConv => { 0x00 => 'Off', 0x10 => 'On' },
+        PrintConv => \%offOn,
     },
     4.2 => { # CSd6
         Name => 'DateImprint',
         Mask => 0x08,
-        PrintConv => {
-            0x00 => 'Off',
-            0x08 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     4.3 => { # CSf5
@@ -2912,6 +7366,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => '+ 0 -',
-            0x80 => '- 0 +',
+            0 => '+ 0 -',
+            1 => '- 0 +',
         },
     },
@@ -2920,6 +7374,6 @@
         Mask => 0x40,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x40 => '1/2 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
         },
     },
@@ -2927,8 +7381,5 @@
         Name => 'ExposureDelayMode',
         Mask => 0x40,
-        PrintConv => {
-            0x00 => 'Off',
-            0x40 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     11.1 => { # CSe2
@@ -2936,7 +7387,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Exposure',
-            0x40 => 'Active D-Lighting', #(NC)
-            0x80 => 'WB Bracketing',
+            0 => 'Exposure',
+            # (NOTE: the following are reversed in the D5100 -- is this correct?)
+            1 => 'Active D-Lighting', #(NC)
+            2 => 'WB Bracketing',
         },
     },
@@ -2945,12 +7397,12 @@
         Mask => 0x38,
         PrintConv => {
-            0x00 => 'Self-timer',
-            0x08 => 'Release Mode',
-            0x10 => 'Image Quality/Size', #(NC)
-            0x18 => 'ISO', #(NC)
-            0x20 => 'White Balance', #(NC)
-            0x28 => 'Active D-Lighting', #(NC)
-            0x30 => '+ NEF (RAW)',
-            0x38 => 'Auto Bracketing',
+            0 => 'Self-timer',
+            1 => 'Release Mode',
+            2 => 'Image Quality/Size', #(NC)
+            3 => 'ISO', #(NC)
+            4 => 'White Balance', #(NC)
+            5 => 'Active D-Lighting', #(NC)
+            6 => '+ NEF (RAW)',
+            7 => 'Auto Bracketing',
         },
     },
@@ -2959,9 +7411,9 @@
         Mask => 0x38,
         PrintConv => {
-            0x00 => 'AE/AF Lock',
-            0x08 => 'AE Lock Only', #(NC)
-            0x10 => 'AF Lock Only', #(NC)
-            0x18 => 'AE Lock (hold)',
-            0x20 => 'AF-ON',
+            0 => 'AE/AF Lock',
+            1 => 'AE Lock Only', #(NC)
+            2 => 'AF Lock Only', #(NC)
+            3 => 'AE Lock (hold)',
+            4 => 'AF-ON',
         },
     },
@@ -2969,10 +7421,10 @@
         Name => 'ShutterReleaseButtonAE-L',
         Mask => 0x02,
-        PrintConv => { 0x00 => 'Off', 0x02 => 'On' },
+        PrintConv => \%offOn,
     },
     16.2 => { # CSf3
         Name => 'CommandDialsReverseRotation',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'No', 0x80 => 'Yes' },
+        PrintConv => \%noYes,
     },
     17.1 => { # CSc2-c
@@ -2980,9 +7432,9 @@
         Mask => 0x70,
         PrintConv => {
-            0x00 => '4 s',
-            0x10 => '8 s',
-            0x20 => '20 s',
-            0x30 => '1 min',
-            0x40 => '30 min',
+            0 => '4 s',
+            1 => '8 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '30 min',
         },
     },
@@ -2991,8 +7443,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => '1 min',
-            0x01 => '5 min',
-            0x02 => '10 min',
-            0x03 => '15 min',
+            0 => '1 min',
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
         },
     },
@@ -3001,8 +7453,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => '2 s',
-            0x40 => '5 s',
-            0x80 => '10 s',
-            0xc0 => '20 s',
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
         },
     },
@@ -3010,6 +7462,4 @@
         Name => 'SelfTimerShotCount',
         Mask => 0x1e,
-        ValueConv => '$val >> 1',
-        ValueConvInv => '$val << 1',
     },
     19.1 => { # CSc2-b
@@ -3017,9 +7467,9 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '4 s',
-            0x20 => '8 s',
-            0x40 => '20 s',
-            0x60 => '1 min',
-            0x80 => '10 min',
+            0 => '4 s',
+            1 => '8 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '10 min',
         },
     },
@@ -3028,9 +7478,9 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '8 s',
-            0x20 => '12 s',
-            0x40 => '20 s',
-            0x60 => '1 min',
-            0x80 => '10 min',
+            0 => '8 s',
+            1 => '12 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '10 min',
         },
     },
@@ -3039,6 +7489,6 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'TTL',
-            0x40 => 'Manual',
+            0 => 'TTL',
+            1 => 'Manual',
         },
     },
@@ -3058,9 +7508,448 @@
         Mask => 0x60,
         PrintConv => {
-            0x00 => 'Face Priority',
-            0x20 => 'Wide Area',
-            0x40 => 'Normal Area',
-            0x60 => 'Subject Tracking',
-        },
+            0 => 'Face Priority',
+            1 => 'Wide Area',
+            2 => 'Normal Area',
+            3 => 'Subject Tracking',
+        },
+    },
+);
+
+# D5100 custom settings (ref PH)
+%Image::ExifTool::NikonCustom::SettingsD5100 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D5100.',
+    0.1 => { # CSa1
+        Name => 'AF-CPrioritySelection',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Focus',
+        },
+    },
+    1.1 => { # CSa2
+        Name => 'AFAssist',
+        Mask => 0x01,
+        PrintConv => \%onOff,
+    },
+    3.1 => { # CSd1
+        Name => 'Beep',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    3.2 => { # CSf4
+        Name => 'NoMemoryCard',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Release Locked',
+            1 => 'Enable Release',
+        },
+    },
+    3.3 => { # CSd2
+        Name => 'ISODisplay',
+        Mask => 0x08,
+        PrintConv => \%onOff,
+    },
+    4.1 => { # CSd3
+        Name => 'FileNumberSequence',
+        Mask => 0x08,
+        PrintConv => \%onOff,
+    },
+    5.1 => { # CSa3
+        Name => 'RangeFinder',
+        Mask => 0x10,
+        PrintConv => \%offOn,
+    },
+    # (it looks like CSd5 DateImprint is not stored)
+    5.2 => { # CSf5
+        Name => 'ReverseIndicators',
+        Mask => 0x80,
+        PrintConv => {
+            0 => '+ 0 -',
+            1 => '- 0 +',
+        },
+    },
+    6.1 => { # CSb1
+        Name => 'EVStepSize',
+        Mask => 0x40,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+        },
+    },
+    10.1 => { # CSd4
+        Name => 'ExposureDelayMode',
+        Mask => 0x40,
+        PrintConv => \%offOn,
+    },
+    12.1 => { # CSe2
+        Name => 'AutoBracketSet',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Exposure',
+            # (NOTE: the following are reversed from the D5000 -- is D5000 correct?)
+            1 => 'WB Bracketing',
+            2 => 'Active D-Lighting',
+        },
+    },
+    13.1 => { # CSf1
+        Name => 'TimerFunctionButton',
+        Mask => 0x38,
+        PrintConv => {
+            0 => 'Self-timer',
+            1 => 'Release Mode',
+            2 => 'Image Quality/Size',
+            3 => 'ISO',
+            4 => 'White Balance',
+            5 => 'Active D-Lighting',
+            6 => '+ NEF (RAW)',
+            7 => 'Auto Bracketing',
+        },
+    },
+    16.1 => { # CSf2
+        Name => 'AELockButton',
+        Mask => 0x38,
+        PrintConv => {
+            0 => 'AE/AF Lock',
+            1 => 'AE Lock Only',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (hold)',
+            4 => 'AF-ON',
+        },
+    },
+    17.1 => { # CSc1
+        Name => 'ShutterReleaseButtonAE-L',
+        Mask => 0x02,
+        PrintConv => \%offOn,
+    },
+    17.2 => { # CSf3
+        Name => 'CommandDialsReverseRotation',
+        Mask => 0x80,
+        PrintConv => \%noYes,
+    },
+    18.1 => { # CSc2-d
+        Name => 'MeteringTime',
+        Mask => 0x70,
+        PrintConv => {
+            0 => '4 s',
+            1 => '8 s',
+            2 => '20 s', #(NC)
+            3 => '1 min',
+            4 => '30 min', #(NC)
+        },
+    },
+    18.2 => { # CSc4
+        Name => 'RemoteOnDuration',
+        Mask => 0x03,
+        PrintConv => {
+            0 => '1 min',
+            1 => '5 min',
+            2 => '10 min', #(NC)
+            3 => '20 min', # (but picture in manual shows 15 min)
+        },
+    },
+    19.1 => { # CSc3-a
+        Name => 'SelfTimerTime',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
+        },
+    },
+    19.2 => { # CSc3-b
+        Name => 'SelfTimerShotCount',
+        Mask => 0x0f,
+    },
+    20.1 => { # CSc2-b
+        Name => 'ImageReviewTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '8 s', #(NC)
+            2 => '20 s',
+            3 => '1 min', #(NC)
+            4 => '10 min', #(NC)
+        },
+    },
+    20.2 => { # CSc2-c
+        Name => 'LiveViewMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '3 min',
+            1 => '5 min', #(NC)
+            2 => '10 min',
+            3 => '15 min', #(NC)
+            4 => '20 min', #(NC)
+            5 => '30 min', #(NC)
+        },
+    },
+    21.1 => { # CSc2-a
+        Name => 'PlaybackMenusTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '8 s', #(NC)
+            1 => '12 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '10 min', #(NC)
+        },
+    },
+    23.1 => { # CSe1-a
+        Name => 'InternalFlash',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Manual',
+        },
+    },
+    23.1 => { # CSe1-b
+        Name => 'ManualFlashOutput',
+        Mask => 0x1f,
+        ValueConv => '2 ** (-$val/3)',
+        ValueConvInv => '$val > 0 ? -3*log($val)/log(2) : 0',
+        PrintConv => q{
+            return 'Full' if $val > 0.99;
+            Image::ExifTool::Exif::PrintExposureTime($val);
+        },
+        PrintConvInv => '$val=~/F/i ? 1 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+);
+
+# D5200 custom settings (ref PH)
+%Image::ExifTool::NikonCustom::SettingsD5200 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D5200.',
+    0.1 => { # CSa1
+        Name => 'AF-CPrioritySelection',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Focus',
+        },
+    },
+    0.2 => { # CSa2
+        Name => 'NumberOfFocusPoints',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '39 Points',
+            1 => '11 Points',
+        },
+    },
+    1.1 => { # CSa3
+        Name => 'AFAssist',
+        Mask => 0x01,
+        PrintConv => \%onOff,
+    },
+    3.1 => { # CSd1
+        Name => 'Beep',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    3.2 => { # CSf4
+        Name => 'NoMemoryCard',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Release Locked',
+            1 => 'Enable Release',
+        },
+    },
+    3.3 => { # CSd3
+        Name => 'ISODisplay',
+        Mask => 0x08,
+        PrintConv => \%onOff,
+    },
+    4.1 => { # CSd3
+        Name => 'FileNumberSequence',
+        Mask => 0x08,
+        PrintConv => \%onOff,
+    },
+    5.1 => { # CSa4
+        Name => 'RangeFinder',
+        Mask => 0x04,
+        PrintConv => \%offOn,
+    },
+    5.2 => { # CSf3-a
+        Name => 'ReverseExposureCompDial',
+        Mask => 0x10,
+        PrintConv => \%noYes,
+    },
+    5.3 => { # CSf3-b
+        Name => 'ReverseShutterSpeedAperture',
+        Mask => 0x08,
+        PrintConv => \%noYes,
+    },
+    5.4 => { # CSf5
+        Name => 'ReverseIndicators',
+        Mask => 0x80,
+        PrintConv => {
+            0 => '+ 0 -',
+            1 => '- 0 +',
+        },
+    },
+    6.1 => { # CSb1
+        Name => 'EVStepSize',
+        Mask => 0x40, # (bit 0x04 also changes)
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+        },
+    },
+    10.1 => { # CSd5
+        Name => 'ExposureDelayMode',
+        Mask => 0x40,
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    12.1 => { # CSe2
+        Name => 'AutoBracketSet',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Exposure',
+            # (NOTE: the following are reversed from the D5000 -- is D5000 correct?)
+            1 => 'WB Bracketing',
+            2 => 'Active D-Lighting',
+        },
+    },
+    13.1 => { # CSf1
+        Name => 'FunctionButton',
+        Mask => 0x1f,
+        PrintConv => {
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-ON',
+            16 => '+ NEF (RAW)',
+            18 => 'Active D-Lighting',
+            25 => 'Live View',
+            26 => 'Image Quality',
+            27 => 'ISO',
+            28 => 'White Balance',
+            29 => 'HDR',
+            30 => 'Auto Bracketing',
+            31 => 'AF-area Mode',
+        },
+    },
+    16.1 => { # CSf2
+        Name => 'AELockButton',
+        Mask => 0x0f,
+        PrintConv => {
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-ON',
+        },
+    },
+    17.1 => { # CSc1
+        Name => 'ShutterReleaseButtonAE-L',
+        Mask => 0x02,
+        PrintConv => \%offOn,
+    },
+    18.1 => { # CSc2-d
+        Name => 'StandbyTimer',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '8 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '30 min',
+        },
+    },
+    18.2 => { # CSc4
+        Name => 'RemoteOnDuration',
+        Mask => 0x03,
+        PrintConv => {
+            0 => '1 min',
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
+        },
+    },
+    19.1 => { # CSc3-a
+        Name => 'SelfTimerTime',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
+        },
+    },
+    19.2 => { # CSc3-b
+        Name => 'SelfTimerShotCount',
+        Mask => 0x0f,
+    },
+    20.1 => { # CSc2-b
+        Name => 'ImageReviewTime',
+        Mask => 0xe0,
+        PrintConv => {
+            1 => '4 s',
+            2 => '8 s',
+            4 => '20 s',
+            5 => '1 min',
+            7 => '10 min',
+        },
+    },
+    20.2 => { # CSc2-c
+        Name => 'LiveViewMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
+            4 => '20 min',
+            5 => '30 min',
+        },
+    },
+    21.1 => { # CSc2-a
+        Name => 'PlaybackMenusTime',
+        Mask => 0xe0,
+        PrintConv => {
+            1 => '8 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    23.1 => { # CSe1-a
+        Name => 'InternalFlash',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Manual',
+        },
+    },
+    23.2 => { # CSe1-b
+        Name => 'ManualFlashOutput',
+        Mask => 0x1f,
+        ValueConv => '2 ** (-$val/3)',
+        ValueConvInv => '$val > 0 ? -3*log($val)/log(2) : 0',
+        PrintConv => q{
+            return 'Full' if $val > 0.99;
+            Image::ExifTool::Exif::PrintExposureTime($val);
+        },
+        PrintConvInv => '$val=~/F/i ? 1 : Image::ExifTool::Exif::ConvertFraction($val)',
     },
 );
@@ -3080,6 +7969,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => 'Release',
-            0x80 => 'Focus',
+            0 => 'Release',
+            1 => 'Focus',
         },
     },
@@ -3088,6 +7977,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Focus',
-            0x20 => 'Release',
+            0 => 'Focus',
+            1 => 'Release',
         },
     },
@@ -3096,6 +7985,6 @@
         Mask => 0x10,
         PrintConv => {
-            0x00 => '39 Points',
-            0x10 => '11 Points',
+            0 => '39 Points',
+            1 => '11 Points',
         },
     },
@@ -3104,33 +7993,33 @@
         Mask => 0x07,
         PrintConv => {
-            0x05 => '5 Long',
-            0x04 => '4',
-            0x03 => '3 Normal',
-            0x02 => '2',
-            0x01 => '1 Short',
-            0x00 => 'Off',
-        },
-    },
-    1.2 => { # CSa5
+            0 => 'Off',
+            1 => '1 Short',
+            2 => '2',
+            3 => '3 Normal',
+            4 => '4',
+            5 => '5 Long',
+        },
+    },
+    1.1 => { # CSa5
         Name => 'FocusPointWrap',
         Mask => 0x08,
         PrintConv => {
-            0x00 => 'No Wrap',
-            0x08 => 'Wrap',
-        },
-    },
-    1.3 => { # CSa4
+            0 => 'No Wrap',
+            1 => 'Wrap',
+        },
+    },
+    1.2 => { # CSa4
         Name => 'AFPointIllumination',
         Mask => 0x06,
         PrintConv => {
-            0x00 => 'Auto',
-            0x02 => 'On',
-            0x04 => 'Off',
-        },
-    },
-    1.4 => { # CSa7
+            0 => 'Auto',
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
+    1.3 => { # CSa7
         Name => 'AFAssist',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     2.1 => { # CSd14
@@ -3138,6 +8027,6 @@
         Mask => 0x40,
         PrintConv => {
-            0x00 => 'MB-D11 First',
-            0x40 => 'Camera Battery First',
+            0 => 'MB-D11 First',
+            1 => 'Camera Battery First',
         },
     },
@@ -3146,11 +8035,11 @@
         Mask => 0x1c,
         PrintConv => {
-            0x00 => 'AE/AF Lock',
-            0x04 => 'AE Lock Only',
-            0x08 => 'AF Lock Only',
-            0x0c => 'AE Lock (hold)',
-            0x10 => 'AF-ON',
-            0x14 => 'FV Lock',
-            0x18 => 'Same as FUNC Button',
+            0 => 'AE/AF Lock',
+            1 => 'AE Lock Only',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (hold)',
+            4 => 'AF-ON',
+            5 => 'FV Lock',
+            6 => 'Same as FUNC Button',
         },
     },
@@ -3159,7 +8048,7 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'LR6 (AA alkaline)',
-            0x01 => 'Ni-MH (AA Ni-MH)',
-            0x02 => 'FR6 (AA lithium)',
+            0 => 'LR6 (AA alkaline)',
+            1 => 'Ni-MH (AA Ni-MH)',
+            2 => 'FR6 (AA lithium)',
         },
     },
@@ -3168,7 +8057,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Off',
-            0x40 => 'Low',
-            0x80 => 'High',
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'High',
         },
     },
@@ -3177,6 +8066,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => 'Release Locked',
-            0x20 => 'Enable Release',
+            0 => 'Release Locked',
+            1 => 'Enable Release',
         },
     },
@@ -3185,7 +8074,7 @@
         Mask => 0x0c,
         PrintConv => {
-            0x00 => 'Show ISO/Easy ISO',
-            0x04 => 'Show ISO Sensitivity',
-            0x0c => 'Show Frame Count',
+            0 => 'Show ISO/Easy ISO',
+            1 => 'Show ISO Sensitivity',
+            3 => 'Show Frame Count',
         },
     },
@@ -3193,10 +8082,10 @@
         Name => 'GridDisplay',
         Mask => 0x02,
-        PrintConv => { 0x00 => 'On', 0x02 => 'Off' },
+        PrintConv => \%onOff,
     },
     3.5 => { # CSd4
         Name => 'ViewfinderWarning',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'On', 0x01 => 'Off' },
+        PrintConv => \%onOff,
     },
     4.1 => { # CSd9
@@ -3204,7 +8093,7 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => 'Auto',
-            0x80 => 'Manual (dark on light)',
-            0xc0 => 'Manual (light on dark)',
+            0 => 'Auto',
+            2 => 'Manual (dark on light)',
+            3 => 'Manual (light on dark)',
         },
     },
@@ -3212,15 +8101,15 @@
         Name => 'LCDIllumination',
         Mask => 0x20,
-        PrintConv => { 0x00 => 'Off', 0x20 => 'On' },
+        PrintConv => \%offOn,
     },
     4.3 => { # CSd8
         Name => 'FileNumberSequence',
         Mask => 0x08,
-        PrintConv => { 0x00 => 'On', 0x08 => 'Off' },
+        PrintConv => \%onOff,
     },
     4.4 => { # CSd5
         Name => 'ScreenTips',
         Mask => 0x04,
-        PrintConv => { 0x00 => 'Off', 0x04 => 'On' },
+        PrintConv => \%offOn,
     },
     4.5 => { # CSd1-a
@@ -3228,8 +8117,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'Off',
-            0x01 => '1',
-            0x02 => '2',
-            0x03 => '3',
+            0 => 'Off',
+            1 => '1',
+            2 => '2',
+            3 => '3',
         },
     },
@@ -3238,6 +8127,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => '+ 0 -',
-            0x80 => '- 0 +',
+            0 => '+ 0 -',
+            1 => '- 0 +',
         },
     },
@@ -3246,7 +8135,7 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => 'Off',
-            0x01 => 'On',
-            0x02 => 'On Auto Reset',
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On Auto Reset',
         },
     },
@@ -3255,6 +8144,6 @@
         Mask => 0x40,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x40 => '1/2 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
         },
     },
@@ -3263,6 +8152,6 @@
         Mask => 0x10,
         PrintConv => {
-            0x00 => '1/3 EV',
-            0x10 => '1/2 EV',
+            0 => '1/3 EV',
+            1 => '1/2 EV',
         },
     },
@@ -3271,9 +8160,9 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '6 mm',
-            0x20 => '8 mm',
-            0x40 => '10 mm',
-            0x60 => '13 mm',
-            0x80 => 'Average',
+            0 => '6 mm',
+            1 => '8 mm',
+            2 => '10 mm',
+            3 => '13 mm',
+            4 => 'Average',
         },
     },
@@ -3281,8 +8170,5 @@
         Name => 'ExposureDelayMode',
         Mask => 0x40,
-        PrintConv => {
-            0x00 => 'Off',
-            0x40 => 'On',
-        },
+        PrintConv => \%offOn,
     },
     10.2 => { # CSd6
@@ -3300,9 +8186,9 @@
         Mask => 0xe0, #(NC)
         PrintConv => {
-            0x00 => 'AE & Flash', # default
-            0x20 => 'AE Only',
-            0x40 => 'Flash Only', #(NC)
-            0x60 => 'WB Bracketing', #(NC)
-            0x80 => 'Active D-Lighting', #(NC)
+            0 => 'AE & Flash', # default
+            1 => 'AE Only',
+            2 => 'Flash Only', #(NC)
+            3 => 'WB Bracketing', #(NC)
+            4 => 'Active D-Lighting', #(NC)
         },
     },
@@ -3311,6 +8197,6 @@
         Mask => 0x10,
         PrintConv => {
-            0x00 => '0,-,+',
-            0x10 => '-,0,+',
+            0 => '0,-,+',
+            1 => '-,0,+',
         },
     },
@@ -3319,24 +8205,24 @@
         Mask => 0xf8,
         PrintConv => {
-            0x00 => 'Grid Display',
-            0x08 => 'FV Lock',
-            0x10 => 'Flash Off',
-            0x18 => 'Matrix Metering',
-            0x20 => 'Center-weighted Metering',
-            0x28 => 'Spot Metering',
-            0x30 => 'My Menu Top',
-            0x38 => '+ NEF (RAW)',
-            0x40 => 'Active D-Lighting',
-            0x48 => 'Preview',
-            0x50 => 'AE/AF Lock',
-            0x58 => 'AE Lock Only',
-            0x60 => 'AF Lock Only',
-            0x68 => 'AE Lock (hold)',
-            0x70 => 'Bracketing Burst',
-            0x78 => 'Playback',
-            0x80 => '1EV Step Speed/Aperture',
-            0x88 => 'Choose Non-CPU Lens',
-            0x90 => 'Virtual Horizon',
-            0x98 => 'Start Movie Recording',
+            0 => 'Grid Display',
+            1 => 'FV Lock',
+            2 => 'Flash Off',
+            3 => 'Matrix Metering',
+            4 => 'Center-weighted Metering',
+            5 => 'Spot Metering',
+            6 => 'My Menu Top',
+            7 => '+ NEF (RAW)',
+            8 => 'Active D-Lighting',
+            9 => 'Preview',
+            10 => 'AE/AF Lock',
+            11 => 'AE Lock Only',
+            12 => 'AF Lock Only',
+            13 => 'AE Lock (hold)',
+            14 => 'Bracketing Burst',
+            15 => 'Playback',
+            16 => '1EV Step Speed/Aperture',
+            17 => 'Choose Non-CPU Lens',
+            18 => 'Virtual Horizon',
+            19 => 'Start Movie Recording',
         },
     },
@@ -3345,24 +8231,24 @@
         Mask => 0xf8,
         PrintConv => {
-            0x00 => 'Grid Display',
-            0x08 => 'FV Lock',
-            0x10 => 'Flash Off',
-            0x18 => 'Matrix Metering',
-            0x20 => 'Center-weighted Metering',
-            0x28 => 'Spot Metering',
-            0x30 => 'My Menu Top',
-            0x38 => '+ NEF (RAW)',
-            0x40 => 'Active D-Lighting',
-            0x48 => 'Preview',
-            0x50 => 'AE/AF Lock',
-            0x58 => 'AE Lock Only',
-            0x60 => 'AF Lock Only',
-            0x68 => 'AE Lock (hold)',
-            0x70 => 'Bracketing Burst',
-            0x78 => 'Playback',
-            0x80 => '1EV Step Speed/Aperture',
-            0x88 => 'Choose Non-CPU Lens',
-            0x90 => 'Virtual Horizon',
-            0x98 => 'Start Movie Recording',
+            0 => 'Grid Display',
+            1 => 'FV Lock',
+            2 => 'Flash Off',
+            3 => 'Matrix Metering',
+            4 => 'Center-weighted Metering',
+            5 => 'Spot Metering',
+            6 => 'My Menu Top',
+            7 => '+ NEF (RAW)',
+            8 => 'Active D-Lighting',
+            9 => 'Preview',
+            10 => 'AE/AF Lock',
+            11 => 'AE Lock Only',
+            12 => 'AF Lock Only',
+            13 => 'AE Lock (hold)',
+            14 => 'Bracketing Burst',
+            15 => 'Playback',
+            16 => '1EV Step Speed/Aperture',
+            17 => 'Choose Non-CPU Lens',
+            18 => 'Virtual Horizon',
+            19 => 'Start Movie Recording',
         },
     },
@@ -3371,10 +8257,10 @@
         Mask => 0x38,
         PrintConv => {
-            0x00 => 'AE/AF Lock',
-            0x08 => 'AE Lock Only',
-            0x10 => 'AF Lock Only',
-            0x18 => 'AE Lock (hold)',
-            0x20 => 'AF-ON',
-            0x28 => 'FV Lock',
+            0 => 'AE/AF Lock',
+            1 => 'AE Lock Only',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (hold)',
+            4 => 'AF-ON',
+            5 => 'FV Lock',
         },
     },
@@ -3383,8 +8269,8 @@
         Mask => 0x18,
         PrintConv => {
-            0x08 => 'Select Center Focus Point',
-            0x10 => 'Highlight Active Focus Point',
-            0x18 => 'Not Used', #(NC)
-            0x00 => 'Off', #(NC)
+            1 => 'Select Center Focus Point',
+            2 => 'Highlight Active Focus Point',
+            3 => 'Not Used', #(NC)
+            0 => 'Off', #(NC)
         },
     },
@@ -3392,5 +8278,5 @@
         Name => 'CommandDialsReverseRotation',
         Mask => 0x80,
-        PrintConv => { 0x00 => 'No', 0x80 => 'Yes' },
+        PrintConv => \%noYes,
     },
     17.2 => { # CSf6-b
@@ -3398,7 +8284,7 @@
         Mask => 0x60,
         PrintConv => {
-            0x00 => 'Off',
-            0x20 => 'On',
-            0x40 => 'On (A mode only)',
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (A mode only)',
         },
     },
@@ -3407,6 +8293,6 @@
         Mask => 0x04,
         PrintConv => {
-            0x00 => 'Sub-command Dial',
-            0x04 => 'Aperture Ring',
+            0 => 'Sub-command Dial',
+            1 => 'Aperture Ring',
         },
     },
@@ -3415,7 +8301,7 @@
         Mask => 0x18,
         PrintConv => {
-            0x00 => 'On',
-            0x10 => 'On (Image Review Exclude)',
-            0x08 => 'Off',
+            0 => 'On',
+            2 => 'On (Image Review Exclude)',
+            1 => 'Off',
         },
     },
@@ -3423,10 +8309,10 @@
         Name => 'ShutterReleaseButtonAE-L',
         Mask => 0x02,
-        PrintConv => { 0x00 => 'Off', 0x02 => 'On' },
+        PrintConv => \%offOn,
     },
     17.6 => { # CSf7
         Name => 'ReleaseButtonToUseDial',
         Mask => 0x01,
-        PrintConv => { 0x00 => 'No', 0x01 => 'Yes' },
+        PrintConv => \%noYes,
     },
     18.1 => { # CSc2
@@ -3435,14 +8321,14 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '4 s',
-            0x10 => '6 s', # default
-            0x20 => '8 s',
-            0x30 => '16 s',
-            0x40 => '30 s',
-            0x50 => '1 min',
-            0x60 => '5 min',
-            0x70 => '10 min',
-            0x80 => '30 min',
-            0x90 => 'No Limit',
+            0 => '4 s',
+            1 => '6 s', # default
+            2 => '8 s',
+            3 => '16 s',
+            4 => '30 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+            8 => '30 min',
+            9 => 'No Limit',
         },
     },
@@ -3451,8 +8337,8 @@
         Mask => 0x03,
         PrintConv => {
-            0x00 => '1 min',
-            0x01 => '5 min',
-            0x02 => '10 min',
-            0x03 => '15 min',
+            0 => '1 min',
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
         },
     },
@@ -3461,8 +8347,8 @@
         Mask => 0xc0,
         PrintConv => {
-            0x00 => '2 s',
-            0x40 => '5 s',
-            0x80 => '10 s', # default
-            0xc0 => '20 s',
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s', # default
+            3 => '20 s',
         },
     },
@@ -3471,8 +8357,8 @@
         Mask => 0x30,
         PrintConv => {
-            0x00 => '0.5 s',
-            0x10 => '1 s',
-            0x20 => '2 s', # default
-            0x30 => '3 s',
+            0 => '0.5 s',
+            1 => '1 s',
+            2 => '2 s', # default
+            3 => '3 s',
         },
     },
@@ -3484,11 +8370,11 @@
         Name => 'ImageReviewTime',
         Mask => 0xe0,
-        PrintConv => { # (NC)
-            0x00 => '4 s',
-            0x20 => '10 s', # default
-            0x40 => '20 s',
-            0x60 => '1 min',
-            0x80 => '5 min',
-            0xa0 => '10 min',
+        PrintConv => { #(NC)
+            0 => '4 s',
+            1 => '10 s', # default
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -3496,11 +8382,11 @@
         Name => 'LiveViewMonitorOffTime',
         Mask => 0x1c,
-        PrintConv => { # (NC)
-            0x00 => '4 s',
-            0x04 => '10 s', # default
-            0x08 => '20 s',
-            0x0c => '1 min',
-            0x10 => '5 min',
-            0x14 => '10 min',
+        PrintConv => { #(NC)
+            0 => '4 s',
+            1 => '10 s', # default
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -3509,10 +8395,10 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '4 s',
-            0x20 => '10 s', # default
-            0x40 => '20 s',
-            0x60 => '1 min',
-            0x80 => '5 min',
-            0xa0 => '10 min',
+            0 => '4 s',
+            1 => '10 s', # default
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -3520,11 +8406,11 @@
         Name => 'ShootingInfoMonitorOffTime',
         Mask => 0x1c,
-        PrintConv => { # (NC)
-            0x00 => '4 s',
-            0x04 => '10 s', # default
-            0x08 => '20 s',
-            0x0c => '1 min',
-            0x10 => '5 min',
-            0x14 => '10 min',
+        PrintConv => { #(NC)
+            0 => '4 s',
+            1 => '10 s', # default
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
@@ -3533,13 +8419,13 @@
         Mask => 0xf0,
         PrintConv => {
-            0x00 => '1/320 s (auto FP)',
-            0x10 => '1/250 s (auto FP)',
-            0x20 => '1/250 s',
-            0x30 => '1/200 s',
-            0x40 => '1/160 s',
-            0x50 => '1/125 s',
-            0x60 => '1/100 s',
-            0x70 => '1/80 s',
-            0x80 => '1/60 s',
+            0 => '1/320 s (auto FP)',
+            1 => '1/250 s (auto FP)',
+            2 => '1/250 s',
+            3 => '1/200 s',
+            4 => '1/160 s',
+            5 => '1/125 s',
+            6 => '1/100 s',
+            7 => '1/80 s',
+            8 => '1/60 s',
        },
     },
@@ -3549,16 +8435,16 @@
         PrintConvColumns => 2,
         PrintConv => {
-            0x00 => '1/60 s',
-            0x01 => '1/30 s',
-            0x02 => '1/15 s',
-            0x03 => '1/8 s',
-            0x04 => '1/4 s',
-            0x05 => '1/2 s',
-            0x06 => '1 s',
-            0x07 => '2 s',
-            0x08 => '4 s',
-            0x09 => '8 s',
-            0x0a => '15 s',
-            0x0b => '30 s',
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
         },
     },
@@ -3566,15 +8452,15 @@
         Name => 'FlashControlBuilt-in',
         Mask => 0xc0,
-        RawConv => '$$self{FlashControlBuiltin} = $val & 0xc0',
-        PrintConv => {
-            0x00 => 'TTL',
-            0x40 => 'Manual',
-            0x80 => 'Repeating Flash',
-            0xc0 => 'Commander Mode',
+        RawConv => '$$self{FlashControlBuiltin} = $val',
+        PrintConv => {
+            0 => 'TTL',
+            1 => 'Manual',
+            2 => 'Repeating Flash',
+            3 => 'Commander Mode',
         },
     },
     23.2 => { # CSe3-b
         Name => 'ManualFlashOutput',
-        Condition => '$$self{FlashControlBuiltin} == 0x40',
+        Condition => '$$self{FlashControlBuiltin} == 1',
         Mask => 0x1f,
         ValueConv => '2 ** (-$val/3)',
@@ -3588,8 +8474,8 @@
     24.1 => { # CSe3-ca
         Name => 'RepeatingFlashOutput',
-        Condition => '$$self{FlashControlBuiltin} == 0x80',
+        Condition => '$$self{FlashControlBuiltin} == 2',
         Mask => 0x70,
-        ValueConv => '2 ** (-($val>>4)-2)',
-        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5)<<4 : 0',
+        ValueConv => '2 ** (-$val-2)',
+        ValueConvInv => '$val > 0 ? int(-log($val)/log(2)-2+0.5) : 0',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
@@ -3597,5 +8483,5 @@
     24.2 => { # CSe3-cb
         Name => 'RepeatingFlashCount',
-        Condition => '$$self{FlashControlBuiltin} == 0x80',
+        Condition => '$$self{FlashControlBuiltin} == 2',
         Mask => 0x0f,
         ValueConv => '$val < 10 ? $val + 1 : 5 * ($val - 7)',
@@ -3604,8 +8490,8 @@
     25.1 => { # CSe3-cc (NC)
         Name => 'RepeatingFlashRate',
-        Condition => '$$self{FlashControlBuiltin} == 0x80',
+        Condition => '$$self{FlashControlBuiltin} == 2',
         Mask => 0xf0,
-        ValueConv => 'my $v=($val>>4); $v < 10 ? $v + 1 : 10 * ($v - 8)',
-        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5) << 4',
+        ValueConv => '$val < 10 ? $val + 1 : 10 * ($val - 8)',
+        ValueConvInv => 'int(($val <= 10 ? $val - 1 : $val / 10 + 8) + 0.5)',
         PrintConv => '"$val Hz"',
         PrintConvInv => '$val=~/(\d+)/; $1 || 0',
@@ -3613,5 +8499,5 @@
     26.1 => { # CSe3-da
         Name => 'CommanderInternalTTLCompBuiltin',
-        Condition => '$$self{FlashControlBuiltin} == 0xc0',
+        Condition => '$$self{FlashControlBuiltin} == 3',
         Mask => 0x1f,
         ValueConv => '($val - 9) / 3',
@@ -3622,5 +8508,5 @@
     27.1 => { # CSe3-db
         Name => 'CommanderInternalTTLCompGroupA',
-        Condition => '$$self{FlashControlBuiltin} == 0xc0',
+        Condition => '$$self{FlashControlBuiltin} == 3',
         Mask => 0x1f,
         ValueConv => '($val - 9) / 3',
@@ -3631,5 +8517,5 @@
     28.1 => { # CSe3-dc
         Name => 'CommanderInternalTTLCompGroupB',
-        Condition => '$$self{FlashControlBuiltin} == 0xc0',
+        Condition => '$$self{FlashControlBuiltin} == 3',
         Mask => 0x1f,
         ValueConv => '($val - 9) / 3',
@@ -3641,13 +8527,10 @@
         Name => 'FlashWarning',
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'On',
-            0x80 => 'Off',
-        },
+        PrintConv => \%onOff,
     },
     30.2 => { # CSe4
         Name => 'ModelingFlash',
         Mask => 0x20,
-        PrintConv => { 0x00 => 'On', 0x20 => 'Off' },
+        PrintConv => \%onOff,
     },
     34.1 => { # CSa8-b
@@ -3655,8 +8538,8 @@
         Mask => 0x60,
         PrintConv => {
-            0x00 => 'Face-Priority',
-            0x20 => 'NormalArea',
-            0x40 => 'WideArea',
-            0x60 => 'SubjectTracking',
+            0 => 'Face-Priority',
+            1 => 'NormalArea',
+            2 => 'WideArea',
+            3 => 'SubjectTracking',
         },
     },
@@ -3665,6 +8548,6 @@
         Mask => 0x02,
         PrintConv => {
-            0x00 => 'AF-C',
-            0x02 => 'AF-F',
+            0 => 'AF-C',
+            1 => 'AF-F',
         },
     },
@@ -3673,14 +8556,960 @@
         Mask => 0xe0,
         PrintConv => {
-            0x00 => '4 s',
-            0x20 => '10 s', # default
-            0x40 => '20 s',
-            0x60 => '1 min',
-            0x80 => '5 min',
-            0xa0 => '10 min',
+            0 => '4 s',
+            1 => '10 s', # default
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
         },
     },
 );
 
+# D4/D4S custom settings (ref 1, decoded from D4S)
+%Image::ExifTool::NikonCustom::SettingsD4 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Custom settings for the D4 and D4S.',
+    0.1 => {
+        Name => 'CustomSettingsBank',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'A',
+            1 => 'B',
+            2 => 'C',
+            3 => 'D',
+        },
+    },
+    1.1 => { #CSa1
+        Name => 'AF-CPrioritySelection',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Release',
+            1 => 'Release + Focus',
+            2 => 'Focus',
+            3 => 'Focus + Release',
+        },
+    },
+    1.2 => { # CSa2
+        Name => 'AF-SPrioritySelection',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Focus',
+            1 => 'Release',
+        },
+    },
+    1.3 => { # CSa7
+        Name => 'AFPointSelection',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '51 Points',
+            1 => '11 Points',
+        },
+    },
+    1.4 => { # CSa3
+        Name => 'FocusTrackingLockOn',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Off',
+            1 => '1 (Short)',
+            2 => '2',
+            3 => '3 (Normal)',
+            4 => '4',
+            5 => '5 (Long)',
+        },
+    },
+    2.1 => { # CSa4
+        Name => 'AFActivation',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Shutter/AF-On',
+            1 => 'AF-On Only',
+        },
+    },
+    2.2 => { # CSa6
+        Name => 'FocusPointWrap',
+        Mask => 0x08,
+        PrintConv => {
+            0 => 'No Wrap',
+            1 => 'Wrap',
+        },
+    },
+    4.1 => { # CSd1-b
+        Name => 'Pitch',
+        Mask => 0x40,
+        PrintConv => { 0 => 'High', 1 => 'Low' },
+    },
+    4.2 => { # CSf12
+        Name => 'NoMemoryCard',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Release Locked',
+            1 => 'Enable Release',
+        },
+    },
+    4.3 => { # CSd6
+        Name => 'GridDisplay',
+        Mask => 0x02,
+        PrintConv => \%onOff,
+    },
+    5.1 => { # CSd9
+        Name => 'ShootingInfoDisplay',
+        Mask => 0xc0,
+        PrintConv => {
+            # 0 - seen for D4 (PH)
+            1 => 'Auto',
+            2 => 'Manual (dark on light)',
+            3 => 'Manual (light on dark)',
+        },
+    },
+    5.2 => { # CSd10
+        Name => 'LCDIllumination',
+        Mask => 0x20,
+        PrintConv => \%offOn,
+    },
+    5.3 => { # CSd8
+        Name => 'ScreenTips',
+        Mask => 0x04,
+        PrintConv => \%offOn,
+    },
+    5.4 => { # CSd1-a
+        Name => 'Beep',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Medium',
+            3 => 'High',
+        },
+    },
+    6.1 => { # CSf13
+        Name => 'ReverseIndicators',
+        Mask => 0x80,
+        PrintConv => {
+            0 => '+ 0 -',
+            1 => '- 0 +',
+        },
+    },
+    6.2 => { # CSd7-a
+        Name => 'RearDisplay',
+        Mask => 0x40,
+        PrintConv => {
+            0 => 'ISO',
+            1 => 'Exposures Remaining',
+        },
+    },
+    6.3 => { # CSd7-b
+        Name => 'ViewfinderDisplay',
+        Mask => 0x20,
+        PrintConv => {
+            0 => 'Frame Count',
+            1 => 'Exposures Remaining',
+        },
+    },
+    6.4 => { # CSd10-a
+        Name => 'CommandDialsReverseRotation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'No',
+            1 => 'Shutter Speed & Aperture',
+            2 => 'Exposure Compensation',
+            3 => 'Exposure Compensation, Shutter Speed & Aperture',
+        },
+    },
+    6.5 => { # CSb4
+        Name => 'EasyExposureCompensation',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            2 => 'On (auto reset)',
+        },
+    },
+    7.1 => { # CSb2
+        Name => 'ExposureControlStepSize',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.2 => { # CSb1
+        Name => 'ISOStepSize',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    7.3 => { # CSb3
+        Name => 'ExposureCompStepSize',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => '1/3 EV',
+            1 => '1/2 EV',
+            2 => '1 EV',
+        },
+    },
+    8.1 => { # CSb6 (CSb5 for D4)
+        Name => 'CenterWeightedAreaSize',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '8 mm',
+            1 => '12 mm',
+            2 => '15 mm',
+            3 => '20 mm',
+            4 => 'Average',
+        },
+    },
+    8.2 => { # CSb7-a
+        Name => 'FineTuneOptMatrixMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.1 => { # CSb7-b
+        Name => 'FineTuneOptCenterWeighted',
+        Mask => 0xf0,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    9.2 => { # CSb7-c
+        Name => 'FineTuneOptSpotMetering',
+        Mask => 0x0f,
+        ValueConv => '($val > 0x7 ? $val - 0x10 : $val) / 6',
+        ValueConvInv => 'int($val*6+($val>0?0.5:-0.5))',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    10.1 => { # CSf1-a
+        Name => 'MultiSelectorShootMode',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Select Center Focus Point (Reset)',
+            2 => 'Preset Focus Point (Pre)',
+            3 => 'Not Used (None)',
+        },
+    },
+    10.2 => { # CSf1-b
+        Name => 'MultiSelectorPlaybackMode',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Thumbnail On/Off',
+            1 => 'View Histograms',
+            2 => 'Zoom On/Off',
+            3 => 'Choose Folder',
+        },
+    },
+    10.3 => { # CSf2
+        Name => 'MultiSelector',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'Do Nothing',
+            1 => 'Reset Meter-off Delay',
+        },
+    },
+    11.1 => { # CSd4
+        Name => 'ExposureDelayMode',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => 'Off',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    11.2 => { # CSd2-a
+        Name => 'CHModeShootingSpeed',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '10 fps',
+            1 => '11 fps',
+        },
+    },
+    11.3 => { # CSd2-b
+        Name => 'CLModeShootingSpeed',
+        Mask => 0x0f,
+        PrintConv => '"$val fps"',
+        PrintConvInv => '$val=~s/\s*fps//i; $val',
+    },
+    12 => { # CSd3
+        Name => 'MaxContinuousRelease',
+        # values: 1-200
+    },
+    13.1 => { # CSe6
+        Name => 'AutoBracketSet',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'AE & Flash',
+            1 => 'AE Only',
+            2 => 'Flash Only',
+            3 => 'WB Bracketing',
+            4 => 'Active D-Lighting',
+        },
+    },
+    13.2 => { # CSe8
+        Name => 'AutoBracketOrder',
+        Mask => 0x10,
+        PrintConv => {
+            0 => '0,-,+',
+            1 => '-,0,+',
+        },
+    },
+    13.3 => { # CSe7
+        Name => 'AutoBracketModeM',
+        Mask => 0x0c,
+        PrintConv => {
+            0 => 'Flash/Speed',
+            1 => 'Flash/Speed/Aperture',
+            2 => 'Flash/Aperture',
+            3 => 'Flash Only',
+        },
+    },
+    14.1 => { # CSf3-a
+        Name => 'FuncButton',
+        Mask => 0xf8,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'My Menu',
+            20 => 'Grid Display',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+        },
+    },
+    14.2 => { # CSf3-b
+        Name => 'FuncButtonPlusDials',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            6 => 'Shooting Bank Menu',
+        },
+    },
+    15.1 => { # CSf4-a
+        Name => 'PreviewButton',
+        Mask => 0xf8,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'My Menu',
+            20 => 'Grid Display',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            26 => 'Flash Disable/Enable',
+        },
+    },
+    15.2 => { # CSf4-b
+        Name => 'PreviewButtonPlusDials',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            6 => 'Shooting Bank Menu',
+        },
+    },
+    16.1 => { # CSf9
+        Name => 'AssignBktButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Auto Bracketing',
+            1 => 'Multiple Exposure',
+            2 => 'HDR (high dynamic range)',
+            3 => 'None',
+        },
+    },
+    18.1 => { # CSf10-b
+        Name => 'CommandDialsChangeMainSub',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => 'Autofocus Off, Exposure Off',
+            1 => 'Autofocus Off, Exposure On',
+            2 => 'Autofocus Off, Exposure On (Mode A)',
+            4 => 'Autofocus On, Exposure Off',
+            5 => 'Autofocus On, Exposure On',
+            6 => 'Autofocus On, Exposure On (Mode A)',
+        },
+    },
+    18.2 => { # CSf10-d
+        Name => 'CommandDialsMenuAndPlayback',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'On',
+            1 => 'Off',
+            2 => 'On (Image Review Excluded)',
+        },
+    },
+    18.3 => { # CSf10-c
+        Name => 'CommandDialsApertureSetting',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Sub-command Dial',
+            1 => 'Aperture Ring',
+        },
+    },
+    18.4 => { # CSc1
+        Name => 'ShutterReleaseButtonAE-L',
+        Mask => 0x02,
+        PrintConv => \%offOn,
+    },
+    18.5 => { # CSf11
+        Name => 'ReleaseButtonToUseDial',
+        Mask => 0x01,
+        PrintConv => \%noYes,
+    },
+    19.1 => { # CSc2
+        Name => 'StandbyTimer',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '6 s',
+            3 => '10 s',
+            5 => '30 s',
+            6 => '1 min',
+            7 => '5 min',
+            8 => '10 min',
+            9 => '30 min',
+        },
+    },
+    20.1 => { # CSc3-a
+        Name => 'SelfTimerTime',
+        Mask => 0xc0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '5 s',
+            2 => '10 s',
+            3 => '20 s',
+        },
+    },
+    20.2 => { # CSc3-b
+        Name => 'SelfTimerShotCount',
+        Mask => 0x0f,
+    },
+    20.3 => { # CSc3-c
+        Name => 'SelfTimerShotInterval',
+        Mask => 0x30,
+        PrintConv => {
+            0 => '0.5 s',
+            1 => '1 s',
+            2 => '2 s',
+            3 => '3 s',
+        },
+    },
+    21.1 => { # CSc4-d
+        Name => 'ImageReviewMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '2 s',
+            1 => '4 s',
+            2 => '10 s',
+            3 => '20 s',
+            4 => '1 min',
+            5 => '5 min',
+            6 => '10 min',
+
+        },
+    },
+    21.2 => { # CSc4-e
+        Name => 'LiveViewMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '5 min',
+            1 => '10 min',
+            2 => '15 min',
+            3 => '20 min',
+            4 => '30 min',
+            5 => 'No Limit',
+        },
+    },
+    22.1 => { # CSc4-b
+        Name => 'MenuMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    22.2 => { # CSc4-c
+        Name => 'ShootingInfoMonitorOffTime',
+        Mask => 0x1c,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    23.1 => { # CSe1
+        Name => 'FlashSyncSpeed',
+        Mask => 0xf0,
+        PrintConv => {
+            # 0x00 - seen for D4 (PH)
+            1 => '1/250 s (auto FP)',
+            2 => '1/250 s',
+            3 => '1/200 s',
+            4 => '1/160 s',
+            5 => '1/125 s',
+            6 => '1/100 s',
+            7 => '1/80 s',
+            8 => '1/60 s',
+        },
+    },
+    23.2 => { # CSe2
+        Name => 'FlashShutterSpeed',
+        Mask => 0x0f,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => '1/60 s',
+            1 => '1/30 s',
+            2 => '1/15 s',
+            3 => '1/8 s',
+            4 => '1/4 s',
+            5 => '1/2 s',
+            6 => '1 s',
+            7 => '2 s',
+            8 => '4 s',
+            9 => '8 s',
+            10 => '15 s',
+            11 => '30 s',
+        },
+    },
+    31.1 => { # CSe5
+        Name => 'ModelingFlash',
+        Mask => 0x20,
+        PrintConv => \%onOff,
+    },
+    36.1 => { # CSc4-a
+        Name => 'PlaybackMonitorOffTime',
+        Mask => 0xe0,
+        PrintConv => {
+            0 => '4 s',
+            1 => '10 s',
+            2 => '20 s',
+            3 => '1 min',
+            4 => '5 min',
+            5 => '10 min',
+        },
+    },
+    37.1 => { # CSf15
+        Name => 'PlaybackZoom',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'Use Separate Zoom Buttons',
+            1 => 'Use Either Zoom Button with Command Dial',
+        },
+    },
+    38.1 => { # CSf8-a
+        Name => 'ShutterSpeedLock',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    38.2 => { # CSf8-b
+        Name => 'ApertureLock',
+        Mask => 0x40,
+        PrintConv => \%offOn,
+    },
+    38.3 => { # CSg4
+        Name => 'MovieShutterButton',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Take Photo',
+            1 => 'Record Movies',
+            2 => 'Live Frame Grab',
+        },
+    },
+    38.4 => { # CSe4
+        Name => 'FlashExposureCompArea',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Entire frame',
+            1 => 'Background only',
+        },
+    },
+    41.1 => { # CSg1-a
+        Name => 'MovieFunctionButton',
+        Mask => 0x70,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Power Aperture (open)', # bit '02' is also toggled on for this setting
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+        },
+    },
+    41.2 => { # CSg2-a
+        Name => 'MoviePreviewButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'None',
+            2 => 'Power Aperture (open)', # bit '10' is also toggled on for this setting
+            3 => 'Index Marking',
+            4 => 'View Photo Shooting Info',
+        },
+    },
+    42.1 => { # CSf14
+        Name => 'VerticalMultiSelector',
+        Mask => 0x60,
+        PrintConv => {
+            0 => 'Same as Multi-Selector with Info(U/D) & Playback(R/L)',
+            1 => 'Same as Multi-Selector with Info(R/L) & Playback(U/D)',
+            2 => 'Focus Point Selection',
+        },
+    },
+    42.2 => { # CSf7-a
+        Name => 'VerticalFuncButton',
+        Mask => 0x1f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'My Menu',
+            20 => 'Grid Display',
+            26 => 'Flash Disable/Enable',
+        },
+    },
+    43.1 => { # CSf7-b
+        Name => 'VerticalFuncButtonPlusDials',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'One Step Speed / Aperture',
+            4 => 'Choose Non-CPU Lens Number',
+            5 => 'Active D-Lighting',
+            6 => 'Shooting Bank Menu',
+            7 => 'ISO Sensitivity',
+            8 => 'Exposure Mode',
+            9 => 'Exposure Compensation',
+            10 => 'Metering',
+        },
+    },
+    43.2 => { # CSf16
+        Name => 'AssignMovieRecordButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            3 => 'ISO Sensitivity',
+            4 => 'Shooting Bank Menu',
+        },
+    },
+    46.1 => { # CSa5-c
+        Name => 'DynamicAreaAFDisplay',
+        Mask => 0x80,
+        PrintConv => \%offOn,
+    },
+    46.2 => { # CSa5-a
+        Name => 'AFPointIllumination',
+        Mask => 0x60,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On in Continuous Shooting Modes',
+            2 => 'On During Manual Focusing',
+            3 => 'On in Continuous Shooting and Manual Focusing',
+        },
+    },
+    46.3 => { # CSa10 (D4 is slightly different -- needs checking)
+        Name => 'StoreByOrientation',
+        Mask => 0x18,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Focus Point',
+            2 => 'Focus Point and AF-area mode',
+        },
+    },
+    46.4 => { # CSa5-d
+        Name => 'GroupAreaAFIllumination',
+        Mask => 0x04,
+        PrintConv => {
+            0 => 'Squares',
+            1 => 'Dots',
+        },
+    },
+    46.5 => { # CSa5-b
+        Name => 'AFPointBrightness',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Low',
+            1 => 'Normal',
+            2 => 'High',
+            3 => 'Extra High',
+        },
+    },
+    47.1 => { # CSa8
+        Name => 'AFOnButton',
+        Mask => 0x70,
+        PrintConv => {
+            0 => 'AF On',
+            1 => 'AE/AF Lock',
+            2 => 'AE Lock Only',
+            3 => 'AE Lock (reset on release)',
+            4 => 'AE Lock (hold)',
+            5 => 'AF Lock Only',
+            6 => 'None',
+        },
+    },
+    47.2 => { # CSa9
+        Name => 'VerticalAFOnButton',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'Same as AF On',
+            1 => 'AF On',
+            2 => 'AE/AF Lock',
+            3 => 'AE Lock Only',
+            4 => 'AE Lock (reset on release)',
+            5 => 'AE Lock (hold)',
+            6 => 'AF Lock Only',
+            7 => 'None',
+        },
+    },
+    48.1 => { # CSf5
+        Name => 'SubSelectorAssignment',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Focus Point Selection',
+            1 => 'Same As Multi-selector',
+        },
+    },
+    48.2 => { # CSg3-a
+        Name => 'MovieSubSelectorAssignment',
+        Mask => 0x07,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Index Marking',
+            2 => 'AE/AF Lock',
+            3 => 'AE Lock Only',
+            4 => 'AE Lock (hold)',
+            5 => 'AF Lock Only',
+            6 => 'View Photo Shooting Info',
+        },
+    },
+    49.1 => { # CSf6-a
+        Name => 'SubSelector',
+        Mask => 0xf8,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock (hold)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            # 9 - seen for D4 (PH)
+            10 => 'Bracketing Burst',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Playback',
+            15 => 'My Menu Top Item',
+            16 => '+NEF(RAW)',
+            17 => 'Virtual Horizon',
+            18 => 'My Menu',
+            19 => 'Reset',    # value appears to be specific to this control at this time
+            20 => 'Grid Display',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            23 => 'Preview',  # value appears to be specific to this control at this time
+            26 => 'Flash Disable/Enable',
+        },
+    },
+    49.2 => { # CSf6-b
+        Name => 'SubSelectorPlusDials',
+        Mask => 0x07,
+        PrintConv => {
+            # (not all values from CSf3-b/CSf4-b are available for CSf6-b)
+            0 => 'None',
+            1 => 'Choose Image Area (FX/DX/5:4)',
+            2 => 'Shutter Speed & Aperture Lock',
+            # 3 => 'One Step Speed / Aperture', # (not available)
+            4 => 'Choose Non-CPU Lens Number',
+            # 5 => 'Active D-Lighting',         # (not available)
+            6 => 'Shooting Bank Menu',
+        },
+    },
+    50.1 => { # CSb5
+        Name => 'MatrixMetering',
+        Condition => '$$self{Model} =~ /\bD4S/',
+        Notes => 'D4S only',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Face Detection On',
+            1 => 'Face Detection Off',
+        },
+    },
+    50.2 => { # CSf17
+        Name => 'LiveViewButtonOptions',
+        Condition => '$$self{Model} =~ /\bD4S/',
+        Notes => 'D4S only',
+        Mask => 0x30,
+        PrintConv => {
+            0 => 'Enable',
+            1 => 'Enable (standby time active)',
+            2 => 'Disable',
+        },
+    },
+    50.3 => { # CSa12
+        Name => 'AFModeRestrictions',
+        Condition => '$$self{Model} =~ /\bD4S/',
+        Notes => 'D4S only',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'AF-C',
+            2 => 'AF-S',
+        },
+    },
+    51.1 => { # CSa11
+        Name => 'LimitAFAreaModeSelection',
+        Condition => '$$self{Model} =~ /\bD4S/',
+        Notes => 'D4S only',
+        Mask => 0x7e,
+        PrintConv => {
+            0 => 'No Restrictions',
+            BITMASK => {
+                0 => 'Auto-area',
+                1 => 'Group-area',
+                2 => '3D-tracking',
+                3 => 'Dynamic area (51 points)',
+                4 => 'Dynamic area (21 points)',
+                5 => 'Dynamic area (9 points)',
+            },
+        },
+    },
+    52.1 => { # CSg1-b
+        Name => 'MovieFunctionButtonPlusDials',
+        Mask => 0x10,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+        },
+    },
+    52.2 => { # CSg2-b
+        Name => 'MoviePreviewButtonPlusDials',
+        Mask => 0x01,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+        },
+    },
+    53.1 => { # CSg3-b
+        Name => 'MovieSubSelectorAssignmentPlusDials',
+        Mask => 0x10,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Choose Image Area',
+        },
+    },
+    54.1 => { # CSf18
+        Name => 'AssignRemoteFnButton',
+        Condition => '$$self{Model} =~ /\bD4S/',
+        Notes => 'D4S only',
+        Mask => 0x1f,
+        PrintConv => {
+            0 => 'None',
+            1 => 'Preview',
+            2 => 'FV Lock',
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            5 => 'AE Lock (reset on release)',
+            7 => 'AF Lock Only',
+            8 => 'AF-On',
+            16 => '+NEF(RAW)',
+            25 => 'Live View',
+            26 => 'Flash Disable/Enable',
+        },
+    },
+    55.1 => { # CSf19
+        Name => 'LensFocusFunctionButtons',
+        Condition => '$$self{Model} =~ /\bD4S/',
+        Notes => 'D4S only',
+        Mask => 0x3f,
+        PrintConv => {
+            3 => 'AE/AF Lock',
+            4 => 'AE Lock Only',
+            7 => 'AF Lock Only',
+            21 => 'Disable Synchronized Release',
+            22 => 'Remote Release Only',
+            24 => 'Preset focus Point',
+            26 => 'Flash Disable/Enable',
+            32 => 'AF-Area Mode:  Single-point AF',
+            33 => 'AF-Area Mode: Dynamic-area AF (9 points)',
+            34 => 'AF-Area Mode: Dynamic-area AF (21 points)',
+            35 => 'AF-Area Mode: Dynamic-area AF (51 points)',
+            36 => 'AF-Area Mode: Group-area AF',
+            37 => 'AF-Area Mode: Auto area AF',
+        },
+    },
+);
 
 1;  # end
@@ -3700,5 +9529,5 @@
 The Nikon custom functions are very specific to the camera model (and
 sometimes even change with firmware version).  The information is stored as
-unformatted binary data in the ShotInfo record of the Nikon MakerNotes. 
+unformatted binary data in the ShotInfo record of the Nikon MakerNotes.
 This module contains the definitions necessary for Image::ExifTool to decode
 this information.
@@ -3706,5 +9535,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -3715,5 +9544,6 @@
 Thanks to Jens Duttke and Warren Hatch for their help decoding the D300 and
 D3 custom settings.  And thanks to the customer service personnel at Best
-Buy for not bugging me while I play with their cameras.
+Buy for not bugging me while I spent lots of time playing with their
+cameras.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonSettings.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonSettings.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/NikonSettings.pm	(revision 34921)
@@ -0,0 +1,2013 @@
+#------------------------------------------------------------------------------
+# File:         NikonSettings.pm
+#
+# Description:  Read Nikon user settings
+#
+# Revisions:    2021/01/08 - Warren Hatch Created
+#               2021/01/12 - PH Created ProcessNikonSettings() to extract tags
+#                            by ID instead of using fixed offsets
+#
+# References:   1) Warren Hatch private communication (D6 and Z7_2)
+#
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::NikonSettings;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.02';
+
+sub ProcessNikonSettings($$$);
+
+my %enableDisable = ( 1 => 'Enable', 2 => 'Disable' );
+
+my %funcButtonZ7m2 = (
+    1 => 'AF-On',
+    2 => 'AF Lock Only',
+    3 => 'AE Lock (hold)',
+    4 => 'AE Lock (reset on release)',
+    5 => 'AE Lock Only',
+    6 => 'AE/AF Lock',
+    7 => 'FV Lock',
+    8 => 'Flash Disable/Enable',
+    9 => 'Preview',
+    10 => 'Matrix Metering',
+    11 => 'Center-weighted Metering',
+    12 => 'Spot Metering',
+    13 => 'Highlight-weighted Metering',
+    14 => 'Bracketing Burst',
+    15 => 'Synchronized Release (Master)',
+    16 => 'Synchronized Release (Remote)',    # no settings map to 17 or 18
+    19 => '+NEF(RAW)',
+    20 => 'Subject Tracking',
+    21 => 'Silent Photography',
+    22 => 'LiveView Info Display On/Off',
+    23 => 'Grid Display',
+    24 => 'Zoom (Low)',
+    25 => 'Zoom (1:1)',
+    26 => 'Zoom (High)',
+    27 => 'My Menu',
+    28 => 'My Menu Top Item',
+    29 => 'Playback',
+    30 => 'Protect',
+    31 => 'Image Area',
+    32 => 'Image Quality',
+    33 => 'White Balance',
+    34 => 'Picture Control',
+    35 => 'Active-D Lighting',
+    36 => 'Metering',
+    37 => 'Flash Mode',
+    38 => 'Focus Mode',
+    39 => 'Auto Bracketing',
+    40 => 'Multiple Exposure',
+    41 => 'HDR',
+    42 => 'Exposure Delay Mode',
+    43 => 'Shutter/Aperture Lock',
+    44 => 'Focus Peaking',
+    45 => 'Rating 0',
+    46 => 'Rating 5',
+    47 => 'Rating 4',
+    48 => 'Rating 3',
+    49 => 'Rating 2',
+    50 => 'Rating 1',    # no settings map to x'51 (possibly intended for 'Candidate for Delection'
+    52 => 'Non-CPU Lens',
+    52 => 'None',
+);
+
+my %flickUpDownD6 = (
+    1 => 'Rating',
+    2 => 'Select To Send',
+    3 => 'Protect',
+    4 => 'Voice Memo',
+    5 => 'None',
+);
+
+my %flickUpDownRatingD6 = (
+    1 => 'Rating 5',
+    2 => 'Rating 4',
+    3 => 'Rating 3',
+    4 => 'Rating 2',
+    5 => 'Rating 1',
+    6 => 'Candidate for Deletion',
+);
+
+my %groupAreaCustom = (
+    1 => '1x7',
+    2 => '1x5',
+    3 => '3x7',
+    4 => '3x5',
+    5 => '3x3',
+    6 => '5x7',
+    7 => '5x5',
+    8 => '5x3',
+    9 => '5x1',
+    10 => '7x7',
+    11 => '7x5',
+    12 => '7x3',
+    13 => '7x1',
+    14 => '11x3',
+    15 => '11x1',
+    16 => '15x3',
+    17 => '15x1',
+);
+
+my %iSOAutoHiLimitD6 = (
+    1 => 'ISO 200',
+    2 => 'ISO 250',
+    3 => 'ISO 280',
+    4 => 'ISO 320',
+    5 => 'ISO 400',
+    6 => 'ISO 500',
+    7 => 'ISO 560',
+    8 => 'ISO 640',
+    9 => 'ISO 800',
+    10 => 'ISO 1000',
+    11 => 'ISO 1100',
+    12 => 'ISO 1250',
+    13 => 'ISO 1600',
+    14 => 'ISO 2000',
+    15 => 'ISO 2200',
+    16 => 'ISO 2500',
+    17 => 'ISO 3200',
+    18 => 'ISO 4000',
+    19 => 'ISO 4500',
+    20 => 'ISO 5000',
+    21 => 'ISO 6400',
+    22 => 'ISO 8000',
+    23 => 'ISO 9000',
+    24 => 'ISO 10000',
+    25 => 'ISO 12800',
+    26 => 'ISO 16000',
+    27 => 'ISO 18000',
+    28 => 'ISO 20000',
+    29 => 'ISO 25600',
+    30 => 'ISO 32000',
+    31 => 'ISO 36000',
+    32 => 'ISO 40000',
+    33 => 'ISO 51200',
+    34 => 'ISO 64000',
+    35 => 'ISO 72000',
+    36 => 'ISO 81200',
+    37 => 'ISO 102400',
+    38 => 'ISO Hi 0.3',
+    39 => 'ISO Hi 0.5',
+    40 => 'ISO Hi 0.7',
+    41 => 'ISO Hi 1.0',
+    42 => 'ISO Hi 2.0',
+    43 => 'ISO Hi 3.0',
+    44 => 'ISO Hi 4.0',
+    45 => 'ISO Hi 5.0',
+);
+
+my %lensFuncButtonZ7m2 = (
+    1 => 'AF-On',
+    2 => 'AF Lock Only',
+    3 => 'AE Lock (hold)',
+    4 => 'AE Lock (reset on release)',
+    5 => 'AE Lock Only',
+    6 => 'AE/AF Lock',
+    7 => 'FV Lock',
+    8 => 'Flash Disable/Enable',
+    9 => 'Preview',
+    10 => 'Matrix Metering',
+    11 => 'Center-weighted Metering',
+    12 => 'Spot Metering',
+    13 => 'Highlight-weighted Metering',
+    14 => 'Bracketing Burst',
+    15 => 'Synchronized Release (Master)',
+    16 => 'Synchronized Release (Remote)',    # no settings map to 17 or 18 (Z7II fw 1.01)
+    19 => '+NEF(RAW)',
+    20 => 'Subject Tracking',
+    21 => 'Grid Display',
+    22 => 'Zoom (Low)',
+    23 => 'Zoom (1:1)',
+    24 => 'Zoom (High)',
+    25 => 'My Menu',
+    26 => 'My Menu Top Item',
+    27 => 'Playback',
+    28 => 'None',
+);
+
+my %limitNolimit = ( 1 => 'Limit', 2 => 'No Limit' );
+
+my %limtReleaseModeSel = (
+    0 => 'No Limit',    # not sure why 0 and 2 both map to 'No Limit', but they do
+    1 => 'Limit',
+    2 => 'No Limit',
+);
+
+my %menuBank = (
+    1 => 'A',
+    2 => 'B',
+    3 => 'C',
+    4 => 'D',
+);
+
+my %noYes = ( 1 => 'No', 2 => 'Yes' );
+my %offOn = ( 1 => 'Off', 2 => 'On' );
+my %onOff = ( 1 => 'On', 2 => 'Off' );
+
+my %previewButtonD6 = (
+    1 => 'Preset Focus Point - Press To Recall',
+    2 => 'Preset Focus Point - Hold To Recall',
+    3 => 'AF-AreaMode S',
+    4 => 'AF-AreaMode D9',
+    5 => 'AF-AreaMode D25',
+    6 => 'AF-AreaMode D49',
+    7 => 'AF-AreaMode D105',
+    8 => 'AF-AreaMode 3D',
+    9 => 'AF-AreaMode Group',
+    10 => 'AF-AreaMode Group C1',
+    11 => 'AF-AreaMode Group C2',
+    12 => 'AF-AreaMode Auto Area',
+    13 => 'AF-AreaMode + AF-On S',
+    14 => 'AF-AreaMode + AF-On D9',
+    15 => 'AF-AreaMode + AF-On D25',
+    16 => 'AF-AreaMode + AF-On D49',
+    17 => 'AF-AreaMode + AF-On D105',
+    18 => 'AF-AreaMode + AF-On 3D',
+    19 => 'AF-AreaMode + AF-On Group',
+    20 => 'AF-AreaMode + AF-On Group C1',
+    21 => 'AF-AreaMode + AF-On Group C2',
+    22 => 'AF-AreaMode + AF-On Auto Area',
+    23 => 'AF-On',
+    24 => 'AF Lock Only',
+    25 => 'AE Lock (hold)',
+    26 => 'AE/WB Lock (hold)',
+    27 => 'AE Lock (reset on release)',
+    28 => 'AE Lock Only',
+    29 => 'AE/AF Lock',
+    30 => 'FV Lock',
+    31 => 'Flash Disable/Enable',
+    32 => 'Preview',
+    33 => 'Recall Shooting Functions',
+    34 => 'Bracketing Burst',
+    35 => 'Synchronized Release (Master)',
+    36 => 'Synchronized Release (Remote)', # no settings map to 37 or 38
+    39 => '+NEF(RAW)',
+    40 => 'Grid Display',
+    41 => 'Virtual Horizon',
+    42 => 'Voice Memo',
+    43 => 'Wired LAN',
+    44 => 'My Menu',
+    45 => 'My Menu Top Item',
+    46 => 'Playback',
+    47 => 'Filtered Playback',
+    48 => 'Photo Shooting Bank',
+    49 => 'AF Mode/AF Area Mode',
+    50 => 'Image Area',
+    51 => 'Active-D Lighting',
+    52 => 'Exposure Delay Mode',
+    53 => 'Shutter/Aperture Lock',
+    54 => '1 Stop Speed/Aperture',
+    55 => 'Non-CPU Lens',
+    56 => 'None',
+);
+
+my %releaseFocus = (
+    1 => 'Release',
+    2 => 'Focus',
+);
+
+my %tagMultiSelector = (
+    1 => 'Restart Standby Timer',
+    2 => 'Do Nothing',
+);
+
+my %tagSecondarySlotFunction = (
+    1 => 'Overflow',
+    2 => 'Backup',
+    3 => 'NEF Primary + JPG Secondary',
+    4 => 'JPG Primary + JPG Secondary',
+);
+
+my %tagSubSelector = (
+    1 => 'Same as MultiSelector',
+    2 => 'Focus Point Selection',
+);
+
+my %thirdHalfFull = (
+    1 => '1/3 EV',
+    2 => '1/2 EV',
+    3 => '1 EV',
+);
+
+my %times4s10s20s1m5m20m = (
+    1 => '4 s',
+    2 => '10 s',
+    3 => '20 s',
+    4 => '1 min',
+    5 => '5 min',
+    6 => '10 min',
+);
+
+my %yesNo = ( 1 => 'Yes', 2 => 'No' );
+
+my %infoZ72 = (
+    Condition => '$$self{Model} =~ /^NIKON Z 6_2/i or $$self{Model} =~ /^NIKON Z 7_2/i',
+    Notes => 'Z7_2',
+);
+
+my %infoD6 = (
+    Condition => '$$self{Model} =~ /^NIKON D6/i',
+    Notes => 'D6',
+);
+
+# Nikon Settings tags (ref 1, tag ID's ref PH)
+%Image::ExifTool::NikonSettings::Main = (
+    PROCESS_PROC => \&ProcessNikonSettings,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        User settings for newer Nikon models.  A number of the tags are marked as
+        Unknown only to reduce the volume of the normal output.
+    },
+    0x001 => [{
+        Name => 'ISOAutoHiLimit',
+        PrintConv => \%iSOAutoHiLimitD6,
+        %infoD6,
+    },{
+        Name => 'ISOAutoHiLimit',
+        PrintConv => {
+            1 => 'ISO 100',
+            2 => 'ISO 125',
+            4 => 'ISO 160',
+            5 => 'ISO 200',
+            6 => 'ISO 250',
+            8 => 'ISO 320',
+            9 => 'ISO 400',
+            10 => 'ISO 500',
+            12 => 'ISO 640',
+            13 => 'ISO 800',
+            14 => 'ISO 1000',
+            16 => 'ISO 1250',
+            17 => 'ISO 1600',
+            18 => 'ISO 2000',
+            20 => 'ISO 2500',
+            21 => 'ISO 3200',
+            22 => 'ISO 4000',
+            24 => 'ISO 5000',
+            25 => 'ISO 6400',
+            26 => 'ISO 8000',
+            28 => 'ISO 10000',
+            29 => 'ISO 12800',
+            30 => 'ISO 16000',
+            32 => 'ISO 20000',
+            33 => 'ISO 25600',
+            38 => 'ISO Hi 0.3',
+            39 => 'ISO Hi 0.5',
+            40 => 'ISO Hi 0.7',
+            41 => 'ISO Hi 1.0',
+            42 => 'ISO Hi 2.0',
+        },
+        %infoZ72,
+    }],
+    0x002 => [{
+        Name => 'ISOAutoFlashLimit',
+        PrintConv => {
+            1 => 'Same As Without Flash',
+            2 => 'ISO 200',
+            3 => 'ISO 250',
+            5 => 'ISO 320',
+            6 => 'ISO 400',
+            7 => 'ISO 500',
+            9 => 'ISO 640',
+            10 => 'ISO 800',
+            11 => 'ISO 1000',
+            13 => 'ISO 1250',
+            14 => 'ISO 1600',
+            15 => 'ISO 2000',
+            17 => 'ISO 2500',
+            18 => 'ISO 3200',
+            19 => 'ISO 4000',
+            21 => 'ISO 5000',
+            22 => 'ISO 6400',
+            23 => 'ISO 8000',
+            25 => 'ISO 10000',
+            26 => 'ISO 12800',
+            27 => 'ISO 16000',
+            29 => 'ISO 20000',
+            30 => 'ISO 25600',
+            31 => 'ISO 32000',
+            33 => 'ISO 40000',
+            34 => 'ISO 51200',
+            35 => 'ISO 64000',
+            36 => 'ISO 72000',
+            37 => 'ISO 81200',
+            38 => 'ISO 102400',
+            39 => 'ISO Hi 0.3',
+            40 => 'ISO Hi 0.5',
+            41 => 'ISO Hi 0.7',
+            42 => 'ISO Hi 1.0',
+            43 => 'ISO Hi 2.0',
+            44 => 'ISO Hi 3.0',
+            45 => 'ISO Hi 4.0',
+            46 => 'ISO Hi 5.0',
+        },
+        %infoD6,
+    },{
+        Name => 'ISOAutoFlashLimit',
+        PrintConv => {
+            1 => 'Same As Without Flash',
+            2 => 'ISO 100',
+            3 => 'ISO 125',
+            5 => 'ISO 160',
+            6 => 'ISO 200',
+            7 => 'ISO 250',
+            9 => 'ISO 320',
+            10 => 'ISO 400',
+            11 => 'ISO 500',
+            13 => 'ISO 640',
+            14 => 'ISO 800',
+            15 => 'ISO 1000',
+            17 => 'ISO 1250',
+            18 => 'ISO 1600',
+            19 => 'ISO 2000',
+            21 => 'ISO 2500',
+            22 => 'ISO 3200',
+            23 => 'ISO 4000',
+            25 => 'ISO 5000',
+            26 => 'ISO 6400',
+            27 => 'ISO 8000',
+            29 => 'ISO 10000',
+            30 => 'ISO 12800',
+            31 => 'ISO 16000',
+            33 => 'ISO 20000',
+            34 => 'ISO 25600',
+            39 => 'ISO Hi 0.3',
+            40 => 'ISO Hi 0.5',
+            41 => 'ISO Hi 0.7',
+            42 => 'ISO Hi 1.0',
+            43 => 'ISO Hi 2.0',
+        },
+        %infoZ72,
+    }],
+    0x003 => { # (D6/Z7_2)
+        Name => 'ISOAutoShutterTime',
+        PrintConv => {
+            1 => 'Auto (Slowest)',
+            2 => 'Auto (Slower)',
+            3 => 'Auto',
+            4 => 'Auto (Faster)',
+            5 => 'Auto (Fastest)',
+            6 => '1/4000 s',
+            7 => '1/3200 s',
+            8 => '1/2500 s',
+            9 => '1/2000 s',
+            10 => '1/1600 s',
+            11 => '1/1250 s',
+            12 => '1/1000 s',
+            13 => '1/800 s',
+            14 => '1/640 s',
+            15 => '1/500 s',
+            16 => '1/400 s',
+            17 => '1/320 s',
+            18 => '1/250 s',
+            19 => '1/200 s',
+            20 => '1/160 s',
+            21 => '1/125 s',
+            22 => '1/100 s',
+            23 => '1/80 s',
+            24 => '1/60 s',
+            25 => '1/50 s',
+            26 => '1/40 s',
+            27 => '1/30 s',
+            28 => '1/25 s',
+            29 => '1/20 s',
+            30 => '1/15 s',
+            31 => '1/13 s',
+            32 => '1/10 s',
+            33 => '1/8 s',
+            34 => '1/6 s',
+            35 => '1/5 s',
+            36 => '1/4 s',
+            37 => '1/3 s',
+            38 => '1/2.5 s',
+            39 => '1/2 s',
+            40 => '1/1.6 s',
+            41 => '1/1.3 s',
+            42 => '1 s',
+            43 => '1.3 s',
+            44 => '1.6 s',
+            45 => '2 s',
+            46 => '2.5 s',
+            47 => '3 s',
+            48 => '4 s',
+            49 => '5 s',
+            50 => '6 s',
+            51 => '8 s',
+            52 => '10 s',
+            53 => '13 s',
+            54 => '15 s',
+            55 => '20 s',
+            56 => '25 s',
+            57 => '30 s',
+        },
+    },
+    0x00b => { Name => 'FlickerReductionShooting', PrintConv => \%enableDisable }, # (D6/Z7_2)
+    0x00c => { Name => 'FlickerReductionIndicator',PrintConv => \%enableDisable }, # (D6)
+    0x00d => [{
+        Name => 'MovieISOAutoHiLimit',
+        PrintConv => \%iSOAutoHiLimitD6,
+        %infoD6,
+    },{
+        Name => 'MovieISOAutoHiLimit',
+        PrintConv => {
+            1 => 'ISO 200',
+            2 => 'ISO 250',
+            4 => 'ISO 320',
+            5 => 'ISO 400',
+            6 => 'ISO 500',
+            8 => 'ISO 640',
+            9 => 'ISO 800',
+            10 => 'ISO 1000',
+            12 => 'ISO 1250',
+            13 => 'ISO 1600',
+            14 => 'ISO 2000',
+            16 => 'ISO 2500',
+            17 => 'ISO 3200',
+            18 => 'ISO 4000',
+            20 => 'ISO 5000',
+            21 => 'ISO 6400',
+            22 => 'ISO 8000',
+            24 => 'ISO 10000',
+            25 => 'ISO 12800',
+            26 => 'ISO 16000',
+            28 => 'ISO 20000',
+            29 => 'ISO 25600',
+            34 => 'ISO Hi 0.3',
+            35 => 'ISO Hi 0.5',
+            36 => 'ISO Hi 0.7',
+            37 => 'ISO Hi 1.0',
+            38 => 'ISO Hi 2.0',
+        },
+        %infoZ72,
+    }],
+    0x00e => { Name => 'MovieISOAutoControlManualMode',PrintConv => \%onOff }, # (D6/Z7_2)
+  # 0x00f => [{   # this tag should reside here, but unable to confirm
+  #     Name => 'MovieISOAutoManualMode',
+  #     PrintConv => \%iSOAutoHiLimitD6,
+  #     %infoD6,
+  # },{
+  #     Name => 'MovieISOAutoManualMode',
+  #     PrintConv => \%iSOAutoHiLimitZ7m2,
+  #     %infoZ72,
+  # }],
+    0x01d => [{ # CSa1 (D6)
+        Name => 'AF-CPrioritySel',
+        PrintConv => { # valid for cameras with 4 options for CS1, otherwise 1=Release, 2=Focus
+            1 => 'Release',
+            2 => 'Release + Focus',
+            3 => 'Focus + Release',
+            4 => 'Focus',
+        },
+        %infoD6,
+    },{ # CSa1 (Z7_2)
+        Name => 'AF-CPrioritySel',
+        PrintConv => \%releaseFocus,
+        %infoZ72,
+    }],
+    0x01e => { Name => 'AF-SPrioritySel',       PrintConv => \%releaseFocus }, # CSa2 (D6), CSa2 (Z7_2)
+    0x020 => [{ # CSa4 (D6)
+        Name => 'AFPointSel',
+        PrintConv => {
+            1 => '105 Points',
+            2 => '27 Points',
+            3 => '15 Points',
+        },
+        %infoD6,
+    },{ # CSa4 (Z7_2)
+        Name => 'AFPointSel',
+        PrintConv => { 1 => 'Use All', 2 => 'Use Half' },
+        %infoZ72,
+    }],
+    0x022 => { Name => 'AFActivation',          PrintConv => { 1 => 'Shutter/AF-On', 2 => 'AF-On Only' } }, # CSa6-a (D6/Z7_2) (missing enable/disable out of focus release) # (D6)
+    0x023 => { Name => 'FocusPointWrap',        PrintConv => { 1 => 'Wrap', 2 => 'No Wrap' } }, # CSa16 (D6), CSa8 (Z7_2)
+    0x025 => { # CSa17-a (D6), CSa9-a (Z7_2)
+        Name => 'ManualFocusPointIllumination',
+        PrintConv => {
+            1 => 'On',
+            2 => 'On During Focus Point Selection Only',
+        },
+    },
+    0x026 => { Name => 'AF-AssistIlluminator',      PrintConv => \%onOff }, # CSa11 (Z7_2)
+  # 0x027 => { Name => 'ManualFocusRingInAFMode',   PrintConv => \%onOff }, # CSa18 (D6,Z7_2) capability documented in manual, but visibility (& ability to test) requires a compatible lens
+    0x029 => { Name => 'ISOStepSize',               PrintConv => \%thirdHalfFull },     # CSb1 (D6)
+    0x02a => { Name => 'ExposureControlStepSize',   PrintConv => \%thirdHalfFull }, # CSb2 (D6), CSb1 (Z7_2)
+    0x02b => { # CSb4 (D6), CSb2 (Z7_2)
+        Name => 'EasyExposureCompensation',
+        PrintConv => {
+            1 => 'On (auto reset)',
+            2 => 'On',
+            3 => 'Off',
+        },
+    },
+    0x02c => { Name => 'MatrixMetering', PrintConv => { 1 => 'Face Detection On', 2 => 'Face Detection Off' } }, # CSb5 (D6)
+    0x02d => [{ # CSb6 (D6)
+        Name => 'CenterWeightedAreaSize',
+        PrintConv => {
+            1 => '8 mm',
+            2 => '12 mm',
+            3 => '15 mm',
+            4 => '20 mm',
+            5 => 'Average',
+        },
+        %infoD6
+    },{ # CSb3 (Z7_2)
+        Name => 'CenterWeightedAreaSize',
+        PrintConv => { 1 => '12 mm', 2 => 'Average' },
+        %infoZ72,
+    }],
+    0x02f => { # CSb7-a (D6), CSb4-a (Z7_2)
+        Name => 'FineTuneOptMatrixMetering',
+        ValueConv => '($val - 7) / 6',
+        ValueConvInv => 'int($val*6+7)',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x030 => { # CSb7-b (D6), CSb4-b (Z7_2)
+        Name => 'FineTuneOptCenterWeighted',
+        ValueConv => '($val - 7) / 6',
+        ValueConvInv => 'int($val*6+7)',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x031 => { # CSb7-c (D6), CSb4-c (Z7_2)
+        Name => 'FineTuneOptSpotMetering',
+        ValueConv => '($val - 7) / 6',
+        ValueConvInv => 'int($val*6+7)',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x032 => { # CSb7-d (D6), CSb4-d (Z7_2)
+        Name => 'FineTuneOptHighlightWeighted',
+        ValueConv => '($val - 7) / 6',
+        ValueConvInv => 'int($val*6+7)',
+        PrintConv => '$val ? sprintf("%+.2f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x033 => { # CSc1 (D6), CSc1 (Z7_2)
+        Name => 'ShutterReleaseButtonAE-L',
+        PrintConv => {
+            1 => 'On (Half Press)',
+            2 => 'On (Burst Mode)',
+            3 => 'Off',
+        },
+    },
+    0x034 => [{ # CSc2 (D6)
+        Name => 'StandbyMonitorOffTime',
+        PrintConv => {
+            1 => '4 s',
+            2 => '6 s',
+            3 => '10 s',
+            4 => '30 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+            8 => '30 min',
+            9 => 'No Limit',
+        },
+        %infoD6,
+    },{ # CSc4-d (Z7_2)
+        Name => 'StandbyMonitorOffTime',
+        PrintConv => {
+            1 => '10 s',
+            2 => '20 s',
+            3 => '30 s',
+            4 => '1 min',
+            5 => '5 min',
+            6 => '10 min',
+            7 => '30 min',
+            8 => 'No Limit',
+        },
+        %infoZ72,
+    }],
+    0x035 => { # CSc3-a (D6), CSc2-a (Z7_2)
+        Name => 'SelfTimerTime',
+        PrintConv => {
+            1 => '2 s',
+            2 => '5 s',
+            3 => '10 s',
+            4 => '20 s',
+        },
+    },
+    0x036 => { Name => 'SelfTimerShotCount', ValueConv => '10 - $val', ValueConvInv => '10 + $val' }, # CSc3-b (D6), CSc2-b (Z7_2)
+    0x037 => { # CSc3-c (D6), CSc2-c (Z7_2)
+        Name => 'SelfTimerShotInterval',
+        PrintConv => {
+            1 => '0.5 s',
+            2 => '1 s',
+            3 => '2 s',
+            4 => '3 s',
+        },
+    },
+    0x038 => { Name => 'PlaybackMonitorOffTime',    PrintConv => \%times4s10s20s1m5m20m }, # CSc4-a (D6), CSc3-a (Z7_2)
+    0x039 => { Name => 'MenuMonitorOffTime',        PrintConv => \%times4s10s20s1m5m20m }, # CSc4-b (D6), CSc3-b (Z7_2)
+    0x03a => { Name => 'ShootingInfoMonitorOffTime',PrintConv => \%times4s10s20s1m5m20m }, # CSc4-c (D6)
+    0x03b => { # CSc4-d (D6), CSc3-c (Z7_2)
+        Name => 'ImageReviewMonitorOffTime',
+        PrintConv => {
+            1 => '2 s',
+            2 => '4 s',
+            3 => '10 s',
+            4 => '20 s',
+            5 => '1 min',
+            6 => '5 min',
+            7 => '10 min',
+        },
+    },
+    0x03c => { # CSc4-e (D6)
+        Name => 'LiveViewMonitorOffTime',
+        PrintConv => {
+            1 => '5 min',
+            2 => '10 min',
+            3 => '15 min',
+            4 => '20 min',
+            5 => '30 min',
+            6 => 'No Limit',
+        },
+    },
+    0x03e => { Name => 'CLModeShootingSpeed',       ValueConv => '6 - $val', ValueConvInv => '6 + $val', PrintConv => '"$val fps"', PrintConvInv => '$val=~s/\s*fps//i; $val' }, # CSd1 (Z7_2)
+    0x03f => { Name => 'MaxContinuousRelease' }, # CSd2       # values: 1-200 # (D6/Z7_2)
+    0x040 => { # CSd5 (D6), CSd4 (Z7_2)
+        Name => 'ExposureDelayMode',
+        PrintConv => {
+            1 => '3 s',
+            2 => '2 s',
+            3 => '1 s',
+            4 => '0.5 s',
+            5 => '0.2 s',
+            6 => 'Off',
+        },
+    },
+    0x041 => { Name => 'ElectronicFront-CurtainShutter',PrintConv => \%onOff }, # CSd6 (D6)
+    0x042 => { Name => 'FileNumberSequence',        PrintConv => \%onOff }, # CSd9 (D6), CSd8 (Z7_2)
+    0x043 => { Name => 'FramingGridDisplay',        PrintConv => \%onOff }, # CSd11 (D6), CSd10 (Z7_2), new tag with implementation of NikonSettings # (Z7_2)
+    0x045 => { Name => 'LCDIllumination',           PrintConv => \%onOff }, # CSd13 (D6)
+    0x046 => { Name => 'OpticalVR',                 PrintConv => \%onOff }, # CSd15 (D6)
+    0x047 => [{ # CSe1 (D6)
+        Name => 'FlashSyncSpeed',
+        PrintConv => {
+            1 => '1/250 s (auto FP)',
+            2 => '1/250 s',
+            3 => '1/200 s',
+            4 => '1/160 s',
+            5 => '1/125 s',
+            6 => '1/100 s',
+            7 => '1/80 s',
+            8 => '1/60 s',
+        },
+        %infoD6,
+    },{ # CSe1 (Z7_2)
+        Name => 'FlashSyncSpeed',
+        PrintConv => {
+            1 => '1/200 s (auto FP)',
+            2 => '1/200 s',
+            3 => '1/160 s',
+            4 => '1/125 s',
+            5 => '1/100 s',
+            6 => '1/80 s',
+            7 => '1/60 s',
+        },
+        %infoZ72,
+    }],
+    0x048 => { # CSe2 (D6/Z7_2)
+        Name => 'FlashShutterSpeed',
+        PrintConv => {
+            1 => '1/60 s',
+            2 => '1/30 s',
+            3 => '1/15 s',
+            4 => '1/8 s',
+            5 => '1/4 s',
+            6 => '1/2 s',
+            7 => '1 s',
+            8 => '2 s',
+        },
+    },
+    0x049 => { Name => 'FlashExposureCompArea', PrintConv => { 1 => 'Entire Frame', 2 => 'Background Only' } }, # CSe3 (D6/Z7_2)
+    0x04a => { # CSe4 (D6/Z7_2)
+        Name => 'AutoFlashISOSensitivity',
+        PrintConv => {
+            1 => 'Subject and Background',
+            2 => 'Subject Only',
+        },
+    },
+    0x051 => { # CSf3-l (D6)
+        Name => 'AssignBktButton',
+        PrintConv => {
+            1 => 'Auto Bracketing',
+            2 => 'Multiple Exposure',
+            3 => 'HDR (high dynamic range)',
+            4 => 'None',
+        },
+    },
+    0x052 => [{ # CSf3-m (D6)
+        Name => 'AssignMovieRecordButton',
+        PrintConv => {
+            1 => 'Voice Memo',
+            2 => 'Photo Shooting Bank',
+            3 => 'Exposure Mode',
+            4 => 'AF Mode/AF Area Mode',
+            5 => 'Image Area',
+            6 => 'Shutter/Aperture Lock',
+            7 => 'None',
+        },
+        %infoD6,
+    },{ # CSf2-f (Z7_2)
+        Name => 'AssignMovieRecordButton',
+        PrintConv => {
+            1 => 'AE Lock (hold)',
+            2 => 'AE Lock (reset on release)',
+            3 => 'Preview',
+            4 => '+NEF(RAW)',
+            5 => 'LiveView Info Display On/Off',
+            6 => 'Grid Display',
+            7 => 'Zoom (Low)',
+            8 => 'Zoom (1:1)',
+            9 => 'Zoom (High)',
+            10 => 'My Menu',
+            11 => 'My Menu Top Item',
+            12 => 'Image Area',
+            13 => 'Image Quality',
+            14 => 'White Balance',
+            15 => 'Picture Control',
+            16 => 'Active-D Lighting',
+            17 => 'Metering',
+            18 => 'Flash Mode',
+            19 => 'Focus Mode',
+            20 => 'Auto Bracketing',
+            21 => 'Multiple Exposure',
+            22 => 'HDR',
+            23 => 'Exposure Delay Mode',
+            24 => 'Shutter/Aperture Lock',
+            25 => 'Non-CPU Lens',
+            26 => 'None',
+        },
+        %infoZ72,
+    }],
+    0x053 => [{ # CSf4-a (D6)
+        Name => 'MultiSelectorShootMode',
+        PrintConv => {
+            1 => 'Select Center Focus Point',
+            2 => 'Preset Focus Point - Press To Recall',
+            3 => 'Preset Focus Point - Hold To Recall',
+            4 => 'None',
+        },
+        %infoD6,
+    },{ # CSf3-a (Z7_2) also called the OK button on this camera
+        Name => 'MultiSelectorShootMode',
+        PrintConv => {
+            1 => 'Select Center Focus Point',
+            2 => 'Zoom (Low)',
+            3 => 'Zoom (1:1)',
+            4 => 'Zoom (High)',
+            5 => 'None',
+        },
+        %infoZ72,
+    }],
+    0x054 => [{ # CSf4-c (D6)
+        Name => 'MultiSelectorPlaybackMode',
+        PrintConv => {
+            1 => 'Filtered Playback',
+            2 => 'View Histograms',
+            3 => 'Zoom (Low)',
+            4 => 'Zoom (1:1)',
+            5 => 'Zoom (High)',
+            6 => 'Choose Folder',
+        },
+        %infoD6,
+    },{ # CSf3-b (Z7_2) # these decodes are correct.  However, a new camera (or one following a 'reset all settings') will report Zoom (Low), despite the camera exhibiting the expected behavior (Zoom 1:1).  Any change to CSf3-b corrects the reporting.
+        Name => 'MultiSelectorPlaybackMode',
+        PrintConv => {
+            1 => 'Thumbnail On/Off',
+            2 => 'View Histograms',
+            3 => 'Zoom (Low)',
+            4 => 'Zoom (1:1)',
+            5 => 'Zoom (High)',
+            6 => 'Choose Folder',
+        },
+        %infoZ72,
+    }],
+    0x056 => { # CSf4-b (D6)
+        Name => 'MultiSelectorLiveView',
+        PrintConv => {
+            1 => 'Select Center Focus Point',
+            2 => 'Zoom (Low)',
+            3 => 'Zoom (1:1)',
+            4 => 'Zoom (High)',
+            5 => 'None',
+        },
+    },
+    0x058 => { # CSf6-a-1 and CSf6-a-2 (D6), CSf5-a-1 and CSf5-a-2 (Z7_2), Previous cameras reported these 2 in a single tag (CmdDialsReverseRotation).  Blend the separate settings together to match extant tag name and values
+        Name => 'CmdDialsReverseRotExposureComp',
+        RawConv => '$$self{CmdDialsReverseRotExposureComp} = $val',
+        Unknown => 1,
+    },
+    0x059 => { # CSf6-b-1 and  CSf6-b-2 (D6), CSf5-b-1 and  CSf5-b-2 (Z7_2), Previous cameras reported these 2 in a single tag (CmdDialsChangeMainSub).  Blend the separate settings together to match extant tag name and values
+        Name => 'CmdDialsChangeMainSubExposure',
+        RawConv => '$$self{CmdDialsChangeMainSubExposure} = $val',
+        Unknown => 1,
+    },
+    0x05a => [{ # CSf6-b-1 and CSf6-b-2 (D6), CSf5-b-1 and CSf5-b-2 (Z7_2), (continued from above)
+        Name => 'CmdDialsChangeMainSub',
+        Condition => '$$self{CmdDialsChangeMainSubExposure} and $$self{CmdDialsChangeMainSubExposure} == 1',
+        PrintConv => {
+            1 => 'Autofocus On, Exposure On',
+            2 => 'Autofocus Off, Exposure On',
+        },
+    },{
+        Name => 'CmdDialsChangeMainSub',
+        Condition => '$$self{CmdDialsChangeMainSubExposure} and $$self{CmdDialsChangeMainSubExposure} == 2',
+        PrintConv => {
+            1 => 'Autofocus On, Exposure On (Mode A)',
+            2 => 'Autofocus Off, Exposure On (Mode A)',
+        },
+    },{
+        Name => 'CmdDialsChangeMainSub',
+        PrintConv => {
+            1 => 'Autofocus On, Exposure Off',
+            2 => 'Autofocus Off, Exposure Off',
+        },
+    }],
+    0x05b => { Name => 'CmdDialsMenuAndPlayback', PrintConv => { 1 => 'On', 2 => 'On (Image Review Excluded)', 3 => 'Off' } }, # CSf5-c (D6), CSf5-c (Z7_2)
+    0x05c => { # CSf6-d (D6), CSf5-d (Z7_2)
+        Name => 'SubDialFrameAdvance',
+        PrintConv => {
+            1 => '10 Frames',
+            2 => '50 Frames',
+            3 => 'Rating',
+            4 => 'Protect',
+            5 => 'Stills Only',
+            6 => 'Movies Only',
+            7 => 'Folder',
+        },
+    },
+    0x05d => { Name => 'ReleaseButtonToUseDial',    PrintConv => \%yesNo }, # CSf8 (D6), CSf6 (Z7_2)
+    0x05e => { Name => 'ReverseIndicators',         PrintConv => { 1 => '+ 0 -', 2 => '- 0 +' } }, # CSf9 (D6), CSf7 (Z7_2)
+    0x062 => { # CSg2-f (D6), CSg2-e (Z7_2)
+        Name => 'MovieShutterButton',
+        PrintConv => {
+            1 => 'Take Photo',
+            2 => 'Record Movies',
+        },
+    },
+    0x063 => { # Settings menu # (D6,Z7_2)
+        Name => 'Language',
+        PrintConv => {
+            5 => 'English',
+            6 => 'Spanish',
+            8 => 'French',
+            15 => 'Portuguese (Br)',
+        },
+    },
+    0x06c => [{
+        Name => 'ShootingInfoDisplay',
+        PrintConv => {
+            1 => 'Auto',
+            2 => 'Manual (dark on light)',
+            3 => 'Manual (light on dark)',
+        },
+        %infoD6,
+    },{
+        Name => 'ShootingInfoDisplay',
+        PrintConv => {
+            1 => 'Manual (dark on light)',
+            2 => 'Manual (light on dark)',
+        },
+        %infoZ72,
+    }],
+    0x074 => { Name => 'FlickAdvanceDirection', PrintConv => { 1 => 'Right to Left', 2 => 'Left to Right' } }, # CSf12-3 (D6)
+    0x080 => [{
+        Name => 'RemoteFuncButton',
+        PrintConv => {
+            1 => 'AF-On',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (reset on release)',
+            4 => 'AE Lock Only',
+            5 => 'AE/AF Lock',
+            6 => 'FV Lock',
+            7 => 'Flash Disable/Enable',
+            8 => 'Preview',
+            9 => '+NEF(RAW)',
+            10 => 'LiveView Info Display On/Off',
+            11 => 'Recall Shooting Functions',
+            12 => 'None',
+        },
+        %infoD6,
+    },{
+        Name => 'RemoteFuncButton',
+        PrintConv => {
+            1 => 'AF-On',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (reset on release)',
+            4 => 'AE Lock Only',
+            5 => 'AE/AF Lock',
+            6 => 'FV Lock',
+            7 => 'Flash Disable/Enable',
+            8 => 'Preview',
+            9 => '+NEF(RAW)',
+            10 => 'None',
+            11 => 'LiveView Info Display On/Off',
+        },
+        %infoZ72,
+    }],
+    0x08b => [{ # CSf6-a-1 and CSf6-a-2 (D6), CSf5-a-1 and CSf5-a-2 (Z7_2), (continued from above)
+        Name => 'CmdDialsReverseRotation',
+        Condition => '$$self{CmdDialsReverseRotExposureComp} and $$self{CmdDialsReverseRotExposureComp} == 1',
+        PrintConv => {
+            1 => 'No',
+            2 => 'Shutter Speed & Aperture',
+        },
+    },{
+        Name => 'CmdDialsReverseRotation',
+        PrintConv => {
+            1 => 'Exposure Compensation',
+            2 => 'Exposure Compensation, Shutter Speed & Aperture',
+        },
+    }],
+    0x08d => { # CSd10-b (D6), CSd11-b (Z7_2)
+        Name => 'FocusPeakingHighlightColor',
+        PrintConv => {
+            1 => 'Red',
+            2 => 'Yellow',
+            3 => 'Blue',
+            4 => 'White',
+        },
+    },
+    0x08e => { Name => 'ContinuousModeDisplay',     PrintConv => \%onOff }, # CSd14 (D6), CSd12 (Z7_2)
+    0x08f => { Name => 'ShutterSpeedLock',          PrintConv => \%onOff }, # CSf54-a (D6), CSf4-a (Z7_2)
+    0x090 => { Name => 'ApertureLock',              PrintConv => \%onOff }, # CSf5-b (D6), CSf4-b (Z7_2 could not select)
+    0x091 => { # CSg4-b (D6), CSg6-b (Z7_2)
+        Name => 'MovieHighlightDisplayThreshold',
+        PrintConv => {
+            1 => '255',
+            2 => '248',
+            3 => '235',
+            4 => '224',
+            5 => '213',
+            6 => '202',
+            7 => '191',
+            8 => '180',
+        },
+    },
+    0x093 => { # CSa3-a (D6), CSa3 (Z7_2)
+        Name => 'BlockShotAFResponse',
+        PrintConv => {
+            1 => '1 (Quick)',
+            2 => '2',
+            3 => '3 (Normal)',
+            4 => '4',
+            5 => '5 (Delay)',
+        },
+    },
+    0x094 => { Name => 'SubjectMotion', PrintConv => { 1 => 'Erratic', 2 => 'Steady' } }, # CSa3-b (D6)
+    0x095 => { Name => 'Three-DTrackingFaceDetection', PrintConv => \%onOff }, # CSa8 (D6)
+    0x097 => [{ # CSa5 (D6)
+        Name => 'StoreByOrientation',
+        PrintConv => {
+            1 => 'Focus Point',
+            2 => 'Focus Point and AF-area mode',
+            3 => 'Off',
+        },
+        %infoD6,
+    },{ # CSa5 (Z7_2)
+        Name => 'StoreByOrientation',
+        PrintConv => {
+            1 => 'Focus Point',
+            2 => 'Off',
+        },
+        %infoZ72,
+    }],
+    0x099 => { Name => 'DynamicAreaAFAssist',PrintConv => \%onOff }, # CSa17-c (D6), CSa9-b (Z7_2)
+    0x09a => { Name => 'ExposureCompStepSize',      PrintConv => \%thirdHalfFull }, # CSb3 (D6)
+    0x09b => { Name => 'SyncReleaseMode',           PrintConv => { 1 => 'Sync', 2 => 'No Sync' } }, # CSd4 (D6), CSd3 (Z7_2)
+    0x09c => { Name => 'ModelingFlash',             PrintConv => \%onOff }, # CSe6 (D6), CSe5 (Z7_2)
+    0x09d => { # CSe7 (D6), CSe6 (Z7_2)
+        Name => 'AutoBracketModeM',
+        PrintConv => {
+            1 => 'Flash/Speed',
+            2 => 'Flash/Speed/Aperture',
+            3 => 'Flash/Aperture',
+            4 => 'Flash Only',
+        },
+    },
+    0x09e => { Name => 'PreviewButton',             PrintConv => \%previewButtonD6 }, # CSf3-a (D6)
+    0x0a0 => [{ # CSf3-b (D6)
+        Name => 'Func1Button',
+        PrintConv => \%previewButtonD6,
+        %infoD6,
+    },{ # CSf2-a (Z7_2)
+        Name => 'Func1Button',
+        PrintConv => \%funcButtonZ7m2,
+        %infoZ72,
+    }],
+    0x0a2 => [{ # CSf3-c (D6)
+        Name => 'Func2Button',
+        PrintConv => \%previewButtonD6,
+        %infoD6,
+    },{ # CSf2-b (Z7_2)
+        Name => 'Func2Button',
+        PrintConv => \%funcButtonZ7m2,
+        %infoZ72,
+    }],
+    0x0a3 => [{ # CSf3-f (D6)
+        Name => 'AF-OnButton',
+        PrintConv => {
+            1 => 'AF-AreaMode S',
+            2 => 'AF-AreaMode D9',
+            3 => 'AF-AreaMode D25',
+            4 => 'AF-AreaMode D49',
+            5 => 'AF-AreaMode D105',
+            6 => 'AF-AreaMode 3D',
+            7 => 'AF-AreaMode Group',
+            8 => 'AF-AreaMode Group C1',
+            9 => 'AF-AreaMode Group C2',
+            10 => 'AF-AreaMode Auto Area',
+            11 => 'AF-AreaMode + AF-On S',
+            12 => 'AF-AreaMode + AF-On D9',
+            13 => 'AF-AreaMode + AF-On D25',
+            14 => 'AF-AreaMode + AF-On D49',
+            15 => 'AF-AreaMode + AF-On D105',
+            16 => 'AF-AreaMode + AF-On 3D',
+            17 => 'AF-AreaMode + AF-On Group',
+            18 => 'AF-AreaMode + AF-On Group C1',
+            19 => 'AF-AreaMode + AF-On Group C2',
+            20 => 'AF-AreaMode + AF-On Auto Area',
+            21 => 'AF-On',
+            22 => 'AF Lock Only',
+            23 => 'AE Lock (hold)',
+            24 => 'AE/WB Lock (hold)',
+            25 => 'AE Lock (reset on release)',
+            26 => 'AE Lock Only',
+            27 => 'AE/AF Lock',
+            28 => 'Recall Shooting Functions',
+            29 => 'None',
+        },
+        %infoD6,
+    },{ # CSf2-c (Z7_2)
+        Name => 'AF-OnButton',
+        PrintConv => {
+            1 => 'Center Focus Point',
+            2 => 'AF-On',
+            3 => 'AF Lock Only',
+            4 => 'AE Lock (hold)',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock Only',
+            7 => 'AE/AF Lock',
+            8 => 'LiveView Info Display On/Off',
+            9 => 'Zoom (Low)',
+            10 => 'Zoom (1:1)',
+            11 => 'Zoom (High)',
+            12 => 'None'
+        },
+        %infoZ72,
+    }],
+    0x0a4 => { Name => 'SubSelector', PrintConv => \%tagSubSelector }, # CSf3-g-1 # (D6), CSf2-d-1 # (Z7_2)
+    0x0a5 => [{ # CSf3-h (D6)
+        Name => 'SubSelectorCenter',
+        PrintConv => {
+            1 => 'Preset Focus Point - Press To Recall',
+            2 => 'Preset Focus Point - Hold To Recall',
+            3 => 'Center Focus Point',
+            4 => 'AF-AreaMode S',
+            5 => 'AF-AreaMode D9',
+            6 => 'AF-AreaMode D25',
+            7 => 'AF-AreaMode D49',
+            8 => 'AF-AreaMode D105',
+            9 => 'AF-AreaMode 3D',
+            10 => 'AF-AreaMode Group',
+            11 => 'AF-AreaMode Group C1',
+            12 => 'AF-AreaMode Group C2',
+            13 => 'AF-AreaMode Auto Area',
+            14 => 'AF-AreaMode + AF-On S',
+            15 => 'AF-AreaMode + AF-On D9',
+            16 => 'AF-AreaMode + AF-On D25',
+            17 => 'AF-AreaMode + AF-On D49',
+            18 => 'AF-AreaMode + AF-On D105',
+            19 => 'AF-AreaMode + AF-On 3D',
+            20 => 'AF-AreaMode + AF-On Group',
+            21 => 'AF-AreaMode + AF-On Group C1',
+            22 => 'AF-AreaMode + AF-On Group C2',
+            23 => 'AF-AreaMode + AF-On Auto Area',
+            24 => 'AF-On',
+            25 => 'AF Lock Only',
+            26 => 'AE Lock (hold)',
+            27 => 'AE/WB Lock (hold)',
+            28 => 'AE Lock (reset on release)',
+            29 => 'AE Lock Only',
+            30 => 'AE/AF Lock',
+            31 => 'FV Lock',
+            32 => 'Flash Disable/Enable',
+            33 => 'Preview',
+            34 => 'Recall Shooting Functions',
+            35 => 'Bracketing Burst',
+            36 => 'Synchronized Release (Master)',
+            37 => 'Synchronized Release (Remote)',
+            38 => 'None',
+        },
+        %infoD6,
+    },{ # CSf2-e (Z7_2)
+        Name => 'SubSelectorCenter',
+        PrintConv => {
+            1 => 'Center Focus Point',
+            2 => 'AF-On',
+            3 => 'AF Lock Only',
+            4 => 'AE Lock (hold)',
+            5 => 'AE Lock (reset on release)',
+            6 => 'AE Lock Only',
+            7 => 'AE/AF Lock',
+            8 => 'FV Lock',
+            9 => 'Flash Disable/Enable',
+            10 => 'Preview',
+            11 => 'Matrix Metering',
+            12 => 'Center-weighted Metering',
+            13 => 'Spot Metering',
+            14 => 'Highlight-weighted Metering',
+            15 => 'Bracketing Burst',
+            16 => 'Synchronized Release (Master)',
+            17 => 'Synchronized Release (Remote)',
+            20 => '+NEF(RAW)',
+            21 => 'LiveView Info Display On/Off',
+            22 => 'Grid Display',
+            23 => 'Image Area',
+            24 => 'Non-CPU Lens',
+            25 => 'None',
+        },
+        %infoZ72,
+    }],
+    0x0a7 => [{ # CSf3-n (D6)
+        Name => 'LensFunc1Button',
+        PrintConv => {
+            1 => 'Preset Focus Point - Press To Recall',
+            2 => 'Preset Focus Point - Hold To Recall',
+            3 => 'AF-AreaMode S',
+            4 => 'AF-AreaMode D9',
+            5 => 'AF-AreaMode D25',
+            6 => 'AF-AreaMode D49',
+            7 => 'AF-AreaMode D105',
+            8 => 'AF-AreaMode 3D',
+            9 => 'AF-AreaMode Group',
+            10 => 'AF-AreaMode Group C1',
+            11 => 'AF-AreaMode Group C2',
+            12 => 'AF-AreaMode Auto Area',
+            13 => 'AF-AreaMode + AF-On S',
+            14 => 'AF-AreaMode + AF-On D9',
+            15 => 'AF-AreaMode + AF-On D25',
+            16 => 'AF-AreaMode + AF-On D49',
+            17 => 'AF-AreaMode + AF-On D105',
+            18 => 'AF-AreaMode + AF-On 3D',
+            19 => 'AF-AreaMode + AF-On Group',
+            20 => 'AF-AreaMode + AF-On Group C1',
+            21 => 'AF-AreaMode + AF-On Group C2',
+            22 => 'AF-AreaMode + AF-On Auto Area',
+            23 => 'AF-On',
+            24 => 'AF Lock Only',
+            25 => 'AE Lock Only',
+            26 => 'AE/AF Lock',
+            27 => 'Flash Disable/Enable',
+            28 => 'Recall Shooting Functions',
+            29 => 'Synchronized Release (Master)',
+            30 => 'Synchronized Release (Remote)',
+        },
+        %infoD6,
+    },{ # CSf2-g (Z7_2)
+        Name => 'LensFunc1Button',
+        PrintConv => \%lensFuncButtonZ7m2,
+        %infoZ72,
+    }],
+    0x0a8 => { Name => 'CmdDialsApertureSetting',   PrintConv => { 1 => 'Sub-command Dial', 2 => 'Aperture Ring' } }, # CSf6-c (D6)
+    0x0a9 => { Name => 'MultiSelector',             PrintConv => \%tagMultiSelector }, # CSf7 (D6)
+    0x0aa => { # CSf10 (D6)
+        Name => 'LiveViewButtonOptions',
+        PrintConv => {
+            1 => 'Enable',
+            2 => 'Enable (Standby Timer Active)',
+            3 => 'Disable',
+        },
+    },
+    0x0ab => { # CSf11 (D6)
+        Name => 'LightSwitch',
+        PrintConv => {
+            1 => 'LCD Backlight',
+            2 => 'LCD Backlight and Shooting Information',
+        },
+    },
+    0x0b1 => [{ # CSg2-a (D6)
+        Name => 'MoviePreviewButton',
+        PrintConv => {
+            1 => 'Power Aperture (Open)',
+            2 => 'Exposure Compensation',
+            3 => 'Grid Display',
+            4 => 'Zoom (Low)',
+            5 => 'Zoom (1:1)',
+            6 => 'Zoom (High)',
+            7 => 'Image Area',
+            8 => 'Microphone Sensitivity',
+            9 => 'None',
+        },
+        %infoD6,
+    },{ # CSg2-a (Z7_2)
+        Name => 'MovieFunc1Button',
+        PrintConv => {
+            1 => 'Power Aperture (Open)',
+            2 => 'Exposure Compensation',
+            3 => 'Subject Tracking',
+            4 => 'LiveView Info Display On/Off',
+            5 => 'Grid Display',
+            6 => 'Zoom (Low)',
+            7 => 'Zoom (1:1)',
+            8 => 'Zoom (High)',
+            9 => 'Protect',
+            10 => 'Image Area',
+            11 => 'White Balance',
+            12 => 'Picture Control',
+            13 => 'Active-D Lighting',
+            14 => 'Metering',
+            15 => 'Focus Mode',
+            16 => 'Microphone Sensitivity',
+            17 => 'Focus Peaking',
+            18 => 'Rating (None)',
+            19 => 'Rating (5)',
+            20 => 'Rating (4)',
+            21 => 'Rating (3)',
+            22 => 'Rating (2)',
+            23 => 'Rating (1)',    # no mapping for 24 on the Z7_2.  Possibly intended for Rating = 'Candidate for Deletion'?
+            25 => 'None',
+        },
+        %infoZ72,
+    }],
+    0x0b3 => [{ # CSg2-b (D6)
+        Name => 'MovieFunc1Button',
+        PrintConv => {
+            1 => 'Power Aperture (Close)',
+            2 => 'Exposure Compensation',
+            3 => 'Grid Display',
+            4 => 'Zoom (Low)',
+            5 => 'Zoom (1:1)',
+            6 => 'Zoom (High)',
+            7 => 'Image Area',
+            8 => 'Microphone Sensitivity',
+            9 => 'None',
+        },
+        %infoD6,
+    },{ # CSg2-b (Z7_2)
+        Name => 'MovieFunc2Button',
+        PrintConv => { # TODO:  simplify Func1 and Func2 movies buttons - identical except for the 1st entry
+            1 => 'Power Aperture (Close)',
+            2 => 'Exposure Compensation',
+            3 => 'Subject Tracking',
+            4 => 'LiveView Info Display On/Off',
+            5 => 'Grid Display',
+            6 => 'Zoom (Low)',
+            7 => 'Zoom (1:1)',
+            8 => 'Zoom (High)',
+            9 => 'Protect',
+            10 => 'Image Area',
+            11 => 'White Balance',
+            12 => 'Picture Control',
+            13 => 'Active-D Lighting',
+            14 => 'Metering',
+            15 => 'Focus Mode',
+            16 => 'Microphone Sensitivity',
+            17 => 'Focus Peaking',
+            18 => 'Rating (None)',
+            19 => 'Rating (5)',
+            20 => 'Rating (4)',
+            21 => 'Rating (3)',
+            22 => 'Rating (2)',
+            23 => 'Rating (1)',    # no mapping for 24 on the Z7_2.  Possibly intended for Rating = 'Candidate for Deletion'?
+            25 => 'None',
+        },
+        %infoZ72,
+    }],
+    0x0b5 => { # CSg2-c (D6)
+        Name => 'MovieFunc2Button',
+        PrintConv => {
+            1 => 'Grid Display',
+            2 => 'Zoom (Low)',
+            3 => 'Zoom (1:1)',
+            4 => 'Zoom (High)',
+            5 => 'Image Area',
+            6 => 'Microphone Sensitivity',
+            7 => 'None',
+        },
+    },
+    0x0b6 => [{ # CSg2-e (D6)
+        Name => 'AssignMovieSubselector',
+        PrintConv => {
+            1 => 'Center Focus Point',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (hold)',
+            4 => 'AE/WB Lock (hold)',
+            5 => 'AE Lock Only',
+            6 => 'AE/AF Lock',
+            7 => 'Zoom (Low)',
+            8 => 'Zoom (1:1)',
+            9 => 'Zoom (High)',
+            10 => 'Record Movies',
+            11 => 'None',
+        },
+        %infoD6,
+    },{ # CSg2-d (Z7_2)
+        Name => 'AssignMovieSubselector',
+        PrintConv => {
+            1 => 'Center Focus Point',
+            2 => 'AF Lock Only',
+            3 => 'AE Lock (hold)',
+            4 => 'AE Lock Only',
+            5 => 'AE/AF Lock',
+            6 => 'LiveView Info Display On/Off',
+            7 => 'Grid Display',
+            8 => 'Zoom (Low)',
+            9 => 'Zoom (1:1)',
+            10 => 'Zoom (High)',
+            11 => 'Record Movies',
+            12 => 'Image Area',
+            13 => 'None',
+        },
+        %infoZ72,
+    }],
+    0x0b8 => { Name => 'LimitAFAreaModeSelD9',          PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-a (D6)
+    0x0b9 => { Name => 'LimitAFAreaModeSelD25',         PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-b (D6)
+    0x0bc => { Name => 'LimitAFAreaModeSel3D',          PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-e (D6)
+    0x0bd => { Name => 'LimitAFAreaModeSelGroup',       PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-f (D6)
+    0x0be => { Name => 'LimitAFAreaModeSelAuto',        PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-i (D6), CSa7-g (Z7_2)
+  # 0x0bf => { Name => 'LimitSelectableImageArea30x20', PrintConv => \%limitNolimit }, # CSd8-1 (D6) further investigation & testing of CSd8-1 and CSd8-2 required.  The other CSd8 tags are fine.
+  # 0x0c0 => { Name => 'LimitSelectableImageAreaDX',    PrintConv => \%limitNolimit }, # CSd8-2 (D6) further investigation & testing of CSd8-1 and CSd8-2 required.  The other CSd8 tags are fine.
+    0x0c1 => { Name => 'LimitSelectableImageArea5To4',  PrintConv => \%limitNolimit, Unknown => 1 }, # CSd8-3 (D6)
+    0x0c2 => { Name => 'LimitSelectableImageArea1To1',  PrintConv => \%limitNolimit, Unknown => 1 }, # CSd8-4 (D6)
+  # 0x0d3 => CSf3-g-2 (D6), CSf2-d-2 (Z7_2) SelectorPlaybackRole 'Scroll' and  'Display Next/Previous' (skipped to reduce volume of output)
+    0x0d4 => { Name => 'PhotoShootingMenuBank',         PrintConv => \%menuBank }, # (D6)
+    0x0d5 => { Name => 'CustomSettingsBank',            PrintConv => \%menuBank }, # (D6)
+    0x0d6 => { Name => 'LimitAF-AreaModeSelPinpoint',   PrintConv => \%limitNolimit, Unknown => 1 }, # CSa7-a (Z7_2)
+    0x0d7 => { Name => 'LimitAF-AreaModeSelDynamic',    PrintConv => \%limitNolimit, Unknown => 1 }, # CSa7-b (Z7_2)
+    0x0d8 => { Name => 'LimitAF-AreaModeSelWideAF_S',   PrintConv => \%limitNolimit, Unknown => 1 }, # CSa7-c (Z7_2)
+    0x0d9 => { Name => 'LimitAF-AreaModeSelWideAF_L',   PrintConv => \%limitNolimit, Unknown => 1 }, # CSa7-d (Z7_2)
+    0x0da => { Name => 'LowLightAF',                    PrintConv => \%onOff }, # CSa10 (Z7_2)
+    0x0db => { Name => 'LimitSelectableImageAreaDX',    PrintConv => \%limitNolimit, Unknown => 1 }, # CSd7-a (Z7_2)
+    0x0dc => { Name => 'LimitSelectableImageArea5To4',  PrintConv => \%limitNolimit, Unknown => 1 }, # CSd7-b (Z7_2)
+    0x0dd => { Name => 'LimitSelectableImageArea1To1',  PrintConv => \%limitNolimit, Unknown => 1 }, # CSd7-c (Z7_2)
+    0x0de => { Name => 'LimitSelectableImageArea16To9', PrintConv => \%limitNolimit, Unknown => 1 }, # CSd7-d (Z7_2)
+    0x0df => { Name => 'ApplySettingsToLiveView',       PrintConv => \%onOff }, # CSd9  # new tag with Z7_2 # (Z7_2)
+    0x0e0 => { # CSd10-a (D6), CSd11-a (Z7_2)
+        Name => 'FocusPeakingLevel',
+        PrintConv => {
+            1 => 'High Sensitivity',
+            2 => 'Standard Sensitivity',
+            3 => 'Low Sensitivity',
+            4 => 'Off',
+        },
+    },
+    0x0e9 => { # CSf2-i        # need to confirm with a Z series lens  # (Z7_2)
+        Name => 'LensControlRing',
+        PrintConv => {
+            1 => 'Focus (M/A)',
+            2 => 'Aperture',
+            3 => 'Exposure Compensation',
+            4 => 'ISO Sensitivity',
+            5 => 'None (Disabled)',
+        },
+    },
+  # 0x0eb  MovieLensControlRing ? # (Z7_2)
+  # 0x0ec # (Z7_2)
+    0x0ed => [{ # CSg3 (D6)
+        Name => 'MovieMultiSelector',
+        PrintConv => {
+            1 => 'Center Focus Point',
+            2 => 'Zoom (Low)',
+            3 => 'Zoom (1:1)',
+            4 => 'Zoom (High)',
+            5 => 'Record Movies',
+            6 => 'None',
+        },
+        %infoD6,
+    },{ # labels Ok button on camera # (Z7_2)
+        Name => 'MovieMultiSelector',
+        PrintConv => { # Z7 has codes for both OK and MultiSelector - although only the OK value can be changed.  [The multiselector served as the OK button on these cameras].
+            1 => 'Center Focus Point',
+            2 => 'Zoom (Low)',
+            3 => 'Zoom (1:1)',
+            4 => 'Zoom (High)',
+            5 => 'Record Movies',
+            6 => 'None',
+        },
+    }],
+    0x0ee => { Name => 'MovieAFSpeed',                  ValueConv => '$val - 6', ValueConvInv => '$val + 6' }, # CSg4-a (Z7_2)
+    0x0ef => { # CSg4-b (Z7_2)
+        Name => 'MovieAFSpeedApply',
+        PrintConv => {
+            1 => 'Always',
+            2 => 'Only During Recording',
+        },
+    },
+    0x0f0 => { # CSg5 (Z7_2)
+        Name => 'MovieAFTrackingSensitivity',
+        PrintConv => {
+            1 => '1 (High)',
+            2 => '2',
+            3 => '3',
+            4 => '4 (Normal)',
+            5 => '5',
+            6 => '6',
+            7 => '7 (Low)',
+        },
+    },
+    0x0f1 => { # CSg4-a (D6), CSg6-a (Z7_2)
+        Name => 'MovieHighlightDisplayPattern',
+        PrintConv => {
+            1 => 'Pattern 1',
+            2 => 'Pattern 2',
+            3 => 'Off',
+        },
+    },
+    0x0f2 => { Name => 'SubDialFrameAdvanceRating5',    PrintConv => \%noYes, Unknown => 1 }, # (D6,Z7_2)
+    0x0f3 => { Name => 'SubDialFrameAdvanceRating4',    PrintConv => \%noYes, Unknown => 1 }, # (D6,Z7_2)
+    0x0f4 => { Name => 'SubDialFrameAdvanceRating3',    PrintConv => \%noYes, Unknown => 1 }, # (D6,Z7_2)
+    0x0f5 => { Name => 'SubDialFrameAdvanceRating2',    PrintConv => \%noYes, Unknown => 1 }, # (D6,Z7_2)
+    0x0f6 => { Name => 'SubDialFrameAdvanceRating1',    PrintConv => \%noYes, Unknown => 1 }, # (D6,Z7_2)
+    0x0f7 => { Name => 'SubDialFrameAdvanceRating0',    PrintConv => \%noYes, Unknown => 1 }, # (D6,Z7_2)
+  # 0x0f8 ??  looks like it should be part of the above, but nothing seems to cause the value to change.  Possibly intended for Rating='Candidate for Deletion' # (D6)
+    0x0f9 => { # CSg2-c (Z7_2)
+        Name => 'MovieAF-OnButton',
+        PrintConv => {
+            1 => 'Center Focus Point',
+            2 => 'AF-On',
+            3 => 'AF Lock Only',
+            4 => 'AE Lock (hold)',
+            5 => 'AE Lock Only',
+            6 => 'AE/AF Lock',
+            7 => 'LiveView Info Display On/Off',
+            8 => 'Zoom (Low)',
+            9 => 'Zoom (1:1)',
+            10 => 'Zoom (High)',
+            11 => 'Record Movies',
+            12 => 'None',
+        },
+    },
+    0x0fb => { Name => 'SecondarySlotFunction', PrintConv => \%tagSecondarySlotFunction },    # tag name selected to maintain compatibility with older cameras # (Z7_2)
+    0x0fb => { Name => 'SecondarySlotFunction', PrintConv => \%tagSecondarySlotFunction }, # (D6)
+    0x0fc => { Name => 'SilentPhotography',     PrintConv => \%onOff }, # (D6,Z7_2)   # tag is associated with Silent LiveView Photography (as distinguisehed from Silent Interval or Silent Focus Shift)
+    0x0fd => { Name => 'ExtendedShutterSpeeds', PrintConv => \%onOff }, # CSd7 (D6), CSd6 (Z7_2)
+    0x109 => { # (D6,Z7_2)
+        Name => 'BracketSet',
+        RawConv => '$$self{BracketSet} = $val',
+        PrintConv => {
+            1 => 'AE/Flash',
+            2 => 'AE',
+            3 => 'Flash',
+            4 => 'White Balance',
+            5 => 'Active-D Lighting',
+        },
+    },
+    0x10a => [{ # (D6/Z7_2)
+        Name => 'BracketProgram',
+        Condition => '$$self{BracketSet} < 4',
+        Notes => 'AE and/or Flash Bracketing',
+        RawConv => '$$self{BracketProgram} = $val',
+        PrintConv =>  {
+            15 => '+3F',
+            16 => '-3F',
+            17 => '+2F',
+            18 => '-2F',
+            19 => 'Disabled',
+            20 => '3F',
+            21 => '5F',
+            22 => '7F',
+            23 => '9F',
+        },
+    },{
+        Name => 'BracketProgram',
+        Condition => '$$self{BracketSet} and $$self{BracketSet} == 4',
+        Notes => 'White Balance Bracketing',
+        RawConv => '$$self{BracketProgram} = $val',
+        PrintConv =>  {
+            1 => 'B3F',
+            2 => 'A3F',
+            3 => 'B2F',
+            4 => 'A2F',
+            5 => 'Disabled',
+            6 => '3F',
+            7 => '5F',
+            8 => '7F',
+            9 => '9F',
+            19 => 'N/A'    # observed when shooting other than JPG
+        },
+    },{
+        Name => 'BracketProgram',
+        Condition => '$$self{BracketSet} and $$self{BracketSet} == 5',
+        Notes => 'Active-D Bracketing',
+        RawConv => '$$self{BracketProgram} = $val',
+        Mask => 0x0f,
+        PrintConv =>  {
+            10 => 'Disabled',
+            11 => '2 Exposures',
+            12 => '3 Exposures',
+            13 => '4 Exposures',
+            14 => '5 Exposures',
+        },
+    }],
+    0x10b => [{ # (D6/Z7_2)
+        Name => 'BracketIncrement',
+        Condition => '$$self{BracketSet} < 4 and $$self{BracketProgram} ne 19',
+        Notes => 'AE and/or Flash Bracketing enabled',
+        PrintConv =>  {
+            0x01 => '0.3',
+            0x03 => '0.5',
+            0x04 => '1.0',
+            0x05 => '2.0',
+            0x06 => '3.0',
+        },
+    },{
+        Name => 'BracketIncrement',
+        Condition => '$$self{BracketSet} == 4 and $$self{BracketProgram} ne 5',
+        Notes => 'White Balance Bracketing enabled',
+        PrintConv => '$val-6',   # TODO:  qualify amber/blue direction of increment (eg, '1A' vs.'1B' vs '1A,1B')
+    }],
+    0x10c => { # (D6/Z7_2)
+        Name => 'BracketIncrement',
+        Condition => '$$self{BracketSet} == 5 and $$self{BracketProgram} ne 10',
+        Notes => 'Active-D Bracketing enabled',
+        PrintConv =>  {
+            0 => 'Off',
+            1 => 'Off, Low',
+            2 => 'Off, Normal',
+            3 => 'Off, High',
+            4 => 'Off, Extra High',
+            5 => 'Off, Auto',
+            6 => 'Off, Low, Normal',
+            7 => 'Off, Low, Normal, High',
+            8 => 'Off, Low, Normal, High, Extra High',
+        },
+    },
+    0x116 => { Name => 'GroupAreaC1',               PrintConv =>\%groupAreaCustom },    # CSa10-a (new with D6) # (D6)
+    0x117 => { Name => 'AutoAreaAFStartingPoint',   PrintConv => \%enableDisable },     # CSa12 (D6)
+    0x118 => { Name => 'FocusPointPersistence',     PrintConv => { 1 => 'Auto', 2 => 'Off' } }, # CSa13 (new with D6) # (D6)
+    0x119 => { Name => 'LimitAFAreaModeSelD49',     PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-c (D6)
+    0x11a => { Name => 'LimitAFAreaModeSelD105',    PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-d (D6)
+    0x11b => { Name => 'LimitAFAreaModeSelGroupC1', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-g (D6)
+    0x11c => { Name => 'LimitAFAreaModeSelGroupC2', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa14-h (D6)
+    0x11d => { # CSa15 (D6)
+        Name => 'AutoFocusModeRestrictions',
+        PrintConv => {
+            1 => 'AF-S',
+            2 => 'AF-C',
+            3 => 'No Limit',
+        },
+    },
+    0x11e => { # CSa17-b (D6)
+        Name => 'FocusPointBrightness',
+        PrintConv => {
+            1 => 'Extra High',
+            2 => 'High',
+            3 => 'Normal',
+            4 => 'Low',
+        },
+    },
+    0x11f => { Name => 'CHModeShootingSpeed',       ValueConv => '15 - $val', ValueConvInv => '15 + $val', PrintConv => '"$val fps"', PrintConvInv => '$val=~s/\s*fps//i; $val' }, # CSd1-a (D6)
+    0x120 => { Name => 'CLModeShootingSpeed',       ValueConv => '11 - $val', ValueConvInv => '11 + $val', PrintConv => '"$val fps"', PrintConvInv => '$val=~s/\s*fps//i; $val' }, # CSd1-b (D6)
+    0x121 => { # CSd1-c (new with D6)
+        Name => 'QuietShutterShootingSpeed',
+        PrintConv => {
+            1 => 'Single',
+            2 => '5 fps',
+            3 => '4 fps',
+            4 => '3 fps',
+            5 => '2 fps',
+            6 => '1 fps',
+        },
+    },
+    0x122 => { Name => 'LimitReleaseModeSelCL',         PrintConv => \%limtReleaseModeSel, Unknown => 1 }, # CSd3-a (D6)
+    0x123 => { Name => 'LimitReleaseModeSelCH',         PrintConv => \%limtReleaseModeSel, Unknown => 1 }, # CSd3-b (D6)
+    0x124 => { Name => 'LimitReleaseModeSelQ',          PrintConv => \%limtReleaseModeSel, Unknown => 1 }, # CSd3-c (D6)
+    0x125 => { Name => 'LimitReleaseModeSelTimer',      PrintConv => \%limtReleaseModeSel, Unknown => 1 }, # CSd3-d (D6)
+    0x126 => { Name => 'LimitReleaseModeSelMirror-Up',  PrintConv => \%limtReleaseModeSel, Unknown => 1 }, # CSd3-e (D6)
+    0x127 => { Name => 'LimitSelectableImageArea16To9', PrintConv => \%limitNolimit, Unknown => 1 }, # CSd8-5 (D6)
+    0x128 => { Name => 'RearControPanelDisplay',        PrintConv => { 1 => 'Release Mode', 2 => 'Frame Count' } }, # CSd12  # new tag with D6 # (D6)
+    0x129 => { Name => 'FlashBurstPriority',            PrintConv => { 1 => 'Frame Rate', 2 => 'Exposure' } }, # CSE5   # new tag with D6 # (D6)
+    0x12a => { Name => 'RecallShootFuncExposureMode',   PrintConv => \%offOn }, # (D6)
+    0x12b => { Name => 'RecallShootFuncShutterSpeed',   PrintConv => \%offOn }, # (D6)
+    0x12c => { Name => 'RecallShootFuncAperture',       PrintConv => \%offOn }, # (D6)
+    0x12d => { Name => 'RecallShootFuncExposureComp',   PrintConv => \%offOn }, # (D6)
+    0x12e => { Name => 'RecallShootFuncISO',            PrintConv => \%offOn }, # (D6)
+    0x12f => { Name => 'RecallShootFuncMeteringMode',   PrintConv => \%offOn }, # (D6)
+    0x130 => { Name => 'RecallShootFuncWhiteBalance',   PrintConv => \%offOn }, # (D6)
+    0x131 => { Name => 'RecallShootFuncAFAreaMode',     PrintConv => \%offOn }, # (D6)
+    0x132 => { Name => 'RecallShootFuncFocusTracking',  PrintConv => \%offOn }, # (D6)
+    0x133 => { Name => 'RecallShootFuncAF-On',          PrintConv => \%offOn }, # (D6)
+    0x134 => { # CSf3-d (D6)
+        Name => 'VerticalFuncButton',
+        PrintConv => {
+            1 => 'Preset Focus Point',
+            2 => 'AE Lock (hold)',
+            3 => 'AE/WB Lock (hold)',
+            4 => 'AE Lock (reset on release)',
+            5 => 'FV Lock',
+            6 => 'Preview',
+            7 => '+NEF(RAW)',
+            8 => 'Grid Display',
+            9 => 'Virtual Horizon',
+            10 => 'Voice Memo',
+            11 => 'Playback',
+            12 => 'Filtered Playback',
+            13 => 'Photo Shooting Bank',
+            14 => 'Exposure Mode',
+            15 => 'Exposure Comp',
+            16 => 'AF Mode/AF Area Mode',
+            17 => 'Image Area',
+            18 => 'ISO',
+            19 => 'Active-D Lighting',
+            20 => 'Metering',
+            21 => 'Exposure Delay Mode',
+            22 => 'Shutter/Aperture Lock',
+            23 => '1 Stop Speed/Aperture',
+            24 => 'Rating 0',
+            25 => 'Rating 5',
+            26 => 'Rating 4',
+            27 => 'Rating 3',
+            28 => 'Rating 2',
+            29 => 'Rating 1',
+            30 => 'Candidate For Deletion',
+            31 => 'Non-CPU Lens',
+            32 => 'None',
+        },
+    },
+    0x135 => { # CSf3-e (D6)
+        Name => 'Func3Button',
+        PrintConv => {
+            1 => 'Voice Memo',
+            2 => 'Select To Send',
+            3 => 'Wired LAN',
+            4 => 'My Menu',
+            5 => 'My Menu Top Item',
+            6 => 'Filtered Playback',
+            7 => 'Rating 0',
+            8 => 'Rating 5',
+            9 => 'Rating 4',
+            10 => 'Rating 3',
+            11 => 'Rating 2',
+            12 => 'Rating 1',
+            13 => 'Candidate For Deletion',
+            14 => 'None',
+        },
+    },
+    0x136 => { # CSf3-i (D6)
+        Name => 'VerticalAF-OnButton',
+        PrintConv => {
+            1 => 'AF-AreaMode S',
+            2 => 'AF-AreaMode D9',
+            3 => 'AF-AreaMode D25',
+            4 => 'AF-AreaMode D49',
+            5 => 'AF-AreaMode D105',
+            6 => 'AF-AreaMode 3D',
+            7 => 'AF-AreaMode Group',
+            8 => 'AF-AreaMode Group C1',
+            9 => 'AF-AreaMode Group C2',
+            10 => 'AF-AreaMode Auto Area',
+            11 => 'AF-AreaMode + AF-On S',
+            12 => 'AF-AreaMode + AF-On D9',
+            13 => 'AF-AreaMode + AF-On D25',
+            14 => 'AF-AreaMode + AF-On D49',
+            15 => 'AF-AreaMode + AF-On D105',
+            16 => 'AF-AreaMode + AF-On 3D',
+            17 => 'AF-AreaMode + AF-On Group',
+            18 => 'AF-AreaMode + AF-On Group C1',
+            19 => 'AF-AreaMode + AF-On Group C2',
+            20 => 'AF-AreaMode + AF-On Auto Area',
+            21 => 'Same as AF-On',
+            22 => 'AF-On',
+            23 => 'AF Lock Only',
+            24 => 'AE Lock (hold)',
+            25 => 'AE/WB Lock (hold)',
+            26 => 'AE Lock (reset on release)',
+            27 => 'AE Lock Only',
+            28 => 'AE/AF Lock',
+            29 => 'Recall Shooting Functions',
+            30 => 'None',
+        },
+    },
+    0x137 => { Name => 'VerticalMultiSelector', PrintConv => \%tagSubSelector }, # CSf3-j-1 # (D6)
+    0x138 => { # CSf3-k (D6)
+        Name => 'MeteringButton',
+        PrintConv => {
+            1 => 'Photo Shooting Bank',
+            2 => 'Image Area',
+            3 => 'Active-D Lighting',
+            4 => 'Metering',
+            5 => 'Exposure Delay Mode',
+            6 => 'Shutter/Aperture Lock',
+            7 => '1 Stop Speed/Aperture',
+            8 => 'Non-CPU Lens',
+            9 => 'None',
+        },
+    },
+    0x139 => { Name => 'PlaybackFlickUp', RawConv => '$$self{PlaybackFlickUp} = $val', PrintConv => \%flickUpDownD6 }, # CSf12-1-a # (D6)
+    0x13a => { Name => 'PlaybackFlickUpRating', Condition => '$$self{PlaybackFlickUp} and $$self{PlaybackFlickUp} == 1', Notes => 'Meaningful only when PlaybackFlickUp is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-1-b # (D6)
+    0x13b => { Name => 'PlaybackFlickDown', RawConv => '$$self{PlaybackFlickDown} = $val', PrintConv => \%flickUpDownD6 }, # CSf12-2-a # (D6)
+    0x13c => { Name => 'PlaybackFlickDownRating', Condition => '$$self{PlaybackFlickDown} and $$self{PlaybackFlickDown} == 1', Notes => 'Meaningful only when PlaybackFlickDown is Rating', PrintConv => \%flickUpDownRatingD6 }, # CSf12-2-b # (D6)
+    0x13d => {  # CSg2-d (D6)
+        Name => 'MovieFunc3Button',
+        PrintConv => {
+            1 => 'Record Movies',
+            2 => 'My Menu',
+            3 => 'My Menu Top Item',
+            4 => 'None',
+        },
+    },
+    0x150 => { # CSd5 (Z7_2) new with Z series
+        Name => 'ShutterType',
+        PrintConv => {
+            1 => 'Auto',
+            2 => 'Mechanical',
+            3 => 'Electronic',
+        },
+    },
+    0x151 => { Name => 'LensFunc2Button',       PrintConv => \%lensFuncButtonZ7m2 }, # CSf2-h (Z7_2)
+    0x158 => { Name => 'USBPowerDelivery',      PrintConv => \%enableDisable }, # (Z7_2)
+    0x15b => { Name => 'GroupAreaC2',           PrintConv =>\%groupAreaCustom },    # CSa10-b (new with D6) # (D6)
+    0x15c => { Name => 'BracketingBurstOptions',PrintConv => \%enableDisable }, # CSe9 (D6)
+  # 0x15d => CSf3-j-2 (D6) 'Same as Multi-Selector with Info(U/D) & Playback(R/L)'  and  'Same as Multi-Selector with Info(R/L) & Playback(U/D)'  (skipped to reduce volume of output)
+    0x15e => { Name => 'PrimarySlot',           PrintConv => { 1 => 'CFexpress/XQD Card', 2 => 'SD Card' } }, # (Z7_2)
+    0x15f => { Name => 'ReverseFocusRing',      PrintConv => { 1 => 'Not Reversed', 2 => 'Reversed' } }, # CSf8 (Z7_2)
+    0x160 => { # CSf9-a (Z7_2)
+        Name => 'VerticalFuncButton',
+        PrintConv => {
+            1 => 'AE Lock (hold)',
+            2 => 'AE Lock (reset on release)',
+            3 => 'FV Lock',
+            4 => 'Preview',
+            5 => '+NEF(RAW)',
+            6 => 'Subject Tracking',
+            7 => 'Silent Photography',
+            8 => 'LiveView Info Display On/Off',
+            9 => 'Playback',
+            10 => 'Image Area',
+            11 => 'Metering',
+            12 => 'Flash Mode',
+            13 => 'Focus Mode',
+            14 => 'Exposure Delay Mode',
+            15 => 'Shutter/Aperture Lock',
+            16 => 'Exposure Compensation',
+            17 => 'ISO Sensitivity',
+            18 => 'None',
+        },
+    },
+    0x161 => { # CSf9-b (Z7_2)
+        Name => 'VerticalAFOnButton',
+        PrintConv => {
+            1 => 'Same as AF-On Button',
+            2 => 'Select Center Focus Point',
+            3 => 'AF-On',
+            4 => 'AF Lock Only',
+            5 => 'AE Lock (hold)',
+            6 => 'AE Lock (reset on release)',
+            7 => 'AE Lock Only',
+            8 => 'AE/AF Lock',
+            9 => 'LiveView Info Display On/Off',
+            10 => 'Zoom (Low)',
+            11 => 'Zoom (1:1)',
+            12 => 'Zoom (High)',
+            13 => 'None',
+        },
+    },
+    0x162 => { Name => 'VerticalMultiSelector', PrintConv => \%tagSubSelector }, # CSf9-c (Z7_2)
+  # 0x163 => CSf9-c-2 (Z7_2) 'Same as Multi-Selector with Info(U/D) & Playback(R/L)' and 'Same as Multi-Selector with Info(R/L) & Playback(U/D)' (skipped to reduce volume of output)
+    0x164 => { # CSg7-a (Z7_2)
+        Name => 'VerticalMovieFuncButton',
+        PrintConv => {
+            1 => 'LiveView Info Display On/Off',
+            2 => 'Record Movies',
+            3 => 'Exposure Compensation',
+            4 => 'ISO',
+            5 => 'None',
+        },
+    },
+    0x165 => { # CSg7-b (Z7_2)
+        Name => 'VerticalMovieAFOnButton',
+        PrintConv => {
+            1 => 'Same as AF-On',
+            2 => 'Center Focus Point',
+            3 => 'AF-On',
+            4 => 'AF Lock Only',
+            5 => 'AE Lock (hold)',
+            6 => 'AE Lock Only',
+            7 => 'AE/AF Lock',
+            8 => 'LiveView Info Display On/Off',
+            9 => 'Zoom (Low)',
+            10 => 'Zoom (1:1)',
+            11 => 'Zoom (High)',
+            12 => 'Record Movies',
+            13 => 'None',
+        },
+    },
+    0x169 => { Name => 'LimitAF-AreaModeSelAutoPeople',   PrintConv => \%limitNolimit, Unknown => 1 }, # CSa7-h (Z7_2)
+    0x16a => { Name => 'LimitAF-AreaModeSelAutoAnimals',  PrintConv => \%limitNolimit, Unknown => 1 }, # CSa7-h (Z7_2)
+    0x16b => { Name => 'LimitAF-AreaModeSelWideLPeople',  PrintConv => \%limitNolimit, Unknown => 1 }, # CSa7-e (Z7_2)
+    0x16c => { Name => 'LimitAF-AreaModeSelWideLAnimals', PrintConv => \%limitNolimit, Unknown => 1 }, # CSa7-f (Z7_2)
+    0x16e => { # (Z7_2)
+        Name => 'AFAreaMode',
+        RawConv => '$$self{AFAreaMode} = $val',
+        PrintConv => {
+            2 => 'Single-point',
+            3 => 'Dynamic-area',
+            4 => 'Wide (S)',
+            5 => 'Wide (L)',
+            6 => 'Wide (L-people)',
+            7 => 'Wide (L-animals)',
+            8 => 'Auto',
+            9 => 'Auto (People)',
+            10 => 'Auto (Animals)',
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# Process NikonSettings directory (ref PH)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessNikonSettings($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+
+    # NikonSettings directory has a 24-byte header:
+    #  0x00 - undef[4]: '0100'
+    #  0x04 - int32u:   1 (D-models), 2 (Z-models)
+    #  0x08 - undef[4]: '0100'
+    #  0x0c - int32u:   1 (Z7), 2 (D850), 3 (D780,Z50), 4 (D6,Z5), 5(Z7m2)
+    #  0x10 - undef[4]: firmware version (eg. '0110' for firmware 1.10)
+    #  0x14 - int32u:   number of entries in directory
+
+    return 0 if $$dirInfo{DirLen} < 24; # sanity check
+
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart};
+    my $num = Get32u($dataPt, $start + 0x14);
+
+    $et->VerboseDir('NikonSettings', $num);
+
+    my $n = int(($$dirInfo{DirLen} - 0x18) / 8);
+    if ($n < $num) {
+        $et->Warn('Missing '.($num-$n).' NikonSettings entries', 1);
+        $num = $n;
+    } elsif ($n > $num) {
+        $et->Warn('Unused space in NikonSettings directory', 1);
+    }
+    my $i;
+    for ($i=0; $i<$num; ++$i) {
+        my $entry = $start + 0x18 + $i * 8;
+        my $tag = Get16u($dataPt, $entry);
+        my $fmt = Get16u($dataPt, $entry + 2);
+        my $val = Get32u($dataPt, $entry + 4);
+        # abort if the tag has a format that we haven't yet seen
+        # (assuming this is a size/format code.  So far we have only seen 0x400)
+        $fmt == 0x400 or $et->Warn(sprintf('Unknown format 0x%x for NikonSettings tag 0x%.4x',$fmt,$tag)), last;
+        $et->HandleTag($tagTablePtr, $tag, $val,
+            DataPt  => $dataPt,
+            DataPos => $$dirInfo{DataPos},
+            Base    => $$dirInfo{Base},
+            Start   => $entry + 4,
+            Size    => 4,
+            Format  => 'int32u',
+            Index   => $i,
+        );
+    }
+    return 1;
+}
+
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::NikonSettings - Read Nikon user settings
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains the definitions necessary to read the user settings for
+Nikon cameras such as the D6 and Z7mk2.
+
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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 Warren Hatch for his work decoding settings for the D6 and Z7mkII,
+and for providing the original source code for this module.
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Nikon Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Nintendo.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Nintendo.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Nintendo.pm	(revision 34921)
@@ -0,0 +1,128 @@
+#------------------------------------------------------------------------------
+# File:         Nintendo.pm
+#
+# Description:  Nintendo EXIF maker notes tags
+#
+# Revisions:    2014/03/25 - P. Harvey Created
+#
+# References:   1) http://3dbrew.org/wiki/MPO
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Nintendo;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.00';
+
+%Image::ExifTool::Nintendo::Main = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => 1,
+    # 0x1000 - undef[28]
+    # 0x1001 - undef[8]
+    # 0x1100 - undef[80] (found in MPO files)
+    0x1101 => {
+        Name => 'CameraInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nintendo::CameraInfo',
+            ByteOrder => 'Little-endian',
+        },
+    },
+);
+
+# Nintendo MPO info (ref 1)
+%Image::ExifTool::Nintendo::CameraInfo = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    PRIORITY => 0,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    0x00 => { # "3DS1"
+        Name => 'ModelID',
+        Format => 'undef[4]',
+    },
+    # 0x04 - int32u: 1,2,4,5
+    0x08 => {
+        Name => 'TimeStamp',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        # zero time is 2000/01/01 (10957 days after Unix time zero)
+        ValueConv => 'ConvertUnixTime($val + 10957 * 24 * 3600)',
+        ValueConvInv => 'GetUnixTime($val) - 10957 * 24 * 3600',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
+    },
+    # 0x10 - int32u: title ID low
+    # 0x14 - int32u: flags
+    0x18 => {
+        Name => 'InternalSerialNumber',
+        Groups => { 2 => 'Camera' },
+        Format => 'undef[4]',
+        ValueConv => '"0x" . unpack("H*",$val)',
+        ValueConvInv => '$val=~s/^0x//; pack("H*",$val)',
+    },
+    0x28 => {
+        Name => 'Parallax',
+        Format => 'float',
+        PrintConv => 'sprintf("%.2f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x30 => {
+        Name => 'Category',
+        Format => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0x0000 => '(none)',
+            0x1000 => 'Mii',
+            0x2000 => 'Man',
+            0x4000 => 'Woman',
+        },
+    },
+    # 0x32 - int16u: filter
+);
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Nintendo - Nintendo EXIF 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 Nintendo maker notes EXIF meta information.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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://3dbrew.org/wiki/MPO>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Nintendo Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/OOXML.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/OOXML.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/OOXML.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool::ZIP;
 
-$VERSION = '1.05';
+$VERSION = '1.08';
 
 # test for recognized OOXML document extensions
@@ -22,4 +22,5 @@
     DOTX => 1,  DOTM => 1,
     POTX => 1,  POTM => 1,
+    PPAX => 1,  PPAM => 1,
     PPSX => 1,  PPSM => 1,
     PPTX => 1,  PPTM => 1,  THMX => 1,
@@ -64,8 +65,8 @@
 
         B<Tips:>
-        
+
         1) Structural ZIP tags may be ignored (if desired) with C<--ZIP:all> on the
         command line.
-        
+
         2) Tags may be grouped by their document number in the ZIP archive with the
         C<-g3> or C<-G3> option.
@@ -135,5 +136,5 @@
     MMClips     => { },
     modified    => {
-        Name => 'ModifyDate', 
+        Name => 'ModifyDate',
         Groups => { 2 => 'Time' },
         Format => 'date',
@@ -209,17 +210,17 @@
 sub FoundTag($$$$;$)
 {
-    my ($exifTool, $tagTablePtr, $props, $val, $attrs) = @_;
+    my ($et, $tagTablePtr, $props, $val, $attrs) = @_;
     return 0 unless @$props;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     my $tag = $$props[-1];
-    $exifTool->VPrint(0, "  | - Tag '", join('/',@$props), "'\n") if $verbose > 1;
+    $et->VPrint(0, "  | - Tag '", join('/',@$props), "'\n") if $verbose > 1;
 
     # un-escape XML character entities
     $val = Image::ExifTool::XMP::UnescapeXML($val);
-    # convert OOXML-escaped characters (ie. "_x0000d_" is a newline)
+    # convert OOXML-escaped characters (eg. "_x0000d_" is a newline)
     $val =~ s/_x([0-9a-f]{4})_/Image::ExifTool::PackUTF8(hex($1))/gie;
     # convert from UTF8 to ExifTool Charset
-    $val = $exifTool->Decode($val, 'UTF8');
+    $val = $et->Decode($val, 'UTF8');
     # queue this attribute for later if necessary
     if ($queueAttrs{$tag}) {
@@ -247,6 +248,6 @@
                 $tagInfo{PrintConv} = '$self->ConvertDateTime($val)';
             }
-            $exifTool->VPrint(0, "  | [adding $tag]\n") if $verbose;
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, \%tagInfo);
+            $et->VPrint(0, "  | [adding $tag]\n") if $verbose;
+            AddTagToTable($tagTablePtr, $tag, \%tagInfo);
         }
     } elsif ($tag eq 'xmlns') {
@@ -289,9 +290,9 @@
         }
     } else {
-        $exifTool->VPrint(0, "  [adding $tag]\n") if $verbose;
-        Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => ucfirst $tag });
+        $et->VPrint(0, "  [adding $tag]\n") if $verbose;
+        AddTagToTable($tagTablePtr, $tag, { Name => ucfirst $tag });
     }
     # save the tag
-    $exifTool->HandleTag($tagTablePtr, $tag, $val);
+    $et->HandleTag($tagTablePtr, $tag, $val);
 
     # start fresh for next tag
@@ -312,5 +313,5 @@
 sub ProcessDOCX($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $zip = $$dirInfo{ZIP};
     my $tagTablePtr = GetTagTable('Image::ExifTool::OOXML::Main');
@@ -321,15 +322,15 @@
     if ($fileType) {
         # THMX is a special case because its contents.main MIME types is PPTX
-        if ($fileType eq 'PPTX' and $$exifTool{FILE_EXT} and $$exifTool{FILE_EXT} eq 'THMX') {
+        if ($fileType eq 'PPTX' and $$et{FILE_EXT} and $$et{FILE_EXT} eq 'THMX') {
             $fileType = 'THMX';
         }
     } else {
-        $exifTool->VPrint(0, "Unrecognized MIME type: $mime\n");
+        $et->VPrint(0, "Unrecognized MIME type: $mime\n");
         # get MIME type according to file extension
-        $fileType = $$exifTool{FILE_EXT};
+        $fileType = $$et{FILE_EXT};
         # default to 'DOCX' if this isn't a known OOXML extension
         $fileType = 'DOCX' unless $fileType and $isOOXML{$fileType};
     }
-    $exifTool->SetFileType($fileType);
+    $et->SetFileType($fileType);
 
     # must catch all Archive::Zip warnings
@@ -343,16 +344,17 @@
         my $file = $member->fileName();
         next unless defined $file;
-        $exifTool->VPrint(0, "File: $file\n");
+        $et->VPrint(0, "File: $file\n");
         # set the document number and extract ZIP tags
-        $$exifTool{DOC_NUM} = ++$docNum;
-        Image::ExifTool::ZIP::HandleMember($exifTool, $member);
-        # process only XML and JPEG files in "docProps" directory
-        next unless $file =~ m{^docProps/.*\.(xml|jpe?g)$}i;
+        $$et{DOC_NUM} = ++$docNum;
+        Image::ExifTool::ZIP::HandleMember($et, $member);
+        # process only XML and JPEG/WMF thumbnail images in "docProps" directory
+        next unless $file =~ m{^docProps/(.*\.xml|(thumbnail\.(jpe?g|wmf)))$}i;
         # get the file contents (CAREFUL! $buff MUST be local since we hand off a value ref)
         my ($buff, $status) = $zip->contents($member);
-        $status and $exifTool->Warn("Error extracting $file"), next;
-        # extract JPEG as PreviewImage (should only be docProps/thumbnail.jpeg)
-        if ($file =~ /\.jpe?g/i) {
-            $exifTool->FoundTag('PreviewImage', \$buff);
+        $status and $et->Warn("Error extracting $file"), next;
+        # extract docProps/thumbnail.(jpg|mwf) as PreviewImage|PreviewMWF
+        if ($file =~ /\.(jpe?g|wmf)$/i) {
+            my $tag = $file =~ /\.wmf$/i ? 'PreviewWMF' : 'PreviewImage';
+            $et->FoundTag($tag, \$buff);
             next;
         }
@@ -366,8 +368,8 @@
             },
         );
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         undef $buff;    # (free memory now)
     }
-    delete $$exifTool{DOC_NUM};
+    delete $$et{DOC_NUM};
     return 1;
 }
@@ -394,5 +396,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Ogg.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Ogg.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Ogg.pm	(revision 34921)
@@ -0,0 +1,240 @@
+#------------------------------------------------------------------------------
+# File:         Ogg.pm
+#
+# Description:  Read Ogg meta information
+#
+# Revisions:    2011/07/13 - P. Harvey Created (split from Vorbis.pm)
+#               2016/07/14 - PH Added Ogg Opus support
+#
+# References:   1) http://www.xiph.org/vorbis/doc/
+#               2) http://flac.sourceforge.net/ogg_mapping.html
+#               3) http://www.theora.org/doc/Theora.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Ogg;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.02';
+
+my $MAX_PACKETS = 2;    # maximum packets to scan from each stream at start of file
+
+# Information types recognizedi in Ogg files
+%Image::ExifTool::Ogg::Main = (
+    NOTES => q{
+        ExifTool extracts the following types of information from Ogg files.  See
+        L<http://www.xiph.org/vorbis/doc/> for the Ogg specification.
+    },
+    # (these are for documentation purposes only, and aren't used by the code below)
+    vorbis => { SubDirectory => { TagTable => 'Image::ExifTool::Vorbis::Main' } },
+    theora => { SubDirectory => { TagTable => 'Image::ExifTool::Theora::Main' } },
+    Opus   => { SubDirectory => { TagTable => 'Image::ExifTool::Opus::Main' } },
+    FLAC   => { SubDirectory => { TagTable => 'Image::ExifTool::FLAC::Main' } },
+    ID3    => { SubDirectory => { TagTable => 'Image::ExifTool::ID3::Main' } },
+);
+
+#------------------------------------------------------------------------------
+# Process Ogg packet
+# Inputs: 0) ExifTool object ref, 1) data ref
+# Returns: 1 on success
+sub ProcessPacket($$)
+{
+    my ($et, $dataPt) = @_;
+    my $rtnVal = 0;
+    if ($$dataPt =~ /^(.)(vorbis|theora)/s or $$dataPt =~ /^(OpusHead|OpusTags)/) {
+        my ($tag, $type, $pos) = $2 ? (ord($1), ucfirst($2), 7) : ($1, 'Opus', 8);
+        # this is an OGV file if it contains Theora video
+        $et->OverrideFileType('OGV') if $type eq 'Theora' and $$et{FILE_TYPE} eq 'OGG';
+        $et->OverrideFileType('OPUS') if $type eq 'Opus' and $$et{FILE_TYPE} eq 'OGG';
+        my $tagTablePtr = GetTagTable("Image::ExifTool::${type}::Main");
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        return 0 unless $tagInfo and $$tagInfo{SubDirectory};
+        my $subdir = $$tagInfo{SubDirectory};
+        my %dirInfo = (
+            DataPt   => $dataPt,
+            DirName  => $$tagInfo{Name},
+            DirStart => $pos,
+        );
+        my $table = GetTagTable($$subdir{TagTable});
+        # set group1 so Theoris comments can be distinguised from Vorbis comments
+        $$et{SET_GROUP1} = $type if $type eq 'Theora';
+        SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
+        $rtnVal = $et->ProcessDirectory(\%dirInfo, $table);
+        SetByteOrder('II');
+        delete $$et{SET_GROUP1};
+    }
+    return $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from an Ogg file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid Ogg file
+sub ProcessOGG($$)
+{
+    my ($et, $dirInfo) = @_;
+
+    # must first check for leading/trailing ID3 information
+    unless ($$et{DoneID3}) {
+        require Image::ExifTool::ID3;
+        Image::ExifTool::ID3::ProcessID3($et, $dirInfo) and return 1;
+    }
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
+    my ($success, $page, $packets, $streams, $stream) = (0,0,0,0,'');
+    my ($buff, $flag, %val, $numFlac, %streamPage);
+
+    for (;;) {
+        # must read ahead to next page to see if it is a continuation
+        # (this code would be a lot simpler if the continuation flag
+        #  was on the leading instead of the trailing page!)
+        if ($raf and $raf->Read($buff, 28) == 28) {
+            # validate magic number
+            unless ($buff =~ /^OggS/) {
+                $success and $et->Warn('Lost synchronization');
+                last;
+            }
+            unless ($success) {
+                # set file type and initialize on first page
+                $success = 1;
+                $et->SetFileType();
+                SetByteOrder('II');
+            }
+            $flag = Get8u(\$buff, 5);       # page flag
+            $stream = Get32u(\$buff, 14);   # stream serial number
+            if ($flag & 0x02) {
+                ++$streams;                 # count start-of-stream pages
+                $streamPage{$stream} = $page = 0;
+            } else {
+                $page = $streamPage{$stream};
+            }
+            ++$packets unless $flag & 0x01; # keep track of packet count
+        } else {
+            # all done unless we have to process our last packet
+            last unless %val;
+            ($stream) = sort keys %val;     # take a stream
+            $flag = 0;                      # no continuation
+            undef $raf;                     # flag for done reading
+        }
+
+        if (defined $numFlac) {
+            # stop to process FLAC headers if we hit the end of file
+            last unless $raf;
+            --$numFlac; # one less header packet to read
+        } else {
+            # can finally process previous packet from this stream
+            # unless this is a continuation page
+            if (defined $val{$stream} and not $flag & 0x01) {
+                ProcessPacket($et, \$val{$stream});
+                delete $val{$stream};
+                # only read the first $MAX_PACKETS packets from each stream
+                if ($packets > $MAX_PACKETS * $streams or not defined $raf) {
+                    last unless %val;   # all done (success!)
+                }
+            }
+            # stop processing Ogg if we have scanned enough packets
+            last if $packets > $MAX_PACKETS * $streams and not %val;
+        }
+
+        # continue processing the current page
+        my $pageNum = Get32u(\$buff, 18);   # page sequence number
+        my $nseg = Get8u(\$buff, 26);       # number of segments
+        # calculate total data length
+        my $dataLen = Get8u(\$buff, 27);
+        if ($nseg) {
+            $raf->Read($buff, $nseg-1) == $nseg-1 or last;
+            my @segs = unpack('C*', $buff);
+            # could check that all these (but the last) are 255...
+            foreach (@segs) { $dataLen += $_ }
+        }
+        if (defined $page) {
+            if ($page == $pageNum) {
+                $streamPage{$stream} = ++$page;
+            } else {
+                $et->Warn('Missing page(s) in Ogg file');
+                undef $page;
+                delete $streamPage{$stream};
+            }
+        }
+        # read page data
+        $raf->Read($buff, $dataLen) == $dataLen or last;
+        if ($verbose > 1) {
+            printf $out "Page %d, stream 0x%x, flag 0x%x (%d bytes)\n",
+                   $pageNum, $stream, $flag, $dataLen;
+            $et->VerboseDump(\$buff, DataPos => $raf->Tell() - $dataLen);
+        }
+        if (defined $val{$stream}) {
+            $val{$stream} .= $buff;     # add this continuation page
+        } elsif (not $flag & 0x01) {    # ignore remaining pages of a continued packet
+            # ignore the first page of any packet we aren't parsing
+            if ($buff =~ /^(.(vorbis|theora)|Opus(Head|Tags))/s) {
+                $val{$stream} = $buff;      # save this page
+            } elsif ($buff =~ /^\x7fFLAC..(..)/s) {
+                $numFlac = unpack('n',$1);
+                $val{$stream} = substr($buff, 9);
+            }
+        }
+        if (defined $numFlac) {
+            # stop to process FLAC headers if we have them all
+            last if $numFlac <= 0;
+        } elsif (defined $val{$stream} and $flag & 0x04) {
+            # process Ogg packet now if end-of-stream bit is set
+            ProcessPacket($et, \$val{$stream});
+            delete $val{$stream};
+        }
+    }
+    if (defined $numFlac and defined $val{$stream}) {
+        # process FLAC headers as if it was a complete FLAC file
+        require Image::ExifTool::FLAC;
+        my %dirInfo = ( RAF => new File::RandomAccess(\$val{$stream}) );
+        Image::ExifTool::FLAC::ProcessFLAC($et, \%dirInfo);
+    }
+    return $success;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Ogg - Read Ogg 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 bitstream container files.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.xiph.org/vorbis/doc/>
+
+=item L<http://flac.sourceforge.net/ogg_mapping.html>
+
+=item L<http://www.theora.org/doc/Theora.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Ogg Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Olympus.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Olympus.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Olympus.pm	(revision 34921)
@@ -10,6 +10,6 @@
 #               2) http://www.cybercom.net/~dcoffin/dcraw/
 #               3) http://www.ozhiker.com/electronics/pjmt/jpeg_info/olympus_mn.html
-#               4) Markku Hnninen private communication (tests with E-1)
-#               5) Rmi 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
@@ -17,12 +17,18 @@
 #               9) Mark Dapoz private communication
 #              10) Lilo Huang private communication (E-330)
-#              11) http://olypedia.de/Olympus_Makernotes
+#              11) http://olypedia.de/Olympus_Makernotes (May 30, 2013)
 #              12) Ioannis Panagiotopoulos private communication (E-510)
 #              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
+#              22) Herbert Kauer private communication
+#              23) Daniel Pollock private communication (PEN-F)
+#              24) Sebastian private communication (E-M1 Mark III)
+#              IB) Iliah Borg private communication (LibRaw)
+#              NJ) Niels Kristian Bech Jensen private communication
 #------------------------------------------------------------------------------
 
@@ -31,8 +37,9 @@
 use strict;
 use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
 use Image::ExifTool::APP12;
 
-$VERSION = '1.79';
+$VERSION = '2.70';
 
 sub PrintLensInfo($$$);
@@ -41,83 +48,527 @@
 
 # lookup for Olympus LensType values
+# (as of ExifTool 9.15, this was the complete list of chipped lenses at www.four-thirds.org)
 my %olympusLensTypes = (
-    '0 0 0'  => 'None',
-    # Olympus lenses
-    '0 1 0'  => 'Olympus Zuiko Digital ED 50mm F2.0 Macro',
-    '0 1 1'  => 'Olympus Zuiko Digital 40-150mm F3.5-4.5', #8
-    '0 1 16' => 'Olympus M.Zuiko Digital ED 14-42mm F3.5-5.6', #PH (E-P1 pre-production)
-    '0 2 0'  => 'Olympus Zuiko Digital ED 150mm F2.0',
-    '0 2 16' => 'Olympus M.Zuiko Digital 17mm F2.8 Pancake', #PH (E-P1 pre-production)
-    '0 3 0'  => 'Olympus Zuiko Digital ED 300mm F2.8',
-    '0 3 16' => 'Olympus M.Zuiko Digital ED 14-150mm F4.0-5.6', #11
-    '0 4 16' => 'Olympus M.Zuiko Digital ED 9-18mm F4.0-5.6', #11
-    '0 5 0'  => 'Olympus Zuiko Digital 14-54mm F2.8-3.5',
-    '0 5 1'  => 'Olympus Zuiko Digital Pro ED 90-250mm F2.8', #9
-    '0 5 16' => 'Olympus M.Zuiko Digital ED 14-42mm F3.5-5.6', #11
-    '0 6 0'  => 'Olympus Zuiko Digital ED 50-200mm F2.8-3.5',
-    '0 6 1'  => 'Olympus Zuiko Digital ED 8mm F3.5 Fisheye', #9
-    '0 7 0'  => 'Olympus Zuiko Digital 11-22mm F2.8-3.5',
-    '0 7 1'  => 'Olympus Zuiko Digital 18-180mm F3.5-6.3', #6
-    '0 8 1'  => 'Olympus Zuiko Digital 70-300mm F4.0-5.6', #7 (seen as release 1 - PH)
-    '0 9 16' => 'Olympus M.Zuiko Digital 14-42mm F3.5-5.6 II', #PH (E-PL2)
-    '0 21 0' => 'Olympus Zuiko Digital ED 7-14mm F4.0',
-    '0 23 0' => 'Olympus Zuiko Digital Pro ED 35-100mm F2.0', #7
-    '0 24 0' => 'Olympus Zuiko Digital 14-45mm F3.5-5.6',
-    '0 32 0' => 'Olympus Zuiko Digital 35mm F3.5 Macro', #9
-    '0 34 0' => 'Olympus Zuiko Digital 17.5-45mm F3.5-5.6', #9
-    '0 35 0' => 'Olympus Zuiko Digital ED 14-42mm F3.5-5.6', #PH
-    '0 36 0' => 'Olympus Zuiko Digital ED 40-150mm F4.0-5.6', #PH
-    '0 48 0' => 'Olympus Zuiko Digital ED 50-200mm F2.8-3.5 SWD', #7
-    '0 49 0' => 'Olympus Zuiko Digital ED 12-60mm F2.8-4.0 SWD', #7
-    '0 50 0' => 'Olympus Zuiko Digital ED 14-35mm F2.0 SWD', #PH
-    '0 51 0' => 'Olympus Zuiko Digital 25mm F2.8', #PH
-    '0 52 0' => 'Olympus Zuiko Digital ED 9-18mm F4.0-5.6', #7
-    '0 53 0' => 'Olympus Zuiko Digital 14-54mm F2.8-3.5 II', #PH
+    Notes => q{
+        The numerical values below are given in hexadecimal.  (Prior to ExifTool
+        9.15 these were in decimal.)
+    },
+    '0 00 00' => 'None',
+    # Olympus lenses (also Kenko Tokina)
+    '0 01 00' => 'Olympus Zuiko Digital ED 50mm F2.0 Macro',
+    '0 01 01' => 'Olympus Zuiko Digital 40-150mm F3.5-4.5', #8
+    '0 01 10' => 'Olympus M.Zuiko Digital ED 14-42mm F3.5-5.6', #PH (E-P1 pre-production)
+    '0 02 00' => 'Olympus Zuiko Digital ED 150mm F2.0',
+    '0 02 10' => 'Olympus M.Zuiko Digital 17mm F2.8 Pancake', #PH (E-P1 pre-production)
+    '0 03 00' => 'Olympus Zuiko Digital ED 300mm F2.8',
+    '0 03 10' => 'Olympus M.Zuiko Digital ED 14-150mm F4.0-5.6 [II]', #11 (The second version of this lens seems to have the same lens ID number as the first version #NJ)
+    '0 04 10' => 'Olympus M.Zuiko Digital ED 9-18mm F4.0-5.6', #11
+    '0 05 00' => 'Olympus Zuiko Digital 14-54mm F2.8-3.5',
+    '0 05 01' => 'Olympus Zuiko Digital Pro ED 90-250mm F2.8', #9
+    '0 05 10' => 'Olympus M.Zuiko Digital ED 14-42mm F3.5-5.6 L', #11 (E-PL1)
+    '0 06 00' => 'Olympus Zuiko Digital ED 50-200mm F2.8-3.5',
+    '0 06 01' => 'Olympus Zuiko Digital ED 8mm F3.5 Fisheye', #9
+    '0 06 10' => 'Olympus M.Zuiko Digital ED 40-150mm F4.0-5.6', #PH
+    '0 07 00' => 'Olympus Zuiko Digital 11-22mm F2.8-3.5',
+    '0 07 01' => 'Olympus Zuiko Digital 18-180mm F3.5-6.3', #6
+    '0 07 10' => 'Olympus M.Zuiko Digital ED 12mm F2.0', #PH
+    '0 08 01' => 'Olympus Zuiko Digital 70-300mm F4.0-5.6', #7 (seen as release 1 - PH)
+    '0 08 10' => 'Olympus M.Zuiko Digital ED 75-300mm F4.8-6.7', #PH
+    '0 09 10' => 'Olympus M.Zuiko Digital 14-42mm F3.5-5.6 II', #PH (E-PL2)
+    '0 10 01' => 'Kenko Tokina Reflex 300mm F6.3 MF Macro', #NJ
+    '0 10 10' => 'Olympus M.Zuiko Digital ED 12-50mm F3.5-6.3 EZ', #PH
+    '0 11 10' => 'Olympus M.Zuiko Digital 45mm F1.8', #17
+    '0 12 10' => 'Olympus M.Zuiko Digital ED 60mm F2.8 Macro', #NJ
+    '0 13 10' => 'Olympus M.Zuiko Digital 14-42mm F3.5-5.6 II R', #PH/NJ
+    '0 14 10' => 'Olympus M.Zuiko Digital ED 40-150mm F4.0-5.6 R', #19
+  # '0 14 10.1' => 'Olympus M.Zuiko Digital ED 14-150mm F4.0-5.6 II', #11 (questionable & unconfirmed -- all samples I can find are '0 3 10' - PH)
+    '0 15 00' => 'Olympus Zuiko Digital ED 7-14mm F4.0',
+    '0 15 10' => 'Olympus M.Zuiko Digital ED 75mm F1.8', #PH
+    '0 16 10' => 'Olympus M.Zuiko Digital 17mm F1.8', #NJ
+    '0 17 00' => 'Olympus Zuiko Digital Pro ED 35-100mm F2.0', #7
+    '0 18 00' => 'Olympus Zuiko Digital 14-45mm F3.5-5.6',
+    '0 18 10' => 'Olympus M.Zuiko Digital ED 75-300mm F4.8-6.7 II', #NJ
+    '0 19 10' => 'Olympus M.Zuiko Digital ED 12-40mm F2.8 Pro', #PH
+    '0 20 00' => 'Olympus Zuiko Digital 35mm F3.5 Macro', #9
+    '0 20 10' => 'Olympus M.Zuiko Digital ED 40-150mm F2.8 Pro', #NJ
+    '0 21 10' => 'Olympus M.Zuiko Digital ED 14-42mm F3.5-5.6 EZ', #NJ
+    '0 22 00' => 'Olympus Zuiko Digital 17.5-45mm F3.5-5.6', #9
+    '0 22 10' => 'Olympus M.Zuiko Digital 25mm F1.8', #NJ
+    '0 23 00' => 'Olympus Zuiko Digital ED 14-42mm F3.5-5.6', #PH
+    '0 23 10' => 'Olympus M.Zuiko Digital ED 7-14mm F2.8 Pro', #NJ
+    '0 24 00' => 'Olympus Zuiko Digital ED 40-150mm F4.0-5.6', #PH
+    '0 24 10' => 'Olympus M.Zuiko Digital ED 300mm F4.0 IS Pro', #NJ
+    '0 25 10' => 'Olympus M.Zuiko Digital ED 8mm F1.8 Fisheye Pro', #NJ
+    '0 26 10' => 'Olympus M.Zuiko Digital ED 12-100mm F4.0 IS Pro', #IB/NJ
+    '0 27 10' => 'Olympus M.Zuiko Digital ED 30mm F3.5 Macro', #IB/NJ
+    '0 28 10' => 'Olympus M.Zuiko Digital ED 25mm F1.2 Pro', #IB/NJ
+    '0 29 10' => 'Olympus M.Zuiko Digital ED 17mm F1.2 Pro', #IB
+    '0 30 00' => 'Olympus Zuiko Digital ED 50-200mm F2.8-3.5 SWD', #7
+    '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 33 10' => 'Olympus M.Zuiko Digital 150-400mm F4.5 TC1.25x IS Pro', #IB
+    '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 1 0'  => 'Sigma 18-50mm F3.5-5.6', #8
-    '1 2 0'  => 'Sigma 55-200mm F4.0-5.6 DC',
-    '1 3 0'  => 'Sigma 18-125mm F3.5-5.6 DC',
-    '1 4 0'  => 'Sigma 18-125mm F3.5-5.6', #7
-    '1 5 0'  => 'Sigma 30mm F1.4', #10
-    '1 6 0'  => 'Sigma 50-500mm F4.0-6.3 EX DG APO HSM RF', #6
-    '1 7 0'  => 'Sigma 105mm F2.8 DG', #PH
-    '1 8 0'  => 'Sigma 150mm F2.8 DG HSM', #PH
-    '1 16 0' => 'Sigma 24mm F1.8 EX DG Aspherical Macro', #PH
-    '1 17 0' => 'Sigma 135-400mm F4.5-5.6 DG ASP APO RF', #11
-    '1 18 0' => 'Sigma 300-800mm F5.6 EX DG APO', #11
-    '1 20 0' => 'Sigma 50-500mm F4.0-6.3 EX DG APO HSM RF', #11
-    '1 21 0' => 'Sigma 10-20mm F4.0-5.6 EX DC HSM', #11
-    '1 22 0' => 'Sigma 70-200mm F2.8 EX DG Macro HSM II', #11
-    '1 23 0' => 'Sigma 50mm F1.4 EX DG HSM', #11
-    # Leica lenses (ref 11)
-    '2 1 0'  => 'Leica D Vario Elmarit 14-50mm F2.8-3.5 Asph.',
-    '2 1 16' => 'Lumix G Vario 14-45mm F3.5-5.6 Asph. Mega OIS', #16
-    '2 2 0'  => 'Leica D Summilux 25mm F1.4 Asph.',
-    '2 2 16' => 'Lumix G Vario 45-200mm F4-5.6 Mega OIS', #16
-    '2 3 1'  => 'Leica D Vario Elmar 14-50mm F3.8-5.6 Asph.', #14 (L10 kit)
-    '2 3 16' => 'Lumix G Vario HD 14-140mm F4-5.8 Asph. Mega OIS', #16
-    '2 4 0'  => 'Leica D Vario Elmar 14-150mm F3.5-5.6', #13
-    '2 4 16' => 'Lumix G Vario 7-14mm F4 Asph.', #PH (E-P1 pre-production)
-    '2 5 16' => 'Lumix G 20mm F1.7 Asph.', #16
-    '2 6 16' => 'Leica DG Macro-Elmarit 45mm F2.8', #PH
-    '2 8 16' => 'Lumix G Fisheye 8mm F3.5', #PH
-    '3 1 0'  => 'Leica D Vario Elmarit 14-50mm F2.8-3.5 Asph.',
-    '3 2 0'  => 'Leica D Summilux 25mm F1.4 Asph.',
+    '1 01 00' => 'Sigma 18-50mm F3.5-5.6 DC', #8
+    '1 01 10' => 'Sigma 30mm F2.8 EX DN', #NJ
+    '1 02 00' => 'Sigma 55-200mm F4.0-5.6 DC',
+    '1 02 10' => 'Sigma 19mm F2.8 EX DN', #NJ
+    '1 03 00' => 'Sigma 18-125mm F3.5-5.6 DC',
+    '1 03 10' => 'Sigma 30mm F2.8 DN | A', #NJ
+    '1 04 00' => 'Sigma 18-125mm F3.5-5.6 DC', #7
+    '1 04 10' => 'Sigma 19mm F2.8 DN | A', #NJ
+    '1 05 00' => 'Sigma 30mm F1.4 EX DC HSM', #10
+    '1 05 10' => 'Sigma 60mm F2.8 DN | A', #NJ
+    '1 06 00' => 'Sigma APO 50-500mm F4.0-6.3 EX DG HSM', #6
+    '1 06 10' => 'Sigma 30mm F1.4 DC DN | C', #NJ
+    '1 07 00' => 'Sigma Macro 105mm F2.8 EX DG', #PH
+    '1 07 10' => 'Sigma 16mm F1.4 DC DN | C (017)', #IB
+    '1 08 00' => 'Sigma APO Macro 150mm F2.8 EX DG HSM', #PH
+    '1 09 00' => 'Sigma 18-50mm F2.8 EX DC Macro', #NJ
+    '1 10 00' => 'Sigma 24mm F1.8 EX DG Aspherical Macro', #PH
+    '1 11 00' => 'Sigma APO 135-400mm F4.5-5.6 DG', #11
+    '1 12 00' => 'Sigma APO 300-800mm F5.6 EX DG HSM', #11
+    '1 13 00' => 'Sigma 30mm F1.4 EX DC HSM', #11
+    '1 14 00' => 'Sigma APO 50-500mm F4.0-6.3 EX DG HSM', #11
+    '1 15 00' => 'Sigma 10-20mm F4.0-5.6 EX DC HSM', #11
+    '1 16 00' => 'Sigma APO 70-200mm F2.8 II EX DG Macro HSM', #11
+    '1 17 00' => 'Sigma 50mm F1.4 EX DG HSM', #11
+    '1 18 60' => 'Test',
+    # Panasonic/Leica lenses
+    '2 01 00' => 'Leica D Vario Elmarit 14-50mm F2.8-3.5 Asph.', #11
+    '2 01 10' => 'Lumix G Vario 14-45mm F3.5-5.6 Asph. Mega OIS', #16
+    '2 02 00' => 'Leica D Summilux 25mm F1.4 Asph.', #11
+    '2 02 10' => 'Lumix G Vario 45-200mm F4.0-5.6 Mega OIS', #16
+    '2 03 00' => 'Leica D Vario Elmar 14-50mm F3.8-5.6 Asph. Mega OIS', #11
+    '2 03 01' => 'Leica D Vario Elmar 14-50mm F3.8-5.6 Asph.', #14 (L10 kit)
+    '2 03 10' => 'Lumix G Vario HD 14-140mm F4.0-5.8 Asph. Mega OIS', #16
+    '2 04 00' => 'Leica D Vario Elmar 14-150mm F3.5-5.6', #13
+    '2 04 10' => 'Lumix G Vario 7-14mm F4.0 Asph.', #PH (E-P1 pre-production)
+    '2 05 10' => 'Lumix G 20mm F1.7 Asph.', #16
+    '2 06 10' => 'Leica DG Macro-Elmarit 45mm F2.8 Asph. Mega OIS', #PH
+    '2 07 10' => 'Lumix G Vario 14-42mm F3.5-5.6 Asph. Mega OIS', #NJ
+    '2 08 10' => 'Lumix G Fisheye 8mm F3.5', #PH
+    '2 09 10' => 'Lumix G Vario 100-300mm F4.0-5.6 Mega OIS', #11
+    '2 10 10' => 'Lumix G 14mm F2.5 Asph.', #17
+    '2 11 10' => 'Lumix G 12.5mm F12 3D', #NJ (H-FT012)
+    '2 12 10' => 'Leica DG Summilux 25mm F1.4 Asph.', #NJ
+    '2 13 10' => 'Lumix G X Vario PZ 45-175mm F4.0-5.6 Asph. Power OIS', #NJ
+    '2 14 10' => 'Lumix G X Vario PZ 14-42mm F3.5-5.6 Asph. Power OIS', #NJ
+    '2 15 10' => 'Lumix G X Vario 12-35mm F2.8 Asph. Power OIS', #PH
+    '2 16 10' => 'Lumix G Vario 45-150mm F4.0-5.6 Asph. Mega OIS', #NJ
+    '2 17 10' => 'Lumix G X Vario 35-100mm F2.8 Power OIS', #PH
+    '2 18 10' => 'Lumix G Vario 14-42mm F3.5-5.6 II Asph. Mega OIS', #NJ
+    '2 19 10' => 'Lumix G Vario 14-140mm F3.5-5.6 Asph. Power OIS', #NJ
+    '2 20 10' => 'Lumix G Vario 12-32mm F3.5-5.6 Asph. Mega OIS', #NJ
+    '2 21 10' => 'Leica DG Nocticron 42.5mm F1.2 Asph. Power OIS', #NJ
+    '2 22 10' => 'Leica DG Summilux 15mm F1.7 Asph.', #NJ
+    '2 23 10' => 'Lumix G Vario 35-100mm F4.0-5.6 Asph. Mega OIS', #NJ
+    '2 24 10' => 'Lumix G Macro 30mm F2.8 Asph. Mega OIS', #NJ
+    '2 25 10' => 'Lumix G 42.5mm F1.7 Asph. Power OIS', #NJ
+    '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 31 10' => 'Lumix G Vario 45-200mm F4.0-5.6 II', #forum3833
+    '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)
+    # Other makes
+    '24 01 10' => 'Venus Optics Laowa 50mm F2.8 2x Macro', #DonKomarechka
 );
 
-# ArtFilter and MagicFilter values (ref PH)
+# lookup for Olympus camera types (ref PH)
+my %olympusCameraTypes = (
+    Notes => q{
+        These values are currently decoded only for Olympus models.  Models with
+        Olympus-style maker notes from other brands such as Acer, BenQ, Hitachi, HP,
+        Premier, Konica-Minolta, Maginon, Ricoh, Rollei, SeaLife, Sony, Supra,
+        Vivitar are not listed.
+    },
+    D4028 => 'X-2,C-50Z',
+    D4029 => 'E-20,E-20N,E-20P',
+    D4034 => 'C720UZ',
+    D4040 => 'E-1',
+    D4041 => 'E-300',
+    D4083 => 'C2Z,D520Z,C220Z',
+    D4106 => 'u20D,S400D,u400D',
+    D4120 => 'X-1',
+    D4122 => 'u10D,S300D,u300D',
+    D4125 => 'AZ-1',
+    D4141 => 'C150,D390',
+    D4193 => 'C-5000Z',
+    D4194 => 'X-3,C-60Z',
+    D4199 => 'u30D,S410D,u410D',
+    D4205 => 'X450,D535Z,C370Z',
+    D4210 => 'C160,D395',
+    D4211 => 'C725UZ',
+    D4213 => 'FerrariMODEL2003',
+    D4216 => 'u15D',
+    D4217 => 'u25D',
+    D4220 => 'u-miniD,Stylus V',
+    D4221 => 'u40D,S500,uD500',
+    D4231 => 'FerrariMODEL2004',
+    D4240 => 'X500,D590Z,C470Z',
+    D4244 => 'uD800,S800',
+    D4256 => 'u720SW,S720SW',
+    D4261 => 'X600,D630,FE5500',
+    D4262 => 'uD600,S600',
+    D4301 => 'u810/S810', # (yes, "/".  Olympus is not consistent in the notation)
+    D4302 => 'u710,S710',
+    D4303 => 'u700,S700',
+    D4304 => 'FE100,X710',
+    D4305 => 'FE110,X705',
+    D4310 => 'FE-130,X-720',
+    D4311 => 'FE-140,X-725',
+    D4312 => 'FE150,X730',
+    D4313 => 'FE160,X735',
+    D4314 => 'u740,S740',
+    D4315 => 'u750,S750',
+    D4316 => 'u730/S730',
+    D4317 => 'FE115,X715',
+    D4321 => 'SP550UZ',
+    D4322 => 'SP510UZ',
+    D4324 => 'FE170,X760',
+    D4326 => 'FE200',
+    D4327 => 'FE190/X750', # (also SX876)
+    D4328 => 'u760,S760',
+    D4330 => 'FE180/X745', # (also SX875)
+    D4331 => 'u1000/S1000',
+    D4332 => 'u770SW,S770SW',
+    D4333 => 'FE240/X795',
+    D4334 => 'FE210,X775',
+    D4336 => 'FE230/X790',
+    D4337 => 'FE220,X785',
+    D4338 => 'u725SW,S725SW',
+    D4339 => 'FE250/X800',
+    D4341 => 'u780,S780',
+    D4343 => 'u790SW,S790SW',
+    D4344 => 'u1020,S1020',
+    D4346 => 'FE15,X10',
+    D4348 => 'FE280,X820,C520',
+    D4349 => 'FE300,X830',
+    D4350 => 'u820,S820',
+    D4351 => 'u1200,S1200',
+    D4352 => 'FE270,X815,C510',
+    D4353 => 'u795SW,S795SW',
+    D4354 => 'u1030SW,S1030SW',
+    D4355 => 'SP560UZ',
+    D4356 => 'u1010,S1010',
+    D4357 => 'u830,S830',
+    D4359 => 'u840,S840',
+    D4360 => 'FE350WIDE,X865',
+    D4361 => 'u850SW,S850SW',
+    D4362 => 'FE340,X855,C560',
+    D4363 => 'FE320,X835,C540',
+    D4364 => 'SP570UZ',
+    D4366 => 'FE330,X845,C550',
+    D4368 => 'FE310,X840,C530',
+    D4370 => 'u1050SW,S1050SW',
+    D4371 => 'u1060,S1060',
+    D4372 => 'FE370,X880,C575',
+    D4374 => 'SP565UZ',
+    D4377 => 'u1040,S1040',
+    D4378 => 'FE360,X875,C570',
+    D4379 => 'FE20,X15,C25',
+    D4380 => 'uT6000,ST6000',
+    D4381 => 'uT8000,ST8000',
+    D4382 => 'u9000,S9000',
+    D4384 => 'SP590UZ',
+    D4385 => 'FE3010,X895',
+    D4386 => 'FE3000,X890',
+    D4387 => 'FE35,X30',
+    D4388 => 'u550WP,S550WP',
+    D4390 => 'FE5000,X905',
+    D4391 => 'u5000',
+    D4392 => 'u7000,S7000',
+    D4396 => 'FE5010,X915',
+    D4397 => 'FE25,X20',
+    D4398 => 'FE45,X40',
+    D4401 => 'XZ-1',
+    D4402 => 'uT6010,ST6010',
+    D4406 => 'u7010,S7010 / u7020,S7020',
+    D4407 => 'FE4010,X930',
+    D4408 => 'X560WP',
+    D4409 => 'FE26,X21',
+    D4410 => 'FE4000,X920,X925',
+    D4411 => 'FE46,X41,X42',
+    D4412 => 'FE5020,X935',
+    D4413 => 'uTough-3000',
+    D4414 => 'StylusTough-6020',
+    D4415 => 'StylusTough-8010',
+    D4417 => 'u5010,S5010',
+    D4418 => 'u7040,S7040',
+    D4419 => 'u9010,S9010',
+    D4423 => 'FE4040',
+    D4424 => 'FE47,X43',
+    D4426 => 'FE4030,X950',
+    D4428 => 'FE5030,X965,X960',
+    D4430 => 'u7030,S7030',
+    D4432 => 'SP600UZ',
+    D4434 => 'SP800UZ',
+    D4439 => 'FE4020,X940',
+    D4442 => 'FE5035',
+    D4448 => 'FE4050,X970',
+    D4450 => 'FE5050,X985',
+    D4454 => 'u-7050',
+    D4464 => 'T10,X27',
+    D4470 => 'FE5040,X980',
+    D4472 => 'TG-310',
+    D4474 => 'TG-610',
+    D4476 => 'TG-810',
+    D4478 => 'VG145,VG140,D715',
+    D4479 => 'VG130,D710',
+    D4480 => 'VG120,D705',
+    D4482 => 'VR310,D720',
+    D4484 => 'VR320,D725',
+    D4486 => 'VR330,D730',
+    D4488 => 'VG110,D700',
+    D4490 => 'SP-610UZ',
+    D4492 => 'SZ-10',
+    D4494 => 'SZ-20',
+    D4496 => 'SZ-30MR',
+    D4498 => 'SP-810UZ',
+    D4500 => 'SZ-11',
+    D4504 => 'TG-615',
+    D4508 => 'TG-620',
+    D4510 => 'TG-820',
+    D4512 => 'TG-1',
+    D4516 => 'SH-21',
+    D4519 => 'SZ-14',
+    D4520 => 'SZ-31MR',
+    D4521 => 'SH-25MR',
+    D4523 => 'SP-720UZ',
+    D4529 => 'VG170',
+    D4531 => 'XZ-2',
+    D4535 => 'SP-620UZ',
+    D4536 => 'TG-320',
+    D4537 => 'VR340,D750',
+    D4538 => 'VG160,X990,D745',
+    D4541 => 'SZ-12',
+    D4545 => 'VH410',
+    D4546 => 'XZ-10', #IB
+    D4547 => 'TG-2',
+    D4548 => 'TG-830',
+    D4549 => 'TG-630',
+    D4550 => 'SH-50',
+    D4553 => 'SZ-16,DZ-105',
+    D4562 => 'SP-820UZ',
+    D4566 => 'SZ-15',
+    D4572 => 'STYLUS1',
+    D4574 => 'TG-3',
+    D4575 => 'TG-850',
+    D4579 => 'SP-100EE',
+    D4580 => 'SH-60',
+    D4581 => 'SH-1',
+    D4582 => 'TG-835',
+    D4585 => 'SH-2 / SH-3',
+    D4586 => 'TG-4',
+    D4587 => 'TG-860',
+    D4591 => 'TG-870',
+    D4593 => 'TG-5', #IB
+    D4603 => 'TG-6', #IB
+    D4809 => 'C2500L',
+    D4842 => 'E-10',
+    D4856 => 'C-1',
+    D4857 => 'C-1Z,D-150Z',
+    DCHC => 'D500L',
+    DCHT => 'D600L / D620L',
+    K0055 => 'AIR-A01',
+    S0003 => 'E-330',
+    S0004 => 'E-500',
+    S0009 => 'E-400',
+    S0010 => 'E-510',
+    S0011 => 'E-3',
+    S0013 => 'E-410',
+    S0016 => 'E-420',
+    S0017 => 'E-30',
+    S0018 => 'E-520',
+    S0019 => 'E-P1',
+    S0023 => 'E-620',
+    S0026 => 'E-P2',
+    S0027 => 'E-PL1',
+    S0029 => 'E-450',
+    S0030 => 'E-600',
+    S0032 => 'E-P3',
+    S0033 => 'E-5',
+    S0034 => 'E-PL2',
+    S0036 => 'E-M5',
+    S0038 => 'E-PL3',
+    S0039 => 'E-PM1',
+    S0040 => 'E-PL1s',
+    S0042 => 'E-PL5',
+    S0043 => 'E-PM2',
+    S0044 => 'E-P5',
+    S0045 => 'E-PL6',
+    S0046 => 'E-PL7', #IB
+    S0047 => 'E-M1',
+    S0051 => 'E-M10',
+    S0052 => 'E-M5MarkII', #IB
+    S0059 => 'E-M10MarkII',
+    S0061 => 'PEN-F', #forum7005
+    S0065 => 'E-PL8',
+    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',
+    SR85 => 'C830L,D340R',
+    SR852 => 'C860L,D360L',
+    SR872 => 'C900Z,D400Z',
+    SR874 => 'C960Z,D460Z',
+    SR951 => 'C2000Z',
+    SR952 => 'C21',
+    SR953 => 'C21T.commu',
+    SR954 => 'C2020Z',
+    SR955 => 'C990Z,D490Z',
+    SR956 => 'C211Z',
+    SR959 => 'C990ZS,D490Z',
+    SR95A => 'C2100UZ',
+    SR971 => 'C100,D370',
+    SR973 => 'C2,D230',
+    SX151 => 'E100RS',
+    SX351 => 'C3000Z / C3030Z',
+    SX354 => 'C3040Z',
+    SX355 => 'C2040Z',
+    SX357 => 'C700UZ',
+    SX358 => 'C200Z,D510Z',
+    SX374 => 'C3100Z,C3020Z',
+    SX552 => 'C4040Z',
+    SX553 => 'C40Z,D40Z',
+    SX556 => 'C730UZ',
+    SX558 => 'C5050Z',
+    SX571 => 'C120,D380',
+    SX574 => 'C300Z,D550Z',
+    SX575 => 'C4100Z,C4000Z',
+    SX751 => 'X200,D560Z,C350Z',
+    SX752 => 'X300,D565Z,C450Z',
+    SX753 => 'C750UZ',
+    SX754 => 'C740UZ',
+    SX755 => 'C755UZ',
+    SX756 => 'C5060WZ',
+    SX757 => 'C8080WZ',
+    SX758 => 'X350,D575Z,C360Z',
+    SX759 => 'X400,D580Z,C460Z',
+    SX75A => 'AZ-2ZOOM',
+    SX75B => 'D595Z,C500Z',
+    SX75C => 'X550,D545Z,C480Z',
+    SX75D => 'IR-300',
+    SX75F => 'C55Z,C5500Z',
+    SX75G => 'C170,D425',
+    SX75J => 'C180,D435',
+    SX771 => 'C760UZ',
+    SX772 => 'C770UZ',
+    SX773 => 'C745UZ',
+    SX774 => 'X250,D560Z,C350Z',
+    SX775 => 'X100,D540Z,C310Z',
+    SX776 => 'C460ZdelSol',
+    SX777 => 'C765UZ',
+    SX77A => 'D555Z,C315Z',
+    SX851 => 'C7070WZ',
+    SX852 => 'C70Z,C7000Z',
+    SX853 => 'SP500UZ',
+    SX854 => 'SP310',
+    SX855 => 'SP350',
+    SX873 => 'SP320',
+    SX875 => 'FE180/X745', # (also D4330)
+    SX876 => 'FE190/X750', # (also D4327)
+#   other brands
+#    4MP9Q3 => 'Camera 4MP-9Q3'
+#    4MP9T2 => 'BenQ DC C420 / Camera 4MP-9T2'
+#    5MP9Q3 => 'Camera 5MP-9Q3',
+#    5MP9X9 => 'Camera 5MP-9X9',
+#   '5MP-9T'=> 'Camera 5MP-9T3',
+#   '5MP-9Y'=> 'Camera 5MP-9Y2',
+#   '6MP-9U'=> 'Camera 6MP-9U9',
+#    7MP9Q3 => 'Camera 7MP-9Q3',
+#   '8MP-9U'=> 'Camera 8MP-9U4',
+#    CE5330 => 'Acer CE-5330',
+#   'CP-853'=> 'Acer CP-8531',
+#    CS5531 => 'Acer CS5531',
+#    DC500  => 'SeaLife DC500',
+#    DC7370 => 'Camera 7MP-9GA',
+#    DC7371 => 'Camera 7MP-9GM',
+#    DC7371 => 'Hitachi HDC-751E',
+#    DC7375 => 'Hitachi HDC-763E / Rollei RCP-7330X / Ricoh Caplio RR770 / Vivitar ViviCam 7330',
+#   'DC E63'=> 'BenQ DC E63+',
+#   'DC P86'=> 'BenQ DC P860',
+#    DS5340 => 'Maginon Performic S5 / Premier 5MP-9M7',
+#    DS5341 => 'BenQ E53+ / Supra TCM X50 / Maginon X50 / Premier 5MP-9P8',
+#    DS5346 => 'Premier 5MP-9Q2',
+#    E500   => 'Konica Minolta DiMAGE E500',
+#    MAGINO => 'Maginon X60',
+#    Mz60   => 'HP Photosmart Mz60',
+#    Q3DIGI => 'Camera 5MP-9Q3',
+#    SLIMLI => 'Supra Slimline X6',
+#    V8300s => 'Vivitar V8300s',
+);
+
+# ArtFilter, ArtFilterEffect and MagicFilter values (ref PH)
 my %filters = (
-    '0'    => 'Off',
-    '1' => 'Soft Focus',
-    '2' => 'Pop Art',
-    '3' => 'Pale & Light Color',
-    '4' => 'Light Tone',
-    '5' => 'Pin Hole',
-    '6' => 'Grainy Film',
-    '9' => 'Diorama',
-    '10' => 'Cross Process',
-    '12' => 'Fish Eye',
-    '13' => 'Drawing',
-    # Punk? Sparkle?
+    0 => 'Off',
+    1 => 'Soft Focus', # (XZ-1)
+    2 => 'Pop Art', # (SZ-10 magic filter 1,SZ-31MR,E-M5,E-PL3)
+    3 => 'Pale & Light Color',
+    4 => 'Light Tone',
+    5 => 'Pin Hole', # (SZ-10 magic filter 2,SZ-31MR,E-PL3)
+    6 => 'Grainy Film',
+    9 => 'Diorama',
+    10 => 'Cross Process',
+    12 => 'Fish Eye', # (SZ-10 magic filter 3)
+    13 => 'Drawing', # (SZ-10 magic filter 4)
+    14 => 'Gentle Sepia', # (E-5)
+    15 => 'Pale & Light Color II', #forum6269 ('Tender Light' ref 11)
+    16 => 'Pop Art II', #11 (E-PL3 "(dark)" - PH)
+    17 => 'Pin Hole II', #11 (E-PL3 "(color 2)" - PH)
+    18 => 'Pin Hole III', #11 (E-M5, E-PL3 "(color 3)" - PH)
+    19 => 'Grainy Film II', #11
+    20 => 'Dramatic Tone', # (XZ-1,SZ-31MR)
+    21 => 'Punk', # (SZ-10 magic filter 6)
+    22 => 'Soft Focus 2', # (SZ-10 magic filter 5)
+    23 => 'Sparkle', # (SZ-10 magic filter 7)
+    24 => 'Watercolor', # (SZ-10 magic filter 8)
+    25 => 'Key Line', # (E-M5)
+    26 => 'Key Line II', #forum6269
+    27 => 'Miniature', # (SZ-31MR)
+    28 => 'Reflection', # (TG-820,SZ-31MR)
+    29 => 'Fragmented', # (TG-820,SZ-31MR)
+    31 => 'Cross Process II', #forum6269
+    32 => 'Dramatic Tone II',  #forum6269 (Dramatic Tone B&W for E-M5)
+    33 => 'Watercolor I', # ('Watercolor I' for EM-1 ref forum6269, 'Watercolor II' for E-PM2 ref PH)
+    34 => 'Watercolor II', #forum6269
+    35 => 'Diorama II', #forum6269
+    36 => 'Vintage', #forum6269
+    37 => 'Vintage II', #forum6269
+    38 => 'Vintage III', #forum6269
+    39 => 'Partial Color', #forum6269
+    40 => 'Partial Color II', #forum6269
+    41 => 'Partial Color III', #forum6269
+);
+
+my %toneLevelType = (
+    0 => '0',
+    -31999 => 'Highlights',
+    -31998 => 'Shadows',
+    -31997 => 'Midtones',
 );
 
@@ -184,12 +635,10 @@
     0x0100 => {
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
         Writable => 'undef',
         WriteCheck => '$self->CheckImage(\$val)',
         Binary => 1,
     },
-    0x0104 => { #11
-        Name => 'BodyFirmwareVersion',
-        Writable => 'string',
-    },
+    0x0104 => { Name => 'BodyFirmwareVersion',    Writable => 'string' }, #11
 #
 # end Konica/Minolta tags
@@ -199,6 +648,6 @@
         Notes => q{
             3 numbers: 1. Shooting mode: 0=Normal, 2=Fast, 3=Panorama;
-            2. Sequence Number; 3. Panorama Direction: 1=Left-Right,
-            2=Right-Left, 3=Bottom-Top, 4=Top-Bottom
+            2. Sequence Number; 3. Panorama Direction: 1=Left-right,
+            2=Right-left, 3=Bottom-Top, 4=Top-Bottom
         },
         Writable => 'int32u',
@@ -236,5 +685,5 @@
                 6 => 'RAW', #PH - C5050WZ
             );
-            my %t2 = ( # all other types
+            my %t2 = ( # all other types (except D4322, ref 22)
                 1 => 'SQ (Low)',
                 2 => 'HQ (Normal)',
@@ -245,5 +694,5 @@
                 33 => 'Uncompressed', #PH - C2100Z
             );
-            my $conv = $self->{CameraType} =~ /^SX(?!151\b)/ ? \%t1 : \%t2;
+            my $conv = $self->{CameraType} =~ /^(SX(?!151\b)|D4322)/ ? \%t1 : \%t2;
             return $$conv{$val} ? $$conv{$val} : "Unknown ($val)";
         },
@@ -263,5 +712,9 @@
         Description => 'Black And White Mode',
         Writable => 'int16u',
-        PrintConv => \%offOn,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            6 => '(none)', #22
+        },
     },
     0x0204 => {
@@ -277,14 +730,17 @@
         PrintConvInv => '$val=~s/\s*mm$//;$val',
     },
-    0x0206 => { #6
-        Name => 'LensDistortionParams',
-        Writable => 'int16s',
-        Count => 6,
-    },
-    0x0207 => { #PH (was incorrectly FirmwareVersion, ref 1,3)
+    0x0206 => { Name => 'LensDistortionParams', Writable => 'int16s', Count => 6 }, #6
+    0x0207 => { #PH (was incorrectly FirmwareVersion, ref 1/3)
         Name => 'CameraType',
+        Condition => '$$valPt ne "NORMAL"', # FE240, SP510, u730 and u1000 write this
         Writable => 'string',
         DataMember => 'CameraType',
         RawConv => '$self->{CameraType} = $val',
+        SeparateTable => 'CameraType',
+        ValueConv => '$val =~ s/\s+$//; $val',  # ("SX151 " has trailing space)
+        ValueConvInv => '$val',
+        PrintConv => \%olympusCameraTypes,
+        Priority => 0,
+        # 'NORMAL' for some models: u730,SP510UZ,u1000,FE240
     },
     0x0208 => {
@@ -298,30 +754,16 @@
         Format => 'string', # this really should have been a string
     },
-    0x020b => { #PH
-        Name => 'EpsonImageWidth',
-        Writable => 'int16u',
-    },
-    0x020c => { #PH
-        Name => 'EpsonImageHeight',
-        Writable => 'int16u',
-    },
-    0x020d => { #PH
-        Name => 'EpsonSoftware',
-        Writable => 'string',
-    },
+    0x020b => { Name => 'EpsonImageWidth',  Writable => 'int32u' }, #PH
+    0x020c => { Name => 'EpsonImageHeight', Writable => 'int32u' }, #PH
+    0x020d => { Name => 'EpsonSoftware',    Writable => 'string' }, #PH
     0x0280 => { #PH
         %Image::ExifTool::previewImageTagInfo,
+        Groups => { 2 => 'Preview' },
         Notes => 'found in ERF and JPG images from some Epson models',
         Format => 'undef',
         Writable => 'int8u',
     },
-    0x0300 => { #6
-        Name => 'PreCaptureFrames',
-        Writable => 'int16u',
-    },
-    0x0301 => { #11
-        Name => 'WhiteBoard',
-        Writable => 'int16u',
-    },
+    0x0300 => { Name => 'PreCaptureFrames', Writable => 'int16u' }, #6
+    0x0301 => { Name => 'WhiteBoard',       Writable => 'int16u' }, #11
     0x0302 => { #6
         Name => 'OneTouchWB',
@@ -333,16 +775,27 @@
         },
     },
-    0x0303 => { #11
-        Name => 'WhiteBalanceBracket',
-        Writable => 'int16u',
-    },
-    0x0304 => { #11
-        Name => 'WhiteBalanceBias',
-        Writable => 'int16u',
-    },
-   # 0x0305 => 'PrintMaching', ? #11
+    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 => '$$self{TIFF_TYPE} eq "ERF"',
+        Writable => 'int32u',
+        Count => 4,
+        Notes => 'found in Epson ERF images',
+    },
+    # 0x0402 - BitCodedAutoFocus (ref 11)
     0x0403 => { #11
         Name => 'SceneMode',
         Writable => 'int16u',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'Normal',
@@ -381,16 +834,14 @@
             33 => 'Pet',
             34 => 'Smile Shot',
+            35 => 'Quick Shutter',
+            43 => 'Hand-held Starlight', #PH (SH-21)
+            100 => 'Panorama', #PH (SH-21)
             101 => 'Magic Filter', #PH
-        },
-    },
-    0x0404 => { #PH (D595Z, C7070WZ)
-        Name => 'SerialNumber',
-        Writable => 'string',
-    },
-    0x0405 => { #11
-        Name => 'Firmware',
-        Writable => 'string',
-    },
-    0x0e00 => {
+            103 => 'HDR', #PH (XZ-2)
+        },
+    },
+    0x0404 => { Name => 'SerialNumber', Writable => 'string' }, #PH (D595Z, C7070WZ)
+    0x0405 => { Name => 'Firmware',     Writable => 'string' }, #11
+    0x0e00 => { # (AFFieldCoord for models XZ-2 and XZ-10, ref 11)
         Name => 'PrintIM',
         Description => 'Print Image Matching',
@@ -400,4 +851,5 @@
         },
     },
+    # 0x0e80 - undef[256] - offset 0x30: uint16[2] WB_RGBLevels = val[0]*561,65536,val[1]*431 (ref IB)
     0x0f00 => {
         Name => 'DataDump',
@@ -412,5 +864,5 @@
     0x0f04 => {
         Name => 'ZoomedPreviewStart',
-        # NOTE: this tag is not currently updated properly when the image is rewritten!
+        # NOTE: this tag is currently not updated properly when the image is rewritten!
         OffsetPair => 0xf05,
         DataTag => 'ZoomedPreviewImage',
@@ -484,16 +936,7 @@
         Writable => 'rational64s',
     },
-    0x1007 => { #6 (E-10, E-20 and C2500L - numbers usually around 30-40)
-        Name => 'SensorTemperature',
-        Writable => 'int16s',
-    },
-    0x1008 => { #6
-        Name => 'LensTemperature',
-        Writable => 'int16s',
-    },
-    0x1009 => { #11
-        Name => 'LightCondition',
-        Writable => 'int16u',
-    },
+    0x1007 => { Name => 'SensorTemperature',Writable => 'int16s' }, #6 (E-10, E-20 and C2500L - numbers usually around 30-40)
+    0x1008 => { Name => 'LensTemperature',  Writable => 'int16s' }, #6
+    0x1009 => { Name => 'LightCondition',   Writable => 'int16u' }, #11
     0x100a => { #11
         Name => 'FocusRange',
@@ -518,12 +961,6 @@
         PrintConvInv => '$val=~s/\s*mm$//; $val',
     },
-    0x100d => { #6
-        Name => 'ZoomStepCount',
-        Writable => 'int16u',
-    },
-    0x100e => { #6
-        Name => 'FocusStepCount',
-        Writable => 'int16u',
-    },
+    0x100d => { Name => 'ZoomStepCount',    Writable => 'int16u' }, #6
+    0x100e => { Name => 'FocusStepCount',   Writable => 'int16u' }, #6
     0x100f => { #6
         Name => 'Sharpness',
@@ -536,8 +973,5 @@
         },
     },
-    0x1010 => { #6
-        Name => 'FlashChargeLevel',
-        Writable => 'int16u',
-    },
+    0x1010 => { Name => 'FlashChargeLevel', Writable => 'int16u' }, #6
     0x1011 => { #3
         Name => 'ColorMatrix',
@@ -546,9 +980,5 @@
         Count => 9,
     },
-    0x1012 => { #3
-        Name => 'BlackLevel',
-        Writable => 'int16u',
-        Count => 4,
-    },
+    0x1012 => { Name => 'BlackLevel',       Writable => 'int16u', Count => 4 }, #3
     0x1013 => { #11
         Name => 'ColorTemperatureBG',
@@ -565,4 +995,5 @@
         Writable => 'int16u',
         Count => 2,
+        PrintConvColumns => 2,
         PrintConv => {
             '1'   => 'Auto',
@@ -594,13 +1025,7 @@
         ValueConvInv => '$val*=256;"$val 64"',
     },
-    0x1019 => { #11
-        Name => 'ColorMatrixNumber',
-        Writable => 'int16u',
-    },
+    0x1019 => { Name => 'ColorMatrixNumber',    Writable => 'int16u' }, #11
     # 0x101a is same as CameraID ("OLYMPUS DIGITAL CAMERA") for C2500L - PH
-    0x101a => { #3
-        Name => 'SerialNumber',
-        Writable => 'string',
-    },
+    0x101a => { Name => 'SerialNumber',         Writable => 'string' }, #3
     0x101b => { #11
         Name => 'ExternalFlashAE1_0',
@@ -608,51 +1033,14 @@
         Unknown => 1, # (what are these?)
     },
-    0x101c => { #11
-        Name => 'ExternalFlashAE2_0',
-        Writable => 'int32u',
-        Unknown => 1,
-    },
-    0x101d => { #11
-        Name => 'InternalFlashAE1_0',
-        Writable => 'int32u',
-        Unknown => 1,
-    },
-    0x101e => { #11
-        Name => 'InternalFlashAE2_0',
-        Writable => 'int32u',
-        Unknown => 1,
-    },
-    0x101f => { #11
-        Name => 'ExternalFlashAE1',
-        Writable => 'int32u',
-        Unknown => 1,
-    },
-    0x1020 => { #11
-        Name => 'ExternalFlashAE2',
-        Writable => 'int32u',
-        Unknown => 1,
-    },
-    0x1021 => { #11
-        Name => 'InternalFlashAE1',
-        Writable => 'int32u',
-        Unknown => 1,
-    },
-    0x1022 => { #11
-        Name => 'InternalFlashAE2',
-        Writable => 'int32u',
-        Unknown => 1,
-    },
-    0x1023 => { #6
-        Name => 'FlashExposureComp',
-        Writable => 'rational64s',
-    },
-    0x1024 => { #11
-        Name => 'InternalFlashTable',
-        Writable => 'int16u',
-    },
-    0x1025 => { #11
-        Name => 'ExternalFlashGValue',
-        Writable => 'rational64s',
-    },
+    0x101c => { Name => 'ExternalFlashAE2_0',   Writable => 'int32u', Unknown => 1 }, #11
+    0x101d => { Name => 'InternalFlashAE1_0',   Writable => 'int32u', Unknown => 1 }, #11
+    0x101e => { Name => 'InternalFlashAE2_0',   Writable => 'int32u', Unknown => 1 }, #11
+    0x101f => { Name => 'ExternalFlashAE1',     Writable => 'int32u', Unknown => 1 }, #11
+    0x1020 => { Name => 'ExternalFlashAE2',     Writable => 'int32u', Unknown => 1 }, #11
+    0x1021 => { Name => 'InternalFlashAE1',     Writable => 'int32u', Unknown => 1 }, #11
+    0x1022 => { Name => 'InternalFlashAE2',     Writable => 'int32u', Unknown => 1 }, #11
+    0x1023 => { Name => 'FlashExposureComp',    Writable => 'rational64s' }, #6
+    0x1024 => { Name => 'InternalFlashTable',   Writable => 'int16u' }, #11
+    0x1025 => { Name => 'ExternalFlashGValue',  Writable => 'rational64s' }, #11
     0x1026 => { #6
         Name => 'ExternalFlashBounce',
@@ -663,12 +1051,6 @@
         },
     },
-    0x1027 => { #6
-        Name => 'ExternalFlashZoom',
-        Writable => 'int16u',
-    },
-    0x1028 => { #6
-        Name => 'ExternalFlashMode',
-        Writable => 'int16u',
-    },
+    0x1027 => { Name => 'ExternalFlashZoom',    Writable => 'int16u' }, #6
+    0x1028 => { Name => 'ExternalFlashMode',    Writable => 'int16u' }, #6
     0x1029 => { #3
         Name => 'Contrast',
@@ -680,34 +1062,11 @@
         },
     },
-    0x102a => { #3
-        Name => 'SharpnessFactor',
-        Writable => 'int16u',
-    },
-    0x102b => { #3
-        Name => 'ColorControl',
-        Writable => 'int16u',
-        Count => 6,
-    },
-    0x102c => { #3
-        Name => 'ValidBits',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x102d => { #3
-        Name => 'CoringFilter',
-        Writable => 'int16u',
-    },
-    0x102e => { #PH
-        Name => 'OlympusImageWidth',
-        Writable => 'int32u',
-    },
-    0x102f => { #PH
-        Name => 'OlympusImageHeight',
-        Writable => 'int32u',
-    },
-    0x1030 => { #11
-        Name => 'SceneDetect',
-        Writable => 'int16u',
-    },
+    0x102a => { Name => 'SharpnessFactor',      Writable => 'int16u' }, #3
+    0x102b => { Name => 'ColorControl',         Writable => 'int16u', Count => 6 }, #3
+    0x102c => { Name => 'ValidBits',            Writable => 'int16u', Count => 2 }, #3
+    0x102d => { Name => 'CoringFilter',         Writable => 'int16u' }, #3
+    0x102e => { Name => 'OlympusImageWidth',    Writable => 'int32u' }, #PH
+    0x102f => { Name => 'OlympusImageHeight',   Writable => 'int32u' }, #PH
+    0x1030 => { Name => 'SceneDetect',          Writable => 'int16u' }, #11
     0x1031 => { #11
         Name => 'SceneArea',
@@ -724,11 +1083,9 @@
         Unknown => 1, # (but what does it mean?)
     },
-    0x1034 => { #3
-        Name => 'CompressionRatio',
-        Writable => 'rational64u',
-    },
+    0x1034 => { Name => 'CompressionRatio',    Writable => 'rational64u' }, #3
     0x1035 => { #6
         Name => 'PreviewImageValid',
         Writable => 'int32u',
+        DelValue => 0,
         PrintConv => { 0 => 'No', 1 => 'Yes' },
     },
@@ -739,4 +1096,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -747,10 +1105,8 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
-    0x1038 => { #11
-        Name => 'AFResult',
-        Writable => 'int16u',
-    },
+    0x1038 => { Name => 'AFResult',             Writable => 'int16u' }, #11
     0x1039 => { #6
         Name => 'CCDScanMode',
@@ -766,20 +1122,8 @@
         PrintConv => \%offOn,
     },
-    0x103b => { #6
-        Name => 'FocusStepInfinity',
-        Writable => 'int16u',
-    },
-    0x103c => { #6
-        Name => 'FocusStepNear',
-        Writable => 'int16u',
-    },
-    0x103d => { #11
-        Name => 'LightValueCenter',
-        Writable => 'rational64s',
-    },
-    0x103e => { #11
-        Name => 'LightValuePeriphery',
-        Writable => 'rational64s',
-    },
+    0x103b => { Name => 'FocusStepInfinity',    Writable => 'int16u' }, #6
+    0x103c => { Name => 'FocusStepNear',        Writable => 'int16u' }, #6
+    0x103d => { Name => 'LightValueCenter',     Writable => 'rational64s' }, #11
+    0x103e => { Name => 'LightValuePeriphery',  Writable => 'rational64s' }, #11
     0x103f => { #11
         Name => 'FieldCount',
@@ -1212,4 +1556,6 @@
         DataMember => 'CameraType',
         RawConv => '$self->{CameraType} = $val',
+        SeparateTable => 'CameraType',
+        PrintConv => \%olympusCameraTypes,
     },
 );
@@ -1231,4 +1577,6 @@
         Writable => 'string',
         Count => 6,
+        SeparateTable => 'CameraType',
+        PrintConv => \%olympusCameraTypes,
     },
     0x101 => { #PH
@@ -1262,15 +1610,15 @@
         Count => 6,
         Notes => q{
-            6 numbers: 0. Make, 1. Unknown, 2. Model, 3. Sub-model, 4-5. Unknown.  Only
-            the Make, Model and Sub-model are used to determine the lens model
+            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)
-        ValueConv => 'my @a = split(" ",$val); "$a[0] $a[2] $a[3]"',
+        # 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); "$a[0] 0 $a[1] $a[2] 0 0"',
+        ValueConvInv => 'my @a=split(" ",$val); hex($a[0])." 0 ".hex($a[1])." ".hex($a[2])." 0 0"',
         PrintConv => \%olympusLensTypes,
     },
@@ -1290,8 +1638,5 @@
         PrintConvInv => 'pack("A31",$val)', # pad with spaces to 31 chars
     },
-    0x203 => { #17
-        Name => 'LensModel',
-        Writable => 'string',
-    },
+    0x203 => { Name => 'LensModel',         Writable => 'string' }, #17
     0x204 => { #6
         Name => 'LensFirmwareVersion',
@@ -1316,14 +1661,8 @@
         PrintConvInv => '$val',
     },
-    0x207 => { #PH
-        Name => 'MinFocalLength',
-        Writable => 'int16u',
-    },
-    0x208 => { #PH
-        Name => 'MaxFocalLength',
-        Writable => 'int16u',
-    },
+    0x207 => { Name => 'MinFocalLength',    Writable => 'int16u' }, #PH
+    0x208 => { Name => 'MaxFocalLength',    Writable => 'int16u' }, #PH
     0x20a => { #9
-        Name => 'MaxApertureAtCurrentFocal',
+        Name => 'MaxAperture', # (at current focal length)
         Writable => 'int16u',
         ValueConv => '$val ? sqrt(2)**($val/256) : 0',
@@ -1343,25 +1682,18 @@
         Count => 6,
         Notes => q{
-            6 numbers: 0. Make, 1. Unknown, 2. Model, 3. Sub-model, 4-5. Unknown.  Only
-            the Make and Model are used to determine the extender model
-        },
-        ValueConv => 'my @a = split(" ",$val); "$a[0] $a[2]"',
-        ValueConvInv => 'my @a=split(" ",$val); "$a[0] 0 $a[1] 0 0 0"',
-        PrintConv => {
-            '0 0'   => 'None',
-            '0 4'   => 'Olympus Zuiko Digital EC-14 1.4x Teleconverter',
-            '0 8'   => 'Olympus EX-25 Extension Tube',
-            '0 16'  => 'Olympus Zuiko Digital EC-20 2.0x Teleconverter', #7
-        },
-    },
-    0x302 => { #4
-        Name => 'ExtenderSerialNumber',
-        Writable => 'string',
-        Count => 32,
-    },
-    0x303 => { #9
-        Name => 'ExtenderModel',
-        Writable => 'string',
-    },
+            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])',
+        ValueConvInv => 'my @a=split(" ",$val); hex($a[0])." 0 ".hex($a[1])." 0 0 0"',
+        PrintConv => {
+            '0 00' => 'None',
+            '0 04' => 'Olympus Zuiko Digital EC-14 1.4x Teleconverter',
+            '0 08' => 'Olympus EX-25 Extension Tube',
+            '0 10' => 'Olympus Zuiko Digital EC-20 2.0x Teleconverter', #7
+        },
+    },
+    0x302 => { Name => 'ExtenderSerialNumber',  Writable => 'string', Count => 32 }, #4
+    0x303 => { Name => 'ExtenderModel',         Writable => 'string' }, #9
     0x304 => { #6
         Name => 'ExtenderFirmwareVersion',
@@ -1370,4 +1702,9 @@
         PrintConvInv => '$val=sprintf("%.3f",$val);$val=~s/\.//;hex($val)',
     },
+    0x403 => { #http://dev.exiv2.org/issues/870
+        Name => 'ConversionLens',
+        Writable => 'string',
+        # (observed values: '','TCON','FCON','WCON')
+    },
     0x1000 => { #6
         Name => 'FlashType',
@@ -1377,4 +1714,5 @@
             2 => 'Simple E-System',
             3 => 'E-System',
+            4 => 'E-System (body powered)', #forum9740
         },
     },
@@ -1382,4 +1720,5 @@
         Name => 'FlashModel',
         Writable => 'int16u',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'None',
@@ -1391,5 +1730,8 @@
             6 => 'FL-50R', #11 (or Metz mecablitz digital)
             7 => 'FL-36R', #11
-            # have seen value of 9 - PH
+            9 => 'FL-14', #11
+            11 => 'FL-600R', #11
+            13 => 'FL-LM3', #forum9740
+            15 => 'FL-900R', #7
         },
     },
@@ -1400,9 +1742,5 @@
         PrintConvInv => '$val=sprintf("%.3f",$val);$val=~s/\.//;hex($val)',
     },
-    0x1003 => { #4
-        Name => 'FlashSerialNumber',
-        Writable => 'string',
-        Count => 32,
-    },
+    0x1003 => { Name => 'FlashSerialNumber', Writable => 'string', Count => 32 }, #4
 );
 
@@ -1430,4 +1768,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -1437,4 +1776,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -1467,7 +1807,8 @@
         },
     },
-    0x203 => { #11 (some E-models only)
-        Name => 'ExposureShift',
-        Writable => 'rational64s',
+    0x203 => { Name => 'ExposureShift', Writable => 'rational64s' }, #11 (some models only)
+    0x204 => { #11 (XZ-1)
+        Name => 'NDFilter',
+        PrintConv => \%offOn,
     },
     0x300 => { #6
@@ -1490,14 +1831,19 @@
             2 => 'Continuous AF',
             3 => 'Multi AF',
-            5 => 'Face detect', #11
+            4 => 'Face detect', #11
             10 => 'MF',
-        }, { BITMASK => { #11
-            0 => 'S-AF',
-            2 => 'C-AF',
-            4 => 'MF',
-            5 => 'Face detect',
-            6 => 'Imager AF',
-            8 => 'AF sensor',
-        }}],
+        }, {
+            0 => '(none)',
+            BITMASK => { #11
+                0 => 'S-AF',
+                2 => 'C-AF',
+                4 => 'MF',
+                5 => 'Face detect',
+                6 => 'Imager AF',
+                7 => 'Live View Magnification Frame',
+                8 => 'AF sensor',
+                9 => 'Starry Sky AF', #24
+            },
+        }],
     },
     0x302 => { #6
@@ -1526,5 +1872,5 @@
         Name => 'AFAreas',
         Notes => 'coordinates range from 0 to 255',
-        Format => 'int32u',
+        Writable => 'int32u',
         Count => 64,
         PrintConv => 'Image::ExifTool::Olympus::PrintAFAreas($val)',
@@ -1533,17 +1879,32 @@
         Name => 'AFPointSelected',
         Notes => 'coordinates expressed as a percent',
-        Format => 'rational64s',
+        Writable => 'rational64s',
         Count => 5,
         ValueConv => '$val =~ s/\S* //; $val', # ignore first undefined value
         ValueConvInv => '"undef $val"',
         PrintConv => q{
-            return $val if $val =~ /undef/;
+            return 'n/a' if $val =~ /undef/;
             sprintf("(%d%%,%d%%) (%d%%,%d%%)", map {$_ * 100} split(" ",$val));
-        }
+        },
+        PrintConvInv => q{
+            return 'undef undef undef undef' if $val eq 'n/a';
+            my @nums = $val =~ /\d+(?:\.\d+)?/g;
+            return undef unless @nums == 4;
+            join ' ', map {$_ / 100} @nums;
+        },
+    },
+    0x306 => { #11
+        Name => 'AFFineTune',
+        Writable => 'int8u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     0x307 => { #15
         Name => 'AFFineTuneAdj',
-        Format => 'int16s',
+        Writable => 'int16s',
         Count => 3, # not sure what the 3 values mean
+    },
+    0x308 => { #forum11578
+        Name => 'FocusBracketStepSize',
+        Writable => 'int8u',
     },
     0x400 => { #6
@@ -1562,13 +1923,11 @@
         },
     },
-    0x401 => { #6
-        Name => 'FlashExposureComp',
-        Writable => 'rational64s',
-    },
-    # 0x402 - FlashMode? bit0=TTL, bit2=SuperFP (ref 11)
+    0x401 => { Name => 'FlashExposureComp', Writable => 'rational64s' }, #6
+    # 0x402 - FlashMode? bit0=TTL, bit1=auto, bit2=SuperFP (ref 11)
     0x403 => { #11
         Name => 'FlashRemoteControl',
         Writable => 'int16u',
         PrintHex => 1,
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'Off',
@@ -1590,5 +1949,6 @@
         Name => 'FlashControlMode',
         Writable => 'int16u',
-        Count => 3,
+        Count => -1,
+        Notes => '3 or 4 values',
         PrintConv => [{
             0 => 'Off',
@@ -1601,14 +1961,22 @@
         Name => 'FlashIntensity',
         Writable => 'rational64s',
-        Count => 3,
-        PrintConv => '$val eq "undef undef undef" ? "n/a" : $val',
-        PrintConvInv => '$val eq "n/a" ? "undef undef undef" : $val',
+        Count => -1,
+        Notes => '3 or 4 values',
+        PrintConv => {
+            OTHER => sub { shift },
+            'undef undef undef' => 'n/a',
+            'undef undef undef undef' => 'n/a (x4)',
+        },
     },
     0x406 => { #11
         Name => 'ManualFlashStrength',
         Writable => 'rational64s',
-        Count => 3,
-        PrintConv => '$val eq "undef undef undef" ? "n/a" : $val',
-        PrintConvInv => '$val eq "n/a" ? "undef undef undef" : $val',
+        Count => -1,
+        Notes => '3 or 4 values',
+        PrintConv => {
+            OTHER => sub { shift },
+            'undef undef undef' => 'n/a',
+            'undef undef undef undef' => 'n/a (x4)',
+        },
     },
     0x500 => { #6
@@ -1617,4 +1985,5 @@
         PrintConv => {
             0 => 'Auto',
+            1 => 'Auto (Keep Warm Color Off)', #IB
             16 => '7500K (Fine Weather with Shade)',
             17 => '6000K (Cloudy)',
@@ -1622,15 +1991,20 @@
             20 => '3000K (Tungsten light)',
             21 => '3600K (Tungsten light-like)',
+            22 => 'Auto Setup', #IB
+            23 => '5500K (Flash)', #IB
             33 => '6600K (Daylight fluorescent)',
             34 => '4500K (Neutral white fluorescent)',
             35 => '4000K (Cool white fluorescent)',
+            36 => 'White Fluorescent', #IB
             48 => '3600K (Tungsten light-like)',
-            256 => 'Custom WB 1',
-            257 => 'Custom WB 2',
-            258 => 'Custom WB 3',
-            259 => 'Custom WB 4',
-            512 => 'Custom WB 5400K',
-            513 => 'Custom WB 2900K',
-            514 => 'Custom WB 8000K',
+            67 => 'Underwater', #IB
+            256 => 'One Touch WB 1', #IB
+            257 => 'One Touch WB 2', #IB
+            258 => 'One Touch WB 3', #IB
+            259 => 'One Touch WB 4', #IB
+            512 => 'Custom WB 1', #IB
+            513 => 'Custom WB 2', #IB
+            514 => 'Custom WB 3', #IB
+            515 => 'Custom WB 4', #IB
         },
     },
@@ -1699,4 +2073,5 @@
         Name => 'SceneMode',
         Writable => 'int16u',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'Standard',
@@ -1746,13 +2121,20 @@
             49 => 'Underwater Snapshot', #11
             50 => 'Shooting Guide', #11
-            51 => 'Face Portrait', #PH (NC)
-            52 => 'Smile Shot', #PH (NC)
-            53 => 'Quick Shutter', #PH (NC)
-            54 => 'Slow Shutter', #PH (NC)
-            55 => 'Bird Watching', #PH (NC)
-            56 => 'Multiple Exposure', #PH (NC)
-            57 => 'e-Portrait', #PH (NC)
-            58 => 'Beauty Fix', #PH (NC)
-            59 => 'Soft Background', #PH (NC)
+            54 => 'Face Portrait', #11
+            57 => 'Bulb', #11
+            59 => 'Smile Shot', #11
+            60 => 'Quick Shutter', #11
+            63 => 'Slow Shutter', #11
+            64 => 'Bird Watching', #11
+            65 => 'Multiple Exposure', #11
+            66 => 'e-Portrait', #11
+            67 => 'Soft Background Shot', #11
+            142 => 'Hand-held Starlight', #PH (SH-21)
+            154 => 'HDR', #PH (XZ-2)
+            197 => 'Panning', #forum11631 (EM5iii)
+            203 => 'Light Trails', #forum11631 (EM5iii)
+            204 => 'Backlight HDR', #forum11631 (EM5iii)
+            205 => 'Silent', #forum11631 (EM5iii)
+            206 => 'Multi Focus Shot', #forum11631 (EM5iii)
         },
     },
@@ -1761,4 +2143,5 @@
         Writable => 'int16u',
         PrintConv => {
+            0 => '(none)',
             BITMASK => {
                 0 => 'Noise Reduction',
@@ -1779,8 +2162,5 @@
         PrintConv => \%offOn,
     },
-    0x50d => { #PH/4
-        Name => 'CompressionFactor',
-        Writable => 'rational64u',
-    },
+    0x50d => { Name => 'CompressionFactor', Writable => 'rational64u' }, #PH/4
     0x50f => { #6
         Name => 'Gradation',
@@ -1790,4 +2170,5 @@
         Relist => [ [0..2], 3 ], # join values 0-2 for PrintConv
         PrintConv => [{
+           '0 0 0' => 'n/a', #PH (?)
            '-1 -1 1' => 'Low Key',
             '0 -1 1' => 'Normal',
@@ -1809,4 +2190,12 @@
             4 => 'Portrait',
             5 => 'i-Enhance', #11
+            6 => 'e-Portrait', #23
+            7 => 'Color Creator', #23
+            9 => 'Color Profile 1', #23
+            10 => 'Color Profile 2', #23
+            11 => 'Color Profile 3', #23
+            12 => 'Monochrome Profile 1', #23
+            13 => 'Monochrome Profile 2', #23
+            14 => 'Monochrome Profile 3', #23
             256 => 'Monotone',
             512 => 'Sepia',
@@ -1846,4 +2235,5 @@
         Name => 'PictureModeBWFilter',
         Writable => 'int16s',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'n/a',
@@ -1858,4 +2248,5 @@
         Name => 'PictureModeTone',
         Writable => 'int16s',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'n/a',
@@ -1872,4 +2263,5 @@
         Count => 3,
         PrintConv => {
+           '0 0 0' => 'n/a', #PH (?)
            '-2 -2 1' => 'Off',
            '-1 -2 1' => 'Low',
@@ -1882,4 +2274,5 @@
         Writable => 'int16u',
         Count => 4,
+        PrintConvColumns => 2,
         PrintConv => [ \%filters ],
     },
@@ -1887,15 +2280,183 @@
         Name => 'MagicFilter',
         Writable => 'int16u',
-        Count => 4, # (2nd number is 0 or 1280, 3rd/4th are 0)
+        Count => 4, # (2nd number is 0, 1280 or 1792, 3rd/4th are 0)
+        # (1792 observed for E-5 Gentle Sepia and XZ-1 Dramatic Tone)
+        PrintConvColumns => 2,
         PrintConv => [ \%filters ],
     },
-    0x600 => { #PH/4
+    0x52d => { #11
+        Name => 'PictureModeEffect',
+        Writable => 'int16s',
+        Count => 3,
+        PrintConv => {
+           '0 0 0' => 'n/a', #PH (?)
+           '-1 -1 1' => 'Low',
+           '0 -1 1' => 'Standard',
+           '1 -1 1' => 'High',
+        },
+    },
+    0x52e => { #11/PH
+        Name => 'ToneLevel',
+        PrintConv => [
+            \%toneLevelType,
+            undef, # (highlights value)
+            undef, # (highlights min)
+            undef, # (highlights max)
+            \%toneLevelType,
+            undef, # (shadows value)
+            undef, # (shadows min)
+            undef, # (shadows max)
+            \%toneLevelType,
+            undef, # (midtones value)
+            undef, # (midtones min)
+            undef, # (midtones max)
+            \%toneLevelType,
+            undef,
+            undef,
+            undef,
+            \%toneLevelType,
+            undef,
+            undef,
+            undef,
+            \%toneLevelType,
+            undef,
+            undef,
+            undef,
+            \%toneLevelType,
+            undef,
+            undef,
+            undef,
+        ]
+    },
+    0x52f => { #PH
+        Name => 'ArtFilterEffect',
+        Writable => 'int16u',
+        Count => 20,
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => [
+            \%filters,
+            undef,
+            undef,
+            '"Partial Color $val"', #23
+            {   # there are 5 available art filter effects for the E-PL3...
+                0x0000 => 'No Effect',
+                0x8010 => 'Star Light',
+                0x8020 => 'Pin Hole',
+                0x8030 => 'Frame',
+                0x8040 => 'Soft Focus',
+                0x8050 => 'White Edge',
+                0x8060 => 'B&W', # (NC - E-PL2 with "Grainy Film" filter)
+                0x8080 => 'Blur Top and Bottom', #23
+                0x8081 => 'Blur Left and Right', #23
+                # (E-PL2 also has "Pict. Tone" effect)
+            },
+            undef,
+            { #23
+                0 => 'No Color Filter',
+                1 => 'Yellow Color Filter',
+                2 => 'Orange Color Filter',
+                3 => 'Red Color Filter',
+                4 => 'Green Color Filter',
+            },
+        ],
+    },
+    0x532 => { #23
+        Name => 'ColorCreatorEffect',
+        Writable => 'int16s',
+        Count => 6,
+        PrintConv => [
+            '"Color $val"',
+            undef, # (Color min)
+            undef, # (Color max)
+            '"Strength $val"',
+            undef, # (Strength min)
+            undef, # (Strength max)
+        ],
+    },
+    0x537 => { #23
+        Name => 'MonochromeProfileSettings',
+        Writable => 'int16s',
+        Count => 6,
+        PrintConv => [
+            {
+                0 => 'No Filter',
+                1 => 'Yellow Filter',
+                2 => 'Orange Filter',
+                3 => 'Red Filter',
+                4 => 'Magenta Filter',
+                5 => 'Blue Filter',
+                6 => 'Cyan Filter',
+                7 => 'Green Filter',
+                8 => 'Yellow-green Filter',
+            },
+            undef, # (Filter number min)
+            undef, # (Filter number max)
+            '"Strength $val"',
+            undef, # (Strength min)
+            undef, # (Strength max)
+        ],
+    },
+    0x538 => { #23
+        Name => 'FilmGrainEffect',
+        Writable => 'int16s',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Medium',
+            3 => 'High',
+        },
+    },
+    0x539 => { #23
+        Name => 'ColorProfileSettings',
+        Writable => 'int16s',
+        Count => 14,
+        PrintConv => [
+            '"Min $val"',
+            '"Max $val"',
+            '"Yellow $val"',
+            '"Orange $val"',
+            '"Orange-red $val"',
+            '"Red $val"',
+            '"Magenta $val"',
+            '"Violet $val"',
+            '"Blue $val"',
+            '"Blue-cyan $val"',
+            '"Cyan $val"',
+            '"Green-cyan $val"',
+            '"Green $val"',
+            '"Yellow-green $val"',
+        ],
+    },
+    0x53a => { #23
+        Name => 'MonochromeVignetting',
+        Writable => 'int16s',
+        Notes => '-5 to +5: positive is white vignetting, negative is black vignetting',
+    },
+    0x53b => { #23
+        Name => 'MonochromeColor',
+        Writable => 'int16s',
+        PrintConv => {
+            0 => '(none)',
+            1 => 'Normal',
+            2 => 'Sepia',
+            3 => 'Blue',
+            4 => 'Purple',
+            5 => 'Green',
+        },
+    },
+    0x600 => { #PH/4/22
         Name => 'DriveMode',
         Writable => 'int16u',
         Count => -1,
-        Notes => '2 or 3 numbers: 1. Mode, 2. Shot number, 3. Mode bits',
+        Notes => '2, 3 or 5 numbers: 1. Mode, 2. Shot number, 3. Mode bits, 5. Shutter mode',
         PrintConv => q{
-            my ($a,$b,$c) = split ' ',$val;
-            return 'Single Shot' unless $a;
+            my ($a,$b,$c,$d,$e) = split ' ',$val;
+            if ($e) {
+                $e = '; ' . ({ 2 => 'Anti-shock 0', 4 => 'Electronic shutter' }->{$e} || "Unknown ($e)");
+            } else {
+                $e = '';
+            }
+            return "Single Shot$e" unless $a;
             if ($a == 5 and defined $c) {
                 $a = DecodeBits($c, { #6
@@ -1904,4 +2465,7 @@
                     2 => 'FL',
                     3 => 'MF',
+                    4 => 'ISO', #forum8906
+                    5 => 'AE Auto', #forum8906
+                    6 => 'Focus', #PH
                 }) . ' Bracketing';
                 $a =~ s/, /+/g;
@@ -1915,5 +2479,5 @@
                 $a = $a{$a} || "Unknown ($a)";
             }
-            return "$a, Shot $b";
+            return "$a, Shot $b$e";
         },
     },
@@ -1931,5 +2495,5 @@
                 4 => 'Top to Bottom',
             );
-            return ($a{$a} || "Unknown ($a)") . ', Shot ' . $b;
+            return(($a{$a} || "Unknown ($a)") . ', Shot ' . $b);
         },
     },
@@ -1955,4 +2519,43 @@
             2 => 'On, Mode 2',
             3 => 'On, Mode 3',
+            4 => 'On, Mode 4', # (NC, E-P5)
+        },
+    },
+    0x804 => { #PH (E-M1 with firmware update)
+        Name => 'StackedImage',
+        Writable => 'int32u',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'No',
+            '1 *' => 'Live Composite (* images)', #24
+            '4 *' => 'Live Time/Bulb (* images)', #24
+            '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' => 'Tripod high resolution', #IB
+            '9 *' => 'Focus-stacked (* images)', #IB (* = 2-15)
+            '11 16' => 'Hand-held high resolution', #IB (perhaps '11 15' would be possible, ref 24)
+            OTHER => sub {
+                my ($val, $inv, $conv) = @_;
+                if ($inv) {
+                    $val = lc $val;
+                    return undef unless $val =~ s/(\d+) images/\* images/;
+                    my $num = $1;
+                    foreach (keys %$conv) {
+                        next unless $val eq lc $$conv{$_};
+                        ($val = $_) =~ s/\*/$num/ or return undef;
+                        return $val;
+                    }
+                } else {
+                    return "Unknown ($_[0])" unless $val =~ s/ (\d+)/ \*/ and $$conv{$val};
+                    my $num = $1;
+                    ($val = $$conv{$val}) =~ s/\*/$num/;
+                    return $val;
+                }
+            },
         },
     },
@@ -1981,12 +2584,27 @@
     },
     0x903 => { #11
-        Name => 'LevelGaugeRoll',
-        Writable => 'int16u',
-        PrintConv => \%offOn,
+        Name => 'RollAngle',
+        Notes => 'converted to degrees of clockwise camera rotation',
+        Writable => 'int16s',
+        Count => 2, # (second value is 0 if level gauge is off)
+        # negate to express as clockwise rotation
+        ValueConv => '$val=~s/ 1$// ? -$val/10 : "n/a"',
+        ValueConvInv => 'IsFloat($val) ? sprintf("%.0f 1",-$val*10) : "0 0"',
     },
     0x904 => { #11
-        Name => 'LevelGaugePitch',
-        Writable => 'int16u',
-        PrintConv => \%offOn,
+        Name => 'PitchAngle',
+        Notes => 'converted to degrees of upward camera tilt',
+        Writable => 'int16s',
+        Count => 2, # (second value is 0 if level gauge is off)
+        ValueConv => '$val =~ s/ 1$// ? $val / 10 : "n/a"',
+        ValueConvInv => 'IsFloat($val) ? sprintf("%.0f 1",$val*10) : "0 0"',
+    },
+    0x908 => { #PH (NC, E-M1)
+        Name => 'DateTimeUTC',
+        Writable => 'string',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,undef,1)',
     },
 );
@@ -2004,40 +2622,12 @@
         Count => 4,
     },
-    0x100 => {
-        Name => 'RawDevExposureBiasValue',
-        Writable => 'rational64s',
-    },
-    0x101 => {
-        Name => 'RawDevWhiteBalanceValue',
-        Writable => 'int16u',
-    },
-    0x102 => {
-        Name => 'RawDevWBFineAdjustment',
-        Writable => 'int16s',
-    },
-    0x103 => {
-        Name => 'RawDevGrayPoint',
-        Writable => 'int16u',
-        Count => 3,
-    },
-    0x104 => {
-        Name => 'RawDevSaturationEmphasis',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x105 => {
-        Name => 'RawDevMemoryColorEmphasis',
-        Writable => 'int16u',
-    },
-    0x106 => {
-        Name => 'RawDevContrastValue',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x107 => {
-        Name => 'RawDevSharpnessValue',
-        Writable => 'int16s',
-        Count => 3,
-    },
+    0x100 => { Name => 'RawDevExposureBiasValue',   Writable => 'rational64s' },
+    0x101 => { Name => 'RawDevWhiteBalanceValue',   Writable => 'int16u' },
+    0x102 => { Name => 'RawDevWBFineAdjustment',    Writable => 'int16s' },
+    0x103 => { Name => 'RawDevGrayPoint',           Writable => 'int16u', Count => 3 },
+    0x104 => { Name => 'RawDevSaturationEmphasis',  Writable => 'int16s', Count => 3 },
+    0x105 => { Name => 'RawDevMemoryColorEmphasis', Writable => 'int16u' },
+    0x106 => { Name => 'RawDevContrastValue',       Writable => 'int16s', Count => 3 },
+    0x107 => { Name => 'RawDevSharpnessValue',      Writable => 'int16s', Count => 3 },
     0x108 => {
         Name => 'RawDevColorSpace',
@@ -2063,4 +2653,5 @@
         Writable => 'int16u',
         PrintConv => { #11
+            0 => '(none)',
             BITMASK => {
                 0 => 'Noise Reduction',
@@ -2084,4 +2675,5 @@
         Writable => 'int16u',
         PrintConv => { #11
+            0 => '(none)',
             BITMASK => {
                 0 => 'WB Color Temp',
@@ -2110,8 +2702,5 @@
         Count => 4,
     },
-    0x100 => {
-        Name => 'RawDevExposureBiasValue',
-        Writable => 'rational64s',
-    },
+    0x100 => { Name => 'RawDevExposureBiasValue',   Writable => 'rational64s' },
     0x101 => {
         Name => 'RawDevWhiteBalance',
@@ -2122,36 +2711,11 @@
         },
     },
-    0x102 => {
-        Name => 'RawDevWhiteBalanceValue',
-        Writable => 'int16u',
-    },
-    0x103 => {
-        Name => 'RawDevWBFineAdjustment',
-        Writable => 'int16s',
-    },
-    0x104 => {
-        Name => 'RawDevGrayPoint',
-        Writable => 'int16u',
-        Count => 3,
-    },
-    0x105 => {
-        Name => 'RawDevContrastValue',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x106 => {
-        Name => 'RawDevSharpnessValue',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x107 => {
-        Name => 'RawDevSaturationEmphasis',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x108 => {
-        Name => 'RawDevMemoryColorEmphasis',
-        Writable => 'int16u',
-    },
+    0x102 => { Name => 'RawDevWhiteBalanceValue',   Writable => 'int16u' },
+    0x103 => { Name => 'RawDevWBFineAdjustment',    Writable => 'int16s' },
+    0x104 => { Name => 'RawDevGrayPoint',           Writable => 'int16u', Count => 3 },
+    0x105 => { Name => 'RawDevContrastValue',       Writable => 'int16s', Count => 3 },
+    0x106 => { Name => 'RawDevSharpnessValue',      Writable => 'int16s', Count => 3 },
+    0x107 => { Name => 'RawDevSaturationEmphasis',  Writable => 'int16s', Count => 3 },
+    0x108 => { Name => 'RawDevMemoryColorEmphasis', Writable => 'int16u' },
     0x109 => {
         Name => 'RawDevColorSpace',
@@ -2167,4 +2731,5 @@
         Writable => 'int16u',
         PrintConv => {
+            0 => '(none)',
             BITMASK => {
                 0 => 'Noise Reduction',
@@ -2193,19 +2758,7 @@
         },
     },
-    0x10d => {
-        Name => 'RawDevPMSaturation',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x10e => {
-        Name => 'RawDevPMContrast',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x10f => {
-        Name => 'RawDevPMSharpness',
-        Writable => 'int16s',
-        Count => 3,
-    },
+    0x10d => { Name => 'RawDevPMSaturation',    Writable => 'int16s', Count => 3 },
+    0x10e => { Name => 'RawDevPMContrast',      Writable => 'int16s', Count => 3 },
+    0x10f => { Name => 'RawDevPMSharpness',     Writable => 'int16s', Count => 3 },
     0x110 => {
         Name => 'RawDevPM_BWFilter',
@@ -2230,22 +2783,14 @@
         },
     },
-    0x112 => {
-        Name => 'RawDevGradation',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x113 => {
-        Name => 'RawDevSaturation3',
-        Writable => 'int16s',
-        Count => 3, #(NC)
-    },
-    0x119 => {
-        Name => 'RawDevAutoGradation',
-        Writable => 'int16u', #(NC)
-        PrintConv => \%offOn,
-    },
-    0x120 => {
-        Name => 'RawDevPMNoiseFilter',
-        Writable => 'int16u', #(NC)
+    0x112 => { Name => 'RawDevGradation',       Writable => 'int16s', Count => 3 },
+    0x113 => { Name => 'RawDevSaturation3',     Writable => 'int16s', Count => 3 }, #(NC Count)
+    0x119 => { Name => 'RawDevAutoGradation',   Writable => 'int16u', PrintConv => \%offOn },
+    0x120 => { Name => 'RawDevPMNoiseFilter',   Writable => 'int16u' }, #(NC format)
+    0x121 => { #PH (E-P5)
+        Name => 'RawDevArtFilter',
+        Writable => 'int16u',
+        Count => 4,
+        PrintConvColumns => 2,
+        PrintConv => [ \%filters ],
     },
 );
@@ -2263,141 +2808,37 @@
         Count => 4,
     },
-    0x100 => { #6
-        Name => 'WB_RBLevels',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x102 => { #11
-        Name => 'WB_RBLevels3000K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x103 => { #11
-        Name => 'WB_RBLevels3300K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x104 => { #11
-        Name => 'WB_RBLevels3600K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x105 => { #11
-        Name => 'WB_RBLevels3900K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x106 => { #11
-        Name => 'WB_RBLevels4000K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x107 => { #11
-        Name => 'WB_RBLevels4300K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x108 => { #11
-        Name => 'WB_RBLevels4500K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x109 => { #11
-        Name => 'WB_RBLevels4800K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x10a => { #11
-        Name => 'WB_RBLevels5300K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x10b => { #11
-        Name => 'WB_RBLevels6000K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x10c => { #11
-        Name => 'WB_RBLevels6600K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x10d => { #11
-        Name => 'WB_RBLevels7500K',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x10e => { #11
-        Name => 'WB_RBLevelsCWB1',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x10f => { #11
-        Name => 'WB_RBLevelsCWB2',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x110 => { #11
-        Name => 'WB_RBLevelsCWB3',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x111 => { #11
-        Name => 'WB_RBLevelsCWB4',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x113 => { #11
-        Name => 'WB_GLevel3000K',
-        Writable => 'int16u',
-    },
-    0x114 => { #11
-        Name => 'WB_GLevel3300K',
-        Writable => 'int16u',
-    },
-    0x115 => { #11
-        Name => 'WB_GLevel3600K',
-        Writable => 'int16u',
-    },
-    0x116 => { #11
-        Name => 'WB_GLevel3900K',
-        Writable => 'int16u',
-    },
-    0x117 => { #11
-        Name => 'WB_GLevel4000K',
-        Writable => 'int16u',
-    },
-    0x118 => { #11
-        Name => 'WB_GLevel4300K',
-        Writable => 'int16u',
-    },
-    0x119 => { #11
-        Name => 'WB_GLevel4500K',
-        Writable => 'int16u',
-    },
-    0x11a => { #11
-        Name => 'WB_GLevel4800K',
-        Writable => 'int16u',
-    },
-    0x11b => { #11
-        Name => 'WB_GLevel5300K',
-        Writable => 'int16u',
-    },
-    0x11c => { #11
-        Name => 'WB_GLevel6000K',
-        Writable => 'int16u',
-    },
-    0x11d => { #11
-        Name => 'WB_GLevel6600K',
-        Writable => 'int16u',
-    },
-    0x11e => { #11
-        Name => 'WB_GLevel7500K',
-        Writable => 'int16u',
-    },
-    0x11f => { #11
-        Name => 'WB_GLevel',
-        Writable => 'int16u',
-    },
+    0x100 => { Name => 'WB_RBLevels',       Writable => 'int16u', Count => 2 }, #6
+    # 0x101 - in-camera AutoWB unless it is all 0's or all 256's (ref IB)
+    0x102 => { Name => 'WB_RBLevels3000K',  Writable => 'int16u', Count => 2 }, #11
+    0x103 => { Name => 'WB_RBLevels3300K',  Writable => 'int16u', Count => 2 }, #11
+    0x104 => { Name => 'WB_RBLevels3600K',  Writable => 'int16u', Count => 2 }, #11
+    0x105 => { Name => 'WB_RBLevels3900K',  Writable => 'int16u', Count => 2 }, #11
+    0x106 => { Name => 'WB_RBLevels4000K',  Writable => 'int16u', Count => 2 }, #11
+    0x107 => { Name => 'WB_RBLevels4300K',  Writable => 'int16u', Count => 2 }, #11
+    0x108 => { Name => 'WB_RBLevels4500K',  Writable => 'int16u', Count => 2 }, #11
+    0x109 => { Name => 'WB_RBLevels4800K',  Writable => 'int16u', Count => 2 }, #11
+    0x10a => { Name => 'WB_RBLevels5300K',  Writable => 'int16u', Count => 2 }, #11
+    0x10b => { Name => 'WB_RBLevels6000K',  Writable => 'int16u', Count => 2 }, #11
+    0x10c => { Name => 'WB_RBLevels6600K',  Writable => 'int16u', Count => 2 }, #11
+    0x10d => { Name => 'WB_RBLevels7500K',  Writable => 'int16u', Count => 2 }, #11
+    0x10e => { Name => 'WB_RBLevelsCWB1',   Writable => 'int16u', Count => 2 }, #11
+    0x10f => { Name => 'WB_RBLevelsCWB2',   Writable => 'int16u', Count => 2 }, #11
+    0x110 => { Name => 'WB_RBLevelsCWB3',   Writable => 'int16u', Count => 2 }, #11
+    0x111 => { Name => 'WB_RBLevelsCWB4',   Writable => 'int16u', Count => 2 }, #11
+    0x113 => { Name => 'WB_GLevel3000K',    Writable => 'int16u' }, #11
+    0x114 => { Name => 'WB_GLevel3300K',    Writable => 'int16u' }, #11
+    0x115 => { Name => 'WB_GLevel3600K',    Writable => 'int16u' }, #11
+    0x116 => { Name => 'WB_GLevel3900K',    Writable => 'int16u' }, #11
+    0x117 => { Name => 'WB_GLevel4000K',    Writable => 'int16u' }, #11
+    0x118 => { Name => 'WB_GLevel4300K',    Writable => 'int16u' }, #11
+    0x119 => { Name => 'WB_GLevel4500K',    Writable => 'int16u' }, #11
+    0x11a => { Name => 'WB_GLevel4800K',    Writable => 'int16u' }, #11
+    0x11b => { Name => 'WB_GLevel5300K',    Writable => 'int16u' }, #11
+    0x11c => { Name => 'WB_GLevel6000K',    Writable => 'int16u' }, #11
+    0x11d => { Name => 'WB_GLevel6600K',    Writable => 'int16u' }, #11
+    0x11e => { Name => 'WB_GLevel7500K',    Writable => 'int16u' }, #11
+    0x11f => { Name => 'WB_GLevel',         Writable => 'int16u' }, #11
+    # 0x121 = WB preset for flash (about 6000K) (ref IB)
+    # 0x125 = WB preset for underwater (ref IB)
     0x200 => { #6
         Name => 'ColorMatrix',
@@ -2414,56 +2855,37 @@
     # 0x0253-0x0255 are Adobe RGB color matrices
     # 0x0256-0x0258 are ProPhoto RGB color matrices
-    0x300 => { #11
-        Name => 'Enhancer',
-        Writable => 'int16u',
-    },
-    0x301 => { #11
-        Name => 'EnhancerValues',
-        Writable => 'int16u',
-        Count => 7,
-    },
-    0x310 => { #11
-        Name => 'CoringFilter',
-        Writable => 'int16u',
-    },
-    0x0311 => { #11
-        Name => 'CoringValues',
-        Writable => 'int16u',
-        Count => 7,
-    },
-    0x600 => { #11
-        Name => 'BlackLevel2',
-        Writable => 'int16u',
-        Count => 4,
-    },
-    0x610 => { #11
-        Name => 'GainBase',
-        Writable => 'int16u',
-    },
-    0x611 => { #4/6
-        Name => 'ValidBits',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x612 => { #11
-        Name => 'CropLeft',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x613 => { #11
-        Name => 'CropTop',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x614 => { #PH/11
-        Name => 'CropWidth',
-        Writable => 'int32u',
-    },
-    0x615 => { #PH/11
-        Name => 'CropHeight',
-        Writable => 'int32u',
+    0x300 => { Name => 'Enhancer',          Writable => 'int16u' }, #11
+    0x301 => { Name => 'EnhancerValues',    Writable => 'int16u', Count => 7 }, #11
+    0x310 => { Name => 'CoringFilter',      Writable => 'int16u' }, #11
+    0x311 => { Name => 'CoringValues',      Writable => 'int16u', Count => 7 }, #11
+    0x600 => { Name => 'BlackLevel2',       Writable => 'int16u', Count => 4 }, #11
+    0x610 => { Name => 'GainBase',          Writable => 'int16u' }, #11
+    0x611 => { Name => 'ValidBits',         Writable => 'int16u', Count => 2 }, #4/6
+    0x612 => { Name => 'CropLeft',          Writable => 'int16u', Count => 2 }, #11
+    0x613 => { Name => 'CropTop',           Writable => 'int16u', Count => 2 }, #11
+    0x614 => { Name => 'CropWidth',         Writable => 'int32u' }, #PH/11
+    0x615 => { Name => 'CropHeight',        Writable => 'int32u' }, #PH/11
+    0x635 => { #PH (data starts with "CMIO\x01\0")
+        Name => 'UnknownBlock1',
+        Writable => 'undef',
+        Notes => 'large unknown data block in ORF images but not JPG images',
+        # 'Drop' because too large for APP1 in JPEG images
+        Flags => [ 'Unknown', 'Binary', 'Drop' ],
+    },
+    0x636 => { #PH (data starts with "CMIO\x01\0")
+        Name => 'UnknownBlock2',
+        Writable => 'undef',
+        Notes => 'large unknown data block in ORF images but not JPG images',
+        # 'Drop' because too large for APP1 in JPEG images
+        Flags => [ 'Unknown', 'Binary', 'Drop' ],
     },
     # 0x800 LensDistortionParams, float[9] (ref 11)
     # 0x801 LensShadingParams, int16u[16] (ref 11)
+    0x0805 => { #IB
+        Name => 'SensorCalibration',
+        Notes => '2 numbers: 1. Recommended maximum, 2. Calibration midpoint',
+        Writable => 'int16s',
+        Count => 2,
+    },
     # 0x1010-0x1012 are the processing options used in camera or in
     # Olympus software, which 0x050a-0x050c are in-camera only (ref 6)
@@ -2472,4 +2894,5 @@
         Writable => 'int16u',
         PrintConv => {
+            0 => '(none)',
             BITMASK => {
                 0 => 'Noise Reduction',
@@ -2495,4 +2918,5 @@
         PrintConv => [{
             0 => 'Off',
+            1 => 'Live Composite', #github issue#61
             2 => 'On (2 frames)',
             3 => 'On (3 frames)',
@@ -2500,7 +2924,14 @@
     },
     0x1103 => { #PH
-        Name => 'UnknownBlock',
+        Name => 'UnknownBlock3',
         Writable => 'undef',
-        Notes => 'unknown 142kB block in ORF images, not copied to JPEG images',
+        Notes => 'large unknown data block in ORF images but not JPG images',
+        # 'Drop' because too large for APP1 in JPEG images
+        Flags => [ 'Unknown', 'Binary', 'Drop' ],
+    },
+    0x1104 => { #PH (overlaps data for 0x1103 in E-M5 ORF images)
+        Name => 'UnknownBlock4',
+        Writable => 'undef',
+        Notes => 'large unknown data block in ORF images but not JPG images',
         # 'Drop' because too large for APP1 in JPEG images
         Flags => [ 'Unknown', 'Binary', 'Drop' ],
@@ -2511,7 +2942,12 @@
         Count => 2,
         PrintConv => {
+            # '0 0' - have seen this with a 16:9 XZ-1 image - PH
             '1 1' => '4:3',
+            '1 4' => '1:1', #PH (E-P5 Storyboard effect, does this indicate 4:3 converted to 6:6?)
+            '2 1' => '3:2 (RAW)', #forum6285
             '2 2' => '3:2',
+            '3 1' => '16:9 (RAW)', #forum6285
             '3 3' => '16:9',
+            '4 1' => '1:1 (RAW)', #forum6285
             '4 4' => '6:6',
             '5 5' => '5:4',
@@ -2519,12 +2955,9 @@
             '7 7' => '6:5',
             '8 8' => '7:5',
+            '9 1' => '3:4 (RAW)', #forum6285
             '9 9' => '3:4',
         },
     },
-    0x1113 => { #11
-        Name => 'AspectFrame',
-        Writable => 'int16u',
-        Count => 4,
-    },
+    0x1113 => { Name => 'AspectFrame',  Writable => 'int16u', Count => 4 }, #11
     0x1200 => { #11/PH
         Name => 'FacesDetected',
@@ -2545,9 +2978,5 @@
         },
     },
-    0x1202 => { #PH
-        Name => 'MaxFaces',
-        Writable => 'int32u',
-        Count => 3,
-    },
+    0x1202 => { Name => 'MaxFaces',     Writable => 'int32u', Count => 3 }, #PH
     0x1203 => { #PH
         Name => 'FaceDetectFrameSize',
@@ -2561,4 +2990,37 @@
         Count => 12,
         Notes => 'X/Y offset and width/height of the cropped face detect frame',
+    },
+    0x1306 => { #PH (NC, E-M1)
+        Name => 'CameraTemperature',
+        Writable => 'int16u',
+        Format => 'int16s', #(NC)
+        ValueConv => '$val ? $val : undef', # zero for some models (how to differentiate from 0 C?)
+        Notes => 'this seems to be in degrees C only for some models',
+    },
+    0x1900 => { #23
+        Name => 'KeystoneCompensation',
+        Writable => 'int8u',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'Off',
+            '0 1' => 'On',
+        },
+    },
+    0x1901 => { #23
+        Name => 'KeystoneDirection',
+        Writable => 'int8u',
+        Count => 2,
+        PrintConv => {
+            0 => 'Vertical',
+            1 => 'Horizontal',
+        },
+    },
+    # 0x1905 - focal length (PH, E-M1)
+    0x1906 => { #23
+        Name => 'KeystoneValue',
+        Writable => 'int16s',
+        Count => 3,
+        # (use in conjunction with KeystoneDirection, -ve is Top or Right, +ve is Bottom or Left)
+        Notes => '3 numbers: 1. Keystone Value, 2. Min, 3. Max',
     },
 );
@@ -2582,8 +3044,5 @@
         Unknown => 1, #6
     },
-    0x210 => { #11
-        Name => 'SceneDetect',
-        Writable => 'int16u',
-    },
+    0x210 => { Name => 'SceneDetect',       Writable => 'int16u' }, #11
     0x211 => { #11
         Name => 'SceneArea',
@@ -2599,20 +3058,9 @@
         Unknown => 1, # (but what does it mean?)
     },
-    0x300 => { #6
-        Name => 'ZoomStepCount',
-        Writable => 'int16u',
-    },
-    0x301 => { #11
-        Name => 'FocusStepCount',
-        Writable => 'int16u',
-    },
-    0x303 => { #11
-        Name => 'FocusStepInfinity',
-        Writable => 'int16u',
-    },
-    0x304 => { #11
-        Name => 'FocusStepNear',
-        Writable => 'int16u',
-    },
+    # 0x214 - int16u: normally 0, but 1 for E-M1 focus-bracketing, and have seen 1 and 256 at other times
+    0x300 => { Name => 'ZoomStepCount',     Writable => 'int16u' }, #6
+    0x301 => { Name => 'FocusStepCount',    Writable => 'int16u' }, #11
+    0x303 => { Name => 'FocusStepInfinity', Writable => 'int16u' }, #11
+    0x304 => { Name => 'FocusStepNear',     Writable => 'int16u' }, #11
     0x305 => { #4
         Name => 'FocusDistance',
@@ -2649,4 +3097,5 @@
             ValueConv => '($val & 0x1f) . " " . ($val & 0xffe0)',
             ValueConvInv => 'my @v=split(" ",$val); @v == 2 ? $v[0] + $v[1] : $val',
+            PrintConvColumns => 2,
             PrintConv => [
                 {
@@ -2674,4 +3123,5 @@
                     0x15 => 'Bottom-center (vertical)',
                     0x16 => 'Bottom-right (vertical)',
+                    0x1f => 'n/a', #PH (NC, E-3)
                 },
                 {
@@ -2679,4 +3129,5 @@
                     0x40 => 'All Target',
                     0x80 => 'Dynamic Single Target',
+                    0xe0 => 'n/a', #PH (NC, E-3)
                 }
             ],
@@ -2716,12 +3167,8 @@
     ],
     # 0x31a Continuous AF parameters?
-    # 0x328 Related to AF (maybe Imager AF data?) (ref PH, E-PL1):
-    #  - offset 0x2a (int8u)  ImagerAFMode?  0=Manual, 1=Auto
-    #  - offset 0x30 (int16u) AFAreaXPosition
-    #  - offset 0x32 (int16u) AFAreaWidth (202)
-    #  - offset 0x34 (int16u) AFAreaYPosition
-    #  - offset 0x36 (int16u) AFAreaHeight (50)
-    #  (AF area positions above give the top-left coordinates of the AF area in the
-    #   AF frame. Increasing Y is downwards, and the AF frame size is about 1280x256)
+    0x328 => { #PH
+        Name => 'AFInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::AFInfo' },
+    },
     # 0x1200-0x1209 Flash information:
     0x1201 => { #6
@@ -2747,8 +3194,5 @@
         },
     },
-    0x1205 => { #11 (ref converts to mm using table)
-        Name => 'ExternalFlashZoom',
-        Writable => 'rational64u',
-    },
+    0x1205 => { Name => 'ExternalFlashZoom', Writable => 'rational64u' }, #11 (ref converts to mm using table)
     0x1208 => { #6
         Name => 'InternalFlash',
@@ -2774,12 +3218,47 @@
         },
     },
-    0x1500 => { #6
+    0x120a => { #PH
+        Name => 'MacroLED',
+        Writable => 'int16u',
+        PrintConv => \%offOn,
+    },
+    0x1500 => [{ #6
+        Name => 'SensorTemperature',
+        # (Stylus 1 stores values like "34 0 0")
+        Condition => '$$self{Model} =~ /E-(1|M5)\b/ || $count != 1',
+        Writable => 'int16s',
+        PrintConv => '$val=~s/ 0 0$//; "$val C"',
+        PrintConvInv => '$val=~s/ ?C$//; $val',
+    },{
         Name => 'SensorTemperature',
         Writable => 'int16s',
-        Notes => q{
-            approximately Celsius for E-1, unknown calibration for E-3/410/420/510, and
-            always zero for E-300/330/400/500, divide by 10 for E-P1?
-        },
-    },
+        RawConv => '($val and $val ne "-32768") ? $val : undef', # ignore 0 and -32768
+        # ValueConv => '-2*(($val/135)**2)+55', #11
+        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',
+        # data from test shots by Eric Sibert:
+        #    E-510           E-620
+        # Raw  Ambient    Raw  Ambient
+        # ---  -------    ---  -------
+        # 534    22.7     518    22.7
+        # 550    20.6     531    19.3
+        # 552    20.8     533    17.9
+        # 558    19.3     582    17.2
+        # 564    19.1     621    12.3
+        # 567    17.8     634     9.7
+        # 576    18.6     650     8.0
+        # 582    17.2     660     7.7
+        # 599    13.8     703     3.3
+        # 631    10.7     880   -20.6
+        # 642    12.4     880   -20.6
+        # 652     9.6     892   -24.4
+        # 692     5.2     892   -22.7
+        # 714     3.3
+        # 895   -19.8
+        # 895   -19.2
+        # 900   -21.7
+    }],
     0x1600 => { # ref http://fourthirdsphoto.com/vbb/showpost.php?p=107607&postcount=15
         Name => 'ImageStabilization',
@@ -2797,9 +3276,23 @@
 );
 
+# AF information (ref PH)
+%Image::ExifTool::Olympus::AFInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    # 0x2a - int8u:  ImagerAFMode?  0=Manual, 1=Auto
+    # 0x30 - int16u: AFAreaXPosition?
+    # 0x32 - int16u: AFAreaWidth? (202)
+    # 0x34 - int16u: AFAreaYPosition?
+    # 0x36 - int16u: AFAreaHeight? (50)
+    #  (AF area positions above give the top-left coordinates of the AF area in the
+    #   AF frame. Increasing Y is downwards, and the AF frame size is about 1280x256)
+);
+
 # Olympus raw information tags (ref 6)
 %Image::ExifTool::Olympus::RawInfo = (
     WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
-    NOTES => 'These tags are found only in ORF images of some models (ie. C8080WZ).',
+    NOTES => 'These tags are found only in ORF images of some models (eg. C8080WZ).',
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     0x000 => {
@@ -2809,59 +3302,15 @@
         Count => 4,
     },
-    0x100 => {
-        Name => 'WB_RBLevelsUsed',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x110 => {
-        Name => 'WB_RBLevelsAuto',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x120 => {
-        Name => 'WB_RBLevelsShade',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x121 => {
-        Name => 'WB_RBLevelsCloudy',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x122 => {
-        Name => 'WB_RBLevelsFineWeather',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x123 => {
-        Name => 'WB_RBLevelsTungsten',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x124 => {
-        Name => 'WB_RBLevelsEveningSunlight',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x130 => {
-        Name => 'WB_RBLevelsDaylightFluor',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x131 => {
-        Name => 'WB_RBLevelsDayWhiteFluor',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x132 => {
-        Name => 'WB_RBLevelsCoolWhiteFluor',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x133 => {
-        Name => 'WB_RBLevelsWhiteFluorescent',
-        Writable => 'int16u',
-        Count => 2,
-    },
+    0x100 => { Name => 'WB_RBLevelsUsed',           Writable => 'int16u', Count => 2 },
+    0x110 => { Name => 'WB_RBLevelsAuto',           Writable => 'int16u', Count => 2 },
+    0x120 => { Name => 'WB_RBLevelsShade',          Writable => 'int16u', Count => 2 },
+    0x121 => { Name => 'WB_RBLevelsCloudy',         Writable => 'int16u', Count => 2 },
+    0x122 => { Name => 'WB_RBLevelsFineWeather',    Writable => 'int16u', Count => 2 },
+    0x123 => { Name => 'WB_RBLevelsTungsten',       Writable => 'int16u', Count => 2 },
+    0x124 => { Name => 'WB_RBLevelsEveningSunlight',Writable => 'int16u', Count => 2 },
+    0x130 => { Name => 'WB_RBLevelsDaylightFluor',  Writable => 'int16u', Count => 2 },
+    0x131 => { Name => 'WB_RBLevelsDayWhiteFluor',  Writable => 'int16u', Count => 2 },
+    0x132 => { Name => 'WB_RBLevelsCoolWhiteFluor', Writable => 'int16u', Count => 2 },
+    0x133 => { Name => 'WB_RBLevelsWhiteFluorescent',Writable => 'int16u', Count => 2 },
     0x200 => {
         Name => 'ColorMatrix2',
@@ -2876,18 +3325,7 @@
     # 0x300 => sharpness-related
     # 0x301 => list of sharpness-related values
-    0x310 => {
-        Name => 'CoringFilter',
-        Writable => 'int16u',
-    },
-    0x311 => {
-        Name => 'CoringValues',
-        Writable => 'int16u',
-        Count => 11,
-    },
-    0x600 => {
-        Name => 'BlackLevel2',
-        Writable => 'int16u',
-        Count => 4,
-    },
+    0x310 => { Name => 'CoringFilter',      Writable => 'int16u' },
+    0x311 => { Name => 'CoringValues',      Writable => 'int16u', Count => 11 },
+    0x600 => { Name => 'BlackLevel2',       Writable => 'int16u', Count => 4 },
     0x601 => {
         Name => 'YCbCrCoefficients',
@@ -2895,25 +3333,9 @@
         Format => 'rational32u',
     },
-    0x611 => {
-        Name => 'ValidPixelDepth',
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0x612 => { #11
-        Name => 'CropLeft',
-        Writable => 'int16u',
-    },
-    0x613 => { #11
-        Name => 'CropTop',
-        Writable => 'int16u',
-    },
-    0x614 => {
-        Name => 'CropWidth',
-        Writable => 'int32u',
-    },
-    0x615 => {
-        Name => 'CropHeight',
-        Writable => 'int32u',
-    },
+    0x611 => { Name => 'ValidPixelDepth',   Writable => 'int16u', Count => 2 },
+    0x612 => { Name => 'CropLeft',          Writable => 'int16u' }, #11
+    0x613 => { Name => 'CropTop',           Writable => 'int16u' }, #11
+    0x614 => { Name => 'CropWidth',         Writable => 'int32u' },
+    0x615 => { Name => 'CropHeight',        Writable => 'int32u' },
     0x1000 => {
         Name => 'LightSource',
@@ -2935,67 +3357,18 @@
     },
     # the following 5 tags all have 3 values: val, min, max
-    0x1001 => {
-        Name => 'WhiteBalanceComp',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x1010 => {
-        Name => 'SaturationSetting',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x1011 => {
-        Name => 'HueSetting',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x1012 => {
-        Name => 'ContrastSetting',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x1013 => {
-        Name => 'SharpnessSetting',
-        Writable => 'int16s',
-        Count => 3,
-    },
+    0x1001 => { Name => 'WhiteBalanceComp',         Writable => 'int16s', Count => 3 },
+    0x1010 => { Name => 'SaturationSetting',        Writable => 'int16s', Count => 3 },
+    0x1011 => { Name => 'HueSetting',               Writable => 'int16s', Count => 3 },
+    0x1012 => { Name => 'ContrastSetting',          Writable => 'int16s', Count => 3 },
+    0x1013 => { Name => 'SharpnessSetting',         Writable => 'int16s', Count => 3 },
     # settings written by Camedia Master 4.x
-    0x2000 => {
-        Name => 'CMExposureCompensation',
-        Writable => 'rational64s',
-    },
-    0x2001 => {
-        Name => 'CMWhiteBalance',
-        Writable => 'int16u',
-    },
-    0x2002 => {
-        Name => 'CMWhiteBalanceComp',
-        Writable => 'int16s',
-    },
-    0x2010 => {
-        Name => 'CMWhiteBalanceGrayPoint',
-        Writable => 'int16u',
-        Count => 3,
-    },
-    0x2020 => {
-        Name => 'CMSaturation',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x2021 => {
-        Name => 'CMHue',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x2022 => {
-        Name => 'CMContrast',
-        Writable => 'int16s',
-        Count => 3,
-    },
-    0x2023 => {
-        Name => 'CMSharpness',
-        Writable => 'int16s',
-        Count => 3,
-    },
+    0x2000 => { Name => 'CMExposureCompensation',   Writable => 'rational64s' },
+    0x2001 => { Name => 'CMWhiteBalance',           Writable => 'int16u' },
+    0x2002 => { Name => 'CMWhiteBalanceComp',       Writable => 'int16s' },
+    0x2010 => { Name => 'CMWhiteBalanceGrayPoint',  Writable => 'int16u', Count => 3 },
+    0x2020 => { Name => 'CMSaturation',             Writable => 'int16s', Count => 3 },
+    0x2021 => { Name => 'CMHue',                    Writable => 'int16s', Count => 3 },
+    0x2022 => { Name => 'CMContrast',               Writable => 'int16s', Count => 3 },
+    0x2023 => { Name => 'CMSharpness',              Writable => 'int16s', Count => 3 },
 );
 
@@ -3038,5 +3411,8 @@
     0x18 => {
         Name => 'Model',
+        Description => 'Camera Model Name',
         Format => 'string[8]',
+        SeparateTable => 'CameraType',
+        PrintConv => \%olympusCameraTypes,
     },
     # (01 00 at offset 0x20)
@@ -3045,5 +3421,5 @@
         Unknown => 1,
         Format => 'int32u',
-        # this conversion doesn't work for all models (ie. gives "1/100000")
+        # this conversion doesn't work for all models (eg. gives "1/100000")
         ValueConv => '$val ? 10 / $val : 0',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
@@ -3084,5 +3460,7 @@
     0x18 => {
         Name => 'Model',
+        Description => 'Camera Model Name',
         Format => 'string[24]',
+        Notes => 'the actual model name, no decoding necessary',
     },
     # (01 00 at offset 0x30)
@@ -3129,5 +3507,18 @@
     0x18 => {
         Name => 'Model',
+        Description => 'Camera Model Name',
         Format => 'string[24]',
+        Notes => 'oddly different than CameraType values in JPEG images by the same camera',
+        PrintConv => {
+            SG472 => 'u7040,S7040',
+            SG473 => 'u9010,S9010',
+            SG475 => 'SP800UZ',
+            SG551 => 'SZ-30MR',
+            SG553 => 'SP-610UZ',
+            SG554 => 'SZ-10',
+            SG555 => 'SZ-20',
+            SG573 => 'SZ-14',
+            SG575 => 'SP-620UZ',
+        },
     },
     0x28 => {
@@ -3141,8 +3532,236 @@
         PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
     },
-    # NEED MORE SAMPLES TO DECODE THIS
+    # 0x38 - int32u: 3
+    # 0x3c - int32u: 1
+    # 0x40 - int16u: 5
+    # 0x42 - int16u: 0,4,9
+    # 0x64 - int32u: 0,6000,12000
+    # 0x48 - int32u: 100 (ISO?)
+    0x68 => {
+        Name => 'MovableInfo',
+        Condition => '$$valPt =~ /^DIGI/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::MovableInfo' },
+    },
+    0x72 => {
+        Name => 'MovableInfo',
+        Condition => '$$valPt =~ /^DIGI/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::MovableInfo' },
+    },
 );
 
+# yet a different QuickTime TAGS format (PH, E-M5)
+%Image::ExifTool::Olympus::MOV3 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'QuickTime information found in the TAGS atom of MOV videos from the E-M5.',
+    OLYM => {
+        Name => 'OlympusAtom',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::OLYM2' },
+    },
+);
+
+# yet a different QuickTime OLYM atom format (PH, E-M5)
+%Image::ExifTool::Olympus::OLYM2 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    prms => {
+        Name => 'MakerNotes',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::prms' },
+    },
+    thmb =>{
+        Name => 'ThumbInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::thmb2' },
+    },
+    scrn =>{
+        Name => 'PreviewInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::scrn2' },
+    },
+);
+
+# the "prms" atom in E-M5 MOV videos (PH, E-M5)
+%Image::ExifTool::Olympus::prms = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        Information extracted from the "prms" atom in MOV videos from Olympus models
+        such as the OM E-M5.
+    },
+    0x12 => {
+        Name => 'Make',
+        Format => 'string[24]',
+    },
+    0x2c => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[24]',
+        SeparateTable => 'CameraType',
+        PrintConv => \%olympusCameraTypes,
+    },
+    0x83 => {
+        Name => 'DateTime1',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+    },
+    0x9d => {
+        Name => 'DateTime2',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+    },
+);
+
+# yet a different "thmb" atom format (PH, E-M5)
+%Image::ExifTool::Olympus::thmb2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'ThumbnailWidth',
+        Format => 'int16u',
+    },
+    2 => {
+        Name => 'ThumbnailHeight',
+        Format => 'int16u',
+    },
+    4 => {
+        Name => 'ThumbnailLength',
+        Format => 'int32u',
+    },
+    8 => {
+        Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{4}]',
+        Notes => '160x120 JPEG thumbnail image',
+        RawConv => '$self->ValidateImage(\$val,$tag)',
+    },
+);
+
+# yet a different "scrn" atom format (PH, E-M5)
+%Image::ExifTool::Olympus::scrn2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    # 0 => int16u: 1 - number of preview images?
+    2 => {
+        Name => 'OlympusPreview',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::scrn' },
+    },
+);
+
+# movable information found in MP4 videos
+%Image::ExifTool::Olympus::MovableInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    0x04 => { #(NC)
+        Name => 'ISO',
+        Format => 'int32u',
+    },
+    0x2c => {
+        Name => 'EncoderVersion',
+        Format => 'string[16]',
+    },
+    0x3c => {
+        Name => 'DecoderVersion',
+        Format => 'string[16]',
+    },
+    0x83 => {
+        Name => 'Thumbnail',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::Thumbnail',
+            Base => '$start', # (use a separate table because of this)
+        },
+    },
+);
+
+# thumbnail image information found in MP4 videos (similar in Olympus,Samsung,Sanyo) (ref PH)
+%Image::ExifTool::Olympus::Thumbnail = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    1 => 'ThumbnailWidth',
+    2 => 'ThumbnailHeight',
+    3 => 'ThumbnailLength',
+    4 => { Name => 'ThumbnailOffset', IsOffset => 1 },
+);
+
+# thumbnail information found in 'thmb' atom of MP4 videos from the TG-810 (ref PH)
+%Image::ExifTool::Olympus::thmb = (
+    NOTES => 'Information extracted from the "thmb" atom of Olympus MP4 videos.',
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'ThumbnailLength',
+        Format => 'int32u',
+    },
+    4 => {
+        Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{0}]',
+        Notes => '160x120 JPEG thumbnail image',
+        RawConv => '$self->ValidateImage(\$val,$tag)',
+    },
+);
+
+# thumbnail information found in 'scrn' atom of MP4 videos from the TG-810 (ref PH)
+%Image::ExifTool::Olympus::scrn = (
+    NOTES => 'Information extracted from the "scrn" atom of Olympus MP4 videos.',
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'PreviewImageLength',
+        Format => 'int32u',
+    },
+    4 => {
+        Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{0}]',
+        Notes => '640x480 JPEG preview image',
+        RawConv => '$self->ValidateImage(\$val,$tag)',
+    },
+);
+
+# information in OLYM atom of MP4 videos from the TG-810 (ref PH)
+%Image::ExifTool::Olympus::OLYM = (
+    NOTES => 'Tags found in the OLYM atom of MP4 videos from the TG-810.',
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0e => {
+        Name => 'Make',
+        Format => 'string[26]',
+    },
+    0x28 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[24]',
+        SeparateTable => 'CameraType',
+        PrintConv => \%olympusCameraTypes,
+    },
+    0x5a => {
+        Name => 'FNumber',
+        Format => 'rational64u',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x7f => {
+        Name => 'DateTimeOriginal', #(NC)
+        Description => 'Date/Time Original',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    0x99 => {
+        Name => 'DateTime2',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+    },
+    0x109 => {
+        Name => 'ThumbnailWidth',
+        Format => 'int16u',
+    },
+    0x10b => {
+        Name => 'ThumbnailHeight',
+        Format => 'int16u',
+    },
+);
+
 # tags in Olympus AVI videos (ref PH)
+# (very similar to Pentax::Junk2 tags)
 %Image::ExifTool::Olympus::AVI = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
@@ -3155,6 +3774,9 @@
     },
     0x2c => {
-        Name => 'ModelType',
+        Name => 'Model',
+        Description => 'Camera Model Name',
         Format => 'string[24]',
+        SeparateTable => 'CameraType',
+        PrintConv => \%olympusCameraTypes,
     },
     0x5e => {
@@ -3173,13 +3795,7 @@
         Groups => { 2 => 'Time' },
     },
-    0x12d => {
-        Name => 'ThumbnailLength',
-        Format => 'int32u',
-    },
-    0x131 => {
-        Name => 'ThumbnailImage',
-        Format => 'undef[$val{0x12d}]',
-        Notes => '160x120 JPEG thumbnail image',
-        RawConv => '$self->ValidateImage(\$val,$tag)',
+    0x129 => {
+        Name => 'ThumbInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::thmb2' },
     },
 );
@@ -3196,4 +3812,5 @@
     0x0c => {
         Name => 'Model',
+        Description => 'Camera Model Name',
         Format => 'string[16]',
     },
@@ -3257,4 +3874,44 @@
 );
 
+# DSS information written by Olympus voice recorders (ref PH)
+%Image::ExifTool::Olympus::DSS = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Audio' },
+    FIRST_ENTRY => 0,
+    NOTES => q{
+        Information extracted from DSS/DS2 files and the ID3 XOLY frame of MP3 files
+        written by some Olympus voice recorders.
+    },
+    # 0 - file format:
+    #   "\x02dss"(DSS file and XOLY frame in MP3 file)
+    #   "\x03ds2"(DS2 file)
+    #   "\x03mp3"(ID3 XOLY frame in MP3 file)
+    12 => { Name => 'Model', Format => 'string[16]' }, # (name truncated by some models)
+    38 => {
+        Name => 'StartTime',
+        Format => 'string[12]',
+        Groups => { 2 => 'Time' },
+        ValueConv => '$val =~ s/(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/20$1:$2:$3 $4:$5:$6/; $val',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    50 => {
+        Name => 'EndTime',
+        Format => 'string[12]',
+        Groups => { 2 => 'Time' },
+        ValueConv => '$val =~ s/(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/20$1:$2:$3 $4:$5:$6/; $val',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    62 => {
+        Name => 'Duration',
+        Format => 'string[6]',
+        ValueConv => '$val =~ /(\d{2})(\d{2})(\d{2})/ ? ($1 * 60 + $2) * 60 + $3 : undef',
+        PrintConv => 'ConvertDuration($val)',
+    },
+    798 => { # (ref http://search.cpan.org/~rgibson/Audio-DSS-0.02/)
+        Name => 'Comment',
+        Format => 'string[100]',
+    },
+);
+
 # Olympus composite tags
 %Image::ExifTool::Olympus::Composite = (
@@ -3279,9 +3936,24 @@
     },
     ZoomedPreviewImage => {
+        Groups => { 2 => 'Preview' },
         Require => {
             0 => 'ZoomedPreviewStart',
             1 => 'ZoomedPreviewLength',
         },
-        RawConv => 'Image::ExifTool::Exif::ExtractImage($self,$val[0],$val[1],"ZoomedPreviewImage")',
+        RawConv => q{
+            @grps = $self->GetGroup($$val{0});  # set groups from input tag
+            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,
     },
 );
@@ -3304,13 +3976,13 @@
     my @info = split ' ', $extender;
     # validate that extender identifier is reasonable
-    return 0 unless @info >= 2 and $info[1];
-    # if it's not an EC-14 (id 0 4) then assume it was really attached
+    return 0 unless @info >= 2 and hex($info[1]);
+    # if it's not an EC-14 (id '0 04') then assume it was really attached
     # (other extenders don't seem to affect the reported max aperture)
-    return 1 if "$info[0] $info[1]" ne '0 4';
+    return 1 if "$info[0] $info[1]" ne '0 04';
     # get the maximum aperture for this lens (in $1)
-    $lensType =~ / F(\d+(.\d+)?)/ or return 1;
+    $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);
 }
 
@@ -3344,4 +4016,25 @@
 
 #------------------------------------------------------------------------------
+# Extract information from a DSS/DS2 voice recorder audio file or ID3 XOLY frame
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success
+sub ProcessDSS($$;$)
+{
+    my ($et, $dirInfo) = @_;
+
+    # allow this to be called with either RAF or DataPt
+    my $raf = $$dirInfo{RAF};
+    if ($raf) {
+        my $buff;
+        $raf->Read($buff, 898) > 68 or return 0;
+        $buff =~ /^(\x02dss|\x03ds2)/ or return 0;
+        $dirInfo = { DataPt => \$buff };
+        $et->SetFileType(uc substr $buff, 1, 3);
+    }
+    my $tagTablePtr = GetTagTable('Image::ExifTool::Olympus::DSS');
+    return $et->ProcessBinaryData($dirInfo, $tagTablePtr);
+}
+
+#------------------------------------------------------------------------------
 # Process ORF file
 # Inputs: 0) ExifTool object reference, 1) directory information reference
@@ -3349,6 +4042,6 @@
 sub ProcessORF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
-    return $exifTool->ProcessTIFF($dirInfo);
+    my ($et, $dirInfo) = @_;
+    return $et->ProcessTIFF($dirInfo);
 }
 
@@ -3372,5 +4065,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/OpenEXR.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/OpenEXR.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/OpenEXR.pm	(revision 34921)
@@ -0,0 +1,324 @@
+#------------------------------------------------------------------------------
+# File:         OpenEXR.pm
+#
+# Description:  Read OpenEXR meta information
+#
+# Revisions:    2011/12/10 - P. Harvey Created
+#
+# References:   1) http://www.openexr.com/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::OpenEXR;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::GPS;
+
+$VERSION = '1.02';
+
+# supported EXR value format types (other types are extracted as undef binary data)
+my %formatType = (
+    box2f          => 'float[4]',
+    box2i          => 'int32s[4]',
+    chlist         => 1,
+    chromaticities => 'float[8]',
+    compression    => 'int8u',
+    double         => 'double',
+    envmap         => 'int8u',
+    float          => 'float',
+   'int'           => 'int32s',
+    keycode        => 'int32s[7]',
+    lineOrder      => 'int8u',
+    m33f           => 'float[9]',
+    m44f           => 'float[16]',
+    rational       => 'rational64s',
+    string         => 'string', # incorrect in specification! (no leading int)
+    stringvector   => 1,
+    tiledesc       => 1,
+    timecode       => 'int32u[2]',
+    v2f            => 'float[2]',
+    v2i            => 'int32s[2]',
+    v3f            => 'float[3]',
+    v3i            => 'int32s[3]',
+);
+
+# OpenEXR tags
+%Image::ExifTool::OpenEXR::Main = (
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+        Information extracted from EXR images.  See L<http://www.openexr.com/> for
+        the official specification.
+    },
+    _ver => { Name => 'EXRVersion' },
+    _lay => {
+        Name => 'Layout',
+        PrintHex => 1,
+        PrintConv => { 0 => 'Scan Lines', 0x200 => 'Tiles' },
+    },
+    adoptedNeutral      => { },
+    altitude => {
+        Name => 'GPSAltitude',
+        Groups => { 2 => 'Location' },
+        PrintConv => q{
+            $val = int($val * 10) / 10;
+            return(($val =~ s/^-// ? "$val m Below" : "$val m Above") . " Sea Level");
+        },
+    },
+    aperture            => { PrintConv => 'sprintf("%.1f",$val)' },
+    channels            => { },
+    chromaticities      => { },
+    capDate => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    comments            => { },
+    compression => {
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'None',
+            1 => 'RLE',
+            2 => 'ZIPS',
+            3 => 'ZIP',
+            4 => 'PIZ',
+            5 => 'PXR24',
+            6 => 'B44',
+            7 => 'B44A',
+        },
+    },
+    dataWindow          => { },
+    displayWindow       => { },
+    envmap => {
+        Name => 'EnvironmentMap',
+        PrintConv => {
+            0 => 'Latitude/Longitude',
+            1 => 'Cube',
+        },
+    },
+    expTime => {
+        Name => 'ExposureTime',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    focus => {
+        Name => 'FocusDistance',
+        PrintConv => '"$val m"',
+    },
+    framesPerSecond     => { },
+    keyCode             => { },
+    isoSpeed            => { Name => 'ISO' },
+    latitude => {
+        Name => 'GPSLatitude',
+        Groups => { 2 => 'Location' },
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    },
+    lineOrder => {
+        PrintConv => {
+            0 => 'Increasing Y',
+            1 => 'Decreasing Y',
+            2 => 'Random Y',
+        },
+    },
+    longitude => {
+        Name => 'GPSLongitude',
+        Groups => { 2 => 'Location' },
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    },
+    lookModTransform    => { },
+    multiView           => { },
+    owner               => { Groups => { 2 => 'Author' } },
+    pixelAspectRatio    => { },
+    preview             => { },
+    renderingTransform  => { },
+    screenWindowCenter  => { },
+    screenWindowWidth   => { },
+    tiles               => { },
+    timeCode            => { },
+    utcOffset => {
+        Name => 'TimeZone',
+        Groups => { 2 => 'Time' },
+        PrintConv => 'TimeZoneString($val / 60)',
+    },
+    whiteLuminance      => { },
+    worldToCamera       => { },
+    worldToNDC          => { },
+    wrapmodes           => { Name => 'WrapModes' },
+    xDensity            => { Name => 'XResolution' },
+    # also observed:
+    # ilut
+);
+
+#------------------------------------------------------------------------------
+# Extract information from an OpenEXR file
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid OpenEXR file
+sub ProcessEXR($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $verbose = $et->Options('Verbose');
+    my $binary = $et->Options('Binary') || $verbose;
+    my ($buff, $dim);
+
+    # verify this is a valid RIFF file
+    return 0 unless $raf->Read($buff, 8) == 8;
+    return 0 unless $buff =~ /^\x76\x2f\x31\x01/s;
+    $et->SetFileType();
+    SetByteOrder('II');
+    my $tagTablePtr = GetTagTable('Image::ExifTool::OpenEXR::Main');
+
+    # extract information from header
+    my $ver = unpack('x4V', $buff);
+    $et->HandleTag($tagTablePtr, '_ver', $ver & 0xff);
+    $et->HandleTag($tagTablePtr, '_lay', $ver & 0x200);
+
+    # extract attributes
+    for (;;) {
+        $raf->Read($buff, 68) or last;
+        last if $buff =~ /^\0/;
+        unless ($buff =~ /^([^\0]{1,31})\0([^\0]{1,31})\0(.{4})/sg) {
+            $et->Warn('EXR format error');
+            last;
+        }
+        my ($tag, $type, $size) = ($1, $2, unpack('V', $3));
+        unless ($raf->Seek(pos($buff) - length($buff), 1)) {
+            $et->Warn('Seek error');
+            last;
+        }
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        unless ($tagInfo) {
+            my $name = ucfirst $tag;
+            $name =~ tr/-_a-zA-Z0-9//dc;
+            if (length $name <= 1) {
+                if (length $name) {
+                    $name = "Tag$name";
+                } else {
+                    $name = 'Invalid';
+                }
+            }
+            $tagInfo = { Name => $name };
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            $et->VPrint(0, $$et{INDENT}, "[adding $tag]\n");
+        }
+        my ($val, $success);
+        my $format = $formatType{$type};
+        if ($format or $binary) {
+            $raf->Read($buff, $size) == $size and $success = 1;
+            if (not $format) {
+                $val = \$buff;  # treat as undef binary data
+            } elsif ($format ne '1') {
+                # handle formats which map nicely into ExifTool format codes
+                if ($format =~ /^(\w+)\[?(\d*)/) {
+                    my ($fmt, $cnt) = ($1, $2);
+                    $cnt = $fmt eq 'string' ? $size : 1 unless $cnt;
+                    $val = ReadValue(\$buff, 0, $fmt, $cnt, $size);
+                }
+            # handle other format types
+            } elsif ($type eq 'tiledesc') {
+                if ($size >= 9) {
+                    my $x = Get32u(\$buff, 0);
+                    my $y = Get32u(\$buff, 4);
+                    my $mode = Get8u(\$buff, 8);
+                    my $lvl = { 0 => 'One Level', 1 => 'MIMAP Levels', 2 => 'RIPMAP Levels' }->{$mode & 0x0f};
+                    $lvl or $lvl = 'Unknown Levels (' . ($mode & 0xf) . ')';
+                    my $rnd = { 0 => 'Round Down', 1 => 'Round Up' }->{$mode >> 4};
+                    $rnd or $rnd = 'Unknown Rounding (' . ($mode >> 4) . ')';
+                    $val = "${x}x$y; $lvl; $rnd";
+                }
+            } elsif ($type eq 'chlist') {
+                $val = [ ];
+                while ($buff =~ /\G([^\0]{1,31})\0(.{16})/sg) {
+                    my ($str, $dat) = ($1, $2);
+                    my ($pix,$lin,$x,$y) = unpack('VCx3VV', $dat);
+                    $pix = { 0 => 'int8u', 1 => 'half', 2 => 'float' }->{$pix} || "unknown($pix)";
+                    push @$val, "$str $pix" . ($lin ? ' linear' : '') . " $x $y";
+                }
+            } elsif ($type eq 'stringvector') {
+                $val = [ ];
+                my $pos = 0;
+                while ($pos + 4 <= length($buff)) {
+                    my $len = Get32u(\$buff, $pos);
+                    last if $pos + 4 + $len > length($buff);
+                    push @$val, substr($buff, $pos + 4, $len);
+                    $pos += 4 + $len;
+                }
+            } else {
+                $val = \$buff;  # (shouldn't happen)
+            }
+        } else {
+            # avoid loading binary data
+            $val = \ "Binary data $size bytes";
+            $success = $raf->Seek($size, 1);
+        }
+        unless ($success) {
+            $et->Warn('Truncated or corrupted EXR file');
+            last;
+        }
+        $val = '<bad>' unless defined $val;
+
+        # take image dimensions from dataWindow (with displayWindow as backup)
+        if (($tag eq 'dataWindow' or (not $dim and $tag eq 'displayWindow')) and
+            $val =~ /^(-?\d+) (-?\d+) (-?\d+) (-?\d+)$/)
+        {
+            $dim = [$3 - $1 + 1, $4 - $2 + 1];
+        }
+        if ($verbose) {
+            my $dataPt = ref $val ? $val : \$val,
+            $et->VerboseInfo($tag, $tagInfo,
+                Table   => $tagTablePtr,
+                Value   => $val,
+                Size    => $size,
+                Format  => $type,
+                DataPt  => \$buff,
+                Addr    => $raf->Tell() - $size,
+            );
+        }
+        $et->FoundTag($tagInfo, $val);
+    }
+    if ($dim) {
+        $et->FoundTag('ImageWidth', $$dim[0]);
+        $et->FoundTag('ImageHeight', $$dim[1]);
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::OpenEXR - Read OpenEXR 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 OpenEXR images.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.openexr.com/documentation.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/OpenEXR Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Opus.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Opus.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Opus.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PCX.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PCX.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PCX.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PDF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PDF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PDF.pm	(revision 34921)
@@ -22,5 +22,5 @@
 require Exporter;
 
-$VERSION = '1.29';
+$VERSION = '1.51';
 
 sub FetchObject($$$$);
@@ -28,9 +28,11 @@
 sub ReadToNested($;$);
 sub ProcessDict($$$$;$$);
+sub ProcessAcroForm($$$$;$$);
+sub ExpandArray($);
 sub ReadPDFValue($);
 sub CheckPDF($$$);
 
 # $lastFetched - last fetched object reference (used for decryption)
-#                (undefined if fetched object was already decrypted, ie. object from stream)
+#                (undefined if fetched object was already decrypted, eg. object from stream)
 
 my $cryptInfo;      # encryption object reference (plus additional information)
@@ -42,4 +44,20 @@
 my $pdfVer;         # version of PDF file being processed
 
+# filters supported in DecodeStream()
+my %supportedFilter = (
+    '/FlateDecode' => 1,
+    '/Crypt' => 1,
+    '/Identity' => 1,  # (not filtered)
+    '/DCTDecode' => 1, # (JPEG image - not filtered)
+    '/JPXDecode' => 1, # (Jpeg2000 image - not filtered)
+    '/LZWDecode' => 1, # (usually a bitmapped image)
+    '/ASCIIHexDecode' => 1,
+    '/ASCII85Decode' => 1,
+    # other standard filters that we currently don't support
+    #'/JBIG2Decode' => 0, # (JBIG2 image format not supported)
+    #'/CCITTFaxDecode' => 0,
+    #'/RunLengthDecode' => 0,
+);
+
 # tags in main PDF directories
 %Image::ExifTool::PDF::Main = (
@@ -48,4 +66,9 @@
     Info => {
         SubDirectory => { TagTable => 'Image::ExifTool::PDF::Info' },
+        # Adobe Acrobat 10.1.5 will create a duplicate Info dictionary with
+        # a different object number when metadata is edited.  This flag
+        # is part of a patch to ignore this duplicate information (unless
+        # the IgnoreMinorErrors option is used)
+        IgnoreDuplicates => 1,
     },
     Root => {
@@ -63,5 +86,5 @@
 );
 
-# tags in PDF Info directory
+# tags in PDF Info dictionary
 %Image::ExifTool::PDF::Info = (
     GROUPS => { 2 => 'Document' },
@@ -71,4 +94,8 @@
     CHECK_PROC => \&CheckPDF,
     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 incremental update)
+    PRIORITY => 0,
     NOTES => q{
         As well as the tags listed below, the PDF specification allows for
@@ -135,4 +162,7 @@
     Perms => {
         SubDirectory => { TagTable => 'Image::ExifTool::PDF::Perms' },
+    },
+    AcroForm => {
+        SubDirectory => { TagTable => 'Image::ExifTool::PDF::AcroForm' },
     },
     Lang       => 'Language',
@@ -170,5 +200,5 @@
 );
 
-# tags in PDF Pages directory
+# tags in PDF Pages dictionary
 %Image::ExifTool::PDF::Pages = (
     GROUPS => { 2 => 'Document' },
@@ -179,5 +209,5 @@
 );
 
-# tags in PDF Perms directory
+# tags in PDF Perms dictionary
 %Image::ExifTool::PDF::Perms = (
     NOTES => 'Additional document permissions imposed by digital signatures.',
@@ -193,5 +223,18 @@
 );
 
-# tags in PDF Kids directory
+# tags in PDF Perms dictionary
+%Image::ExifTool::PDF::AcroForm = (
+    PROCESS_PROC => \&ProcessAcroForm,
+    _has_xfa => {
+        Name => 'HasXFA',
+        Notes => q{
+            this tag is defined if a document contains form fields, and is true if it
+            uses XML Forms Architecture; not a real Tag ID
+        },
+        PrintConv => { 'true' => 'Yes', 'false' => 'No' },
+    },
+);
+
+# tags in PDF Kids dictionary
 %Image::ExifTool::PDF::Kids = (
     Metadata => {
@@ -204,21 +247,43 @@
         SubDirectory => { TagTable => 'Image::ExifTool::PDF::Resources' },
     },
-);
-
-# tags in PDF Resources directory
+    Kids => {
+        Condition => '$self->Options("ExtractEmbedded")',
+        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Kids' },
+    },
+);
+
+# tags in PDF Resources dictionary
 %Image::ExifTool::PDF::Resources = (
     ColorSpace => {
         SubDirectory => { TagTable => 'Image::ExifTool::PDF::ColorSpace' },
     },
-);
-
-# tags in PDF ColorSpace directory
+    XObject => {
+        Condition => '$self->Options("ExtractEmbedded")',
+        SubDirectory => { TagTable => 'Image::ExifTool::PDF::XObject' },
+    },
+    Properties => {
+        Condition => '$self->Options("ExtractEmbedded")',
+        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Properties' },
+    },
+);
+
+# tags in PDF ColorSpace dictionary
 %Image::ExifTool::PDF::ColorSpace = (
     DefaultRGB => {
         SubDirectory => { TagTable => 'Image::ExifTool::PDF::DefaultRGB' },
-    },
-);
-
-# tags in PDF DefaultRGB directory
+        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' },
+    },
+);
+
+# tags in PDF DefaultRGB dictionary
 %Image::ExifTool::PDF::DefaultRGB = (
     ICCBased => {
@@ -227,5 +292,12 @@
 );
 
-# tags in PDF ICCBased directory
+# tags in PDF Cs1 dictionary
+%Image::ExifTool::PDF::Cs1 = (
+    _stream => {
+        SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
+    },
+);
+
+# tags in PDF ICCBased dictionary
 %Image::ExifTool::PDF::ICCBased = (
     _stream => {
@@ -234,5 +306,58 @@
 );
 
-# tags in PDF PieceInfo directory
+# tags in PDF XObject dictionary (parsed only if ExtractEmbedded is enabled)
+%Image::ExifTool::PDF::XObject = (
+    EXTRACT_UNKNOWN => 0,   # extract known but numbered tags (Im1, Im2, etc)
+    Im => {
+        Notes => q{
+            the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option enables information to be extracted from these
+            embedded images
+        },
+        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Im' },
+    },
+);
+
+# tags in PDF Im# dictionary
+%Image::ExifTool::PDF::Im = (
+    NOTES => q{
+        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.
+    },
+    Width => 'EmbeddedImageWidth',
+    Height => 'EmbeddedImageHeight',
+    Filter => { Name => 'EmbeddedImageFilter', List => 1 },
+    ColorSpace => {
+        Name => 'EmbeddedImageColorSpace',
+        List => 1,
+        RawConv => 'ref $val ? undef : $val', # (ignore color space data)
+    },
+    Image_stream => {
+        Name => 'EmbeddedImage',
+        Groups => { 2 => 'Preview' },
+        Binary => 1,
+    },
+);
+
+# tags in PDF Properties dictionary
+%Image::ExifTool::PDF::Properties = (
+    EXTRACT_UNKNOWN => 0,   # extract known but numbered tags (MC0, MC1, etc)
+    MC => {
+        Notes => q{
+            the L<ExtractEmbedded|../ExifTool.html#ExtractEmbedded> option enables information to be extracted from these
+            embedded metadata dictionaries
+        },
+        SubDirectory => { TagTable => 'Image::ExifTool::PDF::MC' },
+    }
+);
+
+# tags in PDF MC# dictionary
+%Image::ExifTool::PDF::MC = (
+    Metadata => {
+        SubDirectory => { TagTable => 'Image::ExifTool::PDF::Metadata' },
+    }
+);
+
+# tags in PDF PieceInfo dictionary
 %Image::ExifTool::PDF::PieceInfo = (
     AdobePhotoshop => {
@@ -250,5 +375,5 @@
 );
 
-# tags in PDF AdobePhotoshop directory
+# tags in PDF AdobePhotoshop dictionary
 %Image::ExifTool::PDF::AdobePhotoshop = (
     Private => {
@@ -257,5 +382,5 @@
 );
 
-# tags in PDF Illustrator directory
+# tags in PDF Illustrator dictionary
 %Image::ExifTool::PDF::Illustrator = (
     Private => {
@@ -264,5 +389,5 @@
 );
 
-# tags in PDF Private directory
+# tags in PDF Private dictionary
 %Image::ExifTool::PDF::Private = (
     ImageResources => {
@@ -271,5 +396,5 @@
 );
 
-# tags in PDF AI Private directory
+# tags in PDF AI Private dictionary
 %Image::ExifTool::PDF::AIPrivate = (
     GROUPS => { 2 => 'Document' },
@@ -280,7 +405,12 @@
     AIPrivateData => {
         Notes => q{
-            the ExtractEmbedded option enables information to be extracted from embedded
-            PostScript documents in the AIPrivateData stream
+            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
+        SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main' },
+    },
+    AIPDFPrivateData => {
+        JoinStreams => 1,   # join streams from numbered tags and process as one
         SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main' },
     },
@@ -290,5 +420,5 @@
 );
 
-# tags in PDF AIMetaData directory
+# tags in PDF AIMetaData dictionary
 %Image::ExifTool::PDF::AIMetaData = (
     _stream => {
@@ -297,5 +427,5 @@
 );
 
-# tags in PDF ImageResources directory
+# tags in PDF ImageResources dictionary
 %Image::ExifTool::PDF::ImageResources = (
     _stream => {
@@ -304,5 +434,5 @@
 );
 
-# tags in PDF MarkInfo directory
+# tags in PDF MarkInfo dictionary
 %Image::ExifTool::PDF::MarkInfo = (
     GROUPS => { 2 => 'Document' },
@@ -314,5 +444,5 @@
 );
 
-# tags in PDF Metadata directory
+# tags in PDF Metadata dictionary
 %Image::ExifTool::PDF::Metadata = (
     GROUPS => { 2 => 'Document' },
@@ -346,5 +476,5 @@
 );
 
-# tags in PDF Reference directory
+# tags in PDF Reference dictionary
 %Image::ExifTool::PDF::Reference = (
     TransformParams => {
@@ -353,36 +483,45 @@
 );
 
-# tags in PDF TransformParams directory
+# tags in PDF TransformParams dictionary
 %Image::ExifTool::PDF::TransformParams = (
     GROUPS => { 2 => 'Document' },
     Annots => {
         Name => 'AnnotationUsageRights',
-        Notes => 'UR3 signatures only',
+        Notes => q{
+            possible values are Create, Delete, Modify, Copy, Import and Export;
+            additional values for UR3 signatures are Online and SummaryView
+        },
         List => 1,
     },
     Document => {
         Name => 'DocumentUsageRights',
-        Notes => 'UR3 signatures only',
+        Notes => 'only possible value is FullSave',
         List => 1,
     },
     Form => {
         Name => 'FormUsageRights',
-        Notes => 'UR3 signatures only',
+        Notes => q{
+            possible values are FillIn, Import, Export, SubmitStandalone and
+            SpawnTemplate; additional values for UR3 signatures are BarcodePlaintext and
+            Online
+        },
+        List => 1,
+    },
+    FormEX => {
+        Name => 'FormExtraUsageRights',
+        Notes => 'UR signatures only; only possible value is BarcodePlaintext',
         List => 1,
     },
     Signature => {
         Name => 'SignatureUsageRights',
-        Notes => 'UR3 signatures only',
+        Notes => 'only possible value is Modify',
         List => 1,
     },
     EF => {
         Name => 'EmbeddedFileUsageRights',
-        Notes => 'UR3 signatures only',
+        Notes => 'possible values are Create, Delete, Modify and Import',
         List => 1,
     },
-    Msg => {
-        Name => 'UsageRightsMessage',
-        Notes => 'UR3 signatures only',
-    },
+    Msg => 'UsageRightsMessage',
     P => {
         Name => 'ModificationPermissions',
@@ -395,5 +534,5 @@
             2 => 'Fill forms, Create page templates, Sign',
             3 => 'Fill forms, Create page templates, Sign, Create/Delete/Edit annotations',
-            'true' => 'Restrict al applications to reader permissions',
+            'true' => 'Restrict all applications to reader permissions',
             'false' => 'Do not restrict applications to reader permissions',
         },
@@ -554,4 +693,42 @@
 
 #------------------------------------------------------------------------------
+# 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
+    ($obj = $ref) =~ s/R/obj/;
+    for (;;) {
+        $raf->ReadLine($data) or $et->Warn("Error reading $tag data"), return undef;
+        last if $data =~ s/^$obj//;
+        next if $data =~ /^\s+$/;   # keep reading if this was a blank line
+        # 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;
+        }
+        last;
+    }
+    # 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,
@@ -562,10 +739,10 @@
 sub FetchObject($$$$)
 {
-    my ($exifTool, $ref, $xref, $tag) = @_;
+    my ($et, $ref, $xref, $tag) = @_;
     $lastFetched = $ref;    # save this for decoding if necessary
     my $offset = LocateAnyObject($xref, $ref);
     $lastOffset = $offset;
     unless ($offset) {
-        $exifTool->Warn("Bad $tag reference") unless defined $offset;
+        $et->Warn("Bad $tag reference") unless defined $offset;
         return undef;
     }
@@ -581,9 +758,9 @@
             $streamObjs{$ref} = '';
             # load the parent object stream
-            $obj = FetchObject($exifTool, $ref, $xref, $tag);
+            $obj = FetchObject($et, $ref, $xref, $tag);
             # make sure it contains everything we need
             return undef unless defined $obj and ref($obj) eq 'HASH';
             return undef unless $$obj{First} and $$obj{N};
-            return undef unless DecodeStream($exifTool, $obj);
+            return undef unless DecodeStream($et, $obj);
             # add a special '_table' entry to this dictionary which contains
             # the list of object number/offset pairs from the stream header
@@ -602,9 +779,9 @@
         my $table = $$obj{_table};
         unless ($index < $$obj{N} and $$table[$i] == $objNum) {
-            $exifTool->Warn("Bad index for stream object $tag");
+            $et->Warn("Bad index for stream object $tag");
             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];
@@ -613,16 +790,11 @@
         # avoid re-decrypting data in already decrypted streams
         undef $lastFetched if $cryptStream;
-        return ExtractObject($exifTool, \$data);
-    }
-    my $raf = $exifTool->{RAF};
-    $raf->Seek($offset, 0) or $exifTool->Warn("Bad $tag offset"), return undef;
-    # verify that we are reading the expected object
-    $raf->ReadLine($data) or $exifTool->Warn("Error reading $tag data"), return undef;
-    ($obj = $ref) =~ s/R/obj/;
-    unless ($data =~ s/^$obj//) {
-        $exifTool->Warn("$tag object ($obj) not found at $offset");
-        return undef;
-    }
-    return ExtractObject($exifTool, \$data, $raf, $xref);
+        return ExtractObject($et, \$data);
+    }
+    # load the start of the object
+    $data = CheckObject($et, $tag, $ref, $offset);
+    return undef unless defined $data;
+
+    return ExtractObject($et, \$data, $$et{RAF}, $xref);
 }
 
@@ -646,5 +818,5 @@
     my $delim = substr($str, 0, 1);
     if ($delim eq '(') {    # literal string
-        $str = $1 if $str =~ /.*?\((.*)\)/s;    # remove brackets
+        $str = $1 if $str =~ /^.*?\((.*)\)/s;   # remove brackets
         # decode escape sequences in literal strings
         while ($str =~ /\\(.)/sg) {
@@ -702,5 +874,5 @@
 sub ExtractObject($$;$$)
 {
-    my ($exifTool, $dataPt, $raf, $xref) = @_;
+    my ($et, $dataPt, $raf, $xref) = @_;
     my (@tags, $data, $objData);
     my $dict = { };
@@ -738,5 +910,5 @@
 #
     } elsif ($delim eq '[') {
-        $objData =~ /.*?\[(.*)\]/s or return undef;
+        $objData =~ /^.*?\[(.*)\]/s or return undef;
         my $data = $1;    # brackets removed
         my @list;
@@ -751,5 +923,5 @@
                 last unless defined $val;
                 pos($data) = $pos + length($val);
-                $val = ExtractObject($exifTool, \$val);
+                $val = ExtractObject($et, \$val);
             } elsif ($val =~ /^\d/) {
                 my $pos = pos($data);
@@ -768,6 +940,6 @@
 #
     # Note: entries are not necessarily separated by whitespace (doh!)
-    # ie) "/Tag/Name", "/Tag(string)", "/Tag[array]", etc are legal!
-    # Also, they may be separated by a comment (ie. "/Tag%comment\nValue"),
+    # eg) "/Tag/Name", "/Tag(string)", "/Tag[array]", etc are legal!
+    # Also, they may be separated by a comment (eg. "/Tag%comment\nValue"),
     # but comments have already been removed
     while ($objData =~ m{(\s*)/([^/[\]()<>{}\s]+)\s*(\S[^[(/<>\s]*)}sg) {
@@ -779,5 +951,5 @@
             $val = ReadToNested(\$objData, $raf);
             last unless defined $val;
-            $val = ExtractObject($exifTool, \$val);
+            $val = ExtractObject($et, \$val);
             pos($objData) = 0;
         } elsif ($val =~ /^\d/) {
@@ -791,5 +963,5 @@
         if ($$dict{$tag}) {
             # duplicate dictionary entries are not allowed
-            $exifTool->Warn('Duplicate $tag entry in dictionary (ignored)');
+            $et->Warn("Duplicate '${tag}' entry in dictionary (ignored)");
         } else {
             # save the entry
@@ -812,15 +984,8 @@
         # (compressed objects are not allowed)
         my $offset = LocateObject($xref, $length) or return $dict;
-        $offset or $exifTool->Warn('Bad Length object'), return $dict;
-        $raf->Seek($offset, 0) or $exifTool->Warn('Bad Length offset'), return $dict;
-        # verify that we are reading the expected object
-        $raf->ReadLine($data) or $exifTool->Warn('Error reading Length data'), return $dict;
-        $length =~ s/R/obj/;
-        unless ($data =~ /^$length/) {
-            $exifTool->Warn("Length object ($length) not found at $offset");
-            return $dict;
-        }
-        $raf->ReadLine($data) or $exifTool->Warn('Error reading stream Length'), return $dict;
-        $data =~ /(\d+)/ or $exifTool->Warn('Stream length not found'), return $dict;
+        $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
@@ -838,5 +1003,5 @@
             if ($more > 0) {
                 unless ($raf->Read($data, $more) == $more) {
-                    $exifTool->Warn('Error reading stream data');
+                    $et->Warn('Error reading stream data');
                     $$dataPt = '';
                     return $dict;
@@ -887,5 +1052,5 @@
         # are we in a literal string?
         if ($delim[0] eq ')') {
-            # ignore escaped delimiters (preceeded by odd number of \'s)
+            # ignore escaped delimiters (preceded by odd number of \'s)
             next if length($1) & 0x01;
             # ignore all delimiters but unescaped braces
@@ -923,4 +1088,61 @@
 
 #------------------------------------------------------------------------------
+# Decode LZW-encoded data (ref 1)
+# Inputs: 0) data reference
+# Returns: true on success and data is decoded, or false and data is untouched
+sub DecodeLZW($)
+{
+    my $dataPt = shift;
+    return 0 if length $$dataPt < 4;
+    my @lzw = (map(chr, 0..255), undef, undef); # LZW code table
+    my $mask = 0x01ff;  # mask for least-significant 9 bits
+    my @dat = unpack 'n*', $$dataPt . "\0";
+    my $word = ($dat[0] << 16) | $dat[1];
+    my ($bit, $pos, $bits, $out) = (0, 2, 9, '');
+    my $lastVal;
+    for (;;) {
+        # bits are packed MSB first in PDF LZW (the PDF spec doesn't mention this)
+        my $shift = 32 - ($bit + $bits);
+        if ($shift < 0) {
+            return 0 if $pos >= @dat; # missing EOD marker
+            $word = (($word & 0xffff) << 16) | $dat[$pos++]; # read next word
+            $bit -= 16;
+            $shift += 16;
+        };
+        my $code = ($word >> $shift) & $mask;
+        $bit += $bits;
+        my $val = $lzw[$code];
+        if (defined $val) {
+            # store new code as previous sequence plus 1st char of new sequence
+            push @lzw, $lastVal . substr($val, 0, 1) if defined $lastVal;
+        } elsif ($code == @lzw) { # new code
+            return 0 unless defined $lastVal;
+            # we are using the code that we are about to generate, so the last
+            # character in the new sequence must be the same as the first
+            # character in the previous sequence (makes sense if you think about it)
+            $val = $lastVal . substr($lastVal, 0, 1);
+            push @lzw, $val;
+        } elsif ($code == 256) { # clear table
+            splice @lzw, 258;
+            $bits = 9;
+            $mask = 0x1ff;
+            undef $lastVal;
+            next;
+        } elsif ($code == 257) { # EOD marker
+            last;   # all done!
+        } else {
+            return 0;
+        }
+        $out .= $val;   # add this byte sequence to the output
+        # we added a new entry to the LZW table, so we must increase
+        # the bit width if necessary, up to a maximum of 12
+        @lzw >= $mask and $bits < 12 and ++$bits, $mask |= $mask << 1;
+        $lastVal = $val;
+    }
+    $$dataPt = $out;    # return decompressed data
+    return 1;
+}
+
+#------------------------------------------------------------------------------
 # Decode filtered stream
 # Inputs: 0) ExifTool object reference, 1) dictionary reference
@@ -928,5 +1150,6 @@
 sub DecodeStream($$)
 {
-    my ($exifTool, $dict) = @_;
+    local $_;
+    my ($et, $dict) = @_;
 
     return 0 unless $$dict{_stream}; # no stream to decode
@@ -939,4 +1162,10 @@
         @filters = ($$dict{Filter});
     }
+    # be sure we can process all the filters before we take the time to do the decryption
+    foreach $filter (@filters) {
+        next if $supportedFilter{$filter};
+        $et->WarnOnce("Unsupported Filter $filter");
+        return 0;
+    }
     # apply decryption first if required (and if the default encryption
     # has not been overridden by a Crypt filter. Note: the Crypt filter
@@ -955,9 +1184,19 @@
         @decodeParms = ($$dict{DecodeParms});
     }
+
     foreach $filter (@filters) {
         my $decodeParms = shift @decodeParms;
 
         if ($filter eq '/FlateDecode') {
-            if (eval 'require Compress::Zlib') {
+            # make sure we support the predictor (if used) before decoding
+            my $pre;
+            if (ref $decodeParms eq 'HASH') {
+                $pre = $$decodeParms{Predictor};
+                if ($pre and $pre ne '1' and $pre ne '12') {
+                    $et->WarnOnce("FlateDecode Predictor $pre currently not supported");
+                    return 0;
+                }
+            }
+            if (eval { require Compress::Zlib }) {
                 my $inflate = Compress::Zlib::inflateInit();
                 my ($buff, $stat);
@@ -966,24 +1205,18 @@
                     $$dict{_stream} = $buff;
                 } else {
-                    $exifTool->Warn('Error inflating stream');
+                    $et->Warn('Error inflating stream');
                     return 0;
                 }
             } else {
-                $exifTool->WarnOnce('Install Compress::Zlib to process filtered streams');
+                $et->WarnOnce('Install Compress::Zlib to process filtered streams');
                 return 0;
             }
-            # apply anti-predictor if necessary
-            next unless ref $decodeParms eq 'HASH';
-            my $pre = $$decodeParms{Predictor};
-            next unless $pre and $pre != 1;
-            if ($pre != 12) {
-                # currently only support 'up' prediction
-                $exifTool->WarnOnce("FlateDecode Predictor $pre not currently supported");
-                return 0;
-            }
+            next unless $pre and $pre eq '12';  # 12 = 'up' prediction
+
+            # apply anti-predictor
             my $cols = $$decodeParms{Columns};
             unless ($cols) {
                 # currently only support 'up' prediction
-                $exifTool->WarnOnce('No Columns for decoding stream');
+                $et->WarnOnce('No Columns for decoding stream');
                 return 0;
             }
@@ -993,5 +1226,5 @@
             while (@bytes > $cols) {
                 unless (($_ = shift @bytes) == 2) {
-                    $exifTool->WarnOnce("Unsupported PNG filter $_"); # (yes, PNG)
+                    $et->WarnOnce("Unsupported PNG filter $_"); # (yes, PNG)
                     return 0;
                 }
@@ -1013,9 +1246,9 @@
             next unless defined $name or $name eq 'Identity';
             if ($name ne 'StdCF') {
-                $exifTool->WarnOnce("Unsupported Crypt Filter $name");
+                $et->WarnOnce("Unsupported Crypt Filter $name");
                 return 0;
             }
             unless ($cryptInfo) {
-                $exifTool->WarnOnce('Missing Encrypt StdCF entry');
+                $et->WarnOnce('Missing Encrypt StdCF entry');
                 return 0;
             }
@@ -1030,8 +1263,55 @@
             $$dict{_decrypted} = ($cryptStream ? 1 : 0);
 
-        } elsif ($filter ne '/Identity') {
-
-            $exifTool->WarnOnce("Unsupported Filter $filter");
-            return 0;
+        } elsif ($filter eq '/LZWDecode') {
+
+            # make sure we don't have any unsupported decoding parameters
+            if (ref $decodeParms eq 'HASH') {
+                if ($$decodeParms{Predictor}) {
+                    $et->WarnOnce("LZWDecode Predictor $$decodeParms{Predictor} currently not supported");
+                    return 0;
+                } elsif ($$decodeParms{EarlyChange}) {
+                    $et->WarnOnce("LZWDecode EarlyChange currently not supported");
+                    return 0;
+                }
+            }
+            unless (DecodeLZW(\$$dict{_stream})) {
+                $et->WarnOnce('LZW decompress error');
+                return 0;
+            }
+
+        } elsif ($filter eq '/ASCIIHexDecode') {
+
+            $$dict{_stream} =~ s/>.*//; # truncate at '>' (end of data mark)
+            $$dict{_stream} =~ tr/0-9a-zA-Z//d; # remove illegal characters
+            $$dict{_stream} = pack 'H*', $$dict{_stream};
+
+        } elsif ($filter eq '/ASCII85Decode') {
+
+            my ($err, @out, $i);
+            my ($n, $val) = (0, 0);
+            foreach (split //, $$dict{_stream}) {
+                if ($_ ge '!' and $_ le 'u') {;
+                    $val = 85 * $val + ord($_) - 33;
+                    next unless ++$n == 5;
+                } elsif ($_ eq '~') {
+                    $n == 1 and $err = 1;   # error to have a single char in the last group of 5
+                    for ($i=$n; $i<5; ++$i) { $val *= 85; }
+                } elsif ($_ eq 'z') {
+                    $n and $err = 2, last;  # error if 'z' isn't the first char
+                    $n = 5;
+                } else {
+                    next if /^\s$/;         # ignore white space
+                    $err = 3, last;         # any other character is an error
+                }
+                $val = unpack('V', pack('N', $val)); # reverse byte order
+                while (--$n > 0) {
+                    push @out, $val & 0xff;
+                    $val >>= 8;
+                }
+                last if $_ eq '~';
+                # (both $n and $val are zero again now)
+            }
+            $err and $et->WarnOnce("ASCII85Decode error $err");
+            $$dict{_stream} = pack('C*', @out);
         }
     }
@@ -1084,4 +1364,80 @@
 
 #------------------------------------------------------------------------------
+# Update AES cipher with a bit of data
+# Inputs: 0) data
+# Returns: encrypted data
+my $cipherMore;
+sub CipherUpdate($)
+{
+    my $dat = shift;
+    my $pos = 0;
+    $dat = $cipherMore . $dat if length $dat;
+    while ($pos + 16 <= length($dat)) {
+        substr($dat,$pos,16) = Image::ExifTool::AES::Cipher(substr($dat,$pos,16));
+        $pos += 16;
+    }
+    if ($pos < length $dat) {
+        $cipherMore = substr($dat,$pos);
+        $dat = substr($dat,0,$pos);
+    } else {
+        $cipherMore = '';
+    }
+    return $dat;
+}
+
+#------------------------------------------------------------------------------
+# Get encrypted hash
+# Inputs: 0) Password, 1) salt, 2) vector, 3) encryption revision
+# Returns: hash
+sub GetHash($$$$)
+{
+    my ($password, $salt, $vector, $rev) = @_;
+
+    # return Rev 5 hash
+    return Digest::SHA::sha256($password, $salt, $vector) if $rev == 5;
+
+    # compute Rev 6 hardened hash
+    # (ref http://code.google.com/p/origami-pdf/source/browse/lib/origami/encryption.rb)
+    my $blockSize = 32;
+    my $input = Digest::SHA::sha256($password, $salt, $vector) . ("\0" x 32);
+    my $key = substr($input, 0, 16);
+    my $iv = substr($input, 16, 16);
+    my $h;
+    my $x = '';
+    my $i = 0;
+    while ($i < 64 or $i < ord(substr($x,-1,1))+32) {
+
+        my $block = substr($input, 0, $blockSize);
+        $x = '';
+        Image::ExifTool::AES::Crypt(\$x, $key, $iv, 1);
+        $cipherMore = '';
+
+        my ($j, $digest);
+        for ($j=0; $j<64; ++$j)  {
+            $x = '';
+            $x .= CipherUpdate($password) if length $password;
+            $x .= CipherUpdate($block);
+            $x .= CipherUpdate($vector) if length $vector;
+            if ($j == 0) {
+                my @a = unpack('C16', $x);
+                my $sum = 0;
+                $sum += $_ foreach @a;
+                # set SHA block size (32, 48 or 64 bytes = SHA-256, 384 or 512)
+                $blockSize = 32 + ($sum % 3) * 16;
+                $digest = Digest::SHA->new($blockSize * 8);
+            }
+            $digest->add($x);
+        }
+
+        $h = $digest->digest();
+        $key = substr($h, 0, 16);
+        substr($input,0,16) = $h;
+        $iv = substr($h, 16, 16);
+        ++$i;
+    }
+    return substr($h, 0, 32);
+}
+
+#------------------------------------------------------------------------------
 # Initialize decryption
 # Inputs: 0) ExifTool object reference, 1) Encrypt dictionary reference,
@@ -1091,5 +1447,5 @@
 {
     local $_;
-    my ($exifTool, $encrypt, $id) = @_;
+    my ($et, $encrypt, $id) = @_;
 
     undef $cryptInfo;
@@ -1109,7 +1465,7 @@
     $enc .= ' (' . ($$encrypt{Length} || 40) . '-bit)' if $filt eq 'Standard';
     my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Encrypt');
-    $exifTool->HandleTag($tagTablePtr, 'Filter', $enc);
+    $et->HandleTag($tagTablePtr, 'Filter', $enc);
     if ($filt ne 'Standard') {
-        return "Encryption filter $filt not currently supported";
+        return "Encryption filter $filt currently not supported";
     } elsif (not defined $$encrypt{R}) {
         return 'Standard security handler missing revision';
@@ -1118,5 +1474,9 @@
         return 'Incomplete Encrypt specification';
     }
-    $exifTool->HandleTag($tagTablePtr, 'P', $$encrypt{P});
+    if ("$ver.$rev" >= 5.6) {
+        # apologize for poor performance (AES is a pure Perl implementation)
+        $et->Warn('Decryption is very slow for encryption V5.6 or higher', 3);
+    }
+    $et->HandleTag($tagTablePtr, 'P', $$encrypt{P});
 
     my %parm;   # optional parameters extracted from Encrypt dictionary
@@ -1152,5 +1512,5 @@
         }
     } else {
-        return "Encryption version $ver not currently supported";
+        return "Encryption version $ver currently not supported";
     }
     $id or return "Can't decrypt (no document ID)";
@@ -1158,9 +1518,9 @@
     # make sure we have the necessary libraries available
     if ($ver < 5) {
-        unless (eval 'require Digest::MD5') {
+        unless (eval { require Digest::MD5 }) {
             return "Install Digest::MD5 to process encrypted PDF";
         }
     } else {
-        unless (eval 'require Digest::SHA') {
+        unless (eval { require Digest::SHA }) {
             return "Install Digest::SHA to process AES-256 encrypted PDF";
         }
@@ -1185,10 +1545,10 @@
             $password = '';
         } elsif ($try == 1) {
-            $password = $exifTool->Options('Password');
+            $password = $et->Options('Password');
             return 'Document is password protected (use Password option)' unless defined $password;
             # make sure there is no UTF-8 flag on the password
-            if ($] >= 5.006 and (eval 'require Encode; Encode::is_utf8($password)' or $@)) {
+            if ($] >= 5.006 and (eval { require Encode; Encode::is_utf8($password) } or $@)) {
                 # repack by hand if Encode isn't available
-                $password = $@ ? pack('C*',unpack('U0C*',$password)) : Encode::encode('utf8',$password);
+                $password = $@ ? pack('C*',unpack($] < 5.010000 ? 'U0C*' : 'C0C*',$password)) : Encode::encode('utf8',$password);
             }
         } else {
@@ -1198,5 +1558,5 @@
             if (length $password) {
                 # password must be encoding in PDFDocEncoding (ref iso32000)
-                $password = $exifTool->Encode($password, 'PDFDoc');
+                $password = $et->Encode($password, 'PDFDoc');
                 # truncate or pad the password to exactly 32 bytes
                 if (length($password) > 32) {
@@ -1247,11 +1607,11 @@
                 # but to be bullet-proof we need to apply the SASLprep (IETF RFC 4013) profile
                 # of stringprep (IETF RFC 3454) to the password before encoding in UTF-8
-                $password = $exifTool->Encode($password, 'UTF8');
+                $password = $et->Encode($password, 'UTF8');
                 $password = substr($password, 0, 127) if length($password) > 127;
             }
             # test for the owner password
-            my $sha = Digest::SHA::sha256($password, substr($o,32,8), substr($u,0,48));
+            my $sha = GetHash($password, substr($o,32,8), substr($u,0,48), $rev);
             if ($sha eq substr($o, 0, 32)) {
-                $key = Digest::SHA::sha256($password, substr($o,40,8), substr($u,0,48));
+                $key = GetHash($password, substr($o,40,8), substr($u,0,48), $rev);
                 my $dat = ("\0" x 16) . $parm{OE};
                 # decrypt with no padding
@@ -1262,7 +1622,7 @@
             }
             # test for the user password
-            $sha = Digest::SHA::sha256($password, substr($u,32,8));
+            $sha = GetHash($password, substr($u,32,8), '', $rev);
             if ($sha eq substr($u, 0, 32)) {
-                $key = Digest::SHA::sha256($password, substr($u,40,8));
+                $key = GetHash($password, substr($u,40,8), '', $rev);
                 my $dat = ("\0" x 16) . $parm{UE};
                 my $err = Image::ExifTool::AES::Crypt(\$dat, $key, 0, 1);
@@ -1355,6 +1715,32 @@
     $name =~ s/(^|_)([a-z])/\U$2/g; # start words with upper case
     my $tagInfo = { Name => $name };
-    Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+    AddTagToTable($tagTablePtr, $tag, $tagInfo);
     return $tagInfo;
+}
+
+#------------------------------------------------------------------------------
+# Process AcroForm dictionary to set HasXMLFormsArchitecture flag
+# Inputs: Same as ProcessDict
+sub ProcessAcroForm($$$$;$$)
+{
+    my ($et, $tagTablePtr, $dict, $xref, $nesting, $type) = @_;
+    $et->HandleTag($tagTablePtr, '_has_xfa', $$dict{XFA} ? 'true' : 'false');
+    return ProcessDict($et, $tagTablePtr, $dict, $xref, $nesting, $type);
+}
+
+#------------------------------------------------------------------------------
+# Expand array into a string
+# Inputs: 0) array ref
+# Return: string
+sub ExpandArray($)
+{
+    my $val = shift;
+    my @list = @$val;
+    foreach (@list) {
+        ref $_ eq 'SCALAR' and $_ = "ref($$_)", next;
+        ref $_ eq 'ARRAY' and $_ = ExpandArray($_), next;
+        defined $_ or $_ = '<undef>', next;
+    }
+    return '[' . join(',',@list) . ']';
 }
 
@@ -1366,8 +1752,8 @@
 sub ProcessDict($$$$;$$)
 {
-    my ($exifTool, $tagTablePtr, $dict, $xref, $nesting, $type) = @_;
-    my $verbose = $exifTool->Options('Verbose');
+    my ($et, $tagTablePtr, $dict, $xref, $nesting, $type) = @_;
+    my $verbose = $et->Options('Verbose');
     my $unknown = $$tagTablePtr{EXTRACT_UNKNOWN};
-    my $embedded = (defined $unknown and not $unknown and $exifTool->Options('ExtractEmbedded'));
+    my $embedded = (defined $unknown and not $unknown and $et->Options('ExtractEmbedded'));
     my @tags = @{$$dict{_tags}};
     my ($next, %join);
@@ -1376,17 +1762,17 @@
     $nesting = ($nesting || 0) + 1;
     if ($nesting > 50) {
-        $exifTool->WarnOnce('Nesting too deep (directory ignored)');
+        $et->WarnOnce('Nesting too deep (directory ignored)');
         return;
     }
     # save entire dictionary for rewriting if specified
-    if ($$exifTool{PDF_CAPTURE} and $$tagTablePtr{VARS} and
+    if ($$et{PDF_CAPTURE} and $$tagTablePtr{VARS} and
         $tagTablePtr->{VARS}->{CAPTURE})
     {
         my $name;
         foreach $name (@{$tagTablePtr->{VARS}->{CAPTURE}}) {
-            next if $exifTool->{PDF_CAPTURE}->{$name};
+            next if $$et{PDF_CAPTURE}{$name};
             # make sure we load the right type if indicated
             next if $type and $type ne $name;
-            $exifTool->{PDF_CAPTURE}->{$name} = $dict;
+            $$et{PDF_CAPTURE}{$name} = $dict;
             last;
         }
@@ -1396,5 +1782,5 @@
 #
     for (;;) {
-        my ($tag, $tagInfo);
+        my ($tag, $isSubDoc);
         if (@tags) {
             $tag = shift @tags;
@@ -1406,17 +1792,24 @@
         }
         my $val = $$dict{$tag};
-        if ($$tagTablePtr{$tag}) {
-            $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        if ($tagInfo) {
             undef $tagInfo if $$tagInfo{NoProcess};
         } elsif ($embedded and $tag =~ /^(.*?)(\d+)$/ and
-            $$tagTablePtr{$1} and ref $val eq 'SCALAR' and not $fetched{$$val})
+            $$tagTablePtr{$1} and (ref $val ne 'SCALAR' or not $fetched{$$val}))
         {
             my ($name, $num) = ($1, $2);
-            $join{$name} = [] unless $join{$name};
-            $fetched{$$val} = 1;
-            my $obj = FetchObject($exifTool, $$val, $xref, $tag);
-            next unless ref $obj eq 'HASH' and $$obj{_stream};
-            # save all the stream data to join later
-            $join{$name}->[$num] = $$obj{_stream};
+            $tagInfo = $et->GetTagInfo($tagTablePtr, $name);
+            if (ref $tagInfo eq 'HASH' and $$tagInfo{JoinStreams}) {
+                $fetched{$$val} = 1;
+                my $obj = FetchObject($et, $$val, $xref, $tag);
+                $join{$name} = [] unless $join{$name};
+                next unless ref $obj eq 'HASH' and $$obj{_stream};
+                # save all the stream data to join later
+                DecodeStream($et, $obj);
+                $join{$name}->[$num] = $$obj{_stream};
+                undef $tagInfo;    # don't process
+            } else {
+                $isSubDoc = 1;  # treat as a sub-document
+            }
         }
         if ($verbose) {
@@ -1432,5 +1825,5 @@
                 } else {
                     $fetched{$$val} = 1;
-                    $val = FetchObject($exifTool, $$val, $xref, $tag);
+                    $val = FetchObject($et, $$val, $xref, $tag);
                     unless (defined $val) {
                         my $str;
@@ -1442,5 +1835,5 @@
                             $str = 'Error reading object';
                         }
-                        $exifTool->VPrint(0, "$$exifTool{INDENT}${str}:\n");
+                        $et->VPrint(0, "$$et{INDENT}${str}:\n");
                     }
                 }
@@ -1469,16 +1862,8 @@
                 $tagInfo or $tagInfo = {
                     Name => $tag,
-                    SubDirectory => {
-                        TagTable => 'Image::ExifTool::PDF::Unknown',
-                    },
+                    SubDirectory => { TagTable => 'Image::ExifTool::PDF::Unknown' },
                 };
             } else {
-                if (ref $val eq 'ARRAY') {
-                    my @list = @$val;
-                    foreach (@list) {
-                        $_ = "ref($$_)" if ref $_ eq 'SCALAR';
-                    }
-                    $val2 = '[' . join(',',@list) . ']';
-                }
+                $val2 = ExpandArray($val) if ref $val eq 'ARRAY';
                 # generate tag info if we will use it later
                 if (not $tagInfo and defined $val and $unknown) {
@@ -1486,5 +1871,5 @@
                 }
             }
-            $exifTool->VerboseInfo($tag, $tagInfo,
+            $et->VerboseInfo($tag, $tagInfo,
                 Value => $val2 || $val,
                 Extra => $extra,
@@ -1494,9 +1879,100 @@
         }
         unless ($tagInfo) {
-            # add any tag found in Info directory to table
+            # add any tag found in Info dictionary to table
             next unless $unknown;
             $tagInfo = NewPDFTag($tagTablePtr, $tag);
         }
-        unless ($$tagInfo{SubDirectory}) {
+        # increment document number if necessary
+        my ($oldDocNum, $oldNumTags);
+        if ($isSubDoc) {
+            $oldDocNum = $$et{DOC_NUM};
+            $oldNumTags = $$et{NUM_FOUND};
+            $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+        }
+        if ($$tagInfo{SubDirectory}) {
+            # process the subdirectory
+            my @subDicts;
+            if (ref $val eq 'ARRAY') {
+                # 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 );
+            }
+            # loop through all values of this tag
+            for (;;) {
+                my $subDict = shift @subDicts or last;
+                # save last fetched object in case we fetch another one here
+                my $prevFetched = $lastFetched;
+                if (ref $subDict eq 'SCALAR') {
+                    # only fetch once (other copies are obsolete)
+                    next if $fetched{$$subDict};
+                    if ($$tagInfo{IgnoreDuplicates}) {
+                        my $flag = "ProcessedPDF_$tag";
+                        if ($$et{$flag}) {
+                            next if $et->WarnOnce("Ignored duplicate $tag dictionary", 2);
+                        } else {
+                            $$et{$flag} = 1;
+                        }
+                    }
+                    # load dictionary via an indirect reference
+                    $fetched{$$subDict} = 1;
+                    my $obj = FetchObject($et, $$subDict, $xref, $tag);
+                    unless (defined $obj) {
+                        unless (defined $lastOffset) {
+                            $et->Warn("Error reading $tag object ($$subDict)");
+                        }
+                        next;
+                    }
+                    $subDict = $obj;
+                }
+                if (ref $subDict eq 'ARRAY') {
+                    # convert array of key/value pairs to a hash
+                    next if @$subDict < 2;
+                    my %hash = ( _tags => [] );
+                    while (@$subDict >= 2) {
+                        my $key = shift @$subDict;
+                        $key =~ s/^\///;
+                        push @{$hash{_tags}}, $key;
+                        $hash{$key} = shift @$subDict;
+                    }
+                    $subDict = \%hash;
+                } else {
+                    next unless ref $subDict eq 'HASH';
+                }
+                # set flag to re-crypt all strings when rewriting if the dictionary
+                # came from an encrypted stream
+                $$subDict{_needCrypt}{'*'} = 1 unless $lastFetched;
+                my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                if (not $verbose) {
+                    my $proc = $$subTablePtr{PROCESS_PROC} || \&ProcessDict;
+                    &$proc($et, $subTablePtr, $subDict, $xref, $nesting);
+                } elsif ($next) {
+                    # handle 'Next' links at this level to avoid deep recursion
+                    undef $next;
+                    $index = 0;
+                    $tagTablePtr = $subTablePtr;
+                    $dict = $subDict;
+                    @tags = @{$$subDict{_tags}};
+                    $et->VerboseDir($tag, scalar(@tags));
+                } else {
+                    my $oldIndent = $$et{INDENT};
+                    my $oldDir = $$et{DIR_NAME};
+                    $$et{INDENT} .= '| ';
+                    $$et{DIR_NAME} = $tag;
+                    $et->VerboseDir($tag, scalar(@{$$subDict{_tags}}));
+                    ProcessDict($et, $subTablePtr, $subDict, $xref, $nesting);
+                    $$et{INDENT} = $oldIndent;
+                    $$et{DIR_NAME} = $oldDir;
+                }
+                $lastFetched = $prevFetched;
+            }
+        } else {
             # fetch object if necessary
             # (OS X 10.6 writes indirect objects in the Info dictionary!)
@@ -1504,108 +1980,47 @@
                 my $prevFetched = $lastFetched;
                 # (note: fetching the same object multiple times is OK here)
-                $val = FetchObject($exifTool, $$val, $xref, $tag);
-                next unless defined $val;
-                $val = ReadPDFValue($val);
-                # set flag to re-encrypt if necessary if rewritten
-                $$dict{_needCrypt}{$tag} = ($lastFetched ? 0 : 1) if $cryptString;
-                $lastFetched = $prevFetched; # restore last fetched object reference
+                $val = FetchObject($et, $$val, $xref, $tag);
+                if (defined $val) {
+                    $val = ReadPDFValue($val);
+                    # set flag to re-encrypt if necessary if rewritten
+                    $$dict{_needCrypt}{$tag} = ($lastFetched ? 0 : 1) if $cryptString;
+                    $lastFetched = $prevFetched; # restore last fetched object reference
+                }
             } else {
                 $val = ReadPDFValue($val);
             }
-            my $format = $$tagInfo{Format} || $$tagInfo{Writable} || 'string';
-            $val = ConvertPDFDate($val) if $format eq 'date';
             # convert from UTF-16 (big endian) to UTF-8 or Latin if necessary
             # unless this is binary data (hex-encoded strings would not have been converted)
             if (ref $val) {
-                next if ref $val ne 'ARRAY';
-                my $v;
-                foreach $v (@$val) {
-                    $exifTool->FoundTag($tagInfo, $v);
-                }
-            } else {
+                if (ref $val eq 'ARRAY') {
+                    my $v;
+                    foreach $v (@$val) {
+                        $et->FoundTag($tagInfo, $v);
+                    }
+                }
+            } elsif (defined $val) {
+                my $format = $$tagInfo{Format} || $$tagInfo{Writable} || 'string';
+                $val = ConvertPDFDate($val) if $format eq 'date';
                 if (not $$tagInfo{Binary} and $val =~ /[\x18-\x1f\x80-\xff]/) {
                     # text string is already in Unicode if it starts with "\xfe\xff",
                     # otherwise we must first convert from PDFDocEncoding
-                    $val = $exifTool->Decode($val, ($val=~s/^\xfe\xff// ? 'UCS2' : 'PDFDoc'), 'MM');
-                }
-                if ($$tagInfo{List}) {
+                    $val = $et->Decode($val, ($val=~s/^\xfe\xff// ? 'UCS2' : 'PDFDoc'), 'MM');
+                }
+                if ($$tagInfo{List} and not $$et{OPTIONS}{NoPDFList}) {
                     # separate tokens in comma or whitespace delimited lists
                     my @values = ($val =~ /,/) ? split /,+\s*/, $val : split ' ', $val;
                     foreach $val (@values) {
-                        $exifTool->FoundTag($tagInfo, $val);
+                        $et->FoundTag($tagInfo, $val);
                     }
                 } else {
                     # a simple tag value
-                    $exifTool->FoundTag($tagInfo, $val);
-                }
-            }
-            next;
-        }
-        # process the subdirectory
-        my @subDicts;
-        if (ref $val eq 'ARRAY') {
-            @subDicts = @{$val};
-        } else {
-            @subDicts = ( $val );
-        }
-        # loop through all values of this tag
-        for (;;) {
-            my $subDict = shift @subDicts or last;
-            # save last fetched object in case we fetch another one here
-            my $prevFetched = $lastFetched;
-            if (ref $subDict eq 'SCALAR') {
-                # only fetch once (other copies are obsolete)
-                next if $fetched{$$subDict};
-                # load dictionary via an indirect reference
-                $fetched{$$subDict} = 1;
-                my $obj = FetchObject($exifTool, $$subDict, $xref, $tag);
-                unless (defined $obj) {
-                    unless (defined $lastOffset) {
-                        $exifTool->Warn("Error reading $tag object ($$subDict)");
-                    }
-                    next;
-                }
-                $subDict = $obj;
-            }
-            if (ref $subDict eq 'ARRAY') {
-                # convert array of key/value pairs to a hash
-                next if @$subDict < 2;
-                my %hash = ( _tags => [] );
-                while (@$subDict >= 2) {
-                    my $key = shift @$subDict;
-                    $key =~ s/^\///;
-                    push @{$hash{_tags}}, $key;
-                    $hash{$key} = shift @$subDict;
-                }
-                $subDict = \%hash;
-            } else {
-                next unless ref $subDict eq 'HASH';
-            }
-            # set flag to re-crypt all strings when rewriting if the dictionary
-            # came from an encrypted stream
-            $$subDict{_needCrypt}{'*'} = 1 unless $lastFetched;
-            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
-            if (not $verbose) {
-                my $proc = $$subTablePtr{PROCESS_PROC} || \&ProcessDict;
-                &$proc($exifTool, $subTablePtr, $subDict, $xref, $nesting);
-            } elsif ($next) {
-                # handle 'Next' links at this level to avoid deep recursion
-                undef $next;
-                $index = 0;
-                $tagTablePtr = $subTablePtr;
-                $dict = $subDict;
-                @tags = @{$$subDict{_tags}};
-                $exifTool->VerboseDir($tag, scalar(@tags));
-            } else {
-                my $oldIndent = $exifTool->{INDENT};
-                my $oldDir = $exifTool->{DIR_NAME};
-                $exifTool->{INDENT} .= '| ';
-                $exifTool->{DIR_NAME} = $tag;
-                $exifTool->VerboseDir($tag, scalar(@{$$subDict{_tags}}));
-                ProcessDict($exifTool, $subTablePtr, $subDict, $xref, $nesting);
-                $exifTool->{INDENT} = $oldIndent;
-                $exifTool->{DIR_NAME} = $oldDir;
-            }
-            $lastFetched = $prevFetched;
+                    $et->FoundTag($tagInfo, $val);
+                }
+            }
+        }
+        if ($isSubDoc) {
+            # restore original document number
+            $$et{DOC_NUM} = $oldDocNum;
+            --$$et{DOC_COUNT} if $oldNumTags == $$et{NUM_FOUND};
         }
     }
@@ -1624,29 +2039,65 @@
                 undef $$list[$i];   # free memory
             }
-            $exifTool->HandleTag($tagTablePtr, $tag, $buff);
-        }
-    }
-#
-# extract information from stream object if it exists (ie. Metadata stream)
-#
-    return unless $$dict{_stream};
-    my $tag = '_stream';
-    # add Subtype (if it exists) to stream name and remove leading '/'
-    ($tag = $$dict{Subtype} . $tag) =~ s/^\/// if $$dict{Subtype};
-    return unless $$tagTablePtr{$tag};
-    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
-    # decode stream if necessary
-    DecodeStream($exifTool, $dict) or return;
-    # extract information from stream
-    my %dirInfo = (
-        DataPt   => \$$dict{_stream},
-        DataLen  => length $$dict{_stream},
-        DirStart => 0,
-        DirLen   => length $$dict{_stream},
-        Parent   => 'PDF',
-    );
-    my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
-    unless ($exifTool->ProcessDirectory(\%dirInfo, $subTablePtr)) {
-        $exifTool->Warn("Error processing $$tagInfo{Name} information");
+            # increment document number for tags extracted from embedded EPS
+            my $oldDocNum = $$et{DOC_NUM};
+            my $oldNumTags = $$et{NUM_FOUND};
+            $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+            # extract PostScript information
+            $et->HandleTag($tagTablePtr, $tag, $buff);
+            $$et{DOC_NUM} = $oldDocNum;
+            # revert document counter if we didn't add any new tags
+            --$$et{DOC_COUNT} if $oldNumTags == $$et{NUM_FOUND};
+            delete $$et{DOC_NUM};
+        }
+    }
+#
+# extract information from stream object if it exists (eg. Metadata stream)
+#
+    for (;;) { # (cheap goto)
+        last unless $$dict{_stream};
+        my $tag = '_stream';
+        # add Subtype (if it exists) to stream name and remove leading '/'
+        ($tag = $$dict{Subtype} . $tag) =~ s/^\/// if $$dict{Subtype};
+        last unless $$tagTablePtr{$tag};
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag) or last;
+        unless ($$tagInfo{SubDirectory}) {
+            # don't build filter lists across different images
+            delete $$et{LIST_TAGS}{$$tagTablePtr{Filter}};
+            # we arrive here only when extracting embedded images
+            # - only extract known image types and ignore others
+            my $filter = $$dict{Filter} || '';
+            $filter = @$filter[-1] if ref $filter eq 'ARRAY'; # (get last Filter type)
+            my $result;
+            if ($filter eq '/DCTDecode' or $filter eq '/JPXDecode') {
+                DecodeStream($et, $dict) or last;
+                # save the image itself
+                $et->FoundTag($tagInfo, \$$dict{_stream});
+                # extract information from embedded image
+                $result = $et->ExtractInfo(\$$dict{_stream}, { ReEntry => 1 });
+            }
+            unless ($result) {
+                $et->FoundTag('FileType', defined $result ? '(unknown)' : '(unsupported)');
+            }
+            last;
+        }
+        # decode stream if necessary
+        DecodeStream($et, $dict) or last;
+        if ($verbose > 2) {
+            $et->VPrint(2,"$$et{INDENT}$$et{DIR_NAME} stream data\n");
+            $et->VerboseDump(\$$dict{_stream});
+        }
+        # extract information from stream
+        my %dirInfo = (
+            DataPt   => \$$dict{_stream},
+            DataLen  => length $$dict{_stream},
+            DirStart => 0,
+            DirLen   => length $$dict{_stream},
+            Parent   => 'PDF',
+        );
+        my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+        unless ($et->ProcessDirectory(\%dirInfo, $subTablePtr)) {
+            $et->Warn("Error processing $$tagInfo{Name} information");
+        }
+        last;
     }
 }
@@ -1658,7 +2109,7 @@
 sub ReadPDF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my ($buff, $encrypt, $id);
 #
@@ -1667,30 +2118,31 @@
     # (linearization dictionary must be in the first 1024 bytes of the file)
     $raf->Read($buff, 1024) >= 8 or return 0;
-    $buff =~ /^%PDF-(\d+\.\d+)/ or return 0;
-    $pdfVer = $1;
-    $exifTool->SetFileType();   # set the FileType tag
-    $exifTool->Warn("May not be able to read a PDF version $pdfVer file") if $pdfVer >= 2.0;
+    $buff =~ /^(\s*)%PDF-(\d+\.\d+)/ or return 0;
+    $$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("The PDF $pdfVer specification is held hostage by the ISO") if $pdfVer >= 2.0;
     # store PDFVersion tag
     my $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Root');
-    $exifTool->HandleTag($tagTablePtr, 'Version', $pdfVer);
+    $et->HandleTag($tagTablePtr, 'Version', $pdfVer);
     $tagTablePtr = GetTagTable('Image::ExifTool::PDF::Main');
 #
 # check for a linearized PDF (only if reading)
 #
-    my $capture = $$exifTool{PDF_CAPTURE};
+    my $capture = $$et{PDF_CAPTURE};
     unless ($capture) {
         my $lin = 'false';
         if ($buff =~ /<</g) {
             $buff = substr($buff, pos($buff) - 2);
-            my $dict = ExtractObject($exifTool, \$buff);
+            my $dict = ExtractObject($et, \$buff);
             if (ref $dict eq 'HASH' and $$dict{Linearized} and $$dict{L}) {
-                if (not $$exifTool{VALUE}{FileSize}) {
+                if (not $$et{VALUE}{FileSize}) {
                     undef $lin; # can't determine if it is linearized
-                } elsif ($$dict{L} == $$exifTool{VALUE}{FileSize}) {
+                } elsif ($$dict{L} == $$et{VALUE}{FileSize} - $$et{PDFBase}) {
                     $lin = 'true';
                 }
             }
         }
-        $exifTool->HandleTag($tagTablePtr, '_linearized', $lin) if $lin;
+        $et->HandleTag($tagTablePtr, '_linearized', $lin) if $lin;
     }
 #
@@ -1704,40 +2156,49 @@
     $raf->Seek(-$len, 2) or return -2;
     $raf->Read($buff, $len) == $len or return -3;
-    # find the last xref table in the file (may be multiple %%EOF marks)
-    $buff =~ /.*startxref *(\x0d\x0a|\x0d|\x0a)\s*?(\d+)\s+%%EOF/s or return -4;
-    local $/ = $1;    # set input record separator
-    push @xrefOffsets, $2, 'Main';
+    # find the LAST xref table in the file (may be multiple %%EOF marks,
+    # and comments between "startxref" and "%%EOF")
+    $buff =~ /^.*startxref(\s+)(\d+)(\s+)(%[^\x0d\x0a]*\s+)*%%EOF/s or return -4;
+    my $ws = $1 . $3;
+    my $xr = $2;
+    push @xrefOffsets, $xr, 'Main';
+    # set input record separator
+    local $/ = $ws =~ /(\x0d\x0a|\x0d|\x0a)/ ? $1 : "\x0a";
     my (%xref, @mainDicts, %loaded, $mainFree);
+    my ($xrefSize, $mainDictSize) = (0, 0);
     # initialize variables to capture when rewriting
     if ($capture) {
-        $capture->{startxref} = $2;
+        $capture->{startxref} = $xr;
         $capture->{xref} = \%xref;
         $capture->{newline} = $/;
         $capture->{mainFree} = $mainFree = { };
     }
+XRef:
     while (@xrefOffsets) {
         my $offset = shift @xrefOffsets;
         my $type = shift @xrefOffsets;
         next if $loaded{$offset};   # avoid infinite recursion
-        unless ($raf->Seek($offset, 0)) {
+        unless ($raf->Seek($offset+$$et{PDFBase}, 0)) {
             %loaded or return -5;
-            $exifTool->Warn('Bad offset for secondary xref table');
+            $et->Warn('Bad offset for secondary xref table');
             next;
         }
         # Note: care must be taken because ReadLine may read more than we want if
         # the newline sequence for this table is different than the rest of the file
-        unless ($raf->ReadLine($buff)) {
-            %loaded or return -6;
-            $exifTool->Warn('Bad offset for secondary xref table');
-            next;
+        for (;;) {
+            unless ($raf->ReadLine($buff)) {
+                %loaded or return -6;
+                $et->Warn('Bad offset for secondary xref table');
+                next XRef;
+            }
+            last if $buff =~/\S/;   # skip blank lines
         }
         my $loadXRefStream;
-        if ($buff =~ s/^xref\s+//s) {
+        if ($buff =~ s/^\s*xref\s+//s) {
             # load xref table
             for (;;) {
                 # read another line if necessary (skipping blank lines)
                 $raf->ReadLine($buff) or return -6 until $buff =~ /\S/;
-                last if $buff =~ s/^\s*trailer\s+//s;
-                $buff =~ s/\s*(\d+)\s+(\d+)\s+//s or return -4;
+                last if $buff =~ s/^\s*trailer([\s<[(])/$1/s;
+                $buff =~ s/^\s*(\d+)\s+(\d+)\s+//s or return -4;
                 my ($start, $num) = ($1, $2);
                 $raf->Seek(-length($buff), 1) or return -4;
@@ -1747,4 +2208,8 @@
                     $buff =~ /^\s*(\d{10}) (\d{5}) (f|n)/s or return -4;
                     my $num = $start + $i;
+                    $xrefSize = $num if $num > $xrefSize;
+                    # 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)
@@ -1766,18 +2231,20 @@
             }
             undef $mainFree;    # only do this for the last xref table
-        } elsif ($buff =~ s/^(\d+)\s+(\d+)\s+obj//s) {
+        } elsif ($buff =~ s/^\s*(\d+)\s+(\d+)\s+obj//s) {
             # this is a PDF-1.5 cross-reference stream dictionary
             $loadXRefStream = 1;
         } else {
             %loaded or return -4;
-            $exifTool->Warn('Invalid secondary xref table');
+            $et->Warn('Invalid secondary xref table');
             next;
         }
-        my $mainDict = ExtractObject($exifTool, \$buff, $raf, \%xref);
+        my $mainDict = ExtractObject($et, \$buff, $raf, \%xref);
         unless (ref $mainDict eq 'HASH') {
             %loaded or return -8;
-            $exifTool->Warn('Error loading secondary dictionary');
+            $et->Warn('Error loading secondary dictionary');
             next;
         }
+        # keep track of total trailer dictionary Size
+        $mainDictSize = $$mainDict{Size} if $$mainDict{Size} and $$mainDict{Size} > $mainDictSize;
         if ($loadXRefStream) {
             # decode and save our XRef stream from PDF-1.5 file
@@ -1790,5 +2257,5 @@
             if ($$mainDict{Type} eq '/XRef' and $$mainDict{W} and
                 @{$$mainDict{W}} > 2 and $$mainDict{Size} and
-                DecodeStream($exifTool, $mainDict))
+                DecodeStream($et, $mainDict))
             {
                 # create Index entry if it doesn't exist
@@ -1804,5 +2271,5 @@
             } else {
                 %loaded or return -9;
-                $exifTool->Warn('Invalid xref stream in secondary dictionary');
+                $et->Warn('Invalid xref stream in secondary dictionary');
             }
         }
@@ -1818,4 +2285,8 @@
         push @xrefOffsets, $$mainDict{Prev}, 'Prev' if $$mainDict{Prev};
     }
+    if ($xrefSize > $mainDictSize) {
+        my $str = "Objects in xref table ($xrefSize) exceed trailer dictionary Size ($mainDictSize)";
+        $capture ? $et->Error($str) : $et->Warn($str);
+    }
 #
 # extract encryption information if necessary
@@ -1823,10 +2294,10 @@
     if ($encrypt) {
         if (ref $encrypt eq 'SCALAR') {
-            $encrypt = FetchObject($exifTool, $$encrypt, \%xref, 'Encrypt');
+            $encrypt = FetchObject($et, $$encrypt, \%xref, 'Encrypt');
         }
         # generate Encryption tag information
-        my $err = DecryptInit($exifTool, $encrypt, $id);
+        my $err = DecryptInit($et, $encrypt, $id);
         if ($err) {
-            $exifTool->Warn($err);
+            $et->Warn($err);
             $$capture{Error} = $err if $capture;
             return -1;
@@ -1836,12 +2307,15 @@
 # extract the information beginning with each of the main dictionaries
 #
+    my $i = 0;
+    my $num = (scalar @mainDicts) / 2;
     while (@mainDicts) {
         my $dict = shift @mainDicts;
         my $type = shift @mainDicts;
         if ($verbose) {
+            ++$i;
             my $n = scalar(@{$$dict{_tags}});
-            $exifTool->VPrint(0, "PDF dictionary with $n entries:\n");
-        }
-        ProcessDict($exifTool, $tagTablePtr, $dict, \%xref, 0, $type);
+            $et->VPrint(0, "PDF dictionary ($i of $num) with $n entries:\n");
+        }
+        ProcessDict($et, $tagTablePtr, $dict, \%xref, 0, $type);
     }
     # handle any decryption errors
@@ -1849,5 +2323,5 @@
         my $err = $$encrypt{_error};
         if ($err) {
-            $exifTool->Warn($err);
+            $et->Warn($err);
             $$capture{Error} = $err if $capture;
             return -1;
@@ -1877,12 +2351,12 @@
 sub ProcessPDF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
 
     undef $cryptInfo;   # (must not delete after returning so writer can use it)
     undef $cryptStream;
     undef $cryptString;
-    my $result = ReadPDF($exifTool, $dirInfo);
+    my $result = ReadPDF($et, $dirInfo);
     if ($result < 0) {
-        $exifTool->Warn($pdfWarning{$result}) if $pdfWarning{$result};
+        $et->Warn($pdfWarning{$result}) if $pdfWarning{$result};
         $result = 1;
     }
@@ -1916,5 +2390,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PGF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PGF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PGF.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.01';
+$VERSION = '1.02';
 
 # PGF header information
@@ -69,5 +69,5 @@
 sub ProcessPGF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -76,24 +76,24 @@
     return 0 unless $raf->Read($buff, 24) == 24 and $buff =~ /^PGF(.)/s;
     my $ver = ord $1;
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('II');
 
     # currently support only version 0x36
     unless ($ver == 0x36) {
-        $exifTool->Error(sprintf('Unsupported PGF version 0x%.2x', $ver));
+        $et->Error(sprintf('Unsupported PGF version 0x%.2x', $ver));
         return 1;
     }
     # extract information from the PGF header
     my $tagTablePtr = GetTagTable('Image::ExifTool::PGF::Main');
-    $exifTool->ProcessDirectory({ DataPt => \$buff, DataPos => 0 }, $tagTablePtr);
+    $et->ProcessDirectory({ DataPt => \$buff, DataPos => 0 }, $tagTablePtr);
 
     my $len = Get32u(\$buff, 4) - 16; # length of post-header data
 
     # skip colour table if necessary
-    $len -= $raf->Seek(1024, 1) ? 1024 : $len if $$exifTool{PGFColorMode} == 2;
+    $len -= $raf->Seek(1024, 1) ? 1024 : $len if $$et{PGFColorMode} == 2;
 
     # extract information from the embedded metadata image (PNG format)
     if ($len > 0 and $len < 0x1000000 and $raf->Read($buff, $len) == $len) {
-        $exifTool->ExtractInfo(\$buff, { ReEntry => 1 });
+        $et->ExtractInfo(\$buff, { ReEntry => 1 });
     }
     return 1;
@@ -120,5 +120,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PICT.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PICT.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PICT.pm	(revision 34921)
@@ -21,5 +21,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.03';
+$VERSION = '1.05';
 
 sub ReadPictValue($$$;$);
@@ -274,5 +274,5 @@
 # PICT image opcodes
 %Image::ExifTool::PICT::Main = (
-    PROCESS_PROC => 0,  # set this to zero to omit tags from lookup
+    VARS => { NO_LOOKUP => 1 }, # omit tags from lookup
     NOTES => q{
 The PICT format contains no true meta information, except for the possible
@@ -822,5 +822,5 @@
     },
     0x00a1 => [
-        # this list for documentation only [not currently extracted]
+        # this list for documentation only [currently not extracted]
         {
             # (not actually a full Photohop IRB record it appears, but it does start
@@ -1025,5 +1025,5 @@
                         my %parms = ( Out => $out );
                         $parms{MaxLen} = 96 if $verbose < 4;
-                        Image::ExifTool::HexDump(\$val, undef, %parms);
+                        HexDump(\$val, undef, %parms);
                     }
                 } else {
@@ -1055,5 +1055,5 @@
                         my %parms = ( Out => $out );
                         $parms{MaxLen} = 96 if $verbose < 4;
-                        Image::ExifTool::HexDump($val, undef, %parms);
+                        HexDump($val, undef, %parms);
                     }
                 }
@@ -1082,8 +1082,8 @@
 sub ProcessPICT($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    $verbose = $exifTool->Options('Verbose');
-    $out = $exifTool->Options('TextOut');
+    $verbose = $et->Options('Verbose');
+    $out = $et->Options('TextOut');
     $indent = '';
     my ($buff, $tried, @hdr, $op, $hRes, $vRes);
@@ -1096,5 +1096,5 @@
         $op = pop @hdr;
         # check for PICT version 1 format
-        if ($op eq 0x1101) {
+        if ($op == 0x1101) {
             $vers = 1;
             undef $extended;
@@ -1102,5 +1102,5 @@
         }
         # 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/) {
@@ -1139,12 +1139,12 @@
         $h = int($h * $vRes / 72 + 0.5);
     }
-    $exifTool->SetFileType();
-    $exifTool->FoundTag('ImageWidth', $w);
-    $exifTool->FoundTag('ImageHeight', $h);
-    $exifTool->FoundTag('XResolution', $hRes) if $hRes;
-    $exifTool->FoundTag('YResolution', $vRes) if $vRes;
+    $et->SetFileType();
+    $et->FoundTag('ImageWidth', $w);
+    $et->FoundTag('ImageHeight', $h);
+    $et->FoundTag('XResolution', $hRes) if $hRes;
+    $et->FoundTag('YResolution', $vRes) if $vRes;
 
     # don't extract image opcodes unless verbose
-    return 1 unless $verbose or $exifTool->Options('Unknown');
+    return 1 unless $verbose or $et->Options('Unknown');
 
     $verbose and printf $out "PICT version $vers%s\n", $extended ? ' extended' : '';
@@ -1163,5 +1163,5 @@
             $op = unpack('n', $buff);
         }
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $op);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $op);
         unless ($tagInfo) {
             my $i;
@@ -1170,10 +1170,10 @@
                 next unless $op >= $reserved[$i];
                 last if $op > $reserved[$i+1];
-                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $reserved[$i]);
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $reserved[$i]);
                 last;
             }
             last unless $tagInfo;
         }
-        if ($op eq 0xff) {
+        if ($op == 0xff) {
             $verbose and print $out "End of picture\n";
             $success = 1;
@@ -1182,5 +1182,5 @@
         my $format = $$tagInfo{Format};
         unless ($format) {
-            $exifTool->Warn("Missing format for $$tagInfo{Name}");
+            $et->Warn("Missing format for $$tagInfo{Name}");
             last;
         }
@@ -1191,5 +1191,5 @@
         my $val = ReadPictValue($raf, $$tagInfo{Name}, $format);
         unless (defined $val) {
-            $exifTool->Warn("Error reading $$tagInfo{Name} information");
+            $et->Warn("Error reading $$tagInfo{Name} information");
             last;
         }
@@ -1201,13 +1201,13 @@
                 $val->{imageDescr}->{compressor} eq 'Photo - JPEG' and
                 ref $val->{imageData} eq 'SCALAR' and
-                $exifTool->ValidateImage($val->{imageData}, 'PreviewImage'))
+                $et->ValidateImage($val->{imageData}, 'PreviewImage'))
             {
-                $exifTool->FoundTag('PreviewImage', $val->{imageData});
+                $et->FoundTag('PreviewImage', $val->{imageData});
             }
         } else {
-            # $exifTool->FoundTag($tagInfo, $val);
+            # $et->FoundTag($tagInfo, $val);
         }
     }
-    $success or $exifTool->Warn('End of picture not found');
+    $success or $et->Warn('End of picture not found');
     return 1;
 }
@@ -1237,5 +1237,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PLIST.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PLIST.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PLIST.pm	(revision 34921)
@@ -0,0 +1,462 @@
+#------------------------------------------------------------------------------
+# File:         PLIST.pm
+#
+# Description:  Read Apple PLIST information
+#
+# Revisions:    2013-02-01 - P. Harvey Created
+#
+# References:   1) http://www.apple.com/DTDs/PropertyList-1.0.dtd
+#               2) http://opensource.apple.com/source/CF/CF-550/CFBinaryPList.c
+#
+# Notes:      - Sony MODD files also use XML PLIST format, but with a few quirks
+#
+#             - Decodes both the binary and XML-based PLIST formats
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PLIST;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::XMP;
+use Image::ExifTool::GPS;
+
+$VERSION = '1.09';
+
+sub ExtractObject($$;$);
+sub Get24u($$);
+
+# access routines to read various-sized integer/real values (add 0x100 to size for reals)
+my %readProc = (
+    1 => \&Get8u,
+    2 => \&Get16u,
+    3 => \&Get24u,
+    4 => \&Get32u,
+    8 => \&Get64u,
+    0x104 => \&GetFloat,
+    0x108 => \&GetDouble,
+);
+
+# recognize different types of PLIST files based on certain tags
+my %plistType = (
+    adjustmentBaseVersion => 'AAE',
+);
+
+# PLIST tags (generated on-the-fly for most tags)
+%Image::ExifTool::PLIST::Main = (
+    PROCESS_PROC => \&ProcessPLIST,
+    GROUPS => { 0 => 'PLIST', 1 => 'XML', 2 => 'Document' },
+    VARS => { LONG_TAGS => 4 },
+    NOTES => q{
+        Apple Property List tags.  ExifTool reads both XML and binary-format PLIST
+        files, and will extract any existing tags even if they aren't listed below.
+        These tags belong to the family 0 "PLIST" group, but family 1 group may be
+        either "XML" or "PLIST" depending on whether the format is XML or binary.
+    },
+#
+# tags found in PLIST information of QuickTime iTunesInfo iTunMOVI atom (ref PH)
+#
+    'cast//name'          => { Name => 'Cast',          List => 1 },
+    'directors//name'     => { Name => 'Directors',     List => 1 },
+    'producers//name'     => { Name => 'Producers',     List => 1 },
+    'screenwriters//name' => { Name => 'Screenwriters', List => 1 },
+    'codirectors//name'   => { Name => 'Codirectors',   List => 1 }, # (NC)
+    'studio//name'        => { Name => 'Studio',        List => 1 }, # (NC)
+#
+# tags found in MODD files (ref PH)
+#
+    'MetaDataList//DateTimeOriginal' => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        # Sony uses a "real" here -- number of days since Dec 31, 1899
+        ValueConv => 'IsFloat($val) ? ConvertUnixTime(($val - 25569) * 24 * 3600) : $val',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    'MetaDataList//Duration' => {
+        Name => 'Duration',
+        Groups => { 2 => 'Video' },
+        PrintConv => 'ConvertDuration($val)',
+    },
+    'MetaDataList//Geolocation/Latitude' => {
+        Name => 'GPSLatitude',
+        Groups => { 2 => 'Location' },
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    },
+    'MetaDataList//Geolocation/Longitude' => {
+        Name => 'GPSLongitude',
+        Groups => { 2 => 'Location' },
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    },
+    'MetaDataList//Geolocation/MapDatum' => {
+        Name => 'GPSMapDatum',
+        Groups => { 2 => 'Location' },
+    },
+    XMLFileType => {
+        # recognize MODD files by their content
+        RawConv => q{
+            if ($val eq 'ModdXML' and $$self{FILE_TYPE} eq 'XMP') {
+                $self->OverrideFileType('MODD');
+            }
+            return $val;
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# We found a PLIST XML property name/value
+# Inputs: 0) ExifTool object ref, 1) tag table ref
+#         2) reference to array of XML property names (last is current property)
+#         3) property value, 4) attribute hash ref (not used here)
+# Returns: 1 if valid tag was found
+sub FoundTag($$$$;$)
+{
+    my ($et, $tagTablePtr, $props, $val, $attrs) = @_;
+    return 0 unless @$props;
+    my $verbose = $et->Options('Verbose');
+    my $keys = $$et{PListKeys} || ( $$et{PListKeys} = [] );
+
+    my $prop = $$props[-1];
+    if ($verbose > 1) {
+        $et->VPrint(0, $$et{INDENT}, '[', join('/',@$props), ' = ',
+                    $et->Printable($val), "]\n");
+    }
+    # un-escape XML character entities
+    $val = Image::ExifTool::XMP::UnescapeXML($val);
+
+    # handle the various PLIST properties
+    if ($prop eq 'data') {
+        if ($val =~ /^[0-9a-f]+$/ and not length($val) & 0x01) {
+            # MODD files use ASCII-hex encoded "data"...
+            my $buff = pack('H*', $val);
+            $val = \$buff;
+        } else {
+            # ...but the PLIST DTD specifies Base64 encoding
+            $val = Image::ExifTool::XMP::DecodeBase64($val);
+        }
+    } elsif ($prop eq 'date') {
+        $val = Image::ExifTool::XMP::ConvertXMPDate($val);
+    } elsif ($prop eq 'true' or $prop eq 'false') {
+        $val = ucfirst $prop;
+    } else {
+        # convert from UTF8 to ExifTool Charset
+        $val = $et->Decode($val, 'UTF8');
+        if ($prop eq 'key') {
+            if (@$props <= 3) { # top-level key should be plist/dict/key
+                @$keys = ( $val );
+            } else {
+                # save key names to be used in tag name
+                push @$keys, '' while @$keys < @$props - 3;
+                pop @$keys while @$keys > @$props - 2;
+                $$keys[@$props - 3] = $val;
+            }
+            return 0;
+        }
+    }
+
+    return 0 unless @$keys; # can't store value if no associated key
+
+    my $tag = join '/', @$keys;     # generate tag ID from 'key' values
+    my $tagInfo = $$tagTablePtr{$tag};
+    unless ($tagInfo) {
+        $et->VPrint(0, $$et{INDENT}, "[adding $tag]\n") if $verbose;
+        # generate tag name from ID
+        my $name = $tag;
+        $name =~ s{^MetaDataList//}{};  # shorten long MODD metadata tag names
+        $name =~ s{//name$}{};          # remove unnecessary MODD "name" property
+        $name =~ s/([^A-Za-z])([a-z])/$1\u$2/g; # capitalize words
+        $name =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
+        $tagInfo = { Name => ucfirst($name), List => 1 };
+        if ($prop eq 'date') {
+            $$tagInfo{Groups}{2} = 'Time';
+            $$tagInfo{PrintConv} = '$self->ConvertDateTime($val)';
+        }
+        AddTagToTable($tagTablePtr, $tag, $tagInfo);
+    }
+    # allow list-behaviour only for consecutive tags with the same ID
+    if ($$et{LastPListTag} and $$et{LastPListTag} ne $tagInfo) {
+        delete $$et{LIST_TAGS}{$$et{LastPListTag}};
+    }
+    $$et{LastPListTag} = $tagInfo;
+    # override file type if applicable
+    $et->OverrideFileType($plistType{$tag}) if $plistType{$tag} and $$et{FILE_TYPE} eq 'XMP';
+    # save the tag
+    $et->HandleTag($tagTablePtr, $tag, $val);
+
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Get big-endian 24-bit integer
+# Inputs: 0) data ref, 1) offset
+# Returns: integer value
+sub Get24u($$)
+{
+    my ($dataPt, $off) = @_;
+    return unpack 'N', "\0" . substr($$dataPt, $off, 3);
+}
+
+#------------------------------------------------------------------------------
+# Extract object from binary PLIST file at the current file position (ref 2)
+# Inputs: 0) ExifTool ref, 1) PLIST info ref, 2) parent tag ID (undef for top)
+# Returns: the object, or undef on error
+sub ExtractObject($$;$)
+{
+    my ($et, $plistInfo, $parent) = @_;
+    my $raf = $$plistInfo{RAF};
+    my ($buff, $val);
+
+    $raf->Read($buff, 1) == 1 or return undef;
+    my $type = ord($buff) >> 4;
+    my $size = ord($buff) & 0x0f;
+    if ($type == 0) {       # null/bool/fill
+        $val = { 0x00=>'<null>', 0x08=>'True', 0x09=>'False', 0x0f=>'<fill>' }->{$size};
+    } elsif ($type == 1 or $type == 2 or $type == 3) { # int, float or date
+        $size = 1 << $size;
+        my $proc = ($type == 1 ? $readProc{$size} : $readProc{$size + 0x100}) or return undef;
+        $val = &$proc(\$buff, 0) if $raf->Read($buff, $size) == $size;
+        if ($type == 3 and defined $val) {   # date
+            # dates are referenced to Jan 1, 2001 (11323 days from Unix time zero)
+            $val = Image::ExifTool::ConvertUnixTime($val + 11323 * 24 * 3600, 1);
+            $$plistInfo{DateFormat} = 1;
+        }
+    } elsif ($type == 8) {  # UID
+        ++$size;
+        $raf->Read($buff, $size) == $size or return undef;
+        my $proc = $readProc{$size};
+        if ($proc) {
+            $val = &$proc(\$buff, 0);
+        } elsif ($size == 16) {
+            require Image::ExifTool::ASF;
+            $val = Image::ExifTool::ASF::GetGUID($buff);
+        } else {
+            $val = "0x" . unpack 'H*', $buff;
+        }
+    } else {
+        # $size is the size of the remaining types
+        if ($size == 0x0f) {
+            # size is stored in extra integer object
+            $size = ExtractObject($et, $plistInfo);
+            return undef unless defined $size and $size =~ /^\d+$/;
+        }
+        if ($type == 4) {  # data
+            if ($size < 1000000 or $et->Options('Binary')) {
+                $raf->Read($buff, $size) == $size or return undef;
+            } else {
+                $buff = "Binary data $size bytes";
+            }
+            $val = \$buff;  # (return reference for binary data)
+        } elsif ($type == 5) {  # ASCII string
+            $raf->Read($val, $size) == $size or return undef;
+        } elsif ($type == 6) {  # UCS-2BE string
+            $size *= 2;
+            $raf->Read($buff, $size) == $size or return undef;
+            $val = $et->Decode($buff, 'UCS2');
+        } elsif ($type == 10 or $type == 12 or $type == 13) { # array, set or dict
+            # the remaining types store a list of references
+            my $refSize = $$plistInfo{RefSize};
+            my $refProc = $$plistInfo{RefProc};
+            my $num = $type == 13 ? $size * 2 : $size;
+            my $len = $num * $refSize;
+            $raf->Read($buff, $len) == $len or return undef;
+            my $table = $$plistInfo{Table};
+            my ($i, $ref, @refs, @array);
+            for ($i=0; $i<$num; ++$i) {
+                my $ref = &$refProc(\$buff, $i * $refSize);
+                return 0 if $ref >= @$table;
+                push @refs, $ref;
+            }
+            if ($type == 13) { # dict
+                # prevent infinite recursion
+                if (defined $parent and length $parent > 1000) {
+                    $et->WarnOnce('Possible deep recursion while parsing PLIST');
+                    return undef;
+                }
+                my $tagTablePtr = $$plistInfo{TagTablePtr};
+                my $verbose = $et->Options('Verbose');
+                for ($i=0; $i<$size; ++$i) {
+                    # get the entry key
+                    $raf->Seek($$table[$refs[$i]], 0) or return undef;
+                    my $key = ExtractObject($et, $plistInfo);
+                    next unless defined $key and length $key; # silently ignore bad dict entries
+                    # get the entry value
+                    $raf->Seek($$table[$refs[$i+$size]], 0) or return undef;
+                    # generate an ID for this tag
+                    my $tag = defined $parent ? "$parent/$key" : $key;
+                    undef $$plistInfo{DateFormat};
+                    my $val = ExtractObject($et, $plistInfo, $tag);
+                    next if not defined $val or ref($val) eq 'HASH';
+                    my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+                    unless ($tagInfo) {
+                        $et->VPrint(0, $$et{INDENT}, "[adding $tag]\n") if $verbose;
+                        my $name = $tag;
+                        $name =~ s/([^A-Za-z])([a-z])/$1\u$2/g; # capitalize words
+                        $name =~ tr/-_a-zA-Z0-9//dc; # remove illegal characters
+                        $tagInfo = { Name => ucfirst($name), List => 1 };
+                        if ($$plistInfo{DateFormat}) {
+                            $$tagInfo{Groups}{2} = 'Time';
+                            $$tagInfo{PrintConv} = '$self->ConvertDateTime($val)';
+                        }
+                        AddTagToTable($tagTablePtr, $tag, $tagInfo);
+                    }
+                    # allow list-behaviour only for consecutive tags with the same ID
+                    if ($$et{LastPListTag} and $$et{LastPListTag} ne $tagInfo) {
+                        delete $$et{LIST_TAGS}{$$et{LastPListTag}};
+                    }
+                    $$et{LastPListTag} = $tagInfo;
+                    $et->HandleTag($tagTablePtr, $tag, $val);
+                }
+                $val = { }; # flag the value as a dictionary (ie. tags already saved)
+            } else {
+                # extract the referenced objects
+                foreach $ref (@refs) {
+                    $raf->Seek($$table[$ref], 0) or return undef;   # seek to this object
+                    $val = ExtractObject($et, $plistInfo, $parent);
+                    next unless defined $val and ref $val ne 'HASH';
+                    push @array, $val;
+                }
+                $val = \@array;
+            }
+        }
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Process binary PLIST data (ref 2)
+# Inputs: 0) ExifTool object ref, 1) DirInfo ref, 2) tag table ref
+# Returns: 1 on success (and returns plist value as $$dirInfo{Value})
+sub ProcessBinaryPLIST($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my ($i, $buff, @table);
+    my $dataPt = $$dirInfo{DataPt};
+
+    $et->VerboseDir('Binary PLIST');
+    SetByteOrder('MM');
+
+    if ($dataPt) {
+        my $start = $$dirInfo{DirStart};
+        if ($start or ($$dirInfo{DirLen} and $$dirInfo{DirLen} != length $$dataPt)) {
+            my $buf2 = substr($$dataPt, $start || 0, $$dirInfo{DirLen});
+            $$dirInfo{RAF} = new File::RandomAccess(\$buf2);
+        } else {
+            $$dirInfo{RAF} = new File::RandomAccess($dataPt);
+        }
+        my $strt = $$dirInfo{DirStart} || 0;
+    }
+    # read and parse the trailer
+    my $raf = $$dirInfo{RAF} or return 0;
+    $raf->Seek(-32,2) and $raf->Read($buff,32)==32 or return 0;
+    my $intSize = Get8u(\$buff, 6);
+    my $refSize = Get8u(\$buff, 7);
+    my $numObj = Get64u(\$buff, 8);
+    my $topObj = Get64u(\$buff, 16);
+    my $tableOff = Get64u(\$buff, 24);
+
+    return 0 if $topObj >= $numObj;
+    my $intProc = $readProc{$intSize} or return 0;
+    my $refProc = $readProc{$refSize} or return 0;
+
+    # read and parse the offset table
+    my $tableSize = $intSize * $numObj;
+    $raf->Seek($tableOff, 0) and $raf->Read($buff, $tableSize) == $tableSize or return 0;
+    for ($i=0; $i<$numObj; ++$i) {
+        push @table, &$intProc(\$buff, $i * $intSize);
+    }
+    my %plistInfo = (
+        RAF => $raf,
+        RefSize => $refSize,
+        RefProc => $refProc,
+        Table => \@table,
+        TagTablePtr => $tagTablePtr,
+    );
+    # position file pointer at the top object, and extract it
+    $raf->Seek($table[$topObj], 0) or return 0;
+    $$dirInfo{Value} = ExtractObject($et, \%plistInfo);
+    return defined $$dirInfo{Value} ? 1 : 0;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a PLIST file
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success, 0 if this wasn't valid PLIST
+sub ProcessPLIST($$;$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+
+    # process XML PLIST data using the XMP module
+    $$dirInfo{XMPParseOpts}{FoundProc} = \&FoundTag;
+    my $result = Image::ExifTool::XMP::ProcessXMP($et, $dirInfo, $tagTablePtr);
+    delete $$dirInfo{XMPParseOpts};
+
+    unless ($result) {
+        my $buff;
+        my $raf = $$dirInfo{RAF} or return 0;
+        $raf->Seek(0,0) and $raf->Read($buff, 64) or return 0;
+        if ($buff =~ /^bplist0/) {
+            # binary PLIST file
+            my $tagTablePtr = GetTagTable('Image::ExifTool::PLIST::Main');
+            $et->SetFileType('PLIST', 'application/x-plist');
+            $$et{SET_GROUP1} = 'PLIST';
+            unless (ProcessBinaryPLIST($et, $dirInfo, $tagTablePtr)) {
+                $et->Error('Error reading binary PLIST file');
+            }
+            delete $$et{SET_GROUP1};
+            $result = 1;
+        } elsif ($$et{FILE_EXT} and $$et{FILE_EXT} eq 'PLIST' and
+            $buff =~ /^\xfe\xff\x00/)
+        {
+            # (have seen very old PLIST files encoded as UCS-2BE with leading BOM)
+            $et->Error('Old PLIST format currently not supported');
+            $result = 1;
+        }
+    }
+    return $result;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PLIST - Read Apple PLIST information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains the routines used by Image::ExifTool to extract
+information from Apple Property List files.
+
+=head1 NOTES
+
+This module decodes both the binary and XML-based PLIST format.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.apple.com/DTDs/PropertyList-1.0.dtd>
+
+=item L<http://opensource.apple.com/source/CF/CF-550/CFBinaryPList.c>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PLIST Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PLUS.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PLUS.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PLUS.pm	(revision 34921)
@@ -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-2021, 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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PNG.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PNG.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PNG.pm	(revision 34921)
@@ -13,4 +13,5 @@
 #               4) http://www.libpng.org/pub/png/spec/register/
 #               5) ftp://ftp.simplesystems.org/pub/png/documents/pngext-1.4.0-pdg.html
+#               6) ftp://ftp.simplesystems.org/pub/png/documents/pngext-1.5.0.html
 #
 # Notes:        Writing meta information in PNG images is a pain in the butt
@@ -19,4 +20,13 @@
 #               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).
 #------------------------------------------------------------------------------
 
@@ -24,18 +34,25 @@
 
 use strict;
-use vars qw($VERSION $AUTOLOAD);
+use vars qw($VERSION $AUTOLOAD %stdCase);
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.24';
+$VERSION = '1.56';
 
 sub ProcessPNG_tEXt($$$);
 sub ProcessPNG_iTXt($$$);
+sub ProcessPNG_eXIf($$$);
 sub ProcessPNG_Compressed($$$);
 sub CalculateCRC($;$$$);
 sub HexEncode($);
-sub AddChunks($$);
+sub AddChunks($$;@);
 sub Add_iCCP($$);
+sub DoneDir($$$;$);
 sub GetLangInfo($$);
 sub BuildTextChunk($$$$$);
+sub ConvertPNGDate($$);
+sub InversePNGDate($$);
+
+# translate lower-case to actual case used for eXIf/zXIf chunks
+%stdCase = ( 'zxif' => 'zxIf', exif => 'eXIf' );
 
 my $noCompressLib;
@@ -63,4 +80,5 @@
     ICC_Profile  => 'PNG',
     Photoshop    => 'PNG',
+   'PNG-pHYs'    => 'PNG',
     IPTC         => 'Photoshop',
     MakerNotes   => 'ExifIFD',
@@ -69,4 +87,12 @@
 # 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
@@ -79,4 +105,23 @@
         L<http://www.libpng.org/pub/png/spec/1.2/> for the official PNG 1.2
         specification.
+
+        According to the specification, a PNG file should end at the IEND chunk,
+        however ExifTool will preserve any data found after this when writing unless
+        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 => {
@@ -98,4 +143,8 @@
     gAMA => {
         Name => 'Gamma',
+        Notes => q{
+            ExifTool reports the gamma for decoding the image, which is consistent with
+            the EXIF convention, but is the inverse of the stored encoding gamma
+        },
         ValueConv => 'my $a=unpack("N",$val);$a ? int(1e9/$a+0.5)/1e4 : $val',
     },
@@ -118,8 +167,13 @@
     iCCP => {
         Name => 'ICC_Profile',
+        Notes => 'this is where ExifTool will write a new ICC_Profile',
         SubDirectory => {
             TagTable => 'Image::ExifTool::ICC_Profile::Main',
             ProcessProc => \&ProcessPNG_Compressed,
         },
+    },
+   'iCCP-name' => {
+        Name => 'ProfileName',
+        Notes => 'not a real tag ID, this tag represents the iCCP profile name',
     },
 #   IDAT
@@ -150,5 +204,8 @@
     pHYs => {
         Name => 'PhysicalPixel',
-        SubDirectory => { TagTable => 'Image::ExifTool::PNG::PhysicalPixel' },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PNG::PhysicalPixel',
+            DirName => 'PNG-pHYs', # (needed for writing)
+        },
     },
     PLTE => {
@@ -210,5 +267,6 @@
     tXMP => {
         Name => 'XMP',
-        Notes => 'obsolete location specified by older XMP draft',
+        Notes => 'obsolete location specified by a September 2001 XMP draft',
+        NonStandard => 'XMP',
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     },
@@ -223,4 +281,46 @@
             ProcessProc => \&ProcessPNG_Compressed,
         },
+    },
+    # animated PNG (ref https://wiki.mozilla.org/APNG_Specification)
+    acTL => {
+        Name => 'AnimationControl',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PNG::AnimationControl',
+        },
+    },
+    # eXIf (ref 6)
+    $stdCase{exif} => {
+        Name => $stdCase{exif},
+        Notes => 'this is where ExifTool will create new EXIF',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            DirName => 'EXIF', # (to write as a block)
+            ProcessProc => \&ProcessPNG_eXIf,
+        },
+    },
+    # zXIf
+    $stdCase{zxif} => {
+        Name => $stdCase{zxif},
+        Notes => 'a once-proposed chunk for compressed EXIF',
+        NonStandard => 'EXIF',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            DirName => 'EXIF', # (to write as a block)
+            ProcessProc => \&ProcessPNG_eXIf,
+        },
+    },
+    # fcTL - animation frame control for each frame
+    # fdAT - animation data for each frame
+    iDOT => { # (ref NealKrawetz)
+        Name => 'AppleDataOffsets',
+        Binary => 1,
+        # Apple offsets into data relative to start of iDOT chunk:
+        #    int32u Divisor  [only ever seen 2]
+        #    int32u Unknown  [always 0]
+        #    int32u TotalDividedHeight  [image height from IDHR/Divisor]
+        #    int32u Size  [always 40 / 0x28; size of this chunk]
+        #    int32u DividedHeight1
+        #    int32u DividedHeight2
+        #    int32u IDAT_Offset2 [location of IDAT with start of DividedHeight2 segment]
     },
 );
@@ -282,16 +382,27 @@
 %Image::ExifTool::PNG::PhysicalPixel = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
-    GROUPS => { 2 => 'Image' },
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    WRITABLE => 1,
+    GROUPS => { 1 => 'PNG-pHYs', 2 => 'Image' },
+    WRITE_GROUP => 'PNG-pHYs',
+    NOTES => q{
+        These tags are found in the PNG pHYs chunk and belong to the PNG-pHYs family
+        1 group.  They are all created together with default values if necessary
+        when any of these tags is written, and may only be deleted as a group.
+    },
     0 => {
         Name => 'PixelsPerUnitX',
         Format => 'int32u',
+        Notes => 'default 2834',
     },
     4 => {
         Name => 'PixelsPerUnitY',
         Format => 'int32u',
+        Notes => 'default 2834',
     },
     8 => {
         Name => 'PixelUnits',
-        PrintConv => { 0 => 'Unknown', 1 => 'Meters' },
+        PrintConv => { 0 => 'Unknown', 1 => 'meters' },
+        Notes => 'default meters',
     },
 );
@@ -303,5 +414,5 @@
     0 => {
         Name => 'SubjectUnits',
-        PrintConv => { 1 => 'Meters', 2 => 'Radians' },
+        PrintConv => { 1 => 'meters', 2 => 'radians' },
     },
     1 => {
@@ -357,17 +468,18 @@
         listed below are the only ones that can be written (unless new user-defined
         tags are added via the configuration file), however ExifTool will extract
-        any other TextualData tags that are found.
-        
+        any other TextualData tags that are found.  All TextualData tags (including
+        tags not listed below) are removed when deleting all PNG tags.
+
         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.
 
         Alternate languages are accessed by suffixing the tag name with a '-',
-        followed by an RFC 3066 language code (ie. "PNG:Comment-fr", or
+        followed by an RFC 3066 language code (eg. "PNG:Comment-fr", or
         "Title-en-US").  See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC 3066
         specification.
@@ -385,4 +497,9 @@
         Groups => { 2 => 'Time' },
         Shift => 'Time',
+        Notes => 'stored in RFC-1123 format and converted to/from EXIF format by ExifTool',
+        RawConv => \&ConvertPNGDate,
+        ValueConvInv => \&InversePNGDate,
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,undef,1)',
     },
     Software    => { },
@@ -392,4 +509,5 @@
     Source      => { },
     Comment     => { },
+    Collection  => { }, # (PNG extensions, 2004)
 #
 # The following tags are not part of the original PNG specification,
@@ -426,11 +544,9 @@
         Name => 'XMP',
         Notes => q{
-            unregistered, but this is the location according to the 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',
-        },
+            unregistered, but this is the location according to the June 2002 or later
+            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' },
     },
    'Raw profile type APP1' => [
@@ -440,6 +556,7 @@
             Name => 'APP1_Profile',
             %unreg,
+            NonStandard => 'EXIF',
             SubDirectory => {
-                TagTable=>'Image::ExifTool::Exif::Main',
+                TagTable => 'Image::ExifTool::Exif::Main',
                 ProcessProc => \&ProcessProfile,
             },
@@ -447,6 +564,7 @@
         {
             Name => 'APP1_Profile',
+            NonStandard => 'XMP',
             SubDirectory => {
-                TagTable=>'Image::ExifTool::XMP::Main',
+                TagTable => 'Image::ExifTool::XMP::Main',
                 ProcessProc => \&ProcessProfile,
             },
@@ -456,6 +574,7 @@
         Name => 'EXIF_Profile',
         %unreg,
+        NonStandard => 'EXIF',
         SubDirectory => {
-            TagTable=>'Image::ExifTool::Exif::Main',
+            TagTable => 'Image::ExifTool::Exif::Main',
             ProcessProc => \&ProcessProfile,
         },
@@ -479,4 +598,24 @@
    'Raw profile type iptc' => {
         Name => 'IPTC_Profile',
+        Notes => q{
+            unregistered.  May be either IPTC IIM or Photoshop IRB format.  This is
+            where ExifTool will add new IPTC, inside a Photoshop IRB container
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Photoshop::Main',
+            ProcessProc => \&ProcessProfile,
+        },
+    },
+   'Raw profile type xmp' => {
+        Name => 'XMP_Profile',
+        %unreg,
+        NonStandard => 'XMP',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::Main',
+            ProcessProc => \&ProcessProfile,
+        },
+    },
+    'Raw profile type 8bim' => {
+        Name => 'Photoshop_Profile',
         %unreg,
         SubDirectory => {
@@ -485,11 +624,22 @@
         },
     },
-   'Raw profile type xmp' => {
-        Name => 'XMP_Profile',
-        %unreg,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::XMP::Main',
-            ProcessProc => \&ProcessProfile,
-        },
+);
+
+# Animation control
+%Image::ExifTool::PNG::AnimationControl = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    FORMAT => 'int32u',
+    NOTES => q{
+        Tags found in the Animation Control chunk.  See
+        L<https://wiki.mozilla.org/APNG_Specification> for details.
+    },
+    0 => {
+        Name => 'AnimationFrames',
+        RawConv => '$self->OverrideFileType("APNG", undef, "PNG"); $val',
+    },
+    1 => {
+        Name => 'AnimationPlays',
+        PrintConv => '$val || "inf"',
     },
 );
@@ -516,6 +666,88 @@
 
 #------------------------------------------------------------------------------
+# Convert date from PNG to EXIF format
+# Inputs: 0) Date/time in PNG format, 1) ExifTool ref
+# Returns: EXIF formatted date/time string
+my %monthNum = (
+    Jan=>1, Feb=>2, Mar=>3, Apr=>4, May=>5, Jun=>6,
+    Jul=>7, Aug=>8, Sep=>9, Oct=>10,Nov=>11,Dec=>12
+);
+my %tzConv = (
+    UT  => '+00:00',  GMT => '+00:00',  UTC => '+00:00', # (UTC not in spec -- PH addition)
+    EST => '-05:00',  EDT => '-04:00',
+    CST => '-06:00',  CDT => '-05:00',
+    MST => '-07:00',  MDT => '-06:00',
+    PST => '-08:00',  PDT => '-07:00',
+    A => '-01:00',    N => '+01:00',
+    B => '-02:00',    O => '+02:00',
+    C => '-03:00',    P => '+03:00',
+    D => '-04:00',    Q => '+04:00',
+    E => '-05:00',    R => '+05:00',
+    F => '-06:00',    S => '+06:00',
+    G => '-07:00',    T => '+07:00',
+    H => '-08:00',    U => '+08:00',
+    I => '-09:00',    V => '+09:00',
+    K => '-10:00',    W => '+10:00',
+    L => '-11:00',    X => '+11:00',
+    M => '-12:00',    Y => '+12:00',
+    Z => '+00:00',
+);
+sub ConvertPNGDate($$)
+{
+    my ($val, $et) = @_;
+    # standard format is like "Mon, 1 Jan 2018 12:10:22 EST" (RFC-1123 section 5.2.14)
+    while ($val =~ /(\d+)\s*(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s*(\d+)\s+(\d+):(\d{2})(:\d{2})?\s*(\S*)/i) {
+        my ($day,$mon,$yr,$hr,$min,$sec,$tz) = ($1,$2,$3,$4,$5,$6,$7);
+        $yr += $yr > 70 ? 1900 : 2000 if $yr < 100;     # boost year to 4 digits if necessary
+        $mon = $monthNum{ucfirst lc $mon} or return $val;
+        if (not $tz) {
+            $tz = '';
+        } elsif ($tzConv{uc $tz}) {
+            $tz = $tzConv{uc $tz};
+        } elsif ($tz =~ /^([-+]\d+):?(\d{2})/) {
+            $tz = $1 . ':' . $2;
+        } else {
+            last;       # (non-standard date)
+        }
+        return sprintf("%.4d:%.2d:%.2d %.2d:%.2d%s%s",$yr,$mon,$day,$hr,$min,$sec||':00',$tz);
+    }
+    if (($et->Options('StrictDate') and not $$et{TAGS_FROM_FILE}) or $et->Options('Validate')) {
+        $et->Warn('Non standard PNG date/time format', 1);
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Convert EXIF date/time to PNG format
+# Inputs: 0) Date/time in EXIF format, 1) ExifTool ref
+# Returns: PNG formatted date/time string
+sub InversePNGDate($$)
+{
+    my ($val, $et) = @_;
+    if ($et->Options('StrictDate')) {
+        my $err;
+        if ($val =~ /^(\d{4}):(\d{2}):(\d{2}) (\d{2})(:\d{2})(:\d{2})?(?:\.\d*)?\s*(\S*)/) {
+            my ($yr,$mon,$day,$hr,$min,$sec,$tz) = ($1,$2,$3,$4,$5,$6,$7);
+            $sec or $sec = '';
+            my %monName = map { $monthNum{$_} => $_ } keys %monthNum;
+            $mon = $monName{$mon + 0} or $err = 1;
+            if (length $tz) {
+                $tz =~ /^(Z|[-+]\d{2}:?\d{2})/ or $err = 1;
+                $tz =~ tr/://d;
+                $tz = ' ' . $tz;
+            }
+            $val = "$day $mon $yr $hr$min$sec$tz" unless $err;
+        }
+        if ($err) {
+            warn "Invalid date/time (use YYYY:mm:dd HH:MM:SS[.ss][+/-HH:MM|Z])\n";
+            undef $val;
+        }
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
 # Get localized version of tagInfo hash
-# Inputs: 0) tagInfo hash ref, 1) language code (ie. "x-default")
+# Inputs: 0) tagInfo hash ref, 1) language code (eg. "x-default")
 # Returns: new tagInfo hash ref, or undef if invalid
 sub GetLangInfo($$)
@@ -539,8 +771,8 @@
 sub FoundPNG($$$$;$$$$)
 {
-    my ($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, $enc, $lang) = @_;
+    my ($et, $tagTablePtr, $tag, $val, $compressed, $outBuff, $enc, $lang) = @_;
     return 0 unless defined $val;
-    my $verbose = $exifTool->Options('Verbose');
-    my $id = $tag;  # generate tag ID which include language code
+    my $verbose = $et->Options('Verbose');
+    my $id = $tag;  # generate tag ID which includes language code
     if ($lang) {
         # case of language code must be normalized since they are case insensitive
@@ -548,11 +780,11 @@
         $id .= '-' . $lang;
     }
-    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $id) ||
+    my $tagInfo = $et->GetTagInfo($tagTablePtr, $id) ||
                   # (some software forgets to capitalize first letter)
-                  $exifTool->GetTagInfo($tagTablePtr, ucfirst($id));
+                  $et->GetTagInfo($tagTablePtr, ucfirst($id));
     # create alternate language tag if necessary
     if (not $tagInfo and $lang) {
-        $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag) ||
-                   $exifTool->GetTagInfo($tagTablePtr, ucfirst($tag));
+        $tagInfo = $et->GetTagInfo($tagTablePtr, $tag) ||
+                   $et->GetTagInfo($tagTablePtr, ucfirst($tag));
         $tagInfo = GetLangInfo($tagInfo, $lang) if $tagInfo;
     }
@@ -563,5 +795,5 @@
     if ($compressed and $compressed > 1) {
         if ($compressed == 2) { # Inflate/Deflate compression
-            if (eval 'require Compress::Zlib') {
+            if (eval { require Compress::Zlib }) {
                 my ($v2, $stat);
                 my $inflate = Compress::Zlib::inflateInit();
@@ -584,11 +816,9 @@
         }
         if ($compressed and $verbose and $tagInfo and $$tagInfo{SubDirectory}) {
-            $exifTool->VerboseDir("Unable to decompress $$tagInfo{Name}", 0, length($val));
+            $et->VerboseDir("Unable to decompress $$tagInfo{Name}", 0, length($val));
         }
         # issue warning if relevant
-        if ($deflateErr and (not $outBuff or
-            ($tagInfo and $$tagInfo{SubDirectory} and $$exifTool{EDIT_DIRS}{$$tagInfo{Name}})))
-        {
-            $exifTool->Warn($deflateErr);
+        if ($deflateErr and not $outBuff) {
+            $et->Warn($deflateErr);
             $noCompressLib = 1 if $deflateErr =~ /^Install/;
         }
@@ -596,5 +826,5 @@
     # translate character encoding if necessary (tEXt/zTXt/iTXt string values only)
     if ($enc and not $compressed and not ($tagInfo and $$tagInfo{SubDirectory})) {
-        $val = $exifTool->Decode($val, $enc);
+        $val = $et->Decode($val, $enc);
     }
 #
@@ -604,47 +834,68 @@
         my $tagName = $$tagInfo{Name};
         my $processed;
-        if ($$tagInfo{SubDirectory} and not $compressed) {
-            my $len = length $val;
-            if ($verbose and $exifTool->{INDENT} ne '  ') {
-                if ($wasCompressed and $verbose > 2) {
-                    my $name = $tagName;
-                    $wasCompressed and $name = "Decompressed $name";
-                    $exifTool->VerboseDir($name, 0, $len);
-                    $exifTool->VerboseDump(\$val);
+        if ($$tagInfo{SubDirectory}) {
+            if ($$et{OPTIONS}{Validate} and $$tagInfo{NonStandard}) {
+                $et->WarnOnce("Non-standard $$tagInfo{NonStandard} in PNG $tag chunk", 1);
+            }
+            my $subdir = $$tagInfo{SubDirectory};
+            my $dirName = $$subdir{DirName} || $tagName;
+            if (not $compressed) {
+                my $len = length $val;
+                if ($verbose and $$et{INDENT} ne '  ') {
+                    if ($wasCompressed and $verbose > 2) {
+                        my $name = $tagName;
+                        $wasCompressed and $name = "Decompressed $name";
+                        $et->VerboseDir($name, 0, $len);
+                        $et->VerboseDump(\$val);
+                    }
+                    # don't indent next directory (since it is really the same data)
+                    $$et{INDENT} =~ s/..$//;
                 }
-                # don't indent next directory (since it is really the same data)
-                $exifTool->{INDENT} =~ s/..$//;
-            }
-            my $subdir = $$tagInfo{SubDirectory};
-            my $processProc = $$subdir{ProcessProc};
-            # nothing more to do if writing and subdirectory is not writable
-            my $subTable = GetTagTable($$subdir{TagTable});
-            return 1 if $outBuff and not $$subTable{WRITE_PROC};
-            my %subdirInfo = (
-                DataPt   => \$val,
-                DirStart => 0,
-                DataLen  => $len,
-                DirLen   => $len,
-                DirName  => $tagName,
-                TagInfo  => $tagInfo,
-                ReadOnly => 1, # (only used by WriteXMP)
-                OutBuff  => $outBuff,
-            );
-            # no need to re-decompress if already done
-            undef $processProc if $wasCompressed and $processProc eq \&ProcessPNG_Compressed;
-            # rewrite this directory if necessary (but always process TextualData normally)
-            if ($outBuff and not $processProc and $subTable ne \%Image::ExifTool::PNG::TextualData) {
-                return 1 unless $exifTool->{EDIT_DIRS}->{$tagName};
-                $$outBuff = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
-                # if this was an XMP directory, we must make it read-only
-                $tagName eq 'XMP' and Image::ExifTool::XMP::ValidateXMP(\$outBuff,'r');
-                delete $exifTool->{ADD_DIRS}->{$tagName};
-            } else {
-                $processed = $exifTool->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
-            }
-            $compressed = 1;    # pretend this is compressed since it is binary data
+                my $processProc = $$subdir{ProcessProc};
+                # nothing more to do if writing and subdirectory is not writable
+                my $subTable = GetTagTable($$subdir{TagTable});
+                return 1 if $outBuff and not $$subTable{WRITE_PROC};
+                my $dirName = $$subdir{DirName} || $tagName;
+                my %subdirInfo = (
+                    DataPt   => \$val,
+                    DirStart => 0,
+                    DataLen  => $len,
+                    DirLen   => $len,
+                    DirName  => $dirName,
+                    TagInfo  => $tagInfo,
+                    ReadOnly => 1, # (used only by WriteXMP)
+                    OutBuff  => $outBuff,
+                );
+                # no need to re-decompress if already done
+                undef $processProc if $wasCompressed and $processProc and $processProc eq \&ProcessPNG_Compressed;
+                # rewrite this directory if necessary (but always process TextualData normally)
+                if ($outBuff and not $processProc and $subTable ne \%Image::ExifTool::PNG::TextualData) {
+                    return 1 unless $$et{EDIT_DIRS}{$dirName};
+                    $$outBuff = $et->WriteDirectory(\%subdirInfo, $subTable);
+                    if ($tagName eq 'XMP' and $$outBuff) {
+                        # make sure the XMP is marked as read-only
+                        Image::ExifTool::XMP::ValidateXMP($outBuff,'r');
+                    }
+                    DoneDir($et, $dirName, $outBuff, $$tagInfo{NonStandard});
+                } else {
+                    $processed = $et->ProcessDirectory(\%subdirInfo, $subTable, $processProc);
+                }
+                $compressed = 1;    # pretend this is compressed since it is binary data
+            } elsif ($outBuff) {
+                if ($$et{DEL_GROUP}{$dirName} or ($dirName eq 'EXIF' and $$et{DEL_GROUP}{IFD0})) {
+                    $$outBuff = '';
+                    ++$$et{CHANGED};
+                    $et->VPrint(0, "  Deleting $tag chunk");
+                } else {
+                    if ($$et{EDIT_DIRS}{$dirName} or ($dirName eq 'EXIF' and $$et{EDIT_DIRS}{IFD0})) {
+                        $et->Warn("Can't write $dirName. Requires Compress::Zlib");
+                    }
+                    # pretend we did this directory so we don't try to recreate it
+                    DoneDir($et, $dirName, $outBuff, $$tagInfo{NonStandard});
+                }
+            }
         }
         if ($outBuff) {
-            my $writable = $tagInfo->{Writable};
+            my $writable = $$tagInfo{Writable};
             my $isOverwriting;
             if ($writable or ($$tagTablePtr{WRITABLE} and
@@ -653,16 +904,16 @@
                 # write new value for this tag if necessary
                 my $newVal;
-                if ($exifTool->{DEL_GROUP}->{PNG}) {
+                if ($$et{DEL_GROUP}{PNG}){
                     # remove this tag now, but keep in ADD_PNG list to add back later
                     $isOverwriting = 1;
                 } else {
                     # remove this from the list of PNG tags to add
-                    delete $exifTool->{ADD_PNG}->{$id};
+                    delete $$et{ADD_PNG}{$id};
                     # (also handle case of tEXt tags written with lowercase first letter)
-                    delete $exifTool->{ADD_PNG}->{ucfirst($id)};
-                    my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-                    $isOverwriting = Image::ExifTool::IsOverwriting($nvHash);
+                    delete $$et{ADD_PNG}{ucfirst($id)};
+                    my $nvHash = $et->GetNewValueHash($tagInfo);
+                    $isOverwriting = $et->IsOverwriting($nvHash);
                     if (defined $deflateErr) {
-                        $newVal = Image::ExifTool::GetNewValues($nvHash);
+                        $newVal = $et->GetNewValue($nvHash);
                         # can only write tag now if always overwriting
                         if ($isOverwriting > 0) {
@@ -670,37 +921,39 @@
                         } elsif ($isOverwriting) {
                             $isOverwriting = 0; # can't overwrite
-                            $exifTool->Warn($deflateErr) if $deflateErr;
+                            $et->Warn($deflateErr) if $deflateErr;
                         }
                     } else {
                         if ($isOverwriting < 0) {
-                            $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val);
+                            $isOverwriting = $et->IsOverwriting($nvHash, $val);
                         }
                         # (must get new value after IsOverwriting() in case it was shifted)
-                        $newVal = Image::ExifTool::GetNewValues($nvHash);
+                        $newVal = $et->GetNewValue($nvHash);
                     }
                 }
                 if ($isOverwriting) {
                     $$outBuff = (defined $newVal) ? $newVal : '';
-                    ++$exifTool->{CHANGED};
-                    $exifTool->VerboseValue("- PNG:$tagName", $val);
-                    $exifTool->VerboseValue("+ PNG:$tagName", $newVal) if defined $newVal;
+                    ++$$et{CHANGED};
+                    $et->VerboseValue("- PNG:$tagName", $val);
+                    $et->VerboseValue("+ PNG:$tagName", $newVal) if defined $newVal;
                 }
             }
             if (defined $$outBuff and length $$outBuff) {
                 if ($enc) { # must be tEXt/zTXt/iTXt if $enc is set
-                    $$outBuff = BuildTextChunk($exifTool, $tag, $tagInfo, $$outBuff, $lang);
+                    $$outBuff = BuildTextChunk($et, $tag, $tagInfo, $$outBuff, $lang);
                 } elsif ($wasCompressed) {
                     # re-compress the output data
-                    my $deflate;
-                    if (eval 'require Compress::Zlib') {
-                        my $deflate = Compress::Zlib::deflateInit();
-                        if ($deflate) {
-                            $$outBuff = $deflate->deflate($$outBuff);
-                            $$outBuff .= $deflate->flush() if defined $$outBuff;
-                        } else {
-                            undef $$outBuff;
-                        }
+                    my $len = length $$outBuff;
+                    my $deflate = Compress::Zlib::deflateInit();
+                    if ($deflate) {
+                        $$outBuff = $deflate->deflate($$outBuff);
+                        $$outBuff .= $deflate->flush() if defined $$outBuff;
+                    } else {
+                        undef $$outBuff;
                     }
-                    $$outBuff or $exifTool->Warn("PNG:$tagName not written (compress error)");
+                    if (not $$outBuff) {
+                        $et->Warn("PNG:$tagName not written (compress error)");
+                    } elsif (lc $tag eq 'zxif') {
+                        $$outBuff = "\0" . pack('N',$len) . $$outBuff;  # add zXIf header
+                    }
                 }
             }
@@ -708,4 +961,12 @@
         }
         return 1 if $processed;
+    } elsif ($outBuff) {
+        if ($$et{DEL_GROUP}{PNG} and $tagTablePtr eq \%Image::ExifTool::PNG::TextualData) {
+            # delete all TextualData tags if deleting the PNG group
+            $$outBuff = '';
+            ++$$et{CHANGED};
+            $et->VerboseValue("- PNG:$tag", $val);
+        }
+        return 1;
     } else {
         my $name;
@@ -715,5 +976,6 @@
         # make unknown profiles binary data type
         $$tagInfo{Binary} = 1 if $tag =~ /^Raw profile type /;
-        Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        $verbose and $et->VPrint(0, "  | [adding $tag]\n");
+        AddTagToTable($tagTablePtr, $tag, $tagInfo);
     }
 #
@@ -725,5 +987,5 @@
         my $subdir = $$tagInfo{SubDirectory};
         delete $$tagInfo{SubDirectory};
-        $exifTool->VerboseInfo($tag, $tagInfo,
+        $et->VerboseInfo($tag, $tagInfo,
             Table  => $tagTablePtr,
             DataPt => \$val,
@@ -737,5 +999,5 @@
         $delRawConv = 1;
     }
-    $exifTool->FoundTag($tagInfo, $val);
+    $et->FoundTag($tagInfo, $val);
     delete $$tagInfo{RawConv} if $delRawConv;
     return 1;
@@ -748,5 +1010,5 @@
 sub ProcessProfile($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $tagInfo = $$dirInfo{TagInfo};
@@ -763,15 +1025,15 @@
     my $actualLen = length $buff;
     if ($len ne $actualLen) {
-        $exifTool->Warn("$tagName is wrong size (should be $len bytes but is $actualLen)");
+        $et->Warn("$tagName is wrong size (should be $len bytes but is $actualLen)");
         $len = $actualLen;
     }
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     if ($verbose) {
         if ($verbose > 2) {
-            $exifTool->VerboseDir("Decoded $tagName", 0, $len);
-            $exifTool->VerboseDump(\$buff);
+            $et->VerboseDir("Decoded $tagName", 0, $len);
+            $et->VerboseDump(\$buff);
         }
         # don't indent next directory (since it is really the same data)
-        $exifTool->{INDENT} =~ s/..$//;
+        $$et{INDENT} =~ s/..$//;
     }
     my %dirInfo = (
@@ -784,10 +1046,16 @@
         OutFile  => $outBuff,
     );
+    $$et{PROCESSED} = { };    # reset processed directory offsets
     my $processed = 0;
-    my $oldChanged = $exifTool->{CHANGED};
+    my $oldChanged = $$et{CHANGED};
     my $exifTable = GetTagTable('Image::ExifTool::Exif::Main');
-    my $editDirs = $exifTool->{EDIT_DIRS};
-    my $addDirs = $exifTool->{ADD_DIRS};
+    my $editDirs = $$et{EDIT_DIRS};
+
     if ($tagTablePtr ne $exifTable) {
+        # this is unfortunate, but the "IPTC" profile may be stored as either
+        # IPTC IIM or a Photoshop IRB resource, so we must test for this
+        if ($tagName eq 'IPTC_Profile' and $buff =~ /^\x1c/) {
+            $tagTablePtr = GetTagTable('Image::ExifTool::IPTC::Main');
+        }
         # process non-EXIF and non-APP1 profile as-is
         if ($outBuff) {
@@ -796,8 +1064,8 @@
             $dir =~ s/_Profile// unless $dir =~ /^ICC/;
             return 1 unless $$editDirs{$dir};
-            $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
-            delete $$addDirs{$dir};
+            $$outBuff = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
+            DoneDir($et, $dir, $outBuff, $$tagInfo{NonStandard});
         } else {
-            $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         }
     } elsif ($buff =~ /^$Image::ExifTool::exifAPP1hdr/) {
@@ -808,10 +1076,16 @@
         $dirInfo{DirLen} -= $hdrLen;
         if ($outBuff) {
-            $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr,
-                                                  \&Image::ExifTool::WriteTIFF);
+            # delete non-standard EXIF if recreating from scratch
+            if ($$et{DEL_GROUP}{EXIF} or $$et{DEL_GROUP}{IFD0}) {
+                $$outBuff = '';
+                $et->VPrint(0, '  Deleting non-standard APP1 EXIF information');
+                return 1;
+            }
+            $$outBuff = $et->WriteDirectory(\%dirInfo, $tagTablePtr,
+                                            \&Image::ExifTool::WriteTIFF);
             $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff;
-            delete $$addDirs{IFD0};
+            DoneDir($et, 'IFD0', $outBuff, $$tagInfo{NonStandard});
         } else {
-            $processed = $exifTool->ProcessTIFF(\%dirInfo);
+            $processed = $et->ProcessTIFF(\%dirInfo);
         }
     } elsif ($buff =~ /^$Image::ExifTool::xmpAPP1hdr/) {
@@ -823,28 +1097,33 @@
         if ($outBuff) {
             return 1 unless $$editDirs{XMP};
-            $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            $$outBuff = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
             $$outBuff and $$outBuff = $Image::ExifTool::xmpAPP1hdr . $$outBuff;
-            delete $$addDirs{XMP};
+            DoneDir($et, 'XMP', $outBuff, $$tagInfo{NonStandard});
         } else {
-            $processed = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $processed = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         }
     } elsif ($buff =~ /^(MM\0\x2a|II\x2a\0)/) {
-        # TIFF information (haven't seen this, but what the heck...)
+        # TIFF information
         return 1 if $outBuff and not $$editDirs{IFD0};
         if ($outBuff) {
-            $$outBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr,
-                                                  \&Image::ExifTool::WriteTIFF);
-            $$outBuff = $Image::ExifTool::exifAPP1hdr . $$outBuff if $$outBuff;
-            delete $$addDirs{IFD0};
+            # delete non-standard EXIF if recreating from scratch
+            if ($$et{DEL_GROUP}{EXIF} or $$et{DEL_GROUP}{IFD0}) {
+                $$outBuff = '';
+                $et->VPrint(0, '  Deleting non-standard EXIF/TIFF information');
+                return 1;
+            }
+            $$outBuff = $et->WriteDirectory(\%dirInfo, $tagTablePtr,
+                                            \&Image::ExifTool::WriteTIFF);
+            DoneDir($et, 'IFD0', $outBuff, $$tagInfo{NonStandard});
         } else {
-            $processed = $exifTool->ProcessTIFF(\%dirInfo);
+            $processed = $et->ProcessTIFF(\%dirInfo);
         }
     } else {
         my $profName = $profileType;
         $profName =~ tr/\x00-\x1f\x7f-\xff/./;
-        $exifTool->Warn("Unknown raw profile '$profName'");
+        $et->Warn("Unknown raw profile '${profName}'");
     }
     if ($outBuff and defined $$outBuff and length $$outBuff) {
-        if ($exifTool->{CHANGED} != $oldChanged) {
+        if ($$et{CHANGED} != $oldChanged) {
             my $hdr = sprintf("\n%s\n%8d\n", $profileType, length($$outBuff));
             # hex encode the data
@@ -864,5 +1143,5 @@
 sub ProcessPNG_Compressed($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my ($tag, $val) = split /\0/, ${$$dirInfo{DataPt}}, 2;
     return 0 unless defined $val;
@@ -873,12 +1152,16 @@
     my $success;
     my $outBuff = $$dirInfo{OutBuff};
+    my $tagInfo = $$dirInfo{TagInfo};
     # use the PNG chunk tag instead of the embedded tag name for iCCP chunks
-    if ($$dirInfo{TagInfo} and $$dirInfo{TagInfo}->{Name} eq 'ICC_Profile') {
-        $tag = 'iCCP';
+    if ($tagInfo and $$tagInfo{Name} eq 'ICC_Profile') {
+        $et->VerboseDir('iCCP');
         $tagTablePtr = \%Image::ExifTool::PNG::Main;
-        $success = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff);
+        if (length($tag) and not $outBuff) {
+            FoundPNG($et, $tagTablePtr, 'iCCP-name', $tag);
+        }
+        $success = FoundPNG($et, $tagTablePtr, 'iCCP', $val, $compressed, $outBuff);
         $$outBuff = $hdr . $$outBuff if $outBuff and $$outBuff;
     } else {
-        $success = FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'Latin');
+        $success = FoundPNG($et, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'Latin');
     }
     return $success;
@@ -892,8 +1175,9 @@
 sub ProcessPNG_tEXt($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my ($tag, $val) = split /\0/, ${$$dirInfo{DataPt}}, 2;
     my $outBuff = $$dirInfo{OutBuff};
-    return FoundPNG($exifTool, $tagTablePtr, $tag, $val, undef, $outBuff, 'Latin');
+    $$et{INDENT} = substr($$et{INDENT}, 0, -2) if $$et{OPTIONS}{Verbose};
+    return FoundPNG($et, $tagTablePtr, $tag, $val, undef, $outBuff, 'Latin');
 }
 
@@ -905,5 +1189,5 @@
 sub ProcessPNG_iTXt($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my ($tag, $dat) = split /\0/, ${$$dirInfo{DataPt}}, 2;
     return 0 unless defined $dat and length($dat) >= 4;
@@ -913,5 +1197,59 @@
     $compressed and $compressed = 2 + $meth;
     my $outBuff = $$dirInfo{OutBuff};
-    return FoundPNG($exifTool, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'UTF8', $lang);
+    $$et{INDENT} = substr($$et{INDENT}, 0, -2) if $$et{OPTIONS}{Verbose};
+    return FoundPNG($et, $tagTablePtr, $tag, $val, $compressed, $outBuff, 'UTF8', $lang);
+}
+
+#------------------------------------------------------------------------------
+# Process PNG eXIf/zXIf chunk
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) Pointer to tag table
+# Returns: 1 on success
+# Notes: writes new chunk data to ${$$dirInfo{OutBuff}} if writing tag
+sub ProcessPNG_eXIf($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $outBuff = $$dirInfo{OutBuff};
+    my $dataPt = $$dirInfo{DataPt};
+    my $tagInfo = $$dirInfo{TagInfo};
+    my $tag = $$tagInfo{TagID};
+    my $del = $outBuff && ($$et{DEL_GROUP}{EXIF} or $$et{DEL_GROUP}{IFD0});
+    my $type;
+
+    if ($$dataPt =~ /^Exif\0\0/) {
+        $et->Warn('Improper "Exif00" header in EXIF chunk');
+        $$dataPt = substr($$dataPt, 6);
+        $$dirInfo{DataLen} = length $$dataPt;
+        $$dirInfo{DirLen} -= 6 if $$dirInfo{DirLen};
+    }
+    if ($$dataPt =~ /^(\0|II|MM)/) {
+        $type = $1;
+    } elsif ($del) {
+        $et->VPrint(0, "  Deleting invalid $tag chunk");
+        $$outBuff = '';
+        ++$$et{CHANGED};
+        return 1;
+    } else {
+        $et->Warn("Invalid $tag chunk");
+        return 0;
+    }
+    if ($type eq "\0") {    # is this compressed EXIF?
+        my $buf = substr($$dataPt, 5);
+        # go around again to uncompress the data
+        $tagTablePtr = GetTagTable('Image::ExifTool::PNG::Main');
+        return FoundPNG($et, $tagTablePtr, $$tagInfo{TagID}, \$buf, 2, $outBuff);
+    } elsif (not $outBuff) {
+        return $et->ProcessTIFF($dirInfo);
+    # (zxIf was not adopted)
+    #} elsif ($del and ($et->Options('Compress') xor lc($tag) eq 'zxif')) {
+    } elsif ($del and lc($tag) eq 'zxif') {
+        $et->VPrint(0, "  Deleting $tag chunk");
+        $$outBuff = '';
+        ++$$et{CHANGED};
+    } elsif ($$et{EDIT_DIRS}{IFD0}) {
+        $$outBuff = $et->WriteDirectory($dirInfo, $tagTablePtr,
+                                        \&Image::ExifTool::WriteTIFF);
+        DoneDir($et, 'IFD0', $outBuff, $$tagInfo{NonStandard});
+    }
+    return 1;
 }
 
@@ -922,5 +1260,5 @@
 sub ProcessPNG($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $outfile = $$dirInfo{OutFile};
     my $raf = $$dirInfo{RAF};
@@ -928,20 +1266,26 @@
     my $datCount = 0;
     my $datBytes = 0;
-    my ($sig, $err, $ok);
+    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};
+
     if ($outfile) {
-        delete $$exifTool{TextChunkType};
+        delete $$et{TextChunkType};
         Write($outfile, $sig) or $err = 1 if $outfile;
         # can only add tags in Main and TextualData tables
-        $exifTool->{ADD_PNG} = $exifTool->GetNewTagInfoHash(
+        $$et{ADD_PNG} = $et->GetNewTagInfoHash(
             \%Image::ExifTool::PNG::Main,
             \%Image::ExifTool::PNG::TextualData);
         # initialize with same directories, with PNG tags taking priority
-        $exifTool->InitWriteDirs(\%pngMap,'PNG');
+        $et->InitWriteDirs(\%pngMap,'PNG');
+    } else {
+        # disable buffering in FastScan mode
+        $$raf{NoBuffer} = 1 if $fastScan;
     }
     my ($fileType, $hdrChunk, $endChunk) = @{$pngLookup{$sig}};
-    $exifTool->SetFileType($fileType);  # set the FileType tag
+    $et->SetFileType($fileType);  # set the FileType tag
     SetByteOrder('MM'); # PNG files are big-endian
     my $tagTablePtr = GetTagTable('Image::ExifTool::PNG::Main');
@@ -950,15 +1294,52 @@
         $mngTablePtr = GetTagTable('Image::ExifTool::MNG::Main');
     }
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
-    my ($hbuf, $dbuf, $cbuf, $foundHdr);
+    my $verbose = $et->Options('Verbose');
+    my $validate = $et->Options('Validate');
+    my $out = $et->Options('TextOut');
+
+    # 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 (;;) {
-        $raf->Read($hbuf,8) == 8 or $exifTool->Warn("Truncated $fileType image"), last;
+        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);
+            last if $n < 8;
+            $$et{SET_GROUP1} = 'Trailer';
+        } elsif ($n != 8) {
+            $et->Warn("Truncated $fileType image") unless $wasEnd;
+            last;
+        }
         my ($len, $chunk) = unpack('Na4',$hbuf);
-        $len > 0x7fffffff and $exifTool->Warn("Invalid $fileType box size"), last;
+        if ($len > 0x7fffffff) {
+            $et->Warn("Invalid $fileType chunk size") unless $wasEnd;
+            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) {
@@ -966,60 +1347,146 @@
                 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->WarnOnce("$fileType image did not start with $hdrChunk");
+            }
+        }
+        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 'IEND') {
-                # add any new chunks immediately before the IEND chunk
-                AddChunks($exifTool, $outfile) or $err = 1;
-            } elsif ($chunk eq 'PLTE' or $chunk eq 'IDAT') {
-                # 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($exifTool, $outfile);
+                Add_iCCP($et, $outfile);
             }
         }
         if ($chunk eq $endChunk) {
+            # read CRC
+            unless ($raf->Read($cbuf,4) == 4) {
+                $et->Warn("Truncated $fileType $endChunk chunk") unless $wasEnd;
+                last;
+            }
+            $verbose and print $out "$fileType $chunk (end of image)\n";
+            $wasEnd = 1;
             if ($outfile) {
-                # copy over the rest of the file if necessary
-                Write($outfile, $hbuf) or $err = 1;
-                while ($raf->Read($hbuf, 65536)) {
+                # write the IEND/MEND chunk with CRC
+                Write($outfile, $hbuf, $cbuf) or $err = 1;
+                if ($$et{DEL_GROUP}{Trailer}) {
+                    if ($raf->Read($hbuf, 1)) {
+                        $verbose and printf $out "  Deleting PNG trailer\n";
+                        ++$$et{CHANGED};
+                    }
+                } else {
+                    # copy over any existing trailer data
+                    my $tot = 0;
+                    for (;;) {
+                        $n = $raf->Read($hbuf, 65536) or last;
+                        $tot += $n;
+                        Write($outfile, $hbuf) or $err = 1;
+                    }
+                    $tot and $verbose and printf $out "  Copying PNG trailer ($tot bytes)\n";
+                }
+                last;
+            }
+            next;
+        }
+        if ($datChunk) {
+            my $chunkSizeLimit = 10000000;  # largest chunk to read into memory
+            if ($outfile) {
+                # avoid loading very large data chunks into memory
+                if ($len > $chunkSizeLimit) {
                     Write($outfile, $hbuf) or $err = 1;
+                    Image::ExifTool::CopyBlock($raf, $outfile, $len+4) or $et->Error("Error copying $datChunk");
+                    next;
                 }
-            }
-            $verbose and print $out "$fileType $chunk (end of image)\n";
-            $ok = 1;
-            last;
+            # skip over data chunks if possible/necessary
+            } elsif (not $validate or $len > $chunkSizeLimit) {
+                $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) {
-            $exifTool->Warn("Corrupted $fileType image");
+            $et->Warn("Corrupted $fileType image") unless $wasEnd;
             last;
         }
-        unless ($foundHdr) {
-            if ($chunk eq $hdrChunk) {
-                $foundHdr = 1;
-            } elsif ($hdrChunk eq 'IHDR' and $chunk eq 'CgBI') {
-                $exifTool->Warn('Non-standard PNG image (Apple iPhone format)');
-            } else {
-                $exifTool->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 $exifTool->Warn("Bad CRC for $chunk chunk");
+            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";
-            $exifTool->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 names that have changed since the first implementation
+        if (not $$tagTablePtr{$chunk} and $stdCase{lc $chunk}) {
+            my $stdChunk = $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
@@ -1027,7 +1494,7 @@
         $outBuff = \$theBuff if $outfile;
         if ($$tagTablePtr{$chunk}) {
-            FoundPNG($exifTool, $tagTablePtr, $chunk, $dbuf, undef, $outBuff);
+            FoundPNG($et, $tagTablePtr, $chunk, $dbuf, undef, $outBuff);
         } elsif ($mngTablePtr and $$mngTablePtr{$chunk}) {
-            FoundPNG($exifTool, $mngTablePtr, $chunk, $dbuf, undef, $outBuff);
+            FoundPNG($et, $mngTablePtr, $chunk, $dbuf, undef, $outBuff);
         }
         if ($outfile) {
@@ -1035,7 +1502,7 @@
                 next unless length $theBuff; # empty if we deleted the information
                 # change chunk type if necessary
-                if ($$exifTool{TextChunkType}) {
-                    $chunk = $$exifTool{TextChunkType};
-                    delete $$exifTool{TextChunkType};
+                if ($$et{TextChunkType}) {
+                    $chunk = $$et{TextChunkType};
+                    delete $$et{TextChunkType};
                 }
                 $hbuf = pack('Na4', length($theBuff), $chunk);
@@ -1048,5 +1515,6 @@
         }
     }
-    return -1 if $outfile and ($err or not $ok);
+    delete $$et{SET_GROUP1};
+    return -1 if $outfile and ($err or not $wasEnd);
     return 1;   # this was a valid PNG/MNG/JNG image
 }
@@ -1072,5 +1540,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PPM.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PPM.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PPM.pm	(revision 34921)
@@ -17,5 +17,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.05';
+$VERSION = '1.10';
 
 #------------------------------------------------------------------------------
@@ -25,9 +25,9 @@
 sub ProcessPPM($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     my ($buff, $num, $type, %info);
 #
@@ -49,5 +49,5 @@
         if ($buff =~ /\G#/gc) {
             # must read more if we are in the middle of a comment
-            next unless $buff =~ /\G ?(.*\n(#.*\n)*)\s*/g;
+            next unless $buff =~ /\G ?(.*[\n\r]+(#.*[\n\r]+)*)\s*/g;
             $info{Comment} = $1;
             next if $buff =~ /\G#/gc;
@@ -55,5 +55,5 @@
             delete $info{Comment};
         }
-        next unless $buff =~ /\G(\S+)\s+(\S+)\s/g;
+        next unless $buff =~ /\G(\S+)\s+(\S+)\s+/g;
         $info{ImageWidth} = $1;
         $info{ImageHeight} = $2;
@@ -61,5 +61,5 @@
         last if $type eq 'PBM'; # (no MaxVal for PBM images)
         if ($buff =~ /\G\s*#/gc) {
-            next unless $buff =~ /\G ?(.*\n(#.*\n)*)\s*/g;
+            next unless $buff =~ /\G ?(.*[\n\r]+(#.*[\n\r]+)*)\s*/g;
             $info{Comment} = '' unless exists $info{Comment};
             $info{Comment} .= $1;
@@ -77,7 +77,7 @@
     if (defined $info{Comment}) {
         $info{Comment} =~ s/^# ?//mg;   # remove "# " at the start of each line
-        $info{Comment} =~ s/\n$//;      # remove trailing newline
+        $info{Comment} =~ s/[\n\r]+$//; # remove trailing newline
     }
-    $exifTool->SetFileType($type);
+    $et->SetFileType($type);
     my $len = pos($buff);
 #
@@ -86,10 +86,10 @@
     if ($outfile) {
         my $nvHash;
-        my $newComment = $exifTool->GetNewValues('Comment', \$nvHash);
+        my $newComment = $et->GetNewValue('Comment', \$nvHash);
         my $oldComment = $info{Comment};
-        if (Image::ExifTool::IsOverwriting($nvHash, $oldComment)) {
-            ++$exifTool->{CHANGED};
-            $exifTool->VerboseValue('- Comment', $oldComment) if defined $oldComment;
-            $exifTool->VerboseValue('+ Comment', $newComment) if defined $newComment;
+        if ($et->IsOverwriting($nvHash, $oldComment)) {
+            ++$$et{CHANGED};
+            $et->VerboseValue('- Comment', $oldComment) if defined $oldComment;
+            $et->VerboseValue('+ Comment', $newComment) if defined $newComment;
         } else {
             $newComment = $oldComment;  # use existing comment
@@ -115,9 +115,9 @@
     if ($verbose > 2) {
         print $out "$type header ($len bytes):\n";
-        Image::ExifTool::HexDump(\$buff, $len, Out => $out);
+        $et->VerboseDump(\$buff, Len => $len);
     }
     my $tag;
     foreach $tag (qw{Comment ImageWidth ImageHeight MaxVal}) {
-        $exifTool->FoundTag($tag, $info{$tag}) if defined $info{$tag};
+        $et->FoundTag($tag, $info{$tag}) if defined $info{$tag};
     }
     return 1;
@@ -144,5 +144,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PSP.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PSP.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PSP.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.03';
+$VERSION = '1.05';
 
 sub ProcessExtData($$$);
@@ -66,4 +66,5 @@
     #18 => {
     #    Name => 'PreviewImage',
+    #    Groups => { 2 => 'Preview' },
     #    RawConv => '$self->ValidateImage(\$val,$tag)',
     #},
@@ -163,5 +164,5 @@
 sub ProcessExtData($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = $$dirInfo{DirLen};
@@ -170,5 +171,5 @@
     while ($pos + 10 < $dirLen) {
         unless (substr($$dataPt, $pos, 4) eq "~FL\0") {
-            $exifTool->Warn('Lost synchronization while reading sub blocks');
+            $et->Warn('Lost synchronization while reading sub blocks');
             last;
         }
@@ -177,12 +178,12 @@
         $pos += 10 + $len;
         if ($pos > $dirLen) {
-            $exifTool->Warn("Truncated sub block ID=$tag len=$len");
+            $et->Warn("Truncated sub block ID=$tag len=$len");
             last;
         }
         next unless $$tagTablePtr{$tag};
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag) or next;
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag) or next;
         my $start = $pos - $len;
         unless ($$tagInfo{Name} eq 'EXIFInfo') {
-            $exifTool->HandleTag($tagTablePtr, $tag, undef,
+            $et->HandleTag($tagTablePtr, $tag, undef,
                 TagInfo => $tagInfo,
                 DataPt  => $dataPt,
@@ -213,5 +214,5 @@
         );
         my $exifTable = GetTagTable($$tagInfo{SubDirectory}{TagTable});
-        Image::ExifTool::Exif::ProcessExif($exifTool, \%dirInfo, $exifTable);
+        Image::ExifTool::Exif::ProcessExif($et, \%dirInfo, $exifTable);
         SetByteOrder('II');
     }
@@ -225,5 +226,5 @@
 sub ProcessPSP($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $tag, $len, $err);
@@ -231,5 +232,5 @@
                     $buff eq "Paint Shop Pro Image File\x0a\x1a\0\0\0\0\0" and
                     $raf->Read($buff, 4) == 4;
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('II');
     my $tagTablePtr = GetTagTable('Image::ExifTool::PSP::Main');
@@ -237,6 +238,6 @@
     # figure out block header length for this format PSP file
     my $hlen = $a[0] > 3 ? 10 : 14;
-    $$exifTool{PSPFileVersion} = $a[0]; # save for use in Condition
-    $exifTool->HandleTag($tagTablePtr, FileVersion => "@a");
+    $$et{PSPFileVersion} = $a[0]; # save for use in Condition
+    $et->HandleTag($tagTablePtr, FileVersion => "@a");
     # loop through blocks in file
     my $pos = 36;
@@ -244,5 +245,5 @@
         last unless $raf->Read($buff, $hlen) == $hlen;
         unless ($buff =~ /^~BK\0/) {
-            $exifTool->Warn('Lost synchronization while reading main PSP blocks');
+            $et->Warn('Lost synchronization while reading main PSP blocks');
             last;
         }
@@ -255,5 +256,5 @@
         }
         $raf->Read($buff, $len) == $len or $err=1, last;
-        $exifTool->HandleTag($tagTablePtr, $tag, $buff,
+        $et->HandleTag($tagTablePtr, $tag, $buff,
             DataPt  => \$buff,
             DataPos => $pos - $len,
@@ -261,5 +262,5 @@
         );
     }
-    $err and $exifTool->Warn("Truncated main block ID=$tag len=$len");
+    $err and $et->Warn("Truncated main block ID=$tag len=$len");
     return 1;
 }
@@ -284,5 +285,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Palm.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Palm.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Palm.pm	(revision 34921)
@@ -0,0 +1,403 @@
+#------------------------------------------------------------------------------
+# File:         Palm.pm
+#
+# Description:  Read Palm Database files
+#
+# Revisions:    2014/05/28 - P. Harvey Created
+#
+# References: 1) http://wiki.mobileread.com/wiki/PDB
+#             2) http://wiki.mobileread.com/wiki/MOBI
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Palm;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.00';
+
+sub ProcessEXTH($$$);
+
+# type/creator ID's for Palm database files
+my %palmTypes = (
+    '.pdfADBE' => 'Adobe Reader',
+    'TEXtREAd' => 'PalmDOC',
+    'BVokBDIC' => 'BDicty',
+    'DB99DBOS' => 'DB (Database program)',
+    'PNRdPPrs' => 'eReader',
+    'DataPPrs' => 'eReader',
+    'vIMGView' => 'FireViewer (ImageViewer)',
+    'PmDBPmDB' => 'HanDBase',
+    'InfoINDB' => 'InfoView',
+    'ToGoToGo' => 'iSilo',
+    'SDocSilX' => 'iSilo 3',
+    'JbDbJBas' => 'JFile',
+    'JfDbJFil' => 'JFile Pro',
+    'DATALSdb' => 'LIST',
+    'Mdb1Mdb1' => 'MobileDB',
+    'BOOKMOBI' => 'Mobipocket',
+    'DataPlkr' => 'Plucker',
+    'DataSprd' => 'QuickSheet',
+    'SM01SMem' => 'SuperMemo',
+    'TEXtTlDc' => 'TealDoc',
+    'InfoTlIf' => 'TealInfo',
+    'DataTlMl' => 'TealMeal',
+    'DataTlPt' => 'TealPaint',
+    'dataTDBP' => 'ThinkDB',
+    'TdatTide' => 'Tides',
+    'ToRaTRPW' => 'TomeRaider',
+    'zTXTGPlm' => 'Weasel',
+    'BDOCWrdS' => 'WordSmith',
+);
+
+my %dateTimeInfo = (
+    # like QuickTime, the time zero should be Jan 1, 1904, but not all software writes this,
+    # so assume a time zero of Jan 1, 1970 if the date is before this
+    RawConv => q{
+        my $offset = (66 * 365 + 17) * 24 * 3600;
+        return $val - $offset if $val >= $offset;
+        return $val;
+    },
+    ValueConv => 'ConvertUnixTime($val, 1)', # (UTC written by "EPUB Converter", ref PH)
+    PrintConv => '$self->ConvertDateTime($val)',
+);
+
+# Palm Database header information
+%Image::ExifTool::Palm::Main = (
+    GROUPS => { 0 => 'Palm', 1 => 'Palm', 2 => 'Document' },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int32u',
+    NOTES => q{
+        Information extracted from Palm database files (PDB and PRC extensions),
+        Mobipocket electronic books (MOBI), and Amazon Kindle KF7 and KF8 books (AZW
+        and AZW3).
+    },
+    0 => { Name => 'DatabaseName', Format => 'string[32]' },
+    # 8 - int16u: file attributes (not very useful)
+    # 8.5 - int16u: version
+    9 => {
+        Name => 'CreateDate',
+        Groups => { 2 => 'Time' },
+        %dateTimeInfo,
+    },
+    10 => {
+        Name => 'ModifyDate',
+        Groups => { 2 => 'Time' },
+        %dateTimeInfo,
+    },
+    11 => {
+        Name => 'LastBackupDate',
+        Groups => { 2 => 'Time' },
+        %dateTimeInfo,
+    },
+    12 => 'ModificationNumber',
+    15 => {
+        Name => 'PalmFileType',
+        Format => 'undef[8]',
+        PrintConv => \%palmTypes,
+    },
+);
+
+
+# MOBI header tags
+%Image::ExifTool::Palm::MOBI = (
+    GROUPS => { 0 => 'Palm', 1 => 'MOBI', 2 => 'Document' },
+    NOTES => q{
+        Information extracted from the MOBI header of Mobipocket and Amazon Kindle
+        KF7 and KF8 files.
+    },
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int32u',
+    0 => {
+        Name => 'Compression',
+        Format => 'int16u',
+        PrintConv => {
+            1 => 'None',
+            2 => 'PalmDOC',
+            17480 => 'HUFF/CDIC',
+        },
+    },
+    1  => {
+        Name => 'UncompressedTextLength',
+        PrintConv => \&Image::ExifTool::ConvertFileSize,
+    },
+    3 => {
+        Name => 'Encryption',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Old Mobipocket',
+            2 => 'Mobipocket',
+        },
+    },
+    6 => {
+        Name => 'MobiType',
+        PrintConv => {
+            2 => 'Mobipocket Book',
+            3 => 'PalmDoc Book',
+            4 => 'Audio',
+            232 => 'mobipocket? generated by kindlegen1.2',
+            248 => 'KF8: generated by kindlegen2',
+            257 => 'News',
+            258 => 'News_Feed',
+            259 => 'News_Magazine',
+            513 => 'PICS',
+            514 => 'WORD',
+            515 => 'XLS',
+            516 => 'PPT',
+            517 => 'TEXT',
+            518 => 'HTML',
+        },
+    },
+    7 => {
+        Name => 'CodePage',
+        RawConv => '$$self{CodePage} = $val',
+        PrintConv => {
+            # just define commonly used code pages
+            # (a much more complete list may be found in FlashPix.pm)
+            1252 => 'Windows Latin 1 (Western European)',
+            65001 => 'Unicode (UTF-8)',
+        },
+    },
+    9 => 'MobiVersion',
+    21 => 'BookName',   # this is actually an offset, but replace it with the string later
+    26 => 'MinimumVersion',
+);
+
+# MOBI extended header tags
+%Image::ExifTool::Palm::EXTH = (
+    GROUPS => { 0 => 'Palm', 1 => 'MOBI', 2 => 'Document' },
+    FORMAT => 'string',
+    NOTES => 'Information extracted from the MOBI extended header.',
+    PROCESS_PROC => \&ProcessEXTH,
+    1 => 'DRMServerID',
+    2 => 'DRMCommerceID',
+    3 => 'DRM_E-BookBaseID',
+    100 => { Name => 'Author', Groups => { 2 => 'Author' } },
+    101 => 'Publisher',
+    102 => 'Imprint',
+    103 => 'Description',
+    104 => 'ISBN',
+    105 => { Name => 'Subject', List => 1 },
+    106 => {
+        Name => 'PublishDate',
+        Groups => { 2 => 'Time' },
+        ValueConv => q{
+            require Image::ExifTool::XMP;
+            Image::ExifTool::XMP::ConvertXMPDate($val, 1);
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    107 => 'Review',
+    108 => 'Contributor',
+    109 => { Name => 'Rights', Groups => { 2 => 'Author' } },
+    110 => 'SubjectCode',
+    111 => 'BookType',
+    112 => 'Source',
+    113 => 'ASIN',
+    114 => 'BookVersion',
+    115 => { Name => 'SampleFlag',   Format => 'int32u' },
+    116 => { Name => 'StartReading', Format => 'int32u' },
+    117 => 'Adult',
+    118 => 'RetailPrice',
+    119 => 'RetailPriceCurrency',
+    # 121 => 'KF8BoundaryOffset',
+    125 => { Name => 'ResourceCount', Format => 'int32u' },
+    129 => 'KF8CoverURI',
+    200 => 'DictionaryShortName',
+    # 201 => { Name => 'CoverOffset', Format => 'int32u' },
+    # 202 => { Name => 'ThumbOffset', Format => 'int32u' },
+    # 203 => 'HasFakeCover',
+    204 => {
+        Name => 'CreatorSoftware',
+        Format => 'int32u',
+        PrintConv => {
+            1 => 'Mobigen',
+            2 => 'Mobipocket',
+            200 => 'Kindlegen (Windows)',
+            201 => 'Kindlegen (Linux)',
+            202 => 'Kindlegen (Mac)',
+        },
+    },
+    205 => { Name => 'CreatorMajorVersion', Format => 'int32u' },
+    206 => { Name => 'CreatorMinorVersion', Format => 'int32u' },
+    207 => { Name => 'CreatorBuildNumber',  Format => 'int32u' },
+    208 => 'Watermark',
+    209 => 'Tamper-proofKeys',
+    # 300 => 'FontSignature',
+    401 => { Name => 'ClippingLimit', Format => 'int8u' },
+    402 => 'PublisherLimit',
+    404 => {
+        Name => 'TextToSpeech',
+        Format => 'int8u',
+        PrintConv => { 0 => 'Enabled', 1 => 'Disabled' },
+    },
+    405 => { Name => 'RentalFlag', Format => 'int8u' }, #?
+    406 => 'RentalExpirationDate',
+    501 => { Name => 'CDEType',    Format => 'int32u' },
+    502 => 'LastUpdateTime',
+    503 => 'UpdatedTitle',
+    504 => 'ASIN2',
+    524 => 'Language',
+    525 => 'Alignment',
+    535 => 'CreatorBuildNumber2',
+);
+
+#------------------------------------------------------------------------------
+# Process the MOBI extended header
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 (EXTH should have already been validated)
+sub ProcessEXTH($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $enc = $$dirInfo{Encoding} || 'UTF8';
+    my $dirLen = length $$dataPt;
+    my ($index, $pos);
+
+    $et->VerboseDir('EXTH', $$dirInfo{NumEntries}, $dirLen);
+
+    # process the EXTH entries
+    for ($index=0, $pos=0; ; ++$index) {
+        last if $pos + 8 > $dirLen;
+        my $tag = Get32u($dataPt, $pos);
+        my $len = Get32u($dataPt, $pos + 4);
+        last if $len < 8 or $pos + $len > $dirLen;
+        my $key = $et->HandleTag($tagTablePtr, $tag, undef,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Start   => $pos + 8,
+            Size    => $len - 8,
+            Index   => $index,
+        );
+        # recode text if necessary
+        $$et{VALUE}{$key} = $et->Decode($$et{VALUE}{$key}, $enc) if $key;
+        $pos += $len;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Extract information from a Palm DB file
+# Inputs: 0) ExifTool ref, 1) dirInfo reference
+# Returns: 1 if this was a recognized PDB file, 0 otherwise
+sub ProcessPDB($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my ($buff, $buf2, $size, $enc);
+    my $verbose = $et->Options('Verbose');
+
+    # verify this is a valid Palm DB file
+    return 0 unless $raf->Read($buff, 86) == 86;
+    my $type = $palmTypes{substr($buff, 60, 8)};
+    return 0 unless $type;
+#
+# Read and process the Palm DB file header
+#
+    $et->SetFileType($type eq 'Mobipocket' ? 'MOBI' : 'PDB');
+    SetByteOrder('MM');
+
+    my $tagTablePtr = GetTagTable('Image::ExifTool::Palm::Main');
+    $et->ProcessDirectory({ DataPt => \$buff }, $tagTablePtr);
+
+    return 1 unless $type eq 'Mobipocket' and Get16u(\$buff, 76);
+#
+# Read and process MOBI header (should be the first record)
+#
+    my $offset = Get32u(\$buff, 78);    # get offset to first record
+    unless ($raf->Seek($offset, 0) and $raf->Read($buff, 274) == 274) {
+        $et->Warn('Truncated MOBI header');
+        return 1;
+    }
+    unless (substr($buff, 16, 4) eq 'MOBI') {
+        $et->Warn('Invalid MOBI header');
+        return 1;
+    }
+    $tagTablePtr = GetTagTable('Image::ExifTool::Palm::MOBI');
+    $et->ProcessDirectory({ DataPt => \$buff }, $tagTablePtr);
+
+    # get text encoding
+    $enc = $Image::ExifTool::charsetName{"cp$$et{CodePage}"} if $$et{CodePage};
+    $enc = 'UTF8' unless $enc;
+
+    # extract the BookName string
+    my $off = Get32u(\$buff, 84);
+    my $len = Get32u(\$buff, 88);
+
+    $raf->Seek($offset+$off, 0) and $raf->Read($buf2, $len) == $len or $buf2 = '<err>';
+    $$et{VALUE}{BookName} = $et->Decode($buf2, $enc);
+#
+# Process the MOBI extended header if it exists
+#
+    # first, check the flag bit to see if the EXTH record should exist
+    my $flag = Get32u(\$buff, 128);
+    return 1 unless $flag & 0x40;   # check extended header flag
+
+    $len = Get32u(\$buff, 20) + 16; # MOBI header length (including PalmDOC header)
+
+    unless ($raf->Seek($offset+$len, 0) and $raf->Read($buf2, 12) == 12 and
+        substr($buf2,0,4) eq 'EXTH' and ($size = Get32u(\$buf2, 4)) > 12)
+    {
+        $et->Warn('Invalid MOBI extended header');
+        return 1;
+    }
+
+    # read and process the MOBI extended header
+    $size -= 12;
+    $raf->Read($buff, $size) == $size or $et->Warn('Truncated MOBI extended header'), return 1;
+    my %dirInfo = (
+        DataPt     => \$buff,
+        DataPos    => $offset + $len + 12,
+        NumEntries => Get32u(\$buf2, 8),
+        Encoding   => $enc,
+    );
+    $tagTablePtr = GetTagTable('Image::ExifTool::Palm::EXTH');
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Palm - Read Palm Database files
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains code to extract metadata from Palm database files (PDB
+and PRC extensions), Mobipocket electronic books (MOBI), and Amazon Kindle
+KF7 and KF8 books (AZW and AZW3).
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.mobileread.com/wiki/PDB>
+
+=item L<http://wiki.mobileread.com/wiki/MOBI>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Palm Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Panasonic.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Panasonic.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Panasonic.pm	(revision 34921)
@@ -15,8 +15,17 @@
 #              10) http://bretteville.com/pdfs/M8Metadata_v2.pdf
 #              11) http://www.digital-leica.com/lens_codes/index.html
+#                  (now https://www.l-camera-forum.com/leica-news/leica-lens-codes/)
 #              12) Joerg - http://www.cpanforum.com/threads/11602 (LX3 firmware 2.0)
 #              13) Michael Byczkowski private communication (Leica M9)
 #              14) Carl Bretteville private communication (M9)
 #              15) Zdenek Mihula private communication (TZ8)
+#              16) Olaf Ulrich private communication
+#              17) https://exiftool.org/forum/index.php/topic,4922.0.html
+#              18) Thomas Modes private communication (G6)
+#              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)
 #------------------------------------------------------------------------------
@@ -25,15 +34,15 @@
 
 use strict;
-use vars qw($VERSION);
+use vars qw($VERSION %leicaLensTypes);
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
 
-$VERSION = '1.59';
-
-sub ProcessPanasonicType2($$$);
+$VERSION = '2.14';
+
+sub ProcessLeicaLEIC($$$);
 sub WhiteBalanceConv($;$$);
 
 # Leica lens types (ref 10)
-my %leicaLensType = (
+%leicaLensTypes = (
     OTHER => sub {
         my ($val, $inv, $conv) = @_;
@@ -42,7 +51,8 @@
     },
     Notes => q{
-        Entries with 2 numbers give the lower 2 bits of the LensType value which are
-        used to identify certain manually coded lenses on the M9, or the focal
-        length of some multi-focal lenses.
+        the LensType value is obtained by splitting the stored value into 2
+        integers:  The stored value divided by 4, and its lower 2 bits.  The second
+        number is used only if necessary to identify certain manually coded lenses
+        on the M9, or the focal length of some multi-focal lenses.
     },
     # All M9 codes (two numbers: first the LensID then the lower 2 bits)
@@ -55,4 +65,8 @@
     # frame selector.  The bits are zero for uncoded lenses when manually coding
     # from the menu on the M9. - PH
+    # Frame selector bits (from ref 10, M8):
+    #   1 => '28/90mm frame lines engaged',
+    #   2 => '24/35mm frame lines engaged',
+    #   3 => '50/75mm frame lines engaged',
     '0 0' => 'Uncoded lens',
 #
@@ -69,4 +83,6 @@
     9 => 'Elmarit-M 135mm f/2.8 (I/II)',    # 11829
     '9 0' => 'Apo-Telyt-M 135mm f/3.4',     # 11889
+    11 => 'Summaron-M 28mm f/5.6',          # ? (ref IB)
+    12 => 'Thambar-M 90mm f/2.2',           # ? (ref IB)
     16 => 'Tri-Elmar-M 16-18-21mm f/4 ASPH.',# 11626
     '16 1' => 'Tri-Elmar-M 16-18-21mm f/4 ASPH. (at 16mm)',
@@ -94,4 +110,6 @@
     '39 0' => 'Tele-Elmar-M 135mm f/4 (II)',# 11861
     40 => 'Macro-Adapter M',                # 14409
+    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)',
@@ -106,5 +124,11 @@
     49 => 'Noctilux-M 50mm f/0.95 ASPH.',   # ? (ref 11)
     50 => 'Elmar-M 24mm f/3.8 ASPH.',       # ? (ref 11)
-    52 => 'Super-Elmar-M 18mm f/3.8 ASPH.', # ? (ref PH/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 => '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)
 );
 
@@ -149,5 +173,7 @@
     49 => 3, # (NC)
     50 => 2, # (NC)
+    51 => 1, # or 2 (ref 16)
     52 => 3,
+    53 => 2, #16
 );
 
@@ -198,5 +224,41 @@
     45 => 'My Color', #PH (GF1)
     46 => 'Photo Frame', #PH (FS7)
+    48 => 'Movie', #PH (GM1)
+    # 49 - seen for FS4 (snow?)
     51 => 'HDR', #12
+    52 => 'Peripheral Defocus', #Horst Wandres
+    55 => 'Handheld Night Shot', #PH (FZ47)
+    57 => '3D', #PH (3D1)
+    59 => 'Creative Control', #PH (FZ47)
+    60 => 'Intelligent Auto Plus', #20
+    62 => 'Panorama', #17
+    63 => 'Glass Through', #17
+    64 => 'HDR', #17
+    66 => 'Digital Filter', #PH (GF5 "Impressive Art", "Cross Process", "Color Select", "Star")
+    67 => 'Clear Portrait', #18
+    68 => 'Silky Skin', #18
+    69 => 'Backlit Softness', #18
+    70 => 'Clear in Backlight', #18
+    71 => 'Relaxing Tone', #18
+    72 => "Sweet Child's Face", #18
+    73 => 'Distinct Scenery', #18
+    74 => 'Bright Blue Sky', #18
+    75 => 'Romantic Sunset Glow', #18
+    76 => 'Vivid Sunset Glow', #18
+    77 => 'Glistening Water', #18
+    78 => 'Clear Nightscape', #18
+    79 => 'Cool Night Sky', #18
+    80 => 'Warm Glowing Nightscape', #18
+    81 => 'Artistic Nightscape', #18
+    82 => 'Glittering Illuminations', #18
+    83 => 'Clear Night Portrait', #18
+    84 => 'Soft Image of a Flower', #18
+    85 => 'Appetizing Food', #18
+    86 => 'Cute Dessert', #18
+    87 => 'Freeze Animal Motion', #18
+    88 => 'Clear Sports Shot', #18
+    89 => 'Monochrome', #18
+    90 => 'Creative Control', #18
+    92 => 'Handheld Night Shot', #forum11523
 );
 
@@ -209,10 +271,15 @@
         Name => 'ImageQuality',
         Writable => 'int16u',
-        PrintConv => {
+        Notes => 'quality of the main image, which may be in a different file',
+        PrintConv => {
+            1 => 'TIFF', #PH (FZ20)
             2 => 'High',
             3 => 'Normal',
+            # 5 - seen this for 1920x1080, 30fps SZ7 video - PH
             6 => 'Very High', #3 (Leica)
-            7 => 'Raw', #3 (Leica)
+            7 => 'RAW', #3 (Leica)
             9 => 'Motion Picture', #PH (LZ6)
+            11 => 'Full HD Movie', #PH (V-LUX)
+            12 => '4k Movie', #PH (V-LUX)
         },
     },
@@ -245,6 +312,11 @@
             8 => 'Flash',
             10 => 'Black & White', #3 (Leica)
-            11 => 'Manual', #PH (FZ8)
+            11 => 'Manual 2', #PH (FZ8)
             12 => 'Shade', #PH (FS7)
+            13 => 'Kelvin', #PeterK (NC)
+            14 => 'Manual 3', #forum9296
+            15 => 'Manual 4', #forum9296
+            # also seen 18,26 (forum9296)
+            19 => 'Auto (cool)', #PH (Leica C-Lux)
         },
     },
@@ -257,5 +329,7 @@
             4 => 'Auto, Focus button', #4
             5 => 'Auto, Continuous', #4
-            # have seens 6 for GF1 - PH
+            6 => 'AF-S', #18 (also seen for GF1 - PH)
+            7 => 'AF-C', #18
+            8 => 'AF-F', #18 (auto-focus flexible)
         },
     },
@@ -279,4 +353,7 @@
                 '0 1'   => '9-area', # (FS7)
                 '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)
@@ -284,9 +361,15 @@
                 '16 0'  => '1-area', # (FZ8)
                 '16 16' => '1-area (high speed)', # (FZ8)
-                '32 0'  => 'Auto or Face Detect', # (Face Detect for FS7, Auto is DMC-L1 guess)
+                # '32 0' is Face Detect for FS7, and Face Detect or Focus Tracking
+                # for the DMC-FZ200 (ref 17), and Auto is DMC-L1 guess,
+                '32 0'  => 'Tracking',
                 '32 1'  => '3-area (left)?', # (DMC-L1 guess)
                 '32 2'  => '3-area (center)?', # (DMC-L1 guess)
                 '32 3'  => '3-area (right)?', # (DMC-L1 guess)
                 '64 0'  => 'Face Detect',
+                '64 1' => 'Face Detect (animal detect on)', #forum11194
+                '64 2' => 'Face Detect (animal detect off)', #forum11194
+                '128 0' => 'Pinpoint focus', #18/forum11194
+                '240 0' => 'Tracking', #22
             },
         },
@@ -296,8 +379,15 @@
         Writable => 'int16u',
         PrintConv => {
-            2 => 'On, Mode 1',
+            2 => 'On, Optical',
             3 => 'Off',
             4 => 'On, Mode 2',
-            # GF1 also has a mode 3
+            5 => 'On, Optical Panning', #18
+            # GF1 also has a "Mode 3" - PH
+            6 => 'On, Body-only', #PH (GX7, sensor shift?)
+            7 => 'On, Body-only Panning', #forum11194
+            9 => 'Dual IS', #20
+            10 => 'Dual IS Panning', #forum11194
+            11 => 'Dual2 IS', #forum9298
+            12 => 'Dual2 IS Panning', #forum11194
         },
     },
@@ -321,5 +411,9 @@
         Name => 'Audio',
         Writable => 'int16u',
-        PrintConv => { 1 => 'Yes', 2 => 'No' },
+        PrintConv => {
+            1 => 'Yes',
+            2 => 'No',
+            3 => 'Stereo', #PH (NC)
+        },
     },
     0x21 => { #2
@@ -342,4 +436,8 @@
         Format => 'int16s',
         Writable => 'int16s',
+        ValueConv => '$val / 3', #17 (older models may not have factor of 3? - PH)
+        ValueConvInv => '$val * 3',
+        PrintConv => 'Image::ExifTool::Exif::PrintFraction($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     },
     0x25 => { #PH
@@ -362,5 +460,13 @@
         Writable => 'undef',
     },
-    # 0x27 - values: 0 (LZ6,FX10K)
+    0x27 => {
+        Name => 'VideoFrameRate',
+        Writable => 'int16u',
+        Notes => 'only valid for older models',
+        PrintConv => {
+            OTHER => sub { shift },
+            0 => 'n/a',
+        },
+    },
     0x28 => {
         Name => 'ColorEffect',
@@ -374,4 +480,5 @@
             5 => 'Sepia',
             6 => 'Happy', #PH (FX70) (yes, really. you wouldn't want sad colors now would you?)
+            8 => 'Vivid', #PH (SZ3)
         },
     },
@@ -397,7 +504,10 @@
             my $m = int($val / 60);
             $val -= $m * 60;
-            my $s = int($val);
-            my $f = 100 * ($val - int($val));
-            return sprintf("%s%.2d:%.2d:%.2d.%.2d",$str,$h,$m,$s,$f);
+            my $ss = sprintf('%05.2f', $val);
+            if ($ss >= 60) {
+                $ss = '00.00';
+                ++$m >= 60 and $m -= 60, ++$h;
+            }
+            return sprintf("%s%.2d:%.2d:%s",$str,$h,$m,$ss);
         },
         PrintConvInv => sub {
@@ -419,6 +529,10 @@
             0 => 'Off',
             1 => 'On', #PH (TZ5) [was "Low/High Quality" from ref 4]
-            2 => 'Infinite',
+            2 => 'Auto Exposure Bracketing (AEB)', #17
+            3 => 'Focus Bracketing', #forum11194
             4 => 'Unlimited', #PH (TZ5)
+            8 => 'White Balance Bracketing', #18
+            17 => 'On (with flash)', #forum5597
+            18 => 'Aperture Bracketing', #forum11194
         },
     },
@@ -430,5 +544,5 @@
         {
             Name => 'ContrastMode',
-            Condition => '$$self{Model} !~ /^DMC-(FX10|G1|L1|L10|LC80|GF1|TZ10|ZS7)$/',
+            Condition => '$$self{Model} !~ /^DMC-(FX10|G1|L1|L10|LC80|GF\d+|G2|TZ10|ZS7)$/',
             Flags => 'PrintHex',
             Writable => 'int16u',
@@ -439,11 +553,19 @@
             },
             PrintConv => {
-                0 => 'Normal',
-                1 => 'Low',
-                2 => 'High',
-                # 3 - observed with LZ6 and TZ5 in Fireworks mode - PH
-                # 5 - observed with FX01, FX40 and FP8 (EXIF contrast "Normal") - PH
-                6 => 'Medium Low', #PH (FZ18)
-                7 => 'Medium High', #PH (FZ18)
+                0x00 => 'Normal',
+                0x01 => 'Low',
+                0x02 => 'High',
+                # 0x03 - observed with LZ6 and TZ5 in Fireworks mode
+                #        and GX7 in Fantasy/Retro/OldDays/HighKey - PH
+                # 0x04 - observed in MP4 movie with GM1 (EXIF and 0x39 Contrast "Normal") - PH
+                0x05 => 'Normal 2', #forum1194
+                0x06 => 'Medium Low', #PH (FZ18)
+                0x07 => 'Medium High', #PH (FZ18)
+                # 0x08 - GX7 in DynamicMonochrome mode
+                0x0d => 'High Dynamic', #PH (FZ47 in ?)
+                # 0x13 - seen for LX100 (PH)
+                0x18 => 'Dynamic Range (film-like)', #forum11194
+                0x2e => 'Match Filter Effects Toy', #forum11194
+                0x37 => 'Match Photo Style L. Monochrome', #forum11194
                 # DMC-LC1 values:
                 0x100 => 'Low',
@@ -453,8 +575,8 @@
         },{
             Name => 'ContrastMode',
-            Condition => '$$self{Model} eq "DMC-GF1"',
-            Notes => 'these values are used by the GF1',
+            Condition => '$$self{Model} =~ /^DMC-(GF\d+|G2)$/',
+            Notes => 'these values are used by the G2, GF1, GF2, GF3, GF5 and GF6',
             Writable => 'int16u',
-            PrintConv => {
+            PrintConv => { # (decoded for GF1 unless otherwise noted)
                 0 => '-2',
                 1 => '-1',
@@ -463,14 +585,50 @@
                 4 => '+2',
                 # Note: Other Contrast tags will be "Normal" in any of these modes:
-                7 => 'Nature (Color Film)',
-                12 => 'Smooth (Color Film) or Pure (My Color)',
-                17 => 'Dynamic (B&W Film)',
-                22 => 'Smooth (B&W Film)',
-                27 => 'Dynamic (Color Film)',
-                32 => 'Vibrant (Color Film) or Expressive (My Color)',
+                5 => 'Normal 2', # 5 - seen for Portrait (FX80) and Normal (GF6)
+                7 => 'Nature (Color Film)', # (GF1,G2; GF3 "Miniature")
+                9 => 'Expressive', #(GF3)
+                12 => 'Smooth (Color Film) or Pure (My Color)', #(GF1,G2 "Smooth Color")
+                17 => 'Dynamic (B&W Film)', #(GF1,G2)
+                22 => 'Smooth (B&W Film)', #(GF1,G2)
+                25 => 'High Dynamic', #(GF5)
+                26 => 'Retro', #(GF5)
+                27 => 'Dynamic (Color Film)', #(GF1,G2) (GF3 "High Key")
+                28 => 'Low Key', #(GF5)
+                29 => 'Toy Effect', #(GF5)
+                32 => 'Vibrant (Color Film) or Expressive (My Color)', # (GF1; G2 "Vibrant"; GF2,GF5 "Expressive")
                 33 => 'Elegant (My Color)',
-                37 => 'Nostalgic (Color Film)',
-                41 => 'Dynamic Art (My Color)',
+                37 => 'Nostalgic (Color Film)', # (GF1,G2; GF5 "Sepia")
+                41 => 'Dynamic Art (My Color)', # (GF5 "High Key")
                 42 => 'Retro (My Color)',
+                45 => 'Cinema', #(GF2)
+                47 => 'Dynamic Mono', #(GF5)
+                50 => 'Impressive Art', #(GF5)
+                51 => 'Cross Process', #(GF5)
+                100 => 'High Dynamic 2', #Exiv2 (G6)
+                101 => 'Retro 2', #Exiv2 (G6)
+                102 => 'High Key 2', #Exiv2 (G6)
+                103 => 'Low Key 2', #Exiv2 (G6)
+                104 => 'Toy Effect 2', #Exiv2 (G6)
+                107 => 'Expressive 2', #(GF6)
+                112 => 'Sepia', #Exiv2 (G6)
+                117 => 'Miniature', #Exiv2 (G6)
+                122 => 'Dynamic Monochrome', #(GF6)
+                127 => 'Old Days', #Exiv2 (G6)
+                132 => 'Dynamic Monochrome 2', #Exiv2 (G6)
+                135 => 'Impressive Art 2', #Exiv2 (G6)
+                136 => 'Cross Process 2', #Exiv2 (G6)
+                137 => 'Toy Pop', #Exiv2 (G6)
+                138 => 'Fantasy', #Exiv2 (G6)
+                256 => 'Normal 3', #Exiv2 (G6)
+                272 => 'Standard', #Exiv2 (G6)
+                288 => 'High', #Exiv2 (G6)
+                # more new modes for GF6:
+                # ? => 'Old Days',
+                # ? => 'Toy Pop',
+                # ? => 'Bleach Bypass',
+                # ? => 'Fantasy',
+                # ? => 'Star Filter',
+                # ? => 'One Point Color',
+                # ? => 'Sunshine',
             },
         },{
@@ -494,4 +652,5 @@
         Name => 'NoiseReduction',
         Writable => 'int16u',
+        Notes => 'the encoding for this value is not consistent between models',
         PrintConv => {
             0 => 'Standard',
@@ -500,4 +659,11 @@
             3 => 'Lowest (-2)', #JD
             4 => 'Highest (+2)', #JD
+            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',
         },
     },
@@ -506,7 +672,12 @@
         Writable => 'int16u',
         PrintConv => {
+            0 => 'Off (0)', #forum11529
             1 => 'Off',
             2 => '10 s',
             3 => '2 s',
+            4 => '10 s / 3 pictures', #17
+            258 => '2 s after shutter pressed', #forum11194
+            266 => '10 s after shutter pressed', #forum11194
+            778 => '3 photos after 10 s', #forum11194
         },
     },
@@ -576,5 +747,18 @@
     },
     # 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)
+    #        --> may indicate battery power (forum11388)
+    0x38 => { #forum11388
+        Name => 'BatteryLevel',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Full',
+            2 => 'Medium',
+            3 => 'Low',
+            4 => 'Near Empty',
+            7 => 'Near Full',
+            8 => 'Medium Low',
+            256 => 'n/a',
+        },
+    },
     0x39 => { #7 (L1/L10)
         Name => 'Contrast',
@@ -599,37 +783,17 @@
     0x3c => { #PH
         Name => 'ProgramISO', # (maybe should rename this ISOSetting?)
-        Writable => 'int16u',
-        PrintConv => {
-            OTHER => sub { return shift },
+        Writable => 'int16u', # (new models store a long here)
+        PrintConv => {
+            OTHER => sub { shift },
             65534 => 'Intelligent ISO', #PH (FS7)
             65535 => 'n/a',
+            -1 => 'n/a',
         },
     },
     0x3d => { #PH
-        Name => 'AdvancedSceneMode',
-        Writable => 'int16u',
-        # values for the FZ28 (SceneMode/AdvancedSceneMode, "*"=add mode name) - PH:
-        # Portrait: 2/1=Normal*, 24/1=Soft Skin, 2/2=Outdoor*, 2/3=Indoor*, 2/4=Creative*
-        # Scenery: 3/1=Normal*, 3/2=Nature, 3/3=Architecture, 3/4=Creative*
-        # Sports: 4/1=Normal*, 4/2=Outdoor*, 4/3=Indoor*, 4/4=Creative*
-        # Night Scenery: 5/1=Night Portrait, 21/1=*, 21/2=Illuminations, 21/4=Creative*
-        # Macro (Close-up): 9/2=Flower, 22/1=Food, 9/3=Objects, 9/4=Creative*
-        # - have seen value of 5 for TZ5 (Macro) and FS20 (Scenery and Intelligent Auto)
-        #   --> I'm guessing this is "Auto" - PH
-        # - values for HDR mode (ref 12): 1=Standard, 2=Art, 3=B&W
-        PrintConv => {
-            1 => 'Normal',
-            2 => 'Outdoor/Illuminations/Flower/HDR Art',
-            3 => 'Indoor/Architecture/Objects/HDR B&W',
-            4 => 'Creative',
-            5 => 'Auto',
-            7 => 'Expressive', #(GF1)
-            8 => 'Retro', #(GF1)
-            9 => 'Pure', #(GF1)
-            10 => 'Elegant', #(GF1)
-            12 => 'Monochrome', #(GF1)
-            13 => 'Dynamic Art', #(GF1)
-            14 => 'Silhouette', #(GF1)
-        },
+        Name => 'AdvancedSceneType',
+        Writable => 'int16u',
+        Notes => 'used together with SceneMode to derive Composite AdvancedSceneMode',
+        # see forum11194 for more info
     },
     0x3e => { #PH (TZ5/FS7)
@@ -659,5 +823,5 @@
         Writable => 'int16u',
         PrintConv => {
-            0 => 'n/a', #PH (ie. FZ100 "Photo Frame" ShootingMode)
+            0 => 'n/a', #PH (eg. FZ100 "Photo Frame" ShootingMode)
             1 => 'Standard (color)',
             2 => 'Dynamic (color)',
@@ -669,14 +833,39 @@
             # 8 => 'My Film 1'? (from owner manual)
             # 9 => 'My Film 2'?
-            10 => 'Nostalgic', # GH1
-            11 => 'Vibrant', # GH1
+            10 => 'Nostalgic', #(GH1)
+            11 => 'Vibrant', #(GH1)
             # 12 => 'Multi Film'? (in the GH1 specs)
         },
     },
-    # 0x43 - int16u: 2,3
-    # 0x44 - int16u: 0,2500
-    # 0x45 - int16u: 0
+    0x43 => { #forum9369
+        Name => 'JPEGQuality',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'n/a (Movie)',
+            2 => 'High',
+            3 => 'Standard',
+            6 => 'Very High',
+            255 => 'n/a (RAW only)',
+        },
+    },
+    0x44 => {
+        Name => 'ColorTempKelvin',
+        Format => 'int16u',
+    },
+    0x45 => { #19
+        Name => 'BracketSettings',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'No Bracket',
+            1 => '3 Images, Sequence 0/-/+',
+            2 => '3 Images, Sequence -/0/+',
+            3 => '5 Images, Sequence 0/-/+',
+            4 => '5 Images, Sequence -/0/+',
+            5 => '7 Images, Sequence 0/-/+',
+            6 => '7 Images, Sequence -/0/+',
+        },
+    },
     0x46 => { #PH/JD
-        Name => 'WBAdjustAB',
+        Name => 'WBShiftAB',
         Format => 'int16s',
         Writable => 'int16u',
@@ -684,11 +873,26 @@
     },
     0x47 => { #PH/JD
-        Name => 'WBAdjustGM',
+        Name => 'WBShiftGM',
         Format => 'int16s',
         Writable => 'int16u',
         Notes => 'positive is a shift toward green',
     },
-    # 0x48 - int16u: 0
-    # 0x49 - int16u: 2
+    0x48 => { #17
+        Name => 'FlashCurtain',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'n/a',
+            1 => '1st',
+            2 => '2nd',
+        },
+    },
+    0x49 => { #19
+        Name => 'LongExposureNoiseReduction', # (indicates availability, forum11194)
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Off',
+            2 => 'On'
+        }
+    },
     # 0x4a - int16u: 0
     0x4b => { #PH
@@ -723,15 +927,26 @@
         Name => 'LensType',
         Writable => 'string',
+        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
+        ValueConvInv => '$val',
     },
     0x52 => { #7 (DMC-L1)
         Name => 'LensSerialNumber',
         Writable => 'string',
+        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
+        ValueConvInv => '$val',
     },
     0x53 => { #7 (DMC-L1)
         Name => 'AccessoryType',
         Writable => 'string',
-    },
-    # 0x54 - string[14]: "0000000"
-    # 0x55 - int16u: 1
+        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
+        ValueConvInv => '$val',
+    },
+    0x54 => { #19
+        Name => 'AccessorySerialNumber',
+        Writable => 'string',
+        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
+        ValueConvInv => '$val',
+    },
+    # 0x55 - int16u: 1 (see forum9372)
     # 0x57 - int16u: 0
     0x59 => { #PH (FS7)
@@ -763,5 +978,13 @@
         },
     },
-    # 0x5e,0x5f,0x60 - undef[4]
+    # 0x5e,0x5f - undef[4]
+    0x60 => { #18
+        Name => 'LensFirmwareVersion',
+        Writable => 'undef',
+        Format => 'int8u',
+        Count => 4,
+        PrintConv => '$val=~tr/ /./; $val',
+        PrintConvInv => '$val=~tr/./ /; $val',
+    },
     0x61 => { #PH
         Name => 'FaceRecInfo',
@@ -816,9 +1039,10 @@
     },
     # 0x6c - int8u: 1
-    0x6d => { #PH (ZS7)
+    0x6d => { #PH (ZS7) (also see forum5997)
         Name => 'City', # (City/Town)
         Groups => { 2 => 'Location' },
         Format => 'string',
         Writable => 'undef', # (Count 72)
+        Notes => 'City/Town as stored by some models, or County/Township for others',
     },
     # 0x6e - int8u: 1
@@ -843,5 +1067,16 @@
     },
     # 0x71 - undef[128] (maybe text stamp text?)
-    # 0x72,0x73,0x74,0x75,0x76,0x77,0x78: 0
+    0x77 => { #18
+        Name => 'BurstSpeed',
+        Writable => 'int16u',
+        Notes => 'images per second',
+    },
+    # 0x72,0x73,0x74,0x75,0x77,0x78: 0
+    # 0x76: 0, (3 for G6 with HDR on, ref 18)
+    0x76 => { #18/21
+        Name => 'HDRShot',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 3 => 'On' },
+    },
     0x79 => { #PH (GH2)
         Name => 'IntelligentD-Range',
@@ -855,11 +1090,347 @@
     },
     # 0x7a,0x7b: 0
+    0x7c => { #18
+        Name => 'ClearRetouch',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x80 => { #forum5997 (seen garbage here for SZ5 - PH)
+        Name => 'City2', # (City/Town/Village)
+        Groups => { 2 => 'Location' },
+        Format => 'string',
+        Writable => 'undef', # (Count 72)
+        Notes => 'City/Town/Village as stored by some models',
+    },
+    # 0x81 - undef[72]: "---"
+    # 0x82 - undef[72]: "---"
+    # 0x83 - undef[72]: "---"
+    # 0x84 - undef[72]: "---"
+    # 0x85 - undef[128]: "---"
+    0x86 => { #http://dev.exiv2.org/issues/825
+        Name => 'ManometerPressure',
+        Writable => 'int16u',
+        RawConv => '$val==65535 ? undef : $val',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f kPa",$val)',
+        PrintConvInv => '$val=~s/ ?kPa//i; $val',
+    },
+    0x89 => {
+        Name => 'PhotoStyle',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Standard or Custom',
+            2 => 'Vivid',
+            3 => 'Natural',
+            4 => 'Monochrome',
+            5 => 'Scenery',
+            6 => 'Portrait',
+            8 => 'Cinelike D', #forum11194
+            9 => 'Cinelike V', #forum11194
+            11 => 'L. Monochrome', #forum11194
+            15 => 'L. Monochrome D', #forum11194
+        },
+    },
+    0x8a => { #18
+        Name => 'ShadingCompensation',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On'
+        }
+    },
+    0x8b => { #21
+        Name => 'WBShiftIntelligentAuto',
+        Writable => 'int16u',
+        Format => 'int16s',
+        Notes => 'value is -9 for blue to +9 for amber.  Valid for Intelligent-Auto modes',
+    },
+    0x8c => {
+        Name => 'AccelerometerZ',
+        Writable => 'int16u',
+        Format => 'int16s',
+        Notes => 'positive is acceleration upwards',
+    },
+    0x8d => {
+        Name => 'AccelerometerX',
+        Writable => 'int16u',
+        Format => 'int16s',
+        Notes => 'positive is acceleration to the left',
+    },
+    0x8e => {
+        Name => 'AccelerometerY',
+        Writable => 'int16u',
+        Format => 'int16s',
+        Notes => 'positive is acceleration backwards',
+    },
+    0x8f => { #18
+        Name => 'CameraOrientation',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Rotate CW',
+            2 => 'Rotate 180',
+            3 => 'Rotate CCW',
+            4 => 'Tilt Upwards',
+            5 => 'Tilt Downwards'
+        }
+    },
+    0x90 => {
+        Name => 'RollAngle',
+        Writable => 'int16u',
+        Format => 'int16s',
+        Notes => 'converted to degrees of clockwise camera rotation',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+    },
+    0x91 => {
+        Name => 'PitchAngle',
+        Writable => 'int16u',
+        Format => 'int16s',
+        Notes => 'converted to degrees of upward camera tilt',
+        ValueConv => '-$val / 10',
+        ValueConvInv => '-$val * 10',
+    },
+    0x92 => { #21 (forum9453) (more to decode in forum11194)
+        Name => 'WBShiftCreativeControl',
+        Writable => 'int8u',
+        Format => 'int8s',
+        Notes => 'WB shift or style strength.  Valid for Creative-Control modes',
+    },
+    0x93 => { #18
+        Name => 'SweepPanoramaDirection',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Left to Right',
+            2 => 'Right to Left',
+            3 => 'Top to Bottom',
+            4 => 'Bottom to Top'
+        }
+    },
+    0x94 => { #18
+        Name => 'SweepPanoramaFieldOfView',
+        Writable => 'int16u'
+    },
+    0x96 => { #18
+        Name => 'TimerRecording',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Time Lapse',
+            2 => 'Stop-motion Animation',
+            3 => 'Focus Bracketing', #forum11194
+        },
+    },
+    0x9d => { #18
+        Name => 'InternalNDFilter',
+        Writable => 'rational64u'
+    },
+    0x9e => { #18
+        Name => 'HDR',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            100 => '1 EV',
+            200 => '2 EV',
+            300 => '3 EV',
+            32868 => '1 EV (Auto)',
+            32968 => '2 EV (Auto)',
+            33068 => '3 EV (Auto)',
+        },
+    },
+    0x9f => { #18
+        Name => 'ShutterType',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Mechanical',
+            1 => 'Electronic',
+            2 => 'Hybrid', #PH (GM1, 1st curtain electronic, 2nd curtain mechanical)
+        },
+    },
+    # 0xa0 - undef[32]: AWB gains and black levels (ref forum9303)
+    0xa1 => { #forum11194
+        Name => 'FilterEffect',
+        Writable => 'rational64u',
+        Format => 'int32u',
+        PrintConv => {
+            '0 0' => 'Expressive',
+            # '0 1' => have seen this for XS1 (PH)
+            '0 2' => 'Retro',
+            '0 4' => 'High Key',
+            '0 8' => 'Sepia',
+            '0 16' => 'High Dynamic',
+            '0 32' => 'Miniature Effect',
+            '0 256' => 'Low Key',
+            '0 512' => 'Toy Effect',
+            '0 1024' => 'Dynamic Monochrome',
+            '0 2048' => 'Soft Focus',
+            '0 4096' => 'Impressive Art',
+            '0 8192' => 'Cross Process',
+            '0 16384' => 'One Point Color',
+            '0 32768' => 'Star Filter',
+            '0 524288' => 'Old Days',
+            '0 1048576' => 'Sunshine',
+            '0 2097152' => 'Bleach Bypass',
+            '0 4194304' => 'Toy Pop',
+            '0 8388608' => 'Fantasy',
+            '0 33554432' => 'Monochrome',
+            '0 67108864' => 'Rough Monochrome',
+            '0 134217728' => 'Silky Monochrome',
+        },
+    },
+    0xa3 => { #18
+        Name => 'ClearRetouchValue',
+        Writable => 'rational64u',
+        # undef if ClearRetouch is off, 0 if it is on
+    },
+    0xa7 => { #forum9374 (conversion table for 14- to 16-bit mapping)
+        Name => 'OutputLUT',
+        Binary => 1,
+        Notes => q{
+            2-column by 432-row binary lookup table of unsigned short values for
+            converting to 16-bit output (1st column) from 14 bits (2nd column) with
+            camera contrast
+        },
+    },
+    0xab => { #18
+        Name => 'TouchAE',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0xac => { #forum11194
+        Name => 'MonochromeFilterEffect',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'Yellow', 2 => 'Orange', 3 => 'Red', 4 => 'Green' },
+    },
+    0xad => { #forum9360
+        Name => 'HighlightShadow',
+        Writable => 'int16u',
+        Format => 'int16s', #forum11194
+        Count => 2,
+    },
+    0xaf => { #PH (is this in UTC maybe? -- sometimes different time zone other times)
+        Name => 'TimeStamp',
+        Writable => 'string',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
+    },
+    0xb3 => { #forum11194
+        Name => 'VideoBurstResolution',
+        Writable => 'int16u',
+        PrintConv => { 1 => 'Off or 4K', 4 => '6K' },
+    },
+    0xb4 => { #forum9429
+        Name => 'MultiExposure',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'n/a', 1 => 'Off', 2 => 'On' },
+    },
+    0xb9 => { #forum9425
+        Name => 'RedEyeRemoval',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0xbb => { #forum9282
+        Name => 'VideoBurstMode',
+        Writable => 'int32u',
+        PrintHex => 1,
+        PrintConv => {
+            0x01 => 'Off',
+            0x04 => 'Post Focus',
+            0x18 => '4K Burst',
+            0x28 => '4K Burst (Start/Stop)',
+            0x48 => '4K Pre-burst',
+            0x108 => 'Loop Recording',
+            0x810 => '6K Burst',
+            0x820 => '6K Burst (Start/Stop)',
+            0x408 => 'Focus Stacking', #forum11563
+            0x1001 => 'High Resolution Mode',
+        },
+    },
+    0xbc => { #forum9282
+        Name => 'DiffractionCorrection',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'Auto' },
+    },
+    0xbd => { #forum11194
+        Name => 'FocusBracket',
+        Notes => 'positive is further, negative is closer',
+        Writable => 'int16u',
+        Format => 'int16s',
+    },
+    0xbe => { #forum11194
+        Name => 'LongExposureNRUsed',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0xbf => { #forum11194
+        Name => 'PostFocusMerging',
+        Format => 'int32u',
+        Count => 2,
+        PrintConv => { '0 0' => 'Post Focus Auto Merging or None' },
+    },
+    0xc1 => { #forum11194
+        Name => 'VideoPreburst',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'No', 1 => '4K or 6K' },
+    },
+    0xca => { #forum11459
+        Name => 'SensorType',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Multi-aspect',
+            1 => 'Standard',
+        },
+    },
+    # 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',
+    },
+    0xd2 => { #forum11194
+        Name => 'MonochromeGrainEffect',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Standard',
+            3 => 'High',
+        },
+    },
+    0xd6 => { #PH (DC-S1)
+        Name => 'NoiseReductionStrength',
+        Writable => 'rational64s',
+    },
     0x0e00 => {
         Name => 'PrintIM',
         Description => 'Print Image Matching',
         Writable => 0,
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::PrintIM::Main',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::PrintIM::Main' },
+    },
+    0x2003 => { #21
+        Name => 'TimeInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::TimeInfo' },
     },
     0x8000 => { #PH
@@ -876,7 +1447,14 @@
         },
     },
-    # 0x8002 - values: 1,2 related to focus? (PH/JD)
-    #          1 for HDR modes, 2 for Portrait (ref 12)
-    # 0x8003 - values: 1,2 related to focus? (PH/JD)
+    0x8002 => { #21
+        Name => 'HighlightWarning',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Disabled', 1 => 'No', 2 => 'Yes' },
+    },
+    0x8003 => { #21
+        Name => 'DarkFocusEnvironment',
+        Writable => 'int16u',
+        PrintConv => { 1 => 'No', 2 => 'Yes' },
+    },
     0x8004 => { #PH/JD
         Name => 'WBRedLevel',
@@ -891,9 +1469,9 @@
         Writable => 'int16u',
     },
-    0x8007 => { #PH
-        Name => 'FlashFired',
-        Writable => 'int16u',
-        PrintConv => { 1 => 'No', 2 => 'Yes' },
-    },
+    #0x8007 => { #PH - questionable [disabled because it conflicts with EXIF in too many samples]
+    #    Name => 'FlashFired',
+    #    Writable => 'int16u',
+    #    PrintConv => { 0 => 'Yes', 1 => 'No' },
+    #},
     0x8008 => { #PH (TZ5/FS7)
         # (tags 0x3b, 0x3e, 0x8008 and 0x8009 have the same values in all my samples - PH)
@@ -978,6 +1556,10 @@
     },
     0x310 => {
-        Name => 'LensInfo',
-        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::LensInfo' },
+        Name => 'LensType',
+        Writable => 'int32u',
+        SeparateTable => 1,
+        ValueConv => '($val >> 2) . " " . ($val & 0x3)',
+        ValueConvInv => \&LensTypeConvInv,
+        PrintConv => \%leicaLensTypes,
     },
     0x311 => {
@@ -1036,4 +1618,8 @@
     WRITABLE => 1,
     NOTES => 'These tags are used by the Leica R8 and R9 digital backs.',
+    0x0b => { #IB
+        Name => 'SerialInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::SerialInfo' },
+    },
     0x0d => {
         Name => 'WB_RGBLevels',
@@ -1041,4 +1627,16 @@
         Count => 3,
     },
+);
+
+# Leica serial number info (ref IB)
+%Image::ExifTool::Panasonic::SerialInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
+    TAG_PREFIX => 'Leica_SerialInfo',
+    FIRST_ENTRY => 0,
+    4 => {
+        Name => 'SerialNumber',
+        Format => 'string[8]',
+    }
 );
 
@@ -1209,5 +1807,5 @@
         ValueConv => '($val >> 2) . " " . ($val & 0x3)',
         ValueConvInv => \&LensTypeConvInv,
-        PrintConv => \%leicaLensType,
+        PrintConv => \%leicaLensTypes,
     },
     0x3406 => { #PH/13
@@ -1244,4 +1842,36 @@
     },
     # 0x3903 - larger binary data block
+);
+
+# time stamp information (ref 21)
+%Image::ExifTool::Panasonic::TimeInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Panasonic', 2 => 'Image' },
+    FIRST_ENTRY => 0,
+    WRITABLE => 1,
+    0 => {
+        Name => 'PanasonicDateTime',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        Format => 'undef[8]',
+        RawConv => '$val =~ /^\0/ ? undef : $val',
+        ValueConv => 'sprintf("%s:%s:%s %s:%s:%s.%s", unpack "H4H2H2H2H2H2H2", $val)',
+        ValueConvInv => q{
+            $val =~ s/[-+].*//;     # remove time zone
+            $val =~ tr/0-9//dc;     # remove non-digits
+            $val = pack("H*",$val);
+            $val .= "\0" while length $val < 8;
+            return $val;
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
+    },
+    # 8 - 8 bytes usually 8 x 0xff (spot for another date/time?)
+    16 => {
+        Name => 'TimeLapseShotNumber',
+        Format => 'int32u',
+    },
 );
 
@@ -1256,10 +1886,10 @@
     0x0016 => {
         Name => 'LensType',
-        Writable => 'int32u',
+        Format => 'int32u',
         Priority => 0,
         SeparateTable => 1,
-        ValueConv => '($val >> 2) . " " . ($val & 0x3)',
+        ValueConv => '(($val >> 2) & 0xffff) . " " . ($val & 0x3)',
         ValueConvInv => \&LensTypeConvInv,
-        PrintConv => \%leicaLensType,
+        PrintConv => \%leicaLensTypes,
     },
 );
@@ -1278,8 +1908,27 @@
     GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
     WRITABLE => 1,
-    NOTES => 'This information is written by the X1.',
+    PRIORITY => 0,
+    NOTES => 'This information is written by the X1, X2, X VARIO and T.',
+    0x0303 => {
+        Name => 'LensType',
+        Condition => '$format eq "string"',
+        Notes => 'Leica T only',
+        Writable => 'string',
+    },
+    # 0x0304 - int8u[1]: may be M-lens ID for Leica SL, mounted through "M-adapter L" (ref IB)
+    #          --> int8u[4] for some models (maybe not lens ID for these?) - PH
+    #          (see http://us.leica-camera.com/Photography/Leica-APS-C/Lenses-for-Leica-TL/L-Adapters/M-Adapter-L)
+    #          58 = 'Leica Noctilux-M 75mm F1.25 ASPH (Typ 601) on Leica SL
+    0x0305 => { #IB
+        Name => 'SerialNumber',
+        Writable => 'int32u',
+    },
     # 0x0406 - saturation or sharpness
     0x0407 => { Name => 'OriginalFileName', Writable => 'string' },
     0x0408 => { Name => 'OriginalDirectory',Writable => 'string' },
+    0x040a => { #IB
+        Name => 'FocusInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::FocusInfo' },
+    },
     # 0x040b - related to white balance
     0x040d => {
@@ -1289,12 +1938,72 @@
         PrintConv => {
             '0 0 0 0' => 'Program AE',
+          # '0 1 0 0' - seen for X (Typ 113) - PH
             '1 0 0 0' => 'Aperture-priority AE',
+            '1 1 0 0' => 'Aperture-priority AE (1)', # (see for Leica T)
             '2 0 0 0' => 'Shutter speed priority AE', #(guess)
             '3 0 0 0' => 'Manual',
         },
     },
-    # 0x0411 - saturation or sharpness
+    0x0410 => {
+        Name => 'ShotInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::ShotInfo' },
+    },
+    # 0x0410 - int8u[16]: first byte is FileNumber
+    # 0x0411 - int8u[4]: first number is FilmMode (1=Standard,2=Vivid,3=Natural,4=BW Natural,5=BW High Contrast)
     0x0412 => { Name => 'FilmMode',         Writable => 'string' },
     0x0413 => { Name => 'WB_RGBLevels',     Writable => 'rational64u', Count => 3 },
+    0x0500 => {
+        Name => 'InternalSerialNumber',
+        Writable => 'undef',
+        PrintConv => q{
+            return $val unless $val=~/^(.{3})(\d{2})(\d{2})(\d{2})(\d{4})/;
+            my $yr = $2 + ($2 < 70 ? 2000 : 1900);
+            return "($1) $yr:$3:$4 no. $5";
+        },
+        PrintConvInv => '$_=$val; tr/A-Z0-9//dc; s/(.{3})(19|20)/$1/; $_',
+    },
+);
+
+# Leica type5 ShotInfo (ref PH) (X2)
+%Image::ExifTool::Panasonic::ShotInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
+    TAG_PREFIX => 'Leica_ShotInfo',
+    FIRST_ENTRY => 0,
+    WRITABLE => 1,
+    0 => {
+        Name => 'FileIndex',
+        Format => 'int16u',
+    },
+);
+
+# Leica type5 FocusInfo (ref IB)
+%Image::ExifTool::Panasonic::FocusInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
+    TAG_PREFIX => 'Leica_FocusInfo',
+    FIRST_ENTRY => 0,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    0 => {
+        Name => 'FocusDistance',
+        ValueConv => '$val / 1000',
+        ValueConvInv => '$val * 1000',
+        PrintConv => '$val < 65535 ? "$val m" : "inf"',
+        PrintConvInv => '$val =~ s/ ?m$//; IsFloat($val) ? $val : 65535',
+    },
+    1 => {
+        Name => 'FocalLength',
+        Priority => 0,
+        RawConv => '$val ? $val : undef',
+        ValueConv => '$val / 1000',
+        ValueConvInv => '$val * 1000',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
 );
 
@@ -1304,9 +2013,13 @@
     CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
-    NOTES => 'This information is written by the S2 (as a trailer in JPEG images).',
+    NOTES => q{
+        This information is written by the S2 and M (Typ 240), as a trailer in JPEG
+        images.
+    },
     0x300 => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         Writable => 'undef',
-        Notes => 'S2',
+        Notes => 'S2 and M (Typ 240)',
         DataTag => 'PreviewImage',
         RawConv => q{
@@ -1325,10 +2038,102 @@
         Flags => [ 'Unknown', 'Binary', 'Drop' ],
     },
-    # 0x302 - same value as 4 unknown bytes at the end of JPEG or after the DNG TIFF header
+    # 0x302 - same value as 4 unknown bytes at the end of JPEG or after the DNG TIFF header (ImageID, ref IB)
     0x303 => {
         Name => 'LensType',
         Writable => 'string',
-    },
-    # 0x340 - same as 0x302
+        ValueConv => '$val=~s/ +$//; $val', # trim trailing spaces
+        ValueConvInv => '$val',
+    },
+    0x304 => { #IB
+        Name => 'FocusDistance',
+        Notes => 'focus distance in mm for most models, but cm for others',
+        Writable => 'int32u',
+    },
+    0x311 => {
+        Name => 'ExternalSensorBrightnessValue',
+        Condition => '$$self{Model} =~ /Typ 006/',
+        Notes => 'Leica S only',
+        Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
+        Writable => 'rational64s',
+        PrintConv => 'sprintf("%.2f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x312 => {
+        Name => 'MeasuredLV',
+        Condition => '$$self{Model} =~ /Typ 006/',
+        Notes => 'Leica S only',
+        Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
+        Writable => 'rational64s',
+        PrintConv => 'sprintf("%.2f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x320 => {
+        Name => 'FirmwareVersion',
+        Condition => '$$self{Model} =~ /Typ 006/',
+        Notes => 'Leica S only',
+        Writable => 'int8u',
+        Count => 4,
+        PrintConv => '$val=~tr/ /./; $val',
+        PrintConvInv => '$val=~tr/./ /; $val',
+    },
+    0x321 => { #IB
+        Name => 'LensSerialNumber',
+        Condition => '$$self{Model} =~ /Typ 006/',
+        Notes => 'Leica S only',
+        Writable => 'int32u',
+        PrintConv => 'sprintf("%.10d",$val)',
+        PrintConvInv => '$val',
+    },
+    # 0x321 - SerialNumber for Leica S? (ref IB)
+    # 0x340 - same as 0x302 (ImageID, ref IB)
+);
+
+# Leica type9 maker notes (ref IB) (S)
+%Image::ExifTool::Panasonic::Leica9 = (
+    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) and M10 models.',
+    0x304 => {
+        Name => 'FocusDistance',
+        Notes => 'focus distance in mm for most models, but cm for others',
+        Writable => 'int32u',
+    },
+    0x311 => {
+        Name => 'ExternalSensorBrightnessValue',
+        Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
+        Writable => 'rational64s',
+        PrintConv => 'sprintf("%.2f", $val)',
+        PrintConvInv => '$val',
+    },
+    0x312 => {
+        Name => 'MeasuredLV',
+        Format => 'rational64s', # (may be incorrectly unsigned in JPEG images)
+        Writable => 'rational64s',
+        PrintConv => 'sprintf("%.2f", $val)',
+        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)
 );
 
@@ -1351,33 +2156,4 @@
     # (minimum is 16, maximum is 136.  Value is 0 for pictures captured from video)
     3 => 'Gain',
-);
-
-# lens information (ref 10)
-%Image::ExifTool::Panasonic::LensInfo = (
-    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
-    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
-    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
-    GROUPS => { 0 => 'MakerNotes', 1 => 'Leica', 2 => 'Camera' },
-    WRITABLE => 1,
-    FORMAT => 'int32u',
-    FIRST_ENTRY => 0,
-    0 => {
-        Name => 'LensType',
-        Mask => 0xfffffffc,
-        PrintHex => 0,
-        SeparateTable => 1,
-        ValueConv => '$val >> 2',
-        ValueConvInv => '$val << 2',
-        PrintConv => \%leicaLensType,
-    },
-    0.1 => { # lower 2 bits give frame selector position
-        Name => 'FrameSelector',
-        Mask => 0x03,
-        PrintConv => {
-            1 => '28/90mm frame lines engaged',
-            2 => '24/35mm frame lines engaged',
-            3 => '50/75mm frame lines engaged',
-        },
-    },
 );
 
@@ -1503,4 +2279,285 @@
 );
 
+# PANA atom found in user data of MP4 videos (ref PH)
+%Image::ExifTool::Panasonic::PANA = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    NOTES => q{
+        Tags extracted from the PANA and LEIC user data found in MP4 videos from
+        various Panasonic and Leica models.
+    },
+    0x00 => {
+        Name => 'Make',
+        Condition => '$$valPt =~ /^(LEICA|Panasonic)/', # (only seen "LEICA")
+        Groups => { 2 => 'Camera' },
+        Format => 'string[22]',
+        RawConv => '$$self{LeicaLEIC} = 1;$$self{Make} = $val',
+    },
+    0x04 => {
+        Name => 'Model',
+        Condition => '$$valPt =~ /^[^\0]{6}/ and not $$self{LeicaLEIC}',
+        Description => 'Camera Model Name',
+        Groups => { 2 => 'Camera' },
+        Format => 'string[16]',
+        RawConv => '$$self{Model} = $val',
+    },
+    0x0c => { # (FZ1000)
+        Name => 'Model',
+        Condition => '$$valPt =~ /^[^\0]{6}/ and not $$self{LeicaLEIC} and not $$self{Model}',
+        Description => 'Camera Model Name',
+        Groups => { 2 => 'Camera' },
+        Format => 'string[16]',
+        RawConv => '$$self{Model} = $val',
+    },
+    0x10 => { # (DC-FT7)
+        Name => 'JPEG-likeData',
+        # looks like a JPEG preview, but not a well-formed JPEG file
+        Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
+        Format => 'undef[$size-0x10]',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            Start => 12,
+        },
+    },
+    0x16 => {
+        Name => 'Model',
+        Condition => '$$self{LeicaLEIC}',
+        Description => 'Camera Model Name',
+        Groups => { 2 => 'Camera' },
+        Format => 'string[30]',
+        RawConv => '$$self{Model} = $val',
+    },
+    0x40 => {
+        Name => 'ThumbnailTest',
+        Format => 'undef[0x600]',
+        Hidden => 1,
+        RawConv => q{
+            if (substr($val,0x1c,3) eq "\xff\xd8\xff") { # offset 0x5c
+                $$self{ThumbType} = 1;
+            } elsif (substr($val,0x506,3) eq "\xff\xd8\xff") { # offset 0x546
+                $$self{ThumbType} = 2;
+            } elsif (substr($val,0x51e,3) eq "\xff\xd8\xff") { # offset 0x55e (Leica T)
+                $$self{ThumbType} = 3;
+            } else {
+                $$self{ThumbType} = 0;
+            }
+            return undef;
+        },
+    },
+    0x34 => {
+        Name => 'Version1',
+        Condition => '$$self{LeicaLEIC}',
+        Format => 'string[14]',
+    },
+    0x3e => {
+        Name => 'Version2',
+        Condition => '$$self{LeicaLEIC}',
+        Format => 'string[14]',
+    },
+    0x50 => {
+        Name => 'MakerNoteLeica5',
+        Condition => '$$self{LeicaLEIC}',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Panasonic::Leica5',
+            ProcessProc => \&ProcessLeicaLEIC,
+        },
+    },
+    0x58 => {
+        Name => 'ThumbnailWidth',
+        Condition => '$$self{ThumbType} == 1',
+        Notes => 'Panasonic models',
+        Format => 'int16u',
+    },
+    0x5a => {
+        Name => 'ThumbnailHeight',
+        Condition => '$$self{ThumbType} == 1',
+        Format => 'int16u',
+    },
+    0x5c => {
+        Name => 'ThumbnailImage',
+        Condition => '$$self{ThumbType} == 1',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[16384]',
+        ValueConv => '$val=~s/\0*$//; \$val',   # remove trailing zeros
+    },
+    # 0x5c - there is some messed-up EXIF-IFD-looking data starting here in
+    #        Leica X VARIO MP4 videos, but it doesn't quite make sense
+    0x536 => { # (Leica X VARIO)
+        Name => 'ThumbnailWidth',
+        Condition => '$$self{ThumbType} == 2',
+        Notes => 'Leica X Vario',
+        Format => 'int32uRev', # (little-endian)
+    },
+    0x53a => { # (Leica X VARIO)
+        Name => 'ThumbnailHeight',
+        Condition => '$$self{ThumbType} == 2',
+        Format => 'int32uRev', # (little-endian)
+    },
+    0x53e => { # (Leica X VARIO)
+        Name => 'ThumbnailLength',
+        Condition => '$$self{ThumbType} == 2',
+        Format => 'int32uRev', # (little-endian)
+    },
+    0x546 => { # (Leica X VARIO)
+        Name => 'ThumbnailImage',
+        Condition => '$$self{ThumbType} == 2',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{0x53e}]',
+        Binary => 1,
+    },
+    0x54e => { # (Leica T)
+        Name => 'ThumbnailWidth',
+        Condition => '$$self{ThumbType} == 3',
+        Notes => 'Leica X Vario',
+        Format => 'int32uRev', # (little-endian)
+    },
+    0x552 => { # (Leica T)
+        Name => 'ThumbnailHeight',
+        Condition => '$$self{ThumbType} == 3',
+        Format => 'int32uRev', # (little-endian)
+    },
+    0x556 => { # (Leica T)
+        Name => 'ThumbnailLength',
+        Condition => '$$self{ThumbType} == 3',
+        Format => 'int32uRev', # (little-endian)
+    },
+    0x55e => { # (Leica T)
+        Name => 'ThumbnailImage',
+        Condition => '$$self{ThumbType} == 3',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{0x556}]',
+        Binary => 1,
+    },
+    0x4068 => {
+        Name => 'ExifData',
+        Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            Start => 12,
+        },
+    },
+    0x4080 => { # (FZ1000)
+        Name => 'ExifData',
+        Condition => '$$valPt =~ /^\xff\xd8\xff\xe1..Exif\0\0/s',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            Start => 12,
+        },
+    },
+);
+
+# Panasonic Composite tags
+%Image::ExifTool::Panasonic::Composite = (
+    GROUPS => { 2 => 'Camera' },
+    AdvancedSceneMode => {
+        SeparateTable => 'Panasonic AdvancedSceneMode',    # print values in a separate table
+        Require => {
+            0 => 'Model',
+            1 => 'SceneMode',
+            2 => 'AdvancedSceneType',
+        },
+        ValueConv => '"$val[0] $val[1] $val[2]"',
+        PrintConv => { #PH
+            OTHER => sub {
+                my ($val,$flag,$conv) = @_;
+                $val =~ s/.* (\d+ \d+)/$1/; # drop model name
+                return $$conv{$val} if $$conv{$val};
+                my @v = split ' ', $val;
+                my $prt = $shootingMode{$v[0]};
+                # AdvancedSceneType=1 for non-automatic modes P,A,S,SCN (ref 19)
+                # AdvancedSceneType=5 for automatic mode iA (ref 19)
+                if ($prt) {
+                    return $prt if $v[1] == 1;
+                    return "$prt (intelligent auto)" if $v[1] == 5; #forum11523
+                    return "$prt (intelligent auto plus)" if $v[1] == 7; #forum11523
+                    return "$prt ($v[1])";
+                }
+                return "Unknown ($val)";
+            },
+            Notes => 'A Composite tag derived from Model, SceneMode and AdvancedSceneType.',
+            '0 1' => 'Off',
+            # '0 7' - seen this for V-LUX movies (PH)
+            # '0 8' - seen for D-LUX(Typ104) movies (PH)
+            '2 2' => 'Outdoor Portrait', #(FZ28)
+            '2 3' => 'Indoor Portrait', #(FZ28)
+            '2 4' => 'Creative Portrait', #(FZ28)
+            '3 2' => 'Nature', #(FZ28)
+            '3 3' => 'Architecture', #(FZ28)
+            '3 4' => 'Creative Scenery', #(FZ28)
+            #'3 5' - ? (FT1)
+            '4 2' => 'Outdoor Sports', #(FZ28)
+            '4 3' => 'Indoor Sports', #(FZ28)
+            '4 4' => 'Creative Sports', #(FZ28)
+            '9 2' => 'Flower', #(FZ28)
+            '9 3' => 'Objects', #(FZ28)
+            '9 4' => 'Creative Macro', #(FZ28)
+            #'9 5' - ? (GF3)
+            '18 1' => 'High Sensitivity', #forum11523 (TZ5)
+            '20 1' => 'Fireworks', #forum11523 (TZ5)
+            '21 2' => 'Illuminations', #(FZ28)
+            '21 4' => 'Creative Night Scenery', #(FZ28)
+            #'21 5' - ? (LX3)
+            '26 1' => 'High-speed Burst (shot 1)', #forum11523 (TZ5)
+            '27 1' => 'High-speed Burst (shot 2)', #forum11523 (TZ5)
+            '29 1' => 'Snow', #forum11523 (TZ5)
+            '30 1' => 'Starry Sky', #forum11523 (TZ5)
+            '31 1' => 'Beach', #forum11523 (TZ5)
+            '36 1' => 'High-speed Burst (shot 3)', #forum11523 (TZ5)
+            #'37 5' - ? (various)
+            '39 1' => 'Aerial Photo / Underwater / Multi-aspect', #forum11523 (TZ5)
+            '45 2' => 'Cinema', #(GF2)
+            '45 7' => 'Expressive', #(GF1,GF2)
+            '45 8' => 'Retro', #(GF1,GF2)
+            '45 9' => 'Pure', #(GF1,GF2)
+            '45 10' => 'Elegant', #(GF1,GF2)
+            '45 12' => 'Monochrome', #(GF1,GF2)
+            '45 13' => 'Dynamic Art', #(GF1,GF2)
+            '45 14' => 'Silhouette', #(GF1,GF2)
+            '51 2' => 'HDR Art', #12
+            '51 3' => 'HDR B&W', #12
+            '59 1' => 'Expressive', #(GF5)
+            '59 2' => 'Retro', #(GF5)
+            '59 3' => 'High Key', #(GF5)
+            '59 4' => 'Sepia', #(GF3,GF5)
+            '59 5' => 'High Dynamic', #(GF3,GF5)
+            '59 6' => 'Miniature', #(GF3)
+            '59 9' => 'Low Key', #(GF5)
+            '59 10' => 'Toy Effect', #(GF5)
+            '59 11' => 'Dynamic Monochrome', #(GF5)
+            '59 12' => 'Soft', #(GF5)
+            '66 1' => 'Impressive Art', #19
+            '66 2' => 'Cross Process', #(GF5)
+            '66 3' => 'Color Select', #(GF5) (called "One Point Color" by some other models - PH)
+            '66 4' => 'Star', #(GF5)
+            '90 3' => 'Old Days', #18
+            '90 4' => 'Sunshine', #18
+            '90 5' => 'Bleach Bypass', #18
+            '90 6' => 'Toy Pop', #18
+            '90 7' => 'Fantasy', #18
+            '90 8' => 'Monochrome', #PH (GX7)
+            '90 9' => 'Rough Monochrome', #PH (GX7)
+            '90 10' => 'Silky Monochrome', #PH (GX7)
+            '92 1' => 'Handheld Night Shot', #Horst Wandres (FZ1000)
+            # TZ40 Creative Control modes (ref 19)
+            'DMC-TZ40 90 1' => 'Expressive',
+            'DMC-TZ40 90 2' => 'Retro',
+            'DMC-TZ40 90 3' => 'High Key',
+            'DMC-TZ40 90 4' => 'Sepia',
+            'DMC-TZ40 90 5' => 'High Dynamic',
+            'DMC-TZ40 90 6' => 'Miniature',
+            'DMC-TZ40 90 9' => 'Low Key',
+            'DMC-TZ40 90 10' => 'Toy Effect',
+            'DMC-TZ40 90 11' => 'Dynamic Monochrome',
+            'DMC-TZ40 90 12' => 'Soft',
+        },
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Panasonic');
+
 #------------------------------------------------------------------------------
 # Inverse conversion for Leica M9 lens codes
@@ -1537,7 +2594,36 @@
 
 #------------------------------------------------------------------------------
+# Process Leica makernotes in LEIC atom of MP4 videos (Leica T and X Vario)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessLeicaLEIC($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
+    return 0 if $dirLen < 6;
+    SetByteOrder('II');
+    my $numEntries = Get16u($dataPt, $dirStart);
+    return 0 if $numEntries < 1 or $numEntries > 255;
+    my $size = Get32u($dataPt, $dirStart + 2);
+    return 0 if $size < $numEntries * 12 or $size + 6 > $dirLen;
+    # the Leica programmers want to make things difficult, so they store
+    # the entry count before the directory size, making it impossible to
+    # process as a standard TIFF IFD without a bit of reorganization...
+    Set16u($numEntries, $dataPt, $dirStart + 4);
+    my %dirInfo = %$dirInfo;
+    $dirInfo{DirStart} = $dirStart + 4;
+    $dirInfo{DirLen} = $size - 4;
+    $dirInfo{DataPos} -= $dirStart;
+    $dirInfo{Base} += $dirStart;
+    return Image::ExifTool::Exif::ProcessExif($et, \%dirInfo, $tagTablePtr);
+    return 1;
+}
+
+#------------------------------------------------------------------------------
 # 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
@@ -1550,7 +2636,7 @@
 sub ProcessLeicaTrailer($;$)
 {
-    my ($exifTool, $newPos) = @_;
-    my $trail = $$exifTool{LeicaTrailer};
-    my $raf = $$exifTool{RAF};
+    my ($et, $newPos) = @_;
+    my $trail = $$et{LeicaTrailer};
+    my $raf = $$et{RAF};
     my $trailPos = $$trail{TrailPos};
     my $pos = $trailPos || $$trail{Offset};
@@ -1558,8 +2644,8 @@
     my ($buff, $result, %tagPtr);
 
-    delete $$exifTool{LeicaTrailer} if $trailPos;   # done after this
+    delete $$et{LeicaTrailer} if $trailPos;   # done after this
     unless ($len > 0) {
-        $exifTool->Warn('Missing Leica MakerNote trailer', 1) if $trailPos;
-        undef $$exifTool{LeicaTrailer};
+        $et->Warn('Missing Leica MakerNote trailer', 1) if $trailPos;
+        delete $$et{LeicaTrailer};
         return undef;
     }
@@ -1568,5 +2654,5 @@
     $raf->Seek($oldPos, 0);
     unless ($ok) {
-        $exifTool->Warn('Error reading Leica MakerNote trailer', 1) if $trailPos;
+        $et->Warn('Error reading Leica MakerNote trailer', 1) if $trailPos;
         return undef;
     }
@@ -1575,5 +2661,5 @@
     if ($buff !~ /^(.{0,256})LEICA\0..../sg) {
         my $what = $trailPos ? 'trailer' : 'offset';
-        $exifTool->Warn("Invalid Leica MakerNote $what", 1);
+        $et->Warn("Invalid Leica MakerNote $what", 1);
         return undef;
     }
@@ -1581,5 +2667,5 @@
     my $start = pos($buff) - 10;
     if ($start and not $trailPos) {
-        $exifTool->Warn('Invalid Leica MakerNote offset', 1);
+        $et->Warn('Invalid Leica MakerNote offset', 1);
         return undef;
     }
@@ -1590,15 +2676,15 @@
     my $dirStart = $start + $hdrLen;
     my $tagInfo = $$trail{TagInfo};
-    if ($$exifTool{HTML_DUMP}) {
+    if ($$et{HTML_DUMP}) {
         my $name = $$tagInfo{Name};
-        $exifTool->HDump($pos+$start, $len-$start, "$name value", 'Leica MakerNote trailer', 4);
-        $exifTool->HDump($pos+$start, $hdrLen, "MakerNotes header", $name);
-    } elsif ($exifTool->Options('Verbose')) {
+        $et->HDump($pos+$start, $len-$start, "$name value", 'Leica MakerNote trailer', 4);
+        $et->HDump($pos+$start, $hdrLen, "MakerNotes header", $name);
+    } elsif ($et->Options('Verbose')) {
         my $where = sprintf('at offset 0x%x', $pos);
-        $exifTool->VPrint(0, "Leica MakerNote trailer ($len bytes $where):\n");
+        $et->VPrint(0, "Leica MakerNote trailer ($len bytes $where):\n");
     }
     # delete LeicaTrailer member so we don't try to process it again
-    delete $$exifTool{LeicaTrailer};
-    $$exifTool{LeicaTrailerPos} = $pos + $start;    # return actual start position of Leica trailer
+    delete $$et{LeicaTrailer};
+    $$et{LeicaTrailerPos} = $pos + $start;    # return actual start position of Leica trailer
 
     my $oldOrder = GetByteOrder();
@@ -1611,28 +2697,38 @@
     if ($valStart < $len) {
         my $valBlock = Image::ExifTool::MakerNotes::GetValueBlocks(\$buff, $dirStart, \%tagPtr);
-        # find the minimum offset (excluding the PreviewImage tag 0x300)
+        # find the minimum offset (excluding the PreviewImage tag 0x300 and 0x301)
         my $minPtr;
         foreach (keys %tagPtr) {
             my $ptr = $tagPtr{$_};
-            next if $_ == 0x300 or not $ptr;
+            next if $_ == 0x300 or $_ == 0x301 or not $ptr or $ptr == 0xffffffff;
             $minPtr = $ptr if not defined $minPtr or $minPtr > $ptr;
         }
         if ($minPtr) {
             my $diff = $minPtr - ($valStart + $pos);
-            # scan value data for the first non-zero byte
             pos($buff) = $valStart;
-            if ($buff =~ /[^\0]/g) {
-                my $n = pos($buff) - 1 - $valStart; # number of zero bytes
-                # S2 writes 282 bytes of zeros, exiftool writes none
-                my $expect = $n >= 282 ? 282 : 0;
-                my $fixBase = $exifTool->Options('FixBase');
-                if ($diff != $expect or defined $fixBase) {
-                    $fix = $expect - $diff;
-                    if (defined $fixBase) {
-                        $fix = $fixBase if $fixBase ne '';
-                        $exifTool->Warn("Adjusted MakerNotes base by $fix",1);
-                    } else {
-                        $exifTool->Warn("Possibly incorrect maker notes offsets (fixed by $fix)",1);
-                    }
+            my $expect;
+            if ($$et{Model} eq 'S2') {
+                # scan value data for the first non-zero byte
+                if ($buff =~ /[^\0]/g) {
+                    my $n = pos($buff) - 1 - $valStart; # number of zero bytes
+                    # S2 writes 282 bytes of zeros, exiftool writes none
+                    $expect = $n >= 282 ? 282 : 0;
+                }
+            } else { # M (Type 240)
+                # scan for the lens type (M writes 114 bytes of garbage first)
+                if ($buff =~ /\G.{114}([\x20-\x7f]*\0*)/sg and length($1) >= 50) {
+                    $expect = 114;
+                }
+            }
+            my $fixBase = $et->Options('FixBase');
+            if (not defined $expect) {
+                $et->Warn('Unrecognized Leica trailer structure');
+            } elsif ($diff != $expect or defined $fixBase) {
+                $fix = $expect - $diff;
+                if (defined $fixBase) {
+                    $fix = $fixBase if $fixBase ne '';
+                    $et->Warn("Adjusted MakerNotes base by $fix",1);
+                } else {
+                    $et->Warn("Possibly incorrect maker notes offsets (fixed by $fix)",1);
                 }
             }
@@ -1654,10 +2750,14 @@
     my $tagTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
     if ($newPos) { # are we writing?
+        if ($$et{Model} ne 'S2') {
+            $et->Warn('Leica MakerNote trailer too messed up to edit.  Copying as a block', 1);
+            return $buff;
+        }
         # set position of new MakerNote IFD (+ 8 for Leica MakerNote header)
         $dirInfo{NewDataPos} = $newPos + $start + 8;
-        $result = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+        $result = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
         # write preview image last if necessary and fix up the preview offsets
-        my $previewInfo = $$exifTool{PREVIEW_INFO};
-        delete $$exifTool{PREVIEW_INFO};
+        my $previewInfo = $$et{PREVIEW_INFO};
+        delete $$et{PREVIEW_INFO};
         if ($result) {
             if ($previewInfo) {
@@ -1671,21 +2771,21 @@
     } else {
         # extract information
-        $result = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $result = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         # also extract as a block if necessary
-        if ($exifTool->Options('MakerNotes') or
-            $exifTool->{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})})
+        if ($et->Options('MakerNotes') or
+            $$et{REQ_TAG_LOOKUP}{lc($$tagInfo{Name})})
         {
             # makernote header must be included in RebuildMakerNotes call
             $dirInfo{DirStart} -= 8;
             $dirInfo{DirLen} += 8;
-            $exifTool->{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
-            # rebuild maker notes (creates $exifTool->{MAKER_NOTE_FIXUP})
-            my $val = Image::ExifTool::Exif::RebuildMakerNotes($exifTool, $tagTablePtr, \%dirInfo);
+            $$et{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
+            # rebuild maker notes (creates $$et{MAKER_NOTE_FIXUP})
+            my $val = Image::ExifTool::Exif::RebuildMakerNotes($et, \%dirInfo, $tagTablePtr);
             unless (defined $val) {
-                $exifTool->Warn('Error rebuilding maker notes (may be corrupt)');
+                $et->Warn('Error rebuilding maker notes (may be corrupt)') if $len > 4;
                 $val = $buff,
             }
-            my $key = $exifTool->FoundTag($tagInfo, $val);
-            $exifTool->SetGroup($key, 'ExifIFD');
+            my $key = $et->FoundTag($tagInfo, $val);
+            $et->SetGroup($key, 'ExifIFD');
         }
     }
@@ -1713,5 +2813,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -1738,6 +2838,6 @@
 =head1 ACKNOWLEDGEMENTS
 
-Thanks to Tels for the information he provided on decoding some tags, and to
-Marcel Coenen, Jens Duttke and Michael Byczkowski for their contributions.
+Thanks to Tels, Marcel Coenen, Jens Duttke, Joerg, Michael Byczkowski, Carl
+Bretteville, Zdenek Mihula and Olaf Ulrich for their contributions.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PanasonicRaw.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PanasonicRaw.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PanasonicRaw.pm	(revision 34921)
@@ -7,6 +7,9 @@
 #               2009/05/12 - PH Added RWL file type (same format as RW2)
 #
-# References:   1) CPAN forum post by 'hardloaf' (http://www.cpanforum.com/threads/2183)
+# 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
+#              IB) Iliah Borg private communication (LibRaw)
 #              JD) Jens Duttke private communication (TZ3,FZ30,FZ50)
 #------------------------------------------------------------------------------
@@ -19,8 +22,10 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.02';
+$VERSION = '1.25';
 
 sub ProcessJpgFromRaw($$$);
 sub WriteJpgFromRaw($$$);
+sub WriteDistortionInfo($$$);
+sub ProcessDistortionInfo($$$);
 
 my %jpgFromRawMap = (
@@ -39,4 +44,27 @@
 );
 
+my %wbTypeInfo = (
+    PrintConv => \%Image::ExifTool::Exif::lightSource,
+    SeparateTable => 'EXIF LightSource',
+);
+
+my %panasonicWhiteBalance = ( #forum9396
+    0 => 'Auto',
+    1 => 'Daylight',
+    2 => 'Cloudy',
+    3 => 'Tungsten',
+    4 => 'n/a',
+    5 => 'Flash',
+    6 => 'n/a',
+    7 => 'n/a',
+    8 => 'Custom#1',
+    9 => 'Custom#2',
+    10 => 'Custom#3',
+    11 => 'Custom#4',
+    12 => 'Shade',
+    13 => 'Kelvin',
+    16 => 'AWBc', # GH5 and G9 (Makernotes WB==19)
+);
+
 # Tags found in Panasonic RAW/RW2/RWL images (ref PH)
 %Image::ExifTool::PanasonicRaw::Main = (
@@ -54,17 +82,42 @@
     0x04 => 'SensorTopBorder', #JD
     0x05 => 'SensorLeftBorder', #JD
-    0x06 => 'ImageHeight', #1/PH
-    0x07 => 'ImageWidth', #1/PH
+    0x06 => 'SensorBottomBorder', #PH
+    0x07 => 'SensorRightBorder', #PH
     # observed values for unknown tags - PH
     # 0x08: 1
     # 0x09: 1,3,4
     # 0x0a: 12
-    # 0x0b: 0x860c,0x880a,0x880c
+    # (IB gave 0x08-0x0a as BlackLevel tags, but Klaus' decoding makes more sense)
+    0x08 => { Name => 'SamplesPerPixel', Writable => 'int16u', Protected => 1 }, #4
+    0x09 => { #4
+        Name => 'CFAPattern',
+        Writable => 'int16u',
+        Protected => 1,
+        PrintConv => {
+            0 => 'n/a',
+            1 => '[Red,Green][Green,Blue]', # (CM-1, FZ70)
+            2 => '[Green,Red][Blue,Green]', # (LX-7)
+            3 => '[Green,Blue][Red,Green]', # (ZS100, FZ2500, FZ1000, ...)
+            4 => '[Blue,Green][Green,Red]', # (LC-100, G-7, V-LUX1, ...)
+        },
+    },
+    0x0a => { Name => 'BitsPerSample', Writable => 'int16u', Protected => 1 }, #4
+    0x0b => { #4
+        Name => 'Compression',
+        Writable => 'int16u',
+        Protected => 1,
+        PrintConv => {
+            34316 => 'Panasonic RAW 1', # (most models - RAW/RW2/RWL)
+            34826 => 'Panasonic RAW 2', # (DIGILUX 2 - RAW)
+            34828 => 'Panasonic RAW 3', # (D-LUX2,D-LUX3,FZ30,LX1 - RAW)
+            34830 => 'Panasonic RAW 4', #IB (Leica DIGILUX 3, Panasonic DMC-L1)
+        },
+    },
     # 0x0c: 2 (only Leica Digilux 2)
     # 0x0d: 0,1
     # 0x0e,0x0f,0x10: 4095
-    # 0x18,0x19,0x1a,0x1c,0x1d,0x1e: 0
-    # 0x1b,0x27,0x29,0x2a,0x2b,0x2c: [binary data]
-    # 0x2d: 2,3
+    0x0e => { Name => 'LinearityLimitRed',   Writable => 'int16u' }, #IB
+    0x0f => { Name => 'LinearityLimitGreen', Writable => 'int16u' }, #IB
+    0x10 => { Name => 'LinearityLimitBlue',  Writable => 'int16u' }, #IB
     0x11 => { #JD
         Name => 'RedBalance',
@@ -80,8 +133,36 @@
         ValueConvInv => 'int($val * 256 + 0.5)',
     },
+    0x13 => { #IB
+        Name => 'WBInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::PanasonicRaw::WBInfo' },
+    },
     0x17 => { #1
         Name => 'ISO',
         Writable => 'int16u',
     },
+    # 0x18,0x19,0x1a: 0
+    0x18 => { #IB
+        Name => 'HighISOMultiplierRed',
+        Writable => 'int16u',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256 + 0.5)',
+    },
+    0x19 => { #IB
+        Name => 'HighISOMultiplierGreen',
+        Writable => 'int16u',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256 + 0.5)',
+    },
+    0x1a => { #IB
+        Name => 'HighISOMultiplierBlue',
+        Writable => 'int16u',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256 + 0.5)',
+    },
+    # 0x1b: [binary data] (something to do with the camera ISO cababilities: int16u count N,
+    #                      followed by table of  N entries: int16u ISO, int16u[3] RGB gains - ref IB)
+    0x1c => { Name => 'BlackLevelRed',   Writable => 'int16u' }, #IB
+    0x1d => { Name => 'BlackLevelGreen', Writable => 'int16u' }, #IB
+    0x1e => { Name => 'BlackLevelBlue',  Writable => 'int16u' }, #IB
     0x24 => { #2
         Name => 'WBRedLevel',
@@ -96,6 +177,26 @@
         Writable => 'int16u',
     },
+    0x27 => { #IB
+        Name => 'WBInfo2',
+        SubDirectory => { TagTable => 'Image::ExifTool::PanasonicRaw::WBInfo2' },
+    },
+    # 0x27,0x29,0x2a,0x2b,0x2c: [binary data]
+    0x2d => { #IB
+        Name => 'RawFormat',
+        Writable => 'int16u',
+        Protected => 1,
+        # 2 - RAW DMC-FZ8/FZ18
+        # 3 - RAW DMC-L10
+        # 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; 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!)
+        Groups => { 2 => 'Preview' },
         Writable => 'undef',
         # protect this tag because it contains all the metadata
@@ -114,4 +215,8 @@
         },
     },
+    0x2f => { Name => 'CropTop',    Writable => 'int16u' },
+    0x30 => { Name => 'CropLeft',   Writable => 'int16u' },
+    0x31 => { Name => 'CropBottom', Writable => 'int16u' },
+    0x32 => { Name => 'CropRight',  Writable => 'int16u' },
     0x10f => {
         Name => 'Make',
@@ -157,12 +262,41 @@
     0x118 => {
         Name => 'RawDataOffset', #PH (RW2/RWL)
-        IsOffset => '$$exifTool{TIFF_TYPE} =~ /^(RW2|RWL)$/', # (invalid in DNG-converted files)
+        IsOffset => '$$et{TIFF_TYPE} =~ /^(RW2|RWL)$/', # (invalid in DNG-converted files)
         PanasonicHack => 1,
         OffsetPair => 0x117, # (use StripByteCounts as the offset pair)
-    },
-    # 0x119 undef[32] - lens distortion data? (http://thinkfat.blogspot.com/2009/02/dissecting-panasonic-rw2-files.html)
+        NotRealPair => 1,    # (to avoid Validate warning)
+    },
+    0x119 => {
+        Name => 'DistortionInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::PanasonicRaw::DistortionInfo' },
+    },
+    # 0x11b - chromatic aberration correction (ref 3) (also see forum9366)
+    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)',
+    },
+    0x120 => {
+        Name => 'CameraIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::PanasonicRaw::CameraIFD',
+            Base => '$start',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+        },
+    },
+    0x121 => { #forum9295
+        Name => 'Multishot',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Off',
+            65536 => 'Pixel Shift',
+        },
+    },
+    # 0x122 - int32u: RAWDataOffset for the GH5s/GX9, or pointer to end of raw data for G9 (forum9295)
     0x2bc => { # PH Extension!!
-        Name => 'ApplicationNotes',
-        Writable => 'int8u', # (writable directory!)
+        Name => 'ApplicationNotes', # (writable directory!)
+        Writable => 'int8u',
         Format => 'undef',
         Flags => [ 'Binary', 'Protected' ],
@@ -170,4 +304,16 @@
             DirName => 'XMP',
             TagTable => 'Image::ExifTool::XMP::Main',
+        },
+    },
+    0x001b => { #forum9250
+        Name => 'NoiseReductionParams',
+        Writable => 'undef',
+        Format => 'int16u',
+        Count => -1,
+        Flags => 'Protected',
+        Notes => q{
+            the camera's default noise reduction setup.  The first number is the number
+            of entries, then for each entry there are 4 numbers: an ISO speed, and
+            noise-reduction strengths the R, G and B channels
         },
     },
@@ -203,5 +349,382 @@
         },
     },
+    # 0xffff => 'DCSHueShiftValues', #exifprobe (NC)
 );
+
+# white balance information (ref IB)
+# (PanasonicRawVersion<200: Digilux 2)
+%Image::ExifTool::PanasonicRaw::WBInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    0 => 'NumWBEntries',
+    1 => { Name => 'WBType1', %wbTypeInfo },
+    2 => { Name => 'WB_RBLevels1', Format => 'int16u[2]' },
+    4 => { Name => 'WBType2', %wbTypeInfo },
+    5 => { Name => 'WB_RBLevels2', Format => 'int16u[2]' },
+    7 => { Name => 'WBType3', %wbTypeInfo },
+    8 => { Name => 'WB_RBLevels3', Format => 'int16u[2]' },
+    10 => { Name => 'WBType4', %wbTypeInfo },
+    11 => { Name => 'WB_RBLevels4', Format => 'int16u[2]' },
+    13 => { Name => 'WBType5', %wbTypeInfo },
+    14 => { Name => 'WB_RBLevels5', Format => 'int16u[2]' },
+    16 => { Name => 'WBType6', %wbTypeInfo },
+    17 => { Name => 'WB_RBLevels6', Format => 'int16u[2]' },
+    19 => { Name => 'WBType7', %wbTypeInfo },
+    20 => { Name => 'WB_RBLevels7', Format => 'int16u[2]' },
+);
+
+# white balance information (ref IB)
+# (PanasonicRawVersion>=200: D-Lux2, D-Lux3, DMC-FZ18/FZ30/LX1/L10)
+%Image::ExifTool::PanasonicRaw::WBInfo2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    0 => 'NumWBEntries',
+    1 => { Name => 'WBType1', %wbTypeInfo },
+    2 => { Name => 'WB_RGBLevels1', Format => 'int16u[3]' },
+    5 => { Name => 'WBType2', %wbTypeInfo },
+    6 => { Name => 'WB_RGBLevels2', Format => 'int16u[3]' },
+    9 => { Name => 'WBType3', %wbTypeInfo },
+    10 => { Name => 'WB_RGBLevels3', Format => 'int16u[3]' },
+    13 => { Name => 'WBType4', %wbTypeInfo },
+    14 => { Name => 'WB_RGBLevels4', Format => 'int16u[3]' },
+    17 => { Name => 'WBType5', %wbTypeInfo },
+    18 => { Name => 'WB_RGBLevels5', Format => 'int16u[3]' },
+    21 => { Name => 'WBType6', %wbTypeInfo },
+    22 => { Name => 'WB_RGBLevels6', Format => 'int16u[3]' },
+    25 => { Name => 'WBType7', %wbTypeInfo },
+    26 => { Name => 'WB_RGBLevels7', Format => 'int16u[3]' },
+);
+
+# lens distortion information (ref 3)
+# (distortion correction equation: Ru = scale*(Rd + a*Rd^3 + b*Rd^5 + c*Rd^7), ref 3)
+%Image::ExifTool::PanasonicRaw::DistortionInfo = (
+    PROCESS_PROC => \&ProcessDistortionInfo,
+    WRITE_PROC => \&WriteDistortionInfo,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    # (don't make this family 0 MakerNotes because we don't want it to be a deletable group)
+    GROUPS => { 0 => 'PanasonicRaw', 1 => 'PanasonicRaw', 2 => 'Image'},
+    WRITABLE => 1,
+    FORMAT => 'int16s',
+    FIRST_ENTRY => 0,
+    NOTES => 'Lens distortion correction information.',
+    # 0,1 - checksums
+    2 => {
+        Name => 'DistortionParam02',
+        ValueConv => '$val / 32768',
+        ValueConvInv => '$val * 32768',
+    },
+    # 3 - usually 0, but seen 0x026b when value 5 is non-zero
+    4 => {
+        Name => 'DistortionParam04',
+        ValueConv => '$val / 32768',
+        ValueConvInv => '$val * 32768',
+    },
+    5 => {
+        Name => 'DistortionScale',
+        ValueConv => '1 / (1 + $val/32768)',
+        ValueConvInv => '(1/$val - 1) * 32768',
+    },
+    # 6 - seen 0x0000-0x027f
+    7.1 => {
+        Name => 'DistortionCorrection',
+        Mask => 0x0f,
+        # (have seen the upper 4 bits set for GF5 and GX1, giving a value of -4095 - PH)
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    8 => {
+        Name => 'DistortionParam08',
+        ValueConv => '$val / 32768',
+        ValueConvInv => '$val * 32768',
+    },
+    9 => {
+        Name => 'DistortionParam09',
+        ValueConv => '$val / 32768',
+        ValueConvInv => '$val * 32768',
+    },
+    # 10 - seen 0xfc,0x0101,0x01f4,0x021d,0x0256
+    11 => {
+        Name => 'DistortionParam11',
+        ValueConv => '$val / 32768',
+        ValueConvInv => '$val * 32768',
+    },
+    12 => {
+        Name => 'DistortionN',
+        Unknown => 1,
+    },
+    # 13 - seen 0x0000,0x01f9-0x02b2
+    # 14,15 - checksums
+);
+
+# Panasonic RW2 camera IFD written by GH5 (ref PH)
+# (doesn't seem to be valid for the GF7 or GM5 -- encrypted?)
+%Image::ExifTool::PanasonicRaw::CameraIFD = (
+    GROUPS => { 0 => 'PanasonicRaw', 1 => 'CameraIFD', 2 => 'Camera'},
+    # (don't know what format codes 0x101 and 0x102 are for, so just
+    #  map them into 4 = int32u for now)
+    VARS => { MAP_FORMAT => { 0x101 => 4, 0x102 => 4 } },
+    0x1001 => { #forum9388
+        Name => 'MultishotOn',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    0x1100 => { #forum9274
+        Name => 'FocusStepNear',
+        Writable => 'int16s',
+    },
+    0x1101 => { #forum9274 (was forum8484)
+        Name => 'FocusStepCount',
+        Writable => 'int16s',
+    },
+    0x1102 => { #forum9417
+        Name => 'FlashFired',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    # 0x1104 - set when camera shoots on lowest possible Extended-ISO (forum9290)
+    0x1105 => { #forum9392
+        Name => 'ZoomPosition',
+        Notes => 'in the range 0-255 for most cameras',
+        Writable => 'int32u',
+    },
+    0x1200 => { #forum9278
+        Name => 'LensAttached',
+        Notes => 'many CameraIFD tags are invalid if there is no lens attached',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    # 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
+        #  258 - ? (seen once)
+    },
+    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',
+        PrintConv => '"$val mm"',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    # 0x1300 - incident light value? (ref forum11395)
+    0x1301 => { #forum11395
+        Name => 'ApertureValue',
+        Writable => 'int16s',
+        Priority => 0,
+        ValueConv => '2 ** ($val / 512)',
+        ValueConvInv => '$val>0 ? 512*log($val)/log(2) : 0',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x1302 => { #forum11395
+        Name => 'ShutterSpeedValue',
+        Writable => 'int16s',
+        Priority => 0,
+        ValueConv => 'abs($val/256)<100 ? 2**(-$val/256) : 0',
+        ValueConvInv => '$val>0 ? -256*log($val)/log(2) : -25600',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x1303 => { #forum11395
+        Name => 'SensitivityValue',
+        Writable => 'int16s',
+        ValueConv => '$val / 256',
+        ValueConvInv => 'int($val * 256)',
+    },
+    0x1305 => { #forum9384
+        Name => 'HighISOMode',
+        Writable => 'int16u',
+        RawConv => '$val || undef',
+        PrintConv => { 1 => 'On', 2 => 'Off' },
+    },
+    # 0x1306 EV for some models like the GX8 (forum11395)
+    # 0x140b - scaled overall black level? (ref forum9281)
+    # 0x1411 - scaled black level per channel difference (ref forum9281)
+    0x1412 => { #forum11397
+        Name => 'FacesDetected',
+        Writable => 'int8u',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    # 0x2000 - WB tungsten=3, daylight=4 (ref forum9467)
+    # 0x2009 - scaled black level per channel (ref forum9281)
+    # 0x3000-0x310b - red/blue balances * 1024 (ref forum9467)
+    #  0x3000 modifiedTungsten-Red (-2?)
+    #  0x3001 modifiedTungsten-Blue (-2?)
+    #  0x3002 modifiedDaylight-Red (-2?)
+    #  0x3003 modifiedDaylight-Blue (-2?)
+    #  0x3004 modifiedTungsten-Red (-1?)
+    #  0x3005 modifiedTungsten-Blue (-1?)
+    #  0x3006 modifiedDaylight-Red (-1?)
+    #  0x3007 modifiedDaylight-Blue (-1?)
+    #  0x3100 DefaultTungsten-Red
+    #  0x3101 DefaultTungsten-Blue
+    #  0x3102 DefaultDaylight-Red
+    #  0x3103 DefaultDaylight-Blue
+    #  0x3104 modifiedTungsten-Red (+1?)
+    #  0x3105 modifiedTungsten-Blue (+1?)
+    #  0x3106 modifiedDaylight-Red (+1?)
+    #  0x3107 modifiedDaylight-Blue (+1?)
+    #  0x3108 modifiedTungsten-Red (+2?)
+    #  0x3109 modifiedTungsten-Blue (+2?)
+    #  0x310a modifiedDaylight-Red (+2?)
+    #  0x310b modifiedDaylight-Blue (+2?)
+    0x3200 => { #forum9275
+        Name => 'WB_CFA0_LevelDaylight',
+        Writable => 'int16u',
+    },
+    0x3201 => { #forum9275
+        Name => 'WB_CFA1_LevelDaylight',
+        Writable => 'int16u',
+    },
+    0x3202 => { #forum9275
+        Name => 'WB_CFA2_LevelDaylight',
+        Writable => 'int16u',
+    },
+    0x3203 => { #forum9275
+        Name => 'WB_CFA3_LevelDaylight',
+        Writable => 'int16u',
+    },
+    # 0x3204-0x3207 - user multipliers * 1024 ? (ref forum9275)
+    # 0x320a - scaled maximum value of raw data (scaling = 4x) (ref forum9281)
+    # 0x3209 - gamma (x256) (ref forum9281)
+    0x3300 => { #forum9296/9396
+        Name => 'WhiteBalanceSet',
+        Writable => 'int8u',
+        PrintConv => \%panasonicWhiteBalance,
+        SeparateTable => 'WhiteBalance',
+    },
+    0x3420 => { #forum9276
+        Name => 'WB_RedLevelAuto',
+        Writable => 'int16u',
+    },
+    0x3421 => { #forum9276
+        Name => 'WB_BlueLevelAuto',
+        Writable => 'int16u',
+    },
+    0x3501 => { #4
+        Name => 'Orientation',
+        Writable => 'int8u',
+        PrintConv => \%Image::ExifTool::Exif::orientation,
+    },
+    # 0x3504 = Tag 0x1301+0x1302-0x1303 (Bv = Av+Tv-Sv) (forum11395)
+    # 0x3505 - same as 0x1300 (forum11395)
+    0x3600 => { #forum9396
+        Name => 'WhiteBalanceDetected',
+        Writable => 'int8u',
+        PrintConv => \%panasonicWhiteBalance,
+        SeparateTable => 'WhiteBalance',
+    },
+);
+
+# PanasonicRaw composite tags
+%Image::ExifTool::PanasonicRaw::Composite = (
+    ImageWidth => {
+        Require => {
+            0 => 'IFD0:SensorLeftBorder',
+            1 => 'IFD0:SensorRightBorder',
+        },
+        ValueConv => '$val[1] - $val[0]',
+    },
+    ImageHeight => {
+        Require => {
+            0 => 'IFD0:SensorTopBorder',
+            1 => 'IFD0:SensorBottomBorder',
+        },
+        ValueConv => '$val[1] - $val[0]',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::PanasonicRaw');
+
+
+#------------------------------------------------------------------------------
+# checksum algorithm for lens distortion correction information (ref 3)
+# Inputs: 0) data ref, 1) start position, 2) number of bytes, 3) incement
+# Returns: checksum value
+sub Checksum($$$$)
+{
+    my ($dataPt, $start, $num, $inc) = @_;
+    my $csum = 0;
+    my $i;
+    for ($i=0; $i<$num; ++$i) {
+        $csum = (73 * $csum + Get8u($dataPt, $start + $i * $inc)) % 0xffef;
+    }
+    return $csum;
+}
+
+#------------------------------------------------------------------------------
+# Read lens distortion information
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessDistortionInfo($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart} || 0;
+    my $size = $$dirInfo{DirLen} || (length($$dataPt) - $start);
+    if ($size == 32) {
+        # verify the checksums (ref 3)
+        my $csum1 = Checksum($dataPt, $start +  4, 12, 1);
+        my $csum2 = Checksum($dataPt, $start + 16, 12, 1);
+        my $csum3 = Checksum($dataPt, $start +  2, 14, 2);
+        my $csum4 = Checksum($dataPt, $start +  3, 14, 2);
+        my $res = $csum1 ^ Get16u($dataPt, $start + 2) ^
+                  $csum2 ^ Get16u($dataPt, $start + 28) ^
+                  $csum3 ^ Get16u($dataPt, $start + 0) ^
+                  $csum4 ^ Get16u($dataPt, $start + 30);
+        $et->Warn('Invalid DistortionInfo checksum',1) if $res;
+    } else {
+        $et->Warn('Invalid DistortionInfo',1);
+    }
+    return $et->ProcessBinaryData($dirInfo, $tagTablePtr);
+}
+
+#------------------------------------------------------------------------------
+# Write lens distortion information
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: updated distortion information or undef on error
+sub WriteDistortionInfo($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;  # (allow dummy access)
+    my $dat = $et->WriteBinaryData($dirInfo, $tagTablePtr);
+    if (defined $dat and length($dat) == 32) {
+        # fix checksums (ref 3)
+        Set16u(Checksum(\$dat,  4, 12, 1), \$dat,  2);
+        Set16u(Checksum(\$dat, 16, 12, 1), \$dat, 28);
+        Set16u(Checksum(\$dat,  2, 14, 2), \$dat,  0);
+        Set16u(Checksum(\$dat,  3, 14, 2), \$dat, 30);
+    } else {
+        $et->Warn('Error wriing DistortionInfo',1);
+    }
+    return $dat;
+}
 
 #------------------------------------------------------------------------------
@@ -261,8 +784,8 @@
 sub WriteJpgFromRaw($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $byteOrder = GetByteOrder();
-    my $fileType = $$exifTool{FILE_TYPE};   # RAW, RW2 or RWL
+    my $fileType = $$et{TIFF_TYPE};   # RAW, RW2 or RWL
     my $dirStart = $$dirInfo{DirStart};
     if ($dirStart) { # DirStart is non-zero in DNG-converted RW2/RWL
@@ -277,19 +800,19 @@
         OutFile => \$outbuff,
     );
-    $$exifTool{BASE} = $$dirInfo{DataPos};
-    $$exifTool{FILE_TYPE} = $$exifTool{TIFF_TYPE} = 'JPEG';
+    $$et{BASE} = $$dirInfo{DataPos};
+    $$et{FILE_TYPE} = $$et{TIFF_TYPE} = 'JPEG';
     # use a specialized map so we don't write XMP or IPTC (or other junk) into the JPEG
-    my $editDirs = $$exifTool{EDIT_DIRS};
-    my $addDirs = $$exifTool{ADD_DIRS};
-    $exifTool->InitWriteDirs(\%jpgFromRawMap);
+    my $editDirs = $$et{EDIT_DIRS};
+    my $addDirs = $$et{ADD_DIRS};
+    $et->InitWriteDirs(\%jpgFromRawMap);
     # don't add XMP segment (IPTC won't get added because it is in Photoshop record)
-    delete $$exifTool{ADD_DIRS}{XMP};
-    my $result = $exifTool->WriteJPEG(\%dirInfo);
+    delete $$et{ADD_DIRS}{XMP};
+    my $result = $et->WriteJPEG(\%dirInfo);
     # restore variables we changed
-    $$exifTool{BASE} = 0;
-    $$exifTool{FILE_TYPE} = 'TIFF';
-    $$exifTool{TIFF_TYPE} = $fileType;
-    $$exifTool{EDIT_DIRS} = $editDirs;
-    $$exifTool{ADD_DIRS} = $addDirs;
+    $$et{BASE} = 0;
+    $$et{FILE_TYPE} = 'TIFF';
+    $$et{TIFF_TYPE} = $fileType;
+    $$et{EDIT_DIRS} = $editDirs;
+    $$et{ADD_DIRS} = $addDirs;
     SetByteOrder($byteOrder);
     return $result > 0 ? $outbuff : $$dataPt;
@@ -302,12 +825,12 @@
 sub ProcessJpgFromRaw($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $byteOrder = GetByteOrder();
-    my $fileType = $$exifTool{FILE_TYPE};   # RAW, RW2 or RWL
+    my $fileType = $$et{TIFF_TYPE};   # RAW, RW2 or RWL
     my $tagInfo = $$dirInfo{TagInfo};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my ($indent, $out);
-    $tagInfo or $exifTool->Warn('No tag info for Panasonic JpgFromRaw'), return 0;
+    $tagInfo or $et->Warn('No tag info for Panasonic JpgFromRaw'), return 0;
     my $dirStart = $$dirInfo{DirStart};
     if ($dirStart) { # DirStart is non-zero in DNG-converted RW2/RWL
@@ -316,7 +839,7 @@
         $dataPt = \$buff;
     }
-    $$exifTool{BASE} = $$dirInfo{DataPos} + ($dirStart || 0);
-    $$exifTool{FILE_TYPE} = $$exifTool{TIFF_TYPE} = 'JPEG';
-    $$exifTool{DOC_NUM} = 1;
+    $$et{BASE} = $$dirInfo{DataPos} + ($dirStart || 0);
+    $$et{FILE_TYPE} = $$et{TIFF_TYPE} = 'JPEG';
+    $$et{DOC_NUM} = 1;
     # extract information from embedded JPEG
     my %dirInfo = (
@@ -325,18 +848,21 @@
     );
     if ($verbose) {
-        my $indent = $$exifTool{INDENT};
-        $$exifTool{INDENT} = '  ';
-        $out = $exifTool->Options('TextOut');
+        my $indent = $$et{INDENT};
+        $$et{INDENT} = '  ';
+        $out = $et->Options('TextOut');
         print $out '--- DOC1:JpgFromRaw ',('-'x56),"\n";
     }
-    my $rtnVal = $exifTool->ProcessJPEG(\%dirInfo);
+    # 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
-    $$exifTool{BASE} = 0;
-    $$exifTool{FILE_TYPE} = 'TIFF';
-    $$exifTool{TIFF_TYPE} = $fileType;
-    delete $$exifTool{DOC_NUM};
+    $$et{BASE} = 0;
+    $$et{FILE_TYPE} = 'TIFF';
+    $$et{TIFF_TYPE} = $fileType;
+    delete $$et{DOC_NUM};
     SetByteOrder($byteOrder);
     if ($verbose) {
-        $$exifTool{INDENT} = $indent;
+        $$et{INDENT} = $indent;
         print $out ('-'x76),"\n";
     }
@@ -363,5 +889,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Parrot.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Parrot.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Parrot.pm	(revision 34921)
@@ -0,0 +1,752 @@
+#------------------------------------------------------------------------------
+# 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.01';
+
+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,
+            Base    => $$dirInfo{Base},
+            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-2021, 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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Pentax.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Pentax.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Pentax.pm	(revision 34921)
@@ -31,5 +31,5 @@
 #              16) Axel Kellner private communication (K10D)
 #              17) Cvetan Ivanov private communication (K100D)
-#              18) http://www.gvsoft.homedns.org/exif/makernote-pentax-type3.html
+#              18) http://gvsoft.homedns.org/exif/makernote-pentax-type3.html
 #              19) Dave Nicholson private communication (K10D)
 #              20) Bogdan and yeryry (http://www.cpanforum.com/posts/8037)
@@ -38,6 +38,13 @@
 #              23) Akos Szalkai (https://rt.cpan.org/Ticket/Display.html?id=43743)
 #              24) Albert Bogner private communication
-#              25) Niels Kristian Bech Jensen private communication
+#              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) 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
+#              NJ) Niels Kristian Bech Jensen private communication
 #
 # Notes:        See POD documentation at the bottom of this file
@@ -47,31 +54,51 @@
 
 use strict;
-use vars qw($VERSION);
+use vars qw($VERSION %pentaxLensTypes);
 use Image::ExifTool::Exif;
+use Image::ExifTool::GPS;
 use Image::ExifTool::HP;
 
-$VERSION = '2.30';
+$VERSION = '3.36';
 
 sub CryptShutterCount($$);
 sub PrintFilter($$$);
+sub DecodeAFPoints($$$$;$);
 
 # pentax lens type codes (ref 4)
 # The first number gives the lens series, and the 2nd gives the model number
 # Series numbers: K=1; A=2; F=3; FAJ=4; DFA=4,7; FA=3,4,5,6; FA*=5,6;
-#                 DA=3,4,7; DA*=7,8; FA645=11; DFA645=13
-my %pentaxLensTypes = (
+#                 DA=3,4,7; DA*=7,8; FA645=11; DFA645=13; Q=21
+%pentaxLensTypes = (
     Notes => q{
         The first number gives the series of the lens, and the second identifies the
         lens model.  Note that newer series numbers may not always be properly
-        identified by cameras running older firmware versions.  Decimal values
-        differentiate lenses which would otherwise have the same LensType, and are
-        used by the Composite LensID tag when attempting to identify the specific
-        lens model.
+        identified by cameras running older firmware versions.  Decimal values have
+        been added to differentiate lenses which would otherwise have the same
+        LensType, and are used by the Composite LensID tag when attempting to
+        identify the specific lens model.
+    },
+    OTHER => sub {
+        my ($val, $inv, $conv) = @_;
+        return undef if $inv;
+        # *istD may report a series number of 4 for series 7 lenses
+        $val =~ s/^4 /7 / and $$conv{$val} and return "$$conv{$val} ($_[0])";
+        # cameras that don't recognize SDM lenses (eg. older K10 firmware)
+        # may report series 7 instead of 8
+        $val =~ s/^7 /8 / and $$conv{$val} and return "$$conv{$val} ? ($_[0])";
+        # there seems to some inconsistency between FA and DFA lenses for the 645D...
+        ($val =~ s/^11 /13 / or $val =~ s/^13 /11 /) and $$conv{$val} and return "$$conv{$val} ? ($_[0])";
+        return undef;
     },
     '0 0' => 'M-42 or No Lens', #17
     '1 0' => 'K or M Lens',
     '2 0' => 'A Series Lens', #7 (from smc PENTAX-A 400mm F5.6)
-    '3 0' => 'Sigma', # (includes 'Sigma 30mm F1.4 EX DC' - PH)
-    '3 17' => 'smc PENTAX-FA SOFT 85mm F2.8',
+    '3 0' => 'Sigma',
+    # (and 'Sigma 18-50mm F2.8 EX Macro')
+    # (and 'Sigma 30mm F1.4 EX DC', ref PH)
+    # (and 'Sigma 50-500mm F4-6.3 DG APO')
+    # (and 'Sigma 70mm F2.8 EX DG Macro')
+    # (and 'Sigma 105mm F2.8 EX DG Macro', ref 24)
+    # (and 'Sigma 180mm F4.5 EX DG Macro')
+    '3 17' => 'smc PENTAX-FA SOFT 85mm F2.8', # (also F version, ref 29)
     '3 18' => 'smc PENTAX-F 1.7X AF ADAPTER',
     '3 19' => 'smc PENTAX-F 24-50mm F4',
@@ -82,9 +109,10 @@
     '3 23.1' => 'Sigma AF 28-300mm F3.5-5.6 DL IF', #JD
     '3 23.2' => 'Sigma AF 28-300mm F3.5-6.3 DG IF Macro', #JD
+    '3 23.3' => 'Tokina 80-200mm F2.8 ATX-Pro', #Exiv2
     '3 24' => 'smc PENTAX-F 35-135mm F3.5-4.5',
     '3 25' => 'smc PENTAX-F 35-105mm F4-5.6 or Sigma or Tokina Lens',
-    '3 25.1' => 'Sigma AF 28-300mm F3.5-5.6 DL IF', #11
-    '3 25.2' => 'Sigma 55-200mm F4-5.6 DC', #JD
-    '3 25.3' => 'Sigma AF 28-300mm F3.5-5.6 DL IF', #JD
+    '3 25.1' => 'Sigma 55-200mm F4-5.6 DC', #JD
+    '3 25.2' => 'Sigma AF 28-300mm F3.5-5.6 DL IF', #11
+    '3 25.3' => 'Sigma AF 28-300mm F3.5-6.3 DL IF', #Exiv2
     '3 25.4' => 'Sigma AF 28-300mm F3.5-6.3 DG IF Macro', #JD
     '3 25.5' => 'Tokina 80-200mm F2.8 ATX-Pro', #12
@@ -94,4 +122,5 @@
     '3 28' => 'smc PENTAX-F 35-70mm F3.5-4.5 or Tokina Lens',
     '3 28.1' => 'Tokina 19-35mm F3.5-4.5 AF', #12
+    '3 28.2' => 'Tokina AT-X AF 400mm F5.6', #NJ
     '3 29' => 'PENTAX-F 28-80mm F3.5-4.5 or Sigma or Tokina Lens',
     '3 29.1' => 'Sigma AF 18-125mm F3.5-5.6 DC', #11
@@ -111,13 +140,17 @@
     '3 41' => 'smc PENTAX-F Macro 50mm F2.8 or Sigma Lens', #4
     '3 41.1' => 'Sigma 50mm F2.8 Macro', #16
+    '3 42' => 'Sigma 300mm F2.8 EX DG APO IF', #27
     '3 44' => 'Sigma or Tamron Lens (3 44)',
     '3 44.1' => 'Sigma AF 10-20mm F4-5.6 EX DC', #JD
-    '3 44.2' => 'Sigma 12-24mm F4.5 EX DG', #12
+    '3 44.2' => 'Sigma 12-24mm F4.5-5.6 EX DG', #12 (added "-5.6", ref 29)
     '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' => 'Tamron 35-90mm F4 AF', #12
-    '3 46' => 'Sigma Lens (3 46)',
+    '3 44.5' => 'Sigma 17-35mm F2.8-4 EX DG', #29
+    '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',
     '3 46.2' => 'Sigma EX APO 100-300mm F4 IF', #JD
+    '3 46.3' => 'Samsung/Schneider D-XENON 50-200mm F4-5.6 ED', #29
     '3 50' => 'smc PENTAX-FA 28-70mm F4 AL',
     '3 51' => 'Sigma 28mm F1.8 EX DG Aspherical Macro',
@@ -141,9 +174,12 @@
     '3 255.7' => 'Sigma 70-300mm F4-5.6 Macro', #JD
     '3 255.8' => 'Sigma 55-200mm F4-5.6 DC', #JD
-    '3 255.9' => 'Sigma 18-50mm F2.8 EX DC', #JD
+    '3 255.9' => 'Sigma 18-50mm F2.8 EX DC', #JD (also Macro version - PH)
     '4 1' => 'smc PENTAX-FA SOFT 28mm F2.8',
     '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
     '4 15' => 'smc PENTAX-FA 28-105mm F4-5.6 [IF]',
@@ -163,5 +199,6 @@
     '4 34' => 'smc PENTAX-FA 24-90mm F3.5-4.5 AL[IF]',
     '4 35' => 'smc PENTAX-FA 100-300mm F4.7-5.8',
-    '4 36' => 'Tamron AF70-300mm F4-5.6 LD Macro', # both 572D and A17 (Di) - ref JD
+  # '4 36' => 'Tamron AF70-300mm F4-5.6 LD Macro', # both 572D and A17 (Di) - ref JD
+    '4 36' => 'Tamron AF 70-300mm F4-5.6 LD Macro 1:2', #NJ
     '4 37' => 'Tamron SP AF 24-135mm F3.5-5.6 AD AL (190D)', #13
     '4 38' => 'smc PENTAX-FA 28-105mm F3.2-4.5 AL[IF]',
@@ -175,17 +212,22 @@
     '4 46' => 'smc PENTAX-FA J 28-80mm F3.5-5.6 AL',
     '4 47' => 'smc PENTAX-FA J 18-35mm F4-5.6 AL',
-    '4 49' => 'Tamron SP AF 28-75mm F2.8 XR Di (A09)',
+   #'4 49' => 'Tamron SP AF 28-75mm F2.8 XR Di (A09)',
+    '4 49' => 'Tamron SP AF 28-75mm F2.8 XR Di LD Aspherical [IF] Macro', #NJ
     '4 51' => 'smc PENTAX-D FA 50mm F2.8 Macro',
     '4 52' => 'smc PENTAX-D FA 100mm F2.8 Macro',
+    '4 55' => 'Samsung/Schneider D-XENOGON 35mm F2', #29
+    '4 56' => 'Samsung/Schneider D-XENON 100mm F2.8 Macro', #Alan Robinson
     '4 75' => 'Tamron SP AF 70-200mm F2.8 Di LD [IF] Macro (A001)', #JD
+    '4 214' => 'smc PENTAX-DA 35mm F2.4 AL', #PH
     '4 229' => 'smc PENTAX-DA 18-55mm F3.5-5.6 AL II', #JD
     '4 230' => 'Tamron SP AF 17-50mm F2.8 XR Di II', #20
     '4 231' => 'smc PENTAX-DA 18-250mm F3.5-6.3 ED AL [IF]', #21
     '4 237' => 'Samsung/Schneider D-XENOGON 10-17mm F3.5-4.5', #JD
-    '4 239' => 'Samsung D-XENON 12-24mm F4 ED AL [IF]', #23
+    '4 239' => 'Samsung/Schneider D-XENON 12-24mm F4 ED AL [IF]', #23
+    '4 242' => 'smc PENTAX-DA* 16-50mm F2.8 ED AL [IF] SDM (SDM unused)', #Pietu Pohjalainen
     '4 243' => 'smc PENTAX-DA 70mm F2.4 Limited', #JD
     '4 244' => 'smc PENTAX-DA 21mm F3.2 AL Limited', #9
-    '4 245' => 'Schneider D-XENON 50-200mm F4-5.6', #15
-    '4 246' => 'Schneider D-XENON 18-55mm F3.5-5.6', #15
+    '4 245' => 'Samsung/Schneider D-XENON 50-200mm F4-5.6', #15
+    '4 246' => 'Samsung/Schneider D-XENON 18-55mm F3.5-5.6', #15
     '4 247' => 'smc PENTAX-DA FISH-EYE 10-17mm F3.5-4.5 ED[IF]', #10
     '4 248' => 'smc PENTAX-DA 12-24mm F4 ED AL [IF]', #10
@@ -228,4 +270,14 @@
     '7 58' => 'smc PENTAX-D FA Macro 100mm F2.8 WR', #PH - this bit of information cost me $600 ;)
     '7 75' => 'Tamron SP AF 70-200mm F2.8 Di LD [IF] Macro (A001)', #(Anton Bondar)
+    '7 201' => 'smc Pentax-DA L 50-200mm F4-5.6 ED WR', #(Bruce Rusk)
+    '7 202' => 'smc PENTAX-DA L 18-55mm F3.5-5.6 AL WR', #29
+    '7 203' => 'HD PENTAX-DA 55-300mm F4-5.8 ED WR', #29
+    '7 204' => 'HD PENTAX-DA 15mm F4 ED AL Limited', #forum5318
+    '7 205' => 'HD PENTAX-DA 35mm F2.8 Macro Limited', #29
+    '7 206' => 'HD PENTAX-DA 70mm F2.4 Limited', #29
+    '7 207' => 'HD PENTAX-DA 21mm F3.2 ED AL Limited', #forum5327
+    '7 208' => 'HD PENTAX-DA 40mm F2.8 Limited', #PH
+    '7 212' => 'smc PENTAX-DA 50mm F1.8', #PH
+    '7 213' => 'smc PENTAX-DA 40mm F2.8 XS', #PH
     '7 214' => 'smc PENTAX-DA 35mm F2.4 AL', #PH
     '7 216' => 'smc PENTAX-DA L 55-300mm F4-5.8 ED', #PH
@@ -235,9 +287,10 @@
     '7 221' => 'smc PENTAX-DA L 50-200mm F4-5.6 ED', #Ar't
     '7 222' => 'smc PENTAX-DA L 18-55mm F3.5-5.6', #PH (tag 0x003f -- was '7 229' in LensInfo of one test image)
-    '7 223' => 'Samsung D-XENON 18-55mm F3.5-5.6 II', #PH
+    '7 223' => 'Samsung/Schneider D-XENON 18-55mm F3.5-5.6 II', #PH
     '7 224' => 'smc PENTAX-DA 15mm F4 ED AL Limited', #JD
-    '7 225' => 'Samsung D-XENON 18-250mm F3.5-6.3', #8/PH
+    '7 225' => 'Samsung/Schneider D-XENON 18-250mm F3.5-6.3', #8/PH
     '7 226' => 'smc PENTAX-DA* 55mm F1.4 SDM (SDM unused)', #PH (NC)
-    '7 227' => 'smc PENTAX DA* 60-250mm F4 [IF] SDM (SDM unused)', #PH (NC)
+    '7 227' => 'smc PENTAX-DA* 60-250mm F4 [IF] SDM (SDM unused)', #PH (NC)
+    '7 228' => 'Samsung 16-45mm F4 ED', #29
     '7 229' => 'smc PENTAX-DA 18-55mm F3.5-5.6 AL II', #JD
     '7 230' => 'Tamron AF 17-50mm F2.8 XR Di-II LD (Model A16)', #JD
@@ -252,9 +305,51 @@
     '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 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
+    '8 12' => 'Sigma 70-300mm F4-5.6 DG OS', #forum3382
+    '8 13' => 'Sigma 120-400mm F4.5-5.6 APO DG OS HSM', #26
     '8 14' => 'Sigma 17-70mm F2.8-4.0 DC Macro OS HSM', #(Hubert Meier)
-    '8 18' => 'Sigma 8-16mm F4.5-5.6 DC HSM', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2998.0.html
+    '8 15' => 'Sigma 150-500mm F5-6.3 APO DG OS HSM', #26
+    '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
+    '8 24' => 'Sigma 17-70mm F2.8-4 DC Macro OS HSM', #27
+    '8 25' => 'Sigma 17-50mm F2.8 EX DC HSM', #Exiv2
+    '8 27' => 'Sigma 18-200mm F3.5-6.3 II DC HSM', #27
+    '8 28' => 'Sigma 18-250mm F3.5-6.3 DC Macro HSM', #27
+    '8 29' => 'Sigma 35mm F1.4 DG HSM', #27
+    '8 30' => 'Sigma 17-70mm F2.8-4 DC Macro HSM | C', #27
+    '8 31' => 'Sigma 18-35mm F1.8 DC HSM', #27
+    '8 32' => 'Sigma 30mm F1.4 DC HSM | A', #27
+    '8 33' => 'Sigma 18-200mm F3.5-6.3 DC Macro HSM', #DieterPearcey (C014)
+    '8 34' => 'Sigma 18-300mm F3.5-6.3 DC Macro HSM', #NJ
+    '8 59' => 'HD PENTAX-D FA 150-450mm F4.5-5.6 ED DC AW', #29
+    '8 60' => 'HD PENTAX-D FA* 70-200mm F2.8 ED DC AW', #29
+    '8 61' => 'HD PENTAX-D FA 28-105mm F3.5-5.6 ED DC WR', #PH
+    '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 66' => 'HD PENTAX-D FA 85mm F1.4 ED SDM AW', #James O'Neill
+    '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
+    '8 200' => 'HD PENTAX-DA 16-85mm F3.5-5.6 ED DC WR', #29
+    '8 209' => 'HD PENTAX-DA 20-40mm F2.8-4 ED Limited DC WR', #29
+    '8 210' => 'smc PENTAX-DA 18-270mm F3.5-6.3 ED SDM', #Helmut Schutz
+    '8 211' => 'HD PENTAX-DA 560mm F5.6 ED AW', #PH
     '8 215' => 'smc PENTAX-DA 18-135mm F3.5-5.6 ED AL [IF] DC WR', #PH
     '8 226' => 'smc PENTAX-DA* 55mm F1.4 SDM', #JD
-    '8 227' => 'smc PENTAX DA* 60-250mm F4 [IF] SDM', #JD
+    '8 227' => 'smc PENTAX-DA* 60-250mm F4 [IF] SDM', #JD
     '8 232' => 'smc PENTAX-DA 17-70mm F4 AL [IF] SDM', #JD
     '8 234' => 'smc PENTAX-DA* 300mm F4 ED [IF] SDM', #19
@@ -264,11 +359,51 @@
     '8 255' => 'Sigma Lens (8 255)',
     '8 255.1' => 'Sigma 70-200mm F2.8 EX DG Macro HSM II', #JD
-    '8 255.2' => 'Sigma APO 150-500mm F5-6.3 DG OS HSM', #JD
-    '8 255.3' => 'Sigma 50-150mm F2.8 II APO EX DC HSM', #http://u88.n24.queensu.ca/exiftool/forum/index.php/topic,2997.0.html
+    '8 255.2' => 'Sigma 150-500mm F5-6.3 DG APO [OS] HSM', #JD (non-OS version has same type, ref 29)
+    '8 255.3' => 'Sigma 50-150mm F2.8 II APO EX DC HSM', #forum2997
+    '8 255.4' => 'Sigma 4.5mm F2.8 EX DC HSM Circular Fisheye', #PH
+    '8 255.5' => 'Sigma 50-200mm F4-5.6 DC OS', #26
+    '8 255.6' => 'Sigma 24-70mm F2.8 EX DG HSM', #29
+#
+# 645 lenses
+#
+    '9 0' => '645 Manual Lens', #PH (NC)
+    '10 0' => '645 A Series Lens', #PH
+    '11 1' => 'smc PENTAX-FA 645 75mm F2.8', #PH
+    '11 2' => 'smc PENTAX-FA 645 45mm F2.8', #PH
+    '11 3' => 'smc PENTAX-FA* 645 300mm F4 ED [IF]', #PH
     '11 4' => 'smc PENTAX-FA 645 45-85mm F4.5', #PH
+    '11 5' => 'smc PENTAX-FA 645 400mm F5.6 ED [IF]', #PH
+    '11 7' => 'smc PENTAX-FA 645 Macro 120mm F4', #PH
     '11 8' => 'smc PENTAX-FA 645 80-160mm F4.5', #PH
+    '11 9' => 'smc PENTAX-FA 645 200mm F4 [IF]', #PH
+    '11 10' => 'smc PENTAX-FA 645 150mm F2.8 [IF]', #PH
     '11 11' => 'smc PENTAX-FA 645 35mm F3.5 AL [IF]', #PH
+    '11 12' => 'smc PENTAX-FA 645 300mm F5.6 ED [IF]', #29
+    '11 14' => 'smc PENTAX-FA 645 55-110mm F5.6', #PH
+    '11 16' => 'smc PENTAX-FA 645 33-55mm F4.5 AL', #PH
     '11 17' => 'smc PENTAX-FA 645 150-300mm F5.6 ED [IF]', #PH
+    '11 21' => 'HD PENTAX-D FA 645 35mm F3.5 AL [IF]', #29
     '13 18' => 'smc PENTAX-D FA 645 55mm F2.8 AL [IF] SDM AW', #PH
+    '13 19' => 'smc PENTAX-D FA 645 25mm F4 AL [IF] SDM AW', #PH
+    '13 20' => 'HD PENTAX-D FA 645 90mm F2.8 ED AW SR', #PH
+    '13 253' => 'HD PENTAX-DA 645 28-45mm F4.5 ED AW SR', #Dominique Schrekling email
+    '13 254' => 'smc PENTAX-DA 645 25mm F4 AL [IF] SDM AW', #forum8253
+#
+# Q-mount lenses (21=auto focus lens, 22=manual focus)
+#
+    '21 0' => 'Pentax Q Manual Lens', #PH
+    '21 1' => '01 Standard Prime 8.5mm F1.9', #PH
+    '21 2' => '02 Standard Zoom 5-15mm F2.8-4.5', #PH
+    '22 3' => '03 Fish-eye 3.2mm F5.6', #PH
+    '22 4' => '04 Toy Lens Wide 6.3mm F7.1', #PH
+    '22 5' => '05 Toy Lens Telephoto 18mm F8', #PH
+    '21 6' => '06 Telephoto Zoom 15-45mm F2.8', #PH
+    '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)
 );
 
@@ -327,8 +462,8 @@
     0x12c3c => 'Optio W20',
     0x12c46 => 'Optio A20',
-    0x12c8c => 'Optio M30',
     0x12c78 => 'Optio E30',
     0x12c7d => 'Optio E35',
     0x12c82 => 'Optio T30',
+    0x12c8c => 'Optio M30',
     0x12c91 => 'Optio L30',
     0x12c96 => 'Optio W30',
@@ -373,7 +508,46 @@
     0x12e6c => 'K-r',
     0x12e76 => 'K-5',
-    0x12e8a => 'Optio RS1000 / RS1500',
+    0x12e8a => 'Optio RS1000/RS1500',
     0x12e94 => 'Optio RZ10',
+    0x12e9e => 'Optio LS1000',
     0x12ebc => 'Optio WG-1 GPS',
+    0x12ed0 => 'Optio S1',
+    0x12ee4 => 'Q',
+    0x12ef8 => 'K-01',
+    0x12f0c => 'Optio RZ18',
+    0x12f16 => 'Optio VS20',
+    0x12f2a => 'Optio WG-2 GPS',
+    0x12f48 => 'Optio LS465',
+    0x12f52 => 'K-30',
+    0x12f5c => 'X-5',
+    0x12f66 => 'Q10',
+    0x12f70 => 'K-5 II',
+    0x12f71 => 'K-5 II s', #forum4515
+    0x12f7a => 'Q7',
+    0x12f84 => 'MX-1',
+    0x12f8e => 'WG-3 GPS',
+    0x12f98 => 'WG-3',
+    0x12fa2 => 'WG-10',
+    0x12fb6 => 'K-50',
+    0x12fc0 => 'K-3', #29
+    0x12fca => 'K-500',
+    0x12fe8 => 'WG-4', # (Ricoh)
+    0x12fde => 'WG-4 GPS', # (Ricoh)
+    0x13006 => 'WG-20', # (Ricoh)
+    0x13010 => '645Z',
+    0x1301a => 'K-S1',
+    0x13024 => 'K-S2', #29 (Ricoh)
+    0x1302e => 'Q-S1',
+    0x13056 => 'WG-30', # (Ricoh)
+    0x1307e => 'WG-30W', # (Ricoh)
+    0x13088 => 'WG-5 GPS', # (Ricoh)
+    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)
+    0x13290 => 'WG-70', # (Ricoh)
 );
 
@@ -384,5 +558,5 @@
     2 => 'Anchorage',
     3 => 'Vancouver',
-    4 => 'San Fransisco',
+    4 => 'San Francisco',
     5 => 'Los Angeles',
     6 => 'Calgary',
@@ -451,5 +625,5 @@
     69 => 'Stockholm',
     70 => 'Lisbon', #14
-    71 => 'Copenhagen', #25
+    71 => 'Copenhagen', #NJ
     72 => 'Warsaw',
     73 => 'Prague',
@@ -489,4 +663,10 @@
         18 => 'Posterization',
         19 => 'Sketch Filter',
+        20 => 'Shading', # (Q)
+        21 => 'Invert Color', # (Q)
+        23 => 'Tone Expansion', #Forum5247
+        27 => 'Unicolor Bold', #31
+        28 => 'Bold Monochrome', #31
+        29 => 'Replace Color', #31
         254 => 'Custom Filter',
     },
@@ -506,9 +686,9 @@
     9  => ['Color',         { 1=>'Red',2=>'Magenta',3=>'Blue',4=>'Cyan',5=>'Green',6=>'Yellow' }], # Color Filter
     10 => ['Density',       { 1=>'Light',2=>'Standard',3=>'Dark' }], # Color Filter
-    11 => ['ExtractedColor',{ 0=>'Off',1=>'Red',2=>'Magenta',3=>'Blue',4=>'Cyan',5=>'Green',6=>'Yellow' }], # ExtractColor [x2]
-    12 => ['ColorRange', '%+d'],    # ExtractColor [x2] (-2-+2)
+    11 => ['ExtractedColor',{ 0=>'Off',1=>'Red',2=>'Magenta',3=>'Blue',4=>'Cyan',5=>'Green',6=>'Yellow' }], # Extract Color [x2]
+    12 => ['ColorRange', '%+d'],    # Extract Color [x2] (-2-+2)
     13 => ['FilterEffect',  { 0=>'Off',1=>'Red',2=>'Green',3=>'Blue',4=>'Infrared'}], # Monochrome
     14 => ['ToningBA', '%+d'],      # Monochrome (-3-+3)
-    15 => ['InvertColor',   { 0=>'Off',1=>'On' }], # Custom
+    15 => ['InvertColor',   { 0=>'Off',1=>'On' }], # Custom/Invert Color
     16 => ['Slim', '%+d'],          # Slim (-8-+8)
     17 => ['EffectDensity', { 1=>'Sparse',2=>'Normal',3=>'Dense' }], # Starburst
@@ -518,6 +698,6 @@
     21 => ['DistortionType', '%d'], # Custom (1-3)
     22 => ['DistortionLevel',{0=>'Off',1=>'Weak',2=>'Medium',3=>'Strong' }], #Custom
-    23 => ['ShadingType', '%d'],    # Custom (1-6)
-    24 => ['ShadingLevel', '%+d'],  # Custom (-3-+3)
+    23 => ['ShadingType', '%d'],    # Custom/Shading (1-6)
+    24 => ['ShadingLevel', '%+d'],  # Custom/Shading (-3-+3)
     25 => ['Shading', '%d'],        # Toy Camera (1-3)
     26 => ['Blur',  '%d'],          # Toy Camera (1-3)
@@ -529,4 +709,5 @@
     32 => ['Saturation2',   { 0=>'Off',1=>'Low',2=>'Medium',3=>'High' }], # Water Color
     33 => ['HDR',           { 1=>'Weak',2=>'Medium',3=>'Strong' }], # HDR
+    # (34 missing)
     35 => ['FocusPlane', '%+d'],    # Miniature (-3-+3)
     36 => ['FocusWidth',    { 1=>'Narrow',2=>'Middle',3=>'Wide' }], # Miniature
@@ -537,4 +718,11 @@
     41 => ['Contrast2',     { 1=>'Low',2=>'Medium',3=>'High'}], # Sketch Filter
     42 => ['ScratchEffect', { 0=>'Off',1=>'On' }], # Sketch Filter
+    45 => ['ToneExpansion', { 1=>'Low',2=>'Medium',3=>'High' }], # Tone Expansion (ref Forum5247)
+    47 => ['UnicolorBold',  { 1=>'Red',2=>'Magenta',3=>'Blue',4=>'Cyan',5=>'Green',6=>'Yellow' }], #31 Unicolor Bold
+    48 => ['BoldMonochrome', '%d'], #31 Bold Monochrome (1-3)
+    49 => ['OriginalColor', { 1=>'Red',2=>'Magenta',3=>'Blue',4=>'Cyan',5=>'Green',6=>'Yellow' }], #31 Replace Color
+    50 => ['NewColor',      { 1=>'Red',2=>'Magenta',3=>'Blue',4=>'Cyan',5=>'Green',6=>'Yellow' }], #31 Replace Color
+    51 => ['ColorScale', '%d'], #31 Replace Color (1-5)
+    52 => ['Toning2', '%+d'], #31 Extract Color (-3-+3)
 );
 
@@ -578,4 +766,47 @@
     PrintConvInv => 'hex($val)',
 );
+
+# conversions for tags 0x0053-0x005a
+my %colorTemp = (
+    Writable => 'undef',
+    Count => 4,
+    ValueConv => sub {
+        my $val = shift;
+        return $val unless length $val == 4;
+        my @a = unpack 'nCC', $val;
+        $a[0] = 53190 - $a[0];
+        $a[1] = ($a[2] & 0x0f); $a[1] -= 16 if $a[1] >= 8;
+        $a[2] = ($a[2] >> 4);   $a[2] -= 16 if $a[2] >= 8;
+        return "@a";
+    },
+    ValueConvInv => sub {
+        my $val = shift;
+        my @a = split ' ', $val;
+        return undef unless @a == 3;
+        return pack 'nCC', 53190 - $a[0], 0, ($a[1] & 0x0f) + (($a[2] & 0x0f) << 4);
+    },
+    PrintConv => sub {
+        $_ = shift;
+        s/ ([1-9])/ +$1/g;
+        s/ 0/  0/g;
+        return $_;
+    },
+    PrintConvInv => '$val',
+);
+
+# conversions for KelvinWB tags
+my %kelvinWB = (
+    Format => 'int16u[4]',
+    ValueConv => sub {
+        my @a = split ' ', shift;
+        (53190 - $a[0]) . ' ' . $a[1] . ' ' . ($a[2] / 8192) . ' ' . ($a[3] / 8192);
+    },
+    ValueConvInv => sub {
+        my @a = split ' ', shift;
+        (53190 - $a[0]) . ' ' . $a[1] . ' ' . int($a[2]*8192+0.5) . ' ' . int($a[3]*8192+0.5);
+    },
+);
+
+my %noYes = ( 0 => 'No', 1 => 'Yes' );
 
 # common attributes for writable BinaryData directories
@@ -600,4 +831,52 @@
         PrintConv => '$val=~tr/ /./; $val',
         PrintConvInv => '$val=~tr/./ /; $val',
+        # 0.1.0.3 - PENTAX Optio E40
+        # 3.0.0.0 - K10D
+        # 3.1.0.0 - Optio A40/S10/L36/L40/M40/V10
+        # 3.1.1.0 - Optio L36/L40/M40/V10
+        # 3.1.2.0 - Optio Z10
+        # 4.0.2.0 - Optio E50
+        # 4.1.0.0 - Optio S12
+        # 4.1.1.0 - Optio M50
+        # 4.1.2.0 - K20D, K200D
+        # 4.2.0.0 - Optio L50/V20
+        # 4.2.1.0 - Optio E60/M90
+        # 4.2.2.0 - Optio W60
+        # 4.2.3.0 - Optio M60
+        # 4.4.0.1 - K-m, K2000
+        # 4.5.0.0 - Optio E70/L70
+        # 4.5.0.0 - Optio E70/L70/P70
+        # 4.6.0.0 - Optio E80/E90/W80
+        # 5.0.0.0 - K-7, Optio P80/WS80
+        # 5.1.0.0 - K-x
+        # 5.2.0.0 - Optio I-10
+        # 5.3.0.0 - Optio H90
+        # 5.3.2.0 - Optio W90/X90
+        # 6.0.0.0 - K-r, 645D
+        # 6.1.3.0 - Optio LS1000/RS1000/RS1500/RZ10
+        # 7.0.0.0 - K-5
+        # 7.1.0.0 - Optio WG-1GPS/WG-10/WG-20
+        # 7.2.0.0 - Optio S1
+        # 8.0.0.0 - Q
+        # 8.0.1.0 - Optio RZ18
+        # 8.0.4.0 - Optio VS20
+        # 8.1.0.0 - Optio LS465/WG-2GPS
+        # 9.0.0.0 - K-01
+        # 9.1.2.0 - X-5
+        # 10.0.0.0 - K-30, K-50, K-500, K-5 II, K-5 II s
+        # 10.0.2.0 - Q10
+        # 10.2.0.0 - WG-3/WG-4
+        # 10.2.1.0 - MX-1
+        # 10.4.1.0 - WG-3/4/5 GPS, WG-30/30W
+        # 10.6.1.0 - Q-S1, Q7
+        # 11.0.0.0 - K-3
+        # 11.2.1.0 - 645Z
+        # 11.3.0.0 - K-S1
+        # 11.5.0.0 - K-S2
+        # 11.6.1.0 - K-3 II
+        # 11.7.5.0 - WG-M2
+        # 12.0.0.0 - K-1
+        # 12.1.3.0 - K-70
+        # 12.1.5.0 - KP
     },
     0x0001 => { #PH
@@ -612,4 +891,5 @@
         Count => 2,
         PrintConv => '$val =~ tr/ /x/; $val',
+        PrintConvInv => '$val =~ tr/x/ /; $val',
     },
     0x0003 => { #PH
@@ -619,4 +899,5 @@
         Groups => { 2 => 'Image' },
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
@@ -624,9 +905,10 @@
         Name => 'PreviewImageStart',
         IsOffset => 2,  # code to use original base
-        Protected => 2,
         OffsetPair => 0x0003, # point to associated byte count
         DataTag => 'PreviewImage',
         Groups => { 2 => 'Image' },
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
+        Protected => 2,
     },
     0x0005 => { #13
@@ -635,4 +917,6 @@
         PrintHex => 1,
         SeparateTable => 1,
+        DataMember => 'PentaxModelID',
+        RawConv => '$$self{PentaxModelID} = $val',
         PrintConv => \%pentaxModelID,
     },
@@ -679,4 +963,7 @@
             4 => 'RAW', #5
             5 => 'Premium', #PH (K20D)
+            7 => 'RAW (pixel shift enabled)', #forum6536 (K-3 II)
+            8 => 'Dynamic Pixel Shift', #IB
+            65535 => 'n/a', #PH (Q MOV video)
         },
     },
@@ -705,5 +992,7 @@
             29 => '4000x3000', #PH (X70)
             30 => '4288x3216', #PH (Optio RS1000)
+            31 => '4608x3456', #PH (Optio RZ18)
             129 => '1920x1080', #PH (Optio RZ10)
+            135 => '4608x2592', #PH (Q10 stretch filter)
             257 => '3216x3216', #PH (Optio RZ10)
             '0 0' => '2304x1728', #13
@@ -717,4 +1006,5 @@
             '36 0' => '3008x2008 or 3040x2024',  #PH
             '37 0' => '3008x2000', #13
+            # 65535 - seen for an X-5 panorama (PH)
         },
     },
@@ -727,5 +1017,5 @@
             different from other models
         },
-        ValueConv => '($val < 4 and $$self{Model} =~ /Optio 555\b/) ? $val + 0.1 : $val',
+        ValueConv => '(IsInt($val) and $val < 4 and $$self{Model} =~ /Optio 555\b/) ? $val + 0.1 : $val',
         ValueConvInv => 'int $val',
         PrintConvColumns => 2,
@@ -764,8 +1054,8 @@
             31 => 'Illustrations', #13
             33 => 'Digital Filter', #13
-            35 => 'Night Scene Portrait', #25
+            35 => 'Night Scene Portrait', #NJ
             37 => 'Museum', #PH
             38 => 'Food', #PH
-            39 => 'Underwater', #25
+            39 => 'Underwater', #NJ
             40 => 'Green Mode', #PH
             49 => 'Light Pet', #PH
@@ -777,8 +1067,16 @@
             56 => 'Synchro Sound Record', #PH
             58 => 'Frame Composite', #14
-            59 => 'Report', #25
+            59 => 'Report', #NJ
             60 => 'Kids', #13
             61 => 'Blur Reduction', #13
+            63 => 'Panorama 2', #PH (X-5)
             65 => 'Half-length Portrait', #JD
+            66 => 'Portrait 2', #PH (LS645)
+            74 => 'Digital Microscope', #PH (WG-4)
+            75 => 'Blue Sky', #PH (LS465)
+            80 => 'Miniature', #PH (VS20)
+            81 => 'HDR', #PH (LS465)
+            83 => 'Fisheye', #PH (VS20)
+            85 => 'Digital Filter 4', #PH (WG-5)
             221 => 'P', #PH (Optio 555)
             255=> 'PICT', #PH (Optio 555)
@@ -822,5 +1120,6 @@
         {
             Name => 'FocusMode',
-            Condition => '$self->{Make} =~ /^PENTAX/',
+            # (can't test for "PENTAX" because MOV videos don't have Make)
+            Condition => '$$self{Make} !~ /^Asahi/',
             Notes => 'Pentax models',
             Writable => 'int16u',
@@ -833,12 +1132,20 @@
                 4 => 'Super Macro', #JD
                 5 => 'Pan Focus',
-                16 => 'AF-S', #17
-                17 => 'AF-C', #17
-                18 => 'AF-A', #PH (educated guess)
-                32 => 'Contrast-detect', #PH (K-5)
-                33 => 'Tracking Contrast-detect', #PH (K-5)
+                # 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)
+                32 => 'Contrast-detect (Focus-priority)', #PH (K-5)
+                33 => 'Tracking Contrast-detect (Focus-priority)', #PH (K-5)
+                # bit 8 indicates release priority
+                272 => 'AF-S (Release-priority)', #PH (K-5,K-3)
+                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',
             Writable => 'int16u',
@@ -852,9 +1159,86 @@
         },
     ],
-    0x000e => { #7
+    0x000e => [{ #29
         Name => 'AFPointSelected',
+        Condition => '$$self{Model} =~ /K-1\b/',
         Writable => 'int16u',
+        Notes => 'K-1',
         PrintConvColumns => 2,
-        PrintConv => {
+        PrintConv => [{
+            0xffff => 'Auto',
+            0xfffe => 'Fixed Center',
+            0xfffd => 'Automatic Tracking AF', #JD
+            0xfffc => 'Face Detect AF', #JD
+            0xfffb => 'AF Select', #PH (Q select from 25-areas)
+            # AF pattern:
+            #       01 02 03 04 05
+            #    06 07 08 09 10 11 12
+            # 13 14 15 16 17 18 19 20 21
+            #    22 23 24 25 26 27 28
+            #       29 30 31 32 33
+            0 => 'None',
+            1 => 'Top-left',
+            2 => 'Top Near-left',
+            3 => 'Top',
+            4 => 'Top Near-right',
+            5 => 'Top-right',
+            6 => 'Upper Far-left',
+            7 => 'Upper-left',
+            8 => 'Upper Near-left',
+            9 => 'Upper-middle',
+            10 => 'Upper Near-right',
+            11 => 'Upper-right',
+            12 => 'Upper Far-right',
+            13 => 'Far Far Left',
+            14 => 'Far Left',
+            15 => 'Left',
+            16 => 'Near-left',
+            17 => 'Center',
+            18 => 'Near-right',
+            19 => 'Right',
+            20 => 'Far Right',
+            21 => 'Far Far Right',
+            22 => 'Lower Far-left',
+            23 => 'Lower-left',
+            24 => 'Lower Near-left',
+            25 => 'Lower-middle',
+            26 => 'Lower Near-right',
+            27 => 'Lower-right',
+            28 => 'Lower Far-right',
+            29 => 'Bottom-left',
+            30 => 'Bottom Near-left',
+            31 => 'Bottom',
+            32 => 'Bottom Near-right',
+            33 => 'Bottom-right',
+            263 => 'Zone Select Upper-left',       # 01,02;06,07,08;14,15,16
+            264 => 'Zone Select Upper Near-left',  # 01,02,03;07,08,09;15,16,17
+            265 => 'Zone Select Upper Middle',     # 02,03,04;08,09,10;16,17,18
+            266 => 'Zone Select Upper Near-right', # 03,04,05;09,10,11;17,18,19
+            267 => 'Zone Select Upper-right',      # 04,05;10,11,12;18,19,20
+            270 => 'Zone Select Far Left',         # 06,07;13,14,15;22,23
+            271 => 'Zone Select Left',             # 06,07,08;14,15,16;22,23,24
+            272 => 'Zone Select Near-left',        # 07,08,09;15,16,17;23,24,25
+            273 => 'Zone Select Center',           # 08,09,10;16,17,18;24,25,26
+            274 => 'Zone Select Near-right',       # 09,10,11;17,18,19;25,26,27
+            275 => 'Zone Select Right',            # 10,11,12;18,19,20;26,27,28
+            276 => 'Zone Select Far Right',        # 11,12;19,20,21;27,28
+            279 => 'Zone Select Lower-left',       # 14,15,16;22,23,24;29,30
+            280 => 'Zone Select Lower Near-left',  # 15,16,17;23,24,25;29,30,31
+            281 => 'Zone Select Lower-middle',     # 16,17,18;24,25,26;30,31,32
+            282 => 'Zone Select Lower Near-right', # 17,18,19;25,26,27;31,32,33
+            283 => 'Zone Select Lower-right',      # 18,19,20;26,27,28;32,33
+        },{
+            0 => 'Single Point',
+            1 => 'Expanded Area 9-point (S)',
+            3 => 'Expanded Area 25-point (M)',
+            5 => 'Expanded Area 33-point (L)',
+        }],
+    },{
+        Name => 'AFPointSelected',
+        Condition => '$$self{Model} =~ /K-3\b/',
+        Writable => 'int16u',
+        Notes => 'K-3',
+        PrintConvColumns => 2,
+        PrintConv => [{
             # 0 - Contrast-detect AF? - PH (K-5)
             0xffff => 'Auto',
@@ -862,4 +1246,86 @@
             0xfffd => 'Automatic Tracking AF', #JD
             0xfffc => 'Face Detect AF', #JD
+            0xfffb => 'AF Select', #PH (Q select from 25-areas)
+            # AF pattern: (ref forum5422)
+            #    01 02 03 04 05
+            #    06 07 08 09 10
+            # 11 12 13 14 15 16 17
+            #    18 19 20 21 22
+            #    23 24 25 26 27
+            0 => 'None',
+            1 => 'Top-left',
+            2 => 'Top Near-left',
+            3 => 'Top',
+            4 => 'Top Near-right',
+            5 => 'Top-right',
+            6 => 'Upper-left',
+            7 => 'Upper Near-left',
+            8 => 'Upper-middle',
+            9 => 'Upper Near-right',
+            10 => 'Upper-right',
+            11 => 'Far Left',
+            12 => 'Left',
+            13 => 'Near-left',
+            14 => 'Center',
+            15 => 'Near-right',
+            16 => 'Right',
+            17 => 'Far Right',
+            18 => 'Lower-left',
+            19 => 'Lower Near-left',
+            20 => 'Lower-middle',
+            21 => 'Lower Near-right',
+            22 => 'Lower-right',
+            23 => 'Bottom-left',
+            24 => 'Bottom Near-left',
+            25 => 'Bottom',
+            26 => 'Bottom Near-right',
+            27 => 'Bottom-right',
+            #forum5892
+            257 => 'Zone Select Top-left',
+            258 => 'Zone Select Top Near-left',
+            259 => 'Zone Select Top',
+            260 => 'Zone Select Top Near-right',
+            261 => 'Zone Select Top-right',
+            262 => 'Zone Select Upper-left',
+            263 => 'Zone Select Upper Near-left',
+            264 => 'Zone Select Upper-middle',
+            265 => 'Zone Select Upper Near-right',
+            266 => 'Zone Select Upper-right',
+            267 => 'Zone Select Far Left',
+            268 => 'Zone Select Left',
+            269 => 'Zone Select Near-left',
+            270 => 'Zone Select Center',
+            271 => 'Zone Select Near-right',
+            272 => 'Zone Select Right',
+            273 => 'Zone Select Far Right',
+            274 => 'Zone Select Lower-left',
+            275 => 'Zone Select Lower Near-left',
+            276 => 'Zone Select Lower-middle',
+            277 => 'Zone Select Lower Near-right',
+            278 => 'Zone Select Lower-right',
+            279 => 'Zone Select Bottom-left',
+            280 => 'Zone Select Bottom Near-left',
+            281 => 'Zone Select Bottom',
+            282 => 'Zone Select Bottom Near-right',
+            283 => 'Zone Select Bottom-right',
+        },{ #forum5892
+            0 => 'Single Point',
+            1 => 'Expanded Area 9-point (S)',
+            3 => 'Expanded Area 25-point (M)',
+            5 => 'Expanded Area 27-point (L)',
+        }],
+    },{ #7
+        Name => 'AFPointSelected',
+        Writable => 'int16u',
+        Notes => 'other models',
+        PrintConvColumns => 2,
+        PrintConv => [{
+            # 0 - Contrast-detect AF? - PH (K-5)
+            0xffff => 'Auto',
+            0xfffe => 'Fixed Center',
+            0xfffd => 'Automatic Tracking AF', #JD
+            0xfffc => 'Face Detect AF', #JD
+            0xfffb => 'AF Select', #PH (Q select from 25-areas)
+            0 => 'None', #PH (Q in manual focus mode)
             1 => 'Upper-left',
             2 => 'Top',
@@ -874,7 +1340,49 @@
             11 => 'Lower-right',
         },
-    },
-    0x000f => { #PH
+        # (second number exists for K-5II(s) is usually 0, but is 1 for AF.C with
+        # AFPointMode=='Select' and extended tracking focus points are enabled in the settings)
+        ],
+    }],
+    0x000f => [{ #PH
         Name => 'AFPointsInFocus',
+        Condition => '$$self{Model} =~ /K-3\b/',
+        Writable => 'int32u',
+        Notes => 'K-3 only',
+        PrintHex => 1,
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => {
+                0 => 'Top-left',
+                1 => 'Top Near-left',
+                2 => 'Top',
+                3 => 'Top Near-right',
+                4 => 'Top-right',
+                5 => 'Upper-left',
+                6 => 'Upper Near-left',
+                7 => 'Upper-middle',
+                8 => 'Upper Near-right',
+                9 => 'Upper-right',
+                10 => 'Far Left',
+                11 => 'Left',
+                12 => 'Near-left',
+                13 => 'Center',
+                14 => 'Near-right',
+                15 => 'Right',
+                16 => 'Far Right',
+                17 => 'Lower-left',
+                18 => 'Lower Near-left',
+                19 => 'Lower-middle',
+                20 => 'Lower Near-right',
+                21 => 'Lower-right',
+                22 => 'Bottom-left',
+                23 => 'Bottom Near-left',
+                24 => 'Bottom',
+                25 => 'Bottom Near-right',
+                26 => 'Bottom-right',
+            },
+        },
+    },{ #PH
+        Name => 'AFPointsInFocus',
+        Notes => 'other models',
         Writable => 'int16u',
         PrintHex => 1,
@@ -892,5 +1400,5 @@
             9 => 'Bottom-right',
         },
-    },
+    }],
     0x0010 => { #PH
         Name => 'FocusPosition',
@@ -956,4 +1464,16 @@
             32 => 40000, #PH
             33 => 51200, #PH
+            34 => 64000, #PH (NC)
+            35 => 80000, #PH (NC)
+            36 => 102400, #27
+            37 => 128000, #PH (NC)
+            38 => 160000, #PH (NC)
+            39 => 204800, #27
+            40 => 256000, #PH (NC)
+            41 => 320000, #PH (NC)
+            42 => 409600, #PH (NC)
+            43 => 512000, #PH (NC)
+            44 => 640000, #PH (NC)
+            45 => 819200, #PH (KP)
             # Optio 330/430 (oddball)
             50 => 50, #PH
@@ -986,4 +1506,14 @@
             277 => 36000, #PH
             278 => 51200, #PH
+            279 => 72000, #PH (NC)
+            280 => 102400, #PH (NC)
+            281 => 144000, #PH (NC)
+            282 => 204800, #PH (NC)
+            283 => 288000, #PH (NC)
+            284 => 409600, #PH (NC)
+            285 => 576000, #PH (NC)
+            286 => 819200, #PH (NC)
+            65534 => 'Auto 2', #PH (Q/Q10/Q7 MOV) [how is this different from 65535?]
+            65535 => 'Auto', #PH/31 (K-01/K-70 MP4)
         },
     },
@@ -995,9 +1525,14 @@
         Notes => q{
             calibrated differently for different models.  For the Optio WP, add 6 to get
-            approximate Light Value.  May not be valid for some models, ie. Optio S
-        },
-    },
-    0x0016 => { #PH
+            approximate Light Value.  May not be valid for some models, eg. Optio S
+        },
+    },
+    0x0016 => [{ #PH
         Name => 'ExposureCompensation',
+        Condition => '$count == 1',
+        Notes => q{
+            some models write two values here.  The second value is meaning of the
+            second value is not yet known
+        },
         Writable => 'int16u',
         ValueConv => '($val - 50) / 10',
@@ -1005,5 +1540,14 @@
         PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
-    },
+    },{
+        Name => 'ExposureCompensation',
+        Writable => 'int16u',
+        # (2 values for K-70, etc -- have only seen "0" for the 2nd value - PH)
+        Count => 2,
+        ValueConv => '$val =~ s/ .*//; ($val - 50) / 10',
+        ValueConvInv => 'int($val * 10 + 50.5) . " 0"',
+        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    }],
     0x0017 => { #3
         Name => 'MeteringMode',
@@ -1026,10 +1570,25 @@
             '+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',
@@ -1077,4 +1636,6 @@
             9 => 'Flash', #13
             10 => 'Cloudy', #13
+            11 => 'Warm White Fluorescent', #PH (K-3)
+            14 => 'Multi Auto', #PH (K-3)
             15 => 'Color Temperature Enhancement', #PH
             17 => 'Kelvin', #PH
@@ -1152,13 +1713,13 @@
         PrintConvColumns => 2,
         PrintConv => [{ # the *istD has pairs of values - PH
-            0 => 'Low', #PH
-            1 => 'Normal', #PH
-            2 => 'High', #PH
-            3 => 'Med Low', #2
-            4 => 'Med High', #2
-            5 => 'Very Low', #(NC)
-            6 => 'Very High', #(NC)
-            7 => '-4', #PH (K-5)
-            8 => '+4', #PH (NC)
+            0 => '-2 (low)', #PH
+            1 => '0 (normal)', #PH
+            2 => '+2 (high)', #PH
+            3 => '-1 (medium low)', #2
+            4 => '+1 (medium high)', #2
+            5 => '-3 (very low)', #PH
+            6 => '+3 (very high)', #PH (NC)
+            7 => '-4 (minimum)', #PH (NC)
+            8 => '+4 (maximum)', #PH (K-5)
             65535 => 'None', #PH (Monochrome)
         }],
@@ -1171,13 +1732,14 @@
         PrintConvColumns => 2,
         PrintConv => [{ # the *istD has pairs of values - PH
-            0 => 'Low', #PH
-            1 => 'Normal', #PH
-            2 => 'High', #PH
-            3 => 'Med Low', #2
-            4 => 'Med High', #2
-            5 => 'Very Low', #PH
-            6 => 'Very High', #PH (NC)
-            7 => '-4', #PH (NC)
-            8 => '+4', #PH (K-5)
+            0 => '-2 (low)', #PH
+            1 => '0 (normal)', #PH
+            2 => '+2 (high)', #PH
+            3 => '-1 (medium low)', #2
+            4 => '+1 (medium high)', #2
+            5 => '-3 (very low)', #PH
+            6 => '+3 (very high)', #PH (NC)
+            7 => '-4 (minimum)', #PH (NC)
+            8 => '+4 (maximum)', #PH (K-5)
+            65535 => 'n/a', # got this for a Backlight Silhouette - PH (Q)
         }],
     },
@@ -1189,13 +1751,13 @@
         PrintConvColumns => 2,
         PrintConv => [{ # the *istD has pairs of values - PH
-            0 => 'Soft', #PH
-            1 => 'Normal', #PH
-            2 => 'Hard', #PH
-            3 => 'Med Soft', #2
-            4 => 'Med Hard', #2
-            5 => 'Very Soft', #(NC)
-            6 => 'Very Hard', #(NC)
-            7 => '-4', #PH (NC)
-            8 => '+4', #PH (NC)
+            0 => '-2 (soft)', #PH
+            1 => '0 (normal)', #PH
+            2 => '+2 (hard)', #PH
+            3 => '-1 (medium soft)', #2
+            4 => '+1 (medium hard)', #2
+            5 => '-3 (very soft)', #(NC)
+            6 => '+3 (very hard)', #(NC)
+            7 => '-4 (minimum)', #PH (NC)
+            8 => '+4 (maximum)', #PH (NC)
         }],
     },
@@ -1256,13 +1818,24 @@
     },
     # 0x002b - definitely exposure related somehow - PH
-    0x002d => { #PH
+    0x002d => [{ #PH
         Name => 'EffectiveLV',
+        Condition => '$format eq "int16u"',
         Notes => 'camera-calculated light value, but includes exposure compensation',
         Writable => 'int16u',
+        Format => 'int16s', # (negative values are valid even though Pentax writes int16u)
         ValueConv => '$val/1024',
         ValueConvInv => '$val * 1024',
         PrintConv => 'sprintf("%.1f",$val)',
         PrintConvInv => '$val',
-    },
+    },{
+        Name => 'EffectiveLV',
+        Condition => '$format eq "int32u"',
+        Writable => 'int32u',
+        Format => 'int32s',
+        ValueConv => '$val/1024',
+        ValueConvInv => '$val * 1024',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    }],
     0x0032 => { #13
         Name => 'ImageEditing',
@@ -1277,6 +1850,7 @@
             '2 0 0 0' => 'Cropped', #PH
             # note: doesn't apply to digital filters applied when picture is taken
-            '4 0 0 0' => 'Digital Filter 4', #PH (K10D)
+            '4 0 0 0' => 'Digital Filter 4', #PH (K10D, Ricoh WG-5)
             '6 0 0 0' => 'Digital Filter 6', #PH (K-5)
+            '8 0 0 0' => 'Red-eye Correction', #PH (WG-10)
             '16 0 0 0' => 'Frame Synthesis?',
         },
@@ -1310,7 +1884,14 @@
             '0 17' => 'Candlelight',
             '0 18' => 'Museum',
-            '0 19' => 'Food', #(n/c)
+            '0 19' => 'Food',
             '0 20' => 'Stage Lighting',
             '0 21' => 'Night Snap',
+            '0 23' => 'Blue Sky', # (Q)
+            '0 24' => 'Sunset', # (Q)
+            '0 26' => 'Night Scene HDR', # (Q)
+            '0 27' => 'HDR', # (Q)
+            '0 28' => 'Quick Macro', # (Q)
+            '0 29' => 'Forest', # (Q)
+            '0 30' => 'Backlight Silhouette', # (Q)
             # AUTO PICT modes (auto-selected)
             '1 4'  => 'Auto PICT (Standard)', #13
@@ -1335,4 +1916,5 @@
             '11 0' => 'Manual, Off-Auto-Aperture',
             '12 0' => 'Bulb, Off-Auto-Aperture',
+            '19 0' => 'Astrotracer', #29
             # extra K10D modes (ref 16)
             '13 0' => 'Shutter & Aperture Priority AE',
@@ -1344,7 +1926,13 @@
             '18 3' => 'Auto Program (MTF)', #PH (NC)
             '18 22' => 'Auto Program (Shallow DOF)', #PH (NC)
-            '254 0' => 'Video', #PH (K-7,K-5)
-            '255 0' => 'Video (Auto Aperture)', #PH (K-5)
-            '255 4' => 'Video (4)', #PH (K-x)
+            '20 22' => 'Blur Control', #PH (Q)
+            '249 0' => 'Movie (TAv)', #31
+            '250 0' => 'Movie (TAv, Auto Aperture)', #31
+            '251 0' => 'Movie (Manual)', #31
+            '252 0' => 'Movie (Manual, Auto Aperture)', #31
+            '253 0' => 'Movie (Av)', #31
+            '254 0' => 'Movie (Av, Auto Aperture)', #31
+            '255 0' => 'Movie (P, Auto Aperture)', #31
+            '255 4' => 'Video (4)', #PH (K-x,K-01)
         },{
             # EV step size (ref 19)
@@ -1358,14 +1946,15 @@
         Count => 4,
         PrintConv => [{
-            0 => 'Single-frame',
+            0 => 'Single-frame', # (also Interval Shooting for K-01 - PH)
             1 => 'Continuous', # (K-5 Hi)
             2 => 'Continuous (Lo)', #PH (K-5)
             3 => 'Burst', #PH (K20D)
+            4 => 'Continuous (Medium)', #PH (K-3)
             255 => 'Video', #PH (K-x)
-            # (K20D also has an Interval mode that needs decoding)
         },{
             0 => 'No Timer',
             1 => 'Self-timer (12 s)',
             2 => 'Self-timer (2 s)',
+            15 => 'Video', #PH (Q MOV)
             16 => 'Mirror Lock-up', # (K-5)
             255 => 'n/a', #PH (K-x)
@@ -1378,9 +1967,18 @@
             0x00 => 'Single Exposure',
             0x01 => 'Multiple Exposure',
+            0x02 => 'Composite Average', #31
+            0x03 => 'Composite Additive', #31
+            0x04 => 'Composite Bright', #31
+            0x08 => 'Interval Shooting', #31
+            0x0a => 'Interval Composite Average', #31
+            0x0b => 'Interval Composite Additive', #31
+            0x0c => 'Interval Composite Bright', #31
+            0x0f => 'Interval Movie', #PH (K-01)
             0x10 => 'HDR', #PH (645D)
             0x20 => 'HDR Strong 1', #PH (NC) (K-5)
             0x30 => 'HDR Strong 2', #PH (K-5)
             0x40 => 'HDR Strong 3', #PH (K-5)
-            0xe0 => 'HDR Auto', #PH (K-5)
+            0x50 => 'HDR Manual', #31 (K-70 HDR 1 and HDR 2)
+            0xe0 => 'HDR Auto', #PH (K-5, K-70)
             0xff => 'Video', #PH (K-x)
         }],
@@ -1394,5 +1992,5 @@
         #  11894 7962 (K10D,K-m)   12012 7987 (*istDS,K100D,K110D)   12012 8019 (*istD),
         #  12061 7988 (K-5)        12053 8005 (K-r,K-x)              14352 9535 (K20D,K-7)
-        #  22315 16711 (645)
+        #  22315 16711 (645)       12080 8008 (K-01)
         ValueConv => 'my @a=split(" ",$val); $_/=500 foreach @a; join(" ",@a)',
         ValueConvInv => 'my @a=split(" ",$val); $_*=500 foreach @a; join(" ",@a)',
@@ -1431,20 +2029,36 @@
         ValueConv => '$val & 0x7ff', # ignore other bits for now
         PrintConvColumns => 2,
-        PrintConv => { BITMASK => {
-            0 => 'Upper-left',
-            1 => 'Top',
-            2 => 'Upper-right',
-            3 => 'Left',
-            4 => 'Mid-left',
-            5 => 'Center',
-            6 => 'Mid-right',
-            7 => 'Right',
-            8 => 'Lower-left',
-            9 => 'Bottom',
-            10 => 'Lower-right',
-        } },
-    },
-    # 0x003d - int16u: 8192 for most images, but occasionally 11571 for K100D/K110D,
-    #              and 8289 or 8456 for the K-x - PH
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => {
+                0 => 'Upper-left',
+                1 => 'Top',
+                2 => 'Upper-right',
+                3 => 'Left',
+                4 => 'Mid-left',
+                5 => 'Center',
+                6 => 'Mid-right',
+                7 => 'Right',
+                8 => 'Lower-left',
+                9 => 'Bottom',
+                10 => 'Lower-right',
+            },
+        },
+    },
+    0x003d => { #IB
+        Name => 'DataScaling',
+        Writable => 'int16u',
+        # divide by the second value of Pentax_0x0201 (WhitePoint), usually
+        # 8192, to get the floating point normalization factor.
+        # One of the examples of how this tag can be used is calculation of
+        # baseline exposure compensation (Adobe-style) for a PEF:
+        # log2(Pentax_0x007e)-14-0.5+log2(Pentax_0x003d)-13
+        # or
+        # log2(Pentax_0x007e*(Pentax_0x003d/(2^13))/(2^14))-0.5
+        # where
+        # makernotes:Pentax_0x003d/(2^13) is the normalization factor. (ref IB)
+        # - 8192 for most images, but occasionally 11571 for K100D/K110D,
+        #   and 8289 or 8456 for the K-x (ref PH)
+    },
     0x003e => { #PH
         Name => 'PreviewImageBorders',
@@ -1454,12 +2068,6 @@
     },
     0x003f => { #PH
-        Name => 'LensType',
-        Writable => 'int8u',
-        Count => 2,
-        SeparateTable => 1,
-        # the K-m adds two zeros to the LensType, some other models add only 1
-        ValueConv => '$val=~s/^(\d+ \d+)( 0){1,2}$/$1/; $val',
-        ValueConvInv => '$val',
-        PrintConv => \%pentaxLensTypes,
+        Name => 'LensRec',
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensRec' },
     },
     0x0040 => { #PH
@@ -1476,5 +2084,5 @@
     },
     0x0047 => { #PH
-        Name => 'CameraTemperature',
+        Name => 'CameraTemperature', # (chassis temperature, ref forum6677)
         Writable => 'int8s',
         PrintConv => '"$val C"',
@@ -1494,6 +2102,7 @@
         PrintConv => { 0 => 'Off', 1 => 'On' },
     },
-    0x004d => { #PH
+    0x004d => [{ #PH
         Name => 'FlashExposureComp',
+        Condition => '$count == 1',
         Writable => 'int32s',
         ValueConv => '$val / 256',
@@ -1501,5 +2110,13 @@
         PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
-    },
+    },{ #PH (K-3)
+        Name => 'FlashExposureComp',
+        Writable => 'int8s',
+        Count => 2,     # (don't know what the 2nd number is for)
+        ValueConv => [ '$val / 6' ],
+        ValueConvInv => [ '$val / 6' ],
+        PrintConv => [ '$val ? sprintf("%+.1f", $val) : 0' ],
+        PrintConvInv => [ 'Image::ExifTool::Exif::ConvertFraction($val)' ],
+    }],
     0x004f => { #PH
         Name => 'ImageTone', # (Called CustomImageMode in K20D manual)
@@ -1514,6 +2131,11 @@
             5 => 'Monochrome', # (K20D)
             6 => 'Muted', # (645D)
-            7 => 'Reversal Film', # (645D)
+            7 => 'Reversal Film', # (645D) (Ricoh WG-5 "Slide Film")
             8 => 'Bleach Bypass', # (K-5)
+            9 => 'Radiant', # (Q)
+            10 => 'Cross Processing', #31 (K-70)
+            11 => 'Flat', #31 (K-70)
+            # 256 - seen for GR III
+            # 262 - seen for GR III
         },
     },
@@ -1526,9 +2148,26 @@
     },
     # 0x0053-0x005a - not in JPEG images - PH
-    0x005c => { #PH
+    0x0053 => { #28
+        Name => 'ColorTempDaylight',
+        %colorTemp,
+        Notes => '0x0053-0x005a are 3 numbers: Kelvin, shift AB, shift GM',
+    },
+    0x0054 => { Name => 'ColorTempShade',        %colorTemp }, #28
+    0x0055 => { Name => 'ColorTempCloudy',       %colorTemp }, #28
+    0x0056 => { Name => 'ColorTempTungsten',     %colorTemp }, #28
+    0x0057 => { Name => 'ColorTempFluorescentD', %colorTemp }, #28
+    0x0058 => { Name => 'ColorTempFluorescentN', %colorTemp }, #28
+    0x0059 => { Name => 'ColorTempFluorescentW', %colorTemp }, #28
+    0x005a => { Name => 'ColorTempFlash',        %colorTemp }, #28
+    0x005c => [{ #PH
+        Name => 'ShakeReductionInfo',
+        Condition => '$count == 4', # (2 bytes for the K-3)
+        Format => 'undef', # (written as int8u) - do this just to save time converting the value
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::SRInfo' },
+    },{
         Name => 'ShakeReductionInfo',
         Format => 'undef', # (written as int8u) - do this just to save time converting the value
-        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::SRInfo' },
-    },
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::SRInfo2' },
+    }],
     0x005d => { #JD/PH
         # (used by all Pentax DSLR's except *istD and *istDS until firmware 2.0 - PH)
@@ -1537,5 +2176,5 @@
         # of test images shot in the factory. (But my new K-5 started at 1 - PH)
         # This count includes shutter actuations even if they don't result in a
-        # recorded image (ie. manual white balance frame or digital preview), but
+        # recorded image (eg. manual white balance frame or digital preview), but
         # does not include actuations due to Live View or video recording - PH
         Name => 'ShutterCount',
@@ -1555,4 +2194,5 @@
         ValueConvInv => '$val',
     },
+    # 0x005e -
     0x0060 => { #PH (K-5)
         Name => 'FaceInfo',
@@ -1560,5 +2200,29 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Pentax::FaceInfo' },
     },
-    # 0x0062 - int16u: 1 (K10D,K200D,K-m,K2000), 3 (K20D), 4 (K-7), 5 (K-x), 6 (645D), 7 (K-r), 8 (K-5)
+    0x0062 => { #forum4803
+        Name => 'RawDevelopmentProcess',
+        Condition => '$$self{Make} =~ /^(PENTAX|RICOH)/', # rules out Kodak, which also use this tag
+        Writable => 'int16u',
+        PrintConv => {
+            1 => '1 (K10D,K200D,K2000,K-m)',
+            3 => '3 (K20D)',
+            4 => '4 (K-7)',
+            5 => '5 (K-x)',
+            6 => '6 (645D)',
+            7 => '7 (K-r)',
+            8 => '8 (K-5,K-5II,K-5IIs)',
+            9 => '9 (Q)',
+            10 => '10 (K-01,K-30,K-50,K-500)',
+            11 => '11 (Q10)',
+            12 => '12 (MX-1,Q-S1,Q7)',
+            13 => '13 (K-3,K-3II)',
+            14 => '14 (645Z)',
+            15 => '15 (K-S1,K-S2)', #PH
+            16 => '16 (K-1)', #PH
+            17 => '17 (K-70)', #29
+            18 => '18 (KP)', #PH
+            19 => '19 (GR III)', #PH
+        },
+    },
     0x0067 => { #PH (K-5)
         Name => 'Hue',
@@ -1584,13 +2248,21 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Pentax::AWBInfo' },
     },
-    0x0069 => { #PH (K20D; K-5 highlights only)
+    0x0069 => { #PH (K20D, K-5, K-01 highlights only)
         Name => 'DynamicRangeExpansion',
+        Notes => q{
+            called highlight correction by Pentax for the K20D, K-5, K-01 and maybe
+            other models
+        },
         Writable => 'undef',
         Format => 'int8u',
         Count => 4,
-        PrintConv => {
-            '0 0 0 0' => 'Off',
-            '1 0 0 0' => 'On',
-        },
+        PrintConv => [{
+            0 => 'Off',
+            1 => 'On',
+        },{
+            0 => 0,
+            1 => 'Enabled', # (K-01)
+            2 => 'Auto', # (K-01)
+        }],
     },
     0x006b => { #PH (K-5)
@@ -1739,4 +2411,5 @@
         DataMember => 'FacesDetected',
         RawConv => '$val =~ / (\d+)/ and $$self{FacesDetected} = $1; $val',
+        # (the K-3 reports "On" even in phase-detect focus modes)
         PrintConv => [
             '$val ? "On ($val faces max)" : "Off"',
@@ -1757,5 +2430,5 @@
     # 0x0078 - int16u[2]: '0 0' (K-5,K-7,K-r,K-x)
     0x0079 => { #PH
-        Name => 'ShadowCompensation',
+        Name => 'ShadowCorrection',
         Writable => 'int8u',
         Count => -1,
@@ -1765,8 +2438,10 @@
             0 => 'Off',
             1 => 'On',
+            2 => 'Auto 2', # (NC, WG-3)
             '0 0' => 'Off',
             '1 1' => 'Weak',
             '1 2' => 'Normal',
             '1 3' => 'Strong',
+            '2 4' => 'Auto', # (K-01)
         },
     },
@@ -1779,4 +2454,5 @@
             '2 0' => 'Standard',
             '3 0' => 'Fast',
+            # '1 108' - seen for GR III
         },
     },
@@ -1801,5 +2477,10 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensCorr' },
     },
-    # 0x007e - int32u: 15859,15860,15864,15865,16315 (K-5 PEF/DNG only) - PH
+    0x007e => { #IB
+        Name => 'WhiteLevel', # (with black level already subtracted)
+        Writable => 'int32u',
+        # 15859,15860,15864,15865,16315 (K-5 PEF/DNG only) - PH
+        # 3934, 3935 (Q DNG) - PH
+    },
     0x007f => { #PH (K-5)
         Name => 'BleachBypassToning',
@@ -1807,5 +2488,6 @@
         PrintConvColumns => 2,
         PrintConv => {
-            65535 => 'Off',
+            65535 => 'n/a', #31
+            0 => 'Off', #31
             1 => 'Green',
             2 => 'Yellow',
@@ -1818,4 +2500,131 @@
         },
     },
+    0x0080 => { #PH (Q)
+        Name => 'AspectRatio',
+        PrintConv => {
+            0 => '4:3',
+            1 => '3:2',
+            2 => '16:9',
+            3 => '1:1',
+        },
+    },
+    # 0x0081 - int8u: 0 (Q)
+    0x0082 => {
+        Name => 'BlurControl',
+        Writable => 'int8u',
+        Count => 4,
+        PrintConv => [
+            {
+                0 => 'Off',
+                1 => 'Low',
+                2 => 'Medium',
+                3 => 'High',
+            },
+            undef, # 0 with BlurControl is Off, seen 0,1,3 when on (related to subject distance?)
+            undef, # 0 with BlurControl Off, 45 when on
+            undef, # always 0
+        ],
+    },
+    # 0x0083 - int8u: 0 (Q DNG)
+    # 0x0084 - int8u: 0 (Q)
+    0x0085 => { #PH
+        Name => 'HDR',
+        Format => 'int8u',
+        Count => 4,
+        PrintConv => [{ # (K-01,K-3)
+            0 => 'Off',
+            1 => 'HDR Auto',
+            2 => 'HDR 1',
+            3 => 'HDR 2',
+            4 => 'HDR 3',
+            5 => 'HDR Advanced', #29 (K-1)
+        },{ # (K-01)
+            0 => 'Auto-align Off',
+            1 => 'Auto-align On',
+        },{
+            # not sure about this - PH
+            # - you can set HDR "Exposure Bracket Value" with the K-3
+            # - guessed from imaging-resource K-3 samples K3OUTBHDR_A{1,2,3}
+            0 => 'n/a',
+            4 => '1 EV',
+            8 => '2 EV',
+            12 => '3 EV', # (get this from K-01, but can't set EV)
+        },
+        # (4th number is always 0)
+        ],
+    },
+    # 0x0086 - int8u: 0, 111[Sport,Pet] (Q) - related to Tracking FocusMode?
+    # 0x0087 - int8u: 0 (Q)
+    0x0087 => { #PH
+        Name => 'ShutterType',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Normal', # ('Mechanical' if the camera has a mechanical shutter)
+            1 => 'Electronic', # (KP)
+        },
+    },
+    0x0088 => { #PH
+        Name => 'NeutralDensityFilter',
+        Writable => 'int8u',
+        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',
+        Priority => 0,
+        Writable => 'int32u',
+    },
+    0x0092 => { #31
+        Name => 'IntervalShooting',
+        Notes => '2 numbers: 1. Shot number 2. Total number of shots',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'Off',
+            OTHER => sub {
+                my ($val, $inv) = @_;
+                if ($inv) {
+                    $val =~ tr/0-9 //dc;
+                } else {
+                    $val =~ s/(\d+) (\d+)/Shot $1 of $2/;
+                }
+                return $val;
+            },
+        },
+    },
+    0x0095 => { #31
+        Name => 'SkinToneCorrection',
+        Writable => 'int8s',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'Off',
+            '1 1' => 'On (type 1)',
+            '1 2' => 'On (type 2)',
+        },
+    },
+    0x0096 => { #31
+        Name => 'ClarityControl',
+        Writable => 'int8s',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'Off',
+            OTHER => sub {
+                my ($val, $inv) = @_;
+                if ($inv) {
+                    $val =~ /(\d+ -?\d+)/ and return $1;
+                    return ("1 $val");
+                } elsif ($val =~ /^1 (-?\d+)$/) {
+                    return $1 ? sprintf('%+d', $1) : 0;
+                } else {
+                    return "Unknown ($val)";
+                }
+            },
+        },
+    },
     0x0200 => { #5
         Name => 'BlackPoint',
@@ -1834,5 +2643,5 @@
     # 0x0202: int16u[4]: all 0's in all my samples
     0x0203 => { #JD (not really sure what these mean)
-        Name => 'ColorMatrixA',
+        Name => 'ColorMatrixA', # (camera RGB to sRGB matrix, *ist D, ref IB)
         Writable => 'int16s',
         Count => 9,
@@ -1843,5 +2652,5 @@
     },
     0x0204 => { #JD
-        Name => 'ColorMatrixB',
+        Name => 'ColorMatrixB', # (camera RGB to Adobe RGB matrix, *ist D, ref IB)
         Writable => 'int16s',
         Count => 9,
@@ -1851,15 +2660,41 @@
         PrintConvInv => '"$val"',
     },
-    0x0205 => { #19
+    0x0205 => [{ #19
         Name => 'CameraSettings',
+        # size: *istD/*istDs/K100D/K110D=16, K-m/K2000=14, K-7/K-x=19,
+        #       K200D/K20D/K-5/645D=20, K-r=21, K10D=22, K-01=25
+        Condition => '$count < 25', # (not valid for the K-01)
         SubDirectory => {
             TagTable => 'Image::ExifTool::Pentax::CameraSettings',
             ByteOrder => 'BigEndian',
         },
-    },
-    0x0206 => { #PH
+    },{
+        Name => 'CameraSettingsUnknown',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::CameraSettingsUnknown',
+            ByteOrder => 'BigEndian',
+        },
+    }],
+    0x0206 => [{ #PH
         Name => 'AEInfo',
+        # size: *istD/*istDs/K100D/K110D=14, K10D/K200D/K20D=16, K-m/K2000=20,
+        #        K-7/K-x=24, K-5/K-r/645D=25
+        Condition => '$count <= 25 and $count != 21 and $$self{AEInfoSize} = $count',
         SubDirectory => { TagTable => 'Image::ExifTool::Pentax::AEInfo' },
-    },
+    },{
+        Name => 'AEInfo2',
+        # size: K-01=21
+        Condition => '$count == 21',
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::AEInfo2' },
+    },{
+        Name => 'AEInfo3',
+        # size: K-30=48
+        Condition => '$count == 48',
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::AEInfo3' },
+    },{
+        Name => 'AEInfoUnknown',
+        # size: Q/Q10=34
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::AEInfoUnknown' },
+    }],
     0x0207 => [ #PH
         {
@@ -1876,14 +2711,20 @@
         },{
             Name => 'LensInfo',
-            Condition => '$count < 90',
+            Condition => '$count != 90 and $count != 91 and $count != 80 and $count != 128 and $count != 168',
             SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo2' },
         },{
-            Name => 'LensInfo',
+            Name => 'LensInfo', # 645D
             Condition => '$count == 90',
             SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo3' },
         },{
-            Name => 'LensInfo',
+            Name => 'LensInfo', # K-r, K-5, K-5II
+            Condition => '$count == 91',
             SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo4' },
+        },{
+            Name => 'LensInfo', # K-01, K-30, K-50, K-500, K-3, K-3II
+            Condition => '$count == 80 or $count == 128',
+            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfo5' },
         }
+        # ($count == 168 - Ricoh GR III)
     ],
     0x0208 => [ #PH
@@ -1904,9 +2745,10 @@
         Notes => q{
             measurements from each of the 16 AE metering segments for models such as the
-            K10D, and 77 metering segments for models such as the K-5, converted to LV
+            K10D, 77 metering segments for models such as the K-5, and 4050 metering
+            segments for the K-3, converted to LV
         },
         %convertMeteringSegments,
-        #    16 metering segment             77 metering segment
-        #    locations (ref JD)              locations (ref PH, K-5)
+        #  16 metering segment              77 metering segment
+        #  locations (ref JD, K10D)         locations (ref PH, K-5)
         # +-------------------------+
         # |           14            | +----------------------------------+
@@ -1986,5 +2828,5 @@
         },
     },
-    # 0x021a - undef[1068] (K-5)
+    # 0x021a - undef[1068] (K-5) - ToneMode/Saturation mapping matrices (ref 28)
     0x021b => { #19
         Name => 'SaturationInfo',
@@ -2003,5 +2845,5 @@
     # 0x021c - undef[18] (K-5)
     # 0x021d - undef[18] (K-5)
-    # 0x021e - undef[8] (K-5)
+    # 0x021e - undef[8] (K-5, Q)
     0x021f => { #JD
         Name => 'AFInfo',
@@ -2019,7 +2861,10 @@
         Flags => [ 'Unknown', 'Binary' ],
         Writable => 0,
-        Notes => 'found in K10D, K20D and K2000D PEF images',
-    },
-    # 0x0221 - undef[138] (K-5)
+        Notes => 'found in K10D, K20D and K2000 PEF images',
+    },
+    0x0221 => { #28
+        Name => 'KelvinWB',
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::KelvinWB' },
+    },
     0x0222 => { #PH
         Name => 'ColorInfo',
@@ -2029,4 +2874,5 @@
     0x0224 => { #19
         Name => 'EVStepInfo',
+        Drop => 200, # drop if larger than 200 bytes (40 kB in Pentax Q and Q10)
         SubDirectory => { TagTable => 'Image::ExifTool::Pentax::EVStepInfo' },
     },
@@ -2050,5 +2896,12 @@
         Notes => 'left blank by some cameras',
     },
-    0x022a => { #PH (K-5)
+    0x022a => [{ #PH (RICOH models (GR III))
+        Name => 'FilterInfo',
+        Condition => '$$self{Make} =~ /^RICOH/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::FilterInfo',
+            ByteOrder => 'LittleEndian',
+        },
+    },{ #PH (K-5)
         Name => 'FilterInfo',
         SubDirectory => {
@@ -2056,5 +2909,5 @@
             ByteOrder => 'BigEndian',
         },
-    },
+    }],
     0x022b => { #PH (K-5)
         Name => 'LevelInfo',
@@ -2062,5 +2915,9 @@
     },
     # 0x022c - undef[46] (K-5)
-    # 0x022d - undef[100] (K-5)
+    0x022d => { #28
+        Name => 'WBLevels',
+        Condition => '$count == 100', # (just to be safe, but no other counts observed)
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::WBLevels' },
+    },
     0x022e => { #PH (K-5 AVI videos)
         Name => 'Artist',
@@ -2073,8 +2930,8 @@
         Writable => 'string',
     },
-    0x0230 => { #PH (K-x AVI videos)
+    0x0230 => { #PH (K-x AVI videos) (and K-70/Q-S1 MOV videos, ref 31)
         Name => 'FirmwareVersion',
-        Notes => 'only in AVI videos',
-        # this tag only exists in AVI videos, and for the K-x the value of
+        Notes => 'only in videos',
+        # this tag only exists in AVI/MOV videos, and for the K-x the value of
         # this tag is "K-x Ver 1.00", which is the same as the EXIF Software
         # tag.  I used a different tag name for this because Pentax uses the
@@ -2098,4 +2955,28 @@
         Count => 10,
     },
+    # 0x0236 - undef[52] (Q)
+    # 0x0237 - undef[11] possibly related to smart effect setting? (Q)
+    # 0x0238 - undef[9] (Q)
+    0x0239 => { #PH
+        Name => 'LensInfoQ',
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensInfoQ' },
+    },
+    # 0x023a - undef[10] (Q)
+    # 0x023b - undef[9] (K-01)
+    #  01a700500000000000, 91a700500000000000, 41a700500000000000, 002700500000000000
+    #  c00500400000000000, 400500500000000000, 4004ff420100000000, 4087ff480000000000
+    0x023f => { #31 (K-70 MOV videos)
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Writable => 'string',
+    },
+    0x0243 => { #PH
+        Name => 'PixelShiftInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::PixelShiftInfo' },
+    },
+    0x0245 => { #29
+        Name => 'AFPointInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::AFPointInfo' },
+    },
     0x03fe => { #PH
         Name => 'DataDump',
@@ -2105,7 +2986,7 @@
     0x03ff => [ #PH
         {
-            Name => 'TempInfoK5',
-            Condition => '$$self{Model} =~ /K-5\b/',
-            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::TempInfoK5' },
+            Name => 'TempInfo',
+            Condition => '$$self{Model} =~ /K-(01|3|30|5|50|500)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::TempInfo' },
         },{
             Name => 'UnknownInfo',
@@ -2122,6 +3003,13 @@
     },
     # 0x0404 - undef[2086] (K-5)
-    # 0x0405 - undef[24200] (K-5 PEF/DNG only)
+    0x0405 => { #PH - undef[24200] (K-5 PEF/DNG only), undef[28672] (Q DNG)
+        Name => 'UnknownBlock',
+        Writable => 'undef',
+        Notes => 'large unknown data block in PEF/DNG images but not JPG images',
+        Flags => [ 'Unknown', 'Binary', 'Drop' ],
+    },
     # 0x0406 - undef[4116] (K-5)
+    # 0x0407 - undef[3072] (Q DNG)
+    # 0x0408 - undef[1024] (Q DNG)
     0x0e00 => {
         Name => 'PrintIM',
@@ -2157,9 +3045,13 @@
             1 => 'On',
             4 => 'Off (4)', # (K20D, K200D, K-7, K-5)
-            5 => 'On (5)', #(guess) (K20D)
-            # (got 5 for K-5 with HDR [auto-align off only], Composition Adjust, and movie with SR off!)
+            5 => 'On but Disabled', # (K20D, K-5)
+            # (can be 5 "On but Disabled" for K-5 with HDR [auto-align off only],
+            # Composition Adjust, DriveMode = Self-timer or Remote, and movie with SR off!)
             6 => 'On (Video)', # (K-7)
             7 => 'On (7)', #(NC) (K20D, K200D, K-m, K-5)
-            15 => 'On (15)', # (K20D (with Tamron 10-20mm @ 10mm))
+            15 => 'On (15)', # (K20D with Tamron 10-20mm @ 10mm)
+            39 => 'On (mode 2)', # (K-01) (on during capture and live view)
+            135 => 'On (135)', # (K-5IIs)
+            167 => 'On (mode 1)', # (K-01) (on during capture only)
         },
     },
@@ -2169,7 +3061,8 @@
         # (from http://www.patentstorm.us/patents/6597867-description.html)
         # (here, SR could more accurately mean Shutter Release, not Shake Reduction)
+        # (not valid for K-01 - PH)
         Notes => q{
             time from when the shutter button was half pressed to when the shutter was
-            released, including time for focusing
+            released, including time for focusing.  Not valid for some models
         },
         # (constant of 60 determined from times: 2sec=127; 3sec=184,197; 4sec=244,249,243,246 - PH)
@@ -2185,4 +3078,37 @@
         PrintConv => '"$val mm"',
         PrintConvInv => '$val=~s/\s*mm//;$val',
+    },
+);
+
+# shake reduction information for the K-3 (ref PH)
+%Image::ExifTool::Pentax::SRInfo2 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Shake reduction information for the K-3.',
+    0 => {
+        Name => 'SRResult',
+        Unknown => 1,
+        PrintConv => { BITMASK => {
+            # Bit 0 - have seen this set in a few Pentax samples - PH
+            # Bit 6 - usually set when SR is Off, and occasionally when On - PH
+            # Bit 7 - set when AA simulation is on - PH
+        }},
+    },
+    1 => {
+        Name => 'ShakeReduction',
+        PrintConv => { #forum5425
+            0 => 'Off', # (NC for K-3)
+            1 => 'On', # (NC for K-3)
+            4 => 'Off (AA simulation off)',
+            5 => 'On but Disabled', # (NC for K-3)
+            6 => 'On (Video)', # (NC for K-3)
+            7 => 'On (AA simulation off)',
+            8 => 'Off (AA simulation type 1) (8)', #forum8362 (K-70)
+            12 => 'Off (AA simulation type 1)', # (AA linear motion)
+            15 => 'On (AA simulation type 1)', # (AA linear motion)
+            16 => 'Off (AA simulation type 2) (16)', #forum8362 (K-70)
+            20 => 'Off (AA simulation type 2)', # (AA circular motion)
+            23 => 'On (AA simulation type 2)', # (AA circular motion)
+        },
     },
 );
@@ -2237,6 +3163,6 @@
         Mask => 0x01,
         PrintConv => {
-            0x00 => 'Hometown',
-            0x01 => 'Destination',
+            0 => 'Hometown',
+            1 => 'Destination',
         },
     },
@@ -2244,16 +3170,10 @@
         Name => 'HometownDST',
         Mask => 0x02,
-        PrintConv => {
-            0x00 => 'No',
-            0x02 => 'Yes',
-        },
+        PrintConv => \%noYes,
     },
     0.3 => {
         Name => 'DestinationDST',
         Mask => 0x04,
-        PrintConv => {
-            0x00 => 'No',
-            0x04 => 'Yes',
-        },
+        PrintConv => \%noYes,
     },
     2 => {
@@ -2281,4 +3201,12 @@
         PrintConv => { 0 => 'Off', 1 => 'On' },
     },
+    2 => {
+        Name => 'PeripheralIlluminationCorr',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    3 => {
+        Name => 'DiffractionCorrection',
+        PrintConv => { 0 => 'Off', 16 => 'On' },
+    },
 );
 
@@ -2288,5 +3216,5 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     PRIORITY => 0,
-    NOTES => 'Shot information written by Pentax DSLR cameras.',
+    NOTES => 'Camera settings information written by Pentax DSLR cameras.',
     0 => {
         Name => 'PictureMode2',
@@ -2325,6 +3253,6 @@
         Mask => 0x20,
         PrintConv => {
-            0x00 => '1/2 EV Steps',
-            0x20 => '1/3 EV Steps',
+            0 => '1/2 EV Steps',
+            1 => '1/3 EV Steps',
         },
     },
@@ -2334,6 +3262,6 @@
         Mask => 0x40,
         PrintConv => {
-            0x00 => 'Tv or Av',
-            0x40 => 'P Shift',
+            0 => 'Tv or Av',
+            1 => 'P Shift',
         },
     },
@@ -2343,6 +3271,6 @@
         Mask => 0x80,
         PrintConv => {
-            0x00 => 'Prohibited',
-            0x80 => 'Permitted',
+            0 => 'Prohibited',
+            1 => 'Permitted',
         },
     },
@@ -2351,6 +3279,4 @@
         Notes => 'the camera flash options settings, set even if the flash is off',
         Mask => 0xf0,
-        ValueConv => '$val>>4',
-        ValueConvInv => '$val<<4',
         # Note: These tags correlate with the FlashMode and InternalFlashMode values,
         # and match what is displayed by the Pentax software
@@ -2370,5 +3296,5 @@
         Name => 'MeteringMode2',
         Mask => 0x0f,
-        Notes => 'may not be valid for some models, ie. *ist D',
+        Notes => 'may not be valid for some models, eg. *ist D',
         PrintConv => {
             0 => 'Multi-segment',
@@ -2383,9 +3309,9 @@
         Mask => 0xf0,
         PrintConv => {
-            0x00 => 'Auto',
+            0 => 'Auto',
             BITMASK => {
-                4 => 'Select',
-                5 => 'Fixed Center',
-                # have seen bit 6 set in pre-production images (firmware 0.20) - PH
+                0 => 'Select',
+                1 => 'Fixed Center',
+                # have seen bit 2 set in pre-production images (firmware 0.20) - PH
             },
         },
@@ -2446,5 +3372,5 @@
         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.
@@ -2485,18 +3411,18 @@
         PrintConv => {
             0 => 'Auto',
-            16 => 'Daylight',
-            32 => 'Shade',
-            48 => 'Cloudy',
-            64 => 'Daylight Fluorescent',
-            80 => 'Day White Fluorescent',
-            96 => 'White Fluorescent',
-            112 => 'Tungsten',
-            128 => 'Flash',
-            144 => 'Manual',
+            1 => 'Daylight',
+            2 => 'Shade',
+            3 => 'Cloudy',
+            4 => 'Daylight Fluorescent',
+            5 => 'Day White Fluorescent',
+            6 => 'White Fluorescent',
+            7 => 'Tungsten',
+            8 => 'Flash',
+            9 => 'Manual',
             # The three Set Color Temperature settings refer to the 3 preset settings which
             # can be saved in the menu (see page 123 of the K10D manual)
-            192 => 'Set Color Temperature 1',
-            208 => 'Set Color Temperature 2',
-            224 => 'Set Color Temperature 3',
+            12 => 'Set Color Temperature 1',
+            13 => 'Set Color Temperature 2',
+            14 => 'Set Color Temperature 3',
         },
     },
@@ -2551,8 +3477,5 @@
         Notes => 'K-5 only',
         Mask => 0x01,
-        PrintConv => {
-            0x00 => 'Off',
-            0x01 => 'On',
-        },
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     14.3 => { #PH (K-5)
@@ -2562,6 +3485,6 @@
         Mask => 0x02,
         PrintConv => {
-            0x00 => '1 EV Steps',
-            0x02 => 'As EV Steps',
+            0 => '1 EV Steps',
+            1 => 'As EV Steps',
         },
     },
@@ -2571,8 +3494,5 @@
         Notes => 'K-5 only',
         Mask => 0x04,
-        PrintConv => {
-            0x00 => 'Off',
-            0x04 => 'On',
-        },
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     # 14.5 Mask 0x80 - changes for K-5
@@ -2589,13 +3509,13 @@
         # (these tags relate closely to InternalFlashMode values - PH)
         PrintConv => {
-            0x00 => 'Normal', # (this value never occurs in Green Mode) - ref 19
-            0x10 => 'Red-eye reduction', # (this value never occurs in Green Mode) - ref 19
-            0x20 => 'Auto',  # (this value only occurs in Green Mode) - ref 19
-            0x30 => 'Auto, Red-eye reduction', # (this value only occurs in Green Mode) - ref 19
-            0x50 => 'Wireless (Master)',
-            0x60 => 'Wireless (Control)',
-            0x80 => 'Slow-sync',
-            0x90 => 'Slow-sync, Red-eye reduction',
-            0xa0 => 'Trailing-curtain Sync'
+            0 => 'Normal', # (this value never occurs in Green Mode) - ref 19
+            1 => 'Red-eye reduction', # (this value never occurs in Green Mode) - ref 19
+            2 => 'Auto',  # (this value only occurs in Green Mode) - ref 19
+            3 => 'Auto, Red-eye reduction', # (this value only occurs in Green Mode) - ref 19
+            5 => 'Wireless (Master)',
+            6 => 'Wireless (Control)',
+            8 => 'Slow-sync',
+            9 => 'Slow-sync, Red-eye reduction',
+            10 => 'Trailing-curtain Sync'
         },
     },
@@ -2622,8 +3542,5 @@
         },
         Mask => 0x80,
-        PrintConv => {
-            0x00 => 'No',
-            0x80 => 'Yes',
-        },
+        PrintConv => \%noYes,
     },
     17.2 => {
@@ -2633,8 +3550,8 @@
         Mask => 0x60,
         PrintConv => {
-            0x00 => 'Horizontal (normal)',
-            0x20 => 'Rotate 180',
-            0x40 => 'Rotate 90 CW',
-            0x60 => 'Rotate 270 CW',
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 180',
+            2 => 'Rotate 90 CW',
+            3 => 'Rotate 270 CW',
         },
     },
@@ -2647,6 +3564,6 @@
         Mask => 0x04,
         PrintConv => {
-            0x00 => 'Manual',
-            0x04 => 'Auto',
+            0 => 'Manual',
+            1 => 'Auto',
         },
     },
@@ -2657,6 +3574,6 @@
         Mask => 0x02,
         PrintConv => {
-            0x00 => '1 EV Steps',
-            0x02 => 'As EV Steps',
+            0 => '1 EV Steps',
+            1 => 'As EV Steps',
         },
     },
@@ -2704,10 +3621,18 @@
 );
 
+# unknown camera settings (K-01)
+%Image::ExifTool::Pentax::CameraSettingsUnknown = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'This information has not yet been decoded for models such as the K-01.',
+);
+
 # auto-exposure information (ref PH)
 %Image::ExifTool::Pentax::AEInfo = (
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    DATAMEMBER => [ 8 ],
-    # instead of /8, should these be PentaxEV(), as in CameraSettings? - PH
+    DATAMEMBER => [ 7 ],
+    NOTES => 'Auto-exposure information for most Pentax models.',
+    # instead of /8, should these be PentaxEv(), as in CameraSettings? - PH
     0 => {
         Name => 'AEExposureTime',
@@ -2777,18 +3702,30 @@
             83 => 'No Flash',
             91 => 'Night Scene',
+            # 96 - seen for Pentax Q10
             99 => 'Surf & Snow',
+            104 => 'Night Snap', # (Q)
             107 => 'Text',
             115 => 'Sunset',
+            # 116 - seen for Pentax Q (vivid?)
             123 => 'Kids',
             131 => 'Pet',
             139 => 'Candlelight',
+            144 => 'SCN', # (Q)
+            160 => 'Program', # (Q)
+            # 142 - seen for Pentax Q in Program mode
             147 => 'Museum',
             184 => 'Shallow DOF Program', # (K-5)
+            216 => 'HDR', # (Q)
         },
     },
     7 => {
         Name => 'AEFlags',
-        Unknown => 1,
         Writable => 0,
+        Hook => '$size > 20 and $varSize += 1',
+        Notes => 'indices after this are incremented by 1 for some models',
+        # (this tag can't be unknown because the Hook must be evaluated
+        #  to shift the following offsets if necessary.  Instead, ignore
+        #  the return value unless Unknown option used)
+        RawConv => '$$self{OPTIONS}{Unknown} ? $val : undef',
         PrintConv => { #19
             # (seems to be the warnings displayed in the viewfinder for several bits)
@@ -2808,16 +3745,16 @@
         },
     },
-    8 => {
-        Name => 'AEUnknown',
-        Notes => 'indices after this are incremented by 1 for some models',
-        Format => 'var_int8u[$size > 20 ? 2 : 1]',
-        Writable => 0,
-        # (this tag can't be unknown because the Format must be evaluated
-        #  to shift the following offsets if necessary.  Instead, ignore
-        #  the return value unless Unknown > 1)
-        RawConv => '$$self{OPTIONS}{Unknown} > 1 ? $val : undef',
-    },
     # Note: Offsets below shifted by 1 if record size is > 20 bytes
-    # (implemented by the var_int8u count above)
+    # (implemented by the Hook above)
+    8 => { #30
+        Name => 'AEApertureSteps',
+        Notes => q{
+            number of steps the aperture has been stopped down from wide open.  There
+            are roughly 8 steps per F-stop for most lenses, or 18 steps for 645D lenses,
+            but it varies slightly by lens
+        },
+        PrintConv => '$val == 255 ? "n/a" : $val',
+        PrintConvInv => '$val eq "n/a" ? 255 : $val',
+    },
     9 => { #19
         Name => 'AEMaxAperture',
@@ -2854,7 +3791,38 @@
         },
     },
-    # 13 - related to program mode somehow - PH
+    13 => { #30
+        Name => 'AEWhiteBalance',
+        Condition => '$$self{AEInfoSize} == 24', # (not thoroughly tested for other sizes)
+        Notes => 'K7 and Kx',
+        Mask => 0xf0,
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Daylight',
+            2 => 'Shade',
+            3 => 'Cloudy',
+            4 => 'Daylight Fluorescent',
+            5 => 'Day White Fluorescent',
+            6 => 'White Fluorescent',
+            7 => 'Tungsten',
+            8 => 'Unknown', #31 (or not set due to inadequate lighting)
+        },
+    },
+    13.1 => { #30
+        Name => 'AEMeteringMode2',
+        Condition => '$$self{AEInfoSize} == 24', # (not thoroughly tested for other sizes)
+        Notes => 'K7 and Kx, override for an incompatible metering mode setting',
+        Mask => 0x0f,
+        PrintConv => {
+            0 => 'Multi-segment',
+            BITMASK => {
+                0 => 'Center-weighted average',
+                1 => 'Spot',
+                # 2 - seen for K7 AVI movie
+            },
+        },
+    },
     14 => { #19
         Name => 'FlashExposureCompSet',
+        Description => 'Flash Exposure Comp. Setting',
         Format => 'int8s',
         Notes => q{
@@ -2868,4 +3836,229 @@
         PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     },
+    21 => { #30
+        Name => 'LevelIndicator',
+        PrintConv => '$val == 90 ? "n/a" : $val',
+        PrintConvInv => '$val eq "n/a" ? 90 : $val',
+    },
+);
+
+# auto-exposure information for the K-01 (ref PH)
+%Image::ExifTool::Pentax::AEInfo2 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Auto-exposure information for the K-01.',
+    # instead of /8, should these be PentaxEv(), as in CameraSettings? - PH
+    2 => {
+        Name => 'AEExposureTime',
+        Notes => 'val = 24 * 2**((32-raw)/8)',
+        ValueConv => '24*exp(-($val-32)*log(2)/8)',
+        ValueConvInv => '-log($val/24)*8/log(2)+32',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    3 => {
+        Name => 'AEAperture',
+        Notes => 'val = 2**((raw-68)/16)',
+        ValueConv => 'exp(($val-68)*log(2)/16)',
+        ValueConvInv => 'log($val)*16/log(2)+68',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    4 => {
+        Name => 'AE_ISO',
+        Notes => 'val = 100 * 2**((raw-32)/8)',
+        ValueConv => '100*exp(($val-32)*log(2)/8)',
+        ValueConvInv => 'log($val/100)*8/log(2)+32',
+        PrintConv => 'int($val + 0.5)',
+        PrintConvInv => '$val',
+    },
+    5 => {
+        Name => 'AEXv',
+        # this is the negative of exposure compensation, not including bracketing
+        Notes => 'val = (raw-64)/8',
+        ValueConv => '($val-64)/8',
+        ValueConvInv => '$val * 8 + 64',
+    },
+    6 => {
+        Name => 'AEBXv',
+        # this is the negative of auto exposure bracketing compensation
+        Format => 'int8s',
+        Notes => 'val = raw / 8',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+    },
+    8 => {
+        Name => 'AEError',
+        Format => 'int8s',
+        # this is usually zero except in M exposure mode, but it can be non-zero
+        # in other modes (eg. if you hit an aperture limit in Tv mode)
+        ValueConv => '-($val-64)/8', # (negate to make overexposed positive)
+        ValueConvInv => '-$val * 8 + 64',
+    },
+    11 => {
+        Name => 'AEApertureSteps',
+        Notes => q{
+            number of steps the aperture has been stopped down from wide open.  There
+            are roughly 8 steps per F-stop, but it varies slightly by lens
+        },
+        PrintConv => '$val == 255 ? "n/a" : $val',
+        PrintConvInv => '$val eq "n/a" ? 255 : $val',
+    },
+    15 => {
+        Name => 'SceneMode',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'HDR',
+            4 => 'Auto PICT',
+            5 => 'Portrait',
+            6 => 'Landscape',
+            7 => 'Macro',
+            8 => 'Sport',
+            9 => 'Night Scene Portrait',
+            10 => 'No Flash',
+            11 => 'Night Scene',
+            12 => 'Surf & Snow',
+            14 => 'Sunset',
+            15 => 'Kids',
+            16 => 'Pet',
+            17 => 'Candlelight',
+            18 => 'Museum',
+            20 => 'Food',
+            21 => 'Stage Lighting',
+            22 => 'Night Snap',
+            25 => 'Night Scene HDR',
+            26 => 'Blue Sky',
+            27 => 'Forest',
+            29 => 'Backlight Silhouette',
+        },
+    },
+    16 => {
+        Name => 'AEMaxAperture',
+        Notes => 'val = 2**((raw-68)/16)',
+        ValueConv => 'exp(($val-68)*log(2)/16)',
+        ValueConvInv => 'log($val)*16/log(2)+68',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    17 => {
+        Name => 'AEMaxAperture2',
+        Notes => 'val = 2**((raw-68)/16)',
+        ValueConv => 'exp(($val-68)*log(2)/16)',
+        ValueConvInv => 'log($val)*16/log(2)+68',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    18 => {
+        Name => 'AEMinAperture',
+        Notes => 'val = 2**((raw-68)/16)',
+        ValueConv => 'exp(($val-68)*log(2)/16)',
+        ValueConvInv => 'log($val)*16/log(2)+68',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    19 => {
+        Name => 'AEMinExposureTime',
+        Notes => 'val = 24 * 2**((32-raw)/8)',
+        ValueConv => '24*exp(-($val-32)*log(2)/8)',
+        ValueConvInv => '-log($val/24)*8/log(2)+32',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+);
+
+# auto-exposure information for the K-30 (ref PH)
+%Image::ExifTool::Pentax::AEInfo3 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Auto-exposure information for the K-3, K-30, K-50 and K-500.',
+    # instead of /8, should these be PentaxEv(), as in CameraSettings? - PH
+    16 => {
+        Name => 'AEExposureTime',
+        Notes => 'val = 24 * 2**((32-raw)/8)',
+        ValueConv => '24*exp(-($val-32)*log(2)/8)',
+        ValueConvInv => '-log($val/24)*8/log(2)+32',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    17 => {
+        Name => 'AEAperture',
+        Notes => 'val = 2**((raw-68)/16)',
+        ValueConv => 'exp(($val-68)*log(2)/16)',
+        ValueConvInv => 'log($val)*16/log(2)+68',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    18 => {
+        Name => 'AE_ISO',
+        Notes => 'val = 100 * 2**((raw-32)/8)',
+        ValueConv => '100*exp(($val-32)*log(2)/8)',
+        ValueConvInv => 'log($val/100)*8/log(2)+32',
+        PrintConv => 'int($val + 0.5)',
+        PrintConvInv => '$val',
+    },
+    28 => {
+        Name => 'AEMaxAperture',
+        Notes => 'val = 2**((raw-68)/16)',
+        ValueConv => 'exp(($val-68)*log(2)/16)',
+        ValueConvInv => 'log($val)*16/log(2)+68',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    29 => {
+        Name => 'AEMaxAperture2',
+        Notes => 'val = 2**((raw-68)/16)',
+        ValueConv => 'exp(($val-68)*log(2)/16)',
+        ValueConvInv => 'log($val)*16/log(2)+68',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    30 => {
+        Name => 'AEMinAperture',
+        Notes => 'val = 2**((raw-68)/16)',
+        ValueConv => 'exp(($val-68)*log(2)/16)',
+        ValueConvInv => 'log($val)*16/log(2)+68',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    31 => {
+        Name => 'AEMinExposureTime',
+        Notes => 'val = 24 * 2**((32-raw)/8)',
+        ValueConv => '24*exp(-($val-32)*log(2)/8)',
+        ValueConvInv => '-log($val/24)*8/log(2)+32',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+);
+
+# unknown auto-exposure information (Q, Q10)
+%Image::ExifTool::Pentax::AEInfoUnknown = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+);
+
+# lens type
+%Image::ExifTool::Pentax::LensRec = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        This record stores the LensType, plus one or two unknown bytes for some
+        models.
+    },
+    0 => {
+        Name => 'LensType',
+        Format => 'int8u[2]',
+        Priority => 0,
+        ValueConvInv => '$val=~s/\.\d+$//; $val',
+        PrintConv => \%pentaxLensTypes,
+        SeparateTable => 1,
+    },
+    3 => { #PH
+        Name => 'ExtenderStatus',
+        Notes => 'not valid if a non-AF lens is used',
+        PrintConv => { 0 => 'Not attached', 1 => 'Attached' },
+    },
+    # this is a binaryData table because some cameras add an extra
+    # byte or two here (typically zeros)...
 );
 
@@ -2880,4 +4073,5 @@
         Format => 'int8u[2]',
         Priority => 0,
+        ValueConvInv => '$val=~s/\.\d+$//; $val',
         PrintConv => \%pentaxLensTypes,
         SeparateTable => 1,
@@ -2906,4 +4100,13 @@
             return "$v[0] $v[1]";
         },
+        # just fill in the missing bits/bytes with zeros...
+        ValueConvInv => q{
+            my @v = split(' ',$val);
+            return undef unless @v == 2;
+            $v[2] = ($v[1] >> 8) & 0xff;
+            $v[3] = $v[1] & 0xff;
+            $v[1] = 0;
+            return "@v";
+        },
         PrintConv => \%pentaxLensTypes,
         SeparateTable => 1,
@@ -2932,4 +4135,13 @@
             return "$v[0] $v[1]";
         },
+        # just fill in the missing bits/bytes with zeros...
+        ValueConvInv => q{
+            my @v = split(' ',$val);
+            return undef unless @v == 2;
+            $v[2] = ($v[1] >> 8) & 0xff;
+            $v[3] = $v[1] & 0xff;
+            $v[1] = 0;
+            return "@v";
+        },
         PrintConv => \%pentaxLensTypes,
         SeparateTable => 1,
@@ -2958,8 +4170,53 @@
             return "$v[0] $v[1]";
         },
+        # just fill in the missing bits/bytes with zeros...
+        ValueConvInv => q{
+            my @v = split(' ',$val);
+            return undef unless @v == 2;
+            $v[2] = ($v[1] >> 8) & 0xff;
+            $v[3] = $v[1] & 0xff;
+            $v[1] = 0;
+            return "@v";
+        },
         PrintConv => \%pentaxLensTypes,
         SeparateTable => 1,
     },
     12 => {
+        Name => 'LensData',
+        Format => 'undef[18]',
+        Condition => '$$self{NewLensData} = 1', # not really a condition, just used to set flag
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::LensData' },
+    },
+);
+
+# lens information for K-01, K-30, K-50, K-500, K-3, K-3II, K-S1 (ref PH)
+%Image::ExifTool::Pentax::LensInfo5 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    IS_SUBDIR => [ 15 ],
+    NOTES => 'Pentax lens information structure for the K-01 and newer models.',
+    1 => {
+        Name => 'LensType',
+        Format => 'int8u[5]',
+        Priority => 0,
+        ValueConv => q{
+            my @v = split(' ',$val);
+            $v[0] &= 0x0f;
+            $v[1] = $v[3] * 256 + $v[4]; # (always high byte first)
+            return "$v[0] $v[1]";
+        },
+        # just fill in the missing bits/bytes with zeros...
+        ValueConvInv => q{
+            my @v = split(' ',$val);
+            return undef unless @v == 2;
+            $v[3] = ($v[1] >> 8) & 0xff;
+            $v[4] = $v[1] & 0xff;
+            $v[1] = $v[2] = 0;
+            return "@v";
+        },
+        PrintConv => \%pentaxLensTypes,
+        SeparateTable => 1,
+    },
+    15 => {
         Name => 'LensData',
         Format => 'undef[17]',
@@ -2972,4 +4229,5 @@
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 12.1 ],
     NOTES => q{
         Pentax lens data information.  Some of these tags require interesting binary
@@ -2980,25 +4238,28 @@
     0.1 => { #JD
         Name => 'AutoAperture',
+        Condition => 'not $$self{NewLensData}',
+        Notes => 'not valid for the K-r, K-5 or K-5II', #29
         Mask => 0x01,
-        PrintConv => {
-            0 => 'On',
-            1 => 'Off',
-        },
+        PrintConv => { 0 => 'On', 1 => 'Off' },
     },
     0.2 => { #JD
         Name => 'MinAperture',
+        Condition => 'not $$self{NewLensData}',
+        Notes => 'not valid for the K-r, K-5 or K-5II', #29
         Mask => 0x06,
         PrintConv => {
-            0x00 => 22,
-            0x02 => 32,
-            0x04 => 45,
-            0x06 => 16,
+            0 => 22,
+            1 => 32,
+            2 => 45,
+            3 => 16,
         },
     },
     0.3 => { #JD
         Name => 'LensFStops',
+        Condition => 'not $$self{NewLensData}',
+        Notes => 'not valid for the K-r, K-5 or K-5II', #29
         Mask => 0x70,
-        ValueConv => '5 + (($val >> 4) ^ 0x07) / 2',
-        ValueConvInv => '((($val - 5) * 2) ^ 0x07) << 4',
+        ValueConv => '5 + ($val ^ 0x07) / 2',
+        ValueConvInv => '(($val - 5) * 2) ^ 0x07',
     },
     # 1-16 look like Lens Codes LC0-LC15, ref patent 5617173 and 5999753 [+notes by PH]
@@ -3011,21 +4272,54 @@
         %lensCode,
     },
-    3 => { # LC2 = distance data
-        Name => 'LC2',
-        %lensCode,
-        # FocusRange decoding needs more testing with various lenses - PH
-        TestName => 'FocusRange',
-        TestPrintConv => q{
-            my @v;
-            my $lsb = $val & 0x07;
-            my $msb = $val >> 3;
-            my $ls2 = $lsb ^ 0x07;
-            $ls2 ^= 0x01 if $ls2 & 0x02;
-            $ls2 ^= 0x03 if $ls2 & 0x04;
-            foreach ($ls2, $ls2+1) {
-                push(@v,'inf'), next if $_ > 7;
-                push @v, sprintf("%.2f m", 2 ** ($msb / 4) * 0.18 * ($_ + 4) / 16);
-            }
-            return join ' - ', @v;
+    # LC2 = distance data
+    3 => { #29
+        Name => 'MinFocusDistance',
+        Notes => 'minimum focus distance for the lens',
+        Mask => 0xf8,
+        PrintConv => {
+            0 => '0.13-0.19 m', # (plus K or M lenses)
+            1 => '0.20-0.24 m',
+            2 => '0.25-0.28 m',
+            3 => '0.28-0.30 m',
+            4 => '0.35-0.38 m',
+            5 => '0.40-0.45 m',
+            6 => '0.49-0.50 m', # (plus many Sigma lenses)
+            7 => '0.6 m',       #PH (NC)
+            8 => '0.7 m',       # (plus Sigma 55-200)
+            9 => '0.8-0.9 m',   #PH (NC) Tokina 28-70/2.6-2.8
+            10 => '1.0 m',      # (plus Sigma 70 macro)
+            11 => '1.1-1.2 m',
+            12 => '1.4-1.5 m',
+            13 => '1.5 m',      # Sigma 70-300/4-5.6 macro
+            14 => '2.0 m',
+            15 => '2.0-2.1 m',  #PH (NC)
+            16 => '2.1 m',      # Sigma 135-400 APO & DG: 2.0-2.2m
+            17 => '2.2-2.9 m',  #PH (NC)
+            18 => '3.0 m',      # Sigma 50-500 : 1.0-3.0m depending on the focal length
+                                 ## 50mm, 100mm => 1.0m
+                                 ## 200mm       => 1.1m
+                                 ## 300mm       => 1.5m
+                                 ## 400mm       => 2.2m
+                                 ## 500mm       => 3.0m
+            19 => '4-5 m',      #PH (NC)
+            20 => '5.6 m',      # Pentax DA 560
+            # To check: Sigma 120-400 OS: MFD 1.5m
+            # To check: Sigma 150-500 OS: MFD 2.2m
+            # To check: Sigma 50-500 has MFD 50-180cm
+            # 0xd0 - seen for the Sigma 4.5mm F2.8 EX DC HSM Circular Fisheye (ref PH)
+        },
+    },
+    3.1 => { #29
+        Name => 'FocusRangeIndex',
+        Mask => 0x07,
+        PrintConv => {
+            7 => '0 (very close)',
+            6 => '1 (close)',
+            4 => '2',
+            5 => '3',
+            1 => '4',
+            0 => '5',
+            2 => '6 (far)',
+            3 => '7 (very far)',
         },
     },
@@ -3034,13 +4328,13 @@
         %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,
@@ -3050,7 +4344,9 @@
         %lensCode,
     },
-    9 => { # LC8 = focal length data
-        Name => 'FocalLength',
+    9 => [{ # LC8 = focal length data
+        Name => 'LensFocalLength',
+        Notes => 'focal length of lens alone, without adapter', #PH
         Priority => 0,
+        Condition => '$$self{Model} !~ /645Z/', #PH (doesn't work for 645Z)
         ValueConv => '10*($val>>2) * 4**(($val&0x03)-2)', #JD
         ValueConvInv => q{
@@ -3061,11 +4357,14 @@
         PrintConv => 'sprintf("%.1f mm", $val)',
         PrintConvInv => '$val=~s/\s*mm//; $val',
-    },
+    },{
+        Name => 'LC8',
+        %lensCode,
+    }],
     # the following aperture values change with focal length
     10 => { # LC9 = nominal AVmin/AVmax data (open/closed aperture values)
         Name => 'NominalMaxAperture',
         Mask => 0xf0,
-        ValueConv => '2**(($val>>4)/4)', #JD
-        ValueConvInv => '4*log($val)/log(2) << 4',
+        ValueConv => '2**($val/4)', #JD
+        ValueConvInv => '4*log($val)/log(2)',
         PrintConv => 'sprintf("%.1f", $val)',
         PrintConvInv => '$val',
@@ -3087,10 +4386,19 @@
         %lensCode,
     },
+    12.1 => {
+        Name => 'NewLensDataHook',
+        Hidden => 1,
+        Hook => '$varSize += 1 if $$self{NewLensData}',
+        RawConv => 'undef',
+    },
     13 => { # LC12 = mv1 AVminsif data
         Name => 'LC12',
+        Notes => "ID's 13-16 are offset by 1 for the K-r, K-5 and K-5II", #29
         %lensCode,
     },
+    # 14 - related to live view for K-5 (normally 3, but 1 or 5 in LV mode)
     14.1 => { # LC13 = AVmin (open aperture value) [MaxAperture=(2**((AVmin-1)/32))]
         Name => 'MaxAperture',
+        Condition => '$$self{Model} ne "K-5"',
         Notes => 'effective wide open aperture for current focal length',
         Mask => 0x7f, # (not sure what the high bit indicates)
@@ -3307,4 +4615,5 @@
         # 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',
@@ -3315,24 +4624,24 @@
         {
             Name => 'BodyBatteryState',
-            Condition => '$$self{Model} =~ /(\*ist|K100D|K200D|K10D|GX10|K20D|GX20)\b/',
+            Condition => '$$self{Model} =~ /(\*ist|K100D|K200D|K10D|GX10|K20D|GX20|GX-1[LS]?)\b/',
             Notes => '*istD, K100D, K200D, K10D and K20D',
             Mask => 0xf0,
             PrintConv => { #19
-                 0x10 => 'Empty or Missing',
-                 0x20 => 'Almost Empty',
-                 0x30 => 'Running Low',
-                 0x40 => 'Full',
+                 1 => 'Empty or Missing',
+                 2 => 'Almost Empty',
+                 3 => 'Running Low',
+                 4 => 'Full',
             },
         },{
             Name => 'BodyBatteryState',
-            Condition => '$$self{Model} =~ /(K-5|K-7|K-r|K-x|645D)\b/',
-            Notes => 'K-5, K-7, K-r, K-x and 645D',
+            Condition => '$$self{Model} !~ /(K110D|K2000|K-m)\b/',
+            Notes => 'other models except the K110D, K2000 and K-m',
             Mask => 0xf0,
             PrintConv => {
-                 0x10 => 'Empty or Missing',
-                 0x20 => 'Almost Empty',
-                 0x30 => 'Running Low',
-                 0x40 => 'Close to Full',
-                 0x50 => 'Full',
+                 1 => 'Empty or Missing',
+                 2 => 'Almost Empty',
+                 3 => 'Running Low',
+                 4 => 'Close to Full',
+                 5 => 'Full',
             },
         },{
@@ -3340,6 +4649,4 @@
             Notes => 'decoding unknown for other models',
             Mask => 0xf0,
-            ValueConv => '$val >> 4',
-            ValueConvInv => '$val << 4',
         },
     ],
@@ -3351,8 +4658,8 @@
             Mask => 0x0f,
             PrintConv => { #19
-                 0x01 => 'Empty or Missing',
-                 0x02 => 'Almost Empty',
-                 0x03 => 'Running Low',
-                 0x04 => 'Full',
+                 1 => 'Empty or Missing',
+                 2 => 'Almost Empty',
+                 3 => 'Running Low',
+                 4 => 'Full',
             },
         },{
@@ -3379,9 +4686,9 @@
             Name => 'BodyBatteryADNoLoad',
             Description => 'Body Battery A/D No Load',
-            Condition => '$$self{Model} =~ /(\*ist|K100D|K200D)\b/',
+            Condition => '$$self{Model} =~ /(\*ist|K100D|K200D|GX-1[LS]?)\b/',
         },
         {
             Name => 'BodyBatteryVoltage1', # (static?)
-            Condition => '$$self{Model} =~ /(K-5|K-7|K-r|K-x|645D)\b/',
+            Condition => '$$self{Model} !~ /(K100D|K110D|K2000|K-m|Q\d*)\b/',
             Format => 'int16u',
             ValueConv => '$val / 100',
@@ -3389,5 +4696,5 @@
             PrintConv => 'sprintf("%.2f V", $val)',
             PrintConvInv => '$val =~ s/\s*V$//',
-            # For my K-5:          Min (0%) Max (100%) Meas
+            # For my K-5:          Min (0%) Max (100%) At Meas
             # BodyBatteryVoltage1  6.24 V   7.75 V     7.66 V
             # BodyBatteryVoltage2  5.98 V   7.43 V     7.34 V
@@ -3418,9 +4725,9 @@
             Name => 'GripBatteryADNoLoad',
             Description => 'Grip Battery A/D No Load',
-            Condition => '$$self{Model} =~ /(\*ist|K10D|GX10|K20D|GX20)\b/',
+            Condition => '$$self{Model} =~ /(\*ist|K10D|GX10|K20D|GX20|GX-1[LS]?)\b/',
         },
         {
             Name => 'BodyBatteryVoltage2', # (less than BodyBatteryVoltage1 -- under load?)
-            Condition => '$$self{Model} =~ /(K-5|K-7|K-r|K-x|645D)\b/',
+            Condition => '$$self{Model} !~ /(K100D|K110D|K2000|K-m|Q\d*)\b/',
             Format => 'int16u',
             ValueConv => '$val / 100',
@@ -3472,4 +4779,5 @@
         PrintConvColumns => 2,
         PrintConv => {
+            0 => '(none)',
             0x07ff => 'All',
             0x0777 => 'Central 9 points',
@@ -3533,7 +4841,9 @@
     0x0b => { #JD
         Name => 'AFPointsInFocus',
+        Condition => '$$self{Model} !~ /K-[13]\b/',
         Notes => q{
-            may report two points in focus even though a single AFPoint has been
-            selected, in which case the selected AFPoint is the first reported
+            models other than the K-1 and K-3.  May report two points in focus even
+            though a single AFPoint has been selected, in which case the selected
+            AFPoint is the first reported
         },
         PrintConvColumns => 2,
@@ -3562,4 +4872,35 @@
         },
     },
+    0x1fd => {
+        Name => 'AFHold',
+        Notes => 'decoded only for the K-3 II',
+        Condition => '$$self{Model} eq "PENTAX K-3 II"',
+        PrintConv => { 0 => 'Off', 1 => 'Short', 2 => 'Medium', 3 => 'Long' },
+    },
+);
+
+# Kelvin white balance information (ref 28, topic 4834)
+%Image::ExifTool::Pentax::KelvinWB = (
+    %binaryDataAttrs,
+    FORMAT => 'int16u',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'White balance Blue/Red gains as a function of color temperature.',
+    1  => { Name => 'KelvinWB_Daylight', %kelvinWB },
+    5  => { Name => 'KelvinWB_01', %kelvinWB },
+    9  => { Name => 'KelvinWB_02', %kelvinWB },
+    13 => { Name => 'KelvinWB_03', %kelvinWB },
+    17 => { Name => 'KelvinWB_04', %kelvinWB },
+    21 => { Name => 'KelvinWB_05', %kelvinWB },
+    25 => { Name => 'KelvinWB_06', %kelvinWB },
+    29 => { Name => 'KelvinWB_07', %kelvinWB },
+    33 => { Name => 'KelvinWB_08', %kelvinWB },
+    37 => { Name => 'KelvinWB_09', %kelvinWB },
+    41 => { Name => 'KelvinWB_10', %kelvinWB },
+    45 => { Name => 'KelvinWB_11', %kelvinWB },
+    49 => { Name => 'KelvinWB_12', %kelvinWB },
+    53 => { Name => 'KelvinWB_13', %kelvinWB },
+    57 => { Name => 'KelvinWB_14', %kelvinWB },
+    61 => { Name => 'KelvinWB_15', %kelvinWB },
+    65 => { Name => 'KelvinWB_16', %kelvinWB },
 );
 
@@ -3574,5 +4915,5 @@
     },
     17 => {
-        Name => 'WBShiftMG',
+        Name => 'WBShiftGM',
         Notes => 'positive is a shift toward green',
     },
@@ -3606,5 +4947,5 @@
     1 => { # (presumably this is from an orientation sensor)
         Name => 'CameraOrientation',
-        Condition => '$$self{Model} =~ /K-[^m]/',
+        Condition => '$$self{Model} =~ /K-(5|7|r|x)\b/',
         Notes => 'K-5, K-7, K-r and K-x',
         PrintHex => 1,
@@ -3970,5 +5311,5 @@
         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.
     },
@@ -4008,5 +5349,8 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     FORMAT => 'int8s',
-    NOTES => 'Tags decoded from the electronic level information.',
+    NOTES => q{
+        Tags decoded from the electronic level information for the K-5.  May not be
+        valid for other models.
+    },
     0 => {
         Name => 'LevelOrientation',
@@ -4014,4 +5358,5 @@
         PrintHex => 0,
         PrintConv => {
+            0 => 'n/a', #PH (NC, GR III)
             1 => 'Horizontal (normal)',
             2 => 'Rotate 180',
@@ -4030,13 +5375,13 @@
         Mask => 0xf0,
         PrintConv => {
-            0x00 => 'Off',
-            0x20 => 'Composition Adjust',
-            0xa0 => 'Composition Adjust + Horizon Correction',
-            0xc0 => 'Horizon Correction',
+            0 => 'Off',
+            2 => 'Composition Adjust',
+            10 => 'Composition Adjust + Horizon Correction',
+            12 => 'Horizon Correction',
         },
     },
     1 => {
         Name => 'RollAngle',
-        Notes => 'degrees of clockwise camera rotation',
+        Notes => 'converted to degrees of clockwise camera rotation',
         ValueConv => '-$val / 2',
         ValueConvInv => '-$val * 2',
@@ -4044,5 +5389,5 @@
     2 => {
         Name => 'PitchAngle',
-        Notes => 'degrees of upward camera tilt',
+        Notes => 'converted to degrees of upward camera tilt',
         ValueConv => '-$val / 2',
         ValueConvInv => '-$val * 2',
@@ -4070,12 +5415,135 @@
 );
 
-# temperature information for the K5 - PH
-%Image::ExifTool::Pentax::TempInfoK5 = (
+# white balance RGGB levels (ref 28)
+%Image::ExifTool::Pentax::WBLevels = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    # 0 - 11 (number of entries in this table)
+    # 1 - 0
+    2 => {
+        Name => 'WB_RGGBLevelsDaylight',
+        Format => 'int16u[4]',
+    },
+    # 10 - 1
+    11 => {
+        Name => 'WB_RGGBLevelsShade',
+        Format => 'int16u[4]',
+    },
+    # 19 - 2
+    20 => {
+        Name => 'WB_RGGBLevelsCloudy',
+        Format => 'int16u[4]',
+    },
+    # 28 - 3
+    29 => {
+        Name => 'WB_RGGBLevelsTungsten',
+        Format => 'int16u[4]',
+    },
+    # 37 - 4
+    38 => {
+        Name => 'WB_RGGBLevelsFluorescentD',
+        Format => 'int16u[4]',
+    },
+    # 46 - 5
+    47 => {
+        Name => 'WB_RGGBLevelsFluorescentN',
+        Format => 'int16u[4]',
+    },
+    # 55 - 6
+    56 => {
+        Name => 'WB_RGGBLevelsFluorescentW',
+        Format => 'int16u[4]',
+    },
+    # 64 - 7
+    65 => {
+        Name => 'WB_RGGBLevelsFlash',
+        Format => 'int16u[4]',
+    },
+    # 73 - 8
+    74 => {
+        Name => 'WB_RGGBLevelsFluorescentL',
+        Format => 'int16u[4]',
+    },
+    # 82 - 0xfe
+    83 => {
+        Name => 'WB_RGGBLevelsUnknown',
+        Format => 'int16u[4]',
+        Unknown => 1,
+    },
+    # 91 - 0xff
+    92 => {
+        Name => 'WB_RGGBLevelsUserSelected',
+        Format => 'int16u[4]',
+    },
+);
+
+# lens information for Penax Q (ref PH)
+# (306 bytes long, I wonder if this contains vignetting information too?)
+%Image::ExifTool::Pentax::LensInfoQ = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'More lens information stored by the Pentax Q.',
+    0x0c => {
+        Name => 'LensModel',
+        Format => 'string[30]',
+    },
+    0x2a => {
+        Name => 'LensInfo',
+        Format => 'string[20]',
+        ValueConv => '$val=~s/mm/mm /; $val',
+        ValueConvInv => '$val=~tr/ //d; $val',
+    }
+);
+
+# Pixel shift information for the K-3II (ref PH)
+%Image::ExifTool::Pentax::PixelShiftInfo = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Pixel shift information stored by the K-3 II.',
+    0x00 => {
+        Name => 'PixelShiftResolution',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+);
+
+# AF point information for the K-1 (ref 29)
+%Image::ExifTool::Pentax::AFPointInfo = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'AF point information written by the K-1.',
+    # 0 - int16u: 1 (version?)
+    2 => {
+        Name => 'NumAFPoints',
+        Format => 'int16u',
+    },
+    4 => {
+        Name => 'AFPointsInFocus',
+        Condition => '$$self{Model} =~ /K-1\b/',
+        Format => 'int8u[9]',
+        PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,33,2,0x02)',
+    },
+    4.1 => {
+        Name => 'AFPointsSelected',
+        Condition => '$$self{Model} =~ /K-1\b/',
+        Format => 'int8u[9]',
+        PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,33,2,0x03)',
+    },
+    4.2 => {
+        Name => 'AFPointsSpecial',
+        Condition => '$$self{Model} =~ /K-1\b/',
+        Format => 'int8u[9]',
+        PrintConv => 'Image::ExifTool::Pentax::DecodeAFPoints($val,33,2,0x03,0x03)',
+    },
+);
+
+# temperature information for some models - PH
+%Image::ExifTool::Pentax::TempInfo = (
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     NOTES => q{
         A number of additional temperature readings are extracted from this 256-byte
-        binary-data block in images from the K-5.  It is not currently known where
-        the corresponding temperature sensors are located in the camera.
+        binary-data block in images from models such as the K-01, K-3, K-5, K-50 and
+        K-500.  It is currently not known where the corresponding temperature
+        sensors are located in the camera.
     },
     # (it would be nice to know where these temperature sensors are located,
@@ -4085,5 +5553,5 @@
     #  more quickly than CameraTemperature when shooting video.)
     0x0c => {
-        Name => 'CameraTemperature2',
+        Name => 'SensorTemperature', #forum6677 (was CameraTemperature2)
         Format => 'int16s',
         ValueConv => '$val / 10',
@@ -4093,5 +5561,5 @@
     },
     0x0e => {
-        Name => 'CameraTemperature3',
+        Name => 'SensorTemperature2', #forum6677 (was CameraTemperature3)
         Format => 'int16s',
         ValueConv => '$val / 10',
@@ -4102,4 +5570,5 @@
     0x14 => {
         Name => 'CameraTemperature4',
+        Condition => '$$self{Model} =~ /K-5\b/',
         Format => 'int16s',
         PrintConv => '"$val C"',
@@ -4108,8 +5577,10 @@
     0x16 => { # usually the same as CameraTemperature4, but not always
         Name => 'CameraTemperature5',
+        Condition => '$$self{Model} =~ /K-5\b/',
         Format => 'int16s',
         PrintConv => '"$val C"',
         PrintConvInv => '$val=~s/ ?c$//i; $val',
     },
+    # 0x18,0x1a,0x1c,0x1e = int16u[4] BlackPoint - PH
 );
 
@@ -4221,4 +5692,6 @@
             1600 => 1600, #PH
             3200 => 3200, #PH
+            65534 => 'Auto 2', #PH (Q-S1 MOV) [how is this different from 65535?]
+            65535 => 'Auto', #PH (K-S1 MOV)
         },
     },
@@ -4271,5 +5744,5 @@
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     FIRST_ENTRY => 0,
-    NOTES => 'This information is found in Pentax MOV videos.',
+    NOTES => 'This information is found in MOV videos from cameras such as the Optio WP.',
     0x00 => {
         Name => 'Make',
@@ -4326,6 +5799,26 @@
             Start => 10,
             Base => '$start',
-            ByteOrder => 'BigEndian',
-        },
+            ByteOrder => 'Unknown', # K-70 is little-endian, K-x is big-endian
+        },
+    },
+    mknt => { # (Q-S1)
+        Name => 'MakerNotes',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::Main',
+            Start => 10,
+            Base => '$start',
+            ByteOrder => 'Unknown',
+        },
+    },
+);
+
+# Pentax metadata in S1 AVI maker notes (PH)
+%Image::ExifTool::Pentax::S1 = (
+    NOTES => 'Tags extracted from the maker notes of AVI videos from the Optio S1.',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x0000 => { #5
+        Name => 'MakerNoteVersion',
+        Writable => 'undef',
+        Count => 4,
     },
 );
@@ -4338,5 +5831,246 @@
     0x0c => {
         Name => 'Model',
+        Description => 'Camera Model Name',
         Format => 'string[32]',
+    },
+);
+
+# PreviewImage information found in PXTH atom of K-01 MOV videos
+%Image::ExifTool::Pentax::PXTH = (
+    NOTES => 'Tags found in the PXTH atom of MOV videos from the K-01.',
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0x00 => {
+        Name => 'PreviewImageLength',
+        Format => 'int32u',
+    },
+    0x04 => {
+        Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{0}]',
+        Notes => '640-pixel-wide JPEG preview', # (360 pixels high, may depend on aspect ratio)
+        RawConv => '$self->ValidateImage(\$val,$tag)',
+    },
+);
+
+# information in PENT atom of MOV videos from the Optio WG-2 GPS
+%Image::ExifTool::Pentax::PENT = (
+    NOTES => 'Tags found in the PENT atom of MOV videos from the Optio WG-2 GPS.',
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    0 => {
+        Name => 'Make',
+        Format => 'string[24]',
+    },
+    0x1a => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[24]',
+    },
+    0x38 => { #(NC)
+        Name => 'ExposureTime',
+        Format => 'int32u',
+        ValueConv => '$val ? 10 / $val : 0',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+    },
+    0x3c => {
+        Name => 'FNumber',
+        Format => 'rational64u',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x44 => { #(NC)
+        Name => 'ExposureCompensation',
+        Format => 'rational64s',
+        PrintConv => '$val ? sprintf("%+.1f", $val) : 0',
+    },
+    0x54 => { #(NC)
+        Name => 'FocalLength',
+        Format => 'int32u',
+        PrintConv => '"$val mm"',
+    },
+    0x71 => {
+        Name => 'DateTime1',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+    },
+    0x8b => {
+        Name => 'DateTime2',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+    },
+    0xa7 => { #(NC)
+        Name => 'ISO',
+        Format => 'int32u',
+    },
+    0xc7 => {
+        Name => 'GPSVersionID',
+        Format => 'undef[8]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        DataMember => 'GPSVersionID',
+        RawConv => '$$self{GPSVersionID} = ($val=~s/GPS_// ? join(" ",unpack("C*",$val)) : undef)',
+        PrintConv => '$val =~ tr/ /./; $val',
+    },
+    0xcf => {
+        Name => 'GPSLatitudeRef',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'string[2]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            N => 'North',
+            S => 'South',
+        },
+    },
+    0xd1 => {
+        Name => 'GPSLatitude',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'rational64u[3]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        ValueConv    => 'Image::ExifTool::GPS::ToDegrees($val)',
+        PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+    },
+    0xe9 => {
+        Name => 'GPSLongitudeRef',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'string[2]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            E => 'East',
+            W => 'West',
+        },
+    },
+    0xeb => {
+        Name => 'GPSLongitude',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'rational64u[3]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        ValueConv    => 'Image::ExifTool::GPS::ToDegrees($val)',
+        PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+    },
+    0x103 => {
+        Name => 'GPSAltitudeRef',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'int8u',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            0 => 'Above Sea Level',
+            1 => 'Below Sea Level',
+        },
+    },
+    0x104 => {
+        Name => 'GPSAltitude',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'rational64u',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
+    },
+    0x11c => {
+        Name => 'GPSTimeStamp',
+        Condition => '$$self{GPSVersionID}',
+        Groups => { 1 => 'GPS', 2 => 'Time' },
+        Format => 'rational64u[3]',
+        ValueConv => 'Image::ExifTool::GPS::ConvertTimeStamp($val)',
+        PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)',
+    },
+    0x134 => {
+        Name => 'GPSSatellites',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'string[3]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+    },
+    0x137 => {
+        Name => 'GPSStatus',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'string[2]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            A => 'Measurement Active',
+            V => 'Measurement Void',
+        },
+    },
+    0x139 => {
+        Name => 'GPSMeasureMode',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'string[2]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+        PrintConv => {
+            2 => '2-Dimensional Measurement',
+            3 => '3-Dimensional Measurement',
+        },
+    },
+    0x13b => {
+        Name => 'GPSMapDatum',
+        Condition => '$$self{GPSVersionID}',
+        Format => 'string[7]',
+        Groups => { 1 => 'GPS', 2 => 'Location' },
+    },
+    0x142 => {
+        Name => 'GPSDateStamp',
+        Condition => '$$self{GPSVersionID}',
+        Groups => { 1 => 'GPS', 2 => 'Time' },
+        Format => 'string[11]',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+    },
+    0x173 => { #(NC)
+        Name => 'AudioCodecID',
+        Format => 'string[4]',
+    },
+    0x7d3 => {
+        Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$size-0x7d3]',
+        Notes => '640x480 JPEG preview image', # (black borders pad to 480 pixels high)
+        RawConv => '$self->ValidateImage(\$val,$tag)',
+    },
+);
+
+# tags in Pentax Optio RZ18 AVI videos (ref PH)
+# (very similar to Olympus::AVI tags)
+%Image::ExifTool::Pentax::Junk2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    NOTES => 'This information is found in AVI videos from the Optio RZ18.',
+    0x12 => {
+        Name => 'Make',
+        Format => 'string[24]',
+    },
+    0x2c => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[24]',
+    },
+    0x5e => {
+        Name => 'FNumber',
+        Format => 'rational64u',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    0x83 => {
+        Name => 'DateTime1',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+    },
+    0x9d => {
+        Name => 'DateTime2',
+        Format => 'string[24]',
+        Groups => { 2 => 'Time' },
+    },
+    0x12b => {
+        Name => 'ThumbnailWidth',
+        Format => 'int16u',
+    },
+    0x12d => {
+        Name => 'ThumbnailHeight',
+        Format => 'int16u',
+    },
+    0x12f => {
+        Name => 'ThumbnailLength',
+        Format => 'int32u',
+    },
+    0x133 => {
+        Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{0x12f}]',
+        Notes => '160x120 JPEG thumbnail image',
+        RawConv => '$self->ValidateImage(\$val,$tag)',
     },
 );
@@ -4409,7 +6143,36 @@
 
 #------------------------------------------------------------------------------
+# Decode AF bit mask (ref 29)
+# Inputs: 0) raw binary value, 1) number of AF points, 2) number of bits per AF point,
+#         3) bit mask, 4) bit value (undef for any bit set)
+sub DecodeAFPoints($$$$;$)
+{
+    my ($val, $num, $bits, $mask, $bitVal) = @_;
+    my @bytes = split ' ', $val;
+    my $i = 1;  # (starts at AF point number 1)
+    my $shift = 8 - $bits;
+    my $byte = shift @bytes;
+    my @bitList;
+    for (;;) {
+        if ($bitVal) {
+            push @bitList, $i if (($byte >> $shift) & $mask) == $bitVal;
+        } else {
+            push @bitList, $i if ($byte >> $shift) & $mask;
+        }
+        last if ++$i > $num;
+        $shift -= $bits;
+        if ($shift < 0) {
+            last unless @bytes;
+            $byte = shift @bytes;
+            $shift += 8;
+        }
+    }
+    return join(',', @bitList);
+}
+
+#------------------------------------------------------------------------------
 # Convert Pentax hex-based EV (modulo 8) to real number
 # Inputs: 0) value to convert
-# ie) 0x00 -> 0
+# eg) 0x00 -> 0
 #     0x03 -> 0.33333
 #     0x04 -> 0.5
@@ -4456,11 +6219,11 @@
 sub CryptShutterCount($$)
 {
-    my ($val, $exifTool) = @_;
+    my ($val, $et) = @_;
     # Pentax Date and Time values are used in the encryption
-    return undef unless $$exifTool{PentaxDate} and $$exifTool{PentaxTime} and
-        length($$exifTool{PentaxDate})==4 and length($$exifTool{PentaxTime})>=3;
+    return undef unless $$et{PentaxDate} and $$et{PentaxTime} and
+        length($$et{PentaxDate})==4 and length($$et{PentaxTime})>=3;
     # get Date and Time as integers (after padding Time with a null byte)
-    my $date = unpack('N', $$exifTool{PentaxDate});
-    my $time = unpack('N', $$exifTool{PentaxTime} . "\0");
+    my $date = unpack('N', $$et{PentaxDate});
+    my $time = unpack('N', $$et{PentaxTime} . "\0");
     return $val ^ $date ^ (0xffffffff - $time);
 }
@@ -4488,6 +6251,6 @@
 I couldn't find a good source for Pentax maker notes information, but I've
 managed to discover a fair bit of information by analyzing sample images
-downloaded from the internet, and through tests with my own Optio WP,
-K10D, and K-5, and with help provided by other ExifTool users (see
+downloaded from the internet, and through tests with my own Optio S, Optio
+WP, K10D, K-01 and K-5, and with help provided by other ExifTool users (see
 L</ACKNOWLEDGEMENTS>).
 
@@ -4521,13 +6284,13 @@
 =head1 ACKNOWLEDGEMENTS
 
-Thanks to Wayne Smith, John Francis, Douglas O'Brien Cvetan Ivanov, Jens
-Duttke and Dave Nicholson for help figuring out some Pentax tags, Ger
-Vermeulen and Niels Kristian Bech Jensen for contributing print conversion
-values for some tags, and everyone who helped contribute to the LensType
-values.
+Thanks to Wayne Smith, John Francis, Douglas O'Brien, Cvetan Ivanov, Jens
+Duttke, Dave Nicholson, Iliah Borg, Klaus Homeister, Louis Granboulan and
+Andras Salamon for help figuring out some Pentax tags, Ger Vermeulen and
+Niels Kristian Bech Jensen for contributing print conversion values for some
+tags, and everyone who helped contribute to the LensType values.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhaseOne.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhaseOne.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhaseOne.pm	(revision 34921)
@@ -0,0 +1,732 @@
+#------------------------------------------------------------------------------
+# File:         PhaseOne.pm
+#
+# Description:  Phase One maker notes tags
+#
+# Revisions:    2013-02-17 - P. Harvey Created
+#
+# References:   1) http://www.cybercom.net/~dcoffin/dcraw/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PhaseOne;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::Exif;
+
+$VERSION = '1.06';
+
+sub WritePhaseOne($$$);
+sub ProcessPhaseOne($$$);
+
+# default formats based on PhaseOne format size
+my @formatName = ( undef, 'string', 'int16s', undef, 'int32s' );
+
+# Phase One maker notes (ref PH)
+%Image::ExifTool::PhaseOne::Main = (
+    PROCESS_PROC => \&ProcessPhaseOne,
+    WRITE_PROC => \&WritePhaseOne,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    WRITABLE => '1',
+    FORMAT => 'int32s',
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    VARS => { ENTRY_SIZE => 16 }, # (entries contain a format field)
+    NOTES => 'These tags are extracted from the maker notes of Phase One images.',
+    0x0100 => { #1
+        Name => 'CameraOrientation',
+        ValueConv => '$val & 0x03',     # ignore other bits for now
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 90 CW',
+            2 => 'Rotate 270 CW',
+            3 => 'Rotate 180',
+        },
+    },
+    # 0x0101 - int32u: 96,160,192,256,544 (same as 0x0213)
+    0x0102 => { Name => 'SerialNumber', Format => 'string' },
+    # 0x0103 - int32u: 19,20,59769034
+    # 0x0104 - int32u: 50,200
+    0x0105 => 'ISO',
+    0x0106 => {
+        Name => 'ColorMatrix1',
+        Format => 'float',
+        Count => 9,
+        PrintConv => q{
+            my @a = map { sprintf('%.3f', $_) } split ' ', $val;
+            return "@a";
+        },
+        PrintConvInv => '$val',
+    },
+    0x0107 => { Name => 'WB_RGBLevels', Format => 'float', Count => 3 },
+    0x0108 => 'SensorWidth',
+    0x0109 => 'SensorHeight',
+    0x010a => 'SensorLeftMargin', #1
+    0x010b => 'SensorTopMargin', #1
+    0x010c => 'ImageWidth',
+    0x010d => 'ImageHeight',
+    0x010e => { #1
+        Name => 'RawFormat',
+        # 1 = raw bit mask 0x5555 (>1 mask 0x1354)
+        # >2 = compressed
+        # 5 = non-linear
+        PrintConv => { #PH
+            1 => 'RAW 1', #? (encrypted)
+            2 => 'RAW 2', #? (encrypted)
+            3 => 'IIQ L',
+            # 4?
+            5 => 'IIQ S',
+            6 => 'IIQ Sv2',
+        },
+    },
+    0x010f => {
+        Name => 'RawData',
+        Format => 'undef', # (actually 2-byte integers, but don't convert)
+        Binary => 1,
+        PutFirst => 1,
+        Writable => 0,
+        Drop => 1, # don't copy to other file types
+    },
+    0x0110 => { #1
+        Name => 'SensorCalibration',
+        SubDirectory => { TagTable => 'Image::ExifTool::PhaseOne::SensorCalibration' },
+    },
+    0x0112 => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Format => 'int32u',
+        Writable => 0, # (don't write because this is an encryption key for RawFormat 1 and 2)
+        Priority => 0,
+        Shift => 'Time',
+        Groups => { 2 => 'Time' },
+        Notes => 'may be used as a key to encrypt the raw data', #1
+        ValueConv => 'ConvertUnixTime($val)',
+        ValueConvInv => 'GetUnixTime($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
+    },
+    0x0113 => 'ImageNumber', # (NC)
+    0x0203 => { Name => 'Software', Format => 'string' },
+    0x0204 => { Name => 'System',   Format => 'string' },
+    # 0x020b - int32u: 0,1
+    # 0x020c - int32u: 1,2
+    # 0x020e - int32u: 1,3
+    0x0210 => { # (NC) (used in linearization formula - ref 1)
+        Name => 'SensorTemperature',
+        Format => 'float',
+        PrintConv => 'sprintf("%.2f C",$val)',
+        PrintConvInv => '$val=~s/ ?C//; $val',
+    },
+    0x0211 => { # (NC)
+        Name => 'SensorTemperature2',
+        Format => 'float',
+        PrintConv => 'sprintf("%.2f C",$val)',
+        PrintConvInv => '$val=~s/ ?C//; $val',
+    },
+    0x0212 => {
+        Name => 'UnknownDate',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        # (this time is within about 10 minutes before or after 0x0112)
+        Unknown => 1,
+        Shift => 'Time',
+        ValueConv => 'ConvertUnixTime($val)',
+        ValueConvInv => 'GetUnixTime($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
+    },
+    # 0x0213 - int32u: 96,160,192,256,544 (same as 0x0101)
+    # 0x0215 - int32u: 4,5
+    # 0x021a - used by dcraw
+    0x021c => { Name => 'StripOffsets', Binary => 1, Writable => 0 },
+    0x021d => 'BlackLevel', #1
+    # 0x021e - int32u: 1
+    # 0x0220 - int32u: 32
+    # 0x0221 - float: 0-271
+    0x0222 => 'SplitColumn', #1
+    0x0223 => { Name => 'BlackLevelData', Format => 'int16u', Count => -1, Binary => 1 }, #1
+    # 0x0224 - int32u: 1688,2748,3372
+    0x0225 => {
+        Name => 'PhaseOne_0x0225',
+        Format => 'int16s',
+        Count => -1,
+        Flags => ['Unknown','Hidden'],
+        PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
+    },
+    0x0226 => {
+        Name => 'ColorMatrix2',
+        Format => 'float',
+        Count => 9,
+        PrintConv => q{
+            my @a = map { sprintf('%.3f', $_) } split ' ', $val;
+            return "@a";
+        },
+        PrintConvInv => '$val',
+    },
+    # 0x0227 - int32u: 0,1
+    # 0x0228 - int32u: 1,2
+    # 0x0229 - int32s: -2,0
+    0x0267 => { #PH
+        Name => 'AFAdjustment',
+        Format => 'float',
+    },
+    0x022b => { #PH
+        Name => 'PhaseOne_0x022b',
+        Format => 'float',
+        Flags => ['Unknown','Hidden'],
+    },
+    # 0x0242 - int32u: 55
+    # 0x0244 - int32u: 102
+    # 0x0245 - float: 1.2
+    0x0258 => { #PH
+        Name => 'PhaseOne_0x0258',
+        Format => 'int16s',
+        Flags => ['Unknown','Hidden'],
+        PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
+    },
+    0x025a => { #PH
+        Name => 'PhaseOne_0x025a',
+        Format => 'int16s',
+        Flags => ['Unknown','Hidden'],
+        PrintConv => 'length($val) > 60 ? substr($val,0,55) . "[...]" : $val',
+    },
+    # 0x0300 - int32u: 100,101,102
+    0x0301 => { Name => 'FirmwareVersions', Format => 'string' },
+    # 0x0304 - int32u: 8,3073,3076
+    0x0400 => {
+        Name => 'ShutterSpeedValue',
+        Format => 'float',
+        ValueConv => 'abs($val)<100 ? 2**(-$val) : 0',
+        ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x0401 => {
+        Name => 'ApertureValue',
+        Format => 'float',
+        ValueConv => '2 ** ($val / 2)',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0402 => {
+        Name => 'ExposureCompensation',
+        Format => 'float',
+        PrintConv => 'sprintf("%.3f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0403 => {
+        Name => 'FocalLength',
+        Format => 'float',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    # 0x0404 - int32u: 0,3
+    # 0x0405 - int32u? (big numbers)
+    # 0x0406 - int32u: 1
+    # 0x0407 - float: -0.333 (exposure compensation again?)
+    # 0x0408-0x0409 - int32u: 1
+    0x0410 => { Name => 'CameraModel',  Format => 'string' },
+    # 0x0411 - int32u: 33556736
+    0x0412 => { Name => 'LensModel',    Format => 'string' },
+    0x0414 => {
+        Name => 'MaxApertureValue',
+        Format => 'float',
+        ValueConv => '2 ** ($val / 2)',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0415 => {
+        Name => 'MinApertureValue',
+        Format => 'float',
+        ValueConv => '2 ** ($val / 2)',
+        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    # 0x0416 - float: (min focal length? ref LR, Credo50) (but looks more like an int32u date for the 645DF - PH)
+    # 0x0417 - float: 80 (max focal length? ref LR)
+    0x0455 => { #PH
+        Name => 'Viewfinder',
+        Format => 'string',
+    },
+);
+
+# Phase One metadata (ref 1)
+%Image::ExifTool::PhaseOne::SensorCalibration = (
+    PROCESS_PROC => \&ProcessPhaseOne,
+    WRITE_PROC => \&WritePhaseOne,
+    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',
+        # list of defects. each defect is 4 x int16u values:
+        # 0=column, 1=row, 2=type (129=bad pixel, 131=bad column), 3=?
+        # (but it isn't really worth the time decoding this -- it can be a few hundred kB)
+        Format => 'undef',
+        Binary => 1,
+    },
+    0x0401 => {
+        Name => 'AllColorFlatField1',
+        Format => 'undef',
+        Flags => ['Unknown','Binary'],
+    },
+    0x0404 => { #PH
+        Name => 'SensorCalibration_0x0404',
+        Format => 'string',
+        Flags => ['Unknown','Hidden'],
+    },
+    0x0405 => { #PH
+        Name => 'SensorCalibration_0x0405',
+        Format => 'string',
+        Flags => ['Unknown','Hidden'],
+    },
+    0x0406 => { #PH
+        Name => 'SensorCalibration_0x0406',
+        Format => 'string',
+        Flags => ['Unknown','Hidden'],
+    },
+    0x0407 => { #PH
+        Name => 'SerialNumber',
+        Format => 'string',
+        Writable => 1,
+    },
+    0x0408 => { #PH
+        Name => 'SensorCalibration_0x0408',
+        Format => 'float',
+        Flags => ['Unknown','Hidden'],
+    },
+    0x040b => {
+        Name => 'RedBlueFlatField',
+        Format => 'undef',
+        Flags => ['Unknown','Binary'],
+    },
+    0x040f => { #PH
+        Name => 'SensorCalibration_0x040f',
+        Format => 'undef',
+        Flags => ['Unknown','Hidden'],
+    },
+    0x0410 => {
+        Name => 'AllColorFlatField2',
+        Format => 'undef',
+        Flags => ['Unknown','Binary'],
+    },
+    # 0x0412 - used by dcraw
+    0x0413 => { #PH
+        Name => 'SensorCalibration_0x0413',
+        Format => 'double',
+        Flags => ['Unknown','Hidden'],
+    },
+    0x0414 => { #PH
+        Name => 'SensorCalibration_0x0414',
+        Format => 'undef',
+        Flags => ['Unknown','Hidden'],
+        ValueConv => q{
+            my $order = GetByteOrder();
+            if (length $val >= 8 and SetByteOrder(substr($val,0,2))) {
+                $val = ReadValue(\$val, 2, 'int16u', 1, length($val)-2) . ' ' .
+                       ReadValue(\$val, 4, 'float', undef, length($val)-4);
+                SetByteOrder($order);
+            }
+            return $val;
+        },
+    },
+    0x0416 => {
+        Name => 'AllColorFlatField3',
+        Format => 'undef',
+        Flags => ['Unknown','Binary'],
+    },
+    0x0418 => { #PH
+        Name => 'SensorCalibration_0x0418',
+        Format => 'undef',
+        Flags => ['Unknown','Hidden'],
+    },
+    0x0419 => {
+        Name => 'LinearizationCoefficients1',
+        Format => 'float',
+        PrintConv => 'my @a=split " ",$val;join " ", map { sprintf("%.5g",$_) } @a',
+    },
+    0x041a => {
+        Name => 'LinearizationCoefficients2',
+        Format => 'float',
+        PrintConv => 'my @a=split " ",$val;join " ", map { sprintf("%.5g",$_) } @a',
+    },
+    0x041c => { #PH
+        Name => 'SensorCalibration_0x041c',
+        Format => 'float',
+        Flags => ['Unknown','Hidden'],
+    },
+    0x041e => { #PH
+        Name => 'SensorCalibration_0x041e',
+        Format => 'undef',
+        Flags => ['Unknown','Hidden'],
+        ValueConv => q{
+            my $order = GetByteOrder();
+            if (length $val >= 8 and SetByteOrder(substr($val,0,2))) {
+                $val = ReadValue(\$val, 2, 'int16u', 1, length($val)-2) . ' ' .
+                       ReadValue(\$val, 4, 'float', undef, length($val)-4);
+                SetByteOrder($order);
+            }
+            return $val;
+        },
+    },
+);
+
+#------------------------------------------------------------------------------
+# Do HTML dump of an IFD entry
+# Inputs: 0) ExifTool ref, 1) tag table ref, 3) tag ID, 4) tag value,
+#         5) IFD entry offset, 6) IFD entry size, 7) parameter hash
+sub HtmlDump($$$$$$%)
+{
+    my ($et, $tagTablePtr, $tagID, $value, $entry, $entryLen, %parms) = @_;
+    my ($dirName, $index, $formatStr, $dataPos, $base, $size, $valuePtr) =
+        @parms{qw(DirName Index Format DataPos Base Size Start)};
+    my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
+    my ($tagName, $colName, $subdir);
+    my $count = $parms{Count} || $size;
+    $base = 0 unless defined $base;
+    if ($tagInfo) {
+        $tagName = $$tagInfo{Name};
+        $subdir = $$tagInfo{SubDirectory};
+        if ($$tagInfo{Format}) {
+            $formatStr = $$tagInfo{Format};
+            $count = $size / Image::ExifTool::FormatSize($formatStr);
+        }
+    } else {
+        $tagName = sprintf("Tag 0x%.4x", $tagID);
+    }
+    my $dname = sprintf("${dirName}-%.2d", $index);
+    # build our tool tip
+    my $fstr = "$formatStr\[$count]";
+    my $tip = sprintf("Tag ID: 0x%.4x\n", $tagID) .
+              "Format: $fstr\nSize: $size bytes\n";
+    if ($size > 4) {
+        $tip .= sprintf("Value offset: 0x%.4x\n", $valuePtr - $base);
+        $tip .= sprintf("Actual offset: 0x%.4x\n", $valuePtr + $dataPos);
+        $tip .= sprintf("Offset base: 0x%.4x\n", $dataPos + $base);
+        $colName = "<span class=F>$tagName</span>";
+    } else {
+        $colName = $tagName;
+    }
+    unless (ref $value) {
+        my $tval = length($value) > 32 ? substr($value,0,28) . '[...]' : $value;
+        $tval =~ tr/\x00-\x1f\x7f-\xff/./;
+        $tip .= "Value: $tval";
+    }
+    $et->HDump($entry+$dataPos, $entryLen, "$dname $colName", $tip, 1);
+    if ($size > 4) {
+        my $dumpPos = $valuePtr + $dataPos;
+        # add value data block
+        $et->HDump($dumpPos,$size,"$tagName value",'SAME', $subdir ? 0x04 : 0);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Write PhaseOne maker notes (both types of PhaseOne IFD)
+# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
+# Returns: data block or undef on error
+sub WritePhaseOne($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;      # allow dummy access to autoload this package
+
+    # nothing to do if we aren't changing any PhaseOne tags
+    my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
+    return undef unless %$newTags or $$et{DropTags} or $$et{EDIT_DIRS}{PhaseOne};
+
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos} || 0;
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || $$dirInfo{DataLen} - $dirStart;
+    my $dirName = $$dirInfo{DirName};
+    my $verbose = $et->Options('Verbose');
+
+    return undef if $dirLen < 12;
+    unless ($$tagTablePtr{VARS} and $$tagTablePtr{VARS}{ENTRY_SIZE}) {
+        $et->WarnOnce("No ENTRY_SIZE for $$tagTablePtr{TABLE_NAME}");
+        return undef;
+    }
+    my $entrySize = $$tagTablePtr{VARS}{ENTRY_SIZE};
+    my $ifdType = $$tagTablePtr{TAG_PREFIX} || 'PhaseOne';
+    my $hdr = substr($$dataPt, $dirStart, 12);
+    if ($entrySize == 16) {
+        return undef unless $hdr =~ /^(IIII.waR|MMMMRaw.)/s;
+    } elsif ($hdr !~ /^(IIII\x01\0\0\0|MMMM\0\0\0\x01)/s) {
+        $et->Warn("Unrecognized $ifdType directory version");
+        return undef;
+    }
+    SetByteOrder(substr($hdr, 0, 2));
+    # get offset to start of PhaseOne directory
+    my $ifdStart = Get32u(\$hdr, 8);
+    return undef if $ifdStart + 8 > $dirLen;
+    # initialize output directory buffer with (fixed) number of entries plus 4-byte padding
+    my $dirBuff = substr($$dataPt, $dirStart + $ifdStart, 8);
+    # get number of entries in PhaseOne directory
+    my $numEntries = Get32u(\$dirBuff, 0);
+    my $ifdEnd = $ifdStart + 8 + $entrySize * $numEntries;
+    return undef if $numEntries < 2 or $numEntries > 300 or $ifdEnd > $dirLen;
+    my $hdrBuff = $hdr;
+    my $valBuff = '';   # buffer for value data
+    my $fixup = new Image::ExifTool::Fixup;
+    my $index;
+    for ($index=0; $index<$numEntries; ++$index) {
+        my $entry = $dirStart + $ifdStart + 8 + $entrySize * $index;
+        my $tagID = Get32u($dataPt, $entry);
+        my $size = Get32u($dataPt, $entry+$entrySize-8);
+        my ($formatSize, $formatStr);
+        if ($entrySize == 16) {
+            $formatSize = Get32u($dataPt, $entry+4);
+            $formatStr = $formatName[$formatSize];
+            unless ($formatStr) {
+                $et->Warn("Possibly invalid $ifdType IFD entry $index",1);
+                delete $$newTags{$tagID};   # make sure we don't try to change this one
+            }
+        } else {
+            # (no format code for SensorCalibration IFD entries)
+            $formatSize = 1;
+            $formatStr = 'undef';
+        }
+        my $valuePtr = $entry + $entrySize - 4;
+        if ($size > 4) {
+            if ($size > 0x7fffffff) {
+                $et->Error("Invalid size for $ifdType IFD entry $index",1);
+                return undef;
+            }
+            $valuePtr = Get32u($dataPt, $valuePtr);
+            if ($valuePtr + $size > $dirLen) {
+                $et->Error(sprintf("Invalid offset 0x%.4x for $ifdType IFD entry $index",$valuePtr),1);
+                return undef;
+            }
+            $valuePtr += $dirStart;
+        }
+        my $value = substr($$dataPt, $valuePtr, $size);
+        my $tagInfo = $$newTags{$tagID} || $$tagTablePtr{$tagID};
+        $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID) if $tagInfo and ref($tagInfo) ne 'HASH';
+        if ($$newTags{$tagID}) {
+            $formatStr = $$tagInfo{Format} if $$tagInfo{Format};
+            my $count = int($size / Image::ExifTool::FormatSize($formatStr));
+            my $val = ReadValue(\$value, 0, $formatStr, $count, $size);
+            my $nvHash = $et->GetNewValueHash($tagInfo);
+            if ($et->IsOverwriting($nvHash, $val)) {
+                my $newVal = $et->GetNewValue($nvHash);
+                # allow count to change for string and undef types only
+                undef $count if $formatStr eq 'string' or $formatStr eq 'undef';
+                my $newValue = WriteValue($newVal, $formatStr, $count);
+                if (defined $newValue) {
+                    $value = $newValue;
+                    $size = length $newValue;
+                    $et->VerboseValue("- $dirName:$$tagInfo{Name}", $val);
+                    $et->VerboseValue("+ $dirName:$$tagInfo{Name}", $newVal);
+                    ++$$et{CHANGED};
+                }
+            }
+        } elsif ($tagInfo and $$tagInfo{SubDirectory}) {
+            my $subTable = GetTagTable($$tagInfo{SubDirectory}{TagTable});
+            my %subdirInfo = (
+                DirName => $$tagInfo{Name},
+                DataPt  => \$value,
+                DataLen => length $value,
+            );
+            my $newValue = $et->WriteDirectory(\%subdirInfo, $subTable);
+            if (defined $newValue and length($newValue)) {
+                $value = $newValue;
+                $size = length $newValue;
+            }
+        } elsif ($$et{DropTags} and (($tagInfo and $$tagInfo{Drop}) or $size > 8192)) {
+            # decrease the number of entries in the directory
+            Set32u(Get32u(\$dirBuff, 0) - 1, \$dirBuff, 0);
+            next;   # drop this tag
+        }
+        # add the tagID, possibly format size, and size to this directory entry
+        $dirBuff .= substr($$dataPt, $entry, $entrySize - 8) . Set32u($size);
+
+        # pad value to an even 4-byte boundary just in case
+        $value .= ("\0" x (4 - ($size & 0x03))) if $size & 0x03 or not $size;
+        if ($size <= 4) {
+            # store value in place of the IFD value pointer (already padded to 4 bytes)
+            $dirBuff .= $value;
+        } elsif ($tagInfo and $$tagInfo{PutFirst}) {
+            # store value immediately after header
+            $dirBuff .= Set32u(length $hdrBuff);
+            $hdrBuff .= $value;
+        } else {
+            # store value at end of value buffer
+            $fixup->AddFixup(length $dirBuff);
+            $dirBuff .= Set32u(length $valBuff);
+            $valBuff .= $value;
+        }
+    }
+    # apply necessary fixup to offsets in PhaseOne directory
+    $$fixup{Shift} = length $hdrBuff;
+    $fixup->ApplyFixup(\$dirBuff);
+    # set pointer to PhaseOneIFD in header
+    Set32u(length($hdrBuff) + length($valBuff), \$hdrBuff, 8);
+    return $hdrBuff . $valBuff . $dirBuff;
+}
+
+#------------------------------------------------------------------------------
+# Read Phase One maker notes
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+# Notes: This routine processes both the main PhaseOne IFD type (with 16 bytes
+#        per entry), and the SensorCalibration IFD type (12 bytes per entry)
+sub ProcessPhaseOne($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = ($$dirInfo{DataPos} || 0) + ($$dirInfo{Base} || 0);
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || $$dirInfo{DataLen} - $dirStart;
+    my $binary = $et->Options('Binary');
+    my $verbose = $et->Options('Verbose');
+    my $htmlDump = $$et{HTML_DUMP};
+
+    return 0 if $dirLen < 12;
+    unless ($$tagTablePtr{VARS} and $$tagTablePtr{VARS}{ENTRY_SIZE}) {
+        $et->WarnOnce("No ENTRY_SIZE for $$tagTablePtr{TABLE_NAME}");
+        return undef;
+    }
+    my $entrySize = $$tagTablePtr{VARS}{ENTRY_SIZE};
+    my $ifdType = $$tagTablePtr{TAG_PREFIX} || 'PhaseOne';
+
+    my $hdr = substr($$dataPt, $dirStart, 12);
+    if ($entrySize == 16) {
+        return 0 unless $hdr =~ /^(IIII.waR|MMMMRaw.)/s;
+    } elsif ($hdr !~ /^(IIII\x01\0\0\0|MMMM\0\0\0\x01)/s) {
+        $et->Warn("Unrecognized $ifdType directory version");
+        return 0;
+    }
+    SetByteOrder(substr($hdr, 0, 2));
+    # get offset to start of PhaseOne directory
+    my $ifdStart = Get32u(\$hdr, 8);
+    return 0 if $ifdStart + 8 > $dirLen;
+    # get number of entries in PhaseOne directory
+    my $numEntries = Get32u($dataPt, $dirStart + $ifdStart);
+    my $ifdEnd = $ifdStart + 8 + $entrySize * $numEntries;
+    return 0 if $numEntries < 2 or $numEntries > 300 or $ifdEnd > $dirLen;
+    $et->VerboseDir($ifdType, $numEntries);
+    if ($htmlDump) {
+        $et->HDump($dirStart + $dataPos, 8, "$ifdType header");
+        $et->HDump($dirStart + $dataPos + 8, 4, "$ifdType IFD offset");
+        $et->HDump($dirStart + $dataPos + $ifdStart, 4, "$ifdType entries",
+                   "Entry count: $numEntries");
+        $et->HDump($dirStart + $dataPos + $ifdStart + 4, 4, '[unused]');
+    }
+    my $index;
+    for ($index=0; $index<$numEntries; ++$index) {
+        my $entry = $dirStart + $ifdStart + 8 + $entrySize * $index;
+        my $tagID = Get32u($dataPt, $entry);
+        my $size = Get32u($dataPt, $entry+$entrySize-8);
+        my $valuePtr = $entry + $entrySize - 4;
+        my ($formatSize, $formatStr, $value);
+        if ($entrySize == 16) {
+            # (format code only for the 16-byte IFD entry)
+            $formatSize = Get32u($dataPt, $entry+4);
+            $formatStr = $formatName[$formatSize];
+            unless ($formatStr) {
+                $et->WarnOnce("Unrecognized $ifdType format size $formatSize",1);
+                $formatSize = 1;
+                $formatStr = 'undef';
+            }
+        } elsif ($size %4) {
+            $formatSize = 1;
+            $formatStr = 'undef';
+        } else {
+            $formatSize = 4;
+            $formatStr = 'int32s';
+        }
+        if ($size > 4) {
+            if ($size > 0x7fffffff) {
+                $et->Warn("Invalid size for $ifdType IFD entry $index");
+                return 0;
+            }
+            $valuePtr = Get32u($dataPt, $valuePtr);
+            if ($valuePtr + $size > $dirLen) {
+                $et->Warn(sprintf("Invalid offset 0x%.4x for $ifdType IFD entry $index",$valuePtr));
+                return 0;
+            }
+            $valuePtr += $dirStart;
+        }
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
+        if ($tagInfo) {
+            $formatStr = $$tagInfo{Format} if $$tagInfo{Format};
+        } else {
+            next unless $verbose or $htmlDump;
+        }
+        my $count = int($size / Image::ExifTool::FormatSize($formatStr));
+        if ($count > 100000 and not $binary) {
+            $value = \ "Binary data $size bytes";
+        } else {
+            $value = ReadValue($dataPt,$valuePtr,$formatStr,$count,$size);
+            # try to distinguish between the various format types
+            if ($formatStr eq 'int32s') {
+                my ($val) = split ' ', $value;
+                if (defined $val) {
+                    # get floating point exponent (has bias of 127)
+                    my $exp = ($val & 0x7f800000) >> 23;
+                    if ($exp > 120 and $exp < 140) {
+                        $formatStr = 'float';
+                        $value = ReadValue($dataPt,$valuePtr,$formatStr,$count,$size);
+                    }
+                }
+            }
+        }
+        my %parms = (
+            DirName => $ifdType,
+            Index   => $index,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Size    => $size,
+            Start   => $valuePtr,
+            Format  => $formatStr,
+            Count   => $count
+        );
+        $htmlDump and HtmlDump($et, $tagTablePtr, $tagID, $value, $entry, $entrySize,
+                               %parms, Base => $dirStart);
+        $et->HandleTag($tagTablePtr, $tagID, $value, %parms);
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PhaseOne - Phase One 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 decode Phase
+One maker notes.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.cybercom.net/~dcoffin/dcraw/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PhaseOne Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhotoCD.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhotoCD.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhotoCD.pm	(revision 34921)
@@ -0,0 +1,506 @@
+#------------------------------------------------------------------------------
+# File:         PhotoCD.pm
+#
+# Description:  Read Kodak Photo CD Image Pac (PCD) metadata
+#
+# Revisions:    2012/05/07 - P. Harvey Created
+#
+# References:   1) http://pcdtojpeg.sourceforge.net/
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::PhotoCD;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.03';
+
+sub ProcessExtData($$$);
+
+# PhotoCD info
+%Image::ExifTool::PhotoCD::Main = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'Tags extracted from Kodak Photo CD Image Pac (PCD) files.',
+    7 => {
+        Name => 'SpecificationVersion',
+        Format => 'int8u[2]',
+        RawConv => '$val eq "255 255" ? "n/a" : $val',
+        ValueConv => '$val =~ tr/ /./; $val',
+    },
+    9 => {
+        Name => 'AuthoringSoftwareRelease',
+        Format => 'int8u[2]',
+        RawConv => '$val eq "255 255" ? "n/a" : $val',
+        ValueConv => '$val =~ tr/ /./; $val',
+    },
+    11 => {
+        Name => 'ImageMagnificationDescriptor',
+        Format => 'int8u[2]',
+        ValueConv => '$val =~ tr/ /./; $val',
+    },
+    13 => {
+        Name => 'CreateDate',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        RawConv => '$val == 0xffffffff ? undef : $val',
+        ValueConv => 'ConvertUnixTime($val,1)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    17 => {
+        Name => 'ModifyDate',
+        Format => 'int32u',
+        Groups => { 2 => 'Time' },
+        RawConv => '$val == 0xffffffff ? undef : $val',
+        ValueConv => 'ConvertUnixTime($val,1)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    21 => {
+        Name => 'ImageMedium',
+        PrintConv => {
+            0 => 'Color negative',
+            1 => 'Color reversal',
+            2 => 'Color hard copy',
+            3 => 'Thermal hard copy',
+            4 => 'Black and white negative',
+            5 => 'Black and white reversal',
+            6 => 'Black and white hard copy',
+            7 => 'Internegative',
+            8 => 'Synthetic image',
+        },
+    },
+    22 => {
+        Name => 'ProductType',
+        Format => 'string[20]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    42 => {
+        Name => 'ScannerVendorID',
+        Format => 'string[20]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    62 => {
+        Name => 'ScannerProductID',
+        Format => 'string[16]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    78 => {
+        Name => 'ScannerFirmwareVersion',
+        Format => 'string[4]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    82 => {
+        Name => 'ScannerFirmwareDate',
+        Format => 'string[8]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    90 => {
+        Name => 'ScannerSerialNumber',
+        Format => 'string[20]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    110 => {
+        Name => 'ScannerPixelSize',
+        Format => 'undef[2]',
+        ValueConv => 'join(".",unpack("H2H2",$val))',
+        PrintConv => '"$val micrometers"',
+    },
+    112 => {
+        Name => 'ImageWorkstationMake',
+        Format => 'string[20]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    132 => {
+        Name => 'CharacterSet',
+        PrintConv => {
+            1 => '38 characters ISO 646',
+            2 => '65 characters ISO 646',
+            3 => '95 characters ISO 646',
+            4 => '191 characters ISO 8850-1',
+            5 => 'ISO 2022',
+            6 => 'Includes characters not ISO 2375 registered',
+        },
+    },
+    133 => {
+        Name => 'CharacterEscapeSequence',
+        Format => 'undef[32]',
+        Binary => 1,
+        Unknown => 1,
+    },
+    165 => {
+        Name => 'PhotoFinisherName',
+        Format => 'string[60]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    225 => {
+        Name => 'HasSBA',
+        Format => 'undef[3]',
+        Hidden => 1,
+        RawConv => '$val eq "SBA" and $$self{HasSBA} = 1; undef',
+    },
+    228 => {
+        Name => 'SceneBalanceAlgorithmRevision',
+        Condition => '$$self{HasSBA}',
+        Format => 'int8u[2]',
+        ValueConv => '$val =~ tr/ /./; $val',
+    },
+    230 => {
+        Name => 'SceneBalanceAlgorithmCommand',
+        Condition => '$$self{HasSBA}',
+        PrintConv => {
+            0 => 'Neutral SBA On, Color SBA On',
+            1 => 'Neutral SBA Off, Color SBA Off',
+            2 => 'Neutral SBA On, Color SBA Off',
+            3 => 'Neutral SBA Off, Color SBA On',
+        },
+    },
+    325 => {
+        Name => 'SceneBalanceAlgorithmFilmID',
+        Condition => '$$self{HasSBA}',
+        Format => 'int16u',
+        PrintConv => {
+            1 => '3M ScotchColor AT 100',
+            2 => '3M ScotchColor AT 200',
+            3 => '3M ScotchColor HR2 400',
+            7 => '3M Scotch HR 200 Gen 2',
+            9 => '3M Scotch HR 400 Gen 2',
+            16 => 'Agfa Agfacolor XRS 400 Gen 1',
+            17 => 'Agfa Agfacolor XRG/XRS 400',
+            18 => 'Agfa Agfacolor XRG/XRS 200',
+            19 => 'Agfa Agfacolor XRS 1000 Gen 2',
+            20 => 'Agfa Agfacolor XRS 400 Gen 2',
+            21 => 'Agfa Agfacolor XRS/XRC 100',
+            26 => 'Fuji Reala 100 (JAPAN)',
+            27 => 'Fuji Reala 100 Gen 1',
+            28 => 'Fuji Reala 100 Gen 2',
+            29 => 'Fuji SHR 400 Gen 2',
+            30 => 'Fuji Super HG 100',
+            31 => 'Fuji Super HG 1600 Gen 1',
+            32 => 'Fuji Super HG 200',
+            33 => 'Fuji Super HG 400',
+            34 => 'Fuji Super HG 100 Gen 2',
+            35 => 'Fuji Super HR 100 Gen 1',
+            36 => 'Fuji Super HR 100 Gen 2',
+            37 => 'Fuji Super HR 1600 Gen 2',
+            38 => 'Fuji Super HR 200 Gen 1',
+            39 => 'Fuji Super HR 200 Gen 2',
+            40 => 'Fuji Super HR 400 Gen 1',
+            43 => 'Fuji NSP 160S (Pro)',
+            45 => 'Kodak Kodacolor VR 100 Gen 2',
+            47 => 'Kodak Gold 400 Gen 3',
+            55 => 'Kodak Ektar 100 Gen 1',
+            56 => 'Kodak Ektar 1000 Gen 1',
+            57 => 'Kodak Ektar 125 Gen 1',
+            58 => 'Kodak Royal Gold 25 RZ',
+            60 => 'Kodak Gold 1600 Gen 1',
+            61 => 'Kodak Gold 200 Gen 2',
+            62 => 'Kodak Gold 400 Gen 2',
+            65 => 'Kodak Kodacolor VR 100 Gen 1',
+            66 => 'Kodak Kodacolor VR 1000 Gen 2',
+            67 => 'Kodak Kodacolor VR 1000 Gen 1',
+            68 => 'Kodak Kodacolor VR 200 Gen 1',
+            69 => 'Kodak Kodacolor VR 400 Gen 1',
+            70 => 'Kodak Kodacolor VR 200 Gen 2',
+            71 => 'Kodak Kodacolor VRG 100 Gen 1',
+            72 => 'Kodak Gold 100 Gen 2',
+            73 => 'Kodak Kodacolor VRG 200 Gen 1',
+            74 => 'Kodak Gold 400 Gen 1',
+            87 => 'Kodak Ektacolor Gold 160',
+            88 => 'Kodak Ektapress 1600 Gen 1 PPC',
+            89 => 'Kodak Ektapress Gold 100 Gen 1 PPA',
+            90 => 'Kodak Ektapress Gold 400 PPB-3',
+            92 => 'Kodak Ektar 25 Professional PHR',
+            97 => 'Kodak T-Max 100 Professional',
+            98 => 'Kodak T-Max 3200 Professional',
+            99 => 'Kodak T-Max 400 Professional',
+            101 => 'Kodak Vericolor 400 Prof VPH',
+            102 => 'Kodak Vericolor III Pro',
+            121 => 'Konika Konica Color SR-G 3200',
+            122 => 'Konika Konica Color Super SR100',
+            123 => 'Konika Konica Color Super SR 400',
+            138 => 'Kodak Gold Unknown',
+            139 => 'Kodak Unknown Neg A- Normal SBA',
+            143 => 'Kodak Ektar 100 Gen 2',
+            147 => 'Kodak Kodacolor CII',
+            148 => 'Kodak Kodacolor II',
+            149 => 'Kodak Gold Plus 200 Gen 3',
+            150 => 'Kodak Internegative +10% Contrast',
+            151 => 'Agfa Agfacolor Ultra 50',
+            152 => 'Fuji NHG 400',
+            153 => 'Agfa Agfacolor XRG 100',
+            154 => 'Kodak Gold Plus 100 Gen 3',
+            155 => 'Konika Konica Color Super SR200 Gen 1',
+            156 => 'Konika Konica Color SR-G 160',
+            157 => 'Agfa Agfacolor Optima 125',
+            158 => 'Agfa Agfacolor Portrait 160',
+            162 => 'Kodak Kodacolor VRG 400 Gen 1',
+            163 => 'Kodak Gold 200 Gen 1',
+            164 => 'Kodak Kodacolor VRG 100 Gen 2',
+            174 => 'Kodak Internegative +20% Contrast',
+            175 => 'Kodak Internegative +30% Contrast',
+            176 => 'Kodak Internegative +40% Contrast',
+            184 => 'Kodak TMax-100 D-76 CI = .40',
+            185 => 'Kodak TMax-100 D-76 CI = .50',
+            186 => 'Kodak TMax-100 D-76 CI = .55',
+            187 => 'Kodak TMax-100 D-76 CI = .70',
+            188 => 'Kodak TMax-100 D-76 CI = .80',
+            189 => 'Kodak TMax-100 TMax CI = .40',
+            190 => 'Kodak TMax-100 TMax CI = .50',
+            191 => 'Kodak TMax-100 TMax CI = .55',
+            192 => 'Kodak TMax-100 TMax CI = .70',
+            193 => 'Kodak TMax-100 TMax CI = .80',
+            195 => 'Kodak TMax-400 D-76 CI = .40',
+            196 => 'Kodak TMax-400 D-76 CI = .50',
+            197 => 'Kodak TMax-400 D-76 CI = .55',
+            198 => 'Kodak TMax-400 D-76 CI = .70',
+            214 => 'Kodak TMax-400 D-76 CI = .80',
+            215 => 'Kodak TMax-400 TMax CI = .40',
+            216 => 'Kodak TMax-400 TMax CI = .50',
+            217 => 'Kodak TMax-400 TMax CI = .55',
+            218 => 'Kodak TMax-400 TMax CI = .70',
+            219 => 'Kodak TMax-400 TMax CI = .80',
+            224 => '3M ScotchColor ATG 400/EXL 400',
+            266 => 'Agfa Agfacolor Optima 200',
+            267 => 'Konika Impressa 50',
+            268 => 'Polaroid Polaroid CP 200',
+            269 => 'Konika Konica Color Super SR200 Gen 2',
+            270 => 'ILFORD XP2 400',
+            271 => 'Polaroid Polaroid Color HD2 100',
+            272 => 'Polaroid Polaroid Color HD2 400',
+            273 => 'Polaroid Polaroid Color HD2 200',
+            282 => '3M ScotchColor ATG-1 200',
+            284 => 'Konika XG 400',
+            307 => 'Kodak Universal Reversal B/W',
+            308 => 'Kodak RPC Copy Film Gen 1',
+            312 => 'Kodak Universal E6',
+            324 => 'Kodak Gold Ultra 400 Gen 4',
+            328 => 'Fuji Super G 100',
+            329 => 'Fuji Super G 200',
+            330 => 'Fuji Super G 400 Gen 2',
+            333 => 'Kodak Universal K14',
+            334 => 'Fuji Super G 400 Gen 1',
+            366 => 'Kodak Vericolor HC 6329 VHC',
+            367 => 'Kodak Vericolor HC 4329 VHC',
+            368 => 'Kodak Vericolor L 6013 VPL',
+            369 => 'Kodak Vericolor L 4013 VPL',
+            418 => 'Kodak Ektacolor Gold II 400 Prof',
+            430 => 'Kodak Royal Gold 1000',
+            431 => 'Kodak Kodacolor VR 200 / 5093',
+            432 => 'Kodak Gold Plus 100 Gen 4',
+            443 => 'Kodak Royal Gold 100',
+            444 => 'Kodak Royal Gold 400',
+            445 => 'Kodak Universal E6 auto-balance',
+            446 => 'Kodak Universal E6 illum. corr.',
+            447 => 'Kodak Universal K14 auto-balance',
+            448 => 'Kodak Universal K14 illum. corr.',
+            449 => 'Kodak Ektar 100 Gen 3 SY',
+            456 => 'Kodak Ektar 25',
+            457 => 'Kodak Ektar 100 Gen 3 CX',
+            458 => 'Kodak Ektapress Plus 100 Prof PJA-1',
+            459 => 'Kodak Ektapress Gold II 100 Prof',
+            460 => 'Kodak Pro 100 PRN',
+            461 => 'Kodak Vericolor HC 100 Prof VHC-2',
+            462 => 'Kodak Prof Color Neg 100',
+            463 => 'Kodak Ektar 1000 Gen 2',
+            464 => 'Kodak Ektapress Plus 1600 Pro PJC-1',
+            465 => 'Kodak Ektapress Gold II 1600 Prof',
+            466 => 'Kodak Super Gold 1600 GF Gen 2',
+            467 => 'Kodak Kodacolor 100 Print Gen 4',
+            468 => 'Kodak Super Gold 100 Gen 4',
+            469 => 'Kodak Gold 100 Gen 4',
+            470 => 'Kodak Gold III 100 Gen 4',
+            471 => 'Kodak Funtime 100 FA',
+            472 => 'Kodak Funtime 200 FB',
+            473 => 'Kodak Kodacolor VR 200 Gen 4',
+            474 => 'Kodak Gold Super 200 Gen 4',
+            475 => 'Kodak Kodacolor 200 Print Gen 4',
+            476 => 'Kodak Super Gold 200 Gen 4',
+            477 => 'Kodak Gold 200 Gen 4',
+            478 => 'Kodak Gold III 200 Gen 4',
+            479 => 'Kodak Gold Ultra 400 Gen 5',
+            480 => 'Kodak Super Gold 400 Gen 5',
+            481 => 'Kodak Gold 400 Gen 5',
+            482 => 'Kodak Gold III 400 Gen 5',
+            483 => 'Kodak Kodacolor 400 Print Gen 5',
+            484 => 'Kodak Ektapress Plus 400 Prof PJB-2',
+            485 => 'Kodak Ektapress Gold II 400 Prof G5',
+            486 => 'Kodak Pro 400 PPF-2',
+            487 => 'Kodak Ektacolor Gold II 400 EGP-4',
+            488 => 'Kodak Ektacolor Gold 400 Prof EGP-4',
+            489 => 'Kodak Ektapress Gold II Multspd PJM',
+            490 => 'Kodak Pro 400 MC PMC',
+            491 => 'Kodak Vericolor 400 Prof VPH-2',
+            492 => 'Kodak Vericolor 400 Plus Prof VPH-2',
+            493 => 'Kodak Unknown Neg Product Code 83',
+            505 => 'Kodak Ektacolor Pro Gold 160 GPX',
+            508 => 'Kodak Royal Gold 200',
+            517 => 'Kodak 4050000000',
+            519 => 'Kodak Gold Plus 100 Gen 5',
+            520 => 'Kodak Gold 800 Gen 1',
+            521 => 'Kodak Gold Super 200 Gen 5',
+            522 => 'Kodak Ektapress Plus 200 Prof',
+            523 => 'Kodak 4050 E6 auto-balance',
+            524 => 'Kodak 4050 E6 ilum. corr.',
+            525 => 'Kodak 4050 K14',
+            526 => 'Kodak 4050 K14 auto-balance',
+            527 => 'Kodak 4050 K14 ilum. corr.',
+            528 => 'Kodak 4050 Reversal B&W',
+            532 => 'Kodak Advantix 200',
+            533 => 'Kodak Advantix 400',
+            534 => 'Kodak Advantix 100',
+            535 => 'Kodak Ektapress Multspd Prof PJM-2',
+            536 => 'Kodak Kodacolor VR 200 Gen 5',
+            537 => 'Kodak Funtime 200 FB Gen 2',
+            538 => 'Kodak Commercial 200',
+            539 => 'Kodak Royal Gold 25 Copystand',
+            540 => 'Kodak Kodacolor DA 100 Gen 5',
+            545 => 'Kodak Kodacolor VR 400 Gen 2',
+            546 => 'Kodak Gold 100 Gen 6',
+            547 => 'Kodak Gold 200 Gen 6',
+            548 => 'Kodak Gold 400 Gen 6',
+            549 => 'Kodak Royal Gold 100 Gen 2',
+            550 => 'Kodak Royal Gold 200 Gen 2',
+            551 => 'Kodak Royal Gold 400 Gen 2',
+            552 => 'Kodak Gold Max 800 Gen 2',
+            554 => 'Kodak 4050 E6 high contrast',
+            555 => 'Kodak 4050 E6 low saturation high contrast',
+            556 => 'Kodak 4050 E6 low saturation',
+            557 => 'Kodak Universal E-6 Low Saturation',
+            558 => 'Kodak T-Max T400 CN',
+            563 => 'Kodak Ektapress PJ100',
+            564 => 'Kodak Ektapress PJ400',
+            565 => 'Kodak Ektapress PJ800',
+            567 => 'Kodak Portra 160NC',
+            568 => 'Kodak Portra 160VC',
+            569 => 'Kodak Portra 400NC',
+            570 => 'Kodak Portra 400VC',
+            575 => 'Kodak Advantix 100-2',
+            576 => 'Kodak Advantix 200-2',
+            577 => 'Kodak Advantix Black & White + 400',
+            578 => 'Kodak Ektapress PJ800-2',
+        },
+    },
+    331 => {
+        Name => 'CopyrightStatus',
+        Condition => '$$self{HasSBA}',
+        RawConv => '$$self{CopyrightStatus} = $val',
+        PrintConv => {
+            1 => 'Restrictions apply',
+            0xff => 'Not specified',
+        },
+    },
+    332 => {
+        Name => 'CopyrightFileName',
+        Condition => '$$self{CopyrightStatus} and $$self{CopyrightStatus} == 1',
+        Format => 'string[12]',
+        ValueConv => '$val =~ s/[ \0]+$//; $val',
+    },
+    1538 => {
+        Name => 'Orientation',
+        Mask => 0x03,
+        RawConv => '$$self{Orient} = $val',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 270 CW',
+            2 => 'Rotate 180',
+            3 => 'Rotate 90 CW',
+        },
+    },
+    1538.1 => {
+        Name => 'ImageWidth',
+        Mask => 0x0c,
+        # 0=Base (768x512), 1=4Base (1536x1024), 2=16Base (3072x2048)
+        ValueConv => '($$self{Orient} & 0x01 ? 512 : 768) * ($val * 2 || 1)',
+    },
+    1538.2 => {
+        Name => 'ImageHeight',
+        Mask => 0x0c,
+        ValueConv => '($$self{Orient} & 0x01 ? 768 : 512) * ($val * 2 || 1)',
+    },
+    1538.3 => {
+        Name => 'CompressionClass',
+        Mask => 0x60,
+        PrintConv => {
+            0 => 'Class 1 - 35mm film; Pictoral hard copy',
+            1 => 'Class 2 - Large format film',
+            2 => 'Class 3 - Text and graphics, high resolution',
+            3 => 'Class 4 - Text and graphics, high dynamic range',
+        },
+    },
+    #1544 => 'InterleaveRatio',
+    #1545 => 'ADPCMResolution',
+    #1546 => {
+    #    Name => 'ADPCMMagnificationPanning',
+    #    Format => 'int8u[2]',
+    #},
+    #1548 => 'ADPCMMagnificationFactor',
+    #1549 => {
+    #    Name => 'ADPCMDisplayOffset',
+    #    Format => 'int8u[2]',
+    #},
+    #1551 => 'ADPCMTransitionDescriptor',
+);
+
+#------------------------------------------------------------------------------
+# Extract information from a PhotoCD image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid PhotoCD file
+sub ProcessPCD($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+    return 0 unless $raf->Seek(2048, 0) and
+                    $raf->Read($buff, 2048) == 2048 and
+                    $buff =~ /^PCD_IPI/;
+    SetByteOrder('MM');
+    $et->SetFileType();
+    my %dirInfo = (
+        DirName => 'PhotoCD',
+        DataPt => \$buff,
+        DataPos => 4096,
+    );
+    my $tagTablePtr = GetTagTable('Image::ExifTool::PhotoCD::Main');
+    return $et->ProcessBinaryData(\%dirInfo, $tagTablePtr);
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::PhotoCD - Read Kodak Photo CD Image Pac (PCD) metadata
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains routines required by Image::ExifTool to extract
+information from Kodak Photo CD Image Pac (PCD) files.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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://pcdtojpeg.sourceforge.net/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/PhotoCD Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhotoMechanic.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhotoMechanic.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PhotoMechanic.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool::XMP;
 
-$VERSION = '1.02';
+$VERSION = '1.06';
 
 sub ProcessPhotoMechanic($$);
@@ -109,8 +109,13 @@
         Below is a list of the observed PhotoMechanic XMP tags.  The actual
         namespace prefix is "photomechanic" but ExifTool shortens this in
-        the "XMP-photomech" family 1 group name.
+        the family 1 group name.
+    },
+    ColorClass  => {
+        Writable => 'integer',
+        PrintConv => \%colorClasses,
     },
     CountryCode => { Avoid => 1, Groups => { 2 => 'Location' } },
     EditStatus  => { },
+    PMVersion   => { },
     Prefs       => {
         Notes => 'format is "Tagged:0, ColorClass:1, Rating:2, FrameNum:3"',
@@ -126,4 +131,5 @@
         },
     },
+    Tagged      => { Writable => 'boolean', PrintConv => { False => 'No', True => 'Yes' } },
     TimeCreated => {
         Avoid => 1,
@@ -143,10 +149,10 @@
 sub ProcessPhotoMechanic($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $offset = $$dirInfo{Offset} || 0;
     my $outfile = $$dirInfo{OutFile};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     my $rtnVal = 0;
     my ($buff, $footer);
@@ -159,9 +165,9 @@
 
         if ($size & 0x80000000 or not $raf->Seek(-$size-12, 1)) {
-            $exifTool->Warn('Bad PhotoMechanic trailer');
+            $et->Warn('Bad PhotoMechanic trailer');
             last;
         }
         unless ($raf->Read($buff, $size) == $size) {
-            $exifTool->Warn('Error reading PhotoMechanic trailer');
+            $et->Warn('Error reading PhotoMechanic trailer');
             last;
         }
@@ -182,18 +188,18 @@
         if (not $outfile) {
             # extract trailer information
-            $exifTool->DumpTrailer($dirInfo) if $verbose or $exifTool->{HTML_DUMP};
-            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
-        } elsif ($exifTool->{DEL_GROUP}->{PhotoMechanic}) {
+            $et->DumpTrailer($dirInfo) if $verbose or $$et{HTML_DUMP};
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        } elsif ($$et{DEL_GROUP}{PhotoMechanic}) {
             # delete the trailer
-            $verbose and printf $out "  Deleting PhotoMechanic trailer\n";
-            ++$exifTool->{CHANGED};
+            $verbose and print $out "  Deleting PhotoMechanic trailer\n";
+            ++$$et{CHANGED};
         } else {
             # rewrite the trailer
             my $newPt;
-            my $newBuff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            my $newBuff = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
             if (defined $newBuff) {
                 $newPt = \$newBuff; # write out the modified trailer
                 my $pad = 0x800 - length($newBuff);
-                if ($pad > 0 and not $exifTool->Options('Compact')) {
+                if ($pad > 0 and not $$et{OPTIONS}{Compact}{NoPadding}) {
                     # pad out to 2kB like PhotoMechanic does
                     $newBuff .= "\0" x $pad;
@@ -231,5 +237,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Photoshop.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Photoshop.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Photoshop.pm	(revision 34921)
@@ -20,4 +20,5 @@
 #               5) http://www.telegraphics.com.au/svn/psdparse/trunk/resources.c
 #               6) http://libpsd.graphest.com/files/Photoshop%20File%20Formats.pdf
+#               7) http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/
 #------------------------------------------------------------------------------
 
@@ -28,8 +29,9 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.41';
+$VERSION = '1.65';
 
 sub ProcessPhotoshop($$$);
 sub WritePhotoshop($$$);
+sub ProcessLayers($$$);
 
 # map of where information is stored in PSD image
@@ -50,4 +52,35 @@
 );
 
+# tag information for PhotoshopThumbnail and PhotoshopBGRThumbnail
+my %thumbnailInfo = (
+    Writable => 'undef',
+    Protected => 1,
+    RawConv => 'my $img=substr($val,0x1c); $self->ValidateImage(\$img,$tag)',
+    ValueConvInv => q{
+        my $et = new Image::ExifTool;
+        my @tags = qw{ImageWidth ImageHeight FileType};
+        my $info = $et->ImageInfo(\$val, @tags);
+        my ($w, $h, $type) = @$info{@tags};
+        $w and $h and $type eq 'JPEG' or warn("Not a valid JPEG image\n"), return undef;
+        my $wbytes = int(($w * 24 + 31) / 32) * 4;
+        return pack('N6n2', 1, $w, $h, $wbytes, $wbytes * $h, length($val), 24, 1) . $val;
+    },
+);
+
+# tag info to decode Photoshop Unicode string
+my %unicodeString = (
+    ValueConv => sub {
+        my ($val, $et) = @_;
+        return '<err>' if length($val) < 4;
+        my $len = unpack('N', $val) * 2;
+        return '<err>' if length($val) < 4 + $len;
+        return $et->Decode(substr($val, 4, $len), 'UCS2', 'MM');
+    },
+    ValueConvInv => sub {
+        my ($val, $et) = @_;
+        return pack('N', length $val) . $et->Encode($val, 'UCS2', 'MM');
+    },
+);
+
 # Photoshop APP13 tag table
 # (set Unknown flag for information we don't want to display normally)
@@ -74,5 +107,5 @@
     0x03f1 => { Unknown => 1, Name => 'BorderInformation' },
     0x03f2 => { Unknown => 1, Name => 'BackgroundColor' },
-    0x03f3 => { Unknown => 1, Name => 'PrintFlags' },
+    0x03f3 => { Unknown => 1, Name => 'PrintFlags', Format => 'int8u' },
     0x03f4 => { Unknown => 1, Name => 'BW_HalftoningInfo' },
     0x03f5 => { Unknown => 1, Name => 'ColorHalftoningInfo' },
@@ -82,12 +115,12 @@
     0x03f9 => { Unknown => 1, Name => 'DuotoneTransferFuncs' },
     0x03fa => { Unknown => 1, Name => 'DuotoneImageInfo' },
-    0x03fb => { Unknown => 1, Name => 'EffectiveBW' },
+    0x03fb => { Unknown => 1, Name => 'EffectiveBW', Format => 'int8u' },
     0x03fc => { Unknown => 1, Name => 'ObsoletePhotoshopTag1' },
     0x03fd => { Unknown => 1, Name => 'EPSOptions' },
     0x03fe => { Unknown => 1, Name => 'QuickMaskInfo' },
     0x03ff => { Unknown => 1, Name => 'ObsoletePhotoshopTag2' },
-    0x0400 => { Unknown => 1, Name => 'LayerStateInfo' },
+    0x0400 => { Unknown => 1, Name => 'TargetLayerID', Format => 'int16u' }, # (LayerStateInfo)
     0x0401 => { Unknown => 1, Name => 'WorkingPath' },
-    0x0402 => { Unknown => 1, Name => 'LayersGroupInfo' },
+    0x0402 => { Unknown => 1, Name => 'LayersGroupInfo', Format => 'int16u' },
     0x0403 => { Unknown => 1, Name => 'ObsoletePhotoshopTag3' },
     0x0404 => {
@@ -109,5 +142,6 @@
         Name => 'PhotoshopBGRThumbnail',
         Notes => 'this is a JPEG image, but in BGR format instead of RGB',
-        RawConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',
+        %thumbnailInfo,
+        Groups => { 2 => 'Preview' },
     },
     0x040a => {
@@ -129,5 +163,6 @@
     0x040c => {
         Name => 'PhotoshopThumbnail',
-        RawConv => 'my $img=substr($val,0x1c);$self->ValidateImage(\$img,$tag)',
+        %thumbnailInfo,
+        Groups => { 2 => 'Preview' },
     },
     0x040d => {
@@ -144,12 +179,12 @@
         },
     },
-    0x0410 => { Unknown => 1, Name => 'Watermark' },
-    0x0411 => { Unknown => 1, Name => 'ICC_Untagged' },
-    0x0412 => { Unknown => 1, Name => 'EffectsVisible' },
+    0x0410 => { Unknown => 1, Name => 'Watermark', Format => 'int8u' },
+    0x0411 => { Unknown => 1, Name => 'ICC_Untagged', Format => 'int8u' },
+    0x0412 => { Unknown => 1, Name => 'EffectsVisible', Format => 'int8u' },
     0x0413 => { Unknown => 1, Name => 'SpotHalftone' },
-    0x0414 => { Unknown => 1, Name => 'IDsBaseValue', Description => 'IDs Base Value' },
+    0x0414 => { Unknown => 1, Name => 'IDsBaseValue', Description => 'IDs Base Value', Format => 'int32u' },
     0x0415 => { Unknown => 1, Name => 'UnicodeAlphaNames' },
-    0x0416 => { Unknown => 1, Name => 'IndexedColourTableCount' },
-    0x0417 => { Unknown => 1, Name => 'TransparentIndex' },
+    0x0416 => { Unknown => 1, Name => 'IndexedColorTableCount', Format => 'int16u' },
+    0x0417 => { Unknown => 1, Name => 'TransparentIndex', Format => 'int16u' },
     0x0419 => {
         Name => 'GlobalAltitude',
@@ -158,10 +193,39 @@
         ValueConvInv => 'pack("N",$val)',
     },
-    0x041a => { Unknown => 1, Name => 'Slices' },
-    0x041b => { Unknown => 1, Name => 'WorkflowURL' },
+    0x041a => {
+        Name => 'SliceInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::SliceInfo' },
+    },
+    0x041b => { Name => 'WorkflowURL', %unicodeString },
     0x041c => { Unknown => 1, Name => 'JumpToXPEP' },
     0x041d => { Unknown => 1, Name => 'AlphaIdentifiers' },
-    0x041e => { Unknown => 1, Name => 'URL_List' },
-    0x0421 => { Unknown => 1, Name => 'VersionInfo' },
+    0x041e => {
+        Name => 'URL_List',
+        List => 1,
+        Writable => 1,
+        ValueConv => sub {
+            my ($val, $et) = @_;
+            return '<err>' if length($val) < 4;
+            my $num = unpack('N', $val);
+            my ($i, @vals);
+            my $pos = 4;
+            for ($i=0; $i<$num; ++$i) {
+                $pos += 8;  # (skip word and ID)
+                last if length($val) < $pos + 4;
+                my $len = unpack("x${pos}N", $val) * 2;
+                last if length($val) < $pos + 4 + $len;
+                push @vals, $et->Decode(substr($val,$pos+4,$len), 'UCS2', 'MM');
+                $pos += 4 + $len;
+            }
+            return \@vals;
+        },
+        # (this is tricky to make writable)
+    },
+    0x0421 => {
+        Name => 'VersionInfo',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Photoshop::VersionInfo',
+        },
+    },
     0x0422 => {
         Name => 'EXIFInfo', #PH (Found in EPS and PSD files)
@@ -184,7 +248,10 @@
         Protected => 1,
         Notes => q{
-            when writing, special values of "new" and "old" represent the digests of the
-            IPTC from the edited and original files respectively, and are undefined if
-            the IPTC does not exist in the respective file
+            this tag indicates provides a way for XMP-aware applications to indicate
+            that the XMP is synchronized with the IPTC.  When writing, special values of
+            "new" and "old" represent the digests of the IPTC from the edited and
+            original files respectively, and are undefined if the IPTC does not exist in
+            the respective file.  Set this to "new" as an indication that the XMP is
+            synchronized with the IPTC
         },
         # also note the 'new' feature requires that the IPTC comes before this tag is written
@@ -194,5 +261,5 @@
                 {
                     local $SIG{'__WARN__'} = sub { };
-                    return lc($val) if eval 'require Digest::MD5';
+                    return lc($val) if eval { require Digest::MD5 };
                 }
                 warn "Digest::MD5 must be installed\n";
@@ -204,9 +271,42 @@
         }
     },
-    0x0426 => { Unknown => 1, Name => 'PrintScale' }, #5
-    0x0428 => { Unknown => 1, Name => 'PixelAspectRatio' }, #5
+    0x0426 => {
+        Name => 'PrintScaleInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::PrintScaleInfo' },
+    },
+    0x0428 => {
+        Name => 'PixelInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::PixelInfo' },
+    },
     0x0429 => { Unknown => 1, Name => 'LayerComps' }, #5
     0x042a => { Unknown => 1, Name => 'AlternateDuotoneColors' }, #5
     0x042b => { Unknown => 1, Name => 'AlternateSpotColors' }, #5
+    0x042d => { #7
+        Name => 'LayerSelectionIDs',
+        Description => 'Layer Selection IDs',
+        Unknown => 1,
+        ValueConv => q{
+            my ($n, @a) = unpack("nN*",$val);
+            $#a = $n - 1 if $n > @a;
+            return join(' ', @a);
+        },
+    },
+    0x042e => { Unknown => 1, Name => 'HDRToningInfo' }, #7
+    0x042f => { Unknown => 1, Name => 'PrintInfo' }, #7
+    0x0430 => { Unknown => 1, Name => 'LayerGroupsEnabledID', Format => 'int8u' }, #7
+    0x0431 => { Unknown => 1, Name => 'ColorSamplersResource2' }, #7
+    0x0432 => { Unknown => 1, Name => 'MeasurementScale' }, #7
+    0x0433 => { Unknown => 1, Name => 'TimelineInfo' }, #7
+    0x0434 => { Unknown => 1, Name => 'SheetDisclosure' }, #7
+    0x0435 => { Unknown => 1, Name => 'DisplayInfo' }, #7
+    0x0436 => { Unknown => 1, Name => 'OnionSkins' }, #7
+    0x0438 => { Unknown => 1, Name => 'CountInfo' }, #7
+    0x043a => { Unknown => 1, Name => 'PrintInfo2' }, #7
+    0x043b => { Unknown => 1, Name => 'PrintStyle' }, #7
+    0x043c => { Unknown => 1, Name => 'MacintoshNSPrintInfo' }, #7
+    0x043d => { Unknown => 1, Name => 'WindowsDEVMODE' }, #7
+    0x043e => { Unknown => 1, Name => 'AutoSaveFilePath' }, #7
+    0x043f => { Unknown => 1, Name => 'AutoSaveFormat' }, #7
+    0x0440 => { Unknown => 1, Name => 'PathSelectionState' }, #7
     # 0x07d0-0x0bb6 Path information
     0x0bb7 => {
@@ -219,4 +319,9 @@
         },
     },
+    0x0bb8 => { Unknown => 1, Name => 'OriginPathInfo' }, #7
+    # 0x0fa0-0x1387 - plug-in resources (ref 7)
+    0x1b58 => { Unknown => 1, Name => 'ImageReadyVariables' }, #7
+    0x1b59 => { Unknown => 1, Name => 'ImageReadyDataSets' }, #7
+    0x1f40 => { Unknown => 1, Name => 'LightroomWorkflow' }, #7
     0x2710 => { Unknown => 1, Name => 'PrintFlagsInfo' },
 );
@@ -239,5 +344,5 @@
         PrintConv => {
             0x0000 => 'Standard',
-            0x0001 => 'Optimised',
+            0x0001 => 'Optimized',
             0x0101 => 'Progressive',
         },
@@ -251,4 +356,11 @@
         },
     },
+);
+
+# Photoshop Slices
+%Image::ExifTool::Photoshop::SliceInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    20 => { Name => 'SlicesGroupName', Format => 'var_ustr32' },
+    24 => { Name => 'NumSlices',       Format => 'int32u' },
 );
 
@@ -294,4 +406,49 @@
         },
     },
+);
+
+# Photoshop version information
+%Image::ExifTool::Photoshop::VersionInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FIRST_ENTRY => 0,
+    GROUPS => { 2 => 'Image' },
+    # (always 1) 0 => { Name => 'PhotoshopVersion', Format => 'int32u' },
+    4 => { Name => 'HasRealMergedData', Format => 'int8u', PrintConv => { 0 => 'No', 1 => 'Yes' } },
+    5 => { Name => 'WriterName', Format => 'var_ustr32' },
+    9 => { Name => 'ReaderName', Format => 'var_ustr32' },
+    # (always 1) 13 => { Name => 'FileVersion', Format => 'int32u' },
+);
+
+# Print Scale
+%Image::ExifTool::Photoshop::PrintScaleInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FIRST_ENTRY => 0,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'PrintStyle',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Centered',
+            1 => 'Size to Fit',
+            2 => 'User Defined',
+        },
+    },
+    2  => { Name => 'PrintPosition', Format => 'float[2]' },
+    10 => { Name => 'PrintScale',    Format => 'float' },
+);
+
+# Pixel Aspect Ratio
+%Image::ExifTool::Photoshop::PixelInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FIRST_ENTRY => 0,
+    GROUPS => { 2 => 'Image' },
+    # 0 - version
+    4 => { Name => 'PixelAspectRatio', Format => 'double' },
 );
 
@@ -322,4 +479,134 @@
 );
 
+# Layer information
+%Image::ExifTool::Photoshop::Layers = (
+    PROCESS_PROC => \&ProcessLayers,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'Tags extracted from Photoshop layer information.',
+    # tags extracted from layer information
+    # (tag ID's are for convenience only)
+    _xcnt => { Name => 'LayerCount', Format => 'int16u' },
+    _xrct => {
+        Name => 'LayerRectangles',
+        Format => 'int32u',
+        Count => 4,
+        List => 1,
+        Notes => 'top left bottom right',
+    },
+    _xnam => { Name => 'LayerNames',
+        Format => 'string',
+        List => 1,
+        ValueConv => q{
+            my $charset = $self->Options('CharsetPhotoshop') || 'Latin';
+            return $self->Decode($val, $charset);
+        },
+    },
+    _xbnd => {
+        Name => 'LayerBlendModes',
+        Format => 'undef',
+        List => 1,
+        RawConv => 'GetByteOrder() eq "II" ? pack "N*", unpack "V*", $val : $val',
+        PrintConv => {
+            pass => 'Pass Through',
+            norm => 'Normal',
+            diss => 'Dissolve',
+            dark => 'Darken',
+           'mul '=> 'Multiply',
+            idiv => 'Color Burn',
+            lbrn => 'Linear Burn',
+            dkCl => 'Darker Color',
+            lite => 'Lighten',
+            scrn => 'Screen',
+           'div '=> 'Color Dodge',
+            lddg => 'Linear Dodge',
+            lgCl => 'Lighter Color',
+            over => 'Overlay',
+            sLit => 'Soft Light',
+            hLit => 'Hard Light',
+            vLit => 'Vivid Light',
+            lLit => 'Linear Light',
+            pLit => 'Pin Light',
+            hMix => 'Hard Mix',
+            diff => 'Difference',
+            smud => 'Exclusion',
+            fsub => 'Subtract',
+            fdiv => 'Divide',
+           'hue '=> 'Hue',
+           'sat '=> 'Saturation',
+            colr => 'Color',
+           'lum '=> 'Luminosity',
+        },
+    },
+    _xopc  => {
+        Name => 'LayerOpacities',
+        Format => 'int8u',
+        List => 1,
+        ValueConv => '100 * $val / 255',
+        PrintConv => 'sprintf("%d%%",$val)',
+    },
+    # tags extracted from additional layer information (tag ID's are real)
+    # - must be able to accommodate a blank entry to preserve the list ordering
+    luni => {
+        Name => 'LayerUnicodeNames',
+        List => 1,
+        RawConv => q{
+            return '' if length($val) < 4;
+            my $len = Get32u(\$val, 0);
+            return $self->Decode(substr($val, 4, $len * 2), 'UCS2');
+        },
+    },
+    lyid => {
+        Name => 'LayerIDs',
+        Description => 'Layer IDs',
+        Format => 'int32u',
+        List => 1,
+        Unknown => 1,
+    },
+    shmd => { # layer metadata (undocumented structure)
+        # (for now, only extract layerTime.  May also contain "layerXMP" --
+        #  it would be nice to decode this but I need a sample)
+        Name => 'LayerModifyDates',
+        Groups => { 2 => 'Time' },
+        List => 1,
+        RawConv => q{
+            return '' unless $val =~ /layerTime(doub|buod)(.{8})/s;
+            my $tmp = $2;
+            return GetDouble(\$tmp, 0);
+        },
+        ValueConv => 'length $val ? ConvertUnixTime($val,1) : ""',
+        PrintConv => 'length $val ? $self->ConvertDateTime($val) : ""',
+    },
+);
+
+# tags extracted from ImageSourceData found in TIFF images (ref PH)
+%Image::ExifTool::Photoshop::DocumentData = (
+    PROCESS_PROC => \&ProcessDocumentData,
+    GROUPS => { 2 => 'Image' },
+    Layr => {
+        Name => 'Layers',
+        SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Layers' },
+    },
+    Lr16 => { # (NC)
+        Name => 'Layers',
+        SubDirectory => { TagTable => 'Image::ExifTool::Photoshop::Layers' },
+    },
+);
+
+# image data
+%Image::ExifTool::Photoshop::ImageData = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    0 => {
+        Name => 'Compression',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Uncompressed',
+            1 => 'RLE',
+            2 => 'ZIP without prediction',
+            3 => 'ZIP with prediction',
+        },
+    },
+);
+
 # tags for unknown resource types
 %Image::ExifTool::Photoshop::Unknown = (
@@ -345,5 +632,5 @@
 sub ConvertPascalString($$)
 {
-    my ($exifTool, $inStr) = @_;
+    my ($et, $inStr) = @_;
     my $outStr = '';
     my $len = length($inStr);
@@ -356,6 +643,252 @@
         $i += $n + 1;
     }
-    my $charset = $exifTool->Options('CharsetPhotoshop') || 'Latin';
-    return $exifTool->Decode($outStr, $charset);
+    my $charset = $et->Options('CharsetPhotoshop') || 'Latin';
+    return $et->Decode($outStr, $charset);
+}
+
+#------------------------------------------------------------------------------
+# Process Photoshop layers and mask information section of PSD/PSB file
+# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
+# Returns: 1 on success (and seeks to the end of this section)
+sub ProcessLayersAndMask($$$)
+{
+    local $_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $fileType = $$et{VALUE}{FileType};
+    my $data;
+
+    return 0 unless $fileType eq 'PSD' or $fileType eq 'PSB';   # (no layer section in CS1 files)
+
+    # (some words are 4 bytes in PSD files and 8 bytes in PSB)
+    my ($psb, $psiz) = $fileType eq 'PSB' ? (1, 8) : (undef, 4);
+
+    # read the layer information header
+    my $n = $psiz * 2 + 2;
+    $raf->Read($data, $n) == $n or return 0;
+    my $tot = $psb ? Get64u(\$data, 0) : Get32u(\$data, 0); # length of layer and mask info
+    return 1 if $tot == 0;
+    my $end = $raf->Tell() - $psiz - 2 + $tot;
+    $data = substr $data, $psiz;
+    my $len = $psb ? Get64u(\$data, 0) : Get32u(\$data, 0); # length of layer info section
+    my $num = Get16s(\$data, $psiz);
+    # 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) {
+            $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;
+        }
+    }
+    $len += 2;  # include layer count with layer info section
+    $raf->Seek(-2, 1) or return 0;
+    my %dinfo = (
+        RAF => $raf,
+        DirLen => $len,
+    );
+    $$et{IsPSB} = $psb; # set PSB flag
+    ProcessLayers($et, \%dinfo, $tagTablePtr);
+
+    # seek to the end of this section and return success flag
+    return $raf->Seek($end, 0) ? 1 : 0;
+}
+
+#------------------------------------------------------------------------------
+# Process Photoshop layers (beginning with layer count)
+# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
+# Returns: 1 on success
+# Notes: Uses ExifTool IsPSB member to determine whether file is PSB format
+sub ProcessLayers($$$)
+{
+    local $_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my ($i, $n, %count, $buff, $buf2);
+    my $raf = $$dirInfo{RAF};
+    my $dirLen = $$dirInfo{DirLen};
+    my $verbose = $$et{OPTIONS}{Verbose};
+    my %dinfo = ( DataPt => \$buff, Base => $raf->Tell() );
+    my $pos = 0;
+    return 0 if $dirLen < 2;
+    $raf->Read($buff, 2) == 2 or return 0;
+    my $num = Get16s(\$buff, 0);
+    $num = -$num if $num < 0;       # (first channel is transparency data if negative)
+    $et->VerboseDir('Layers', $num, $dirLen);
+    $et->HandleTag($tagTablePtr, '_xcnt', $num, Start => $pos, Size => 2, %dinfo); # LayerCount
+    my $oldIndent = $$et{INDENT};
+    $$et{INDENT} .= '| ';
+
+    $pos += 2;
+    my $psb = $$et{IsPSB};  # is PSB format?
+    my $psiz = $psb ? 8 : 4;
+    for ($i=0; $i<$num; ++$i) {
+        $et->VPrint(0, $oldIndent.'+ [Layer '.($i+1)." of $num]\n");
+        last if $pos + 18 > $dirLen;
+        $raf->Read($buff, 18) == 18 or last;
+        $dinfo{DataPos} = $pos;
+        # save the layer rectangle
+        $et->HandleTag($tagTablePtr, '_xrct', undef, Start => 0, Size => 16, %dinfo);
+        my $numChannels = Get16u(\$buff, 16);
+        $n = (2 + $psiz) * $numChannels;    # size of channel information
+        $raf->Seek($n, 1) or last;
+        $pos += 18 + $n;
+        last if $pos + 20 > $dirLen;
+        $raf->Read($buff, 20) == 20 or last;
+        $dinfo{DataPos} = $pos;
+        my $sig = substr($buff, 0, 4);
+        $sig =~ /^(8BIM|MIB8)$/ or last;    # verify signature
+        $et->HandleTag($tagTablePtr, '_xbnd', undef, Start => 4, Size => 4, %dinfo);
+        $et->HandleTag($tagTablePtr, '_xopc', undef, Start => 8, Size => 1, %dinfo);
+        my $nxt = $pos + 16 + Get32u(\$buff, 12);
+        $n = Get32u(\$buff, 16);        # get size of layer mask data
+        $pos += 20 + $n;                # skip layer mask data
+        last if $pos + 4 > $dirLen;
+        $raf->Seek($n, 1) and $raf->Read($buff, 4) == 4 or last;
+        $n = Get32u(\$buff, 0);         # get size of layer blending ranges
+        $pos += 4 + $n;                 # skip layer blending ranges data
+        last if $pos + 1 > $dirLen;
+        $raf->Seek($n, 1) and $raf->Read($buff, 1) == 1 or last;
+        $n = Get8u(\$buff, 0);          # get length of layer name
+        last if $pos + 1 + $n > $dirLen;
+        $raf->Read($buff, $n) == $n or last;
+        $dinfo{DataPos} = $pos + 1;
+        $et->HandleTag($tagTablePtr, '_xnam', undef, Start => 0, Size => $n, %dinfo);
+        my $frag = ($n + 1) & 0x3;
+        $raf->Seek(4 - $frag, 1) or last if $frag;
+        $n = ($n + 4) & 0xfffffffc;     # +1 for length byte then pad to multiple of 4 bytes
+        $pos += $n;
+        # process additional layer info
+        while ($pos + 12 <= $nxt) {
+            $raf->Read($buff, 12) == 12 or last;
+            my $dat = substr($buff, 0, 8);
+            $dat = pack 'N*', unpack 'V*', $dat if GetByteOrder() eq 'II';
+            my $sig = substr($dat, 0, 4);
+            last unless $sig eq '8BIM' or $sig eq '8B64';   # verify signature
+            my $tag = substr($dat, 4, 4);
+            # (some structures have an 8-byte size word [augh!]
+            # --> it would be great if '8B64' indicated a 64-bit version, and this may well
+            # be the case, but it is not mentioned in the Photoshop file format specification)
+            if ($psb and $tag =~ /^(LMsk|Lr16|Lr32|Layr|Mt16|Mt32|Mtrn|Alph|FMsk|lnk2|FEid|FXid|PxSD)$/) {
+                last if $pos + 16 > $nxt;
+                $raf->Read($buf2, 4) == 4 or last;
+                $buff .= $buf2;
+                $n = Get64u(\$buff, 8);
+                $pos += 4;
+            } else {
+                $n = Get32u(\$buff, 8);
+            }
+            $pos += 12;
+            last if $pos + $n > $nxt;
+            $frag = $n & 0x3;
+            if ($$tagTablePtr{$tag} or $verbose) {
+                # pad with empty entries if necessary to keep the same index for each item in the layer
+                $count{$tag} = 0 unless defined $count{$tag};
+                $raf->Read($buff, $n) == $n or last;
+                $dinfo{DataPos} = $pos;
+                while ($count{$tag} < $i) {
+                    $et->HandleTag($tagTablePtr, $tag, '');
+                    ++$count{$tag};
+                }
+                $et->HandleTag($tagTablePtr, $tag, undef, Start => 0, Size => $n, %dinfo);
+                ++$count{$tag};
+                if ($frag) {
+                    $raf->Seek(4 - $frag, 1) or last;
+                    $n += 4 - $frag;    # pad to multiple of 4 bytes (PH NC)
+                }
+            } else {
+                $n += 4 - $frag if $frag;
+                $raf->Seek($n, 1) or last;
+            }
+            $pos += $n; # step to start of next structure
+        }
+        $pos = $nxt;
+    }
+    $$et{INDENT} = $oldIndent;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Photoshop ImageSourceData
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessDocumentData($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $$et{OPTIONS}{Verbose};
+    my $raf = $$dirInfo{RAF};
+    my $dirLen = $$dirInfo{DirLen};
+    my $pos = 36;   # length of header
+    my ($buff, $n, $err);
+
+    $et->VerboseDir('Photoshop Document Data', undef, $dirLen);
+    unless ($raf) {
+        my $dataPt = $$dirInfo{DataPt};
+        my $start = $$dirInfo{DirStart} || 0;
+        $raf = new File::RandomAccess($dataPt);
+        $raf->Seek($start, 0) if $start;
+        $dirLen = length $$dataPt - $start unless defined $dirLen;
+        $et->VerboseDump($dataPt, Start => $start, Len => $dirLen, Base => $$dirInfo{Base});
+    }
+    unless ($raf->Read($buff, $pos) == $pos and
+            $buff =~ /^Adobe Photoshop Document Data (Block|V0002)\0/)
+    {
+        $et->Warn('Invalid Photoshop Document Data');
+        return 0;
+    }
+    my $psb = ($1 eq 'V0002');
+    my %dinfo = ( DataPt => \$buff );
+    $$et{IsPSB} = $psb; # set PSB flag (needed when handling Layers directory)
+    while ($pos + 12 <= $dirLen) {
+        $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);
+        $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)$/) {
+            $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 $err = 'Error reading PSD resource', last;
+            $n = Get32u(\$buff, 0);
+        }
+        $pos += 12;
+        $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) {
+            if ($tagInfo and $$tagInfo{SubDirectory}) {
+                my $fpos = $raf->Tell() + $n + $pad;
+                my $subTable = GetTagTable($$tagInfo{SubDirectory}{TagTable});
+                $et->ProcessDirectory({ RAF => $raf, DirLen => $n }, $subTable);
+                $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 $err = 'Error reading photoshop resource', last;
+                $et->HandleTag($tagTablePtr, $tag, undef, %dinfo);
+                $raf->Seek($pad, 1) or $err = 'Seek error', last;
+            }
+        } else {
+            $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;
 }
 
@@ -367,16 +900,33 @@
 sub ProcessPhotoshop($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart};
     my $dirEnd = $pos + $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $success = 0;
 
+    # ignore non-standard XMP while in strict MWG compatibility mode
+    if (($Image::ExifTool::MWG::strict or $et->Options('Validate')) and
+        $$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
+    {
+        my $path = $et->MetadataPath();
+        unless ($path =~ /^(JPEG-APP13-Photoshop|TIFF-IFD0-Photoshop|PSD)$/) {
+            if ($Image::ExifTool::MWG::strict) {
+                $et->Warn("Ignored non-standard Photoshop at $path");
+                return 1;
+            } else {
+                $et->Warn("Non-standard Photoshop at $path", 1);
+            }
+        }
+    }
+    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 $exifTool->VerboseDir('Photoshop', 0, $$dirInfo{DirLen});
+    $verbose and $et->VerboseDir('Photoshop', 0, $$dirInfo{DirLen});
 
     # scan through resource blocks:
-    # Format: 0) Type, 4 bytes - '8BIM' (or the rare 'PHUT', 'DCSR' or 'AgHg')
+    # Format: 0) Type, 4 bytes - '8BIM' (or the rare 'PHUT', 'DCSR', 'AgHg' or 'MeSa')
     #         1) TagID,2 bytes
     #         2) Name, pascal string padded to even no. bytes
@@ -388,9 +938,9 @@
         if ($type eq '8BIM') {
             $ttPtr = $tagTablePtr;
-        } elsif ($type =~ /^(PHUT|DCSR|AgHg)$/) {
+        } elsif ($type =~ /^(PHUT|DCSR|AgHg|MeSa)$/) { # (PHUT~ImageReady, MeSa~PhotoDeluxe)
             $ttPtr = GetTagTable('Image::ExifTool::Photoshop::Unknown');
         } else {
             $type =~ s/([^\w])/sprintf("\\x%.2x",ord($1))/ge;
-            $exifTool->Warn(qq{Bad Photoshop IRB resource "$type"});
+            $et->Warn(qq{Bad Photoshop IRB resource "$type"});
             last;
         }
@@ -403,5 +953,5 @@
         ++$pos unless $nameLen & 0x01;
         if ($pos + 4 > $dirEnd) {
-            $exifTool->Warn("Bad Photoshop resource block");
+            $et->Warn("Bad Photoshop resource block");
             last;
         }
@@ -409,5 +959,5 @@
         $pos += 4;
         if ($size + $pos > $dirEnd) {
-            $exifTool->Warn("Bad Photoshop resource data size $size");
+            $et->Warn("Bad Photoshop resource data size $size");
             last;
         }
@@ -419,5 +969,5 @@
             $name = '';
         }
-        my $tagInfo = $exifTool->GetTagInfo($ttPtr, $tag);
+        my $tagInfo = $et->GetTagInfo($ttPtr, $tag);
         # append resource name to value if requested (braced by "/#...#/")
         if ($tagInfo and defined $$tagInfo{SetResourceName} and
@@ -426,5 +976,5 @@
             $val = substr($$dataPt, $pos, $size) . '/#' . $name . '#/';
         }
-        $exifTool->HandleTag($ttPtr, $tag, $val,
+        $et->HandleTag($ttPtr, $tag, $val,
             TagInfo => $tagInfo,
             Extra   => $extra,
@@ -433,4 +983,5 @@
             Size    => $size,
             Start   => $pos,
+            Base    => $$dirInfo{Base},
             Parent  => $$dirInfo{DirName},
         );
@@ -438,4 +989,5 @@
         $pos += $size;
     }
+    delete $$et{LOW_PRIORITY_DIR}{'*'};
     return $success;
 }
@@ -447,5 +999,5 @@
 sub ProcessPSD($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
@@ -455,5 +1007,5 @@
     $data =~ /^8BPS\0([\x01\x02])/ or return 0;
     SetByteOrder('MM');
-    $exifTool->SetFileType($1 eq "\x01" ? 'PSD' : 'PSB'); # set the FileType tag
+    $et->SetFileType($1 eq "\x01" ? 'PSD' : 'PSB'); # set the FileType tag
     my %dirInfo = (
         DataPt => \$data,
@@ -467,12 +1019,13 @@
         Write($outfile, $data) or $err = 1; # write color mode data
         # initialize map of where things are written
-        $exifTool->InitWriteDirs(\%psdMap);
+        $et->InitWriteDirs(\%psdMap);
     } else {
         # process the header
         $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Header');
         $dirInfo{DirLen} = 30;
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         $raf->Seek($len, 1) or $err = 1;    # skip over color mode data
     }
+    # read image resource section
     $raf->Read($data, 4) == 4 or $err = 1;
     $len = Get32u(\$data, 0);
@@ -483,5 +1036,5 @@
     if ($outfile) {
         # rewrite IRB resources
-        $data = WritePhotoshop($exifTool, \%dirInfo, $tagTablePtr);
+        $data = WritePhotoshop($et, \%dirInfo, $tagTablePtr);
         if ($data) {
             $len = Set32u(length $data);
@@ -493,5 +1046,5 @@
                 $$trailInfo{OutFile} = \$tbuf;  # rewrite trailer(s)
                 # rewrite all trailers to buffer
-                if ($exifTool->ProcessTrailers($trailInfo)) {
+                if ($et->ProcessTrailers($trailInfo)) {
                     my $copyBytes = $$trailInfo{DataPos} - $raf->Tell();
                     if ($copyBytes >= 0) {
@@ -504,7 +1057,7 @@
                         }
                         # write the trailer (or not)
-                        $exifTool->WriteTrailerBuffer($trailInfo, $outfile) or $err = 1;
+                        $et->WriteTrailerBuffer($trailInfo, $outfile) or $err = 1;
                     } else {
-                        $exifTool->Warn('Overlapping trailer');
+                        $et->Warn('Overlapping trailer');
                         undef $trailInfo;
                     }
@@ -524,10 +1077,28 @@
         $rtnVal = -1 if $err;
     } elsif ($err) {
-        $exifTool->Warn('File format error');
+        $et->Warn('File format error');
     } else {
-        ProcessPhotoshop($exifTool, \%dirInfo, $tagTablePtr);
+        # read IRB resources
+        ProcessPhotoshop($et, \%dirInfo, $tagTablePtr);
+        # read layer and mask information section
+        $dirInfo{RAF} = $raf;
+        $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::Layers');
+        my $oldIndent = $$et{INDENT};
+        $$et{INDENT} .= '| ';
+        if (ProcessLayersAndMask($et, \%dirInfo, $tagTablePtr) and
+            # read compression mode from image data section
+            $raf->Read($data,2) == 2)
+        {
+            my %dirInfo = (
+                DataPt  => \$data,
+                DataPos => $raf->Tell() - 2,
+            );
+            $tagTablePtr = GetTagTable('Image::ExifTool::Photoshop::ImageData');
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        }
+        $$et{INDENT} = $oldIndent;
         # process trailers if they exist
         my $trailInfo = Image::ExifTool::IdentifyTrailer($raf);
-        $exifTool->ProcessTrailers($trailInfo) if $trailInfo;
+        $et->ProcessTrailers($trailInfo) if $trailInfo;
     }
     return $rtnVal;
@@ -567,5 +1138,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -583,4 +1154,6 @@
 
 =item L<http://libpsd.graphest.com/files/Photoshop%20File%20Formats.pdf>
+
+=item L<http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/>
 
 =back
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PostScript.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PostScript.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PostScript.pm	(revision 34921)
@@ -17,5 +17,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.33';
+$VERSION = '1.44';
 
 sub WritePS($$);
@@ -39,4 +39,5 @@
         Writable => 'string',
         PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
     },
     Creator     => { Priority => 0, Writable => 'string' },
@@ -50,4 +51,5 @@
         Writable => 'string',
         PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
     },
     Pages       => { Priority => 0 },
@@ -76,4 +78,5 @@
     },
     TIFFPreview => {
+        Groups => { 2 => 'Preview' },
         Binary => 1,
         Notes => q{
@@ -87,12 +90,37 @@
             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 '%')
+    AI9_ColorModel => {
+        Name => 'AIColorModel',
+        PrintConv => {
+            1 => 'RGB',
+            2 => 'CMYK',
+        },
+    },
+    AI3_ColorUsage       => { Name => 'AIColorUsage' },
+    AI5_RulerUnits       => {
+        Name => 'AIRulerUnits',
+        PrintConv => {
+            0 => 'Inches',
+            1 => 'Millimeters',
+            2 => 'Points',
+            3 => 'Picas',
+            4 => 'Centimeters',
+            6 => 'Pixels',
+        },
+    },
+    AI5_TargetResolution => { Name => 'AITargetResolution' },
+    AI5_NumLayers        => { Name => 'AINumLayers' },
+    AI5_FileFormat       => { Name => 'AIFileFormat' },
+    AI8_CreatorVersion   => { Name => 'AICreatorVersion' }, # (double leading '%')
+    AI12_BuildNumber     => { Name => 'AIBuildNumber' },
 );
 
@@ -159,9 +187,9 @@
 sub PSErr($$)
 {
-    my ($exifTool, $str) = @_;
+    my ($et, $str) = @_;
     # set file type if not done already
-    my $ext = $$exifTool{FILE_EXT};
-    $exifTool->SetFileType(($ext and $ext eq 'AI') ? 'AI' : 'PS');
-    $exifTool->Warn("PostScript format error ($str)");
+    my $ext = $$et{FILE_EXT};
+    $et->SetFileType(($ext and $ext eq 'AI') ? 'AI' : 'PS');
+    $et->Warn("PostScript format error ($str)");
     return 1;
 }
@@ -181,7 +209,7 @@
     $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) {
@@ -195,4 +223,95 @@
 
 #------------------------------------------------------------------------------
+# 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
@@ -206,17 +325,5 @@
     # check for continuation comments
     for (;;) {
-        unless (@$lines) {
-            my $buff;
-            $raf->ReadLine($buff) or last;
-            my $altnl = $/ eq "\x0d" ? "\x0a" : "\x0d";
-            if ($buff =~ /$altnl/) {
-                # 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 $/;
-            } 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
@@ -317,11 +424,14 @@
 sub ProcessPS($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
-    my $embedded = $exifTool->Options('ExtractEmbedded');
+    my $embedded = $et->Options('ExtractEmbedded');
     my ($data, $dos, $endDoc, $fontTable, $comment);
 
     # allow read from data
-    $raf = new File::RandomAccess($$dirInfo{DataPt}) unless $raf;
+    unless ($raf) {
+        $raf = new File::RandomAccess($$dirInfo{DataPt});
+        $et->VerboseDir('PostScript');
+    }
 #
 # determine if this is a postscript file
@@ -338,9 +448,11 @@
         $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($exifTool, 'invalid header');
-        }
+            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)
@@ -348,5 +460,5 @@
         $data .= $d2 if $raf->Read($d2,12);
         if ($data =~ /^%!(PS-(AdobeFont-|Bitstream )|FontType1-)/) {
-            $exifTool->SetFileType('PFA');  # PostScript ASCII font file
+            $et->SetFileType('PFA');  # PostScript ASCII font file
             $fontTable = GetTagTable('Image::ExifTool::Font::PSInfo');
             # PostScript font files may contain an unformatted comments which may
@@ -360,5 +472,5 @@
 #
     local $/ = GetInputRecordSeparator($raf);
-    $/ or return PSErr($exifTool, 'invalid PS data');
+    $/ or return PSErr($et, 'invalid PS data');
 
     # set file type (PostScript or EPS)
@@ -378,5 +490,6 @@
         $raf->Seek($pos, 0);
     }
-    $exifTool->SetFileType($type);
+    $et->SetFileType($type);
+    return 1 if $$et{OPTIONS}{FastScan} and $$et{OPTIONS}{FastScan} == 3;
 #
 # extract TIFF information from DOS header
@@ -389,9 +502,9 @@
             # extract the TIFF preview
             my $len = Get32u(\$dos, 20);
-            my $val = $exifTool->ExtractBinary($base, $len, 'TIFFPreview');
+            my $val = $et->ExtractBinary($base, $len, 'TIFFPreview');
             if (defined $val and $val =~ /^(MM\0\x2a|II\x2a\0|Binary)/) {
-                $exifTool->HandleTag($tagTablePtr, 'TIFFPreview', $val);
+                $et->HandleTag($tagTablePtr, 'TIFFPreview', $val);
             } else {
-                $exifTool->Warn('Bad TIFF preview image');
+                $et->Warn('Bad TIFF preview image');
             }
             # extract information from TIFF in DOS header
@@ -402,5 +515,5 @@
                 Base => $base,
             );
-            $exifTool->ProcessTIFF(\%dirInfo) or $exifTool->Warn('Bad embedded TIFF');
+            $et->ProcessTIFF(\%dirInfo) or $et->Warn('Bad embedded TIFF');
             # position file pointer to extract PS information
             $raf->Seek($pos, 0);
@@ -453,5 +566,5 @@
             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') {
@@ -475,5 +588,5 @@
             $docNum =~ s/-?(\d+)$//;        # decrement nesting level
             $subDocNum = $1;                # remember our last sub-document number
-            $$exifTool{DOC_NUM} = $docNum;
+            $$et{DOC_NUM} = $docNum;
             undef $endDoc unless $docNum;   # done with document if top level
             next;
@@ -504,12 +617,12 @@
                 } else {
                     # this is the Nth document
-                    $docNum = $$exifTool{DOC_COUNT} + 1;
+                    $docNum = $$et{DOC_COUNT} + 1;
                 }
                 $subDocNum = 0; # new level, so reset subDocNum
                 next unless $embedded;  # skip over this document
                 # set document number for family 4-7 group names
-                $$exifTool{DOC_NUM} = $docNum;
-                $$exifTool{LIST_TAGS} = { };  # don't build lists across different documents
-                $exifTool->{PROCESSED} = { }; # re-initialize processed directory lookup too
+                $$et{DOC_NUM} = $docNum;
+                $$et{LIST_TAGS} = { };  # don't build lists across different documents
+                $$et{PROCESSED} = { }; # re-initialize processed directory lookup too
                 $endDoc = $endToken;          # parse to EndDocument token
                 # reset mode to allow parsing into sub-directories
@@ -521,5 +634,5 @@
                     # remove brackets if necessary
                     $docName = $1 if $docName =~ /^\((.*)\)$/;
-                    $exifTool->HandleTag($tagTablePtr, 'EmbeddedFileName', $docName);
+                    $et->HandleTag($tagTablePtr, 'EmbeddedFileName', $docName);
                 }
             }
@@ -531,17 +644,17 @@
             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' to have single leading '%'
-            next unless $data =~ /^%%/ or $1 eq 'ImageData';
+            # only allow 'ImageData' and AI tags to have single leading '%'
+            next unless $data =~ /^%(%|AI\d+_)/ or $tag eq 'ImageData';
             # decode comment string (reading continuation lines if necessary)
             $val = DecodeComment($val, $raf, \@lines);
-            $exifTool->HandleTag($tagTablePtr, $tag, $val);
+            $et->HandleTag($tagTablePtr, $tag, $val);
             next;
         } elsif ($embedded and $data =~ /^%AI12_CompressedData/) {
             # the rest of the file is compressed
-            unless (eval 'require Compress::Zlib') {
-                $exifTool->Warn('Install Compress::Zlib to extract compressed embedded data');
+            unless (eval { require Compress::Zlib }) {
+                $et->Warn('Install Compress::Zlib to extract compressed embedded data');
                 last;
             }
@@ -554,10 +667,10 @@
             last unless $data =~ s/.*?%AI12_CompressedData//;
             my $inflate = Compress::Zlib::inflateInit();
-            $inflate or $exifTool->Warn('Error initializing inflate'), last;
+            $inflate or $et->Warn('Error initializing inflate'), last;
             # generate a PS-like file in memory from the compressed data
-            my $verbose = $exifTool->Options('Verbose');
+            my $verbose = $et->Options('Verbose');
             if ($verbose > 1) {
-                $exifTool->VerboseDir('AI12_CompressedData (first 4kB)');
-                $exifTool->VerboseDump(\$data);
+                $et->VerboseDir('AI12_CompressedData (first 4kB)');
+                $et->VerboseDump(\$data);
             }
             # remove header if it exists (Windows AI files only)
@@ -578,12 +691,12 @@
                 $raf->Read($data, 65536) or last;
             }
-            defined $val or $exifTool->Warn('Error inflating AI compressed data'), last;
+            defined $val or $et->Warn('Error inflating AI compressed data'), last;
             if ($verbose > 1) {
-                $exifTool->VerboseDir('Uncompressed AI12 Data');
-                $exifTool->VerboseDump(\$val);
+                $et->VerboseDir('Uncompressed AI12 Data');
+                $et->VerboseDump(\$val);
             }
             # extract information from embedded images in the uncompressed data
             $val =  # add PS header in case it needs one
-            ProcessPS($exifTool, { DataPt => \$val });
+            ProcessPS($et, { DataPt => \$val });
             last;
         } elsif ($fontTable) {
@@ -596,5 +709,5 @@
                 } elsif ($data !~ /^%/) {
                     # stop extracting comments at the first non-comment line
-                    $exifTool->FoundTag('Comment', $comment) if length $comment;
+                    $et->FoundTag('Comment', $comment) if length $comment;
                     undef $comment;
                 }
@@ -607,5 +720,5 @@
                     $val = $1;
                 }
-                $exifTool->HandleTag($fontTable, $tag, $val);
+                $et->HandleTag($fontTable, $tag, $val);
             } elsif ($data =~ /^currentdict end/) {
                 # only extract tags from initial FontInfo dict
@@ -625,6 +738,6 @@
         );
         my $subTablePtr = GetTagTable("Image::ExifTool::${mode}::Main");
-        unless ($exifTool->ProcessDirectory(\%dirInfo, $subTablePtr)) {
-            $exifTool->Warn("Error processing $mode information in PostScript file");
+        unless ($et->ProcessDirectory(\%dirInfo, $subTablePtr)) {
+            $et->Warn("Error processing $mode information in PostScript file");
         }
         undef $buff;
@@ -632,5 +745,5 @@
     }
     $mode = 'Document' if $endDoc and not $mode;
-    $mode and PSErr($exifTool, "unterminated $mode data");
+    $mode and PSErr($et, "unterminated $mode data");
     return 1;
 }
@@ -665,5 +778,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PrintIM.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PrintIM.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/PrintIM.pm	(revision 34921)
@@ -13,5 +13,5 @@
 use Image::ExifTool qw(:DataAccess);
 
-$VERSION = '1.06';
+$VERSION = '1.07';
 
 sub ProcessPrintIM($$$);
@@ -43,20 +43,20 @@
 sub ProcessPrintIM($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $offset = $$dirInfo{DirStart};
     my $size = $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     unless ($size) {
-        $exifTool->Warn('Empty PrintIM data', 1);
+        $et->Warn('Empty PrintIM data', 1);
         return 0;
     }
     unless ($size > 15) {
-        $exifTool->Warn('Bad PrintIM data');
+        $et->Warn('Bad PrintIM data');
         return 0;
     }
     unless (substr($$dataPt, $offset, 7) eq 'PrintIM') {
-        $exifTool->Warn('Invalid PrintIM header');
+        $et->Warn('Invalid PrintIM header');
         return 0;
     }
@@ -68,10 +68,10 @@
         $num = Get16u($dataPt, $offset + 14);
         if ($size < 16 + $num * 6) {
-            $exifTool->Warn('Bad PrintIM size');
+            $et->Warn('Bad PrintIM size');
             return 0;
         }
     }
-    $verbose and $exifTool->VerboseDir('PrintIM', $num);
-    $exifTool->HandleTag($tagTablePtr, 'PrintIMVersion', substr($$dataPt, $offset + 8, 4),
+    $verbose and $et->VerboseDir('PrintIM', $num);
+    $et->HandleTag($tagTablePtr, 'PrintIMVersion', substr($$dataPt, $offset + 8, 4),
         DataPt => $dataPt,
         Start  => $offset + 8,
@@ -83,5 +83,5 @@
         my $tag = Get16u($dataPt, $pos);
         my $val = Get32u($dataPt, $pos + 2);
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $et->HandleTag($tagTablePtr, $tag, $val,
             Index  => $n,
             DataPt => $dataPt,
@@ -113,5 +113,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Qualcomm.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Qualcomm.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Qualcomm.pm	(revision 34921)
@@ -0,0 +1,1344 @@
+#------------------------------------------------------------------------------
+# File:         Qualcomm.pm
+#
+# Description:  Read Qualcomm APP7 meta information
+#
+# Revisions:    2012/02/14 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Qualcomm;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.01';
+
+sub ProcessQualcomm($$$);
+sub MakeNameAndDesc($$);
+
+# Qualcomm format codes (ref PH (NC))
+my @qualcommFormat = (
+    'int8u',    'int8s',    'int16u',   'int16s',
+    'int32u',   'int32s',   'float',    'double',
+);
+
+# information found in JPEG APP7 Qualcomm Camera Attributes segment
+%Image::ExifTool::Qualcomm::Main = (
+    PROCESS_PROC => \&ProcessQualcomm,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    VARS => { NO_ID => 1, NO_LOOKUP => 1 }, # too long, too many, and too obscure
+    NOTES => q{
+        The tags below have been observed in the JPEG APP7 "Qualcomm Camera
+        Attributes" segment written by some cameras such as the HP iPAQ Voice
+        Messenger.  ExifTool will extract any information found from this segment,
+        even if it is not listed in this table.
+    },
+    'aec_current_sensor_luma' => { },
+    'af_position' => { },
+    'aec_current_exp_index' => { },
+    'awb_sample_decision' => { },
+    'asf5_enable' => { },
+    'asf5_filter_mode' => { },
+    'asf5_exposure_index_1' => { },
+    'asf5_exposure_index_2' => { },
+    'asf5_max_exposure_index' => { },
+    'asf5_luma_filter[0]' => { },
+    'asf5_luma_filter[1]' => { },
+    'asf5_luma_filter[2]' => { },
+    'asf5_luma_filter[3]' => { },
+    'asf5_luma_filter[4]' => { },
+    'asf5_luma_filter[5]' => { },
+    'asf5_luma_filter[6]' => { },
+    'asf5_luma_filter[7]' => { },
+    'asf5_luma_filter[8]' => { },
+    'asf5_filter1_a11' => { },
+    'asf5_filter1_a12' => { },
+    'asf5_filter1_a13' => { },
+    'asf5_filter1_a14' => { },
+    'asf5_filter1_a15' => { },
+    'asf5_filter1_a21' => { },
+    'asf5_filter1_a22' => { },
+    'asf5_filter1_a23' => { },
+    'asf5_filter1_a24' => { },
+    'asf5_filter1_a25' => { },
+    'asf5_filter1_a31' => { },
+    'asf5_filter1_a32' => { },
+    'asf5_filter1_a33' => { },
+    'asf5_filter1_a34' => { },
+    'asf5_filter1_a35' => { },
+    'asf5_filter1_a41' => { },
+    'asf5_filter1_a42' => { },
+    'asf5_filter1_a43' => { },
+    'asf5_filter1_a44' => { },
+    'asf5_filter1_a45' => { },
+    'asf5_filter1_a51' => { },
+    'asf5_filter1_a52' => { },
+    'asf5_filter1_a53' => { },
+    'asf5_filter1_a54' => { },
+    'asf5_filter1_a55' => { },
+    'asf5_filter2_a11' => { },
+    'asf5_filter2_a12' => { },
+    'asf5_filter2_a13' => { },
+    'asf5_filter2_a14' => { },
+    'asf5_filter2_a15' => { },
+    'asf5_filter2_a21' => { },
+    'asf5_filter2_a22' => { },
+    'asf5_filter2_a23' => { },
+    'asf5_filter2_a24' => { },
+    'asf5_filter2_a25' => { },
+    'asf5_filter2_a31' => { },
+    'asf5_filter2_a32' => { },
+    'asf5_filter2_a33' => { },
+    'asf5_filter2_a34' => { },
+    'asf5_filter2_a35' => { },
+    'asf5_filter2_a41' => { },
+    'asf5_filter2_a42' => { },
+    'asf5_filter2_a43' => { },
+    'asf5_filter2_a44' => { },
+    'asf5_filter2_a45' => { },
+    'asf5_filter2_a51' => { },
+    'asf5_filter2_a52' => { },
+    'asf5_filter2_a53' => { },
+    'asf5_filter2_a54' => { },
+    'asf5_filter2_a55' => { },
+    'asf5_nrmize_factor1' => { },
+    'asf5_nrmize_factor2' => { },
+    'asf5_low_lo_thres' => { },
+    'asf5_low_up_thres' => { },
+    'asf5_low_shrp_deg_f1' => { },
+    'asf5_low_shrp_deg_f2' => { },
+    'asf5_low_smth_prcnt' => { },
+    'asf5_nrm_lo_thres' => { },
+    'asf5_nrm_up_thres' => { },
+    'asf5_nrm_shrp_deg_f1' => { },
+    'asf5_nrm_shrp_deg_f2' => { },
+    'asf5_nrm_smth_prcnt' => { },
+    'asf5_brt_lo_thres' => { },
+    'asf5_brt_up_thres' => { },
+    'asf5_brt_shrp_deg_f1' => { },
+    'asf5_brt_shrp_deg_f2' => { },
+    'asf5_brt_smth_percent' => { },
+    'asf3_enable' => { },
+    'asf3_edge_filter_a11' => { },
+    'asf3_edge_filter_a12' => { },
+    'asf3_edge_filter_a13' => { },
+    'asf3_edge_filter_a21' => { },
+    'asf3_edge_filter_a22' => { },
+    'asf3_edge_filter_a23' => { },
+    'asf3_edge_filter_a31' => { },
+    'asf3_edge_filter_a32' => { },
+    'asf3_edge_filter_a33' => { },
+    'asf3_noise_filter_a11' => { },
+    'asf3_noise_filter_a12' => { },
+    'asf3_noise_filter_a13' => { },
+    'asf3_noise_filter_a21' => { },
+    'asf3_noise_filter_a22' => { },
+    'asf3_noise_filter_a23' => { },
+    'asf3_noise_filter_a31' => { },
+    'asf3_noise_filter_a32' => { },
+    'asf3_noise_filter_a33' => { },
+    'asf3_lower_threshold' => { },
+    'asf3_upper_threshold' => { },
+    'asf3_edge_detect' => { },
+    'aec_enable' => { },
+    'aec_mode' => { },
+    'aec_aggressiveness' => { },
+    'aec_luma_target' => { },
+    'aec_luma_tolerance' => { },
+    'aec_indoor_idx' => { },
+    'aec_odoor_idx' => { },
+    'aec_exposure_index_adj_step' => { },
+    'aec_outdoor_gamma_index' => { },
+    'aec_vfe_luma' => { },
+    'aec_high_luma_region_threshold' => { },
+    'aec_snapshot_sensor_gain' => { },
+    'aec_snapshot_digital_gain' => { },
+    'aec_snapshot_line_count' => { },
+    'aec_snapshot_exposure_time_ms' => { },
+    'aec_outdoor_bright_enable' => { },
+    'aec_outdoor_bright_reduction' => { },
+    'aec_outdoor_bright_threshold_LO' => { },
+    'aec_outdoor_bright_threshold_HI' => { },
+    'aec_outdoor_bright_discarded' => { },
+    'aec_high_luma_region_count' => { },
+    'antibanding_enable' => { },
+    'anti_bading_pixel_clk' => { },
+    'anti_bading_pixel_clk_per_line' => { },
+    'afr_enable' => { },
+    'afr_faster_0_trigger' => { },
+    'afr_slower_0_trigger' => { },
+    'afr_faster_0_exp_mod' => { },
+    'afr_slower_0_exp_mod' => { },
+    'afr_faster_1_trigger' => { },
+    'afr_slower_1_trigger' => { },
+    'afr_faster_1_exp_mod' => { },
+    'afr_slower_1_exp_mod' => { },
+    'afr_faster_2_trigger' => { },
+    'afr_slower_2_trigger' => { },
+    'afr_faster_2_exp_mod' => { },
+    'afr_slower_2_exp_mod' => { },
+    'afr_faster_3_trigger' => { },
+    'afr_slower_3_trigger' => { },
+    'afr_faster_3_exp_mod' => { },
+    'afr_slower_3_exp_mod' => { },
+    'afr_faster_4_trigger' => { },
+    'afr_slower_4_trigger' => { },
+    'afr_faster_4_exp_mod' => { },
+    'afr_slower_4_exp_mod' => { },
+    'afr_possible_frame_cnt' => { },
+    'af_enable' => { },
+    'af_steps_near_far' => { },
+    'af_steps_near_infinity' => { },
+    'af_gross_step' => { },
+    'af_fine_step' => { },
+    'af_fine_srch_points' => { },
+    'af_process' => { },
+    'af_mode' => { },
+    'af_near_end' => { },
+    'af_boundary' => { },
+    'af_far_end' => { },
+    'af_collect_end_stat' => { },
+    'af_test_mode' => { },
+    'af_undershoot_protect' => { },
+    'af_reset_lens_after_snap' => { },
+    'clip_to_af_rato' => { },
+    'af_pos_def_macro' => { },
+    'af_pos_def_norm' => { },
+    'af_vfe_vert_offset' => { },
+    'af_vfe_horz_offset' => { },
+    'af_vfe_vert_height' => { },
+    'af_vfe_horz_width' => { },
+    'af_vfe_metric_max' => { },
+    'af_trace_positions[0]' => { },
+    'af_trace_positions[1]' => { },
+    'af_trace_positions[2]' => { },
+    'af_trace_positions[3]' => { },
+    'af_trace_positions[4]' => { },
+    'af_trace_positions[5]' => { },
+    'af_trace_positions[6]' => { },
+    'af_trace_positions[7]' => { },
+    'af_trace_positions[8]' => { },
+    'af_trace_positions[9]' => { },
+    'af_trace_positions[10]' => { },
+    'af_trace_positions[11]' => { },
+    'af_trace_positions[12]' => { },
+    'af_trace_positions[13]' => { },
+    'af_trace_positions[14]' => { },
+    'af_trace_positions[15]' => { },
+    'af_trace_positions[16]' => { },
+    'af_trace_positions[17]' => { },
+    'af_trace_positions[18]' => { },
+    'af_trace_positions[19]' => { },
+    'af_trace_positions[20]' => { },
+    'af_trace_positions[21]' => { },
+    'af_trace_positions[22]' => { },
+    'af_trace_positions[23]' => { },
+    'af_trace_positions[24]' => { },
+    'af_trace_positions[25]' => { },
+    'af_trace_positions[26]' => { },
+    'af_trace_positions[27]' => { },
+    'af_trace_positions[28]' => { },
+    'af_trace_positions[29]' => { },
+    'af_trace_positions[30]' => { },
+    'af_trace_positions[31]' => { },
+    'af_trace_positions[32]' => { },
+    'af_trace_positions[33]' => { },
+    'af_trace_positions[34]' => { },
+    'af_trace_positions[35]' => { },
+    'af_trace_positions[36]' => { },
+    'af_trace_positions[37]' => { },
+    'af_trace_positions[38]' => { },
+    'af_trace_positions[39]' => { },
+    'af_trace_positions[40]' => { },
+    'af_trace_positions[41]' => { },
+    'af_trace_positions[42]' => { },
+    'af_trace_positions[43]' => { },
+    'af_trace_positions[44]' => { },
+    'af_trace_positions[45]' => { },
+    'af_trace_positions[46]' => { },
+    'af_trace_positions[47]' => { },
+    'af_trace_positions[48]' => { },
+    'af_trace_positions[49]' => { },
+    'af_trace_stats[0]' => { },
+    'af_trace_stats[1]' => { },
+    'af_trace_stats[2]' => { },
+    'af_trace_stats[3]' => { },
+    'af_trace_stats[4]' => { },
+    'af_trace_stats[5]' => { },
+    'af_trace_stats[6]' => { },
+    'af_trace_stats[7]' => { },
+    'af_trace_stats[8]' => { },
+    'af_trace_stats[9]' => { },
+    'af_trace_stats[10]' => { },
+    'af_trace_stats[11]' => { },
+    'af_trace_stats[12]' => { },
+    'af_trace_stats[13]' => { },
+    'af_trace_stats[14]' => { },
+    'af_trace_stats[15]' => { },
+    'af_trace_stats[16]' => { },
+    'af_trace_stats[17]' => { },
+    'af_trace_stats[18]' => { },
+    'af_trace_stats[19]' => { },
+    'af_trace_stats[20]' => { },
+    'af_trace_stats[21]' => { },
+    'af_trace_stats[22]' => { },
+    'af_trace_stats[23]' => { },
+    'af_trace_stats[24]' => { },
+    'af_trace_stats[25]' => { },
+    'af_trace_stats[26]' => { },
+    'af_trace_stats[27]' => { },
+    'af_trace_stats[28]' => { },
+    'af_trace_stats[29]' => { },
+    'af_trace_stats[30]' => { },
+    'af_trace_stats[31]' => { },
+    'af_trace_stats[32]' => { },
+    'af_trace_stats[33]' => { },
+    'af_trace_stats[34]' => { },
+    'af_trace_stats[35]' => { },
+    'af_trace_stats[36]' => { },
+    'af_trace_stats[37]' => { },
+    'af_trace_stats[38]' => { },
+    'af_trace_stats[39]' => { },
+    'af_trace_stats[40]' => { },
+    'af_trace_stats[41]' => { },
+    'af_trace_stats[42]' => { },
+    'af_trace_stats[43]' => { },
+    'af_trace_stats[44]' => { },
+    'af_trace_stats[45]' => { },
+    'af_trace_stats[46]' => { },
+    'af_trace_stats[47]' => { },
+    'af_trace_stats[48]' => { },
+    'af_trace_stats[49]' => { },
+    'af_focus_time' => { },
+    'awb_enable' => { },
+    'awb_algorithm' => { },
+    'awb_aggressiveness' => { },
+    'awb_red_gain_ref1' => { },
+    'awb_blue_gain_ref1' => { },
+    'awb_red_gain_adj_ref1' => { },
+    'awb_blue_gain_adj_ref1' => { },
+    'awb_red_gain_ref2' => { },
+    'awb_blue_gain_ref2' => { },
+    'awb_red_gain_adj_ref2' => { },
+    'awb_blue_gain_adj_ref2' => { },
+    'awb_red_gain_ref3' => { },
+    'awb_blue_gain_ref3' => { },
+    'awb_red_gain_adj_ref3' => { },
+    'awb_blue_gain_adj_ref3' => { },
+    'awb_red_gain_ref4' => { },
+    'awb_blue_gain_ref4' => { },
+    'awb_red_gain_adj_ref4' => { },
+    'awb_blue_gain_adj_ref4' => { },
+    'awb_red_gain_ref5' => { },
+    'awb_blue_gain_ref5' => { },
+    'awb_red_gain_adj_ref5' => { },
+    'awb_blue_gain_adj_ref5' => { },
+    'awb_red_gain_ref6' => { },
+    'awb_blue_gain_ref6' => { },
+    'awb_red_gain_adj_ref6' => { },
+    'awb_blue_gain_adj_ref6' => { },
+    'awb_red_gain_ref7' => { },
+    'awb_blue_gain_ref7' => { },
+    'awb_red_gain_adj_ref7' => { },
+    'awb_blue_gain_adj_ref7' => { },
+    'awb_red_gain_ref8' => { },
+    'awb_blue_gain_ref8' => { },
+    'awb_red_gain_adj_ref8' => { },
+    'awb_blue_gain_adj_ref8' => { },
+    'awb_lo_vfe_max_y' => { },
+    'awb_lo_vfe_min_y' => { },
+    'awb_lo_vfe_m1' => { },
+    'awb_lo_vfe_m2' => { },
+    'awb_lo_vfe_m3' => { },
+    'awb_lo_vfe_m4' => { },
+    'awb_lo_vfe_c1' => { },
+    'awb_lo_vfe_c2' => { },
+    'awb_lo_vfe_c3' => { },
+    'awb_lo_vfe_c4' => { },
+    'awb_norm_vfe_max_y' => { },
+    'awb_norm_vfe_min_y' => { },
+    'awb_norm_vfe_m1' => { },
+    'awb_norm_vfe_m2' => { },
+    'awb_norm_vfe_m3' => { },
+    'awb_norm_vfe_m4' => { },
+    'awb_norm_vfe_c1' => { },
+    'awb_norm_vfe_c2' => { },
+    'awb_norm_vfe_c3' => { },
+    'awb_norm_vfe_c4' => { },
+    'awb_oudor_vfe_max_y' => { },
+    'awb_oudor_vfe_min_y' => { },
+    'awb_oudor_vfe_m1' => { },
+    'awb_oudor_vfe_m2' => { },
+    'awb_oudor_vfe_m3' => { },
+    'awb_oudor_vfe_m4' => { },
+    'awb_oudor_vfe_c1' => { },
+    'awb_oudor_vfe_c2' => { },
+    'awb_oudor_vfe_c3' => { },
+    'awb_oudor_vfe_c4' => { },
+    'awb_cc_bias' => { },
+    'awb_min_r_gain' => { },
+    'awb_min_g_gain' => { },
+    'awb_min_b_gain' => { },
+    'awb_max_r_gain' => { },
+    'awb_max_g_gain' => { },
+    'awb_max_b_gain' => { },
+    'awb_outdoor_sample_influence' => { },
+    'awb_indoor_sample_influence' => { },
+    'awb_low_lig_col_cor_ena' => { },
+    'awb_agw_grid_dist_2_thresh' => { },
+    'awb_ave_rg_ratio' => { },
+    'awb_ave_bg_ratio' => { },
+    'awb_compact_cluster_R2' => { },
+    'outlier_distance' => { },
+    'awb_green_offset_rg' => { },
+    'awb_green_offset_bg' => { },
+    'awb_prev_wb_rgain' => { },
+    'awb_prev_wb_ggain' => { },
+    'awb_prev_wb_bgain' => { },
+    'awb_snapshot_r_gain' => { },
+    'awb_snapshot_b_gain' => { },
+    'rolloff_enable' => { },
+    'r2_tl84_cx' => { },
+    'r2_tl84_cy' => { },
+    'r2_tl84_width' => { },
+    'r2_tl84_height' => { },
+    'r2_tl84_intervals' => { },
+    'r2_tl84_tbl[0]' => { },
+    'r2_tl84_tbl[1]' => { },
+    'r2_tl84_tbl[2]' => { },
+    'r2_tl84_tbl[3]' => { },
+    'r2_tl84_tbl[4]' => { },
+    'r2_tl84_tbl[5]' => { },
+    'r2_tl84_tbl[6]' => { },
+    'r2_tl84_tbl[7]' => { },
+    'r2_tl84_tbl[8]' => { },
+    'r2_tl84_tbl[9]' => { },
+    'r2_tl84_tbl[10]' => { },
+    'r2_tl84_tbl[11]' => { },
+    'r2_tl84_tbl[12]' => { },
+    'r2_tl84_tbl[13]' => { },
+    'r2_tl84_tbl[14]' => { },
+    'r2_tl84_tbl[15]' => { },
+    'r2_tl84_tbl[16]' => { },
+    'r2_tl84_tbl[17]' => { },
+    'r2_tl84_tbl[18]' => { },
+    'r2_tl84_tbl[19]' => { },
+    'r2_tl84_tbl[20]' => { },
+    'r2_tl84_tbl[21]' => { },
+    'r2_tl84_tbl[22]' => { },
+    'r2_tl84_tbl[23]' => { },
+    'r2_tl84_tbl[24]' => { },
+    'r2_tl84_tbl[25]' => { },
+    'r2_tl84_tbl[26]' => { },
+    'r2_tl84_tbl[27]' => { },
+    'r2_tl84_tbl[28]' => { },
+    'r2_tl84_tbl[29]' => { },
+    'r2_tl84_tbl[30]' => { },
+    'r2_tl84_tbl[31]' => { },
+    'r2_tl84_red_ctbl[0]' => { },
+    'r2_tl84_red_ctbl[1]' => { },
+    'r2_tl84_red_ctbl[2]' => { },
+    'r2_tl84_red_ctbl[3]' => { },
+    'r2_tl84_red_ctbl[4]' => { },
+    'r2_tl84_red_ctbl[5]' => { },
+    'r2_tl84_red_ctbl[6]' => { },
+    'r2_tl84_red_ctbl[7]' => { },
+    'r2_tl84_red_ctbl[8]' => { },
+    'r2_tl84_red_ctbl[9]' => { },
+    'r2_tl84_red_ctbl[10]' => { },
+    'r2_tl84_red_ctbl[11]' => { },
+    'r2_tl84_red_ctbl[12]' => { },
+    'r2_tl84_red_ctbl[13]' => { },
+    'r2_tl84_red_ctbl[14]' => { },
+    'r2_tl84_red_ctbl[15]' => { },
+    'r2_tl84_red_ctbl[16]' => { },
+    'r2_tl84_red_ctbl[17]' => { },
+    'r2_tl84_red_ctbl[18]' => { },
+    'r2_tl84_red_ctbl[19]' => { },
+    'r2_tl84_red_ctbl[20]' => { },
+    'r2_tl84_red_ctbl[21]' => { },
+    'r2_tl84_red_ctbl[22]' => { },
+    'r2_tl84_red_ctbl[23]' => { },
+    'r2_tl84_red_ctbl[24]' => { },
+    'r2_tl84_red_ctbl[25]' => { },
+    'r2_tl84_red_ctbl[26]' => { },
+    'r2_tl84_red_ctbl[27]' => { },
+    'r2_tl84_red_ctbl[28]' => { },
+    'r2_tl84_red_ctbl[29]' => { },
+    'r2_tl84_red_ctbl[30]' => { },
+    'r2_tl84_red_ctbl[31]' => { },
+    'r2_tl84_green_ctbl[0]' => { },
+    'r2_tl84_green_ctbl[1]' => { },
+    'r2_tl84_green_ctbl[2]' => { },
+    'r2_tl84_green_ctbl[3]' => { },
+    'r2_tl84_green_ctbl[4]' => { },
+    'r2_tl84_green_ctbl[5]' => { },
+    'r2_tl84_green_ctbl[6]' => { },
+    'r2_tl84_green_ctbl[7]' => { },
+    'r2_tl84_green_ctbl[8]' => { },
+    'r2_tl84_green_ctbl[9]' => { },
+    'r2_tl84_green_ctbl[10]' => { },
+    'r2_tl84_green_ctbl[11]' => { },
+    'r2_tl84_green_ctbl[12]' => { },
+    'r2_tl84_green_ctbl[13]' => { },
+    'r2_tl84_green_ctbl[14]' => { },
+    'r2_tl84_green_ctbl[15]' => { },
+    'r2_tl84_green_ctbl[16]' => { },
+    'r2_tl84_green_ctbl[17]' => { },
+    'r2_tl84_green_ctbl[18]' => { },
+    'r2_tl84_green_ctbl[19]' => { },
+    'r2_tl84_green_ctbl[20]' => { },
+    'r2_tl84_green_ctbl[21]' => { },
+    'r2_tl84_green_ctbl[22]' => { },
+    'r2_tl84_green_ctbl[23]' => { },
+    'r2_tl84_green_ctbl[24]' => { },
+    'r2_tl84_green_ctbl[25]' => { },
+    'r2_tl84_green_ctbl[26]' => { },
+    'r2_tl84_green_ctbl[27]' => { },
+    'r2_tl84_green_ctbl[28]' => { },
+    'r2_tl84_green_ctbl[29]' => { },
+    'r2_tl84_green_ctbl[30]' => { },
+    'r2_tl84_green_ctbl[31]' => { },
+    'r2_tl84_blue_ctbl[0]' => { },
+    'r2_tl84_blue_ctbl[1]' => { },
+    'r2_tl84_blue_ctbl[2]' => { },
+    'r2_tl84_blue_ctbl[3]' => { },
+    'r2_tl84_blue_ctbl[4]' => { },
+    'r2_tl84_blue_ctbl[5]' => { },
+    'r2_tl84_blue_ctbl[6]' => { },
+    'r2_tl84_blue_ctbl[7]' => { },
+    'r2_tl84_blue_ctbl[8]' => { },
+    'r2_tl84_blue_ctbl[9]' => { },
+    'r2_tl84_blue_ctbl[10]' => { },
+    'r2_tl84_blue_ctbl[11]' => { },
+    'r2_tl84_blue_ctbl[12]' => { },
+    'r2_tl84_blue_ctbl[13]' => { },
+    'r2_tl84_blue_ctbl[14]' => { },
+    'r2_tl84_blue_ctbl[15]' => { },
+    'r2_tl84_blue_ctbl[16]' => { },
+    'r2_tl84_blue_ctbl[17]' => { },
+    'r2_tl84_blue_ctbl[18]' => { },
+    'r2_tl84_blue_ctbl[19]' => { },
+    'r2_tl84_blue_ctbl[20]' => { },
+    'r2_tl84_blue_ctbl[21]' => { },
+    'r2_tl84_blue_ctbl[22]' => { },
+    'r2_tl84_blue_ctbl[23]' => { },
+    'r2_tl84_blue_ctbl[24]' => { },
+    'r2_tl84_blue_ctbl[25]' => { },
+    'r2_tl84_blue_ctbl[26]' => { },
+    'r2_tl84_blue_ctbl[27]' => { },
+    'r2_tl84_blue_ctbl[28]' => { },
+    'r2_tl84_blue_ctbl[29]' => { },
+    'r2_tl84_blue_ctbl[30]' => { },
+    'r2_tl84_blue_ctbl[31]' => { },
+    'r2_tl84_red_stbl[0]' => { },
+    'r2_tl84_red_stbl[1]' => { },
+    'r2_tl84_red_stbl[2]' => { },
+    'r2_tl84_red_stbl[3]' => { },
+    'r2_tl84_red_stbl[4]' => { },
+    'r2_tl84_red_stbl[5]' => { },
+    'r2_tl84_red_stbl[6]' => { },
+    'r2_tl84_red_stbl[7]' => { },
+    'r2_tl84_red_stbl[8]' => { },
+    'r2_tl84_red_stbl[9]' => { },
+    'r2_tl84_red_stbl[10]' => { },
+    'r2_tl84_red_stbl[11]' => { },
+    'r2_tl84_red_stbl[12]' => { },
+    'r2_tl84_red_stbl[13]' => { },
+    'r2_tl84_red_stbl[14]' => { },
+    'r2_tl84_red_stbl[15]' => { },
+    'r2_tl84_red_stbl[16]' => { },
+    'r2_tl84_red_stbl[17]' => { },
+    'r2_tl84_red_stbl[18]' => { },
+    'r2_tl84_red_stbl[19]' => { },
+    'r2_tl84_red_stbl[20]' => { },
+    'r2_tl84_red_stbl[21]' => { },
+    'r2_tl84_red_stbl[22]' => { },
+    'r2_tl84_red_stbl[23]' => { },
+    'r2_tl84_red_stbl[24]' => { },
+    'r2_tl84_red_stbl[25]' => { },
+    'r2_tl84_red_stbl[26]' => { },
+    'r2_tl84_red_stbl[27]' => { },
+    'r2_tl84_red_stbl[28]' => { },
+    'r2_tl84_red_stbl[29]' => { },
+    'r2_tl84_red_stbl[30]' => { },
+    'r2_tl84_red_stbl[31]' => { },
+    'r2_tl84_blue_stbl[0]' => { },
+    'r2_tl84_blue_stbl[1]' => { },
+    'r2_tl84_blue_stbl[2]' => { },
+    'r2_tl84_blue_stbl[3]' => { },
+    'r2_tl84_blue_stbl[4]' => { },
+    'r2_tl84_blue_stbl[5]' => { },
+    'r2_tl84_blue_stbl[6]' => { },
+    'r2_tl84_blue_stbl[7]' => { },
+    'r2_tl84_blue_stbl[8]' => { },
+    'r2_tl84_blue_stbl[9]' => { },
+    'r2_tl84_blue_stbl[10]' => { },
+    'r2_tl84_blue_stbl[11]' => { },
+    'r2_tl84_blue_stbl[12]' => { },
+    'r2_tl84_blue_stbl[13]' => { },
+    'r2_tl84_blue_stbl[14]' => { },
+    'r2_tl84_blue_stbl[15]' => { },
+    'r2_tl84_blue_stbl[16]' => { },
+    'r2_tl84_blue_stbl[17]' => { },
+    'r2_tl84_blue_stbl[18]' => { },
+    'r2_tl84_blue_stbl[19]' => { },
+    'r2_tl84_blue_stbl[20]' => { },
+    'r2_tl84_blue_stbl[21]' => { },
+    'r2_tl84_blue_stbl[22]' => { },
+    'r2_tl84_blue_stbl[23]' => { },
+    'r2_tl84_blue_stbl[24]' => { },
+    'r2_tl84_blue_stbl[25]' => { },
+    'r2_tl84_blue_stbl[26]' => { },
+    'r2_tl84_blue_stbl[27]' => { },
+    'r2_tl84_blue_stbl[28]' => { },
+    'r2_tl84_blue_stbl[29]' => { },
+    'r2_tl84_blue_stbl[30]' => { },
+    'r2_tl84_blue_stbl[31]' => { },
+    'r2_tl84_green_stbl[0]' => { },
+    'r2_tl84_green_stbl[1]' => { },
+    'r2_tl84_green_stbl[2]' => { },
+    'r2_tl84_green_stbl[3]' => { },
+    'r2_tl84_green_stbl[4]' => { },
+    'r2_tl84_green_stbl[5]' => { },
+    'r2_tl84_green_stbl[6]' => { },
+    'r2_tl84_green_stbl[7]' => { },
+    'r2_tl84_green_stbl[8]' => { },
+    'r2_tl84_green_stbl[9]' => { },
+    'r2_tl84_green_stbl[10]' => { },
+    'r2_tl84_green_stbl[11]' => { },
+    'r2_tl84_green_stbl[12]' => { },
+    'r2_tl84_green_stbl[13]' => { },
+    'r2_tl84_green_stbl[14]' => { },
+    'r2_tl84_green_stbl[15]' => { },
+    'r2_tl84_green_stbl[16]' => { },
+    'r2_tl84_green_stbl[17]' => { },
+    'r2_tl84_green_stbl[18]' => { },
+    'r2_tl84_green_stbl[19]' => { },
+    'r2_tl84_green_stbl[20]' => { },
+    'r2_tl84_green_stbl[21]' => { },
+    'r2_tl84_green_stbl[22]' => { },
+    'r2_tl84_green_stbl[23]' => { },
+    'r2_tl84_green_stbl[24]' => { },
+    'r2_tl84_green_stbl[25]' => { },
+    'r2_tl84_green_stbl[26]' => { },
+    'r2_tl84_green_stbl[27]' => { },
+    'r2_tl84_green_stbl[28]' => { },
+    'r2_tl84_green_stbl[29]' => { },
+    'r2_tl84_green_stbl[30]' => { },
+    'r2_tl84_green_stbl[31]' => { },
+    'r2_d65_cx' => { },
+    'r2_d65_cy' => { },
+    'r2_d65_width' => { },
+    'r2_d65_height' => { },
+    'r2_d65_intervals' => { },
+    'r2_d65_tbl[0]' => { },
+    'r2_d65_tbl[1]' => { },
+    'r2_d65_tbl[2]' => { },
+    'r2_d65_tbl[3]' => { },
+    'r2_d65_tbl[4]' => { },
+    'r2_d65_tbl[5]' => { },
+    'r2_d65_tbl[6]' => { },
+    'r2_d65_tbl[7]' => { },
+    'r2_d65_tbl[8]' => { },
+    'r2_d65_tbl[9]' => { },
+    'r2_d65_tbl[10]' => { },
+    'r2_d65_tbl[11]' => { },
+    'r2_d65_tbl[12]' => { },
+    'r2_d65_tbl[13]' => { },
+    'r2_d65_tbl[14]' => { },
+    'r2_d65_tbl[15]' => { },
+    'r2_d65_tbl[16]' => { },
+    'r2_d65_tbl[17]' => { },
+    'r2_d65_tbl[18]' => { },
+    'r2_d65_tbl[19]' => { },
+    'r2_d65_tbl[20]' => { },
+    'r2_d65_tbl[21]' => { },
+    'r2_d65_tbl[22]' => { },
+    'r2_d65_tbl[23]' => { },
+    'r2_d65_tbl[24]' => { },
+    'r2_d65_tbl[25]' => { },
+    'r2_d65_tbl[26]' => { },
+    'r2_d65_tbl[27]' => { },
+    'r2_d65_tbl[28]' => { },
+    'r2_d65_tbl[29]' => { },
+    'r2_d65_tbl[30]' => { },
+    'r2_d65_tbl[31]' => { },
+    'r2_d65_red_ctbl[0]' => { },
+    'r2_d65_red_ctbl[1]' => { },
+    'r2_d65_red_ctbl[2]' => { },
+    'r2_d65_red_ctbl[3]' => { },
+    'r2_d65_red_ctbl[4]' => { },
+    'r2_d65_red_ctbl[5]' => { },
+    'r2_d65_red_ctbl[6]' => { },
+    'r2_d65_red_ctbl[7]' => { },
+    'r2_d65_red_ctbl[8]' => { },
+    'r2_d65_red_ctbl[9]' => { },
+    'r2_d65_red_ctbl[10]' => { },
+    'r2_d65_red_ctbl[11]' => { },
+    'r2_d65_red_ctbl[12]' => { },
+    'r2_d65_red_ctbl[13]' => { },
+    'r2_d65_red_ctbl[14]' => { },
+    'r2_d65_red_ctbl[15]' => { },
+    'r2_d65_red_ctbl[16]' => { },
+    'r2_d65_red_ctbl[17]' => { },
+    'r2_d65_red_ctbl[18]' => { },
+    'r2_d65_red_ctbl[19]' => { },
+    'r2_d65_red_ctbl[20]' => { },
+    'r2_d65_red_ctbl[21]' => { },
+    'r2_d65_red_ctbl[22]' => { },
+    'r2_d65_red_ctbl[23]' => { },
+    'r2_d65_red_ctbl[24]' => { },
+    'r2_d65_red_ctbl[25]' => { },
+    'r2_d65_red_ctbl[26]' => { },
+    'r2_d65_red_ctbl[27]' => { },
+    'r2_d65_red_ctbl[28]' => { },
+    'r2_d65_red_ctbl[29]' => { },
+    'r2_d65_red_ctbl[30]' => { },
+    'r2_d65_red_ctbl[31]' => { },
+    'r2_d65_green_ctbl[0]' => { },
+    'r2_d65_green_ctbl[1]' => { },
+    'r2_d65_green_ctbl[2]' => { },
+    'r2_d65_green_ctbl[3]' => { },
+    'r2_d65_green_ctbl[4]' => { },
+    'r2_d65_green_ctbl[5]' => { },
+    'r2_d65_green_ctbl[6]' => { },
+    'r2_d65_green_ctbl[7]' => { },
+    'r2_d65_green_ctbl[8]' => { },
+    'r2_d65_green_ctbl[9]' => { },
+    'r2_d65_green_ctbl[10]' => { },
+    'r2_d65_green_ctbl[11]' => { },
+    'r2_d65_green_ctbl[12]' => { },
+    'r2_d65_green_ctbl[13]' => { },
+    'r2_d65_green_ctbl[14]' => { },
+    'r2_d65_green_ctbl[15]' => { },
+    'r2_d65_green_ctbl[16]' => { },
+    'r2_d65_green_ctbl[17]' => { },
+    'r2_d65_green_ctbl[18]' => { },
+    'r2_d65_green_ctbl[19]' => { },
+    'r2_d65_green_ctbl[20]' => { },
+    'r2_d65_green_ctbl[21]' => { },
+    'r2_d65_green_ctbl[22]' => { },
+    'r2_d65_green_ctbl[23]' => { },
+    'r2_d65_green_ctbl[24]' => { },
+    'r2_d65_green_ctbl[25]' => { },
+    'r2_d65_green_ctbl[26]' => { },
+    'r2_d65_green_ctbl[27]' => { },
+    'r2_d65_green_ctbl[28]' => { },
+    'r2_d65_green_ctbl[29]' => { },
+    'r2_d65_green_ctbl[30]' => { },
+    'r2_d65_green_ctbl[31]' => { },
+    'r2_d65_blue_ctbl[0]' => { },
+    'r2_d65_blue_ctbl[1]' => { },
+    'r2_d65_blue_ctbl[2]' => { },
+    'r2_d65_blue_ctbl[3]' => { },
+    'r2_d65_blue_ctbl[4]' => { },
+    'r2_d65_blue_ctbl[5]' => { },
+    'r2_d65_blue_ctbl[6]' => { },
+    'r2_d65_blue_ctbl[7]' => { },
+    'r2_d65_blue_ctbl[8]' => { },
+    'r2_d65_blue_ctbl[9]' => { },
+    'r2_d65_blue_ctbl[10]' => { },
+    'r2_d65_blue_ctbl[11]' => { },
+    'r2_d65_blue_ctbl[12]' => { },
+    'r2_d65_blue_ctbl[13]' => { },
+    'r2_d65_blue_ctbl[14]' => { },
+    'r2_d65_blue_ctbl[15]' => { },
+    'r2_d65_blue_ctbl[16]' => { },
+    'r2_d65_blue_ctbl[17]' => { },
+    'r2_d65_blue_ctbl[18]' => { },
+    'r2_d65_blue_ctbl[19]' => { },
+    'r2_d65_blue_ctbl[20]' => { },
+    'r2_d65_blue_ctbl[21]' => { },
+    'r2_d65_blue_ctbl[22]' => { },
+    'r2_d65_blue_ctbl[23]' => { },
+    'r2_d65_blue_ctbl[24]' => { },
+    'r2_d65_blue_ctbl[25]' => { },
+    'r2_d65_blue_ctbl[26]' => { },
+    'r2_d65_blue_ctbl[27]' => { },
+    'r2_d65_blue_ctbl[28]' => { },
+    'r2_d65_blue_ctbl[29]' => { },
+    'r2_d65_blue_ctbl[30]' => { },
+    'r2_d65_blue_ctbl[31]' => { },
+    'r2_d65_red_stbl[0]' => { },
+    'r2_d65_red_stbl[1]' => { },
+    'r2_d65_red_stbl[2]' => { },
+    'r2_d65_red_stbl[3]' => { },
+    'r2_d65_red_stbl[4]' => { },
+    'r2_d65_red_stbl[5]' => { },
+    'r2_d65_red_stbl[6]' => { },
+    'r2_d65_red_stbl[7]' => { },
+    'r2_d65_red_stbl[8]' => { },
+    'r2_d65_red_stbl[9]' => { },
+    'r2_d65_red_stbl[10]' => { },
+    'r2_d65_red_stbl[11]' => { },
+    'r2_d65_red_stbl[12]' => { },
+    'r2_d65_red_stbl[13]' => { },
+    'r2_d65_red_stbl[14]' => { },
+    'r2_d65_red_stbl[15]' => { },
+    'r2_d65_red_stbl[16]' => { },
+    'r2_d65_red_stbl[17]' => { },
+    'r2_d65_red_stbl[18]' => { },
+    'r2_d65_red_stbl[19]' => { },
+    'r2_d65_red_stbl[20]' => { },
+    'r2_d65_red_stbl[21]' => { },
+    'r2_d65_red_stbl[22]' => { },
+    'r2_d65_red_stbl[23]' => { },
+    'r2_d65_red_stbl[24]' => { },
+    'r2_d65_red_stbl[25]' => { },
+    'r2_d65_red_stbl[26]' => { },
+    'r2_d65_red_stbl[27]' => { },
+    'r2_d65_red_stbl[28]' => { },
+    'r2_d65_red_stbl[29]' => { },
+    'r2_d65_red_stbl[30]' => { },
+    'r2_d65_red_stbl[31]' => { },
+    'r2_d65_blue_stbl[0]' => { },
+    'r2_d65_blue_stbl[1]' => { },
+    'r2_d65_blue_stbl[2]' => { },
+    'r2_d65_blue_stbl[3]' => { },
+    'r2_d65_blue_stbl[4]' => { },
+    'r2_d65_blue_stbl[5]' => { },
+    'r2_d65_blue_stbl[6]' => { },
+    'r2_d65_blue_stbl[7]' => { },
+    'r2_d65_blue_stbl[8]' => { },
+    'r2_d65_blue_stbl[9]' => { },
+    'r2_d65_blue_stbl[10]' => { },
+    'r2_d65_blue_stbl[11]' => { },
+    'r2_d65_blue_stbl[12]' => { },
+    'r2_d65_blue_stbl[13]' => { },
+    'r2_d65_blue_stbl[14]' => { },
+    'r2_d65_blue_stbl[15]' => { },
+    'r2_d65_blue_stbl[16]' => { },
+    'r2_d65_blue_stbl[17]' => { },
+    'r2_d65_blue_stbl[18]' => { },
+    'r2_d65_blue_stbl[19]' => { },
+    'r2_d65_blue_stbl[20]' => { },
+    'r2_d65_blue_stbl[21]' => { },
+    'r2_d65_blue_stbl[22]' => { },
+    'r2_d65_blue_stbl[23]' => { },
+    'r2_d65_blue_stbl[24]' => { },
+    'r2_d65_blue_stbl[25]' => { },
+    'r2_d65_blue_stbl[26]' => { },
+    'r2_d65_blue_stbl[27]' => { },
+    'r2_d65_blue_stbl[28]' => { },
+    'r2_d65_blue_stbl[29]' => { },
+    'r2_d65_blue_stbl[30]' => { },
+    'r2_d65_blue_stbl[31]' => { },
+    'r2_d65_green_stbl[0]' => { },
+    'r2_d65_green_stbl[1]' => { },
+    'r2_d65_green_stbl[2]' => { },
+    'r2_d65_green_stbl[3]' => { },
+    'r2_d65_green_stbl[4]' => { },
+    'r2_d65_green_stbl[5]' => { },
+    'r2_d65_green_stbl[6]' => { },
+    'r2_d65_green_stbl[7]' => { },
+    'r2_d65_green_stbl[8]' => { },
+    'r2_d65_green_stbl[9]' => { },
+    'r2_d65_green_stbl[10]' => { },
+    'r2_d65_green_stbl[11]' => { },
+    'r2_d65_green_stbl[12]' => { },
+    'r2_d65_green_stbl[13]' => { },
+    'r2_d65_green_stbl[14]' => { },
+    'r2_d65_green_stbl[15]' => { },
+    'r2_d65_green_stbl[16]' => { },
+    'r2_d65_green_stbl[17]' => { },
+    'r2_d65_green_stbl[18]' => { },
+    'r2_d65_green_stbl[19]' => { },
+    'r2_d65_green_stbl[20]' => { },
+    'r2_d65_green_stbl[21]' => { },
+    'r2_d65_green_stbl[22]' => { },
+    'r2_d65_green_stbl[23]' => { },
+    'r2_d65_green_stbl[24]' => { },
+    'r2_d65_green_stbl[25]' => { },
+    'r2_d65_green_stbl[26]' => { },
+    'r2_d65_green_stbl[27]' => { },
+    'r2_d65_green_stbl[28]' => { },
+    'r2_d65_green_stbl[29]' => { },
+    'r2_d65_green_stbl[30]' => { },
+    'r2_d65_green_stbl[31]' => { },
+    'r2_a_cx' => { },
+    'r2_a_cy' => { },
+    'r2_a_width' => { },
+    'r2_a_height' => { },
+    'r2_a_intervals' => { },
+    'r2_a_tbl[0]' => { },
+    'r2_a_tbl[1]' => { },
+    'r2_a_tbl[2]' => { },
+    'r2_a_tbl[3]' => { },
+    'r2_a_tbl[4]' => { },
+    'r2_a_tbl[5]' => { },
+    'r2_a_tbl[6]' => { },
+    'r2_a_tbl[7]' => { },
+    'r2_a_tbl[8]' => { },
+    'r2_a_tbl[9]' => { },
+    'r2_a_tbl[10]' => { },
+    'r2_a_tbl[11]' => { },
+    'r2_a_tbl[12]' => { },
+    'r2_a_tbl[13]' => { },
+    'r2_a_tbl[14]' => { },
+    'r2_a_tbl[15]' => { },
+    'r2_a_tbl[16]' => { },
+    'r2_a_tbl[17]' => { },
+    'r2_a_tbl[18]' => { },
+    'r2_a_tbl[19]' => { },
+    'r2_a_tbl[20]' => { },
+    'r2_a_tbl[21]' => { },
+    'r2_a_tbl[22]' => { },
+    'r2_a_tbl[23]' => { },
+    'r2_a_tbl[24]' => { },
+    'r2_a_tbl[25]' => { },
+    'r2_a_tbl[26]' => { },
+    'r2_a_tbl[27]' => { },
+    'r2_a_tbl[28]' => { },
+    'r2_a_tbl[29]' => { },
+    'r2_a_tbl[30]' => { },
+    'r2_a_tbl[31]' => { },
+    'r2_a_red_ctbl[0]' => { },
+    'r2_a_red_ctbl[1]' => { },
+    'r2_a_red_ctbl[2]' => { },
+    'r2_a_red_ctbl[3]' => { },
+    'r2_a_red_ctbl[4]' => { },
+    'r2_a_red_ctbl[5]' => { },
+    'r2_a_red_ctbl[6]' => { },
+    'r2_a_red_ctbl[7]' => { },
+    'r2_a_red_ctbl[8]' => { },
+    'r2_a_red_ctbl[9]' => { },
+    'r2_a_red_ctbl[10]' => { },
+    'r2_a_red_ctbl[11]' => { },
+    'r2_a_red_ctbl[12]' => { },
+    'r2_a_red_ctbl[13]' => { },
+    'r2_a_red_ctbl[14]' => { },
+    'r2_a_red_ctbl[15]' => { },
+    'r2_a_red_ctbl[16]' => { },
+    'r2_a_red_ctbl[17]' => { },
+    'r2_a_red_ctbl[18]' => { },
+    'r2_a_red_ctbl[19]' => { },
+    'r2_a_red_ctbl[20]' => { },
+    'r2_a_red_ctbl[21]' => { },
+    'r2_a_red_ctbl[22]' => { },
+    'r2_a_red_ctbl[23]' => { },
+    'r2_a_red_ctbl[24]' => { },
+    'r2_a_red_ctbl[25]' => { },
+    'r2_a_red_ctbl[26]' => { },
+    'r2_a_red_ctbl[27]' => { },
+    'r2_a_red_ctbl[28]' => { },
+    'r2_a_red_ctbl[29]' => { },
+    'r2_a_red_ctbl[30]' => { },
+    'r2_a_red_ctbl[31]' => { },
+    'r2_a_green_ctbl[0]' => { },
+    'r2_a_green_ctbl[1]' => { },
+    'r2_a_green_ctbl[2]' => { },
+    'r2_a_green_ctbl[3]' => { },
+    'r2_a_green_ctbl[4]' => { },
+    'r2_a_green_ctbl[5]' => { },
+    'r2_a_green_ctbl[6]' => { },
+    'r2_a_green_ctbl[7]' => { },
+    'r2_a_green_ctbl[8]' => { },
+    'r2_a_green_ctbl[9]' => { },
+    'r2_a_green_ctbl[10]' => { },
+    'r2_a_green_ctbl[11]' => { },
+    'r2_a_green_ctbl[12]' => { },
+    'r2_a_green_ctbl[13]' => { },
+    'r2_a_green_ctbl[14]' => { },
+    'r2_a_green_ctbl[15]' => { },
+    'r2_a_green_ctbl[16]' => { },
+    'r2_a_green_ctbl[17]' => { },
+    'r2_a_green_ctbl[18]' => { },
+    'r2_a_green_ctbl[19]' => { },
+    'r2_a_green_ctbl[20]' => { },
+    'r2_a_green_ctbl[21]' => { },
+    'r2_a_green_ctbl[22]' => { },
+    'r2_a_green_ctbl[23]' => { },
+    'r2_a_green_ctbl[24]' => { },
+    'r2_a_green_ctbl[25]' => { },
+    'r2_a_green_ctbl[26]' => { },
+    'r2_a_green_ctbl[27]' => { },
+    'r2_a_green_ctbl[28]' => { },
+    'r2_a_green_ctbl[29]' => { },
+    'r2_a_green_ctbl[30]' => { },
+    'r2_a_green_ctbl[31]' => { },
+    'r2_a_blue_ctbl[0]' => { },
+    'r2_a_blue_ctbl[1]' => { },
+    'r2_a_blue_ctbl[2]' => { },
+    'r2_a_blue_ctbl[3]' => { },
+    'r2_a_blue_ctbl[4]' => { },
+    'r2_a_blue_ctbl[5]' => { },
+    'r2_a_blue_ctbl[6]' => { },
+    'r2_a_blue_ctbl[7]' => { },
+    'r2_a_blue_ctbl[8]' => { },
+    'r2_a_blue_ctbl[9]' => { },
+    'r2_a_blue_ctbl[10]' => { },
+    'r2_a_blue_ctbl[11]' => { },
+    'r2_a_blue_ctbl[12]' => { },
+    'r2_a_blue_ctbl[13]' => { },
+    'r2_a_blue_ctbl[14]' => { },
+    'r2_a_blue_ctbl[15]' => { },
+    'r2_a_blue_ctbl[16]' => { },
+    'r2_a_blue_ctbl[17]' => { },
+    'r2_a_blue_ctbl[18]' => { },
+    'r2_a_blue_ctbl[19]' => { },
+    'r2_a_blue_ctbl[20]' => { },
+    'r2_a_blue_ctbl[21]' => { },
+    'r2_a_blue_ctbl[22]' => { },
+    'r2_a_blue_ctbl[23]' => { },
+    'r2_a_blue_ctbl[24]' => { },
+    'r2_a_blue_ctbl[25]' => { },
+    'r2_a_blue_ctbl[26]' => { },
+    'r2_a_blue_ctbl[27]' => { },
+    'r2_a_blue_ctbl[28]' => { },
+    'r2_a_blue_ctbl[29]' => { },
+    'r2_a_blue_ctbl[30]' => { },
+    'r2_a_blue_ctbl[31]' => { },
+    'r2_a_red_stbl[0]' => { },
+    'r2_a_red_stbl[1]' => { },
+    'r2_a_red_stbl[2]' => { },
+    'r2_a_red_stbl[3]' => { },
+    'r2_a_red_stbl[4]' => { },
+    'r2_a_red_stbl[5]' => { },
+    'r2_a_red_stbl[6]' => { },
+    'r2_a_red_stbl[7]' => { },
+    'r2_a_red_stbl[8]' => { },
+    'r2_a_red_stbl[9]' => { },
+    'r2_a_red_stbl[10]' => { },
+    'r2_a_red_stbl[11]' => { },
+    'r2_a_red_stbl[12]' => { },
+    'r2_a_red_stbl[13]' => { },
+    'r2_a_red_stbl[14]' => { },
+    'r2_a_red_stbl[15]' => { },
+    'r2_a_red_stbl[16]' => { },
+    'r2_a_red_stbl[17]' => { },
+    'r2_a_red_stbl[18]' => { },
+    'r2_a_red_stbl[19]' => { },
+    'r2_a_red_stbl[20]' => { },
+    'r2_a_red_stbl[21]' => { },
+    'r2_a_red_stbl[22]' => { },
+    'r2_a_red_stbl[23]' => { },
+    'r2_a_red_stbl[24]' => { },
+    'r2_a_red_stbl[25]' => { },
+    'r2_a_red_stbl[26]' => { },
+    'r2_a_red_stbl[27]' => { },
+    'r2_a_red_stbl[28]' => { },
+    'r2_a_red_stbl[29]' => { },
+    'r2_a_red_stbl[30]' => { },
+    'r2_a_red_stbl[31]' => { },
+    'r2_a_blue_stbl[0]' => { },
+    'r2_a_blue_stbl[1]' => { },
+    'r2_a_blue_stbl[2]' => { },
+    'r2_a_blue_stbl[3]' => { },
+    'r2_a_blue_stbl[4]' => { },
+    'r2_a_blue_stbl[5]' => { },
+    'r2_a_blue_stbl[6]' => { },
+    'r2_a_blue_stbl[7]' => { },
+    'r2_a_blue_stbl[8]' => { },
+    'r2_a_blue_stbl[9]' => { },
+    'r2_a_blue_stbl[10]' => { },
+    'r2_a_blue_stbl[11]' => { },
+    'r2_a_blue_stbl[12]' => { },
+    'r2_a_blue_stbl[13]' => { },
+    'r2_a_blue_stbl[14]' => { },
+    'r2_a_blue_stbl[15]' => { },
+    'r2_a_blue_stbl[16]' => { },
+    'r2_a_blue_stbl[17]' => { },
+    'r2_a_blue_stbl[18]' => { },
+    'r2_a_blue_stbl[19]' => { },
+    'r2_a_blue_stbl[20]' => { },
+    'r2_a_blue_stbl[21]' => { },
+    'r2_a_blue_stbl[22]' => { },
+    'r2_a_blue_stbl[23]' => { },
+    'r2_a_blue_stbl[24]' => { },
+    'r2_a_blue_stbl[25]' => { },
+    'r2_a_blue_stbl[26]' => { },
+    'r2_a_blue_stbl[27]' => { },
+    'r2_a_blue_stbl[28]' => { },
+    'r2_a_blue_stbl[29]' => { },
+    'r2_a_blue_stbl[30]' => { },
+    'r2_a_blue_stbl[31]' => { },
+    'r2_a_green_stbl[0]' => { },
+    'r2_a_green_stbl[1]' => { },
+    'r2_a_green_stbl[2]' => { },
+    'r2_a_green_stbl[3]' => { },
+    'r2_a_green_stbl[4]' => { },
+    'r2_a_green_stbl[5]' => { },
+    'r2_a_green_stbl[6]' => { },
+    'r2_a_green_stbl[7]' => { },
+    'r2_a_green_stbl[8]' => { },
+    'r2_a_green_stbl[9]' => { },
+    'r2_a_green_stbl[10]' => { },
+    'r2_a_green_stbl[11]' => { },
+    'r2_a_green_stbl[12]' => { },
+    'r2_a_green_stbl[13]' => { },
+    'r2_a_green_stbl[14]' => { },
+    'r2_a_green_stbl[15]' => { },
+    'r2_a_green_stbl[16]' => { },
+    'r2_a_green_stbl[17]' => { },
+    'r2_a_green_stbl[18]' => { },
+    'r2_a_green_stbl[19]' => { },
+    'r2_a_green_stbl[20]' => { },
+    'r2_a_green_stbl[21]' => { },
+    'r2_a_green_stbl[22]' => { },
+    'r2_a_green_stbl[23]' => { },
+    'r2_a_green_stbl[24]' => { },
+    'r2_a_green_stbl[25]' => { },
+    'r2_a_green_stbl[26]' => { },
+    'r2_a_green_stbl[27]' => { },
+    'r2_a_green_stbl[28]' => { },
+    'r2_a_green_stbl[29]' => { },
+    'r2_a_green_stbl[30]' => { },
+    'r2_a_green_stbl[31]' => { },
+    'def_cor_c0' => { },
+    'def_cor_c1' => { },
+    'def_cor_c2' => { },
+    'def_cor_c3' => { },
+    'def_cor_c4' => { },
+    'def_cor_c5' => { },
+    'def_cor_c6' => { },
+    'def_cor_c7' => { },
+    'def_cor_c8' => { },
+    'def_cor_k0' => { },
+    'def_cor_k1' => { },
+    'def_cor_k2' => { },
+    'yhi_ylo_cor_c0' => { },
+    'yhi_ylo_cor_c1' => { },
+    'yhi_ylo_cor_c2' => { },
+    'yhi_ylo_cor_c3' => { },
+    'yhi_ylo_cor_c4' => { },
+    'yhi_ylo_cor_c5' => { },
+    'yhi_ylo_cor_c6' => { },
+    'yhi_ylo_cor_c7' => { },
+    'yhi_ylo_cor_c8' => { },
+    'yhi_ylo_cor_k0' => { },
+    'yhi_ylo_cor_k1' => { },
+    'yhi_ylo_cor_k2' => { },
+    'def_conv_chrm_a_m' => { },
+    'def_conv_chrm_a_p' => { },
+    'def_conv_chrm_b_m' => { },
+    'def_conv_chrm_b_p' => { },
+    'def_conv_chrm_c_m' => { },
+    'def_conv_chrm_c_p' => { },
+    'def_conv_chrm_d_m' => { },
+    'def_conv_chrm_d_p' => { },
+    'def_conv_chrm_k_cb' => { },
+    'def_conv_chrm_k_cr' => { },
+    'def_conv_luma_v0' => { },
+    'def_conv_luma_v1' => { },
+    'def_conv_luma_v2' => { },
+    'def_conv_luma_k' => { },
+    'tl84_conv_chrm_a_m' => { },
+    'tl84_conv_chrm_a_p' => { },
+    'tl84_conv_chrm_b_m' => { },
+    'tl84_conv_chrm_b_p' => { },
+    'tl84_conv_chrm_c_m' => { },
+    'tl84_conv_chrm_c_p' => { },
+    'tl84_conv_chrm_d_m' => { },
+    'tl84_conv_chrm_d_p' => { },
+    'tl84_conv_chrm_k_cb' => { },
+    'tl84_conv_chrm_k_cr' => { },
+    'tl84_conv_luma_v0' => { },
+    'tl84_conv_luma_v1' => { },
+    'tl84_conv_luma_v2' => { },
+    'tl84_conv_luma_k' => { },
+    'incand_conv_chrm_a_m' => { },
+    'incand_conv_chrm_a_p' => { },
+    'incand_conv_chrm_b_m' => { },
+    'incand_conv_chrm_b_p' => { },
+    'incand_conv_chrm_c_m' => { },
+    'incand_conv_chrm_c_p' => { },
+    'incand_conv_chrm_d_m' => { },
+    'incand_conv_chrm_d_p' => { },
+    'incand_conv_chrm_k_cb' => { },
+    'incand_conv_chrm_k_cr' => { },
+    'incand_conv_luma_v0' => { },
+    'incand_conv_luma_v1' => { },
+    'incand_conv_luma_v2' => { },
+    'incand_conv_luma_k' => { },
+    'daylt_conv_chrm_a_m' => { },
+    'daylt_conv_chrm_a_p' => { },
+    'daylt_conv_chrm_b_m' => { },
+    'daylt_conv_chrm_b_p' => { },
+    'daylt_conv_chrm_c_m' => { },
+    'daylt_conv_chrm_c_p' => { },
+    'daylt_conv_chrm_d_m' => { },
+    'daylt_conv_chrm_d_p' => { },
+    'daylt_conv_chrm_k_cb' => { },
+    'daylt_conv_chrm_k_cr' => { },
+    'daylt_conv_luma_v0' => { },
+    'daylt_conv_luma_v1' => { },
+    'daylt_conv_luma_v2' => { },
+    'daylt_conv_luma_k' => { },
+    'yhi_ylo_conv_chrm_a_m' => { },
+    'yhi_ylo_conv_chrm_a_p' => { },
+    'yhi_ylo_conv_chrm_b_m' => { },
+    'yhi_ylo_conv_chrm_b_p' => { },
+    'yhi_ylo_conv_chrm_c_m' => { },
+    'yhi_ylo_conv_chrm_c_p' => { },
+    'yhi_ylo_conv_chrm_d_m' => { },
+    'yhi_ylo_conv_chrm_d_p' => { },
+    'yhi_ylo_conv_chrm_k_cb' => { },
+    'yhi_ylo_conv_chrm_k_cr' => { },
+    'yhi_ylo_conv_luma_v0' => { },
+    'yhi_ylo_conv_luma_v1' => { },
+    'yhi_ylo_conv_luma_v2' => { },
+    'yhi_ylo_conv_luma_k' => { },
+    'gamma_enable' => { },
+    'def_luma_gamma_mode' => { },
+    'def_rgb_gamma_mode' => { },
+    'blck_lvl_even_cols' => { },
+    'blck_lvl_odd_cols' => { },
+    'defect_pix_min_thresh' => { },
+    'defect_pix_max_thresh' => { },
+    'defect_pix_cor_enable' => { },
+    'prview_resol' => { },
+    'snapshot_resol' => { },
+    'curr_resol' => { },
+    'sensor_fmt' => { },
+    'discard_frst_frm' => { },
+    'frm_skip_pttrn' => { },
+    'sensor_type' => { },
+    'max_video_fps' => { },
+    'video_fps' => { },
+    'max_prview_fps' => { },
+    'prview_fps' => { },
+    'nghtsht_fps' => { },
+    'sensr_ful_wdth' => { },
+    'sensr_ful_hght' => { },
+    'sensr_qtr_wdth' => { },
+    'sensr_qtr_hght' => { },
+    'nightshot_mode' => { },
+    'pclk_invert' => { },
+    'cam_mclk_hz' => { },
+    'chrom_supress' => { },
+    'chro_sup_luma_thres_1' => { },
+    'chro_sup_luma_thres_2' => { },
+    'chro_sup_luma_thres_3' => { },
+    'chro_sup_luma_thres_4' => { },
+    'chro_sup_chro_thres_1' => { },
+    'chro_sup_chro_thres_2' => { },
+    'la_detect' => { },
+    'la_enable' => { },
+    'HJR_enable' => { },
+    'HJR_max_num_frames' => { },
+    'HJR_one_to_two_offset' => { },
+    'HJR_n_reduction_flat' => { },
+    'HJR_n_reduction_texture' => { },
+    'HJR_texture_threshold' => { },
+);
+
+# generate tag names and descriptions
+{
+    local $_;
+    my $table = \%Image::ExifTool::Qualcomm::Main;
+    MakeNameAndDesc($_, $$table{$_}) foreach TagTableKeys($table);
+}
+
+#------------------------------------------------------------------------------
+# Generate tag Name and Description from a Qualcomm tag ID
+# Inputs: 0) tag ID, 1) tagInfo ref
+# Returns: true on success
+sub MakeNameAndDesc($$)
+{
+    local $_ = shift;
+    my $tagInfo = shift;
+    # capitalize various leading acronyms or just first letter...
+    s/^(asf|awb|aec|afr|af_|la_|r2_tl|tl)/\U$1/ or $_ = ucfirst;
+    s/_([a-z])/_\u$1/g;     # capitalize first letter of each word
+    s/\[(\d+)\]$/sprintf("_%.2d",$1)/e; # use 2-digit subscripts (and remove brackets)
+    tr/-_a-zA-Z0-9//dc;     # delete invalid characters
+    my $desc = $_;
+    # convert underlines to spaces in description
+    if ($desc =~ tr/_/ /) {
+        # remove unnecessary underlines from tag name...
+        s/_([A-Z][a-z])/$1/g;
+        s/([a-z0-9])_([A-Z])/$1$2/g;
+        s/([A-Za-z])_(\d)/$1$2/g;
+    }
+    return 0 unless length;
+    $$tagInfo{Name} = $_;
+    $$tagInfo{Description} = $desc;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Qualcomm APP7 metadata (ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessQualcomm($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{DataPos};
+    my $pos = $$dirInfo{DirStart};
+    my $dirEnd = $pos + $$dirInfo{DirLen};
+
+    $et->VerboseDir('Qualcomm', undef, $$dirInfo{DirLen});
+    SetByteOrder('II');
+
+    while ($pos + 3 < $dirEnd) {
+        my $valLen = Get16u($dataPt, $pos);
+        my $tagLen = Get8u($dataPt, $pos + 2);
+        last if $pos + 8 + $tagLen + $valLen > $dirEnd;
+        my $tag = substr($$dataPt, $pos + 3, $tagLen);
+        $pos += 3 + $tagLen;    # point to format byte
+        my $fmt = Get8u($dataPt, $pos);
+        # (not sure what these counts are for -- both are always 1 in my samples)
+        #my $cnt1 = Get16u($dataPt, $pos + 1);
+        #my $cnt2 = Get16u($dataPt, $pos + 3);
+        $pos += 5;              # point to start of value data
+        my ($val, $format);
+        if ($fmt <= 7) {
+            $format = $qualcommFormat[$fmt];
+            $val = ReadValue($dataPt, $pos, $format, undef, $valLen);
+        } else {
+            $format = "format $fmt";
+            my $value = substr($$dataPt, $pos, $valLen);
+            $val = \$value;
+        }
+        unless (defined $$tagTablePtr{$tag} or $Image::ExifTool::specialTags{$tag}) {
+            my %tagInfo;
+            if (MakeNameAndDesc($tag, \%tagInfo)) {
+                $et->VPrint(0, $$et{INDENT}, "[adding Qualcomm:$tagInfo{Name}]\n");
+                AddTagToTable($tagTablePtr, $tag, \%tagInfo);
+            }
+        }
+        $et->HandleTag($tagTablePtr, $tag, $val,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Start   => $pos,
+            Size    => $valLen,
+            Format  => $format,
+        );
+        $pos += $valLen;        # point to start of next entry
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Qualcomm - Read Qualcomm APP7 meta information
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read
+information from the APP7 Qualcomm segment in JPEG images.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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/Qualcomm Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/QuickTime.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/QuickTime.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/QuickTime.pm	(revision 34921)
@@ -2,5 +2,5 @@
 # File:         QuickTime.pm
 #
-# Description:  Read QuickTime, MP4 and M4A meta information
+# Description:  Read QuickTime and MP4 meta information
 #
 # Revisions:    10/04/2005 - P. Harvey Created
@@ -9,18 +9,33 @@
 #               07/27/2010 - P. Harvey Updated to 2010-05-03 QuickTime spec
 #
-# References:   1) http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html
-#               2) http://search.cpan.org/dist/MP4-Info-1.04/
-#               3) http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
-#               4) http://wiki.multimedia.cx/index.php?title=Apple_QuickTime
-#               5) ISO 14496-12 (http://neuron2.net/library/avc/c041828_ISO_IEC_14496-12_2005(E).pdf)
-#               6) ISO 14496-16 (http://www.iec-normen.de/previewpdf/info_isoiec14496-16%7Bed2.0%7Den.pdf)
-#               7) http://atomicparsley.sourceforge.net/mpeg-4files.html
-#               8) http://wiki.multimedia.cx/index.php?title=QuickTime_container
-#               9) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart3.pdf (Oct 2008)
-#               10) http://code.google.com/p/mp4v2/wiki/iTunesMetadata
-#               11) http://www.canieti.com.mx/assets/files/1011/IEC_100_1384_DC.pdf
-#               12) QuickTime file format specification 2010-05-03
-#               13) http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf
-#               14) http://standards.iso.org/ittf/PubliclyAvailableStandards/c051533_ISO_IEC_14496-12_2008.zip
+# References:
+#
+#   1) http://developer.apple.com/mac/library/documentation/QuickTime/QTFF/QTFFChap1/qtff1.html
+#   2) http://search.cpan.org/dist/MP4-Info-1.04/
+#   3) http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
+#   4) http://wiki.multimedia.cx/index.php?title=Apple_QuickTime
+#   5) ISO 14496-12 (http://read.pudn.com/downloads64/ebook/226547/ISO_base_media_file_format.pdf)
+#   6) ISO 14496-16 (http://www.iec-normen.de/previewpdf/info_isoiec14496-16%7Bed2.0%7Den.pdf)
+#   7) http://atomicparsley.sourceforge.net/mpeg-4files.html
+#   8) http://wiki.multimedia.cx/index.php?title=QuickTime_container
+#   9) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart3.pdf (Oct 2008)
+#   10) http://code.google.com/p/mp4v2/wiki/iTunesMetadata
+#   11) http://www.canieti.com.mx/assets/files/1011/IEC_100_1384_DC.pdf
+#   12) QuickTime file format specification 2010-05-03
+#   13) http://www.adobe.com/devnet/flv/pdf/video_file_format_spec_v10.pdf
+#   14) http://standards.iso.org/ittf/PubliclyAvailableStandards/c051533_ISO_IEC_14496-12_2008.zip
+#   15) http://getid3.sourceforge.net/source/module.audio-video.quicktime.phps
+#   16) http://qtra.apple.com/atoms.html
+#   17) http://www.etsi.org/deliver/etsi_ts/126200_126299/126244/10.01.00_60/ts_126244v100100p.pdf
+#   18) https://github.com/appsec-labs/iNalyzer/blob/master/scinfo.m
+#   19) http://nah6.com/~itsme/cvs-xdadevtools/iphone/tools/decodesinf.pl
+#   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
+#   27) https://exiftool.org/forum/index.php?topic=11517.0
 #------------------------------------------------------------------------------
 
@@ -28,58 +43,47 @@
 
 use strict;
-use vars qw($VERSION);
+use vars qw($VERSION $AUTOLOAD %stringEncoding);
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
-
-$VERSION = '1.48';
-
-sub FixWrongFormat($);
+use Image::ExifTool::GPS;
+
+$VERSION = '2.59';
+
 sub ProcessMOV($$;$);
 sub ProcessKeys($$$);
+sub ProcessMetaKeys($$$);
 sub ProcessMetaData($$$);
+sub ProcessEncodingParams($$$);
+sub ProcessSampleDesc($$$);
+sub ProcessHybrid($$$);
+sub ProcessRights($$$);
+# ++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($);
-
-# information for time/date-based tags (time zero is Jan 1, 1904)
-my %timeInfo = (
-    # Note: This value will be in UTC if generated by a system that is aware of the time zone
-    ValueConv => 'ConvertUnixTime($val - ((66 * 365 + 17) * 24 * 3600))',
-    PrintConv => '$self->ConvertDateTime($val)',
-    # (can't put Groups here because they aren't constant!)
-);
-# information for duration tags
-my %durationInfo = (
-    ValueConv => '$$self{TimeScale} ? $val / $$self{TimeScale} : $val',
-    PrintConv => '$$self{TimeScale} ? ConvertDuration($val) : $val',
-);
-
-# 4-character Vendor ID codes (ref PH)
-my %vendorID = (
-    appl => 'Apple',
-    fe20 => 'Olympus (fe20)', # (FE200)
-    FFMP => 'FFmpeg',
-   'GIC '=> 'General Imaging Co.',
-    kdak => 'Kodak',
-    KMPI => 'Konica-Minolta',
-    mino => 'Minolta',
-    niko => 'Nikon',
-    NIKO => 'Nikon',
-    olym => 'Olympus',
-    pana => 'Panasonic',
-    pent => 'Pentax',
-    pr01 => 'Olympus (pr01)', # (FE100,FE110,FE115)
-    sany => 'Sanyo',
-   'SMI '=> 'Sorenson Media Inc.',
-    ZORA => 'Zoran Corporation',
-);
-
-# QuickTime data atom encodings for string types (ref 12)
-my %stringEncoding = (
-    1 => 'UTF8',
-    2 => 'UTF16',
-    3 => 'ShiftJIS',
-    4 => 'UTF8',
-    5 => 'UTF16',
-);
+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
@@ -88,4 +92,5 @@
    '3G2' => 'video/3gpp2',
    '3GP' => 'video/3gpp',
+    AAX  => 'audio/vnd.audible.aax',
     DVB  => 'video/vnd.dvb.file',
     F4A  => 'audio/mp4',
@@ -100,40 +105,11 @@
     MOV  => 'video/quicktime',
     MQV  => 'video/quicktime',
-);
-
-my %graphicsMode = (
-    # (ref http://homepage.mac.com/vanhoek/MovieGuts%20docs/64.html)
-    0x00 => 'srcCopy',
-    0x01 => 'srcOr',
-    0x02 => 'srcXor',
-    0x03 => 'srcBic',
-    0x04 => 'notSrcCopy',
-    0x05 => 'notSrcOr',
-    0x06 => 'notSrcXor',
-    0x07 => 'notSrcBic',
-    0x08 => 'patCopy',
-    0x09 => 'patOr',
-    0x0a => 'patXor',
-    0x0b => 'patBic',
-    0x0c => 'notPatCopy',
-    0x0d => 'notPatOr',
-    0x0e => 'notPatXor',
-    0x0f => 'notPatBic',
-    0x20 => 'blend',
-    0x21 => 'addPin',
-    0x22 => 'addOver',
-    0x23 => 'subPin',
-    0x24 => 'transparent',
-    0x25 => 'addMax',
-    0x26 => 'subOver',
-    0x27 => 'addMin',
-    0x31 => 'grayishTextOr',
-    0x32 => 'hilite',
-    0x40 => 'ditherCopy',
-    # the following ref ISO/IEC 15444-3
-    0x100 => 'Alpha',
-    0x101 => 'White Alpha',
-    0x102 => 'Pre-multiplied Black Alpha',
-    0x110 => 'Component Alpha',
+    HEIC => 'image/heic',
+    HEVC => 'image/heic-sequence',
+    HEICS=> 'image/heic-sequence',
+    HEIF => 'image/heif',
+    HEIFS=> 'image/heif-sequence',
+    AVIF => 'image/avif', #PH (NC)
+    CRX  => 'video/x-canon-crx',    # (will get overridden)
 );
 
@@ -156,4 +132,5 @@
     '3gp6' => '3GPP Media (.3GP) Release 6 Streaming Servers', # video/3gpp
     '3gs7' => '3GPP Media (.3GP) Release 7 Streaming Servers', # video/3gpp
+    'aax ' => 'Audible Enhanced Audiobook (.AAX)', #PH
     'avc1' => 'MP4 Base w/ AVC ext [ISO 14496-12:2005]', # video/mp4
     'CAEP' => 'Canon Digital Camera',
@@ -191,4 +168,5 @@
     'jpx ' => 'JPEG 2000 with extensions (.JPX) [ISO 15444-2]', # image/jpx
     'KDDI' => '3GPP2 EZmovie for KDDI 3G cellphones', # video/3gpp2
+    #LCAG  => (found in CompatibleBrands of Leica MOV videos)
     'M4A ' => 'Apple iTunes AAC-LC (.M4A) Audio', # audio/x-m4a
     'M4B ' => 'Apple iTunes AAC-LC (.M4B) Audio Book', # audio/mp4
@@ -227,4 +205,240 @@
     'ssc1' => 'Samsung stereoscopic, single stream',
     'ssc2' => 'Samsung stereoscopic, dual stream',
+    'XAVC' => 'Sony XAVC', #PH
+    'heic' => 'High Efficiency Image Format HEVC still image (.HEIC)', # image/heic
+    '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)
+);
+
+# information for int32u date/time tags (time zero is Jan 1, 1904)
+my %timeInfo = (
+    Notes => 'converted from UTC to local time if the QuickTimeUTC option is set',
+    Shift => 'Time',
+    Writable => 1,
+    Permanent => 1,
+    DelValue => 0,
+    # It is not uncommon for brain-dead software to use the wrong time zero,
+    # so assume a time zero of Jan 1, 1970 if the date is before this
+    # Note: This value will be in UTC if generated by a system that is aware of the time zone
+    RawConv => q{
+        my $offset = (66 * 365 + 17) * 24 * 3600;
+        return $val - $offset if $val >= $offset or $$self{OPTIONS}{QuickTimeUTC};
+        if ($val and not $$self{IsWriting}) {
+            $self->WarnOnce('Patched incorrect time zero for QuickTime date/time tag',1);
+        }
+        return $val;
+    },
+    RawConvInv => q{
+        if ($$self{FileType} eq 'CR3' and not $self->Options('QuickTimeUTC')) {
+            # convert to UTC
+            my $offset = (66 * 365 + 17) * 24 * 3600;
+            $val = ConvertUnixTime($val - $offset);
+            $val = GetUnixTime($val, 1) + $offset;
+        }
+        return $val;
+    },
+    # (all CR3 files store UTC times - PH)
+    ValueConv => 'ConvertUnixTime($val, $self->Options("QuickTimeUTC") || $$self{FileType} eq "CR3")',
+    ValueConvInv => 'GetUnixTime($val, $self->Options("QuickTimeUTC")) + (66 * 365 + 17) * 24 * 3600',
+    PrintConv => '$self->ConvertDateTime($val)',
+    PrintConvInv => '$self->InverseDateTime($val)',
+    # (can't put Groups here because they aren't constant!)
+);
+# information for duration tags
+my %durationInfo = (
+    ValueConv => '$$self{TimeScale} ? $val / $$self{TimeScale} : $val',
+    PrintConv => '$$self{TimeScale} ? ConvertDuration($val) : $val',
+);
+# handle unknown tags
+my %unknownInfo = (
+    Unknown => 1,
+    ValueConv => '$val =~ /^([\x20-\x7e]*)\0*$/ ? $1 : \$val',
+);
+
+# multi-language text with 6-byte header
+my %langText = ( IText => 6 );
+
+# parsing for most of the 3gp udta language text boxes
+my %langText3gp = (
+    Notes => 'used in 3gp videos',
+    Avoid => 1,
+    IText => 6,
+);
+
+# 4-character Vendor ID codes (ref PH)
+my %vendorID = (
+    appl => 'Apple',
+    fe20 => 'Olympus (fe20)', # (FE200)
+    FFMP => 'FFmpeg',
+   'GIC '=> 'General Imaging Co.',
+    kdak => 'Kodak',
+    KMPI => 'Konica-Minolta',
+    leic => 'Leica',
+    mino => 'Minolta',
+    niko => 'Nikon',
+    NIKO => 'Nikon',
+    olym => 'Olympus',
+    pana => 'Panasonic',
+    pent => 'Pentax',
+    pr01 => 'Olympus (pr01)', # (FE100,FE110,FE115)
+    sany => 'Sanyo',
+   'SMI '=> 'Sorenson Media Inc.',
+    ZORA => 'Zoran Corporation',
+   'AR.D'=> 'Parrot AR.Drone',
+   ' KD '=> 'Kodak', # (FZ201)
+);
+
+# QuickTime data atom encodings for string types (ref 12)
+%stringEncoding = (
+    1 => 'UTF8',
+    2 => 'UTF16',
+    3 => 'ShiftJIS',
+    4 => 'UTF8',
+    5 => 'UTF16',
+);
+
+my %graphicsMode = (
+    # (ref http://homepage.mac.com/vanhoek/MovieGuts%20docs/64.html)
+    0x00 => 'srcCopy',
+    0x01 => 'srcOr',
+    0x02 => 'srcXor',
+    0x03 => 'srcBic',
+    0x04 => 'notSrcCopy',
+    0x05 => 'notSrcOr',
+    0x06 => 'notSrcXor',
+    0x07 => 'notSrcBic',
+    0x08 => 'patCopy',
+    0x09 => 'patOr',
+    0x0a => 'patXor',
+    0x0b => 'patBic',
+    0x0c => 'notPatCopy',
+    0x0d => 'notPatOr',
+    0x0e => 'notPatXor',
+    0x0f => 'notPatBic',
+    0x20 => 'blend',
+    0x21 => 'addPin',
+    0x22 => 'addOver',
+    0x23 => 'subPin',
+    0x24 => 'transparent',
+    0x25 => 'addMax',
+    0x26 => 'subOver',
+    0x27 => 'addMin',
+    0x31 => 'grayishTextOr',
+    0x32 => 'hilite',
+    0x40 => 'ditherCopy',
+    # the following ref ISO/IEC 15444-3
+    0x100 => 'Alpha',
+    0x101 => 'White Alpha',
+    0x102 => 'Pre-multiplied Black Alpha',
+    0x110 => 'Component Alpha',
+);
+
+my %channelLabel = (
+    0xFFFFFFFF => 'Unknown',
+    0 => 'Unused',
+    100 => 'UseCoordinates',
+    1 => 'Left',
+    2 => 'Right',
+    3 => 'Center',
+    4 => 'LFEScreen',
+    5 => 'LeftSurround',
+    6 => 'RightSurround',
+    7 => 'LeftCenter',
+    8 => 'RightCenter',
+    9 => 'CenterSurround',
+    10 => 'LeftSurroundDirect',
+    11 => 'RightSurroundDirect',
+    12 => 'TopCenterSurround',
+    13 => 'VerticalHeightLeft',
+    14 => 'VerticalHeightCenter',
+    15 => 'VerticalHeightRight',
+    16 => 'TopBackLeft',
+    17 => 'TopBackCenter',
+    18 => 'TopBackRight',
+    33 => 'RearSurroundLeft',
+    34 => 'RearSurroundRight',
+    35 => 'LeftWide',
+    36 => 'RightWide',
+    37 => 'LFE2',
+    38 => 'LeftTotal',
+    39 => 'RightTotal',
+    40 => 'HearingImpaired',
+    41 => 'Narration',
+    42 => 'Mono',
+    43 => 'DialogCentricMix',
+    44 => 'CenterSurroundDirect',
+    45 => 'Haptic',
+    200 => 'Ambisonic_W',
+    201 => 'Ambisonic_X',
+    202 => 'Ambisonic_Y',
+    203 => 'Ambisonic_Z',
+    204 => 'MS_Mid',
+    205 => 'MS_Side',
+    206 => 'XY_X',
+    207 => 'XY_Y',
+    301 => 'HeadphonesLeft',
+    302 => 'HeadphonesRight',
+    304 => 'ClickTrack',
+    305 => 'ForeignLanguage',
+    400 => 'Discrete',
+    0x10000 => 'Discrete_0',
+    0x10001 => 'Discrete_1',
+    0x10002 => 'Discrete_2',
+    0x10003 => 'Discrete_3',
+    0x10004 => 'Discrete_4',
+    0x10005 => 'Discrete_5',
+    0x10006 => 'Discrete_6',
+    0x10007 => 'Discrete_7',
+    0x10008 => 'Discrete_8',
+    0x10009 => 'Discrete_9',
+    0x1000a => 'Discrete_10',
+    0x1000b => 'Discrete_11',
+    0x1000c => 'Discrete_12',
+    0x1000d => 'Discrete_13',
+    0x1000e => 'Discrete_14',
+    0x1000f => 'Discrete_15',
+    0x1ffff => 'Discrete_65535',
+);
+
+# 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 => 'stbl', co64 => 'stbl', stsz => 'stbl', stz2 => 'stbl',
+              stsc => 'stbl', stts => 'stbl' );
+
+# 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 => 'stsd',
+    },
+    text => { %eeStd },
+    meta => { %eeStd },
+    sbtl => { %eeStd },
+    data => { %eeStd },
+    camm => { %eeStd }, # (Insta360)
+    ctbx => { %eeStd }, # (GM cars)
+    ''   => { 'gps ' => 'moov', 'GPS ' => 'main' }, # (no handler -- in top level 'moov' box, and main)
+);
+# boxes to save when ExtractEmbedded is set to 2 or higher
+my %eeBox2 = (
+    vide => { avcC => 'stsd' }, # (parses H264 video stream)
 );
 
@@ -232,14 +446,58 @@
 %Image::ExifTool::QuickTime::Main = (
     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.  Exiftool extracts meta information from the UserData atom
-        (including some proprietary manufacturer-specific information), as well as
-        extracting various audio, video and image parameters.  Tags with a question
-        mark after their name are not extracted unless the Unknown option is set.
-    },
-    free => { Unknown => 1, Binary => 1 },
-    skip => { Unknown => 1, Binary => 1 },
+    meta => { # 'meta' is found here in my Sony ILCE-7S MP4 sample - PH
+        Name => 'Meta',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::Meta',
+            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,
+        },
+        # (also Samsung WB750 uncompressed thumbnail data starting with "SDIC\0")
+    ],
+    # fre1 - 4 bytes: "june" (Kodak PixPro SP360)
+    frea => {
+        Name => 'Kodak_frea',
+        SubDirectory => { TagTable => 'Image::ExifTool::Kodak::frea' },
+    },
+    skip => [
+        {
+            Name => 'CanonSkip',
+            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 },
     ftyp => { #MP4
@@ -253,17 +511,26 @@
     PICT => {
         Name => 'PreviewPICT',
+        Groups => { 2 => 'Preview' },
         Binary => 1,
     },
     pict => { #8
         Name => 'PreviewPICT',
+        Groups => { 2 => 'Preview' },
         Binary => 1,
     },
+    # (note that moov is present for an HEIF sequence)
     moov => {
         Name => 'Movie',
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Movie' },
     },
-    mdat => { Name => 'MovieData', Unknown => 1, Binary => 1 },
+    moof => {
+        Name => 'MovieFragment',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::MovieFragment' },
+    },
+    # mfra - movie fragment random access: contains tfra (track fragment random access), and
+    #           mfro (movie fragment random access offset) (ref 5)
+    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
@@ -271,9 +538,12 @@
         },
     },
+    'mdat-offset' => 'MediaDataOffset',
     junk => { Unknown => 1, Binary => 1 }, #8
     uuid => [
         { #9 (MP4 files)
-            Name => 'UUID-XMP',
+            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',
@@ -291,5 +561,5 @@
         { #PH (Flip MP4 files)
             Name => 'UUID-Flip',
-            Condition => '$$valPt=~/\x4a\xb0\x3b\x0f\x61\x8d\x40\x75\x82\xb2\xd9\xfa\xce\xd3\x5f\xf5/',
+            Condition => '$$valPt=~/^\x4a\xb0\x3b\x0f\x61\x8d\x40\x75\x82\xb2\xd9\xfa\xce\xd3\x5f\xf5/',
             SubDirectory => {
                 TagTable => 'Image::ExifTool::QuickTime::Flip',
@@ -298,10 +568,149 @@
         },
         # "\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-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,
+            },
+        },
+        { # (ref https://github.com/JamesHeinrich/getID3/blob/master/getid3/module.audio-video.quicktime.php)
+            Name => 'SensorData', # sensor data for the 360Fly
+            Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/ and $$self{OPTIONS}{ExtractEmbedded}',
+            SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Tags360Fly' },
+        },
+        {
+            Name => 'SensorData',
+            Condition => '$$valPt=~/^\xef\xe1\x58\x9a\xbb\x77\x49\xef\x80\x95\x27\x75\x9e\xb1\xdc\x6f/',
+            Notes => 'raw 360Fly sensor data without ExtractEmbedded option',
+            RawConv => q{
+                $self->WarnOnce('Use the ExtractEmbedded option to decode timed SensorData',3);
+                return \$val;
+            },
+        },
+        { #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
             Name => 'UUID-Unknown',
-            Unknown => 1,
-            Binary => 1,
+            %unknownInfo,
         },
     ],
+    _htc => {
+        Name => 'HTCInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HTCInfo' },
+    },
+    udta => {
+        Name => 'UserData',
+        SubDirectory => { TagTable => 'Image::ExifTool::FLIR::UserData' },
+    },
+    thum => { #PH
+        Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        Binary => 1,
+    },
+   'thm ' => { #PH (70mai A800)
+        Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        Binary => 1,
+    },
+    ardt => { #PH
+        Name => 'ARDroneFile',
+        ValueConv => 'length($val) > 4 ? substr($val,4) : $val', # remove length
+    },
+    prrt => { #PH
+        Name => 'ARDroneTelemetry',
+        Notes => q{
+            telemetry information for each video frame: status1, status2, time, pitch,
+            roll, yaw, speed, altitude
+        },
+        ValueConv => q{
+            my $size = length $val;
+            return \$val if $size < 12 or not $$self{OPTIONS}{Binary};
+            my $len = Get16u(\$val, 2);
+            my $str = '';
+            SetByteOrder('II');
+            my $pos = 12;
+            while ($pos + $len <= $size) {
+                my $s1 = Get16u(\$val, $pos);
+                # s2: 7=take-off?, 3=moving, 4=hovering, 9=landing?, 2=landed
+                my $s2 = Get16u(\$val, $pos + 2);
+                $str .= "$s1 $s2";
+                my $num = int(($len-4)/4);
+                my ($i, $v);
+                for ($i=0; $i<$num; ++$i) {
+                    my $pt = $pos + 4 + $i * 4;
+                    if ($i > 0 && $i < 4) {
+                        $v = GetFloat(\$val, $pt); # pitch/roll/yaw
+                    } else {
+                        $v = Get32u(\$val, $pt);
+                        # convert time to sec, and speed(NC)/altitude to metres
+                        $v /= 1000 if $i <= 5;
+                    }
+                    $str .= " $v";
+                }
+                $str .= "\n";
+                $pos += $len;
+            }
+            SetByteOrder('MM');
+            return \$str;
+        },
+    },
+    udat => { #PH (GPS NMEA-format log written by Datakam Player software)
+        Name => 'GPSLog',
+        Binary => 1,    # (actually ASCII, but very lengthy)
+    },
+    # 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,1)', # (add time zone if it didn't exist)
+    },
+    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)
+   'GPS ' => {  # GPS data written by 70mai dashcam (parsed in QuickTimeStream.pl)
+        Name => 'GPSDataList2',
+        Unknown => 1,
+        Binary => 1,
+    },
 );
 
@@ -326,5 +735,17 @@
         Format => 'undef[$size-8]',
         # ignore any entry with a null, and return others as a list
-        ValueConv => 'my @a=($val=~/.{4}/sg); @a=grep(!/\0/,@a); \@a', 
+        ValueConv => 'my @a=($val=~/.{4}/sg); @a=grep(!/\0/,@a); \@a',
+    },
+);
+
+# proprietary HTC atom (HTC One MP4 video)
+%Image::ExifTool::QuickTime::HTCInfo = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'Tags written by some HTC camera phones.',
+    slmt => {
+        Name => 'Unknown_slmt',
+        Unknown => 1,
+        Format => 'int32u', # (observed values: 4)
     },
 );
@@ -351,5 +772,6 @@
 # image description data block
 %Image::ExifTool::QuickTime::ImageDesc = (
-    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    PROCESS_PROC => \&ProcessHybrid,
+    VARS => { ID_LABEL => 'ID/Index' },
     GROUPS => { 2 => 'Image' },
     FORMAT => 'int16u',
@@ -385,4 +807,5 @@
 #            v410 => "Uncompressed Y'CbCr, 10-bit 4:4:4",
 #            v210 => "Uncompressed Y'CbCr, 10-bit 4:2:2",
+#            hvc1 => 'HEVC', #PH
 #        },
     },
@@ -410,4 +833,184 @@
     },
     41 => 'BitDepth',
+#
+# Observed offsets for child atoms of various CompressorID types:
+#
+#   CompressorID  Offset  Child atoms
+#   -----------   ------  ----------------
+#   avc1          86      avcC, btrt, colr, pasp, fiel, clap, svcC
+#   mp4v          86      esds, pasp
+#   s263          86      d263
+#
+    btrt => {
+        Name => 'BitrateInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Bitrate' },
+    },
+    # Reference for fiel, colr, pasp, clap:
+    # https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9
+    fiel => {
+        Name => 'VideoFieldOrder',
+        ValueConv => 'join(" ", unpack("C*",$val))',
+        PrintConv => [{
+            1 => 'Progressive',
+            2 => '2:1 Interlaced',
+        }],
+    },
+    colr => {
+        Name => 'ColorRepresentation',
+        ValueConv => 'join(" ", substr($val,0,4), unpack("x4n*",$val))',
+    },
+    pasp => {
+        Name => 'PixelAspectRatio',
+        ValueConv => 'join(":", unpack("N*",$val))',
+    },
+    clap => {
+        Name => 'CleanAperture',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::CleanAperture' },
+    },
+    avcC => {
+        # (see http://thompsonng.blogspot.ca/2010/11/mp4-file-format-part-2.html)
+        Name => 'AVCConfiguration',
+        Unknown => 1,
+        Binary => 1,
+    },
+    JPEG => { # (found in CR3 images; used as a flag to identify JpgFromRaw 'vide' stream)
+        Name => 'JPEGInfo',
+        # (4 bytes all zero)
+        Unknown => 1,
+        Binary => 1,
+    },
+    # hvcC - HEVC configuration
+    # svcC - 7 bytes: 00 00 00 00 ff e0 00
+    # esds - elementary stream descriptor
+    # d263
+    gama => { Name => 'Gamma', Format => 'fixed32u' },
+    # mjqt - default quantization table for MJPEG
+    # mjht - default Huffman table for MJPEG
+    # csgm ? (seen in hevc video)
+    CMP1 => { # Canon CR3
+        Name => 'CMP1',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CMP1' },
+    },
+    CDI1 => { # Canon CR3
+        Name => 'CDI1',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Canon::CDI1',
+            Start => 4,
+        },
+    },
+    # JPEG - 4 bytes all 0 (Canon CR3)
+    # free - (Canon CR3)
+#
+# spherical video v2 stuff (untested)
+#
+    st3d => {
+        Name => 'Stereoscopic3D',
+        Format => 'int8u',
+        ValueConv => '$val =~ s/.* //; $val', # (remove leading version/flags bytes?)
+        PrintConv => {
+            0 => 'Monoscopic',
+            1 => 'Stereoscopic Top-Bottom',
+            2 => 'Stereoscopic Left-Right',
+            3 => 'Stereoscopic Stereo-Custom', # (provisional in spec as of 2017-10-10)
+        },
+    },
+    sv3d => {
+        Name => 'SphericalVideo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::sv3d' },
+    },
+);
+
+# 'sv3d' atom information (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md)
+%Image::ExifTool::QuickTime::sv3d = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        Tags defined by the Spherical Video V2 specification.  See
+        L<https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md>
+        for the specification.
+    },
+    svhd => {
+        Name => 'MetadataSource',
+        Format => 'undef',
+        ValueConv => '$val=~tr/\0//d; $val', # (remove version/flags? and terminator?)
+    },
+    proj => {
+        Name => 'Projection',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::proj' },
+    },
+);
+
+# 'proj' atom information (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md)
+%Image::ExifTool::QuickTime::proj = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    prhd => {
+        Name => 'ProjectionHeader',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::prhd' },
+    },
+    cbmp => {
+        Name => 'CubemapProj',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::cbmp' },
+    },
+    equi => {
+        Name => 'EquirectangularProj',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::equi' },
+    },
+    # mshp - MeshProjection (P.I.T.A. to decode, for not much reward, see ref)
+);
+
+# 'prhd' atom information (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md)
+%Image::ExifTool::QuickTime::prhd = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    FORMAT => 'fixed32s',
+    # 0 - version (high 8 bits) / flags (low 24 bits)
+    1 => 'PoseYawDegrees',
+    2 => 'PosePitchDegrees',
+    3 => 'PoseRollDegrees',
+);
+
+# 'cbmp' atom information (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md)
+%Image::ExifTool::QuickTime::cbmp = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    FORMAT => 'int32u',
+    # 0 - version (high 8 bits) / flags (low 24 bits)
+    1 => 'Layout',
+    2 => 'Padding',
+);
+
+# 'equi' atom information (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md)
+%Image::ExifTool::QuickTime::equi = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    FORMAT => 'int32u', # (actually 0.32 fixed point)
+    # 0 - version (high 8 bits) / flags (low 24 bits)
+    1 => { Name => 'ProjectionBoundsTop',   ValueConv => '$val / 4294967296' },
+    2 => { Name => 'ProjectionBoundsBottom',ValueConv => '$val / 4294967296' },
+    3 => { Name => 'ProjectionBoundsLeft',  ValueConv => '$val / 4294967296' },
+    4 => { Name => 'ProjectionBoundsRight', ValueConv => '$val / 4294967296' },
+);
+
+# 'btrt' atom information (ref http://lists.freedesktop.org/archives/gstreamer-commits/2011-October/054459.html)
+%Image::ExifTool::QuickTime::Bitrate = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    FORMAT => 'int32u',
+    PRIORITY => 0, # often filled with zeros
+    0 => 'BufferSize',
+    1 => 'MaxBitrate',
+    2 => 'AverageBitrate',
+);
+
+# 'clap' atom information (ref https://developer.apple.com/library/mac/technotes/tn2162/_index.html#//apple_ref/doc/uid/DTS40013070-CH1-TNTAG9)
+%Image::ExifTool::QuickTime::CleanAperture = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    FORMAT => 'rational64s',
+    0 => 'CleanApertureWidth',
+    1 => 'CleanApertureHeight',
+    2 => 'CleanApertureOffsetX',
+    3 => 'CleanApertureOffsetY',
 );
 
@@ -415,4 +1018,6 @@
 %Image::ExifTool::QuickTime::Preview = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     GROUPS => { 2 => 'Image' },
     FORMAT => 'int16u',
@@ -434,4 +1039,5 @@
 %Image::ExifTool::QuickTime::Movie = (
     PROCESS_PROC => \&ProcessMOV,
+    WRITE_PROC => \&WriteQuickTime,
     GROUPS => { 2 => 'Video' },
     mvhd => {
@@ -441,4 +1047,5 @@
     trak => {
         Name => 'Track',
+        CanCreate => 0, # don't create this atom
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Track' },
     },
@@ -464,13 +1071,88 @@
             },
         },
+        { #PH (Canon SX280)
+            Name => 'UUID-Canon',
+            Condition => '$$valPt=~/^\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Canon::uuid',
+                Start => 16,
+            },
+        },
         {
             Name => 'UUID-Unknown',
-            Unknown => 1,
-            Binary => 1,
+            %unknownInfo,
         },
     ],
+    cmov => {
+        Name => 'CompressedMovie',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::CMovie' },
+    },
+    htka => { # (written by HTC One M8 in slow-motion 1280x720 video - PH)
+        Name => 'HTCTrack',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Track' },
+    },
+   'gps ' => {  # GPS data written by Novatek cameras (parsed in QuickTimeStream.pl)
+        Name => 'GPSDataList',
+        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)
+    # ICAT - 4 bytes: "6350" (Nikon CoolPix S6900), "6500" (Panasonic FT7)
+);
+
+# (ref CFFMediaFormat-2_1.pdf)
+%Image::ExifTool::QuickTime::MovieFragment = (
+    PROCESS_PROC => \&ProcessMOV,
+    WRITE_PROC => \&WriteQuickTime,
+    GROUPS => { 2 => 'Video' },
+    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)
+%Image::ExifTool::QuickTime::TrackFragment = (
+    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
+    # trik - trick play box
+    # trun - track fragment run box
+    # avcn - AVC NAL unit storage box
+    # secn - sample encryption box
+    # saio - sample auxiliary information offsets box
+    # sbgp - sample to group box
+    # sgpd - sample group description box
+    # sdtp - independent and disposable samples (ref 5)
+    # subs - sub-sample information (ref 5)
 );
 
@@ -478,6 +1160,9 @@
 %Image::ExifTool::QuickTime::MovieHeader = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     GROUPS => { 2 => 'Video' },
     FORMAT => 'int32u',
+    DATAMEMBER => [ 0, 1, 2, 3, 4 ],
     0 => {
         Name => 'MovieHeaderVersion',
@@ -541,5 +1226,6 @@
 %Image::ExifTool::QuickTime::Track = (
     PROCESS_PROC => \&ProcessMOV,
-    GROUPS => { 2 => 'Video' },
+    WRITE_PROC => \&WriteQuickTime,
+    GROUPS => { 1 => 'Track#', 2 => 'Video' },
     tkhd => {
         Name => 'TrackHeader',
@@ -561,4 +1247,8 @@
         Name => 'TrackRef',
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackRef' },
+    },
+    tapt => {
+        Name => 'TrackAperture',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TrackAperture' },
     },
     uuid => [
@@ -571,13 +1261,25 @@
             },
         },
+        { #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/',
+            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',
+            },
+        },
         {
             Name => 'UUID-Unknown',
-            Unknown => 1,
-            Binary => 1,
+            %unknownInfo,
         },
     ],
+    meco => { #ISO14492-12:2015 pg 83
+        Name => 'OtherMeta',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::OtherMeta' },
+    },
     # edts - edits --> contains elst (edit list)
-    # tapt - TrackApertureModeDimensionsAID --> contains clef (TrackCleanApertureDimensionsAID),
-    #        prof (TrackProductionApertureDimensionsAID), enof (TrackEncodedPixelsDimensionsAID)
     # clip - clipping --> contains crgn (clip region)
     # matt - track matt --> contains kmat (compressed matt)
@@ -590,6 +1292,9 @@
 %Image::ExifTool::QuickTime::TrackHeader = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     GROUPS => { 1 => 'Track#', 2 => 'Video' },
     FORMAT => 'int32u',
+    DATAMEMBER => [ 0, 1, 2, 5, 7 ],
     0 => {
         Name => 'TrackHeaderVersion',
@@ -625,4 +1330,10 @@
         Hook => '$$self{TrackHeaderVersion} and $format = "int64u", $varSize += 4',
     },
+    7 => { # (used only for writing MatrixStructure)
+        Name => 'ImageSizeLookahead',
+        Hidden => 1,
+        Format => 'int32u[14]',
+        RawConv => '$$self{ImageSizeLookahead} = $val; undef',
+    },
     8 => {
         Name => 'TrackLayer',
@@ -640,4 +1351,10 @@
         Name => 'MatrixStructure',
         Format => 'fixed32s[9]',
+        Notes => 'writable for the video track via the Composite Rotation tag',
+        Writable => 1,
+        Protected => 1,
+        Permanent => 1,
+        # only set rotation if image size is non-zero
+        RawConvInv => \&GetMatrixStructure,
         # (the right column is fixed 2.30 instead of 16.16)
         ValueConv => q{
@@ -646,4 +1363,9 @@
             return "@a";
         },
+        ValueConvInv => q{
+            my @a = split ' ',$val;
+            $_ *= 0x4000 foreach @a[2,5,8];
+            return "@a";
+        },
     },
     19 => {
@@ -662,15 +1384,29 @@
 %Image::ExifTool::QuickTime::UserData = (
     PROCESS_PROC => \&ProcessMOV,
-    GROUPS => { 2 => 'Video' },
+    WRITE_PROC => \&WriteQuickTime,
+    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 => 'CreateDate',
+        Name => 'ContentCreateDate',
         Groups => { 2 => 'Time' },
+        Shift => 'Time',
         # handle values in the form "2010-02-12T13:27:14-0800" (written by Apple iPhone)
         ValueConv => q{
@@ -680,5 +1416,12 @@
             return $val;
         },
+        ValueConvInv => q{
+            require Image::ExifTool::XMP;
+            my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
+            ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
+            return $val;
+        },
         PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
     },
     "\xa9ART" => 'Artist', #PH (iTunes 8.0.2)
@@ -717,5 +1460,4 @@
     "\xa9prk" => 'PerformerKeywords', #12
     "\xa9prl" => 'PerformerURL',
-    "\xa9dir" => 'Director', #12
     "\xa9req" => 'Requirements',
     "\xa9snk" => 'SubtitleKeywords', #12
@@ -727,11 +1469,35 @@
     "\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)
+    "\xa9ysp" => 'SpeedY', #PH (guess)
+    "\xa9zsp" => 'SpeedZ', #PH (guess)
+    "\xa9fpt" => 'Pitch', #PH
+    "\xa9fyw" => 'Yaw', #PH
+    "\xa9frl" => 'Roll', #PH
+    "\xa9gpt" => 'CameraPitch', #PH
+    "\xa9gyw" => 'CameraYaw', #PH
+    "\xa9grl" => 'CameraRoll', #PH
+    "\xa9enc" => 'EncoderID', #PH (forum9271)
+    # and the following entries don't have the proper 4-byte header for \xa9 tags:
+    "\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',
+        Notes => 'non-standard-format DJI tag',
+        Format => 'string',
+        Avoid => 1,
+    },
+    # end DJI tags
     name => 'Name',
     WLOC => {
@@ -762,25 +1528,225 @@
         },
     },
-    DcMD => {
-        Name => 'DcMD',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::QuickTime::DcMD',
-        },
-    },
    'ptv '=> {
         Name => 'PrintToVideo',
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Video' },
     },
-   'hnti'=> {
+    hnti => {
         Name => 'HintInfo',
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HintInfo' },
     },
-   'hinf' => {
+    hinf => {
         Name => 'HintTrackInfo',
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HintTrackInfo' },
     },
+    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 %langText3gp tags are Avoid => 1)
+    cprt => { Name => 'Copyright',  %langText3gp, Groups => { 2 => 'Author' } },
+    auth => { Name => 'Author',     %langText3gp, Groups => { 2 => 'Author' } },
+    titl => { Name => 'Title',      %langText3gp },
+    dscp => { Name => 'Description',%langText3gp },
+    perf => { Name => 'Performer',  %langText3gp },
+    gnre => { Name => 'Genre',      %langText3gp },
+    albm => { Name => 'Album',      %langText3gp },
+    coll => { Name => 'CollectionName', %langText3gp }, #17
+    rtng => {
+        Name => 'Rating',
+        # (4-byte flags, 4-char entity, 4-char criteria, 2-byte lang, string)
+        RawConv => q{
+            return '<err>' unless length $val >= 14;
+            my $str = 'Entity=' . substr($val,4,4) . ' Criteria=' . substr($val,8,4);
+            $str =~ tr/\0-\x1f\x7f-\xff//d; # remove unprintable characters
+            my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 12));
+            $lang = $lang ? "($lang) " : '';
+            $val = substr($val, 14);
+            $val = $self->Decode($val, 'UCS2') if $val =~ /^\xfe\xff/;
+            return $lang . $str . ' ' . $val;
+        },
+    },
+    clsf => {
+        Name => 'Classification',
+        # (4-byte flags, 4-char entity, 2-byte index, 2-byte lang, string)
+        RawConv => q{
+            return '<err>' unless length $val >= 12;
+            my $str = 'Entity=' . substr($val,4,4) . ' Index=' . Get16u(\$val,8);
+            $str =~ tr/\0-\x1f\x7f-\xff//d; # remove unprintable characters
+            my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 10));
+            $lang = $lang ? "($lang) " : '';
+            $val = substr($val, 12);
+            $val = $self->Decode($val, 'UCS2') if $val =~ /^\xfe\xff/;
+            return $lang . $str . ' ' . $val;
+        },
+    },
+    kywd => {
+        Name => 'Keywords',
+        # (4 byte flags, 2-byte lang, 1-byte count, count x pascal strings, ref 17)
+        # (but I have also seen a simple string written by iPhone)
+        RawConv => q{
+            my $sep = $self->Options('ListSep');
+            return join($sep, split /\0+/, $val) unless $val =~ /^\0/; # (iPhone)
+            return '<err>' unless length $val >= 7;
+            my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 4));
+            $lang = $lang ? "($lang) " : '';
+            my $num = Get8u(\$val, 6);
+            my ($i, @vals);
+            my $pos = 7;
+            for ($i=0; $i<$num; ++$i) {
+                last if $pos >= length $val;
+                my $len = Get8u(\$val, $pos++);
+                last if $pos + $len > length $val;
+                my $v = substr($val, $pos, $len);
+                $v = $self->Decode($v, 'UCS2') if $v =~ /^\xfe\xff/;
+                push @vals, $v;
+                $pos += $len;
+            }
+            return $lang . join($sep, @vals);
+        },
+    },
+    loci => {
+        Name => 'LocationInformation',
+        Groups => { 2 => 'Location' },
+        # (4-byte flags, 2-byte lang, location string, 1-byte role, 4-byte fixed longitude,
+        #  4-byte fixed latitude, 4-byte fixed altitude, body string, notes string)
+        RawConv => q{
+            return '<err>' unless length $val >= 6;
+            my $lang = Image::ExifTool::QuickTime::UnpackLang(Get16u(\$val, 4));
+            $lang = $lang ? "($lang) " : '';
+            $val = substr($val, 6);
+            my $str;
+            if ($val =~ /^\xfe\xff/) {
+                $val =~ s/^(\xfe\xff(.{2})*?)\0\0//s or return '<err>';
+                $str = $self->Decode($1, 'UCS2');
+            } else {
+                $val =~ s/^(.*?)\0//s or return '<err>';
+                $str = $1;
+            }
+            $str = '(none)' unless length $str;
+            return '<err>' if length $val < 13;
+            my $role = Get8u(\$val, 0);
+            my $lon = GetFixed32s(\$val, 1);
+            my $lat = GetFixed32s(\$val, 5);
+            my $alt = GetFixed32s(\$val, 9);
+            my $roleStr = {0=>'shooting',1=>'real',2=>'fictional',3=>'reserved'}->{$role};
+            $str .= ' Role=' . ($roleStr || "unknown($role)");
+            $str .= sprintf(' Lat=%.5f Lon=%.5f Alt=%.2f', $lat, $lon, $alt);
+            $val = substr($val, 13);
+            if ($val =~ s/^(\xfe\xff(.{2})*?)\0\0//s) {
+                $str .= ' Body=' . $self->Decode($1, 'UCS2');
+            } elsif ($val =~ s/^(.*?)\0//s) {
+                $str .= " Body=$1";
+            }
+            if ($val =~ s/^(\xfe\xff(.{2})*?)\0\0//s) {
+                $str .= ' Notes=' . $self->Decode($1, 'UCS2');
+            } elsif ($val =~ s/^(.*?)\0//s) {
+                $str .= " Notes=$1";
+            }
+            return $lang . $str;
+        },
+    },
+    yrrc => {
+        Name => 'Year',
+        Groups => { 2 => 'Time' },
+        RawConv => 'length($val) >= 6 ? Get16u(\$val,4) : "<err>"',
+    },
+    urat => { #17
+        Name => 'UserRating',
+        RawConv => q{
+            return '<err>' unless length $val >= 8;
+            return Get8u(\$val, 7);
+        },
+    },
+    # tsel - TrackSelection (ref 17)
+    # 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)
+    cmid => { Name => 'CameraID',     Format => 'string' }, # (NC)
+    cmnm => { # (NC)
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Avoid => 1,
+        Format => 'string', # (necessary to remove the trailing NULL)
+    },
+    date => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        Notes => q{
+            Apple Photos has been reported to show a crazy date/time for some MP4 files
+            containing this tag, but perhaps only if it is missing a time zone
+        }, #forum10690/11125
+        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,1)', # (add time zone if it didn't exist)
+    },
+    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',
+    },
+    reel => { Name => 'ReelName',     Format => 'string' }, # (NC)
+    scen => { Name => 'Scene',        Format => 'string' }, # (NC)
+    shot => { Name => 'ShotName',     Format => 'string' }, # (NC)
+    slno => { Name => 'SerialNumber', Format => 'string' }, # (NC)
+    apmd => { Name => 'ApertureMode', Format => 'undef' }, #20
+    kgtt => { #http://lists.ffmpeg.org/pipermail/ffmpeg-devel-irc/2012-June/000707.html
+        # 'TrackType' will expand to 'Track#Type' when found inside a track
+        Name => 'TrackType',
+        # set flag to process this as international text
+        # even though the tag ID doesn't start with 0xa9
+        IText => 4, # IText with 4-byte header
+    },
+    chpl => { # (Nero chapter list)
+        Name => 'ChapterList',
+        ValueConv => \&ConvertChapterList,
+        PrintConv => \&PrintChapter,
+    },
+    # ndrm - 7 bytes (0 0 0 1 0 0 0) Nero Digital Rights Management? (PH)
+    # other non-Apple tags (ref 16)
+    # hpix - HipixRichPicture (ref 16, HIPIX)
+    # strk - sub-track information (ref 16, ISO)
+#
+# Manufacturer-specific metadata
+#
     TAGS => [ #PH
         # these tags were initially discovered in a Pentax movie,
         # but similar information is found in videos from other manufacturers
+        {
+            Name => 'FujiFilmTags',
+            Condition => '$$valPt =~ /^FUJIFILM DIGITAL CAMERA\0/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::FujiFilm::MOV',
+                ByteOrder => 'LittleEndian',
+            },
+        },
         {
             Name => 'KodakTags',
@@ -837,4 +1803,12 @@
                 TagTable => 'Image::ExifTool::Olympus::MP4',
                 ByteOrder => 'LittleEndian',
+            },
+        },
+        {
+            Name => 'OlympusTags4',
+            Condition => '$$valPt =~ /^.{16}OLYM\0/s',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Olympus::MOV3',
+                Start => 12,
             },
         },
@@ -883,16 +1857,31 @@
         },
     ],
-    NCDT => { #PH
-        Name => 'NikonNCDT',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Nikon::NCDT',
-            ProcessProc => \&ProcessMOV,
-        },
-    },
+    # ---- Canon ----
+    CNCV => { Name => 'CompressorVersion', Format => 'string' }, #PH (5D Mark II)
+    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)
+    CNTH => { #PH (PowerShot S95)
+        Name => 'CanonCNTH',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CNTH' },
+    },
+    CNOP => { #PH (7DmkII)
+        Name => 'CanonCNOP',
+        SubDirectory => { TagTable => 'Image::ExifTool::Canon::CNOP' },
+    },
+    # CNDB - 2112 bytes (550D)
+    # CNDM - 4 bytes - 0xff,0xd8,0xff,0xd9 (S95)
+    # CNDG - 10232 bytes, mostly zeros (N100)
+    # ---- Casio ----
     QVMI => { #PH
         Name => 'CasioQVMI',
-        # Casio stores standard EXIF-format information in MOV videos (ie. EX-S880)
+        # Casio stores standard EXIF-format information in MOV videos (eg. EX-S880)
         SubDirectory => {
             TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::Exif::ProcessExif, # (because ProcessMOV is default)
             DirName => 'IFD0',
             Multi => 0, # (no NextIFD pointer)
@@ -901,35 +1890,5 @@
         },
     },
-    MMA0 => { #PH (DiMage 7Hi)
-        Name => 'MinoltaMMA0',
-        SubDirectory => { TagTable => 'Image::ExifTool::Minolta::MMA' },
-    },
-    MMA1 => { #PH (Dimage A2)
-        Name => 'MinoltaMMA1',
-        SubDirectory => { TagTable => 'Image::ExifTool::Minolta::MMA' },
-    },
-    XMP_ => { #PH (Adobe CS3 Bridge)
-        Name => 'XMP',
-        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
-    },
-    vndr => 'Vendor', #PH (Samsung PL70)
-    SDLN => 'PlayMode', #PH (NC, Samsung ST80 "SEQ_PLAY")
-    # Canon tags
-    CNCV => 'CompressorVersion', #PH (5D Mark II)
-    CNMN => 'Model', #PH (EOS 550D)
-    CNFV => 'FirmwareVersion', #PH (EOS 550D)
-    CNTH => { #PH (PowerShot S95)
-        Name => 'CanonCNTH',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::Canon::CNTH',
-            ProcessProc => \&ProcessMOV,
-        },
-    },
-    # CNDB - 2112 bytes (550D)
-    # CNDM - 4 bytes - 0xff,0xd8,0xff,0xd9 (S95)
-    INFO => {
-        Name => 'SamsungINFO',
-        SubDirectory => { TagTable => 'Image::ExifTool::Samsung::INFO' },
-    },
+    # ---- FujiFilm ----
     FFMV => { #PH (FinePix HS20EXR)
         Name => 'FujiFilmFFMV',
@@ -940,4 +1899,5 @@
         SubDirectory => {
             TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::Exif::ProcessExif, # (because ProcessMOV is default)
             DirName => 'IFD0',
             Start => 16,
@@ -946,4 +1906,363 @@
         },
     },
+    # ---- Garmin ---- (ref PH)
+    uuid => [{
+        Name => 'GarminSoftware', # (NC)
+        Condition => '$$valPt =~ /^VIRBactioncamera/',
+        RawConv => 'substr($val, 16)',
+        RawConvInv => '"VIRBactioncamera$val"',
+    },{
+        # have seen "28 f3 11 e2 b7 91 4f 6f 94 e2 4f 5d ea cb 3c 01" for RicohThetaZ1 accelerometer RADT data (not yet decoded)
+        Name => 'UUID-Unknown',
+        Writable => 0,
+        %unknownInfo,
+    }],
+    pmcc => {
+        Name => 'GarminSettings',
+        ValueConv => 'substr($val, 4)',
+        ValueConvInv => '"\0\0\0\x01$val"',
+    },
+    # hmtp - "\0\0\0\x01" followed by 408 bytes of zero
+    # vrin - "\0\0\0\x01" followed by 8 bytes of zero
+    # ---- GoPro ---- (ref PH)
+    GoPr => 'GoProType', # (Hero3+)
+    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)
+    # HMMT? 404 bytes (Hero4, all zero)
+    # BCID? 26 bytes (Hero5, all zero), 36 bytes GoPro Max
+    # GUMI? 16 bytes (Hero5)
+   "FOV\0" => 'FieldOfView', #forum8938 (Hero2) seen: "Wide"
+    GPMF => {
+        Name => 'GoProGPMF',
+        SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
+    },
+    # free (all zero)
+    "\xa9TSC" => 'StartTimeScale', # (Hero6)
+    "\xa9TSZ" => 'StartTimeSampleSize', # (Hero6)
+    "\xa9TIM" => 'StartTimecode', #PH (NC)
+    # --- HTC ----
+    htcb => {
+        Name => 'HTCBinary',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::HTCBinary' },
+    },
+    # ---- Kodak ----
+    DcMD => {
+        Name => 'KodakDcMD',
+        SubDirectory => { TagTable => 'Image::ExifTool::Kodak::DcMD' },
+    },
+    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 },
+    lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess)
+    Lvlm => { Name => 'LevelMeter', Format => 'rational64s', Unknown => 1 }, # (guess)
+    pose => { Name => 'pose', SubDirectory => { TagTable => 'Image::ExifTool::Kodak::pose' } },
+    # AMBA => Ambarella AVC atom (unknown data written by Kodak Playsport video cam)
+    # tmlp - 1 byte: 0 (PixPro SP360/4KVR360)
+    # pivi - 72 bytes (PixPro SP360)
+    # pive - 12 bytes (PixPro SP360)
+    # loop - 4 bytes: 0 0 0 0 (PixPro 4KVR360)
+    # m cm - 2 bytes: 0 0 (PixPro 4KVR360)
+    # m ev - 2 bytes: 0 0 (PixPro SP360/4KVR360) (exposure comp?)
+    # m vr - 2 bytes: 0 1 (PixPro 4KVR360) (virtual reality?)
+    # m wb - 4 bytes: 0 0 0 0 (PixPro SP360/4KVR360) (white balance?)
+    # mclr - 4 bytes: 0 0 0 0 (PixPro SP360/4KVR360)
+    # mmtr - 4 bytes: 0,6 0 0 0 (PixPro SP360/4KVR360)
+    # mflr - 4 bytes: 0 0 0 0 (PixPro SP360)
+    # lvlm - 24 bytes (PixPro SP360)
+    # Lvlm - 24 bytes (PixPro 4KVR360)
+    # ufdm - 4 bytes: 0 0 0 1 (PixPro SP360)
+    # mtdt - 1 byte: 0 (PixPro SP360/4KVR360)
+    # gdta - 75240 bytes (PixPro SP360)
+    # EIS1 - 4 bytes: 03 07 00 00 (PixPro 4KVR360)
+    # EIS2 - 4 bytes: 04 97 00 00 (PixPro 4KVR360)
+    # ---- LG ----
+    adzc => { Name => 'Unknown_adzc', Unknown => 1, Hidden => 1, %langText }, # "false\0/","true\0/"
+    adze => { Name => 'Unknown_adze', Unknown => 1, Hidden => 1, %langText }, # "false\0/"
+    adzm => { Name => 'Unknown_adzm', Unknown => 1, Hidden => 1, %langText }, # "\x0e\x04/","\x10\x06"
+    # ---- Microsoft ----
+    Xtra => { #PH (microsoft)
+        Name => 'MicrosoftXtra',
+        SubDirectory => { TagTable => 'Image::ExifTool::Microsoft::Xtra' },
+    },
+    # ---- Minolta ----
+    MMA0 => { #PH (DiMage 7Hi)
+        Name => 'MinoltaMMA0',
+        SubDirectory => { TagTable => 'Image::ExifTool::Minolta::MMA' },
+    },
+    MMA1 => { #PH (Dimage A2)
+        Name => 'MinoltaMMA1',
+        SubDirectory => { TagTable => 'Image::ExifTool::Minolta::MMA' },
+    },
+    # ---- Nikon ----
+    NCDT => { #PH
+        Name => 'NikonNCDT',
+        SubDirectory => { TagTable => 'Image::ExifTool::Nikon::NCDT' },
+    },
+    # ---- Olympus ----
+    scrn => { #PH (TG-810)
+        Name => 'OlympusPreview',
+        Condition => '$$valPt =~ /^.{4}\xff\xd8\xff\xdb/s',
+        SubDirectory => { TagTable => 'Image::ExifTool::Olympus::scrn' },
+    },
+    # ---- Panasonic/Leica ----
+    PANA => { #PH
+        Name => 'PanasonicPANA',
+        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::PANA' },
+    },
+    LEIC => { #PH
+        Name => 'LeicaLEIC',
+        SubDirectory => { TagTable => 'Image::ExifTool::Panasonic::PANA' },
+    },
+    # ---- Pentax ----
+    thmb => [ # (apparently defined by 3gpp, ref 16)
+        { #PH (Pentax Q)
+            Name => 'MakerNotePentax5a',
+            Condition => '$$valPt =~ /^PENTAX \0II/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Pentax::Main',
+                ProcessProc => \&Image::ExifTool::Exif::ProcessExif, # (because ProcessMOV is default)
+                Start => 10,
+                Base => '$start - 10',
+                ByteOrder => 'LittleEndian',
+            },
+        },{ #PH (TG-810)
+            Name => 'OlympusThumbnail',
+            Condition => '$$valPt =~ /^.{4}\xff\xd8\xff\xdb/s',
+            SubDirectory => { TagTable => 'Image::ExifTool::Olympus::thmb' },
+        },{ #17 (format is in bytes 3-7)
+            Name => 'ThumbnailImage',
+            Condition => '$$valPt =~ /^.{8}\xff\xd8\xff[\xdb\xe0]/s',
+            Groups => { 2 => 'Preview' },
+            RawConv => 'substr($val, 8)',
+            Binary => 1,
+        },{ #17 (format is in bytes 3-7)
+            Name => 'ThumbnailPNG',
+            Condition => '$$valPt =~ /^.{8}\x89PNG\r\n\x1a\n/s',
+            Groups => { 2 => 'Preview' },
+            RawConv => 'substr($val, 8)',
+            Binary => 1,
+        },{
+            Name => 'UnknownThumbnail',
+            Groups => { 2 => 'Preview' },
+            Binary => 1,
+        },
+    ],
+    PENT => { #PH
+        Name => 'PentaxPENT',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::PENT',
+            ByteOrder => 'LittleEndian',
+        },
+    },
+    PXTH => { #PH (Pentax K-01)
+        Name => 'PentaxPreview',
+        SubDirectory => { TagTable => 'Image::ExifTool::Pentax::PXTH' },
+    },
+    PXMN => [{ #PH (Pentax K-01)
+        Name => 'MakerNotePentax5b',
+        Condition => '$$valPt =~ /^PENTAX \0MM/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::Main',
+            ProcessProc => \&Image::ExifTool::Exif::ProcessExif, # (because ProcessMOV is default)
+            Start => 10,
+            Base => '$start - 10',
+            ByteOrder => 'BigEndian',
+        },
+    },{ #PH (Pentax 645Z)
+        Name => 'MakerNotePentax5c',
+        Condition => '$$valPt =~ /^PENTAX \0II/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::Main',
+            ProcessProc => \&Image::ExifTool::Exif::ProcessExif, # (because ProcessMOV is default)
+            Start => 10,
+            Base => '$start - 10',
+            ByteOrder => 'LittleEndian',
+        },
+    },{
+        Name => 'MakerNotePentaxUnknown',
+        Binary => 1,
+    }],
+    # ---- Ricoh ----
+    RTHU => { #PH (GR)
+        Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
+        RawConv => '$self->ValidateImage(\$val, $tag)',
+    },
+    RMKN => { #PH (GR)
+        Name => 'RicohRMKN',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF, # (because ProcessMOV is default)
+        },
+    },
+    '@mak' => { Name => 'Make',     Avoid => 1 },
+    '@mod' => { Name => 'Model',    Avoid => 1 },
+    '@swr' => { Name => 'SoftwareVersion', Avoid => 1 },
+    '@day' => {
+        Name => 'ContentCreateDate',
+        Notes => q{
+            some stupid Ricoh programmer used the '@' symbol instead of the copyright
+            symbol in these tag ID's for the Ricoh Theta Z1 and maybe other models
+        },
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        Avoid => 1,
+        # handle values in the form "2010-02-12T13:27:14-0800"
+        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;
+            my $tmp = Image::ExifTool::XMP::FormatXMPDate($val);
+            ($val = $tmp) =~ s/([-+]\d{2}):(\d{2})$/$1$2/ if defined $tmp; # remove time zone colon
+            return $val;
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,1)', # (add time zone if it didn't exist)
+    },
+    '@xyz' => { #PH (iPhone 3GS)
+        Name => 'GPSCoordinates',
+        Groups => { 2 => 'Location' },
+        Avoid => 1,
+        ValueConv => \&ConvertISO6709,
+        ValueConvInv => \&ConvInvISO6709,
+        PrintConv => \&PrintGPSCoordinates,
+        PrintConvInv => \&PrintInvGPSCoordinates,
+    },
+    # RDT1 - pairs of int32u_BE, starting at byte 8: "458275 471846"
+    # RDT2 - pairs of int32u_BE, starting at byte 8: "472276 468526"
+    # RDT3 - pairs of int32u_BE, starting at byte 8: "876603 482191"
+    # RDT4 - pairs of int32u_BE, starting at byte 8: "1955 484612"
+    # RDT6 - empty
+    # RDT7 - empty
+    # RDT8 - empty
+    # RDT9 - only 16-byte header?
+    # the boxes below all have a similar header (little-endian):
+    #  0 int32u - number of records
+    #  4 ? - "1e 00"
+    #  6 int16u - record length in bytes
+    #  8 ? - "23 01 00 00 00 00 00 00"
+    #  16 - start of records (each record ends in an int64u timestamp in ns)
+    # RDTA - float[4],ts: "-0.31289672 -0.2245330 11.303817 0 775.780"
+    # RDTB - float[4],ts: "-0.04841613 -0.2166595 0.0724792 0 775.780"
+    # RDTC - float[4],ts: "27.60925 -27.10037 -13.27285 0 775.829"
+    # RDTD - int16s[3],ts: "353 -914 16354 0 775.829"
+    # RDTG - ts: "775.825"
+    # RDTI - float[4],ts: "0.00165951 0.005770059 0.06838259 0.1744695 775.862"
+    # ---- Samsung ----
+    vndr => 'Vendor', #PH (Samsung PL70)
+    SDLN => 'PlayMode', #PH (NC, Samsung ST80 "SEQ_PLAY")
+    INFO => {
+        Name => 'SamsungINFO',
+        SubDirectory => { TagTable => 'Image::ExifTool::Samsung::INFO' },
+    },
+   '@sec' => { #PH (Samsung WB30F)
+        Name => 'SamsungSec',
+        SubDirectory => { TagTable => 'Image::ExifTool::Samsung::sec' },
+    },
+    'smta' => { #PH (Samsung SM-C101)
+        Name => 'SamsungSmta',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Samsung::smta',
+            Start => 4,
+        },
+    },
+    cver => 'CodeVersion', #PH (guess, Samsung MV900F)
+    # ducp - 4 bytes all zero (Samsung ST96,WB750), 52 bytes all zero (Samsung WB30F)
+    # edli - 52 bytes all zero (Samsung WB30F)
+    # @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)
+#
+    ccid => 'ContentID',
+    icnu => 'IconURI',
+    infu => 'InfoURL',
+    cdis => 'ContentDistributorID',
+    albr => { Name => 'AlbumArtist', Groups => { 2 => 'Author' } },
+    cvru => 'CoverURI',
+    lrcu => 'LyricsURI',
+
+    tags => {   # found in Audible .m4b audio books (ref PH)
+        Name => 'Audible_tags',
+        SubDirectory => { TagTable => 'Image::ExifTool::Audible::tags' },
+    },
+);
+
+# Unknown information stored in HTC One (M8) videos - PH
+%Image::ExifTool::QuickTime::HTCBinary = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 1 => 'HTC', 2 => 'Video' },
+    TAG_PREFIX => 'HTCBinary',
+    FORMAT => 'int32u',
+    FIRST_ENTRY => 0,
+    # 0 - values: 1
+    # 1 - values: 0
+    # 2 - values: 0
+    # 3 - values: FileSize minus 12 (why?)
+    # 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"' },
 );
 
@@ -960,5 +2279,5 @@
 # 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',
@@ -967,7 +2286,13 @@
         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',
@@ -985,14 +2310,38 @@
         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)',
+    },
+);
+
+# compressed movie atoms (ref http://wiki.multimedia.cx/index.php?title=QuickTime_container#cmov)
+%Image::ExifTool::QuickTime::CMovie = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    dcom => 'Compression',
+    # cmvd - compressed moov atom data
 );
 
@@ -1012,4 +2361,11 @@
         Name => 'VideoProfile',
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::VideoProf' },
+    },
+    OLYM => { #PH
+        Name => 'OlympusOLYM',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Olympus::OLYM',
+            ByteOrder => 'BigEndian',
+        },
     },
 );
@@ -1130,5 +2486,6 @@
 %Image::ExifTool::QuickTime::Meta = (
     PROCESS_PROC => \&ProcessMOV,
-    GROUPS => { 2 => 'Video' },
+    WRITE_PROC => \&WriteQuickTime,
+    GROUPS => { 1 => 'Meta', 2 => 'Video' },
     ilst => {
         Name => 'ItemList',
@@ -1144,6 +2501,6 @@
     },
     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 => {
@@ -1153,5 +2510,7 @@
     iloc => {
         Name => 'ItemLocation',
-        Flags => ['Binary','Unknown'],
+        RawConv => \&ParseItemLocation,
+        WriteHook => \&ParseItemLocation,
+        Notes => 'parsed, but not extracted as a tag',
     },
     ipro => {
@@ -1159,11 +2518,25 @@
         Flags => ['Binary','Unknown'],
     },
-    iinf => {
+    iinf => [{
         Name => 'ItemInformation',
-        Flags => ['Binary','Unknown'],
-    },
+        Condition => '$$valPt =~ /^\0/', # (check for version 0)
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::ItemInfo',
+            Start => 6, # (4-byte version/flags + 2-byte count)
+        },
+    },{
+        Name => 'ItemInformation',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::ItemInfo',
+            Start => 8, # (4-byte version/flags + 4-byte count)
+        },
+    }],
    'xml ' => {
         Name => 'XML',
-        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
+        Flags => [ 'Binary', 'Protected' ],
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::XMP::XML',
+            IgnoreProp => { NonRealTimeMeta => 1 }, # ignore container for Sony 'nrtm'
+        },
     },
    'keys' => {
@@ -1175,12 +2548,389 @@
         Flags => ['Binary','Unknown'],
     },
-    pitm => {
+    pitm => [{
         Name => 'PrimaryItemReference',
-        Flags => ['Binary','Unknown'],
-    },
+        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',
         Flags => ['Binary','Unknown'],
     },
+    iprp => {
+        Name => 'ItemProperties',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ItemProp' },
+    },
+    iref => {
+        Name => 'ItemReference',
+        # the version is needed to parse some of the item references
+        Condition => '$$self{ItemRefVersion} = ord($$valPt); 1',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::ItemRef',
+            Start => 4,
+        },
+    },
+    idat => {
+        Name => 'MetaImageSize', #PH (NC)
+        Format => 'int16u',
+        # (don't know what the first two numbers are for)
+        PrintConv => '$val =~ s/^(\d+) (\d+) (\d+) (\d+)/${3}x$4/; $val',
+    },
+    uuid => [
+        { #PH (Canon R5/R6 HIF)
+            Name => 'MetaVersion', # (NC)
+            Condition => '$$valPt=~/^\x85\xc0\xb6\x87\x82\x0f\x11\xe0\x81\x11\xf4\xce\x46\x2b\x6a\x48/',
+            RawConv => 'substr($val, 0x14)',
+        },
+        {
+            Name => 'UUID-Unknown',
+            %unknownInfo,
+        },
+    ],
+);
+
+# 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',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ItemPropCont' },
+    },
+    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 => [{
+        Name => 'ICC_Profile',
+        Condition => '$$valPt =~ /^(prof|rICC)/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::ICC_Profile::Main',
+            Start => 4,
+        },
+    },{
+        Name => 'ColorRepresentation',
+        ValueConv => 'join(" ", substr($val,0,4), unpack("x4n*",$val))',
+    }],
+    irot => {
+        Name => 'Rotation',
+        Format => 'int8u',
+        Writable => 'int8u',
+        Protected => 1,
+        ValueConv => '$val * 90',
+        ValueConvInv => 'int($val / 90 + 0.5)',
+    },
+    ispe => {
+        Name => 'ImageSpatialExtent',
+        Condition => '$$valPt =~ /^\0{4}/',     # (version/flags == 0/0)
+        RawConv => q{
+            my @dim = unpack("x4N*", $val);
+            return undef if @dim < 2;
+            unless ($$self{DOC_NUM}) {
+                $self->FoundTag(ImageWidth => $dim[0]);
+                $self->FoundTag(ImageHeight => $dim[1]);
+            }
+            return join ' ', @dim;
+        },
+        PrintConv => '$val =~ tr/ /x/; $val',
+    },
+    pixi => {
+        Name => 'ImagePixelDepth',
+        Condition => '$$valPt =~ /^\0{4}./s',   # (version/flags == 0/0 and count)
+        RawConv => 'join " ", unpack("x5C*", $val)',
+    },
+    auxC => {
+        Name => 'AuxiliaryImageType',
+        Format => 'undef',
+        RawConv => '$val = substr($val, 4); $val =~ s/\0.*//s; $val',
+    },
+    pasp => {
+        Name => 'PixelAspectRatio',
+        Format => 'int32u',
+        Writable => 'int32u',
+        Protected => 1,
+    },
+    rloc => {
+        Name => 'RelativeLocation',
+        Format => 'int32u',
+        RawConv => '$val =~ s/^\S+\s+//; $val', # remove version/flags
+    },
+    clap => {
+        Name => 'CleanAperture',
+        Format => 'rational64s',
+        Notes => '4 numbers: width, height, left and top',
+    },
+    hvcC => {
+        Name => 'HEVCConfiguration',
+        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)
+    NOTES => q{
+        The Item reference entries listed in the table below contain information about
+        the associations between items in the file.  This information is used by
+        ExifTool, but these entries are not extracted as tags.
+    },
+    dimg => { Name => 'DerivedImageRef',   RawConv => 'undef' },
+    thmb => { Name => 'ThumbnailRef',      RawConv => 'undef' },
+    auxl => { Name => 'AuxiliaryImageRef', RawConv => 'undef' },
+    cdsc => {
+        Name => 'ContentDescribes',
+        RawConv => \&ParseContentDescribes,
+        WriteHook => \&ParseContentDescribes,
+    },
+);
+
+%Image::ExifTool::QuickTime::ItemInfo = (
+    PROCESS_PROC => \&ProcessMOV,
+    WRITE_PROC => \&WriteQuickTime,
+    GROUPS => { 2 => 'Image' },
+    # avc1 - AVC image
+    # hvc1 - HEVC image
+    # lhv1 - L-HEVC image
+    # infe - ItemInformationEntry
+    # infe types: avc1,hvc1,lhv1,Exif,xml1,iovl(overlay image),grid,mime,hvt1(tile image)
+    infe => {
+        Name => 'ItemInfoEntry',
+        RawConv => \&ParseItemInfoEntry,
+        WriteHook => \&ParseItemInfoEntry,
+        Notes => 'parsed, but not extracted as a tag',
+    },
 );
 
@@ -1188,7 +2938,47 @@
 %Image::ExifTool::QuickTime::TrackRef = (
     PROCESS_PROC => \&ProcessMOV,
-    GROUPS => { 2 => 'Video' },
-    chap => { Name => 'ChapterList', Format => 'int32u' },
-    # also: tmcd, sync, scpt, ssrc, iTunesInfo
+    GROUPS => { 1 => 'Track#', 2 => 'Video' },
+    chap => { Name => 'ChapterListTrackID', Format => 'int32u' },
+    tmcd => { Name => 'TimeCode', Format => 'int32u' },
+    mpod => { #PH (FLIR MP4)
+        Name => 'ElementaryStreamTrack',
+        Format => 'int32u',
+        ValueConv => '$val =~ s/^1 //; $val',  # (why 2 numbers? -- ignore the first if "1")
+    },
+    # also: sync, scpt, ssrc, iTunesInfo
+    cdsc => {
+        Name => 'ContentDescribes',
+        Format => 'int32u',
+        PrintConv => '"Track $val"',
+    },
+    # cdep (Structural Dependency QT tag?)
+);
+
+# track aperture mode dimensions atoms
+# (ref https://developer.apple.com/library/mac/#documentation/QuickTime/QTFF/QTFFChap2/qtff2.html)
+%Image::ExifTool::QuickTime::TrackAperture = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 1 => 'Track#', 2 => 'Video' },
+    clef => {
+        Name => 'CleanApertureDimensions',
+        Format => 'fixed32u',
+        Count => 3,
+        ValueConv => '$val =~ s/^.*? //; $val', # remove flags word
+        PrintConv => '$val =~ tr/ /x/; $val',
+    },
+    prof => {
+        Name => 'ProductionApertureDimensions',
+        Format => 'fixed32u',
+        Count => 3,
+        ValueConv => '$val =~ s/^.*? //; $val',
+        PrintConv => '$val =~ tr/ /x/; $val',
+    },
+    enof => {
+        Name => 'EncodedPixelsDimensions',
+        Format => 'fixed32u',
+        Count => 3,
+        ValueConv => '$val =~ s/^.*? //; $val',
+        PrintConv => '$val =~ tr/ /x/; $val',
+    },
 );
 
@@ -1197,16 +2987,51 @@
 %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 adds an 'mdir' (Metadata) Handler
+        box because Apple software may ignore ItemList tags otherwise, but the API
+        L<QuickTimeHandler|../ExifTool.html#QuickTimeHandler> option may be set to 0 to avoid this.
     },
     # 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',
-    "\xa9day" => { Name => 'Year', Groups => { 2 => 'Time' } },
+    "\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;
+            $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,1)', # (add time zone if it didn't exist)
+    },
     "\xa9des" => 'Description', #4
     "\xa9enc" => 'EncodedBy', #10
@@ -1215,24 +3040,54 @@
     "\xa9lyr" => 'Lyrics',
     "\xa9nam" => 'Title',
-    # "\xa9st3" ? #10
     "\xa9too" => 'Encoder',
     "\xa9trk" => 'Track',
     "\xa9wrt" => 'Composer',
+#
+# the following tags written by AtomicParsley 0.9.6
+# (ref https://exiftool.org/forum/index.php?topic=11455.0)
+#
+    "\xa9st3" => 'Subtitle',
+    "\xa9con" => 'Conductor',
+    "\xa9sol" => 'Soloist',
+    "\xa9arg" => 'Arranger',
+    "\xa9ope" => 'OriginalArtist',
+    "\xa9dir" => 'Director',
+    "\xa9ard" => 'ArtDirector',
+    "\xa9sne" => 'SoundEngineer',
+    "\xa9prd" => 'Producer',
+    "\xa9xpd" => 'ExecutiveProducer',
+    sdes      => 'StoreDescription',
+#
     '----' => {
         Name => 'iTunesInfo',
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::iTunesInfo' },
     },
-    aART => 'AlbumArtist',
-    covr => 'CoverArt',
+    aART => { Name => 'AlbumArtist', Groups => { 2 => 'Author' } },
+    covr => { Name => 'CoverArt',    Groups => { 2 => 'Preview' } },
     cpil => { #10
         Name => 'Compilation',
+        Format => 'int8u', #27 (ref 23 contradicts what AtomicParsley actually writes, which is int8s)
+        Writable => 'int8s',
         PrintConv => { 0 => 'No', 1 => 'Yes' },
     },
     disk => {
         Name => 'DiskNumber',
-        ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
+        Format => 'undef',  # (necessary to prevent decoding as string!)
+        ValueConv => q{
+            return \$val unless length($val) >= 6;
+            my @a = unpack 'x2nn', $val;
+            return $a[1] ? join(' of ', @a) : $a[0];
+        },
+        ValueConvInv => q{
+            my @a = $val =~ /\d+/g;
+            return undef if @a == 0 or @a > 2;
+            push @a, 0 if @a == 1;
+            return pack('n3', 0, @a);
+        },
     },
     pgap => { #10
         Name => 'PlayGap',
+        Format => 'int8u', #23
+        Writable => 'int8s', #27
         PrintConv => {
             0 => 'Insert Gap',
@@ -1242,9 +3097,24 @@
     tmpo => {
         Name => 'BeatsPerMinute',
-        Format => 'int16u', # marked as boolean but really int16u in my sample
+        # marked as boolean but really int16u in my sample
+        # (but written as int16s by iTunes and AtomicParsley, ref forum11506)
+        Format => 'int16u',
+        Writable => 'int16s',
     },
     trkn => {
         Name => 'TrackNumber',
-        ValueConv => 'length($val) >= 6 ? join(" of ",unpack("x2nn",$val)) : \$val',
+        Format => 'undef',  # (necessary to prevent decoding as string!)
+        ValueConv => q{
+            return \$val unless length($val) >= 6;
+            my @a = unpack 'x2nn', $val;
+            return $a[1] ? join(' of ', @a) : $a[0];
+        },
+        # (see forum11501 for discussion about the format used)
+        ValueConvInv => q{
+            my @a = $val =~ /\d+/g;
+            return undef if @a == 0 or @a > 2;
+            push @a, 0 if @a == 1;
+            return pack('n4', 0, @a, 0);
+        },
     },
 #
@@ -1254,4 +3124,6 @@
     akID => { #10
         Name => 'AppleStoreAccountType',
+        Format => 'int8u', #24
+        Writable => 'int8s', #27
         PrintConv => {
             0 => 'iTunes',
@@ -1259,9 +3131,10 @@
         },
     },
-    albm => 'Album', #(ffmpeg source)
+    albm => { Name => 'Album', Avoid => 1 }, #(ffmpeg source)
     apID => 'AppleStoreAccount',
     atID => { #10 (or TV series)
         Name => 'AlbumTitleID',
         Format => 'int32u',
+        Writable => 'int32s', #27
     },
     auth => { Name => 'Author', Groups => { 2 => 'Author' } },
@@ -1270,10 +3143,16 @@
         Name => 'AppleStoreCatalogID',
         Format => 'int32u',
+        Writable => 'int32s', #27
     },
     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: see https://exiftool.org/forum/index.php?topic=11537.0)
+        Format => 'undef',
+        ValueConv => 'unpack("n",$val)',
+        ValueConvInv => '$val =~ /^\d+$/ ? pack("n",$val) : undef',
         PrintConv => q{
             return $val unless $val =~ /^\d+$/;
@@ -1281,4 +3160,11 @@
             Image::ExifTool::ID3::PrintGenre($val - 1); # note the "- 1"
         },
+        PrintConvInv => q{
+            return $val if $val =~ /^[0-9]+$/;
+            require Image::ExifTool::ID3;
+            my $id = Image::ExifTool::ID3::GetGenreID($val);
+            return unless defined $id and $id =~ /^\d+$/;
+            return $id + 1;
+        }, 
     },
     egid => 'EpisodeGlobalUniqueID', #7
@@ -1286,10 +3172,2658 @@
         Name => 'GenreID',
         Format => 'int32u',
-        # 4005 = Kids
-        # 4010 = Teens
-    },
-    grup => 'Grouping', #10
+        Writable => 'int32s', #27
+        SeparateTable => 1,
+        # 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",
+            5 => 'Music|Classical',
+            6 => 'Music|Country',
+            7 => 'Music|Electronic',
+            8 => 'Music|Holiday',
+            9 => 'Music|Classical|Opera',
+            10 => 'Music|Singer/Songwriter',
+            11 => 'Music|Jazz',
+            12 => 'Music|Latino',
+            13 => 'Music|New Age',
+            14 => 'Music|Pop',
+            15 => 'Music|R&B/Soul',
+            16 => 'Music|Soundtrack',
+            17 => 'Music|Dance',
+            18 => 'Music|Hip-Hop/Rap',
+            19 => 'Music|World',
+            20 => 'Music|Alternative',
+            21 => 'Music|Rock',
+            22 => 'Music|Christian & Gospel',
+            23 => 'Music|Vocal',
+            24 => 'Music|Reggae',
+            25 => 'Music|Easy Listening',
+            26 => 'Podcasts',
+            27 => 'Music|J-Pop',
+            28 => 'Music|Enka',
+            29 => 'Music|Anime',
+            30 => 'Music|Kayokyoku',
+            31 => 'Music Videos',
+            32 => 'TV Shows',
+            33 => 'Movies',
+            34 => 'Music',
+            35 => 'iPod Games',
+            36 => 'App Store',
+            37 => 'Tones',
+            38 => 'Books',
+            39 => 'Mac App Store',
+            40 => 'Textbooks',
+            50 => 'Music|Fitness & Workout',
+            51 => 'Music|Pop|K-Pop',
+            52 => 'Music|Karaoke',
+            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',
+            1004 => 'Music|Alternative|Indie Rock',
+            1005 => 'Music|Alternative|New Wave',
+            1006 => 'Music|Alternative|Punk',
+            1007 => 'Music|Blues|Chicago Blues',
+            1009 => 'Music|Blues|Classic Blues',
+            1010 => 'Music|Blues|Contemporary Blues',
+            1011 => 'Music|Blues|Country Blues',
+            1012 => 'Music|Blues|Delta Blues',
+            1013 => 'Music|Blues|Electric Blues',
+            1014 => "Music|Children's Music|Lullabies",
+            1015 => "Music|Children's Music|Sing-Along",
+            1016 => "Music|Children's Music|Stories",
+            1017 => 'Music|Classical|Avant-Garde',
+            1018 => 'Music|Classical|Baroque Era',
+            1019 => 'Music|Classical|Chamber Music',
+            1020 => 'Music|Classical|Chant',
+            1021 => 'Music|Classical|Choral',
+            1022 => 'Music|Classical|Classical Crossover',
+            1023 => 'Music|Classical|Early Music',
+            1024 => 'Music|Classical|Impressionist',
+            1025 => 'Music|Classical|Medieval Era',
+            1026 => 'Music|Classical|Minimalism',
+            1027 => 'Music|Classical|Modern Era',
+            1028 => 'Music|Classical|Opera',
+            1029 => 'Music|Classical|Orchestral',
+            1030 => 'Music|Classical|Renaissance',
+            1031 => 'Music|Classical|Romantic Era',
+            1032 => 'Music|Classical|Wedding Music',
+            1033 => 'Music|Country|Alternative Country',
+            1034 => 'Music|Country|Americana',
+            1035 => 'Music|Country|Bluegrass',
+            1036 => 'Music|Country|Contemporary Bluegrass',
+            1037 => 'Music|Country|Contemporary Country',
+            1038 => 'Music|Country|Country Gospel',
+            1039 => 'Music|Country|Honky Tonk',
+            1040 => 'Music|Country|Outlaw Country',
+            1041 => 'Music|Country|Traditional Bluegrass',
+            1042 => 'Music|Country|Traditional Country',
+            1043 => 'Music|Country|Urban Cowboy',
+            1044 => 'Music|Dance|Breakbeat',
+            1045 => 'Music|Dance|Exercise',
+            1046 => 'Music|Dance|Garage',
+            1047 => 'Music|Dance|Hardcore',
+            1048 => 'Music|Dance|House',
+            1049 => "Music|Dance|Jungle/Drum'n'bass",
+            1050 => 'Music|Dance|Techno',
+            1051 => 'Music|Dance|Trance',
+            1052 => 'Music|Jazz|Big Band',
+            1053 => 'Music|Jazz|Bop',
+            1054 => 'Music|Easy Listening|Lounge',
+            1055 => 'Music|Easy Listening|Swing',
+            1056 => 'Music|Electronic|Ambient',
+            1057 => 'Music|Electronic|Downtempo',
+            1058 => 'Music|Electronic|Electronica',
+            1060 => 'Music|Electronic|IDM/Experimental',
+            1061 => 'Music|Electronic|Industrial',
+            1062 => 'Music|Singer/Songwriter|Alternative Folk',
+            1063 => 'Music|Singer/Songwriter|Contemporary Folk',
+            1064 => 'Music|Singer/Songwriter|Contemporary Singer/Songwriter',
+            1065 => 'Music|Singer/Songwriter|Folk-Rock',
+            1066 => 'Music|Singer/Songwriter|New Acoustic',
+            1067 => 'Music|Singer/Songwriter|Traditional Folk',
+            1068 => 'Music|Hip-Hop/Rap|Alternative Rap',
+            1069 => 'Music|Hip-Hop/Rap|Dirty South',
+            1070 => 'Music|Hip-Hop/Rap|East Coast Rap',
+            1071 => 'Music|Hip-Hop/Rap|Gangsta Rap',
+            1072 => 'Music|Hip-Hop/Rap|Hardcore Rap',
+            1073 => 'Music|Hip-Hop/Rap|Hip-Hop',
+            1074 => 'Music|Hip-Hop/Rap|Latin Rap',
+            1075 => 'Music|Hip-Hop/Rap|Old School Rap',
+            1076 => 'Music|Hip-Hop/Rap|Rap',
+            1077 => 'Music|Hip-Hop/Rap|Underground Rap',
+            1078 => 'Music|Hip-Hop/Rap|West Coast Rap',
+            1079 => 'Music|Holiday|Chanukah',
+            1080 => 'Music|Holiday|Christmas',
+            1081 => "Music|Holiday|Christmas: Children's",
+            1082 => 'Music|Holiday|Christmas: Classic',
+            1083 => 'Music|Holiday|Christmas: Classical',
+            1084 => 'Music|Holiday|Christmas: Jazz',
+            1085 => 'Music|Holiday|Christmas: Modern',
+            1086 => 'Music|Holiday|Christmas: Pop',
+            1087 => 'Music|Holiday|Christmas: R&B',
+            1088 => 'Music|Holiday|Christmas: Religious',
+            1089 => 'Music|Holiday|Christmas: Rock',
+            1090 => 'Music|Holiday|Easter',
+            1091 => 'Music|Holiday|Halloween',
+            1092 => 'Music|Holiday|Holiday: Other',
+            1093 => 'Music|Holiday|Thanksgiving',
+            1094 => 'Music|Christian & Gospel|CCM',
+            1095 => 'Music|Christian & Gospel|Christian Metal',
+            1096 => 'Music|Christian & Gospel|Christian Pop',
+            1097 => 'Music|Christian & Gospel|Christian Rap',
+            1098 => 'Music|Christian & Gospel|Christian Rock',
+            1099 => 'Music|Christian & Gospel|Classic Christian',
+            1100 => 'Music|Christian & Gospel|Contemporary Gospel',
+            1101 => 'Music|Christian & Gospel|Gospel',
+            1103 => 'Music|Christian & Gospel|Praise & Worship',
+            1104 => 'Music|Christian & Gospel|Southern Gospel',
+            1105 => 'Music|Christian & Gospel|Traditional Gospel',
+            1106 => 'Music|Jazz|Avant-Garde Jazz',
+            1107 => 'Music|Jazz|Contemporary Jazz',
+            1108 => 'Music|Jazz|Crossover Jazz',
+            1109 => 'Music|Jazz|Dixieland',
+            1110 => 'Music|Jazz|Fusion',
+            1111 => 'Music|Jazz|Latin Jazz',
+            1112 => 'Music|Jazz|Mainstream Jazz',
+            1113 => 'Music|Jazz|Ragtime',
+            1114 => 'Music|Jazz|Smooth Jazz',
+            1115 => 'Music|Latino|Latin Jazz',
+            1116 => 'Music|Latino|Contemporary Latin',
+            1117 => 'Music|Latino|Pop Latino',
+            1118 => 'Music|Latino|Raices', # (Ra&iacute;ces)
+            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|Musica tropical', # (M&uacute;sica tropical)
+            1125 => 'Music|New Age|Environmental',
+            1126 => 'Music|New Age|Healing',
+            1127 => 'Music|New Age|Meditation',
+            1128 => 'Music|New Age|Nature',
+            1129 => 'Music|New Age|Relaxation',
+            1130 => 'Music|New Age|Travel',
+            1131 => 'Music|Pop|Adult Contemporary',
+            1132 => 'Music|Pop|Britpop',
+            1133 => 'Music|Pop|Pop/Rock',
+            1134 => 'Music|Pop|Soft Rock',
+            1135 => 'Music|Pop|Teen Pop',
+            1136 => 'Music|R&B/Soul|Contemporary R&B',
+            1137 => 'Music|R&B/Soul|Disco',
+            1138 => 'Music|R&B/Soul|Doo Wop',
+            1139 => 'Music|R&B/Soul|Funk',
+            1140 => 'Music|R&B/Soul|Motown',
+            1141 => 'Music|R&B/Soul|Neo-Soul',
+            1142 => 'Music|R&B/Soul|Quiet Storm',
+            1143 => 'Music|R&B/Soul|Soul',
+            1144 => 'Music|Rock|Adult Alternative',
+            1145 => 'Music|Rock|American Trad Rock',
+            1146 => 'Music|Rock|Arena Rock',
+            1147 => 'Music|Rock|Blues-Rock',
+            1148 => 'Music|Rock|British Invasion',
+            1149 => 'Music|Rock|Death Metal/Black Metal',
+            1150 => 'Music|Rock|Glam Rock',
+            1151 => 'Music|Rock|Hair Metal',
+            1152 => 'Music|Rock|Hard Rock',
+            1153 => 'Music|Rock|Metal',
+            1154 => 'Music|Rock|Jam Bands',
+            1155 => 'Music|Rock|Prog-Rock/Art Rock',
+            1156 => 'Music|Rock|Psychedelic',
+            1157 => 'Music|Rock|Rock & Roll',
+            1158 => 'Music|Rock|Rockabilly',
+            1159 => 'Music|Rock|Roots Rock',
+            1160 => 'Music|Rock|Singer/Songwriter',
+            1161 => 'Music|Rock|Southern Rock',
+            1162 => 'Music|Rock|Surf',
+            1163 => 'Music|Rock|Tex-Mex',
+            1165 => 'Music|Soundtrack|Foreign Cinema',
+            1166 => 'Music|Soundtrack|Musicals',
+            1167 => 'Music|Comedy|Novelty',
+            1168 => 'Music|Soundtrack|Original Score',
+            1169 => 'Music|Soundtrack|Soundtrack',
+            1171 => 'Music|Comedy|Standup Comedy',
+            1172 => 'Music|Soundtrack|TV Soundtrack',
+            1173 => 'Music|Vocal|Standards',
+            1174 => 'Music|Vocal|Traditional Pop',
+            1175 => 'Music|Jazz|Vocal Jazz',
+            1176 => 'Music|Vocal|Vocal Pop',
+            1177 => 'Music|African|Afro-Beat',
+            1178 => 'Music|African|Afro-Pop',
+            1179 => 'Music|World|Cajun',
+            1180 => 'Music|World|Celtic',
+            1181 => 'Music|World|Celtic Folk',
+            1182 => 'Music|World|Contemporary Celtic',
+            1183 => 'Music|Reggae|Modern Dancehall',
+            1184 => 'Music|World|Drinking Songs',
+            1185 => 'Music|Indian|Indian Pop',
+            1186 => 'Music|World|Japanese Pop',
+            1187 => 'Music|World|Klezmer',
+            1188 => 'Music|World|Polka',
+            1189 => 'Music|World|Traditional Celtic',
+            1190 => 'Music|World|Worldbeat',
+            1191 => 'Music|World|Zydeco',
+            1192 => 'Music|Reggae|Roots Reggae',
+            1193 => 'Music|Reggae|Dub',
+            1194 => 'Music|Reggae|Ska',
+            1195 => 'Music|World|Caribbean',
+            1196 => 'Music|World|South America',
+            1197 => 'Music|Arabic',
+            1198 => 'Music|World|North America',
+            1199 => 'Music|World|Hawaii',
+            1200 => 'Music|World|Australia',
+            1201 => 'Music|World|Japan',
+            1202 => 'Music|World|France',
+            1203 => 'Music|African',
+            1204 => 'Music|World|Asia',
+            1205 => 'Music|World|Europe',
+            1206 => 'Music|World|South Africa',
+            1207 => 'Music|Jazz|Hard Bop',
+            1208 => 'Music|Jazz|Trad Jazz',
+            1209 => 'Music|Jazz|Cool Jazz',
+            1210 => 'Music|Blues|Acoustic Blues',
+            1211 => 'Music|Classical|High Classical',
+            1220 => 'Music|Brazilian|Axe', # (Ax&eacute;)
+            1221 => 'Music|Brazilian|Bossa Nova',
+            1222 => 'Music|Brazilian|Choro',
+            1223 => 'Music|Brazilian|Forro', # (Forr&oacute;)
+            1224 => 'Music|Brazilian|Frevo',
+            1225 => 'Music|Brazilian|MPB',
+            1226 => 'Music|Brazilian|Pagode',
+            1227 => 'Music|Brazilian|Samba',
+            1228 => 'Music|Brazilian|Sertanejo',
+            1229 => 'Music|Brazilian|Baile Funk',
+            1230 => 'Music|Alternative|Chinese Alt',
+            1231 => 'Music|Alternative|Korean Indie',
+            1232 => 'Music|Chinese',
+            1233 => 'Music|Chinese|Chinese Classical',
+            1234 => 'Music|Chinese|Chinese Flute',
+            1235 => 'Music|Chinese|Chinese Opera',
+            1236 => 'Music|Chinese|Chinese Orchestral',
+            1237 => 'Music|Chinese|Chinese Regional Folk',
+            1238 => 'Music|Chinese|Chinese Strings',
+            1239 => 'Music|Chinese|Taiwanese Folk',
+            1240 => 'Music|Chinese|Tibetan Native Music',
+            1241 => 'Music|Hip-Hop/Rap|Chinese Hip-Hop',
+            1242 => 'Music|Hip-Hop/Rap|Korean Hip-Hop',
+            1243 => 'Music|Korean',
+            1244 => 'Music|Korean|Korean Classical',
+            1245 => 'Music|Korean|Korean Trad Song',
+            1246 => 'Music|Korean|Korean Trad Instrumental',
+            1247 => 'Music|Korean|Korean Trad Theater',
+            1248 => 'Music|Rock|Chinese Rock',
+            1249 => 'Music|Rock|Korean Rock',
+            1250 => 'Music|Pop|C-Pop',
+            1251 => 'Music|Pop|Cantopop/HK-Pop',
+            1252 => 'Music|Pop|Korean Folk-Pop',
+            1253 => 'Music|Pop|Mandopop',
+            1254 => 'Music|Pop|Tai-Pop',
+            1255 => 'Music|Pop|Malaysian Pop',
+            1256 => 'Music|Pop|Pinoy Pop',
+            1257 => 'Music|Pop|Original Pilipino Music',
+            1258 => 'Music|Pop|Manilla Sound',
+            1259 => 'Music|Pop|Indo Pop',
+            1260 => 'Music|Pop|Thai Pop',
+            1261 => 'Music|Vocal|Trot',
+            1262 => 'Music|Indian',
+            1263 => 'Music|Indian|Bollywood',
+            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|Russian|Russian Chanson',
+            1271 => 'Music|World|Dini',
+            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|Turkish|Arabesque',
+            1281 => 'Music|African|Afrikaans',
+            1282 => 'Music|World|Farsi',
+            1283 => 'Music|World|Israeli',
+            1284 => 'Music|Arabic|Khaleeji',
+            1285 => 'Music|Arabic|North African',
+            1286 => 'Music|Arabic|Arabic Pop',
+            1287 => 'Music|Arabic|Islamic',
+            1288 => 'Music|Soundtrack|Sound Effects',
+            1289 => 'Music|Folk',
+            1290 => 'Music|Orchestral',
+            1291 => 'Music|Marching',
+            1293 => 'Music|Pop|Oldies',
+            1294 => 'Music|Country|Thai Country',
+            1295 => 'Music|World|Flamenco',
+            1296 => 'Music|World|Tango',
+            1297 => 'Music|World|Fado',
+            1298 => 'Music|World|Iberia',
+            1299 => 'Music|Russian',
+            1300 => 'Music|Turkish',
+            1301 => 'Podcasts|Arts',
+            1302 => 'Podcasts|Society & Culture|Personal Journals',
+            1303 => 'Podcasts|Comedy',
+            1304 => 'Podcasts|Education',
+            1305 => 'Podcasts|Kids & Family',
+            1306 => 'Podcasts|Arts|Food',
+            1307 => 'Podcasts|Health',
+            1309 => 'Podcasts|TV & Film',
+            1310 => 'Podcasts|Music',
+            1311 => 'Podcasts|News & Politics',
+            1314 => 'Podcasts|Religion & Spirituality',
+            1315 => 'Podcasts|Science & Medicine',
+            1316 => 'Podcasts|Sports & Recreation',
+            1318 => 'Podcasts|Technology',
+            1320 => 'Podcasts|Society & Culture|Places & Travel',
+            1321 => 'Podcasts|Business',
+            1323 => 'Podcasts|Games & Hobbies',
+            1324 => 'Podcasts|Society & Culture',
+            1325 => 'Podcasts|Government & Organizations',
+            1337 => 'Music Videos|Classical|Piano',
+            1401 => 'Podcasts|Arts|Literature',
+            1402 => 'Podcasts|Arts|Design',
+            1404 => 'Podcasts|Games & Hobbies|Video Games',
+            1405 => 'Podcasts|Arts|Performing Arts',
+            1406 => 'Podcasts|Arts|Visual Arts',
+            1410 => 'Podcasts|Business|Careers',
+            1412 => 'Podcasts|Business|Investing',
+            1413 => 'Podcasts|Business|Management & Marketing',
+            1415 => 'Podcasts|Education|K-12',
+            1416 => 'Podcasts|Education|Higher Education',
+            1417 => 'Podcasts|Health|Fitness & Nutrition',
+            1420 => 'Podcasts|Health|Self-Help',
+            1421 => 'Podcasts|Health|Sexuality',
+            1438 => 'Podcasts|Religion & Spirituality|Buddhism',
+            1439 => 'Podcasts|Religion & Spirituality|Christianity',
+            1440 => 'Podcasts|Religion & Spirituality|Islam',
+            1441 => 'Podcasts|Religion & Spirituality|Judaism',
+            1443 => 'Podcasts|Society & Culture|Philosophy',
+            1444 => 'Podcasts|Religion & Spirituality|Spirituality',
+            1446 => 'Podcasts|Technology|Gadgets',
+            1448 => 'Podcasts|Technology|Tech News',
+            1450 => 'Podcasts|Technology|Podcasting',
+            1454 => 'Podcasts|Games & Hobbies|Automotive',
+            1455 => 'Podcasts|Games & Hobbies|Aviation',
+            1456 => 'Podcasts|Sports & Recreation|Outdoor',
+            1459 => 'Podcasts|Arts|Fashion & Beauty',
+            1460 => 'Podcasts|Games & Hobbies|Hobbies',
+            1461 => 'Podcasts|Games & Hobbies|Other Games',
+            1462 => 'Podcasts|Society & Culture|History',
+            1463 => 'Podcasts|Religion & Spirituality|Hinduism',
+            1464 => 'Podcasts|Religion & Spirituality|Other',
+            1465 => 'Podcasts|Sports & Recreation|Professional',
+            1466 => 'Podcasts|Sports & Recreation|College & High School',
+            1467 => 'Podcasts|Sports & Recreation|Amateur',
+            1468 => 'Podcasts|Education|Educational Technology',
+            1469 => 'Podcasts|Education|Language Courses',
+            1470 => 'Podcasts|Education|Training',
+            1471 => 'Podcasts|Business|Business News',
+            1472 => 'Podcasts|Business|Shopping',
+            1473 => 'Podcasts|Government & Organizations|National',
+            1474 => 'Podcasts|Government & Organizations|Regional',
+            1475 => 'Podcasts|Government & Organizations|Local',
+            1476 => 'Podcasts|Government & Organizations|Non-Profit',
+            1477 => 'Podcasts|Science & Medicine|Natural Sciences',
+            1478 => 'Podcasts|Science & Medicine|Medicine',
+            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",
+            1605 => 'Music Videos|Classical',
+            1606 => 'Music Videos|Country',
+            1607 => 'Music Videos|Electronic',
+            1608 => 'Music Videos|Holiday',
+            1609 => 'Music Videos|Classical|Opera',
+            1610 => 'Music Videos|Singer/Songwriter',
+            1611 => 'Music Videos|Jazz',
+            1612 => 'Music Videos|Latin',
+            1613 => 'Music Videos|New Age',
+            1614 => 'Music Videos|Pop',
+            1615 => 'Music Videos|R&B/Soul',
+            1616 => 'Music Videos|Soundtrack',
+            1617 => 'Music Videos|Dance',
+            1618 => 'Music Videos|Hip-Hop/Rap',
+            1619 => 'Music Videos|World',
+            1620 => 'Music Videos|Alternative',
+            1621 => 'Music Videos|Rock',
+            1622 => 'Music Videos|Christian & Gospel',
+            1623 => 'Music Videos|Vocal',
+            1624 => 'Music Videos|Reggae',
+            1625 => 'Music Videos|Easy Listening',
+            1626 => 'Music Videos|Podcasts',
+            1627 => 'Music Videos|J-Pop',
+            1628 => 'Music Videos|Enka',
+            1629 => 'Music Videos|Anime',
+            1630 => 'Music Videos|Kayokyoku',
+            1631 => 'Music Videos|Disney',
+            1632 => 'Music Videos|French Pop',
+            1633 => 'Music Videos|German Pop',
+            1634 => 'Music Videos|German Folk',
+            1635 => 'Music Videos|Alternative|Chinese Alt',
+            1636 => 'Music Videos|Alternative|Korean Indie',
+            1637 => 'Music Videos|Chinese',
+            1638 => 'Music Videos|Chinese|Chinese Classical',
+            1639 => 'Music Videos|Chinese|Chinese Flute',
+            1640 => 'Music Videos|Chinese|Chinese Opera',
+            1641 => 'Music Videos|Chinese|Chinese Orchestral',
+            1642 => 'Music Videos|Chinese|Chinese Regional Folk',
+            1643 => 'Music Videos|Chinese|Chinese Strings',
+            1644 => 'Music Videos|Chinese|Taiwanese Folk',
+            1645 => 'Music Videos|Chinese|Tibetan Native Music',
+            1646 => 'Music Videos|Hip-Hop/Rap|Chinese Hip-Hop',
+            1647 => 'Music Videos|Hip-Hop/Rap|Korean Hip-Hop',
+            1648 => 'Music Videos|Korean',
+            1649 => 'Music Videos|Korean|Korean Classical',
+            1650 => 'Music Videos|Korean|Korean Trad Song',
+            1651 => 'Music Videos|Korean|Korean Trad Instrumental',
+            1652 => 'Music Videos|Korean|Korean Trad Theater',
+            1653 => 'Music Videos|Rock|Chinese Rock',
+            1654 => 'Music Videos|Rock|Korean Rock',
+            1655 => 'Music Videos|Pop|C-Pop',
+            1656 => 'Music Videos|Pop|Cantopop/HK-Pop',
+            1657 => 'Music Videos|Pop|Korean Folk-Pop',
+            1658 => 'Music Videos|Pop|Mandopop',
+            1659 => 'Music Videos|Pop|Tai-Pop',
+            1660 => 'Music Videos|Pop|Malaysian Pop',
+            1661 => 'Music Videos|Pop|Pinoy Pop',
+            1662 => 'Music Videos|Pop|Original Pilipino Music',
+            1663 => 'Music Videos|Pop|Manilla Sound',
+            1664 => 'Music Videos|Pop|Indo Pop',
+            1665 => 'Music Videos|Pop|Thai Pop',
+            1666 => 'Music Videos|Vocal|Trot',
+            1671 => 'Music Videos|Brazilian',
+            1672 => 'Music Videos|Brazilian|Axe', # (Ax&eacute;)
+            1673 => 'Music Videos|Brazilian|Baile Funk',
+            1674 => 'Music Videos|Brazilian|Bossa Nova',
+            1675 => 'Music Videos|Brazilian|Choro',
+            1676 => 'Music Videos|Brazilian|Forro',
+            1677 => 'Music Videos|Brazilian|Frevo',
+            1678 => 'Music Videos|Brazilian|MPB',
+            1679 => 'Music Videos|Brazilian|Pagode',
+            1680 => 'Music Videos|Brazilian|Samba',
+            1681 => 'Music Videos|Brazilian|Sertanejo',
+            1682 => 'Music Videos|Classical|High Classical',
+            1683 => 'Music Videos|Fitness & Workout',
+            1684 => 'Music Videos|Instrumental',
+            1685 => 'Music Videos|Jazz|Big Band',
+            1686 => 'Music Videos|Pop|K-Pop',
+            1687 => 'Music Videos|Karaoke',
+            1688 => 'Music Videos|Rock|Heavy Metal',
+            1689 => 'Music Videos|Spoken Word',
+            1690 => 'Music Videos|Indian',
+            1691 => 'Music Videos|Indian|Bollywood',
+            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|Russian|Russian Chanson',
+            1699 => 'Music Videos|World|Dini',
+            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',
+            1705 => 'Music Videos|World|Calypso',
+            1706 => 'Music Videos|World|Soca',
+            1707 => 'Music Videos|Indian|Ghazals',
+            1708 => 'Music Videos|Indian|Indian Folk',
+            1709 => 'Music Videos|Turkish|Arabesque',
+            1710 => 'Music Videos|African|Afrikaans',
+            1711 => 'Music Videos|World|Farsi',
+            1712 => 'Music Videos|World|Israeli',
+            1713 => 'Music Videos|Arabic',
+            1714 => 'Music Videos|Arabic|Khaleeji',
+            1715 => 'Music Videos|Arabic|North African',
+            1716 => 'Music Videos|Arabic|Arabic Pop',
+            1717 => 'Music Videos|Arabic|Islamic',
+            1718 => 'Music Videos|Soundtrack|Sound Effects',
+            1719 => 'Music Videos|Folk',
+            1720 => 'Music Videos|Orchestral',
+            1721 => 'Music Videos|Marching',
+            1723 => 'Music Videos|Pop|Oldies',
+            1724 => 'Music Videos|Country|Thai Country',
+            1725 => 'Music Videos|World|Flamenco',
+            1726 => 'Music Videos|World|Tango',
+            1727 => 'Music Videos|World|Fado',
+            1728 => 'Music Videos|World|Iberia',
+            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',
+            1734 => 'Music Videos|Alternative|Indie Rock',
+            1735 => 'Music Videos|Alternative|New Wave',
+            1736 => 'Music Videos|Alternative|Punk',
+            1737 => 'Music Videos|Blues|Acoustic Blues',
+            1738 => 'Music Videos|Blues|Chicago Blues',
+            1739 => 'Music Videos|Blues|Classic Blues',
+            1740 => 'Music Videos|Blues|Contemporary Blues',
+            1741 => 'Music Videos|Blues|Country Blues',
+            1742 => 'Music Videos|Blues|Delta Blues',
+            1743 => 'Music Videos|Blues|Electric Blues',
+            1744 => "Music Videos|Children's Music|Lullabies",
+            1745 => "Music Videos|Children's Music|Sing-Along",
+            1746 => "Music Videos|Children's Music|Stories",
+            1747 => 'Music Videos|Christian & Gospel|CCM',
+            1748 => 'Music Videos|Christian & Gospel|Christian Metal',
+            1749 => 'Music Videos|Christian & Gospel|Christian Pop',
+            1750 => 'Music Videos|Christian & Gospel|Christian Rap',
+            1751 => 'Music Videos|Christian & Gospel|Christian Rock',
+            1752 => 'Music Videos|Christian & Gospel|Classic Christian',
+            1753 => 'Music Videos|Christian & Gospel|Contemporary Gospel',
+            1754 => 'Music Videos|Christian & Gospel|Gospel',
+            1755 => 'Music Videos|Christian & Gospel|Praise & Worship',
+            1756 => 'Music Videos|Christian & Gospel|Southern Gospel',
+            1757 => 'Music Videos|Christian & Gospel|Traditional Gospel',
+            1758 => 'Music Videos|Classical|Avant-Garde',
+            1759 => 'Music Videos|Classical|Baroque Era',
+            1760 => 'Music Videos|Classical|Chamber Music',
+            1761 => 'Music Videos|Classical|Chant',
+            1762 => 'Music Videos|Classical|Choral',
+            1763 => 'Music Videos|Classical|Classical Crossover',
+            1764 => 'Music Videos|Classical|Early Music',
+            1765 => 'Music Videos|Classical|Impressionist',
+            1766 => 'Music Videos|Classical|Medieval Era',
+            1767 => 'Music Videos|Classical|Minimalism',
+            1768 => 'Music Videos|Classical|Modern Era',
+            1769 => 'Music Videos|Classical|Orchestral',
+            1770 => 'Music Videos|Classical|Renaissance',
+            1771 => 'Music Videos|Classical|Romantic Era',
+            1772 => 'Music Videos|Classical|Wedding Music',
+            1773 => 'Music Videos|Comedy|Novelty',
+            1774 => 'Music Videos|Comedy|Standup Comedy',
+            1775 => 'Music Videos|Country|Alternative Country',
+            1776 => 'Music Videos|Country|Americana',
+            1777 => 'Music Videos|Country|Bluegrass',
+            1778 => 'Music Videos|Country|Contemporary Bluegrass',
+            1779 => 'Music Videos|Country|Contemporary Country',
+            1780 => 'Music Videos|Country|Country Gospel',
+            1781 => 'Music Videos|Country|Honky Tonk',
+            1782 => 'Music Videos|Country|Outlaw Country',
+            1783 => 'Music Videos|Country|Traditional Bluegrass',
+            1784 => 'Music Videos|Country|Traditional Country',
+            1785 => 'Music Videos|Country|Urban Cowboy',
+            1786 => 'Music Videos|Dance|Breakbeat',
+            1787 => 'Music Videos|Dance|Exercise',
+            1788 => 'Music Videos|Dance|Garage',
+            1789 => 'Music Videos|Dance|Hardcore',
+            1790 => 'Music Videos|Dance|House',
+            1791 => "Music Videos|Dance|Jungle/Drum'n'bass",
+            1792 => 'Music Videos|Dance|Techno',
+            1793 => 'Music Videos|Dance|Trance',
+            1794 => 'Music Videos|Easy Listening|Lounge',
+            1795 => 'Music Videos|Easy Listening|Swing',
+            1796 => 'Music Videos|Electronic|Ambient',
+            1797 => 'Music Videos|Electronic|Downtempo',
+            1798 => 'Music Videos|Electronic|Electronica',
+            1799 => 'Music Videos|Electronic|IDM/Experimental',
+            1800 => 'Music Videos|Electronic|Industrial',
+            1801 => 'Music Videos|Hip-Hop/Rap|Alternative Rap',
+            1802 => 'Music Videos|Hip-Hop/Rap|Dirty South',
+            1803 => 'Music Videos|Hip-Hop/Rap|East Coast Rap',
+            1804 => 'Music Videos|Hip-Hop/Rap|Gangsta Rap',
+            1805 => 'Music Videos|Hip-Hop/Rap|Hardcore Rap',
+            1806 => 'Music Videos|Hip-Hop/Rap|Hip-Hop',
+            1807 => 'Music Videos|Hip-Hop/Rap|Latin Rap',
+            1808 => 'Music Videos|Hip-Hop/Rap|Old School Rap',
+            1809 => 'Music Videos|Hip-Hop/Rap|Rap',
+            1810 => 'Music Videos|Hip-Hop/Rap|Underground Rap',
+            1811 => 'Music Videos|Hip-Hop/Rap|West Coast Rap',
+            1812 => 'Music Videos|Holiday|Chanukah',
+            1813 => 'Music Videos|Holiday|Christmas',
+            1814 => "Music Videos|Holiday|Christmas: Children's",
+            1815 => 'Music Videos|Holiday|Christmas: Classic',
+            1816 => 'Music Videos|Holiday|Christmas: Classical',
+            1817 => 'Music Videos|Holiday|Christmas: Jazz',
+            1818 => 'Music Videos|Holiday|Christmas: Modern',
+            1819 => 'Music Videos|Holiday|Christmas: Pop',
+            1820 => 'Music Videos|Holiday|Christmas: R&B',
+            1821 => 'Music Videos|Holiday|Christmas: Religious',
+            1822 => 'Music Videos|Holiday|Christmas: Rock',
+            1823 => 'Music Videos|Holiday|Easter',
+            1824 => 'Music Videos|Holiday|Halloween',
+            1825 => 'Music Videos|Holiday|Thanksgiving',
+            1826 => 'Music Videos|Jazz|Avant-Garde Jazz',
+            1828 => 'Music Videos|Jazz|Bop',
+            1829 => 'Music Videos|Jazz|Contemporary Jazz',
+            1830 => 'Music Videos|Jazz|Cool Jazz',
+            1831 => 'Music Videos|Jazz|Crossover Jazz',
+            1832 => 'Music Videos|Jazz|Dixieland',
+            1833 => 'Music Videos|Jazz|Fusion',
+            1834 => 'Music Videos|Jazz|Hard Bop',
+            1835 => 'Music Videos|Jazz|Latin Jazz',
+            1836 => 'Music Videos|Jazz|Mainstream Jazz',
+            1837 => 'Music Videos|Jazz|Ragtime',
+            1838 => 'Music Videos|Jazz|Smooth Jazz',
+            1839 => 'Music Videos|Jazz|Trad Jazz',
+            1840 => 'Music Videos|Latin|Alternative & Rock in Spanish',
+            1841 => 'Music Videos|Latin|Baladas y Boleros',
+            1842 => 'Music Videos|Latin|Contemporary Latin',
+            1843 => 'Music Videos|Latin|Latin Jazz',
+            1844 => 'Music Videos|Latin|Latin Urban',
+            1845 => 'Music Videos|Latin|Pop in Spanish',
+            1846 => 'Music Videos|Latin|Raices',
+            1847 => 'Music Videos|Latin|Musica Mexicana', # (M&uacute;sica Mexicana)
+            1848 => 'Music Videos|Latin|Salsa y Tropical',
+            1849 => 'Music Videos|New Age|Healing',
+            1850 => 'Music Videos|New Age|Meditation',
+            1851 => 'Music Videos|New Age|Nature',
+            1852 => 'Music Videos|New Age|Relaxation',
+            1853 => 'Music Videos|New Age|Travel',
+            1854 => 'Music Videos|Pop|Adult Contemporary',
+            1855 => 'Music Videos|Pop|Britpop',
+            1856 => 'Music Videos|Pop|Pop/Rock',
+            1857 => 'Music Videos|Pop|Soft Rock',
+            1858 => 'Music Videos|Pop|Teen Pop',
+            1859 => 'Music Videos|R&B/Soul|Contemporary R&B',
+            1860 => 'Music Videos|R&B/Soul|Disco',
+            1861 => 'Music Videos|R&B/Soul|Doo Wop',
+            1862 => 'Music Videos|R&B/Soul|Funk',
+            1863 => 'Music Videos|R&B/Soul|Motown',
+            1864 => 'Music Videos|R&B/Soul|Neo-Soul',
+            1865 => 'Music Videos|R&B/Soul|Soul',
+            1866 => 'Music Videos|Reggae|Modern Dancehall',
+            1867 => 'Music Videos|Reggae|Dub',
+            1868 => 'Music Videos|Reggae|Roots Reggae',
+            1869 => 'Music Videos|Reggae|Ska',
+            1870 => 'Music Videos|Rock|Adult Alternative',
+            1871 => 'Music Videos|Rock|American Trad Rock',
+            1872 => 'Music Videos|Rock|Arena Rock',
+            1873 => 'Music Videos|Rock|Blues-Rock',
+            1874 => 'Music Videos|Rock|British Invasion',
+            1875 => 'Music Videos|Rock|Death Metal/Black Metal',
+            1876 => 'Music Videos|Rock|Glam Rock',
+            1877 => 'Music Videos|Rock|Hair Metal',
+            1878 => 'Music Videos|Rock|Hard Rock',
+            1879 => 'Music Videos|Rock|Jam Bands',
+            1880 => 'Music Videos|Rock|Prog-Rock/Art Rock',
+            1881 => 'Music Videos|Rock|Psychedelic',
+            1882 => 'Music Videos|Rock|Rock & Roll',
+            1883 => 'Music Videos|Rock|Rockabilly',
+            1884 => 'Music Videos|Rock|Roots Rock',
+            1885 => 'Music Videos|Rock|Singer/Songwriter',
+            1886 => 'Music Videos|Rock|Southern Rock',
+            1887 => 'Music Videos|Rock|Surf',
+            1888 => 'Music Videos|Rock|Tex-Mex',
+            1889 => 'Music Videos|Singer/Songwriter|Alternative Folk',
+            1890 => 'Music Videos|Singer/Songwriter|Contemporary Folk',
+            1891 => 'Music Videos|Singer/Songwriter|Contemporary Singer/Songwriter',
+            1892 => 'Music Videos|Singer/Songwriter|Folk-Rock',
+            1893 => 'Music Videos|Singer/Songwriter|New Acoustic',
+            1894 => 'Music Videos|Singer/Songwriter|Traditional Folk',
+            1895 => 'Music Videos|Soundtrack|Foreign Cinema',
+            1896 => 'Music Videos|Soundtrack|Musicals',
+            1897 => 'Music Videos|Soundtrack|Original Score',
+            1898 => 'Music Videos|Soundtrack|Soundtrack',
+            1899 => 'Music Videos|Soundtrack|TV Soundtrack',
+            1900 => 'Music Videos|Vocal|Standards',
+            1901 => 'Music Videos|Vocal|Traditional Pop',
+            1902 => 'Music Videos|Jazz|Vocal Jazz',
+            1903 => 'Music Videos|Vocal|Vocal 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',
+            1910 => 'Music Videos|World|Caribbean',
+            1911 => 'Music Videos|World|Celtic',
+            1912 => 'Music Videos|World|Celtic Folk',
+            1913 => 'Music Videos|World|Contemporary Celtic',
+            1914 => 'Music Videos|World|Europe',
+            1915 => 'Music Videos|World|France',
+            1916 => 'Music Videos|World|Hawaii',
+            1917 => 'Music Videos|World|Japan',
+            1918 => 'Music Videos|World|Klezmer',
+            1919 => 'Music Videos|World|North America',
+            1920 => 'Music Videos|World|Polka',
+            1921 => 'Music Videos|World|South Africa',
+            1922 => 'Music Videos|World|South America',
+            1923 => 'Music Videos|World|Traditional Celtic',
+            1924 => 'Music Videos|World|Worldbeat',
+            1925 => 'Music Videos|World|Zydeco',
+            1926 => 'Music Videos|Christian & Gospel',
+            1928 => 'Music Videos|Classical|Art Song',
+            1929 => 'Music Videos|Classical|Brass & Woodwinds',
+            1930 => 'Music Videos|Classical|Solo Instrumental',
+            1931 => 'Music Videos|Classical|Contemporary Era',
+            1932 => 'Music Videos|Classical|Oratorio',
+            1933 => 'Music Videos|Classical|Cantata',
+            1934 => 'Music Videos|Classical|Electronic',
+            1935 => 'Music Videos|Classical|Sacred',
+            1936 => 'Music Videos|Classical|Guitar',
+            1938 => 'Music Videos|Classical|Violin',
+            1939 => 'Music Videos|Classical|Cello',
+            1940 => 'Music Videos|Classical|Percussion',
+            1941 => 'Music Videos|Electronic|Dubstep',
+            1942 => 'Music Videos|Electronic|Bass',
+            1943 => 'Music Videos|Hip-Hop/Rap|UK Hip-Hop',
+            1944 => 'Music Videos|Reggae|Lovers Rock',
+            1945 => 'Music Videos|Alternative|EMO',
+            1946 => 'Music Videos|Alternative|Pop Punk',
+            1947 => 'Music Videos|Alternative|Indie Pop',
+            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|Classics',
+            4005 => 'TV Shows|Kids & Family',
+            4006 => 'TV Shows|Nonfiction',
+            4007 => 'TV Shows|Reality TV',
+            4008 => 'TV Shows|Sci-Fi & Fantasy',
+            4009 => 'TV Shows|Sports',
+            4010 => 'TV Shows|Teens',
+            4011 => 'TV Shows|Latino TV',
+            4401 => 'Movies|Action & Adventure',
+            4402 => 'Movies|Anime',
+            4403 => 'Movies|Classics',
+            4404 => 'Movies|Comedy',
+            4405 => 'Movies|Documentary',
+            4406 => 'Movies|Drama',
+            4407 => 'Movies|Foreign',
+            4408 => 'Movies|Horror',
+            4409 => 'Movies|Independent',
+            4410 => 'Movies|Kids & Family',
+            4411 => 'Movies|Musicals',
+            4412 => 'Movies|Romance',
+            4413 => 'Movies|Sci-Fi & Fantasy',
+            4414 => 'Movies|Short Films',
+            4415 => 'Movies|Special Interest',
+            4416 => 'Movies|Thriller',
+            4417 => 'Movies|Sports',
+            4418 => 'Movies|Western',
+            4419 => 'Movies|Urban',
+            4420 => 'Movies|Holiday',
+            4421 => 'Movies|Made for TV',
+            4422 => 'Movies|Concert Films',
+            4423 => 'Movies|Music Documentaries',
+            4424 => 'Movies|Music Feature Films',
+            4425 => 'Movies|Japanese Cinema',
+            4426 => 'Movies|Jidaigeki',
+            4427 => 'Movies|Tokusatsu',
+            4428 => 'Movies|Korean Cinema',
+            4429 => 'Movies|Russian',
+            4430 => 'Movies|Turkish',
+            4431 => 'Movies|Bollywood',
+            4432 => 'Movies|Regional Indian',
+            4433 => 'Movies|Middle Eastern',
+            4434 => 'Movies|African',
+            6000 => 'App Store|Business',
+            6001 => 'App Store|Weather',
+            6002 => 'App Store|Utilities',
+            6003 => 'App Store|Travel',
+            6004 => 'App Store|Sports',
+            6005 => 'App Store|Social Networking',
+            6006 => 'App Store|Reference',
+            6007 => 'App Store|Productivity',
+            6008 => 'App Store|Photo & Video',
+            6009 => 'App Store|News',
+            6010 => 'App Store|Navigation',
+            6011 => 'App Store|Music',
+            6012 => 'App Store|Lifestyle',
+            6013 => 'App Store|Health & Fitness',
+            6014 => 'App Store|Games',
+            6015 => 'App Store|Finance',
+            6016 => 'App Store|Entertainment',
+            6017 => 'App Store|Education',
+            6018 => 'App Store|Books',
+            6020 => 'App Store|Medical',
+            6021 => 'App Store|Magazines & Newspapers',
+            6022 => 'App Store|Catalogs',
+            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|Casual',
+            7004 => 'App Store|Games|Board',
+            7005 => 'App Store|Games|Card',
+            7006 => 'App Store|Games|Casino',
+            7007 => 'App Store|Games|Dice',
+            7008 => 'App Store|Games|Educational',
+            7009 => 'App Store|Games|Family',
+            7011 => 'App Store|Games|Music',
+            7012 => 'App Store|Games|Puzzle',
+            7013 => 'App Store|Games|Racing',
+            7014 => 'App Store|Games|Role Playing',
+            7015 => 'App Store|Games|Simulation',
+            7016 => 'App Store|Games|Sports',
+            7017 => 'App Store|Games|Strategy',
+            7018 => 'App Store|Games|Trivia',
+            7019 => 'App Store|Games|Word',
+            8001 => 'Tones|Ringtones|Alternative',
+            8002 => 'Tones|Ringtones|Blues',
+            8003 => "Tones|Ringtones|Children's Music",
+            8004 => 'Tones|Ringtones|Classical',
+            8005 => 'Tones|Ringtones|Comedy',
+            8006 => 'Tones|Ringtones|Country',
+            8007 => 'Tones|Ringtones|Dance',
+            8008 => 'Tones|Ringtones|Electronic',
+            8009 => 'Tones|Ringtones|Enka',
+            8010 => 'Tones|Ringtones|French Pop',
+            8011 => 'Tones|Ringtones|German Folk',
+            8012 => 'Tones|Ringtones|German Pop',
+            8013 => 'Tones|Ringtones|Hip-Hop/Rap',
+            8014 => 'Tones|Ringtones|Holiday',
+            8015 => 'Tones|Ringtones|Inspirational',
+            8016 => 'Tones|Ringtones|J-Pop',
+            8017 => 'Tones|Ringtones|Jazz',
+            8018 => 'Tones|Ringtones|Kayokyoku',
+            8019 => 'Tones|Ringtones|Latin',
+            8020 => 'Tones|Ringtones|New Age',
+            8021 => 'Tones|Ringtones|Classical|Opera',
+            8022 => 'Tones|Ringtones|Pop',
+            8023 => 'Tones|Ringtones|R&B/Soul',
+            8024 => 'Tones|Ringtones|Reggae',
+            8025 => 'Tones|Ringtones|Rock',
+            8026 => 'Tones|Ringtones|Singer/Songwriter',
+            8027 => 'Tones|Ringtones|Soundtrack',
+            8028 => 'Tones|Ringtones|Spoken Word',
+            8029 => 'Tones|Ringtones|Vocal',
+            8030 => 'Tones|Ringtones|World',
+            8050 => 'Tones|Alert Tones|Sound Effects',
+            8051 => 'Tones|Alert Tones|Dialogue',
+            8052 => 'Tones|Alert Tones|Music',
+            8053 => 'Tones|Ringtones',
+            8054 => 'Tones|Alert Tones',
+            8055 => 'Tones|Ringtones|Alternative|Chinese Alt',
+            8056 => 'Tones|Ringtones|Alternative|College Rock',
+            8057 => 'Tones|Ringtones|Alternative|Goth Rock',
+            8058 => 'Tones|Ringtones|Alternative|Grunge',
+            8059 => 'Tones|Ringtones|Alternative|Indie Rock',
+            8060 => 'Tones|Ringtones|Alternative|Korean Indie',
+            8061 => 'Tones|Ringtones|Alternative|New Wave',
+            8062 => 'Tones|Ringtones|Alternative|Punk',
+            8063 => 'Tones|Ringtones|Anime',
+            8064 => 'Tones|Ringtones|Arabic',
+            8065 => 'Tones|Ringtones|Arabic|Arabic Pop',
+            8066 => 'Tones|Ringtones|Arabic|Islamic',
+            8067 => 'Tones|Ringtones|Arabic|Khaleeji',
+            8068 => 'Tones|Ringtones|Arabic|North African',
+            8069 => 'Tones|Ringtones|Blues|Acoustic Blues',
+            8070 => 'Tones|Ringtones|Blues|Chicago Blues',
+            8071 => 'Tones|Ringtones|Blues|Classic Blues',
+            8072 => 'Tones|Ringtones|Blues|Contemporary Blues',
+            8073 => 'Tones|Ringtones|Blues|Country Blues',
+            8074 => 'Tones|Ringtones|Blues|Delta Blues',
+            8075 => 'Tones|Ringtones|Blues|Electric Blues',
+            8076 => 'Tones|Ringtones|Brazilian',
+            8077 => 'Tones|Ringtones|Brazilian|Axe', # (Ax&eacute;)
+            8078 => 'Tones|Ringtones|Brazilian|Baile Funk',
+            8079 => 'Tones|Ringtones|Brazilian|Bossa Nova',
+            8080 => 'Tones|Ringtones|Brazilian|Choro',
+            8081 => 'Tones|Ringtones|Brazilian|Forro', # (Forr&oacute;)
+            8082 => 'Tones|Ringtones|Brazilian|Frevo',
+            8083 => 'Tones|Ringtones|Brazilian|MPB',
+            8084 => 'Tones|Ringtones|Brazilian|Pagode',
+            8085 => 'Tones|Ringtones|Brazilian|Samba',
+            8086 => 'Tones|Ringtones|Brazilian|Sertanejo',
+            8087 => "Tones|Ringtones|Children's Music|Lullabies",
+            8088 => "Tones|Ringtones|Children's Music|Sing-Along",
+            8089 => "Tones|Ringtones|Children's Music|Stories",
+            8090 => 'Tones|Ringtones|Chinese',
+            8091 => 'Tones|Ringtones|Chinese|Chinese Classical',
+            8092 => 'Tones|Ringtones|Chinese|Chinese Flute',
+            8093 => 'Tones|Ringtones|Chinese|Chinese Opera',
+            8094 => 'Tones|Ringtones|Chinese|Chinese Orchestral',
+            8095 => 'Tones|Ringtones|Chinese|Chinese Regional Folk',
+            8096 => 'Tones|Ringtones|Chinese|Chinese Strings',
+            8097 => 'Tones|Ringtones|Chinese|Taiwanese Folk',
+            8098 => 'Tones|Ringtones|Chinese|Tibetan Native Music',
+            8099 => 'Tones|Ringtones|Christian & Gospel',
+            8100 => 'Tones|Ringtones|Christian & Gospel|CCM',
+            8101 => 'Tones|Ringtones|Christian & Gospel|Christian Metal',
+            8102 => 'Tones|Ringtones|Christian & Gospel|Christian Pop',
+            8103 => 'Tones|Ringtones|Christian & Gospel|Christian Rap',
+            8104 => 'Tones|Ringtones|Christian & Gospel|Christian Rock',
+            8105 => 'Tones|Ringtones|Christian & Gospel|Classic Christian',
+            8106 => 'Tones|Ringtones|Christian & Gospel|Contemporary Gospel',
+            8107 => 'Tones|Ringtones|Christian & Gospel|Gospel',
+            8108 => 'Tones|Ringtones|Christian & Gospel|Praise & Worship',
+            8109 => 'Tones|Ringtones|Christian & Gospel|Southern Gospel',
+            8110 => 'Tones|Ringtones|Christian & Gospel|Traditional Gospel',
+            8111 => 'Tones|Ringtones|Classical|Avant-Garde',
+            8112 => 'Tones|Ringtones|Classical|Baroque Era',
+            8113 => 'Tones|Ringtones|Classical|Chamber Music',
+            8114 => 'Tones|Ringtones|Classical|Chant',
+            8115 => 'Tones|Ringtones|Classical|Choral',
+            8116 => 'Tones|Ringtones|Classical|Classical Crossover',
+            8117 => 'Tones|Ringtones|Classical|Early Music',
+            8118 => 'Tones|Ringtones|Classical|High Classical',
+            8119 => 'Tones|Ringtones|Classical|Impressionist',
+            8120 => 'Tones|Ringtones|Classical|Medieval Era',
+            8121 => 'Tones|Ringtones|Classical|Minimalism',
+            8122 => 'Tones|Ringtones|Classical|Modern Era',
+            8123 => 'Tones|Ringtones|Classical|Orchestral',
+            8124 => 'Tones|Ringtones|Classical|Renaissance',
+            8125 => 'Tones|Ringtones|Classical|Romantic Era',
+            8126 => 'Tones|Ringtones|Classical|Wedding Music',
+            8127 => 'Tones|Ringtones|Comedy|Novelty',
+            8128 => 'Tones|Ringtones|Comedy|Standup Comedy',
+            8129 => 'Tones|Ringtones|Country|Alternative Country',
+            8130 => 'Tones|Ringtones|Country|Americana',
+            8131 => 'Tones|Ringtones|Country|Bluegrass',
+            8132 => 'Tones|Ringtones|Country|Contemporary Bluegrass',
+            8133 => 'Tones|Ringtones|Country|Contemporary Country',
+            8134 => 'Tones|Ringtones|Country|Country Gospel',
+            8135 => 'Tones|Ringtones|Country|Honky Tonk',
+            8136 => 'Tones|Ringtones|Country|Outlaw Country',
+            8137 => 'Tones|Ringtones|Country|Thai Country',
+            8138 => 'Tones|Ringtones|Country|Traditional Bluegrass',
+            8139 => 'Tones|Ringtones|Country|Traditional Country',
+            8140 => 'Tones|Ringtones|Country|Urban Cowboy',
+            8141 => 'Tones|Ringtones|Dance|Breakbeat',
+            8142 => 'Tones|Ringtones|Dance|Exercise',
+            8143 => 'Tones|Ringtones|Dance|Garage',
+            8144 => 'Tones|Ringtones|Dance|Hardcore',
+            8145 => 'Tones|Ringtones|Dance|House',
+            8146 => "Tones|Ringtones|Dance|Jungle/Drum'n'bass",
+            8147 => 'Tones|Ringtones|Dance|Techno',
+            8148 => 'Tones|Ringtones|Dance|Trance',
+            8149 => 'Tones|Ringtones|Disney',
+            8150 => 'Tones|Ringtones|Easy Listening',
+            8151 => 'Tones|Ringtones|Easy Listening|Lounge',
+            8152 => 'Tones|Ringtones|Easy Listening|Swing',
+            8153 => 'Tones|Ringtones|Electronic|Ambient',
+            8154 => 'Tones|Ringtones|Electronic|Downtempo',
+            8155 => 'Tones|Ringtones|Electronic|Electronica',
+            8156 => 'Tones|Ringtones|Electronic|IDM/Experimental',
+            8157 => 'Tones|Ringtones|Electronic|Industrial',
+            8158 => 'Tones|Ringtones|Fitness & Workout',
+            8159 => 'Tones|Ringtones|Folk',
+            8160 => 'Tones|Ringtones|Hip-Hop/Rap|Alternative Rap',
+            8161 => 'Tones|Ringtones|Hip-Hop/Rap|Chinese Hip-Hop',
+            8162 => 'Tones|Ringtones|Hip-Hop/Rap|Dirty South',
+            8163 => 'Tones|Ringtones|Hip-Hop/Rap|East Coast Rap',
+            8164 => 'Tones|Ringtones|Hip-Hop/Rap|Gangsta Rap',
+            8165 => 'Tones|Ringtones|Hip-Hop/Rap|Hardcore Rap',
+            8166 => 'Tones|Ringtones|Hip-Hop/Rap|Hip-Hop',
+            8167 => 'Tones|Ringtones|Hip-Hop/Rap|Korean Hip-Hop',
+            8168 => 'Tones|Ringtones|Hip-Hop/Rap|Latin Rap',
+            8169 => 'Tones|Ringtones|Hip-Hop/Rap|Old School Rap',
+            8170 => 'Tones|Ringtones|Hip-Hop/Rap|Rap',
+            8171 => 'Tones|Ringtones|Hip-Hop/Rap|Underground Rap',
+            8172 => 'Tones|Ringtones|Hip-Hop/Rap|West Coast Rap',
+            8173 => 'Tones|Ringtones|Holiday|Chanukah',
+            8174 => 'Tones|Ringtones|Holiday|Christmas',
+            8175 => "Tones|Ringtones|Holiday|Christmas: Children's",
+            8176 => 'Tones|Ringtones|Holiday|Christmas: Classic',
+            8177 => 'Tones|Ringtones|Holiday|Christmas: Classical',
+            8178 => 'Tones|Ringtones|Holiday|Christmas: Jazz',
+            8179 => 'Tones|Ringtones|Holiday|Christmas: Modern',
+            8180 => 'Tones|Ringtones|Holiday|Christmas: Pop',
+            8181 => 'Tones|Ringtones|Holiday|Christmas: R&B',
+            8182 => 'Tones|Ringtones|Holiday|Christmas: Religious',
+            8183 => 'Tones|Ringtones|Holiday|Christmas: Rock',
+            8184 => 'Tones|Ringtones|Holiday|Easter',
+            8185 => 'Tones|Ringtones|Holiday|Halloween',
+            8186 => 'Tones|Ringtones|Holiday|Thanksgiving',
+            8187 => 'Tones|Ringtones|Indian',
+            8188 => 'Tones|Ringtones|Indian|Bollywood',
+            8189 => 'Tones|Ringtones|Indian|Devotional & Spiritual',
+            8190 => 'Tones|Ringtones|Indian|Ghazals',
+            8191 => 'Tones|Ringtones|Indian|Indian Classical',
+            8192 => 'Tones|Ringtones|Indian|Indian Folk',
+            8193 => 'Tones|Ringtones|Indian|Indian Pop',
+            8194 => 'Tones|Ringtones|Indian|Regional Indian',
+            8195 => 'Tones|Ringtones|Indian|Sufi',
+            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',
+            8202 => 'Tones|Ringtones|Jazz|Bop',
+            8203 => 'Tones|Ringtones|Jazz|Contemporary Jazz',
+            8204 => 'Tones|Ringtones|Jazz|Cool Jazz',
+            8205 => 'Tones|Ringtones|Jazz|Crossover Jazz',
+            8206 => 'Tones|Ringtones|Jazz|Dixieland',
+            8207 => 'Tones|Ringtones|Jazz|Fusion',
+            8208 => 'Tones|Ringtones|Jazz|Hard Bop',
+            8209 => 'Tones|Ringtones|Jazz|Latin Jazz',
+            8210 => 'Tones|Ringtones|Jazz|Mainstream Jazz',
+            8211 => 'Tones|Ringtones|Jazz|Ragtime',
+            8212 => 'Tones|Ringtones|Jazz|Smooth Jazz',
+            8213 => 'Tones|Ringtones|Jazz|Trad Jazz',
+            8214 => 'Tones|Ringtones|Pop|K-Pop',
+            8215 => 'Tones|Ringtones|Karaoke',
+            8216 => 'Tones|Ringtones|Korean',
+            8217 => 'Tones|Ringtones|Korean|Korean Classical',
+            8218 => 'Tones|Ringtones|Korean|Korean Trad Instrumental',
+            8219 => 'Tones|Ringtones|Korean|Korean Trad Song',
+            8220 => 'Tones|Ringtones|Korean|Korean Trad Theater',
+            8221 => 'Tones|Ringtones|Latin|Alternative & Rock in Spanish',
+            8222 => 'Tones|Ringtones|Latin|Baladas y Boleros',
+            8223 => 'Tones|Ringtones|Latin|Contemporary Latin',
+            8224 => 'Tones|Ringtones|Latin|Latin Jazz',
+            8225 => 'Tones|Ringtones|Latin|Latin Urban',
+            8226 => 'Tones|Ringtones|Latin|Pop in Spanish',
+            8227 => 'Tones|Ringtones|Latin|Raices',
+            8228 => 'Tones|Ringtones|Latin|Musica Mexicana', # (M&uacute;sica Mexicana)
+            8229 => 'Tones|Ringtones|Latin|Salsa y Tropical',
+            8230 => 'Tones|Ringtones|Marching Bands',
+            8231 => 'Tones|Ringtones|New Age|Healing',
+            8232 => 'Tones|Ringtones|New Age|Meditation',
+            8233 => 'Tones|Ringtones|New Age|Nature',
+            8234 => 'Tones|Ringtones|New Age|Relaxation',
+            8235 => 'Tones|Ringtones|New Age|Travel',
+            8236 => 'Tones|Ringtones|Orchestral',
+            8237 => 'Tones|Ringtones|Pop|Adult Contemporary',
+            8238 => 'Tones|Ringtones|Pop|Britpop',
+            8239 => 'Tones|Ringtones|Pop|C-Pop',
+            8240 => 'Tones|Ringtones|Pop|Cantopop/HK-Pop',
+            8241 => 'Tones|Ringtones|Pop|Indo Pop',
+            8242 => 'Tones|Ringtones|Pop|Korean Folk-Pop',
+            8243 => 'Tones|Ringtones|Pop|Malaysian Pop',
+            8244 => 'Tones|Ringtones|Pop|Mandopop',
+            8245 => 'Tones|Ringtones|Pop|Manilla Sound',
+            8246 => 'Tones|Ringtones|Pop|Oldies',
+            8247 => 'Tones|Ringtones|Pop|Original Pilipino Music',
+            8248 => 'Tones|Ringtones|Pop|Pinoy Pop',
+            8249 => 'Tones|Ringtones|Pop|Pop/Rock',
+            8250 => 'Tones|Ringtones|Pop|Soft Rock',
+            8251 => 'Tones|Ringtones|Pop|Tai-Pop',
+            8252 => 'Tones|Ringtones|Pop|Teen Pop',
+            8253 => 'Tones|Ringtones|Pop|Thai Pop',
+            8254 => 'Tones|Ringtones|R&B/Soul|Contemporary R&B',
+            8255 => 'Tones|Ringtones|R&B/Soul|Disco',
+            8256 => 'Tones|Ringtones|R&B/Soul|Doo Wop',
+            8257 => 'Tones|Ringtones|R&B/Soul|Funk',
+            8258 => 'Tones|Ringtones|R&B/Soul|Motown',
+            8259 => 'Tones|Ringtones|R&B/Soul|Neo-Soul',
+            8260 => 'Tones|Ringtones|R&B/Soul|Soul',
+            8261 => 'Tones|Ringtones|Reggae|Modern Dancehall',
+            8262 => 'Tones|Ringtones|Reggae|Dub',
+            8263 => 'Tones|Ringtones|Reggae|Roots Reggae',
+            8264 => 'Tones|Ringtones|Reggae|Ska',
+            8265 => 'Tones|Ringtones|Rock|Adult Alternative',
+            8266 => 'Tones|Ringtones|Rock|American Trad Rock',
+            8267 => 'Tones|Ringtones|Rock|Arena Rock',
+            8268 => 'Tones|Ringtones|Rock|Blues-Rock',
+            8269 => 'Tones|Ringtones|Rock|British Invasion',
+            8270 => 'Tones|Ringtones|Rock|Chinese Rock',
+            8271 => 'Tones|Ringtones|Rock|Death Metal/Black Metal',
+            8272 => 'Tones|Ringtones|Rock|Glam Rock',
+            8273 => 'Tones|Ringtones|Rock|Hair Metal',
+            8274 => 'Tones|Ringtones|Rock|Hard Rock',
+            8275 => 'Tones|Ringtones|Rock|Metal',
+            8276 => 'Tones|Ringtones|Rock|Jam Bands',
+            8277 => 'Tones|Ringtones|Rock|Korean Rock',
+            8278 => 'Tones|Ringtones|Rock|Prog-Rock/Art Rock',
+            8279 => 'Tones|Ringtones|Rock|Psychedelic',
+            8280 => 'Tones|Ringtones|Rock|Rock & Roll',
+            8281 => 'Tones|Ringtones|Rock|Rockabilly',
+            8282 => 'Tones|Ringtones|Rock|Roots Rock',
+            8283 => 'Tones|Ringtones|Rock|Singer/Songwriter',
+            8284 => 'Tones|Ringtones|Rock|Southern Rock',
+            8285 => 'Tones|Ringtones|Rock|Surf',
+            8286 => 'Tones|Ringtones|Rock|Tex-Mex',
+            8287 => 'Tones|Ringtones|Singer/Songwriter|Alternative Folk',
+            8288 => 'Tones|Ringtones|Singer/Songwriter|Contemporary Folk',
+            8289 => 'Tones|Ringtones|Singer/Songwriter|Contemporary Singer/Songwriter',
+            8290 => 'Tones|Ringtones|Singer/Songwriter|Folk-Rock',
+            8291 => 'Tones|Ringtones|Singer/Songwriter|New Acoustic',
+            8292 => 'Tones|Ringtones|Singer/Songwriter|Traditional Folk',
+            8293 => 'Tones|Ringtones|Soundtrack|Foreign Cinema',
+            8294 => 'Tones|Ringtones|Soundtrack|Musicals',
+            8295 => 'Tones|Ringtones|Soundtrack|Original Score',
+            8296 => 'Tones|Ringtones|Soundtrack|Sound Effects',
+            8297 => 'Tones|Ringtones|Soundtrack|Soundtrack',
+            8298 => 'Tones|Ringtones|Soundtrack|TV Soundtrack',
+            8299 => 'Tones|Ringtones|Vocal|Standards',
+            8300 => 'Tones|Ringtones|Vocal|Traditional Pop',
+            8301 => 'Tones|Ringtones|Vocal|Trot',
+            8302 => 'Tones|Ringtones|Jazz|Vocal Jazz',
+            8303 => 'Tones|Ringtones|Vocal|Vocal Pop',
+            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',
+            8312 => 'Tones|Ringtones|World|Calypso',
+            8313 => 'Tones|Ringtones|World|Caribbean',
+            8314 => 'Tones|Ringtones|World|Celtic',
+            8315 => 'Tones|Ringtones|World|Celtic Folk',
+            8316 => 'Tones|Ringtones|World|Contemporary Celtic',
+            8317 => 'Tones|Ringtones|World|Dangdut',
+            8318 => 'Tones|Ringtones|World|Dini',
+            8319 => 'Tones|Ringtones|World|Europe',
+            8320 => 'Tones|Ringtones|World|Fado',
+            8321 => 'Tones|Ringtones|World|Farsi',
+            8322 => 'Tones|Ringtones|World|Flamenco',
+            8323 => 'Tones|Ringtones|World|France',
+            8324 => 'Tones|Ringtones|Turkish|Halk',
+            8325 => 'Tones|Ringtones|World|Hawaii',
+            8326 => 'Tones|Ringtones|World|Iberia',
+            8327 => 'Tones|Ringtones|World|Indonesian Religious',
+            8328 => 'Tones|Ringtones|World|Israeli',
+            8329 => 'Tones|Ringtones|World|Japan',
+            8330 => 'Tones|Ringtones|World|Klezmer',
+            8331 => 'Tones|Ringtones|World|North America',
+            8332 => 'Tones|Ringtones|World|Polka',
+            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|Turkish',
+            8342 => 'Tones|Ringtones|World|Worldbeat',
+            8343 => 'Tones|Ringtones|World|Zydeco',
+            8345 => 'Tones|Ringtones|Classical|Art Song',
+            8346 => 'Tones|Ringtones|Classical|Brass & Woodwinds',
+            8347 => 'Tones|Ringtones|Classical|Solo Instrumental',
+            8348 => 'Tones|Ringtones|Classical|Contemporary Era',
+            8349 => 'Tones|Ringtones|Classical|Oratorio',
+            8350 => 'Tones|Ringtones|Classical|Cantata',
+            8351 => 'Tones|Ringtones|Classical|Electronic',
+            8352 => 'Tones|Ringtones|Classical|Sacred',
+            8353 => 'Tones|Ringtones|Classical|Guitar',
+            8354 => 'Tones|Ringtones|Classical|Piano',
+            8355 => 'Tones|Ringtones|Classical|Violin',
+            8356 => 'Tones|Ringtones|Classical|Cello',
+            8357 => 'Tones|Ringtones|Classical|Percussion',
+            8358 => 'Tones|Ringtones|Electronic|Dubstep',
+            8359 => 'Tones|Ringtones|Electronic|Bass',
+            8360 => 'Tones|Ringtones|Hip-Hop/Rap|UK Hip Hop',
+            8361 => 'Tones|Ringtones|Reggae|Lovers Rock',
+            8362 => 'Tones|Ringtones|Alternative|EMO',
+            8363 => 'Tones|Ringtones|Alternative|Pop Punk',
+            8364 => 'Tones|Ringtones|Alternative|Indie Pop',
+            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',
+            9007 => 'Books|Arts & Entertainment',
+            9008 => 'Books|Biographies & Memoirs',
+            9009 => 'Books|Business & Personal Finance',
+            9010 => 'Books|Children & Teens',
+            9012 => 'Books|Humor',
+            9015 => 'Books|History',
+            9018 => 'Books|Religion & Spirituality',
+            9019 => 'Books|Science & Nature',
+            9020 => 'Books|Sci-Fi & Fantasy',
+            9024 => 'Books|Lifestyle & Home',
+            9025 => 'Books|Self-Development',
+            9026 => 'Books|Comics & Graphic Novels',
+            9027 => 'Books|Computers & Internet',
+            9028 => 'Books|Cookbooks, Food & Wine',
+            9029 => 'Books|Professional & Technical',
+            9030 => 'Books|Parenting',
+            9031 => 'Books|Fiction & Literature',
+            9032 => 'Books|Mysteries & Thrillers',
+            9033 => 'Books|Reference',
+            9034 => 'Books|Politics & Current Events',
+            9035 => 'Books|Sports & Outdoors',
+            10001 => 'Books|Lifestyle & Home|Antiques & Collectibles',
+            10002 => 'Books|Arts & Entertainment|Art & Architecture',
+            10003 => 'Books|Religion & Spirituality|Bibles',
+            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',
+            10008 => 'Books|Business & Personal Finance|Personal Finance',
+            10009 => 'Books|Business & Personal Finance|Reference',
+            10010 => 'Books|Business & Personal Finance|Careers',
+            10011 => 'Books|Business & Personal Finance|Economics',
+            10012 => 'Books|Business & Personal Finance|Investing',
+            10013 => 'Books|Business & Personal Finance|Finance',
+            10014 => 'Books|Business & Personal Finance|Management & Leadership',
+            10015 => 'Books|Comics & Graphic Novels|Graphic Novels',
+            10016 => 'Books|Comics & Graphic Novels|Manga',
+            10017 => 'Books|Computers & Internet|Computers',
+            10018 => 'Books|Computers & Internet|Databases',
+            10019 => 'Books|Computers & Internet|Digital Media',
+            10020 => 'Books|Computers & Internet|Internet',
+            10021 => 'Books|Computers & Internet|Network',
+            10022 => 'Books|Computers & Internet|Operating Systems',
+            10023 => 'Books|Computers & Internet|Programming',
+            10024 => 'Books|Computers & Internet|Software',
+            10025 => 'Books|Computers & Internet|System Administration',
+            10026 => 'Books|Cookbooks, Food & Wine|Beverages',
+            10027 => 'Books|Cookbooks, Food & Wine|Courses & Dishes',
+            10028 => 'Books|Cookbooks, Food & Wine|Special Diet',
+            10029 => 'Books|Cookbooks, Food & Wine|Special Occasions',
+            10030 => 'Books|Cookbooks, Food & Wine|Methods',
+            10031 => 'Books|Cookbooks, Food & Wine|Reference',
+            10032 => 'Books|Cookbooks, Food & Wine|Regional & Ethnic',
+            10033 => 'Books|Cookbooks, Food & Wine|Specific Ingredients',
+            10034 => 'Books|Lifestyle & Home|Crafts & Hobbies',
+            10035 => 'Books|Professional & Technical|Design',
+            10036 => 'Books|Arts & Entertainment|Theater',
+            10037 => 'Books|Professional & Technical|Education',
+            10038 => 'Books|Nonfiction|Family & Relationships',
+            10039 => 'Books|Fiction & Literature|Action & Adventure',
+            10040 => 'Books|Fiction & Literature|African American',
+            10041 => 'Books|Fiction & Literature|Religious',
+            10042 => 'Books|Fiction & Literature|Classics',
+            10043 => 'Books|Fiction & Literature|Erotica',
+            10044 => 'Books|Sci-Fi & Fantasy|Fantasy',
+            10045 => 'Books|Fiction & Literature|Gay',
+            10046 => 'Books|Fiction & Literature|Ghost',
+            10047 => 'Books|Fiction & Literature|Historical',
+            10048 => 'Books|Fiction & Literature|Horror',
+            10049 => 'Books|Fiction & Literature|Literary',
+            10050 => 'Books|Mysteries & Thrillers|Hard-Boiled',
+            10051 => 'Books|Mysteries & Thrillers|Historical',
+            10052 => 'Books|Mysteries & Thrillers|Police Procedural',
+            10053 => 'Books|Mysteries & Thrillers|Short Stories',
+            10054 => 'Books|Mysteries & Thrillers|British Detectives',
+            10055 => 'Books|Mysteries & Thrillers|Women Sleuths',
+            10056 => 'Books|Romance|Erotic Romance',
+            10057 => 'Books|Romance|Contemporary',
+            10058 => 'Books|Romance|Paranormal',
+            10059 => 'Books|Romance|Historical',
+            10060 => 'Books|Romance|Short Stories',
+            10061 => 'Books|Romance|Suspense',
+            10062 => 'Books|Romance|Western',
+            10063 => 'Books|Sci-Fi & Fantasy|Science Fiction',
+            10064 => 'Books|Sci-Fi & Fantasy|Science Fiction & Literature',
+            10065 => 'Books|Fiction & Literature|Short Stories',
+            10066 => 'Books|Reference|Foreign Languages',
+            10067 => 'Books|Arts & Entertainment|Games',
+            10068 => 'Books|Lifestyle & Home|Gardening',
+            10069 => 'Books|Self-Development|Health & Fitness',
+            10070 => 'Books|History|Africa',
+            10071 => 'Books|History|Americas',
+            10072 => 'Books|History|Ancient',
+            10073 => 'Books|History|Asia',
+            10074 => 'Books|History|Australia & Oceania',
+            10075 => 'Books|History|Europe',
+            10076 => 'Books|History|Latin America',
+            10077 => 'Books|History|Middle East',
+            10078 => 'Books|History|Military',
+            10079 => 'Books|History|United States',
+            10080 => 'Books|History|World',
+            10081 => "Books|Children & Teens|Children's Fiction",
+            10082 => "Books|Children & Teens|Children's Nonfiction",
+            10083 => 'Books|Professional & Technical|Law',
+            10084 => 'Books|Fiction & Literature|Literary Criticism',
+            10085 => 'Books|Science & Nature|Mathematics',
+            10086 => 'Books|Professional & Technical|Medical',
+            10087 => 'Books|Arts & Entertainment|Music',
+            10088 => 'Books|Science & Nature|Nature',
+            10089 => 'Books|Arts & Entertainment|Performing Arts',
+            10090 => 'Books|Lifestyle & Home|Pets',
+            10091 => 'Books|Nonfiction|Philosophy',
+            10092 => 'Books|Arts & Entertainment|Photography',
+            10093 => 'Books|Fiction & Literature|Poetry',
+            10094 => 'Books|Self-Development|Psychology',
+            10095 => 'Books|Reference|Almanacs & Yearbooks',
+            10096 => 'Books|Reference|Atlases & Maps',
+            10097 => 'Books|Reference|Catalogs & Directories',
+            10098 => 'Books|Reference|Consumer Guides',
+            10099 => 'Books|Reference|Dictionaries & Thesauruses',
+            10100 => 'Books|Reference|Encyclopedias',
+            10101 => 'Books|Reference|Etiquette',
+            10102 => 'Books|Reference|Quotations',
+            10103 => 'Books|Reference|Words & Language',
+            10104 => 'Books|Reference|Writing',
+            10105 => 'Books|Religion & Spirituality|Bible Studies',
+            10106 => 'Books|Religion & Spirituality|Buddhism',
+            10107 => 'Books|Religion & Spirituality|Christianity',
+            10108 => 'Books|Religion & Spirituality|Hinduism',
+            10109 => 'Books|Religion & Spirituality|Islam',
+            10110 => 'Books|Religion & Spirituality|Judaism',
+            10111 => 'Books|Science & Nature|Astronomy',
+            10112 => 'Books|Science & Nature|Chemistry',
+            10113 => 'Books|Science & Nature|Earth Sciences',
+            10114 => 'Books|Science & Nature|Essays',
+            10115 => 'Books|Science & Nature|History',
+            10116 => 'Books|Science & Nature|Life Sciences',
+            10117 => 'Books|Science & Nature|Physics',
+            10118 => 'Books|Science & Nature|Reference',
+            10119 => 'Books|Self-Development|Self-Improvement',
+            10120 => 'Books|Nonfiction|Social Science',
+            10121 => 'Books|Sports & Outdoors|Baseball',
+            10122 => 'Books|Sports & Outdoors|Basketball',
+            10123 => 'Books|Sports & Outdoors|Coaching',
+            10124 => 'Books|Sports & Outdoors|Extreme Sports',
+            10125 => 'Books|Sports & Outdoors|Football',
+            10126 => 'Books|Sports & Outdoors|Golf',
+            10127 => 'Books|Sports & Outdoors|Hockey',
+            10128 => 'Books|Sports & Outdoors|Mountaineering',
+            10129 => 'Books|Sports & Outdoors|Outdoors',
+            10130 => 'Books|Sports & Outdoors|Racket Sports',
+            10131 => 'Books|Sports & Outdoors|Reference',
+            10132 => 'Books|Sports & Outdoors|Soccer',
+            10133 => 'Books|Sports & Outdoors|Training',
+            10134 => 'Books|Sports & Outdoors|Water Sports',
+            10135 => 'Books|Sports & Outdoors|Winter Sports',
+            10136 => 'Books|Reference|Study Aids',
+            10137 => 'Books|Professional & Technical|Engineering',
+            10138 => 'Books|Nonfiction|Transportation',
+            10139 => 'Books|Travel & Adventure|Africa',
+            10140 => 'Books|Travel & Adventure|Asia',
+            10141 => 'Books|Travel & Adventure|Specialty Travel',
+            10142 => 'Books|Travel & Adventure|Canada',
+            10143 => 'Books|Travel & Adventure|Caribbean',
+            10144 => 'Books|Travel & Adventure|Latin America',
+            10145 => 'Books|Travel & Adventure|Essays & Memoirs',
+            10146 => 'Books|Travel & Adventure|Europe',
+            10147 => 'Books|Travel & Adventure|Middle East',
+            10148 => 'Books|Travel & Adventure|United States',
+            10149 => 'Books|Nonfiction|True Crime',
+            11001 => 'Books|Sci-Fi & Fantasy|Fantasy|Contemporary',
+            11002 => 'Books|Sci-Fi & Fantasy|Fantasy|Epic',
+            11003 => 'Books|Sci-Fi & Fantasy|Fantasy|Historical',
+            11004 => 'Books|Sci-Fi & Fantasy|Fantasy|Paranormal',
+            11005 => 'Books|Sci-Fi & Fantasy|Fantasy|Short Stories',
+            11006 => 'Books|Sci-Fi & Fantasy|Science Fiction & Literature|Adventure',
+            11007 => 'Books|Sci-Fi & Fantasy|Science Fiction & Literature|High Tech',
+            11008 => 'Books|Sci-Fi & Fantasy|Science Fiction & Literature|Short Stories',
+            11009 => 'Books|Professional & Technical|Education|Language Arts & Disciplines',
+            11010 => 'Books|Communications & Media',
+            11011 => 'Books|Communications & Media|Broadcasting',
+            11012 => 'Books|Communications & Media|Digital Media',
+            11013 => 'Books|Communications & Media|Journalism',
+            11014 => 'Books|Communications & Media|Photojournalism',
+            11015 => 'Books|Communications & Media|Print',
+            11016 => 'Books|Communications & Media|Speech',
+            11017 => 'Books|Communications & Media|Writing',
+            11018 => 'Books|Arts & Entertainment|Art & Architecture|Urban Planning',
+            11019 => 'Books|Arts & Entertainment|Dance',
+            11020 => 'Books|Arts & Entertainment|Fashion',
+            11021 => 'Books|Arts & Entertainment|Film',
+            11022 => 'Books|Arts & Entertainment|Interior Design',
+            11023 => 'Books|Arts & Entertainment|Media Arts',
+            11024 => 'Books|Arts & Entertainment|Radio',
+            11025 => 'Books|Arts & Entertainment|TV',
+            11026 => 'Books|Arts & Entertainment|Visual Arts',
+            11027 => 'Books|Biographies & Memoirs|Arts & Entertainment',
+            11028 => 'Books|Biographies & Memoirs|Business',
+            11029 => 'Books|Biographies & Memoirs|Culinary',
+            11030 => 'Books|Biographies & Memoirs|Gay & Lesbian',
+            11031 => 'Books|Biographies & Memoirs|Historical',
+            11032 => 'Books|Biographies & Memoirs|Literary',
+            11033 => 'Books|Biographies & Memoirs|Media & Journalism',
+            11034 => 'Books|Biographies & Memoirs|Military',
+            11035 => 'Books|Biographies & Memoirs|Politics',
+            11036 => 'Books|Biographies & Memoirs|Religious',
+            11037 => 'Books|Biographies & Memoirs|Science & Technology',
+            11038 => 'Books|Biographies & Memoirs|Sports',
+            11039 => 'Books|Biographies & Memoirs|Women',
+            11040 => 'Books|Romance|New Adult',
+            11042 => 'Books|Romance|Romantic Comedy',
+            11043 => 'Books|Romance|Gay & Lesbian',
+            11044 => 'Books|Fiction & Literature|Essays',
+            11045 => 'Books|Fiction & Literature|Anthologies',
+            11046 => 'Books|Fiction & Literature|Comparative Literature',
+            11047 => 'Books|Fiction & Literature|Drama',
+            11049 => 'Books|Fiction & Literature|Fairy Tales, Myths & Fables',
+            11050 => 'Books|Fiction & Literature|Family',
+            11051 => 'Books|Comics & Graphic Novels|Manga|School Drama',
+            11052 => 'Books|Comics & Graphic Novels|Manga|Human Drama',
+            11053 => 'Books|Comics & Graphic Novels|Manga|Family Drama',
+            11054 => 'Books|Sports & Outdoors|Boxing',
+            11055 => 'Books|Sports & Outdoors|Cricket',
+            11056 => 'Books|Sports & Outdoors|Cycling',
+            11057 => 'Books|Sports & Outdoors|Equestrian',
+            11058 => 'Books|Sports & Outdoors|Martial Arts & Self Defense',
+            11059 => 'Books|Sports & Outdoors|Motor Sports',
+            11060 => 'Books|Sports & Outdoors|Rugby',
+            11061 => 'Books|Sports & Outdoors|Running',
+            11062 => 'Books|Self-Development|Diet & Nutrition',
+            11063 => 'Books|Science & Nature|Agriculture',
+            11064 => 'Books|Science & Nature|Atmosphere',
+            11065 => 'Books|Science & Nature|Biology',
+            11066 => 'Books|Science & Nature|Ecology',
+            11067 => 'Books|Science & Nature|Environment',
+            11068 => 'Books|Science & Nature|Geography',
+            11069 => 'Books|Science & Nature|Geology',
+            11070 => 'Books|Nonfiction|Social Science|Anthropology',
+            11071 => 'Books|Nonfiction|Social Science|Archaeology',
+            11072 => 'Books|Nonfiction|Social Science|Civics',
+            11073 => 'Books|Nonfiction|Social Science|Government',
+            11074 => 'Books|Nonfiction|Social Science|Social Studies',
+            11075 => 'Books|Nonfiction|Social Science|Social Welfare',
+            11076 => 'Books|Nonfiction|Social Science|Society',
+            11077 => 'Books|Nonfiction|Philosophy|Aesthetics',
+            11078 => 'Books|Nonfiction|Philosophy|Epistemology',
+            11079 => 'Books|Nonfiction|Philosophy|Ethics',
+            11080 => 'Books|Nonfiction|Philosophy|Language',
+            11081 => 'Books|Nonfiction|Philosophy|Logic',
+            11082 => 'Books|Nonfiction|Philosophy|Metaphysics',
+            11083 => 'Books|Nonfiction|Philosophy|Political',
+            11084 => 'Books|Nonfiction|Philosophy|Religion',
+            11085 => 'Books|Reference|Manuals',
+            11086 => 'Books|Kids',
+            11087 => 'Books|Kids|Animals',
+            11088 => 'Books|Kids|Basic Concepts',
+            11089 => 'Books|Kids|Basic Concepts|Alphabet',
+            11090 => 'Books|Kids|Basic Concepts|Body',
+            11091 => 'Books|Kids|Basic Concepts|Colors',
+            11092 => 'Books|Kids|Basic Concepts|Counting & Numbers',
+            11093 => 'Books|Kids|Basic Concepts|Date & Time',
+            11094 => 'Books|Kids|Basic Concepts|General',
+            11095 => 'Books|Kids|Basic Concepts|Money',
+            11096 => 'Books|Kids|Basic Concepts|Opposites',
+            11097 => 'Books|Kids|Basic Concepts|Seasons',
+            11098 => 'Books|Kids|Basic Concepts|Senses & Sensation',
+            11099 => 'Books|Kids|Basic Concepts|Size & Shape',
+            11100 => 'Books|Kids|Basic Concepts|Sounds',
+            11101 => 'Books|Kids|Basic Concepts|Words',
+            11102 => 'Books|Kids|Biography',
+            11103 => 'Books|Kids|Careers & Occupations',
+            11104 => 'Books|Kids|Computers & Technology',
+            11105 => 'Books|Kids|Cooking & Food',
+            11106 => 'Books|Kids|Arts & Entertainment',
+            11107 => 'Books|Kids|Arts & Entertainment|Art',
+            11108 => 'Books|Kids|Arts & Entertainment|Crafts',
+            11109 => 'Books|Kids|Arts & Entertainment|Music',
+            11110 => 'Books|Kids|Arts & Entertainment|Performing Arts',
+            11111 => 'Books|Kids|Family',
+            11112 => 'Books|Kids|Fiction',
+            11113 => 'Books|Kids|Fiction|Action & Adventure',
+            11114 => 'Books|Kids|Fiction|Animals',
+            11115 => 'Books|Kids|Fiction|Classics',
+            11116 => 'Books|Kids|Fiction|Comics & Graphic Novels',
+            11117 => 'Books|Kids|Fiction|Culture, Places & People',
+            11118 => 'Books|Kids|Fiction|Family & Relationships',
+            11119 => 'Books|Kids|Fiction|Fantasy',
+            11120 => 'Books|Kids|Fiction|Fairy Tales, Myths & Fables',
+            11121 => 'Books|Kids|Fiction|Favorite Characters',
+            11122 => 'Books|Kids|Fiction|Historical',
+            11123 => 'Books|Kids|Fiction|Holidays & Celebrations',
+            11124 => 'Books|Kids|Fiction|Monsters & Ghosts',
+            11125 => 'Books|Kids|Fiction|Mysteries',
+            11126 => 'Books|Kids|Fiction|Nature',
+            11127 => 'Books|Kids|Fiction|Religion',
+            11128 => 'Books|Kids|Fiction|Sci-Fi',
+            11129 => 'Books|Kids|Fiction|Social Issues',
+            11130 => 'Books|Kids|Fiction|Sports & Recreation',
+            11131 => 'Books|Kids|Fiction|Transportation',
+            11132 => 'Books|Kids|Games & Activities',
+            11133 => 'Books|Kids|General Nonfiction',
+            11134 => 'Books|Kids|Health',
+            11135 => 'Books|Kids|History',
+            11136 => 'Books|Kids|Holidays & Celebrations',
+            11137 => 'Books|Kids|Holidays & Celebrations|Birthdays',
+            11138 => 'Books|Kids|Holidays & Celebrations|Christmas & Advent',
+            11139 => 'Books|Kids|Holidays & Celebrations|Easter & Lent',
+            11140 => 'Books|Kids|Holidays & Celebrations|General',
+            11141 => 'Books|Kids|Holidays & Celebrations|Halloween',
+            11142 => 'Books|Kids|Holidays & Celebrations|Hanukkah',
+            11143 => 'Books|Kids|Holidays & Celebrations|Other',
+            11144 => 'Books|Kids|Holidays & Celebrations|Passover',
+            11145 => 'Books|Kids|Holidays & Celebrations|Patriotic Holidays',
+            11146 => 'Books|Kids|Holidays & Celebrations|Ramadan',
+            11147 => 'Books|Kids|Holidays & Celebrations|Thanksgiving',
+            11148 => "Books|Kids|Holidays & Celebrations|Valentine's Day",
+            11149 => 'Books|Kids|Humor',
+            11150 => 'Books|Kids|Humor|Jokes & Riddles',
+            11151 => 'Books|Kids|Poetry',
+            11152 => 'Books|Kids|Learning to Read',
+            11153 => 'Books|Kids|Learning to Read|Chapter Books',
+            11154 => 'Books|Kids|Learning to Read|Early Readers',
+            11155 => 'Books|Kids|Learning to Read|Intermediate Readers',
+            11156 => 'Books|Kids|Nursery Rhymes',
+            11157 => 'Books|Kids|Government',
+            11158 => 'Books|Kids|Reference',
+            11159 => 'Books|Kids|Religion',
+            11160 => 'Books|Kids|Science & Nature',
+            11161 => 'Books|Kids|Social Issues',
+            11162 => 'Books|Kids|Social Studies',
+            11163 => 'Books|Kids|Sports & Recreation',
+            11164 => 'Books|Kids|Transportation',
+            11165 => 'Books|Young Adult',
+            11166 => 'Books|Young Adult|Animals',
+            11167 => 'Books|Young Adult|Biography',
+            11168 => 'Books|Young Adult|Careers & Occupations',
+            11169 => 'Books|Young Adult|Computers & Technology',
+            11170 => 'Books|Young Adult|Cooking & Food',
+            11171 => 'Books|Young Adult|Arts & Entertainment',
+            11172 => 'Books|Young Adult|Arts & Entertainment|Art',
+            11173 => 'Books|Young Adult|Arts & Entertainment|Crafts',
+            11174 => 'Books|Young Adult|Arts & Entertainment|Music',
+            11175 => 'Books|Young Adult|Arts & Entertainment|Performing Arts',
+            11176 => 'Books|Young Adult|Family',
+            11177 => 'Books|Young Adult|Fiction',
+            11178 => 'Books|Young Adult|Fiction|Action & Adventure',
+            11179 => 'Books|Young Adult|Fiction|Animals',
+            11180 => 'Books|Young Adult|Fiction|Classics',
+            11181 => 'Books|Young Adult|Fiction|Comics & Graphic Novels',
+            11182 => 'Books|Young Adult|Fiction|Culture, Places & People',
+            11183 => 'Books|Young Adult|Fiction|Dystopian',
+            11184 => 'Books|Young Adult|Fiction|Family & Relationships',
+            11185 => 'Books|Young Adult|Fiction|Fantasy',
+            11186 => 'Books|Young Adult|Fiction|Fairy Tales, Myths & Fables',
+            11187 => 'Books|Young Adult|Fiction|Favorite Characters',
+            11188 => 'Books|Young Adult|Fiction|Historical',
+            11189 => 'Books|Young Adult|Fiction|Holidays & Celebrations',
+            11190 => 'Books|Young Adult|Fiction|Horror, Monsters & Ghosts',
+            11191 => 'Books|Young Adult|Fiction|Crime & Mystery',
+            11192 => 'Books|Young Adult|Fiction|Nature',
+            11193 => 'Books|Young Adult|Fiction|Religion',
+            11194 => 'Books|Young Adult|Fiction|Romance',
+            11195 => 'Books|Young Adult|Fiction|Sci-Fi',
+            11196 => 'Books|Young Adult|Fiction|Coming of Age',
+            11197 => 'Books|Young Adult|Fiction|Sports & Recreation',
+            11198 => 'Books|Young Adult|Fiction|Transportation',
+            11199 => 'Books|Young Adult|Games & Activities',
+            11200 => 'Books|Young Adult|General Nonfiction',
+            11201 => 'Books|Young Adult|Health',
+            11202 => 'Books|Young Adult|History',
+            11203 => 'Books|Young Adult|Holidays & Celebrations',
+            11204 => 'Books|Young Adult|Holidays & Celebrations|Birthdays',
+            11205 => 'Books|Young Adult|Holidays & Celebrations|Christmas & Advent',
+            11206 => 'Books|Young Adult|Holidays & Celebrations|Easter & Lent',
+            11207 => 'Books|Young Adult|Holidays & Celebrations|General',
+            11208 => 'Books|Young Adult|Holidays & Celebrations|Halloween',
+            11209 => 'Books|Young Adult|Holidays & Celebrations|Hanukkah',
+            11210 => 'Books|Young Adult|Holidays & Celebrations|Other',
+            11211 => 'Books|Young Adult|Holidays & Celebrations|Passover',
+            11212 => 'Books|Young Adult|Holidays & Celebrations|Patriotic Holidays',
+            11213 => 'Books|Young Adult|Holidays & Celebrations|Ramadan',
+            11214 => 'Books|Young Adult|Holidays & Celebrations|Thanksgiving',
+            11215 => "Books|Young Adult|Holidays & Celebrations|Valentine's Day",
+            11216 => 'Books|Young Adult|Humor',
+            11217 => 'Books|Young Adult|Humor|Jokes & Riddles',
+            11218 => 'Books|Young Adult|Poetry',
+            11219 => 'Books|Young Adult|Politics & Government',
+            11220 => 'Books|Young Adult|Reference',
+            11221 => 'Books|Young Adult|Religion',
+            11222 => 'Books|Young Adult|Science & Nature',
+            11223 => 'Books|Young Adult|Coming of Age',
+            11224 => 'Books|Young Adult|Social Studies',
+            11225 => 'Books|Young Adult|Sports & Recreation',
+            11226 => 'Books|Young Adult|Transportation',
+            11227 => 'Books|Communications & Media',
+            11228 => 'Books|Military & Warfare',
+            11229 => 'Books|Romance|Inspirational',
+            11231 => 'Books|Romance|Holiday',
+            11232 => 'Books|Romance|Wholesome',
+            11233 => 'Books|Romance|Military',
+            11234 => 'Books|Arts & Entertainment|Art History',
+            11236 => 'Books|Arts & Entertainment|Design',
+            11243 => 'Books|Business & Personal Finance|Accounting',
+            11244 => 'Books|Business & Personal Finance|Hospitality',
+            11245 => 'Books|Business & Personal Finance|Real Estate',
+            11246 => 'Books|Humor|Jokes & Riddles',
+            11247 => 'Books|Religion & Spirituality|Comparative Religion',
+            11255 => 'Books|Cookbooks, Food & Wine|Culinary Arts',
+            11259 => 'Books|Mysteries & Thrillers|Cozy',
+            11260 => 'Books|Politics & Current Events|Current Events',
+            11261 => 'Books|Politics & Current Events|Foreign Policy & International Relations',
+            11262 => 'Books|Politics & Current Events|Local Government',
+            11263 => 'Books|Politics & Current Events|National Government',
+            11264 => 'Books|Politics & Current Events|Political Science',
+            11265 => 'Books|Politics & Current Events|Public Administration',
+            11266 => 'Books|Politics & Current Events|World Affairs',
+            11273 => 'Books|Nonfiction|Family & Relationships|Family & Childcare',
+            11274 => 'Books|Nonfiction|Family & Relationships|Love & Romance',
+            11275 => 'Books|Sci-Fi & Fantasy|Fantasy|Urban',
+            11276 => 'Books|Reference|Foreign Languages|Arabic',
+            11277 => 'Books|Reference|Foreign Languages|Bilingual Editions',
+            11278 => 'Books|Reference|Foreign Languages|African Languages',
+            11279 => 'Books|Reference|Foreign Languages|Ancient Languages',
+            11280 => 'Books|Reference|Foreign Languages|Chinese',
+            11281 => 'Books|Reference|Foreign Languages|English',
+            11282 => 'Books|Reference|Foreign Languages|French',
+            11283 => 'Books|Reference|Foreign Languages|German',
+            11284 => 'Books|Reference|Foreign Languages|Hebrew',
+            11285 => 'Books|Reference|Foreign Languages|Hindi',
+            11286 => 'Books|Reference|Foreign Languages|Italian',
+            11287 => 'Books|Reference|Foreign Languages|Japanese',
+            11288 => 'Books|Reference|Foreign Languages|Korean',
+            11289 => 'Books|Reference|Foreign Languages|Linguistics',
+            11290 => 'Books|Reference|Foreign Languages|Other Languages',
+            11291 => 'Books|Reference|Foreign Languages|Portuguese',
+            11292 => 'Books|Reference|Foreign Languages|Russian',
+            11293 => 'Books|Reference|Foreign Languages|Spanish',
+            11294 => 'Books|Reference|Foreign Languages|Speech Pathology',
+            11295 => 'Books|Science & Nature|Mathematics|Advanced Mathematics',
+            11296 => 'Books|Science & Nature|Mathematics|Algebra',
+            11297 => 'Books|Science & Nature|Mathematics|Arithmetic',
+            11298 => 'Books|Science & Nature|Mathematics|Calculus',
+            11299 => 'Books|Science & Nature|Mathematics|Geometry',
+            11300 => 'Books|Science & Nature|Mathematics|Statistics',
+            11301 => 'Books|Professional & Technical|Medical|Veterinary',
+            11302 => 'Books|Professional & Technical|Medical|Neuroscience',
+            11303 => 'Books|Professional & Technical|Medical|Immunology',
+            11304 => 'Books|Professional & Technical|Medical|Nursing',
+            11305 => 'Books|Professional & Technical|Medical|Pharmacology & Toxicology',
+            11306 => 'Books|Professional & Technical|Medical|Anatomy & Physiology',
+            11307 => 'Books|Professional & Technical|Medical|Dentistry',
+            11308 => 'Books|Professional & Technical|Medical|Emergency Medicine',
+            11309 => 'Books|Professional & Technical|Medical|Genetics',
+            11310 => 'Books|Professional & Technical|Medical|Psychiatry',
+            11311 => 'Books|Professional & Technical|Medical|Radiology',
+            11312 => 'Books|Professional & Technical|Medical|Alternative Medicine',
+            11317 => 'Books|Nonfiction|Philosophy|Political Philosophy',
+            11319 => 'Books|Nonfiction|Philosophy|Philosophy of Language',
+            11320 => 'Books|Nonfiction|Philosophy|Philosophy of Religion',
+            11327 => 'Books|Nonfiction|Social Science|Sociology',
+            11329 => 'Books|Professional & Technical|Engineering|Aeronautics',
+            11330 => 'Books|Professional & Technical|Engineering|Chemical & Petroleum Engineering',
+            11331 => 'Books|Professional & Technical|Engineering|Civil Engineering',
+            11332 => 'Books|Professional & Technical|Engineering|Computer Science',
+            11333 => 'Books|Professional & Technical|Engineering|Electrical Engineering',
+            11334 => 'Books|Professional & Technical|Engineering|Environmental Engineering',
+            11335 => 'Books|Professional & Technical|Engineering|Mechanical Engineering',
+            11336 => 'Books|Professional & Technical|Engineering|Power Resources',
+            11337 => 'Books|Comics & Graphic Novels|Manga|Boys',
+            11338 => 'Books|Comics & Graphic Novels|Manga|Men',
+            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',
+            12004 => 'Mac App Store|Entertainment',
+            12005 => 'Mac App Store|Finance',
+            12006 => 'Mac App Store|Games',
+            12007 => 'Mac App Store|Health & Fitness',
+            12008 => 'Mac App Store|Lifestyle',
+            12010 => 'Mac App Store|Medical',
+            12011 => 'Mac App Store|Music',
+            12012 => 'Mac App Store|News',
+            12013 => 'Mac App Store|Photography',
+            12014 => 'Mac App Store|Productivity',
+            12015 => 'Mac App Store|Reference',
+            12016 => 'Mac App Store|Social Networking',
+            12017 => 'Mac App Store|Sports',
+            12018 => 'Mac App Store|Travel',
+            12019 => 'Mac App Store|Utilities',
+            12020 => 'Mac App Store|Video',
+            12021 => 'Mac App Store|Weather',
+            12022 => 'Mac App Store|Graphics & Design',
+            12201 => 'Mac App Store|Games|Action',
+            12202 => 'Mac App Store|Games|Adventure',
+            12203 => 'Mac App Store|Games|Casual',
+            12204 => 'Mac App Store|Games|Board',
+            12205 => 'Mac App Store|Games|Card',
+            12206 => 'Mac App Store|Games|Casino',
+            12207 => 'Mac App Store|Games|Dice',
+            12208 => 'Mac App Store|Games|Educational',
+            12209 => 'Mac App Store|Games|Family',
+            12210 => 'Mac App Store|Games|Kids',
+            12211 => 'Mac App Store|Games|Music',
+            12212 => 'Mac App Store|Games|Puzzle',
+            12213 => 'Mac App Store|Games|Racing',
+            12214 => 'Mac App Store|Games|Role Playing',
+            12215 => 'Mac App Store|Games|Simulation',
+            12216 => 'Mac App Store|Games|Sports',
+            12217 => 'Mac App Store|Games|Strategy',
+            12218 => 'Mac App Store|Games|Trivia',
+            12219 => 'Mac App Store|Games|Word',
+            13001 => 'App Store|Magazines & Newspapers|News & Politics',
+            13002 => 'App Store|Magazines & Newspapers|Fashion & Style',
+            13003 => 'App Store|Magazines & Newspapers|Home & Garden',
+            13004 => 'App Store|Magazines & Newspapers|Outdoors & Nature',
+            13005 => 'App Store|Magazines & Newspapers|Sports & Leisure',
+            13006 => 'App Store|Magazines & Newspapers|Automotive',
+            13007 => 'App Store|Magazines & Newspapers|Arts & Photography',
+            13008 => 'App Store|Magazines & Newspapers|Brides & Weddings',
+            13009 => 'App Store|Magazines & Newspapers|Business & Investing',
+            13010 => "App Store|Magazines & Newspapers|Children's Magazines",
+            13011 => 'App Store|Magazines & Newspapers|Computers & Internet',
+            13012 => 'App Store|Magazines & Newspapers|Cooking, Food & Drink',
+            13013 => 'App Store|Magazines & Newspapers|Crafts & Hobbies',
+            13014 => 'App Store|Magazines & Newspapers|Electronics & Audio',
+            13015 => 'App Store|Magazines & Newspapers|Entertainment',
+            13017 => 'App Store|Magazines & Newspapers|Health, Mind & Body',
+            13018 => 'App Store|Magazines & Newspapers|History',
+            13019 => 'App Store|Magazines & Newspapers|Literary Magazines & Journals',
+            13020 => "App Store|Magazines & Newspapers|Men's Interest",
+            13021 => 'App Store|Magazines & Newspapers|Movies & Music',
+            13023 => 'App Store|Magazines & Newspapers|Parenting & Family',
+            13024 => 'App Store|Magazines & Newspapers|Pets',
+            13025 => 'App Store|Magazines & Newspapers|Professional & Trade',
+            13026 => 'App Store|Magazines & Newspapers|Regional News',
+            13027 => 'App Store|Magazines & Newspapers|Science',
+            13028 => 'App Store|Magazines & Newspapers|Teens',
+            13029 => 'App Store|Magazines & Newspapers|Travel & Regional',
+            13030 => "App Store|Magazines & Newspapers|Women's Interest",
+            15000 => 'Textbooks|Arts & Entertainment',
+            15001 => 'Textbooks|Arts & Entertainment|Art & Architecture',
+            15002 => 'Textbooks|Arts & Entertainment|Art & Architecture|Urban Planning',
+            15003 => 'Textbooks|Arts & Entertainment|Art History',
+            15004 => 'Textbooks|Arts & Entertainment|Dance',
+            15005 => 'Textbooks|Arts & Entertainment|Design',
+            15006 => 'Textbooks|Arts & Entertainment|Fashion',
+            15007 => 'Textbooks|Arts & Entertainment|Film',
+            15008 => 'Textbooks|Arts & Entertainment|Games',
+            15009 => 'Textbooks|Arts & Entertainment|Interior Design',
+            15010 => 'Textbooks|Arts & Entertainment|Media Arts',
+            15011 => 'Textbooks|Arts & Entertainment|Music',
+            15012 => 'Textbooks|Arts & Entertainment|Performing Arts',
+            15013 => 'Textbooks|Arts & Entertainment|Photography',
+            15014 => 'Textbooks|Arts & Entertainment|Theater',
+            15015 => 'Textbooks|Arts & Entertainment|TV',
+            15016 => 'Textbooks|Arts & Entertainment|Visual Arts',
+            15017 => 'Textbooks|Biographies & Memoirs',
+            15018 => 'Textbooks|Business & Personal Finance',
+            15019 => 'Textbooks|Business & Personal Finance|Accounting',
+            15020 => 'Textbooks|Business & Personal Finance|Careers',
+            15021 => 'Textbooks|Business & Personal Finance|Economics',
+            15022 => 'Textbooks|Business & Personal Finance|Finance',
+            15023 => 'Textbooks|Business & Personal Finance|Hospitality',
+            15024 => 'Textbooks|Business & Personal Finance|Industries & Professions',
+            15025 => 'Textbooks|Business & Personal Finance|Investing',
+            15026 => 'Textbooks|Business & Personal Finance|Management & Leadership',
+            15027 => 'Textbooks|Business & Personal Finance|Marketing & Sales',
+            15028 => 'Textbooks|Business & Personal Finance|Personal Finance',
+            15029 => 'Textbooks|Business & Personal Finance|Real Estate',
+            15030 => 'Textbooks|Business & Personal Finance|Reference',
+            15031 => 'Textbooks|Business & Personal Finance|Small Business & Entrepreneurship',
+            15032 => 'Textbooks|Children & Teens',
+            15033 => 'Textbooks|Children & Teens|Fiction',
+            15034 => 'Textbooks|Children & Teens|Nonfiction',
+            15035 => 'Textbooks|Comics & Graphic Novels',
+            15036 => 'Textbooks|Comics & Graphic Novels|Graphic Novels',
+            15037 => 'Textbooks|Comics & Graphic Novels|Manga',
+            15038 => 'Textbooks|Communications & Media',
+            15039 => 'Textbooks|Communications & Media|Broadcasting',
+            15040 => 'Textbooks|Communications & Media|Digital Media',
+            15041 => 'Textbooks|Communications & Media|Journalism',
+            15042 => 'Textbooks|Communications & Media|Photojournalism',
+            15043 => 'Textbooks|Communications & Media|Print',
+            15044 => 'Textbooks|Communications & Media|Speech',
+            15045 => 'Textbooks|Communications & Media|Writing',
+            15046 => 'Textbooks|Computers & Internet',
+            15047 => 'Textbooks|Computers & Internet|Computers',
+            15048 => 'Textbooks|Computers & Internet|Databases',
+            15049 => 'Textbooks|Computers & Internet|Digital Media',
+            15050 => 'Textbooks|Computers & Internet|Internet',
+            15051 => 'Textbooks|Computers & Internet|Network',
+            15052 => 'Textbooks|Computers & Internet|Operating Systems',
+            15053 => 'Textbooks|Computers & Internet|Programming',
+            15054 => 'Textbooks|Computers & Internet|Software',
+            15055 => 'Textbooks|Computers & Internet|System Administration',
+            15056 => 'Textbooks|Cookbooks, Food & Wine',
+            15057 => 'Textbooks|Cookbooks, Food & Wine|Beverages',
+            15058 => 'Textbooks|Cookbooks, Food & Wine|Courses & Dishes',
+            15059 => 'Textbooks|Cookbooks, Food & Wine|Culinary Arts',
+            15060 => 'Textbooks|Cookbooks, Food & Wine|Methods',
+            15061 => 'Textbooks|Cookbooks, Food & Wine|Reference',
+            15062 => 'Textbooks|Cookbooks, Food & Wine|Regional & Ethnic',
+            15063 => 'Textbooks|Cookbooks, Food & Wine|Special Diet',
+            15064 => 'Textbooks|Cookbooks, Food & Wine|Special Occasions',
+            15065 => 'Textbooks|Cookbooks, Food & Wine|Specific Ingredients',
+            15066 => 'Textbooks|Engineering',
+            15067 => 'Textbooks|Engineering|Aeronautics',
+            15068 => 'Textbooks|Engineering|Chemical & Petroleum Engineering',
+            15069 => 'Textbooks|Engineering|Civil Engineering',
+            15070 => 'Textbooks|Engineering|Computer Science',
+            15071 => 'Textbooks|Engineering|Electrical Engineering',
+            15072 => 'Textbooks|Engineering|Environmental Engineering',
+            15073 => 'Textbooks|Engineering|Mechanical Engineering',
+            15074 => 'Textbooks|Engineering|Power Resources',
+            15075 => 'Textbooks|Fiction & Literature',
+            15076 => 'Textbooks|Fiction & Literature|Latino',
+            15077 => 'Textbooks|Fiction & Literature|Action & Adventure',
+            15078 => 'Textbooks|Fiction & Literature|African American',
+            15079 => 'Textbooks|Fiction & Literature|Anthologies',
+            15080 => 'Textbooks|Fiction & Literature|Classics',
+            15081 => 'Textbooks|Fiction & Literature|Comparative Literature',
+            15082 => 'Textbooks|Fiction & Literature|Erotica',
+            15083 => 'Textbooks|Fiction & Literature|Gay',
+            15084 => 'Textbooks|Fiction & Literature|Ghost',
+            15085 => 'Textbooks|Fiction & Literature|Historical',
+            15086 => 'Textbooks|Fiction & Literature|Horror',
+            15087 => 'Textbooks|Fiction & Literature|Literary',
+            15088 => 'Textbooks|Fiction & Literature|Literary Criticism',
+            15089 => 'Textbooks|Fiction & Literature|Poetry',
+            15090 => 'Textbooks|Fiction & Literature|Religious',
+            15091 => 'Textbooks|Fiction & Literature|Short Stories',
+            15092 => 'Textbooks|Health, Mind & Body',
+            15093 => 'Textbooks|Health, Mind & Body|Fitness',
+            15094 => 'Textbooks|Health, Mind & Body|Self-Improvement',
+            15095 => 'Textbooks|History',
+            15096 => 'Textbooks|History|Africa',
+            15097 => 'Textbooks|History|Americas',
+            15098 => 'Textbooks|History|Americas|Canada',
+            15099 => 'Textbooks|History|Americas|Latin America',
+            15100 => 'Textbooks|History|Americas|United States',
+            15101 => 'Textbooks|History|Ancient',
+            15102 => 'Textbooks|History|Asia',
+            15103 => 'Textbooks|History|Australia & Oceania',
+            15104 => 'Textbooks|History|Europe',
+            15105 => 'Textbooks|History|Middle East',
+            15106 => 'Textbooks|History|Military',
+            15107 => 'Textbooks|History|World',
+            15108 => 'Textbooks|Humor',
+            15109 => 'Textbooks|Language Studies',
+            15110 => 'Textbooks|Language Studies|African Languages',
+            15111 => 'Textbooks|Language Studies|Ancient Languages',
+            15112 => 'Textbooks|Language Studies|Arabic',
+            15113 => 'Textbooks|Language Studies|Bilingual Editions',
+            15114 => 'Textbooks|Language Studies|Chinese',
+            15115 => 'Textbooks|Language Studies|English',
+            15116 => 'Textbooks|Language Studies|French',
+            15117 => 'Textbooks|Language Studies|German',
+            15118 => 'Textbooks|Language Studies|Hebrew',
+            15119 => 'Textbooks|Language Studies|Hindi',
+            15120 => 'Textbooks|Language Studies|Indigenous Languages',
+            15121 => 'Textbooks|Language Studies|Italian',
+            15122 => 'Textbooks|Language Studies|Japanese',
+            15123 => 'Textbooks|Language Studies|Korean',
+            15124 => 'Textbooks|Language Studies|Linguistics',
+            15125 => 'Textbooks|Language Studies|Other Language',
+            15126 => 'Textbooks|Language Studies|Portuguese',
+            15127 => 'Textbooks|Language Studies|Russian',
+            15128 => 'Textbooks|Language Studies|Spanish',
+            15129 => 'Textbooks|Language Studies|Speech Pathology',
+            15130 => 'Textbooks|Lifestyle & Home',
+            15131 => 'Textbooks|Lifestyle & Home|Antiques & Collectibles',
+            15132 => 'Textbooks|Lifestyle & Home|Crafts & Hobbies',
+            15133 => 'Textbooks|Lifestyle & Home|Gardening',
+            15134 => 'Textbooks|Lifestyle & Home|Pets',
+            15135 => 'Textbooks|Mathematics',
+            15136 => 'Textbooks|Mathematics|Advanced Mathematics',
+            15137 => 'Textbooks|Mathematics|Algebra',
+            15138 => 'Textbooks|Mathematics|Arithmetic',
+            15139 => 'Textbooks|Mathematics|Calculus',
+            15140 => 'Textbooks|Mathematics|Geometry',
+            15141 => 'Textbooks|Mathematics|Statistics',
+            15142 => 'Textbooks|Medicine',
+            15143 => 'Textbooks|Medicine|Anatomy & Physiology',
+            15144 => 'Textbooks|Medicine|Dentistry',
+            15145 => 'Textbooks|Medicine|Emergency Medicine',
+            15146 => 'Textbooks|Medicine|Genetics',
+            15147 => 'Textbooks|Medicine|Immunology',
+            15148 => 'Textbooks|Medicine|Neuroscience',
+            15149 => 'Textbooks|Medicine|Nursing',
+            15150 => 'Textbooks|Medicine|Pharmacology & Toxicology',
+            15151 => 'Textbooks|Medicine|Psychiatry',
+            15152 => 'Textbooks|Medicine|Psychology',
+            15153 => 'Textbooks|Medicine|Radiology',
+            15154 => 'Textbooks|Medicine|Veterinary',
+            15155 => 'Textbooks|Mysteries & Thrillers',
+            15156 => 'Textbooks|Mysteries & Thrillers|British Detectives',
+            15157 => 'Textbooks|Mysteries & Thrillers|Hard-Boiled',
+            15158 => 'Textbooks|Mysteries & Thrillers|Historical',
+            15159 => 'Textbooks|Mysteries & Thrillers|Police Procedural',
+            15160 => 'Textbooks|Mysteries & Thrillers|Short Stories',
+            15161 => 'Textbooks|Mysteries & Thrillers|Women Sleuths',
+            15162 => 'Textbooks|Nonfiction',
+            15163 => 'Textbooks|Nonfiction|Family & Relationships',
+            15164 => 'Textbooks|Nonfiction|Transportation',
+            15165 => 'Textbooks|Nonfiction|True Crime',
+            15166 => 'Textbooks|Parenting',
+            15167 => 'Textbooks|Philosophy',
+            15168 => 'Textbooks|Philosophy|Aesthetics',
+            15169 => 'Textbooks|Philosophy|Epistemology',
+            15170 => 'Textbooks|Philosophy|Ethics',
+            15171 => 'Textbooks|Philosophy|Philosophy of Language',
+            15172 => 'Textbooks|Philosophy|Logic',
+            15173 => 'Textbooks|Philosophy|Metaphysics',
+            15174 => 'Textbooks|Philosophy|Political Philosophy',
+            15175 => 'Textbooks|Philosophy|Philosophy of Religion',
+            15176 => 'Textbooks|Politics & Current Events',
+            15177 => 'Textbooks|Politics & Current Events|Current Events',
+            15178 => 'Textbooks|Politics & Current Events|Foreign Policy & International Relations',
+            15179 => 'Textbooks|Politics & Current Events|Local Governments',
+            15180 => 'Textbooks|Politics & Current Events|National Governments',
+            15181 => 'Textbooks|Politics & Current Events|Political Science',
+            15182 => 'Textbooks|Politics & Current Events|Public Administration',
+            15183 => 'Textbooks|Politics & Current Events|World Affairs',
+            15184 => 'Textbooks|Professional & Technical',
+            15185 => 'Textbooks|Professional & Technical|Design',
+            15186 => 'Textbooks|Professional & Technical|Language Arts & Disciplines',
+            15187 => 'Textbooks|Professional & Technical|Engineering',
+            15188 => 'Textbooks|Professional & Technical|Law',
+            15189 => 'Textbooks|Professional & Technical|Medical',
+            15190 => 'Textbooks|Reference',
+            15191 => 'Textbooks|Reference|Almanacs & Yearbooks',
+            15192 => 'Textbooks|Reference|Atlases & Maps',
+            15193 => 'Textbooks|Reference|Catalogs & Directories',
+            15194 => 'Textbooks|Reference|Consumer Guides',
+            15195 => 'Textbooks|Reference|Dictionaries & Thesauruses',
+            15196 => 'Textbooks|Reference|Encyclopedias',
+            15197 => 'Textbooks|Reference|Etiquette',
+            15198 => 'Textbooks|Reference|Quotations',
+            15199 => 'Textbooks|Reference|Study Aids',
+            15200 => 'Textbooks|Reference|Words & Language',
+            15201 => 'Textbooks|Reference|Writing',
+            15202 => 'Textbooks|Religion & Spirituality',
+            15203 => 'Textbooks|Religion & Spirituality|Bible Studies',
+            15204 => 'Textbooks|Religion & Spirituality|Bibles',
+            15205 => 'Textbooks|Religion & Spirituality|Buddhism',
+            15206 => 'Textbooks|Religion & Spirituality|Christianity',
+            15207 => 'Textbooks|Religion & Spirituality|Comparative Religion',
+            15208 => 'Textbooks|Religion & Spirituality|Hinduism',
+            15209 => 'Textbooks|Religion & Spirituality|Islam',
+            15210 => 'Textbooks|Religion & Spirituality|Judaism',
+            15211 => 'Textbooks|Religion & Spirituality|Spirituality',
+            15212 => 'Textbooks|Romance',
+            15213 => 'Textbooks|Romance|Contemporary',
+            15214 => 'Textbooks|Romance|Erotic Romance',
+            15215 => 'Textbooks|Romance|Paranormal',
+            15216 => 'Textbooks|Romance|Historical',
+            15217 => 'Textbooks|Romance|Short Stories',
+            15218 => 'Textbooks|Romance|Suspense',
+            15219 => 'Textbooks|Romance|Western',
+            15220 => 'Textbooks|Sci-Fi & Fantasy',
+            15221 => 'Textbooks|Sci-Fi & Fantasy|Fantasy',
+            15222 => 'Textbooks|Sci-Fi & Fantasy|Fantasy|Contemporary',
+            15223 => 'Textbooks|Sci-Fi & Fantasy|Fantasy|Epic',
+            15224 => 'Textbooks|Sci-Fi & Fantasy|Fantasy|Historical',
+            15225 => 'Textbooks|Sci-Fi & Fantasy|Fantasy|Paranormal',
+            15226 => 'Textbooks|Sci-Fi & Fantasy|Fantasy|Short Stories',
+            15227 => 'Textbooks|Sci-Fi & Fantasy|Science Fiction',
+            15228 => 'Textbooks|Sci-Fi & Fantasy|Science Fiction & Literature',
+            15229 => 'Textbooks|Sci-Fi & Fantasy|Science Fiction & Literature|Adventure',
+            15230 => 'Textbooks|Sci-Fi & Fantasy|Science Fiction & Literature|High Tech',
+            15231 => 'Textbooks|Sci-Fi & Fantasy|Science Fiction & Literature|Short Stories',
+            15232 => 'Textbooks|Science & Nature',
+            15233 => 'Textbooks|Science & Nature|Agriculture',
+            15234 => 'Textbooks|Science & Nature|Astronomy',
+            15235 => 'Textbooks|Science & Nature|Atmosphere',
+            15236 => 'Textbooks|Science & Nature|Biology',
+            15237 => 'Textbooks|Science & Nature|Chemistry',
+            15238 => 'Textbooks|Science & Nature|Earth Sciences',
+            15239 => 'Textbooks|Science & Nature|Ecology',
+            15240 => 'Textbooks|Science & Nature|Environment',
+            15241 => 'Textbooks|Science & Nature|Essays',
+            15242 => 'Textbooks|Science & Nature|Geography',
+            15243 => 'Textbooks|Science & Nature|Geology',
+            15244 => 'Textbooks|Science & Nature|History',
+            15245 => 'Textbooks|Science & Nature|Life Sciences',
+            15246 => 'Textbooks|Science & Nature|Nature',
+            15247 => 'Textbooks|Science & Nature|Physics',
+            15248 => 'Textbooks|Science & Nature|Reference',
+            15249 => 'Textbooks|Social Science',
+            15250 => 'Textbooks|Social Science|Anthropology',
+            15251 => 'Textbooks|Social Science|Archaeology',
+            15252 => 'Textbooks|Social Science|Civics',
+            15253 => 'Textbooks|Social Science|Government',
+            15254 => 'Textbooks|Social Science|Social Studies',
+            15255 => 'Textbooks|Social Science|Social Welfare',
+            15256 => 'Textbooks|Social Science|Society',
+            15257 => 'Textbooks|Social Science|Society|African Studies',
+            15258 => 'Textbooks|Social Science|Society|American Studies',
+            15259 => 'Textbooks|Social Science|Society|Asia Pacific Studies',
+            15260 => 'Textbooks|Social Science|Society|Cross-Cultural Studies',
+            15261 => 'Textbooks|Social Science|Society|European Studies',
+            15262 => 'Textbooks|Social Science|Society|Immigration & Emigration',
+            15263 => 'Textbooks|Social Science|Society|Indigenous Studies',
+            15264 => 'Textbooks|Social Science|Society|Latin & Caribbean Studies',
+            15265 => 'Textbooks|Social Science|Society|Middle Eastern Studies',
+            15266 => 'Textbooks|Social Science|Society|Race & Ethnicity Studies',
+            15267 => 'Textbooks|Social Science|Society|Sexuality Studies',
+            15268 => "Textbooks|Social Science|Society|Women's Studies",
+            15269 => 'Textbooks|Social Science|Sociology',
+            15270 => 'Textbooks|Sports & Outdoors',
+            15271 => 'Textbooks|Sports & Outdoors|Baseball',
+            15272 => 'Textbooks|Sports & Outdoors|Basketball',
+            15273 => 'Textbooks|Sports & Outdoors|Coaching',
+            15274 => 'Textbooks|Sports & Outdoors|Equestrian',
+            15275 => 'Textbooks|Sports & Outdoors|Extreme Sports',
+            15276 => 'Textbooks|Sports & Outdoors|Football',
+            15277 => 'Textbooks|Sports & Outdoors|Golf',
+            15278 => 'Textbooks|Sports & Outdoors|Hockey',
+            15279 => 'Textbooks|Sports & Outdoors|Motor Sports',
+            15280 => 'Textbooks|Sports & Outdoors|Mountaineering',
+            15281 => 'Textbooks|Sports & Outdoors|Outdoors',
+            15282 => 'Textbooks|Sports & Outdoors|Racket Sports',
+            15283 => 'Textbooks|Sports & Outdoors|Reference',
+            15284 => 'Textbooks|Sports & Outdoors|Soccer',
+            15285 => 'Textbooks|Sports & Outdoors|Training',
+            15286 => 'Textbooks|Sports & Outdoors|Water Sports',
+            15287 => 'Textbooks|Sports & Outdoors|Winter Sports',
+            15288 => 'Textbooks|Teaching & Learning',
+            15289 => 'Textbooks|Teaching & Learning|Adult Education',
+            15290 => 'Textbooks|Teaching & Learning|Curriculum & Teaching',
+            15291 => 'Textbooks|Teaching & Learning|Educational Leadership',
+            15292 => 'Textbooks|Teaching & Learning|Educational Technology',
+            15293 => 'Textbooks|Teaching & Learning|Family & Childcare',
+            15294 => 'Textbooks|Teaching & Learning|Information & Library Science',
+            15295 => 'Textbooks|Teaching & Learning|Learning Resources',
+            15296 => 'Textbooks|Teaching & Learning|Psychology & Research',
+            15297 => 'Textbooks|Teaching & Learning|Special Education',
+            15298 => 'Textbooks|Travel & Adventure',
+            15299 => 'Textbooks|Travel & Adventure|Africa',
+            15300 => 'Textbooks|Travel & Adventure|Americas',
+            15301 => 'Textbooks|Travel & Adventure|Americas|Canada',
+            15302 => 'Textbooks|Travel & Adventure|Americas|Latin America',
+            15303 => 'Textbooks|Travel & Adventure|Americas|United States',
+            15304 => 'Textbooks|Travel & Adventure|Asia',
+            15305 => 'Textbooks|Travel & Adventure|Caribbean',
+            15306 => 'Textbooks|Travel & Adventure|Essays & Memoirs',
+            15307 => 'Textbooks|Travel & Adventure|Europe',
+            15308 => 'Textbooks|Travel & Adventure|Middle East',
+            15309 => 'Textbooks|Travel & Adventure|Oceania',
+            15310 => 'Textbooks|Travel & Adventure|Specialty Travel',
+            15311 => 'Textbooks|Comics & Graphic Novels|Comics',
+            15312 => 'Textbooks|Reference|Manuals',
+            16001 => 'App Store|Stickers|Emoji & Expressions',
+            16003 => 'App Store|Stickers|Animals & Nature',
+            16005 => 'App Store|Stickers|Art',
+            16006 => 'App Store|Stickers|Celebrations',
+            16007 => 'App Store|Stickers|Celebrities',
+            16008 => 'App Store|Stickers|Comics & Cartoons',
+            16009 => 'App Store|Stickers|Eating & Drinking',
+            16010 => 'App Store|Stickers|Gaming',
+            16014 => 'App Store|Stickers|Movies & TV',
+            16015 => 'App Store|Stickers|Music',
+            16017 => 'App Store|Stickers|People',
+            16019 => 'App Store|Stickers|Places & Objects',
+            16021 => 'App Store|Stickers|Sports & Activities',
+            16025 => 'App Store|Stickers|Kids & Family',
+            16026 => 'App Store|Stickers|Fashion',
+            100000 => 'Music|Christian & Gospel',
+            100001 => 'Music|Classical|Art Song',
+            100002 => 'Music|Classical|Brass & Woodwinds',
+            100003 => 'Music|Classical|Solo Instrumental',
+            100004 => 'Music|Classical|Contemporary Era',
+            100005 => 'Music|Classical|Oratorio',
+            100006 => 'Music|Classical|Cantata',
+            100007 => 'Music|Classical|Electronic',
+            100008 => 'Music|Classical|Sacred',
+            100009 => 'Music|Classical|Guitar',
+            100010 => 'Music|Classical|Piano',
+            100011 => 'Music|Classical|Violin',
+            100012 => 'Music|Classical|Cello',
+            100013 => 'Music|Classical|Percussion',
+            100014 => 'Music|Electronic|Dubstep',
+            100015 => 'Music|Electronic|Bass',
+            100016 => 'Music|Hip-Hop/Rap|UK Hip-Hop',
+            100017 => 'Music|Reggae|Lovers Rock',
+            100018 => 'Music|Alternative|EMO',
+            100019 => 'Music|Alternative|Pop Punk',
+            100020 => 'Music|Alternative|Indie Pop',
+            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 & 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',
+            40000012 => 'iTunes U|Engineering|Computer Science',
+            40000013 => 'iTunes U|Engineering|Electrical Engineering',
+            40000014 => 'iTunes U|Engineering|Environmental Engineering',
+            40000015 => 'iTunes U|Engineering|Mechanical Engineering',
+            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',
+            40000029 => 'iTunes U|Health & Medicine|Dentistry',
+            40000030 => 'iTunes U|Health & Medicine|Diet & Nutrition',
+            40000031 => 'iTunes U|Health & Medicine|Emergency Medicine',
+            40000032 => 'iTunes U|Health & Medicine|Genetics',
+            40000033 => 'iTunes U|Health & Medicine|Gerontology',
+            40000034 => 'iTunes U|Health & Medicine|Health & Exercise Science',
+            40000035 => 'iTunes U|Health & Medicine|Immunology',
+            40000036 => 'iTunes U|Health & Medicine|Neuroscience',
+            40000037 => 'iTunes U|Health & Medicine|Pharmacology & Toxicology',
+            40000038 => 'iTunes U|Health & Medicine|Psychiatry',
+            40000039 => 'iTunes U|Health & Medicine|Global Health',
+            40000040 => 'iTunes U|Health & Medicine|Radiology',
+            40000041 => 'iTunes U|History',
+            40000042 => 'iTunes U|History|Ancient History',
+            40000043 => 'iTunes U|History|Medieval History',
+            40000044 => 'iTunes U|History|Military History',
+            40000045 => 'iTunes U|History|Modern History',
+            40000046 => 'iTunes U|History|African History',
+            40000047 => 'iTunes U|History|Asia-Pacific History',
+            40000048 => 'iTunes U|History|European History',
+            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 & Journalism',
+            40000054 => 'iTunes U|Philosophy',
+            40000055 => 'iTunes U|Religion & Spirituality',
+            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',
+            40000080 => 'iTunes U|Mathematics|Arithmetic',
+            40000081 => 'iTunes U|Mathematics|Calculus',
+            40000082 => 'iTunes U|Mathematics|Geometry',
+            40000083 => 'iTunes U|Mathematics|Statistics',
+            40000084 => 'iTunes U|Science',
+            40000085 => 'iTunes U|Science|Agricultural',
+            40000086 => 'iTunes U|Science|Astronomy',
+            40000087 => 'iTunes U|Science|Atmosphere',
+            40000088 => 'iTunes U|Science|Biology',
+            40000089 => 'iTunes U|Science|Chemistry',
+            40000090 => 'iTunes U|Science|Ecology',
+            40000091 => 'iTunes U|Science|Geography',
+            40000092 => 'iTunes U|Science|Geology',
+            40000093 => 'iTunes U|Science|Physics',
+            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|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',
+            40000105 => 'iTunes U|Society|Indigenous Studies',
+            40000106 => 'iTunes U|Society|Latin & Caribbean Studies',
+            40000107 => 'iTunes U|Society|Middle Eastern Studies',
+            40000108 => "iTunes U|Society|Women's Studies",
+            40000109 => 'iTunes U|Teaching & Learning',
+            40000110 => 'iTunes U|Teaching & Learning|Curriculum & Teaching',
+            40000111 => 'iTunes U|Teaching & Learning|Educational Leadership',
+            40000112 => 'iTunes U|Teaching & Learning|Family & Childcare',
+            40000113 => 'iTunes U|Teaching & Learning|Learning Resources',
+            40000114 => 'iTunes U|Teaching & Learning|Psychology & Research',
+            40000115 => 'iTunes U|Teaching & Learning|Special Education',
+            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|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|Writing & Literature|Comparative Literature',
+            40000146 => 'iTunes U|Philosophy|Aesthetics',
+            40000147 => 'iTunes U|Philosophy|Epistemology',
+            40000148 => 'iTunes U|Philosophy|Ethics',
+            40000149 => 'iTunes U|Philosophy|Metaphysics',
+            40000150 => 'iTunes U|Philosophy|Political Philosophy',
+            40000151 => 'iTunes U|Philosophy|Logic',
+            40000152 => 'iTunes U|Philosophy|Philosophy of Language',
+            40000153 => 'iTunes U|Philosophy|Philosophy of Religion',
+            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',
+            40000159 => 'iTunes U|Religion & Spirituality|Hinduism',
+            40000160 => 'iTunes U|Religion & Spirituality|Islam',
+            40000161 => 'iTunes U|Religion & Spirituality|Judaism',
+            40000162 => 'iTunes U|Religion & Spirituality|Other Religions',
+            40000163 => 'iTunes U|Religion & Spirituality|Spirituality',
+            40000164 => 'iTunes U|Science|Environment',
+            40000165 => 'iTunes U|Society|African Studies',
+            40000166 => 'iTunes U|Society|American Studies',
+            40000167 => 'iTunes U|Society|Cross-cultural Studies',
+            40000168 => 'iTunes U|Society|Immigration & Emigration',
+            40000169 => 'iTunes U|Society|Race & Ethnicity Studies',
+            40000170 => 'iTunes U|Society|Sexuality Studies',
+            40000171 => 'iTunes U|Teaching & Learning|Educational Technology',
+            40000172 => 'iTunes U|Teaching & Learning|Information/Library Science',
+            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|Biographies & Memoirs',
+            50000043 => 'Audiobooks|Business & Personal Finance',
+            50000044 => 'Audiobooks|Kids & Young Adults',
+            50000045 => 'Audiobooks|Classics',
+            50000046 => 'Audiobooks|Comedy',
+            50000047 => 'Audiobooks|Drama & Poetry',
+            50000048 => 'Audiobooks|Speakers & Storytellers',
+            50000049 => 'Audiobooks|History',
+            50000050 => 'Audiobooks|Languages',
+            50000051 => 'Audiobooks|Mysteries & Thrillers',
+            50000052 => 'Audiobooks|Nonfiction',
+            50000053 => 'Audiobooks|Religion & Spirituality',
+            50000054 => 'Audiobooks|Science & Nature',
+            50000055 => 'Audiobooks|Sci Fi & Fantasy',
+            50000056 => 'Audiobooks|Self-Development',
+            50000057 => 'Audiobooks|Sports & Outdoors',
+            50000058 => 'Audiobooks|Technology',
+            50000059 => 'Audiobooks|Travel & Adventure',
+            50000061 => 'Music|Spoken Word',
+            50000063 => 'Music|Disney',
+            50000064 => 'Music|French Pop',
+            50000066 => 'Music|German Pop',
+            50000068 => 'Music|German Folk',
+            50000069 => 'Audiobooks|Romance',
+            50000070 => 'Audiobooks|Audiobooks Latino',
+            50000071 => 'Books|Comics & Graphic Novels|Manga|Action',
+            50000072 => 'Books|Comics & Graphic Novels|Manga|Comedy',
+            50000073 => 'Books|Comics & Graphic Novels|Manga|Erotica',
+            50000074 => 'Books|Comics & Graphic Novels|Manga|Fantasy',
+            50000075 => 'Books|Comics & Graphic Novels|Manga|Four Cell Manga',
+            50000076 => 'Books|Comics & Graphic Novels|Manga|Gay & Lesbian',
+            50000077 => 'Books|Comics & Graphic Novels|Manga|Hard-Boiled',
+            50000078 => 'Books|Comics & Graphic Novels|Manga|Heroes',
+            50000079 => 'Books|Comics & Graphic Novels|Manga|Historical Fiction',
+            50000080 => 'Books|Comics & Graphic Novels|Manga|Mecha',
+            50000081 => 'Books|Comics & Graphic Novels|Manga|Mystery',
+            50000082 => 'Books|Comics & Graphic Novels|Manga|Nonfiction',
+            50000083 => 'Books|Comics & Graphic Novels|Manga|Religious',
+            50000084 => 'Books|Comics & Graphic Novels|Manga|Romance',
+            50000085 => 'Books|Comics & Graphic Novels|Manga|Romantic Comedy',
+            50000086 => 'Books|Comics & Graphic Novels|Manga|Science Fiction',
+            50000087 => 'Books|Comics & Graphic Novels|Manga|Sports',
+            50000088 => 'Books|Fiction & Literature|Light Novels',
+            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 => { Name => 'Grouping', Avoid => 1 }, #10
     hdvd => { #10
         Name => 'HDVideo',
+        Format => 'int8u', #24
+        Writable => 'int8s', #27
         PrintConv => { 0 => 'No', 1 => 'Yes' },
     },
@@ -1298,4 +5832,6 @@
     pcst => { #7
         Name => 'Podcast',
+        Format => 'int8u', #23
+        Writable => 'int8s', #27
         PrintConv => { 0 => 'No', 1 => 'Yes' },
     },
@@ -1304,4 +5840,5 @@
         Name => 'PlayListID',
         Format => 'int8u',  # actually int64u, but split it up
+        Writable => 'int32s', #27
     },
     purd => 'PurchaseDate', #7
@@ -1309,8 +5846,11 @@
     rtng => { #10
         Name => 'Rating',
+        Format => 'int8u', #23
+        Writable => 'int8s', #27
         PrintConv => {
             0 => 'none',
+            1 => 'Explicit',
             2 => 'Clean',
-            4 => 'Explicit',
+            4 => 'Explicit (old)',
         },
     },
@@ -1318,27 +5858,162 @@
         Name => 'AppleStoreCountry',
         Format => 'int32u',
-        PrintConv => {
-            143460 => 'Australia',
-            143445 => 'Austria',
-            143446 => 'Belgium',
-            143455 => 'Canada',
-            143458 => 'Denmark',
-            143447 => 'Finland',
-            143442 => 'France',
-            143443 => 'Germany',
-            143448 => 'Greece',
-            143449 => 'Ireland',
-            143450 => 'Italy',
-            143462 => 'Japan',
-            143451 => 'Luxembourg',
-            143452 => 'Netherlands',
-            143461 => 'New Zealand',
-            143457 => 'Norway',
-            143453 => 'Portugal',
-            143454 => 'Spain',
-            143456 => 'Sweden',
-            143459 => 'Switzerland',
-            143444 => 'United Kingdom',
-            143441 => 'United States',
+        Writable => 'int32s', #27
+        SeparateTable => 1,
+        PrintConv => { #21
+            143441 => 'United States', # US
+            143442 => 'France', # FR
+            143443 => 'Germany', # DE
+            143444 => 'United Kingdom', # GB
+            143445 => 'Austria', # AT
+            143446 => 'Belgium', # BE
+            143447 => 'Finland', # FI
+            143448 => 'Greece', # GR
+            143449 => 'Ireland', # IE
+            143450 => 'Italy', # IT
+            143451 => 'Luxembourg', # LU
+            143452 => 'Netherlands', # NL
+            143453 => 'Portugal', # PT
+            143454 => 'Spain', # ES
+            143455 => 'Canada', # CA
+            143456 => 'Sweden', # SE
+            143457 => 'Norway', # NO
+            143458 => 'Denmark', # DK
+            143459 => 'Switzerland', # CH
+            143460 => 'Australia', # AU
+            143461 => 'New Zealand', # NZ
+            143462 => 'Japan', # JP
+            143463 => 'Hong Kong', # HK
+            143464 => 'Singapore', # SG
+            143465 => 'China', # CN
+            143466 => 'Republic of Korea', # KR
+            143467 => 'India', # IN
+            143468 => 'Mexico', # MX
+            143469 => 'Russia', # RU
+            143470 => 'Taiwan', # TW
+            143471 => 'Vietnam', # VN
+            143472 => 'South Africa', # ZA
+            143473 => 'Malaysia', # MY
+            143474 => 'Philippines', # PH
+            143475 => 'Thailand', # TH
+            143476 => 'Indonesia', # ID
+            143477 => 'Pakistan', # PK
+            143478 => 'Poland', # PL
+            143479 => 'Saudi Arabia', # SA
+            143480 => 'Turkey', # TR
+            143481 => 'United Arab Emirates', # AE
+            143482 => 'Hungary', # HU
+            143483 => 'Chile', # CL
+            143484 => 'Nepal', # NP
+            143485 => 'Panama', # PA
+            143486 => 'Sri Lanka', # LK
+            143487 => 'Romania', # RO
+            143489 => 'Czech Republic', # CZ
+            143491 => 'Israel', # IL
+            143492 => 'Ukraine', # UA
+            143493 => 'Kuwait', # KW
+            143494 => 'Croatia', # HR
+            143495 => 'Costa Rica', # CR
+            143496 => 'Slovakia', # SK
+            143497 => 'Lebanon', # LB
+            143498 => 'Qatar', # QA
+            143499 => 'Slovenia', # SI
+            143501 => 'Colombia', # CO
+            143502 => 'Venezuela', # VE
+            143503 => 'Brazil', # BR
+            143504 => 'Guatemala', # GT
+            143505 => 'Argentina', # AR
+            143506 => 'El Salvador', # SV
+            143507 => 'Peru', # PE
+            143508 => 'Dominican Republic', # DO
+            143509 => 'Ecuador', # EC
+            143510 => 'Honduras', # HN
+            143511 => 'Jamaica', # JM
+            143512 => 'Nicaragua', # NI
+            143513 => 'Paraguay', # PY
+            143514 => 'Uruguay', # UY
+            143515 => 'Macau', # MO
+            143516 => 'Egypt', # EG
+            143517 => 'Kazakhstan', # KZ
+            143518 => 'Estonia', # EE
+            143519 => 'Latvia', # LV
+            143520 => 'Lithuania', # LT
+            143521 => 'Malta', # MT
+            143523 => 'Moldova', # MD
+            143524 => 'Armenia', # AM
+            143525 => 'Botswana', # BW
+            143526 => 'Bulgaria', # BG
+            143528 => 'Jordan', # JO
+            143529 => 'Kenya', # KE
+            143530 => 'Macedonia', # MK
+            143531 => 'Madagascar', # MG
+            143532 => 'Mali', # ML
+            143533 => 'Mauritius', # MU
+            143534 => 'Niger', # NE
+            143535 => 'Senegal', # SN
+            143536 => 'Tunisia', # TN
+            143537 => 'Uganda', # UG
+            143538 => 'Anguilla', # AI
+            143539 => 'Bahamas', # BS
+            143540 => 'Antigua and Barbuda', # AG
+            143541 => 'Barbados', # BB
+            143542 => 'Bermuda', # BM
+            143543 => 'British Virgin Islands', # VG
+            143544 => 'Cayman Islands', # KY
+            143545 => 'Dominica', # DM
+            143546 => 'Grenada', # GD
+            143547 => 'Montserrat', # MS
+            143548 => 'St. Kitts and Nevis', # KN
+            143549 => 'St. Lucia', # LC
+            143550 => 'St. Vincent and The Grenadines', # VC
+            143551 => 'Trinidad and Tobago', # TT
+            143552 => 'Turks and Caicos', # TC
+            143553 => 'Guyana', # GY
+            143554 => 'Suriname', # SR
+            143555 => 'Belize', # BZ
+            143556 => 'Bolivia', # BO
+            143557 => 'Cyprus', # CY
+            143558 => 'Iceland', # IS
+            143559 => 'Bahrain', # BH
+            143560 => 'Brunei Darussalam', # BN
+            143561 => 'Nigeria', # NG
+            143562 => 'Oman', # OM
+            143563 => 'Algeria', # DZ
+            143564 => 'Angola', # AO
+            143565 => 'Belarus', # BY
+            143566 => 'Uzbekistan', # UZ
+            143568 => 'Azerbaijan', # AZ
+            143571 => 'Yemen', # YE
+            143572 => 'Tanzania', # TZ
+            143573 => 'Ghana', # GH
+            143575 => 'Albania', # AL
+            143576 => 'Benin', # BJ
+            143577 => 'Bhutan', # BT
+            143578 => 'Burkina Faso', # BF
+            143579 => 'Cambodia', # KH
+            143580 => 'Cape Verde', # CV
+            143581 => 'Chad', # TD
+            143582 => 'Republic of the Congo', # CG
+            143583 => 'Fiji', # FJ
+            143584 => 'Gambia', # GM
+            143585 => 'Guinea-Bissau', # GW
+            143586 => 'Kyrgyzstan', # KG
+            143587 => "Lao People's Democratic Republic", # LA
+            143588 => 'Liberia', # LR
+            143589 => 'Malawi', # MW
+            143590 => 'Mauritania', # MR
+            143591 => 'Federated States of Micronesia', # FM
+            143592 => 'Mongolia', # MN
+            143593 => 'Mozambique', # MZ
+            143594 => 'Namibia', # NA
+            143595 => 'Palau', # PW
+            143597 => 'Papua New Guinea', # PG
+            143598 => 'Sao Tome and Principe', # ST (S&atilde;o Tom&eacute; and Pr&iacute;ncipe)
+            143599 => 'Seychelles', # SC
+            143600 => 'Sierra Leone', # SL
+            143601 => 'Solomon Islands', # SB
+            143602 => 'Swaziland', # SZ
+            143603 => 'Tajikistan', # TJ
+            143604 => 'Turkmenistan', # TM
+            143605 => 'Zimbabwe', # ZW
         },
     },
@@ -1351,21 +6026,28 @@
     stik => { #10
         Name => 'MediaType',
+        Format => 'int8u', #23
+        Writable => 'int8s', #27
+        PrintConvColumns => 2,
         PrintConv => { #(http://weblog.xanga.com/gryphondwb/615474010/iphone-ringtones---what-did-itunes-741-really-do.html)
-            0 => 'Movie',
+            0 => 'Movie (old)', #forum9059 (was Movie)
             1 => 'Normal (Music)',
             2 => 'Audiobook',
             5 => 'Whacked Bookmark',
             6 => 'Music Video',
-            9 => 'Short Film',
+            9 => 'Movie', #forum9059 (was Short Film)
             10 => 'TV Show',
             11 => 'Booklet',
             14 => 'Ringtone',
-        },
-    },
-    titl => 'Title',
+            21 => 'Podcast', #15
+            23 => 'iTunes U', #forum9059
+        },
+    },
+    rate => 'RatingPercent', #PH
+    titl => { Name => 'Title', Avoid => 1 },
     tven => 'TVEpisodeID', #7
     tves => { #7/10
         Name => 'TVEpisode',
         Format => 'int32u',
+        Writable => 'int32s', #27
     },
     tvnn => 'TVNetworkName', #7
@@ -1376,13 +6058,131 @@
     },
     yrrc => 'Year', #(ffmpeg source)
+    itnu => { #PH (iTunes 10.5)
+        Name => 'iTunesU',
+        Format => 'int8u', #27
+        Writable => 'int8s', #27
+        Description => 'iTunes U',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    #https://github.com/communitymedia/mediautilities/blob/master/src/net/sourceforge/jaad/mp4/boxes/BoxTypes.java
+    gshh => { Name => 'GoogleHostHeader',   Format => 'string' },
+    gspm => { Name => 'GooglePingMessage',  Format => 'string' },
+    gspu => { Name => 'GooglePingURL',      Format => 'string' },
+    gssd => { Name => 'GoogleSourceData',   Format => 'string' },
+    gsst => { Name => 'GoogleStartTime',    Format => 'string' },
+    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', Avoid => 1, Groups => { 2 => 'Author' } },
+    "\xa9pub" => 'Publisher',
+    "\xa9nrt" => 'Narrator',
+    '@pti' => 'ParentTitle', # (guess -- same as "\xa9nam")
+    '@PST' => 'ParentShortTitle', # (guess -- same as "\xa9nam")
+    '@ppi' => 'ParentProductID', # (guess -- same as 'prID')
+    '@sti' => 'ShortTitle', # (guess -- same as "\xa9nam")
+    prID => 'ProductID',
+    rldt => { Name => 'ReleaseDate', Groups => { 2 => 'Time' }},
+    CDEK => { Name => 'Unknown_CDEK', Unknown => 1 }, # eg: "B004ZMTFEG" - used in URL's ("asin=")
+    CDET => { Name => 'Unknown_CDET', Unknown => 1 }, # eg: "ADBL"
+    VERS => 'ProductVersion',
+    GUID => 'GUID',
+    AACR => { Name => 'Unknown_AACR', Unknown => 1 }, # eg: "CR!1T1H1QH6WX7T714G2BMFX3E9MC4S"
+    # ausr - 30 bytes (User Alias?)
+    "\xa9xyz" => { #PH (written by Google Photos)
+        Name => 'GPSCoordinates',
+        Groups => { 2 => 'Location' },
+        ValueConv => \&ConvertISO6709,
+        ValueConvInv => \&ConvInvISO6709,
+        PrintConv => \&PrintGPSCoordinates,
+        PrintConvInv => \&PrintInvGPSCoordinates,
+    },
+    # the following tags written by iTunes 12.5.1.21
+    # (ref https://www.ventismedia.com/mantis/view.php?id=14963
+    #  https://community.mp3tag.de/t/x-mp4-new-tag-problems/19488)
+    "\xa9wrk" => 'Work', #PH
+    "\xa9mvn" => 'MovementName', #PH
+    "\xa9mvi" => { #PH
+        Name => 'MovementNumber',
+        Format => 'int16u', #27
+        Writable => 'int16s', #27
+    },
+    "\xa9mvc" => { #PH
+        Name => 'MovementCount',
+        Format => 'int16u', #27
+        Writable => 'int16s', #27
+    },
+    shwm => { #PH
+        Name => 'ShowMovement',
+        Format => 'int8u', #27
+        Writable => 'int8s', #27
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+);
+
+# tag decoded from timed face records
+%Image::ExifTool::QuickTime::FaceInfo = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    crec => {
+        Name => 'FaceRec',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::FaceRec',
+        },
+    },
+);
+
+# tag decoded from timed face records
+%Image::ExifTool::QuickTime::FaceRec = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 2 => 'Video' },
+    cits => {
+        Name => 'FaceItem',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::Keys',
+            ProcessProc => \&Process_mebx,
+        },
+    },
 );
 
 # 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',
@@ -1396,4 +6196,5 @@
         Name => 'CreationDate',
         Groups => { 2 => 'Time' },
+        Shift => 'Time',
         ValueConv => q{
             require Image::ExifTool::XMP;
@@ -1402,11 +6203,21 @@
             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,1)', # (add time zone if it didn't exist)
     },
     description => { },
     director    => { },
+    displayname => { Name => 'DisplayName' },
+    title       => { }, #22
     genre       => { },
     information => { },
     keywords    => { },
+    producer    => { }, #22
     make        => { Name => 'Make',        Groups => { 2 => 'Camera' } },
     model       => { Name => 'Model',       Groups => { 2 => 'Camera' } },
@@ -1418,5 +6229,7 @@
         Name => 'FrameReadoutTime',
         ValueConv => '$val * 1e-6',
+        ValueConvInv => 'int($val * 1e6 + 0.5)',
         PrintConv => '$val * 1e6 . " microseconds"',
+        PrintConvInv => '$val =~ s/ .*//; $val * 1e-6',
     },
     'location.ISO6709' => {
@@ -1424,5 +6237,7 @@
         Groups => { 2 => 'Location' },
         ValueConv => \&ConvertISO6709,
+        ValueConvInv => \&ConvInvISO6709,
         PrintConv => \&PrintGPSCoordinates,
+        PrintConvInv => \&PrintInvGPSCoordinates,
     },
     'location.name' => { Name => 'LocationName', Groups => { 2 => 'Location' } },
@@ -1441,4 +6256,5 @@
         Name => 'LocationDate',
         Groups => { 2 => 'Time' },
+        Shift => 'Time',
         ValueConv => q{
             require Image::ExifTool::XMP;
@@ -1447,9 +6263,16 @@
             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,1)', # (add time zone if it didn't exist)
     },
     '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',
@@ -1467,4 +6290,80 @@
         PrintConv => { 0 => 'Off', 1 => 'On' },
     },
+    'rating.user'  => 'UserRating', # (Canon ELPH 510 HS)
+    'collection.user' => 'UserCollection', #22
+    'Encoded_With' => 'EncodedWith',
+#
+# 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' => { 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 ( ----
+    # --> 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'    => { Name => 'DetectedFaceID',        Writable => 0 },
+    # (fiel)com.apple.quicktime.detected-face.roll-angle (dtyp=23, float)
+    'detected-face.roll-angle' => { Name => 'DetectedFaceRollAngle', Writable => 0 },
+    # (fiel)com.apple.quicktime.detected-face.yaw-angle (dtyp=23, float)
+    'detected-face.yaw-angle'  => { Name => 'DetectedFaceYawAngle',  Writable => 0 },
+#
+# seen in Apple ProRes RAW file
+#
+    # (mdta)com.apple.proapps.manufacturer (eg. "Sony")
+    # (mdta)com.apple.proapps.exif.{Exif}.FNumber (float, eg. 1.0)
+    # (mdta)org.smpte.rdd18.lens.irisfnumber (eg. "F1.0")
+    # (mdta)com.apple.proapps.exif.{Exif}.ShutterSpeedValue (float, eg. 1.006)
+    # (mdta)org.smpte.rdd18.camera.shutterspeed_angle (eg. "179.2deg")
+    # (mdta)org.smpte.rdd18.camera.neutraldensityfilterwheelsetting (eg. "ND1")
+    # (mdta)org.smpte.rdd18.camera.whitebalance (eg. "4300K")
+    # (mdta)com.apple.proapps.exif.{Exif}.ExposureIndex (float, eg. 4000)
+    # (mdta)org.smpte.rdd18.camera.isosensitivity (eg. "4000")
+    # (mdta)com.apple.proapps.image.{TIFF}.Make (eg. "Atmos")
+    # (mdta)com.apple.proapps.image.{TIFF}.Model (eg. "ShogunInferno")
+    # (mdta)com.apple.proapps.image.{TIFF}.Software (eg. "9.0")
 );
 
@@ -1473,20 +6372,140 @@
     PROCESS_PROC => \&ProcessMOV,
     GROUPS => { 2 => 'Audio' },
+    NOTES => q{
+        ExifTool will extract any iTunesInfo tags that exist, even if they are not
+        defined in this table.
+    },
     # 'mean'/'name'/'data' atoms form a triplet, but unfortunately
-    # I can't find any source for decoding 'data'.
+    # I haven't been able to find any documentation on this.
     # 'mean' is normally 'com.apple.iTunes'
-    # 'name' values: 'tool', 'iTunNORM' (volume normalization),
-    #   'iTunSMPB', 'iTunes_CDDB_IDs', 'iTunes_CDDB_TrackNumber'
     mean => {
         Name => 'Mean',
-        Unknown => 1,
+        # the 'Triplet' flag tells ProcessMOV() to generate
+        # a single tag from the mean/name/data triplet
+        Triplet => 1,
+        Hidden => 1,
     },
     name => {
         Name => 'Name',
-        Unknown => 1,
+        Triplet => 1,
+        Hidden => 1,
     },
     data => {
         Name => 'Data',
-        Flags => ['Binary','Unknown'],
+        Triplet => 1,
+        Hidden => 1,
+    },
+    # the tag ID's below are composed from "mean/name",
+    # but "mean/" is omitted if it is "com.apple.iTunes/":
+    'iTunMOVI' => {
+        Name => 'iTunMOVI',
+        SubDirectory => { TagTable => 'Image::ExifTool::PLIST::Main' },
+    },
+    'tool' => {
+        Name => 'iTunTool',
+        Description => 'iTunTool',
+        Format => 'int32u',
+        PrintConv => 'sprintf("0x%.8x",$val)',
+    },
+    'iTunEXTC' => {
+        Name => 'ContentRating',
+        Notes => 'standard | rating | score | reasons',
+        # eg. 'us-tv|TV-14|500|V', 'mpaa|PG-13|300|For violence and sexuality'
+        # (see http://shadowofged.blogspot.ca/2008/06/itunes-content-ratings.html)
+    },
+    'iTunNORM' => {
+        Name => 'VolumeNormalization',
+        PrintConv => '$val=~s/ 0+(\w)/ $1/g; $val=~s/^\s+//; $val',
+    },
+    'iTunSMPB' => {
+        Name => 'iTunSMPB',
+        Description => 'iTunSMPB',
+        # hex format, similar to iTunNORM, but 12 words instead of 10,
+        # and 4th word is 16 hex digits (all others are 8)
+        # (gives AAC encoder delay, ref http://code.google.com/p/l-smash/issues/detail?id=1)
+        PrintConv => '$val=~s/ 0+(\w)/ $1/g; $val=~s/^\s+//; $val',
+    },
+    # (CDDB = Compact Disc DataBase)
+    # iTunes_CDDB_1 = <CDDB1 disk ID>+<# tracks>+<logical block address for each track>...
+    'iTunes_CDDB_1' => 'CDDB1Info',
+    'iTunes_CDDB_TrackNumber' => 'CDDBTrackNumber',
+    'Encoding Params' => {
+        Name => 'EncodingParams',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::EncodingParams' },
+    },
+    # also heard about 'iTunPGAP', but I haven't seen a sample
+    DISCNUMBER => 'DiscNumber', #PH
+    TRACKNUMBER => 'TrackNumber', #PH
+    popularimeter => 'Popularimeter', #PH
+);
+
+# iTunes audio encoding parameters
+# ref https://developer.apple.com/library/mac/#documentation/MusicAudio/Reference/AudioCodecServicesRef/Reference/reference.html
+%Image::ExifTool::QuickTime::EncodingParams = (
+    PROCESS_PROC => \&ProcessEncodingParams,
+    GROUPS => { 2 => 'Audio' },
+    # (I have commented out the ones that don't have integer values because they
+    #  probably don't appear, and definitely wouldn't work with current decoding - PH)
+
+    # global codec properties
+    #'lnam' => 'AudioCodecName',
+    #'lmak' => 'AudioCodecManufacturer',
+    #'lfor' => 'AudioCodecFormat',
+    'vpk?' => 'AudioHasVariablePacketByteSizes',
+    #'ifm#' => 'AudioSupportedInputFormats',
+    #'ofm#' => 'AudioSupportedOutputFormats',
+    #'aisr' => 'AudioAvailableInputSampleRates',
+    #'aosr' => 'AudioAvailableOutputSampleRates',
+    'abrt' => 'AudioAvailableBitRateRange',
+    'mnip' => 'AudioMinimumNumberInputPackets',
+    'mnop' => 'AudioMinimumNumberOutputPackets',
+    'cmnc' => 'AudioAvailableNumberChannels',
+    'lmrc' => 'AudioDoesSampleRateConversion',
+    #'aicl' => 'AudioAvailableInputChannelLayoutTags',
+    #'aocl' => 'AudioAvailableOutputChannelLayoutTags',
+    #'if4o' => 'AudioInputFormatsForOutputFormat',
+    #'of4i' => 'AudioOutputFormatsForInputFormat',
+    #'acfi' => 'AudioFormatInfo',
+
+    # instance codec properties
+    'tbuf' => 'AudioInputBufferSize',
+    'pakf' => 'AudioPacketFrameSize',
+    'pakb' => 'AudioMaximumPacketByteSize',
+    #'ifmt' => 'AudioCurrentInputFormat',
+    #'ofmt' => 'AudioCurrentOutputFormat',
+    #'kuki' => 'AudioMagicCookie',
+    'ubuf' => 'AudioUsedInputBufferSize',
+    'init' => 'AudioIsInitialized',
+    'brat' => 'AudioCurrentTargetBitRate',
+    #'cisr' => 'AudioCurrentInputSampleRate',
+    #'cosr' => 'AudioCurrentOutputSampleRate',
+    'srcq' => 'AudioQualitySetting',
+    #'brta' => 'AudioApplicableBitRateRange',
+    #'isra' => 'AudioApplicableInputSampleRates',
+    #'osra' => 'AudioApplicableOutputSampleRates',
+    'pad0' => 'AudioZeroFramesPadded',
+    'prmm' => 'AudioCodecPrimeMethod',
+    #'prim' => 'AudioCodecPrimeInfo',
+    #'icl ' => 'AudioInputChannelLayout',
+    #'ocl ' => 'AudioOutputChannelLayout',
+    #'acs ' => 'AudioCodecSettings',
+    #'acfl' => 'AudioCodecFormatList',
+    'acbf' => 'AudioBitRateControlMode',
+    'vbrq' => 'AudioVBRQuality',
+    'mdel' => 'AudioMinimumDelayMode',
+
+    # deprecated
+    'pakd' => 'AudioRequiresPacketDescription',
+    #'brt#' => 'AudioAvailableBitRates',
+    'acef' => 'AudioExtendFrequencies',
+    'ursr' => 'AudioUseRecommendedSampleRate',
+    'oppr' => 'AudioOutputPrecedence',
+    #'loud' => 'AudioCurrentLoudnessStatistics',
+
+    # others
+    'vers' => 'AudioEncodingParamsVersion', #PH
+    'cdcv' => { #PH
+        Name => 'AudioComponentVersion',
+        ValueConv => 'join ".", unpack("ncc", pack("N",$val))',
     },
 );
@@ -1565,36 +6584,8 @@
     payt => {
         Name => 'PayloadType',
+        Format => 'undef',  # (necessary to prevent decoding as string!)
         ValueConv => 'unpack("N",$val) . " " . substr($val, 5)',
         PrintConv => '$val=~s/ /, /;$val',
     },
-);
-
-# Kodak DcMD atoms (ref PH)
-%Image::ExifTool::QuickTime::DcMD = (
-    PROCESS_PROC => \&ProcessMOV,
-    GROUPS => { 2 => 'Video' },
-    NOTES => 'Metadata directory found in MOV videos from some Kodak cameras.',
-    Cmbo => {
-        Name => 'CameraByteOrder',
-        PrintConv => {
-            II => 'Little-endian (Intel, II)',
-            MM => 'Big-endian (Motorola, MM)',
-        },
-    },
-    DcME => {
-        Name => 'DcME',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::QuickTime::DcME',
-        },
-    },
-);
-
-# Kodak DcME atoms (ref PH)
-%Image::ExifTool::QuickTime::DcME = (
-    PROCESS_PROC => \&ProcessMOV,
-    GROUPS => { 2 => 'Video' },
-    # Mtmd = binary data ("00 00 00 00 00 00 00 01" x 3)
-    # Keyw = keywords? (six bytes all zero)
-    # Rate = 2 bytes "00 00"
 );
 
@@ -1602,5 +6593,6 @@
 %Image::ExifTool::QuickTime::Media = (
     PROCESS_PROC => \&ProcessMOV,
-    GROUPS => { 2 => 'Video' },
+    WRITE_PROC => \&WriteQuickTime,
+    GROUPS => { 1 => 'Track#', 2 => 'Video' },
     NOTES => 'MP4 media box.',
     mdhd => {
@@ -1621,6 +6613,9 @@
 %Image::ExifTool::QuickTime::MediaHeader = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
-    GROUPS => { 2 => 'Video' },
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 1 => 'Track#', 2 => 'Video' },
     FORMAT => 'int32u',
+    DATAMEMBER => [ 0, 1, 2, 3, 4 ],
     0 => {
         Name => 'MediaHeaderVersion',
@@ -1657,5 +6652,5 @@
         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+$/;
@@ -1669,5 +6664,6 @@
 %Image::ExifTool::QuickTime::MediaInfo = (
     PROCESS_PROC => \&ProcessMOV,
-    GROUPS => { 2 => 'Video' },
+    WRITE_PROC => \&WriteQuickTime,
+    GROUPS => { 1 => 'Track#', 2 => 'Video' },
     NOTES => 'MP4 media info box.',
     vmhd => {
@@ -1688,5 +6684,5 @@
     },
     dinf => {
-        Name => 'DataInfo',
+        Name => 'DataInfo', # (don't change this name -- used to recognize directory when writing)
         SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::DataInfo' },
     },
@@ -1743,4 +6739,5 @@
 %Image::ExifTool::QuickTime::SampleTable = (
     PROCESS_PROC => \&ProcessMOV,
+    WRITE_PROC => \&WriteQuickTime,
     GROUPS => { 2 => 'Video' },
     NOTES => 'MP4 sample table box.',
@@ -1751,5 +6748,5 @@
             SubDirectory => {
                 TagTable => 'Image::ExifTool::QuickTime::AudioSampleDesc',
-                Start => 8, # skip version number and count
+                ProcessProc => \&ProcessSampleDesc,
             },
         },{
@@ -1758,5 +6755,5 @@
             SubDirectory => {
                 TagTable => 'Image::ExifTool::QuickTime::ImageDesc',
-                Start => 8, # skip version number and count
+                ProcessProc => \&ProcessSampleDesc,
             },
         },{
@@ -1765,5 +6762,12 @@
             SubDirectory => {
                 TagTable => 'Image::ExifTool::QuickTime::HintSampleDesc',
-                Start => 8, # skip version number and count
+                ProcessProc => \&ProcessSampleDesc,
+            },
+        },{
+            Name => 'MetaSampleDesc',
+            Condition => '$$self{HandlerType} and $$self{HandlerType} eq "meta"',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::QuickTime::MetaSampleDesc',
+                ProcessProc => \&ProcessSampleDesc,
             },
         },{
@@ -1771,5 +6775,5 @@
             SubDirectory => {
                 TagTable => 'Image::ExifTool::QuickTime::OtherSampleDesc',
-                Start => 8, # skip version number and count
+                ProcessProc => \&ProcessSampleDesc,
             },
         },
@@ -1781,4 +6785,5 @@
             Notes => 'average rate calculated from time-to-sample table for video media',
             Condition => '$$self{HandlerType} and $$self{HandlerType} eq "vide"',
+            Format => 'undef',  # (necessary to prevent decoding as string!)
             # (must be RawConv so appropriate MediaTS is used in calculation)
             RawConv => 'Image::ExifTool::QuickTime::CalcSampleRate($self, \$val)',
@@ -1841,4 +6846,10 @@
         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 => {
@@ -1850,16 +6861,25 @@
         Flags => ['Binary','Unknown'],
     },
+    stps => {
+        Name => 'PartialSyncSamples',
+        ValueConv => 'join " ",unpack("x8N*",$val)',
+    },
+    # mark - 8 bytes all zero (GoPro)
 );
 
-# MP4 audio sample description box (ref 5)
+# MP4 audio sample description box (ref 5/AtomicParsley 0.9.4 parsley.cpp)
 %Image::ExifTool::QuickTime::AudioSampleDesc = (
-    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    PROCESS_PROC => \&ProcessHybrid,
+    VARS => { ID_LABEL => 'ID/Index' },
     GROUPS => { 2 => 'Audio' },
-    FORMAT => 'int16u',
-    NOTES => 'MP4 audio sample description.',
-    2  => {
+    NOTES => q{
+        MP4 audio sample description.  This hybrid atom contains both data and child
+        atoms.
+    },
+    4  => {
         Name => 'AudioFormat',
         Format => 'undef[4]',
         RawConv => q{
+            $$self{AudioFormat} = $val;
             return undef unless $val =~ /^[\w ]{4}$/i;
             # check for protected audio format
@@ -1867,7 +6887,10 @@
             return $val;
         },
-    },
-    10 => { #PH
+        # 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',
+        Condition => '$$self{AudioFormat} ne "mp4s"',
         Format => 'undef[4]',
         RawConv => '$val eq "\0\0\0\0" ? undef : $val',
@@ -1875,28 +6898,550 @@
         SeparateTable => 'VendorID',
     },
-    12 => 'AudioChannels',
-    13 => 'AudioBitsPerSample',
-    16 => { Name => 'AudioSampleRate', Format => 'fixed32u' },
-    28 => { #PH
-        Name => 'AudioFormat',
+    24 => { Name => 'AudioChannels',        Format => 'int16u' },
+    26 => { Name => 'AudioBitsPerSample',   Format => 'int16u' },
+    32 => { Name => 'AudioSampleRate',      Format => 'fixed32u' },
+#
+# Observed offsets for child atoms of various AudioFormat types:
+#
+#   AudioFormat  Offset  Child atoms
+#   -----------  ------  ----------------
+#   mp4a         52 *    wave, chan, esds, SA3D(Insta360 spherical video params?,also GoPro Max)
+#   in24         52      wave, chan
+#   "ms\0\x11"   52      wave
+#   sowt         52      chan
+#   mp4a         36 *    esds, pinf
+#   drms         36      esds, sinf
+#   samr         36      damr
+#   alac         36      alac
+#   ac-3         36      dac3
+#
+# (* child atoms found at different offsets in mp4a)
+#
+    pinf => {
+        Name => 'PurchaseInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ProtectionInfo' },
+    },
+    sinf => { # "protection scheme information"
+        Name => 'ProtectionInfo', #3
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ProtectionInfo' },
+    },
+    # f - 16/36 bytes
+    # esds - 31/40/42/43 bytes - ES descriptor (ref 3)
+    damr => { #3
+        Name => 'DecodeConfig',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::DecodeConfig' },
+    },
+    wave => {
+        Name => 'Wave',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Wave' },
+    },
+    chan => {
+        Name => 'AudioChannelLayout',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::ChannelLayout' },
+    }
+    # alac - 28 bytes
+    # adrm - AAX DRM atom? 148 bytes
+    # aabd - AAX unknown 17kB (contains 'aavd' strings)
+    # SA3D - written by Garmin VIRB360
+);
+
+# AMR decode config box (ref 3)
+%Image::ExifTool::QuickTime::DecodeConfig = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    0 => {
+        Name => 'EncoderVendor',
         Format => 'undef[4]',
-        RawConv => '$val =~ /^[\w ]{4}$/i ? $val : undef',
-        Notes => 'in Casio MOV videos',
-    },
+    },
+    4 => 'EncoderVersion',
+    # 5 - int16u - packet modes
+    # 7 - int8u - number of packet mode changes
+    # 8 - int8u - bytes per packet
 );
 
+%Image::ExifTool::QuickTime::ProtectionInfo = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 2 => 'Audio' },
+    NOTES => 'Child atoms found in "sinf" and/or "pinf" atoms.',
+    frma => 'OriginalFormat',
+    # imif - IPMP information
+    schm => {
+        Name => 'SchemeType',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SchemeType' },
+    },
+    schi => {
+        Name => 'SchemeInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::SchemeInfo' },
+    },
+    enda => {
+        Name => 'Endianness',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Big-endian (Motorola, MM)',
+            1 => 'Little-endian (Intel, II)',
+        },
+    },
+    # skcr
+);
+
+%Image::ExifTool::QuickTime::Wave = (
+    PROCESS_PROC => \&ProcessMOV,
+    frma => 'PurchaseFileFormat',
+    enda => {
+        Name => 'Endianness',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Big-endian (Motorola, MM)',
+            1 => 'Little-endian (Intel, II)',
+        },
+    },
+    # "ms\0\x11" - 20 bytes
+);
+
+# audio channel layout (ref CoreAudioTypes.h)
+%Image::ExifTool::QuickTime::ChannelLayout = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    DATAMEMBER => [ 0, 8 ],
+    NOTES => 'Audio channel layout.',
+    # 0 - version and flags
+    4 => {
+        Name => 'LayoutFlags',
+        Format => 'int16u',
+        RawConv => '$$self{LayoutFlags} = $val',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'UseDescriptions',
+            1 => 'UseBitmap',
+            100 => 'Mono',
+            101 => 'Stereo',
+            102 => 'StereoHeadphones',
+            100 => 'Mono',
+            101 => 'Stereo',
+            102 => 'StereoHeadphones',
+            103 => 'MatrixStereo',
+            104 => 'MidSide',
+            105 => 'XY',
+            106 => 'Binaural',
+            107 => 'Ambisonic_B_Format',
+            108 => 'Quadraphonic',
+            109 => 'Pentagonal',
+            110 => 'Hexagonal',
+            111 => 'Octagonal',
+            112 => 'Cube',
+            113 => 'MPEG_3_0_A',
+            114 => 'MPEG_3_0_B',
+            115 => 'MPEG_4_0_A',
+            116 => 'MPEG_4_0_B',
+            117 => 'MPEG_5_0_A',
+            118 => 'MPEG_5_0_B',
+            119 => 'MPEG_5_0_C',
+            120 => 'MPEG_5_0_D',
+            121 => 'MPEG_5_1_A',
+            122 => 'MPEG_5_1_B',
+            123 => 'MPEG_5_1_C',
+            124 => 'MPEG_5_1_D',
+            125 => 'MPEG_6_1_A',
+            126 => 'MPEG_7_1_A',
+            127 => 'MPEG_7_1_B',
+            128 => 'MPEG_7_1_C',
+            129 => 'Emagic_Default_7_1',
+            130 => 'SMPTE_DTV',
+            131 => 'ITU_2_1',
+            132 => 'ITU_2_2',
+            133 => 'DVD_4',
+            134 => 'DVD_5',
+            135 => 'DVD_6',
+            136 => 'DVD_10',
+            137 => 'DVD_11',
+            138 => 'DVD_18',
+            139 => 'AudioUnit_6_0',
+            140 => 'AudioUnit_7_0',
+            141 => 'AAC_6_0',
+            142 => 'AAC_6_1',
+            143 => 'AAC_7_0',
+            144 => 'AAC_Octagonal',
+            145 => 'TMH_10_2_std',
+            146 => 'TMH_10_2_full',
+            147 => 'DiscreteInOrder',
+            148 => 'AudioUnit_7_0_Front',
+            149 => 'AC3_1_0_1',
+            150 => 'AC3_3_0',
+            151 => 'AC3_3_1',
+            152 => 'AC3_3_0_1',
+            153 => 'AC3_2_1_1',
+            154 => 'AC3_3_1_1',
+            155 => 'EAC_6_0_A',
+            156 => 'EAC_7_0_A',
+            157 => 'EAC3_6_1_A',
+            158 => 'EAC3_6_1_B',
+            159 => 'EAC3_6_1_C',
+            160 => 'EAC3_7_1_A',
+            161 => 'EAC3_7_1_B',
+            162 => 'EAC3_7_1_C',
+            163 => 'EAC3_7_1_D',
+            164 => 'EAC3_7_1_E',
+            165 => 'EAC3_7_1_F',
+            166 => 'EAC3_7_1_G',
+            167 => 'EAC3_7_1_H',
+            168 => 'DTS_3_1',
+            169 => 'DTS_4_1',
+            170 => 'DTS_6_0_A',
+            171 => 'DTS_6_0_B',
+            172 => 'DTS_6_0_C',
+            173 => 'DTS_6_1_A',
+            174 => 'DTS_6_1_B',
+            175 => 'DTS_6_1_C',
+            176 => 'DTS_7_0',
+            177 => 'DTS_7_1',
+            178 => 'DTS_8_0_A',
+            179 => 'DTS_8_0_B',
+            180 => 'DTS_8_1_A',
+            181 => 'DTS_8_1_B',
+            182 => 'DTS_6_1_D',
+            183 => 'AAC_7_1_B',
+            0xffff => 'Unknown',
+        },
+    },
+    6  => {
+        Name => 'AudioChannels',
+        Condition => '$$self{LayoutFlags} != 0 and $$self{LayoutFlags} != 1',
+        Format => 'int16u',
+    },
+    8 => {
+        Name => 'AudioChannelTypes',
+        Condition => '$$self{LayoutFlags} == 1',
+        Format => 'int32u',
+        PrintConv => { BITMASK => {
+            0 => 'Left',
+            1 => 'Right',
+            2 => 'Center',
+            3 => 'LFEScreen',
+            4 => 'LeftSurround',
+            5 => 'RightSurround',
+            6 => 'LeftCenter',
+            7 => 'RightCenter',
+            8 => 'CenterSurround',
+            9 => 'LeftSurroundDirect',
+            10 => 'RightSurroundDirect',
+            11 => 'TopCenterSurround',
+            12 => 'VerticalHeightLeft',
+            13 => 'VerticalHeightCenter',
+            14 => 'VerticalHeightRight',
+            15 => 'TopBackLeft',
+            16 => 'TopBackCenter',
+            17 => 'TopBackRight',
+        }},
+    },
+    12  => {
+        Name => 'NumChannelDescriptions',
+        Condition => '$$self{LayoutFlags} == 1',
+        Format => 'int32u',
+        RawConv => '$$self{NumChannelDescriptions} = $val',
+    },
+    16 => {
+        Name => 'Channel1Label',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 0',
+        Format => 'int32u',
+        SeparateTable => 'ChannelLabel',
+        PrintConv => \%channelLabel,
+    },
+    20 => {
+        Name => 'Channel1Flags',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 0',
+        Format => 'int32u',
+        PrintConv => { BITMASK => { 0 => 'Rectangular', 1 => 'Spherical', 2 => 'Meters' }},
+    },
+    24 => {
+        Name => 'Channel1Coordinates',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 0',
+        Notes => q{
+            3 numbers:  for rectangular coordinates left/right, back/front, down/up; for
+            spherical coordinates left/right degrees, down/up degrees, distance
+        },
+        Format => 'float[3]',
+    },
+    36 => {
+        Name => 'Channel2Label',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 1',
+        Format => 'int32u',
+        SeparateTable => 'ChannelLabel',
+        PrintConv => \%channelLabel,
+    },
+    40 => {
+        Name => 'Channel2Flags',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 1',
+        Format => 'int32u',
+        PrintConv => { BITMASK => { 0 => 'Rectangular', 1 => 'Spherical', 2 => 'Meters' }},
+    },
+    44 => {
+        Name => 'Channel2Coordinates',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 1',
+        Format => 'float[3]',
+    },
+    56 => {
+        Name => 'Channel3Label',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 2',
+        Format => 'int32u',
+        SeparateTable => 'ChannelLabel',
+        PrintConv => \%channelLabel,
+    },
+    60 => {
+        Name => 'Channel3Flags',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 2',
+        Format => 'int32u',
+        PrintConv => { BITMASK => { 0 => 'Rectangular', 1 => 'Spherical', 2 => 'Meters' }},
+    },
+    64 => {
+        Name => 'Channel3Coordinates',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 2',
+        Format => 'float[3]',
+    },
+    76 => {
+        Name => 'Channel4Label',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 3',
+        Format => 'int32u',
+        SeparateTable => 'ChannelLabel',
+        PrintConv => \%channelLabel,
+    },
+    80 => {
+        Name => 'Channel4Flags',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 3',
+        Format => 'int32u',
+        PrintConv => { BITMASK => { 0 => 'Rectangular', 1 => 'Spherical', 2 => 'Meters' }},
+    },
+    84 => {
+        Name => 'Channel4Coordinates',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 3',
+        Format => 'float[3]',
+    },
+    96 => {
+        Name => 'Channel5Label',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 4',
+        Format => 'int32u',
+        SeparateTable => 'ChannelLabel',
+        PrintConv => \%channelLabel,
+    },
+    100 => {
+        Name => 'Channel5Flags',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 4',
+        Format => 'int32u',
+        PrintConv => { BITMASK => { 0 => 'Rectangular', 1 => 'Spherical', 2 => 'Meters' }},
+    },
+    104 => {
+        Name => 'Channel5Coordinates',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 4',
+        Format => 'float[3]',
+    },
+    116 => {
+        Name => 'Channel6Label',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 5',
+        Format => 'int32u',
+        SeparateTable => 'ChannelLabel',
+        PrintConv => \%channelLabel,
+    },
+    120 => {
+        Name => 'Channel6Flags',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 5',
+        Format => 'int32u',
+        PrintConv => { BITMASK => { 0 => 'Rectangular', 1 => 'Spherical', 2 => 'Meters' }},
+    },
+    124 => {
+        Name => 'Channel6Coordinates',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 5',
+        Format => 'float[3]',
+    },
+    136 => {
+        Name => 'Channel7Label',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 6',
+        Format => 'int32u',
+        SeparateTable => 'ChannelLabel',
+        PrintConv => \%channelLabel,
+    },
+    140 => {
+        Name => 'Channel7Flags',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 6',
+        Format => 'int32u',
+        PrintConv => { BITMASK => { 0 => 'Rectangular', 1 => 'Spherical', 2 => 'Meters' }},
+    },
+    144 => {
+        Name => 'Channel7Coordinates',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 6',
+        Format => 'float[3]',
+    },
+    156 => {
+        Name => 'Channel8Label',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 7',
+        Format => 'int32u',
+        SeparateTable => 'ChannelLabel',
+        PrintConv => \%channelLabel,
+    },
+    160 => {
+        Name => 'Channel8Flags',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 7',
+        Format => 'int32u',
+        PrintConv => { BITMASK => { 0 => 'Rectangular', 1 => 'Spherical', 2 => 'Meters' }},
+    },
+    164 => {
+        Name => 'Channel8Coordinates',
+        Condition => '$$self{LayoutFlags} == 1 and $$self{NumChannelDescriptions} > 7',
+        Format => 'float[3]',
+    },
+    # (arbitrarily decode only first 8 channels)
+);
+
+# scheme type atom
+# ref http://xhelmboyx.tripod.com/formats/mp4-layout.txt
+%Image::ExifTool::QuickTime::SchemeType = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    # 0 - 4 bytes version
+    4 => { Name => 'SchemeType',    Format => 'undef[4]' },
+    8 => { Name => 'SchemeVersion', Format => 'int16u' },
+    10 => { Name => 'SchemeURL',    Format => 'string[$size-10]' },
+);
+
+%Image::ExifTool::QuickTime::SchemeInfo = (
+    PROCESS_PROC => \&ProcessMOV,
+    GROUPS => { 2 => 'Audio' },
+    user => {
+        Name => 'UserID',
+        Groups => { 2 => 'Author' },
+        ValueConv => '"0x" . unpack("H*",$val)',
+    },
+    cert => { # ref http://www.onvif.org/specs/stream/ONVIF-ExportFileFormat-Spec-v100.pdf
+        Name => 'Certificate',
+        ValueConv => '"0x" . unpack("H*",$val)',
+    },
+    'key ' => {
+        Name => 'KeyID',
+        ValueConv => '"0x" . unpack("H*",$val)',
+    },
+    iviv => {
+        Name => 'InitializationVector',
+        ValueConv => 'unpack("H*",$val)',
+    },
+    righ => {
+        Name => 'Rights',
+        Groups => { 2 => 'Author' },
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Rights' },
+    },
+    name => { Name => 'UserName', Groups => { 2 => 'Author' } },
+    # chtb
+    # priv - private data
+    # sign
+    # adkm - Adobe DRM key management system (ref http://download.macromedia.com/f4v/video_file_format_spec_v10_1.pdf)
+    # iKMS
+    # iSFM
+    # iSLT
+);
+
+%Image::ExifTool::QuickTime::Rights = (
+    PROCESS_PROC => \&ProcessRights,
+    GROUPS => { 2 => 'Audio' },
+    veID => 'ItemVendorID', #PH ("VendorID" ref 19)
+    plat => 'Platform', #18?
+    aver => 'VersionRestrictions', #19 ("appversion?" ref 18)
+    tran => 'TransactionID', #18
+    song => 'ItemID', #19 ("appid" ref 18)
+    tool => {
+        Name => 'ItemTool', #PH (guess) ("itunes build?" ref 18)
+        Format => 'string',
+    },
+    medi => 'MediaFlags', #PH (?)
+    mode => 'ModeFlags', #PH (?) 0x04 is HD flag (https://compilr.com/heksesang/requiem-mac/UnDrm.java)
+);
+
 # MP4 hint sample description box (ref 5)
+# (ref https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/QTFFChap3/qtff3.html#//apple_ref/doc/uid/TP40000939-CH205-SW1)
 %Image::ExifTool::QuickTime::HintSampleDesc = (
-    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
-    FORMAT => 'int16u',
+    PROCESS_PROC => \&ProcessHybrid,
+    VARS => { ID_LABEL => 'ID/Index' },
     NOTES => 'MP4 hint sample description.',
-    2 => { Name => 'HintFormat', Format => 'undef[4]' },
+    4  => { Name => 'HintFormat', Format => 'undef[4]' },
+    # 14 - int16u DataReferenceIndex
+    16 => { Name => 'HintTrackVersion', Format => 'int16u' },
+    # 18 - int16u LastCompatibleHintTrackVersion
+    20 => { Name => 'MaxPacketSize', Format => 'int32u' },
+#
+# Observed offsets for child atoms of various HintFormat types:
+#
+#   HintFormat   Offset  Child atoms
+#   -----------  ------  ----------------
+#   "rtp "       24      tims
+#
+    tims => { Name => 'RTPTimeScale',               Format => 'int32u' },
+    tsro => { Name => 'TimestampRandomOffset',      Format => 'int32u' },
+    snro => { Name => 'SequenceNumberRandomOffset', Format => 'int32u' },
+);
+
+# MP4 metadata sample description box
+%Image::ExifTool::QuickTime::MetaSampleDesc = (
+    PROCESS_PROC => \&ProcessHybrid,
+    NOTES => 'MP4 metadata sample description.',
+    4 => {
+        Name => 'MetaFormat',
+        Format => 'undef[4]',
+        RawConv => '$$self{MetaFormat} = $val',
+    },
+#
+# Observed offsets for child atoms of various MetaFormat types:
+#
+#   MetaFormat   Offset  Child atoms
+#   -----------  ------  ----------------
+#   mebx         24      keys,btrt,lidp,lidl
+#   fdsc         -       -
+#   gpmd         -       -
+#   rtmd         -       -
+#   CTMD         -       -
+#
+   'keys' => { #PH (iPhone7+ hevc)
+        Name => 'Keys',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::Keys',
+            ProcessProc => \&ProcessMetaKeys,
+        },
+    },
+    btrt => {
+        Name => 'BitrateInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Bitrate' },
+    },
 );
 
 # MP4 generic sample description box
 %Image::ExifTool::QuickTime::OtherSampleDesc = (
-    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
-    FORMAT => 'int16u',
-    2 => { Name => 'OtherFormat', Format => 'undef[4]' },
+    PROCESS_PROC => \&ProcessHybrid,
+    4 => {
+        Name => 'OtherFormat',
+        Format => 'undef[4]',
+        RawConv => '$$self{MetaFormat} = $val', # (yes, use MetaFormat for this too)
+    },
+#
+# Observed offsets for child atoms of various OtherFormat types:
+#
+#   OtherFormat  Offset  Child atoms
+#   -----------  ------  ----------------
+#   avc1         86      avcC
+#   mp4a         36      esds
+#   mp4s         16      esds
+#   tmcd         34      name
+#   data         -       -
+#
+    ftab => { Name => 'FontTable',  Format => 'undef', ValueConv => 'substr($val, 5)' },
+    name => { Name => 'OtherName',  Format => 'undef', ValueConv => 'substr($val, 4)' },
+    # mrlh = GM header?
+    # mrlv = GM data
+    # mrld = GM data (448-byte records):
+    #            0 - int32u count
+    #            4 - int32u ? (related to units) 0=none,1=m/km,2=L,3=kph,4=C,7=deg,8=rpm,9=kPa,10=G,11=V,15=Nm,16=%
+    #            8 - int32u ? (0,1,3,4,5)
+    #           12 - string[64] units
+    #           76 - int32u ? (1,3,7,15)
+    #           80 - int32u 0
+    #           84 - undef[4] ?
+    #           88 - int16u[6] ?
+    #           100 - undef[32] ?
+    #           132 - string[64] measurement name
+    #           196 - string[64] measurement name
 );
 
@@ -1904,4 +7449,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 => {
@@ -1924,4 +7470,62 @@
         Name => 'Text',
         Flags => ['Binary','Unknown'],
+    },
+    tmcd => {
+        Name => 'TimeCode',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TimeCode' },
+    },
+);
+
+# TimeCode header
+%Image::ExifTool::QuickTime::TimeCode = (
+    PROCESS_PROC => \&ProcessMOV,
+    tcmi => {
+        Name => 'TCMediaInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::TCMediaInfo' },
+    },
+);
+
+# TimeCode media info (ref 12)
+%Image::ExifTool::QuickTime::TCMediaInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    4 => {
+        Name => 'TextFont',
+        Format => 'int16u',
+        PrintConv => { 0 => 'System' },
+    },
+    6 => {
+        Name => 'TextFace',
+        Format => 'int16u',
+        PrintConv => {
+            0 => 'Plain',
+            BITMASK => {
+                0 => 'Bold',
+                1 => 'Italic',
+                2 => 'Underline',
+                3 => 'Outline',
+                4 => 'Shadow',
+                5 => 'Condense',
+                6 => 'Extend',
+            },
+        },
+    },
+    8 => {
+        Name => 'TextSize',
+        Format => 'int16u',
+    },
+    # 10 - reserved
+    12 => {
+        Name => 'TextColor',
+        Format => 'int16u[3]',
+    },
+    18 => {
+        Name => 'BackgroundColor',
+        Format => 'int16u[3]',
+    },
+    24 => {
+        Name => 'FontName',
+        Format => 'pstring',
+        ValueConv => '$self->Decode($val, $self->Options("CharsetQuickTime"))',
     },
 );
@@ -1946,7 +7550,9 @@
 %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',
+        Format => 'undef',  # (necessary to prevent decoding as string!)
         RawConv => q{
             # ignore if self-contained (flags bit 0 set)
@@ -1955,9 +7561,19 @@
         },
     },
+    "url\0" => { # (written by GoPro)
+        Name => 'URL',
+        Format => 'undef',  # (necessary to prevent decoding as string!)
+        RawConv => q{
+            # ignore if self-contained (flags bit 0 set)
+            return undef if unpack("N",$val) & 0x01;
+            $_ = substr($val,4); s/\0.*//s; $_;
+        },
+    },
     'urn ' => {
         Name => 'URN',
+        Format => 'undef',  # (necessary to prevent decoding as string!)
         RawConv => q{
             return undef if unpack("N",$val) & 0x01;
-            $_ = substr($val,4); s/\0.*//s; $_;
+            $_ = substr($val,4); s/\0+/; /; s/\0.*//s; $_;
         },
     },
@@ -1980,5 +7596,6 @@
         Name => 'HandlerType',
         Format => 'undef[4]',
-        RawConv => '$$self{HandlerType} = $val unless $val eq "alis"; $val',
+        RawConv => '$$self{HandlerType} = $val unless $val eq "alis" or $val eq "url "; $val',
+        PrintConvColumns => 2,
         PrintConv => {
             alis => 'Alias Data', #PH
@@ -1987,4 +7604,5 @@
             ipsm => 'IPMP', #3
             m7sm => 'MPEG-7 Stream', #3
+            meta => 'NRT Metadata', #PH
             mdir => 'Metadata', #3
             mdta => 'Metadata Tags', #PH
@@ -1992,9 +7610,18 @@
             ocsm => 'Object Content', #3
             odsm => 'Object Descriptor', #3
+            priv => 'Private', #PH
             sdsm => 'Scene Description', #3
             soun => 'Audio Track',
             text => 'Text', #PH (but what type? subtitle?)
+            tmcd => 'Time Code', #PH
            'url '=> 'URL', #3
             vide => 'Video Track',
+            subp => 'Subpicture', #http://www.google.nl/patents/US7778526
+            nrtm => 'Non-Real Time Metadata', #PH (Sony ILCE-7S) [how is this different from "meta"?]
+            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)
         },
     },
@@ -2034,6 +7661,67 @@
     28 => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         Format => 'undef[$val{13}]',
         RawConv => '$self->ValidateImage(\$val, $tag)',
+    },
+);
+
+# 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)',
     },
 );
@@ -2043,14 +7731,24 @@
     GROUPS => { 2 => 'Video' },
     Rotation => {
+        Notes => q{
+            writing this tag updates QuickTime MatrixStructure for all tracks with a
+            non-zero image size
+        },
         Require => {
             0 => 'QuickTime:MatrixStructure',
             1 => 'QuickTime:HandlerType',
         },
+        Writable => 1,
+        Protected => 1,
+        WriteAlso => {
+            MatrixStructure => 'Image::ExifTool::QuickTime::GetRotationMatrix($val)',
+        },
         ValueConv => 'Image::ExifTool::QuickTime::CalcRotation($self)',
+        ValueConvInv => '$val',
     },
     AvgBitrate => {
         Priority => 0,  # let QuickTime::AvgBitrate take priority
         Require => {
-            0 => 'QuickTime::MovieDataSize',
+            0 => 'QuickTime::MediaDataSize',
             1 => 'QuickTime::Duration',
         },
@@ -2058,5 +7756,11 @@
             return undef unless $val[1];
             $val[1] /= $$self{TimeScale} if $$self{TimeScale};
-            return int($val[0] * 8 / $val[1] + 0.5);
+            my $key = 'MediaDataSize';
+            my $size = $val[0];
+            for (;;) {
+                $key = $self->NextTagKey($key) or last;
+                $size += $self->GetValue($key, 'ValueConv');
+            }
+            return int($size * 8 / $val[1] + 0.5);
         },
         PrintConv => 'ConvertBitrate($val)',
@@ -2066,8 +7770,5 @@
         Groups => { 2 => 'Location' },
         ValueConv => 'my @c = split " ", $val; $c[0]',
-        PrintConv => q{
-            require Image::ExifTool::GPS;
-            Image::ExifTool::GPS::ToDMS($self, $val, 1, 'N');
-        },
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
     },
     GPSLongitude => {
@@ -2075,8 +7776,5 @@
         Groups => { 2 => 'Location' },
         ValueConv => 'my @c = split " ", $val; $c[1]',
-        PrintConv => q{
-            require Image::ExifTool::GPS;
-            Image::ExifTool::GPS::ToDMS($self, $val, 1, 'E');
-        },
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
     },
     # split altitude into GPSAltitude/GPSAltitudeRef like EXIF and XMP
@@ -2098,4 +7796,46 @@
         },
     },
+    GPSLatitude2 => {
+        Name => 'GPSLatitude',
+        Require => 'QuickTime:LocationInformation',
+        Groups => { 2 => 'Location' },
+        ValueConv => '$val =~ /Lat=([-+.\d]+)/; $1',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    },
+    GPSLongitude2 => {
+        Name => 'GPSLongitude',
+        Require => 'QuickTime:LocationInformation',
+        Groups => { 2 => 'Location' },
+        ValueConv => '$val =~ /Lon=([-+.\d]+)/; $1',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    },
+    GPSAltitude2 => {
+        Name => 'GPSAltitude',
+        Require => 'QuickTime:LocationInformation',
+        Groups => { 2 => 'Location' },
+        ValueConv => '$val =~ /Alt=([-+.\d]+)/; abs($1)',
+        PrintConv => '"$val m"',
+    },
+    GPSAltitudeRef2  => {
+        Name => 'GPSAltitudeRef',
+        Require => 'QuickTime:LocationInformation',
+        Groups => { 2 => 'Location' },
+        ValueConv => '$val =~ /Alt=([-+.\d]+)/; $1 < 0 ? 1 : 0',
+        PrintConv => {
+            0 => 'Above Sea Level',
+            1 => 'Below Sea Level',
+        },
+    },
+    CDDBDiscPlayTime => {
+        Require => 'CDDB1Info',
+        Groups => { 2 => 'Audio' },
+        ValueConv => '$val =~ /^..([a-z0-9]{4})/i ? hex($1) : undef',
+        PrintConv => 'ConvertDuration($val)',
+    },
+    CDDBDiscTracks => {
+        Require => 'CDDB1Info',
+        Groups => { 2 => 'Audio' },
+        ValueConv => '$val =~ /^.{6}([a-z0-9]{2})/i ? hex($1) : undef',
+    },
 );
 
@@ -2103,4 +7843,48 @@
 Image::ExifTool::AddCompositeTags('Image::ExifTool::QuickTime');
 
+
+#------------------------------------------------------------------------------
+# AutoLoad our routines when necessary
+#
+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';
+        return &$AUTOLOAD(@_);
+    } else {
+        return Image::ExifTool::DoAutoLoad($AUTOLOAD, @_);
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get rotation matrix
+# Inputs: 0) angle in degrees
+# Returns: 9-element rotation matrix as a string (with 0 x/y offsets)
+sub GetRotationMatrix($)
+{
+    my $ang = 3.1415926536 * shift() / 180;
+    my $cos = cos $ang;
+    my $sin = sin $ang;
+    my $msn = -$sin;
+    return "$cos $sin 0 $msn $cos 0 0 0 1";
+}
+
+#------------------------------------------------------------------------------
+# Get rotation angle from a matrix
+# Inputs: 0) rotation matrix as a string
+# Return: positive rotation angle in degrees rounded to 3 decimal points,
+#         or undef on error
+sub GetRotationAngle($)
+{
+    my $rotMatrix = shift;
+    my @a = split ' ', $rotMatrix;
+    return undef if $a[0]==0 and $a[1]==0;
+    # calculate the rotation angle (assume uniform rotation)
+    my $angle = atan2($a[1], $a[0]) * 180 / 3.14159;
+    $angle += 360 if $angle < 0;
+    return int($angle * 1000 + 0.5) / 1000;
+}
 
 #------------------------------------------------------------------------------
@@ -2110,8 +7894,8 @@
 sub CalcRotation($)
 {
-    my $exifTool = shift;
-    my $value = $$exifTool{VALUE};
+    my $et = shift;
+    my $value = $$et{VALUE};
     my ($i, $track);
-    # get the video track family 1 group (ie. "Track1");
+    # get the video track family 1 group (eg. "Track1");
     for ($i=0; ; ++$i) {
         my $idx = $i ? " ($i)" : '';
@@ -2119,5 +7903,5 @@
         last unless $$value{$tag};
         next unless $$value{$tag} eq 'vide';
-        $track = $exifTool->GetGroup($tag, 1);
+        $track = $et->GetGroup($tag, 1);
         last;
     }
@@ -2128,13 +7912,37 @@
         my $tag = "MatrixStructure$idx";
         last unless $$value{$tag};
-        next unless $exifTool->GetGroup($tag, 1) eq $track;
-        my @a = split ' ', $$value{$tag};
-        return undef unless $a[0] or $a[1];
-        # calculate the rotation angle (assume uniform rotation)
-        my $angle = atan2($a[1], $a[0]) * 180 / 3.14159;
-        $angle += 360 if $angle < 0;
-        return int($angle * 1000 + 0.5) / 1000;
+        next unless $et->GetGroup($tag, 1) eq $track;
+        return GetRotationAngle($$value{$tag});
     }
     return undef;
+}
+
+#------------------------------------------------------------------------------
+# Get MatrixStructure for a given rotation angle
+# Inputs: 0) rotation angle (deg), 1) ExifTool ref
+# Returns: matrix structure as a string, or undef if it can't be rotated
+# - requires ImageSizeLookahead to determine the video image size, and doesn't
+#   rotate matrix unless image size is valid
+sub GetMatrixStructure($$)
+{
+    my ($val, $et) = @_;
+    my @a = split ' ', $val;
+    # pass straight through if it already has an offset
+    return $val unless $a[6] == 0 and $a[7] == 0;
+    my @s = split ' ', $$et{ImageSizeLookahead};
+    my ($w, $h) = @s[12,13];
+    return undef unless $w and $h;  # don't rotate 0-sized track
+    $_ = Image::ExifTool::QuickTime::FixWrongFormat($_) foreach $w,$h;
+    # apply necessary offsets for the standard rotations
+    my $angle = GetRotationAngle($val);
+    return undef unless defined $angle;
+    if ($angle == 90) {
+        @a[6,7] = ($h, 0);
+    } elsif ($angle == 180) {
+        @a[6,7] = ($w, $h);
+    } elsif ($angle == 270) {
+        @a[6,7] = (0, $w);
+    }
+    return "@a";
 }
 
@@ -2145,5 +7953,5 @@
 sub CalcSampleRate($$)
 {
-    my ($exifTool, $valPt) = @_;
+    my ($et, $valPt) = @_;
     my @dat = unpack('N*', $$valPt);
     my ($num, $dur) = (0, 0);
@@ -2153,6 +7961,6 @@
         $dur += $dat[$i] * $dat[$i+1];  # total sample duration
     }
-    return undef unless $num and $dur and $$exifTool{MediaTS};
-    return $num * $$exifTool{MediaTS} / $dur;
+    return undef unless $num and $dur and $$et{MediaTS};
+    return $num * $$et{MediaTS} / $dur;
 }
 
@@ -2163,8 +7971,5 @@
     my $val = shift;
     return undef unless $val;
-    if ($val & 0xffff0000) {
-        $val = unpack('n',pack('N',$val));
-    }
-    return $val;
+    return $val & 0xfff00000 ? unpack('n',pack('N',$val)) : $val;
 }
 
@@ -2172,13 +7977,15 @@
 # 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($)
 {
     my $val = shift;
-    if ($val =~ /^([-+]\d{2}(?:\.\d*)?)([-+]\d{3}(?:\.\d*)?)([-+]\d+)?/) {
+    if ($val =~ /^([-+]\d{1,2}(?:\.\d*)?)([-+]\d{1,3}(?:\.\d*)?)([-+]\d+(?:\.\d*)?)?/) {
+        # +DD.DDD+DDD.DDD+AA.AAA
         $val = ($1 + 0) . ' ' . ($2 + 0);
         $val .= ' ' . ($3 + 0) if $3;
-    } elsif ($val =~ /^([-+])(\d{2})(\d{2}(?:\.\d*)?)([-+])(\d{3})(\d{2}(?:\.\d*)?)([-+]\d+)?/) {
+    } elsif ($val =~ /^([-+])(\d{2})(\d{2}(?:\.\d*)?)([-+])(\d{3})(\d{2}(?:\.\d*)?)([-+]\d+(?:\.\d*)?)?/) {
+        # +DDMM.MMM+DDDMM.MMM+AA.AAA
         my $lat = $2 + $3 / 60;
         $lat = -$lat if $1 eq '-';
@@ -2187,5 +7994,6 @@
         $val = "$lat $lon";
         $val .= ' ' . ($7 + 0) if $7;
-    } elsif ($val =~ /^([-+])(\d{2})(\d{2})(\d{2}(?:\.\d*)?)([-+])(\d{3})(\d{2})(\d{2}(?:\.\d*)?)([-+]\d+)?/) {
+    } elsif ($val =~ /^([-+])(\d{2})(\d{2})(\d{2}(?:\.\d*)?)([-+])(\d{3})(\d{2})(\d{2}(?:\.\d*)?)([-+]\d+(?:\.\d*)?)?/) {
+        # +DDMMSS.SSS+DDDMMSS.SSS+AA.AAA
         my $lat = $2 + $3 / 60 + $4 / 3600;
         $lat = -$lat if $1 eq '-';
@@ -2199,4 +8007,49 @@
 
 #------------------------------------------------------------------------------
+# Convert Nero chapter list (ref ffmpeg libavformat/movenc.c)
+# Inputs: 0) binary chpl data
+# Returns: chapter list
+sub ConvertChapterList($)
+{
+    my $val = shift;
+    my $size = length $val;
+    return '<invalid>' if $size < 9;
+    my $num = Get8u(\$val, 8);
+    my ($i, @chapters);
+    my $pos = 9;
+    for ($i=0; $i<$num; ++$i) {
+        last if $pos + 9 > $size;
+        my $dur = Get64u(\$val, $pos) / 10000000;
+        my $len = Get8u(\$val, $pos + 8);
+        last if $pos + 9 + $len > $size;
+        my $title = substr($val, $pos + 9, $len);
+        $pos += 9 + $len;
+        push @chapters, "$dur $title";
+    }
+    return \@chapters;  # return as a list
+}
+
+#------------------------------------------------------------------------------
+# Print conversion for a Nero chapter list item
+# Inputs: 0) ValueConv chapter string
+# Returns: formatted chapter string
+sub PrintChapter($)
+{
+    my $val = shift;
+    $val =~ /^(\S+) (.*)/ or return $val;
+    my ($dur, $title) = ($1, $2);
+    my $h = int($dur / 3600);
+    $dur -= $h * 3600;
+    my $m = int($dur / 60);
+    my $s = $dur - $m * 60;
+    my $ss = sprintf('%06.3f', $s);
+    if ($ss >= 60) {
+        $ss = '00.000';
+        ++$m >= 60 and $m -= 60, ++$h;
+    }
+    return sprintf("[%d:%.2d:%s] %s",$h,$m,$ss,$title);
+}
+
+#------------------------------------------------------------------------------
 # Format GPSCoordinates for printing
 # Inputs: 0) string with numerical lat, lon and optional alt, separated by spaces
@@ -2205,9 +8058,8 @@
 sub PrintGPSCoordinates($)
 {
-    my ($val, $exifTool) = @_;
-    require Image::ExifTool::GPS;
+    my ($val, $et) = @_;
     my @v = split ' ', $val;
-    my $prt = Image::ExifTool::GPS::ToDMS($exifTool, $v[0], 1, "N") . ', ' .
-              Image::ExifTool::GPS::ToDMS($exifTool, $v[1], 1, "E");
+    my $prt = Image::ExifTool::GPS::ToDMS($et, $v[0], 1, "N") . ', ' .
+              Image::ExifTool::GPS::ToDMS($et, $v[1], 1, "E");
     if (defined $v[2]) {
         $prt .= ', ' . ($v[2] < 0 ? -$v[2] . ' m Below' : $v[2] . ' m Above') . ' Sea Level';
@@ -2218,16 +8070,16 @@
 #------------------------------------------------------------------------------
 # 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
@@ -2238,4 +8090,508 @@
 
 #------------------------------------------------------------------------------
+# 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
+# Returns: new tagInfo hash ref, or undef if invalid
+sub GetLangInfoQT($$$)
+{
+    my ($et, $tagInfo, $langCode) = @_;
+    my $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $langCode);
+    if ($langInfo) {
+        $$et{QTLang} or $$et{QTLang} = [ ];
+        push @{$$et{QTLang}}, $$langInfo{Name};
+    }
+    return $langInfo;
+}
+
+#------------------------------------------------------------------------------
+# Get variable-length integer from data (used by ParseItemLocation)
+# Inputs: 0) data ref, 1) start position, 2) integer size in bytes (0, 4 or 8),
+#         3) default value
+# Returns: integer value, and updates current position
+sub GetVarInt($$$;$)
+{
+    my ($dataPt, $pos, $n, $default) = @_;
+    my $len = length $$dataPt;
+    $_[1] = $pos + $n;  # update current position
+    return undef if $pos + $n > $len;
+    if ($n == 0) {
+        return $default || 0;
+    } elsif ($n == 4) {
+        return Get32u($dataPt, $pos);
+    } elsif ($n == 8) {
+        return Get64u($dataPt, $pos);
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Get null-terminated string from binary data (used by ParseItemInfoEntry)
+# Inputs: 0) data ref, 1) start position
+# Returns: string, and updates current position
+sub GetString($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $len = length $$dataPt;
+    my $str = '';
+    while ($pos < $len) {
+        my $ch = substr($$dataPt, $pos, 1);
+        ++$pos;
+        last if ord($ch) == 0;
+        $str .= $ch;
+    }
+    $_[1] = $pos;   # update current position
+    return $str;
+}
+
+#------------------------------------------------------------------------------
+# Get a printable version of the tag ID
+# 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 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;
+}
+
+#==============================================================================
+# The following ParseXxx routines parse various boxes to extract this
+# information about embedded items in a $$et{ItemInfo} hash, keyed by item ID:
+#
+# iloc:
+#  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 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
+#  ContentType        - mime type of item
+#  ContentEncoding    - item encoding
+#  URI                - URI of a 'uri '-type item
+# ipma:
+#  Association        - list of associated properties in the ipco container
+#  Essential          - list of "essential" flags for the associated properties
+# cdsc:
+#  RefersTo           - hash lookup of flags based on referred item ID
+# other:
+#  DocNum             - exiftool document number for this item
+#
+#------------------------------------------------------------------------------
+# 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;
+    my $ver = Get8u(\$val, 0);
+    my $siz = Get16u(\$val, 4);
+    my $noff = ($siz >> 12);
+    my $nlen = ($siz >> 8) & 0x0f;
+    my $nbas = ($siz >> 4) & 0x0f;
+    my $nind = $siz & 0x0f;
+    if ($ver < 2) {
+        $num = Get16u(\$val, 6);
+        $pos = 8;
+    } else {
+        return undef if $len < 10;
+        $num = Get32u(\$val, 6);
+        $pos = 10;
+    }
+    for ($i=0; $i<$num; ++$i) {
+        if ($ver < 2) {
+            return undef if $pos + 2 > $len;
+            $id = Get16u(\$val, $pos);
+            $pos += 2;
+        } else {
+            return undef if $pos + 4 > $len;
+            $id = Get32u(\$val, $pos);
+            $pos += 4;
+        }
+        if ($ver == 1 or $ver == 2) {
+            return undef if $pos + 2 > $len;
+            $$items{$id}{ConstructionMethod} = Get16u(\$val, $pos) & 0x0f;
+            $pos += 2;
+        }
+        return undef if $pos + 2 > $len;
+        $$items{$id}{DataReferenceIndex} = Get16u(\$val, $pos);
+        $pos += 2;
+        $$items{$id}{BaseOffset} = GetVarInt(\$val, $pos, $nbas);
+        return undef if $pos + 2 > $len;
+        my $ext_num = Get16u(\$val, $pos);
+        $pos += 2;
+        my @extents;
+        for ($j=0; $j<$ext_num; ++$j) {
+            if ($ver == 1 or $ver == 2) {
+                $extent_index = GetVarInt(\$val, $pos, $nind, 1);
+            }
+            $extent_offset = GetVarInt(\$val, $pos, $noff);
+            $extent_length = GetVarInt(\$val, $pos, $nlen);
+            return undef unless defined $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;
+    }
+    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
+# Returns: undef, and fills in ExifTool ItemInfo hash
+sub ParseItemInfoEntry($$)
+{
+    my ($val, $et) = @_;
+    my $id;
+
+    my $verbose = $$et{IsWriting} ? 0 : $et->Options('Verbose');
+    my $items = $$et{ItemInfo} || ($$et{ItemInfo} = { });
+    my $len = length $val;
+    return undef if $len < 4;
+    my $ver = Get8u(\$val, 0);
+    my $pos = 4;
+    return undef if $pos + 4 > $len;
+    if ($ver == 0 or $ver == 1) {
+        $id = Get16u(\$val, $pos);
+        $$items{$id}{ProtectionIndex} = Get16u(\$val, $pos + 2);
+        $pos += 4;
+        $$items{$id}{Name} = GetString(\$val, $pos);
+        $$items{$id}{ContentType} = GetString(\$val, $pos);
+        $$items{$id}{ContentEncoding} = GetString(\$val, $pos);
+    } else {
+        if ($ver == 2) {
+            $id = Get16u(\$val, $pos);
+            $pos += 2;
+        } elsif ($ver == 3) {
+            $id = Get32u(\$val, $pos);
+            $pos += 4;
+        }
+        return undef if $pos + 6 > $len;
+        $$items{$id}{ProtectionIndex} = Get16u(\$val, $pos);
+        my $type = substr($val, $pos + 2, 4);
+        $$items{$id}{Type} = $type;
+        $pos += 6;
+        $$items{$id}{Name} = GetString(\$val, $pos);
+        if ($type eq 'mime') {
+            $$items{$id}{ContentType} = GetString(\$val, $pos);
+            $$items{$id}{ContentEncoding} = GetString(\$val, $pos);
+        } elsif ($type eq 'uri ') {
+            $$items{$id}{URI} = GetString(\$val, $pos);
+        }
+    }
+    $et->VPrint(1, "$$et{INDENT}  Item $id: Type=", $$items{$id}{Type} || '',
+                   ' Name=', $$items{$id}{Name} || '',
+                   ' ContentType=', $$items{$id}{ContentType} || '',
+                   "\n") if $verbose > 1;
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Parse item property association (ipma) box (ref https://github.com/gpac/gpac/blob/master/src/isomedia/iff.c)
+# Inputs: 0) ipma data, 1) ExifTool ref
+# Returns: undef, and fills in ExifTool ItemInfo hash
+sub ParseItemPropAssoc($$)
+{
+    my ($val, $et) = @_;
+    my ($i, $j, $id);
+
+    my $verbose = $$et{IsWriting} ? 0 : $et->Options('Verbose');
+    my $items = $$et{ItemInfo} || ($$et{ItemInfo} = { });
+    my $len = length $val;
+    return undef if $len < 8;
+    my $ver = Get8u(\$val, 0);
+    my $flg = Get32u(\$val, 0);
+    my $num = Get32u(\$val, 4);
+    my $pos = 8;
+    for ($i=0; $i<$num; ++$i) {
+        if ($ver == 0) {
+            return undef if $pos + 3 > $len;
+            $id = Get16u(\$val, $pos);
+            $pos += 2;
+        } else {
+            return undef if $pos + 5 > $len;
+            $id = Get32u(\$val, $pos);
+            $pos += 4;
+        }
+        my $n = Get8u(\$val, $pos++);
+        my (@association, @essential);
+        if ($flg & 0x01) {
+            return undef if $pos + $n * 2 > $len;
+            for ($j=0; $j<$n; ++$j) {
+                my $tmp = Get16u(\$val, $pos + $j * 2);
+                push @association, $tmp & 0x7fff;
+                push @essential, ($tmp & 0x8000) ? 1 : 0;
+            }
+            $pos += $n * 2;
+        } else {
+            return undef if $pos + $n > $len;
+            for ($j=0; $j<$n; ++$j) {
+                my $tmp = Get8u(\$val, $pos + $j);
+                push @association, $tmp & 0x7f;
+                push @essential, ($tmp & 0x80) ? 1 : 0;
+            }
+            $pos += $n;
+        }
+        $$items{$id}{Association} = \@association;
+        $$items{$id}{Essential} = \@essential;
+        $et->VPrint(1, "$$et{INDENT}  Item $id properties: @association\n") if $verbose > 1;
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Process item information now
+# Inputs: 0) ExifTool ref
+sub HandleItemInfo($)
+{
+    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;
+            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");
+            }
+            # 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 ($warn) {
+                $et->VPrint(0, "$$et{INDENT}    [not extracted]  ($warn)\n") if $verbose > 2;
+                next;
+            }
+            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}}) {
+                $val .= $buff if defined $buff;
+                $raf->Seek($$extent[1] + $base, 0) or last;
+                $raf->Read($buff, $$extent[2]) or last;
+            }
+            next unless defined $buff;
+            $buff = $val . $buff if length $val;
+            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) {
+                if ($buff =~ /^(MM\0\x2a|II\x2a\0)/) {
+                    $et->Warn('Missing Exif header');
+                    $start = 0;
+                } elsif ($buff =~ /^Exif\0\0/) {
+                    # (haven't seen this yet, but it is just a matter of time
+                    #  until someone screws it up like this)
+                    $et->Warn('Missing Exif header size');
+                    $start = 6;
+                } else {
+                    my $n = unpack('N', $buff);
+                    $start = 4 + $n; # skip "Exif\0\0" header if it exists
+                    if ($start > length($buff)) {
+                        $et->Warn('Invalid EXIF header');
+                        next;
+                    }
+                    if ($$et{HTML_DUMP}) {
+                        $et->HDump($pos, 4, 'Exif header length', "Value: $n");
+                        $et->HDump($pos+4, $start-4, 'Exif header') if $n;
+                    }
+                }
+                $subTable = GetTagTable('Image::ExifTool::Exif::Main');
+                $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 + $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}) {
+                # set document number if this doesn't refer to the primary document
+                $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+                # associate this document number with the lowest item index
+                my ($lowest) = sort { $a <=> $b } keys %{$$item{RefersTo}};
+                $$items{$lowest}{DocNum} = $$et{DOC_NUM};
+            }
+            $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}) {
+        my ($dirInfo, $subTable, $proc) = @{$$et{ItemPropertyContainer}};
+        $$et{IsItemProperty} = 1;   # set item property flag
+        $et->ProcessDirectory($dirInfo, $subTable, $proc);
+        delete $$et{ItemPropertyContainer};
+        delete $$et{IsItemProperty};
+        delete $$et{DOC_NUM};
+    }
+    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
@@ -2243,11 +8599,11 @@
 sub ProcessMetaData($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = length $$dataPt;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     return 0 unless $dirLen >= 2;
     my $count = Get16u($dataPt, 0);
-    $verbose and $exifTool->VerboseDir('MetaData', $count);
+    $verbose and $et->VerboseDir('MetaData', $count);
     my $i;
     my $pos = 2;
@@ -2260,5 +8616,5 @@
         my $enc  = Get16u($dataPt, $pos + 8);
         my $val  = substr($$dataPt, $pos + 10, $size);
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($tagInfo) {
             # convert language code to ASCII (ignore read-only bit)
@@ -2266,8 +8622,8 @@
             # handle alternate languages
             if ($lang) {
-                my $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang);
+                my $langInfo = GetLangInfoQT($et, $tagInfo, $lang);
                 $tagInfo = $langInfo if $langInfo;
             }
-            $verbose and $exifTool->VerboseInfo($tag, $tagInfo,
+            $verbose and $et->VerboseInfo($tag, $tagInfo,
                 Value  => $val,
                 DataPt => $dataPt,
@@ -2276,10 +8632,10 @@
             );
             # convert from UTF-16 BE if necessary
-            $val = $exifTool->Decode($val, 'UCS2') if $enc == 1;
+            $val = $et->Decode($val, 'UCS2') if $enc == 1;
             if ($enc == 0 and $$tagInfo{Unknown}) {
                 # binary data
-                $exifTool->FoundTag($tagInfo, \$val);
+                $et->FoundTag($tagInfo, \$val);
             } else {
-                $exifTool->FoundTag($tagInfo, $val);
+                $et->FoundTag($tagInfo, $val);
             }
         }
@@ -2290,21 +8646,153 @@
 
 #------------------------------------------------------------------------------
-# Process Meta keys and add tags to the ItemList table ('mdta' handler) (ref PH)
+# Process sample description table
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+# (ref https://developer.apple.com/library/content/documentation/QuickTime/QTFF/QTFFChap2/qtff2.html#//apple_ref/doc/uid/TP40000939-CH204-25691)
+sub ProcessSampleDesc($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $pos = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $pos);
+    return 0 if $pos + 8 > $dirLen;
+
+    my $num = Get32u($dataPt, 4);   # get number of sample entries in table
+    $pos += 8;
+    my $i;
+    for ($i=0; $i<$num; ++$i) {     # loop through sample entries
+        last if $pos + 8 > $dirLen;
+        my $size = Get32u($dataPt, $pos);
+        last if $pos + $size > $dirLen;
+        $$dirInfo{DirStart} = $pos;
+        $$dirInfo{DirLen} = $size;
+        ProcessHybrid($et, $dirInfo, $tagTablePtr);
+        $pos += $size;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process hybrid binary data + QuickTime container (ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessHybrid($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    # brute-force search for child atoms after first 8 bytes of binary data
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || length($$dataPt) - $dirStart;
+    my $end = $dirStart + $dirLen;
+    my $pos = $dirStart + 8;   # skip length/version
+    my $try = $pos;
+    my $childPos;
+
+    while ($pos <= $end - 8) {
+        my $tag = substr($$dataPt, $try+4, 4);
+        # look only for well-behaved tag ID's
+        $tag =~ /[^\w ]/ and $try = ++$pos, next;
+        my $size = Get32u($dataPt, $try);
+        if ($size + $try == $end) {
+            # the atom ends exactly at the end of the parent -- this must be it
+            $childPos = $pos;
+            $$dirInfo{DirLen} = $pos;   # the binary data ends at the first child atom
+            last;
+        }
+        if ($size < 8 or $size + $try > $end - 8) {
+            $try = ++$pos;  # fail.  try next position
+        } else {
+            $try += $size;  # could be another atom following this
+        }
+    }
+    # process binary data
+    $$dirInfo{MixedTags} = 1; # ignore non-integer tag ID's
+    $et->ProcessBinaryData($dirInfo, $tagTablePtr);
+    # process child atoms if found
+    if ($childPos) {
+        $$dirInfo{DirStart} = $childPos;
+        $$dirInfo{DirLen} = $end - $childPos;
+        ProcessMOV($et, $dirInfo, $tagTablePtr);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process iTunes 'righ' atom (ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessRights($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = $$dirInfo{Base};
+    my $dirLen = length $$dataPt;
+    my $unknown = $$et{OPTIONS}{Unknown} || $$et{OPTIONS}{Verbose};
+    my $pos;
+    $et->VerboseDir('righ', $dirLen / 8);
+    for ($pos = 0; $pos + 8 <= $dirLen; $pos += 8) {
+        my $tag = substr($$dataPt, $pos, 4);
+        last if $tag eq "\0\0\0\0";
+        my $val = substr($$dataPt, $pos + 4, 4);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        unless ($tagInfo) {
+            next unless $unknown;
+            my $name = PrintableTagID($tag);
+            $tagInfo = {
+                Name => "Unknown_$name",
+                Description => "Unknown $name",
+                Unknown => 1,
+            },
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        $val = '0x' . unpack('H*', $val) unless $$tagInfo{Format};
+        $et->HandleTag($tagTablePtr, $tag, $val,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Start   => $pos + 4,
+            Size    => 4,
+        );
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process iTunes Encoding Params (ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessEncodingParams($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirLen = length $$dataPt;
+    my $pos;
+    $et->VerboseDir('Encoding Params', $dirLen / 8);
+    for ($pos = 0; $pos + 8 <= $dirLen; $pos += 8) {
+        my ($tag, $val) = unpack("x${pos}a4N", $$dataPt);
+        $et->HandleTag($tagTablePtr, $tag, $val);
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# 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($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    local $_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = length $$dataPt;
     my $out;
-    if ($exifTool->Options('Verbose')) {
-        $exifTool->VerboseDir('Keys');
-        $out = $exifTool->Options('TextOut');
+    if ($et->Options('Verbose')) {
+        $et->VerboseDir('Keys');
+        $out = $et->Options('TextOut');
     }
     my $pos = 8;
     my $index = 1;
-    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);
@@ -2314,42 +8802,61 @@
         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
-        }
-        next unless $tag;
+        $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 = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         unless ($tagInfo) {
-            $tagInfo = $exifTool->GetTagInfo($infoTable, $tag);
+            $tagInfo = $et->GetTagInfo($itemList, $tag);
             unless ($tagInfo) {
-                $tagInfo = $exifTool->GetTagInfo($userTable, $tag);
+                $tagInfo = $et->GetTagInfo($userData, $tag);
                 if (not $tagInfo and $tag =~ /^\w{3}\xa9$/) {
                     $tag = pack('N', unpack('V', $tag));
-                    $tagInfo = $exifTool->GetTagInfo($infoTable, $tag);
-                    $tagInfo or $tagInfo = $exifTool->GetTagInfo($userTable, $tag);
+                    $tagInfo = $et->GetTagInfo($itemList, $tag);
+                    $tagInfo or $tagInfo = $et->GetTagInfo($userData, $tag);
                 }
             }
         }
-        my $newInfo;
+        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. ]+$/ or $tag =~ /\w{4}/) {
             # 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 =~ tr/-0-9a-zA-Z_. //dc;
+            $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
-        delete $$infoTable{$index};
+        my $id = $$et{KeysCount} . '.' . $index;
+        if (ref $$itemList{$id} eq 'HASH') {
+            # delete other languages too if they exist
+            my $oldInfo = $$itemList{$id};
+            if ($$oldInfo{OtherLang}) {
+                delete $$itemList{$_} foreach @{$$oldInfo{OtherLang}};
+            }
+            delete $$itemList{$id};
+        }
         if ($newInfo) {
-            Image::ExifTool::AddTagToTable($infoTable, $index, $newInfo);
-            $out and printf $out "%sAdded ItemList Tag 0x%.4x = $tag\n", $exifTool->{INDENT}, $index;
+            AddTagToTable($itemList, $id, $newInfo);
+            $msg or $msg = '';
+            $out and print $out "$$et{INDENT}Added ItemList Tag $id = ($ns) $tag$msg\n";
         }
         $pos += $len;
@@ -2360,4 +8867,16 @@
 
 #------------------------------------------------------------------------------
+# Process keys in MetaSampleDesc directory
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessMetaKeys($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    # save this information to decode timed metadata samples when ExtractEmbedded is used
+    SaveMetaKeys($et, $dirInfo, $tagTablePtr) if $$et{OPTIONS}{ExtractEmbedded};
+    return 1;
+}
+
+#------------------------------------------------------------------------------
 # Process a QuickTime atom
 # Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) optional tag table ref
@@ -2365,13 +8884,29 @@
 sub ProcessMOV($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    local $_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
     my $dataPt = $$dirInfo{DataPt};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
+    my $validate = $$et{OPTIONS}{Validate};
     my $dataPos = $$dirInfo{Base} || 0;
-    my ($buff, $tag, $size, $track);
-
+    my $dirID = $$dirInfo{DirID} || '';
+    my $charsetQuickTime = $et->Options('CharsetQuickTime');
+    my ($buff, $tag, $size, $track, $isUserData, %triplet, $doDefaultLang, $index);
+    my ($dirEnd, $unkOpt, %saveOptions, $atomCount);
+
+    my $topLevel = not $$et{InQuickTime};
+    $$et{InQuickTime} = 1;
+    $$et{HandlerType} = $$et{MetaFormat} = '' unless defined $$et{HandlerType};
+
+    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
-    $raf or $raf = new File::RandomAccess($dataPt);
+    unless ($raf) {
+        $raf = new File::RandomAccess($dataPt);
+        $dirEnd = $dataPos + $$dirInfo{DirLen} + ($$dirInfo{DirStart} || 0) if $$dirInfo{DirLen};
+    }
     # skip leading bytes if necessary
     if ($$dirInfo{DirStart}) {
@@ -2382,63 +8917,150 @@
     $raf->Read($buff,8) == 8 or return 0;
     $dataPos += 8;
-    $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::Main');
+    if ($tagTablePtr) {
+        $isUserData = ($tagTablePtr eq \%Image::ExifTool::QuickTime::UserData);
+    } else {
+        $tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::Main');
+    }
     ($size, $tag) = unpack('Na4', $buff);
     if ($dataPt) {
-        $verbose and $exifTool->VerboseDir($$dirInfo{DirName});
+        $verbose and $et->VerboseDir($$dirInfo{DirName});
     } else {
         # check on file type if called with a RAF
         $$tagTablePtr{$tag} or return 0;
-        if ($tag eq 'ftyp') {
-            # read ahead 4 bytes to see what type of file this is
+        if ($tag eq 'ftyp' and $size >= 12) {
+            # read ftyp atom to see what type of file this is
             my $fileType;
-            if ($raf->Read($buff, 4) == 4) {
-                $raf->Seek(-4, 1);
+            if ($raf->Read($buff, $size-8) == $size-8) {
+                $raf->Seek(-($size-8), 1);
+                my $type = substr($buff, 0, 4);
                 # see if we know the extension for this file type
-                $fileType = $1 if $ftypLookup{$buff} and $ftypLookup{$buff} =~ /\(\.(\w+)/;
+                if ($ftypLookup{$type} and $ftypLookup{$type} =~ /\(\.(\w+)/) {
+                    $fileType = $1;
+                # check compatible brands
+                } elsif ($buff =~ /^.{8}(.{4})+(mp41|mp42|avc1)/s) {
+                    $fileType = 'MP4';
+                } elsif ($buff =~ /^.{8}(.{4})+(f4v )/s) {
+                    $fileType = 'F4V';
+                } elsif ($buff =~ /^.{8}(.{4})+(qt  )/s) {
+                    $fileType = 'MOV';
+                }
             }
             $fileType or $fileType = 'MP4'; # default to MP4
-            $exifTool->SetFileType($fileType, $mimeLookup{$fileType} || 'video/mp4');
+            $et->SetFileType($fileType, $mimeLookup{$fileType} || 'video/mp4');
+            # temporarily set ExtractEmbedded option for CRX files
+            $saveOptions{ExtractEmbedded} = $et->Options(ExtractEmbedded => 1) if $fileType eq 'CRX';
         } else {
-            $exifTool->SetFileType();       # MOV
+            $et->SetFileType();       # MOV
         }
         SetByteOrder('MM');
+        $$et{PRIORITY_DIR} = 'XMP';   # have XMP take priority
+    }
+    $$raf{NoBuffer} = 1 if $et->Options('FastScan'); # disable buffering in FastScan mode
+
+    my $ee = $$et{OPTIONS}{ExtractEmbedded};
+    if ($ee) {
+        $unkOpt = $$et{OPTIONS}{Unknown};
+        require 'Image/ExifTool/QuickTimeStream.pl';
+    }
+    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) {
-            last if $size == 0;
-            $size == 1 or $exifTool->Warn('Invalid atom size'), last;
-            $raf->Read($buff, 8) == 8 or last;
+            if ($size == 0) {
+                if ($dataPt) {
+                    # a zero size isn't legal for contained atoms, but Canon uses it to
+                    # terminate the CNTH atom (eg. CanonEOS100D.mov), so tolerate it here
+                    my $pos = $raf->Tell() - 4;
+                    $raf->Seek(0,2);
+                    my $str = $$dirInfo{DirName} . ' with ' . ($raf->Tell() - $pos) . ' bytes';
+                    $et->VPrint(0,"$$et{INDENT}\[Terminator found in $str remaining]");
+                } else {
+                    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 $et->Warn('Truncated atom header'), last;
             $dataPos += 8;
             my ($hi, $lo) = unpack('NN', $buff);
-            $size = $lo;
             if ($hi or $lo > 0x7fffffff) {
                 if ($hi > 0x7fffffff) {
-                    $exifTool->Warn('Invalid atom size');
+                    $et->Warn('Invalid atom size');
                     last;
-                } elsif (not $exifTool->Options('LargeFileSupport')) {
-                    $exifTool->Warn('End of processing at large atom (LargeFileSupport not enabled)');
+                } elsif (not $et->Options('LargeFileSupport')) {
+                    $et->Warn('End of processing at large atom (LargeFileSupport not enabled)');
                     last;
                 }
             }
-            $size = $hi * 4294967296 + $lo;
+            $size = $hi * 4294967296 + $lo - 16;
+            $size < 0 and $et->Warn('Invalid extended size'), last;
+        } else {
+            $size -= 8;
         }
-        $size -= 8;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        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
+            $tag = $$et{SET_GROUP1} . $tag;
+            if (not $$tagTablePtr{$tag} and $tagInfo) {
+                my %newInfo = %$tagInfo;
+                foreach ('Name', 'Description') {
+                    next unless $$tagInfo{$_};
+                    $newInfo{$_} = $$et{SET_GROUP1} . $$tagInfo{$_};
+                    $newInfo{$_} =~ s/^(Track\d+)Track/$1/; # remove duplicate "Track" in name
+                }
+                AddTagToTable($tagTablePtr, $tag, \%newInfo);
+            }
+        }
+        # set flag to store additional information for ExtractEmbedded option
+        my $handlerType = $$et{HandlerType};
+        if ($eeBox{$handlerType} and $eeBox{$handlerType}{$tag}) {
+            if ($ee) {
+                # (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}) {
+                EEWarn($et);
+            }
+        } elsif ($ee and $ee > 1 and $eeBox2{$handlerType} and $eeBox2{$handlerType}{$tag}) {
+            $eeTag = 1;
+            $$et{OPTIONS}{Unknown} = 1;
+        }
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+
+        $$et{OPTIONS}{Unknown} = $unkOpt if $eeTag;     # restore Unknown option
+
         # allow numerical tag ID's
         unless ($tagInfo) {
-            my $num = unpack('N', $tag);
-            if ($$tagTablePtr{$num}) {
-                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $num);
-                $tag = $num;
+            my $id = $$et{KeysCount} . '.' . unpack('N', $tag);
+            if ($$tagTablePtr{$id}) {
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $id);
+                $tag = $id;
             }
         }
         # generate tagInfo if Unknown option set
-        if (not defined $tagInfo and ($exifTool->{OPTIONS}->{Unknown} or
+        if (not defined $tagInfo and ($$et{OPTIONS}{Unknown} or
             $verbose or $tag =~ /^\xa9/))
         {
-            my $name = $tag;
-            my $n = ($name =~ s/([\x00-\x1f\x7f-\xff])/'x'.unpack('H*',$1)/eg);
-            # print in hex if tag is numerical
-            $name = sprintf('0x%.4x',unpack('N',$tag)) if $n > 2;
+            my $name = PrintableTagID($tag,1);
             if ($name =~ /^xa9(.*)/) {
                 $tagInfo = {
@@ -2450,28 +9072,157 @@
                     Name => "Unknown_$name",
                     Description => "Unknown $name",
-                    Unknown => 1,
-                    Binary => 1,
+                    %unknownInfo,
                 };
             }
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
         }
         # save required tag sizes
-        $exifTool->HandleTag($tagTablePtr, "$tag-size", $size) if $$tagTablePtr{"$tag-size"};
-        # load values only if associated with a tag (or verbose) and < 16MB long
-        if ((defined $tagInfo or $verbose) and $size < 0x1000000) {
+        if ($$tagTablePtr{"$tag-size"}) {
+            $et->HandleTag($tagTablePtr, "$tag-size", $size);
+            $et->HandleTag($tagTablePtr, "$tag-offset", $raf->Tell()) if $$tagTablePtr{"$tag-offset"};
+        }
+        # 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,2);
+                if ($size > 0x8000000) {
+                    $et->Warn("Skipping '${t}' atom > 128 MB", 1);
+                } else {
+                    $et->Warn("Skipping '${t}' atom > 32 MB", 2) or $ignore = 0;
+                }
+            }
+        }
+        if (defined $tagInfo and not $ignore) {
+            # set document number for this item property if necessary
+            if ($$et{IsItemProperty}) {
+                my $items = $$et{ItemInfo};
+                my ($id, $prop, $docNum, $lowest);
+                my $primary = $$et{PrimaryItem} || 0;
+ItemID:         foreach $id (keys %$items) {
+                    next unless $$items{$id}{Association};
+                    my $item = $$items{$id};
+                    foreach $prop (@{$$item{Association}}) {
+                        next unless $prop == $index;
+                        if ($id == $primary or (not $dontInherit{$tag} and
+                            (not $$item{RefersTo} or $$item{RefersTo}{$primary})))
+                        {
+                            # this is associated with the primary item or an item describing
+                            # the primary item, so consider this part of the main document
+                            undef $docNum;
+                            undef $lowest;
+                            last ItemID;
+                        } elsif ($$item{DocNum}) {
+                            # this property is already associated with an item that has
+                            # 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
+                            $lowest = $id;
+                        }
+                    }
+                }
+                if (not defined $docNum and defined $lowest) {
+                    # this is the first time we've seen metadata from this item,
+                    # so use a new document number
+                    $docNum = ++$$et{DOC_COUNT};
+                    $$items{$lowest}{DocNum} = $docNum;
+                }
+                $$et{DOC_NUM} = $docNum;
+            }
             my $val;
-            unless ($raf->Read($val, $size) == $size) {
-                $exifTool->Warn("Truncated '$tag' data");
+            my $missing = $size - $raf->Read($val, $size);
+            if ($missing) {
+                my $t = PrintableTagID($tag,2);
+                $et->Warn("Truncated '${t}' data (missing $missing bytes)");
                 last;
             }
             # use value to get tag info if necessary
-            $tagInfo or $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag, \$val);
+            $tagInfo or $tagInfo = $et->GetTagInfo($tagTablePtr, $tag, \$val);
             my $hasData = ($$dirInfo{HasData} and $val =~ /\0...data\0/s);
             if ($verbose and not $hasData) {
-                $exifTool->VerboseInfo($tag, $tagInfo,
-                    Value => $val,
-                    DataPt => \$val,
+                my $tval;
+                if ($tagInfo and $$tagInfo{Format}) {
+                    $tval = ReadValue(\$val, 0, $$tagInfo{Format}, $$tagInfo{Count}, length($val));
+                }
+                $et->VerboseInfo($tag, $tagInfo,
+                    Value   => $tval,
+                    DataPt  => \$val,
                     DataPos => $dataPos,
+                    Size    => $size,
+                    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) {
+                ParseTag($et, $tag, \$val);
+                # forget this tag if we generated it only for ExtractEmbedded
+                undef $tagInfo if $tagInfo and $$tagInfo{Unknown} and not $unkOpt;
+            }
+
+            # handle iTunesInfo mean/name/data triplets
+            if ($tagInfo and $$tagInfo{Triplet}) {
+                if ($tag eq 'data' and $triplet{mean} and $triplet{name}) {
+                    $tag = $triplet{name};
+                    # add 'mean' to name unless it is 'com.apple.iTunes'
+                    $tag = $triplet{mean} . '/' . $tag unless $triplet{mean} eq 'com.apple.iTunes';
+                    $tagInfo = $et->GetTagInfo($tagTablePtr, $tag, \$val);
+                    unless ($tagInfo) {
+                        my $name = $triplet{name};
+                        my $desc = $name;
+                        $name =~ tr/-_a-zA-Z0-9//dc;
+                        $desc =~ tr/_/ /;
+                        $tagInfo = {
+                            Name => $name,
+                            Description => $desc,
+                        };
+                        AddTagToTable($tagTablePtr, $tag, $tagInfo);
+                    }
+                    # ignore 8-byte header
+                    $val = substr($val, 8) if length($val) >= 8;
+                    unless ($$tagInfo{Format} or $$tagInfo{SubDirectory}) {
+                        # extract as binary if it contains any non-ASCII or control characters
+                        if ($val =~ /[^\x20-\x7e]/) {
+                            my $buff = $val;
+                            $val = \$buff;
+                        }
+                    }
+                    undef %triplet;
+                } else {
+                    undef %triplet if $tag eq 'mean';
+                    $triplet{$tag} = substr($val,4) if length($val) > 4;
+                    undef $tagInfo;  # don't store this tag
+                }
             }
             if ($tagInfo) {
@@ -2485,27 +9236,47 @@
                     }
                     my %dirInfo = (
-                        DataPt   => \$val,
-                        DataLen  => $size,
-                        DirStart => $start,
-                        DirLen   => $size - $start,
-                        DirName  => $$subdir{DirName} || $$tagInfo{Name},
-                        HasData  => $$subdir{HasData},
-                        Multi    => $$subdir{Multi},
-                        DataPos  => $dPos,
-                        # Base needed for IsOffset tags in binary data
-                        Base     => $base,
+                        DataPt     => \$val,
+                        DataLen    => $size,
+                        DirStart   => $start,
+                        DirLen     => $size - $start,
+                        DirName    => $$subdir{DirName} || $$tagInfo{Name},
+                        DirID      => $tag,
+                        HasData    => $$subdir{HasData},
+                        Multi      => $$subdir{Multi},
+                        IgnoreProp => $$subdir{IgnoreProp}, # (XML hack)
+                        DataPos    => $dPos,
+                        Base       => $base, # (needed for IsOffset tags in binary data)
                     );
+                    $dirInfo{BlockInfo} = $tagInfo if $$tagInfo{BlockExtract};
                     if ($$subdir{ByteOrder} and $$subdir{ByteOrder} =~ /^Little/) {
                         SetByteOrder('II');
                     }
-                    my $oldGroup1 = $exifTool->{SET_GROUP1};
-                    if ($$tagInfo{Name} eq 'Track') {
+                    my $oldGroup1 = $$et{SET_GROUP1};
+                    if ($$tagInfo{SubDirectory} and $$tagInfo{SubDirectory}{TagTable} and
+                        $$tagInfo{SubDirectory}{TagTable} eq 'Image::ExifTool::QuickTime::Track')
+                    {
                         $track or $track = 0;
-                        $exifTool->{SET_GROUP1} = 'Track' . (++$track);
+                        $$et{SET_GROUP1} = 'Track' . (++$track);
                     }
                     my $subTable = GetTagTable($$subdir{TagTable});
                     my $proc = $$subdir{ProcessProc};
-                    $exifTool->ProcessDirectory(\%dirInfo, $subTable, $proc) if $size > $start;
-                    $exifTool->{SET_GROUP1} = $oldGroup1;
+                    # make ProcessMOV() the default processing procedure for subdirectories
+                    $proc = \&ProcessMOV unless $proc or $$subTable{PROCESS_PROC};
+                    if ($size > $start) {
+                        # delay processing of ipco box until after all other boxes
+                        if ($tag eq 'ipco' and not $$et{IsItemProperty}) {
+                            $$et{ItemPropertyContainer} = [ \%dirInfo, $subTable, $proc ];
+                            $et->VPrint(0,"$$et{INDENT}\[Process ipco box later]");
+                        } else {
+                            $et->ProcessDirectory(\%dirInfo, $subTable, $proc);
+                        }
+                    }
+                    if ($tag eq 'stbl') {
+                        # process sample data when exiting SampleTable box if extracting embedded
+                        ProcessSamples($et) if $ee;
+                    } elsif ($tag eq 'minf') {
+                        $$et{HandlerType} = ''; # reset handler type at end of media info box
+                    }
+                    $$et{SET_GROUP1} = $oldGroup1;
                     SetByteOrder('MM');
                 } elsif ($hasData) {
@@ -2517,5 +9288,5 @@
                         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) {
@@ -2530,23 +9301,9 @@
                             if ($stringEncoding{$flags}) {
                                 # handle all string formats
-                                $value = $exifTool->Decode($value, $stringEncoding{$flags});
+                                $value = $et->Decode($value, $stringEncoding{$flags});
+                                # (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);
@@ -2558,24 +9315,18 @@
                             }
                         }
-                        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";
+                            my $langCode = GetLangCode($lang, $ctry);
+                            if ($langCode) {
+                                # get tagInfo for other language
+                                $langInfo = GetLangInfoQT($et, $tagInfo, $langCode);
+                                # save other language tag ID's so we can delete later if necessary
+                                if ($langInfo) {
+                                    $$tagInfo{OtherLang} or $$tagInfo{OtherLang} = [ ];
+                                    push @{$$tagInfo{OtherLang}}, $$langInfo{TagID};
                                 }
                             }
-                            $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang) if $lang;
                         }
                         $langInfo or $langInfo = $tagInfo;
-                        $exifTool->VerboseInfo($tag, $langInfo,
+                        $et->VerboseInfo($tag, $langInfo,
                             Value   => ref $value ? $$value : $value,
                             DataPt  => \$val,
@@ -2584,23 +9335,44 @@
                             Size    => $len,
                             Format  => $format,
-                            Extra   => sprintf(", Type='$type', Flags=0x%x",$flags)
+                            Index   => $index,
+                            Extra   => sprintf(", Type='${type}', Flags=0x%x, Lang=0x%.4x",$flags,$lang),
                         ) if $verbose;
-                        $exifTool->FoundTag($langInfo, $value) if defined $value;
+                        # 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/) {
+                } elsif ($tag =~ /^\xa9/ or $$tagInfo{IText}) {
                     # parse international text to extract all languages
                     my $pos = 0;
+                    if ($$tagInfo{Format}) {
+                        $et->FoundTag($tagInfo, ReadValue(\$val, 0, $$tagInfo{Format}, undef, length($val)));
+                        $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
@@ -2608,15 +9380,21 @@
                         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) {
+                                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", so
-                            # I can only assume that it is the most common one
-                            $str = $exifTool->Decode($str, 'MacRoman');
+                            # the spec says only "Macintosh text encoding", but
+                            # allow this to be configured by the user
+                            $str = $et->Decode($str, $charsetQuickTime);
                         } else {
                             # convert language code to ASCII (ignore read-only bit)
@@ -2624,24 +9402,82 @@
                             # may be either UTF-8 or UTF-16BE
                             my $enc = $str=~s/^\xfe\xff// ? 'UTF16' : 'UTF8';
-                            $str = $exifTool->Decode($str, $enc);
+                            $str = $et->Decode($str, $enc);
                         }
-                        $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $lang) if $lang;
-                        $exifTool->FoundTag($langInfo || $tagInfo, $str);
+                        $str =~ s/\0+$//;   # remove any trailing nulls (eg. 3gp tags)
+                        $langInfo = GetLangInfoQT($et, $tagInfo, $lang) if $lang;
+                        $et->FoundTag($langInfo || $tagInfo, $str);
                         $pos += $len;
                     }
                 } else {
-                    if ($$tagInfo{Format}) {
-                        $val = ReadValue(\$val, 0, $$tagInfo{Format}, $$tagInfo{Count}, length($val));
+                    my $format = $$tagInfo{Format};
+                    if ($format) {
+                        $val = ReadValue(\$val, 0, $format, $$tagInfo{Count}, length($val));
                     }
-                    $exifTool->FoundTag($tagInfo, $val);
+                    my $oldBase;
+                    if ($$tagInfo{SetBase}) {
+                        $oldBase = $$et{BASE};
+                        $$et{BASE} = $dataPos;
+                    }
+                    my $key = $et->FoundTag($tagInfo, $val);
+                    $$et{BASE} = $oldBase if defined $oldBase;
+                    # decode if necessary (NOTE: must be done after RawConv)
+                    if (defined $key and (not $format or $format =~ /^string/) and
+                        not $$tagInfo{Unknown} and not $$tagInfo{ValueConv} and
+                        not $$tagInfo{Binary} and defined $$et{VALUE}{$key} and not ref $val)
+                    {
+                        my $vp = \$$et{VALUE}{$key};
+                        if (not ref $$vp and length($$vp) <= 65536 and $$vp =~ /[\x80-\xff]/) {
+                            # the encoding of this is not specified, so use CharsetQuickTime
+                            # unless the string is valid UTF-8
+                            require Image::ExifTool::XMP;
+                            my $enc = Image::ExifTool::XMP::IsUTF8($vp) > 0 ? 'UTF8' : $charsetQuickTime;
+                            $$vp = $et->Decode($$vp, $enc);
+                        }
+                    }
                 }
             }
         } else {
-            $raf->Seek($size, 1) or $exifTool->Warn("Truncated '$tag' data"), last;
+            $et->VerboseInfo($tag, $tagInfo,
+                Size  => $size,
+                Extra => sprintf(' at offset 0x%.4x', $raf->Tell()),
+            ) if $verbose;
+            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)
         $raf->Read($buff, 8) == 8 or last;
-        $dataPos += $size + 8;
         ($size, $tag) = unpack('Na4', $buff);
+        ++$index if defined $index;
     }
+    # fill in missing defaults for alternate language tags
+    # (the first language is taken as the default)
+    if ($doDefaultLang and $$et{QTLang}) {
+QTLang: foreach $tag (@{$$et{QTLang}}) {
+            next unless defined $$et{VALUE}{$tag};
+            my $langInfo = $$et{TAG_INFO}{$tag} or next;
+            my $tagInfo = $$langInfo{SrcTagInfo} or next;
+            my $infoHash = $$et{TAG_INFO};
+            my $name = $$tagInfo{Name};
+            # loop through all instances of this tag name and generate the default-language
+            # version only if we don't already have a QuickTime tag with this name
+            my ($i, $key);
+            for ($i=0, $key=$name; $$infoHash{$key}; ++$i, $key="$name ($i)") {
+                next QTLang if $et->GetGroup($key, 0) eq 'QuickTime';
+            }
+            $et->FoundTag($tagInfo, $$et{VALUE}{$tag});
+        }
+        delete $$et{QTLang};
+    }
+    # 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;
 }
@@ -2653,7 +9489,7 @@
 sub ProcessQTIF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $table = GetTagTable('Image::ExifTool::QuickTime::ImageFile');
-    return ProcessMOV($exifTool, $dirInfo, $table);
+    return ProcessMOV($et, $dirInfo, $table);
 }
 
@@ -2673,9 +9509,9 @@
 
 This module contains routines required by Image::ExifTool to extract
-information from QuickTime and MP4 video, and M4A audio files.
+information from QuickTime and MP4 video, M4A audio, and HEIC image files.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/QuickTimeStream.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/QuickTimeStream.pl	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/QuickTimeStream.pl	(revision 34921)
@@ -0,0 +1,2721 @@
+#------------------------------------------------------------------------------
+# 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/
+#               6) Thomas Allen https://github.com/exiftool/exiftool/pull/62
+#------------------------------------------------------------------------------
+package Image::ExifTool::QuickTime;
+
+use strict;
+
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::QuickTime;
+
+sub Process_tx3g($$$);
+sub Process_marl($$$);
+sub Process_mebx($$$);
+sub ProcessFreeGPS($$$);
+sub ProcessFreeGPS2($$$);
+sub Process360Fly($$$);
+
+# 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)
+    ctbx => 1,  # ('marl' in GM videos)
+);
+
+# data lengths for each INSV record type
+my %insvDataLen = (
+    0x300 => 56,    # accelerometer
+    0x400 => 16,    # exposure (ref 6)
+    0x600 => 8,     # timestamps (ref 6)
+    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 49 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' } },
+    VideoTimeStamp => { Groups => { 2 => 'Video' } },
+    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' } },
+    SampleDateTime => {
+        Groups => { 2 => 'Time' },
+        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;
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+#
+# 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_GoPro',
+        Condition => '$$valPt !~ /^\0\0\xf2\xe1\xf0\xeeTT/',
+        SubDirectory => { TagTable => 'Image::ExifTool::GoPro::GPMF' },
+    },{
+        Name => 'gpmd_Rove', # Rove Stealth 4K encrypted text
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::Stream',
+            ProcessProc => \&Process_text,
+        },
+    }],
+    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' },
+    },
+    marl => {
+        Name => 'marl',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::marl' },
+    },
+    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 => q{
+        Tags extracted from the tx3g sbtl timed metadata of Yuneec drones, and
+        subtitle text in some other videos.
+    },
+    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',
+    DateTime => { # for date/time-format subtitle text
+        Groups => { 2 => 'Time' },
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    Text => { Groups => { 2 => 'Other' } },
+);
+
+%Image::ExifTool::QuickTime::INSV_MakerNotes = (
+    GROUPS => { 1 => 'MakerNotes', 2 => 'Camera' },
+    0x0a => 'SerialNumber',
+    0x12 => 'Model',
+    0x1a => 'Firmware',
+    0x2a => {
+        Name => 'Parameters',
+        ValueConv => '$val =~ tr/_/ /; $val',
+    },
+);
+
+%Image::ExifTool::QuickTime::Tags360Fly = (
+    PROCESS_PROC => \&Process360Fly,
+    NOTES => 'Timed metadata found in MP4 videos from the 360Fly.',
+    1 => {
+        Name => 'Accel360Fly',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Accel360Fly' },
+    },
+    2 => {
+        Name => 'Gyro360Fly',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Gyro360Fly' },
+    },
+    3 => {
+        Name => 'Mag360Fly',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Mag360Fly' },
+    },
+    5 => {
+        Name => 'GPS360Fly',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::GPS360Fly' },
+    },
+    6 => {
+        Name => 'Rot360Fly',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Rot360Fly' },
+    },
+    250 => {
+        Name => 'Fusion360Fly',
+        SubDirectory => { TagTable => 'Image::ExifTool::QuickTime::Fusion360Fly' },
+    },
+);
+
+%Image::ExifTool::QuickTime::Accel360Fly = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Location' },
+    1  => { Name => 'AccelMode', Unknown => 1 }, # (always 2 in my sample)
+    2  => {
+        Name => 'SampleTime',
+        Groups => { 2 => 'Video' },
+        Format => 'int64u',
+        ValueConv => '$val / 1e6',
+        PrintConv => 'ConvertDuration($val)',
+    },
+    10 => { Name => 'AccelYPR',  Format => 'float[3]' },
+);
+
+%Image::ExifTool::QuickTime::Gyro360Fly = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Location' },
+    1  => { Name => 'GyroMode', Unknown => 1 }, # (always 1 in my sample)
+    2  => {
+        Name => 'SampleTime',
+        Groups => { 2 => 'Video' },
+        Format => 'int64u',
+        ValueConv => '$val / 1e6',
+        PrintConv => 'ConvertDuration($val)',
+    },
+    10 => { Name => 'GyroYPR', Format => 'float[3]' },
+);
+
+%Image::ExifTool::QuickTime::Mag360Fly = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Location' },
+    1  => { Name => 'MagMode', Unknown => 1 }, # (always 1 in my sample)
+    2  => {
+        Name => 'SampleTime',
+        Groups => { 2 => 'Video' },
+        Format => 'int64u',
+        ValueConv => '$val / 1e6',
+        PrintConv => 'ConvertDuration($val)',
+    },
+    10 => { Name => 'MagnetometerXYZ', Format => 'float[3]' },
+);
+
+%Image::ExifTool::QuickTime::GPS360Fly = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Location' },
+    1  => { Name => 'GPSMode', Unknown => 1 }, # (always 16 in my sample)
+    2  => {
+        Name => 'SampleTime',
+        Groups => { 2 => 'Video' },
+        Format => 'int64u',
+        ValueConv => '$val / 1e6',
+        PrintConv => 'ConvertDuration($val)',
+    },
+    10 => { Name => 'GPSLatitude',  Format => 'float', PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")' },
+    14 => { Name => 'GPSLongitude', Format => 'float', PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")' },
+    18 => { Name => 'GPSAltitude',  Format => 'float', PrintConv => '"$val m"' }, # (questionable accuracy)
+    22 => {
+        Name => 'GPSSpeed',
+        Notes => 'converted to km/hr',
+        Format => 'int16u',
+        ValueConv => '$val * 0.036',
+        PrintConv => 'sprintf("%.1f",$val)',
+    },
+    24 => { Name => 'GPSTrack',     Format => 'int16u', ValueConv => '$val / 100' },
+    26 => { Name => 'Acceleration', Format => 'int16u', ValueConv => '$val / 1000' },
+);
+
+%Image::ExifTool::QuickTime::Rot360Fly = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Location' },
+    1  => { Name => 'RotMode', Unknown => 1 }, # (always 1 in my sample)
+    2  => {
+        Name => 'SampleTime',
+        Groups => { 2 => 'Video' },
+        Format => 'int64u',
+        ValueConv => '$val / 1e6',
+        PrintConv => 'ConvertDuration($val)',
+    },
+    10 => { Name => 'RotationXYZ', Format => 'float[3]' },
+);
+
+%Image::ExifTool::QuickTime::Fusion360Fly = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Location' },
+    1  => { Name => 'FusionMode', Unknown => 1 }, # (always 0 in my sample)
+    2  => {
+        Name => 'SampleTime',
+        Groups => { 2 => 'Video' },
+        Format => 'int64u',
+        ValueConv => '$val / 1e6',
+        PrintConv => 'ConvertDuration($val)',
+    },
+    10 => { Name => 'FusionYPR', Format => 'float[3]' },
+);
+
+# tags found in 'marl' ctbx timed metadata (ref PH)
+%Image::ExifTool::QuickTime::marl = (
+    PROCESS_PROC => \&Process_marl,
+    GROUPS => { 2 => 'Other' },
+    NOTES => 'Tags extracted from the marl ctbx timed metadata of GM cars.',
+);
+
+#------------------------------------------------------------------------------
+# 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 (s)
+#         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');
+    }
+}
+
+#------------------------------------------------------------------------------
+# Handle tags that we found in the subtitle 'text'
+# Inputs: 0) ExifTool ref, 1) tag table ref, 2) hash of tag names/values
+sub HandleTextTags($$$)
+{
+    my ($et, $tagTbl, $tags) = @_;
+    my $tag;
+    delete $$tags{done};
+    delete $$tags{GPSTimeStamp} if $$tags{GPSDateTime};
+    foreach $tag (sort keys %$tags) {
+        $et->HandleTag($tagTbl, $tag => $$tags{$tag});
+    }
+    $$et{UnknownTextCount} = 0;
+    undef %$tags;   # clear the hash
+}
+
+#------------------------------------------------------------------------------
+# Process subtitle 'text'
+# Inputs: 0) ExifTool ref, 1) data ref or dirInfo ref, 2) tag table ref
+sub Process_text($$$)
+{
+    my ($et, $dataPt, $tagTbl) = @_;
+    my %tags;
+
+    return if $$et{NoMoreTextDecoding};
+
+    if (ref $dataPt eq 'HASH') {
+        my $dirName = $$dataPt{DirName};
+        $dataPt = $$dataPt{DataPt};
+        $et->VerboseDir($dirName, undef, length($$dataPt));
+    }
+
+    while ($$dataPt =~ /\$(\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 $time = "$1:$2:$3";
+            if ($$et{LastTime}) {
+                if ($$et{LastTime} eq $time) {
+                    $$et{DOC_NUM} = $$et{LastDoc};
+                } elsif (%tags) {
+                    HandleTextTags($et, $tagTbl, \%tags);
+                    $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+                }
+            }
+            $$et{LastTime} = $time;
+            $$et{LastDoc} = $$et{DOC_NUM};
+            my $year = $14 + ($14 >= 70 ? 1900 : 2000);
+            my $dateTime = sprintf('%.4d:%.2d:%.2d %sZ', $year, $13, $12, $time);
+            $tags{GPSDateTime} = $dateTime;
+            $tags{GPSLatitude} = (($4 || 0) + $5/60) * ($6 eq 'N' ? 1 : -1);
+            $tags{GPSLongitude} = (($7 || 0) + $8/60) * ($9 eq 'E' ? 1 : -1);
+            if (length $10) {
+                $tags{GPSSpeed} = $10 * $knotsToKph;
+                $tags{GPSSpeedRef} = 'K';
+            }
+            if (length $11) {
+                $tags{GPSTrack} = $11;
+                $tags{GPSTrackRef} = 'T';
+            }
+        } elsif ($tag =~ /^[A-Z]{2}GGA$/ and $dat =~ /^,(\d{2})(\d{2})(\d+(?:\.\d*)?),(\d*?)(\d{1,2}\.\d+),([NS]),(\d*?)(\d{1,2}\.\d+),([EW]),[1-6]?,(\d+)?,(\.\d+|\d+\.?\d*)?,(-?\d+\.?\d*)?,M?/s) {
+            my $time = "$1:$2:$3";
+            if ($$et{LastTime}) {
+                if ($$et{LastTime} eq $time) {
+                    $$et{DOC_NUM} = $$et{LastDoc};
+                } elsif (%tags) {
+                    HandleTextTags($et, $tagTbl, \%tags);
+                    $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+                }
+            }
+            $$et{LastTime} = $time;
+            $$et{LastDoc} = $$et{DOC_NUM};
+            $tags{GPSTimeStamp} = $time;
+            $tags{GPSLatitude} = (($4 || 0) + $5/60) * ($6 eq 'N' ? 1 : -1);
+            $tags{GPSLongitude} = (($7 || 0) + $8/60) * ($9 eq 'E' ? 1 : -1);
+            $tags{GPSSatellites} = $10 if defined $10;
+            $tags{GPSDOP} = $11 if defined $11;
+            $tags{GPSAltitude} = $12 if defined $12;
+        } elsif ($tag eq 'BEGINGSENSOR' and $dat =~ /^:([-+]\d+\.\d+):([-+]\d+\.\d+):([-+]\d+\.\d+)/) {
+            $tags{Accelerometer} = "$1 $2 $3";
+        } elsif ($tag eq 'TIME' and $dat =~ /^:(\d+)/) {
+            $tags{TimeCode} = $1 / ($$et{MediaTS} || 1);
+        } elsif ($tag eq 'BEGIN') {
+            $tags{Text} = $dat if length $dat;
+            $tags{done} = 1;
+        } elsif ($tag ne 'END') {
+            $tags{Text} = "\$$tag$dat";
+        }
+    }
+    %tags and HandleTextTags($et, $tagTbl, \%tags), return;
+
+    # 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 ($$dataPt =~ /^\0\0(..\xaa\xaa|\xf2\xe1\xf0\xee)/s and length $$dataPt >= 282) {
+        my $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 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($$dataPt, 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($$dataPt, 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($$dataPt, 0x39, 5)));
+            $tags{GPSAltitude} = $val + 0 if $val =~ /^[-+]\d+$/;
+            $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 0x3e, 3)));
+            if ($val =~ /^\d+$/) {
+                $tags{GPSSpeed} = $val + 0;
+                $tags{GPSSpeedRef} = 'K';
+            }
+            if ($$dataPt =~ /^\0\0..\xaa\xaa/s) { # (BlueSkySea)
+                $val = pack('C*', map { $_ ^ 0xaa } unpack('C*', substr($$dataPt, 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($$dataPt, 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($$dataPt, 0x41, 195)));
+                push @acc, $1, $2, $3 while $val =~ /\G([-+]\d{3})([-+]\d{3})([-+]\d{3})/g;
+                $tags{Accelerometer} = "@acc" if @acc;
+            }
+        }
+        %tags and HandleTextTags($et, $tagTbl, \%tags), return;
+    }
+
+    # 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 ($$dataPt =~ /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 $$dataPt =~ /,\s*H\s+([-+]?\d+\.?\d*)m/;
+        if ($$dataPt =~ /,\s*H.S\s+([-+]?\d+\.?\d*)/) {
+            $tags{GPSSpeed} = $1 * $mpsToKph;
+            $tags{GPSSpeedRef} = 'K';
+        }
+        $tags{Distance} = $1 * $mpsToKph if $$dataPt =~ /,\s*D\s+(\d+\.?\d*)m/;
+        $tags{VerticalSpeed} = $1 if $$dataPt =~ /,\s*V.S\s+([-+]?\d+\.?\d*)/;
+        $tags{FNumber} = $1 if $$dataPt =~ /\bF\/(\d+\.?\d*)/;
+        $tags{ExposureTime} = 1 / $1 if $$dataPt =~ /\bSS\s+(\d+\.?\d*)/;
+        $tags{ExposureCompensation} = ($1 / ($2 || 1)) if $$dataPt =~ /\bEV\s+([-+]?\d+\.?\d*)(\/\d+)?/;
+        $tags{ISO} = $1 if $$dataPt =~ /\bISO\s+(\d+\.?\d*)/;
+        HandleTextTags($et, $tagTbl, \%tags);
+        return;
+    }
+
+    # 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 ($$dataPt =~ /^A,(\d{2})(\d{2})(\d{2}),(\d{2})(\d{2})(\d{2}(\.\d+)?)/) {
+        $tags{GPSDateTime} = "20$3:$2:$1 $4:$5:$6Z";
+        if ($$dataPt =~ /^A,.*?,.*?,(\d{2})(\d+\.\d+),([NS])/) {
+            $tags{GPSLatitude} = ($1 + $2/60) * ($3 eq 'S' ? -1 : 1);
+        }
+        if ($$dataPt =~ /^A,.*?,.*?,.*?,.*?,(\d{3})(\d+\.\d+),([EW])/) {
+            $tags{GPSLongitude} = ($1 + $2/60) * ($3 eq 'W' ? -1 : 1);
+        }
+        my @a = split ',', $$dataPt;
+        $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*$//;
+        HandleTextTags($et, $tagTbl, \%tags);
+        return;
+    }
+
+    # check for Roadhawk dashcam text
+    # ".;;;;D?JL;6+;;;D;R?;4;;;;DBB;;O;;;=D;L;;HO71G>F;-?=J-F:FNJJ;DPP-JF3F;;PL=DBRLBF0F;=?DNF-RD-PF;N;?=JF;;?D=F:*6F~"
+    # decoded:
+    # "X0000.2340Y-000.0720Z0000.9900G0001.0400$GPRMC,082138,A,5330.6683,N,00641.9749,W,012.5,87.86,050213,002.1,A"
+    # (note: "002.1" is magnetic variation and is not decoded; it should have ",E" or ",W" afterward for direction)
+    if ($$dataPt =~ /\*[0-9A-F]{2}~$/) {
+        # (ref https://reverseengineering.stackexchange.com/questions/11582/how-to-reverse-engineer-dash-cam-metadata)
+        my @decode = unpack 'C*', '-I8XQWRVNZOYPUTA0B1C2SJ9K.L,M$D3E4F5G6H7';
+        my @chars = unpack 'C*', substr($$dataPt, 0, -4);
+        foreach (@chars) {
+            my $n = $_ - 43;
+            $_ = $decode[$n] if $n >= 0 and defined $decode[$n];
+        }
+        my $buff = pack 'C*', @chars;
+        if ($buff =~ /X(.*?)Y(.*?)Z(.*?)G(.*?)\$/) {
+            # yup. the decoding worked out
+            $tags{Accelerometer} = "$1 $2 $3 $4";
+            $$dataPt = $buff;   # (process GPRMC below)
+        }
+    }
+
+    # check for Thinkware format (and other NMEA RMC), 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"
+    if ($$dataPt =~ /[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 $$dataPt =~ /\bgsensori,(.*?)(;|$)/;
+    $tags{Car} = $1 if $$dataPt =~ /\bCAR,(.*?)(;|$)/;
+
+    if (%tags) {
+        HandleTextTags($et, $tagTbl, \%tags);
+    } 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'), last;
+            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);
+            }
+            if ($$et{GotNAL06}) {
+                my $eeOpt = $et->Options('ExtractEmbedded');
+                last unless $eeOpt and $eeOpt > 2;
+            }
+            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 =~ /^(\0.{3})?PNDM/s) {
+                    # Garmin Dashcam format (actually binary, not text)
+                    my $n = $1 ? 4 : 0; # skip leading 4-byte size word if it exists
+                    next if length($buff) < 20 + $n;
+                    $et->HandleTag($tagTbl, GPSLatitude  => Get32s(\$buff, 12+$n) * 180/0x80000000);
+                    $et->HandleTag($tagTbl, GPSLongitude => Get32s(\$buff, 16+$n) * 180/0x80000000);
+                    $et->HandleTag($tagTbl, GPSSpeed => Get16u(\$buff, 8+$n));
+                    $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, \$buff, $tagTbl);
+
+        } 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 => 0,
+                        Base    => $$start[$i], # (Base must be set for CR3 files)
+                        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, \$buff, $tagTbl);
+                }
+            } elsif ($verbose) {
+                $et->VPrint(0, "Unknown $type 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 => 0,
+                    Base    => $$start[$i], # (Base must be set for CR3 files)
+                    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,18,8) eq "\xaa\xaa\xf2\xe1\xf0\xee\x54\x54") {
+
+        # (this is very similar to the encrypted text format)
+        # 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 [................]
+        # decrypted (from byte 18):
+        #  0000: 00 00 58 4b 5a 44 fe fe 32 30 31 38 30 39 32 34 [..XKZD..20180924]
+        #  0010: 32 32 34 39 32 38 0c 35 35 36 37 47 50 20 20 20 [224928.5567GP   ]
+        #  0020: 00 00 00 00 00 03 4e 34 30 34 36 34 33 35 30 57 [......N40464350W]
+        #  0030: 30 30 37 30 34 30 33 30 38 30 30 30 30 30 30 30 [0070403080000000]
+        #  0040: 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [7...............]
+        #  [...]
+        #  00a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 2b 30 39 [.............+09]
+        #  00b0: 33 2d 30 30 33 2d 30 30 35 00 00 00 00 00 00 00 [3-003-005.......]
+        # header looks like this for EEEkit gps:
+        #  0000: 00 00 04 00 66 72 65 65 47 50 53 20 f0 03 00 00 [....freeGPS ....]
+        #  0010: 01 03 aa aa f2 e1 f0 ee 54 54 98 9a 98 9a 9a 9f [........TT......]
+        #  0020: 9b 93 9b 9c 98 99 99 9f a6 9a 9a 98 9a 9a 9f 9b [................]
+        #  0030: 93 9b 9c 98 99 99 9c a9 e4 99 9d 9e 9f 98 9e 9b [................]
+        #  0040: 9c fd 9b 98 98 98 9f 9f 9a 9a 93 81 9a 9b 9d 9f [................]
+        # decrypted (from byte 18):
+        #  0000: 00 00 58 4b 5a 44 fe fe 32 30 32 30 30 35 31 39 [..XKZD..20200519]
+        #  0010: 31 36 32 33 33 35 0c 30 30 32 30 30 35 31 39 31 [162335.002005191]
+        #  0020: 36 32 33 33 36 03 4e 33 37 34 35 32 34 31 36 57 [62336.N37452416W]
+        #  0030: 31 32 32 32 35 35 30 30 39 2b 30 31 37 35 30 31 [122255009+017501]
+        #  0040: 31 2b 30 31 34 2b 30 30 32 2b 30 32 36 2b 30 31 [1+014+002+026+01]
+        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);
+        if (defined $spd) { # (Azdome)
+            $spd += 0;  # remove leading 0's
+        } elsif ($buf2 =~ /^.{57}([-+]\d{4})(\d{3})/s) { # (EEEkit)
+            # $alt = $1 + 0;  (doesn't look right for my sample, but the Ambarella A12 text has this)
+            $spd = $2 + 0;
+        }
+        $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)
+        if ($buf2 =~ /^.{65}(([-+]\d{3})([-+]\d{3})([-+]\d{3})([-+]\d{3})*)/s) {
+            $_ = $1;
+            @acc = ($2/100, $3/100, $4/100);
+            s/([-+])/ $1/g;  s/^ //;
+            push @xtra, AccelerometerData => $_;
+        } elsif ($buf2 =~ /^.{173}([-+]\d{3})([-+]\d{3})([-+]\d{3})/s) { # (Azdome)
+            @acc = ($1/100, $2/100, $3/100);
+        }
+
+    } 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 `...]
+        # 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...........]
+        # 0030: 12 00 00 00 2f 00 00 00 19 00 00 00 41 00 00 00 [..../.......A...]
+        # 0040: 13 b3 ca 44 4e 00 00 00 29 92 fb 45 45 00 00 00 [...DN...)..EE...]
+        # 0050: d9 ee b4 41 ec d1 d3 42 e4 07 00 00 01 00 00 00 [...A...B........]
+        # 0060: 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');
+
+    } elsif ($$dataPt =~ /^.{16}YndAkasoCar/s) {
+
+        # Akaso V1 dascham
+        #  0000: 00 00 80 00 66 72 65 65 47 50 53 20 78 00 00 00 [....freeGPS x...]
+        #  0010: 59 6e 64 41 6b 61 73 6f 43 61 72 00 00 00 00 00 [YndAkasoCar.....]
+        #  0020: 30 30 30 30 30 00 00 00 00 00 00 00 00 00 00 00 [00000...........]
+        #  0030: 0e 00 00 00 27 00 00 00 2c 00 00 00 e3 07 00 00 [....'...,.......]
+        #  0040: 05 00 00 00 1d 00 00 00 41 4e 45 00 00 00 00 00 [........ANE.....]
+        #  0050: f1 4e 3e 3d 90 df ca 40 e3 50 bf 0b 0b 31 a0 40 [.N>=...@.P...1.@]
+        #  0060: 4b dc c8 41 9a 79 a7 43 34 58 43 31 4f 37 31 35 [K..A.y.C4XC1O715]
+        #  0070: 35 31 32 36 36 35 37 35 59 4e 44 53 0d e7 cc f9 [51266575YNDS....]
+        #  0080: 00 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 [................]
+        ($hr,$min,$sec,$yr,$mon,$day,$stat,$latRef,$lonRef) =
+            unpack('x48V6a1a1a1x1', $$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');
+
+        $et->WarnOnce("Can't yet decrypt Akaso V1 timed GPS", 1);
+        # (see https://exiftool.org/forum/index.php?topic=11320.0)
+        return 1;
+
+        SetByteOrder('II');
+        $lat = GetDouble($dataPt, 0x50);    # latitude is here, but encrypted somehow
+        $lon = GetDouble($dataPt, 0x58);    # longitude is here, but encrypted somehow
+        SetByteOrder('MM');
+        #my $serialNum = substr($$dataPt, 0x68, 20);
+
+    } elsif ($$dataPt =~ /^.{12}\xac\0\0\0.{44}(.{72})/s) {
+
+        # EACHPAI dash cam
+        #  0000: 00 00 80 00 66 72 65 65 47 50 53 20 ac 00 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 [................]
+        #  0030: 00 00 00 00 00 00 00 00 00 00 00 00 34 57 60 62 [............4W`b]
+        #  0040: 5d 53 3c 41 47 45 45 42 42 3e 40 40 40 3c 51 3c []S<AGEEBB>@@@<Q<]
+        #  0050: 44 42 44 40 3e 48 46 43 45 3c 5e 3c 40 48 43 41 [DBD@>HFCE<^<@HCA]
+        #  0060: 42 3e 46 42 47 48 3c 67 3c 40 3e 40 42 3c 43 3e [B>FBGH<g<@>@B<C>]
+        #  0070: 43 41 3c 40 42 40 46 42 40 3c 3c 3c 51 3a 47 46 [CA<@B@FB@<<<Q:GF]
+        #  0080: 00 2a 36 35 00 00 00 00 00 00 00 00 00 00 00 00 [.*65............]
+
+        $et->WarnOnce("Can't yet decrypt EACHPAI timed GPS", 1);
+        # (see https://exiftool.org/forum/index.php?topic=5095.msg61266#msg61266)
+        return 1;
+
+        my $time = pack 'C*', map { $_ ^= 0 } unpack 'C*', $1;
+        # bytes 7-12 are the timestamp in ASCII HHMMSS after xor-ing with 0x70
+        substr($time,7,6) = pack 'C*', map { $_ ^= 0x70 } unpack 'C*', substr($time,7,6);
+        # (other values are currently unknown)
+
+    } 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;
+        # lat/lon also stored as doubles by Transcend Driver Pro 230 (ref PH)
+        SetByteOrder('II');
+        my ($lat2, $lon2, $alt2) = (
+            GetDouble($dataPt, 0x70),
+            GetDouble($dataPt, 0x80),
+          # GetDouble($dataPt, 0x98), # (don't know what this is)
+            GetDouble($dataPt,0xa0),
+          # GetDouble($dataPt,0xa8)) # (don't know what this is)
+        );
+        if (abs($lat2-$lat) < 0.001 and abs($lon2-$lon) < 0.001) {
+            $lat = $lat2;
+            $lon = $lon2;
+            $alt = $alt2;
+        }
+        SetByteOrder('MM');
+        $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);
+        }
+
+    } elsif ($$dataPt =~ /^.{60}A\0.{6}([NS])\0.{6}([EW])\0/s and $dirLen >= 112) {
+
+        # header looks like this in my sample (unknown dashcam, "Anticlock 2 2020_1125_1455_007.MOV"):
+        #  0000: 00 00 80 00 66 72 65 65 47 50 53 20 68 00 00 00 [....freeGPS h...]
+        #  0010: 32 30 31 33 30 33 32 35 41 00 00 00 00 00 00 00 [20130325A.......]
+        #  0020: 41 70 72 20 20 36 20 32 30 31 36 2c 20 31 36 3a [Apr  6 2016, 16:]
+        #  0030: 0e 00 00 00 38 00 00 00 22 00 00 00 41 00 00 00 [....8..."...A...]
+        #  0040: 8a 63 24 45 53 00 00 00 9f e6 42 45 45 00 00 00 [.c$ES.....BEE...]
+        #  0050: 59 c0 04 3f 52 b8 42 41 14 00 00 00 0b 00 00 00 [Y..?R.BA........]
+        #  0060: 19 00 00 00 06 00 00 00 05 00 00 00 f6 ff ff ff [................]
+        #  0070: 03 00 00 00 04 00 00 00 00 00 00 00 00 00 00 00 [................]
+        ($latRef, $lonRef) = ($1, $2);
+        ($hr,$min,$sec,$yr,$mon,$day,@acc) = unpack('x48V3x28V6',$$dataPt);
+        map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 1000 } @acc; # (NC)
+        $lat = GetFloat($dataPt, 0x40);
+        $lon = GetFloat($dataPt, 0x48);
+        $spd = GetFloat($dataPt, 0x50);
+        $trk = GetFloat($dataPt, 0x54);
+
+    } 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));
+    if (defined $spd) {
+        $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
+    } elsif ($tag eq 'GPS ') {
+        my $pos = 0;
+        my $tagTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
+        SetByteOrder('II');
+        while ($pos + 36 < $dataLen) {
+            my $dat = substr($$dataPt, $pos, 36);
+            last if $dat eq "\x0" x 36;
+            my @a = unpack 'VVVVCVCV', $dat;
+            $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+            # 0=1, 1=1, 2=secs, 3=?
+            SetGPSDateTime($et, $tagTbl, $a[2]);
+            my $lat = $a[5] / 1e3;
+            my $lon = $a[7] / 1e3;
+            my $deg = int($lat / 100);
+            $lat = $deg + ($lat - $deg * 100) / 60;
+            $deg = int($lon / 100);
+            $lon = $deg + ($lon - $deg * 100) / 60;
+            $lat = -$lat if $a[4] eq 'S';
+            $lon = -$lon if $a[6] eq 'W';
+            $et->HandleTag($tagTbl, GPSLatitude  => $lat);
+            $et->HandleTag($tagTbl, GPSLongitude => $lon);
+            $et->HandleTag($tagTbl, GPSSpeed => $a[3] / 1e3);
+            $et->HandleTag($tagTbl, GPSSpeedRef => 'K');
+            $pos += 36;
+        }
+        SetByteOrder('MM');
+        delete $$et{DOC_NUM};
+    }
+}
+
+#------------------------------------------------------------------------------
+# 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->VerboseDir('tx3g', undef, length($$dataPt)-2);
+    $et->HandleTag($tagTablePtr, 'Text', substr($$dataPt, 2));
+    if ($$dataPt =~ /^..\w{3} (\d{4})-(\d{2})-(\d{2}) (\d{2}:\d{2}:\d{2}) ?([-+])(\d{2}):?(\d{2})$/s) {
+        $et->HandleTag($tagTablePtr, 'DateTime', "$1:$2:$3 $4$5$6:$7");
+    } else {
+        $et->HandleTag($tagTablePtr, $1, $2) while $$dataPt =~ /(\w+):([^:]*[^:\s])(\s|$)/sg;
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process GM 'marl' ctbx metadata (ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub Process_marl($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    return 0 if length $$dataPt < 2;
+
+    # 8-byte records:
+    # byte 0 seems to be tag ID (0=timestamp in sec * 1e7)
+    # bytes 1-3 seem to be 24-bit signed integer (unknown meaning)
+    # bytes 4-7 are an int32u value, usually a multiple of 10000
+
+    $et->WarnOnce("Can't yet decode timed GM data", 1);
+    # (see https://exiftool.org/forum/index.php?topic=11335.msg61393#msg61393)
+    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) {
+                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, ExposureTime => GetDouble(\$buff, $p + 8)); #6
+                }
+            } elsif ($id == 0x600) { #6
+                for ($p=0; $p<$len; $p+=$dlen) {
+                    $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+                    $et->HandleTag($tagTbl, VideoTimeStamp => sprintf('%.3f', Get64u(\$buff, $p) / 1000));
+                }
+            } 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; # millisecond counter (https://exiftool.org/forum/index.php?topic=9884.msg65143#msg65143)
+                }
+            }
+        } 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;
+}
+
+#------------------------------------------------------------------------------
+# Process 360Fly 'uuid' atom containing sensor data
+# (ref https://github.com/JamesHeinrich/getID3/blob/master/getid3/module.audio-video.quicktime.php)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub Process360Fly($$$)
+{
+    my ($et, $dirInfo, $tagTbl) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataLen = length $$dataPt;
+    my $pos = 16;
+    my $lastTime = -1;
+    my $streamTbl = GetTagTable('Image::ExifTool::QuickTime::Stream');
+    while ($pos + 32 <= $dataLen) {
+        my $type = ord substr $$dataPt, $pos, 1;
+        my $time = Get64u($dataPt, $pos + 2); # (only valid for some types)
+        if ($$tagTbl{$type}) {
+            if ($time != $lastTime) {
+                $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+                $lastTime = $time;
+            }
+        }
+        $et->HandleTag($tagTbl, $type, undef, DataPt => $dataPt, Start => $pos, Size => 32);
+        # synthesize GPSDateTime from the timestamp for GPS records
+        SetGPSDateTime($et, $streamTbl, $time / 1e6) if $type == 5;
+        $pos += 32;
+    }
+    delete $$et{DOC_NUM};
+    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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/README
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/README	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/README	(revision 34921)
@@ -15,13 +15,14 @@
 hash value provides information about the tag (explained later).
 
-Twenty-five 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, 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 by GetTagTable()).
+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()).
 
   SHORT_NAME : Table name with leading "Image::ExifTool::" removed.
@@ -29,8 +30,10 @@
   PROCESS_PROC : Reference to a function used to process the directory for this
   table.  If PROCESS_PROC is not given, \&Image::ExifTool::Exif::ProcessExif is
-  assumed.  If PROCESS_PROC is set to 0, the tags are not added to the lookup.
-  The process proc returns 1 on success or 0 on failure, and takes 3 arguments:
-  0) reference to the ExifTool object, 1) reference to a directory information
-  hash (with the following entries:), 2) reference to the tag table hash.
+  assumed (except for QuickTime atoms for which
+  \&Image::ExifTool::QuickTime::ProcessMOV is the default).  If PROCESS_PROC is
+  set to 0, the tags are not added to the lookup. The process proc returns 1 on
+  success or 0 on failure, and takes 3 arguments: 0) reference to the ExifTool
+  object, 1) reference to a directory information hash (with the following
+  entries:), 2) reference to the tag table hash.
 
     Name        - Tag name for this SubDirectory entry (for verbose messages)
@@ -51,26 +54,30 @@
     LastIFD     - Used by WriteExif() to return offset of last IFD written
     ImageData   - Used by WriteExif() to avoid buffering large image data blocks
-
-  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
+    NoRefTest   - Flag to bypass "referenced by previous directory" test
+
+  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.
 
   CHECK_PROC : Reference to a function which validates Raw values for writing.
-  The function takes three arguments: 0) ExifTool object reference, 1) tagInfo
-  reference, 2) value reference, and returns undefined (and possibly modifies
-  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.
+  The function takes 3-4 arguments: 0) ExifTool object reference, 1) tagInfo
+  reference, 2) value reference, and 3) [optional] conversion type.  It returns
+  undefined (and possibly modifies 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 Group 0 and 1 names will be set automatically
-  according to the name of the module.
-
-  FORMAT : Specifies the default tag Format and corresponding pointer increment
-  for entries in a BinaryData table, and defaults to 'int8u' if not specified.
-  Format names starting with 'var_' cause subsequent tag ID's in BinaryData
-  tables to be incremented according to the size of the data (not including the
-  terminator).  The possible values of FORMAT are:
+  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
+  name will be set to 'Other'.
+
+  FORMAT : Specifies the default tag Format, and corresponding pointer increment
+  for entries in a BinaryData table.  Defaults to 'int8u' for BinaryData tables
+  if not specified.  The possible values of FORMAT are:
 
     int8s       - Signed 8-bit integer                    (EXIF 'SBYTE')
@@ -96,13 +103,33 @@
     ifd         - Unsigned 32-bit integer sub-IFD pointer (EXIF 'IFD')
     ifd64       - Unsigned 64-bit integer sub-IFD pointer (BigTIFF 'IFD8')
-    string      - Series of 8-bit ASCII characters        (EXIF 'ASCII')
-    pstring     - Pascal string [BinaryData tables only]
+    string      - Series of 8-bit characters              (EXIF 'ASCII')
     undef       - Undefined-format binary data            (EXIF 'UNDEFINED')
-    binary      - Binary data
-    var_string  - variable-length null-terminated ASCII string [BinaryData]
-    var_ustring - variable-length null-terminated UCS-2 string [BinaryData]
-    var_pstring - variable-length Pascal string                [BinaryData]
-    var_pstr32  - variable-length Pascal string /w 32-bit len  [BinaryData]
-    var_int16u  - variable-length undef data with int6u count  [BinaryData]
+    binary      - Binary data (same as 'undef')
+
+  Additionally, the following variable-length Format types may be used in
+  individual tag information hashes of a BinaryData table.  The 'var_' formats
+  cause subsequent tag indices to be incremented according to the size of the
+  data, not including the terminator.  See "Format" below for more details.
+
+    pstring     - Pascal string (1-byte length followed by ASCII string)
+    var_string  - variable-length null-terminated ASCII string
+    var_ustring - variable-length null-terminated UCS-2 string
+    var_pstring - variable-length Pascal string
+    var_pstr32  - variable-length Pascal string /w 32-bit len
+    var_ustr32  - variable-length UCS-2 string /w 32-bit len
+    var_int16u  - variable-length undef data with int6u count
+    var_ue7     - variable-length 7-bit-at-a-time integer (BPG)
+
+  And the following format codes are used for string values in XMP metadata.
+  (See the XMP specification for more details.)
+
+    boolean     - "True" or "False"
+    date        - date/time string
+    integer     - integer as a string
+    lang-alt    - list of alternate-language strings
+    rational    - "N/D" where N=numerator, D=Denominator
+    real        - floating point value as a string
+    string      - unformatted string
+    struct      - structure
 
   FIRST_ENTRY : Specifies the index for the first tag entry in a binary table.
@@ -124,11 +151,11 @@
 
   NOTES : Notes to introduce the table in the TagNames documentation.  Pod
-  formatting codes B<> and C<> may be used in this text.
-
-  IS_OFFSET : Reference to list of sorted TagID's representing offsets for
-  writable binary data tables only.  Not used for EXIF tables.
-
-  IS_SUBDIR : BinaryData tables only.  A reference to a list of sorted tag ID's
-  representing subdirectories.  Required for writable subdirectories only.
+  formatting codes B<>, C<> and L<> may be used in this text.
+
+  IS_OFFSET : Writable BinaryData tables only.  Reference to list of sorted
+  TagID's representing offsets.
+
+  IS_SUBDIR : Writable BinaryData tables only.  A reference to a list of sorted
+  tag ID's representing subdirectories.
 
   EXTRACT_UNKNOWN : Used in PDF tables to specify a directory where all unknown
@@ -137,20 +164,29 @@
 
   NAMESPACE : Namespace prefix for tags in the XMP table.  If this isn't a
-  standard (pre-defined) namespace, then the URI must be defined as well.  To do
-  this, the NAMESPACE value is a reference to either a list or a hash, where the
-  first element (or hash key) is the namespace prefix and and the second element
-  (or hash value) is the URI.  This is undef for XMP tables in which tags have
-  variable namespaces, and in this case each tag must have a Namespace entry.
+  standard namespace defined in %Image::ExifTool::XMP::nsURI, then the URI must
+  be defined as well (however, this is not recommended for pre-defined
+  namespaces because then non-standard namespace prefixes won't be recognized).
+  To define the URI, the NAMESPACE value is a reference to a hash where the key
+  is the namespace prefix and and the value is the URI (alternatively, a
+  reference to a 2-element array containing the prefix and URI is also allowed
+  for backward compatibility).  The NAMESPACE value may be undef for XMP tables
+  where tags have variable namespaces (in this case each tag must have a
+  Namespace entry).
 
   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.
 
   PRIORITY : Default Priority for all tags in this table.
+
+  AVOID : Flag set to Avoid writing all tags in this table.
 
   WRITE_GROUP : Default WriteGroup for all tags in the table.
@@ -159,5 +195,5 @@
   language-specific tag information hash.  The routine takes two arguments: a
   reference to the non-specific tagInfo hash, and the language code. Used only
-  in tables with writable tags which support tag name language extensions (ie.
+  in tables with writable tags which support tag name language extensions (eg.
   MIE and XMP).
 
@@ -168,9 +204,16 @@
     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).  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.
 
     CAPTURE       Used by PDF module to name dictionaries to capture when
@@ -183,5 +226,24 @@
                   the entire IFD from the image.
 
-    NUMBERS_LAST  Sort numerical tags after character tags in documentation.
+    ALPHA_FIRST   Sort alphabetical tags before numerical in documentation.
+
+    LONG_TAGS     Suppress "Long tags" warning when generating documentation.
+                  Value is the number of long tag names to expect.
+
+    SORT_PROC     Reference to sort procedure for sorting tag ID's in the
+                  documentation.  Takes two arguments and returns -1, 0 or 1
+                  if the first argument is less than, equal to, or greater than
+                  the second argument.
+
+    ENTRY_SIZE    Used by ProcessPhaseOne to specify size of IFD entry
+
+    MAP_FORMAT    Lookup to map unknown format numbers (eg. Panasonic CameraIFD)
+
+    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
@@ -200,5 +262,5 @@
 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
@@ -210,7 +272,7 @@
                   to the form "TagName (N)", where N starts at 1 and increments
                   for subsequent duplicate tags.  A tag name should start with
-                  an uppercase letter, and contain only the charcters in the set
-                  [A-Za-z0-9_-].  If not given, the Name is taken from the tag
-                  ID with the first character changed to upper case.
+                  an uppercase letter, and contain only the characters in the
+                  set [A-Za-z0-9_-].  If not given, the Name is taken from the
+                  tag ID with the first character changed to upper case.
 
   Description   : A more readable description of tag name.  If a tag doesn't
@@ -220,7 +282,8 @@
   Notes         : Notes for this tag in the HTML TagNames documentation.
 
-  Groups        : Hash lookup for group names for this tag.
-
-  Format        : Only valid for BinaryData, EXIF and IPTC tables. For a Binary
+  Groups        : Hash lookup for group names for this tag.  If not specified,
+                  defaults to the GROUPS specified in the table definition.
+
+  Format        : Only valid for BinaryData, EXIF and IPTC tables.  For a Binary
                   or EXIF table, this gives the format that is used to convert
                   the binary data, and is one of the FORMAT types specified
@@ -232,15 +295,17 @@
                   Condition.  For BinaryData tables, the format may have a size
                   in trailing brackets which is a Perl expression to be
-                  evaluated. The expression may access any of the previous table
-                  entries through a %val hash (read-only tables), the data size
-                  via $size, or the ExifTool object via $self. For example,
-                  'string[$val{3}]' defines a string with length given by the
-                  table entry with tag index '3'.  An initial "var_" may be
-                  added to the Format name of any BinaryData tag with a size in
-                  brackets.  In this case, subsequent offsets are adjusted by
-                  the total size minus the size of the base Format (ie.
-                  "var_int16u[10]" causes subsequent offsets to be incremented
-                  by sizeof(int16u) * 9).  Note that all "var_" Format tags must
-                  have corresponding DATAMEMBER entries.
+                  evaluated.  The expression may access any of the previous
+                  table entries through a %val hash (read-only tags), the data
+                  size via $size, or the ExifTool object via $self.  For
+                  example, 'string[$val{3}]' defines a string with length given
+                  by the table entry with tag index '3'.  An initial "var_" may
+                  be added to the Format name of any BinaryData tag with a size
+                  in brackets.  In this case, subsequent offsets are adjusted by
+                  the value length minus the size of the default table FORMAT
+                  (eg. "var_int16u[10]" causes subsequent offsets to be
+                  incremented by sizeof(int16u) * 10 - sizeof(int8u) if the
+                  default table FORMAT is "int8u").  Note that all "var_" Format
+                  tags (as well as tags with values used within "var_" Format
+                  expressions) must have corresponding DATAMEMBER entries.
 
   Count         : Used when writing EXIF information to specify the number
@@ -248,7 +313,8 @@
                   string.  A value of -1 indicates that the count is variable
                   and should be determined by the number of values provided.
-                  Note that this count that corresponds to the specified Format,
-                  so if a different-sized Writable format is defined, the actual
-                  count written to the file will be different.
+                  Defaults to 1 if not specified for non-string formats.  Note
+                  that this count corresponds to the specified Format, so if a
+                  different-sized Writable format is defined, the actual count
+                  written to the file will be different.
 
   FixCount      : Flag set to determine correct count from offsets in IFD.  This
@@ -258,8 +324,8 @@
   Flags         : Flags to specify characteristics for this tag.  May be a
                   simple scalar flag name, a reference to a list of flag names,
-                  or a reference to a hash of flag/value pairs. If not a hash
-                  reference, the flag value is set to 1. Flags are expanded for
+                  or a reference to a hash of flag/value pairs.  If not a hash
+                  reference, the flag value is set to 1.  Flags are expanded for
                   faster access at run time into members of the tagInfo hash,
-                  and may be written directly as members if desired. The
+                  and may be written directly as members if desired.  The
                   available flag names are:
 
@@ -269,5 +335,6 @@
 
                   'Avoid' - avoid creating this tag if possible.  This is only
-                  effective if another tag exists with the same name.
+                  effective if another tag exists with the same name.  Setting
+                  this flag also sets the default Priority to 0 for this tag.
 
                   'Binary' - set to 1 for binary data.  This has the same effect
@@ -280,5 +347,11 @@
                   information which are extracted by default.  Otherwise
                   writable directories are only extracted as a block if
-                  specified explicitly.
+                  specified explicitly.  Also used for Jpeg2000 and QuickTime
+                  XMP-like tags to extract as a block with a name other than
+                  'XMP'.
+
+                  'ConvertBinary' - true to apply ValueConv and/or PrintConv to
+                  Binary values (ie. SCALAR references).  (By default, these
+                  conversions are not done for Binary values.)
 
                   'DataMember' - name of exiftool data member associated with
@@ -287,5 +360,5 @@
                   affects other written information.  Currently only used for
                   tags in EXIF tables where it triggers the execution of the
-                  RawConv to convert and stores the value as an ExifTool data
+                  RawConv to convert and store the value as an ExifTool data
                   member when writing.
 
@@ -293,6 +366,12 @@
                   byte count tags.
 
-                  'Drop' - set to 1 for tags that should be excluded when
-                  rebuilding maker notes when copying all 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
+                  only if data is larger than this size. Works for SubDirectory
+                  tags too.
 
                   'EntryBased' - set to 1 if the offset for this value is based
@@ -310,9 +389,14 @@
                   which have been processed to generate flattened equivalents.
 
-                  'GotGroups' - [reserved] flag used internally to indicate that
-                  the Groups hash has been initialized for this tag.
-
-                  'Hidden' - set to hide tag from the TagName documentation. 
+                  'NotFlat' - [XMP tags only] Flag indicates that this tag ID
+                  does not represent a flattened tag.  Used to avoid a conflict
+                  if the tag ID would be the same as a generated ID for a
+                  flattened tag.  The result is that the flattened tag will not
+                  be accessible.
+
+                  'Hidden' - set to hide tag from the TagName documentation.
                   Also suppresses verbose output of a BinaryData tag.
+
+                  'IsComposite' - flag set for Composite tags
 
                   'IsOffset' - flag set if the tag represents an offset to some
@@ -322,5 +406,5 @@
                   (only some maker notes are this messed up).  Set to 3 if
                   absolute file offsets are used.  May be set to an expression
-                  to be evaluated.  Expression may access $val and $exifTool,
+                  to be evaluated.  Expression may access $val and $et,
                   and is evaluated only when reading.
 
@@ -331,7 +415,7 @@
                   well, a value of '1' is used internally in XMP to allow list
                   behaviour for a flattened tag which is itself not a list
-                  element (ie. a member of list of structures).  Note that in
+                  element (eg. a member of list of structures).  Note that in
                   ExifTool an XMP lang-alt tag (Writable="lang-alt") is NOT a
-                  List-type tag (unless it is a list of lang-alt lists, which is
+                  list-type tag (unless it is a list of lang-alt lists, which is
                   uncommon).
 
@@ -342,5 +426,5 @@
 
                   'Mandatory' - set for mandatory tags.  Used only by TagInfoXML
-                  and documentation purposes.  Mandatory tags may be added
+                  and for documentation purposes.  Mandatory tags may be added
                   automatically by ExifTool.
 
@@ -350,7 +434,8 @@
                   only be underlined if nested inside other maker notes.
 
-                  'NotIFD' - set for 'MakerNotes' tags only if the data is not
-                  in standard EXIF IFD format.  (Note: All SubDirectory tags in
-                  the MakerNotes table are 'MakerNotes' type by default.)
+                  'NotIFD' - set for 'MakerNotes' SubDirectory tags only if the
+                  SubDirectory is not EXIF IFD format.  (Note: All SubDirectory
+                  tags in the MakerNotes table are 'MakerNotes' type by
+                  default.)
 
                   'OffsetPair' - set if the tag represents half of an offset/
@@ -364,7 +449,11 @@
 
                   'PrintHex' - specifies that unknown PrintConv values should
-                  be printed in hex (ie. 'Unknown (0x01)').  Also causes
+                  be printed in hex (eg. 'Unknown (0x1)').  Also causes
                   numerical tag values to be printed in hex in the HTML tag name
-                  documentation.
+                  documentation, padded to the number of digits given by the
+                  PrintHex value.
+
+                  'PrintSort' - causes PrintConv values to be sorted by value
+                  rather than key in the HTML tag name documentation.
 
                   'PrintString' - flag set to force PrintConv values to be
@@ -390,6 +479,12 @@
                   '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
+                  ValueConv and PrintConv to act on the concatenated string so
+                  the tag does not exhibit list-type behaviour.  When writing,
+                  the inverse is performed and the value is split at whitespace.
 
                   'Resource' - [XMP only] flag to write value as an rdf:resource
@@ -403,5 +498,5 @@
 
                   'SetResourceName' - [Photoshop tags only] set to 1 to append
-                  resource name to the extracted value (ie. 'VALUE/#NAME#/').
+                  resource name to the extracted value (eg. 'VALUE/#NAME#/').
                   Also allows resource name to be appended when writing new
                   values.  May be set to any value other than 1 for a default
@@ -413,20 +508,31 @@
                   more enclosing structures has a TYPE field.
 
-                  'SubDoc' - [Composite tags only] set to cause this composite
+                  'SubDoc' - [Composite tags only] set to cause this Composite
                   tag to also be generated for each sub-document.  To achieve
                   this, 'Main:' and 'Doc#:' prefixes are added to all Require'd
                   and Desire'd tag names which don't already start with 'Main:'
-                  or 'Doc#:', and the composite tag is built once for each of
-                  the main document and all sub-documents.
+                  or 'Doc#:', and the Composite tag is built once for each of
+                  the main document and all sub-documents.  May be a reference
+                  to a list of indices for Desire'd tags, one of which must
+                  exist to generate this tag for sub-documents.
 
                   'SubIFD' - used in writing to determine that the tag specifies
                   an offset to a sub-IFD.  When this flag is set, the Group1
                   name gives the name of the IFD.  Must be set if and only if
-                  the tag has a SubDirectory Start of '$val' (this is validated
-                  by BuildTagLookup).  Set to 2 for standard EXIF SubIFD's where
-                  the PutFirst flag is valid.
+                  the tag has a SubDirectory Start that references '$val' (this
+                  is validated by BuildTagLookup).  Set to 2 for standard EXIF
+                  SubIFD's where the PutFirst flag is valid.
 
                   'Unknown' - this is an unknown tag (only extracted when the
                   Unknown option is set).
+
+                  'WriteNothing' - flag indicating that nothing is actually
+                  written when this tag is set.  It is a fake writable tag that
+                  isn't actually written (eg. Geotag).  Used to avoid processing
+                  a file unnecessarily if nothing will actually be written.
+
+                  'WritePseudo' - flag indicating that this is a writable pseudo
+                  tag.  If set, this tag may be written without actually writing
+                  to the file (eg. FileName, FileModifyDate).
 
                   'WrongBase' - ['IsOffset' tags only] An expression using $self
@@ -438,50 +544,63 @@
                   which are done later only if the value is requested).  May be
                   a scalar expression using $val (the Raw tag value), $self (the
-                  current ExifTool object), $tag (the tag key) and $tagInfo
-                  (reference to the tag information hash) or a code reference
-                  with $val and $self as arguments.  For Composite tags, $val is
-                  a reference to a hash of source ("derived from") tag names,
-                  and @val may be used to access the Raw values of these tags.
-                  If RawConv is specified for a Composite tag, then ValueConv
-                  and PrintConv evals will no longer have access to the source
-                  @val and @prt values.  The returned value may be a scalar
-                  which is used as the new Raw value, a scalar reference to a
-                  binary data value, a hash reference for Composite tags, an
-                  ARRAY reference for a list of values, or undefined to indicate
-                  that the tag should be ignored.  Also, RawConv may generate
-                  Warning or Error tags, while ValueConv and PrintConv may not. 
+                  current ExifTool object), $tag (the tag key), $tagInfo
+                  (reference to the tag information hash), $priority (to
+                  dynamically set the priority of a tag), and @grps (to
+                  dynamically set the family and/or groups), or a code reference
+                  with $val and $self as arguments (in which case $$self{grps}
+                  may be used to set the groups).  For Composite tags, $val is a
+                  reference to a hash of source ("derived from") tag names, and
+                  @val may be used to access the Raw values of these tags.  The
+                  returned value may be a scalar which is used as the new Raw
+                  value, a scalar reference to a binary data value, a hash
+                  reference for Composite tags, an ARRAY reference for a list of
+                  values, or undefined to indicate that the tag should be
+                  ignored.  If RawConv is specified for a Composite tag, then
+                  ValueConv and PrintConv evals will no longer have access to
+                  the source @val and @prt values unless the input $val is
+                  returned.  RawConv may generate Warning or Error tags, while
+                  ValueConv and PrintConv should not (see ValueConv note below).
                   Note: RawConv should only be used if necessary (in general,
-                  only if the conversion may return undef to ignore the tag)
-                  because ValueConv is more efficient since it is only executed
-                  if the tag value is requested, while RawConv is executed for
-                  all extracted tags.
+                  only if the conversion may return undef to ignore the tag, or
+                  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
-                  evaluated as a Perl expression, or a code reference to a
-                  subroutine.  May also be a list reference, in which case the
-                  value is split at whitespace into a list of values and each
-                  value is converted by the associated entry in the ValueConv
-                  list.  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 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.  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 expression or subroutine is
-                  evaluated when and if 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
+                  evaluated as a Perl expression, a code reference to a
+                  subroutine, or an ARRAY reference (in which case the value is
+                  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 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
+                  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
@@ -491,7 +610,8 @@
                   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
+                  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. 
+                  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
@@ -500,6 +620,9 @@
                   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. If ValueConv is not
-                  specified, the Raw value is not converted.
+                  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
@@ -542,14 +665,24 @@
                   undef).
 
-  PrintConvInv  : The inverse of PrintConv.  Only necessary if for Writable tags
-                  when PrintConv is specified (unless WriteAlso is used).  See
-                  ValueConvInv above for more details.
-
-  PrintConvColumns : Number of columns for PrintConv lookup in HTML docs.
-                  Default is 1 if not specified.
+  PrintConvInv  : The inverse of PrintConv.  Necessary for Writable tags
+                  when PrintConv is specified (unless WriteAlso is used), but
+                  may be used without PrintConv.  See ValueConvInv above for
+                  more details.
+
+  PrintConvColumns : Number of columns for PrintConv lookup in HTML docs. If not
+                  set, the number of columns is determined automatically
+                  according to the maximum width of the entries.
 
   DelValue      : Raw value to be used when deleting a permanent tag.  (Note all
                   MakerNotes tags are permanent.)  If not specified, an attempt
                   is made to convert an empty string for the raw value.
+
+  Validate      : Scalar expression used to validate the raw value of a tag when
+                  the Validate option is set.  The expression may access $val
+                  (the Raw tag value), $tag (the tag key) and $self (the current
+                  ExifTool object), and should return a warning if any problem
+                  is found, or false if OK.  The evaluation is performed in the
+                  Image::ExifTool::Validate package namespace, so functions of
+                  this package need not be prefixed by the package name.
 
   Relist        : [Only if ValueConv or PrintConv is a list ref] Reference to a
@@ -563,6 +696,11 @@
                   may have the same index by using floating point indices.  An
                   unknown tag will only be generated for a certain TagID if
-                  there is no integral TagID for that tag.)  When Mask is used,
-                  PrintHex=1 is implied unless otherwise defined.
+                  there is no integral TagID for that tag.)  The Mask and
+                  BitShift are applied before evaluating RawConv.
+
+  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 right by this number of
+                  bits after the Mask is applied.
 
   Condition     : If given, specifies scalar which is evaluated as a Perl
@@ -573,29 +711,35 @@
                   expression may use $self to access the ExifTool object.  The
                   first 128 bytes of the raw data value are accessible through
-                  the reference $valPt for EXIF, Jpeg2000 and BinaryData tags
-                  only (note that for BinaryData tags, the raw data of $$valPt
-                  is always 'undef' type, and may not be used when writing
-                  except for SubDirectory tags).  EXIF tags may also reference
-                  the format string and value count through $format and $count.
-                  Note that if the value is writable and $valPt is used, the tag
-                  must have a Format (unless 'undef' or 'string'), and a Count
-                  (unless 1 or length of the 'undef' or 'string'), so the raw
-                  data may be generated for evaluating the Condition.  When
-                  writing, $valPt, $format and $count refer to the new value,
-                  except for MakerNotes tags where $format and $count refer to
-                  the old tag if it existed.
+                  the reference $valPt for EXIF, Jpeg2000, QuickTime and
+                  BinaryData tags only (note that for BinaryData tags, the raw
+                  data of $$valPt is always 'undef' type, and may not be used
+                  when writing except for SubDirectory tags).  EXIF tags (and
+                  maybe some other types) may also reference the format string
+                  and value count through $format and $count.  Note that if the
+                  value is writable and $valPt is used, the tag must have a
+                  Format (unless 'undef' or 'string'), and a Count (unless 1 or
+                  length of the 'undef' or 'string'), so the raw data may be
+                  generated for evaluating the Condition.  When writing, $valPt,
+                  $format and $count refer to the new value, except for
+                  MakerNotes tags where $format and $count refer to the old tag
+                  if it existed.
 
   Require       : [Composite tags only] A hash reference specifying the tags
-                  required to calculate the composite tag value.  The hash
+                  required to calculate the Composite tag value.  The hash
                   values are the names of the required tags, and the keys
                   specify the indices where the tag values are stored in the
                   @val list used in the ValueConv and/or PrintConv expression.
-                  The composite value is only calculated if the values for all
-                  Require'd tags are defined.  Require and Desire tag names may
-                  be prefixed by an optional group family 0 or 1 name followed
-                  by a colon.  Case IS significant.  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:
+                  The Composite value is only calculated if the values for all
+                  Require'd tags are defined.  Require, Desire and Inhibit tag
+                  names may be prefixed by an optional group family 0 or 1 name
+                  followed by a colon.  Case IS significant.  The keys used by
+                  the Require, Desire and Inhibit hashes must not overlap (since
+                  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, 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' },
@@ -603,32 +747,45 @@
 
   Desire        : [Composite tags only] This is the same as Require except that
-                  the value is still calculated even if the specified tags don't
-                  exist.  Beware that the elements of @val, @prt and @raw may be
-                  undefined for Desire'd tags.  Both Require and Desire may
-                  exist together, however be sure to specify unique keys for
-                  each tag since they are used as indices into the @val, @prt
-                  and @raw lists common to both Require'd and Desire'd tags.
+                  the Composite value is calculated even if the specified tags
+                  don't exist.  Beware that the elements of @val, @prt and @raw
+                  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.  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.  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
-                  tags.
-
-  Writable      : Indicates this tag can be written (or not written if value 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).
+                  tags, or '0' to prevent tag from being shifted or
+                  conditionally deleted.
+
+  Writable      : Indicates this tag can be written (or not written if Writable
+                  is set to zero), and for EXIF and QuickTime 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 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 and QuickTime 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
@@ -636,19 +793,21 @@
                   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 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
-                  and DelValue 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 value being
+                  expression for a one-time validatation the Raw value being
                   written.  The expression has access to 3 variables: $val is
                   the value to be written, $self is the ExifTool object, and
@@ -658,9 +817,14 @@
                   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
                   expression may access $self, $tagInfo and $wantGroup.  Returns
                   error string, or undef on success, and may set $val to
                   something other than undef.  May return empty string ('') to
-                  suppress warning messages but not delete tag (ie. when
+                  suppress warning messages but not delete tag (eg. when
                   deleting only associated tags).
 
@@ -670,10 +834,17 @@
                   and returns true if it is OK for writing.  Unlike WriteCheck
                   which is done only once when the new value is set, this
-                  condition is evaluated just before the tags of the specific
-                  SubDirectory are written.
-
-  WriteGroup    : [Writable EXIF tags only] Specifies the IFD where the
-                  information gets written by default.  Must be defined for
-                  writable EXIF tags if WRITE_GROUP is not specified in table.
+                  condition is evaluated just before the tag is written to the
+                  file.
+
+  WriteGroup    : [Writable EXIF and Composite tags only] Specifies the IFD
+                  where the information gets written by default.  Must be
+                  defined for writable EXIF tags if WRITE_GROUP is not specified
+                  in table.  A WriteGroup of 'All' is special:  For writable
+                  Composite tags this causes any group specified for the
+                  Composite tag to be propagated to the WriteAlso tags when
+                  writing.  For other tags this allows writing to all EXIF IFD's
+                  simultaneously (in which case the tag should have a Condition
+                  or WriteCondition to restrict the IFD's to which the tag is
+                  actually written).
 
   IsOverwriting : [Writable EXIF tags only] Specifies reference to subroutine
@@ -681,4 +852,11 @@
                   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
+                  otherwise specified.
 
   AllowGroup    : [Writable tags only] Regular expression string (case
@@ -701,4 +879,13 @@
                   image offset, and is only used if the preview is outside the
                   APP1 EXIF segment.
+
+  BitsPerWord   : [BITMASK tags only] Number of bits per decoded word.  Defaults
+                  to 32 if not specified.
+
+  BitsTotal     : [Writable BITMASK tags only] Total number of bits in bit mask.
+                  Defaults to BitsPerWord if not specified.
+
+  FixedSize     : [EXIF only] Hack to ignore value size and use this instead.
+                  Only valid if Format is also defined.
 
   Struct        : [XMP tags only] Reference to structure hash for structured XMP
@@ -710,9 +897,18 @@
                   have ValueConv/PrintConv entries, because values that are HASH
                   references are are also used by Composite tags, which use the
-                  the Conv entries to generate the composite value.
+                  the Conv entries to generate the Composite value.
+
+  NoSubStruct   : [XMP tags only] Flag set in flattened tag to break cyclical
+                  recursion in nested structures.
 
   Namespace     : [XMP tags only] Gives standard XMP namespace prefix to use for
                   this tag.  If not defined, the tag table NAMESPACE is used.
 
+  FlatName      : [Struct tags and structure fields only] Name used for
+                  automatically-generated flattened tag names, defaults to Name
+                  if not specified.  In general, this is used to remove the
+                  redundant names found in some specifications.  May be empty
+                  ('') for a Struct tag but not for a structure field.
+
   Units         : [MIE tags only] Reference to a list of valid units strings.
                   The default units are the first item in the list.
@@ -720,7 +916,21 @@
   Hook          : [BinaryData tags only] Expression to be evaluated when
                   extracting tag to allow dynamic Format, etc for BinaryData
-                  tags.  May access $self, 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.
+                  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
+                  hash, even if the tag exists as a DATAMEMBER.
+
+  SetBase       : [QuickTime and BinaryData tags only] Sets ExifTool BASE offset
+                  for use when ExtractInfo is called with the ReEntry flag from
+                  inside the RawConv of a tag.
 
   TagID         : [reserved] Used internally to save the table key for this tag.
@@ -742,6 +952,9 @@
                   for these the full property path is not stored.
 
-  SrcTagInfo    : [reserved] Used internally by XMP module to store reference to
-                  default language tagInfo hash for alternate-language tags.
+  SrcTagInfo    : [reserved] Used internally to store reference to default
+                  language tagInfo hash for alternate-language tags.
+
+  OtherLang     : [reserved] Used internally by QuickTime module to store a list
+                  of tag ID's for alternate-language tags based on this one.
 
   RootTagInfo   : [reserved] Used internally to store a reference to the tag
@@ -753,11 +966,13 @@
 
   LangCode      : [reserved] Used internally to indicate language code for
-                  alternate language tags (ie. 'fr').  Only used with formats
-                  which support alternate languages (ie. XMP, MIE, etc).
+                  alternate language tags (eg. 'fr').  Only used with formats
+                  which support alternate languages (eg. XMP, MIE, etc).
 
   SubDirectory {  If it exists, this specifies the start of a new subdirectory.
                   It contains a collection of variables which specify the type
-                  and location of the subdirectory.  These variables are
-                  described below:
+                  and location of the subdirectory.  Note that ValueConv and
+                  PrintConv do not apply to SubDirectory tags, but RawConv is
+                  evaluated before the SubDirectory is processed.  The following
+                  is a list of SubDirectory variables:
 
      TagTable   : Specifies the name of the tag table lookup for the new
@@ -770,23 +985,23 @@
                   of '$valuePtr' is assumed.
 
-     OffsetPt   : If specified, this is a Perl expression that gives the
-                  position of a 32-bit word in the current directory that is
-                  added to the Start position to get the position of the new
-                  subdirectory.  The expression should use the position of the
-                  current tag ($valuePtr).
-
-     Base       : This specifies the base offset for all pointers in the
-                  subdirectory.  This need not be specified if the offset is the
-                  same as the current directory, which is normally the case.
+     OffsetPt   : [EXIF directories only] If specified, this is a Perl
+                  expression that gives the position of a 32-bit word in the
+                  current directory that is added to the Start position to get
+                  the position of the new subdirectory.  The expression
+                  should use the position of the current tag ($valuePtr).
+
+     Base       : This expression specifies the base offset for all pointers in
+                  the subdirectory.  This need not be specified if the offset is
+                  the same as the current directory, which is normally the case.
                   May use $start to represent the subdirectory start location
                   relative to the current base, and $base for the value of the
                   current base.  If this is defined, the automatic validation of
-                  base offsets is disabled for maker notes directories.  The
-                  IFD is flagged as using relative offsets when writing if
-                  '$start' is used in this expression.
-
-     EntryBased : Flag indicating that the offsets are based on the individual
-                  directory entry position, so offsets are incremented by 12
-                  times the corresponding entry index.
+                  base offsets is disabled for maker notes directories.  The IFD
+                  is flagged as using relative offsets when writing if '$start'
+                  is used in this expression.
+
+     EntryBased : [EXIF directories only] Flag indicating that the offsets are
+                  based on the individual directory entry position, so offsets
+                  are incremented by 12 times the corresponding entry index.
 
      MaxSubdirs : Maximum number of subdirectories specified by the current tag
@@ -803,9 +1018,9 @@
 
      Validate   : If given, specifies Perl expression which is used to validate
-                  the subdirectory data.  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.
+                  the subdirectory data (regardless of Validate option setting).
+                  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 subdirectory is valid.
 
      ProcessProc: If given, specifies processing procedure used to decode this
@@ -813,5 +1028,5 @@
                   specified by PROCESS_PROC in the tag table.
 
-     WriteProc:  If given, specifies processing procedure used to write this
+     WriteProc  : If given, specifies processing procedure used to write this
                   subdirectory data.  This overrides the default procedure
                   specified by WRITE_PROC in the tag table.
@@ -858,5 +1073,8 @@
                 tags (where it defaults to the NAMESPACE of the tag table).
 
-  STRUCT_NAME : Name of structure (used in warning messages).
+  STRUCT_NAME : Name of structure (used in warning messages and documentation).
+                May contain leading module name separated by a space to avoid
+                name conflicts with same-named structures in other modules.
+                Default module is "XMP" unless otherwise specified.
 
   TYPE        : rdf:type resource for structure.
@@ -871,5 +1089,5 @@
 
   Raw/Value/PrintConv (and their inverses), TagID (optional), Groups, List,
-  Writable, Struct, Namespace, LangCode, PropertyPath.
+  Writable, Struct, Namespace, FlatName, LangCode, PropertyPath, Notes.
 
 But note that for PropertyPath, only the element of the path corresponding to
@@ -878,11 +1096,11 @@
 
 Flattened tags corresponding to each field in a structure are automatically
-generated (using an on-demand approach to avoid spending time generating them
-unless necessary).  Pre-defined 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
-that the List tag is generated automatically unless explicity set to 0 in a
-pre-defined flattened tag.
+generated (using an on-demand approach to reduce startup overhead).  Pre-defined
+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 explicitly set to 0 in a pre-defined flattened
+tag.
 
 --------------------------------------------------------------------------------
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RIFF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RIFF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RIFF.pm	(revision 34921)
@@ -2,7 +2,8 @@
 # File:         RIFF.pm
 #
-# Description:  Read RIFF/WAV/AVI meta information
+# Description:  Read RIFF/AVI/WAV meta information
 #
 # Revisions:    09/14/2005 - P. Harvey Created
+#               06/28/2017 - PH Added MBWF/RF64 support
 #
 # References:   1) http://www.exif.org/Exif2-2.PDF
@@ -19,4 +20,6 @@
 #              12) http://abcavi.kibi.ru/infotags.htm
 #              13) http://tech.ebu.ch/docs/tech/tech3285.pdf
+#              14) https://developers.google.com/speed/webp/docs/riff_container
+#              15) https://tech.ebu.ch/docs/tech/tech3306-2009.pdf
 #------------------------------------------------------------------------------
 
@@ -27,10 +30,52 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.28';
+$VERSION = '1.57';
 
 sub ConvertTimecode($);
-
-# type of current stream
-$Image::ExifTool::RIFF::streamType = '';
+sub ProcessSGLT($$$);
+sub ProcessSLLT($$$);
+sub ProcessLucas($$$);
+
+# recognized RIFF variants
+my %riffType = (
+    'WAVE' => 'WAV', 'AVI ' => 'AVI', 'WEBP' => 'WEBP',
+    'LA02' => 'LA',  'LA03' => 'LA',  'LA04' => 'LA',
+    'OFR ' => 'OFR', 'LPAC' => 'PAC', 'wvpk' => 'WV',
+);
+
+# MIME types of recognized RIFF-format files
+my %riffMimeType = (
+    WAV  => 'audio/x-wav',
+    AVI  => 'video/x-msvideo',
+    WEBP => 'image/webp',
+    LA   => 'audio/x-nspaudio',
+    OFR  => 'audio/x-ofr',
+    PAC  => 'audio/x-lpac',
+    WV   => 'audio/x-wavpack',
+);
+
+# character sets for recognized Windows code pages
+my %code2charset = (
+    0     => 'Latin',
+    65001 => 'UTF8',
+    1252  => 'Latin',
+    1250  => 'Latin2',
+    1251  => 'Cyrillic',
+    1253  => 'Greek',
+    1254  => 'Turkish',
+    1255  => 'Hebrew',
+    1256  => 'Arabic',
+    1257  => 'Baltic',
+    1258  => 'Vietnam',
+    874   => 'Thai',
+    10000 => 'MacRoman',
+    10029 => 'MacLatin2',
+    10007 => 'MacCyrillic',
+    10006 => 'MacGreek',
+    10081 => 'MacTurkish',
+    10010 => 'MacRomanian',
+    10079 => 'MacIceland',
+    10082 => 'MacCroatian',
+);
 
 %Image::ExifTool::RIFF::audioEncoding = ( #2
@@ -99,5 +144,5 @@
     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
@@ -285,11 +330,16 @@
     PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
     NOTES => q{
-        The RIFF container format is used various types of fines including WAV, AVI
-        and WEBP.  According to the EXIF specification, Meta information is embedded
-        in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>, and information
-        about the audio content is stored in the C<fmt > chunk.  As well as this
-        information, some video information and proprietary manufacturer-specific
-        information is also extracted.
-    },
+        The RIFF container format is used various types of fines including AVI, WAV,
+        WEBP, LA, OFR, PAC and WV.  According to the EXIF specification, Meta
+        information is embedded in two types of RIFF C<LIST> chunks: C<INFO> and
+        C<exif>, and information about the audio content is stored in the C<fmt >
+        chunk.  As well as this information, some video information and proprietary
+        manufacturer-specific information is also extracted.
+
+        Large AVI videos may be a concatenation of two or more RIFF chunks.  For
+        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 concatenation technique mentioned above is valid - PH)
    'fmt ' => {
         Name => 'AudioFormat',
@@ -299,4 +349,13 @@
         Name => 'BroadcastExtension',
         SubDirectory => { TagTable => 'Image::ExifTool::RIFF::BroadcastExt' },
+    },
+    ds64 => { #15
+        Name => 'DataSize64',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::DS64' },
+    },
+    list => 'ListType',  #15
+    labl => { #15
+        Name => 'Label',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::Label' },
     },
     LIST_INFO => {
@@ -331,4 +390,12 @@
         },
     },
+    LIST_pntx => { #Andras Salamon (Q-S1 AVI)
+        Name => 'PentaxData2',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Pentax::AVI',
+            ProcessProc => \&Image::ExifTool::RIFF::ProcessChunks,
+        },
+    },
+    # seen LIST_JUNK
     JUNK => [
         {
@@ -364,4 +431,17 @@
         },
         {
+            Name => 'PentaxJunk2', # (Optio RZ18)
+            Condition => '$$valPt =~ /^PENTDigital Camera/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Pentax::Junk2' },
+        },
+        {
+            Name => 'LucasJunk', # (Lucas LK-7900 Ace)
+            Condition => '$$valPt =~ /^0G(DA|PS)/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::QuickTime::Stream',
+                ProcessProc => \&ProcessLucas,
+            },
+        },
+        {
             Name => 'TextJunk',
             # try to interpret unknown junk as an ASCII string
@@ -371,4 +451,5 @@
     _PMX => { #PH (Adobe CS3 Bridge)
         Name => 'XMP',
+        Notes => 'AVI and WAV files',
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
     },
@@ -382,4 +463,138 @@
         SubDirectory => { TagTable => 'Image::ExifTool::Olympus::WAV' },
     },
+    fact => {
+        Name => 'NumberOfSamples',
+        RawConv => 'Get32u(\$val, 0)',
+    },
+   'cue ' => {
+        Name => 'CuePoints',
+        Binary => 1,
+    },
+    afsp => { },
+    IDIT => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        ValueConv => 'Image::ExifTool::RIFF::ConvertRIFFDate($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    CSET => {
+        Name => 'CharacterSet',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::CSET' },
+    },
+    # tx_ tags are generated based on the Codec used for the txts stream
+    tx_USER => {
+        Name => 'UserText',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::UserText' },
+    },
+    tx_Unknown => { # (untested)
+        Name => 'Text',
+        Notes => 'streamed text, extracted when the ExtractEmbedded option is used',
+    },
+#
+# WebP-specific tags
+#
+    EXIF => [{ # (WebP)
+        Name => 'EXIF',
+        Condition => '$$valPt =~ /^(II\x2a\0|MM\0\x2a)/',
+        Notes => 'WebP files',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+        },
+    },{ # (WebP) - have also seen with "Exif\0\0" header - PH
+        Name => 'EXIF',
+        Condition => '$$valPt =~ /^Exif\0\0(II\x2a\0|MM\0\x2a)/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Exif::Main',
+            ProcessProc => \&Image::ExifTool::ProcessTIFF,
+            Start => 6,
+        },
+    },{
+        Name => 'UnknownEXIF',
+        Binary => 1,
+    }],
+   'XMP ' => { #14 (WebP)
+        Name => 'XMP',
+        Notes => 'WebP files',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::Main' },
+    },
+    ICCP => { #14 (WebP)
+        Name => 'ICC_Profile',
+        Notes => 'WebP files',
+        SubDirectory => { TagTable => 'Image::ExifTool::ICC_Profile::Main' },
+    },
+   'VP8 ' => { # (WebP lossy)
+        Name => 'VP8Bitstream',
+        Condition => '$$valPt =~ /^...\x9d\x01\x2a/s',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::VP8' },
+    },
+    VP8L => { #14 (WebP lossless)
+        Name => 'VP8L',
+        Condition => '$$valPt =~ /^\x2f/',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::VP8L' },
+    },
+    VP8X => { #14 (WebP extended)
+        Name => 'VP8X',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::VP8X' },
+    },
+    ANIM => { #14 (WebP animation)
+        Name => 'ANIM',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::ANIM' },
+    },
+    ANMF => { #14 (WebP animation frame)
+        Name => 'ANMF',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::ANMF' },
+    },
+    ALPH => { #14 (WebP alpha)
+        Name => 'ALPH',
+        SubDirectory => { TagTable => 'Image::ExifTool::RIFF::ALPH' },
+    },
+    SGLT => { #PH (BikeBro)
+        Name => 'BikeBroAccel',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::Stream',
+            ProcessProc => \&ProcessSGLT,
+        },
+    },
+    SLLT => { #PH (BikeBro)
+        Name => 'BikeBroGPS',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::QuickTime::Stream',
+            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"
 );
 
@@ -453,5 +668,9 @@
         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 => {
@@ -461,10 +680,48 @@
 );
 
+# 64-bit chunk sizes (ref 15)
+%Image::ExifTool::RIFF::DS64 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    FORMAT => 'int64u',
+    NOTES => q{
+        64-bit data sizes for MBWF/RF64 files.  See
+        L<https://tech.ebu.ch/docs/tech/tech3306-2009.pdf> for the specification.
+    },
+    0 => {
+        Name => 'RIFFSize64',
+        PrintConv => \&Image::ExifTool::ConvertFileSize,
+    },
+    1 => {
+        Name => 'DataSize64',
+        DataMember => 'DataSize64',
+        RawConv => '$$self{DataSize64} = $val',
+        PrintConv => \&Image::ExifTool::ConvertFileSize,
+    },
+    2 => 'NumberOfSamples64',
+    # (after this comes a table of size overrides for chunk
+    #  types other than 'data', but since these are currently
+    #  very unlikely, support for these is not yet implemented)
+);
+
+# cue point labels (ref 15)
+%Image::ExifTool::RIFF::Label = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Audio' },
+    FORMAT => 'int32u',
+    0 => 'LabelID',
+    1 => {
+        Name => 'LabelText',
+        Format => 'string[$size-4]',
+    },
+);
+
 # Sub chunks of INFO LIST chunk
 %Image::ExifTool::RIFF::Info = (
     PROCESS_PROC => \&Image::ExifTool::RIFF::ProcessChunks,
     GROUPS => { 2 => 'Audio' },
+    FORMAT => 'string',
     NOTES => q{
-        RIFF INFO tags found in WAV audio and AVI video files.  Tags which are part
+        RIFF INFO tags found in AVI video and WAV audio files.  Tags which are part
         of the EXIF 2.3 specification have an underlined Tag Name in the HTML
         version of this documentation.  Other tags are found in AVI files generated
@@ -615,4 +872,6 @@
             my @v = split ' ', $val;
             return undef unless @v == 2;
+            # the Kodak EASYSHARE Sport stores this incorrectly as a string:
+            return $val if $val =~ /^\d{4}:\d{2}:\d{2} \d{2}:\d{2}:\d{2}$/;
             # get time in seconds
             $val = 1e-7 * ($v[0] * 4294967296 + $v[1]);
@@ -623,4 +882,13 @@
         PrintConv => '$self->ConvertDateTime($val)',
     },
+    # not observed, but apparently part of the standard:
+    IDIT => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Groups => { 2 => 'Time' },
+        ValueConv => 'Image::ExifTool::RIFF::ConvertRIFFDate($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    ISMP => 'TimeCode',
 );
 
@@ -634,9 +902,9 @@
     etim => { Name => 'TimeCreated', Groups => { 2 => 'Time' } },
     ecor => { Name => 'Make',        Groups => { 2 => 'Camera' } },
-    emdl => { Name => 'Model',       Groups => { 2 => 'Camera' } },
+    emdl => { Name => 'Model',       Groups => { 2 => 'Camera' }, Description => 'Camera Model Name' },
     emnt => { Name => 'MakerNotes',  Binary => 1 },
     eucm => {
         Name => 'UserComment',
-        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val)',
+        PrintConv => 'Image::ExifTool::Exif::ConvertExifText($self,$val,"RIFF:UserComment")',
     },
 );
@@ -657,5 +925,5 @@
         PrintConv => '$self->ConvertDateTime($val)',
     },
-    ISMP => 'Timecode',
+    ISMP => 'TimeCode',
     LIST_strl => {
         Name => 'Stream',
@@ -673,4 +941,18 @@
     GROUPS => { 2 => 'Video' },
     # (have seen tc_O, tc_A, rn_O and rn_A)
+);
+
+# RIFF character set chunk
+%Image::ExifTool::RIFF::CSET = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Other' },
+    FORMAT => 'int16u',
+    0 => {
+        Name => 'CodePage',
+        RawConv => '$$self{CodePage} = $val',
+    },
+    1 => 'CountryCode',
+    2 => 'LanguageCode',
+    3 => 'Dialect',
 );
 
@@ -715,11 +997,17 @@
         {
             Name => 'AudioFormat',
-            Condition => '$Image::ExifTool::RIFF::streamType eq "auds"',
+            Condition => '$$self{RIFFStreamType} eq "auds"',
             SubDirectory => { TagTable => 'Image::ExifTool::RIFF::AudioFormat' },
         },
         {
             Name => 'VideoFormat',
-            Condition => '$Image::ExifTool::RIFF::streamType eq "vids"',
+            Condition => '$$self{RIFFStreamType} eq "vids"',
             SubDirectory => { TagTable => 'Image::ExifTool::BMP::Main' },
+        },
+        {
+            Name => 'TextFormat',
+            Condition => '$$self{RIFFStreamType} eq "txts"',
+            Hidden => 1,
+            RawConv => '$self->Options("ExtractEmbedded") or $self->WarnOnce("Use ExtractEmbedded option to extract timed text"); undef',
         },
     ],
@@ -753,5 +1041,5 @@
         Name => 'StreamType',
         Format => 'string[4]',
-        RawConv => '$Image::ExifTool::RIFF::streamType = $val',
+        RawConv => '$$self{RIFFStreamNum} = ($$self{RIFFStreamNum} || 0) + 1; $$self{RIFFStreamType} = $val',
         PrintConv => {
             auds => 'Audio',
@@ -759,4 +1047,5 @@
             txts => 'Text',
             vids => 'Video',
+            iavs => 'Interleaved Audio+Video',
         },
     },
@@ -764,10 +1053,12 @@
         {
             Name => 'AudioCodec',
-            Condition => '$Image::ExifTool::RIFF::streamType eq "auds"',
+            Condition => '$$self{RIFFStreamType} eq "auds"',
+            RawConv => '$$self{RIFFStreamCodec}[$$self{RIFFStreamNum}-1] = $val',
             Format => 'string[4]',
         },
         {
             Name => 'VideoCodec',
-            Condition => '$Image::ExifTool::RIFF::streamType eq "vids"',
+            Condition => '$$self{RIFFStreamType} eq "vids"',
+            RawConv => '$$self{RIFFStreamCodec}[$$self{RIFFStreamNum}-1] = $val',
             Format => 'string[4]',
         },
@@ -775,4 +1066,5 @@
             Name => 'Codec',
             Format => 'string[4]',
+            RawConv => '$$self{RIFFStreamCodec}[$$self{RIFFStreamNum}-1] = $val',
         },
     ],
@@ -784,5 +1076,5 @@
         {
             Name => 'AudioSampleRate',
-            Condition => '$Image::ExifTool::RIFF::streamType eq "auds"',
+            Condition => '$$self{RIFFStreamType} eq "auds"',
             Format => 'rational64u',
             ValueConv => '$val ? 1/$val : 0',
@@ -791,5 +1083,5 @@
         {
             Name => 'VideoFrameRate',
-            Condition => '$Image::ExifTool::RIFF::streamType eq "vids"',
+            Condition => '$$self{RIFFStreamType} eq "vids"',
             Format => 'rational64u',
             # (must use RawConv because raw value used in Composite tag)
@@ -808,9 +1100,9 @@
         {
             Name => 'AudioSampleCount',
-            Condition => '$Image::ExifTool::RIFF::streamType eq "auds"',
+            Condition => '$$self{RIFFStreamType} eq "auds"',
         },
         {
             Name => 'VideoFrameCount',
-            Condition => '$Image::ExifTool::RIFF::streamType eq "vids"',
+            Condition => '$$self{RIFFStreamType} eq "vids"',
         },
         {
@@ -858,4 +1150,198 @@
 );
 
+# VP8 bitstream (ref http://www.rfc-editor.org/rfc/pdfrfc/rfc6386.txt.pdf)
+%Image::ExifTool::RIFF::VP8 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+        This chunk is found in simple-format (lossy) WebP files. See
+        L<https://developers.google.com/speed/webp/docs/riff_container> for the WebP
+        container specification.
+    },
+    0 => {
+        Name => 'VP8Version',
+        Mask => 0x0e,
+        PrintConv => {
+            0 => '0 (bicubic reconstruction, normal loop)',
+            1 => '1 (bilinear reconstruction, simple loop)',
+            2 => '2 (bilinear reconstruction, no loop)',
+            3 => '3 (no reconstruction, no loop)',
+        },
+    },
+    6 => {
+        Name => 'ImageWidth',
+        Format => 'int16u',
+        Mask => 0x3fff,
+    },
+    6.1 => {
+        Name => 'HorizontalScale',
+        Format => 'int16u',
+        Mask => 0xc000,
+    },
+    8 => {
+        Name => 'ImageHeight',
+        Format => 'int16u',
+        Mask => 0x3fff,
+    },
+    8.1 => {
+        Name => 'VerticalScale',
+        Format => 'int16u',
+        Mask => 0xc000,
+    },
+);
+
+# WebP lossless info (ref 14)
+%Image::ExifTool::RIFF::VP8L = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    NOTES => 'This chunk is found in lossless WebP files.',
+    GROUPS => { 2 => 'Image' },
+    1 => {
+        Name => 'ImageWidth',
+        Format => 'int16u',
+        ValueConv => '($val & 0x3fff) + 1',
+    },
+    2 => {
+        Name => 'ImageHeight',
+        Format => 'int32u',
+        ValueConv => '(($val >> 6) & 0x3fff) + 1',
+    },
+);
+
+# WebP extended info (ref 14)
+%Image::ExifTool::RIFF::VP8X = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'This chunk is found in extended WebP files.',
+    # 0 - bitmask: 2=ICC, 3=alpha, 4=EXIF, 5=XMP, 6=animation
+    4 => {
+        Name => 'ImageWidth',
+        Format => 'int32u',
+        ValueConv => '($val & 0xffffff) + 1',
+    },
+    6 => {
+        Name => 'ImageHeight',
+        Format => 'int32u',
+        ValueConv => '($val >> 8) + 1',
+    },
+);
+
+# WebP animation info (ref 14)
+%Image::ExifTool::RIFF::ANIM = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'WebP animation chunk.',
+    0 => {
+        Name => 'BackgroundColor',
+        Format => 'int8u[4]',
+    },
+    4 => {
+        Name => 'AnimationLoopCount',
+        PrintConv => '$val || "inf"',
+    },
+);
+
+# WebP animation frame info (ref 14)
+%Image::ExifTool::RIFF::ANMF = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'WebP animation frame chunk.',
+    12 => {
+        Name => 'Duration',
+        Format => 'int32u',
+        Notes => 'extracted as the sum of durations of all animation frames',
+        RawConv => q{
+            if (defined $$self{VALUE}{Duration}) {
+                $$self{VALUE}{Duration} += $val & 0x0fff;
+                return undef;
+            }
+            return $val & 0x0fff;
+        },
+        ValueConv => '$val / 1000',
+        PrintConv => 'ConvertDuration($val)',
+    },
+);
+
+# streamed USER txts written by Momento M6 dashcam (ref PH)
+%Image::ExifTool::RIFF::UserText = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Location' },
+    NOTES => q{
+        Tags decoded from the USER-format txts stream written by Momento M6 dashcam.
+        Extracted only if the ExtractEmbedded option is used.
+    },
+    # (little-endian)
+  #  0 - int32u: 32
+  #  4 - int32u: sample number (starting from unknown offset)
+  #  8 - int8u[4]: "w x y z" ? (w 0=front cam, 1=rear cam, z mostly 5-8)
+  # 12 - int8u[4]: "0 x 1 0" ? (x incrementing once per second)
+  # 16 - int8u[4]: "0 32 0 x" ?
+  # 20 - int32u: 100-150(mostly), 250-300(once per second)
+  # 24 - int8u[4]: "0 x y 0" ?
+    28 => { Name => 'GPSAltitude', Format => 'int32u', ValueConv => '$val / 10' }, # (NC)
+  # 32 - int32u: 0(mostly), 23(once per second)
+  # 36 - int32u: 0
+    40 => { Name => 'Accelerometer', Format => 'float[3]' },
+  # 52 - int32u: 1
+    56 => { Name => 'GPSSpeed',      Format => 'float' }, # km/h
+    60 => {
+        Name => 'GPSLatitude',
+        Format => 'float',
+        # Note: these values are unsigned and I don't know where the hemisphere is stored,
+        # but my only sample is from the U.S., so assume a positive latitude (for now)
+        ValueConv => 'my $deg = int($val / 100); $deg + ($val - $deg * 100) / 60',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
+    },
+    64 => {
+        Name => 'GPSLongitude',
+        Format => 'float',
+        # Note: these values are unsigned and I don't know where the hemisphere is stored,
+        # but my only sample is from the U.S., so assume a negative longitude (for now)
+        ValueConv => 'my $deg = int($val / 100); -($deg + ($val - $deg * 100) / 60)',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
+    },
+    68 => {
+        Name => 'GPSDateTime',
+        Description => 'GPS Date/Time',
+        Groups => { 2 => 'Time' },
+        Format => 'int32u',
+        ValueConv => 'ConvertUnixTime($val)',
+        # (likely local time, but clock seemed off by 3 hours in my sample)
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+);
+
+# WebP alpha info (ref 14)
+%Image::ExifTool::RIFF::ALPH = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Image' },
+    NOTES => 'WebP alpha chunk.',
+    0 => {
+        Name => 'AlphaPreprocessing',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'none',
+            1 => 'Level Reduction',
+        },
+    },
+    0.1 => {
+        Name => 'AlphaFiltering',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'none',
+            1 => 'Horizontal',
+            2 => 'Vertical',
+            3 => 'Gradient',
+        },
+    },
+    0.2 => {
+        Name => 'AlphaCompression',
+        Mask => 0x03,
+        PrintConv => {
+            0 => 'none',
+            1 => 'Lossless',
+        },
+    },
+);
+
 # RIFF composite tags
 %Image::ExifTool::RIFF::Composite = (
@@ -869,17 +1355,5 @@
             3 => 'VideoFrameCount',
         },
-        # this is annoying.  Apparently (although I couldn't verify this), FrameCount
-        # in the RIFF header includes multiple video tracks if they exist (ie. with the
-        # FujiFilm REAL 3D AVI's), but the video stream information isn't reliable for
-        # some cameras (ie. Olympus FE models), so use the video stream information
-        # only if the RIFF header duration is 2 to 3 times longer
-        RawConv => q {
-            my ($dur1, $dur2);
-            $dur1 = $val[1] / $val[0] if $val[0];
-            return $dur1 unless $val[2] and $val[3];
-            $dur2 = $val[3] / $val[2];
-            my $rat = $dur1 / $dur2;
-            return ($rat > 1.9 and $rat < 3.1) ? $dur2 : $dur1;
-        },
+        RawConv => 'Image::ExifTool::RIFF::CalcDuration($self, @val)',
         PrintConv => 'ConvertDuration($val)',
     },
@@ -892,9 +1366,13 @@
         Desire => {
             # check FrameCount because this calculation only applies
-            # to audio-only files (ie. WAV)
+            # to audio-only files (eg. WAV)
             2 => 'FrameCount',
             3 => 'VideoFrameCount',
         },
-        RawConv => '($val[0] and not ($val[2] or $val[3])) ? $val[1] / $val[0] : undef',
+        # (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);
+        },
         PrintConv => 'ConvertDuration($val)',
     },
@@ -917,5 +1395,5 @@
     my $mon;
     if (@part >= 5 and $mon = $monthNum{ucfirst(lc($part[1]))}) {
-        # the standard AVI date format (ie. "Mon Mar 10 15:04:43 2003")
+        # the standard AVI date format (eg. "Mon Mar 10 15:04:43 2003")
         $val = sprintf("%.4d:%.2d:%.2d %s", $part[4],
                        $mon, $part[2], $part[3]);
@@ -924,4 +1402,7 @@
         # and the Casio EX-Z30 writes "2005/11/28/ 09:19"... doh!
         $val = sprintf("%.4d:%.2d:%.2d %.2d:%.2d:00",$1,$2,$3,$4+($6?12:0),$5);
+    } elsif ($val =~ m{(\d{4})[-/](\d+)[-/](\d+)\s+(\d+:\d+:\d+)}) {
+        # the Konica KD500Z writes "2002-12-16  15:35:01\0\0"
+        $val = "$1:$2:$3 $4";
     }
     return $val;
@@ -939,5 +1420,64 @@
     my $min = int($val / 60);
     $val -= $min * 60;
-    return sprintf("%d:%.2d:%05.2f", $hr, $min, $val);
+    my $ss = sprintf('%05.2f', $val);
+    if ($ss >= 60) {    # handle round-off problems
+        $ss = '00.00';
+        ++$min >= 60 and $min -= 60, ++$hr;
+    }
+    return sprintf('%d:%.2d:%s', $hr, $min, $ss);
+}
+
+#------------------------------------------------------------------------------
+# Calculate duration of RIFF
+# Inputs: 0) ExifTool ref, 1/2) RIFF:FrameRate/Count, 2/3) VideoFrameRate/Count
+# Returns: Duration in seconds or undef
+# Notes: Sums duration of all sub-documents (concatenated AVI files)
+sub CalcDuration($@)
+{
+    my ($et, @val) = @_;
+    my $totalDuration = 0;
+    my $subDoc = 0;
+    my @keyList;
+    for (;;) {
+        # this is annoying.  Apparently (although I couldn't verify this), FrameCount
+        # in the RIFF header includes multiple video tracks if they exist (eg. with the
+        # 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;
+        $dur1 = $val[1] / $val[0] if $val[0];
+        if ($val[2] and $val[3]) {
+            my $dur2 = $val[3] / $val[2];
+            my $rat = $dur1 / $dur2;
+            $dur1 = $dur2 if $rat > 1.9 and $rat < 3.1;
+        }
+        $totalDuration += $dur1 if defined $dur1;
+        last unless $subDoc++ < $$et{DOC_COUNT};
+        # get tag values for next sub-document
+        my @tags = qw(FrameRate FrameCount VideoFrameRate VideoFrameCount);
+        my $rawValue = $$et{VALUE};
+        my ($i, $j, $key, $keys);
+        for ($i=0; $i<@tags; ++$i) {
+            if ($subDoc == 1) {
+                # generate list of available keys for each tag
+                $keys = $keyList[$i] = [ ];
+                for ($j=0; ; ++$j) {
+                    $key = $tags[$i];
+                    $key .= " ($j)" if $j;
+                    last unless defined $$rawValue{$key};
+                    push @$keys, $key;
+                }
+            } else {
+                $keys = $keyList[$i];
+            }
+            # find key for tag in this sub-document
+            my $grp = "Doc$subDoc";
+            $grp .= ":RIFF" if $i < 2; # (tags 0 and 1 also in RIFF group)
+            $key = $et->GroupMatches($grp, $keys);
+            $val[$i] = $key ? $$rawValue{$key} : undef;
+        }
+        last unless defined $val[0] and defined $val[1]; # (Require'd tags)
+    }
+    return $totalDuration;
 }
 
@@ -948,16 +1488,16 @@
 sub ProcessStreamData($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTbl) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $start = $$dirInfo{DirStart};
     my $size = $$dirInfo{DirLen};
     return 0 if $size < 4;
-    if ($exifTool->Options('Verbose')) {
-        $exifTool->VerboseDir($$dirInfo{DirName}, 0, $size);
+    if ($et->Options('Verbose')) {
+        $et->VerboseDir($$dirInfo{DirName}, 0, $size);
     }
     my $tag = substr($$dataPt, $start, 4);
-    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+    my $tagInfo = $et->GetTagInfo($tagTbl, $tag);
     unless ($tagInfo) {
-        $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 'unknown');
+        $tagInfo = $et->GetTagInfo($tagTbl, 'unknown');
         return 1 unless $tagInfo;
     }
@@ -979,12 +1519,12 @@
             # allow processing of 2nd directory at the same address
             my $addr = $subdirInfo{DirStart} + $subdirInfo{DataPos} + $subdirInfo{Base};
-            delete $exifTool->{PROCESSED}->{$addr}
+            delete $$et{PROCESSED}{$addr}
         }
         # (we could set FIRST_EXIF_POS to $subdirInfo{Base} here to make
         #  htmlDump offsets relative to EXIF base if we wanted...)
         my $subTable = GetTagTable($$subdir{TagTable});
-        $exifTool->ProcessDirectory(\%subdirInfo, $subTable);
+        $et->ProcessDirectory(\%subdirInfo, $subTable);
     } else {
-        $exifTool->HandleTag($tagTablePtr, $tag, undef,
+        $et->HandleTag($tagTbl, $tag, undef,
             DataPt  => $dataPt,
             DataPos => $$dirInfo{DataPos},
@@ -998,11 +1538,28 @@
 
 #------------------------------------------------------------------------------
+# Make tag information hash for unknown tag
+# Inputs: 0) Tag table ref, 1) tag ID
+sub MakeTagInfo($$)
+{
+    my ($tagTbl, $tag) = @_;
+    my $name = $tag;
+    my $n = ($name =~ s/([\x00-\x1f\x7f-\xff])/'x'.unpack('H*',$1)/eg);
+    # print in hex if tag is numerical
+    $name = sprintf('0x%.4x',unpack('N',$tag)) if $n > 2;
+    AddTagToTable($tagTbl, $tag, {
+        Name => "Unknown_$name",
+        Description => "Unknown $name",
+        Unknown => 1,
+        Binary => 1,
+    });
+}
+
+#------------------------------------------------------------------------------
 # 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($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTbl) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $start = $$dirInfo{DirStart};
@@ -1010,8 +1567,18 @@
     my $end = $start + $size;
     my $base = $$dirInfo{Base};
-
-    if ($exifTool->Options('Verbose')) {
-        $exifTool->VerboseDir($$dirInfo{DirName}, 0, $size);
+    my $verbose = $et->Options('Verbose');
+    my $unknown = $et->Options('Unknown');
+    my $charset = $et->Options('CharsetRIFF');
+
+    unless ($charset) {
+        if ($$et{CodePage}) {
+            $charset = $$et{CodePage};
+        } elsif (defined $charset and $charset eq '0') {
+            $charset = 'Latin';
+        }
     }
+
+    $et->VerboseDir($$dirInfo{DirName}, 0, $size) if $verbose;
+
     while ($start + 8 < $end) {
         my $tag = substr($$dataPt, $start, 4);
@@ -1019,5 +1586,5 @@
         $start += 8;
         if ($start + $len > $end) {
-            $exifTool->Warn("Bad $tag chunk");
+            $et->Warn("Bad $tag chunk");
             return 0;
         }
@@ -1027,5 +1594,5 @@
             $start += 4;
         }
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTbl, $tag);
         my $baseShift = 0;
         my $val;
@@ -1044,9 +1611,16 @@
                 }
             } elsif (not $$tagInfo{Binary}) {
-                $val = substr($$dataPt, $start, $len);
-                $val =~ s/\0+$//;   # remove trailing nulls from strings
+                my $format = $$tagInfo{Format} || $$tagTbl{FORMAT};
+                if ($format and $format eq 'string') {
+                    $val = substr($$dataPt, $start, $len);
+                    $val =~ s/\0+$//;   # remove trailing nulls from strings
+                    # decode if necessary
+                    $val = $et->Decode($val, $charset) if $charset;
+                }
             }
+        } elsif ($verbose or $unknown) {
+            MakeTagInfo($tagTbl, $tag);
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+        $et->HandleTag($tagTbl, $tag, $val,
             DataPt  => $dataPt,
             DataPos => $$dirInfo{DataPos} - $baseShift,
@@ -1054,4 +1628,5 @@
             Size    => $len,
             Base    => $base + $baseShift,
+            Addr    => $base + $baseShift + $start,
         );
         ++$len if $len & 0x01;  # must account for padding if odd number of bytes
@@ -1062,4 +1637,177 @@
 
 #------------------------------------------------------------------------------
+# Process BikeBro SGLT chunk (accelerometer data) (ref PH)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessSGLT($$$)
+{
+    my ($et, $dirInfo, $tagTbl) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataLen = length $$dataPt;
+    my $ee = $et->Options('ExtractEmbedded');
+    my $pos;
+    # example accelerometer record:
+    # 0           1  2  3           4  5           6  7
+    # 00 00 00 24 02 00 00 01 17 04 00 00 00 00 00 00 00 00 9b 02
+    # frame------ ?? Xs X---------- Ys Y---------- Zs Z----------
+    $$et{SET_GROUP0} = $$et{SET_GROUP1} = 'RIFF';
+    for ($pos=0; $pos<=$dataLen-20; $pos+=20) {
+        $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+        my $buff = substr($$dataPt, $pos);
+        my @a = unpack('NCCNCNCN', $buff);
+        my @acc = ($a[3]*($a[2]?-1:1)/1e5, $a[5]*($a[4]?-1:1)/1e5, $a[7]*($a[6]?-1:1)/1e5);
+        $et->HandleTag($tagTbl, FrameNumber   => $a[0]);
+        $et->HandleTag($tagTbl, Accelerometer => "@acc");
+        unless ($ee) {
+            $et->Warn('Use ExtractEmbedded option to extract all accelerometer data', 3);
+            last;
+        }
+    }
+    delete $$et{SET_GROUP0};
+    delete $$et{SET_GROUP1};
+    $$et{DOC_NUM} = 0;
+    return 0;
+}
+
+#------------------------------------------------------------------------------
+# Process BikeBro SLLT chunk (GPS information) (ref PH)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessSLLT($$$)
+{
+    my ($et, $dirInfo, $tagTbl) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataLen = length $$dataPt;
+    my $ee = $et->Options('ExtractEmbedded');
+    my $pos;
+    # example GPS record:
+    # 0           1  2     3           4     5           6     7     8  9  10 11    12 13 14 15
+    # 00 00 00 17 01 00 00 03 fa 21 ec 00 35 01 6e c0 06 00 08 00 62 10 0b 1b 07 e2 03 0e 57 4e
+    # frame------ ?? lonDD lonDDDDDDDD latDD latDDDDDDDD alt-- spd-- hr mn sc yr--- mn dy EW NS
+    $$et{SET_GROUP0} = $$et{SET_GROUP1} = 'RIFF';
+    for ($pos=0; $pos<=$dataLen-30; $pos+=30) {
+        $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+        my $buff = substr($$dataPt, $pos);
+        my @a = unpack('NCnNnNnnCCCnCCaa', $buff);
+        # - is $a[1] perhaps GPSStatus? (only seen 1, or perhaps record type 1=GPS, 2=acc?)
+        my $time = sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2dZ', @a[11..13, 8..10]);
+        $et->HandleTag($tagTbl, FrameNumber  => $a[0]);
+        $et->HandleTag($tagTbl, GPSDateTime  => $time);
+        $et->HandleTag($tagTbl, GPSLatitude  => ($a[4] + $a[5]/1e8) * ($a[15] eq 'S' ? -1 : 1));
+        $et->HandleTag($tagTbl, GPSLongitude => ($a[2] + $a[3]/1e8) * ($a[14] eq 'W' ? -1 : 1));
+        $et->HandleTag($tagTbl, GPSAltitude  => $a[6]);
+        $et->HandleTag($tagTbl, GPSSpeed     => $a[7]);
+        $et->HandleTag($tagTbl, GPSSpeedRef  => 'K');
+        unless ($ee) {
+            $et->Warn('Use ExtractEmbedded option to extract timed GPS', 3);
+            last;
+        }
+    }
+    delete $$et{SET_GROUP0};
+    delete $$et{SET_GROUP1};
+    $$et{DOC_NUM} = 0;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# Process Lucas streaming GPS information (Lucas LK-7900 Ace) (ref PH)
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessLucas($$$)
+{
+    my ($et, $dirInfo, $tagTbl) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataLen = length $$dataPt;
+
+    unless ($et->Options('ExtractEmbedded')) {
+        $et->Warn('Use ExtractEmbedded option to extract timed GPS', 3);
+        return 1;
+    }
+    my %recLen = (  # record lengths (not including 4-byte ID)
+        '0GDA' => 24,
+        '0GPS' => 48,
+    );
+    my ($date,$time,$lat,$lon,$alt,$spd,$sat,$dop,$ew,$ns);
+    $$et{SET_GROUP0} = $$et{SET_GROUP1} = 'RIFF';
+    while ($$dataPt =~ /(0GDA|0GPS)/g) {
+        my ($rec, $pos) = ($1, pos $$dataPt);
+        $pos + $recLen{$rec} > $dataLen and $et->Warn("Truncated $1 record"), last;
+        $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+        # records start with int64u sample date/time in ms since 1970
+        $et->HandleTag($tagTbl, SampleDateTime => Get64u($dataPt, $pos) / 1000);
+        if ($rec eq '0GPS') {
+            my $len = Get32u($dataPt, $pos+8);
+            my $endPos = $pos + $recLen{$rec} + $len;
+            $endPos > $dataLen and $et->Warn('Truncated 0GPS record'), last;
+            my $buff = substr($$dataPt, $pos+$recLen{$rec}, $len);
+            while ($buff =~ /\$(GC|GA),(\d+),/g) {
+                my $p = pos $buff;
+                $time = $2;
+                if ($1 eq 'GC') {
+                    #     time   date   dist    ? sat dop alt  A
+                    # $GC,052350,180914,0000955,1,08,1.1,0017,,A*45\x0d\x0a\0
+                    if ($buff =~ /\G(\d+),\d*,\d*,(\d+),([-\d.]+),(\d+),\d*,A/g) {
+                        ($date,$sat,$dop,$alt) = ($1,$2,$3,$4);
+                    }
+                } else {
+                    #     time   A lat       lon        spd N W
+                    # $GA,052351,A,0949.6626,07635.4439,049,N,E,*4C\x0d\x0a\0
+                    if ($buff =~ /\GA,([\d.]+),([\d.]+),(\d+),([NS]),([EW])/g) {
+                        ($lat,$lon,$spd,$ns,$ew) = ($1,$2,$3,$4,$5,$6);
+                        # 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;
+                        $lat *= -1 if $ns eq 'S';
+                        $lon *= -1 if $ew eq 'W';
+                    }
+                }
+                # look ahead to next NMEA-like sentence, and store the fix
+                # now only if the next sentence is not at the same time
+                if ($buff !~ /\$(GC|GA),$time,/g) {
+                    pos($$dataPt) = $endPos;
+                    if ($$dataPt !~ /\$(GC|GA),(\d+)/ or $1 ne $time) {
+                        $time =~ s/(\d{2})(\d{2})(\d{2})/$1:$2:$3Z/;
+                        if ($date) {
+                            $date =~ s/(\d{2})(\d{2})(\d{2})/20$3:$2:$1/;
+                            $et->HandleTag($tagTbl, GPSDateTime => "$date $time");
+                        } else {
+                            $et->HandleTag($tagTbl, GPSTimeStamp => $time);
+                        }
+                        if (defined $lat) {
+                            $et->HandleTag($tagTbl, GPSLatitude => $lat);
+                            $et->HandleTag($tagTbl, GPSLongitude => $lon);
+                            $et->HandleTag($tagTbl, GPSSpeed => $spd);
+                        }
+                        if (defined $alt) {
+                            $et->HandleTag($tagTbl, GPSAltitude => $alt);
+                            $et->HandleTag($tagTbl, GPSSatellites => $sat);
+                            $et->HandleTag($tagTbl, GPSDOP => $dop);
+                        }
+                        undef $lat;
+                        undef $alt;
+                    }
+                }
+                pos($buff) = $p;
+            }
+            $pos += $len;
+        } else { # this is an accelerometer (0GDA) record
+            # record has 4 more int32s values (the last is always 57 or 58 --
+            # maybe related to sample time in ms? -- not extracted)
+            my @acc = unpack('x'.($pos+8).'V3', $$dataPt);
+            # change to signed integer and divide by 256
+            map { $_ = $_ - 4294967296 if $_ >= 0x80000000; $_ /= 256 } @acc;
+            $et->HandleTag($tagTbl, Accelerometer => "@acc");
+        }
+        pos($$dataPt) = $pos + $recLen{$rec};
+    }
+    delete $$et{SET_GROUP0};
+    delete $$et{SET_GROUP1};
+    $$et{DOC_NUM} = 0;
+    return 1;
+}
+
+#------------------------------------------------------------------------------
 # Extract information from a RIFF file
 # Inputs: 0) ExifTool object reference, 1) DirInfo reference
@@ -1067,17 +1815,31 @@
 sub ProcessRIFF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my ($buff, $err);
-    my %types = ( 'WAVE' => 'WAV', 'AVI ' => 'AVI', 'WEBP' => 'WEBP' );
-    my $verbose = $exifTool->Options('Verbose');
+    my ($buff, $buf2, $type, $mime, $err, $rf64);
+    my $verbose = $et->Options('Verbose');
+    my $unknown = $et->Options('Unknown');
+    my $ee = $et->Options('ExtractEmbedded');
 
     # verify this is a valid RIFF file
     return 0 unless $raf->Read($buff, 12) == 12;
-    return 0 unless $buff =~ /^RIFF....(.{4})/s;
-    $exifTool->SetFileType($types{$1}); # set type to 'WAV', 'AVI', 'WEBP' or 'RIFF'
-    $Image::ExifTool::RIFF::streamType = '';    # initialize stream type
+    if ($buff =~ /^(RIFF|RF64)....(.{4})/s) {
+        $type = $riffType{$2};
+        $rf64 = 1 if $1 eq 'RF64';
+    } else {
+        # minimal support for a few obscure lossless audio formats...
+        return 0 unless $buff =~ /^(LA0[234]|OFR |LPAC|wvpk)/ and $raf->Read($buf2, 1024);
+        $type = $riffType{$1};
+        $buff .= $buf2;
+        return 0 unless $buff =~ /WAVE(.{4})?fmt /sg and $raf->Seek(pos($buff) - 4, 0);
+    }
+    $$raf{NoBuffer} = 1 if $et->Options('FastScan'); # disable buffering in FastScan mode
+    $mime = $riffMimeType{$type} if $type;
+    $et->SetFileType($type, $mime);
+    $$et{VALUE}{FileType} .= ' (RF64)' if $rf64;
+    $$et{RIFFStreamType} = '';      # initialize stream type
+    $$et{RIFFStreamCodec} = [];     # initialize codec array
     SetByteOrder('II');
-    my $tagTablePtr = GetTagTable('Image::ExifTool::RIFF::Main');
+    my $tagTbl = GetTagTable('Image::ExifTool::RIFF::Main');
     my $pos = 12;
 #
@@ -1098,20 +1860,45 @@
             $tag .= "_$buff";
             $len -= 4;  # already read 4 bytes (the LIST type)
+        } elsif ($tag eq 'data' and $len == 0xffffffff and $$et{DataSize64}) {
+            $len = $$et{DataSize64};
         }
-        $exifTool->VPrint(0, "RIFF '$tag' chunk ($len bytes of data):\n");
+        $et->VPrint(0, "RIFF '${tag}' chunk ($len bytes of data):\n");
+        if ($len <= 0) {
+            if ($len < 0) {
+                $et->Warn('Invalid chunk length');
+            } elsif ($tag eq "\0\0\0\0") {
+                # avoid reading through corupted files filled with nulls because it takes forever
+                $et->Warn('Encountered empty null chunk. Processing aborted');
+            } else {
+                next;
+            }
+            last;
+        }
         # stop when we hit the audio data or AVI index or AVI movie data
         # --> no more because Adobe Bridge stores XMP after this!!
         # (so now we only do this on the FastScan option)
-        if (($tag eq 'data' or $tag eq 'idx1' or $tag eq 'LIST_movi') and
-            $exifTool->Options('FastScan'))
+        if ($et->Options('FastScan') and ($tag eq 'data' or $tag eq 'idx1' or
+            ($tag eq 'LIST_movi' and not $ee)))
         {
-            $exifTool->VPrint(0, "(end of parsing)\n");
+            $et->VPrint(0, "(end of parsing)\n");
             last;
         }
         # RIFF chunks are padded to an even number of bytes
         my $len2 = $len + ($len & 0x01);
-        if ($$tagTablePtr{$tag} or ($verbose and $tag !~ /^(data|idx1|LIST_movi)$/)) {
+        # change name of stream txts data depending on the Codec
+        if ($ee and $tag =~ /^(\d{2})tx$/) {
+            $tag = 'tx_' . ($$et{RIFFStreamCodec}[$1] || 'Unknown');
+            $tag = "tx_Unknown" unless defined $$tagTbl{$tag};
+            $$et{DOC_NUM} = ++$$et{DOC_COUNT};
+        }
+        my $tagInfo = $$tagTbl{$tag};
+        if ($tagInfo or (($verbose or $unknown) and $tag !~ /^(data|idx1|LIST_movi|RIFF|\d{2}(db|dc|wb))$/)) {
             $raf->Read($buff, $len2) == $len2 or $err=1, last;
-            $exifTool->HandleTag($tagTablePtr, $tag, $buff,
+            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)
@@ -1120,10 +1907,27 @@
                 Base    => $pos,
             );
+            if ($setGroups) {
+                delete $$et{SET_GROUP0};
+                delete $$et{SET_GROUP1};
+            }
+            delete $$et{DOC_NUM} if $ee;
+        } elsif ($tag eq 'RIFF') {
+            # don't read into RIFF chunk (eg. concatenated video file)
+            $raf->Read($buff, 4) == 4 or $err=1, last;
+            # extract information from remaining file as an embedded file
+            $$et{DOC_NUM} = ++$$et{DOC_COUNT}
+        } elsif ($tag eq 'LIST_movi' and $ee) {
+            next; # parse into movi chunk
         } else {
+            if ($len > 0x7fffffff and not $et->Options('LargeFileSupport')) {
+                $et->Warn("Stopped parsing at large $tag chunk (LargeFileSupport not set)");
+                last;
+            }
             $raf->Seek($len2, 1) or $err=1, last;
         }
         $pos += $len2;
     }
-    $err and $exifTool->Warn('Error reading RIFF file (corrupted?)');
+    delete $$et{DOC_NUM};
+    $err and $et->Warn('Error reading RIFF file (corrupted?)');
     return 1;
 }
@@ -1135,5 +1939,5 @@
 =head1 NAME
 
-Image::ExifTool::RIFF - Read RIFF/WAV/AVI meta information
+Image::ExifTool::RIFF - Read RIFF/AVI/WAV meta information
 
 =head1 SYNOPSIS
@@ -1145,9 +1949,9 @@
 This module contains routines required by Image::ExifTool to extract
 information from RIFF-based (Resource Interchange File Format) files,
-including Windows WAV audio and AVI video files.
+including AVI videos, WAV audio files and WEBP images.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -1170,4 +1974,8 @@
 =item L<http://wiki.multimedia.cx/index.php?title=TwoCC>
 
+=item L<https://developers.google.com/speed/webp/docs/riff_container>
+
+=item L<https://tech.ebu.ch/docs/tech/tech3306-2009.pdf>
+
 =back
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RSRC.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RSRC.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RSRC.pm	(revision 34921)
@@ -15,15 +15,20 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.02';
+$VERSION = '1.09';
+
+sub ProcessRSRC($$);
 
 # Information decoded from Mac OS resources
 %Image::ExifTool::RSRC::Main = (
     GROUPS => { 2 => 'Document' },
+    PROCESS_PROC => \&ProcessRSRC,
     NOTES => q{
-        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 "/rsrc" to the filename to process the resource fork alone, or by
-        using the ExtractEmbedded (-ee) option to process the resource fork as a
-        sub-document of the main file.
+        Tags extracted from Mac OS resource files, DFONT files and "._" sidecar
+        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 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.
     },
     '8BIM' => {
@@ -34,4 +39,10 @@
         Name => 'Font',
         SubDirectory => { TagTable => 'Image::ExifTool::Font::Name' },
+    },
+    # my samples of postscript-type DFONT files have a POST resource
+    # with ID 0x1f5 and the same format as a PostScript file
+    'POST_0x01f5' => {
+        Name => 'PostscriptFont',
+        SubDirectory => { TagTable => 'Image::ExifTool::PostScript::Main' },
     },
     'usro_0x0000' => 'OpenWithApplication',
@@ -55,7 +66,10 @@
 sub ProcessRSRC($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($hdr, $map, $buff, $i, $j);
+
+    # allow access with data reference
+    $raf or $raf = new File::RandomAccess($$dirInfo{DataPt});
 
     # attempt to validate the format as thoroughly as practical
@@ -74,15 +88,16 @@
     my $typeOff = Get16u(\$map, 24);
     my $nameOff = Get16u(\$map, 26);
-    my $numTypes = Get16u(\$map, 28);
+    my $numTypes = (Get16u(\$map, 28) + 1) & 0xffff;
 
     # validate offsets in the resource map
     return 0 if $typeOff < 28 or $nameOff < 30;
 
-    $exifTool->SetFileType('RSRC') unless $$exifTool{IN_RESOURCE};
-    my $verbose = $exifTool->Options('Verbose');
+    $et->SetFileType('RSRC') unless $$et{IN_RESOURCE};
+    my $verbose = $et->Options('Verbose');
     my $tagTablePtr = GetTagTable('Image::ExifTool::RSRC::Main');
+    $et->VerboseDir('RSRC', $numTypes);
 
     # parse resource type list
-    for ($i=0; $i<=$numTypes; ++$i) {
+    for ($i=0; $i<$numTypes; ++$i) {
         my $off = $typeOff + 2 + 8 * $i;    # offset of entry in type list
         last if $off + 8 > $mapLen;
@@ -109,8 +124,8 @@
             if ($tagInfo or $verbose) {
                 unless ($raf->Seek($resOff, 0) and $raf->Read($buff, 4) == 4 and
-                        ($valLen = unpack('N', $buff)) < 1024000 and # arbitrary size limit
+                        ($valLen = unpack('N', $buff)) < 100000000 and # arbitrary size limit (100MB)
                         $raf->Read($val, $valLen) == $valLen)
                 {
-                    $exifTool->Warn("Error reading $resType resource");
+                    $et->Warn("Error reading $resType resource");
                     next;
                 }
@@ -120,6 +135,7 @@
                 $resName = '' unless $raf->Seek($resNameOff, 0) and $raf->Read($buff, 1) and
                     ($nameLen = ord $buff) != 0 and $raf->Read($resName, $nameLen) == $nameLen;
-                $exifTool->VPrint(0,sprintf("$resType resource ID 0x%.4x (offset 0x%.4x, $valLen bytes, name='$resName'):\n", $id, $resOff));
-                $exifTool->VerboseDump(\$val);
+                $et->VPrint(0,sprintf("%s resource ID 0x%.4x (offset 0x%.4x, $valLen bytes, name='%s'):\n",
+                    $resType, $id, $resOff, $resName));
+                $et->VerboseDump(\$val);
             }
             next unless $tagInfo;
@@ -133,5 +149,5 @@
                 next if $p + $vlen > $valLen;
                 my $tagTablePtr = GetTagTable('Image::ExifTool::RSRC::Main');
-                $val = $exifTool->Decode(substr($val, $p, $vlen), 'MacRoman');
+                $val = $et->Decode(substr($val, $p, $vlen), 'MacRoman');
             } elsif ($resType eq 'sfnt') {
                 # parse the OTF font block
@@ -139,12 +155,13 @@
                 $$dirInfo{Base} = $resOff + 4;
                 require Image::ExifTool::Font;
-                unless (Image::ExifTool::Font::ProcessOTF($exifTool, $dirInfo)) {
-                    $exifTool->Warn('Unrecognized sfnt resource format');
+                unless (Image::ExifTool::Font::ProcessOTF($et, $dirInfo)) {
+                    $et->Warn('Unrecognized sfnt resource format');
                 }
-                $exifTool->OverrideFileType('DFONT');
+                # assume this is a DFONT file unless processing the rsrc fork
+                $et->OverrideFileType('DFONT') unless $$et{DOC_NUM};
                 next;
             } elsif ($resType eq '8BIM') {
                 my $ttPtr = GetTagTable('Image::ExifTool::Photoshop::Main');
-                $exifTool->HandleTag($ttPtr, $id, $val,
+                $et->HandleTag($ttPtr, $id, $val,
                     DataPt  => \$val,
                     DataPos => $resOff + 4,
@@ -177,8 +194,12 @@
                 }
                 $val = \@vals;
+            } elsif ($resType eq 'POST') {
+                # assume this is a DFONT file unless processing the rsrc fork
+                $et->OverrideFileType('DFONT') unless $$et{DOC_NUM};
+                $val = substr $val, 2;
             } elsif ($resType ne 'TEXT') {
                 next;
             }
-            $exifTool->HandleTag($tagTablePtr, $tag, $val);
+            $et->HandleTag($tagTablePtr, $tag, $val);
         }
     }
@@ -205,5 +226,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RTF.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RTF.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/RTF.pm	(revision 34921)
@@ -16,5 +16,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.01';
+$VERSION = '1.04';
 
 sub ProcessUserProps($$$);
@@ -40,6 +40,6 @@
         will also extract any non-standard tags found in this group.  As well,
         ExifTool will extract any custom properties that are found.  See
-        L<http://download.microsoft.com/download/2/f/5/2f599e18-07ee-4ec5-a1e7-f4e6a9423592/Word2007RTFSpec9.doc>
-        for the specification.
+        L<http://www.microsoft.com/en-ca/download/details.aspx?id=10725> for the
+        specification.
     },
     title    => { },
@@ -147,5 +147,5 @@
 sub UnescapeRTF($$$)
 {
-    my ($exifTool, $val, $charset) = @_;
+    my ($et, $val, $charset) = @_;
 
     # return now unless we have a control sequence
@@ -154,8 +154,10 @@
         return $val;
     }
-    # CR/LF is signficant if it terminates a control sequence (so change these to a space)
-    $val =~ s/(^|[^\\])((?:\\\\)*)(\\[a-zA-Z]+(?:-?\d+)?)[\n\r]/$1$2$3 /g;
+    # 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
-    $val =~ s/(^|[^\\])((?:\\\\)*)(\\[\n\r])/$1$2\\par /g;
+    # (was $val =~ s/(^|[^\\])((?:\\\\)*)(\\[\n\r])/$1$2\\par /g;)
+    $val =~ s/(\\[\n\r])|(\\.)/$2 || '\\par '/sge;
     # all other CR/LF's are ignored (so delete them)
     $val =~ tr/\n\r//d;
@@ -180,14 +182,19 @@
                 $skip = $2;
             } elsif ($1 eq 'u') {   # \uN
-                require Image::ExifTool::Charset;
-                $rtnVal .= Image::ExifTool::Charset::Recompose($exifTool, [$2]);
-                if ($skip) {
-                    # must skip the specified number of characters
-                    # (not simple because RTF control words count as a single character)
-                    last unless $val =~ /\G([^\\]|\\([a-zA-Z]+)(-?\d+)? ?|\\'.{2}|\\.){$skip}/g;
+                if ($2 < 0) {
+                    $et->WarnOnce('Invalid Unicode character(s) in text');
+                    $rtnVal .= '?';
+                } else {
+                    require Image::ExifTool::Charset;
+                    $rtnVal .= Image::ExifTool::Charset::Recompose($et, [$2]);
+                    if ($skip) {
+                        # must skip the specified number of characters
+                        # (not simple because RTF control words count as a single character)
+                        last unless $val =~ /\G([^\\]|\\([a-zA-Z]+)(-?\d+)? ?|\\'.{2}|\\.){$skip}/g;
+                    }
                 }
             } elsif ($rtfEntity{$1}) {
                 require Image::ExifTool::Charset;
-                $rtnVal .= Image::ExifTool::Charset::Recompose($exifTool, [$rtfEntity{$1}]);
+                $rtnVal .= Image::ExifTool::Charset::Recompose($et, [$rtfEntity{$1}]);
             } # (else ignore the command)
         } else {
@@ -199,5 +206,5 @@
                 if ($hex =~ /^[0-9a-fA-F]{2}$/) {
                     require Image::ExifTool::Charset;
-                    $rtnVal .= $exifTool->Decode(chr(hex($hex)), $charset);
+                    $rtnVal .= $et->Decode(chr(hex($hex)), $charset);
                 }
                 pos($val) = $p1 + 3;    # skip to after the hex code
@@ -221,15 +228,15 @@
 sub ProcessRTF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $buf2, $cs);
-    
+
     return 0 unless $raf->Read($buff, 64) and $raf->Seek(0,0);
     return 0 unless $buff =~ /^[\n\r]*\{[\n\r]*\\rtf[^a-zA-Z]/;
-    $exifTool->SetFileType();
+    $et->SetFileType();
 #
 # determine the RTF character set
 #
-    if ($buff=~ /\\ansicpg(\d*)/) { 
+    if ($buff=~ /\\ansicpg(\d*)/) {
         $cs = "cp$1";
     } elsif ($buff=~ /\\(ansi|mac|pc|pca)[^a-zA-Z]/) {
@@ -242,10 +249,10 @@
         $cs = $trans{$1};
     } else {
-        $exifTool->Warn('Unspecified RTF encoding. Will assume Latin');
+        $et->Warn('Unspecified RTF encoding. Will assume Latin');
         $cs = 'Latin';
     }
     my $charset = $Image::ExifTool::charsetName{lc $cs};
     unless ($charset) {
-        $exifTool->Warn("Unsupported RTF encoding $cs. Will assume Latin.");
+        $et->Warn("Unsupported RTF encoding $cs. Will assume Latin.");
         $charset = 'Latin';
     }
@@ -268,8 +275,8 @@
         my $info = ReadToNested(\$buff, $raf);
         unless (defined $info) {
-            $exifTool->Warn('Unterminated information group');
+            $et->Warn('Unterminated information group');
             last;
         }
-        # process info commands (ie. "\author", "\*\copyright");
+        # process info commands (eg. "\author", "\*\copyright");
         while ($info =~ /\{[\n\r]*(\\\*[\n\r]*)?\\([a-zA-Z]+)([^a-zA-Z])/g) {
             pos($info) = pos($info) - 1 if $3 ne ' ';
@@ -289,11 +296,11 @@
             } else {
                 # unescape RTF string value
-                $val = UnescapeRTF($exifTool, $val, $charset);
+                $val = UnescapeRTF($et, $val, $charset);
             }
             # create tagInfo for unknown tags
             if (not $tagInfo) {
-                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => ucfirst($tag) });
-            }
-            $exifTool->HandleTag($tagTablePtr, $tag, $val);
+                AddTagToTable($tagTablePtr, $tag, { Name => ucfirst($tag) });
+            }
+            $et->HandleTag($tagTablePtr, $tag, $val);
         }
     }
@@ -310,5 +317,5 @@
         $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::RTF::UserProps');
         unless (defined $props) {
-            $exifTool->Warn('Unterminated user properties');
+            $et->Warn('Unterminated user properties');
             last;
         }
@@ -320,5 +327,5 @@
             my $val = ReadToNested(\$props);
             last unless defined $val;
-            $val = UnescapeRTF($exifTool, $val, $charset);
+            $val = UnescapeRTF($et, $val, $charset);
             if ($t eq 'propname') {
                 $tag = $val;
@@ -332,7 +339,7 @@
             # create tagInfo for unknown tags
             unless ($$tagTablePtr{$tag}) {
-                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $tag });
-            }
-            $exifTool->HandleTag($tagTablePtr, $tag, $val);
+                AddTagToTable($tagTablePtr, $tag, { Name => $tag });
+            }
+            $et->HandleTag($tagTablePtr, $tag, $val);
         }
         last;   # (didn't really want to loop)
@@ -360,5 +367,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Radiance.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Radiance.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Radiance.pm	(revision 34921)
@@ -0,0 +1,149 @@
+#------------------------------------------------------------------------------
+# File:         Radiance.pm
+#
+# Description:  Read Radiance RGBE HDR meta information
+#
+# Revisions:    2011/12/10 - P. Harvey Created
+#
+# References:   1) http://www.graphics.cornell.edu/online/formats/rgbe/
+#               2) http://radsite.lbl.gov/radiance/refer/filefmts.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Radiance;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.02';
+
+# Radiance tags
+%Image::ExifTool::Radiance::Main = (
+    GROUPS => { 2 => 'Image' },
+    NOTES => q{
+        Information extracted from Radiance RGBE HDR images.  Tag ID's are all
+        uppercase as stored in the file, but converted to lowercase by when
+        extracting to avoid conflicts with internal ExifTool variables.  See
+        L<http://radsite.lbl.gov/radiance/refer/filefmts.pdf> and
+        L<http://www.graphics.cornell.edu/online/formats/rgbe/> for the
+        specification.
+    },
+    _orient   => {
+        Name => 'Orientation',
+        PrintConv => {
+            '-Y +X' => 'Horizontal (normal)',
+            '-Y -X' => 'Mirror horizontal',
+            '+Y -X' => 'Rotate 180',
+            '+Y +X' => 'Mirror vertical',
+            '+X -Y' => 'Mirror horizontal and rotate 270 CW',
+            '+X +Y' => 'Rotate 90 CW',
+            '-X +Y' => 'Mirror horizontal and rotate 90 CW',
+            '-X -Y' => 'Rotate 270 CW',
+        },
+    },
+    _command  => 'Command',
+    _comment  => 'Comment',
+    software  => 'Software',
+    view      => 'View',
+   'format'   => 'Format', # <-- this is the one that caused the conflict when uppercase
+    exposure  => {
+        Name => 'Exposure',
+        Notes => 'divide pixel values by this to get watts/steradian/meter^2',
+    },
+    gamma     => 'Gamma',
+    colorcorr => 'ColorCorrection',
+    pixaspect => 'PixelAspectRatio',
+    primaries => 'ColorPrimaries',
+);
+
+#------------------------------------------------------------------------------
+# Extract information from a Radiance HDR file
+# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid RGBE image
+sub ProcessHDR($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $buff;
+    local $/ = "\x0a";  # set newline character for reading
+
+    # verify this is a valid RIFF file
+    return 0 unless $raf->ReadLine($buff) and $buff =~ /^#\?(RADIANCE|RGBE)\x0a/s;
+    $et->SetFileType();
+    my $tagTablePtr = GetTagTable('Image::ExifTool::Radiance::Main');
+
+    while ($raf->ReadLine($buff)) {
+        chomp $buff;
+        last unless length($buff) > 0 and length($buff) < 4096;
+        if ($buff =~ s/^#\s*//) {
+            $et->HandleTag($tagTablePtr, '_comment', $buff) if length $buff;
+            next;
+        }
+        unless ($buff =~ /^(.*)?\s*=\s*(.*)/) {
+            $et->HandleTag($tagTablePtr, '_command', $buff) if length $buff;
+            next;
+        }
+        # use lower-case tag names to avoid conflicts with reserved tag table entries
+        my ($tag, $val) = (lc $1, $2);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        unless ($tagInfo) {
+            my $name = $tag;
+            $name =~ tr/-_a-zA-Z0-9//dc;
+            next unless length($name) > 1;
+            $name = ucfirst $name;
+            $tagInfo = { Name => $name };
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        $et->FoundTag($tagInfo, $val);
+    }
+    # get image dimensions
+    if ($raf->ReadLine($buff) and $buff =~ /([-+][XY])\s*(\d+)\s*([-+][XY])\s*(\d+)/) {
+        $et->HandleTag($tagTablePtr, '_orient', "$1 $3");
+        $et->FoundTag('ImageHeight', $2);
+        $et->FoundTag('ImageWidth', $4);
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Radiance - Read Radiance RGBE HDR 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 Radiance RGBE images.  RGBE (Red Green Blue Exponent)
+images are a type of high dynamic-range image.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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://radsite.lbl.gov/radiance/refer/filefmts.pdf>
+
+=item L<http://www.graphics.cornell.edu/online/formats/rgbe/>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Radiance Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Rawzor.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Rawzor.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Rawzor.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.01';
+$VERSION = '1.05';
 
 # currently support this version Rawzor images
@@ -52,5 +52,5 @@
 sub ProcessRWZ($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $buf2);
@@ -72,21 +72,21 @@
     my $origSize = Get64u(\$buff, 18);
     my $tagTablePtr = GetTagTable('Image::ExifTool::Rawzor::Main');
-    $exifTool->HandleTag($tagTablePtr, RawzorRequiredVersion => $reqVers);
-    $exifTool->HandleTag($tagTablePtr, RawzorCreatorVersion => $creatorVers);
-    $exifTool->HandleTag($tagTablePtr, OriginalFileSize => $origSize);
-    $exifTool->HandleTag($tagTablePtr, CompressionFactor => $origSize/$rwzSize) if $rwzSize;
+    $et->HandleTag($tagTablePtr, RawzorRequiredVersion => $reqVers);
+    $et->HandleTag($tagTablePtr, RawzorCreatorVersion => $creatorVers);
+    $et->HandleTag($tagTablePtr, OriginalFileSize => $origSize);
+    $et->HandleTag($tagTablePtr, CompressionFactor => $origSize/$rwzSize) if $rwzSize;
     # check version numbers
     if ($reqVers > $implementedRawzorVersion) {
-        $exifTool->Warn("Version $reqVers Rawzor images not yet supported");
+        $et->Warn("Version $reqVers Rawzor images not yet supported");
         return 1;
     }
     my $metaOffset = Get64u(\$buff, 38);
     if ($metaOffset > 0x7fffffff) {
-        $exifTool->Warn('Bad metadata offset');
+        $et->Warn('Bad metadata offset');
         return 1;
     }
     # check for the ability to uncompress the information
-    unless (eval 'require IO::Uncompress::Bunzip2') {
-        $exifTool->Warn('Install IO::Compress::Bzip2 to decode Rawzor bzip2 compression');
+    unless (eval { require IO::Uncompress::Bunzip2 }) {
+        $et->Warn('Install IO::Compress::Bzip2 to decode Rawzor bzip2 compression');
         return 1;
     }
@@ -100,9 +100,10 @@
     # 40 int32u - compressed metadata size
     unless ($raf->Seek($metaOffset, 0) and $raf->Read($buff, 44) == 44) {
-        $exifTool->Warn('Error reading metadata header');
+        $et->Warn('Error reading metadata header');
         return 1;
     }
     my $metaSize = Get32u(\$buff, 36);
     if ($metaSize) {
+        $$et{DontValidateImageData} = 1;
         # validate the metadata header and read the compressed metadata
         my $end0 = Get64u(\$buff, 0);
@@ -115,5 +116,5 @@
             $end0 <= $pos1 and $pos1 <= $end1 and $end1 <= $pos2)
         {
-            $exifTool->Warn('Error reading image metadata');
+            $et->Warn('Error reading image metadata');
             return 1;
         }
@@ -122,5 +123,5 @@
             length($buf2) eq $metaSize)
         {
-            $exifTool->Warn('Error uncompressing image metadata');
+            $et->Warn('Error uncompressing image metadata');
             return 1;
         }
@@ -133,17 +134,16 @@
 
         # extract original information by calling ExtractInfo recursively
-        $exifTool->ExtractInfo(\$buff, { ReEntry => 1 });
+        $et->ExtractInfo(\$buff, { ReEntry => 1 });
         undef $buff;
     }
     # set OriginalFileType from FileType of original file
     # then change FileType and MIMEType to indicate a Rawzor image
-    my $origFileType = $exifTool->{VALUE}->{FileType};
+    my $origFileType = $$et{VALUE}{FileType};
     if ($origFileType) {
-        $exifTool->HandleTag($tagTablePtr, OriginalFileType => $origFileType);
-        $exifTool->{VALUE}->{FileType} = 'RWZ';
-        $exifTool->{VALUE}->{MIMEType} = 'image/x-rawzor';
+        $et->HandleTag($tagTablePtr, OriginalFileType => $origFileType);
+        $et->OverrideFileType('RWZ');
     } else {
-        $exifTool->HandleTag($tagTablePtr, OriginalFileType => 'Unknown');
-        $exifTool->SetFileType();
+        $et->HandleTag($tagTablePtr, OriginalFileType => 'Unknown');
+        $et->SetFileType();
     }
     return 1;
@@ -169,5 +169,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Real.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Real.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Real.pm	(revision 34921)
@@ -17,5 +17,5 @@
 use Image::ExifTool::Canon;
 
-$VERSION = '1.04';
+$VERSION = '1.06';
 
 sub ProcessRealMeta($$$);
@@ -356,11 +356,11 @@
 sub ProcessRealProperties($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirLen = $$dirInfo{DirLen};
     my $pos = $$dirInfo{DirStart};
-    my $verbose = $exifTool->Options('Verbose');
-
-    $verbose and $exifTool->VerboseDir('RealProperties', undef, $dirLen);
+    my $verbose = $et->Options('Verbose');
+
+    $verbose and $et->VerboseDir('RealProperties', undef, $dirLen);
 
     while ($pos + 6 <= $dirLen) {
@@ -391,5 +391,5 @@
         my $val = ReadValue($dataPt, $pos, $format, $count, $dirLen-$pos);
 
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         unless ($tagInfo) {
             my $tagName;
@@ -397,8 +397,8 @@
             next unless $tagName =~ /^\w+$/;    # ignore crazy names
             $tagInfo = { Name => ucfirst($tagName) };
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
         }
         if ($verbose) {
-            $exifTool->VerboseInfo($tag, $tagInfo,
+            $et->VerboseInfo($tag, $tagInfo,
                 Table  => $tagTablePtr,
                 Value  => $val,
@@ -411,5 +411,5 @@
             );
         }
-        $exifTool->FoundTag($tagInfo, $val);
+        $et->FoundTag($tagInfo, $val);
         $pos += $valLen;
     }
@@ -423,14 +423,14 @@
 sub ProcessRealMeta($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos};
     my $pos = $$dirInfo{DirStart};
     my $dirEnd = $pos + $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $prefix = $$dirInfo{Prefix} || '';
     $prefix and $prefix .= '/';
 
-    $verbose and $exifTool->VerboseDir('RealMetadata', undef, $$dirInfo{DirLen});
+    $verbose and $et->VerboseDir('RealMetadata', undef, $$dirInfo{DirLen});
 
     for (;;) {
@@ -455,10 +455,10 @@
 
         my $format = $metadataFormat{$type};
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         unless ($tagInfo) {
             my $tagName = $tag;
             $tagName =~ tr/A-Za-z0-9//dc;
             $tagInfo = { Name => ucfirst($tagName) };
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
         }
         if ($verbose) {
@@ -481,5 +481,5 @@
             my $count = int($valueLen / Image::ExifTool::FormatSize($format));
             my $val = ReadValue($dataPt, $valuePos, $format, $count, $dirEnd-$valuePos);
-            $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            $et->HandleTag($tagTablePtr, $tag, $val,
                 DataPt => $dataPt,
                 DataPos => $dataPos,
@@ -499,10 +499,10 @@
                 Prefix => $tag,
             );
-            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         }
         $pos += $size;  # step to next Metadata structure
     }
     unless ($pos == $dirEnd) {
-        $exifTool->Warn('Format error in Real Metadata');
+        $et->Warn('Format error in Real Metadata');
         return 0;
     }
@@ -516,5 +516,5 @@
 sub ProcessReal($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($buff, $tag, $vers, $extra, @mimeTypes, %dirCount);
@@ -523,4 +523,5 @@
     $buff =~ m{^(\.RMF|\.ra\xfd|pnm://|rtsp://|http://)} or return 0;
 
+    my $fast3 = $$et{OPTIONS}{FastScan} && $$et{OPTIONS}{FastScan} == 3;
     my ($type, $tagTablePtr);
     if ($1 eq '.RMF') {
@@ -532,5 +533,5 @@
     } else {
         $tagTablePtr = GetTagTable('Image::ExifTool::Real::Metafile');
-        my $ext = $exifTool->{FILE_EXT};
+        my $ext = $$et{FILE_EXT};
         $type = ($ext and $ext eq 'RPM') ? 'RPM' : 'RAM';
         require Image::ExifTool::PostScript;
@@ -544,17 +545,19 @@
                 # must be a Real file type if protocol is http
                 return 0 if $buff =~ /^http/ and $buff !~ /\.(ra|rm|rv|rmvb|smil)$/i;
-                $exifTool->SetFileType($type);
+                $et->SetFileType($type);
+                return 1 if $fast3;
                 undef $type;
             }
             # save URL or Text from RAM file
             my $tag = $buff =~ m{^[a-z]{3,4}://} ? 'url' : 'txt';
-            $exifTool->HandleTag($tagTablePtr, $tag, $buff);
+            $et->HandleTag($tagTablePtr, $tag, $buff);
         }
         return 1;
     }
 
-    $exifTool->SetFileType($type);
+    $et->SetFileType($type);
+    return 1 if $fast3;
     SetByteOrder('MM');
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 #
 # Process RealAudio file
@@ -565,10 +568,10 @@
         my $fpos = $raf->Tell();
         unless ($raf->Read($buff, 512)) {
-            $exifTool->Warn('Error reading audio header');
+            $et->Warn('Error reading audio header');
             return 1;
         }
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($verbose > 2) {
-            $exifTool->VerboseInfo($tag, $tagInfo, DataPt => \$buff, DataPos => $fpos);
+            $et->VerboseInfo($tag, $tagInfo, DataPt => \$buff, DataPos => $fpos);
         }
         if ($tagInfo) {
@@ -580,7 +583,7 @@
                 DirStart => 0,
             );
-            $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $subTablePtr);
         } else {
-            $exifTool->Warn('Unsupported RealAudio version');
+            $et->Warn('Unsupported RealAudio version');
         }
         return 1;
@@ -592,5 +595,5 @@
     my $size = unpack('x4N', $buff);
     unless ($raf->Seek($size - 8, 1)) {
-        $exifTool->Warn('Error seeking in file');
+        $et->Warn('Error seeking in file');
         return 0;
     }
@@ -602,21 +605,21 @@
         last if $tag eq "\0\0\0\0";
         if ($verbose) {
-            $exifTool->VPrint(0, "$tag chunk ($size bytes):\n");
+            $et->VPrint(0, "$tag chunk ($size bytes):\n");
         } else {
             last if $tag eq 'DATA'; # stop normal parsing at DATA tag
         }
         if ($size & 0x80000000) {
-            $exifTool->Warn('Bad chunk header');
+            $et->Warn('Bad chunk header');
             last;
         }
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($tagInfo and $$tagInfo{SubDirectory}) {
             my $fpos = $raf->Tell();
             unless ($raf->Read($buff, $size-10) == $size-10) {
-                $exifTool->Warn("Error reading $tag chunk");
+                $et->Warn("Error reading $tag chunk");
                 last;
             }
             if ($verbose > 2) {
-                $exifTool->VerboseInfo($tag, $tagInfo, DataPt => \$buff, DataPos => $fpos);
+                $et->VerboseInfo($tag, $tagInfo, DataPt => \$buff, DataPos => $fpos);
             }
             my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
@@ -628,14 +631,14 @@
             );
             if ($dirCount{$tag}) {
-                $exifTool->{SET_GROUP1} = '+' . ++$dirCount{$tag};
+                $$et{SET_GROUP1} = '+' . ++$dirCount{$tag};
             } else {
                 $dirCount{$tag} = 1;
             }
-            $exifTool->ProcessDirectory(\%dirInfo, $subTablePtr);
-            delete $exifTool->{SET_GROUP1};
+            $et->ProcessDirectory(\%dirInfo, $subTablePtr);
+            delete $$et{SET_GROUP1};
             # keep track of stream MIME types
-            my $mime = $exifTool->{RealStreamMime};
+            my $mime = $$et{RealStreamMime};
             if ($mime) {
-                delete $exifTool->{RealStreamMime};
+                delete $$et{RealStreamMime};
                 $mime =~ s/\0.*//s;
                 push @mimeTypes, $mime unless $mime =~ /^logical-/;
@@ -643,5 +646,5 @@
         } else {
             unless ($raf->Seek($size-10, 1)) {
-                $exifTool->Warn('Error seeking in file');
+                $et->Warn('Error seeking in file');
                 last;
             }
@@ -650,6 +653,6 @@
     # override MIMEType with stream MIME type if we only have one stream
     if (@mimeTypes == 1 and length $mimeTypes[0]) {
-        $exifTool->{VALUE}->{MIMEType} = $mimeTypes[0];
-        $exifTool->VPrint(0, "  MIMEType = $mimeTypes[0]\n");
+        $$et{VALUE}{MIMEType} = $mimeTypes[0];
+        $et->VPrint(0, "  MIMEType = $mimeTypes[0]\n");
     }
 #
@@ -669,10 +672,10 @@
             );
             my $tagTablePtr = GetTagTable('Image::ExifTool::Real::Metadata');
-            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         } else {
-            $exifTool->Warn('Bad metadata footer');
+            $et->Warn('Bad metadata footer');
         }
         if ($raf->Seek(-128, 2) and $raf->Read($buff, 128) == 128 and $buff =~ /^TAG/) {
-            $exifTool->VPrint(0, "ID3v1:\n");
+            $et->VPrint(0, "ID3v1:\n");
             my %dirInfo = (
                 DataPt => \$buff,
@@ -681,5 +684,5 @@
             );
             my $tagTablePtr = GetTagTable('Image::ExifTool::ID3::v1');
-            $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+            $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         }
     }
@@ -713,5 +716,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Reconyx.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Reconyx.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Reconyx.pm	(revision 34921)
@@ -7,4 +7,6 @@
 #
 # References:   1) RCNX_MN10.pdf (courtesy of Reconyx Inc.)
+#               2) ultrafire_makernote.pdf (courtesy of Reconyx Inc.)
+#               3) Reconyx private communication
 #------------------------------------------------------------------------------
 
@@ -14,5 +16,15 @@
 use vars qw($VERSION);
 
-$VERSION = '1.02';
+$VERSION = '1.06';
+
+# info for Type2 version tags
+my %versionInfo = (
+    Format => 'undef[7]',
+    ValueConv => 'sprintf("V%.2x.%.2x %.4x:%.2x:%.2x Rev.%s", unpack("CCvCCa", $val))',
+    ValueConvInv => q{
+        my @v = $val =~ /^V([0-9a-f]+)\.([0-9a-f]+) (\d{4}):(\d{2}):(\d{2})\s*Rev\.(\w)/i or return undef;
+        pack('CCvCCa', map(hex, @v[0..4]), $v[5]);
+    },
+);
 
 # maker notes for Reconyx Hyperfire cameras (ref PH)
@@ -81,7 +93,12 @@
         Format => 'int16u[6]',
         Groups => { 2 => 'Time' },
+        Priority => 0, # (not as reliable as EXIF)
         Shift => 'Time',
         ValueConv => q{
             my @a = split ' ', $val;
+            # have seen these values written big-endian when everything else is little-endian
+            if ($a[0] & 0xff00 and not $a[0] & 0xff) {
+                $_ = ($_ >> 8) | (($_ & 0xff) << 8) foreach @a;
+            }
             sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', @a[5,3,4,2,1,0]);
         },
@@ -92,5 +109,5 @@
         },
         PrintConv => '$self->ConvertDateTime($val)',
-        PrintConvInv => '$val',
+        PrintConvInv => '$self->InverseDateTime($val)',
     },
     0x12 => {
@@ -110,11 +127,13 @@
     0x13 => {
         Name => 'AmbientTemperatureFahrenheit',
+        Format => 'int16s',
         PrintConv => '"$val F"',
-        PrintConvInv => '$val=~/(\d+)/ ? $1 : $val',
+        PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
     },
     0x14 => {
         Name => 'AmbientTemperature',
+        Format => 'int16s',
         PrintConv => '"$val C"',
-        PrintConvInv => '$val=~/(\d+)/ ? $1 : $val',
+        PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
     },
     0x15 => {
@@ -134,8 +153,5 @@
     0x28 => {
         Name => 'InfraredIlluminator',
-        PrintConv => {
-            0 => 'Off',
-            1 => 'On',
-        },
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     0x29 => 'MotionSensitivity', #1
@@ -153,4 +169,249 @@
 );
 
+# maker notes for Reconyx UltraFire cameras (ref PH)
+%Image::ExifTool::Reconyx::Type2 = (
+    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 UltraFire.',
+  # 0x0a - int32u makernote ID 0x00020000 #2
+  # 0x0e - int16u makernote size #2
+  # 0x12 - int32u public structure ID 0x07f100001 #2
+  # 0x16 - int16u public structure size #2 (0x5d = start of public ID to end of UserLabel)
+    0x18 => { Name => 'FirmwareVersion',   %versionInfo },
+    0x1f => { Name => 'Micro1Version',     %versionInfo }, #2
+    0x26 => { Name => 'BootLoaderVersion', %versionInfo }, #2
+    0x2d => { Name => 'Micro2Version',     %versionInfo }, #2
+    0x34 => {
+        Name => 'TriggerMode',
+        Format => 'undef[1]',
+        PrintConv => {
+            M => 'Motion Detection',
+            T => 'Time Lapse',
+            P => 'Point and Shoot', #2
+        },
+    },
+    0x35 => {
+        Name => 'Sequence',
+        Format => 'int8u[2]',
+        PrintConv => '$val =~ s/ / of /; $val',
+        PrintConvInv => 'join(" ", $val=~/\d+/g)',
+    },
+    0x37 => { #2
+        Name => 'EventNumber',
+        Format => 'int32u',
+    },
+    0x3b => {
+        Name => 'DateTimeOriginal',
+        Description => 'Date/Time Original',
+        Format => 'int8u[7]',
+        Groups => { 2 => 'Time' },
+        Priority => 0, # (not as reliable as EXIF)
+        Shift => 'Time',
+        ValueConv => q{
+            my @a = split ' ', $val;
+            $a[5] += pop(@a) * 256;
+            sprintf('%.4d:%.2d:%.2d %.2d:%.2d:%.2d', reverse @a);
+        },
+        ValueConvInv => q{
+            my @a = ($val =~ /\d+/g);
+            return undef unless @a >= 6;
+            unshift @a, ($a[0] >> 8);
+            $a[1] -= $a[0] * 256;
+            join ' ', @a[6,5,4,3,2,1,0];
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
+    },
+    0x42 => { #2
+        Name => 'DayOfWeek',
+        Groups => { 2 => 'Time' },
+        PrintConv => {
+            0 => 'Sunday',
+            1 => 'Monday',
+            2 => 'Tuesday',
+            3 => 'Wednesday',
+            4 => 'Thursday',
+            5 => 'Friday',
+            6 => 'Saturday',
+        },
+    },
+    0x43 => {
+        Name => 'MoonPhase',
+        Groups => { 2 => 'Time' },
+        PrintConv => {
+            0 => 'New',
+            1 => 'New Crescent',
+            2 => 'First Quarter',
+            3 => 'Waxing Gibbous',
+            4 => 'Full',
+            5 => 'Waning Gibbous',
+            6 => 'Last Quarter',
+            7 => 'Old Crescent',
+        },
+    },
+    0x44 => {
+        Name => 'AmbientTemperatureFahrenheit',
+        Format => 'int16s',
+        PrintConv => '"$val F"',
+        PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
+    },
+    0x46 => {
+        Name => 'AmbientTemperature',
+        Format => 'int16s',
+        PrintConv => '"$val C"',
+        PrintConvInv => '$val=~/(-?\d+)/ ? $1 : $val',
+    },
+    0x48 => {
+        Name => 'Illumination',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x49 => {
+        Name => 'BatteryVoltage',
+        Format => 'int16u',
+        ValueConv => '$val / 1000',
+        ValueConvInv => '$val * 1000',
+        PrintConv => '"$val V"',
+        PrintConvInv => '$val=~s/ ?V$//; $val',
+    },
+    0x4b => {
+        Name => 'SerialNumber',
+        Format => 'string[15]',
+    },
+    0x5a => {
+        Name => 'UserLabel',
+        Format => 'string[21]',
+    },
+);
+
+# 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__
@@ -167,9 +428,9 @@
 
 This module contains definitions required by Image::ExifTool to interpret
-maker notes in Reconyx cameras.
+maker notes in images from Reconyx cameras.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Red.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Red.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Red.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Ricoh.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Ricoh.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Ricoh.pm	(revision 34921)
@@ -8,4 +8,7 @@
 # References:   1) http://www.ozhiker.com/electronics/pjmt/jpeg_info/ricoh_mn.html
 #               2) http://homepage3.nifty.com/kamisaka/makernote/makernote_ricoh.htm
+#               3) Tim Gray private communication (GR)
+#               4) https://github.com/atotto/ricoh-theta-tools/
+#               IB) Iliah Borg private communication (LibRaw)
 #------------------------------------------------------------------------------
 
@@ -17,5 +20,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.17';
+$VERSION = '1.35';
 
 sub ProcessRicohText($$$);
@@ -34,4 +37,6 @@
     'RL3' => 'Ricoh Lens P10 28-300mm F3.5-5.6 VC',
     'RL5' => 'GR Lens A12 28mm F2.5',
+    'RL8' => 'Mount A12',
+    'RL6' => 'Ricoh Lens A16 24-85mm F3.5-5.5',
 );
 
@@ -45,5 +50,5 @@
         Name => 'FirmwareVersion',
         Writable => 'string',
-        # ie. "Rev0113" is firmware version 1.13
+        # eg. "Rev0113" is firmware version 1.13
         PrintConv => '$val=~/^Rev(\d+)$/ ? sprintf("%.2f",$1/100) : $val',
         PrintConvInv => '$val=~/^(\d+)\.(\d+)$/ ? sprintf("Rev%.2d%.2d",$1,$2) : $val',
@@ -66,6 +71,6 @@
             Writable => 'undef',
             Count => 16,
-            PrintConv => 'unpack("H*", $val)',
-            PrintConvInv => 'pack("H*", $val)',
+            ValueConv => 'unpack("H*", $val)',
+            ValueConvInv => 'pack("H*", $val)',
         },
     ],
@@ -76,10 +81,44 @@
         SubDirectory => { TagTable => 'Image::ExifTool::PrintIM::Main' },
     },
-    0x1001 => {
+    0x1000 => { #3
+        Name => 'RecordingFormat',
+        Writable => 'int16u',
+        PrintConv => {
+            2 => 'JPEG',
+            3 => 'DNG',
+        },
+    },
+    0x1001 => [{
         Name => 'ImageInfo',
+        Condition => '$format ne "int16u"',
         SubDirectory => { TagTable => 'Image::ExifTool::Ricoh::ImageInfo' },
-    },
-    0x1003 => {
+    },{ #3
+        Name => 'ExposureProgram',
+        Writable => 'int16u',
+        Notes => 'GR',
+        PrintConv => {
+            1 => 'Auto',
+            2 => 'Program AE',
+            3 => 'Aperture-priority AE',
+            4 => 'Shutter speed priority AE',
+            5 => 'Shutter/aperture priority AE', # TAv
+            6 => 'Manual',
+            7 => 'Movie', #PH
+        },
+    }],
+    0x1002 => { #3
+        Name => 'DriveMode',
+        Condition => '$format eq "int16u"',
+        Notes => 'valid only for some models',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Single-frame',
+            1 => 'Continuous',
+            8 => 'AF-priority Continuous',
+        },
+    },
+    0x1003 => [{
         Name => 'Sharpness',
+        Condition => '$format ne "int16u"',
         Writable => 'int32u',
         PrintConv => {
@@ -88,13 +127,291 @@
             2 => 'Soft',
         },
-    },
+    },{ #3
+        Name => 'WhiteBalance',
+        Writable => 'int16u',
+        Notes => 'GR',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Multi-P Auto',
+            2 => 'Daylight',
+            3 => 'Cloudy',
+            4 => 'Incandescent 1',
+            5 => 'Incandescent 2',
+            6 => 'Daylight Fluorescent',
+            7 => 'Neutral White Fluorescent',
+            8 => 'Cool White Fluorescent',
+            9 => 'Warm White Fluorescent',
+            10 => 'Manual',
+            11 => 'Kelvin',
+            12 => 'Shade', #IB
+        },
+    }],
+    0x1004 => { #3
+        Name => 'WhiteBalanceFineTune',
+        Condition => '$format eq "int16u"',
+        Format => 'int16s',
+        Writable => 'int16u',
+        Notes => q{
+            2 numbers: amount of adjustment towards Amber and Green.  Not valid for all
+            models
+        },
+    },
+    # 0x1005 int16u - 5
+    0x1006 => { #3
+        Name => 'FocusMode',
+        Writable => 'int16u',
+        PrintConv => {
+            1 => 'Manual',
+            2 => 'Multi AF',
+            3 => 'Spot AF',
+            4 => 'Snap',
+            5 => 'Infinity',
+            7 => 'Face Detect', #PH
+            8 => 'Subject Tracking',
+            9 => 'Pinpoint AF',
+            10 => 'Movie', #PH
+        },
+    },
+    0x1007 => { #3
+        Name => 'AutoBracketing',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            9 => 'AE',
+            11 => 'WB',
+            16 => 'DR', # (dynamic range)
+            17 => 'Contrast',
+            18 => 'WB2', # (selects two different WB presets besides normal)
+            19 => 'Effect',
+        },
+    },
+    0x1009 => { #3
+        Name => 'MacroMode',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x100a => { #3
+        Name => 'FlashMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Auto, Fired',
+            2 => 'On',
+            3 => 'Auto, Fired, Red-eye reduction',
+            4 => 'Slow Sync',
+            5 => 'Manual',
+            6 => 'On, Red-eye reduction',
+            7 => 'Synchro, Red-eye reduction',
+            8 => 'Auto, Did not fire',
+        },
+    },
+    0x100b => { #3
+        Name => 'FlashExposureComp',
+        Writable => 'rational64s',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    0x100c => { #3
+        Name => 'ManualFlashOutput',
+        Writable => 'rational64s',
+        PrintConv => {
+               0 => 'Full',
+             -24 => '1/1.4',
+             -48 => '1/2',
+             -72 => '1/2.8',
+             -96 => '1/4',
+            -120 => '1/5.6',
+            -144 => '1/8',
+            -168 => '1/11',
+            -192 => '1/16',
+            -216 => '1/22',
+            -240 => '1/32',
+            -288 => '1/64',
+        },
+    },
+    0x100d => { #3
+        Name => 'FullPressSnap',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x100e => { #3
+        Name => 'DynamicRangeExpansion',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            3 => 'Weak',
+            4 => 'Medium',
+            5 => 'Strong',
+        },
+    },
+    0x100f => { #3
+        Name => 'NoiseReduction',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Weak',
+            2 => 'Medium',
+            3 => 'Strong',
+        },
+    },
+    0x1010 => { #3
+        Name => 'ImageEffects',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Vivid',
+            3 => 'Black & White',
+            5 => 'B&W Toning Effect',
+            6 => 'Setting 1',
+            7 => 'Setting 2',
+            9 => 'High-contrast B&W',
+            10 => 'Cross Process',
+            11 => 'Positive Film',
+            12 => 'Bleach Bypass',
+            13 => 'Retro',
+            15 => 'Miniature',
+            17 => 'High Key',
+        },
+    },
+    0x1011 => { #3
+        Name => 'Vignetting',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Medium',
+            3 => 'High',
+        },
+    },
+    0x1012 => { #PH
+        Name => 'Contrast',
+        Writable => 'int32u',
+        Format => 'int32s', #3 (high-contrast B&W also has -1 and -2 settings)
+        PrintConv => {
+            OTHER => sub { shift },
+            2147483647 => 'MAX', #3 (high-contrast B&W effect MAX setting)
+        },
+    },
+    0x1013 => { Name => 'Saturation', Writable => 'int32u' }, #PH
+    0x1014 => { Name => 'Sharpness',  Writable => 'int32u' }, #3
+    0x1015 => { #3
+        Name => 'ToningEffect',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Sepia',
+            2 => 'Red',
+            3 => 'Green',
+            4 => 'Blue',
+            5 => 'Purple',
+            6 => 'B&W',
+            7 => 'Color',
+        },
+    },
+    0x1016 => { #3
+        Name => 'HueAdjust',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Basic',
+            2 => 'Magenta',
+            3 => 'Yellow',
+            4 => 'Normal',
+            5 => 'Warm',
+            6 => 'Cool',
+        },
+    },
+    0x1017 => { #3
+        Name => 'WideAdapter',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Not Attached',
+            2 => 'Attached', # (21mm)
+        },
+    },
+    0x1018 => { #3
+        Name => 'CropMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On (35mm)',
+            2 => 'On (47mm)', #IB
+        },
+    },
+    0x1019 => { #3
+        Name => 'NDFilter',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x101a => { Name => 'WBBracketShotNumber', Writable => 'int16u' }, #3
+    # 0x1100 - related to DR correction (ref 3)
+    0x1307 => { Name => 'ColorTempKelvin',     Writable => 'int32u' }, #3
+    0x1308 => { Name => 'ColorTemperature',    Writable => 'int32u' }, #3
+    0x1500 => { #3
+        Name => 'FocalLength',
+        Writable => 'rational64u',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//;$val',
+    },
+    0x1200 => { #3
+        Name => 'AFStatus',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Out of Focus',
+            1 => 'In Focus',
+        },
+    },
+    # 0x1201-0x1204 - related to focus points (ref 3)
+    0x1201 => { #PH (NC)
+        Name => 'AFAreaXPosition1',
+        Writable => 'int32u',
+        Notes => 'manual AF area position in a 1280x864 image',
+    },
+    0x1202 => { Name => 'AFAreaYPosition1', Writable => 'int32u' }, #PH (NC)
+    0x1203 => { #PH (NC)
+        Name => 'AFAreaXPosition',
+        Writable => 'int32u',
+        Notes => 'manual AF area position in the full image',
+        # (coordinates change to correspond with smaller image
+        #  when recording reduced-size JPEG)
+    },
+    0x1204 => { Name => 'AFAreaYPosition', Writable => 'int32u' }, #PH (NC)
+    0x1205 => { #3
+        Name => 'AFAreaMode',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Auto',
+            2 => 'Manual',
+        },
+    },
+    0x1601 => { Name => 'SensorWidth',  Writable => 'int32u' }, #3
+    0x1602 => { Name => 'SensorHeight', Writable => 'int32u' }, #3
+    0x1603 => { Name => 'CroppedImageWidth',  Writable => 'int32u' }, #3
+    0x1604 => { Name => 'CroppedImageHeight', Writable => 'int32u' }, #3
+    # 0x1700 - Composite? (0=normal image, 1=interval composite, 2=multi-exposure composite) (ref 3)
+    # 0x1703 - 0=normal, 1=final composite (ref 3)
+    # 0x1704 - 0=normal, 2=final composite (ref 3)
     0x2001 => [
         {
             Name => 'RicohSubdir',
-            Condition => '$self->{Model} !~ /^Caplio RR1\b/',
+            Condition => q{
+                $self->{Model} !~ /^Caplio RR1\b/ and
+                ($format ne 'int32u' or $count != 1)
+            },
             SubDirectory => {
                 Validate => '$val =~ /^\[Ricoh Camera Info\]/',
                 TagTable => 'Image::ExifTool::Ricoh::Subdir',
                 Start => '$valuePtr + 20',
+                ByteOrder => 'BigEndian',
+            },
+        },
+        {
+            Name => 'RicohSubdirIFD',
+            # the CX6 and GR Digital 4 write an int32u pointer in AVI videos -- doh!
+            Condition => '$self->{Model} !~ /^Caplio RR1\b/',
+            Flags => 'SubIFD',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Ricoh::Subdir',
+                Start => '$val + 20', # (skip over "[Ricoh Camera Info]\0" header)
                 ByteOrder => 'BigEndian',
             },
@@ -112,4 +429,49 @@
         },
     ],
+    0x4001 => {
+        Name => 'ThetaSubdir',
+        Groups => { 1 => 'MakerNotes' },    # SubIFD needs group 1 set
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Ricoh::ThetaSubdir',
+            Start => '$val',
+        },
+    },
+);
+
+# Ricoh type 2 maker notes (ref PH)
+# (similar to Kodak::Type11 and GE::Main)
+%Image::ExifTool::Ricoh::Type2 = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        Tags written by models such as the Ricoh HZ15 and the Pentax XG-1.  These
+        are not writable due to numerous formatting errors as written by these
+        cameras.
+    },
+    # 0x104 - int32u: 1
+    # 0x200 - int32u[3]: 0 0 0
+    # 0x202 - int16u: 0 (GE Macro?)
+    # 0x203 - int16u: 0,3 (Kodak PictureEffect?)
+    # 0x204 - rational64u: 0/10
+    # 0x205 - rational64u: 150/1
+    # 0x206 - float[6]: (not really float because size should be 2 bytes)
+    0x207 => {
+        Name => 'RicohModel',
+        Writable => 'string',
+    },
+    0x300 => {
+        # brutal.  There are lots of errors in the XG-1 maker notes.  For the XG-1,
+        # 0x300 has a value of "XG-1Pentax".  The "XG-1" part is likely an improperly
+        # stored 0x207 RicohModel, resulting in an erroneous 4-byte offset for this tag
+        Name => 'RicohMake',
+        Writable => 'undef',
+        ValueConv => '$val =~ s/ *$//; $val',
+    },
+    # 0x306 - int16u: 1
+    # 0x500 - int16u: 0,1
+    # 0x501 - int16u: 0
+    # 0x502 - int16u: 0
+    # 0x9c9c - int8u[6]: ?
+    # 0xadad - int8u[20480]: ?
 );
 
@@ -150,13 +512,14 @@
     28 => {
         Name => 'PreviewImageStart',
-        Format => 'int16u',
+        Format => 'int16u', # ha!  (only the lower 16 bits, even if > 0xffff)
         Flags => 'IsOffset',
         OffsetPair => 30,   # associated byte count tagID
         DataTag => 'PreviewImage',
         Protected => 2,
-        # prevent preview from being written to raw images
+        WriteGroup => 'MakerNotes',
+        # prevent preview from being written to MakerNotes of DNG images
         RawConvInv => q{
             return $val if $$self{FILE_TYPE} eq "JPEG";
-            warn "Can't write PreviewImage to $$self{TIFF_TYPE} file\n";
+            warn "\n"; # suppress warning
             return undef;
         },
@@ -168,7 +531,8 @@
         DataTag => 'PreviewImage',
         Protected => 2,
+        WriteGroup => 'MakerNotes',
         RawConvInv => q{
             return $val if $$self{FILE_TYPE} eq "JPEG";
-            warn "\n"; # suppress warning (already issued for PreviewImageStart)
+            warn "\n"; # suppress warning
             return undef;
         },
@@ -218,4 +582,6 @@
             8 => 1600,
             9 => 'Auto', #PH (? CX3)
+            10 => 3200, #PH (A16)
+            11 => '100 (Low)', #PH (A16)
         },
     },
@@ -235,5 +601,5 @@
 
 # Ricoh subdirectory tags (ref PH)
-# NOTE: this subdir is not currently writable because the offsets would require
+# NOTE: this subdir is currently not writable because the offsets would require
 # special code to handle the funny start location and base offset
 %Image::ExifTool::Ricoh::Subdir = (
@@ -244,4 +610,5 @@
     # within a month of each other, but I have seen differences of nearly a year.
     # Sometimes the first is more recent, and sometimes the second.
+    # 0x0003 - int32u[1]
     0x0004 => { # (NC)
         Name => 'ManufactureDate1',
@@ -256,6 +623,8 @@
         Count => 20,
     },
+    # 0x0006 - undef[16] ?
+    # 0x0007 - int32u[1] ?
     # 0x000c - int32u[2] 1st number is a counter (file number? shutter count?) - PH
-    # 0x0014 - int8u[338] - could contain some data related to face detection? - PH
+    # 0x0014 - int8u[338] could contain some data related to face detection? - PH
     # 0x0015 - int8u[2]: related to noise reduction?
     0x001a => { #PH
@@ -283,4 +652,36 @@
     }
     # 0x000E ProductionNumber? (ref 2) [no. zero for most models - PH]
+);
+
+# Ricoh Theta subdirectory tags - Contains orientation information (ref 4)
+%Image::ExifTool::Ricoh::ThetaSubdir = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
+    CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
+    # 0x0001 - int16u[1] ?
+    # 0x0002 - int16u[1] ?
+    0x0003 => {
+        Name => 'Accelerometer',
+        Writable => 'rational64s',
+        Count => 2,
+    },
+    0x0004 => {
+        Name => 'Compass',
+        Writable => 'rational64u',
+    },
+    # 0x0005 - int16u[1] ?
+    # 0x0006 - int16u[1] ?
+    # 0x0007 - int16u[1] ?
+    # 0x0008 - int16u[1] ?
+    # 0x0009 - int16u[1] ?
+    0x000a => {
+        Name => 'TimeZone',
+        Writable => 'string',
+    },
+    # 0x0101 - int16u[4] ISO (why 4 values?)
+    # 0x0102 - rational64s[2] FNumber (why 2 values?)
+    # 0x0103 - rational64u[2] ExposureTime (why 2 values?)
+    # 0x0104 - string[9] SerialNumber?
+    # 0x0105 - string[9] SerialNumber?
 );
 
@@ -471,4 +872,9 @@
         16 => 'NNW',
     } },
+    _audio => {
+        Name => 'SoundFile',
+        Notes => 'audio data recorded in JPEG images by the G700SE',
+    },
+    _barcode => { Name => 'Barcodes', List => 1 },
 );
 
@@ -498,4 +904,5 @@
     thum => {
         Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
         Binary => 1,
     },
@@ -512,4 +919,12 @@
         PrintConv => \%ricohLensIDs,
     },
+    RicohPitch => {
+        Require => 'Ricoh:Accelerometer',
+        ValueConv => 'my @v = split(" ",$val); $v[1]',
+    },
+    RicohRoll => {
+        Require => 'Ricoh:Accelerometer',
+        ValueConv => 'my @v = split(" ",$val); $v[0] <= 180 ? $v[0] : $v[0] - 360',
+    },
 );
 
@@ -526,10 +941,10 @@
 sub ProcessRicohText($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataLen = $$dirInfo{DataLen};
     my $dirStart = $$dirInfo{DirStart} || 0;
     my $dirLen = $$dirInfo{DirLen} || $dataLen - $dirStart;
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     my $data = substr($$dataPt, $dirStart, $dirLen);
@@ -537,5 +952,5 @@
     # validate text maker notes
     unless ($data =~ /^(Rev|Rv)/) {
-        $exifTool->Warn('Bad Ricoh maker notes');
+        $et->Warn('Bad Ricoh maker notes');
         return 0;
     }
@@ -543,7 +958,7 @@
         my $tag = $1;
         my $val = $2;
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($verbose) {
-            $exifTool->VerboseInfo($tag, $tagInfo,
+            $et->VerboseInfo($tag, $tagInfo,
                 Table  => $tagTablePtr,
                 Value  => $val,
@@ -551,5 +966,5 @@
         }
         unless ($tagInfo) {
-            next unless $exifTool->{OPTIONS}->{Unknown};
+            next unless $$et{OPTIONS}{Unknown};
             $tagInfo = {
                 Name => "Ricoh_Text_$tag",
@@ -558,7 +973,7 @@
             };
             # add tag information to table
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
         }
-        $exifTool->FoundTag($tagInfo, $val);
+        $et->FoundTag($tagInfo, $val);
     }
     return 1;
@@ -567,91 +982,143 @@
 #------------------------------------------------------------------------------
 # Process Ricoh APP5 RMETA information
-# Inputs: 0) ExifTool object reference
-#         1) Reference to directory information hash
-#         2) Pointer to tag table for this directory
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
 # Returns: 1 on success, otherwise returns 0 and sets a Warning
 sub ProcessRicohRMETA($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dirStart = $$dirInfo{DirStart};
     my $dataLen = length($$dataPt);
-    my $verbose = $exifTool->Options('Verbose');
-
-    $dataLen > 6 or $exifTool->Warn('Truncated Ricoh RMETA data'), return 0;
+    my $dirLen = $dataLen - $dirStart;
+    my $verbose = $et->Options('Verbose');
+
+    $et->VerboseDir('Ricoh RMETA') if $verbose;
+    $dirLen < 20 and $et->Warn('Truncated Ricoh RMETA data', 1), return 0;
     my $byteOrder = substr($$dataPt, $dirStart, 2);
-    SetByteOrder($byteOrder) or $exifTool->Warn('Bad Ricoh RMETA data'), return 0;
-    my (@tags, @vals, @nums, $valPos);
-    my $pos = $dirStart + 6;
+    $byteOrder = GetByteOrder() if $byteOrder eq "\0\0"; # (same order as container)
+    SetByteOrder($byteOrder) or $et->Warn('Bad Ricoh RMETA data', 1), return 0;
+    # get the RMETA segment number
+    my $rmetaNum = Get16u($dataPt, $dirStart+4);
+    if ($rmetaNum != 0) {
+        # not sure how to recognize audio, so do it by checking for "RIFF" header
+        # and assume all subsequent RMETA segments are part of the audio data
+        # (but it looks like the int16u at $dirStart+6 is the next block number
+        # if the data is continued, or 0 for the last block)
+        $dirLen < 14 and $et->Warn('Short Ricoh RMETA block', 1), return 0;
+        if ($$dataPt =~ /^.{20}BARCODE/s) {
+            my $val = substr($$dataPt, 20);
+            $val =~ s/\0.*//s;
+            $val =~ s/^BARCODE\w+,\d{2},//;
+            my @codes;
+            for (;;) {
+                $val =~ s/(\d+),// and length $val >= $1 or last;
+                push @codes, substr($val, 0, $1);
+                last unless length $val > $1;
+                $val = substr($val, $1+1);
+            }
+            $et->HandleTag($tagTablePtr, '_barcode', \@codes) if @codes;
+            return 1;
+        } elsif ($$dataPt =~ /^.{18}ASCII/s) {
+            # (ignore barcode tag names for now)
+            return 1;
+        }
+        my $audioLen = Get16u($dataPt, $dirStart+12);
+        $audioLen + 14 > $dirLen and $et->Warn('Truncated Ricoh RMETA audio data', 1), return 0;
+        my $buff = substr($$dataPt, $dirStart + 14, $audioLen);
+        if ($audioLen >= 4 and substr($buff, 0, 4) eq 'RIFF') {
+            $et->HandleTag($tagTablePtr, '_audio', \$buff);
+        } elsif ($$et{VALUE}{SoundFile}) {
+            ${$$et{VALUE}{SoundFile}} .= $buff;
+        } else {
+            $et->Warn('Unknown Ricoh RMETA type', 1);
+            return 0;
+        }
+        return 1;
+    }
+    # decode standard RMETA tag directory
+    my (@tags, @vals, @nums, $valPos, $numPos);
+    my $pos = $dirStart + Get16u($dataPt, $dirStart+8);
+    my $numEntries = Get16u($dataPt, $pos);
+    $numEntries > 100 and $et->Warn('Bad RMETA entry count'), return 0;
+    $pos += 10; # start of first RMETA section
+    # loop through RMETA sections
     while ($pos <= $dataLen - 4) {
         my $type = Get16u($dataPt, $pos);
         my $size = Get16u($dataPt, $pos + 2);
+        last unless $size;
         $pos += 4;
         $size -= 2;
         if ($size < 0 or $pos + $size > $dataLen) {
-            $exifTool->Warn('Corrupted Ricoh RMETA data');
+            $et->Warn('Corrupted Ricoh RMETA data', 1);
             last;
         }
-        if ($type eq 1) {
+        my $dat = substr($$dataPt, $pos, $size);
+        if ($verbose) {
+            $et->VPrint(2, "$$et{INDENT}RMETA section type=$type size=$size\n");
+            $et->VerboseDump(\$dat, Addr => $$dirInfo{DataPos} + $pos);
+        }
+        if ($type == 1) {                       # section 1: tag names
             # save the tag names
-            my $tags = substr($$dataPt, $pos, $size);
-            $tags =~ s/\0+$//;  # remove trailing nulls
-            @tags = split /\0/, $tags;
-        } elsif ($type eq 2) {
-            # save the ASCII tag values
-            my $vals = substr($$dataPt, $pos, $size);
-            $vals =~ s/\0+$//;
-            @vals = split /\0/, $vals;
-            $valPos = $pos; # save position of first ASCII value
-        } elsif ($type eq 3) {
-            # save the numerical tag values
-            my $nums = substr($$dataPt, $pos, $size);
-            @nums = unpack($byteOrder eq 'MM' ? 'n*' : 'v*', $nums);
-        } elsif ($type eq 0) {
-            $pos += 2;  # why 2 extra bytes?
+            @tags = split /\0/, $dat, $numEntries+1;
+        } elsif ($type == 2 || $type == 18) {   # section 2/18: string values (G800 uses type 18)
+            # save the tag values (assume "ASCII\0" encoding since others never seen)
+            @vals = split /\0/, $dat, $numEntries+1;
+            $valPos = $pos; # save position of first string value
+        } elsif ($type == 3) {                  # section 3: numerical values
+            if ($size < $numEntries * 2) {
+                $et->Warn('Truncated RMETA section 3');
+            } else {
+                # save the numerical tag values
+                # (0=empty, 0xffff=text input, otherwise menu item number)
+                @nums = unpack(($byteOrder eq 'MM' ? 'n' : 'v').$numEntries, $dat);
+                $numPos = $pos; # save position of numerical values
+            }
+        } elsif ($type != 16) {
+            $et->Warn("Unrecognized RMETA section (type $type, len $size)");
         }
         $pos += $size;
     }
-    if (@tags or @vals) {
-        if (@tags != @vals) {
-            my ($nt, $nv) = (scalar(@tags), scalar(@vals));
-            $exifTool->Warn("Number of tags ($nt) and values ($nv) differs in Ricoh RMETA");
+    return 1 unless @tags or @vals;
+    $valPos or $valPos = 0; # (just in case there was no value section)
+    # find next tag in null-delimited list
+    # unpack numerical values from block of int16u values
+    my ($i, $name);
+    for ($i=0; $i<$numEntries; ++$i) {
+        my $tag = $tags[$i];
+        my $val = $vals[$i];
+        $val = '' unless defined $val;
+        unless (defined $tag and length $tag) {
+            length $val or ++$valPos, next;     # (skip empty entries)
+            $tag = '';
         }
-        # find next tag in null-delimited list
-        # unpack numerical values from block of int16u values
-        my ($tag, $name, $val);
-        foreach $tag (@tags) {
-            $val = shift @vals;
-            last unless defined $val;
-            ($name = $tag) =~ s/\b([a-z])/\U$1/gs;  # make capitalize all words
-            $name =~ s/ (\w)/\U$1/g;                # remove special characters
-            $name = 'RMETA_Unknown' unless length($name);
-            my $num = shift @nums;
-            my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
-            if ($tagInfo) {
-                # make sure print conversion is defined
-                $$tagInfo{PrintConv} = { } unless $$tagInfo{PrintConv};
-            } else {
-                # create tagInfo hash
-                $tagInfo = { Name => $name, PrintConv => { } };
-                Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        ($name = $tag) =~ s/\b([a-z])/\U$1/gs;  # capitalize all words
+        $name =~ s/ (\w)/\U$1/g;                # remove special characters
+        $name = 'RMETA_Unknown' unless length($name);
+        my $num = $nums[$i];
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+        if ($tagInfo) {
+            # make sure print conversion is defined
+            $$tagInfo{PrintConv} = { } unless ref $$tagInfo{PrintConv} eq 'HASH';
+        } else {
+            # create tagInfo hash
+            $tagInfo = { Name => $name, PrintConv => { } };
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+        # use string value directly if no numerical value
+        $num = $val unless defined $num;
+        # add conversion for this value (replacing any existing entry)
+        $tagInfo->{PrintConv}->{$num} = length $val ? $val : $num;
+        if ($verbose) {
+            my %datParms;
+            if (length $val) {
+                %datParms = ( Start => $valPos, Size => length($val), Format => 'string' );
+            } elsif ($numPos) {
+                %datParms = ( Start => $numPos + $i * 2, Size => 2, Format => 'int16u' );
             }
-            # use string value directly if no numerical value
-            $num = $val unless defined $num;
-            # add conversion for this value (replacing any existing entry)
-            $tagInfo->{PrintConv}->{$num} = $val;
-            if ($verbose) {
-                $exifTool->VerboseInfo($tag, $tagInfo,
-                    Table   => $tagTablePtr,
-                    Value   => $num,
-                    DataPt  => $dataPt,
-                    DataPos => $$dirInfo{DataPos},
-                    Start   => $valPos,
-                    Size    => length($val),
-                );
-            }
-            $exifTool->FoundTag($tagInfo, $num);
-            $valPos += length($val) + 1;
+            %datParms and $datParms{DataPt} = $dataPt, $datParms{DataPos} = $$dirInfo{DataPos};
+            $et->VerboseInfo($tag, $tagInfo, Table=>$tagTablePtr, Value=>$num, %datParms);
         }
+        $et->FoundTag($tagInfo, $num);
+        $valPos += length($val) + 1;
     }
     return 1;
@@ -677,5 +1144,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -690,4 +1157,8 @@
 =back
 
+=head1 ACKNOWLEDGEMENTS
+
+Thanks to Tim Gray for his help decoding a number of tags for the Ricoh GR.
+
 =head1 SEE ALSO
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Samsung.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Samsung.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Samsung.pm	(revision 34921)
@@ -8,4 +8,10 @@
 # References:   1) Tae-Sun Park private communication
 #               2) http://www.cybercom.net/~dcoffin/dcraw/
+#               3) Pascal de Bruijn private communication (NX100)
+#               4) Jaroslav Stepanek via rt.cpan.org
+#               5) Nick Livchits private communication
+#               6) Sreerag Raghavan private communication (SM-C200)
+#               IB) Iliah Borg private communication (LibRaw)
+#               NJ) Niels Kristian Bech Jensen private communication
 #------------------------------------------------------------------------------
 
@@ -13,12 +19,39 @@
 
 use strict;
-use vars qw($VERSION);
+use vars qw($VERSION %samsungLensTypes);
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
 
-$VERSION = '1.08';
+$VERSION = '1.48';
 
 sub WriteSTMN($$$);
 sub ProcessINFO($$$);
+sub ProcessSamsungMeta($$$);
+sub ProcessSamsungIFD($$$);
+
+# Samsung LensType lookup
+%samsungLensTypes = (
+    # (added "Samsung NX" in all of these lens names - ref 4)
+    0 => 'Built-in or Manual Lens', #PH (EX1, WB2000)
+    1 => 'Samsung NX 30mm F2 Pancake',
+    2 => 'Samsung NX 18-55mm F3.5-5.6 OIS', # (also version II, ref 1)
+    3 => 'Samsung NX 50-200mm F4-5.6 ED OIS',
+    # what about the non-OIS version of the 18-55,
+    # which was supposed to be available before the 20-50? - PH
+    4 => 'Samsung NX 20-50mm F3.5-5.6 ED', #PH/4
+    5 => 'Samsung NX 20mm F2.8 Pancake', #PH
+    6 => 'Samsung NX 18-200mm F3.5-6.3 ED OIS', #4
+    7 => 'Samsung NX 60mm F2.8 Macro ED OIS SSA', #1
+    8 => 'Samsung NX 16mm F2.4 Pancake', #1/4
+    9 => 'Samsung NX 85mm F1.4 ED SSA', #4
+    10 => 'Samsung NX 45mm F1.8', #3
+    11 => 'Samsung NX 45mm F1.8 2D/3D', #3
+    12 => 'Samsung NX 12-24mm F4-5.6 ED', #4
+    13 => 'Samsung NX 16-50mm F2-2.8 S ED OIS', #forum3833
+    14 => 'Samsung NX 10mm F3.5 Fisheye', #NJ
+    15 => 'Samsung NX 16-50mm F3.5-5.6 Power Zoom ED OIS', #5
+    20 => 'Samsung NX 50-150mm F2.8 S ED OIS', #PH
+    21 => 'Samsung NX 300mm F2.8 ED OIS', #IB
+);
 
 # range of values for Formats used in encrypted information
@@ -31,5 +64,5 @@
 
 # Samsung "STMN" maker notes (ref PH)
-%Image::ExifTool::Samsung::Type1 = (
+%Image::ExifTool::Samsung::Main = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
     WRITE_PROC => \&WriteSTMN,
@@ -39,4 +72,5 @@
     FIRST_ENTRY => 0,
     IS_OFFSET => [ 2 ],   # tag 2 is 'IsOffset'
+    IS_SUBDIR => [ 11 ],
     GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     NOTES => q{
@@ -54,4 +88,5 @@
         IsOffset => 3,
         Protected => 2,
+        WriteGroup => 'MakerNotes',
     },
     3 => {
@@ -60,5 +95,31 @@
         DataTag => 'PreviewImage',
         Protected => 2,
-    },
+        WriteGroup => 'MakerNotes',
+    },
+    11 => {
+        Name => 'SamsungIFD',
+        # Note: this is not always an IFD.  In many models the string
+        # "Park Byeongchan" is found at this location
+        Condition => '$$valPt =~ /^[^\0]\0\0\0/',
+        Format => 'undef[$size - 44]',
+        SubDirectory => { TagTable => 'Image::ExifTool::Samsung::IFD' },
+    },
+);
+
+%Image::ExifTool::Samsung::IFD = (
+    PROCESS_PROC => \&ProcessSamsungIFD,
+    NOTES => q{
+        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 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' },
+    # 0x0001 - undef[4000|4100]: starts with "MN_PRV" (or all zeros)
+    # 0x0002 - undef[7000]     : starts with "Kim Miae"
+    # 0x0003 - undef[5000]     : starts with "Lee BK"
+    # 0x0004 - undef[500|2000] : starts with "IPCD"   (or all zeros)
+    # 0x0006 - undef[100|200]  : starts with "MN_ADS" (or all zeros)
 );
 
@@ -75,23 +136,156 @@
         Count => 4,
     },
+    0x0002 => {
+        Name => 'DeviceType',
+        Groups => { 2 => 'Camera' },
+        Writable => 'int32u',
+        PrintHex => 1,
+        PrintConv => {
+            0x1000 => 'Compact Digital Camera',
+            0x2000 => 'High-end NX Camera',
+            0x3000 => 'HXM Video Camera',
+            0x12000 => 'Cell Phone',
+            0x300000 => 'SMX Video Camera',
+        },
+    },
+    0x0003 => {
+        Name => 'SamsungModelID',
+        Groups => { 2 => 'Camera' },
+        Writable => 'int32u',
+        PrintHex => 1,
+        PrintConv => {
+            0x100101c => 'NX10',
+            0x1001226 => 'HMX-S10BP',
+            0x1001226 => 'HMX-S15BP',
+            0x1001233 => 'HMX-Q10',
+            0x1001234 => 'HMX-H300',
+            0x1001234 => 'HMX-H304',
+            0x100130c => 'NX100',
+            0x1001327 => 'NX11',
+            0x170104b => 'ES65, ES67 / VLUU ES65, ES67 / SL50',
+            0x170104e => 'ES70, ES71 / VLUU ES70, ES71 / SL600',
+            0x1701052 => 'ES73 / VLUU ES73 / SL605',
+            0x1701055 => 'ES25, ES27 / VLUU ES25, ES27 / SL45',
+            0x1701300 => 'ES28 / VLUU ES28',
+            0x1701303 => 'ES74,ES75,ES78 / VLUU ES75,ES78',
+            0x2001046 => 'PL150 / VLUU PL150 / TL210 / PL151',
+            0x2001048 => 'PL100 / TL205 / VLUU PL100 / PL101',
+            0x2001311 => 'PL120,PL121 / VLUU PL120,PL121',
+            0x2001315 => 'PL170,PL171 / VLUUPL170,PL171',
+            0x200131e => 'PL210, PL211 / VLUU PL210, PL211',
+            0x2701317 => 'PL20,PL21 / VLUU PL20,PL21',
+            0x2a0001b => 'WP10 / VLUU WP10 / AQ100',
+            0x3000000 => 'Various Models (0x3000000)',
+           #0x3000000 => 'DV150F / DV151F / DV155F',
+           #0x3000000 => 'NX mini',
+           #0x3000000 => 'NX3000',
+           #0x3000000 => 'NX3300',
+           #0x3000000 => 'ST150F / ST151F / ST152F',
+           #0x3000000 => 'WB200F / WB201F / WB202F',
+           #0x3000000 => 'WB250F / WB251F / WB252F',
+           #0x3000000 => 'WB30F / WB31F / WB32F',
+           #0x3000000 => 'WB350F / WB351F / WB352F',
+           #0x3000000 => 'WB800F',
+            0x3a00018 => 'Various Models (0x3a00018)',
+           #0x3a00018 => 'ES30 / VLUU ES30',
+           #0x3a00018 => 'ES80 / ES81',
+           #0x3a00018 => 'ES9 / ES8',
+           #0x3a00018 => 'PL200 / VLUU PL200',
+           #0x3a00018 => 'PL80 / VLUU PL80 / SL630 / PL81',
+           #0x3a00018 => 'PL90 / VLUU PL90',
+           #0x3a00018 => 'WB1100F / WB1101F / WB1102F',
+           #0x3a00018 => 'WB2200F',
+            0x400101f => 'ST1000 / ST1100 / VLUU ST1000 / CL65',
+            0x4001022 => 'ST550 / VLUU ST550 / TL225',
+            0x4001025 => 'Various Models (0x4001025)',
+           #0x4001025 => 'DV300 / DV300F / DV305F',
+           #0x4001025 => 'ST500 / VLUU ST500 / TL220',
+           #0x4001025 => 'ST200 / ST200F / ST201 / ST201F / ST205F',
+            0x400103e => 'VLUU ST5500, ST5500, CL80',
+            0x4001041 => 'VLUU ST5000, ST5000, TL240',
+            0x4001043 => 'ST70 / VLUU ST70 / ST71',
+            0x400130a => 'Various Models (0x400130a)',
+           #0x400130a => 'VLUU ST100, ST100',
+           #0x400130a => 'VLUU ST600, ST600',
+           #0x400130a => 'VLUU ST80, ST80',
+            0x400130e => 'ST90,ST91 / VLUU ST90,ST91',
+            0x4001313 => 'VLUU ST95, ST95',
+            0x4a00015 => 'VLUU ST60',
+            0x4a0135b => 'ST30, ST65 / VLUU ST65 / ST67',
+            0x5000000 => 'Various Models (0x5000000)',
+           #0x5000000 => 'EX2F',
+           #0x5000000 => 'NX1000',
+           #0x5000000 => 'NX20',
+           #0x5000000 => 'NX200',
+           #0x5000000 => 'NX210',
+           #0x5000000 => 'ST96',
+           #0x5000000 => 'WB750',
+           #0x5000000 => 'ST700',
+            0x5001038 => 'Various Models (0x5001038)',
+           #0x5001038 => 'EK-GN120',
+           #0x5001038 => 'HMX-E10',
+           #0x5001038 => 'NX1',
+           #0x5001038 => 'NX2000',
+           #0x5001038 => 'NX30',
+           #0x5001038 => 'NX300',
+           #0x5001038 => 'NX500',
+           #0x5001038 => 'SM-C200',
+           #0x5001038 => 'WB2000',
+            0x500103a => 'WB650 / VLUU WB650 / WB660',
+            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',
+        },
+    },
+    # 0x0004 - undef[x] (SamsungContentsID?)
+    # 0x000a - int32u (ContinuousShotMode?)
+    # 0x000b - int16u (BestPhotoMode?)
+    # 0x000c - int32u ? values: 0,1
+    # 0x000e - int32u[2] (SoundMultiPicture?)
+    # 0x0010 - rational64u ? values: undef,inf
+    0x0011 => { #6
+        Name => 'OrientationInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Samsung::OrientationInfo' },
+    },
+    0x0020 => [{ #forum7685
+        Name => 'SmartAlbumColor',
+        Condition => '$$valPt =~ /^\0{4}/',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'n/a',
+        },
+    },{
+        Name => 'SmartAlbumColor',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => [{
+            0 => 'Red',
+            1 => 'Yellow',
+            2 => 'Green',
+            3 => 'Blue',
+            4 => 'Magenta',
+            5 => 'Black',
+            6 => 'White',
+            7 => 'Various',
+        }],
+    }],
     0x0021 => { #1
         Name => 'PictureWizard',
         Writable => 'int16u',
-        Count => 5,
-        PrintConv => q{
-            my @a = split ' ', $val;
-            return $val unless @a == 5;
-            sprintf("Mode: %d, Col: %d, Sat: %d, Sha: %d, Con: %d",
-                    $a[0], $a[1], $a[2]-4, $a[3]-4, $a[4]-4);
-        },
-        PrintConvInv => q{
-            my @a = ($val =~ /[+-]?\d+/g);
-            return $val unless @a >= 5;
-            sprintf("%d %d %d %d %d", $a[0], $a[1], $a[2]+4, $a[3]+4, $a[4]+4);
-        },
-    },
-    # 0x0023 - string: "0123456789" (PH)
+        SubDirectory => { TagTable => 'Image::ExifTool::Samsung::PictureWizard' },
+    },
+    # 0x0022 - int32u (CaptureMode?) (Gamma? eg. 65538 = 1.2, ref forum7720)
+    # 0x0023 - string: "0123456789" (PH) (placeholder for SerialNumber?)
+    # 0x0025 - int32u (ImageCount?)
+    # 0x002a - undef[4] (SNSDirectShare?)
+    # 0x002f - string (GPSInfo01?)
     0x0030 => { #1 (NX100 with GPS)
         Name => 'LocalLocationName',
+        Groups => { 2 => 'Location' },
         Writable => 'string',
         Format => 'undef',
@@ -103,7 +297,21 @@
     0x0031 => { #1 (NX100 with GPS)
         Name => 'LocationName',
+        Groups => { 2 => 'Location' },
         Writable => 'string',
     },
-    0x0035 => {
+    # 0x0032 - string (GPSInfo03)
+    # 0x0033 - string (GPSInfo04)
+    # 0x0034 - string (GPSInfo05)
+    0x0035 => [{
+        Name => 'PreviewIFD',
+        Condition => '$$self{TIFF_TYPE} eq "SRW" and $$self{Model} ne "EK-GN120"', # (not an IFD in JPEG images)
+        Groups => { 1 => 'PreviewIFD' },
+        Flags => 'SubIFD',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Nikon::PreviewIFD',
+            ByteOrder => 'Unknown',
+            Start => '$val',
+        },
+    },{
         Name => 'PreviewIFD',
         Condition => '$$self{TIFF_TYPE} eq "SRW"', # (not an IFD in JPEG images)
@@ -113,5 +321,26 @@
             TagTable => 'Image::ExifTool::Nikon::PreviewIFD',
             ByteOrder => 'Unknown',
-            Start => '$val',
+            Start => '$val - 36',
+        },
+    }],
+    # 0x003a - int16u[2] (SmartLensInfo?)
+    # 0x003b - int16u[2] (PhotoStyleSelectInfo?)
+    # 0x003c - int16u (SmartRange?)
+    # 0x003d - int16u[5] (SmartCropInfo?)
+    # 0x003e - int32u (DualCapture?)
+    # 0x003f - int16u[2] (SGIFInfo?)
+    0x0040 => { #forum7432
+        Name => 'RawDataByteOrder',
+        PrintConv => {
+            0 => 'Little-endian (Intel, II)',
+            1 => 'Big-endian (Motorola, MM)', #(NC)
+        },
+    },
+    0x0041 => { #forum7684
+        Name => 'WhiteBalanceSetup',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Auto',
+            1 => 'Manual',
         },
     },
@@ -121,14 +350,49 @@
         Writable => 'rational64s',
         # (DPreview samples all 0.2 C --> pre-production model)
-        PrintConv => '"$val C"',
+        PrintConv => '$val =~ /\d/ ? "$val C" : $val',
         PrintConvInv => '$val=~s/ ?C//; $val',
     },
-    # 0x00a0 - undef[8192]: white balance information (ref 1):
+    # 0x0045 => { Name => 'RawCompressionMode', Writable => 'int32u' }, # (related to ExposureMode, not raw compresison? ref forum7432)
+    # 0x004a - int32u[7] (ImageVerification?)
+    # 0x004b - int32u[2] (RewindInfo?)
+    # 0x0050 - int32u (ColorSpace? - inconsistent) values: 1 (related to compression mode, ref forum7432)
+    0x0050 => { #forum7432
+        Name => 'RawDataCFAPattern',
+        PrintConv => {
+            0 => 'Unchanged',
+            1 => 'Swap',
+            65535 => 'Roll',
+        },
+    },
+    # 0x0054 - int16u[2] (WeatherInfo?)
+    # 0x0060 - undef (AEInfo?)
+    # 0x0080 - undef (AFInfo?)
+    # 0x00a0 - undef[8192] (AWBInfo1): white balance information (ref 1):
     #   At byte 5788, the WBAdjust: "Adjust\0\X\0\Y\0\Z\xee\xea\xce\xab", where
     #   Y = BA adjust (0=Blue7, 7=0, 14=Amber7), Z = MG (0=Magenta7, 7=0, 14=Green7)
+    # 0x00a1 - undef (AWBInfo2?)
+    # 0x00c0 - undef (IPCInfo?)
+    # 0x00c7 - undef (SmartFunctionInfo?)
+    # 0x00e0 - int16u (SceneResult?)
+    # 0x00e1 - int16u[8] (SADebugInfo01?)
+    # 0x00e1 - int16u[x] (SADebugInfo02?)
+    0x0100 => {
+        Name => 'FaceDetect',
+        Writable => 'int16u',
+        PrintConv => { 0 => 'Off', 1 => 'On' }, #(NC)
+    },
+    # 0x0101 - int16u[6] (FaceDetectInfo?)
+    # 0x0102 - int16u[x] (FaceDetectInfo?)
+    0x0120 => {
+        Name => 'FaceRecognition',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'Off', 1 => 'On' }, #(NC)
+    },
+    0x0123 => { Name => 'FaceName', Writable => 'string' },
+    # 0x140 - undef (LensInfo?)
 #
 # the following tags found only in SRW images
 #
-    # 0xa000 - rational64u: 1 or 1.1 (ref PH)
+    # 0xa000 - rational64u: 1 or 1.1 (ref PH) (MakerNoteVersion?)
     0xa001 => { #1
         Name => 'FirmwareName',
@@ -136,19 +400,16 @@
         Writable => 'string',
     },
-    # 0xa002 - string[30]: '0' or 'DY049P000000' (ref PH)
+    0xa002 => { #PH/IB
+        Name => 'SerialNumber',
+        Condition => '$$valPt =~ /^\w{5}/', # should be at least 5 characters long
+        Groups => { 2 => 'Camera' },
+        Writable => 'string',
+    },
     0xa003 => { #1 (SRW images only)
         Name => 'LensType',
         Groups => { 2 => 'Camera' },
         Writable => 'int16u',
-        PrintConv => {
-            0 => 'Built-in', #PH (EX1, WB2000)
-            1 => 'Samsung 30mm F2 Pancake',
-            2 => 'Samsung Zoom 18-55mm F3.5-5.6 OIS',
-            3 => 'Samsung Zoom 50-200mm F4-5.6 ED OIS',
-            # what about the non-OIS version of the 18-55,
-            # which was supposed to be available before the 20-50?
-            4 => 'Samsung 20-50mm F3.5-5.6 Compact Zoom', #PH
-            5 => 'Samsung 20mm F2.8 Pancake', #PH (guess)
-        },
+        Count => -1,
+        PrintConv => [ \%samsungLensTypes ],
     },
     0xa004 => { #1
@@ -157,5 +418,9 @@
         Writable => 'string',
     },
-    # 0xa005 - string[30]: constant for a given lens? Not the printed serial number (ref 1)
+    0xa005 => {
+        Name => 'InternalLensSerialNumber', # Not the printed serial number (ref 1)
+        Groups => { 2 => 'Camera' },
+        Writable => 'string',
+    },
     0xa010 => { #1
         Name => 'SensorAreas',
@@ -190,8 +455,9 @@
         Writable => 'rational64u',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => '$val',
     },
     0xa019 => { #1
         Name => 'FNumber',
+        Priority => 0,
         Writable => 'rational64u',
         PrintConv => 'sprintf("%.1f",$val)',
@@ -201,4 +467,5 @@
         Name => 'FocalLengthIn35mmFormat',
         Groups => { 2 => 'Camera' },
+        Priority => 0,
         Format => 'int32u',
         ValueConv => '$val / 10',
@@ -207,4 +474,6 @@
         PrintConvInv => '$val=~s/\s*mm$//;$val',
     },
+    # 0xa01b - int32u (ImageCount?)
+    # 0xa01b - int16u (LDCLens?)
     0xa020 => { #1
         Name => 'EncryptionKey',
@@ -246,11 +515,14 @@
         RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,1)',
     },
-    #this doesn't seem correct
-    #0xa025 => { #PH/1
-    #    Name => 'ColorTemperatureAuto',
-    #    Writable => 'int32u',
-    #    RawConv    => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,6)',
-    #    RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-6)',
-    #},
+    0xa025 => { # (PostAEGain?)
+        Name => 'DigitalGain', #IB
+        Writable => 'int32u',
+        RawConv    => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,6)',
+        RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-6)',
+    },
+    0xa025 => { #IB
+        Name => 'HighlightLinearityLimit',
+        Writable => 'int32u',
+    },
     0xa028 => { #2/PH
         Name => 'WB_RGGBLevelsBlack',
@@ -282,7 +554,5 @@
     },
     0xa033 => { #1
-        Name => 'Samsung_Type2_0xa033',
-        Unknown => 1,
-        Hidden => 1,
+        Name => 'CbCrMatrixDefault',
         Writable => 'int32s',
         Count => 4,
@@ -291,7 +561,5 @@
     },
     0xa034 => { #1
-        Name => 'Samsung_Type2_0xa034',
-        Unknown => 1,
-        Hidden => 1,
+        Name => 'CbCrMatrix',
         Writable => 'int32s',
         Count => 4,
@@ -300,7 +568,5 @@
     },
     0xa035 => { #1
-        Name => 'Samsung_Type2_0xa035',
-        Unknown => 1,
-        Hidden => 1,
+        Name => 'CbCrGainDefault',
         Writable => 'int32u',
         Count => 2,
@@ -309,7 +575,5 @@
     },
     0xa036 => { #1
-        Name => 'Samsung_Type2_0xa036',
-        Unknown => 1,
-        Hidden => 1,
+        Name => 'CbCrGain',
         Writable => 'int32u',
         Count => 2,
@@ -318,5 +582,5 @@
     },
     0xa040 => { #1
-        Name => 'ToneCurve1',
+        Name => 'ToneCurveSRGBDefault',
         Writable =>  'int32u',
         Count => 23,
@@ -329,5 +593,5 @@
     },
     0xa041 => { #1
-        Name => 'ToneCurve2',
+        Name => 'ToneCurveAdobeRGBDefault',
         Writable =>  'int32u',
         Count => 23,
@@ -336,5 +600,5 @@
     },
     0xa042 => { #1
-        Name => 'ToneCurve3',
+        Name => 'ToneCurveSRGB',
         Writable =>  'int32u',
         Count => 23,
@@ -343,5 +607,5 @@
     },
     0xa043 => { #1
-        Name => 'ToneCurve4',
+        Name => 'ToneCurveAdobeRGB',
         Writable =>  'int32u',
         Count => 23,
@@ -350,7 +614,6 @@
     },
     0xa048 => { #1
-        Name => 'Samsung_Type2_0xa048',
+        Name => 'RawData',
         Unknown => 1,
-        Hidden => 1,
         Writable => 'int32s',
         Count => 12,
@@ -358,8 +621,7 @@
         RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,"-0")',
     },
-    0xa050 => { #1 (vignette curve?)
-        Name => 'Samsung_Type2_0xa050',
+    0xa050 => { #1
+        Name => 'Distortion',
         Unknown => 1,
-        Hidden => 1,
         Writable => 'int32s',
         Count => 8,
@@ -368,7 +630,6 @@
     },
     0xa051 => { #1
-        Name => 'Samsung_Type2_0xa051',
+        Name => 'ChromaticAberration',
         Unknown => 1,
-        Hidden => 1,
         Writable => 'int16u',
         Count => 22,
@@ -376,8 +637,7 @@
         RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,0,7,3)',
     },
-    0xa052 => { #1 (vignette curve?)
-        Name => 'Samsung_Type2_0xa052',
+    0xa052 => { #1
+        Name => 'Vignetting',
         Unknown => 1,
-        Hidden => 1,
         Writable => 'int16u',
         Count => 15,
@@ -386,7 +646,6 @@
     },
     0xa053 => { #1
-        Name => 'Samsung_Type2_0xa053',
+        Name => 'VignettingCorrection',
         Unknown => 1,
-        Hidden => 1,
         Writable => 'int16u',
         Count => 15,
@@ -395,7 +654,6 @@
     },
     0xa054 => { #1
-        Name => 'Samsung_Type2_0xa054',
+        Name => 'VignettingSetting',
         Unknown => 1,
-        Hidden => 1,
         Writable => 'int16u',
         Count => 15,
@@ -404,5 +662,5 @@
     },
     0xa055 => { #1
-        Name => 'Samsung_Type2_0xa055',
+        Name => 'Samsung_Type2_0xa055', # (DistortionCamera1st?)
         Unknown => 1,
         Hidden => 1,
@@ -413,5 +671,5 @@
     },
     0xa056 => { #1
-        Name => 'Samsung_Type2_0xa056',
+        Name => 'Samsung_Type2_0xa056', # (DistortionCamera2nd?)
         Unknown => 1,
         Hidden => 1,
@@ -422,5 +680,5 @@
     },
     0xa057 => { #1
-        Name => 'Samsung_Type2_0xa057',
+        Name => 'Samsung_Type2_0xa057', # (DistortionCameraSetting?)
         Unknown => 1,
         Hidden => 1,
@@ -429,4 +687,77 @@
         RawConv    => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,2)',
         RawConvInv => 'Image::ExifTool::Samsung::Crypt($self,$val,$tagInfo,-2)',
+    },
+    # 0xa060 - rational64u (CISTemperature?)
+    # 0xa061 - int16u (Compression?)
+);
+
+# orientation information (ref 6)
+%Image::ExifTool::Samsung::OrientationInfo = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'rational64s',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Camera orientation information written by the Gear 360 (SM-C200).',
+    0 => {
+        Name => 'YawAngle', #(NC)
+        Unknown => 1,
+        Notes => 'always zero',
+    },
+    1 => {
+        Name => 'PitchAngle',
+        Notes => 'upward tilt of rear camera in degrees',
+    },
+    2 => {
+        Name => 'RollAngle',
+        Notes => 'clockwise rotation of rear camera in degrees',
+    },
+);
+
+# Picture Wizard information (ref 1)
+%Image::ExifTool::Samsung::PictureWizard = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    WRITABLE => 1,
+    FORMAT => 'int16u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0 => {
+        Name => 'PictureWizardMode',
+        PrintConvColumns => 3,
+        PrintConv => { #3
+             0 => 'Standard',
+             1 => 'Vivid',
+             2 => 'Portrait',
+             3 => 'Landscape',
+             4 => 'Forest',
+             5 => 'Retro',
+             6 => 'Cool',
+             7 => 'Calm',
+             8 => 'Classic',
+             9 => 'Custom1',
+            10 => 'Custom2',
+            11 => 'Custom3',
+           255 => 'n/a', #PH
+        },
+    },
+    1 => 'PictureWizardColor',
+    2 => {
+        Name => 'PictureWizardSaturation',
+        ValueConv => '$val - 4',
+        ValueConvInv => '$val + 4',
+    },
+    3 => {
+        Name => 'PictureWizardSharpness',
+        ValueConv => '$val - 4',
+        ValueConvInv => '$val + 4',
+    },
+    4 => {
+        Name => 'PictureWizardContrast',
+        ValueConv => '$val - 4',
+        ValueConvInv => '$val + 4',
     },
 );
@@ -465,5 +796,5 @@
         Format => 'string[16]',
     },
-    0x2e => { # (NC)
+    0x2e => { #(NC)
         Name => 'ExposureTime',
         Format => 'int32u',
@@ -476,5 +807,5 @@
         PrintConv => 'sprintf("%.1f",$val)',
     },
-    0x3a => { # (NC)
+    0x3a => { #(NC)
         Name => 'ExposureCompensation',
         Format => 'rational64s',
@@ -488,5 +819,5 @@
         Name => 'Software',
         Format => 'string[32]',
-        # (these tags are not at a constant offset for Sanyo videos,
+        # (these tags are not at a constant offset for Olympus/Sanyo videos,
         #  so just to be safe use this to validate subsequent tags)
         RawConv => q{
@@ -496,26 +827,244 @@
         },
     },
-    0xf8 => {
-        Name => 'ThumbnailWidth',
+    0xf4 => {
+        Name => 'Thumbnail',
         Condition => '$$self{SamsungMP4}',
-        Format => 'int32u',
-    },
-    0xfc => {
-        Name => 'ThumbnailHeight',
-        Condition => '$$self{SamsungMP4}',
-        Format => 'int32u',
-    },
-    0x100 => {
-        Name => 'ThumbnailLength',
-        Condition => '$$self{SamsungMP4}',
-        Format => 'int32u',
-    },
-    0x104 => {
-        Name => 'ThumbnailOffset',
-        Condition => '$$self{SamsungMP4}',
-        IsOffset => 1,
-        Format => 'int32u',
-        RawConv => '$val + 0xf4',
-    },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Samsung::Thumbnail',
+            Base => '$start',
+        },
+    },
+);
+
+# thumbnail image information found in MP4 videos (similar in Olympus,Samsung,Sanyo)
+%Image::ExifTool::Samsung::Thumbnail = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    1 => 'ThumbnailWidth',
+    2 => 'ThumbnailHeight',
+    3 => 'ThumbnailLength',
+    4 => { Name => 'ThumbnailOffset', IsOffset => 1 },
+);
+
+# Samsung MP4 @sec information (PH - from WB30F sample)
+%Image::ExifTool::Samsung::sec = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        This information is found in the @sec atom of Samsung MP4 videos from models
+        such as the WB30F.
+    },
+    0x00 => {
+        Name => 'Make',
+        Format => 'string[32]',
+        PrintConv => 'ucfirst(lc($val))',
+    },
+    0x20 => {
+        Name => 'Model',
+        Description => 'Camera Model Name',
+        Format => 'string[32]',
+    },
+    0x200 => { Name => 'ThumbnailWidth',  Format => 'int32u' },
+    0x204 => { Name => 'ThumbnailHeight', Format => 'int32u' },
+    0x208 => { Name => 'ThumbnailLength', Format => 'int32u' }, # (2 bytes too long in my sample)
+    0x20c => {
+        Name => 'ThumbnailImage',
+        Groups => { 2 => 'Preview' },
+        Format => 'undef[$val{0x208}]',
+        Notes => 'the THM image, embedded metadata is extracted as the first sub-document',
+        SetBase => 1,
+        RawConv => q{
+            my $pt = $self->ValidateImage(\$val, $tag);
+            if ($pt) {
+                $$self{BASE} += 0x20c;
+                $$self{DOC_NUM} = ++$$self{DOC_COUNT};
+                $self->ExtractInfo($pt, { ReEntry => 1 });
+                $$self{DOC_NUM} = 0;
+            }
+            return $pt;
+        },
+    },
+);
+
+# Samsung MP4 smta information (PH - from SM-C101 sample)
+%Image::ExifTool::Samsung::smta = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
+    NOTES => q{
+        This information is found in the smta atom of Samsung MP4 videos from models
+        such as the Galaxy S4.
+    },
+    svss => {
+        Name => 'SamsungSvss',
+        SubDirectory => { TagTable => 'Image::ExifTool::Samsung::svss' },
+    },
+    # swtr - 4 bytes, all zero
+    # scid - 8 bytes, all zero
+    # saut - 4 bytes, all zero
+);
+
+# Samsung MP4 svss information (PH - from SM-C101 sample)
+%Image::ExifTool::Samsung::svss = (
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Video' },
+    NOTES => q{
+        This information is found in the svss atom of Samsung MP4 videos from models
+        such as the Galaxy S4.
+    },
+    # junk - 10240 bytes, all zero
+);
+
+# thumbnail image information found in some MP4 videos
+%Image::ExifTool::Samsung::Thumbnail2 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    1 => 'ThumbnailWidth',
+    2 => 'ThumbnailHeight',
+    3 => 'ThumbnailLength',
+    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, 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
+        as the Galaxy S4 and Tab S.
+    },
+    '0x0001-name' => 'EmbeddedImageName', # ("DualShot_1","DualShot_2")
+    '0x0001' => { Name => 'EmbeddedImage', Groups => { 2 => 'Preview' }, Binary => 1 },
+    '0x0100-name' => 'EmbeddedAudioFileName', # ("SoundShot_000")
+    '0x0100' => { Name => 'EmbeddedAudioFile', Groups => { 2 => 'Audio' }, Binary => 1 },
+    '0x0201-name' => 'SurroundShotVideoName', # ("Interactive_Panorama_000")
+    '0x0201' => { Name => 'SurroundShotVideo', Groups => { 2 => 'Video' }, Binary => 1 },
+   # 0x0800-name - seen 'SoundShot_Meta_Info'
+   # 0x0800 - unknown (29 bytes) (contains already-extracted EmbeddedAudioFileName)
+   # 0x0830-name - seen '1165724808.pre'
+   # 0x0830 - unknown (164004 bytes)
+   # 0x08d0-name - seen 'Interactive_Panorama_Info'
+   # 0x08d0 - unknown (7984 bytes)
+   # 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'
+    '0x0a01' => { #forum7161
+        Name => 'TimeStamp',
+        Groups => { 2 => 'Time' },
+        ValueConv => 'ConvertUnixTime($val / 1e3, 1)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    '0x0a20-name' => 'DualCameraImageName', # ("FlipPhoto_002")
+    '0x0a20' => { Name => 'DualCameraImage', Groups => { 2 => 'Preview' }, Binary => 1 },
+    '0x0a30-name' => 'EmbeddedVideoType', # ("MotionPhoto_Data")
+    '0x0a30' => { Name => 'EmbeddedVideoFile', Groups => { 2 => 'Video' }, Binary => 1 }, #forum7161
+   # 0x0aa1-name - seen 'MCC_Data'
+   # 0x0aa1 - seen '234','222','429'
+   # 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 => '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::DualShotExtra = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    # 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            => { },
 );
 
@@ -533,4 +1082,28 @@
             $a[$_] -= $b[$_] foreach 0..$#a;
             return "@a";
+        },
+    },
+    DepthMapTiff => {
+        Require => {
+            0 => 'DepthMapData',
+            1 => 'DepthMapWidth',
+            2 => 'DepthMapHeight',
+        },
+        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;
+        },
+    },
+    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;
         },
     },
@@ -551,6 +1124,6 @@
 sub Crypt($$$@)
 {
-    my ($exifTool, $val, $tagInfo, @salt) = @_;
-    my $key = $$exifTool{EncryptionKey} or return undef;
+    my ($et, $val, $tagInfo, @salt) = @_;
+    my $key = $$et{EncryptionKey} or return undef;
     my $format = $$tagInfo{Writable} || $$tagInfo{Format} or return undef;
     return undef unless $formatMinMax{$format};
@@ -583,10 +1156,10 @@
 sub ProcessINFO($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $pos = $$dirInfo{DirStart};
     my $len = $$dirInfo{DirLen};
     my $end = $pos + $len;
-    $exifTool->VerboseDir('INFO', undef, $len);
+    $et->VerboseDir('INFO', undef, $len);
     while ($pos + 8 <= $end) {
         my $tag = substr($$dataPt, $pos, 4);
@@ -595,10 +1168,248 @@
             my $name = "Samsung_INFO_$tag";
             $name =~ tr/-_0-9a-zA-Z//dc;
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name }) if $name;
+            AddTagToTable($tagTablePtr, $tag, { Name => $name }) if $name;
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, $val);
+        $et->HandleTag($tagTablePtr, $tag, $val);
         $pos += 8;
     }
     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
+sub ProcessSamsungIFD($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $len = $$dirInfo{DataLen};
+    my $pos = $$dirInfo{DirStart};
+    return 0 unless $pos + 4 < $len;
+    my $dataPt = $$dirInfo{DataPt};
+    my $buff = substr($$dataPt, $pos, 4);
+    # this is not an IFD for many models
+    # (the string "Park Byeongchan" is often found here)
+    return 0 unless $buff =~ s/^([^\0])\0\0\0/$1\0$1\0/s;
+    my $numEntries = ord $1;
+    if ($$et{HTML_DUMP}) {
+        my $pt = $$dirInfo{DirStart} + $$dirInfo{DataPos} + $$dirInfo{Base};
+        $et->HDump($pt-44, 44, "MakerNotes header", 'Samsung');
+        $et->HDump($pt, 4, "MakerNotes entries", "Format: int32u\nEntry count: $numEntries");
+        $$dirInfo{NoDumpEntryCount} = 1;
+    }
+    substr($$dataPt, $pos, 4) = $buff;      # insert bogus 2-byte entry count
+    # offset base is at end of IFD
+    my $shift = $$dirInfo{DirStart} + 4 + $numEntries * 12 + 4;
+    $$dirInfo{Base} += $shift;
+    $$dirInfo{DataPos} -= $shift;
+    $$dirInfo{DirStart} += 2;       # start at bogus entry count
+    $$dirInfo{ZeroOffsetOK} = 1;    # disable check for zero offset
+    delete $$et{NO_UNKNOWN};  # (set for BinaryData, but not for EXIF IFD's)
+    my $rtn = Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
+    substr($$dataPt, $pos + 2, 1) = "\0";   # remove bogus count
+    return $rtn;
+}
+
+#------------------------------------------------------------------------------
+# Read/write Samsung trailer (ie. "Sound & Shot" written by Galaxy Tab S (SM-T805))
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 not valid Samsung trailer, or -1 error writing
+# - updates DataPos to point to start of Samsung trailer
+# - updates DirLen to existing trailer length
+sub ProcessSamsung($$$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my $offset = $$dirInfo{Offset} || 0;
+    my $outfile = $$dirInfo{OutFile};
+    my $verbose = $et->Options('Verbose');
+    my $unknown = $et->Options('Unknown');
+    my ($buff, $buf2, $index, $offsetPos, $audioNOff, $audioSize);
+
+    return 0 unless $raf->Seek(-6-$offset, 2) and $raf->Read($buff, 6) == 6 and
+                    ($buff eq 'QDIOBS' or $buff eq "\0\0SEFT");
+    my $endPos = $raf->Tell();
+    $raf->Seek(-2, 1) or return 0 if $buff eq 'QDIOBS'; # rewind to before 'BS'
+    my $blockEnd = $raf->Tell();
+    SetByteOrder('II');
+
+    # read blocks backward until we find the SEFH/SEFT block
+    # (the only other block I have seen is QDIO/QDIO)
+SamBlock:
+    for (;;) {
+        last unless $raf->Seek($blockEnd-8, 0) and $raf->Read($buff, 8) == 8;
+        my $type = substr($buff, 4);
+        last unless $type =~ /^\w+$/;
+        my $len = Get32u(\$buff, 0);
+        last unless $len < 0x10000 and $len >= 4 and $len + 8 < $blockEnd;
+        last unless $raf->Seek(-8-$len, 1) and $raf->Read($buff, $len) == $len;
+        $blockEnd -= $len + 8;
+        unless ($type eq 'SEFT') {  # look for directory block (ends with "SEFT")
+            next unless $outfile and $type eq 'QDIO';
+            # QDIO block format:
+            #   0 - 'QDIO'
+            #   4 - int32u: 101 (version)
+            #   8 - int32u: 1
+            #  12 - int32u: absolute offset of audio file start (augh!!)
+            #  16 - int32u: absolute offset of audio file end (augh!!)
+            #  20 - int32u: 20 (QDIO block length minus 8)
+            #  24 - 'QDIO'
+            if ($len == 20) {
+                # save position of audio file offset in QDIO block
+                $offsetPos = $endPos - $raf->Tell() + $len - 12;
+            } else {
+                $et->Error('Unsupported Samsung trailer QDIO block', 1);
+            }
+            next;
+        }
+        last unless $buff =~ /^SEFH/ and $len >= 12;   # validate SEFH header
+        my $dirPos = $raf->Tell() - $len;
+        # my $ver = Get32u(\$buff, 0x04);  # version (=101)
+        my $count = Get32u(\$buff, 0x08);
+        last if 12 + 12 * $count > $len;
+        my $tagTablePtr = GetTagTable('Image::ExifTool::Samsung::Trailer');
+
+        # scan ahead quickly to look for the block where the data comes first
+        # (have only seen this to be the first in the directory, but just in case)
+        my $firstBlock = 0;
+        for ($index=0; $index<$count; ++$index) {
+            my $entry = 12 + 12 * $index;
+            my $noff = Get32u(\$buff, $entry + 4);  # negative offset
+            $firstBlock = $noff if $firstBlock < $noff;
+        }
+        # save trailer position and length
+        my $dataPos = $$dirInfo{DataPos} = $dirPos - $firstBlock;
+        my $dirLen = $$dirInfo{DirLen} = $endPos - $dataPos;
+        if (($verbose or $$et{HTML_DUMP}) and not $outfile) {
+            $et->DumpTrailer($dirInfo);
+            return 1 if $$et{HTML_DUMP};
+        }
+        # read through the SEFH/SEFT directory entries
+        for ($index=0; $index<$count; ++$index) {
+            my $entry = 12 + 12 * $index;
+            # first 2 bytes always 0 (may be part of block type)
+            my $type = Get16u(\$buff, $entry + 2);  # block type
+            my $noff = Get32u(\$buff, $entry + 4);  # negative offset
+            my $size = Get32u(\$buff, $entry + 8);  # block size
+            last SamBlock if $noff > $dirPos or $size > $noff or $size < 8;
+            $firstBlock = $noff if $firstBlock < $noff;
+            if ($outfile) {
+                next unless $type == 0x0100 and not $audioNOff;
+                # save offset and length of first audio file for QDIO block
+                last unless $raf->Seek($dirPos-$noff, 0) and $raf->Read($buf2, 8) == 8;
+                $len = Get32u(\$buf2, 4);
+                $audioNOff = $noff - 8 - $len;   # negative offset to start of audio data
+                $audioSize = $size - 8 - $len;
+                next;
+            }
+            # add unknown tags if necessary
+            my $tag = sprintf("0x%.4x", $type);
+            unless ($$tagTablePtr{$tag}) {
+                next unless $unknown or $verbose;
+                my %tagInfo = (
+                    Name        => "SamsungTrailer_$tag",
+                    Description => "Samsung Trailer $tag",
+                    Unknown     => 1,
+                    Binary      => 1,
+                );
+                AddTagToTable($tagTablePtr, $tag, \%tagInfo);
+            }
+            unless ($$tagTablePtr{"$tag-name"}) {
+                my %tagInfo2 = (
+                    Name        => "SamsungTrailer_${tag}Name",
+                    Description => "Samsung Trailer $tag Name",
+                    Unknown     => 1,
+                );
+                AddTagToTable($tagTablePtr, "$tag-name", \%tagInfo2);
+            }
+            last unless $raf->Seek($dirPos-$noff, 0) and $raf->Read($buf2, $size) == $size;
+            # (could validate the first 4 bytes of the block because they
+            # are the same as the first 4 bytes of the directory entry)
+            $len = Get32u(\$buf2, 4);
+            last if $len + 8 > $size;
+            # extract tag name and value
+            $et->HandleTag($tagTablePtr, "$tag-name", undef,
+                DataPt  => \$buf2,
+                DataPos => $dirPos - $noff,
+                Start   => 8,
+                Size    => $len,
+            );
+            $et->HandleTag($tagTablePtr, $tag, undef,
+                DataPt  => \$buf2,
+                DataPos => $dirPos - $noff,
+                Start   => 8 + $len,
+                Size    => $size - (8 + $len),
+            );
+        }
+        if ($outfile) {
+            last unless $raf->Seek($dataPos, 0) and $raf->Read($buff, $dirLen) == $dirLen;
+            # adjust the absolute offset in the QDIO block if necessary
+            if ($offsetPos and $audioNOff) {
+                # initialize the audio file start/end position in the QDIO block
+                my $newPos = Tell($outfile) + $dirPos - $audioNOff - $dataPos;
+                Set32u($newPos, \$buff, length($buff) - $offsetPos);
+                Set32u($newPos + $audioSize, \$buff, length($buff) - $offsetPos + 4);
+                # add a fixup so the calling routine can apply further shifts if necessary
+                require Image::ExifTool::Fixup;
+                my $fixup = $$dirInfo{Fixup};
+                $fixup or $fixup = $$dirInfo{Fixup} = new Image::ExifTool::Fixup;
+                $fixup->AddFixup(length($buff) - $offsetPos);
+                $fixup->AddFixup(length($buff) - $offsetPos + 4);
+            }
+            $et->VPrint(0, "Writing Samsung trailer ($dirLen bytes)\n") if $verbose;
+            Write($$dirInfo{OutFile}, $buff) or return -1;
+            return 1;
+        }
+        return 1;
+    }
+    $et->Warn('Error processing Samsung trailer',1);
+    return 0;
 }
 
@@ -609,10 +1420,10 @@
 sub WriteSTMN($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     # create a Fixup for the PreviewImage
     $$dirInfo{Fixup} = new Image::ExifTool::Fixup;
-    my $val = Image::ExifTool::WriteBinaryData($exifTool, $dirInfo, $tagTablePtr);
+    my $val = Image::ExifTool::WriteBinaryData($et, $dirInfo, $tagTablePtr);
     # force PreviewImage into the trailer even if it fits in EXIF segment
-    $$exifTool{PREVIEW_INFO}{IsTrailer} = 1 if $$exifTool{PREVIEW_INFO};
+    $$et{PREVIEW_INFO}{IsTrailer} = 1 if $$et{PREVIEW_INFO};
     return $val;
 }
@@ -637,12 +1448,22 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, 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.cybercom.net/~dcoffin/dcraw/>
+
+=back
+
 =head1 ACKNOWLEDGEMENTS
 
-Thanks to Tae-Sun Park for decoding a number of tags.
+Thanks to Tae-Sun Park for decoding a number of tags, Pascal de Bruijn for
+the PictureWizard values, and everyone else who helped by discovering new
+Samsung information.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sanyo.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sanyo.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sanyo.pm	(revision 34921)
@@ -15,5 +15,5 @@
 use Image::ExifTool::Exif;
 
-$VERSION = '1.14';
+$VERSION = '1.16';
 
 my %offOn = (
@@ -34,4 +34,5 @@
     0x0100 => {
         Name => 'SanyoThumbnail',
+        Groups => { 2 => 'Preview' },
         Writable => 'undef',
         WriteCheck => '$self->CheckImage(\$val)',
@@ -351,29 +352,34 @@
         },
     },
-    0xfd => {
-        Name => 'ThumbnailLength',
+    0xf1 => {
+        Name => 'Thumbnail',
         Condition => '$$self{SanyoSledder0xd1}',
-        Format => 'int32u',
-    },
-    0xfe => {
-        Name => 'ThumbnailLength',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sanyo::Thumbnail',
+            Base => '$start',
+        },
+    },
+    0xf2 => {
+        Name => 'Thumbnail',
         Condition => '$$self{SanyoSledder0xd2}',
-        Format => 'int32u',
-    },
-    0x101 => {
-        Name => 'ThumbnailOffset',
-        Condition => '$$self{SanyoSledder0xd1}',
-        IsOffset => 1,
-        Format => 'int32u',
-        RawConv => '$val + 0xf1',
-    },
-    0x102 => {
-        Name => 'ThumbnailOffset',
-        Condition => '$$self{SanyoSledder0xd2}',
-        IsOffset => 1,
-        Format => 'int32u',
-        RawConv => '$val + 0xf2',
-    },
-);
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sanyo::Thumbnail',
+            Base => '$start',
+        },
+    },
+);
+
+# thumbnail image information found in MP4 videos (similar in Olympus,Samsung,Sanyo)
+%Image::ExifTool::Sanyo::Thumbnail = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FIRST_ENTRY => 0,
+    FORMAT => 'int32u',
+    1 => 'ThumbnailWidth',
+    2 => 'ThumbnailHeight',
+    3 => 'ThumbnailLength',
+    4 => { Name => 'ThumbnailOffset', IsOffset => 1 },
+);
+
 
 #------------------------------------------------------------------------------
@@ -414,5 +420,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Scalado.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Scalado.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Scalado.pm	(revision 34921)
@@ -0,0 +1,141 @@
+#------------------------------------------------------------------------------
+# File:         Scalado.pm
+#
+# Description:  Read APP4 SCALADO metadata
+#
+# Revisions:    2013-09-13 - P. Harvey Created
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Scalado;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+use Image::ExifTool::PLIST;
+
+$VERSION = '1.01';
+
+sub ProcessScalado($$$);
+
+# JPEG APP4 SCALADO tags
+%Image::ExifTool::Scalado::Main = (
+    GROUPS => { 0 => 'APP4', 1 => 'Scalado', 2 => 'Image' },
+    PROCESS_PROC => \&ProcessScalado,
+    TAG_PREFIX => 'Scalado',
+    FORMAT => 'int32s',
+    NOTES => q{
+        Tags extracted from the JPEG APP4 "SCALADO" segment found in images from
+        HTC, LG and Samsung phones.  (Presumably written by Scalado mobile software,
+        L<http://www.scalado.com/>.)
+    },
+    SPMO => {
+        Name => 'DataLength',
+        Unknown => 1,
+    },
+    WDTH => {
+        Name => 'PreviewImageWidth',
+        ValueConv => '$val ? abs($val) : undef',
+    },
+    HGHT => {
+        Name => 'PreviewImageHeight',
+        ValueConv => '$val ? abs($val) : undef',
+    },
+    QUAL => {
+        Name => 'PreviewQuality',
+        ValueConv => '$val ? abs($val) : undef',
+    },
+    # tags not yet decoded with observed values:
+    # CHKH: 0, various negative values
+    # CHKL: various negative values
+    # CLEN: -1024
+    # CSPC: -2232593
+    # DATA: (+ve data length)
+    # HDEC: 0
+    # MAIN: 0, 60
+    # META: 24
+    # SCI0: (+ve data length) often 36
+    # SCI1: (+ve data length) 36
+    # SCX0: (+ve data length)
+    # SCX1: (+ve data length) often 84
+    # WDEC: 0
+    # VERS: -131328
+);
+
+#------------------------------------------------------------------------------
+# Extract information from the JPEG APP4 SCALADO segment
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub ProcessScalado($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $pos = 0;
+    my $end = length $$dataPt;
+    my $unknown = $et->Options('Unknown');
+
+    $et->VerboseDir('APP4 SCALADO', undef, $end);
+    SetByteOrder('MM');
+
+    for (;;) {
+        last if $pos + 12 > $end;
+        my $tag = substr($$dataPt, $pos, 4);
+        my $ver = Get32u($dataPt, $pos + 4); # (looks like a version for some tags)
+        if (not $$tagTablePtr{$tag} and $unknown) {
+            my $name = $tag;
+            $name =~ tr/-A-Za-z0-9_//dc;
+            last unless length $name;   # stop if tag is garbage
+            AddTagToTable($tagTablePtr, $tag, {
+                Name => "Scalado_$name",
+                Description => "Scalado $name",
+                Unknown => 1,
+            });
+        }
+        $et->HandleTag($tagTablePtr, $tag, undef,
+            DataPt  => $dataPt,
+            Start   => $pos + 8,
+            Size    => 4,
+            Extra   => ", ver $ver",
+        );
+        if ($tag eq 'SPMO') {
+            my $val = Get32u($dataPt, $pos + 8) ;
+            if ($ver < 5) { # (I don't have samples for version 3 or 4, so I'm not sure about these)
+                $end -= $val;     # SPMO gives trailer data length
+            } else {
+                $end = $val + 12; # SPMO gives length of Scalado directory (excepting this entry)
+            }
+        }
+        $pos += 12;
+    }
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Scalado - Read APP4 SCALADO metadata
+
+=head1 SYNOPSIS
+
+This module is loaded automatically by Image::ExifTool when required.
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read
+metadata from the JPEG APP4 SCALADO segment.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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/Scalado Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shift.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shift.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shift.pl	(revision 34921)
@@ -5,4 +5,5 @@
 #
 # Revisions:    10/28/2005 - P. Harvey Created
+#               03/13/2019 - PH Added single-argument form of ShiftTime()
 #------------------------------------------------------------------------------
 
@@ -11,21 +12,20 @@
 use strict;
 
-sub ShiftTime($$$;$);
+sub ShiftTime($;$$$);
 
 #------------------------------------------------------------------------------
 # apply shift to value in new value hash
-# Inputs: 0) shift type, 1) shift string, 2) raw date/time value, 3) new value hash ref
+# Inputs: 0) ExifTool ref, 1) shift type, 2) shift string, 3) raw date/time value,
+#         4) new value hash ref
 # Returns: error string or undef on success and updates value in new value hash
-sub ApplyShift($$$;$)
+sub ApplyShift($$$$;$)
 {
-    my ($func, $shift, $val, $nvHash) = @_;
+    my ($self, $func, $shift, $val, $nvHash) = @_;
 
     # get shift direction from first character in shift string
-    $shift =~ s/^(\+|-)// or return 'Bad shift string (no sign)';
-    my $pre = $1;
+    my $pre = ($shift =~ s/^(\+|-)//) ? $1 : '+';
     my $dir = ($pre eq '+') ? 1 : -1;
     my $tagInfo = $$nvHash{TagInfo};
     my $tag = $$tagInfo{Name};
-    my $self = $$nvHash{Self};    # (used in eval)
     my $shiftOffset;
     if ($$nvHash{ShiftOffset}) {
@@ -266,13 +266,34 @@
 
 #------------------------------------------------------------------------------
+# Shift an integer or floating-point number
+# Inputs: 0) date/time string, 1) shift string, 2) shift direction (+1 or -1)
+#         3) (unused)
+# Returns: undef and updates input value
+sub ShiftNumber($$$;$)
+{
+    my ($val, $shift, $dir) = @_;
+    $_[0] = $val + $shift * $dir;   # return shifted value
+    return undef;                   # success!
+}
+
+#------------------------------------------------------------------------------
 # Shift date/time string
-# Inputs: 0) date/time string, 1) shift string, 2) shift direction (+1 or -1)
+# 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)
@@ -280,4 +301,5 @@
     SplitTime($val, \@time) or return "Invalid time string ($val)";
     if (defined $time[0]) {
+        return "Can't shift from year 0000" if $time[0] eq '0000';
         $mode = defined $time[3] ? 'DateTime' : 'Date';
     } elsif (defined $time[3]) {
@@ -406,5 +428,5 @@
 # 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];
@@ -435,11 +457,13 @@
         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;
-    }
-    $err and return "Error packing shifted time ($val)";
-    $_[0] = $val;   # return shifted value
-    return undef;   # success!
+        pos($val) = $pos + length($newNum) - $len;
+    }
+    if (@_ == 1) {
+        $_ = $val;      # set $_ to the returned value
+    } else {
+        $_[0] = $val;   # return shifted value
+    }
+    return undef;       # success!
 }
 
@@ -458,9 +482,44 @@
 values.
 
-=head1 DETAILS
-
-Time shifts are applied to standard EXIF-formatted date/time values (ie.
+=head1 METHODS
+
+=head2 ShiftTime
+
+Shift date/time value
+
+    use Image::ExifTool;
+    $err = Image::ExifTool::ShiftTime($dateTime, $shift);
+
+=over 4
+
+=item Inputs:
+
+0) Date/time string in EXIF format (eg. C<2016:01:30 11:45:00>).
+
+1) Shift string (see below) with optional leading sign for shift direction.
+
+2) [optional] Direction of shift (-1 or +1), or 0 or undef to use the sign
+from the shift string.
+
+3) [optional] Reference to time-shift hash -- filled in by first call to
+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
+by the specified amount.
+
+=back
+
+=head1 SHIFT STRING
+
+Time shifts are applied to standard EXIF-formatted date/time values (eg.
 C<2005:03:14 18:55:00>).  Date-only and time-only values may also be
-shifted, and an optional timezone (ie. C<-05:00>) is also supported.  Here
+shifted, and an optional timezone (eg. C<-05:00>) is also supported.  Here
 are some general rules and examples to explain how shift strings are
 interpreted:
@@ -490,5 +549,5 @@
 value.  For example:
 
-    '7'         - shift by 1 hour if applied to a time or date/time
+    '1'         - shift by 1 hour if applied to a time or date/time
                   value, or by one day if applied to a date value
     '2:0'       - shift 2 hours (time, date/time), or 2 months (date)
@@ -515,5 +574,5 @@
     '1::'       - shift by 1 hour (time, date/time) or 1 year (date)
     '26:: 0'    - shift date by 26 years
-    '+:30       - shift timezone by 30 minutes
+    '+:30'      - shift timezone by 30 minutes
 
 Below are some specific examples applied to real date and/or time values
@@ -524,4 +583,5 @@
     '20:30:00'             '5'       +   '01:30:00'
     '2005:01:27'           '5'       +   '2005:02:01'
+    '2005:01:27 20:30:00'  '5'       +   '2005:01:28 01:30:00'
     '11:54:00'             '2.5 0'   -   '23:54:00'
     '2005:11:02'           '2.5 0'   -   '2005:10:31'
@@ -533,5 +593,5 @@
     '1970:01:01'           '35::'    +   '2005:01:01'
     '2005:01:01'           '400'     +   '2006:02:05'
-    '10:00:00.00'          '::1.33'  +   '09:59:58.67'
+    '10:00:00.00'          '::1.33'  -   '09:59:58.67'
 
 =head1 NOTES
@@ -550,8 +610,8 @@
 applied...
 
-The ability to shift dates by Y years, M months, etc, is somewhat
-contradictory to the goal of maintaining a constant shift for all time
-values when applying a batch shift.  This is because shifting by 1 month can
-be equivalent to anything from 28 to 31 days, and 1 year can be 365 or 366
+The ability to shift dates by Y years, M months, etc, conflicts with the
+design goal of maintaining a constant shift for all time values when
+applying a batch shift.  This is because shifting by 1 month can be
+equivalent to anything from 28 to 31 days, and 1 year can be 365 or 366
 days, depending on the starting date.
 
@@ -566,10 +626,10 @@
 =head1 BUGS
 
-This feature uses the standard time library functions, which typically are
-limited to dates in the range 1970 to 2038.
+Due to the use of the standard time library functions, dates are typically
+limited to the range 1970 to 2038 on 32-bit systems.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shortcuts.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shortcuts.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Shortcuts.pm	(revision 34921)
@@ -4,9 +4,13 @@
 # Description:  ExifTool shortcut tags
 #
-# Revisions:    02/07/2004 - P. Harvey Moved out of Exif.pm
-#               09/15/2004 - P. Harvey Added D70Boring from Greg Troxel
-#               01/11/2005 - P. Harvey Added Canon20D from Christian Koller
-#               03/03/2005 - P. Harvey Added user defined shortcuts
-#               03/26/2005 - P. Harvey Added Nikon from Tom Christiansen
+# Revisions:    02/07/2004 - PH Moved out of Exif.pm
+#               09/15/2004 - PH Added D70Boring from Greg Troxel
+#               01/11/2005 - PH Added Canon20D from Christian Koller
+#               03/03/2005 - PH Added user defined shortcuts
+#               03/26/2005 - PH Added Nikon from Tom Christiansen
+#               02/28/2007 - PH Removed model-dependent shortcuts
+#                            --> this is what UserDefined::Shortcuts is for
+#               02/25/2009 - PH Added Unsafe
+#               07/03/2010 - PH Added CommonIFD0
 #------------------------------------------------------------------------------
 
@@ -16,7 +20,8 @@
 use vars qw($VERSION);
 
-$VERSION = '1.41';
+$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)
 %Image::ExifTool::Shortcuts::Main = (
     # this shortcut allows the three common date/time tags to be shifted at once
@@ -109,10 +114,14 @@
     MakerNotes => [
         'MakerNotes',   # (for RIFF MakerNotes)
+        'MakerNoteApple',
         'MakerNoteCanon',
         'MakerNoteCasio',
         'MakerNoteCasio2',
+        'MakerNoteDJI',
+        'MakerNoteFLIR',
         'MakerNoteFujiFilm',
         'MakerNoteGE',
         'MakerNoteGE2',
+        'MakerNoteHasselblad',
         'MakerNoteHP',
         'MakerNoteHP2',
@@ -133,6 +142,9 @@
         'MakerNoteKodak8a',
         'MakerNoteKodak8b',
+        'MakerNoteKodak8c',
         'MakerNoteKodak9',
         'MakerNoteKodak10',
+        'MakerNoteKodak11',
+        'MakerNoteKodak12',
         'MakerNoteKodakUnknown',
         'MakerNoteKyocera',
@@ -140,7 +152,9 @@
         'MakerNoteMinolta2',
         'MakerNoteMinolta3',
+        'MakerNoteMotorola',
         'MakerNoteNikon',
         'MakerNoteNikon2',
         'MakerNoteNikon3',
+        'MakerNoteNintendo',
         'MakerNoteOlympus',
         'MakerNoteOlympus2',
@@ -151,6 +165,11 @@
         'MakerNoteLeica5',
         'MakerNoteLeica6',
+        'MakerNoteLeica7',
+        'MakerNoteLeica8',
+        'MakerNoteLeica9',
+        'MakerNoteLeica10',
         'MakerNotePanasonic',
         'MakerNotePanasonic2',
+        'MakerNotePanasonic3',
         'MakerNotePentax',
         'MakerNotePentax2',
@@ -158,7 +177,12 @@
         'MakerNotePentax4',
         'MakerNotePentax5',
+        'MakerNotePentax6',
         'MakerNotePhaseOne',
         'MakerNoteReconyx',
+        'MakerNoteReconyx2',
+        'MakerNoteReconyx3',
         'MakerNoteRicoh',
+        'MakerNoteRicoh2',
+        'MakerNoteRicohPentax',
         'MakerNoteRicohText',
         'MakerNoteSamsung1a',
@@ -173,7 +197,9 @@
         'MakerNoteSony3',
         'MakerNoteSony4',
+        'MakerNoteSony5',
         'MakerNoteSonyEricsson',
         'MakerNoteSonySRF',
         'MakerNoteUnknownText',
+        'MakerNoteUnknownBinary',
         'MakerNoteUnknown',
     ],
@@ -191,4 +217,12 @@
         'InteropIFD:RelatedImageHeight',
     ],
+    # standard tags used to define the color space of an image
+    # (useful to preserve color space when deleting all meta information)
+    ColorSpaceTags => [
+        'ExifIFD:ColorSpace',
+        'ExifIFD:Gamma',
+        'InteropIFD:InteropIndex',
+        'ICC_Profile',
+    ],
     # common metadata tags found in IFD0 of TIFF images
     CommonIFD0 => [
@@ -202,5 +236,5 @@
         'IFD0:Copyright',
         # other TIFF tags
-        'IFD0:Rating', 
+        'IFD0:Rating',
         'IFD0:RatingPercent',
         'IFD0:DNGLensInfo',
@@ -212,4 +246,32 @@
         'IFD0:XPKeywords',
         'IFD0:XPSubject',
+    ],
+    # large binary data tags which won't be loaded if excluded when extracting
+    LargeTags => [
+        'CanonVRD',
+        'DLOData',
+        'EXIF',
+        'ICC_Profile',
+        'IDCPreviewImage',
+        'ImageData',
+        'IPTC',
+        'JpgFromRaw',
+        'OriginalRawImage',
+        'OtherImage',
+        'PreviewImage',
+        'ThumbnailImage',
+        'TIFFPreview',
+        'XML',
+        'XMP',
+        'ZoomedPreviewImage',
+    ],
+    'ls-l' => [
+        'FilePermissions',
+        'FileHardLinks',
+        'FileUserID',
+        'FileGroupID',
+        'FileSize#',
+        'FileModifyDate',
+        'FileName',
     ],
 );
@@ -274,7 +336,11 @@
 FocalLengthIn35mmFormat.
 
+The target tag names may contain an optional group name prefix.  A group
+name applied to the shortcut will be ignored for any target tag with a group
+name prefix.
+
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sigma.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sigma.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sigma.pm	(revision 34921)
@@ -8,5 +8,8 @@
 #               24/06/2010 - PH decode some SD15 tags
 #
-# Reference:    http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html
+# References:   1) http://www.x3f.info/technotes/FileDocs/MakerNoteDoc.html
+#               IB) Iliah Borg private communication (LibRaw)
+#               NJ) Niels Kristian Bech Jensen
+#               JR) Jos Roost
 #------------------------------------------------------------------------------
 
@@ -14,8 +17,223 @@
 
 use strict;
-use vars qw($VERSION);
+use vars qw($VERSION %sigmaLensTypes);
 use Image::ExifTool::Exif;
 
-$VERSION = '1.09';
+$VERSION = '1.31';
+
+# sigma LensType lookup (ref IB)
+%sigmaLensTypes = (
+    Notes => q{
+        Sigma LensType values are hexadecimal numbers stored as a string (without
+        the leading "0x").  Decimal values have been added to differentiate lenses
+        which would otherwise have the same LensType, and are used by the Composite
+        LensID tag when attempting to identify the specific lens model.
+    },
+    # 0x0 => 'Sigma 50mm F2.8 EX Macro', (0x0 used for other lenses too)
+    # 0x8 - 18-125mm LENSARANGE@18mm=22-4
+    0x10, 'Sigma 50mm F2.8 EX DG MACRO',
+    # (0x10 = 16)
+    16.1 => 'Sigma 70mm F2.8 EX DG Macro',
+    16.2 => 'Sigma 105mm F2.8 EX DG Macro',
+    0x16 => 'Sigma 18-50mm F3.5-5.6 DC', #PH
+    0x103 => 'Sigma 180mm F3.5 EX IF HSM APO Macro',
+    0x104 => 'Sigma 150mm F2.8 EX DG HSM APO Macro',
+    0x105 => 'Sigma 180mm F3.5 EX DG HSM APO Macro',
+    0x106 => 'Sigma 150mm F2.8 EX DG OS HSM APO Macro',
+    0x107 => 'Sigma 180mm F2.8 EX DG OS HSM APO Macro',
+    # (0x129 = 297)
+    0x129 => 'Sigma Lens (0x129)', #PH
+    297.1 => 'Sigma 14mm F2.8 EX Aspherical', #PH
+    297.2 => 'Sigma 30mm F1.4',
+    # (0x131 = 305)
+    0x131 => 'Sigma Lens (0x131)',
+    305.1 => 'Sigma 17-70mm F2.8-4.5 DC Macro', #PH
+    305.2 => 'Sigma 70-200mm F2.8 APO EX HSM',
+    305.3 => 'Sigma 120-300mm F2.8 APO EX IF HSM',
+    0x134 => 'Sigma 100-300mm F4 EX DG HSM APO',
+    0x135 => 'Sigma 120-300mm F2.8 EX DG HSM APO',
+    0x136 => 'Sigma 120-300mm F2.8 EX DG OS HSM APO',
+    0x137 => 'Sigma 120-300mm F2.8 DG OS HSM | S',
+    0x143 => 'Sigma 600mm F8 Mirror',
+    # (0x145 = 325)
+    0x145 => 'Sigma Lens (0x145)', #PH
+    325.1 => 'Sigma 15-30mm F3.5-4.5 EX DG Aspherical', #PH
+    325.2 => 'Sigma 18-50mm F2.8 EX DG', #PH (NC)
+    325.3 => 'Sigma 20-40mm F2.8 EX DG', #PH
+    0x150 => 'Sigma 30mm F1.4 DC HSM',
+    # (0x152 = 338)
+    0x152 => 'Sigma Lens (0x152)',
+    338.1 => 'Sigma APO 800mm F5.6 EX DG HSM',
+    338.2 => 'Sigma 12-24mm F4.5-5.6 EX DG ASP HSM',
+    338.3 => 'Sigma 10-20mm F4-5.6 EX DC HSM',
+    0x165 => 'Sigma 70-200mm F2.8 EX', # ...but what specific model?:
+    # 70-200mm F2.8 EX APO - Original version, minimum focus distance 1.8m (1999)
+    # 70-200mm F2.8 EX DG - Adds 'digitally optimized' lens coatings to reduce flare (2005)
+    # 70-200mm F2.8 EX DG Macro (HSM) - Minimum focus distance reduced to 1m (2006)
+    # 70-200mm F2.8 EX DG Macro HSM II - Improved optical performance (2007)
+    0x169 => 'Sigma 18-50mm F2.8 EX DC', #PH (NC)
+    0x183 => 'Sigma 500mm F4.5 EX HSM APO',
+    0x184 => 'Sigma 500mm F4.5 EX DG HSM APO',
+    0x185 => 'Sigma 500mm F4 DG OS HSM | S', #JR (NC; based on product number) (016)
+    0x194 => 'Sigma 300mm F2.8 EX HSM APO',
+    0x195 => 'Sigma 300mm F2.8 EX DG HSM APO',
+    0x200 => 'Sigma 12-24mm F4.5-5.6 EX DG ASP HSM',
+    0x201 => 'Sigma 10-20mm F4-5.6 EX DC HSM',
+    0x202 => 'Sigma 10-20mm F3.5 EX DC HSM',
+    0x203 => 'Sigma 8-16mm F4.5-5.6 DC HSM',
+    0x204 => 'Sigma 12-24mm F4.5-5.6 DG HSM II',
+    0x205 => 'Sigma 12-24mm F4 DG HSM | A', #JR (NC; based on product number) (016)
+    0x210 => 'Sigma 18-35mm F1.8 DC HSM | A',
+    0x240 => 'Sigma 135mm F1.8 DG HSM | A', #JR (NC; based on product number) (017)
+    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)
+    0x310 => 'Sigma 50mm F1.4 EX DG HSM',
+    0x311 => 'Sigma 50mm F1.4 DG HSM | A',
+    0x320 => 'Sigma 85mm F1.4 EX DG HSM',
+    0x321 => 'Sigma 85mm F1.4 DG HSM | A', #JR (NC; based on product number) (016)
+    0x330 => 'Sigma 30mm F2.8 EX DN',
+    0x340 => 'Sigma 35mm F1.4 DG HSM',
+    0x345 => 'Sigma 50mm F2.8 EX Macro',
+    0x346 => 'Sigma 50mm F2.8 EX DG Macro',
+    0x350 => 'Sigma 60mm F2.8 DN | A',
+    0x400 => 'Sigma 19mm F2.8 EX DN',
+    0x401 => 'Sigma 24mm F1.4 DG HSM | A',
+    0x411 => 'Sigma 20mm F1.8 EX DG ASP RF',
+    0x412 => 'Sigma 20mm F1.4 DG HSM | A',
+    0x432 => 'Sigma 24mm F1.8 EX DG ASP Macro',
+    0x440 => 'Sigma 28mm F1.8 EX DG ASP Macro',
+    0x450 => 'Sigma 14mm F1.8 DH HSM | A', #JR (NC; based on product number) (017)
+    0x461 => 'Sigma 14mm F2.8 EX ASP HSM',
+    0x475 => 'Sigma 15mm F2.8 EX Diagonal FishEye',
+    0x476 => 'Sigma 15mm F2.8 EX DG Diagonal Fisheye',
+    0x477 => 'Sigma 10mm F2.8 EX DC HSM Fisheye',
+    0x483 => 'Sigma 8mm F4 EX Circular Fisheye',
+    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',
+    0x509 => 'Sigma 70-300mm F4-5.6 DG Macro',
+    0x510 => 'Sigma 17-35 F2.8-4 EX DG ASP',
+    0x512 => 'Sigma 15-30mm F3.5-4.5 EX DG ASP DF',
+    0x513 => 'Sigma 20-40mm F2.8 EX DG',
+    0x519 => 'Sigma 17-35 F2.8-4 EX ASP HSM',
+    0x520 => 'Sigma 100-300mm F4.5-6.7 DL',
+    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',
+    0x566 => 'Sigma 70-200mm F2.8 EX IF APO',
+    0x567 => 'Sigma 70-200mm F2.8 EX IF HSM APO',
+    0x568 => 'Sigma 70-200mm F2.8 EX DG IF HSM APO',
+    0x569 => 'Sigma 70-200 F2.8 EX DG HSM APO Macro',
+    0x571 => 'Sigma 24-70mm F2.8 IF EX DG HSM',
+    0x572 => 'Sigma 70-300mm F4-5.6 DG OS',
+    0x576 => 'Sigma 24-70mm F2.8 DG OS HSM | A', #JR (NC; based on product number) (017)
+    0x579 => 'Sigma 70-200mm F2.8 EX DG HSM APO Macro', # (also II version)
+    0x580 => 'Sigma 18-50mm F2.8 EX DC',
+    0x581 => 'Sigma 18-50mm F2.8 EX DC Macro', #PH (SD1)
+    0x582 => 'Sigma 18-50mm F2.8 EX DC HSM Macro',
+    0x583 => 'Sigma 17-50mm F2.8 EX DC OS HSM', #PH (also SD1 Kit, is this HSM? - PH)
+    0x588 => 'Sigma 24-35mm F2 DG HSM | A',
+    0x589 => 'Sigma APO 70-200mm F2.8 EX DG OS HSM',
+    0x594 => 'Sigma 300-800mm F5.6 EX HSM IF APO',
+    0x595 => 'Sigma 300-800mm F5.6 EX DG APO HSM',
+    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',
+    0x644 => 'Sigma 28-80mm F3.5-5.6 ASP HF Macro',
+    0x659 => 'Sigma 28-80mm F3.5-5.6 Mini Zoom Macro II ASP',
+    0x661 => 'Sigma 28-105mm F2.8-4 IF ASP',
+    0x663 => 'Sigma 28-105mm F3.8-5.6 IF UC-III ASP',
+    0x664 => 'Sigma 28-105mm F2.8-4 IF DG ASP',
+    0x667 => 'Sigma 24-135mm F2.8-4.5 IF ASP',
+    0x668 => 'Sigma 17-70mm F2.8-4 DC Macro OS HSM',
+    0x669 => 'Sigma 17-70mm F2.8-4.5 DC HSM Macro',
+    0x684 => 'Sigma 55-200mm F4-5.6 DC',
+    0x686 => 'Sigma 50-200mm F4-5.6 DC OS HSM',
+    0x689 => 'Sigma 17-70mm F2.8-4.5 DC Macro',
+    0x690 => 'Sigma 50-150mm F2.8 EX DC HSM APO',
+    0x691 => 'Sigma 50-150mm F2.8 EX DC APO HSM II',
+    0x692 => 'Sigma APO 50-150mm F2.8 EX DC OS HSM',
+    0x693 => 'Sigma 50-100mm F1.8 DC HSM | A', #JR (NC; based on product number) (016)
+    0x709 => 'Sigma 28-135mm F3.8-5.6 IF ASP Macro',
+    0x723 => 'Sigma 135-400mm F4.5-5.6 ASP APO',
+    0x725 => 'Sigma 80-400mm F4.5-5.6 EX OS',
+    0x726 => 'Sigma 80-400mm F4.5-5.6 EX DG OS APO',
+    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',
+    0x736 => 'Sigma 50-500mm F4-6.3 EX DG HSM APO',
+    0x737 => 'Sigma 150-500mm F5-6.3 APO DG OS HSM',
+    0x738 => 'Sigma 50-500mm F4.5-6.3 APO DG OS HSM',
+    0x740 => 'Sigma 150-600mm F5-6.3 DG OS HSM | S',
+    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',
+    0x823 => 'Sigma 1.4X TC EX APO',
+    0x824 => 'Sigma 1.4X Teleconverter EX APO DG',
+    0x853 => 'Sigma 18-125mm F3.8-5.6 DC OS HSM',
+    0x861 => 'Sigma 18-50mm F2.8-4.5 DC OS HSM', #NJ (SD1)
+    0x870 => 'Sigma 2.0X Teleconverter TC-2001', #JR
+    0x875 => 'Sigma 2.0X TC EX APO',
+    0x876 => 'Sigma 2.0X Teleconverter EX APO DG',
+    0x879 => 'Sigma 1.4X Teleconverter TC-1401', #JR
+    0x880 => 'Sigma 18-250mm F3.5-6.3 DC OS HSM',
+    0x882 => 'Sigma 18-200mm F3.5-6.3 II DC OS HSM',
+    0x883 => 'Sigma 18-250mm F3.5-6.3 DC Macro OS HSM',
+    0x884 => 'Sigma 17-70mm F2.8-4 DC OS HSM Macro | C',
+    0x885 => 'Sigma 18-200mm F3.5-6.3 DC OS HSM Macro | C',
+    0x886 => 'Sigma 18-300mm F3.5-6.3 DC OS HSM Macro | C',
+    0x888 => 'Sigma 18-200mm F3.5-6.3 DC OS',
+    0x890 => 'Sigma Mount Converter MC-11', #JR
+    0x929 => 'Sigma 19mm F2.8 DN | A',
+    0x929 => 'Sigma 30mm F2.8 DN | A',
+    0x929 => 'Sigma 60mm F2.8 DN | A',
+    0x1003 => 'Sigma 19mm F2.8', #PH (DP1 Merrill kit)
+    0x1004 => 'Sigma 30mm F2.8', #PH (DP2 Merrill kit)
+    0x1005 => 'Sigma 50mm F2.8 Macro', #PH (DP3 Merrill kit)
+    0x1006 => 'Sigma 19mm F2.8', #NJ (DP1 Quattro kit)
+    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
+);
 
 %Image::ExifTool::Sigma::Main = (
@@ -24,4 +242,10 @@
     WRITABLE => 'string',
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        These tags are written by Sigma/Foveon cameras.  In the early days Sigma was
+        a class leader by releasing their maker note specification to the public,
+        but since then they have deviated from this standard and newer camera models
+        are less than consistent about their metadata formats.
+    },
     0x0002 => 'SerialNumber',
     0x0003 => 'DriveMode',
@@ -73,4 +297,5 @@
             Name => 'Contrast',
             Writable => 'rational64s',
+            Priority => 0,
         },
     ],
@@ -82,7 +307,8 @@
             ValueConvInv => 'IsFloat($val) ? sprintf("Shad:%+.1f",$val) : undef',
         },
-        { #PH
+        { #PH (may be incorrect for the SD1)
             Name => 'Shadow',
             Writable => 'rational64s',
+            Priority => 0,
         },
     ],
@@ -94,7 +320,8 @@
             ValueConvInv => 'IsFloat($val) ? sprintf("High:%+.1f",$val) : undef',
         },
-        { #PH
+        { #PH (may be incorrect for the SD1)
             Name => 'Highlight',
             Writable => 'rational64s',
+            Priority => 0,
         },
     ],
@@ -106,7 +333,8 @@
             ValueConvInv => 'IsFloat($val) ? sprintf("Satu:%+.1f",$val) : undef',
         },
-        { #PH
+        { #PH (may be incorrect for the SD1)
             Name => 'Saturation',
             Writable => 'rational64s',
+            Priority => 0,
         },
     ],
@@ -118,7 +346,8 @@
             ValueConvInv => 'IsFloat($val) ? sprintf("Shar:%+.1f",$val) : undef',
         },
-        { #PH
+        { #PH (may be incorrect for the SD1)
             Name => 'Sharpness',
             Writable => 'rational64s',
+            Priority => 0,
         },
     ],
@@ -155,5 +384,8 @@
     },
     0x0017 => 'Firmware',
-    0x0018 => 'Software',
+    0x0018 => {
+        Name => 'Software',
+        Priority => 0,
+    },
     0x0019 => 'AutoBracket',
     0x001a => [ #PH
@@ -161,14 +393,22 @@
             Name => 'PreviewImageStart',
             Condition => '$format eq "int32u"',
+            Notes => q{
+                Sigma Photo Pro writes ChrominanceNoiseReduction here, but various
+                models use this for PreviewImageStart
+            },
             IsOffset => 1,
             OffsetPair => 0x001b,
             DataTag => 'PreviewImage',
             Writable => 'int32u',
+            WriteGroup => 'MakerNotes',
             Protected => 2,
         },{ # (written by Sigma Photo Pro)
             Name => 'ChrominanceNoiseReduction',
+            Condition => '$format eq "string"',
             ValueConv => '$val =~ s/Chro:\s*//, $val',
             ValueConvInv => 'IsFloat($val) ? sprintf("Chro:%+.1f",$val) : undef',
         },
+        # the SD1 writes something else here (rational64s, value 0/10)
+        # (but we can't test by model because Sigma Photo Pro writes this too)
     ],
     0x001b => [ #PH
@@ -176,40 +416,155 @@
             Name => 'PreviewImageLength',
             Condition => '$format eq "int32u"',
+            Notes => q{
+                Sigma Photo Pro writes LuminanceNoiseReduction here, but various models use
+                this for PreviewImageLength
+            },
             OffsetPair => 0x001a,
             DataTag => 'PreviewImage',
             Writable => 'int32u',
+            WriteGroup => 'MakerNotes',
             Protected => 2,
         },{ # (written by Sigma Photo Pro)
             Name => 'LuminanceNoiseReduction',
+            Condition => '$format eq "string"',
             ValueConv => '$val =~ s/Luma:\s*//, $val',
             ValueConvInv => 'IsFloat($val) ? sprintf("Luma:%+.1f",$val) : undef',
         },
-    ],
-    0x001c => { #PH
+        # the SD1 writes something else here (rational64s, value 0/10)
+    ],
+    0x001c => [ #PH
+        {
+            Name => 'PreviewImageSize',
+            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"',
+            IsOffset => 1,
+            OffsetPair => 0x001d,
+            DataTag => 'PreviewImage',
+            Writable => 'int32u',
+            WriteGroup => 'MakerNotes',
+            Protected => 2,
+        },
+    ],
+    0x001d => [ #PH
+        {
+            Name => 'MakerNoteVersion',
+            Condition => '$$self{MakerNoteSigmaVer} < 3',
+            Notes => q{
+                PreviewImageLength for the SD1 and Merrill/Quattro models, and
+                MakerNoteVersion for others
+            },
+            Writable => 'undef',
+        },{
+            Name => 'PreviewImageLength',
+            Condition => '$format eq "int32u"',
+            OffsetPair => 0x001c,
+            DataTag => 'PreviewImage',
+            Writable => 'int32u',
+            WriteGroup => 'MakerNotes',
+            Protected => 2,
+        },
+    ],
+    # 0x001e - int16u: 0, 4, 13 - flash mode for other models?
+    0x001e => { #PH
         Name => 'PreviewImageSize',
+        Condition => '$$self{MakerNoteSigmaVer} >= 3',
+        Notes => 'only valid for some models',
         Writable => 'int16u',
         Count => 2,
-    },
-    0x001d => { #PH
-        Name => 'MakerNoteVersion',
-        Writable => 'undef',
-    },
-    # 0x001e - int16u: 0, 4, 13 - flash mode?
-    0x001f => { #PH (NC)
-        Name => 'AFPoint',
-        # values: "", "Center", "Center,Center", "Right,Right"
-    },
-    # 0x0020-21 - string: " "
+        PrintConv => '$val =~ tr/ /x/; $val',
+        PrintConvInv => '$val =~ tr/x/ /; $val',
+    },
+    0x001f => [ #PH
+        {
+            Name => 'AFPoint', # (NC -- invalid for SD9,SD14?)
+            Condition => '$$self{MakerNoteSigmaVer} < 3',
+            Notes => q{
+                MakerNoteVersion for the SD1 and Merrill/Quattro models, and AFPoint for
+                others
+            },
+            # values: "", "Center", "Center,Center", "Right,Right"
+        },{
+            Name => 'MakerNoteVersion',
+            Writable => 'undef',
+        },
+    ],
+    # 0x0020 - string: " " for most models, or int16u: 4 for the DP3 Merrill
+    # 0x0021 - string: " " for most models, or int8u[2]: '3 3' for the DP3 Merrill
     0x0022 => { #PH (NC)
         Name => 'FileFormat',
-        # values: "JPG", "JPG-S" or "X3F"
+        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 => 'Calibration',
+    0x0024 => { # (invalid for SD9,SD14?)
+        Name => 'Calibration',
+        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{MakerNoteSigmaVer} >= 3',
+        Notes => 'some newer models only',
+        # (also Sigma fp)
+    },
+    0x0027 => [{ #PH
+        Name => 'LensType',
+        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{MakerNoteSigmaVer} >= 3',
+        Notes => 'some newer models only',
+        Writable => 'rational64u',
+        Count => 2,
+        PrintConv => '$val=~s/ / to /; $val',
+        PrintConvInv => '$val=~s/to //; $val',
+    },
+    0x002b => { #PH
+        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{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"',
+        Notes => 'not valid for some models',
         Writable => 'int32u',
+        # this tag written by Sigma Photo Pro even for cameras that write 'n/a' here
         PrintConv => {
             0 => 'n/a',
@@ -221,4 +576,5 @@
             6 => 'Portrait',
             7 => 'Landscape',
+            8 => 'FOV Classic Blue',
         },
     },
@@ -226,23 +582,39 @@
     # 0x002e - rational64s: (the negative of FlashExposureComp, but why?)
     # 0x002f - int32u: 0, 1
-    0x0030 => { #PH
-        Name => 'LensApertureRange',
-        Notes => 'changes with focal length. MaxAperture for some models',
-    },
+    0x0030 => [ #PH
+        {
+            Name => 'LensApertureRange',
+            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
+                models report the maximum aperture here
+            },
+        },{
+            Name => 'Calibration',
+        },
+    ],
     0x0031 => { #PH
         Name => 'FNumber',
+        Condition => '$$self{MakerNoteSigmaVer} < 3',
+        Notes => 'models other than the SD1 and Merrill/Quattro models',
         Writable => 'rational64u',
         PrintConv => 'sprintf("%.1f",$val)',
         PrintConvInv => '$val',
+        Priority => 0,
     },
     0x0032 => { #PH
         Name => 'ExposureTime',
+        Condition => '$$self{MakerNoteSigmaVer} < 3',
+        Notes => 'models other than the SD1 and Merrill/Quattro models',
         Writable => 'rational64u',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => '$val',
+        Priority => 0,
     },
     0x0033 => { #PH
         Name => 'ExposureTime2',
-        Writable => 'string',
+        Condition => '$$self{Model} !~ / (SD1|SD9|SD15|Merrill|Quattro|fp)$/',
+        Notes => 'models other than the SD1, SD9, SD15 and Merrill/Quattro models',
         ValueConv => '$val * 1e-6',
         ValueConvInv => 'int($val * 1e6 + 0.5)',
@@ -252,4 +624,6 @@
     0x0034 => { #PH
         Name => 'BurstShot',
+        Condition => '$$self{MakerNoteSigmaVer} < 3',
+        Notes => 'models other than the SD1 and Merrill/Quattro models',
         Writable => 'int32u',
     },
@@ -257,4 +631,6 @@
     0x0035 => { #PH
         Name => 'ExposureCompensation',
+        Condition => '$$self{MakerNoteSigmaVer} < 3',
+        Notes => 'models other than the SD1 and Merrill/Quattro models',
         Writable => 'rational64s',
         # add a '+' sign to positive values
@@ -264,6 +640,8 @@
     # 0x0036 - string: "                    "
     # 0x0037-38 - string: ""
-    0x0039 => { #PH
+    0x0039 => { #PH (invalid for SD9, SD14?)
         Name => 'SensorTemperature',
+        Condition => '$$self{MakerNoteSigmaVer} < 3',
+        Notes => 'models other than the SD1 and Merrill/Quattro models',
         # (string format)
         PrintConv => 'IsInt($val) ? "$val C" : $val',
@@ -272,16 +650,172 @@
     0x003a => { #PH
         Name => 'FlashExposureComp',
+        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{MakerNoteSigmaVer} < 3',
+        Notes => 'models other than the SD1 and Merrill/Quattro models',
         Priority => 0,
     },
-    0x003c => 'WhiteBalance', #PH
-    0x003d => { #PH (new for SD15)
+    0x003c => { #PH
+        Name => 'WhiteBalance',
+        Condition => '$$self{MakerNoteSigmaVer} < 3',
+        Notes => 'models other than the SD1 and Merrill/Quattro models',
+        Priority => 0,
+    },
+    0x003d => { #PH (new for SD15 and SD1)
         Name => 'PictureMode',
         Notes => 'same as ColorMode, but "Standard" when ColorMode is Sepia or B&W',
     },
+    0x0048 => { #PH
+        Name => 'LensApertureRange',
+        Condition => '$$self{MakerNoteSigmaVer} >= 3',
+        Notes => 'some newer models only',
+    },
+    0x0049 => { #PH
+        Name => 'FNumber',
+        Condition => '$$self{MakerNoteSigmaVer} >= 3',
+        Notes => 'some newer models only',
+        Writable => 'rational64u',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+        Priority => 0,
+    },
+    0x004a => { #PH
+        Name => 'ExposureTime',
+        Condition => '$$self{MakerNoteSigmaVer} >= 3',
+        Notes => 'some newer models only',
+        Writable => 'rational64u',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => '$val',
+        Priority => 0,
+    },
+    0x004b => [{ #PH
+        Name => 'ExposureTime2',
+        Condition => '$$self{Model} =~ /^SIGMA (SD1( Merrill)?|DP\d Merrill)$/',
+        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 => 'DP Quattro models only',
+        ValueConv => '$val / 1000000',
+        ValueConvInv => '$val * 1000000',
+        PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    }],
+    0x004d => { #PH
+        Name => 'ExposureCompensation',
+        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',
+        PrintConvInv => '$val',
+    },
+    # 0x0054 - string: "F20","F23"
+    0x0055 => { #PH
+        Name => 'SensorTemperature',
+        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{MakerNoteSigmaVer} >= 3',
+        Notes => 'some newer models only',
+        Writable => 'rational64s',
+    },
+    0x0057 => { #PH (how is this different from other Firmware?)
+        Name => 'Firmware2',
+        Condition => '$format eq "string"',
+        Notes => 'some newer models only',
+        Priority => 0,
+    },
+    0x0058 => { #PH
+        Name => 'WhiteBalance',
+        Condition => '$$self{MakerNoteSigmaVer} >= 3',
+        Notes => 'some newer models only',
+        Priority => 0,
+    },
+    0x0059 => { #PH
+        Name => 'DigitalFilter',
+        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 (Quattro models and fp)
+        Name => 'Model',
+        Description => 'Camera Model Name',
+    },
+    # 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
@@ -304,5 +838,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/SigmaRaw.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/SigmaRaw.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/SigmaRaw.pm	(revision 34921)
@@ -15,31 +15,11 @@
 use vars qw($VERSION);
 use Image::ExifTool qw(:DataAccess :Utils);
-
-$VERSION = '1.14';
+use Image::ExifTool::Sigma;
+
+$VERSION = '1.27';
 
 sub ProcessX3FHeader($$$);
 sub ProcessX3FDirectory($$$);
 sub ProcessX3FProperties($$$);
-
-# sigma LensType lookup (ref PH)
-my %sigmaLensTypes = (
-    # 0 => 'Sigma 50mm F2.8 EX Macro', (0 used for other lenses too)
-    # 8 - 18-125mm LENSARANGE@18mm=22-4
-    16 => 'Sigma 18-50mm F3.5-5.6 DC',
-    129 => 'Sigma 14mm F2.8 EX Aspherical',
-    131 => 'Sigma 17-70mm F2.8-4.5 DC Macro',
-    145 => 'Sigma Lens (145)',
-    145.1 => 'Sigma 15-30mm F3.5-4.5 EX DG Aspherical',
-    145.2 => 'Sigma 18-50mm F2.8 EX DG', #(NC)
-    145.3 => 'Sigma 20-40mm F2.8 EX DG',
-    165 => 'Sigma 70-200mm F2.8 EX', # ...but what specific model?:
-    # 70-200mm F2.8 EX APO - Original version, minimum focus distance 1.8m (1999)
-    # 70-200mm F2.8 EX DG - Adds 'digitally optimized' lens coatings to reduce flare (2005)
-    # 70-200mm F2.8 EX DG Macro (HSM) - Minimum focus distance reduced to 1m (2006)
-    # 70-200mm F2.8 EX DG Macro HSM II - Improved optical performance (2007)
-    169 => 'Sigma 18-50mm F2.8 EX DC', #(NC)
-    '100' => 'Sigma 24-70mm f/2.8 DG Macro', # (SD15)
-    8900 => 'Sigma 70-300mm f/4-5.6 DG OS', # (SD15)
-);
 
 # main X3F sections (plus header stuff)
@@ -54,4 +34,7 @@
         SubDirectory => { TagTable => 'Image::ExifTool::SigmaRaw::Header' },
     },
+    Header4 => {
+        SubDirectory => { TagTable => 'Image::ExifTool::SigmaRaw::Header4' },
+    },
     HeaderExt => {
         SubDirectory => { TagTable => 'Image::ExifTool::SigmaRaw::HeaderExt' },
@@ -63,4 +46,5 @@
     IMAG => {
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         Binary => 1,
     },
@@ -69,8 +53,10 @@
             Name => 'PreviewImage',
             Condition => 'not $$self{IsJpgFromRaw}',
+            Groups => { 2 => 'Preview' },
             Binary => 1,
         },
         {
             Name => 'JpgFromRaw',
+            Groups => { 2 => 'Preview' },
             Binary => 1,
         },
@@ -82,4 +68,5 @@
     PROCESS_PROC => \&ProcessX3FHeader,
     FORMAT => 'int32u',
+    NOTES => 'Information extracted from the header of an X3F file.',
     1 => {
         Name => 'FileVersion',
@@ -110,7 +97,25 @@
 );
 
+# X3F version 4 header structure (ref PH)
+%Image::ExifTool::SigmaRaw::Header4 = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    FORMAT => 'int32u',
+    NOTES => 'Header information for version 4.0 or greater X3F.',
+    1 => {
+        Name => 'FileVersion',
+        ValueConv => '($val >> 16) . "." . ($val & 0xffff)',
+    },
+    # 8 - undef[4]: 4 random ASCII characters
+    10 => 'ImageWidth',
+    11 => 'ImageHeight',
+    12 => 'Rotation',
+    # don't know what the rest of the header contains, but none of
+    # these values change in any of my samples...
+);
+
 # extended header tags
 %Image::ExifTool::SigmaRaw::HeaderExt = (
     GROUPS => { 2 => 'Camera' },
+    FORMAT => 'float',
     NOTES => 'Extended header data found in version 2.1 and 2.2 files',
     0 => 'Unused',
@@ -131,4 +136,5 @@
     PROCESS_PROC => \&ProcessX3FProperties,
     GROUPS => { 2 => 'Camera' },
+    PRIORITY => 0,  # (because these aren't writable like the EXIF ones)
     AEMODE => {
         Name => 'MeteringMode',
@@ -221,10 +227,9 @@
     LENSMODEL   => {
         Name => 'LensType',
-        Notes => q{
-            decimal values differentiate lenses which would otherwise have the same
-            LensType, and are used by the Composite LensID tag when attempting to
-            identify the specific lens model
-        },
-        PrintConv => \%sigmaLensTypes,
+        ValueConv => '$val =~ /^[0-9a-f]+$/i ? hex($val) : $val',
+        ValueConvInv => '$val=~s/\.\d+$//; IsInt($val) ? sprintf("%x",$val) : $val', # (truncate decimal part)
+        SeparateTable => 'Sigma LensType',
+        PrintHex => 1,
+        PrintConv => \%Image::ExifTool::Sigma::sigmaLensTypes,
     },
     PMODE => {
@@ -265,9 +270,9 @@
 #------------------------------------------------------------------------------
 # Extract null-terminated unicode string from list of characters
-# Inputs: 0) ExifTool object ref, 1) list ref, 2) position in list
+# Inputs: 0) ExifTool ref, 1) list ref, 2) position in list
 # Returns: Converted string
 sub ExtractUnicodeString($$$)
 {
-    my ($exifTool, $chars, $pos) = @_;
+    my ($et, $chars, $pos) = @_;
     my $i;
     for ($i=$pos; $i<@$chars; ++$i) {
@@ -275,51 +280,34 @@
     }
     my $buff = pack('v*', @$chars[$pos..$i-1]);
-    return $exifTool->Decode($buff, 'UCS2', 'II');
+    return $et->Decode($buff, 'UCS2', 'II');
 }
 
 #------------------------------------------------------------------------------
 # Process an X3F header
-# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
+# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
 # Returns: 1 on success
 sub ProcessX3FHeader($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $hdrLen = $$dirInfo{DirLen};
-    my $verbose = $exifTool->Options('Verbose');
 
     # process the static header structure first
-    $exifTool->ProcessBinaryData($dirInfo, $tagTablePtr);
+    $et->ProcessBinaryData($dirInfo, $tagTablePtr);
 
     # process extended data if available
-    if (length $$dataPt >= 232) {
+    if (length($$dataPt) - $hdrLen >= 160) {
+        my $verbose = $et->Options('Verbose');
         if ($verbose) {
-            $exifTool->VerboseDir('X3F HeaderExt', 32);
-            Image::ExifTool::HexDump($dataPt, undef,
-                MaxLen => $verbose > 3 ? 1024 : 96,
-                Out    => $exifTool->Options('TextOut'),
-                Prefix => $$exifTool{INDENT},
-                Start  => $$dirInfo{DirLen},
-            ) if $verbose > 2;
+            $et->VerboseDir('X3F HeaderExt', 32);
+            $et->VerboseDump($dataPt, Start => $hdrLen);
         }
         $tagTablePtr = GetTagTable('Image::ExifTool::SigmaRaw::HeaderExt');
-        my @vals = unpack("x${hdrLen}C32V32", $$dataPt);
+        my @tags = unpack("x${hdrLen}C32", $$dataPt);
         my $i;
         my $unused = 0;
         for ($i=0; $i<32; ++$i) {
-            $vals[$i] or ++$unused, next;
-            my $val = $vals[$i+32];
-            # convert value 0x40000000 => 2 ** 1, 0x3f800000 => 2 ** 0, 0x3f000000 => 2 ** -1
-            if ($val) {
-                my $sign;
-                if ($val & 0x80000000) {
-                    $sign = -1;
-                    $val &= 0x7fffffff;
-                } else {
-                    $sign = 1;
-                }
-                $val = $sign * 2 ** (($val - 0x3f800000) / 0x800000);
-            }
-            $exifTool->HandleTag($tagTablePtr, $vals[$i], $val,
+            $tags[$i] or ++$unused, next;
+            $et->HandleTag($tagTablePtr, $tags[$i], undef,
                 Index  => $i,
                 DataPt => $dataPt,
@@ -328,5 +316,5 @@
             );
         }
-        $exifTool->VPrint(0, "$exifTool->{INDENT}($unused entries unused)\n");
+        $et->VPrint(0, "$$et{INDENT}($unused entries unused)\n");
     }
     return 1;
@@ -335,25 +323,25 @@
 #------------------------------------------------------------------------------
 # Process an X3F properties
-# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
+# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
 # Returns: 1 on success
 sub ProcessX3FProperties($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $size = length($$dataPt);
-    my $verbose = $exifTool->Options('Verbose');
-    my $unknown = $exifTool->Options('Unknown');
+    my $verbose = $et->Options('Verbose');
+    my $unknown = $et->Options('Unknown');
 
     unless ($size >= 24 and $$dataPt =~ /^SECp/) {
-        $exifTool->Warn('Bad properties header');
+        $et->Warn('Bad properties header');
         return 0;
     }
     my ($entries, $fmt, $len) = unpack('x8V2x4V', $$dataPt);
     unless ($size >= 24 + 8 * $entries + $len) {
-        $exifTool->Warn('Truncated Property directory');
+        $et->Warn('Truncated Property directory');
         return 0;
     }
-    $verbose and $exifTool->VerboseDir('Properties', $entries);
-    $fmt == 0 or $exifTool->Warn("Unsupported character format $fmt"), return 0;
+    $verbose and $et->VerboseDir('Properties', $entries);
+    $fmt == 0 or $et->Warn("Unsupported character format $fmt"), return 0;
     my $charPos = 24 + 8 * $entries;
     my @chars = unpack('v*',substr($$dataPt, $charPos, $len * 2));
@@ -362,9 +350,9 @@
         my ($namePos, $valPos) = unpack('V2',substr($$dataPt, $index*8 + 24, 8));
         if ($namePos >= @chars or $valPos >= @chars) {
-            $exifTool->Warn('Bad Property pointer');
+            $et->Warn('Bad Property pointer');
             return 0;
         }
-        my $tag = ExtractUnicodeString($exifTool, \@chars, $namePos);
-        my $val = ExtractUnicodeString($exifTool, \@chars, $valPos);
+        my $tag = ExtractUnicodeString($et, \@chars, $namePos);
+        my $val = ExtractUnicodeString($et, \@chars, $valPos);
         if (not $$tagTablePtr{$tag} and $unknown and $tag =~ /^\w+$/) {
             my $tagInfo = {
@@ -375,8 +363,8 @@
             };
             # add tag information to table
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $tagInfo);
-        }
-
-        $exifTool->HandleTag($tagTablePtr, $tag, $val,
+            AddTagToTable($tagTablePtr, $tag, $tagInfo);
+        }
+
+        $et->HandleTag($tagTablePtr, $tag, $val,
             Index => $index,
             DataPt => $dataPt,
@@ -390,10 +378,10 @@
 #------------------------------------------------------------------------------
 # Write an X3F file
-# Inputs: 0) ExifTool object reference, 1) DirInfo reference (DirStart = directory offset)
+# Inputs: 0) ExifTool ref, 1) DirInfo ref (DirStart = directory offset)
 # Returns: error string, undef on success, or -1 on write error
 # Notes: Writes metadata to embedded JpgFromRaw image
 sub WriteX3F($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
@@ -440,34 +428,41 @@
 
             # only rewrite full-sized JpgFromRaw (version 2.0, type 2, format 18)
-            if ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/ and
-                $$exifTool{ImageWidth} == unpack('x16V', $buff))
-            {
+            if ($buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/) {
                 $raf->Read($buff, $len) == $len or return 'Error reading JpgFromRaw';
-                # use same write directories as JPEG
-                $exifTool->InitWriteDirs('JPEG');
-                # rewrite the embedded JPEG in memory
-                my $newData;
-                my %jpegInfo = (
-                    Parent  => 'X3F',
-                    RAF     => new File::RandomAccess(\$buff),
-                    OutFile => \$newData,
-                );
-                $$exifTool{FILE_TYPE} = 'JPEG';
-                my $success = $exifTool->WriteJPEG(\%jpegInfo);
-                $$exifTool{FILE_TYPE} = 'X3F';
-                SetByteOrder('II');
-                return 'Error writing X3F JpgFromRaw' unless $success and $newData;
-                return -1 if $success < 0;
-                # write new data if anything changed, otherwise copy old image
-                my $outPt = $$exifTool{CHANGED} ? \$newData : \$buff;
-                Write($outfile, $$outPt) or return -1;
-                # set $len to the total subsection data length
-                $len = length($$outPt) + 28;
-                $didContain = 1;
+                if ($buff =~ /^\xff\xd8\xff\xe1/) { # does this preview contain EXIF?
+                    # use same write directories as JPEG
+                    $et->InitWriteDirs('JPEG');
+                    # make sure we don't add APP0 JFIF because it would mess up our preview identification
+                    delete $$et{ADD_DIRS}{APP0};
+                    delete $$et{ADD_DIRS}{JFIF};
+                    # rewrite the embedded JPEG in memory
+                    my $newData;
+                    my %jpegInfo = (
+                        Parent  => 'X3F',
+                        RAF     => new File::RandomAccess(\$buff),
+                        OutFile => \$newData,
+                    );
+                    $$et{FILE_TYPE} = 'JPEG';
+                    my $success = $et->WriteJPEG(\%jpegInfo);
+                    $$et{FILE_TYPE} = 'X3F';
+                    SetByteOrder('II');
+                    return 'Error writing X3F JpgFromRaw' unless $success and $newData;
+                    return -1 if $success < 0;
+                    # (this shouldn't happen unless someone tries to delete the EXIF...)
+                    return 'EXIF segment must come first in X3F JpgFromRaw' unless $newData =~ /^\xff\xd8\xff\xe1/;
+                    # write new data if anything changed, otherwise copy old image
+                    my $outPt = $$et{CHANGED} ? \$newData : \$buff;
+                    Write($outfile, $$outPt) or return -1;
+                    # set $len to the total subsection data length
+                    $len = length($$outPt);
+                    $didContain = 1;
+                } else {
+                    Write($outfile, $buff) or return -1;
+                }
             } else {
                 # copy original image data
                 Image::ExifTool::CopyBlock($raf, $outfile, $len) or return 'Corrupted X3F image';
-                $len += 28;
             }
+            $len += 28;     # add back header length
         } else {
             # copy data for this subsection
@@ -485,5 +480,5 @@
     }
     # warn if we couldn't add metadata to this image (should only be SD9 or SD10)
-    $didContain or $exifTool->Warn("Can't yet write SD9 or SD10 X3F images");
+    $didContain or $et->Warn("Can't yet write SD9 or SD10 X3F images");
     # write out the directory and the directory pointer, and we are done
     Write($outfile, $outDir, pack('V', $outPos)) or return -1;
@@ -493,11 +488,11 @@
 #------------------------------------------------------------------------------
 # Process an X3F directory
-# Inputs: 0) ExifTool object reference, 1) DirInfo reference, 2) tag table ref
+# Inputs: 0) ExifTool ref, 1) DirInfo ref, 2) tag table ref
 # Returns: error string or undef on success
 sub ProcessX3FDirectory($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     $raf->Seek($$dirInfo{DirStart}, 0) or return 'Error seeking to directory start';
@@ -508,16 +503,16 @@
     $buff =~ /^SECd/ or return 'Bad section header';
     ($ver, $entries) = unpack('x4V2', $buff);
-    $verbose and $exifTool->VerboseDir('X3F Subsection', $entries);
+    $verbose and $et->VerboseDir('X3F Subsection', $entries);
     $raf->Read($dir, $entries * 12) == $entries * 12 or return 'Truncated X3F directory';
     for ($index=0; $index<$entries; ++$index) {
         my $pos = $index * 12;
         my ($offset, $len, $tag) = unpack("x${pos}V2a4", $dir);
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
         if ($verbose) {
-            $exifTool->VPrint(0, "$exifTool->{INDENT}$index) $tag Subsection ($len bytes):\n");
+            $et->VPrint(0, "$$et{INDENT}$index) $tag Subsection ($len bytes):\n");
             if ($verbose > 2) {
                 $raf->Seek($offset, 0) or return 'Error seeking';
                 $raf->Read($buff, $len) == $len or return 'Truncated image';
-                $exifTool->VerboseDump(\$buff);
+                $et->VerboseDump(\$buff);
             }
         }
@@ -529,19 +524,21 @@
             # ignore all image data but JPEG compressed (version 2.0, type 2, format 18)
             next unless $buff =~ /^SECi\0\0\x02\0\x02\0\0\0\x12\0\0\0/;
-            # check preview image size and extract full-sized preview as JpgFromRaw
-            if ($$exifTool{ImageWidth} == unpack('x16V', $buff)) {
-                $$exifTool{IsJpgFromRaw} = 1;
-                $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
-                delete $$exifTool{IsJpgFromRaw};
-            }
             $offset += 28;
             $len -= 28;
-        }
-        $raf->Read($buff, $len) == $len or return "Error reading $$tagInfo{Name} data";
+            $raf->Read($buff, $len) == $len or return "Error reading PreviewImage data";
+            # check fore EXIF segment, and extract this image as the JpgFromRaw
+            if ($buff =~ /^\xff\xd8\xff\xe1/) {
+                $$et{IsJpgFromRaw} = 1;
+                $tagInfo = $et->GetTagInfo($tagTablePtr, $tag);
+                delete $$et{IsJpgFromRaw};
+            }
+        } else {
+            $raf->Read($buff, $len) == $len or return "Error reading $$tagInfo{Name} data";
+        }
         my $subdir = $$tagInfo{SubDirectory};
         if ($subdir) {
             my %dirInfo = ( DataPt => \$buff );
             my $subTable = GetTagTable($$subdir{TagTable});
-            $exifTool->ProcessDirectory(\%dirInfo, $subTable);
+            $et->ProcessDirectory(\%dirInfo, $subTable);
         } else {
             # extract metadata from JpgFromRaw
@@ -551,10 +548,10 @@
                     RAF    => new File::RandomAccess(\$buff),
                 );
-                $$exifTool{BASE} += $offset;
-                $exifTool->ProcessJPEG(\%dirInfo);
-                $$exifTool{BASE} -= $offset;
+                $$et{BASE} += $offset;
+                $et->ProcessJPEG(\%dirInfo);
+                $$et{BASE} -= $offset;
                 SetByteOrder('II');
             }
-            $exifTool->FoundTag($tagInfo, $buff);
+            $et->FoundTag($tagInfo, $buff);
         }
     }
@@ -564,13 +561,13 @@
 #------------------------------------------------------------------------------
 # Read/write information from a Sigma raw (X3F) image
-# Inputs: 0) ExifTool object reference, 1) DirInfo reference
+# Inputs: 0) ExifTool ref, 1) DirInfo ref
 # Returns: 1 on success, 0 if this wasn't a valid X3F image, or -1 on write error
 sub ProcessX3F($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $outfile = $$dirInfo{OutFile};
     my $raf = $$dirInfo{RAF};
     my $warn = $outfile ? \&Image::ExifTool::Error : \&Image::ExifTool::Warn;
-    my ($buff, $err);
+    my ($buff, $err, $hdrLen);
 
     return 0 unless $raf->Read($buff, 40) == 40;
@@ -578,33 +575,34 @@
 
     SetByteOrder('II');
-    $exifTool->SetFileType();
+    $et->SetFileType();
 
     # check version number
     my $ver = unpack('x4V',$buff);
     $ver = ($ver >> 16) . '.' . ($ver & 0xffff);
-    if ($ver >= 3) {
-        &$warn($exifTool, "Can't read version $ver X3F image");
-        return 1;
-    } elsif ($ver > 2.3) {
-        &$warn($exifTool, 'Untested X3F version. Please submit sample for testing', 1);
-    }
-    my $hdrLen = length $buff;
+    if ($ver > 5) {
+        &$warn($et, "Untested X3F version ($ver). Please submit sample for testing", 1);
+    }
     # read version 2.1/2.2/2.3 extended header
     if ($ver > 2) {
-        $hdrLen += $ver > 2.2 ? 64 : 32;            # SceneCaptureType string added in 2.3
-        my $more = $hdrLen - length($buff) + 160;   # (extended header is 160 bytes)
-        my $buf2;
+        my ($extra, $buf2);
+        if ($ver >= 4) {
+            $hdrLen = 0x300;
+            $extra = 0;
+        } else {
+            $hdrLen = $ver > 2.2 ? 104 : 72;    # SceneCaptureType string added in 2.3
+            $extra = 160;                       # (extended header is 160 bytes)
+        }
+        my $more = $hdrLen - length($buff) + $extra;
         unless ($raf->Read($buf2, $more) == $more) {
-            &$warn($exifTool, 'Error reading extended header');
+            &$warn($et, 'Error reading X3F header');
             return 1;
         }
         $buff .= $buf2;
     }
-    # extract ImageWidth for later
-    $$exifTool{ImageWidth} = Get32u(\$buff, 28);
+    my ($widPos, $hdrType) = $ver < 4 ? (28, 'Header') : (40, 'Header4');
     # process header information
     my $tagTablePtr = GetTagTable('Image::ExifTool::SigmaRaw::Main');
     unless ($outfile) {
-        $exifTool->HandleTag($tagTablePtr, 'Header', $buff,
+        $et->HandleTag($tagTablePtr, $hdrType, $buff,
             DataPt => \$buff,
             Size   => $hdrLen,
@@ -612,7 +610,7 @@
     }
     # read the directory pointer
-    $raf->Seek(-4, 2) or &$warn($exifTool, 'Seek error'), return 1;
+    $raf->Seek(-4, 2) or &$warn($et, 'Seek error'), return 1;
     unless ($raf->Read($buff, 4) == 4) {
-        &$warn($exifTool, 'Error reading X3F dir pointer');
+        &$warn($et, 'Error reading X3F dir pointer');
         return 1;
     }
@@ -624,11 +622,11 @@
     if ($outfile) {
         $dirInfo{OutFile} = $outfile;
-        $err = WriteX3F($exifTool, \%dirInfo);
+        $err = WriteX3F($et, \%dirInfo);
         return -1 if $err and $err eq '-1';
     } else {
         # process the X3F subsections
-        $err = $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
-    }
-    $err and &$warn($exifTool, $err);
+        $err = $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    }
+    $err and &$warn($et, $err);
     return 1;
 }
@@ -653,5 +651,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sony.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sony.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Sony.pm	(revision 34921)
@@ -14,8 +14,15 @@
 #               7) Rudiger Lange private communication (A700)
 #               8) Igal Milchtaich private communication
-#               9) Michael Reitinger private communication (DSC-TX7)
+#               9) Michael Reitinger private communication (DSC-TX7,RX100)
 #               10) http://www.klingebiel.com/tempest/hd/pmp.html
-#               11 Mike Battilana private communication
+#               11) Mike Battilana private communication
+#               13) http://www.mi-fo.de/forum/index.php?showtopic=33239
+#                   http://www.dyxum.com/dforum/the-alpha-shutter-count-tool_topic97489_page4.html
+#               14) Albert Shan private communication (A7M3)
+#               IB) Iliah Borg private communication (LibRaw)
 #               JD) Jens Duttke private communication
+#               JR) Jos Roost private communication
+#
+#               NC = Not Confirmed
 #------------------------------------------------------------------------------
 
@@ -23,16 +30,227 @@
 
 use strict;
-use vars qw($VERSION);
+use vars qw($VERSION %sonyLensTypes %sonyLensTypes2);
 use Image::ExifTool qw(:DataAccess :Utils);
 use Image::ExifTool::Exif;
 use Image::ExifTool::Minolta;
 
-$VERSION = '1.50';
+$VERSION = '3.36';
 
 sub ProcessSRF($$$);
 sub ProcessSR2($$$);
+sub ProcessSonyPIC($$$);
+sub ProcessMoreInfo($$$);
+sub Process_rtmd($$$);
+sub Decipher($;$);
+sub ProcessEnciphered($$$);
+sub WriteEnciphered($$$);
 sub WriteSR2($$$);
-
-my %sonyLensTypes;  # filled in based on Minolta LensType's
+sub ConvLensSpec($);
+sub ConvInvLensSpec($);
+sub PrintLensSpec($);
+sub PrintInvLensSpec($;$$);
+
+# (%sonyLensTypes is filled in based on Minolta LensType's)
+
+# Sony E-mount lenses
+# (NOTE: these should be kept in sync with the 65535 entries in %minoltaLensTypes)
+%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',
+    6 => 'Sony LA-EA4 Adapter',
+    7 => 'Sony LA-EA5 Adapter', #JR
+    # 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
+    24593 => 'LA-EA4r MonsterAdapter',
+                                                # Sony VX product code: (http://www.mi-fo.de/forum/index.php?s=7df1c8d3b1cd675f2abf4f4442e19cf2&showtopic=35035&view=findpost&p=303746)
+    32784 => 'Sony E 16mm F2.8',                # VX9100
+    32785 => 'Sony E 18-55mm F3.5-5.6 OSS',     # VX9101
+    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', # 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 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 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
+    32801 => 'Sony FE 12-24mm F4 G', #JR
+    32802 => 'Sony FE 90mm F2.8 Macro G OSS',   # VX?
+    32803 => 'Sony E 18-50mm F4-5.6',
+    32804 => 'Sony FE 24mm F1.4 GM', #IB
+    32805 => 'Sony FE 24-105mm F4 G OSS', #IB   # VX9121
+
+    32807 => 'Sony E PZ 18-200mm F3.5-6.3 OSS', # VX9123
+    32808 => 'Sony FE 55mm F1.8 ZA',            # VX9124
+
+    32810 => 'Sony FE 70-200mm F4 G OSS', #JR   # VX9126
+    32811 => 'Sony FE 16-35mm F4 ZA OSS', #JR   # VX9127
+    32812 => 'Sony FE 50mm F2.8 Macro', #JR
+    32813 => 'Sony FE 28-70mm F3.5-5.6 OSS',    # VX9129
+    32814 => 'Sony FE 35mm F1.4 ZA',            # VX?
+    32815 => 'Sony FE 24-240mm F3.5-6.3 OSS',   # VX?
+    32816 => 'Sony FE 28mm F2', #JR             # VX?
+    32817 => 'Sony FE PZ 28-135mm F4 G OSS',#JR # VX?
+
+    32819 => 'Sony FE 100mm F2.8 STF GM OSS',   #JR (appears to use 33076 when switched to macro mode)
+    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 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)
+    32827 => 'Sony FE 16mm F3.5 Fisheye (SEL28F20 + SEL057FEC)', #JR  # (+ Fisheye converter)
+    32828 => 'Sony FE 70-300mm F4.5-5.6 G OSS', #JR
+    32829 => 'Sony FE 100-400mm F4.5-5.6 GM OSS', #JR
+    32830 => 'Sony FE 70-200mm F2.8 GM OSS', #JR
+    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
+    32860 => 'Sony FE 12-24mm F2.8 GM', #JR/IB
+    32864 => 'Sony FE 28-60mm F4-5.6', #JR
+    32865 => 'Sony FE 35mm F1.4 GM', #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
+    33073 => 'Sony FE 70-200mm F2.8 GM OSS + 2X Teleconverter', #JR
+    33076 => 'Sony FE 100mm F2.8 STF GM OSS (macro mode)', #JR (with macro switching ring set to "0.57m - 1.0m")
+    33077 => 'Sony FE 100-400mm F4.5-5.6 GM OSS + 1.4X Teleconverter', #JR
+    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)
+    49203 => 'Zeiss Touit 50mm F2.8 Macro', #JR (lens firmware Ver.02)
+    49216 => 'Zeiss Batis 25mm F2', #JR
+    49217 => 'Zeiss Batis 85mm F1.8', #JR
+    49218 => 'Zeiss Batis 18mm F2.8', #IB
+    49219 => 'Zeiss Batis 135mm F2.8', #IB
+    49220 => 'Zeiss Batis 40mm F2 CF', #IB
+    49232 => 'Zeiss Loxia 50mm F2', #JR (lens firmware Ver.02)
+    49233 => 'Zeiss Loxia 35mm F2', #JR (lens firmware Ver.02)
+    49234 => 'Zeiss Loxia 21mm F2.8', #PH
+    49235 => 'Zeiss Loxia 85mm F2.4', #JR
+    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)
+    49462 => 'Tamron 70-180mm F2.8 Di III VXD', #JR (Model A056)
+    49463 => 'Tamron 28-200mm F2.8-5.6 Di III RXD', #JR (Model A071)
+    49464 => 'Tamron 70-300mm F4.5-6.3 Di III RXD', #JR (Model A047)
+    49465 => 'Tamron 17-70mm F2.8 Di III-A VC RXD', #JR (Model B070)
+    49473 => 'Tokina atx-m 85mm F1.8 FE', #JR
+    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', #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', #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)
+    50493 => 'Sigma 17-70mm F2.8-4 DC MACRO OS HSM | C + MC-11', #JR (013)
+    50495 => 'Sigma 50-100mm F1.8 DC HSM | A + MC-11', #JR (016)
+    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)
+    50518 => 'Sigma 100-400mm F5-6.3 DG DN OS | C', #JR (020)
+    50521 => 'Sigma 85mm F1.4 DG DN | A', #JR (020)
+    50522 => 'Sigma 105mm F2.8 DG DN MACRO | A', #JR (020)
+    50523 => 'Sigma 65mm F2 DG DN | C', #IB (020)
+    50524 => 'Sigma 35mm F2 DG DN | C', #IB (020)
+    50525 => 'Sigma 24mm F3.5 DG DN | C', #JR (021)
+
+    50992 => 'Voigtlander SUPER WIDE-HELIAR 15mm F4.5 III', #JR
+    50993 => 'Voigtlander HELIAR-HYPER WIDE 10mm F5.6', #IB
+    50994 => 'Voigtlander ULTRA WIDE-HELIAR 12mm F5.6 III', #IB
+    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
+    51003 => 'Voigtlander NOKTON 35mm F1.2 Aspherical SE', #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 30mm F1.4 DC HSM | A + MC-11', # (013)
+
+    # Note: For Samyang lenses, the "FE" designation isn't written to
+    # EXIF:LensModel, so it isn't included in these strings either - JR/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 or Samyang AF 35mm F1.8', #JR
+    51510.1 => 'Samyang AF 35mm F1.8', #JR
+    51512 => 'Samyang AF 75mm F1.8', #IB/JR
+);
 
 # ExposureProgram values (ref PH, mainly decoded from A200)
@@ -45,11 +263,251 @@
     8 => 'Program Shift A', #7
     9 => 'Program Shift S', #7
+    16 => 'Portrait', # (A330)
+    17 => 'Sports', # (A330)
+    18 => 'Sunset', # (A330)
     19 => 'Night Portrait', # (A330)
-    18 => 'Sunset', # (A330)
-    17 => 'Sports', # (A330)
+    20 => 'Landscape', # (A330)
     21 => 'Macro', # (A330)
-    20 => 'Landscape', # (A330)
-    16 => 'Portrait', # (A330)
     35 => 'Auto No Flash', # (A330)
+);
+
+# ExposureProgram values in CameraSettings3 (ref JR)
+my %sonyExposureProgram2 = (            # A580 Mode Dial setting:
+     1 => 'Program AE',                 # P
+     2 => 'Aperture-priority AE',       # A
+     3 => 'Shutter speed priority AE',  # S
+     4 => 'Manual',                     # M
+     5 => 'Cont. Priority AE',          # (A35)
+    16 => 'Auto',                       # AUTO
+    17 => 'Auto (no flash)',            # "flash strike-out" symbol
+    18 => 'Auto+',                      #PH (A33)
+    49 => 'Portrait',                   # SCN
+    50 => 'Landscape',                  # SCN
+    51 => 'Macro',                      # SCN
+    52 => 'Sports',                     # SCN
+    53 => 'Sunset',                     # SCN
+    54 => 'Night view',                 # SCN
+    55 => 'Night view/portrait',        # SCN
+    56 => 'Handheld Night Shot',        # SCN (also called "Hand-held Twilight")
+    57 => '3D Sweep Panorama',          # "Panorama" symbol
+    64 => 'Auto 2',                     #PH (A33 AUTO)
+    65 => 'Auto 2 (no flash)',          #JR (NC, A35)
+    80 => 'Sweep Panorama',             # "Panorama" symbol
+    96 => 'Anti Motion Blur',           #PH (NEX-5)
+    # 128-138 are A35 picture effects (combined SCN/Picture effect mode dial position)
+    128 => 'Toy Camera',
+    129 => 'Pop Color',
+    130 => 'Posterization',
+    131 => 'Posterization B/W',
+    132 => 'Retro Photo',
+    133 => 'High-key',
+    134 => 'Partial Color Red',
+    135 => 'Partial Color Green',
+    136 => 'Partial Color Blue',
+    137 => 'Partial Color Yellow',
+    138 => 'High Contrast Monochrome',
+);
+
+# ExposureProgram values in Tags 2010 and 94xx (ref JR)
+my %sonyExposureProgram3 = (
+     0 => 'Program AE',
+     1 => 'Aperture-priority AE',
+     2 => 'Shutter speed priority AE',
+     3 => 'Manual',
+     4 => 'Auto',
+     5 => 'iAuto',
+     6 => 'Superior Auto',
+     7 => 'iAuto+',
+     8 => 'Portrait',
+     9 => 'Landscape',
+    10 => 'Twilight',
+    11 => 'Twilight Portrait',
+    12 => 'Sunset',
+    14 => 'Action (High speed)', #PH (RX100)
+    16 => 'Sports',
+    17 => 'Handheld Night Shot',
+    18 => 'Anti Motion Blur',
+    19 => 'High Sensitivity',
+    21 => 'Beach',
+    22 => 'Snow',
+    23 => 'Fireworks',
+    26 => 'Underwater',
+    27 => 'Gourmet',
+    28 => 'Pet',
+    29 => 'Macro',
+    30 => 'Backlight Correction HDR',
+    # 32 => 'Night ... ???', # seen for HDR-CX360E
+    33 => 'Sweep Panorama',
+    36 => 'Background Defocus',
+    37 => 'Soft Skin',
+    42 => '3D Image',
+    43 => 'Cont. Priority AE',
+    45 => 'Document',
+    46 => 'Party',
+);
+
+# WhiteBalanceSetting values (ref JR)
+my %whiteBalanceSetting = (
+    0x10 => 'Auto (-3)', #(NC)
+    0x11 => 'Auto (-2)', #(NC)
+    0x12 => 'Auto (-1)', #(NC)
+    0x13 => 'Auto (0)',
+    0x14 => 'Auto (+1)', #(NC)
+    0x15 => 'Auto (+2)', #(NC)
+    0x16 => 'Auto (+3)', #(NC)
+    0x20 => 'Daylight (-3)',
+    0x21 => 'Daylight (-2)', #(NC)
+    0x22 => 'Daylight (-1)', #(NC)
+    0x23 => 'Daylight (0)',
+    0x24 => 'Daylight (+1)',
+    0x25 => 'Daylight (+2)',
+    0x26 => 'Daylight (+3)',
+    0x30 => 'Shade (-3)', #(NC)
+    0x31 => 'Shade (-2)', #(NC)
+    0x32 => 'Shade (-1)', #(NC)
+    0x33 => 'Shade (0)',
+    0x34 => 'Shade (+1)', #(NC)
+    0x35 => 'Shade (+2)', #(NC)
+    0x36 => 'Shade (+3)',
+    0x40 => 'Cloudy (-3)', #(NC)
+    0x41 => 'Cloudy (-2)', #(NC)
+    0x42 => 'Cloudy (-1)', #(NC)
+    0x43 => 'Cloudy (0)',
+    0x44 => 'Cloudy (+1)', #(NC)
+    0x45 => 'Cloudy (+2)', #(NC)
+    0x46 => 'Cloudy (+3)', #(NC)
+    0x50 => 'Tungsten (-3)', #(NC)
+    0x51 => 'Tungsten (-2)', #(NC)
+    0x52 => 'Tungsten (-1)', #(NC)
+    0x53 => 'Tungsten (0)',
+    0x54 => 'Tungsten (+1)', #(NC)
+    0x55 => 'Tungsten (+2)', #(NC)
+    0x56 => 'Tungsten (+3)', #(NC)
+    0x60 => 'Fluorescent (-3)', #(NC)
+    0x61 => 'Fluorescent (-2)', #(NC)
+    0x62 => 'Fluorescent (-1)', #(NC)
+    0x63 => 'Fluorescent (0)',
+    0x64 => 'Fluorescent (+1)', #(NC)
+    0x65 => 'Fluorescent (+2)', #(NC)
+    0x66 => 'Fluorescent (+3)', #(NC)
+    0x70 => 'Flash (-3)', #(NC)
+    0x71 => 'Flash (-2)', #(NC)
+    0x72 => 'Flash (-1)', #(NC)
+    0x73 => 'Flash (0)',
+    0x74 => 'Flash (+1)', #(NC)
+    0x75 => 'Flash (+2)', #(NC)
+    0x76 => 'Flash (+3)', #(NC)
+    0xa3 => 'Custom',
+    0xf3 => 'Color Temperature/Color Filter',
+);
+
+# AF points for cameras with 15-point AF (ref JR)
+my %afPoint15 = (
+    0 => 'Upper-left',
+    1 => 'Left',
+    2 => 'Lower-left',
+    3 => 'Far Left',
+    4 => 'Top (horizontal)',
+    5 => 'Near Right',
+    6 => 'Center (horizontal)',
+    7 => 'Near Left',
+    8 => 'Bottom (horizontal)',
+    9 => 'Top (vertical)',
+    10 => 'Center (vertical)',
+    11 => 'Bottom (vertical)',
+    12 => 'Far Right',
+    13 => 'Upper-right',
+    14 => 'Right',
+    15 => 'Lower-right',
+    16 => 'Upper-middle',
+    17 => 'Lower-middle',
+);
+
+# AF points for cameras with 19-point AF (ref PH)
+# (verified for A77 firmware 1.07)
+my %afPoint19 = (
+    0 => 'Upper Far Left',
+    1 => 'Upper-left (horizontal)',
+    2 => 'Far Left (horizontal)',
+    3 => 'Left (horizontal)',
+    4 => 'Lower Far Left',
+    5 => 'Lower-left (horizontal)',
+    6 => 'Upper-left (vertical)',
+    7 => 'Left (vertical)',
+    8 => 'Lower-left (vertical)',
+    9 => 'Far Left (vertical)',
+    10 => 'Top (horizontal)',
+    11 => 'Near Right',
+    12 => 'Center (horizontal)',
+    13 => 'Near Left',
+    14 => 'Bottom (horizontal)',
+    15 => 'Top (vertical)',
+    16 => 'Upper-middle',
+    17 => 'Center (vertical)',
+    18 => 'Lower-middle',
+    19 => 'Bottom (vertical)',
+    20 => 'Upper Far Right',
+    21 => 'Upper-right (horizontal)',
+    22 => 'Far Right (horizontal)',
+    23 => 'Right (horizontal)',
+    24 => 'Lower Far Right',
+    25 => 'Lower-right (horizontal)',
+    26 => 'Far Right (vertical)',
+    27 => 'Upper-right (vertical)',
+    28 => 'Right (vertical)',
+    29 => 'Lower-right (vertical)',
+);
+
+# 79 AF point layout and indices for ILCA-68/77M2, numbered 0-78 for direct look-up from BITMASK in 0x2020,
+# E6 = Center (ref JR)
+my %afPoints79 = (
+                                             0=>'A5',  1=>'A6',  2=>'A7',
+               3=>'B2',  4=>'B3',  5=>'B4',  6=>'B5',  7=>'B6',  8=>'B7',  9=>'B8', 10=>'B9', 11=>'B10',
+    12=>'C1', 13=>'C2', 14=>'C3', 15=>'C4', 16=>'C5', 17=>'C6', 18=>'C7', 19=>'C8', 20=>'C9', 21=>'C10', 22=>'C11',
+    23=>'D1', 24=>'D2', 25=>'D3', 26=>'D4', 27=>'D5', 28=>'D6', 29=>'D7', 30=>'D8', 31=>'D9', 32=>'D10', 33=>'D11',
+    34=>'E1', 35=>'E2', 36=>'E3', 37=>'E4', 38=>'E5', 39=>'E6', 40=>'E7', 41=>'E8', 42=>'E9', 43=>'E10', 44=>'E11',
+    45=>'F1', 46=>'F2', 47=>'F3', 48=>'F4', 49=>'F5', 50=>'F6', 51=>'F7', 52=>'F8', 53=>'F9', 54=>'F10', 55=>'F11',
+    56=>'G1', 57=>'G2', 58=>'G3', 59=>'G4', 60=>'G5', 61=>'G6', 62=>'G7', 63=>'G8', 64=>'G9', 65=>'G10', 66=>'G11',
+              67=>'H2', 68=>'H3', 69=>'H4', 70=>'H5', 71=>'H6', 72=>'H7', 73=>'H8', 74=>'H9', 75=>'H10',
+                                            76=>'I5', 77=>'I6', 78=>'I7',
+);
+
+# AFPoint and AFStatus tags in AFInfo(Tag940e) use numbers 0 to 94 for the 79 positions + 15 cross + 1 F2.8
+my %afPoints79_940e = (
+                                            59=>'A5', 50=>'A6', 41=>'A7',
+              14=>'B2',  7=>'B3',  0=>'B4', 60=>'B5', 51=>'B6', 42=>'B7', 87=>'B8', 80=>'B9', 73=>'B10',
+    21=>'C1', 15=>'C2',  8=>'C3',  1=>'C4', 61=>'C5', 52=>'C6', 43=>'C7', 88=>'C8', 81=>'C9', 74=>'C10', 68=>'C11',
+    22=>'D1', 16=>'D2',  9=>'D3',  2=>'D4', 62=>'D5', 53=>'D6', 44=>'D7', 89=>'D8', 82=>'D9', 75=>'D10', 69=>'D11',
+    23=>'E1', 17=>'E2', 10=>'E3',  3=>'E4', 63=>'E5', 54=>'E6 Center', 45=>'E7', 90=>'E8', 83=>'E9', 76=>'E10', 70=>'E11',
+    24=>'F1', 18=>'F2', 11=>'F3',  4=>'F4', 64=>'F5', 55=>'F6', 46=>'F7', 91=>'F8', 84=>'F9', 77=>'F10', 71=>'F11',
+    25=>'G1', 19=>'G2', 12=>'G3',  5=>'G4', 65=>'G5', 56=>'G6', 47=>'G7', 92=>'G8', 85=>'G9', 78=>'G10', 72=>'G11',
+              20=>'H2', 13=>'H3',  6=>'H4', 66=>'H5', 57=>'H6', 48=>'H7', 93=>'H8', 86=>'H9', 79=>'H10',
+                                            67=>'I5', 58=>'I6', 49=>'I7',
+
+                                   28=>'A5 Vertical', 27=>'A6 Vertical', 26=>'A7 Vertical',
+                                   31=>'C5 Vertical', 30=>'C6 Vertical', 29=>'C7 Vertical',
+                                   34=>'E5 Vertical', 33=>'E6 Center Vertical', 32=>'E7 Vertical',
+                                   37=>'G5 Vertical', 36=>'G6 Vertical', 35=>'G7 Vertical',
+                                   40=>'I5 Vertical', 39=>'I6 Vertical', 38=>'I7 Vertical',
+
+                                                      94=>'E6 Center F2.8',
+);
+
+# ILCA-99M2 has dedicated 79 point Phase Detection AF sensor with similar layout as ILCA-68 and ILCA-77M2.
+# ILCA-99M2 has also 399 Focal Plane Phase-Detection AF Points in 19 rows of 21 points, same as ILCE-7RM2.
+# Of these 399 points, 323 points are selectable: 19 rows of 17 points (2 left-most and right-most columns not selectable).
+# The 79 Focal Plane points that overlap with the 79 points of the dedicated sensor provide for Hybrid Phase AF Points.
+# Tag 0x201e gives value 162 for the Center AF point, and 162 is exactly the center of 323 points...
+# The below table lists the selectable AF points that correspond to the 79 points of the dedicated sensor. (ref JR)
+my %afPoints99M2 = (
+                                                                           93=>'A5 (93)',   94=>'A6 (94)',   95=>'A7 (95)',
+                    106=>'B2 (106)', 107=>'B3 (107)', 108=>'B4 (108)',    110=>'B5 (110)', 111=>'B6 (111)', 112=>'B7 (112)',    114=>'B8 (114)', 115=>'B9 (115)', 116=>'B10 (116)',
+   122=>'C1 (122)', 123=>'C2 (123)', 124=>'C3 (124)', 125=>'C4 (125)',    127=>'C5 (127)', 128=>'C6 (128)', 129=>'C7 (129)',    131=>'C8 (131)', 132=>'C9 (132)', 133=>'C10 (133)', 134=>'C11 (134)',
+   139=>'D1 (139)', 140=>'D2 (140)', 141=>'D3 (141)', 142=>'D4 (142)',    144=>'D5 (144)', 145=>'D6 (145)', 146=>'D7 (146)',    148=>'D8 (148)', 149=>'D9 (149)', 150=>'D10 (150)', 151=>'D11 (151)',
+   156=>'E1 (156)', 157=>'E2 (157)', 158=>'E3 (158)', 159=>'E4 (159)',    161=>'E5 (161)', 162=>'E6 (162)', 163=>'E7 (163)',    165=>'E8 (165)', 166=>'E9 (166)', 167=>'E10 (167)', 168=>'E11 (168)',
+   173=>'F1 (173)', 174=>'F2 (174)', 175=>'F3 (175)', 176=>'F4 (176)',    178=>'F5 (178)', 179=>'F6 (179)', 180=>'F7 (180)',    182=>'F8 (182)', 183=>'F9 (183)', 184=>'F10 (184)', 185=>'F11 (185)',
+   190=>'G1 (190)', 191=>'G2 (191)', 192=>'G3 (192)', 193=>'G4 (193)',    195=>'G5 (195)', 196=>'G6 (196)', 197=>'G7 (197)',    199=>'G8 (199)', 200=>'G9 (200)', 201=>'G10 (201)', 202=>'G11 (202)',
+                    208=>'H2 (208)', 209=>'H3 (209)', 210=>'H4 (210)',    212=>'H5 (212)', 213=>'H6 (213)', 214=>'H7 (214)',    216=>'H8 (216)', 217=>'H9 (217)', 218=>'H10 (218)',
+                                                                          229=>'I5 (229)', 230=>'I6 (230)', 231=>'I7 (231)',
 );
 
@@ -62,8 +520,100 @@
 );
 
+# tagInfo attributes for unknown cipher block tags
+my %unknownCipherData = (
+    Unknown => 1,   # require Unknown option
+    Hidden => 1,    # doesn't appear in Tag Name documentation
+    RawConv => sub { Decipher(\$_[0]); return $_[0] },
+    ValueConv => 'PrintHex($val)',                      # print as hex
+    PrintConv => 'length($val) > 65 ? substr($val,0,60) . "[...]" : $val',  # limit length
+);
+
+my %meterInfo1 = (
+    Format => 'int32u[27]',
+    PrintConv => 'sprintf("%19d %4d %6d" . " %3d %4d %6d" x 8, split(" ",$val))',
+    PrintConvInv => '$val',
+);
+my %meterInfo2 = (
+    Format => 'int32u[33]',
+    PrintConv => 'sprintf("%3d %4d %6d" . " %3d %4d %6d" x 10, split(" ",$val))',
+    PrintConvInv => '$val',
+);
+my %meterInfo1b = (
+    Format => 'undef[90]',
+    ValueConv => \&ConvMeter1,
+    PrintConv => 'sprintf("%19d %4d %6d" . " %3d %4d %6d" x 8, split(" ",$val))',
+);
+my %meterInfo2b = (
+    Format => 'undef[110]',
+    ValueConv => \&ConvMeter2,
+    PrintConv => 'sprintf("%3d %4d %6d" . " %3d %4d %6d" x 10, split(" ",$val))',
+);
+
+my %hidUnk = ( Hidden => 1, Unknown => 1 );
+
+# Sony maker notes tags (some elements in common with %Image::ExifTool::Minolta::Main)
 %Image::ExifTool::Sony::Main = (
     WRITE_PROC => \&Image::ExifTool::Exif::WriteExif,
     CHECK_PROC => \&Image::ExifTool::Exif::CheckExif,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        The following information has been decoded from the MakerNotes of Sony
+        cameras.  Some of these tags have been inherited from the Minolta
+        MakerNotes.
+    },
+    0x0010 => [ #PH
+        # appears to contain mostly AF related information;
+        # for SLT-A77V and newer, similar info is found in 0x940e AFInfo" (ref JR)
+        {
+            Name => 'CameraInfo',
+            # count: A700=368, A850/A900=5478
+            Condition => '$count == 368 or $count == 5478',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sony::CameraInfo',
+                ByteOrder => 'BigEndian',
+            },
+        },{
+            Name => 'CameraInfo2',
+            # count: A200/A300/A350=5506, A230/A290/A330/A380/A390=6118
+            Condition => '$count == 5506 or $count == 6118',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sony::CameraInfo2',
+                ByteOrder => 'LittleEndian',
+            },
+        },{
+            Name => 'CameraInfo3',
+            # count: A33/A35/A55V/A450/A500/A550/A560/A580/NEX3/5/5C/C3/VG10E=15360
+            Condition => '$count == 15360',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sony::CameraInfo3',
+                ByteOrder => 'LittleEndian',
+            },
+        },{
+            Name => 'CameraInfoUnknown',
+            SubDirectory => { TagTable => 'Image::ExifTool::Sony::CameraInfoUnknown' },
+        },
+    ],
+    # 0x0018 - starts with "GYRO" for sweep panorama images (ref JR)
+    #        - contains ImageStabilization information for Minolta
+    0x0020 => [
+        # similar to WBInfoA100 in Minolta.pm.
+        # appears to contain various types of information, as in MoreInfo. (ref JR)
+        {
+            Name => 'FocusInfo', #PH
+            # count: A200/A230/A290/A300/A330/A350/A380/A390==19154, A700/A850/A900=19148
+            Condition => '$count == 19154 or $count == 19148',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sony::FocusInfo',
+                ByteOrder => 'LittleEndian',
+            },
+        },{
+            Name => 'MoreInfo', #JR
+            # count: A450/A500/A550/A560/A580/A33/A35/A55/NEX-3/5/C3/VG10E==20480
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sony::MoreInfo',
+                ByteOrder => 'LittleEndian',
+            },
+        },
+    ],
     0x0102 => { #5/JD
         Name => 'Quality',
@@ -79,4 +629,5 @@
             7 => 'Compressed RAW',
             8 => 'Compressed RAW + JPEG',
+            0xffffffff => 'n/a', #PH (SLT-A57 panorama)
         },
     },
@@ -86,15 +637,9 @@
         Writable => 'rational64s',
     },
-    0x0105 => { #5/JD
+    0x0105 => { #5/JD (models since mid-2014, ILCA-77M2, ILCE-7M2/7RM2/7SM2, do not report this tag anymore, ref JR)
         Name => 'Teleconverter',
         Writable => 'int32u',
         PrintHex => 1,
-        PrintConv => {
-            0 => 'None',
-            72 => 'Minolta AF 2x APO (D)',
-            80 => 'Minolta AF 2x APO II',
-            136 => 'Minolta AF 1.4x APO (D)',
-            144 => 'Minolta AF 1.4x APO II',
-        },
+        PrintConv => \%Image::ExifTool::Minolta::minoltaTeleconverters,
     },
     0x0112 => { #JD
@@ -106,19 +651,27 @@
         {
             Name => 'CameraSettings',
-            Condition => '$$self{Model} =~ /DSLR-A(200|230|300|350|700|850|900)\b/',
+            # count: A200/A300/A350/A700=280, A850/A900=364
+            Condition => '$count == 280 or $count == 364',
             SubDirectory => {
                 TagTable => 'Image::ExifTool::Sony::CameraSettings',
                 ByteOrder => 'BigEndian',
             },
-        },
-        {
+        },{
             Name => 'CameraSettings2',
-            Condition => '$$self{Model} =~ /DSLR-A(330|380)\b/',
+            # count: A230/A290/A330/A380/A390=332
+            Condition => '$count == 332',
             SubDirectory => {
                 TagTable => 'Image::ExifTool::Sony::CameraSettings2',
                 ByteOrder => 'BigEndian',
             },
-        },
-        {
+        },{
+            Name => 'CameraSettings3',
+            # count: A560/A580/A33/A35/A55/NEX3/5/5C/C3/VG10E=1536, A450/A500/A550=2048
+            Condition => '$count == 1536 || $count == 2048',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sony::CameraSettings3',
+                ByteOrder => 'LittleEndian',
+            },
+        },{
             Name => 'CameraSettingsUnknown',
             SubDirectory => {
@@ -131,4 +684,5 @@
         Name => 'WhiteBalance',
         Writable => 'int32u',
+        Priority => 2, # (more reliable for the RX100)
         PrintHex => 1,
         PrintConv => {
@@ -142,12 +696,31 @@
             0x60 => 'Fluorescent',
             0x70 => 'Custom',
-        },
-    },
+            0x80 => 'Underwater',
+        },
+    },
+    # Tag 0x0116: extra hardware info (ref JR)
+    # (tag not present for A100, A200, A300, A350, A700, nor for A37, A57, A65, A77)
+    0x0116 => [ #JR
+        {
+            Name => 'ExtraInfo',
+            Condition => '$$self{Model} =~ /^DSLR-A(850|900)\b/',
+            SubDirectory => {
+                TagTable => 'Image::ExifTool::Sony::ExtraInfo',
+                ByteOrder => 'BigEndian',
+            },
+        },{
+            Name => 'ExtraInfo2',
+            Condition => '$$self{Model} =~ /^DSLR-A(230|290|330|380|390)\b/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Sony::ExtraInfo2' },
+        },{
+            Name => 'ExtraInfo3',
+            # for DSLR-A450/500/550/560/580, SLT-A33/35/55 and NEX-3/5/5C.
+            SubDirectory => { TagTable => 'Image::ExifTool::Sony::ExtraInfo3' },
+        }
+    ],
     0x0e00 => {
         Name => 'PrintIM',
         Description => 'Print Image Matching',
-        SubDirectory => {
-            TagTable => 'Image::ExifTool::PrintIM::Main',
-        },
+        SubDirectory => { TagTable => 'Image::ExifTool::PrintIM::Main' },
     },
     # the next 3 tags have a different meaning for some models (with format int32u)
@@ -170,19 +743,43 @@
         Writable => 'int16u',
     },
-    0x1003 => { #9 (TX7, panorama mode only)
+    0x1003 => { #9 (64 bytes, contains Panorama info for various DSC, NEX, SLT and DSLR models)
         Name => 'Panorama',
+        # panorama: first 4 bytes '1 1 0 0' (little-endian) or '0 0 1 1' (big-endian)
+        # non-panorama: all bytes are '0' (ref JR)
+        Condition => '$$self{Panorama} = ($$valPt =~ /^(\0\0)?\x01\x01/)', # (little- or big-endian int32u = 257)
         SubDirectory => { TagTable => 'Image::ExifTool::Sony::Panorama' },
     },
+    # 0x2000 - undef[1]
     0x2001 => { #PH (JPEG images from all DSLR's except the A100)
         Name => 'PreviewImage',
+        Groups => { 2 => 'Preview' },
         Writable => 'undef',
         DataTag => 'PreviewImage',
+        Notes => 'HD-size preview in JPEG images from almost all DSLR/SLT/ILCA/NEX/ILCE.',
         # Note: the preview data starts with a 32-byte proprietary Sony header
+        #       first 8 bytes after 32-byte header:
+        #          \x00\xd8\xff\xe1\x00\x27\xff\xff for JPEG files from A33/35/55V/450/500/550/560/580, NEX-3/5/5C/C3/VG10
+        #          \x00\xd8\xff\xdb\x00\x84\x00\x01 for JPEG files from all other models
+        #        ( \xff\xd8\xff\xdb\x00\x84\x00\x01 corresponding bytes for all ARW files )
+        #
+        # DSLR-A700/A850/A900 and DSLR-A200/A300/A350:
+        # - no MPImage2
+        # DSLR-A230/A290/A330/A380/A390:
+        # - PreviewImage start-offset is at 110 bytes inside MPImage2
+        # DSLR-A450/A500/A550/A560/A580, SLT-A33/A35/A55V, NEX-3/5/5C/C3/VG10/VG10E:
+        # - PreviewImage start-offset is at 106 bytes inside MPImage2
+        # - different first bytes after 32-byte header
+        # SLT-A37/A57/A58/A65V/A77V/A99V, ILCA-77M2, NEX-3N/5N/5R/5T/6/7/F3, ILCE-3000/3500/5000/6000/7/7R/7S:
+        # - PreviewImage start-offset is at 130 bytes inside MPImage2
+        # NEX-VG20E/VG30E/VG900, ILCE-QX1: 0x2001 not present
+        # ILCE-5100/ILCE-7M2/7RM2/7SM2   : 0x2001 present but Size 0 and Offset 0
+        #
         WriteCheck => 'return $val=~/^(none|.{32}\xff\xd8\xff)/s ? undef : "Not a valid image"',
         RawConv => q{
             return \$val if $val =~ /^Binary/;
             $val = substr($val,0x20) if length($val) > 0x20;
-            return \$val if $val =~ s/^.(\xd8\xff\xdb)/\xff$1/s;
-            $$self{PreviewError} = 1 unless $val eq 'none';
+#            return \$val if $val =~ s/^.(\xd8\xff\xdb)/\xff$1/s;
+            return \$val if $val =~ s/^.(\xd8\xff[\xdb\xe1])/\xff$1/s;
+            $$self{PreviewError} = 1 unless $val eq 'none' or $val eq '';
             return undef;
         },
@@ -197,5 +794,9 @@
         },
     },
-    # 0x2002 - probably Sharpness (PH guess)
+    0x2002 => { #JR (written by Sony IDC)
+        Name => 'Rating',
+        Writable => 'int32u', # (0-5 stars) (4294967295 for an HX9V iSweep Panorama, ref JR)
+    },
+    # 0x2003 - string[256]: all 0 for DSLR, SLT, NEX; data for DSC-HX9V
     0x2004 => { #PH (NEX-5)
         Name => 'Contrast',
@@ -228,7 +829,8 @@
         PrintConv => {
             0 => 'Off',
-            1 => 'On',
-            0xffff0000 => 'Off 2',
-            0xffff0001 => 'On 2',
+            1 => 'On (unused)',
+            0x10001 => 'On (dark subtracted)', # (NEX-C3)
+            0xffff0000 => 'Off (65535)',
+            0xffff0001 => 'On (65535)',
             0xffffffff => 'n/a',
         },
@@ -243,4 +845,5 @@
             3 => 'High',
             256 => 'Auto',
+            # it seems that all DSC models except DSC-RX models give n/a here (ref JR)
             65535 => 'n/a',
         },
@@ -249,24 +852,33 @@
         Name => 'HDR',
         Writable => 'int32u',
+        Format => 'int16u',
+        Count => 2,
+        Notes => 'stored as a 32-bit integer, but read as two 16-bit integers',
         PrintHex => 1,
-        PrintConv => {
+        PrintConv => [{
             0x0 => 'Off',
-            0x10001 => 'Auto',
-            0x10010 => '1.0 EV', # (NEX_5)
-            0x10011 => '1.5 EV',
-            0x10012 => '2.0 EV',
-            0x10013 => '2.5 EV',
-            0x10014 => '3.0 EV',
-            0x10015 => '3.5 EV',
-            0x10016 => '4.0 EV',
-            0x10017 => '4.5 EV',
-            0x10018 => '5.0 EV',
-            0x10019 => '5.5 EV',
-            0x1001a => '6.0 EV', # (SLT-A55V)
-        },
+            0x01 => 'Auto',
+            0x10 => '1.0 EV',
+            0x11 => '1.5 EV',
+            0x12 => '2.0 EV',
+            0x13 => '2.5 EV',
+            0x14 => '3.0 EV',
+            0x15 => '3.5 EV',
+            0x16 => '4.0 EV',
+            0x17 => '4.5 EV',
+            0x18 => '5.0 EV',
+            0x19 => '5.5 EV',
+            0x1a => '6.0 EV',
+        },{ #JR (A580)
+            0 => 'Uncorrected image',  # A580 stores 2 images: uncorrected and HDR
+            1 => 'HDR image (good)',
+            2 => 'HDR image (fail 1)', # alignment problem?
+            3 => 'HDR image (fail 2)', # contrast problem?
+        }],
     },
     0x200b => { #PH
         Name => 'MultiFrameNoiseReduction',
         Writable => 'int32u',
+        Notes => 'may not be valid for RS100', # (RS100 sample was 0 when this feature was turned on)
         PrintConv => {
             0 => 'Off',
@@ -275,11 +887,959 @@
         },
     },
+    # 0x200c - int32u[3]: '0 0 0'; seen '2 1 0' for HX9V 3D-Image (in both JPG and MPO image)
+    # 0x200d - rational64u: 10/10, seen 2.5 for DSC-TX300V, 8 for DSC-HX100V/RX10
+    0x200e => { #PH (HX20V)
+        Name => 'PictureEffect',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Toy Camera', #JR (A35)
+            2 => 'Pop Color', # (also A35/NEX-C3, ref JR)
+            3 => 'Posterization', #JR (A35)
+            4 => 'Posterization B/W', #JR (A35)
+            5 => 'Retro Photo', #JR (A35, NEX-5)
+            6 => 'Soft High Key', # (also A65V, A35/NEX-C3 call this "High-key", ref JR)
+            7 => 'Partial Color (red)', #JR (A35)
+            8 => 'Partial Color (green)', #JR (A35, NEX-5)
+            9 => 'Partial Color (blue)', #JR (A35)
+            10 => 'Partial Color (yellow)', #JR (A35, NEX-5)
+            13 => 'High Contrast Monochrome', #JR (A35)
+            16 => 'Toy Camera (normal)', # (also A65, ref JR)
+            17 => 'Toy Camera (cool)', # (RX100)
+            18 => 'Toy Camera (warm)', # (RX100)
+            19 => 'Toy Camera (green)', # (RX100)
+            20 => 'Toy Camera (magenta)', # (RX100)
+            32 => 'Soft Focus (low)', #JR (RX100)
+            33 => 'Soft Focus', #JR (A65V)
+            34 => 'Soft Focus (high)', # (RX100)
+            48 => 'Miniature (auto)', #JR (A65V/NEX-7, horizontal)
+            49 => 'Miniature (top)', # (RX100)
+            50 => 'Miniature (middle horizontal)', # (WX100/HX20V, horizontal)
+            51 => 'Miniature (bottom)', # (WX100, rotate 90 CW)
+            52 => 'Miniature (left)', # (RX100)
+            53 => 'Miniature (middle vertical)', # (RX100)
+            54 => 'Miniature (right)', # (RX100)
+            64 => 'HDR Painting (low)', # (RX100)
+            65 => 'HDR Painting', # (also A65V, ref JR)
+            66 => 'HDR Painting (high)', # (RX100)
+            80 => 'Rich-tone Monochrome', # (also A65V, ref JR)
+            97 => 'Water Color', # (HX200V)
+            98 => 'Water Color 2',
+            112 => 'Illustration (low)', # (RX100)
+            113 => 'Illustration', # (RX100)
+            114 => 'Illustration (high)', # (RX100)
+        },
+    },
+    0x200f => { #PH (RX100)
+        Name => 'SoftSkinEffect',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Mid',
+            3 => 'High',
+            # 0x10001 - seen (ref JR)
+            # 0x10002 - seen for landscape and portrait flash (ref JR)
+            # 0x10003 - seen (ref JR)
+            0xffffffff => 'n/a', # (A35)
+        },
+    },
+    0x2010 => [ #JR
+        # different camera models have similar content but at different offsets, appears to correlate with:
+        # 0x1206 - 0x1207 deciphered (0x1205 changes with firmware version):
+        #   ad c3 - NEX-5N
+        # 0x0192 - 0x0193 deciphered (0x0191 changes with firmware version):
+        #   91 c3 - NEX-VG20E
+        #   93 c3 - NEX-7, SLT-A65V/A77V
+        #   94 c3 - Hasselblad Lunar
+        # 0x0012 - 0x0013 deciphered (0x0011 changes with firmware version):
+        #   94 c3 - SLT-A37/A57, NEX-F3
+        #   95 d3 - DSC-WX50, WX70
+        #   98 c3 - DSC-HX200V, HX20V, HX30V, TX200V, TX300V
+        #   98 d3 - DSC-HX10V, TX66, WX100, WX150
+        #   9a c3 - DSC-RX1, RX1R
+        #   9b c3 - SLT-A99V, Hasselblad HV
+        #   9c c3 - NEX-VG30E
+        #   9d c3 - DSC-RX100, Hasselblad Stellar
+        #   9e c3 - NEX-VG900, SLT-A58
+        #   a1 d3 - DSC-TX30
+        #   a2 d3 - DSC-WX60, WX80, WX200, WX300
+        #   a3 c3 - NEX-6, DSC-HX300, HX50V
+        #   a4 c3 - NEX-3N/5R/5T, ILCE-3000/3500
+        # 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-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/7C/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M6/RX100M5A/RX100M7/HX99
+        # July 2020: ILCE-7SM3 doesn't write this tag anymore
+    {
+        Name => 'Tag2010a', # ad
+        Condition => '$$self{Model} =~ /^NEX-5N$/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010a' },
+    },{
+        Name => 'Tag2010b', # 91, 93
+        Condition => '$$self{Model} =~ /^(SLT-A(65|77)V?|NEX-(7|VG20E)|Lunar)$/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010b' },
+    },{
+        Name => 'Tag2010c', # 94
+        Condition => '$$self{Model} =~ /^(SLT-A(37|57)|NEX-F3)$/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010c' },
+    },{
+        Name => 'Tag2010d', # 95, 98
+        Condition => q{
+            $$self{Model} =~ /^(DSC-(HX10V|HX20V|HX30V|HX200V|TX66|TX200V|TX300V|WX50|WX70|WX100|WX150))$/ and
+            not $$self{Panorama}
+        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010d' },
+    },{
+        Name => 'Tag2010e', # 9a, 9b, 9c, 9d, 9e, a1, a2, a3, a4
+        Condition => q{
+            $$self{Model} =~ /^(SLT-A99V?|HV|SLT-A58|ILCE-(3000|3500)|NEX-(3N|5R|5T|6|VG900|VG30E)|DSC-(RX100|RX1|RX1R)|Stellar)$/ or
+            ($$self{Model} =~ /^(DSC-(HX300|HX50|HX50V|TX30|WX60|WX80|WX200|WX300))$/ and not $$self{Panorama})
+        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010e' },
+    },{
+        Name => 'Tag2010f', # ?
+        Condition => '$$self{Model} =~ /^(DSC-(RX100M2|QX10|QX100))$/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010f' },
+    },{
+        Name => 'Tag2010g', # ?
+        Condition => '$$self{Model} =~ /^(DSC-(QX30|RX10|RX100M3|HX60V|HX350|HX400V|WX220|WX350)|ILCE-(7(R|S|M2)?|[56]000|5100|QX1)|ILCA-(68|77M2))\b/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010g' },
+    },{
+        Name => 'Tag2010h', # ?
+        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-(6100|6400|6600|7C|7M3|7RM3|7RM4|9|9M2)|DSC-(RX10M4|RX100M6|RX100M5A|RX100M7|HX99|RX0M2)|ZV-1)\b/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag2010i' },
+    },{
+        Name => 'Tag_0x2010',
+        %unknownCipherData,
+    }],
+    0x2011 => { #PH (A77, NEX-5N)
+        Name => 'VignettingCorrection',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Off',
+            2 => 'Auto',
+            0xffffffff => 'n/a', # (RX100)
+        },
+    },
+    0x2012 => { #PH (A77, NEX-5N)
+        Name => 'LateralChromaticAberration',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Off',
+            2 => 'Auto',
+            0xffffffff => 'n/a', # (RX100)
+        },
+    },
+    0x2013 => { #PH (A77, NEX-5N) ("Setting"; application of such correction is indicated in Tag9405 - ref JR)
+        Name => 'DistortionCorrectionSetting',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Off',
+            2 => 'Auto',
+            0xffffffff => 'n/a', # (RX100)
+        },
+    },
+    0x2014 => { #JR/9
+        Name => 'WBShiftAB_GM',
+        Writable => 'int32s',
+        Count => 2,
+        Notes => q{
+            2 numbers: 1. positive is a shift toward amber, 2. positive is a shift
+            toward magenta
+        },
+    },
+    # 0x2015 - int16u: 65535, also for 'normal' HDR images; 0 for HDR-paint and Rich-tone Monochrome effect images
+    0x2016 => { #PH (RX100)
+        Name => 'AutoPortraitFramed',
+        Writable => 'int16u',
+        Notes => '"Yes" if this image was created by the Auto Portrait Framing feature',
+        PrintConv => { 0 => 'No', 1 => 'Yes' },
+    },
+    # 0x2017 - int32u: flash mode. 0=off, 1=fired, 2=red-eye (PH, NEX-6) (also in A99, RX1, NEX-5R)
+    0x2017 => { #JR
+        Name => 'FlashAction',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Did not fire',
+            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
+    # 0x2019 - 0 or 1 (seen 1 for ILCA-77M2, ILCE-7M2/7RM2)
+    # 0x201a - 0 or 1
+    0x201a => { #JR
+        Name => 'ElectronicFrontCurtainShutter',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x201b => { #PH
+        # 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|RX100M7|RX100M5A|HX99|RX0M2)/)',
+        Writable => 'int8u',
+        Priority => 0,
+        PrintConv => {
+            0 => 'Manual',
+            2 => 'AF-S',
+            3 => 'AF-C',
+            4 => 'AF-A',
+            6 => 'DMF', # "Direct Manual Focus"
+            7 => 'AF-D', # "Depth Map Assist Continuous AF"
+        },
+    },
+    0x201c => [ #JR
+        # AFAreaModeSetting 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
+        # all DSLR/SLT/HV         Wide  Zone Spot   Local
+        # all NEX and ILCE-3000   Multi      Center FlexibleSpot
+        # all ILCE and ILCA       Wide  Zone Center FlexibleSpot  ExpandedFlexibleSpot
+        # (actual AFAreaMode used may be different as camera can override this under certain conditions)
+        {
+            Name => 'AFAreaModeSetting',
+            Condition => '$$self{Model} =~ /^(SLT-|HV)/',
+            Notes => 'SLT models',
+            Writable => 'int8u',
+            PrintConv => {
+                0 => 'Wide',
+                4 => 'Local',
+                8 => 'Zone', #PH
+                9 => 'Spot',
+            },
+        },{
+            Name => 'AFAreaModeSetting',
+            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',
+            Writable => 'int8u',
+            PrintConv => {
+                0 => 'Wide', # all NEX and ILCE-3000/3500 use the name 'Multi'
+                1 => 'Center',
+                3 => 'Flexible Spot',
+                4 => 'Flexible Spot (LA-EA4)', # seen for ILCE-7RM2 with LA-EA4
+                9 => 'Center (LA-EA4)', # seen for ILCE-7RM2 with LA-EA4
+                11 => 'Zone',
+                12 => 'Expanded Flexible Spot',
+            },
+        },{
+            Name => 'AFAreaModeSetting',
+            Condition => '$$self{Model} =~ /^ILCA-/',
+            Notes => 'ILCA models',
+            RawConv => '$$self{AFAreaILCA} = $val',
+            DataMember => 'AFAreaILCA',
+            Writable => 'int8u',
+            PrintConv => {
+                0 => 'Wide',
+                4 => 'Flexible Spot',
+                8 => 'Zone',
+                9 => 'Center',
+                12 => 'Expanded Flexible Spot',
+            },
+        },
+    ],
+    0x201d => { #JR
+        # Flexible Spot position for NEX/ILCE, non-zero only when AFAreaMode='Flexible Spot'
+        #    from 2018: at least DSC-RX10M4 and RX100M6 also use this tag
+        # 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|RX100M7|RX100M5A|HX99|RX0M2))/',
+        Writable => 'int16u',
+        Count => 2,
+        Notes => q{
+            X and Y coordinates of the AF point, valid only when AFAreaMode is Flexible
+            Spot
+        },
+    },
+    0x201e => [{ #PH (A99)
+        # Selected AF Point for SLT/HV/ILCA or ILCE with LA-EA2/EA4
+        # Selected AF Zone for NEX/ILCE/ILCA when AFAreaMode = 'Zone',
+        #      but also with Expanded Flexible Spot for ILCE-7RM2/7SM2/9 ...
+        # doesn't seem to apply to DSC models (always 0)
+        Name => 'AFPointSelected',
+        Condition => q{
+            ($$self{Model} =~ /^(SLT-|HV)/) or ($$self{Model} =~ /^ILCE-/ and
+            defined $$self{AFAreaILCE} and  $$self{AFAreaILCE} == 4)
+        },
+        Notes => 'SLT models or ILCE with LA-EA2/EA4',
+        Writable => 'int8u',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Auto', #(NC)
+            1 => 'Center',
+            2 => 'Top',
+            3 => 'Upper-right',
+            4 => 'Right',
+            5 => 'Lower-right',
+            6 => 'Bottom',
+            7 => 'Lower-left',
+            8 => 'Left',
+            9 => 'Upper-left',
+            10 => 'Far Right',
+            11 => 'Far Left',
+            12 => 'Upper-middle',
+            13 => 'Near Right',
+            14 => 'Lower-middle',
+            15 => 'Near Left',
+            16 => 'Upper Far Right',
+            17 => 'Lower Far Right',
+            18 => 'Lower Far Left',
+            19 => 'Upper Far Left',
+        },
+    },{
+        Name => 'AFPointSelected',
+        Condition => '$$self{Model} =~ /^ILCA-(68|77M2)/ and defined $$self{AFAreaILCA} and $$self{AFAreaILCA} != 8',
+        Notes => 'ILCA-68 and ILCA-77M2',
+        Writable => 'int8u',
+        ValueConv => '$val - 1', # to get the same numbers as from the BITMASK in 0x2020
+        ValueConvInv => '$val + 1',
+        PrintConvColumns => 5,
+        PrintConv => {
+            -1 => 'Auto',
+            %afPoints79,
+            39 => 'E6 (Center)', # (add " (Center)" to central point)
+        },
+    },{
+        Name => 'AFPointSelected',
+        Condition => '($$self{Model} =~ /^ILCA-99M2/ and defined $$self{AFAreaILCA} and $$self{AFAreaILCA} != 8)',
+        Notes => 'ILCA-99M2 when AFAreaModeSetting is not Zone',
+        # (appears to indicate the number of the selectable Focal Plane AF Point)
+        Writable => 'int8u',
+        PrintConvColumns => 4,
+        PrintConv => {
+            0 => 'Auto',                # seen for AFAreaModeSetting = Center, Wide
+            %afPoints99M2,              # for selected AFPoints corresponding to the 79 dedicated AF points
+            162 => 'E6 (162, Center)',  # add " (Center)" to central point
+            OTHER => sub { shift },     # pass other values straight through
+        },
+    },{
+        Name => 'AFPointSelected',
+        Condition => '($$self{Model} =~ /^ILCA-/ and defined $$self{AFAreaILCA} and $$self{AFAreaILCA} == 8)',
+        Notes => 'ILCA models when AFAreaModeSetting is set to Zone',
+        # ILCA-68 and 77M2 have 9 Zones: numbers/locations verified for ILCA-77M2
+        # ILCA-99M2 has 15 Zones in Hybrid-AF and 9 Zones in dedicated Phase AF Area, so may not be valid for ILCA-99M2...
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Top Left Zone',
+            2 => 'Top Zone',
+            3 => 'Top Right Zone',
+            4 => 'Left Zone',
+            5 => 'Center Zone',
+            6 => 'Right Zone',
+            7 => 'Bottom Left Zone',
+            8 => 'Bottom Zone',
+            9 => 'Bottom Right Zone',
+          #14 => ' ??? ', # seen for ILCA-99M2
+        },
+    },{
+        Name => 'AFPointSelected',
+        # non-zero only when AFAreaMode is 'Zone', and 'Expanded-Flexible-Spot' for ILCE-6300/7RM2/7SM2
+        # each Zone has 3x3 AF Areas --> 9 positions within 5x5 total Contrast AF Areas
+        Condition => '$$self{Model} =~ /^(NEX-|ILCE-)/',
+        Notes => 'NEX and ILCE models',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Center Zone',
+            2 => 'Top Zone',
+            3 => 'Right Zone',
+            4 => 'Left Zone',
+            5 => 'Bottom Zone',
+            6 => 'Bottom Right Zone',
+            7 => 'Bottom Left Zone',
+            8 => 'Top Left Zone',
+            9 => 'Top Right Zone',
+        },
+    }],
+    # 0x201f - 0 0 0 0 for SLT and DSC; 4 values for NEX/ILCE with 4th value always 0:
+    # possibly bits relating to the 25 AF-Contrast-areas ???
+    # 0x2020 - 10 values; for SLT/ILCA and NEX/ILCE with A-mount lens: relates to (phase-detect) AFPoints
+    #          but not used by ILCA-99M2 anymore ... ?
+    0x2020 => [{
+        Name => 'AFPointsUsed',
+        Condition => '$$self{Model} !~ /^(ILCA-|DSC-)/', # (doesn't seem to apply to DSC-models)
+        Notes => 'SLT models, or NEX/ILCE with A-mount lenses',
+        BitsPerWord => 8,
+        BitsTotal => 80,
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => {
+                0 => 'Center',
+                1 => 'Top',
+                2 => 'Upper-right',
+                3 => 'Right',
+                4 => 'Lower-right',
+                5 => 'Bottom',
+                6 => 'Lower-left',
+                7 => 'Left',
+                8 => 'Upper-left',
+                9 => 'Far Right',
+                10 => 'Far Left',
+                11 => 'Upper-middle',
+                12 => 'Near Right',
+                13 => 'Lower-middle',
+                14 => 'Near Left',
+                15 => 'Upper Far Right',
+                16 => 'Lower Far Right',
+                17 => 'Lower Far Left',
+                18 => 'Upper Far Left',
+            },
+        },
+    },{
+        Name => 'AFPointsUsed',
+        Condition => '$$self{Model} =~ /^ILCA-(68|77M2)/',
+        Notes => 'ILCA models',
+        BitsPerWord => 8,
+        BitsTotal => 80,
+        PrintConvColumns => 4,
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => { %afPoints79 },
+        },
+    }],
+    # 0x2021 - 0 for DSC; 0, 1 or 2 for SLT/ILCA and NEX/ILCE: 1=Face, 2=object-tracking ?
+    #    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|RX100M7|RX100M5A|HX99|RX0M2)/)',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Face tracking',
+            2 => 'Lock On AF',
+        },
+    },
+    # 0x2022 - 13 bytes (104 bits) for SLT-A58/A99V, NEX-3N/5R/5T/6/VG30E/VG900, ILCE-3000/3500/5000/7/7R
+    #          26 bytes (208 bits) for ILCA-77M2, ILCE-5100/6000/7M2/7S/QX1 (7M2 has 117, 5100/6000 have 179 PhaseAFPoints)
+    #          52 bytes (416 bits) for ILCE-7RM2 (which has 399 PhaseAFPoints) and ILCE-7SM2
+    #          Only seen non-zero values for ILCE-5100/6000/7M2/7RM2 in AF-C mode: maybe FocalPlaneAFPointsUsed ???
+    #          (Similar number of bytes for contemporary DSC models, but mostly all non-zero values.)
+    #          ILCE-6300 does not write this tag anymore, but writes 0x202a ...
+    0x2022 => [{
+        Name => 'FocalPlaneAFPointsUsed',
+        Condition => '$$self{Model} =~ /^(ILCE-(5100|6000|7M2))/',
+        Notes => 'On-sensor/focal-plane phase AF points for ILCE with hybrid AF',
+        BitsPerWord => 8,
+        BitsTotal => 208, # 26 words
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => { },
+        },
+    },{
+        Name => 'FocalPlaneAFPointsUsed',
+        Condition => '$$self{Model} =~ /^ILCE-7RM2/',
+        # ILCE-7RM2 has 399 points in 19 rows of 21 points, numbered [0] to [398], [199] is Center
+        BitsPerWord => 8,
+        BitsTotal => 416, # 52 words
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => { },
+        },
+    }],
+    0x2023 => { #JR
+        Name => 'MultiFrameNREffect',
+        Writable => 'int32u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'High', # seen this only for ILCA-77M2 MFNR-12 images
+        },
+    },
+    # 0x2024 - 96 byte data block, very similar to 0x3000 ShotInfo, seen in Xperia Z5
+    # 0x2025 - n1 n2 0 0         DSC-RX100M3/RX100M4/RX10M2/HX90V/WX500, ILCA-77M2, ILCE-5100/7M2/7RM2/7S/QX1
+    #          seen n1=0,2,4,5,7 and n2=0,1,3, very often: 7 3 0 0
+
+    # 0x2026 - 2 values: more precise WB Shift: AB in steps of 0.50, GM in steps of 0.25 (ILCE-7RM2 onwards)
+    0x2026 => { #JR
+        Name => 'WBShiftAB_GM_Precise',
+        Writable => 'int32s',
+        Count => 2,
+        Notes => q{
+            2 numbers: 1. positive is a shift toward amber, 2. positive is a shift
+            toward magenta
+        },
+        PrintConv => 'my @v=split(" ",$val); $_/=1000 foreach @v; sprintf("%.2f %.2f",$v[0],$v[1])',
+    },
+    # 0x2027 - W H W/2 H/2  or  W H val1 val2  (0 0 0 0 for Panorama images)
+    #          Probably location of focus for Playback Zoom.
+    #          Origin appears to be top-left, i.e. 1st coord to the right, 2nd coord. pointing down.
+    0x2027 => { #JR
+        Name => 'FocusLocation', #(NC)
+        Writable => 'int16u',
+        Count => 4,
+        NOTES => q{
+            Location in the image where the camera focused, used for Playback Zoom.
+            If the focus location information cannot be obtained, the centre of the
+            image will be used.
+        },
+    },
+    # 0x2028 - 0 0 for DSC-RX100M4/RX10M2, ILCE-7RM2/7SM2; seen non-zero values only for DSC-RX1RM2
+    0x2028 => { #JR
+        Name => 'VariableLowPassFilter',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'n/a',
+            '1 0' => 'Off',
+            '1 1' => 'Standard',
+            '1 2' => 'High',
+            '65535 65535' => 'n/a', # ILCE-7SM3
+        },
+    },
+    0x2029 => { # uncompressed 14-bit RAW file type setting introduced 2015
+        Name => 'RAWFileType',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Compressed RAW',
+            1 => 'Uncompressed RAW',
+            2 => 'Lossless Compressed RAW', #JR (NC) seen for ILCE-1
+           65535 => 'n/a', # seen for ILCE-7SM3 JPEG-only
+        },
+    },
+    # 0x202a - first seen for ILCE-6300: 66 bytes
+    #          possibly a 'replacement' for Tag2022 FocalPlaneAFPointsUsed,
+    #          but now indicating locations in a 640x428 grid (3:2 part of LCD ?)
+    # first byte value 1 for ILCE-6300/6500/9, ILCA-99M2
+    #            values 110,137, ... for DSC-RX10M3, therefore limit to first byte = 1 for now
+    0x202a => {
+        Name => 'Tag202a',
+        Condition => '$$valPt =~ /^\x01/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag202a' },
+    },
+    0x202b => { #JR (ILCA-99M2, ILCE-6500/7M3/7RM3/9, DSC-RX10M4/RX100M5 and newer)
+        Name => 'PrioritySetInAWB',
+        Writable => 'int8u',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Ambience',
+            2 => 'White',
+        },
+    },
+    0x202c => { #JR
+        Name => 'MeteringMode2',
+        Writable => 'int16u',
+        PrintHex => 1,
+        PrintConv => {
+            0x100 => 'Multi-segment',
+            0x200 => 'Center-weighted average',
+            0x301 => 'Spot (Standard)',
+            0x302 => 'Spot (Large)',
+            0x400 => 'Average',
+            0x500 => 'Highlight',
+        },
+    },
+    0x202d => { #JR first seen for ILCA-99M2, ILCE-6500, DSC-RX100M5
+        Name => 'ExposureStandardAdjustment',
+        Writable => 'rational64s',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    0x202e => { #JR (ILCE-7M3/7RM3 and newer)
+        Name => 'Quality',
+        Writable => 'int16u',
+        Count => 2,
+        PrintConv => {
+            '0 0' => 'n/a',
+            '0 1' => 'Standard JPEG',
+            '0 2' => 'Fine JPEG',
+            '0 3' => 'Extra Fine JPEG',
+            '1 0' => 'RAW',
+            '1 1' => 'RAW + Standard JPEG',
+            '1 2' => 'RAW + Fine JPEG',
+            '1 3' => 'RAW + Extra Fine JPEG',
+        },
+    },
+    0x202f => { #JR (ILCE-7RM3)
+        Name => 'PixelShiftInfo',
+        Writable => 'undef',
+        # 6 bytes, all 0 for non-PixelShift images
+        # 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) 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);
+        },
+        RawConvInv => q{
+            my ($a,$b,$c,$d) = split ' ', $val;
+            my @a = $a =~ /../g;
+            return undef unless @a == 4;
+            return Set32u((hex($d)<<22) | ($a[0]<<17) | ($a[1]<<12) | ($a[2]<<6) | $a[3]) . chr($b) . chr($c);
+        },
+        PrintConv => {
+            '00000000 0 0 0x0' => 'n/a',
+            OTHER => sub {
+                my ($val, $inv) = @_;
+                if ($inv) {
+                    $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 0+/0*(\d+)\b}{Composed $1-shot}i;
+                }
+                return $val;
+            },
+        },
+    },
+    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',
+        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',
+    },
+# 0x2032 - first seen for ILCE-7SM3, July 2020
+# 0x2033 - first seen for ILCE-7SM3, July 2020
+# 0x2034 - first seen for ILCE-7SM3, July 2020
+# 0x2035 - first seen for ILCE-7SM3, July 2020
+# 0x2036 - first seen for ILCE-7SM3, July 2020
+# 0x2037 - first seen for ILCE-7SM3, July 2020
+# 0x2039 - first seen for ILCE-7SM3, July 2020
     0x3000 => {
         Name => 'ShotInfo',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::ShotInfo' },
+    },
+    # 0x3000: data block that includes DateTimeOriginal string
+    # 0x5001 - 0
+    # 0x5002 - 128
+#
+# at least some data for tags 0x2010, 0x9050 and 0x94xx is encrypted - PH
+# (This is certainly true for at least parts of 0x2010, 0x9050, 0x9400, 0x9402 and 0x9403,
+# but hasn't been verified for other tags -- just to be thorough, decipher all of them)
+# Note: "(e)" in a comment indicates an enciphered value, all other values are deciphered
+#
+    # 0x900b - 1st byte 0xae: face detection info for A450/500/550/560/580, A33/35/55, NEX-3/5/5C/C3/VG10
+    #        - other 1st byte values for some DSC-models
+    #        - seen many 1,8,27,64... values: assume encrypted like other 9xxx tags
+    0x900b => {
+        Name => 'Tag900b',
+        Condition => '$$valPt =~ /^\xae/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag900b' },
+    },
+    0x9050 => [
+    # 944 bytes for A37, A57, A99, NEX-F3, NEX-5R, NEX-6, DSC-RX1, DSC-RX100
+    # 3072 bytes for A65, A77, NEX-5N, NEX-7, NEX-VG20 (ref JR)
+    # not valid for DSC/Stellar models
+    # from mid-2015: ILCE-7RM2/7SM2/6300 and newer models use different offsets
+    {
+        Name => 'Tag9050a',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar|ILCE-(1|6100|6300|6400|6500|6600|7C|7M3|7RM2|7RM3|7RM4|7SM2|7SM3|9|9M2)|ILCA-99M2|ZV-)/',
         SubDirectory => {
-            TagTable => 'Image::ExifTool::Sony::ShotInfo',
-        },
-    },
-    # 0x3000: data block that includes DateTimeOriginal string
+            TagTable => 'Image::ExifTool::Sony::Tag9050a',
+            ByteOrder => 'LittleEndian',
+        },
+    },{
+        Name => 'Tag9050b',
+        Condition => '$$self{Model} =~ /^(ILCE-(6100|6300|6400|6500|6600|7C|7M3|7RM2|7RM3|7RM4|7SM2|9|9M2)|ILCA-99M2)/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sony::Tag9050b',
+            ByteOrder => 'LittleEndian',
+        },
+    },{
+        Name => 'Tag9050c',
+        Condition => '$$self{Model} =~ /^(ILCE-(1|7SM3))/',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Sony::Tag9050c',
+            ByteOrder => 'LittleEndian',
+        },
+    },{
+        Name => 'Sony_0x9050',
+        %unknownCipherData,
+    }],
+    0x9400 => [
+    # first byte:
+    # 0x07 (e) for DSC-HX7V/HX9V/HX100V/TX10/TX100/TX100V/WX7/WX9/WX10, HDR-CX../PJ..
+    # 0x09 (e) for DSC-TX20/TX55/WX30
+    # 0x0a (e) for SLT-A37/A57/A65V/A77V/A99V, NEX-F3/5N/5R/5T/6/7/VG20E, DSC-RX100/RX1/RX1R/HX10V/HX20V/HX30V/HX200V/TX200V/TX300V/TX66/WX50/WX100/WX150, Lunar/Stellar/HV
+    # 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-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, ZV-1
+    # 0x31 (e) for ILCE-1, 7SM3
+    # first byte decoded: 40, 204, 202, 27, 58, 62, 48, 215, 28, 106 respectively
+    {
+        Name => 'Tag9400a',
+        Condition => q{
+            $$valPt =~ /^[\x07\x09\x0a]/ or
+           ($$valPt =~ /^[\x5e\xe7\x04]/ and $$self{DoubleCipher} = 1)
+        },
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9400a' },
+    },{
+        Name => 'Tag9400b',
+        Condition => '$$valPt =~ /^\x0c/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9400b' },
+    },{
+        Name => 'Tag9400c',
+        Condition => '$$valPt =~ /^[\x23\x24\x26\x28\x31]/', 
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9400c' },
+    },{
+        Name => 'Sony_0x9400',
+        %unknownCipherData,
+    }],
+    0x9401 => {
+        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
+        #                  Mode
+        #   f4 00 00 03      -        -   DSC-H90/W650/W690
+        #   cf 0b 9f 0f    0x09bc    (a)  DSC-WX9
+        #   1c 00 ac 0f    0x09c9    (b)  HDR-CX130E/CX160E/CX360E/CX560E/CX700E/PJ10E/PJ30E
+        #   b7 0f f7 0f    0x09dd    (c)  DSC-HX7V/TX10/WX7/WX10
+        #   b7 0f fa 0f    0x09e0    (d)  DSC-HX9V/HX100V/TX100/TX100V
+        #   27 00 fd 0f    0x09e7    (e)  DSC-TX20/TX55/WX30
+        #   69 1f ff 0f    0x09e9    (f)  NEX-5N
+        #   21 2b cf 0f    0x09e9    (f)  NEX-7/VG20E, SLT-A65V/A77V, Lunar
+        #   2d 00 d5 0d    0x09a2    (g)  DSC-HX10V/HX20V/HX30V/HX200V/TX66/TX200V/TX300V/WX50/WX70/WX100/WX150
+        #   2f 00 d6 0d    0x09a3    (h)  NEX-F3, SLT-A37/A57
+        #   30 00 d8 0d    0x09a5    (i)  HDR-AS15
+        #   32 00 e2 0d    0x09ac    (j)  DSC-RX100, Stellar
+        #   33 00 e2 0d    0x09ac    (j)  NEX-5R/5T/6, NEX-VG900/VG30E
+        #   33 50 e2 0d    0x09ac    (j)  SLT-A99V, HV
+        #   33 40 0d 0e    0x09d7    (k)  DSC-RX1 v0.01
+        #   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
+        #   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
+        #   44 00 9c 0e    0x0a39    (o)  ILCE-6000 v1.00/v1.10, DSC-HX60V/HX350/HX400V/WX220/WX350 (also DSC-QX30 samples from sony.net)
+        #   44 10 a2 0e    0x0a39    (o)  ILCE-6000 v1.20/v1.21
+        #   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.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-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
+        #   5d 10 56 0f    0x0ac7    (t)  ILCE-6300 v1.00 (samples from Sony)
+        #   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.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/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 => {
+        #     Name => 'DynamicRangeOptimizer_9401',
+        #     PrintConv => {
+        #         0 => 'Disabled', # seen for Panorama images
+        #         1 => 'Auto',
+        #         3 => 'Lv1', #(NC)
+        #         4 => 'Lv2', #(NC)
+        #         5 => 'Lv3',
+        #         6 => 'Lv4',
+        #         7 => 'Lv5',
+        #         # 8 - seen for VG20E and some other models - PH
+        #         255 => 'Off',
+        #     },
+        # },
+    },
+    0x9402 => [{
+        Name => 'Tag9402',
+        # first 2 bytes deciphered:
+        #   0x00      0x00     SLT-A37/A57/A65/A77
+        #   0x0e      0x00     DSC-H90/HX7V/HX9V/HX100V/TX10/TX100/TX100V/TX20/TX55/W650/W690/W730/WX10/WX30/WX7/WX9, but also seen:
+        #     0x0e      0x01     for a few DSC-W650/W690 samples ...
+        #   0x0f      0x01     NEX-5N/7/VG20, Lunar
+        #   0x10      0x01     DSC-HX10V/HX200V/HX20V/HX300/HX30V/HX50V/TX200V/TX30/TX300V/TX66/RX100/RX1/RX1R/WX100/WX150/WX200/WX300/WX50/WX60/WX70/WX80, Stellar,
+        #                      ILCE-3000/3500, NEX-F3/3N/5R/5T/6/VG30/VG900
+        #   0x11      0x01     DSC-RX100M2/QX10/QX100
+        #   0x13      0x01     ILCE-5000/7/7R, DSC-RX10, but also seen:
+        #     0x12      0x01     for ILCE-7/7R and DSC-RX10 samples from Sony.net ...
+        #     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-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-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/',
+# alternative simpler Condition:
+# not valid for SLT/HV/ILCA models, and not valid for first byte 0x0e or 0xff (enciphered 0x05 or 0xff)
+        Condition => '$$self{Model} !~ /^(SLT-|HV|ILCA-)/ and $$valPt !~ /^[\x05\xff]/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9402' },
+    },{
+        Name => 'Sony_0x9402',
+        %unknownCipherData,
+    }],
+    0x9403 => {
+        Name => 'Tag9403',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9403' },
+    },
+    # 0x9404 first 5 bytes (deciphered):
+    #  4  0  163  1  2     SLT-A65V/A77V, NEX-5N/7, Lunar, DSC-HX7V/HX9V/HX100V/TX10/TX20/TX55/TX100/TX100V/WX9/WX10/WX30...
+    #  5  0  172  1  2     DSC-HX10V/HX200V/HX20V/HX30V/TX66/TX200V/TX300V/WX50/WX70/WX100/WX150...
+    #  9  0   38  2  2     SLT-A37/A57/A99V, NEX-5R/5T/6/F3/VG30E/VG900, DSC-RX1/RX1R/RX100, Stellar
+    # 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-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/7C/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2, ILCA-99M2, ZV-1
+    # 18  0   20  0 164    ILCE-7SM3 
+    # other values for Panorama images and several other models
+    0x9404 => [{
+        Name => 'Tag9404a',
+        # first byte must be 4 or 5 and 4th byte must be 1 (deciphered)
+        Condition => '$$valPt =~ /^[\x40\x7d]..\x01/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9404a' },
+    },{
+        Name => 'Tag9404b',
+        # first byte must be 9 or 12 or 13 or 15 or 16 and 4th byte must be 2 (deciphered)
+        Condition => '$$valPt =~ /^[\xe7\xea\xcd\x8a\x70]..\x08/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9404b' },
+    },{
+        Name => 'Tag9404c',
+        # first byte must be 17 and 4th byte must be 1 (deciphered)
+        Condition => '$$valPt =~ /^\xb6..\x01/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9404c' },
+    },{
+        Name => 'Sony_0x9404',
+        %unknownCipherData,
+    }],
+    # 0x9405 first 2 bytes:
+    #   0   0  (0x00 =   0   0 enc.) DSC-H90
+    #   2   0  (0x08 =   8   0 enc.) DSC and HDR of HX9V generation
+    #   3   0  (0x1b =  27   0 enc.) SLT, NEX, ILCE-3000/3500, DSC-RX100/RX1 + other DSC of same generation, also QX10 and QX100
+    #   4   0  (0x40 =  64   0 enc.) DSC-RX1R
+    #   5   0  (0x7d = 125   0 enc.) DSC-RX100M2
+    # 136 var  (0x3a =  58 var enc.) ILCE-7/7R/5000/6000, DSC-HX60V/HX350/HX400V/RX10/WX220/WX350
+    # 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-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-6100/6400/6600/7C/7M3/7RM3/7RM4/9/9M2, DSC-RX0M2/RX10M4/RX100M5A/RX100M6/RX100M7/HX99, ZV-1
+    # July 2020: ILCE-7SM3 doesn't write this tag anymore, but writes 0x9416
+    0x9405 => [{
+        Name => 'Tag9405a',
+        # first byte must be 0x1b or 0x40 or 0x7d
+        Condition => '$$valPt =~ /^[\x1b\x40\x7d]/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9405a' },
+    },{
+        Name => 'Tag9405b',
+        # first byte must be 0x3a, 0xb3, 0x7e, 0x9a, 0x25, 0xe1, 0x76 or 0x8b
+        Condition => '$$valPt =~ /^[\x3a\xb3\x7e\x9a\x25\xe1\x76\x8b]/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9405b' },
+    },{
+        Name => 'Sony_0x9405',
+        %unknownCipherData,
+    }],
+    0x9406 => [{
+        Name => 'Tag9406',
+        # - 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/ILCA and NEX/ILCE models, but no DSC models)
+        Condition => '$$valPt =~ /^[\x01\x08\x1b].[\x08\x1b]/s',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9406' },
+    },{
+        Name => 'Sony_0x9406',
+        %unknownCipherData,
+    }],
+    0x9407 => {
+        Name => 'Sony_0x9407',
+        %unknownCipherData,
+    },
+    0x9408 => {
+        Name => 'Sony_0x9408',
+        %unknownCipherData,
+    },
+    0x9409 => {
+        Name => 'Sony_0x9409',
+        %unknownCipherData,
+    },
+    0x940a => [{
+        Name => 'Tag940a',
+        Condition => '$$self{Model} =~ /^(SLT-|HV)/', # but appears not valid for ILCA models ...
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag940a' },
+    },{
+        Name => 'Sony_0x940a',
+        %unknownCipherData,
+    }],
+    0x940b => {
+        Name => 'Sony_0x940b',
+        %unknownCipherData,
+    },
+    0x940c => [{
+        Name => 'Tag940c',
+        Condition => '$$self{Model} =~ /^(NEX-|ILCE-|Lunar)\b/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag940c' },
+    },{
+        Name => 'Sony_0x940c',
+        %unknownCipherData,
+    }],
+    0x940d => {
+        Name => 'Sony_0x940d',
+        %unknownCipherData,
+    },
+#   0x940e: 2nd byte = 0: no AFInfo, default for NEX/ILCE
+#           2nd byte = 1: AFInfo for SLT/ILCA models (but also seen 1 for DSC-HX20W/HX300/WX70 ...)
+#           2nd byte = 2: AFInfo for NEX/ILCE with LA-EA2/EA4 Phase-detect AF Adapter
+    0x940e => [{
+        Name => 'AFInfo',
+        Condition => '$$self{Model} =~ /^(SLT-|HV|ILCA-)/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::AFInfo' },
+    },{
+        Name => 'Tag940e',
+        Condition => '$$self{Model} =~ /^(NEX-|ILCE-|Lunar)/',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag940e' },
+    },{
+        Name => 'Sony_0x940e',
+        %unknownCipherData,
+    }],
+    0x940f => {
+        Name => 'Sony_0x940f',
+        %unknownCipherData,
+    },
+    0x9411 => {
+        Name => 'Sony_0x9411',
+        %unknownCipherData,
+        # 0x02 - int32u?: 1,3,5,7,9 (A77)
+    },
+    0x9416 => { # replaces 0x9405 for the Sony ILCE-7SM3, from July 2020
+        Name => 'Sony_0x9416',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Tag9416' },
+    },
     0xb000 => { #8
         Name => 'FileFormat',
@@ -291,4 +1851,5 @@
             return $val;
         },
+        PrintConvColumns => 2,
         PrintConv => {
             '0 0 0 2' => 'JPEG',
@@ -297,14 +1858,21 @@
             '3 0 0 0' => 'ARW 2.0',
             '3 1 0 0' => 'ARW 2.1',
-            '3 2 0 0' => 'ARW 2.2', # (NEX-5)
+            '3 2 0 0' => 'ARW 2.2', #PH (NEX-5)
+            '3 3 0 0' => 'ARW 2.3', #PH (SLT-A65,SLT-A77)
+            '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)
+            '4 0 0 0' => 'ARW 4.0', # (ILCE-7SM3)
             # what about cRAW images?
         },
     },
     0xb001 => { # ref http://forums.dpreview.com/forums/read.asp?forum=1037&message=33609644
-        # (ARW and SR2 images only)
+        # (ARW and SR2 images only until the SLT-A65V started writing them to JPEG too)
         Name => 'SonyModelID',
         Writable => 'int16u',
         PrintConvColumns => 2,
         PrintConv => {
+            #0 => 'DSC-HX80', #PH  (and several other DSC models)
             2 => 'DSC-R1',
             256 => 'DSLR-A100',
@@ -314,4 +1882,5 @@
             260 => 'DSLR-A350',
             261 => 'DSLR-A300',
+            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',
@@ -319,25 +1888,118 @@
             266 => 'DSLR-A290', #PH
             269 => 'DSLR-A850',
+            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)
+            275 => 'DSLR-A450', #http://dev.exiv2.org/issues/show/0000611
             278 => 'NEX-5', #PH
             279 => 'NEX-3', #PH
             280 => 'SLT-A33', #PH
-            281 => 'SLT-A55V', #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
+            287 => 'SLT-A77 / SLT-A77V', #PH
+            288 => 'NEX-5N', #PH
+            289 => 'NEX-7', #PH (also Hasselblad Lunar, ref JR)
+            290 => 'NEX-VG20E', #JR
+            291 => 'SLT-A37', #JR
+            292 => 'SLT-A57', #JR
+            293 => 'NEX-F3', #PH
+            294 => 'SLT-A99 / SLT-A99V', #JR (also Hasselblad HV)
+            295 => 'NEX-6', #JR
+            296 => 'NEX-5R', #JR
+            297 => 'DSC-RX100', #PH (also Hasselblad Stellar, ref JR)
+            298 => 'DSC-RX1', #JR
+            299 => 'NEX-VG900', #JR
+            300 => 'NEX-VG30E', #JR
+            302 => 'ILCE-3000 / ILCE-3500', #JR
+            303 => 'SLT-A58', #JR
+            305 => 'NEX-3N', #PH
+            306 => 'ILCE-7', #JR
+            307 => 'NEX-5T', #JR
+            308 => 'DSC-RX100M2', #JR
+            309 => 'DSC-RX10', #JR
+            310 => 'DSC-RX1R', #JR
+            311 => 'ILCE-7R', #JR
+            312 => 'ILCE-6000', #JR
+            313 => 'ILCE-5000', #JR
+            317 => 'DSC-RX100M3', #JR
+            318 => 'ILCE-7S', #JR
+            319 => 'ILCA-77M2', #IB
+            339 => 'ILCE-5100', #JR
+            340 => 'ILCE-7M2', #JR
+            341 => 'DSC-RX100M4', #PH
+            342 => 'DSC-RX10M2', #JR
+            344 => 'DSC-RX1RM2', #JR
+            346 => 'ILCE-QX1', #IB
+            347 => 'ILCE-7RM2', #JR
+            350 => 'ILCE-7SM2', #JR
+            353 => 'ILCA-68', #IB
+            354 => 'ILCA-99M2', #JR
+            355 => 'DSC-RX10M3', #PH
+            356 => 'DSC-RX100M5', #IB/JR
+            357 => 'ILCE-6300', #IB
+            358 => 'ILCE-9', #JR
+            360 => 'ILCE-6500', #JR
+            362 => 'ILCE-7RM3', #IB
+            363 => 'ILCE-7M3', #JR/IB
+            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
+            380 => 'ZV-1', #JR
+            381 => 'ILCE-7C', #JR
+            383 => 'ILCE-7SM3',
+            384 => 'ILCE-1', #PH
         },
     },
     0xb020 => { #2
-        Name => 'ColorReproduction',
-        # observed values: None, Standard, Vivid, Real, AdobeRGB - PH
+        Name => 'CreativeStyle', # (called CreativeLook by the 7SM3, ref JR)
         Writable => 'string',
+        # (all of these values have been observed, ref JR and PH)
+        # - this PrintConv is included to make these strings consistent with
+        #   other CreativeStyle tags, and to facilitate the language translations
+        # - these values are always English, regardless of the camera language settings
+        PrintConv => {
+            OTHER => sub { shift }, # pass other values straight through
+            None        => 'None',
+            AdobeRGB    => 'Adobe RGB',
+            Real        => 'Real',
+            Standard    => 'Standard',
+            Vivid       => 'Vivid',
+            Portrait    => 'Portrait',
+            Landscape   => 'Landscape',
+            Sunset      => 'Sunset',
+            Nightview   => 'Night View/Portrait',
+            BW          => 'B&W',
+            Neutral     => 'Neutral',
+            Clear       => 'Clear',
+            Deep        => 'Deep',
+            Light       => 'Light',
+            Autumnleaves=> 'Autumn Leaves',
+            Sepia       => 'Sepia',
+            # new for the ILCE-7SM3 (ref JR)
+            VV2 => 'Vivid 2',  # (NC)
+            FL => 'FL', # "moody finish with sharp contrast and calm coloring as well as the impressive sky and colors of the greens"
+            IN => 'IN', # "matte textures by suppressing the contrast and saturation"
+            SH => 'SH', # "bright, transparent, soft, and vivid mood"
+            # (...also Custom Look 1-6, but don't konw the values)
+        },
     },
     0xb021 => { #2
         Name => 'ColorTemperature',
         Writable => 'int32u',
-        PrintConv => '$val ? $val : "Auto"',
-        PrintConvInv => '$val=~/Auto/i ? 0 : $val',
+        PrintConv => '$val ? ($val==0xffffffff ? "n/a" : $val) : "Auto"',
+        PrintConvInv => '$val=~/Auto/i ? 0 : ($val eq "n/a" ? 0xffffffff : $val)',
     },
     0xb022 => { #7
@@ -350,4 +2012,5 @@
         Name => 'SceneMode',
         Writable => 'int32u',
+        PrintConvColumns => 2,
         PrintConv => \%Image::ExifTool::Minolta::minoltaSceneMode,
     },
@@ -364,4 +2027,5 @@
         Name => 'DynamicRangeOptimizer',
         Writable => 'int32u',
+        PrintConvColumns => 2,
         PrintConv => {
             0 => 'Off',
@@ -374,5 +2038,5 @@
             11 => 'Advanced Lv4', #JD
             12 => 'Advanced Lv5', #JD
-            16 => 'Lv1', # (NEX_5)
+            16 => 'Lv1', # (NEX-5)
             17 => 'Lv2',
             18 => 'Lv3',
@@ -384,5 +2048,9 @@
         Name => 'ImageStabilization',
         Writable => 'int32u',
-        PrintConv => { 0 => 'Off', 1 => 'On' },
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+            0xffffffff => 'n/a', # (HX9V sweep panorama, ref JR)
+        },
     },
     0xb027 => { #2
@@ -390,4 +2058,6 @@
         Writable => 'int32u',
         SeparateTable => 1,
+        # set to 65535 for E-mount lenses (values 0x80xx)
+        ValueConvInv => '($val & 0xff00) == 0x8000 ? 65535 : int($val)',
         PrintConv => \%sonyLensTypes,
     },
@@ -407,5 +2077,20 @@
         Name => 'ColorMode',
         Writable => 'int32u',
+        PrintConvColumns => 2,
         PrintConv => \%Image::ExifTool::Minolta::sonyColorMode,
+    },
+    0xb02a => {
+        Name => 'LensSpec',
+        Format => 'undef',
+        Writable => 'int8u',
+        Count => 8,
+        Notes => q{
+            like LensInfo, but also specifies lens features: DT, E, ZA, G, SSM, SAM,
+            OSS, STF, Reflex, Macro and Fisheye
+        },
+        ValueConv => \&ConvLensSpec,
+        ValueConvInv => \&ConvInvLensSpec,
+        PrintConv => \&PrintLensSpec,
+        PrintConvInv => \&PrintInvLensSpec,
     },
     0xb02b => { #PH (A550 JPEG and A200, A230, A300, A350, A380, A700 and A900 ARW)
@@ -443,29 +2128,38 @@
         Writable => 'int16u',
         RawConv => '$val == 65535 ? undef : $val',
-        PrintConv => {
-            0 => 'Auto',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Program AE', # (RX100 'Program','Sunset' - PH)
             1 => 'Portrait', #PH (HX1)
             2 => 'Beach', #9
+            3 => 'Sports', #9
             4 => 'Snow', #9
             5 => 'Landscape',
-            6 => 'Program',
-            7 => 'Aperture Priority',
-            8 => 'Shutter Priority',
+            6 => 'Auto', # (RX100 'Intelligent Auto' - PH)
+            7 => 'Aperture-priority AE',
+            8 => 'Shutter speed priority AE',
             9 => 'Night Scene / Twilight',#2/9
             10 => 'Hi-Speed Shutter', #9
-            11 => 'Twilight Portrait', #9
-            12 => 'Soft Snap', #9
+            11 => 'Twilight Portrait', #9 (RX100 'Night Portrait' - PH)
+            12 => 'Soft Snap/Portrait', #9 (TX7 'Soft Snap'; RX100/A37 'Portrait' but manuals say "reproduces soft skin tone" - PH)
             13 => 'Fireworks', #9
             14 => 'Smile Shutter', #9 (T200)
             15 => 'Manual',
             18 => 'High Sensitivity', #9
+            19 => 'Macro', #JR
             20 => 'Advanced Sports Shooting', #9
             29 => 'Underwater', #9
-            33 => 'Gourmet', #9
-            34 => 'Panorama', #PH (HX1)
-            35 => 'Handheld Twilight', #PH (HX1/TX1)
+            # 30 seen for DSC-W110 and W390, maybe something with Face or Portrait ??
+            33 => 'Food', #9
+            34 => 'Sweep Panorama', #PH (HX1)
+            35 => 'Handheld Night Shot', #PH (HX1/TX1, also called "Hand-held Twilight")
             36 => 'Anti Motion Blur', #PH (TX1)
             37 => 'Pet', #9
             38 => 'Backlight Correction HDR', #9
+            39 => 'Superior Auto', #9
+            40 => 'Background Defocus', #PH (HX20V)
+            41 => 'Soft Skin', #JR (HX9V) (HX200V Portrait - PH)
+            42 => '3D Image', #JR (HX9V)
+            # 50 seen for DSC-W530
             65535 => 'n/a', #PH (A100)
         },
@@ -473,29 +2167,59 @@
     0xb042 => { #9
         Name => 'FocusMode',
+        # Only FocusMode for older DSC models;
+        # Newest DSC models give only 0, many models of 'HX9V generation' give only 4 -
+        # these models give FocusMode in tag 0xb04e, and are excluded here.
+        Condition => q{
+            ($$self{TagB042} = Get16u($valPt, 0)) and
+            (not $$self{MetaVersion} or $$self{MetaVersion} ne 'DC7303320222000')
+        },
+        Notes => 'not valid for all models',
         Writable => 'int16u',
         RawConv => '$val == 65535 ? undef : $val',
         PrintConv => {
+            # 0 - seen this for panorama shot
             1 => 'AF-S', # (called Single-AF by Sony)
             2 => 'AF-C', # (called Monitor-AF by Sony)
-            4 => 'Permanent-AF', # (TX7)
+            4 => 'Permanent-AF', # (TX7,HX9V?)
+            65535 => 'n/a', #PH (A100), also for DSC-W690 panorama shots
+        },
+    },
+    0xb043 => [{ #9
+        Name => 'AFAreaMode',
+        # AFAreaMode only for older models;
+        # exclude newest DSC models, which give AFAreaMode in Tag9402 0x0017 (eg. RX100 - PH)
+        Writable => 'int16u',
+        Condition => 'not $$self{MetaVersion} or $$self{MetaVersion} ne "DC7303320222000"', #JR
+        RawConv => '$val == 65535 ? undef : $val',
+        Notes => 'older models',
+        PrintConv => {
+            # 0 - (takes this value after camera reset, but can't be set back once changed)
+            0 => 'Default',
+            1 => 'Multi',
+            2 => 'Center',
+            3 => 'Spot',
+            4 => 'Flexible Spot', # (T200)
+            6 => 'Touch',
+            14 => 'Tracking', #JR (HX9V) ("Manual" for the T200?, ref 9)
+            15 => 'Face Tracking', # (not set when in face detect mode and no faces detected)
             65535 => 'n/a', #PH (A100)
         },
-    },
-    0xb043 => { #9
-        Name => 'AFMode',
+    },{ #JR
+        Name => 'AFAreaMode',
+        # AFAreaMode for DSC-HX9V generation, having values that appear to be different from older models.
         Writable => 'int16u',
-        RawConv => '$val == 65535 ? undef : $val',
-        PrintConv => {
-            0 => 'Default', # (takes this value after camera reset, but can't be set back once changed)
-            1 => 'Multi AF',
-            2 => 'Center AF',
-            3 => 'Spot AF',
-            4 => 'Flexible Spot AF', # (T200)
-            6 => 'Touch AF',
-            14 => 'Manual Focus', # (T200)
-            15 => 'Face Detected', # (not set when in face detect mode and no faces detected)
-            65535 => 'n/a', #PH (A100)
-        },
-    },
+        Condition => '$$self{TagB042} and $$self{TagB042} != 0',
+        Notes => 'DSC-HX9V generation cameras',
+        PrintConv => {
+            0 => 'Multi',
+            1 => 'Center',
+            2 => 'Spot', #(NC) seen for DSC-WX9
+            3 => 'Flexible Spot',
+            10 => 'Selective (for Miniature effect)', # seen for Miniature effect of DSC-WX30
+            14 => 'Tracking',
+            15 => 'Face Tracking',
+            255 => 'Manual',
+        },
+    }],
     0xb044 => { #9
         Name => 'AFIlluminator',
@@ -508,22 +2232,39 @@
         },
     },
+    # 0xb045 - int16u: 0
+    # 0xb046 - int16u: 0
     0xb047 => { #2
-        Name => 'Quality',
+        Name => 'JPEGQuality',
         Writable => 'int16u',
         RawConv => '$val == 65535 ? undef : $val',
         PrintConv => {
+            0 => 'Standard',
+            1 => 'Fine',
+            2 => 'Extra Fine', #JR
+            65535 => 'n/a', #PH (A100)
+        },
+    },
+    0xb048 => { #9
+        Name => 'FlashLevel',  #JR other name, but values -9 to 9 match FlashExposureCompensation
+        Writable => 'int16s',
+        RawConv => '($val == -1 and $$self{Model} =~ /DSLR-A100\b/) ? undef : $val',
+        PrintConv => {
+            -32768 => 'Low',
+            -9 => '-9/3', #JR
+            -6 => '-6/3', #JR
+            -5 => '-5/3', #JR
+            -4 => '-4/3', #JR
+            -3 => '-3/3',
+            -2 => '-2/3',
+            -1 => '-1/3', # (for the A100, -1 is effectively 'n/a' - PH)
             0 => 'Normal',
-            1 => 'Fine',
-            65535 => 'n/a', #PH (A100)
-        },
-    },
-    0xb048 => { #9
-        Name => 'FlashLevel',
-        Writable => 'int16s',
-        RawConv => '$val == -1 ? undef : $val',
-        PrintConv => {
-            -32768 => 'Low',
-            -1 => 'n/a', #PH (A100)
-            0 => 'Normal',
+            1 => '+1/3',
+            2 => '+2/3',
+            3 => '+3/3',
+            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',
         },
@@ -534,8 +2275,9 @@
         RawConv => '$val == 65535 ? undef : $val',
         PrintConv => {
-            0 => 'Normal',
-            2 => 'Burst',
+            0 => 'Normal', # (ie. shutter button)
+            2 => 'Continuous',
             5 => 'Exposure Bracketing',
             6 => 'White Balance Bracketing', # (HX5)
+            8 => 'DRO Bracketing', #JR (ILCE-7RM2)
             65535 => 'n/a', #PH (A100)
         },
@@ -563,12 +2305,33 @@
         },
     },
-    0xb04e => { #2
-        Name => 'LongExposureNoiseReduction',
+    # 0xb04c - rational64u: 10/10 (seen 5 for HX9V Manual-exposure images, ref JR)
+    # 0xb04d - int16u: 0
+    # (the Kamisaka decoding of 0xb04e seems wrong - ref JR)
+    # 0xb04e => { #2
+    #     Name => 'LongExposureNoiseReduction',
+    #     Notes => 'LongExposureNoiseReduction for other models',
+    #     Writable => 'int16u',
+    #     RawConv => '$val == 65535 ? undef : $val',
+    #     PrintConv => {
+    #         0 => 'Off',
+    #         1 => 'On',
+    #         2 => 'On 2', #PH (TX10, TX100, WX9, WX10, etc)
+    #         # 4 - seen this (CX360E, CX700E)
+    #         65535 => 'n/a', #PH (A100)
+    #     },
+    # },
+    0xb04e => { #PH (RX100) - but not in RX100M3 anymore (ref JR)
+        Name => 'FocusMode',
+        Condition => '$$self{MetaVersion} and $$self{MetaVersion} eq "DC7303320222000"', #JR
+        Notes => 'valid for DSC-HX9V generation and newer',
         Writable => 'int16u',
-        RawConv => '$val == 65535 ? undef : $val',
-        PrintConv => {
-            0 => 'Off',
-            1 => 'On',
-            65535 => 'n/a', #PH (A100)
+        PrintConv => {
+            0 => 'Manual',
+            # 1 - seen for DSC-WX7 burst, HDR-CX130E/CX560E
+            2 => 'AF-S',
+            3 => 'AF-C',
+            # 4 - seen for HDR-CX360E/CX700E
+            5 => 'Semi-manual', #JR (HX9V)
+            6 => 'DMF', # "Direct Manual Focus"
         },
     },
@@ -576,10 +2339,27 @@
         Name => 'DynamicRangeOptimizer',
         Writable => 'int16u',
+        Priority => 0, # (unreliable for the A77)
         PrintConv => {
             0 => 'Off',
             1 => 'Standard',
             2 => 'Plus',
-        },
-    },
+            # 8 for HDR models - what does this mean?
+        },
+    },
+    0xb050 => { #PH (RX100)
+        Name => 'HighISONoiseReduction2',
+        Condition => '$$self{Model} =~ /^(DSC-|Stellar)/',
+        Notes => 'DSC models only',
+        Writable => 'int16u',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'High',
+            2 => 'Low',
+            3 => 'Off', #JR
+            # it seems that all SLT and NEX models give n/a here (ref JR)
+            65535 => 'n/a',
+        },
+    },
+    # 0xb051 - int16u: 0
     0xb052 => { #PH (TX1)
         Name => 'IntelligentAuto',
@@ -591,20 +2371,29 @@
         },
     },
-    0xb054 => { #PH (TX1)
+    # 0xb053 - int16u: normally 0, but got 1 for a superior auto backlight picture (RX100)
+    0xb054 => { #PH/9/JR (TX1,TX7,RX100,HX9V)
         Name => 'WhiteBalance',
         Writable => 'int16u',
-        Priority => 0, # (until more values are filled in)
+        Notes => q{
+            decoding of the Fluorescent settings matches the EXIF standard, which is
+            different than the names used by Sony for some models
+        },
         PrintConv => {
             0 => 'Auto',
-            4 => 'Manual',
+            4 => 'Custom', # (manual)
             5 => 'Daylight',
-            6 => 'Cloudy', #9
-            7 => 'White Flourescent', #9      (Sony "Fluorescent 1 (White)")
-            8 => 'Cool White Flourescent', #9 (Sony "Fluorescent 2 (Natural White)")
-            9 => 'Day White Flourescent', #9  (Sony "Fluorescent 3 (Day White)")
+            6 => 'Cloudy',
+            # PrintConv names matching Exif Fluorescent LightSource names (ref JR)
+            # (Sony uses conflicting names for some models)
+            7 => 'Cool White Fluorescent', # (RX100) (TX7/HX9V "Fluorescent 1 (White)", ref 9/JR)
+            8 => 'Day White Fluorescent',  # (RX100) (TX7/HX9V "Fluorescent 2 (Natural White)", ref 9/JR)
+            9 => 'Daylight Fluorescent',   # (RX100) (TX7/HX9V "Fluorescent 3 (Day White)", ref 9/JR)
+            10 => 'Incandescent2', #JR (HX9V)
+            11 => 'Warm White Fluorescent',
             14 => 'Incandescent',
-            15 => 'Flash', #9
+            15 => 'Flash',
             17 => 'Underwater 1 (Blue Water)', #9
             18 => 'Underwater 2 (Green Water)', #9
+            19 => 'Underwater Auto', #JR
         },
     },
@@ -629,4 +2418,5 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
         Notes => 'a small 320x200 preview image',
@@ -637,40 +2427,32 @@
         DataTag => 'PreviewImage',
         Writable => 'int32u',
+        WriteGroup => 'MakerNotes',
         Protected => 2,
     },
 );
 
-# Camera settings (ref PH) (decoded mainly from A200)
-%Image::ExifTool::Sony::CameraSettings = (
+# camera information for the A700/A850/A900 (ref JR)
+%Image::ExifTool::Sony::CameraInfo = (
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
-    FORMAT => 'int16u',
-    NOTES => q{
-        Camera settings for the A200, A230, A300, A350, A700, A850 and A900.  Some
-        tags are only valid for certain models.
-    },
-    0x04 => { #7 (A700, not valid for other models)
-        Name => 'DriveMode',
-        Condition => '$$self{Model} =~ /DSLR-A700\b/',
-        Notes => 'A700 only',
-        PrintConv => {
-            1 => 'Single Frame',
-            2 => 'Continuous High',
-            4 => 'Self-timer 10 sec',
-            5 => 'Self-timer 2 sec',
-            7 => 'Continuous Bracketing',
-            12 => 'Continuous Low',
-            18 => 'White Balance Bracketing Low',
-            19 => 'D-Range Optimizer Bracketing Low',
-        },
-    },
-    0x06 => { #7 (A700, not valid for other models)
-        Name => 'WhiteBalanceFineTune',
-        Condition => '$$self{Model} =~ /DSLR-A700\b/',
-        Format => 'int16s',
-        Notes => 'A700 only',
-    },
-    0x10 => { #7 (A700, not confirmed for other models)
-        Name => 'FocusMode',
+    NOTES => 'Camera information for the A700, A850 and A900.',
+    0x00 => {
+        Name => 'LensSpec',
+        # the A700/A850/A900 use a different int16 byte ordering! - PH
+        Format => 'undef[8]',
+        ValueConv => sub {
+            my $val = shift;;
+            return ConvLensSpec(pack('v*', unpack('n*', $val)));
+        },
+        ValueConvInv => sub {
+            my $val = shift;
+            return pack('v*', unpack('n*', ConvInvLensSpec($val)));
+        },
+        PrintConv => \&PrintLensSpec,
+        PrintConvInv => \&PrintInvLensSpec,
+    },
+    0x0014 => {
+        Name => 'FocusModeSetting',
+        Notes => 'FocusModeSetting for the A700, A850 and A900',
         PrintConv => {
             0 => 'Manual',
@@ -678,54 +2460,484 @@
             2 => 'AF-C',
             3 => 'AF-A',
-        },
-    },
-    0x11 => { #JD (A700)
-        Name => 'AFAreaMode',
-        PrintConv => {
-            0 => 'Wide',
-            1 => 'Local',
-            2 => 'Spot',
-        },
-    },
-    0x12 => { #7 (A700, not confirmed for other models)
-        Name => 'LocalAFAreaPoint',
-        Format => 'int16u',
-        Condition => '$$self{Model} !~ /DSLR-A230/',
-        PrintConv => {
+            4 => 'DMF',
+        },
+    },
+    0x0015 => { # the AF Point selected in AFAreaMode=Local or Spot; always '0' for AFAreaMode=Wide
+        Name => 'AFPointSelected',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Auto',
             1 => 'Center',
             2 => 'Top',
-            3 => 'Top-Right',
+            3 => 'Upper-right',
             4 => 'Right',
-            5 => 'Bottom-Right',
+            5 => 'Lower-right',
             6 => 'Bottom',
-            7 => 'Bottom-Left',
+            7 => 'Lower-left',
             8 => 'Left',
-            9 => 'Top-Left',
+            9 => 'Upper-left',
+            10 => 'Far Right', # only given by A700
+            11 => 'Far Left',  # only given by A700
+        },
+    },
+    # 0x0019 - AF sensor used for focusing for A700/A850/A900:
+    #
+    #   A700 AF sensor layout:         A850/A900 AF sensor layout:
+    #
+    #              -                             *-*                 - = AF sensor
+    #        |           |                  |           |            * = assist sensor
+    #              -                             *-*                 o = F2.8 sensor
+    #   |    |    |o|    |    |        |    *    |o|    *    |       A700 center: double-cross + F2.8
+    #              -                             *-*                 A850 center: double-cross + F2.8 + 4 assist
+    #        |           |                  |           |
+    #              -                             *-*
+    #
+    # Following values seen for A700/A850 in AFAreaMode=Local or Spot: (other values only seen in "Wide")
+    #
+    #              16
+    #         0           19
+    #              13
+    #    3    1    22     20    18
+    #               8
+    #         2           21
+    #               5
+    #
+    # Note 1: A850/A900 AFPoint Selected 'Left'/'Right' (in 0x0015) corresponds in position (see diagram)
+    #         to A700 Local AFPoint 'Far Left'/'Far Right', and gives 'Far Left'/'Far Right' in 0x0019.
+    # Note 2: A700 in "Wide" also gives all 23 values in 0x0019, although it doesn't have assist-points ...
+    0x0019 => { # the AF sensor used for focusing
+        Name => 'AFPoint',
+        PrintConv => {
+            0 => 'Upper-left',
+            1 => 'Left',
+            2 => 'Lower-left',
+            3 => 'Far Left',
+            4 => 'Bottom Assist-left', #(NC)
+            5 => 'Bottom',
+            6 => 'Bottom Assist-right', #(NC)
+            # values 7-14: 8 center points: 4 from double-cross + 4 assist; 7-10 appear horizontal, 11-14 vertical
+            7  => 'Center (7)', #(NC)
+            8  => 'Center (horizontal)',
+            9  => 'Center (9)', #(NC)
+            10 => 'Center (10)', #(NC)
+            11 => 'Center (11)', #(NC)
+            12 => 'Center (12)', #(NC)
+            13 => 'Center (vertical)',
+            14 => 'Center (14)', #(NC)
+            15 => 'Top Assist-left', #(NC)
+            16 => 'Top',
+            17 => 'Top Assist-right', #(NC)
+            18 => 'Far Right',
+            19 => 'Upper-right',
+            20 => 'Right',
+            21 => 'Lower-right',
+            22 => 'Center F2.8',
+        },
+    },
+    # AF Status for A700/A850/A900, which have different sensor layout
+    # and different int16 byte ordering
+    0x001e => { Name => 'AFStatusActiveSensor',       %Image::ExifTool::Minolta::afStatusInfo },
+    0x0020 => { Name => 'AFStatusUpper-left',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x0022 => { Name => 'AFStatusLeft',               %Image::ExifTool::Minolta::afStatusInfo },
+    0x0024 => { Name => 'AFStatusLower-left',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x0026 => { Name => 'AFStatusFarLeft',            %Image::ExifTool::Minolta::afStatusInfo },
+    0x0028 => { Name => 'AFStatusBottomAssist-left',  %Image::ExifTool::Minolta::afStatusInfo },
+    0x002a => { Name => 'AFStatusBottom',             %Image::ExifTool::Minolta::afStatusInfo },
+    0x002c => { Name => 'AFStatusBottomAssist-right', %Image::ExifTool::Minolta::afStatusInfo },
+    0x002e => { Name => 'AFStatusCenter-7',           %Image::ExifTool::Minolta::afStatusInfo },
+    0x0030 => { Name => 'AFStatusCenter-horizontal',  %Image::ExifTool::Minolta::afStatusInfo },
+    0x0032 => { Name => 'AFStatusCenter-9',           %Image::ExifTool::Minolta::afStatusInfo },
+    0x0034 => { Name => 'AFStatusCenter-10',          %Image::ExifTool::Minolta::afStatusInfo },
+    0x0036 => { Name => 'AFStatusCenter-11',          %Image::ExifTool::Minolta::afStatusInfo },
+    0x0038 => { Name => 'AFStatusCenter-12',          %Image::ExifTool::Minolta::afStatusInfo },
+    0x003a => { Name => 'AFStatusCenter-vertical',    %Image::ExifTool::Minolta::afStatusInfo },
+    0x003c => { Name => 'AFStatusCenter-14',          %Image::ExifTool::Minolta::afStatusInfo },
+    0x003e => { Name => 'AFStatusTopAssist-left',     %Image::ExifTool::Minolta::afStatusInfo },
+    0x0040 => { Name => 'AFStatusTop',                %Image::ExifTool::Minolta::afStatusInfo },
+    0x0042 => { Name => 'AFStatusTopAssist-right',    %Image::ExifTool::Minolta::afStatusInfo },
+    0x0044 => { Name => 'AFStatusFarRight',           %Image::ExifTool::Minolta::afStatusInfo },
+    0x0046 => { Name => 'AFStatusUpper-right',        %Image::ExifTool::Minolta::afStatusInfo },
+    0x0048 => { Name => 'AFStatusRight',              %Image::ExifTool::Minolta::afStatusInfo },
+    0x004a => { Name => 'AFStatusLower-right',        %Image::ExifTool::Minolta::afStatusInfo },
+    0x004c => { Name => 'AFStatusCenterF2-8',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x0130 => {
+        Name => 'AFMicroAdjValue',
+        Condition => '$$self{Model} =~ /^DSLR-A(850|900)\b/',
+        ValueConv => '$val - 20',
+        ValueConvInv => '$val + 20',
+    },
+    0x0131 => {
+        Name => 'AFMicroAdjMode',
+        Condition => '$$self{Model} =~ /^DSLR-A(850|900)\b/',
+        Mask => 0x80,
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    305.1 => { # (0x131)
+        Name => 'AFMicroAdjRegisteredLenses',
+        Notes => 'number of registered lenses with a non-zero AFMicroAdjValue',
+        Condition => '$$self{Model} =~ /^DSLR-A(850|900)\b/',
+        Mask => 0x7f,
+    },
+    # 0x0166 - 40 x 128 int8u values: AF Info Blocks for A850 and A900, not for A700
+);
+
+# camera information for other DSLR models (ref JR)
+%Image::ExifTool::Sony::CameraInfo2 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        Camera information for the DSLR-A200, A230, A290, A300, A330, A350, A380 and
+        A390.
+    },
+    0x00 => {
+        Name => 'LensSpec',
+        Format => 'undef[8]',
+        ValueConv => \&ConvLensSpec,
+        ValueConvInv => \&ConvInvLensSpec,
+        PrintConv => \&PrintLensSpec,
+        PrintConvInv => \&PrintInvLensSpec,
+    },
+    # 0x0010 - maybe to do with AFStatus: 0 na./Manual, 4 Failed, 16 Tracking, 64 Focused
+    0x0014 => {
+        Name => 'AFPointSelected',
+        PrintConvColumns => 2,
+        PrintConv => { #JR (NC) same list as A100, A700/A900, as all have 9 point AF
+            0 => 'Auto',
+            1 => 'Center',
+            2 => 'Top',
+            3 => 'Upper-right',
+            4 => 'Right',
+            5 => 'Lower-right',
+            6 => 'Bottom',
+            7 => 'Lower-left',
+            8 => 'Left',
+            9 => 'Upper-left',
+        },
+    },
+    0x0015 => {
+        Name => 'FocusModeSetting',
+        Notes => 'FocusModeSetting for other models',
+        PrintConv => {
+            0 => 'Manual',
+            1 => 'AF-S',
+            2 => 'AF-C',
+            3 => 'AF-A',
+            4 => 'DMF',
+        },
+    },
+    # 0x0018 - AF sensor used for focusing for A200/A230/A290/A300/A330/A350/A380/A390; AF sensor layout:
+    #
+    #               -              - = AF sensor
+    #        |              |      + = cross sensor
+    #
+    #            -  +  -
+    #
+    #        |              |
+    #               -
+    #
+    0x0018 => { # used A100 list which appears to match
+        Name => 'AFPoint',
+        PrintConv => {
+            0 => 'Top-right',
+            1 => 'Bottom-right',
+            2 => 'Bottom',
+            3 => 'Middle Horizontal',
+            4 => 'Center Vertical',
+            5 => 'Top',
+            6 => 'Top-left',
+            7 => 'Bottom-left',
+        },
+    },
+    # AF Status for A200/A230/A290/A300/A330/A350/A380/A390: analogous to A100 in Minolta.pm
+    0x001b => { Name => 'AFStatusActiveSensor',     %Image::ExifTool::Minolta::afStatusInfo },
+    0x001d => { Name => 'AFStatusTop-right',        %Image::ExifTool::Minolta::afStatusInfo },
+    0x001f => { Name => 'AFStatusBottom-right',     %Image::ExifTool::Minolta::afStatusInfo },
+    0x0021 => { Name => 'AFStatusBottom',           %Image::ExifTool::Minolta::afStatusInfo },
+    # MiddleHorizontal is any of the 3 central horizontal sensors
+    0x0023 => { Name => 'AFStatusMiddleHorizontal', %Image::ExifTool::Minolta::afStatusInfo },
+    0x0025 => { Name => 'AFStatusCenterVertical',   %Image::ExifTool::Minolta::afStatusInfo },
+    0x0027 => { Name => 'AFStatusTop',              %Image::ExifTool::Minolta::afStatusInfo },
+    0x0029 => { Name => 'AFStatusTop-left',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x002b => { Name => 'AFStatusBottom-left',      %Image::ExifTool::Minolta::afStatusInfo },
+    # the 3 MiddleHorizontal sensors
+    0x002d => { Name => 'AFStatusLeft',             %Image::ExifTool::Minolta::afStatusInfo },
+    0x002f => { Name => 'AFStatusCenterHorizontal', %Image::ExifTool::Minolta::afStatusInfo },
+    0x0031 => { Name => 'AFStatusRight',            %Image::ExifTool::Minolta::afStatusInfo },
+    # 0x0166 -  59 x 96 int8u values: AF Info Blocks for A230/A290/A330/A380/A390
+    # 0x0182 -  58 x 88 int8u values: AF Info Blocks for A200/A300/A350
+);
+
+# Camera information for the A55 (ref PH)
+# (also valid for A33, A35, A560, A580 - ref JR)
+%Image::ExifTool::Sony::CameraInfo3 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    IS_SUBDIR => [ 0x23 ],
+    NOTES => q{
+        Camera information stored by the A33, A35, A55, A450, A500, A550, A560,
+        A580, NEX-3/5/5C/C3 and VG10E.  Some tags are valid only for some of these
+        models.
+    },
+    0x00 => { #JR
+        Name => 'LensSpec',
+        Condition => '$$self{Model} !~ /^NEX-5C/',
+        Format => 'undef[8]',
+        ValueConv => \&ConvLensSpec,
+        ValueConvInv => \&ConvInvLensSpec,
+        PrintConv => \&PrintLensSpec,
+        PrintConvInv => \&PrintInvLensSpec,
+    },
+    0x0e => { #JR
+        Name => 'FocalLength',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        Format => 'int16u',
+        Priority => 0,
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ mm//; $val',
+    },
+    0x10 => { #JR
+        Name => 'FocalLengthTeleZoom',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        Format => 'int16u',
+        ValueConv => '$val * 2 / 3',
+        ValueConvInv => 'int($val * 3 / 2 + 0.5)',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ mm//; $val',
+    },
+#
+# Note:
+# The below AF decoding covers cameras with 2 different AF systems, with overlapping offsets !
+#  1) DSLR-A450/A500/A550 with 9 point AF system: decoding/offsets identical to A200 - A390 in CameraInfo
+#  2) SLT-A33/A35/A55 and DSLR-A560/A580 with 15 point AF system: similar/more info but at different offsets
+#
+    0x14 => { #JR
+        Name => 'AFPointSelected',
+        Condition => '$$self{Model} =~ /^(DSLR-A(450|500|550))\b/',
+        # (these cameras have a 9-point AF system, ref JR)
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Auto', # (seen in Wide mode and for Manual Focus)
+            1 => 'Center', # seen for AFArea=Spot
+            2 => 'Top',
+            3 => 'Upper-right',
+            4 => 'Right',
+            5 => 'Lower-right',
+            6 => 'Bottom',
+            7 => 'Lower-left',
+            8 => 'Left',
+            9 => 'Upper-left',
+        },
+    },
+    0x15 => { #JR
+        Name => 'FocusMode',
+        Condition => '$$self{Model} =~ /^(DSLR-A(450|500|550))\b/',
+        PrintConv => {
+            0 => 'Manual',
+            1 => 'AF-S',
+            2 => 'AF-C',
+            3 => 'AF-A',
+        },
+    },
+    0x18 => { #JR
+        Name => 'AFPoint',
+        Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/',
+        PrintConv => {
+            0 => 'Top-right',
+            1 => 'Bottom-right',
+            2 => 'Bottom',
+            3 => 'Middle Horizontal',
+            4 => 'Center Vertical',
+            5 => 'Top',
+            6 => 'Top-left',
+            7 => 'Bottom-left',
+        },
+    },
+    0x19 => { #JR
+        Name => 'FocusStatus',
+        Condition => '$$self{Model} =~ /^(SLT-|DSLR-A(560|580))\b/',
+        Notes => 'not valid with Contrast AF or for NEX models',
+        # seen the following values:
+        #  0 with MF (A35, A55V-HDR, A560, A580), non-AF lens (A35), and A580 Contrast-AF
+        #  4 with MF (A33, A55V), and A580 Contrast-AF
+        # 16 with AF-C (or AF-A) and focus OK
+        # 24 with AF-C (or AF-A) and unsharp or fast moving subject e.g. bird in flight
+        # 64 with AF-S (or AF-A) and focus OK
+        PrintConv => {
+            0 => 'Manual - Not confirmed (0)',
+            4 => 'Manual - Not confirmed (4)',
+            16 => 'AF-C - Confirmed',
+            24 => 'AF-C - Not Confirmed',
+            64 => 'AF-S - Confirmed',
+        },
+    },
+    0x1b => { #JR
+        Name => 'AFStatusActiveSensor',
+        Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/',
+        %Image::ExifTool::Minolta::afStatusInfo,
+    },
+    0x1c => {
+        Name => 'AFPointSelected',  # (v8.88: renamed from LocalAFAreaPointSelected)
+        Condition => '$$self{Model} =~ /^(SLT-|DSLR-A(560|580))\b/',
+        Notes => 'not valid for Contrast AF', #JR
+        # (all of these cameras have an 15-point three-cross AF system, ref JR)
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => 'Auto', # (seen in Wide mode)
+            1 => 'Center',
+            2 => 'Top',
+            3 => 'Upper-right',
+            4 => 'Right',
+            5 => 'Lower-right',
+            6 => 'Bottom',
+            7 => 'Lower-left',
+            8 => 'Left',
+            9 => 'Upper-left',
             10 => 'Far Right',
             11 => 'Far Left',
-            # have seen value of 128 for A230, A330, A380 - PH
-        },
+            12 => 'Upper-middle',
+            13 => 'Near Right',
+            14 => 'Lower-middle',
+            15 => 'Near Left',
+        },
+    },
+    0x1d => [
+        {
+            Name => 'FocusMode',
+            Condition => '$$self{Model} =~ /^(SLT-|DSLR-A(560|580))\b/',
+            PrintConv => {
+                0 => 'Manual',
+                1 => 'AF-S',
+                2 => 'AF-C',
+                3 => 'AF-A',
+            },
+        },{ #JR
+            Name => 'AFStatusTop-right',
+            Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/',
+            %Image::ExifTool::Minolta::afStatusInfo,
+        },
+    ],
+    0x1f => { #JR
+        Name => 'AFStatusBottom-right',
+        Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/',
+        %Image::ExifTool::Minolta::afStatusInfo,
+    },
+    0x20 => { #JR
+        Name => 'AFPoint',  # (v8.88: renamed from LocalAFAreaPointUsed)
+        Condition => '$$self{Model} =~ /^(SLT-|DSLR-A(560|580))\b/',
+        Notes => 'the AF sensor used for focusing. Not valid for Contrast AF',
+        PrintConvColumns => 2,
+        PrintConv => {
+            %afPoint15,
+            255 => '(none)', #PH (A55, guess; also A35 with non-AF lens, ref JR)
+        },
+    },
+    0x21 => [ #JR
+        {
+            Name => 'AFStatusActiveSensor',
+            Condition => '$$self{Model} =~ /^(SLT-|DSLR-A(560|580))\b/',
+            %Image::ExifTool::Minolta::afStatusInfo,
+        },{
+            Name => 'AFStatusBottom',
+            Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/',
+            %Image::ExifTool::Minolta::afStatusInfo,
+        },
+    ],
+    0x23 => [ #JR
+        {
+            Name => 'AFStatus15',
+            Condition => '$$self{Model} =~ /^(SLT-|DSLR-A(560|580))\b/',
+            Format => 'int16s[18]',
+            SubDirectory => { TagTable => 'Image::ExifTool::Sony::AFStatus15' },
+        },{
+            Name => 'AFStatusMiddleHorizontal', # MiddleHorizontal is any of the 3 central horizontal sensors
+            Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/',
+            %Image::ExifTool::Minolta::afStatusInfo,
+        },
+    ],
+    0x25 => { Name => 'AFStatusCenterVertical',   Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/', %Image::ExifTool::Minolta::afStatusInfo },
+    0x27 => { Name => 'AFStatusTop',              Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/', %Image::ExifTool::Minolta::afStatusInfo },
+    0x29 => { Name => 'AFStatusTop-left',         Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/', %Image::ExifTool::Minolta::afStatusInfo },
+    0x2b => { Name => 'AFStatusBottom-left',      Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/', %Image::ExifTool::Minolta::afStatusInfo },
+    # the 3 MiddleHorizontal sensors:
+    0x2d => { Name => 'AFStatusLeft',             Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/', %Image::ExifTool::Minolta::afStatusInfo },
+    0x2f => { Name => 'AFStatusCenterHorizontal', Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/', %Image::ExifTool::Minolta::afStatusInfo },
+    0x31 => { Name => 'AFStatusRight',            Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)\b/', %Image::ExifTool::Minolta::afStatusInfo },
+    # 0x0166 - starting here there are 96 AF Info blocks of 155 bytes each for the SLT-A33/A35/A55 and DSLR-A560/A580,
+    #          starting here there are 86 AF Info blocks of 174 bytes each for the DSLR-A450/A500/A550,
+    #          but NOT for NEX, and not for the A580 in Contrast-AF mode (ref JR)
+    #          The 43rd byte of each block for A580 appears to be the AFPoint as in offset 0x20,
+    #          possibly also 73rd and 74th byte
+);
+
+# Camera information for other models (ref PH)
+%Image::ExifTool::Sony::CameraInfoUnknown = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+);
+
+# white balance and other camera information (ref PH)
+%Image::ExifTool::Sony::FocusInfo = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PRIORITY => 0,
+    NOTES => q{
+        More camera settings and focus information decoded for models such as the
+        A200, A230, A290, A300, A330, A350, A380, A390, A700, A850 and A900.
+    },
+    0x0e => [{ #7/JR
+        Name => 'DriveMode2',
+        Condition => '$$self{Model} =~ /^DSLR-A(230|290|330|380|390)$/',
+        Notes => 'A230, A290, A330, A380 and A390',
+        ValueConvInv => '$val',
+        PrintHex => 1,
+        PrintConv => { # (values confirmed for specified models - PH)
+            0x01 => 'Single Frame', # (A230,A330,A380)
+            0x02 => 'Continuous High', #PH (A230,A330)
+            0x04 => 'Self-timer 10 sec', # (A230)
+            0x05 => 'Self-timer 2 sec, Mirror Lock-up', # (A230,A290,A330,A380,390)
+            0x07 => 'Continuous Bracketing', # (A230,A330)
+            0x0a => 'Remote Commander', # (A230)
+            0x0b => 'Continuous Self-timer', # (A230,A330)
+        },
+    },{
+        Name => 'DriveMode2',
+        Notes => 'A200, A300, A350, A700, A850 and A900',
+        ValueConvInv => '$val',
+        PrintHex => 1,
+        PrintConv => {
+            0x01 => 'Single Frame',
+            0x02 => 'Continuous High', # A700/A900; not on A850
+            0x12 => 'Continuous Low', #JR
+            0x04 => 'Self-timer 10 sec',
+            0x05 => 'Self-timer 2 sec, Mirror Lock-up',
+            0x06 => 'Single-frame Bracketing',
+            0x07 => 'Continuous Bracketing',
+            0x18 => 'White Balance Bracketing Low', #JR
+            0x28 => 'White Balance Bracketing High', #JR
+            0x19 => 'D-Range Optimizer Bracketing Low', #JR
+            0x29 => 'D-Range Optimizer Bracketing High', #JR
+            0x0a => 'Remote Commander', #JR
+            0x0b => 'Mirror Lock-up', #JR (A850/A900; not on A700)
+        },
+    }],
+    0x10 => { #JR (1 and 2 inverted!)
+        Name => 'Rotation',
+        PrintConv => {
+            0 => 'Horizontal (normal)',
+            1 => 'Rotate 270 CW',
+            2 => 'Rotate 90 CW',
+        },
+    },
+    0x14 => {
+        Name => 'ImageStabilizationSetting',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     0x15 => { #7
-        Name => 'MeteringMode',
-        Condition => '$$self{Model} !~ /DSLR-A230/',
-        PrintConv => {
-            1 => 'Multi-segment',
-            2 => 'Center-weighted Average',
-            4 => 'Spot',
-        },
-    },
-    0x16 => {
-        Name => 'ISOSetting',
-        Condition => '$$self{Model} !~ /DSLR-A230/',
-        # 0 indicates 'Auto' (I think)
-        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
-        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
-        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
-        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
-    },
-    0x18 => { #7
         Name => 'DynamicRangeOptimizerMode',
-        Condition => '$$self{Model} !~ /DSLR-A230/',
         PrintConv => {
             0 => 'Off',
@@ -733,14 +2945,40 @@
             2 => 'Advanced Auto',
             3 => 'Advanced Level',
-            4097 => 'Auto', #PH (A550)
-        },
-    },
-    0x19 => { #7
-        Name => 'DynamicRangeOptimizerLevel',
-        Condition => '$$self{Model} !~ /DSLR-A230/',
-    },
-    0x1a => { # style actually used (combination of mode dial + creative style menu)
+        },
+    },
+    0x2b => { #JR seen 2,1,3 for both WB and DRO bracketing
+        Name => 'BracketShotNumber',
+        Notes => 'WB and DRO bracketing',
+    },
+    0x2c => { #JR
+        Name => 'WhiteBalanceBracketing',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    0x2d => { #JR seen 2,1,3 for both WB and DRO bracketing
+        Name => 'BracketShotNumber2',
+    },
+    0x2e => { #JR
+        Name => 'DynamicRangeOptimizerBracket',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'High',
+        },
+    },
+    0x2f => { #JR seen 0,1,2 and 0,1,2,3,4 for 3 and 5 image bracketing sequences
+        Name => 'ExposureBracketShotNumber',
+    },
+    0x3f => { #JR
+        Name => 'ExposureProgram',
+        SeparateTable => 'ExposureProgram',
+        PrintConv => \%sonyExposureProgram,
+    },
+    0x41 => { #JR style actually used (combination of mode dial + creative style menu)
         Name => 'CreativeStyle',
-        Condition => '$$self{Model} !~ /DSLR-A230/',
+        PrintConvColumns => 2,
         PrintConv => {
             1 => 'Standard',
@@ -751,11 +2989,1158 @@
             6 => 'Night View/Portrait',
             8 => 'B&W',
-            9 => 'Adobe RGB', # A900
+            9 => 'Adobe RGB', # A700
             11 => 'Neutral',
             12 => 'Clear', #7
             13 => 'Deep', #7
             14 => 'Light', #7
-            15 => 'Autumn', #7
+            15 => 'Autumn Leaves', #7
             16 => 'Sepia', #7
+        },
+    },
+    0x6d => {
+        Name => 'ISOSetting',
+        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
+        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
+        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
+        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
+    },
+    0x6f => {
+        Name => 'ISO',
+        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
+        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
+        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
+        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
+    },
+    0x77 => { #JR
+        Name => 'DynamicRangeOptimizerMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Standard',
+            2 => 'Advanced Auto',
+            3 => 'Advanced Level',
+        },
+    },
+    0x79 => 'DynamicRangeOptimizerLevel',
+#    0x06f1 - int16u    LensType,  Condition => '$$self{Model} =~ /^DSLR-A(700|850|900)$/',
+#    0x4a81 - int16u    LensType,  Condition => '$$self{Model} !~ /^DSLR-A(700|850|900)$/',
+#    0x4a84 - int16uRev LensType,  Condition => '$$self{Model} =~ /^DSLR-A(700|850|900)$/',
+    0x0846 => { #13
+        Name => 'ShutterCount', # (=ImageCount for these models)
+        Condition => '$$self{Model} =~ /^DSLR-A(230|290|330|380|390|850|900)$/',
+        Format => 'int32u',
+        Notes => 'only valid for some DSLR models',
+        RawConv => '$val & 0x00ffffff', #PH
+    },
+    0x09bb => { #PH (validated only for DSLR-A850)
+        Name => 'FocusPosition',
+        Condition => '$$self{Model} =~ /^DSLR-A(200|230|290|300|330|350|380|390|700|850|900)$/',
+        Notes => 'only valid for some DSLR models',
+        # 128 = infinity -- see Composite:FocusDistance below
+    },
+    0x1110 => { # (9600 bytes: 4 sets of 40x30 int16u values in the range 0-8191)
+        Name => 'TiffMeteringImage',
+        Format => 'undef[9600]',
+        Notes => q{
+            13-bit RBGG (?) 40x30 pixels, presumably metering info, extracted as a
+            16-bit TIFF image;
+        },
+        ValueConv => sub {
+            my ($val, $et) = @_;
+            return undef unless length $val >= 9600;
+            return \ "Binary data 7404 bytes" unless $et->Options('Binary');
+            my @dat = unpack('n*', $val);
+            # TIFF header for a 16-bit RGB 10dpi 40x30 image
+            $val = Image::ExifTool::MakeTiffHeader(40,30,3,16,10);
+            # re-order data to RGB pixels
+            my ($i, @val);
+            for ($i=0; $i<40*30; ++$i) {
+                # data is 13-bit (max 8191), shift left to fill 16 bits
+                # (typically, this gives a very dark image since the data should
+                # really be anti-logged to convert from EV to perceived brightness)
+#                push @val, $dat[$i]<<3, $dat[$i+2400]<<3, $dat[$i+1200]<<3;
+                push @val, int(5041.1*log($dat[$i]+1)/log(2)), int(5041.1*log($dat[$i+2400]+1)/log(2)), int(5041.1*log($dat[$i+1200]+1)/log(2));
+            }
+            $val .= pack('v*', @val);   # add TIFF strip data
+            return \$val;
+        },
+    },
+);
+
+# more camera setting information (ref JR)
+# - many of these tags are the same as in CameraSettings3
+%Image::ExifTool::Sony::MoreInfo = (
+    PROCESS_PROC => \&ProcessMoreInfo,
+    WRITE_PROC => \&ProcessMoreInfo,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        More camera settings information decoded for the A450, A500, A550, A560,
+        A580, A33, A35, A55, NEX-3/5/C3 and VG10E.
+    },
+    0x0001 => { # (256 bytes)
+        Name => 'MoreSettings',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MoreSettings' },
+    },
+    # (byte sizes for a single A580 image -- not checked for other images)
+    0x0002 => [ # (256 bytes)
+        {
+            Name => 'FaceInfo',
+            Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Sony::FaceInfo' },
+        },{
+            Name => 'FaceInfoA',
+            Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+            SubDirectory => { TagTable => 'Image::ExifTool::Sony::FaceInfoA' },
+        },
+    ],
+    # 0x0101:  512 bytes
+    # 0x0102: 1804 bytes
+    # 0x0103:  176 bytes
+    # 0x0104: 1088 bytes
+    # 0x0105:  160 bytes (all zero unless flash is used, ref JR)
+    # 0x0106:  256 bytes (faces detected if first byte is non-zero? ref JR)
+    0x0107 => { # (7200 bytes: 3 sets of 40x30 int16u values in the range 0-1023)
+        Name => 'TiffMeteringImage',
+        Notes => q{
+            10-bit RGB data from the 1200 AE metering segments, extracted as a 16-bit
+            TIFF image
+        },
+        ValueConv => sub {
+            my ($val, $et) = @_;
+            return undef unless length $val >= 7200;
+            return \ "Binary data 7404 bytes" unless $et->Options('Binary');
+            my @dat = unpack('v*', $val);
+            # TIFF header for a 16-bit RGB 10dpi 40x30 image
+            $val = Image::ExifTool::MakeTiffHeader(40,30,3,16,10);
+            # re-order data to RGB pixels
+            my ($i, @val);
+            for ($i=0; $i<40*30; ++$i) {
+                # data is 10-bit (max 1023), shift left to fill 16 bits
+                # (typically, this gives a very dark image since the data should
+                # really be anti-logged to convert from EV to perceived brightness)
+                push @val, $dat[$i]<<6, $dat[$i+1200]<<6, $dat[$i+2400]<<6;
+            }
+            $val .= pack('v*', @val);   # add TIFF strip data
+            return \$val;
+        },
+    },
+    # 0x0108:  140 bytes
+    # 0x0109:  256 bytes
+    # 0x010a:  256 bytes
+    # 0x0306:  276 bytes
+    # 0x0307:  256 bytes
+    # 0x0308:   96 bytes
+    # 0x0309:  112 bytes
+    # 0xffff:  788 bytes
+    0x0201 => { # (368 bytes)
+        Name => 'MoreInfo0201',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MoreInfo0201' },
+    },
+    # 0x0202:  144 bytes
+    # 0x0401: 4608 bytes
+    0x0401 => {
+        Name => 'MoreInfo0401',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MoreInfo0401' },
+    },
+);
+
+%Image::ExifTool::Sony::MoreInfo0201 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PRIORITY => 0,
+#    0x005d - also from 0 - 255, in sync with but lower than 0x005e, depending on FocalLength
+#    0x005e => {
+#        # FocusPosition for A560/A580/A33/A35/A55V
+#        # seen values from 80 - 255 (= infinity) -- see Composite:FocusDistance2 below
+#        Name => 'FocusPosition2_0201',
+#        Condition => '$$self{Model} !~ /^(NEX-|DSLR-(A450|A500|A550)$)/',
+#    },
+#    0x0093 - also from 0 - 255, in sync with but lower than 0x0094, depending on FocalLength
+#    0x0094 => {
+#        # FocusPosition for A450/A500/A550
+#        # seen values from 80 - 255 (= infinity) -- see Composite:FocusDistance2 below
+#        Name => 'FocusPosition2_0201',
+#        Condition => '$$self{Model} =~ /^(DSLR-(A450|A500|A550)$)/',
+#    },
+    0x011b => { #13
+        Name => 'ImageCount',
+        Condition => '$$self{Model} !~ /^DSLR-A(450|500|550)$/', #JR
+        Format => 'int32u',
+        Notes => 'not valid for the A450, A500 or A550',
+        RawConv => '$val & 0x00ffffff',
+    },
+    0x0125 => { #13
+        Name => 'ShutterCount',
+        Condition => '$$self{Model} !~ /^DSLR-A(450|500|550)$/', #JR
+        Format => 'int32u',
+        Notes => 'not valid for the A450, A500 or A550',
+        RawConv => '$val & 0x00ffffff',
+    },
+    0x014a => { #13
+        Name => 'ShutterCount', # (=ImageCount for these models)
+        Condition => '$$self{Model} =~ /^DSLR-A(450|500|550)$/', #JR
+        Format => 'int32u',
+        Notes => 'A450, A500 and A550 only',
+        RawConv => '$val & 0x00ffffff',
+    },
+);
+
+%Image::ExifTool::Sony::MoreInfo0401 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PRIORITY => 0,
+    0x044e => { #JR
+        Name => 'ShotNumberSincePowerUp',
+        Condition => '$$self{Model} !~ /^NEX-(3|5)$/',
+        Format => 'int32u',
+        Notes => 'Not valid for the NEX-3 or NEX-5',
+        RawConv => '$val & 0x00ffffff',
+    },
+#    0x101e - int16u LensType  Condition => '$$self{Model} =~ /^SLT-A(33|55V)/',
+#    0x1022 - int16u LensType  Condition => '$$self{Model} =~ /^DSLR-A(560|580)/',
+#    0x102a - int16u LensType  Condition => '$$self{Model} =~ /^(SLT-A35|NEX-C3)/',
+
+#    0x10a8 - int16u LensType  Condition => '$$self{Model} =~ /^SLT-A(33|55V)/',
+#    0x10ac - int16u LensType  Condition => '$$self{Model} =~ /^DSLR-A(560|580)/',
+#    0x10b4 - int16u LensType  Condition => '$$self{Model} =~ /^(SLT-A35|NEX-C3)/',
+#
+#    0x10f7 - int16u LensType  Condition => '$$self{Model} =~ /^SLT-A(33|55V)/',
+#    0x10fb - int16u LensType  Condition => '$$self{Model} =~ /^DSLR-A(560|580)/',
+#    0x1103 - int16u LensType  Condition => '$$self{Model} =~ /^(SLT-A35|NEX-C3)/',
+#
+#    0x1181 - int16u LensType  Condition => '$$self{Model} =~ /^SLT-A(33|55V)/',
+#    0x1185 - int16u LensType  Condition => '$$self{Model} =~ /^DSLR-A(560|580)/',
+#    0x118d - int16u LensType  Condition => '$$self{Model} =~ /^(SLT-A35|NEX-C3)/',
+);
+
+# more camera setting information (ref JR)
+# - many of these tags are the same as in CameraSettings3
+%Image::ExifTool::Sony::MoreSettings = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    PRIORITY => 0,
+    0x01 => { # interesting: somewhere between CameraSettings3 0x04 and 0x34
+        Name => 'DriveMode2',
+        PrintHex => 1,
+        PrintConv => {
+            0x10 => 'Single Frame',
+            0x21 => 'Continuous High', # also automatically selected for Scene mode Sports-action (0x05=52)
+            0x22 => 'Continuous Low',
+            0x30 => 'Speed Priority Continuous',
+            0x51 => 'Self-timer 10 sec',
+            0x52 => 'Self-timer 2 sec, Mirror Lock-up',
+            0x71 => 'Continuous Bracketing 0.3 EV',
+            0x75 => 'Continuous Bracketing 0.7 EV',
+            0x91 => 'White Balance Bracketing Low',
+            0x92 => 'White Balance Bracketing High',
+            0xc0 => 'Remote Commander',
+        },
+    },
+    0x02 => {
+        Name => 'ExposureProgram',
+        SeparateTable => 'ExposureProgram2',
+        PrintConv => \%sonyExposureProgram2,
+    },
+    0x03 => {
+        Name => 'MeteringMode',
+        PrintConv => {
+            1 => 'Multi-segment',
+            2 => 'Center-weighted average',
+            3 => 'Spot',
+        },
+    },
+    0x04 => {
+        Name => 'DynamicRangeOptimizerSetting',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On (Auto)',
+            17 => 'On (Manual)',
+        },
+    },
+    0x05 => 'DynamicRangeOptimizerLevel',
+    0x06 => {
+        Name => 'ColorSpace',
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+        },
+    },
+    0x07 => {
+        Name => 'CreativeStyleSetting',
+        PrintConvColumns => 2,
+        PrintConv => {
+            16 => 'Standard',
+            32 => 'Vivid',
+            64 => 'Portrait',
+            80 => 'Landscape',
+            96 => 'B&W',
+            160 => 'Sunset',
+        },
+    },
+    0x08 => { #JR
+        Name => 'ContrastSetting',
+        Format => 'int8s',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x09 => {
+        Name => 'SaturationSetting',
+        Format => 'int8s',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x0a => {
+        Name => 'SharpnessSetting',
+        Format => 'int8s',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x0d => {
+        Name => 'WhiteBalanceSetting',
+        # many guessed, based on "logical system" as observed for Daylight and Shade and steps of 16 between the modes
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => \%whiteBalanceSetting,
+        SeparateTable => 1,
+    },
+    0x0e => {
+        Name => 'ColorTemperatureSetting',
+        # matches "0xb021 ColorTemperature" when WB set to "Custom" or "Color Temperature/Color Filter"
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+        PrintConv => '"$val K"',
+        PrintConvInv => '$val =~ s/ ?K$//i; $val',
+    },
+    0x0f => {
+        Name => 'ColorCompensationFilterSet',
+        # seen 0, 1-9 and 245-255, corresponding to 0, M1-M9 and G9-G1 on camera display
+        # matches "0xb022 ColorCompensationFilter" when WB set to "Custom" or "Color Temperature/Color Filter"
+        Format => 'int8s',
+        Notes => 'negative is green, positive is magenta',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x10 => {
+        Name => 'FlashMode',
+        PrintConvColumns => 2,
+        PrintConv => {
+            1 => 'Flash Off',
+            16 => 'Autoflash',
+            17 => 'Fill-flash',
+            18 => 'Slow Sync',
+            19 => 'Rear Sync',
+            20 => 'Wireless',
+        },
+    },
+    0x11 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On',  # (unused or dark subject)
+        },
+    },
+    0x12 => {
+        Name => 'HighISONoiseReduction',
+        PrintConv => {
+            16 => 'Low',
+            17 => 'High',
+            19 => 'Auto',
+        },
+    },
+    0x13 => { # why is this not valid for A450/A500/A550 ?
+        Name => 'FocusMode',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            17 => 'AF-S',
+            18 => 'AF-C',
+            19 => 'AF-A',
+            32 => 'Manual',
+            48 => 'DMF', #(NC) (seen for NEX-5)
+        },
+    },
+    0x15 => {
+        Name => 'MultiFrameNoiseReduction',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            0 => 'n/a', # seen for A450/A500/A550
+            1 => 'Off',
+            16 => 'On',
+            255 => 'None', # seen for NEX-3/5/C3
+        },
+    },
+    0x16 => {
+        Name => 'HDRSetting',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On (Auto)',
+            17 => 'On (Manual)',
+        },
+    },
+    0x17 => {
+        Name => 'HDRLevel',
+        PrintConvColumns => 3,
+        PrintConv => {
+            33 => '1 EV',
+            34 => '1.5 EV', #JR (NC)
+            35 => '2 EV',
+            36 => '2.5 EV', #JR (NC)
+            37 => '3 EV',
+            38 => '3.5 EV', #PH (NC)
+            39 => '4 EV',
+            40 => '5 EV',
+            41 => '6 EV',
+        },
+    },
+    0x18 => {
+        Name => 'ViewingMode',
+        PrintConv => {
+            16 => 'ViewFinder',
+            33 => 'Focus Check Live View',
+            34 => 'Quick AF Live View',
+        },
+    },
+    0x19 => {
+        Name => 'FaceDetection',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On',
+        },
+    },
+    0x1a => {
+        Name => 'CustomWB_RBLevels',
+        # matches "0x7313 WB_RGGBLevels" when WB set to "Custom", except factor of 4
+        Format => 'int16uRev[2]',
+    },
+    # From here different and overlapping offsets for 3 groups of cameras:
+    # 1) DSLR-A450/A500/A550
+    # 2) NEX-3/5/5C
+    # 3) DSLR-A560/A580, NEX-C3/VG10/VG10E, SLT-A33/A35/A55V
+    0x1e => [{
+        Name => 'BrightnessValue',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        ValueConv => '($val-106)/8',
+        ValueConvInv => '$val * 8 + 106',
+    },{
+        Name => 'ExposureCompensationSet',
+        Notes => 'other models',
+        ValueConv => '($val - 128) / 24', #PH
+        ValueConvInv => 'int($val * 24 + 128.5)',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    }],
+    0x1f => [{
+        Name => 'ISO',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
+        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
+        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
+        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
+    },{
+        Name => 'FlashExposureCompSet',
+        Notes => 'other models',
+        Description => 'Flash Exposure Comp. Setting',
+        ValueConv => '($val - 128) / 24', #PH
+        ValueConvInv => 'int($val * 24 + 128.5)',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    }],
+    0x20 => [{
+        Name => 'FNumber',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
+    },{
+        Name => 'LiveViewAFMethod',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)/',
+        Notes => 'other models except the NEX-3/5/5C',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Phase-detect AF',
+            2 => 'Contrast AF',
+            # Contrast AF is only available with SSM/SAM lenses and in Focus Check LV,
+            # NOT in Quick AF LV, and is automatically set when mounting SSM/SAM lens
+            # - changes into Phase-AF when switching to Quick AF LV.
+        },
+    }],
+    0x21 => [{
+        Name => 'ExposureTime',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },{
+        Name => 'ISO',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        Notes => 'NEX-3/5/5C',
+        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
+        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
+        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
+        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
+    }],
+    0x22 => {
+        Name => 'FNumber',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        Notes => 'NEX-3/5/5C only',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
+    },
+    0x23 => [{
+        Name => 'FocalLength2',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        ValueConv => '10 * 2 ** (($val-28)/16)',
+        ValueConvInv => '$val>0 ? log($val/10)/log(2) * 16 + 28 : 0',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//; $val',
+    },{
+        Name => 'ExposureTime',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        Notes => 'NEX-3/5/5C',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    }],
+    0x24 => {
+        Name => 'ExposureCompensation2',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        Format => 'int16s',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },
+    0x25 => [{
+        Name => 'FocalLength2',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        Notes => 'NEX-3/5/5C',
+        ValueConv => '10 * 2 ** (($val-28)/16)',
+        ValueConvInv => '$val>0 ? log($val/10)/log(2) * 16 + 28 : 0',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//; $val',
+    },{
+        Name => 'ISO',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'other models except the A450, A500 and A550',
+        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
+        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
+        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
+        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
+    }],
+    0x26 => [{
+        Name => 'FlashExposureCompSet2',
+        Description => 'Flash Exposure Comp. Setting 2',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        Format => 'int16s',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },{
+        Name => 'ExposureCompensation2',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        Notes => 'NEX-3/5/5C',
+        Format => 'int16s',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    },{
+        Name => 'FNumber',
+        Notes => 'other models',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
+    }],
+    0x27 => {
+        Name => 'ExposureTime',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)|DSLR-(A450|A500|A550)/',
+        Notes => 'models other than the A450, A500, A550 and NEX-3/5/5C',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x28 => {
+        Name => 'Orientation2',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        PrintConv => {
+            1 => 'Horizontal (normal)',
+            2 => 'Rotate 180',
+            6 => 'Rotate 90 CW',
+            8 => 'Rotate 270 CW',
+        },
+    },
+    0x29 => [{
+        # FocusPosition for A450/A500/A550
+        # seen values from 80 - 255 (= infinity) -- see Composite:FocusDistance2 below
+        Name => 'FocusPosition2',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+    },{
+        # value increase of 16 corresponds to doubling of FocalLength
+        Name => 'FocalLength2',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)/',
+        Notes => 'other models except the NEX-3/5/5C',
+        ValueConv => '10 * 2 ** (($val-28)/16)',
+        ValueConvInv => '$val>0 ? log($val/10)/log(2) * 16 + 28 : 0',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val=~s/\s*mm$//; $val',
+    }],
+    0x2a => [{
+        Name => 'FlashAction',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        PrintConv => {
+            0 => 'Did not fire',
+            1 => 'Fired',
+        },
+    },{
+        Name => 'ExposureCompensation2',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)/',
+        Notes => 'other models except the NEX-3/5/5C',
+        Format => 'int16s',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    }],
+    0x2b => {
+        # FocusPosition for NEX-3/5/5C
+        # seen values from 80 - 255 (= infinity) -- see Composite:FocusDistance2 below
+        Name => 'FocusPosition2',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        Notes => 'NEX-3/5/5C only',
+    },
+    0x2c => [{
+        Name => 'FocusMode2',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'A450, A500 and A550',
+        PrintConv => {
+            0 => 'AF',
+            1 => 'MF',
+        },
+    },{
+        Name => 'FlashAction',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        Notes => 'NEX-3/5/5C FlashAction2',
+        PrintConv => {
+            0 => 'Did not fire',
+            1 => 'Fired',
+        },
+    },{
+        Name => 'FlashExposureCompSet2',
+        Description => 'Flash Exposure Comp. Setting 2',
+        Notes => 'other models FlashExposureCompSet2',
+        Format => 'int16s',
+        ValueConv => '$val / 8',
+        ValueConvInv => '$val * 8',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => '$val',
+    }],
+    0x2e => [{
+        Name => 'FocusMode2',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        Notes => 'NEX-3/5/5C',
+        PrintConv => {
+            0 => 'AF',
+            1 => 'MF',
+        },
+    },{
+        Name => 'Orientation2', # seen some A55 images where this does not match the other Orientation tags
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)/',
+        Notes => 'other models except the A450, A500 and A550',
+        PrintConv => {
+            1 => 'Horizontal (normal)',
+            2 => 'Rotate 180',
+            6 => 'Rotate 90 CW',
+            8 => 'Rotate 270 CW',
+        },
+    }],
+    0x2f => {
+        # FocusPosition for A560/A580/A33/A35/A55V and NEX-C3/VG10/VG10E
+        # seen values from 80 - 255 (= infinity) -- see Composite:FocusDistance2 below
+        Name => 'FocusPosition2',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)|DSLR-(A450|A500|A550)/',
+        Notes => 'models other than the A450, A500, A550 and NEX-3/5/5C',
+    },
+    0x30 => {
+        Name => 'FlashAction',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)|DSLR-(A450|A500|A550)/',
+        Notes => 'models other than the A450, A500, A550 and NEX-3/5/5C',
+        PrintConv => {
+            0 => 'Did not fire',
+            1 => 'Fired',
+        },
+    },
+    0x32 => {
+        Name => 'FocusMode2',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)|DSLR-(A450|A500|A550)/',
+        Notes => 'models other than the A450, A500, A550 and NEX-3/5/5C',
+        PrintConv => {
+            0 => 'AF',
+            1 => 'MF',
+        },
+    },
+    0x0077 => {
+        Name => 'FlashAction2',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)/',
+        PrintConv => {
+            0 => 'Did not fire',
+            2 => 'External Flash fired (2)',
+            3 => 'Built-in Flash fired',
+            4 => 'External Flash fired (4)', # what is difference with 2 ?
+        },
+    },
+    0x0078 => {
+        Name => 'FlashActionExternal',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        PrintConv => {
+            136 => 'Did not fire',
+            121 => 'Fired', # what is difference with 122 ?
+            122 => 'Fired',
+        },
+    },
+    0x007c => {
+        Name => 'FlashActionExternal',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)|DSLR-(A450|A500|A550)/',
+        PrintConv => {
+            136 => 'Did not fire',
+            167 => 'Fired',
+            182 => 'Fired, HSS',
+        },
+    },
+    0x0082 => {
+        Name => 'FlashStatus',
+        Condition => '$$self{Model} =~ /^NEX-(3|5|5C)/',
+        PrintConv => {
+            0 => 'None',
+            2 => 'External',
+        },
+    },
+    0x0086 => {
+        Name => 'FlashStatus',
+        Condition => '$$self{Model} !~ /^NEX-(3|5|5C)|DSLR-(A450|A500|A550)/',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Built-in',
+            2 => 'External',
+        },
+    },
+);
+
+# Face detection information (ref JR)
+my %faceInfo = (
+    Format => 'int16u[4]',
+    # re-order to top,left,height,width and scale to full-sized image like other Sony models
+    ValueConv => 'my @v=split(" ",$val); $_*=15 foreach @v; "$v[1] $v[0] $v[3] $v[2]"',
+    ValueConvInv => 'my @v=split(" ",$val); $_=int($_/15+0.5) foreach @v; "$v[1] $v[0] $v[3] $v[2]"',
+);
+%Image::ExifTool::Sony::FaceInfo = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int16u',
+    DATAMEMBER => [ 0x00 ],
+    0x00 => {
+        Name => 'FacesDetected',
+        DataMember => 'FacesDetected',
+        Format => 'int16s',
+        RawConv => '$$self{FacesDetected} = ($val == -1 ? 0 : $val); $val',
+        PrintConv => {
+            OTHER => sub { shift }, # pass other values straight through
+            -1 => 'n/a',
+        },
+    },
+    0x01 => {
+        Name => 'Face1Position',
+        Condition => '$$self{FacesDetected} >= 1',
+        %faceInfo,
+        Notes => q{
+            re-ordered and scaled to return the top, left, height and width of detected
+            face, with coordinates relative to the full-sized unrotated image and
+            increasing Y downwards
+        },
+    },
+    0x06 => {
+        Name => 'Face2Position',
+        Condition => '$$self{FacesDetected} >= 2',
+        %faceInfo,
+    },
+    0x0b => {
+        Name => 'Face3Position',
+        Condition => '$$self{FacesDetected} >= 3',
+        %faceInfo,
+    },
+    0x10 => {
+        Name => 'Face4Position',
+        Condition => '$$self{FacesDetected} >= 4',
+        %faceInfo,
+    },
+    0x15 => {
+        Name => 'Face5Position',
+        Condition => '$$self{FacesDetected} >= 5',
+        %faceInfo,
+    },
+    0x1a => {
+        Name => 'Face6Position',
+        Condition => '$$self{FacesDetected} >= 6',
+        %faceInfo,
+    },
+    0x1f => {
+        Name => 'Face7Position',
+        Condition => '$$self{FacesDetected} >= 7',
+        %faceInfo,
+    },
+    0x24 => {
+        Name => 'Face8Position',
+        Condition => '$$self{FacesDetected} >= 8',
+        %faceInfo,
+    },
+);
+
+%Image::ExifTool::Sony::FaceInfoA = ( # different offsets for A450/A500/A550
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int16u',
+    DATAMEMBER => [ 0x02, 0x03, 0x08 ],
+#
+# The FacesDetected number at 0x03 below is often 1 lower than the one at Tag900b 0x02.
+# The number of Face Positions starting at 0x5b (max. 4) corresponds to the number at 0x03.
+# The number of Face Positions starting at 0x0b usually corresponds to the FacesDetected number of Tag900b...
+# Therefore created the extra condition at 0x0b (11.1) to output an available FacePosition, even when 0x03=0...
+#
+    0x02 => {
+        Name => 'FaceTest2',
+        DataMember => 'FaceTest2',
+        Hidden => 1,
+        RawConv => '$$self{FaceTest2} = $val; $$self{OPTIONS}{Unknown}<2 ? undef : $val',
+    },
+    0x03 => {
+        Name => 'FacesDetected',
+        DataMember => 'FacesDetected',
+        RawConv => '$$self{FacesDetected} = ($val > 8 ? 0 : $val); $val',
+        ValueConv => '$val > 8 ? 0 : $val',
+    },
+    0x08 => {
+        Name => 'FaceTest8',
+        DataMember => 'FaceTest8',
+        Hidden => 1,
+        RawConv => '$$self{FaceTest8} = $val; $$self{OPTIONS}{Unknown}<2 ? undef : $val',
+    },
+# 0x0b - start of 8 Face Positions of 10 int16u values each
+    0x0b => {
+        Name => 'PotentialFace1Position',
+        Condition => q{
+            $$self{FacesDetected} >= 1 or
+            ($$self{FaceTest8} > 0 and ($$self{FaceTest2} == 1 or $$self{FaceTest2} == 257))
+        },
+        %faceInfo,
+    },
+    0x15 => {
+        Name => 'PotentialFace2Position',
+        Condition => '$$self{FacesDetected} >= 2 or ($$self{FacesDetected} == 1 and $$self{FaceTest8} > 0)',
+        %faceInfo,
+    },
+    0x1f => {
+        Name => 'PotentialFace3Position',
+        Condition => '$$self{FacesDetected} >= 3 or ($$self{FacesDetected} == 2 and $$self{FaceTest8} > 0)',
+        %faceInfo,
+    },
+    0x29 => {
+        Name => 'PotentialFace4Position',
+        Condition => '$$self{FacesDetected} >= 4 or ($$self{FacesDetected} == 3 and $$self{FaceTest8} > 0)',
+        %faceInfo,
+    },
+    0x33 => {
+        Name => 'PotentialFace5Position',
+        Condition => '$$self{FacesDetected} >= 5 or ($$self{FacesDetected} == 4 and $$self{FaceTest8} > 0)',
+        %faceInfo,
+    },
+    0x3d => {
+        Name => 'PotentialFace6Position',
+        Condition => '$$self{FacesDetected} >= 6 or ($$self{FacesDetected} == 5 and $$self{FaceTest8} > 0)',
+        %faceInfo,
+    },
+    0x47 => {
+        Name => 'PotentialFace7Position',
+        Condition => '$$self{FacesDetected} >= 7 or ($$self{FacesDetected} == 6 and $$self{FaceTest8} > 0)',
+        %faceInfo,
+    },
+    0x51 => {
+        Name => 'PotentialFace8Position',
+        Condition => '$$self{FacesDetected} >= 8 or ($$self{FacesDetected} == 7 and $$self{FaceTest8} > 0)',
+        %faceInfo,
+    },
+# 0x5b - start of max. 4 further Face Positions here
+    0x5b => {
+        Name => 'Face1Position',
+        Condition => '$$self{FacesDetected} >= 1',
+        %faceInfo,
+    },
+    0x65 => {
+        Name => 'Face2Position',
+        Condition => '$$self{FacesDetected} >= 2',
+        %faceInfo,
+    },
+    0x6f => {
+        Name => 'Face3Position',
+        Condition => '$$self{FacesDetected} >= 3',
+        %faceInfo,
+    },
+    0x79 => {
+        Name => 'Face4Position',
+        Condition => '$$self{FacesDetected} >= 4',
+        %faceInfo,
+    },
+);
+
+# Camera settings (ref PH) (decoded mainly from A200)
+%Image::ExifTool::Sony::CameraSettings = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int16u',
+    PRIORITY => 0,
+    NOTES => 'Camera settings for the A200, A300, A350, A700, A850 and A900.',
+    0x00 => { #JR
+        Name => 'ExposureTime',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x01 => { #JR
+        Name => 'FNumber',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
+    },
+    0x02 => { #JR (requires external flash)
+        Name => 'HighSpeedSync',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x03 => { #JR
+        Name => 'ExposureCompensationSet',
+        ValueConv => '($val - 128) / 24',
+        ValueConvInv => 'int($val * 24 + 128.5)',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x04 => { #7/JR
+        Name => 'DriveMode',
+        Mask => 0xff, # (not sure what upper byte is for)
+        PrintHex => 1,
+        PrintConv => {
+            0x01 => 'Single Frame',
+            0x02 => 'Continuous High', # A700/A900; not on A850
+            0x12 => 'Continuous Low', #JR
+            0x04 => 'Self-timer 10 sec',
+            0x05 => 'Self-timer 2 sec, Mirror Lock-up',
+            0x06 => 'Single-frame Bracketing',
+            0x07 => 'Continuous Bracketing', # (A200 val=0x1107)
+            0x18 => 'White Balance Bracketing Low', #JR
+            0x28 => 'White Balance Bracketing High', #JR
+            0x19 => 'D-Range Optimizer Bracketing Low', #JR
+            0x29 => 'D-Range Optimizer Bracketing High', #JR
+            0x0a => 'Remote Commander', #JR
+            0x0b => 'Mirror Lock-up', #JR (A850/A900; not on A700)
+        },
+    },
+    0x05 => { #JR
+        Name => 'WhiteBalanceSetting',
+        PrintConv => {
+            2 => 'Auto',
+            4 => 'Daylight',
+            5 => 'Fluorescent',
+            6 => 'Tungsten',
+            7 => 'Flash',
+            16 => 'Cloudy',
+            17 => 'Shade',
+            18 => 'Color Temperature/Color Filter',
+            32 => 'Custom 1',
+            33 => 'Custom 2',
+            34 => 'Custom 3',
+        },
+    },
+    0x06 => { #7 (A700) (ref JR: at least also valid for A200, ValueConv as for ColorCompensationFilterSet)
+        Name => 'WhiteBalanceFineTune',
+        ValueConv => '$val > 128 ? $val - 256 : $val',
+        ValueConvInv => '$val < 0 ? $val + 256 : $val',
+    },
+    0x07 => { #JR as set in WB "Color Temperature/Color Filter" and in White Balance Bracketing
+        Name => 'ColorTemperatureSet',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+        PrintConv => '"$val K"',
+        PrintConvInv => '$val =~ s/ ?K$//i; $val',
+    },
+    0x08 => { #JR as set in WB "Color Temperature/Color Filter"
+        Name => 'ColorCompensationFilterSet',
+        Notes => 'negative is green, positive is magenta',
+        ValueConv => '$val > 128 ? $val - 256 : $val',
+        ValueConvInv => '$val < 0 ? $val + 256 : $val',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x0c => { #JR as set in WB "Custom" and in White Balance Bracketing
+        Name => 'ColorTemperatureCustom',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+        PrintConv => '"$val K"',
+        PrintConvInv => '$val =~ s/ ?K$//i; $val',
+    },
+    0x0d => { #JR as set in WB "Custom"
+        Name => 'ColorCompensationFilterCustom',
+        Notes => 'negative is green, positive is magenta',
+        ValueConv => '$val > 128 ? $val - 256 : $val',
+        ValueConvInv => '$val < 0 ? $val + 256 : $val',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x0f => { #JR
+        Name => 'WhiteBalance',
+        PrintConv => {
+            2 => 'Auto',
+            4 => 'Daylight',
+            5 => 'Fluorescent',
+            6 => 'Tungsten',
+            7 => 'Flash',
+            12 => 'Color Temperature',
+            13 => 'Color Filter',
+            14 => 'Custom',
+            16 => 'Cloudy',
+            17 => 'Shade',
+        },
+    },
+    0x10 => { #7 (A700)
+        Name => 'FocusModeSetting',
+        PrintConv => {
+            0 => 'Manual',
+            1 => 'AF-S',
+            2 => 'AF-C',
+            3 => 'AF-A',
+            4 => 'DMF', #JR
+        },
+    },
+    0x11 => { #JD (A700)
+        Name => 'AFAreaMode',
+        PrintConv => {
+            0 => 'Wide',
+            1 => 'Local',
+            2 => 'Spot',
+        },
+    },
+    0x12 => { #7 (A700)
+        Name => 'AFPointSetting',
+        Format => 'int16u',
+        # The AF point as selected by the user in AFAreaMode=Local or Spot;
+        # Reported value remains at the last-set position in AFAreaModes=Wide.
+        # A200, A300, A350: 9-point centre-cross (ref JR)
+        # A700: 11-point centre-dual-cross (ref JR)
+        # A850, A900: 9-point centre-dual-cross with 10 assist-points (ref JR)
+        PrintConvColumns => 2,
+        PrintConv => {
+            1 => 'Center',
+            2 => 'Top',
+            3 => 'Upper-right',
+            4 => 'Right',
+            5 => 'Lower-right',
+            6 => 'Bottom',
+            7 => 'Lower-left',
+            8 => 'Left',
+            9 => 'Upper-left',
+            10 => 'Far Right', # (presumably A700 only)
+            11 => 'Far Left', # (presumably A700 only)
+        },
+    },
+    0x13 => { #JR
+        Name => 'FlashMode',
+        PrintConv => {
+            0 => 'Autoflash',
+            2 => 'Rear Sync',
+            3 => 'Wireless',
+            4 => 'Fill-flash',
+            5 => 'Flash Off',
+            6 => 'Slow Sync',
+        },
+    },
+    0x14 => { #JR
+        Name => 'FlashExposureCompSet',
+        Description => 'Flash Exposure Comp. Setting',
+        # (as pre-selected by the user, not zero if flash didn't fire)
+        ValueConv => '($val - 128) / 24', #PH
+        ValueConvInv => 'int($val * 24 + 128.5)',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x15 => { #7
+        Name => 'MeteringMode',
+        PrintConv => {
+            1 => 'Multi-segment',
+            2 => 'Center-weighted average',
+            4 => 'Spot',
+        },
+    },
+    0x16 => {
+        Name => 'ISOSetting',
+        # 0 indicates 'Auto' (I think)
+        ValueConv => '$val ? exp(($val/8-6)*log(2))*100 : $val',
+        ValueConvInv => '$val ? 8*(log($val/100)/log(2)+6) : $val',
+        PrintConv => '$val ? sprintf("%.0f",$val) : "Auto"',
+        PrintConvInv => '$val =~ /auto/i ? 0 : $val',
+    },
+    0x18 => { #7
+        Name => 'DynamicRangeOptimizerMode',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Standard',
+            2 => 'Advanced Auto',
+            3 => 'Advanced Level',
+        },
+    },
+    0x19 => { #7
+        Name => 'DynamicRangeOptimizerLevel',
+    },
+    0x1a => { # style actually used (combination of mode dial + creative style menu)
+        Name => 'CreativeStyle',
+        PrintConvColumns => 2,
+        PrintConv => {
+            1 => 'Standard',
+            2 => 'Vivid',
+            3 => 'Portrait',
+            4 => 'Landscape',
+            5 => 'Sunset',
+            6 => 'Night View/Portrait',
+            8 => 'B&W',
+            9 => 'Adobe RGB', # A700
+            11 => 'Neutral',
+            12 => 'Clear', #7
+            13 => 'Deep', #7
+            14 => 'Light', #7
+            15 => 'Autumn Leaves', #7
+            16 => 'Sepia', #7
+        },
+    },
+    0x1b => { #JR
+        Name => 'ColorSpace',
+        PrintConv => {
+            0 => 'sRGB',
+            1 => 'Adobe RGB',        # (A850, selected via Colorspace menu item)
+            5 => 'Adobe RGB (A700)', # (A700, selected via CreativeStyle menu)
         },
     },
@@ -783,5 +4168,4 @@
     0x1f => { #7
         Name => 'ZoneMatchingValue',
-        Condition => '$$self{Model} !~ /DSLR-A230/',
         ValueConv => '$val - 10',
         ValueConvInv => '$val + 10',
@@ -791,5 +4175,4 @@
     0x22 => { #7
         Name => 'Brightness',
-        Condition => '$$self{Model} !~ /DSLR-A230/',
         ValueConv => '$val - 10',
         ValueConvInv => '$val + 10',
@@ -798,14 +4181,13 @@
     },
     0x23 => {
-        Name => 'FlashMode',
+        Name => 'FlashControl',
         PrintConv => {
             0 => 'ADI',
-            1 => 'TTL',
+            1 => 'Pre-flash TTL',
+            2 => 'Manual',
         },
     },
     0x28 => { #7
         Name => 'PrioritySetupShutterRelease',
-        Condition => '$$self{Model} =~ /DSLR-A700\b/',
-        Notes => 'A700 only',
         PrintConv => {
             0 => 'AF',
@@ -815,6 +4197,4 @@
     0x29 => { #7
         Name => 'AFIlluminator',
-        Condition => '$$self{Model} =~ /DSLR-A700\b/',
-        Notes => 'A700 only',
         PrintConv => {
             0 => 'Auto',
@@ -824,30 +4204,30 @@
     0x2a => { #7
         Name => 'AFWithShutter',
-        Condition => '$$self{Model} =~ /DSLR-A700\b/',
-        Notes => 'A700 only',
         PrintConv => { 0 => 'On', 1 => 'Off' },
     },
     0x2b => { #7
         Name => 'LongExposureNoiseReduction',
-        Condition => '$$self{Model} =~ /DSLR-A700\b/',
-        Notes => 'A700 only',
         PrintConv => { 0 => 'Off', 1 => 'On' },
     },
     0x2c => { #7
         Name => 'HighISONoiseReduction',
-        Condition => '$$self{Model} =~ /DSLR-A700\b/',
-        Notes => 'A700 only',
-        0 => 'Normal',
-        1 => 'Low',
-        2 => 'High',
-        3 => 'Off',
+        PrintConv => {
+            0 => 'Normal',
+            1 => 'Low',
+            2 => 'High',
+            3 => 'Off',
+        },
     },
     0x2d => { #7
         Name => 'ImageStyle',
-        Condition => '$$self{Model} =~ /DSLR-A700\b/',
-        Notes => 'A700 only',
+        PrintConvColumns => 2,
         PrintConv => {
             1 => 'Standard',
             2 => 'Vivid',
+            3 => 'Portrait', #PH
+            4 => 'Landscape', #PH
+            5 => 'Sunset', #PH
+            7 => 'Night View/Portrait', #PH (A200/A350 when CreativeStyle was 6!)
+            8 => 'B&W', #PH (guess)
             9 => 'Adobe RGB',
             11 => 'Neutral',
@@ -855,15 +4235,49 @@
             130 => 'StyleBox2',
             131 => 'StyleBox3',
-        },
-    },
-    # 0x2d - A900:1=?,4=?,129=std,130=vivid,131=neutral,132=portrait,133=landscape,134=b&w
+            132 => 'StyleBox4', #JR (A850)
+            133 => 'StyleBox5', #JR (A850)
+            134 => 'StyleBox6', #JR (A850)
+        },
+    },
+    0x2e => { #JR (may not apply to A200/A300/A350 -- they don't have the AF/MF button)
+        Name => 'FocusModeSwitch',
+        PrintConv => {
+            0 => 'AF',
+            1 => 'Manual',
+        },
+    },
+    0x2f => { #JR
+        Name => 'ShutterSpeedSetting',
+        Notes => 'used in M, S and Program Shift S modes',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x30 => { #JR
+        Name => 'ApertureSetting',
+        Notes => 'used in M, A and Program Shift A modes',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
+    },
     0x3c => {
         Name => 'ExposureProgram',
-        Priority => 0,
+        SeparateTable => 'ExposureProgram',
         PrintConv => \%sonyExposureProgram,
     },
     0x3d => {
-        Name => 'ImageStabilization',
+        Name => 'ImageStabilizationSetting',
         PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x3e => { #JR
+        Name => 'FlashAction',
+        PrintConv => {
+            0 => 'Did not fire',
+            1 => 'Fired',
+            2 => 'External Flash, Did not fire',
+            3 => 'External Flash, Fired',
+        },
     },
     0x3f => { # (verified for A330/A380)
@@ -873,4 +4287,62 @@
             1 => 'Rotate 90 CW', #(NC)
             2 => 'Rotate 270 CW',
+        },
+    },
+    0x40 => { #JR
+        Name => 'AELock',
+        PrintConv => {
+            1 => 'Off',
+            2 => 'On',
+        },
+    },
+    0x4c => { #JR
+        Name => 'FlashAction2',
+        PrintConv => {
+            1 => 'Fired, Autoflash',
+            2 => 'Fired, Fill-flash',
+            3 => 'Fired, Rear Sync',
+            4 => 'Fired, Wireless',
+            5 => 'Did not fire',
+            6 => 'Fired, Slow Sync',
+            17 => 'Fired, Autoflash, Red-eye reduction',
+            18 => 'Fired, Fill-flash, Red-eye reduction',
+            34 => 'Fired, Fill-flash, HSS',
+        },
+    },
+    0x4d => { #JR
+        Name => 'FocusMode', # (focus mode actually used)
+        PrintConv => {
+            0 => 'Manual',
+            1 => 'AF-S',
+            2 => 'AF-C',
+            3 => 'AF-A',
+            4 => 'DMF', #JR
+        },
+    },
+    0x50 => { #JR
+        Name => 'BatteryState',
+        PrintConv => {
+            2 => 'Empty',      # 0%
+            3 => 'Very Low',   # 1 - 20%
+            4 => 'Low',        # 21 - 50%
+            5 => 'Sufficient', # 51 - 80%
+            6 => 'Full',       # > 80%
+        },
+    },
+    0x51 => { #JR
+        Name => 'BatteryLevel',
+        PrintConv => '"$val%"',
+        PrintConvInv => '$val=~s/\s*\%//; $val',
+    },
+    0x53 => { #JR
+        Name => 'FocusStatus',
+        PrintConv => {
+            0 => 'Not confirmed',
+            4 => 'Not confirmed, Tracking',
+            BITMASK => {
+                0 => 'Confirmed',
+                1 => 'Failed',
+                2 => 'Tracking',
+            },
         },
     },
@@ -908,15 +4380,135 @@
             50 => '1/2 EV',
         },
-    },            
+    },
+    0x6a => { #JR
+        Name => 'RedEyeReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x9a => { #JR
+        Name => 'FolderNumber',
+        Mask => 0x03ff, # (not sure what the upper 6 bits are for)
+        PrintConv => 'sprintf("%.3d",$val)',
+        PrintConvInv => '$val',
+    },
+    0x9b => { #JR
+        Name => 'ImageNumber',
+        Mask => 0x3fff, # (not sure what the upper 2 bits are for)
+        PrintConv => 'sprintf("%.4d",$val)',
+        PrintConvInv => '$val',
+    },
 );
 
-# Camera settings (ref PH) (A330 and A380)
+# Camera settings (ref PH) (A230, A290, A330, A380 and A390)
 %Image::ExifTool::Sony::CameraSettings2 = (
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
     FORMAT => 'int16u',
-    NOTES => 'Camera settings for the A330 and A380.',
-    0x10 => { #7 (A700, not confirmed for other models)
-        Name => 'FocusMode',
+    PRIORITY => 0,
+    NOTES => 'Camera settings for the A230, A290, A330, A380 and A390.',
+### 0x00-0x03: same TagID as CameraSettings
+    0x00 => { #JR
+        Name => 'ExposureTime',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x01 => { #JR
+        Name => 'FNumber',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
+    },
+    0x02 => { #JR (requires external flash)
+        Name => 'HighSpeedSync',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x03 => { #JR
+        Name => 'ExposureCompensationSet',
+        ValueConv => '($val - 128) / 24',
+        ValueConvInv => 'int($val * 24 + 128.5)',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+### 0x04-0x11: subtract 1 from CameraSettings TagID
+    0x04 => { #JR
+        Name => 'WhiteBalanceSetting',
+        PrintConv => {
+            2 => 'Auto',
+            4 => 'Daylight',
+            5 => 'Fluorescent',
+            6 => 'Tungsten',
+            7 => 'Flash',
+            16 => 'Cloudy',
+            17 => 'Shade',
+            18 => 'Color Temperature/Color Filter',
+            32 => 'Custom 1',
+            33 => 'Custom 2',
+            34 => 'Custom 3',
+        },
+    },
+    0x05 => { #JR
+        Name => 'WhiteBalanceFineTune',
+        ValueConv => '$val > 128 ? $val - 256 : $val',
+        ValueConvInv => '$val < 0 ? $val + 256 : $val',
+    },
+    0x06 => { #JR as set in WB "Color Temperature/Color Filter" and in White Balance Bracketing
+        Name => 'ColorTemperatureSet',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+        PrintConv => '"$val K"',
+        PrintConvInv => '$val =~ s/ ?K$//i; $val',
+    },
+    0x07 => { #JR as set in WB "Color Temperature/Color Filter"
+        Name => 'ColorCompensationFilterSet',
+        Notes => 'negative is green, positive is magenta',
+        ValueConv => '$val > 128 ? $val - 256 : $val',
+        ValueConvInv => '$val < 0 ? $val + 256 : $val',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x08 => { #JR
+        Name => 'CustomWB_RGBLevels',
+        Format => 'int16u[3]',
+    },
+    0x0b => { #JR as set in WB "Custom" and in White Balance Bracketing
+        Name => 'ColorTemperatureCustom',
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+        PrintConv => '"$val K"',
+        PrintConvInv => '$val =~ s/ ?K$//i; $val',
+    },
+    0x0c => { #JR as set in WB "Custom"
+        Name => 'ColorCompensationFilterCustom',
+        Notes => 'negative is green, positive is magenta',
+        ValueConv => '$val > 128 ? $val - 256 : $val',
+        ValueConvInv => '$val < 0 ? $val + 256 : $val',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x0e => { #JR
+        Name => 'WhiteBalance',
+        PrintConv => {
+            2 => 'Auto',
+            4 => 'Daylight',
+            5 => 'Fluorescent',
+            6 => 'Tungsten',
+            7 => 'Flash',
+            12 => 'Color Temperature',
+            13 => 'Color Filter',
+            14 => 'Custom',
+            16 => 'Cloudy',
+            17 => 'Shade',
+        },
+    },
+    0x0f => { #JR/PH (educated guess)
+        Name => 'FocusModeSetting',
         PrintConv => {
             0 => 'Manual',
@@ -924,7 +4516,8 @@
             2 => 'AF-C',
             3 => 'AF-A',
-        },
-    },
-    0x11 => { #JD (A700)
+            # seen 5 for A380 (FocusMode was Manual and FocusStatus was Confirmed)
+        },
+    },
+    0x10 => { #JR/PH (educated guess)
         Name => 'AFAreaMode',
         PrintConv => {
@@ -934,21 +4527,32 @@
         },
     },
-    0x12 => { #7 (A700, not confirmed for other models)
-        Name => 'LocalAFAreaPoint',
+    0x11 => { #JR/PH (educated guess)
+        Name => 'AFPointSetting',
         Format => 'int16u',
+        # The AF point as selected by the user in AFAreaMode=Local or Spot;
+        # Reported value remains at the last-set position in AFAreaModes=Wide.
+        # (all of these cameras have a 9-point centre-cross AF system, ref JR)
+        PrintConvColumns => 2,
         PrintConv => {
             1 => 'Center',
             2 => 'Top',
-            3 => 'Top-Right',
+            3 => 'Upper-right',
             4 => 'Right',
-            5 => 'Bottom-Right',
+            5 => 'Lower-right',
             6 => 'Bottom',
-            7 => 'Bottom-Left',
+            7 => 'Lower-left',
             8 => 'Left',
-            9 => 'Top-Left',
-            10 => 'Far Right',
-            11 => 'Far Left',
-            # see value of 128 for some models
-        },
+            9 => 'Upper-left',
+        },
+    },
+### 0x12-0x18: subtract 2 from CameraSettings TagID
+    0x12 => { #JR
+        Name => 'FlashExposureCompSet',
+        Description => 'Flash Exposure Comp. Setting',
+        # (as pre-selected by the user, not zero if flash didn't fire)
+        ValueConv => '($val - 128) / 24', #PH
+        ValueConvInv => 'int($val * 24 + 128.5)',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
     },
     0x13 => {
@@ -956,5 +4560,5 @@
         PrintConv => {
             1 => 'Multi-segment',
-            2 => 'Center-weighted Average',
+            2 => 'Center-weighted average',
             4 => 'Spot',
         },
@@ -977,9 +4581,8 @@
         },
     },
-    0x17 => {
-        Name => 'DynamicRangeOptimizerLevel',
-    },
+    0x17 => 'DynamicRangeOptimizerLevel',
     0x18 => { # A380
         Name => 'CreativeStyle',
+        PrintConvColumns => 2,
         PrintConv => {
             1 => 'Standard',
@@ -990,8 +4593,8 @@
             6 => 'Night View/Portrait',
             8 => 'B&W',
-            9 => 'Adobe RGB',
-            11 => 'Neutral',
-        },
-    },
+            # (these models don't have Neutral - PH)
+        },
+    },
+### 0x19-0x1b: subtract 3 from CameraSettings TagID
     0x19 => {
         Name => 'Sharpness',
@@ -1015,17 +4618,77 @@
         PrintConvInv => '$val',
     },
-    0x23 => {
-        Name => 'FlashMode',
+### 0x1c-0x24: subtract 4 from CameraSettings TagID (not sure about 0x1c)
+    0x1f => { #PH (educated guess)
+        Name => 'FlashControl',
         PrintConv => {
             0 => 'ADI',
-            1 => 'TTL',
-        },
-    },
-    # 0x27 - also related to CreativeStyle:
-    #  A380:1=std,2=vivid,3=portrait,4=landscape,5=sunset,7=night view,8=b&w
+            1 => 'Pre-flash TTL',
+            2 => 'Manual',
+        },
+    },
+### 0x25-0x27: subtract 6 from CameraSettings TagID
+    0x25 => { #PH
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x26 => { #PH
+        Name => 'HighISONoiseReduction',
+        # (Note: the order is different from that in CameraSettings)
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Normal',
+            3 => 'High',
+        },
+    },
+    0x27 => { #PH
+        Name => 'ImageStyle',
+        PrintConvColumns => 2,
+        PrintConv => {
+            1 => 'Standard',
+            2 => 'Vivid',
+            3 => 'Portrait', #PH
+            4 => 'Landscape', #PH
+            5 => 'Sunset', #PH
+            7 => 'Night View/Portrait', #PH (A200 when CreativeStyle was 6!)
+            8 => 'B&W', #PH (A380)
+            # (these models don't have Neutral - PH)
+        },
+    },
+### 0x28-0x3b: subtract 7 from CameraSettings TagID
+    0x28 => { #PH
+        Name => 'ShutterSpeedSetting',
+        Notes => 'used in M, S and Program Shift S modes',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x29 => { #PH
+        Name => 'ApertureSetting',
+        Notes => 'used in M, A and Program Shift A modes',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
+    },
+### 0x3c-0x59: same TagID as CameraSettings
     0x3c => {
         Name => 'ExposureProgram',
-        Priority => 0,
+        SeparateTable => 'ExposureProgram',
         PrintConv => \%sonyExposureProgram,
+    },
+    0x3d => { # (copied from CameraSettings, ref JR)
+        Name => 'ImageStabilizationSetting',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x3e => { #JR
+        Name => 'FlashAction',
+        PrintConv => {
+            0 => 'Did not fire',
+            1 => 'Fired',
+            2 => 'External Flash, Did not fire',
+            3 => 'External Flash, Fired',
+        },
     },
     0x3f => { # (verified for A330/A380)
@@ -1037,4 +4700,46 @@
         },
     },
+    0x40 => { #JR
+        Name => 'AELock',
+        PrintConv => {
+            1 => 'Off',
+            2 => 'On',
+        },
+    },
+    0x4c => { #JR
+        Name => 'FlashAction2',
+        PrintConv => {
+            1 => 'Fired, Autoflash',
+            2 => 'Fired, Fill-flash',
+            3 => 'Fired, Rear Sync',
+            4 => 'Fired, Wireless',
+            5 => 'Did not fire',
+            6 => 'Fired, Slow Sync',
+            17 => 'Fired, Autoflash, Red-eye reduction',
+            18 => 'Fired, Fill-flash, Red-eye reduction',
+            34 => 'Fired, Fill-flash, HSS',
+        },
+    },
+    0x4d => { #JR
+        Name => 'FocusMode', # (focus mode actually used)
+        PrintConv => {
+            0 => 'Manual',
+            1 => 'AF-S',
+            2 => 'AF-C',
+            3 => 'AF-A',
+        },
+    },
+    0x53 => { #JR (copied from CameraSettings, but all bits may not be applicable for these models)
+        Name => 'FocusStatus',
+        PrintConv => {
+            0 => 'Not confirmed',
+            4 => 'Not confirmed, Tracking',
+            BITMASK => {
+                0 => 'Confirmed',
+                1 => 'Failed',
+                2 => 'Tracking',
+            },
+        },
+    },
     0x54 => {
         Name => 'SonyImageSize',
@@ -1045,5 +4750,743 @@
         },
     },
-    # 0x56 - something to do with JPEG quality?
+    0x55 => { # (copied from CameraSettings, ref JR)
+        Name => 'AspectRatio',
+        PrintConv => {
+            1 => '3:2',
+            2 => '16:9',
+        },
+    },
+    0x56 => { # (copied from CameraSettings, ref JR)
+        Name => 'Quality',
+        PrintConv => {
+            0 => 'RAW',
+            2 => 'CRAW',
+            34 => 'RAW + JPEG',
+            35 => 'CRAW + JPEG',
+            16 => 'Extra Fine',
+            32 => 'Fine',
+            48 => 'Standard',
+        },
+    },
+    0x58 => { # (copied from CameraSettings, ref JR)
+        Name => 'ExposureLevelIncrements',
+        PrintConv => {
+            33 => '1/3 EV',
+            50 => '1/2 EV',
+        },
+    },
+### 0x5a onwards: subtract 1 from CameraSettings TagID
+    # (0x69 not confirmed)
+    #0x69 => { #JR
+    #    Name => 'RedEyeReduction',
+    #    PrintConv => {
+    #        0 => 'Off',
+    #        1 => 'On',
+    #    },
+    #},
+    0x7e => { #JR
+        Name => 'DriveMode',
+        Mask => 0xff, # (not sure what upper byte is for)
+        PrintConv => { # (values confirmed for specified models - PH)
+            1 => 'Single Frame', # (A230,A330,A380)
+            2 => 'Continuous High', #PH (A230,A330)
+            4 => 'Self-timer 10 sec', # (A230)
+            5 => 'Self-timer 2 sec, Mirror Lock-up', # (A230,A290,A330,A380,390)
+            7 => 'Continuous Bracketing', # (A230 val=0x1107, A330 val=0x1307 [0.7 EV])
+            10 => 'Remote Commander', # (A230)
+            11 => 'Continuous Self-timer', # (A230 val=0x800b [5 shots], A330 val=0x400b [3 shots])
+        },
+    },
+    0x7f => { #JR
+        Name => 'FlashMode',
+        PrintConv => {
+            0 => 'Autoflash',
+            2 => 'Rear Sync',
+            3 => 'Wireless',
+            4 => 'Fill-flash',
+            5 => 'Flash Off',
+            6 => 'Slow Sync',
+        },
+    },
+    0x83 => { #PH
+        Name => 'ColorSpace',
+        PrintConv => {
+            5 => 'Adobe RGB',
+            6 => 'sRGB',
+        },
+    },
+);
+
+# more Camera settings (ref PH)
+# This was decoded for the A55, but it seems to apply to the following models:
+# A33, A35, A55, A450, A500, A550, A560, A580, NEX-3, NEX-5, NEX-C3 and NEX-VG10E
+%Image::ExifTool::Sony::CameraSettings3 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int8u',
+    PRIORITY => 0,
+    DATAMEMBER => [ 0x99 ],
+    NOTES => q{
+        Camera settings for models such as the A33, A35, A55, A450, A500, A550,
+        A560, A580, NEX-3, NEX-5, NEX-C3 and NEX-VG10E.
+    },
+    0x00 => { #JR
+        Name => 'ShutterSpeedSetting',
+        Notes => 'used only in M and S exposure modes',
+        ValueConv => '$val ? 2 ** (6 - $val/8) : 0',
+        ValueConvInv => '$val ? int((6 - log($val) / log(2)) * 8 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x01 => { #JR
+        Name => 'ApertureSetting',
+        Notes => 'used only in M and A exposure modes',
+        ValueConv => '2 ** (($val/8 - 1) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
+        PrintConvInv => '$val',
+    },
+    0x02 => {
+        Name => 'ISOSetting',
+        ValueConv => '($val and $val < 254) ? exp(($val/8-6)*log(2))*100 : $val',
+        ValueConvInv => '($val and $val != 254) ? 8*(log($val/100)/log(2)+6) : $val',
+        PrintConv => {
+            OTHER => sub {
+                my ($val, $inv) = @_;
+                return int($val + 0.5) unless $inv;
+                return Image::ExifTool::IsFloat($val) ? $val : undef;
+            },
+            0 => 'Auto',
+            254 => 'n/a', # get this for multi-shot noise reduction
+        },
+    },
+    0x03 => { #JR
+        Name => 'ExposureCompensationSet',
+        ValueConv => '($val - 128) / 24', #PH
+        ValueConvInv => 'int($val * 24 + 128.5)',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x04 => { #JR
+        Name => 'DriveModeSetting',
+        # Same drivemode info is repeated in 0x0034, but with at least the following exceptions:
+        # - 0x0034 not for A550 ? - seen "0"
+        # - hand-held night   (0x05=56): 0x0004=0x10 and 0x0034=0xd3
+        # - 3D sweep panorama (0x05=57): 0x0004=0x10 and 0x0034=0xd6
+        # - sweep panorama    (0x05=80): 0x0004=0x10 and 0x0034=0xd5
+        # preliminary conclusion: 0x0004 is Drivemode as pre-set, but may be overruled by Scene/Panorama mode selections
+        #                         0x0034 is Divemode as actually used
+        PrintHex => 1,
+        PrintConv => {
+            0x10 => 'Single Frame',
+            0x21 => 'Continuous High', # also automatically selected for Scene mode Sports-action (0x05=52)
+            0x22 => 'Continuous Low',
+            0x30 => 'Speed Priority Continuous',
+            0x51 => 'Self-timer 10 sec',
+            0x52 => 'Self-timer 2 sec, Mirror Lock-up',
+            0x71 => 'Continuous Bracketing 0.3 EV',
+            0x75 => 'Continuous Bracketing 0.7 EV',
+            0x91 => 'White Balance Bracketing Low',
+            0x92 => 'White Balance Bracketing High',
+            0xc0 => 'Remote Commander',
+        },
+    },
+    0x05 => { #JR
+        Name => 'ExposureProgram',
+        # Camera exposure program/mode as selected with the Mode dial.
+        # For SCN a further selection is done via the menu
+        # Matches OK with 0xb023
+        SeparateTable => 'ExposureProgram2',
+        PrintConv => \%sonyExposureProgram2,
+    },
+    0x06 => { #JR
+        Name => 'FocusModeSetting',
+        PrintConv => {
+            17 => 'AF-S',
+            18 => 'AF-C',
+            19 => 'AF-A',
+            32 => 'Manual',
+            48 => 'DMF', #(NC) (seen for NEX-5)
+        },
+    },
+    0x07 => { #JR
+        Name => 'MeteringMode',
+        PrintConv => {
+            1 => 'Multi-segment',
+            2 => 'Center-weighted average',
+            3 => 'Spot',
+        },
+    },
+    0x09 => { #JR
+        Name => 'SonyImageSize',
+        PrintConv => {  # values confirmed as noted for the A580 and A33
+           21 => 'Large (3:2)',    # A580: 16M  (4912x3264), A33: 14M  (4592x3056)
+           22 => 'Medium (3:2)',   # A580: 8.4M (3568x2368), A33: 7.4M (3344x2224)
+           23 => 'Small (3:2)',    # A580: 4.0M (2448x1624), A33: 3.5M (2288x1520)
+           25 => 'Large (16:9)',   # A580: 14M  (4912x2760)
+           26 => 'Medium (16:9)',  # A580: 7.1M (3568x2000)
+           27 => 'Small (16:9)',   # A580: 3.4M (2448x1376)
+        },
+    },
+    0x0a => { #JR
+        Name => 'AspectRatio',
+        # normally 4 for A580 3:2 ratio images
+        # seen 8 when selecting 16:9 via menu, and when selecting Panorama mode
+        PrintConv => {
+            4 => '3:2',
+            8 => '16:9',
+        },
+    },
+    0x0b => { #JR
+        Name => 'Quality',
+        PrintConv => {
+            2 => 'RAW',
+            4 => 'RAW + JPEG',
+            6 => 'Fine',
+            7 => 'Standard',
+        },
+    },
+    0x0c => {
+        Name => 'DynamicRangeOptimizerSetting',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On (Auto)',
+            17 => 'On (Manual)',
+        },
+    },
+    0x0d => 'DynamicRangeOptimizerLevel',
+    0x0e => { #JR
+        Name => 'ColorSpace',
+        PrintConv => {
+            1 => 'sRGB',
+            2 => 'Adobe RGB',
+        },
+    },
+    0x0f => { #JR
+        Name => 'CreativeStyleSetting',
+        PrintConvColumns => 2,
+        PrintConv => {
+            16 => 'Standard',
+            32 => 'Vivid',
+            64 => 'Portrait',
+            80 => 'Landscape',
+            96 => 'B&W',
+            160 => 'Sunset',
+        },
+    },
+    0x10 => { #JR (seen values 253, 254, 255, 0, 1, 2, 3)
+        Name => 'ContrastSetting',
+        Format => 'int8s',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x11 => { #JR
+        Name => 'SaturationSetting',
+        Format => 'int8s',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x12 => { #JR
+        Name => 'SharpnessSetting',
+        Format => 'int8s',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x16 => { #JR
+        Name => 'WhiteBalanceSetting',
+        # many guessed, based on "logical system" as observed for Daylight and Shade and steps of 16 between the modes
+        PrintHex => 1,
+        PrintConvColumns => 2,
+        PrintConv => \%whiteBalanceSetting,
+        SeparateTable => 1,
+    },
+    0x17 => { #JR
+        Name => 'ColorTemperatureSetting',
+        # matches "0xb021 ColorTemperature" when WB set to "Custom" or "Color Temperature/Color Filter"
+        ValueConv => '$val * 100',
+        ValueConvInv => '$val / 100',
+        PrintConv => '"$val K"',
+        PrintConvInv => '$val =~ s/ ?K$//i; $val',
+    },
+    0x18 => { #JR
+        Name => 'ColorCompensationFilterSet',
+        # seen 0, 1-9 and 245-255, corresponding to 0, M1-M9 and G9-G1 on camera display
+        # matches "0xb022 ColorCompensationFilter" when WB set to "Custom" or "Color Temperature/Color Filter"
+        Format => 'int8s',
+        Notes => 'negative is green, positive is magenta',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x19 => { #JR
+        Name => 'CustomWB_RGBLevels',
+        Format => 'int16uRev[3]',
+        # 0x19 - 0x1e are related to Custom WB measurements performed by the camera.
+        # The values change only each time when measuring and setting a new Custom WB.
+        # (0x19,0x1a) and (0x1d,0x1e) are same as MoreSettings (0x1a,0x1b) and (0x1c,0x1d)
+    },
+    # 0x1f - always 2 (ref JR)
+    0x20 => { #JR
+        Name => 'FlashMode',
+        PrintConvColumns => 2,
+        PrintConv => {
+            1 => 'Flash Off',
+            16 => 'Autoflash',
+            17 => 'Fill-flash',
+            18 => 'Slow Sync',
+            19 => 'Rear Sync',
+            20 => 'Wireless',
+        },
+    },
+    0x21 => { #JR
+        Name => 'FlashControl',
+        PrintConv => {
+            1 => 'ADI Flash',
+            2 => 'Pre-flash TTL',
+        },
+    },
+    0x23 => { #JR
+        Name => 'FlashExposureCompSet',
+        Description => 'Flash Exposure Comp. Setting',
+        # (as pre-selected by the user, not zero if flash didn't fire)
+        ValueConv => '($val - 128) / 24', #PH
+        ValueConvInv => 'int($val * 24 + 128.5)',
+        PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x24 => {
+        Name => 'AFAreaMode',
+        PrintConv => {
+            1 => 'Wide',
+            2 => 'Spot',
+            3 => 'Local',
+            4 => 'Flexible', #JR
+            # (Flexible Spot is a grid of 17x11 points for the NEX-5)
+        },
+    },
+    0x25 => { #JR
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On',  # (unused or dark subject)
+        },
+    },
+    0x26 => { #JR
+        Name => 'HighISONoiseReduction',
+        PrintConv => {
+            16 => 'Low',
+            17 => 'High',
+            19 => 'Auto',
+        },
+    },
+    0x27 => { #JR
+        Name => 'SmileShutterMode',
+        PrintConv => {
+            17 => 'Slight Smile',
+            18 => 'Normal Smile',
+            19 => 'Big Smile',
+        },
+    },
+    0x28 => { #JR
+        Name => 'RedEyeReduction',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On',
+        },
+    },
+    0x2d => {
+        Name => 'HDRSetting',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On (Auto)',
+            17 => 'On (Manual)',
+        },
+    },
+    0x2e => {
+        Name => 'HDRLevel',
+        PrintConvColumns => 3,
+        PrintConv => {
+            33 => '1 EV',
+            34 => '1.5 EV', #JR (NC)
+            35 => '2 EV',
+            36 => '2.5 EV', #JR (NC)
+            37 => '3 EV',
+            38 => '3.5 EV', #PH (NC)
+            39 => '4 EV',
+            40 => '5 EV',
+            41 => '6 EV',
+        },
+    },
+    0x2f => { #JR (not sure what is difference with 0x85)
+        Name => 'ViewingMode',
+        PrintConv => {
+            16 => 'ViewFinder',
+            33 => 'Focus Check Live View',
+            34 => 'Quick AF Live View',
+        },
+    },
+    0x30 => { #JR
+        Name => 'FaceDetection',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On',
+        },
+    },
+    0x31 => { #JR
+        Name => 'SmileShutter',
+        PrintConv => {
+            1 => 'Off',
+            16 => 'On',
+        },
+    },
+    0x32 => { #JR
+        Name => 'SweepPanoramaSize',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            1 => 'Standard',
+            2 => 'Wide',
+        },
+    },
+    0x33 => { #JR
+        Name => 'SweepPanoramaDirection',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            1 => 'Right',
+            2 => 'Left',
+            3 => 'Up',
+            4 => 'Down',
+        },
+    },
+    0x34 => { #JR
+        Name => 'DriveMode', # (drive mode actually used)
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        PrintHex => 1,
+        PrintConv => {
+            0x10 => 'Single Frame',
+            0x21 => 'Continuous High', # also automatically selected for Scene mode Sports-action (0x05=52)
+            0x22 => 'Continuous Low',
+            0x30 => 'Speed Priority Continuous',
+            0x51 => 'Self-timer 10 sec',
+            0x52 => 'Self-timer 2 sec, Mirror Lock-up',
+            0x71 => 'Continuous Bracketing 0.3 EV',
+            0x75 => 'Continuous Bracketing 0.7 EV',
+            0x91 => 'White Balance Bracketing Low',
+            0x92 => 'White Balance Bracketing High',
+            0xc0 => 'Remote Commander',
+            0xd1 => 'Continuous - HDR',
+            0xd2 => 'Continuous - Multi Frame NR',
+            0xd3 => 'Continuous - Handheld Night Shot', # (also called "Hand-held Twilight")
+            0xd4 => 'Continuous - Anti Motion Blur', #PH (NEX-5)
+            0xd5 => 'Continuous - Sweep Panorama',
+            0xd6 => 'Continuous - 3D Sweep Panorama',
+        },
+    },
+    0x35 => {
+        Name => 'MultiFrameNoiseReduction',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            0 => 'n/a', # seen for A450/A500/A550
+            1 => 'Off',
+            16 => 'On',
+            255 => 'None', # seen for NEX-3/5/C3
+        },
+    },
+    0x36 => { #JR (not 100% sure about this one)
+        Name => 'LiveViewAFSetting',
+        Condition => '$$self{Model} !~ /^(NEX-|DSLR-(A450|A500|A550)$)/',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Phase-detect AF',
+            2 => 'Contrast AF',
+            # Contrast AF is only available with SSM/SAM lenses and in Focus Check LV,
+            # NOT in Quick AF LV, and is automatically set when mounting SSM/SAM lens
+            # - changes into Phase-AF when switching to Quick AF LV.
+        },
+    },
+    0x38 => { #JR
+        Name => 'PanoramaSize3D',
+        Description => '3D Panorama Size',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'Standard',
+            2 => 'Wide',
+            3 => '16:9',
+        },
+    },
+    0x83 => { #JR
+        Name => 'AFButtonPressed',
+        # only indicates pressing and holding the "AF" button (centre-controller),
+        # not pressing the shutter release button halfway down
+        Condition => '$$self{Model} !~ /^(NEX-|DSLR-(A450|A500|A550)$)/',
+        PrintConv => {
+            1 => 'No',
+            16 => 'Yes',
+        },
+    },
+    0x84 => { #JR (not 100% sure about this one)
+        Name => 'LiveViewMetering',
+        Condition => '$$self{Model} !~ /^(NEX-|DSLR-(A450|A500|A550)$)/',
+        PrintConv => {
+            0 => 'n/a',
+            16 => '40 Segment',             # DSLR with LiveView/OVF switch in OVF position
+            32 => '1200-zone Evaluative',   # SLT, or DSLR with LiveView/OVF switch in LiveView position
+        },
+    },
+    0x85 => { #JR (not sure what is difference with 0x2f)
+        Name => 'ViewingMode2',
+        Condition => '$$self{Model} !~ /^(NEX-|DSLR-(A450|A500|A550)$)/',
+        PrintConv => {
+            0 => 'n/a',
+            16 => 'Viewfinder',
+            33 => 'Focus Check Live View',
+            34 => 'Quick AF Live View',
+        },
+    },
+    0x86 => { #JR
+        Name => 'AELock',
+        Condition => '$$self{Model} !~ /^(NEX-|DSLR-(A450|A500|A550)$)/',
+        PrintConv => {
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
+    0x87 => { #JR
+        Name => 'FlashStatusBuilt-in',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)/',
+        PrintConv => {
+            1 => 'Off',
+            2 => 'On',
+        },
+    },
+    0x88 => { #JR
+        Name => 'FlashStatusExternal',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)/',
+        PrintConv => {
+            1 => 'None',
+            2 => 'Off',
+            3 => 'On',
+        },
+    },
+#    0x8a => { #JR
+#        Name => 'LensAF',
+#        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+#        PrintConv => {
+#            1  => 'No',
+#            16 => 'AF Lens',
+#        },
+#    },
+    0x8b => { #JR
+        Name => 'LiveViewFocusMode',
+        Condition => '$$self{Model} !~ /^(NEX-|DSLR-(A450|A500|A550)$)/',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'AF',
+            16 => 'Manual',
+        },
+    },
+#    0x8e => { #JR
+#        Name => 'LensSAM',
+#        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+#        PrintConv => {
+#            1  => 'No',
+#            16 => 'SAM Lens',
+#        },
+#    },
+    0x99 => { #JR
+        Name => 'LensMount',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val',
+        PrintConv => {
+            1  => 'Unknown',
+            16 => 'A-mount',
+            17 => 'E-mount',
+        },
+    },
+#    0x9b => { #JR
+#        Name => 'LensOSS',
+#        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+#        PrintConv => {
+#            1  => 'No',
+#            16 => 'OSS Lens',
+#            17 => 'OSS Lens (NEX-VG)', # active ?
+#        },
+#    },
+    # 0x9c - 1; 2 for multi-shot modes
+    0x10c => { #JR
+        Name => 'SequenceNumber',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/', # seen 18 for A550, so better exclude ?
+        # normally 0; seen 1,2,3 for bracketing, 6 for Handheld Night Shot, 3 for HDR, 6 for MFNR
+        PrintConv => {
+            0 => 'Single',
+            255 => 'n/a',
+            OTHER => sub { shift }, # pass all other numbers straight through
+        },
+    },
+    # when reading 0x0114 - 0x0117 as int32u:
+    # - upper 8 bits (0x0117): always value 4, meaning unknown
+    # - next 10 bits: FolderNumber (max. 999 according to manual)
+    # - last 14 bits: ImageNumber  (max 9999)
+    0x0114 => { #JR
+        Name => 'FolderNumber',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        Format => 'int32u',
+        Mask => 0x00ffc000,
+        PrintConv => 'sprintf("%.3d",$val)',
+        PrintConvInv => '$val',
+    },
+    276.1 => { #JR (0x0114.1)
+        Name => 'ImageNumber',
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        Format => 'int32u',
+        Mask => 0x00003fff,
+        PrintConv => 'sprintf("%.4d",$val)',
+        PrintConvInv => '$val',
+    },
+    0x200 => { #JR
+        Name => 'ShotNumberSincePowerUp2',
+        Notes => q{
+            same as ShotNumberSincePowerUp for single-shot images, but includes all
+            shots of the current image in multi-shot modes like HDR, panorama, and
+            multi-frame noise reduction
+        },
+        # (includes all shutter actuations of the current shot)
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/',
+        Format => 'int32u',
+    },
+    0x283 => { #JR
+        Name => 'AFButtonPressed',
+        # only indicates pressing and holding the "AF" button (centre-controller),
+        # not pressing the shutter release button halfway down
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            1 => 'No',
+            16 => 'Yes',
+        },
+    },
+    0x284 => { #JR (not 100% sure about this one)
+        Name => 'LiveViewMetering',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            0 => 'n/a',
+            16 => '40 Segment',             # DSLR with LiveView/OVF switch in OVF position
+            32 => '1200-zone Evaluative',   # DSLR with LiveView/OVF switch in LiveView position
+        },
+    },
+    0x285 => { #JR (not sure what is difference with 0x2f)
+        Name => 'ViewingMode2',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            0 => 'n/a',
+            16 => 'Viewfinder',
+            33 => 'Focus Check Live View',
+            34 => 'Quick AF Live View',
+        },
+    },
+    0x286 => { #JR
+        Name => 'AELock',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
+    0x287 => { #JR
+        Name => 'FlashStatusBuilt-in',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        Notes => 'A450, A500 and A550',
+        PrintConv => {
+            1 => 'Off',
+            2 => 'On',
+        },
+    },
+    0x288 => { #JR
+        Name => 'FlashStatusExternal',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        Notes => 'A450, A500 and A550',
+        PrintConv => {
+            1 => 'None',
+            2 => 'Off',
+            3 => 'On',
+        },
+    },
+    0x28b => { #JR
+        Name => 'LiveViewFocusMode',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        PrintConv => {
+            0 => 'n/a',
+            1 => 'AF',
+            16 => 'Manual',
+        },
+    },
+    0x30c => { #JR
+        Name => 'SequenceNumber',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        Notes => 'A450, A500 and A550',
+        # normally 0; seen 2 for HDR
+        PrintConv => {
+            0 => 'Single',
+            255 => 'n/a',
+            OTHER => sub { shift }, # pass all other numbers straight through
+        },
+    },
+    0x314 => { #JR
+        Name => 'ImageNumber',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        Format => 'int16u',
+        Notes => 'A450, A500 and A550',
+        Mask => 0x3fff, #PH (not sure what the upper 2 bits are for)
+        PrintConv => 'sprintf("%.4d",$val)',
+        PrintConvInv => '$val',
+    },
+    0x316 => { #JR
+        Name => 'FolderNumber',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        Notes => 'A450, A500 and A550',
+        Format => 'int16u',
+        Mask => 0x03ff, #(NC)
+        PrintConv => 'sprintf("%.3d",$val)',
+        PrintConvInv => '$val',
+    },
+    0x03f0 => {
+        Name => 'LensE-mountVersion',
+        Format => 'int16u',
+        Condition => '($$self{Model} =~ /^NEX-/)',
+        PrintConv => 'sprintf("%x.%.2x",$val>>8,$val&0xff)',
+        PrintConvInv => 'my @a=split(/\./,$val);(hex($a[0])<<8)|hex($a[1])',
+    },
+    # 0x03f3 - this is probably LensFirmwareVersion and not CameraE-MountVersion (ref JR, Sept.2015)
+    # 0x03f3 and 0x03f4 change together and behave similarly to Tag940c 0x0014 and 0x0015 - see comments there.
+    0x03f3 => {
+        Name => 'LensFirmwareVersion',
+        Format => 'int16u',
+        Condition => '($$self{Model} =~ /^NEX-/)',
+        PrintConv => 'sprintf("Ver.%.2x.%.3d",$val>>8,$val&0xff)',
+    },
+    0x3f7 => { #JR
+        Name => 'LensType2',
+        Condition => '($$self{Model} =~ /^NEX-/) and ($$self{LensMount} != 1)',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x400 => { #JR
+        Name => 'ImageNumber',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        Format => 'int16u',
+        Notes => 'A450, A500 and A550',
+        Mask => 0x3fff, #PH (not sure what the upper 2 bits are for)
+        PrintConv => 'sprintf("%.4d",$val)',
+        PrintConvInv => '$val',
+    },
+    0x402 => { #JR
+        Name => 'FolderNumber',
+        Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)$/',
+        Format => 'int16u',
+        Mask => 0x03ff, #(NC)
+        Notes => 'A450, A500 and A550',
+        PrintConv => 'sprintf("%.3d",$val)',
+        PrintConvInv => '$val',
+    },
 );
 
@@ -1055,9 +5498,286 @@
 );
 
+# extra hardware information (ref JR)
+%Image::ExifTool::Sony::ExtraInfo = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Extra hardware information for the A850 and A900.',
+    # 0x0000: seen values 5 or 6
+    0x0001 => {
+        Name => 'BatteryTemperature',
+        # seen values of appr. 55 - 115: looks like temperature Fahrenheit
+        # changing battery in cold weather: new battery starts with value 53
+        ValueConv => '($val - 32) / 1.8', # convert to Celsius
+        ValueConvInv => '$val * 1.8 + 32',
+        PrintConv => 'sprintf("%.1f C",$val)',
+        PrintConvInv => '$val=~ s/\s*C//; $val',
+        # (may be invalid for non-OEM batteries)
+    },
+    0x0002 => {
+        Name => 'BatteryUnknown',
+        # appears to be an int16u value together with 0x0005 (values similar to ExtraInfo3 0x0000)
+        # seen values of appr. 800 at 23 deg C to 630 at 40 deg C for A850 with NP-FM500H battery (7.2 V nominal)
+        # i.e. inversely proportional to BatteryTemperature: can not be BatteryVoltage, must be something else ?
+        Unknown => 1,
+        Format => 'undef[4]',
+        ValueConv => sub {
+            my $val = shift;;
+            my @a = unpack("CvC",pack('v*', unpack('n*', $val)));
+            return $a[1];
+        },
+    },
+    # 0x0003: seen 0 or 16
+    # 0x0004: always 255
+    # 0x0006: int16u value together with 0x0009: same behaviour and almost same values as 0x0002
+    # 0x0007: always 3
+    0x0008 => {
+        Name => 'BatteryVoltage',
+        # 0x0008: int16u value together with 0x000b:
+        # values follow BatteryLevel: from appr.900 when battery full, to appr. 775 when empty.
+        # with factor 118 they range from appr. 7.6 to 6.6 - looks like battery voltage (nominal 7.2 V)
+        Unknown => 1,
+        Format => 'undef[4]',
+        ValueConv => sub {
+            my $val = shift;;
+            my @a = unpack("CvC",pack('v*', unpack('n*', $val)));
+            return $a[1]/118;
+        },
+        PrintConv => 'sprintf("%.2f V",$val)',
+    },
+    0x000a => {
+        # seen mostly 213 and 246, corresponding with other ImageStabilization On/Off tags.
+        Name => 'ImageStabilization2',
+        Unknown => 1, # (because the decoding is funny and possibly incomplete - PH)
+        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 continuous drive
+            213 => 'On',
+            246 => 'Off',
+        },
+    },
+    # 0x000c: seen always decreasing values, from max. 107 to min. 0,
+    #   then jump back to high value: correlates with battery change/recharging
+    #   Seen once 255 immediately after inserting new battery, next frame OK at 106.
+    #   Validation: matches exactly with batterylevel display on camera (all 100+ values displayed as 100%)
+    0x000c => {
+        Name => 'BatteryLevel',
+        PrintConv => '"$val%"',
+        PrintConvInv => '$val=~s/\s*\%//; $val',
+    },
+    # 0x000d: always 2
+    # 0x000e: always 204
+    # 0x000f: always 0
+    # 0x0010-0x0019: always 204
+    0x001a => {
+        Name => 'ExtraInfoVersion',
+        Format => 'int8u[4]',
+        PrintConv => '$val=~tr/ /./; $val',
+        PrintConvInv => '$val=~tr/./ /; $val',
+        # always 0 1 0 1 for 0x0131 Software = DSLR-A850 v1.00
+        # always 0 2 0 4 for 0x0131 Software = DSLR-A850 v2.00
+        # seen   0 2 0 0 for 0x0131 Software = DSLR-A900 v1.00
+        # seen   0 4 0 0 for 0x0131 Software = DSLR-A900 v1.00
+        # seen   0 5 0 4 for 0x0131 Software = DSLR-A900 v2.00
+        # A850: correlates exactly with Firmware versions.
+        # A900: have there been different FW 1.0 versions ?
+    },
+);
+
+# extra hardware information (ref JR)
+%Image::ExifTool::Sony::ExtraInfo2 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'Extra hardware information for the A230/290/330/380/390.',
+    0x0004 => {
+        Name => 'BatteryLevel',
+        PrintConv => '"$val%"',
+        PrintConvInv => '$val=~s/\s*\%//; $val',
+    },
+    0x0012 => {
+        Name => 'ImageStabilization',
+        PrintConv => {
+            0 => 'Off',
+            64 => 'On',
+        },
+    },
+);
+
+# extra hardware information (ref JR)
+%Image::ExifTool::Sony::ExtraInfo3 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        Extra hardware information for the A33, A35, A55, A450, A500, A550, A560,
+        A580 and NEX-3/5/C3/VG10.
+    },
+    0x0000 => {
+        Name => 'BatteryUnknown',
+        # seen values of appr. 870 at 10 deg C to 650 at 39 deg C for A580 with NP-FM500H battery (7.2 V nominal)
+        # i.e. inversely proportional to BatteryTemperature: can not be BatteryVoltage, must be something else ?
+        Unknown => 1,
+        Format => 'int16u',
+    },
+    0x0002 => {
+        Name => 'BatteryTemperature',
+        ValueConv => '($val - 32) / 1.8', # convert to Celsius
+        ValueConvInv => '$val * 1.8 + 32',
+        PrintConv => 'sprintf("%.1f C",$val)',
+        PrintConvInv => '$val=~ s/\s*C//; $val',
+    },
+    0x0004 => {
+        Name => 'BatteryLevel',
+        PrintConv => '"$val%"',
+        PrintConvInv => '$val=~s/\s*\%//; $val',
+    },
+    # 0x0005:  always 255
+    # from here on the differences between DSLR, SLT and NEX
+    # 0x0006 and 0x0008:
+    #   values follow BatteryLevel: start high (970, 940) when battery full,
+    #   and decrease with decreasing battery level to (850, 815)
+    #   with factor 128 they range from (7.6, 7.3) to (6.6, 6.4) - looks like battery voltage (nominal 7.2 V)
+    0x0006 => {
+        Name => 'BatteryVoltage1',
+        Format => 'int16u',
+        Condition => '$$self{Model} !~ /^(NEX-(3|5|5C|C3|VG10|VG10E))\b/',
+        ValueConv => '$val / 128',
+        ValueConvInv => '$val * 128',
+        PrintConv => 'sprintf("%.2f V",$val)',
+        PrintConvInv => '$val=~s/\s*V//; $val',
+    },
+    0x0008 => {
+        Name => 'BatteryVoltage2',
+        Format => 'int16u',
+        Condition => '$$self{Model} !~ /^(NEX-(3|5|5C|C3|VG10|VG10E))\b/',
+        ValueConv => '$val / 128',
+        ValueConvInv => '$val * 128',
+        PrintConv => 'sprintf("%.2f V",$val)',
+        PrintConvInv => '$val=~s/\s*V//; $val',
+    },
+    # 0x000a - 0x000f: 3 int16u values: probably some mode or status info:
+    # seen various 3-number-sequences for SLT and DSLR, but meaning unknown
+    # 0x000a => {
+    #     Name => 'ExtraInfo_000a',
+    #     Format => 'int16u[3]',
+    #     Condition => '$$self{Model} !~ /^(NEX-(3|5|5C|C3|VG10|VG10E))\b/',
+    # },
+    # 0x0010 seen:
+    #     176 for SLT
+    #     204 for NEX
+    #     240 for DSLR
+    0x0011 => {
+        Name => 'ImageStabilization',
+        Condition => '$$self{Model} !~ /^(NEX-(3|5|5C|C3|VG10|VG10E))\b/',
+        # usually matches 0xb026 ImageStabilization, except some images with SelfTimer and on tripod
+        PrintConv => {
+            0 => 'Off',
+            64 => 'On',
+        },
+    },
+    0x0014 => [
+        {
+            Name => 'BatteryState',
+            Condition => '$$self{Model} =~ /^SLT-/',
+            # possibly relates to "simple" batterylevel indication with battery-icon, but not completely sure
+            Notes => 'BatteryState for SLT models',
+            PrintConv => {
+                1 =>  'Empty',
+                2 =>  'Low',
+                3 =>  'Half full',
+                4 =>  'Almost full',
+                5 =>  'Full',
+            },
+        },{
+            Name => 'ExposureProgram',
+            Condition => '$$self{Model} =~ /^DSLR-(A450|A500|A550)\b/',
+            Notes => 'ExposureProgram for the A450, A500 and A550',
+            Priority => 0, # (some unknown values)
+            PrintConv => {
+                241 => 'Landscape',
+                243 => 'Aperture-priority AE',
+                245 => 'Portrait',
+                246 => 'Auto',
+                247 => 'Program AE',
+                249 => 'Macro',
+                252 => 'Sunset',
+                253 => 'Sports', #PH (A550)
+                255 => 'Manual',
+                # missing: Shutter speed priority AE, No Flash, Night View
+            },
+        },{
+            Name => 'ModeDialPosition',
+            Condition => '$$self{Model} =~ /^DSLR-/',
+            Notes => 'ModeDialPosition for other DSLR models',
+            # (decoded from A560/A580)
+            PrintConv => {
+                248 => 'No Flash',
+                249 => 'Aperture-priority AE',
+                250 => 'SCN', # <-- the reason we don't call it ExposureProgram for these models
+                251 => 'Shutter speed priority AE',
+                252 => 'Auto',
+                253 => 'Program AE',
+                254 => 'Panorama',
+                255 => 'Manual',
+            },
+        },
+    ],
+    # 0x0015: DSLR: appears to be a bitmask relating to "switch" positions:
+    #   bit 0 (  1) only seen OFF for A580
+    #   bit 1 (  2) ON = Flash down, OFF = Flash raised
+    #   bit 2 (  4) only seen ON for A580
+    #   bit 3 (  8) only seen ON for A580
+    #   bit 4 ( 16) ON = AF,         OFF = MF
+    #   bit 5 ( 32) ON = OVF,        OFF = LiveView
+    #   bit 6 ( 64) seen ON and OFF, meaning unknown
+    #   bit 7 (128) seen ON and OFF, meaning unknown
+    # 0x0016: DSLR: seen 244,245,252,254, decoded for A580 with 32GB SD and 16GB MS cards
+    # 0x0016: NEX:  seen 61,62,  125,126,  190: bits '64' and '128' appear to relate to CameraOrientation
+    # 0x0016: SLT:  seen 64 - 78, meaning unknown
+    0x0016 => [{
+        Name => 'MemoryCardConfiguration',
+        Condition => '$$self{Model} =~ /^DSLR-/',
+        PrintConv => {
+            244 => 'MemoryStick in use, SD card present',
+            245 => 'MemoryStick in use, SD slot empty',
+            252 => 'SD card in use, MemoryStick present',
+            254 => 'SD card in use, MemoryStick slot empty',
+        },
+    },{
+        Name => 'CameraOrientation',
+        Condition => '$$self{Model} =~ /^(NEX-(3|5|5C|C3|VG10|VG10E))\b/',
+        Mask => 0xc0, # (don't know what other bits mean)
+        PrintConv => {
+            0 =>  'Horizontal (normal)',
+            1 =>  'Rotate 90 CW',
+            2 =>  'Rotate 270 CW',
+            3 =>  'Rotate 180', #(NC)
+        },
+
+    }],
+    # 0x0017: seen 0 for SLT, 255 for DSLR, variable for NEX
+    0x0018 => {
+        Name => 'CameraOrientation',
+        Condition => '$$self{Model} !~ /^(NEX-(3|5|5C|C3|VG10|VG10E))\b/',
+        Mask => 0x30, # (don't know what other bits mean)
+        PrintConv => {
+            0 =>  'Horizontal (normal)',
+            1 =>  'Rotate 90 CW',
+            2 =>  'Rotate 270 CW',
+            3 =>  'Rotate 180',
+        },
+    },
+    # 0x0019:
+    #   A450/500/550:  0 - 12 and 233 - 255
+    #   A560/580:  1 or 64, seen a few 0 and 8
+    #   A33/35/55: seen 0, 1, 64
+    #   NEX:       204
+    # 0x001a, 0x001c appear to be 2 int16u values, meaning unknown
+);
+
 # shot information (ref PH)
 %Image::ExifTool::Sony::ShotInfo = (
     %binaryDataAttrs,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
-    DATAMEMBER => [ 0x02, 0x30, 0x32 ],
+    DATAMEMBER => [ 0x02, 0x30, 0x32, 0x34 ],
     IS_SUBDIR => [ 0x48, 0x5e ],
     # 0x00 - byte order 'II'
@@ -1077,4 +5797,6 @@
         PrintConvInv => '$self->InverseDateTime($val,0)',
     },
+    0x1a => { Name => 'SonyImageHeight', Format => 'int16u' }, #JR
+    0x1c => { Name => 'SonyImageWidth',  Format => 'int16u' }, #JR
     0x30 => { #Jeffrey Friedl
         Name => 'FacesDetected',
@@ -1090,10 +5812,14 @@
         RawConv => '$$self{FaceInfoLength} = $val',
     },
-    #0x34 => {
-    #    # values: 'DC5303320222000', 'DC6303320222000' or 'DC7303320222000'
-    #    Name => 'UnknownString',
-    #    Format => 'string[16]',
-    #    Unknown => 1,
-    #},
+    0x34 => {
+        # oldest/other DSC/other        -
+        # older DSC models              "DC5303320222000" or "DC6303320222000"
+        # DSC-W650/W690/W730            "THm101000000000" or "THm211000000000"
+        # DSC-HX9V generation and newer "DC7303320222000"
+        Name => 'MetaVersion', # (tentative)
+        Format => 'string[16]',
+        DataMember => 'MetaVersion',
+        RawConv => '$$self{MetaVersion} = $val',
+    },
     0x48 => { # (most models: DC5303320222000 and DC6303320222000)
         Name => 'FaceInfo1',
@@ -1116,4 +5842,3711 @@
 );
 
+# tags used in Tag2010 and Tag9400 tables
+my %sequenceImageNumber = ( #PH
+    Name => 'SequenceImageNumber',
+    Notes => 'number of images captured in burst sequence',
+    # (not shutter count because it increments for auto portrait framing)
+    Format => 'int32u',
+    ValueConv => '$val + 1',
+    ValueConvInv => '$val - 1',
+);
+my %sequenceFileNumber = ( #PH
+    Name => 'SequenceFileNumber',
+    Notes => 'file number in burst sequence',
+    Format => 'int32u',
+    ValueConv => '$val + 1', #JR
+    ValueConvInv => '$val - 1',
+);
+my %releaseMode2 = ( #JR
+    Name => 'ReleaseMode2',
+    SeparateTable => 'ReleaseMode2',
+    PrintConv => {
+        0 => 'Normal',
+        1 => 'Continuous', # (RX100 "Continuous - Self-timer")
+        2 => 'Continuous - Exposure Bracketing', # (RX100)
+# 3 - also DRO Bracketing (ILCE-7RM2), not "Continuous" because only single exposure from which camera makes 3 versions
+        3 => 'DRO or White Balance Bracketing', # (HX9V) (RX100) (ILCE-7RM2)
+        5 => 'Continuous - Burst', # (HX9V)
+        6 => 'Single Frame - Capture During Movie', #PH (RX100)
+        7 => 'Continuous - Sweep Panorama',
+        8 => 'Continuous - Anti-Motion Blur, Hand-held Twilight', # (HX9V)
+        9 => 'Continuous - HDR',
+        10 => 'Continuous - Background defocus', # (HX9V)
+        13 => 'Continuous - 3D Sweep Panorama', #PH/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 => '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)
+        26 => 'Continuous Low', #PH (A77)
+        27 => 'Continuous - High Sensitivity',  # seen for DSC-WX60 and WX300
+        28 => 'Smile Shutter', #PH (RX100)
+        29 => 'Continuous - Tele-zoom Advance Priority',
+       # 30 - seen quite often for single-shot images ... SLT-A58, ILCE-5100/6000
+       # 33 - Continuous - seen for DSC-RX100M5, RX10M4, maybe 24 fps mode ???
+        146 => 'Single Frame - Movie Capture', #PH (seen in Tag2010 ReleaseMode2 values)
+    },
+);
+
+# tag definitions for Tag2010 tables (ref JR)
+my %sonyDateTime2010 = (
+    Name => 'SonyDateTime',
+    Format => 'undef[7]',
+    Shift => 'Time',
+    ValueConv => q{
+        my @v = unpack('vC*', $val);
+        return sprintf("%.4d:%.2d:%.2d %.2d:%.2d:%.2d", @v)
+    },
+    ValueConvInv => q{
+        my @v = ($val =~ /\d+/g);
+        return undef unless @v == 6;
+        return pack('vC*', @v);
+    },
+    PrintConv => '$self->ConvertDateTime($val)',
+    PrintConvInv => '$self->InverseDateTime($val,0)',
+);
+my %releaseMode2010 = (
+    Name => 'ReleaseMode3',
+    PrintConv => {
+        0 => 'Normal',
+        1 => 'Continuous',
+        2 => 'Bracketing', # (all types: Continuous and Single-Frame Exposure, White Balance and DRO bracketing - PH/JR)
+        # 3 => 'Remote Commander', (NC) (seen this when other ReleaseMode and ReleaseMode2 are 'Normal' - PH, A77)
+        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 = (
+    Name => 'SelfTimer',
+    PrintConv => {
+        0 => 'Off',
+        1 => 'Self-timer 10 s',
+        2 => 'Self-timer 2 s',
+    },
+);
+my %selfTimerB2010 = (  # also value 1 for new 5 s mode of DSC-HX90V/RX10M2/RX100M4/WX500, ILCE-7RM2/7SM2
+    Name => 'SelfTimer',
+    PrintConv => {
+        0 => 'Off',
+        1 => 'Self-timer 5 or 10 s',
+        2 => 'Self-timer 2 s',
+    },
+);
+my %gain2010 = (
+    Name => 'StopsAboveBaseISO',
+    # BaseISO is 100 for SLT, ILCE-3000, NEX-5N/5R/5T/6/7/VG20/VG30/VG900, DSC-RX1/RX1R
+    # BaseISO is 200 for NEX-F3/3N
+    # BaseISO is 160 for DSC-RX100M2
+    # BaseISO is 125 for DSC-RX100
+    # Also several other DSC models have BaseISO different from 100.
+    Format => 'int16u',
+    ValueConv => '16 - $val/256',
+    ValueConvInv => '(16 - $val) * 256',
+    PrintConv => '$val ? sprintf("%.1f",$val) : $val',
+    PrintConvInv => '$val',
+);
+my %brightnessValue2010 = (
+    Name => 'BrightnessValue',
+    Format => 'int16u',
+    ValueConv => '$val/256 - 56.6',
+    ValueConvInv => '($val + 56.6) * 256',
+);
+my %dynamicRangeOptimizer2010 = (
+    Name => 'DynamicRangeOptimizer',
+    PrintConv => {
+        0 => 'Off',
+        1 => 'Auto',
+        3 => 'Lv1',
+        4 => 'Lv2',
+        5 => 'Lv3',
+        6 => 'Lv4',
+        7 => 'Lv5',
+        8 => 'n/a',
+    },
+);
+my %hdr2010 = (
+    Name => 'HDRSetting', # (Off when HDR tag is On for RX100 superior auto backlight - PH)
+    PrintConv => {
+        0 => 'Off',
+        1 => 'HDR Auto',
+        3 => 'HDR 1 EV',
+        5 => 'HDR 2 EV',
+        7 => 'HDR 3 EV',
+        9 => 'HDR 4 EV',
+        11 => 'HDR 5 EV',
+        13 => 'HDR 6 EV',
+    },
+);
+my %exposureComp2010 = ( # only as set manually, remains 0 in exposure-bracketing modes
+    Name => 'ExposureCompensation',
+    Format=>'int16s',
+    ValueConv => '-$val/256',
+    ValueConvInv => '-$val*256',
+    PrintConv => '$val ? sprintf("%+.1f",$val) : 0',
+    PrintConvInv => '$val',
+);
+my %pictureEffect2010 = (
+    Name => 'PictureEffect2',
+    SeparateTable => 'PictureEffect2',
+    PrintConv => {
+        0 => 'Off',
+        1 => 'Toy Camera',
+        2 => 'Pop Color',
+        3 => 'Posterization',
+        4 => 'Retro Photo',
+        5 => 'Soft High Key',
+        6 => 'Partial Color',
+        7 => 'High Contrast Monochrome',
+        8 => 'Soft Focus',
+        9 => 'HDR Painting',
+        10 => 'Rich-tone Monochrome',
+        11 => 'Miniature',
+        12 => 'Water Color',
+        13 => 'Illustration',
+    },
+);
+my %quality2010 = (
+    Name => 'Quality2',
+    PrintConv => {
+        0 => 'JPEG',
+        1 => 'RAW',
+        2 => 'RAW + JPEG',
+    },
+);
+my %meteringMode2010 = (
+    Name => 'MeteringMode',
+    PrintConv => {
+        0 => 'Multi-segment',
+        2 => 'Center-weighted average',
+        3 => 'Spot',
+        4 => 'Average',
+        5 => 'Highlight',
+    },
+);
+my %flashMode2010 = (
+    Name => 'FlashMode',
+    PrintConv => {
+        0 => 'Autoflash',
+        1 => 'Fill-flash',
+        2 => 'Flash Off',
+        3 => 'Slow Sync',
+        4 => 'Rear Sync',
+        6 => 'Wireless',
+      # 129 => 'unknown',  # seen for ILCE-7M3 images
+    },
+);
+my %exposureProgram2010 = (
+    Name => 'ExposureProgram',
+    SeparateTable => 'ExposureProgram3',
+    PrintConv => \%sonyExposureProgram3,
+);
+my %pictureProfile2010 = (
+    Name => 'PictureProfile',
+    # values 0-9:    Seen for all cameras writing this tag: matches CreativeStyle and/or SceneMode settings.
+    # 10 and higher: Seen for ILCE-7S/7M2 and newer, having a PictureProfile setting, also some DSC/HDR models.
+    #                Although intended for video, when set these profiles are also applied to (JPG) still images.
+    PrintConv => {
+        0 => 'Gamma Still - Standard/Neutral (PP2)', # CreativeStyle = Standard or Neutral
+        1 => 'Gamma Still - Portrait',
+       #2 - seen for DSC-HX90
+        3 => 'Gamma Still - Night View/Portrait',
+        4 => 'Gamma Still - B&W/Sepia',
+        5 => 'Gamma Still - Clear',
+        6 => 'Gamma Still - Deep',
+        7 => 'Gamma Still - Light',
+        8 => 'Gamma Still - Vivid', # SceneMode or CreativeStyle =  Vivid, Autumn, Sunset or Landscape
+        9 => 'Gamma Still - Real',
+        10 => 'Gamma Movie (PP1)',
+        22 => 'Gamma ITU709 (PP3 or PP4)', # (also PP4 for A7M3, ref 14)
+        24 => 'Gamma Cine1 (PP5)',
+        25 => 'Gamma Cine2 (PP6)',
+        26 => 'Gamma Cine3',
+        27 => 'Gamma Cine4',
+        28 => 'Gamma S-Log2 (PP7)',
+        29 => 'Gamma ITU709 (800%)',
+        31 => 'Gamma S-Log3 (PP8 or PP9)', #14
+        33 => 'Gamma HLG2 (PP10)', #14
+        34 => 'Gamma HLG3', #IB
+    },
+);
+my %isoSetting2010 = (
+     0 => 'Auto',
+     5 => 25,
+     7 => 40,
+     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,
+    36 => 32000,
+    37 => 40000,
+    38 => 51200,
+    39 => 64000,
+    40 => 80000,
+    41 => 102400,
+    42 => 128000,
+    43 => 160000,
+    44 => 204800,
+    45 => 256000,
+    46 => 320000, 
+    47 => 409600,
+);
+
+%Image::ExifTool::Sony::Tag2010a = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => 'Valid for NEX-5N.',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    IS_SUBDIR => [ 0x04b0 ],
+    0x04b0 => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x1128 => { %releaseMode2010 },
+    0x112c => { %releaseMode2 },
+    0x1134 => { %selfTimer2010 },
+    0x1138 => { %flashMode2010 },
+    0x113e => { %gain2010 },
+    0x1140 => { %brightnessValue2010 },
+    0x1144 => { %dynamicRangeOptimizer2010 },
+    0x1148 => { %hdr2010 },
+    0x114c => { %exposureComp2010 },
+    0x115e => { %pictureProfile2010 },
+    0x115f => { %pictureProfile2010 },
+    0x1163 => { %pictureEffect2010 },
+    0x1170 => { %quality2010 },
+    0x1174 => { %meteringMode2010 },
+    0x1175 => { %exposureProgram2010 },
+    0x117c => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    #0x1a08 => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    #0x1a0c => { Name => 'SonyImageHeight', Format => 'int16u' },
+);
+
+%Image::ExifTool::Sony::Tag2010b = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => 'Valid for SLT-A65/A77, NEX-7/VG20E.',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    IS_SUBDIR => [ 0x04b4 ],
+    0x0000 => { %sequenceImageNumber }, #PH
+    0x0004 => { %sequenceFileNumber }, #PH
+    0x0008 => { %releaseMode2, Format => 'int32u' },
+    #0x0044 => { Name => 'SonyImageWidth3',  Format => 'int16u' },
+    #0x0048 => { Name => 'SonyImageHeight3', Format => 'int16u' },
+    #0x0054 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x0058 => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x0064 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x0068 => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x00a8 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x00ac => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x00b8 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x00bc => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x00c8 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x00cc => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    0x01b6 => { %sonyDateTime2010, Groups => { 2 => 'Time' } },
+    #0x0204 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x0206 => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    0x0324 => { %dynamicRangeOptimizer2010 },
+    0x04b4 => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x1128 => { %releaseMode2010 },
+    0x112c => { %releaseMode2 },
+    0x1134 => { %selfTimer2010 },
+    0x1138 => { %flashMode2010 },
+    0x113e => { %gain2010 },
+    0x1140 => { %brightnessValue2010 },
+    0x1144 => { %dynamicRangeOptimizer2010 },
+    0x1148 => { %hdr2010 },
+    0x114c => { %exposureComp2010 },
+    0x1162 => { %pictureProfile2010 },
+    0x1163 => { %pictureProfile2010 },
+    0x1167 => { %pictureEffect2010 },
+    0x1174 => { %quality2010 },
+    0x1178 => { %meteringMode2010 },
+    0x1179 => { %exposureProgram2010 },
+    0x1180 => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    0x1218 => {
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    #0x1a08 => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    #0x1a0c => { Name => 'SonyImageHeight', Format => 'int16u' },
+    0x1a23 => { # only for NEX-7 with Firmware v1.02 and higher, but slightly different from Tag9405 ...
+        Name => 'DistortionCorrParams',
+        Format => 'int16s[16]',
+    },
+);
+
+%Image::ExifTool::Sony::Tag2010c = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => 'Valid for SLT-A37/A57 and NEX-F3.',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    IS_SUBDIR => [ 0x0490 ],
+    0x0000 => { %sequenceImageNumber }, #PH
+    0x0004 => { %sequenceFileNumber }, #PH
+    0x0008 => { %releaseMode2, Format => 'int32u' },
+    #0x0048 => { Name => 'SonyImageWidth3',  Format => 'int16u' },
+    #0x004c => { Name => 'SonyImageHeight3', Format => 'int16u' },
+    #0x0058 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x005c => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x0068 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x006c => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x00c0 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x00c4 => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x00d0 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x00d4 => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x00e0 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x00e4 => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x0134 => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x0144 => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x0154 => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    0x0200 => { Name => 'DigitalZoomRatio', ValueConv => '$val/16', ValueConvInv => '$val*16', Priority => 0 },
+    0x0210 => { %sonyDateTime2010, Groups => { 2 => 'Time' } },
+    0x0300 => { %dynamicRangeOptimizer2010 },
+    0x0490 => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x1104 => { %releaseMode2010 },
+    0x1108 => { %releaseMode2 },
+    0x1110 => { %selfTimer2010 },
+    0x1114 => { %flashMode2010 },
+    0x111a => { %gain2010 },
+    0x111c => { %brightnessValue2010 },
+    0x1120 => { %dynamicRangeOptimizer2010 },
+    0x1124 => { %hdr2010 },
+    0x1128 => { %exposureComp2010 },
+    0x113e => { %pictureProfile2010 },
+    0x113f => { %pictureProfile2010 },
+    0x1143 => { %pictureEffect2010 },
+    0x1150 => { %quality2010 },
+    0x1154 => { %meteringMode2010 },
+    0x1155 => { %exposureProgram2010 },
+    0x115c => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    0x11f4 => {
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    #0x1a08 => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    #0x1a0c => { Name => 'SonyImageHeight', Format => 'int16u' },
+);
+
+%Image::ExifTool::Sony::Tag2010d = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => q{
+        Valid for DSC-HX10V/HX20V/HX200V/TX66/TX200V/TX300V/WX50/WX100/WX150, but
+        not valid for panorama images.
+    },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    IS_SUBDIR => [ 0x050c ],
+    0x0000 => { %sequenceImageNumber }, #PH
+    0x0004 => { %sequenceFileNumber }, #PH
+    0x0008 => { %releaseMode2, Format => 'int32u' },
+    #0x0048 => { Name => 'SonyImageWidth3',  Format => 'int16u' },
+    #0x004c => { Name => 'SonyImageHeight3', Format => 'int16u' },
+    #0x0058 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x005c => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x0068 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x006c => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x00c0 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x00c4 => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x00d0 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x00d4 => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x00e0 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x00e4 => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    0x01fe => { %sonyDateTime2010, Groups => { 2 => 'Time' } },
+    0x037c => { %dynamicRangeOptimizer2010 },
+    0x050c => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x1180 => { %releaseMode2010 },
+    0x1184 => { %releaseMode2 },
+    0x118c => { %selfTimer2010 },
+    0x1190 => { %flashMode2010 },
+    0x1196 => { %gain2010 },
+    0x1198 => { %brightnessValue2010 },
+    0x119c => { %dynamicRangeOptimizer2010 },
+    0x11a0 => { %hdr2010 },
+    0x11ba => { %pictureProfile2010 },
+    0x11bb => { %pictureProfile2010 },
+    0x11bf => { %pictureEffect2010 },
+    0x11d0 => { %meteringMode2010 },
+    # 0x11d1 - not valid for HX20V panorama images - PH
+    0x11d1 => { %exposureProgram2010 },
+    0x11d8 => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    0x1270 => {
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+);
+
+%Image::ExifTool::Sony::Tag2010e = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    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.
+    },
+    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' },
+    #0x0048 => { Name => 'SonyImageWidth3',  Format => 'int16u' },
+    #0x004c => { Name => 'SonyImageHeight3', Format => 'int16u' },
+    #0x0058 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x005c => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x0068 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x006c => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x00c0 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x00c4 => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x00d0 => { Name => 'SonyImageWidth2',  Format => 'int16u' },
+    #0x00d4 => { Name => 'SonyImageHeight2', Format => 'int16u' },
+    #0x00e0 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    #0x00e4 => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x01fa => { Name => 'SonyImageHeight',  Format => 'int16u' },
+    #0x0200 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    0x021c => { Name => 'DigitalZoomRatio', ValueConv => '$val/16', ValueConvInv => '$val*16', Priority => 0 },
+    0x022c => { %sonyDateTime2010, Groups => { 2 => 'Time' } },
+    0x0328 => { %dynamicRangeOptimizer2010 },
+    0x04b8 => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x115c => { %releaseMode2010 },
+    0x1160 => { %releaseMode2 },
+    0x1168 => { %selfTimer2010 },
+    0x116c => { %flashMode2010 },
+    0x1172 => { %gain2010 },
+    0x1174 => { %brightnessValue2010 },
+    0x1178 => { %dynamicRangeOptimizer2010 },
+    0x117c => { %hdr2010 },
+    0x1180 => { %exposureComp2010 },
+    0x1196 => { %pictureProfile2010 },
+    0x1197 => { %pictureProfile2010 },
+    0x119b => { %pictureEffect2010 },
+    0x11a8 => { %quality2010 },
+    0x11ac => { %meteringMode2010 },
+    0x11ad => { %exposureProgram2010 },
+    0x11b4 => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    0x1254 => {
+        Condition => '$$self{Model} =~ /^(SLT-(A99|A99V)|NEX-(5R|5T|6|VG900|VG30E)|DSC-RX100|Stellar|HV)\b/',
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x1258 => {
+        Condition => '$$self{Model} =~ /^(DSC-(RX1|RX1R))\b/',
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x1278 => {
+        Condition => '$$self{Model} =~ /^(SLT-A58|ILCE-(3000|3500)|NEX-3N|DSC-(HX300|HX50V|WX60|WX80|WX200|WX300|TX30))\b/',
+        Name => 'FocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x127a => {
+        Condition => '$$self{Model} =~ /^(SLT-A58|ILCE-(3000|3500)|NEX-3N|DSC-(HX300|HX50V|WX60|WX80|WX200|WX300|TX30))\b/',
+        Name => 'MinFocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x127c => { # may give 0 for fixed focal length lenses
+        Condition => '$$self{Model} =~ /^(SLT-A58|ILCE-(3000|3500)|NEX-3N|DSC-(HX300|HX50V|WX60|WX80|WX200|WX300|TX30))\b/',
+        Name => 'MaxFocalLength',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x1280 => {
+        Condition => '$$self{Model} =~ /^(SLT-A58|ILCE-(3000|3500)|NEX-3N|DSC-(HX300|HX50V|WX60|WX80|WX200|WX300|TX30))\b/',
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x1870 => {
+        Name => 'DistortionCorrParams',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+        Format => 'int16s[16]',
+    },
+    # 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)/',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x1892 => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^(DSC-|Stellar)/ ? undef : $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+        },
+    },
+    0x1893 => { #JR
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x1896 => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Priority => 0, #PH (just to be safe)
+        Format => 'int16u', #PH
+        SeparateTable => 1,
+        ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
+        PrintConv => \%sonyLensTypes,
+    },
+    0x1898 => {
+        Name => 'DistortionCorrParamsPresent',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+        PrintConv => { 0 => 'No', 1 => 'Yes'},
+    },
+    0x1899 => {
+        Name => 'DistortionCorrParamsNumber',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => { 11 => '11 (APS-C)', 16 => '16 (Full-frame)'},
+    },
+    #0x1914 => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    #0x1918 => { Name => 'SonyImageHeight', Format => 'int16u' },
+    #0x192e => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    #0x1930 => { Name => 'SonyImageHeight', Format => 'int16u' },
+);
+
+%Image::ExifTool::Sony::Tag2010f = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => 'Valid for DSC-RX100M2, DSC-QX10/QX100.',
+    WRITABLE => 1,
+    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' },
+    0x0050 => { %dynamicRangeOptimizer2010 },
+    0x01e0 => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x1014 => { %releaseMode2010 },
+    0x1018 => { %releaseMode2 },
+    0x1020 => { %selfTimer2010 },
+    0x1024 => { %flashMode2010 },
+    0x102a => { %gain2010 },
+    0x102c => { %brightnessValue2010 },
+    0x1030 => { %dynamicRangeOptimizer2010 },
+    0x1034 => { %hdr2010 },
+    0x1038 => { %exposureComp2010 },
+    0x104e => { %pictureProfile2010 },
+    0x104f => { %pictureProfile2010 },
+    0x1053 => { %pictureEffect2010 },
+    0x1060 => { %quality2010 },
+    0x1064 => { %meteringMode2010 },
+    0x1065 => { %exposureProgram2010 },
+    0x106c => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    #0x1096 => { Name => 'SonyImageWidth3', Format => 'int16u' },
+    #0x10aa => { Name => 'SonyImageWidth3', Format => 'int16u' },
+    0x1134 => {
+        Name => 'FocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x1136 => {
+        Name => 'MinFocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x1138 => {
+        Name => 'MaxFocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x113c => {
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    #0x1914 => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    #0x1918 => { Name => 'SonyImageHeight', Format => 'int16u' },
+    #0x192e => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    #0x1930 => { Name => 'SonyImageHeight', Format => 'int16u' },
+);
+
+%Image::ExifTool::Sony::Tag2010g = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => q{
+        Valid for DSC-HX60V/HX350/HX400V/QX30/RX10/RX100M3/WX220/WX350,
+        ILCE-7/7R/7S/7M2/5000/5100/6000/QX1, ILCA-68/77M2.
+    },
+    WRITABLE => 1,
+    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 },
+    0x0210 => { %releaseMode2 },
+    0x0218 => { %selfTimer2010 },
+    0x021c => { %flashMode2010 },
+    0x0222 => { %gain2010 },
+    0x0224 => { %brightnessValue2010 },
+    0x0228 => { %dynamicRangeOptimizer2010 },
+    0x022c => { %hdr2010 },
+    0x0230 => { %exposureComp2010 },
+    0x0246 => { %pictureProfile2010 },
+    0x0247 => { %pictureProfile2010 },
+    0x024b => { %pictureEffect2010 },
+    0x0258 => { %quality2010 },
+    0x025c => { %meteringMode2010 },
+    0x025d => { %exposureProgram2010 },
+    0x0264 => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    0x032c => {
+        Name => 'FocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x032e => {
+        Name => 'MinFocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x0330 => { # may give 0 for fixed focal length lenses
+        Name => 'MaxFocalLength',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x0344 => {
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0388 => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x189c => {
+        Name => 'DistortionCorrParams',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        Format => 'int16s[16]',
+    },
+    # 0x18bc - same as 0x18be, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2
+    0x18bd => {
+        Name => 'LensFormat',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x18be => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^DSC-/ ? undef : $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+        },
+    },
+    0x18bf => { #JR
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x18c2 => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Priority => 0, #PH (just to be safe)
+        Format => 'int16u', #PH
+        SeparateTable => 1,
+        ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
+        PrintConv => \%sonyLensTypes,
+    },
+    0x18c4 => {
+        Name => 'DistortionCorrParamsPresent',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => { 0 => 'No', 1 => 'Yes'},
+    },
+    0x18c5 => {
+        Name => 'DistortionCorrParamsNumber',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => { 11 => '11 (APS-C)', 16 => '16 (Full-frame)'},
+    },
+    # 0x1940 => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    # 0x1944 => { Name => 'SonyImageHeight', Format => 'int16u' },
+    # 0x195a => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    # 0x195c => { Name => 'SonyImageHeight', Format => 'int16u' },
+);
+
+%Image::ExifTool::Sony::Tag2010h = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => q{
+        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 },
+    0x0210 => { %releaseMode2 },
+    0x0218 => { %selfTimerB2010 },
+    0x021c => { %flashMode2010 },
+    0x0222 => { %gain2010 },
+    0x0224 => { %brightnessValue2010 },
+    0x0228 => { %dynamicRangeOptimizer2010 },
+    0x022c => { %hdr2010 },
+    0x0230 => { %exposureComp2010 },
+    0x0246 => { %pictureProfile2010 },
+    0x0247 => { %pictureProfile2010 },
+    0x024b => { %pictureEffect2010 },
+    0x0258 => { %quality2010 },
+    0x025c => { %meteringMode2010 },
+    0x025d => { %exposureProgram2010 },
+    0x0264 => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    0x032c => {
+        Name => 'FocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x032e => {
+        Name => 'MinFocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x0330 => { # may give 0 for fixed focal length lenses
+        Name => 'MaxFocalLength',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x0346 => {
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0388 => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Condition => '$$self{Model} !~ /^(ILCA-99M2|ILCE-6500|DSC-(RX0|RX100M5))/',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x0398 => {
+        Name => 'MeterInfo',
+        Format => 'int32u[486]',
+        Condition => '$$self{Model} =~ /^(ILCA-99M2|ILCE-6500|DSC-(RX0|RX100M5))/',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo' },
+    },
+    0x18cc => {
+        Name => 'DistortionCorrParams',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        Format => 'int16s[16]',
+    },
+    # 0x18ec - same as 0x18ee, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2
+    0x18ed => {
+        Name => 'LensFormat',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x18ee => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^DSC-/ ? undef : $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+        },
+    },
+    0x18ef => { #JR
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x18f2 => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Priority => 0, #PH (just to be safe)
+        Format => 'int16u', #PH
+        SeparateTable => 1,
+        ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
+        PrintConv => \%sonyLensTypes,
+    },
+    0x18f4 => {
+        Name => 'DistortionCorrParamsPresent',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => { 0 => 'No', 1 => 'Yes'},
+    },
+    0x18f5 => {
+        Name => 'DistortionCorrParamsNumber',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => { 11 => '11 (APS-C)', 16 => '16 (Full-frame)'},
+    },
+    # 0x1970 => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    # 0x1974 => { Name => 'SonyImageHeight', Format => 'int16u' },
+    # 0x198a => { Name => 'SonyImageWidth',  Format => 'int16u' },
+    # 0x198c => { Name => 'SonyImageHeight', Format => 'int16u' },
+);
+
+%Image::ExifTool::Sony::Tag2010i = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => q{
+        Valid for ILCE-6100/6400/6600/7C/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 },
+    0x0208 => { %releaseMode2 },
+    0x0210 => { %selfTimerB2010 },
+    0x0211 => { %flashMode2010 },
+    0x0217 => { %gain2010 },
+    0x0219 => { %brightnessValue2010 },
+    0x021b => { %dynamicRangeOptimizer2010 },
+    0x021f => { %hdr2010 },
+    0x0223 => { %exposureComp2010 },
+    0x0237 => { %pictureProfile2010 },
+    0x0238 => { %pictureProfile2010 },
+    0x023c => { %pictureEffect2010 },
+    0x0247 => { %quality2010 },
+    0x024b => { %meteringMode2010 },
+    0x024c => { %exposureProgram2010 },
+    0x0252 => { Name => 'WB_RGBLevels', Format => 'int16u[3]' },
+    0x030a => {
+        Name => 'FocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x030c => {
+        Name => 'MinFocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x030e => { # may give 0 for fixed focal length lenses
+        Name => 'MaxFocalLength',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x0320 => {
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x036d => { # different format from all previous cameras: now each triple is int16u-int32u-int32u
+        Name => 'MeterInfo',
+        Format => 'undef[1620]',
+        Unknown => 1,
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::MeterInfo9' },
+    },
+    0x17d0 => {
+        Name => 'DistortionCorrParams',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        Format => 'int16s[16]',
+    },
+    # 0x17f0 - same as 0x17f2, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2
+    0x17f1 => {
+        Name => 'LensFormat',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x17f2 => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^DSC-/ ? undef : $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+        },
+    },
+    0x17f3 => { #JR
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x17f6 => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Priority => 0, #PH (just to be safe)
+        Format => 'int16u', #PH
+        SeparateTable => 1,
+        ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
+        PrintConv => \%sonyLensTypes,
+    },
+    0x17f8 => {
+        Name => 'DistortionCorrParamsPresent',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => { 0 => 'No', 1 => 'Yes'},
+    },
+    0x17f9 => {
+        Name => 'DistortionCorrParamsNumber',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => { 11 => '11 (APS-C)', 16 => '16 (Full-frame)'},
+    },
+);
+
+%Image::ExifTool::Sony::Tag202a = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    FORMAT => 'int8u',
+    DATAMEMBER => [ 0x01 ],
+#
+# first seen for ILCE-6300
+# Possibly the Locations of the FocalPlaneAFPointsUsed are indicated here.
+# 66 bytes, structure appears to be as follows:
+# 0x00 - 1 for ILCE-6300/6500, ILCA-99M2
+# 0x01 - int8u: 0 to 15 - nr of locations to follow
+# 0x02 and 0x03 - (128 2) or 640 - (max.) width (X) of (LCD screen) area of following locations
+# 0x04 and 0x05 - (172 1) or 428 - (max.) height (Y) of (LCD screen) area of following locations
+#                 origin of X-Y coordinates appears to be top-left, i.e. X to the right, Y pointing down.
+# 0x06 0x07 0x08 0x09 - 2x int16u : X and Y coordinates of Location 1
+# etc.
+#
+    0x01 => {
+        Name => 'FocalPlaneAFPointsUsed',
+        DataMember => 'Locations',
+        Format => 'int8u',
+        RawConv => '$$self{Locations} = $val',
+    },
+    0x02 => {
+        Name => 'FocalPlaneAFPointArea',
+        Condition => '$$self{Locations} >= 1', # only output this if at least 1 Location follows ?
+        Format => 'int16u[2]',
+    },
+    0x06 => { Name => 'FocalPlaneAFPointLocation1',  Condition => '$$self{Locations} >= 1',  Format => 'int16u[2]' },
+    0x0a => { Name => 'FocalPlaneAFPointLocation2',  Condition => '$$self{Locations} >= 2',  Format => 'int16u[2]' },
+    0x0e => { Name => 'FocalPlaneAFPointLocation3',  Condition => '$$self{Locations} >= 3',  Format => 'int16u[2]' },
+    0x12 => { Name => 'FocalPlaneAFPointLocation4',  Condition => '$$self{Locations} >= 4',  Format => 'int16u[2]' },
+    0x16 => { Name => 'FocalPlaneAFPointLocation5',  Condition => '$$self{Locations} >= 5',  Format => 'int16u[2]' },
+    0x1a => { Name => 'FocalPlaneAFPointLocation6',  Condition => '$$self{Locations} >= 6',  Format => 'int16u[2]' },
+    0x1e => { Name => 'FocalPlaneAFPointLocation7',  Condition => '$$self{Locations} >= 7',  Format => 'int16u[2]' },
+    0x22 => { Name => 'FocalPlaneAFPointLocation8',  Condition => '$$self{Locations} >= 8',  Format => 'int16u[2]' },
+    0x26 => { Name => 'FocalPlaneAFPointLocation9',  Condition => '$$self{Locations} >= 9',  Format => 'int16u[2]' },
+    0x2a => { Name => 'FocalPlaneAFPointLocation10', Condition => '$$self{Locations} >= 10', Format => 'int16u[2]' },
+    0x2e => { Name => 'FocalPlaneAFPointLocation11', Condition => '$$self{Locations} >= 11', Format => 'int16u[2]' },
+    0x32 => { Name => 'FocalPlaneAFPointLocation12', Condition => '$$self{Locations} >= 12', Format => 'int16u[2]' },
+    0x36 => { Name => 'FocalPlaneAFPointLocation13', Condition => '$$self{Locations} >= 13', Format => 'int16u[2]' },
+    0x3a => { Name => 'FocalPlaneAFPointLocation14', Condition => '$$self{Locations} >= 14', Format => 'int16u[2]' },
+    0x3e => { Name => 'FocalPlaneAFPointLocation15', Condition => '$$self{Locations} >= 15', Format => 'int16u[2]' },
+);
+
+# possible metering information (ref JR)
+%Image::ExifTool::Sony::MeterInfo = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    NOTES => q{
+        Information possibly related to metering.  Extracted only if the Unknown
+        option is used.
+    },
+#
+# 162 'triplets' of 3 int32u numbers: (k,n1,n2)
+# These appear to relate to two sets of brightness distribution over the image area:
+# Set 1: 7 rows of 9
+# Set 2: 9 rows of 11
+#
+# Exact meaning presently unknown, however:
+# n1 ranges from 0 (black) - appr. 1300 (bright white)
+# n2 ranges from 0 (black) - appr. 142000 (bright white), i.e. roughly factor 100 higher
+# Many panorama images: all 0
+# Flash images: n2 = n1
+# k maybe some kind of 'gain' or multiplication factor ?
+# k distribution over the image as function of Aspect-Ratio is as follows:
+#
+#                3:2 image                           16:9 image                          4:3 image
+# set 1:
+#
+#     12 12 12 12 12 12 12 12 12          12 12 12 15 18 15 12 12 12           9 12 12 12 12 12 12 12  9
+#     12 12 12 12 12 12 12 12 12          12 12 12 15 18 15 12 12 12           9 12 12 12 12 12 12 12  9
+#     16 16 16 16 16 16 16 16 16          12 12 12 15 18 15 12 12 12          12 16 16 16 16 16 16 16 12
+#     16 16 16 16 16 16 16 16 16          12 12 12 15 18 15 12 12 12          12 16 16 16 16 16 16 16 12
+#     16 16 16 16 16 16 16 16 16          12 12 12 15 18 15 12 12 12          12 16 16 16 16 16 16 16 12
+#     12 12 12 12 12 12 12 12 12          12 12 12 15 18 15 12 12 12           9 12 12 12 12 12 12 12  9
+#     12 12 12 12 12 12 12 12 12          12 12 12 15 18 15 12 12 12           9 12 12 12 12 12 12 12  9
+#
+# set 2:
+#
+#  12 12 12 12 12 12 12 12 12 12 12    12 12 12 12 15 18 15 12 12 12 12     9  9 12 12 12 12 12 12 12  9  9
+#  12 12 12 12 12 12 12 12 12 12 12    12 12 12 12 15 18 15 12 12 12 12     9  9 12 12 12 12 12 12 12  9  9
+#  12 12 12 12 12 12 12 12 12 12 12    12 12 12 12 15 18 15 12 12 12 12     9  9 12 12 12 12 12 12 12  9  9
+#  16 16 16 16 16 16 16 16 16 16 16    12 12 12 12 15 18 15 12 12 12 12    12 12 16 16 16 16 16 16 16 12 12
+#  16 16 16 16 16 16 16 16 16 16 16    12 12 12 12 15 18 15 12 12 12 12    12 12 16 16 16 16 16 16 16 12 12
+#  16 16 16 16 16 16 16 16 16 16 16    12 12 12 12 15 18 15 12 12 12 12    12 12 16 16 16 16 16 16 16 12 12
+#  12 12 12 12 12 12 12 12 12 12 12    12 12 12 12 15 18 15 12 12 12 12     9  9 12 12 12 12 12 12 12  9  9
+#  12 12 12 12 12 12 12 12 12 12 12    12 12 12 12 15 18 15 12 12 12 12     9  9 12 12 12 12 12 12 12  9  9
+#  12 12 12 12 12 12 12 12 12 12 12     8  8  8  8 10 12 10  8  8  8  8     9  9 12 12 12 12 12 12 12  9  9
+#
+# Usually, in the center, the numbers of set 1 row 2-6 match with set 2 row 3-7, except for first and last 2 columns.
+#
+    0x0000 => { Name => 'MeterInfo1Row1', %meterInfo1 },
+    0x006c => { Name => 'MeterInfo1Row2', %meterInfo1 },
+    0x00d8 => { Name => 'MeterInfo1Row3', %meterInfo1 },
+    0x0144 => { Name => 'MeterInfo1Row4', %meterInfo1 },
+    0x01b0 => { Name => 'MeterInfo1Row5', %meterInfo1 },
+    0x021c => { Name => 'MeterInfo1Row6', %meterInfo1 },
+    0x0288 => { Name => 'MeterInfo1Row7', %meterInfo1 },
+
+    0x02f4 => { Name => 'MeterInfo2Row1', %meterInfo2 },
+    0x0378 => { Name => 'MeterInfo2Row2', %meterInfo2 },
+    0x03fc => { Name => 'MeterInfo2Row3', %meterInfo2 },
+    0x0480 => { Name => 'MeterInfo2Row4', %meterInfo2 },
+    0x0504 => { Name => 'MeterInfo2Row5', %meterInfo2 },
+    0x0588 => { Name => 'MeterInfo2Row6', %meterInfo2 },
+    0x060c => { Name => 'MeterInfo2Row7', %meterInfo2 },
+    0x0690 => { Name => 'MeterInfo2Row8', %meterInfo2 },
+    0x0714 => { Name => 'MeterInfo2Row9', %meterInfo2 },
+);
+
+# possible metering information (ref JR)
+%Image::ExifTool::Sony::MeterInfo9 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    NOTES => q{
+        Information possibly related to metering.  Extracted only if the Unknown
+        option is used.
+    },
+# new format for ILCE-9:
+# 162 'triplets' of (int16u int32u int32u) numbers: (k,n1,n2)
+# Set 1: 7 rows of 9
+# Set 2: 9 rows of 11
+    0x0000 => { Name => 'MeterInfo1Row1', %meterInfo1b },
+    0x005a => { Name => 'MeterInfo1Row2', %meterInfo1b },
+    0x00b4 => { Name => 'MeterInfo1Row3', %meterInfo1b },
+    0x010e => { Name => 'MeterInfo1Row4', %meterInfo1b },
+    0x0168 => { Name => 'MeterInfo1Row5', %meterInfo1b },
+    0x01c2 => { Name => 'MeterInfo1Row6', %meterInfo1b },
+    0x021c => { Name => 'MeterInfo1Row7', %meterInfo1b },
+
+    0x0276 => { Name => 'MeterInfo2Row1', %meterInfo2b },
+    0x02e4 => { Name => 'MeterInfo2Row2', %meterInfo2b },
+    0x0352 => { Name => 'MeterInfo2Row3', %meterInfo2b },
+    0x03c0 => { Name => 'MeterInfo2Row4', %meterInfo2b },
+    0x042e => { Name => 'MeterInfo2Row5', %meterInfo2b },
+    0x049c => { Name => 'MeterInfo2Row6', %meterInfo2b },
+    0x050a => { Name => 'MeterInfo2Row7', %meterInfo2b },
+    0x0578 => { Name => 'MeterInfo2Row8', %meterInfo2b },
+    0x05e6 => { Name => 'MeterInfo2Row9', %meterInfo2b },
+);
+
+%Image::ExifTool::Sony::Tag900b = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    # 0x0000 - always 174 (e)
+    0x0002 => {
+        Name => 'FacesDetected',
+        PrintConv => {
+            0   => '0',
+            98  => '1',
+            57  => '2',
+            93  => '3',
+            77  => '4',
+            33  => '5',
+            168 => '6',
+            241 => '7',
+            115 => '8',
+        },
+    },
+    # 0x00bc - always 98 (221 (e))
+    0x00bd => {
+        Condition => '$$self{Model} !~ /^DSLR-(A450|A500|A550)$/', # always 98 for A450/A500/A550: exclude
+        Name => 'FaceDetection',
+        PrintConv => {
+            0 => 'Off',
+            98 => 'On',
+        },
+    },
+);
+
+%Image::ExifTool::Sony::Tag9050a = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => q{
+        Valid for SLT, ILCA, NEX and ILCE models, except ILCE-6300/6500/7RM2/7SM2,
+        ILCA-99M2.
+    },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    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.
+    },
+    0x0000 => {
+        Condition => '$$self{Model} !~ /^(NEX-|Lunar|ILCE-)/',
+        Name => 'SonyMaxAperture', # (at current focal length)
+        # seen values from 17 - 48
+        ValueConv => '2 ** (($val/8 - 1.06) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0001 => {
+        Condition => '$$self{Model} !~ /^(NEX-|Lunar|ILCE-)/',
+        Name => 'SonyMinAperture', # (at current focal length)
+        # seen values from 80 - 95
+        ValueConv => '2 ** (($val/8 - 1.06) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+#    0x0002 and 0x0004 (int16u) for SLT:
+#           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',
+        PrintConv => {
+            0 => 'No Flash present',
+            2 => 'Flash Inhibited',           # seen for ILCE-7/7R continuous, panorama, HDR mode
+            64 => 'Built-in Flash present',
+            65 => 'Built-in Flash Fired',
+            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
+        },
+    },
+    0x0032 => { #13
+        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.
+        Format => 'int32u',
+        Notes => q{
+            total number of image exposures made by the camera, modulo 65536 for some
+            models
+        },
+        RawConv => '$val & 0x00ffffff',
+    },
+    0x003a => { # appr. same value as Exif ExposureTime, but longer in HDR-modes
+        Name => 'SonyExposureTime',
+        Format => 'int16u',
+        ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
+        ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x003c => {
+        Name => 'SonyFNumber',
+        Format => 'int16u',
+        ValueConv => '2 ** (($val/256 - 16) / 2)',
+        ValueConvInv => '(log($val)*2/log(2)+16)*256',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x003f => {
+        Name => 'ReleaseMode2',
+        %releaseMode2,
+    },
+# 0x004c - 0x005b: 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)
+# 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 => 'ShutterCount2',
+        Condition => '($$self{Model} =~ /^(ILCE-(7(R|S|M2)?|[56]000|5100|QX1))\b/) and (($$self{FlashFired} & 0x01) != 1)',
+        Format => 'int32u',
+        RawConv => '$val & 0x00ffffff',
+    },
+    0x0051 => { # only ILCE-7/7R/7S/7M2/5000/5100/6000/QX1, but hours usually different from SonyDateTime - UTC?
+                # appears not valid (all '0') when flash is used, panorama, hdr modes ...
+        Name => 'SonyDateTime2',
+        Condition => '$$self{Model} =~ /^(ILCE-(7(R|S|M2)?|[56]000|5100|QX1))\b/',
+        Groups => { 2 => 'Time' },
+        Shift => 'Time',
+        Format => 'undef[6]',
+        ValueConv => q{
+            my @v = unpack('C*', $val);
+            return undef unless $v[0] > 0;
+            return sprintf("20%.2d:%.2d:%.2d %.2d:%.2d:%.2d", @v)
+        },
+        ValueConvInv => q{
+            my @v = ($val =~ /\d+/g);
+            return undef unless @v == 6 and ($v[0]-=2000) >= 0;
+            return pack('C*', @v);
+        },
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val,0)',
+    },
+    0x0067 => {
+        Name => 'ReleaseMode2',
+        Condition => '$$self{Model} !~ /^(SLT-A(65|77)V?|Lunar|NEX-(5N|7|VG20E))/',
+        %releaseMode2,
+    },
+    0x007c => { #JR valid for ILCE and most NEX
+        Name => 'InternalSerialNumber', #(NC)
+        Condition => '$$self{Model} !~ /^(Lunar|NEX-(5N|7|VG20E)|SLT-|HV|ILCA-)/',
+        Format => 'int8u[4]',
+        PrintConv => 'unpack "H*", pack "C*", split " ", $val',
+    },
+    0x00f0 => { #JR valid for SLT/ILCA models
+        Name => 'InternalSerialNumber', #(NC)
+        Condition => '$$self{Model} =~ /^(SLT-|HV|ILCA-)/',
+        Format => 'int8u[5]',
+        PrintConv => 'unpack "H*", pack "C*", split " ", $val',
+        PrintConvInv => 'join " ", unpack "C*", pack "H*", $val',
+    },
+    # 0x0104 - same as 0x0105, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2
+    0x0105 => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+        },
+    },
+    0x0106 => {
+        Name => 'LensFormat',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x0107 => {
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x0109 => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Priority => 0, #PH (just to be safe)
+        Format => 'int16u', #PH
+        Notes => 'SLT models, and NEX with A-mount lenses',
+        SeparateTable => 1,
+        # has a value of 0 for E-mount lenses (values 0x80xx)
+        ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
+        PrintConv => \%sonyLensTypes,
+    },
+    0x010b => {
+        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.
+    0x0115 => {
+        Name => 'LensSpecFeatures',
+        Condition => '$$self{Model} =~ /^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/',
+        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)',
+    },
+    0x0116 => {
+        Name => 'LensSpecFeatures',
+        Condition => '$$self{Model} !~ /^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/',
+        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)',
+    },
+
+#    0x0122 => {Name=>'LensType',Format=>'int16u',Condition =>'$$self{Model}=~/^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/'},
+#    0x0123 => {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))/'},
+#    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))/'},
+
+#    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 => 'ShutterCount3',
+        Format => 'int32u',
+        RawConv => '$val == 0 ? undef : $val',
+        Condition => '$$self{Model} =~ /^(ILCE-(5100|QX1)|ILCA-(68|77M2))/',
+    },
+    0x01aa => {
+        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 => 'ShutterCount3',
+        Format => 'int32u',
+        RawConv => '$val == 0 ? undef : $val',
+        Condition => '$$self{Model} =~ /^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/',
+    },
+
+#    0x0222 => {Name=>'LensType2',Format=>'int16u',Condition =>'$$self{Model}=~/^(ILCE-(5100|7S|7M2|QX1))/'},
+#    0x0224 => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(ILCE-(5100|7S|7M2|QX1)|ILCA-(68|77M2))/'},
+#    0x0229 => {Name=>'LensType2',Format=>'int16u',Condition =>'$$self{Model}=~/^(NEX-(5R|5T|6|VG30E|VG900))/'},
+#    0x022b => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(NEX-(5R|5T|6|VG30E|VG900))/'},
+#    0x022c => {Name=>'LensType2',Format=>'int16u',Condition =>'$$self{Model}=~/^(ILCE-(3000|3500|5000|6000|7|7R)|NEX-3N)\b/'},
+#    0x022e => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(ILCE-(3000|3500|5000|6000|7|7R)|NEX-3N|SLT-A(58|99V?)|HV)\b/'},
+
+#    0x0231 => {Name=>'LensSpecFeatures',Format=>'undef[2]',Condition=>'$$self{Model}=~/^(ILCE-(7S|7M2|5100|QX1)|ILCA-(68|77M2))/'},
+#    0x0238 => {Name=>'LensSpecFeatures',Format=>'undef[2]',Condition=>'$$self{Model}=~/^(NEX-(5R|5T|6|VG30E|VG900))/'},
+#    0x023b => {Name=>'LensSpecFeatures',Format=>'undef[2]',Condition=>'$$self{Model}=~/^(SLT-A(58|99V?)|HV|ILCE-(3000|3500|5000|6000|7|7R)|NEX-3N)\b/'},
+
+#    0x023c => {Name=>'LensType2',Format=>'int16u',Condition =>'$$self{Model}=~/^(Lunar|NEX-(F3|5N|7|VG20E))/'},
+#    0x023e => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E)|ILCE-(5100|7S|7M2|QX1)|ILCA-(68|77M2))/'},
+#    0x0245 => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(NEX-(5R|5T|6|VG30E|VG900))/'},
+#    0x0248 => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(SLT-A(58|99V?)|HV|ILCE-(3000|3500|5000|6000|7|7R)|NEX-3N)\b/'},
+#    0x0249 => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(ILCE-(5100|7S|7M2|QX1)|ILCA-(68|77M2))/'},
+
+#    0x024a => {Name=>'LensSpecFeatures',Format=>'undef[2]',Condition=>'$$self{Model}=~/^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/'},
+
+#    0x0250 => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(NEX-(5R|5T|6|VG30E|VG900))/'},
+#    0x0253 => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(SLT-A(58|99V?)|HV|ILCE-(3000|3500|5000|6000|7|7R|7S|7M2)|NEX-3N)\b/'},
+#    0x0257 => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/'},
+#    0x0262 => {Name=>'LensType', Format=>'int16u',Condition =>'$$self{Model}=~/^(SLT-A(37|57|65|77)V?|Lunar|NEX-(F3|5N|7|VG20E))/'},
+
+#    0x031b => {%gain2010,Condition=>'$$self{Model}=~/^(DSC-RX100M3|ILCA-(68|77M2)|ILCE-(5100|7S|7M2|QX1))/'},
+#    0x032c => {%gain2010,Condition=>'$$self{Model}=~/^(NEX-(5R|5T|6|VG30E|VG900))/'},
+#    0x032f => {%gain2010,Condition=>'$$self{Model}=~/^(DSC-RX10|SLT-A(58|99V?)|HV|ILCE-(3000|3500|5000|6000|7|7R)|NEX-3N)\b/'},
+#    0x0350 => {%gain2010,Condition=>'$$self{Model}=~/^(SLT-A(37|57)|NEX-F3)/'},
+#    0x037b => {%gain2010,Condition=>'$$self{Model}=~/^(SLT-A(65|77)V?|Lunar|NEX-(7|VG20E))/'},
+);
+
+%Image::ExifTool::Sony::Tag9050b = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => q{
+        Valid from July 2015 for ILCE-6100/6300/6400/6500/6600/7C/7M3/7RM2/7RM3/7RM4/
+        7SM2/9/9M2, ILCA-99M2.
+    },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    DATAMEMBER => [ 0x0039, 0x0105 ],
+    0x0000 => {
+        Condition => '$$self{Model} =~ /^(ILCA-)/',
+        Name => 'SonyMaxAperture', # (at current focal length)
+        # seen values from 17 - 48
+        ValueConv => '2 ** (($val/8 - 1.06) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0001 => {
+        Condition => '$$self{Model} =~ /^(ILCA-)/',
+        Name => 'SonyMinAperture', # (at current focal length)
+        # seen values from 80 - 95
+        ValueConv => '2 ** (($val/8 - 1.06) / 2)',
+        ValueConvInv => 'int((log($val) * 2 / log(2) + 1) * 8 + 0.5)',
+        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',
+        PrintConv => {
+            0 => 'No Flash present',
+            2 => 'Flash Inhibited',           # seen for ILCE-7/7R continuous, panorama, HDR mode
+            64 => 'Built-in Flash present',
+            65 => 'Built-in Flash Fired',
+            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 => 'ShutterCount',
+        # or "ShutterCount"? : number of shutter actuations, does not increase during Silent Shooting,
+        # at least for ILCE-7RM2
+        Format => 'int32u',
+        Notes => 'total number of image exposures made by the camera',
+        RawConv => '$val & 0x00ffffff',
+    },
+    0x0046 => { # appr. same value as Exif ExposureTime, but longer in HDR-modes
+        Name => 'SonyExposureTime',
+        Format => 'int16u',
+        ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
+        ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x0048 => {
+        Name => 'SonyFNumber',
+        Format => 'int16u',
+        ValueConv => '2 ** (($val/256 - 16) / 2)',
+        ValueConvInv => '(log($val)*2/log(2)+16)*256',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x004b => {
+        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|7C|7RM4|9M2))/ or $$self{Software} =~ /^ILCE-9 (v5.0|v6.0)/)',
+        Format => 'int32u',
+        RawConv => '$val & 0x00ffffff',
+    },
+    0x0052 => {
+        Name => 'ShutterCount2',
+        Condition => '(($$self{FlashFired} & 0x01) != 1) and ($$self{Model} =~ /^(ILCE-(7M3|7RM3))/)',
+        Format => 'int32u',
+        RawConv => '$val & 0x00ffffff',
+    },
+# 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: ShutterCount and dateTime
+    0x0058 => { # appears not valid when flash is used ... not for ILCA-99M2
+        Name => 'ShutterCount2',
+        Condition => '(($$self{FlashFired} & 0x01) != 1) and ($$self{Model} !~ /^(ILCA-99M2|ILCE-(6100|6400|6600|7C|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-(6100|6400|6600|7C|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|7C|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-(6100|6400|6600|7C|7M3|7RM3|7RM4|9M2))/ and $$self{Software} !~ /^ILCE-9 (v5.0|v6.0)/',
+        %releaseMode2,
+    },
+    0x0088 => {
+        Name => 'InternalSerialNumber', #(NC)
+        Format => 'int8u[6]',
+        PrintConv => 'unpack "H*", pack "C*", split " ", $val',
+    },
+
+##### same offsets for lens info tags
+
+    # 0x0104 - same as 0x0105, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2
+    0x0105 => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+        },
+    },
+    0x0106 => {
+        Name => 'LensFormat',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x0107 => {
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x0109 => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Priority => 0, #PH (just to be safe)
+        Format => 'int16u', #PH
+        Notes => 'SLT models, and NEX with A-mount lenses',
+        SeparateTable => 1,
+        # has a value of 0 for E-mount lenses (values 0x80xx)
+        ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
+        PrintConv => \%sonyLensTypes,
+    },
+    0x010b => {
+        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.
+    0x0116 => {
+        Name => 'LensSpecFeatures',
+        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)',
+    },
+#
+# tags becoming model- and/or firmware-dependent from here.
+#
+    0x019f => {
+        Name => 'ShutterCount3',
+        Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7C|7M3|7RM3|7RM4|9|9M2))\b/',
+        Format => 'int32u',
+        RawConv => '$val == 0 ? undef : $val',
+    },
+    0x01cb => {
+        Name => 'ShutterCount3',
+        Condition => '$$self{Model} =~ /^(ILCE-(7RM2|7SM2))/',
+        Format => 'int32u',
+        RawConv => '$val == 0 ? undef : $val',
+    },
+    0x01cd => {
+        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|7C|9M2)/ or $$self{Software} =~ /^ILCE-9 (v5.0|v6.0)/',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    },
+    0x01ed => {
+        Name => 'LensSpecFeatures',
+        Condition => '$$self{Model} =~ /^ILCE-(7RM4|7C|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 => {
+#         Name=>'LensType2',
+#         Condition => '$$self{Model} =~ /^(ILCE-(7RM2|7SM2))/',
+#         Format=>'int16u',
+#     },
+#     0x020f => [{
+#         Name=>'LensType',
+#         Condition => '$$self{Model} =~ /^(ILCE-(7RM2|7SM2))/',
+#         Format=>'int16u',
+#     },{
+#         Name=>'LensType2',
+#         Condition => '$$self{Model} =~ /^(ILCE-(6300|6500)|ILCA-99M2)/',
+#         Format=>'int16u',
+#     }],
+#     0x0211 => {
+#         Name=>'LensType',
+#         Condition => '$$self{Model} =~ /^(ILCE-(6300|6500)|ILCA-99M2)/',
+#         Format=>'int16u',
+#     },
+    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,
+        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)',
+    },{
+        Name => 'APS-CSizeCapture',
+        Condition => '$$self{Model} =~ /^(ILCA-99M2)/',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',
+        },
+    }],
+    0x021e => {
+        Name => 'LensSpecFeatures',
+        Condition => '$$self{Model} =~ /^(ILCE-(6300|6500)|ILCA-99M2)/',
+        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)',
+    },
+);
+
+%Image::ExifTool::Sony::Tag9050c = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => q{
+        Valid from July 2020 for ILCE-1/7SM3.
+    },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    DATAMEMBER => [ 0x0039 ],
+    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)";
+            },
+        },
+    },
+    0x0039 => {
+        Name => 'FlashStatus',
+        RawConv => '$$self{FlashFired} = $val',
+        PrintConv => {
+            0 => 'No Flash present',
+            2 => 'Flash Inhibited',           # seen for ILCE-7/7R continuous, panorama, HDR mode
+            64 => 'Built-in Flash present',
+            65 => 'Built-in Flash Fired',
+            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
+        },
+    },
+    0x003a => {
+        Name => 'ShutterCount',
+        # or "ShutterCount"? : number of shutter actuations, does not increase during Silent Shooting,
+        # at least for ILCE-7RM2
+        Format => 'int32u',
+        Notes => 'total number of image exposures made by the camera',
+        RawConv => '$val & 0x00ffffff',
+        PrintConv => 'sprintf("%6d",$val)',
+    },
+    0x0046 => { # appr. same value as Exif ExposureTime, but longer in HDR-modes
+        Name => 'SonyExposureTime',
+        Format => 'int16u',
+        ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
+        ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x0048 => {
+        Name => 'SonyFNumber',
+        Format => 'int16u',
+        ValueConv => '2 ** (($val/256 - 16) / 2)',
+        ValueConvInv => '(log($val)*2/log(2)+16)*256',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x004b => {
+        Name => 'ReleaseMode2',
+        %releaseMode2,
+    },
+    0x0050 => {
+        Name => 'ShutterCount2',
+        Condition => '($$self{FlashFired} & 0x01) != 1',
+        Format => 'int32u',
+        RawConv => '$val & 0x00ffffff',
+    },
+    0x0066 => { # appr. same value as Exif ExposureTime, but not valid in HDR-modes
+        Name => 'SonyExposureTime',
+        Format => 'int16u',
+        ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
+        ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x0068 => { # appr. same value as Exif ExposureTime, but not valid in HDR-modes
+        Name => 'SonyFNumber',
+        Format => 'int16u',
+        ValueConv => '2 ** (($val/256 - 16) / 2)',
+        ValueConvInv => '(log($val)*2/log(2)+16)*256',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x006b => {
+        Name => 'ReleaseMode2',
+        %releaseMode2,
+    },
+    0x0088 => {
+        Name => 'InternalSerialNumber', #(NC)
+        Format => 'int8u[6]',
+        PrintConv => 'unpack "H*", pack "C*", split " ", $val',
+    },
+);
+
+%Image::ExifTool::Sony::Tag9400a = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => 'Valid for many DSC, NEX and SLT models',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x0008 => { %sequenceImageNumber }, #PH
+    0x000c => { %sequenceFileNumber }, #PH
+    0x0010 => { %releaseMode2 },
+    0x0012 => {
+        Name => 'DigitalZoom',
+        Condition => '$$self{Model} !~ /^(SLT-(A65|A77)V?|NEX-(5N|7|VG20E)|Lunar|DSC-(HX10V|HX20V|HX200V|TX20|TX55|TX300V|WX30|WX70))\b/',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Yes',
+        },
+    },
+#    0x0013 - Flash fired 0=no, 1=yes
+#    0x0014 - related to flash / RedEyeReduction ?
+#    0x0015 - CameraType: 1=HDR, 2=DSC, 3=SLT/NEX
+    0x001a => { #PH
+        Name => 'ShotNumberSincePowerUp',
+        Format => 'int32u',
+    },
+#    0x001e - increments by 4 or 6 or 8 each shutter release press since power up
+#    0x001f - 0=most pictures, 1='Self-timer/Self-portrait', 2='Self-portrait (2 people)',
+#             3='Continuous Self-timer', 26='Sweep Panorama' (PH, RX100)
+#    0x0021 - maybe related to Image Stabilization or Smile Shutter ?
+    0x0022 => {
+        Name => 'SequenceLength',
+        PrintConv => {
+            0 => 'Continuous', # (RX100 too)
+            1 => '1 shot',
+            2 => '2 shots', # (Background defocus, 3D Image)
+            3 => '3 shots', # (HDR, WB Bracketing) (RX100, also continuous bracket)
+            4 => '4 shots', # seen for DSC-WX300 in Superior-Auto Anti-Motion-Blur
+            5 => '5 shots', # (PH, RX100)
+            6 => '6 shots', # (Multi Frame NR, Anti Motion blur, Hand-held Twilight)
+            10 => '10 shots', # (HX9V Burst)
+            100 => 'Continuous - iSweep Panorama', # (HX9V)
+            200 => 'Continuous - Sweep Panorama',
+        },
+    },
+#    0x0027 - 1=single exposure, 2=multi-exposure (eg. pano,some superior auto) (PH, RX100)
+    0x0028 => {
+        Name => 'CameraOrientation', # (also RX100 - PH)
+        PrintConv => {
+            1 => 'Horizontal (normal)',
+            3 => 'Rotate 180',
+            6 => 'Rotate 90 CW',
+            8 => 'Rotate 270 CW',
+        },
+    },
+    0x0029 => {
+        Name => 'Quality2', # (also RX100 - PH)
+        PrintConv => {
+            0 => 'JPEG',
+            1 => 'RAW',
+            2 => 'RAW + JPEG',
+            3 => 'JPEG + MPO', # 3D images
+        },
+    },
+#    0x002b - FacesDetected_OK  0=no, 1=yes  appears valid for SLT, but not for NEX and DSC-HX9V
+#    0x0030 - long exposure noise reduction used 0=no, 1=yes (PH, RX100)
+#    0x0031 - smile shutter used 0=no, 1=yes (PH, RX100)
+#    0x0033 - 0 for DSC-HX9V, 8 for SLT, NEX
+#    0x0034 and 0x0038 - different offset for HX9V and SLT/NEX, but similar numbers, non-zero when flash fired
+    0x0044 => {
+        Condition => '$$self{Model} =~ /^(SLT-|HV|NEX-|Lunar|DSC-RX|Stellar)/', # not valid for most other DSC and HDR models
+        Name => 'SonyImageHeight',
+        Format => 'int16u',
+        PrintConv => '$val > 0 ? 8*$val : "n.a."',
+    },
+    0x0052 => {
+        Name => 'ModelReleaseYear',
+        Condition => '$$self{Model} =~ /^(SLT-|HV|NEX-|Lunar|DSC-RX|Stellar)/', # not valid for most other DSC and HDR models
+        Format => 'int8u',
+        PrintConv => 'sprintf("20%.2d", $val)',
+    },
+);
+
+%Image::ExifTool::Sony::Tag9400b = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => q{
+        Valid for NEX-3N, ILCE-3000/3500, SLT-A58, DSC-WX60, DSC-WX300, DSC-RX100M2,
+        DSC-HX50V, DSC-QX10/QX100.
+    },
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x0008 => { %sequenceImageNumber }, #PH
+    0x000c => { %sequenceFileNumber }, #PH
+    0x0010 => { %releaseMode2 },
+    0x0012 => {
+        Name => 'DigitalZoom',
+        PrintConv => {
+            0 => 'No',
+            1 => 'Yes',
+        },
+    },
+#    0x0013 - Flash fired 0=no, 1=yes
+#    0x0014 - related to flash / RedEyeReduction ?
+#    0x0015 - CameraType: 1=HDR, 2=DSC, 3=SLT/NEX
+    0x0016 => { #PH
+        Name => 'ShotNumberSincePowerUp',
+        Format => 'int32u',
+    },
+    0x001e => {
+        Name => 'SequenceLength',
+        PrintConv => {
+            0 => 'Continuous',
+            1 => '1 shot',
+            2 => '2 shots',
+            3 => '3 shots',
+            4 => '4 shots',
+            5 => '5 shots',
+            6 => '6 shots',
+            10 => '10 shots',
+            100 => 'Continuous - iSweep Panorama',
+            200 => 'Continuous - Sweep Panorama',
+        },
+    },
+    0x0024 => {
+        Name => 'CameraOrientation',
+        PrintConv => {
+            1 => 'Horizontal (normal)',
+            3 => 'Rotate 180',
+            6 => 'Rotate 90 CW',
+            8 => 'Rotate 270 CW',
+        },
+    },
+    0x0025 => {
+        Name => 'Quality2',
+        PrintConv => {
+            0 => 'JPEG',
+            1 => 'RAW',
+            2 => 'RAW + JPEG',
+            3 => 'JPEG + MPO', # 3D images
+        },
+    },
+#    0x0027 - FacesDetected_OK  0=no, 1=yes
+#    0x002c - long exposure noise reduction used 0=no, 1=yes (PH, RX100)
+    0x003f => {
+        Name => 'SonyImageHeight',
+        Format => 'int16u',
+        PrintConv => '$val > 0 ? 8*$val : "n.a."',
+    },
+    0x0046 => { # but Panorama images give incorrect result
+        Name => 'ModelReleaseYear',
+        Format => 'int8u',
+        PrintConv => 'sprintf("20%.2d", $val)',
+    },
+);
+
+%Image::ExifTool::Sony::Tag9400c = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    NOTES => q{
+        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-1/7/7C/7R/7S/7M2/7M3/7RM2/7RM3/7RM4/7SM2/7SM3/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 => {
+        Name => 'ShotNumberSincePowerUp',
+        Condition => '$$self{Model} =~ /^(ILCA-(68|77M2|99M2)|ILCE-(5000|5100|6000|6300|6500|7|7M2|7R|7RM2|7S|7SM2|QX1)|DSC-(HX350|HX400V|HX60V|HX80|HX90|HX90V|QX30|RX0|RX1RM2|RX10|RX10M2|RX10M3|RX100M3|RX100M4|RX100M5|WX220|WX350|WX500))\b/',
+        Notes => 'valid only for some models',
+        Format => 'int32u',
+    },
+    0x0012 => { %sequenceImageNumber },
+    0x0016 => {
+        Name => 'SequenceLength',
+        PrintConv => {
+            0 => 'Continuous',
+            1 => '1 shot',
+            2 => '2 shots',
+            3 => '3 shots',
+            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',
+        },
+    },
+    0x001a => { %sequenceFileNumber },
+    0x001e => {
+        Name => 'SequenceLength',
+        PrintConv => {
+            0 => 'Continuous',
+            1 => '1 file',
+            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
+        },
+    },
+    0x0029 => {
+        Name => 'CameraOrientation',
+        PrintConv => {
+            1 => 'Horizontal (normal)',
+            3 => 'Rotate 180',
+            6 => 'Rotate 90 CW',
+            8 => 'Rotate 270 CW',
+        },
+    },
+    0x002a => {
+        Name => 'Quality2',
+        Condition => '$$self{Model} !~ /^(ILCE-(1|7SM3))\b/',
+        PrintConv => {
+            0 => 'JPEG',
+            1 => 'RAW',
+            2 => 'RAW + JPEG',
+            3 => 'JPEG + MPO', # 3D images
+        },
+    },
+    0x0047 => {
+        Name => 'SonyImageHeight',
+        Condition => '$$self{Model} !~ /^(ILCE-(1|7SM3))\b/',
+        Format => 'int16u',
+        PrintConv => '$val > 0 ? 8*$val : "n.a."',
+    },
+    0x0053 => {
+        Name => 'ModelReleaseYear',
+        Condition => '$$self{Model} !~ /^(ILCE-(1|7SM3))\b/',
+        Format => 'int8u',
+        PrintConv => 'sprintf("20%.2d", $val)',
+    },
+);
+
+%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, 0x04a1, 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' } },
+    0x04a1 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(160|164)/', Format => 'int8u[5]', SubDirectory => { TagTable => 'Image::ExifTool::Sony::ISOInfo' } },
+    0x04a2 => { Name => 'ISOInfo', Condition => '$$self{Ver9401} =~ /^(152|154|155)/', 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,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    DATAMEMBER => [ 0x02 ],
+    PRIORITY => 0,
+    0x02 => {
+        Name => 'TempTest1',
+        DataMember => 'TempTest1',
+        Hidden => 1,
+        RawConv => '$$self{TempTest1}=$val; $$self{OPTIONS}{Unknown}<2 ? undef : $val',
+    },
+    0x04 => {
+        Name => 'AmbientTemperature',
+        # this (and many other values) are only valid if 0x02 is 255 (why?)
+        Condition => '$$self{TempTest1} == 255',
+        Format => 'int8s', # (verified for negative temperature)
+        PrintConv => '"$val C"',
+        PrintConvInv => '$val=~s/ ?C//; $val',
+    },
+    0x16 => { #JR
+        Name => 'FocusMode',
+        Mask => 0x7f, # (often +128, not sure what upper bit is for)
+        PrintConv => {
+            0 => 'Manual',
+            2 => 'AF-S',
+            3 => 'AF-C',
+            4 => 'AF-A', # seen in ILCE-6000 images
+            6 => 'DMF',
+            # 7 => 'AF-D', # not for DSC, NEX, ILCE ...
+        },
+    },
+    0x17 => {
+        Name => 'AFAreaMode',
+        PrintConv => {
+            0 => 'Multi', # newer DSC/ILC use name 'Wide'
+            1 => 'Center',
+            2 => 'Spot', #(NC) seen for DSC-WX300
+            3 => 'Flexible Spot',
+            10 => 'Selective (for Miniature effect)', # seen for DSC-HX30V,TX30,WX60,WX100
+            11 => 'Zone', #JR (ILCE-7 series)
+            12 => 'Expanded Flexible Spot', #JR (HX90V, ILCE-7 series)
+            14 => 'Tracking',
+            15 => 'Face Tracking',
+            20 => 'Animal Eye Tracking',
+#            21 => '???',  # (ILCE-7SM3)
+            255 => 'Manual',
+        },
+    },
+    # 0x24, 0x26: factor 10 for NEX and ILCE, factor 100 for DSC
+    # 0x24, 0x26, 0x28, 0x2a: inconsistent for A-mount lenses on NEX/ILCE: some correct, some 0, some incorrect ...
+    # 0x28 - not valid for DSC-[HTW]X models, or DSC-RX100
+#    0x24 => { # same values as Exif FocalLength (but have seen FocalLength for previous shot, ref IB, RX100M5)
+#        Name => 'FocalLength',
+#        Format => 'int16u',
+#        RawConv => '$val || undef',
+#        ValueConv => '$val / ($$self{Model}=~/DSC/ ? 100 : 10)',
+#        ValueConvInv => '$val * ($$self{Model}=~/DSC/ ? 100 : 10)',
+#        PrintConv => 'sprintf("%.1f mm",$val)',
+#        PrintConvInv => '$val =~ s/ ?mm//; $val',
+#    },
+#    0x26 => { # usually identical to 0x24 or 0
+#        Name => 'FocalLength',
+#        Format => 'int16u',
+#        ValueConv => '$val / ($$self{Model}=~/DSC/ ? 100 : 10)',
+#        ValueConvInv => '$val * ($$self{Model}=~/DSC/ ? 100 : 10)',
+#        PrintConv => 'sprintf("%.1f mm",$val)',
+#        PrintConvInv => '$val =~ s/ ?mm//; $val',
+#    },
+#    0x28 => { # values slightly different from Exif FocalLength
+#        Name => 'FocalLength2',
+#        Format => 'int16u',
+#        RawConv => '$val || undef',
+#        ValueConv => '$val / 10',
+#        ValueConvInv => '$val * 10',
+#        PrintConv => 'sprintf("%.1f mm",$val)',
+#        PrintConvInv => '$val =~ s/ ?mm//; $val',
+#    },
+#    0x2a => { # usually identical to 0x28 or 0
+#        Name => 'FocalLength2',
+#        Format => 'int16u',
+#        ValueConv => '$val / 10',
+#        ValueConvInv => '$val * 10',
+#        PrintConv => 'sprintf("%.1f mm",$val)',
+#        PrintConvInv => '$val =~ s/ ?mm//; $val',
+#    },
+#    0x002c => {
+#        # seen values from 80 - 255 (= infinity) -- see Composite:FocusDistance2 below
+#        Name => 'FocusPosition2',
+#        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+#    },
+    0x002d => { # usually same as 0x002c, but some differences
+        # seen values from 80 - 255 (= infinity) -- see Composite:FocusDistance2 below
+        Name => 'FocusPosition2',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+    },
+    # 0x8a - int32u: some sort of accumulated time or something since power up
+    #        (doesn't increment during continuous shooting and at some other times)
+);
+
+# PH (RX100)
+%Image::ExifTool::Sony::Tag9403 = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    DATAMEMBER => [ 0x04 ],
+    0x04 => {
+        # seen values 0,2,3,18,32,49,50,83,148
+        # CameraTemperature is valid for all values except 0,148
+        Name => 'TempTest2',
+        DataMember => 'TempTest2',
+        Hidden => 1,
+        RawConv => '$$self{TempTest2}=$val; $$self{OPTIONS}{Unknown}<2 ? undef : $val',
+    },
+    0x05 => {
+        Name => 'CameraTemperature', # (maybe SensorTemperature? - heats up when taking movies)
+        Condition => '$$self{TempTest2} and $$self{TempTest2} < 100',
+        Format => 'int8s', # have seen as low as -1 for AmbientTemperature of -18
+        PrintConv => '"$val C"',
+        PrintConvInv => '$val=~s/ ?C//; $val',
+    },
+    # 0x0f - same as 0x05
+    # 0x18 - maybe another temperature?
+);
+
+# Tag9404 (ref JR)
+%Image::ExifTool::Sony::Tag9404a = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x000b => { %exposureProgram2010 },
+    0x000d => { Name => 'IntelligentAuto', PrintConv => { 0 => 'Off', 1 => 'On'} },
+    0x0019 => {
+        Name => 'LensZoomPosition',
+        Format => 'int16u',
+        Condition => '$$self{Model} !~ /^SLT-/',
+        PrintConv => 'sprintf("%.0f%%",$val/10.24)',
+        PrintConvInv => '$val=~s/ ?%$//; $val * 10.24',
+    },
+);
+
+# Tag9404 (ref JR)
+%Image::ExifTool::Sony::Tag9404b= (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x000c => { %exposureProgram2010 },
+    0x000e => { Name => 'IntelligentAuto', PrintConv => { 0 => 'Off', 1 => 'On'} },
+    0x001e => {
+        Name => 'LensZoomPosition',
+        Format => 'int16u',
+        Condition => '$$self{Model} !~ /^(SLT-|HV|ILCA-)/',
+        PrintConv => 'sprintf("%.0f%%",$val/10.24)',
+        PrintConvInv => '$val=~s/ ?%$//; $val * 10.24',
+    },
+    0x0020 => {
+        # seen values from 80 - 255 (= infinity) -- see Composite:FocusDistance2 below
+        Name => 'FocusPosition2',
+        Condition => '$$self{Model} =~ /^(SLT-|HV|ILCA-)/',
+    },
+);
+
+# Tag9404 (ref JR)
+%Image::ExifTool::Sony::Tag9404c= (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x000b => { %exposureProgram2010 },
+    0x000d => { Name => 'IntelligentAuto', PrintConv => { 0 => 'Off', 1 => 'On'} },
+);
+
+# Tag9405 (ref JR)
+%Image::ExifTool::Sony::Tag9405a = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    DATAMEMBER => [ 0x0604 ],
+    NOTES => 'Valid for SLT, NEX, ILCE-3000/3500 and several DSC models.',
+    0x0600 => {
+        Name => 'DistortionCorrParamsPresent',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+        PrintConv => { 0 => 'No', 1 => 'Yes'},
+    },
+    0x0601 => {
+        Name => 'DistortionCorrection',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Applied',
+        },
+    },
+    # 0x0602 - same as 0x0604, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2
+    0x0603 => {
+        Name => 'LensFormat',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x0604 => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^(DSC-|Stellar)/ ? undef : $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+            # 6 - seen for A58 panorama image
+        },
+    },
+    0x0605 => {
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        Notes => 'E-mount lenses',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x0608 => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Format => 'int16u',
+        Notes => 'A-mount lenses on SLT and NEX',
+        SeparateTable => 1,
+        PrintConv => \%sonyLensTypes,
+    },
+    0x064a => {
+        Name => 'VignettingCorrParams',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+        Format => 'int16s[16]',
+    },
+    0x066a => {
+        Name => 'ChromaticAberrationCorrParams',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+        Format => 'int16s[32]',
+    },
+    0x06ca => {
+        Name => 'DistortionCorrParams',
+        Condition => '$$self{Model} !~ /^(DSC-|Stellar)/',
+        Format => 'int16s[16]',
+    },
+);
+
+# Tag9405b (ref JR)
+%Image::ExifTool::Sony::Tag9405b = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    DATAMEMBER => [ 0x005e ],
+    NOTES => q{
+        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',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0006 => {
+        Name => 'BaseISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x000a => { %gain2010 },
+    0x000e => { # appr. same value as Exif ExposureTime, but shorter in HDR-modes
+        Name => 'SonyExposureTime2',
+        Format => 'int16u',
+        ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
+        ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x0010 => {
+        Name => 'ExposureTime',
+        Format => 'rational32u',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"', # (Bulb NC)
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : $val',
+    },
+    0x0014 => { # but often odd results for DSC models: exclude
+                # also often deviating results for Sony FE 90mm F2.8 Macro G OSS ...
+        Name => 'SonyFNumber',
+        Format => 'int16u',
+        Condition => '$$self{Model} !~ /^(DSC-|ZV-)/',
+        ValueConv => '2 ** (($val/256 - 16) / 2)',
+        ValueConvInv => '(log($val)*2/log(2)+16)*256',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0016 => {
+        Name => 'SonyMaxApertureValue', # (at current focal length)
+        Format => 'int16u',
+        ValueConv => '2 ** (($val/256 - 16) / 2)',
+        ValueConvInv => '(log($val)*2/log(2)+16)*256',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0024 => { %sequenceImageNumber },
+    0x0034 => { %releaseMode2 },
+    #  0x003e and 0x0040: maximum image size; ShotInfo gives actual image size
+    0x003e => { Name => 'SonyImageWidthMax', Format => 'int16u' },
+    0x0040 => { Name => 'SonyImageHeightMax', Format => 'int16u' },
+    0x0042 => {
+        Name => 'HighISONoiseReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'Low',
+            2 => 'Normal',
+            3 => 'High',
+        },
+    },
+    0x0044 => {
+        Name => 'LongExposureNoiseReduction',
+        PrintConv => {
+            0 => 'Off',
+            1 => 'On',  # (unused or dark subject)
+        },
+    },
+    0x0046 => { %pictureEffect2010 },
+    0x0048 => { %exposureProgram2010 },
+    0x004a => {
+        Name => 'CreativeStyle',
+        PrintConv => {
+            0 => 'Standard',
+            1 => 'Vivid',
+            2 => 'Neutral',
+            3 => 'Portrait',
+            4 => 'Landscape',
+            5 => 'B&W',
+            6 => 'Clear',
+            7 => 'Deep',
+            8 => 'Light',
+            9 => 'Sunset',
+            10 => 'Night View/Portrait',
+            11 => 'Autumn Leaves',
+            13 => 'Sepia',
+        },
+    },
+    0x0052 => {
+        Name => 'Sharpness',
+        Format => 'int8s',
+        PrintConv => '$val > 0 ? "+$val" : $val',
+        PrintConvInv => '$val',
+    },
+    0x005a => {
+        Name => 'DistortionCorrParamsPresent',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => { 0 => 'No', 1 => 'Yes'},
+    },
+    0x005b => {
+        Name => 'DistortionCorrection',
+        PrintConv => {
+            0 => 'None',
+            1 => 'Applied',
+        },
+    },
+    # 0x005c - same as 0x005e, but has value 3 for SAL18135, SAL50F14Z, SAL55300, SAL70200G2, SAL70300G2, SAL70400G2
+    0x005d => {
+        Name => 'LensFormat',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x005e => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^DSC-/ ? undef : $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+        },
+    },
+    0x0060 => {
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        Notes => 'E-mount lenses',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x0062 => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Format => 'int16u',
+        Notes => 'A-mount lenses on SLT and NEX',
+        SeparateTable => 1,
+        PrintConv => \%sonyLensTypes,
+    },
+    0x0064 => {
+        Name => 'DistortionCorrParams',
+        Condition => '$$self{Model} !~ /^DSC-/',
+        Format => 'int16s[16]',
+    },
+    0x0342 => {
+        Name => 'LensZoomPosition',
+        Condition => '$$self{Model} !~ /^(ILCA-|ILCE-(7RM2|7M3|7RM3|7RM4|7SM2|6100|6300|6400|6500|6600|7C|9|9M2)|DSC-(HX80|HX90V|HX99|RX0|RX10M2|RX10M3|RX10M4|RX100M4|RX100M5|RX100M5A|RX100M6|RX100M7|WX500)|ZV-)/',
+        Format => 'int16u',
+        PrintConv => 'sprintf("%.0f%%",$val/10.24)',
+        PrintConvInv => '$val=~s/ ?%$//; $val * 10.24',
+    },
+    0x034a => {
+        Name => 'VignettingCorrParams',
+        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|7C|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)/',
+        Format => 'int16s[16]',
+    },
+    0x035c => {
+        Name => 'VignettingCorrParams',
+        Condition => '$$self{Model} =~ /^(ILCA-99M2|ILCE-(6100|6400|6500|6600|7C|7M3|7RM3|7RM4|9|9M2))/',
+        Format => 'int16s[16]',
+    },
+    0x035a => {
+        Name => 'LensZoomPosition',
+        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',
+    },
+    0x0368 => {
+        Name => 'VignettingCorrParams',
+        Condition => '$$self{Model} =~ /^(ILCE-(6300|7RM2|7SM2))/',
+        Format => 'int16s[16]',
+    },
+    0x037c => {
+        Name => 'ChromaticAberrationCorrParams',
+        Condition => '$$self{Model} =~ /^(ILCA-(68|77M2)|ILCE-(5000|5100|6000|7|7R|7S|QX1)|Lusso)\b/',
+        Format => 'int16s[32]',
+    },
+    0x0384 => {
+        Name => 'ChromaticAberrationCorrParams',
+        Condition => '$$self{Model} =~ /^(ILCE-7M2)/',
+        Format => 'int16s[32]',
+    },
+    0x039c => {
+        Name => 'ChromaticAberrationCorrParams',
+        Condition => '$$self{Model} =~ /^(ILCE-(6300|7RM2|7SM2))/',
+        Format => 'int16s[32]',
+    },
+    0x03b0 => {
+        Name => 'ChromaticAberrationCorrParams',
+        Condition => '$$self{Model} =~ /^(ILCA-99M2|ILCE-6500)/',
+        Format => 'int16s[32]',
+    },
+    0x03b8 => {
+        Name => 'ChromaticAberrationCorrParams',
+        Condition => '$$self{Model} =~ /^(ILCE-(6100|6400|6600|7C|7M3|7RM3|7RM4|9|9M2))/',
+        Format => 'int16s[32]',
+    },
+);
+
+# Tag9406 (ref JR)
+%Image::ExifTool::Sony::Tag9406 = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    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-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 => {
+        Name => 'BatteryTemperature',
+        ValueConv => '($val - 32) / 1.8', # convert to Celsius
+        ValueConvInv => '$val * 1.8 + 32',
+        PrintConv => 'sprintf("%.1f C",$val)',
+        PrintConvInv => '$val=~s/\s*C//; $val',
+    },
+    # 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',
+        RawConv => '$val ? $val : undef',   # only valid when not 0
+        PrintConv => '"$val%"',
+        PrintConvInv => '$val=~s/\s*\%//; $val',
+    },
+    # 0x0007: seen values from 8 - 105, decreasing in sequences of images: BatteryLevel
+    0x0007 => {
+        Name => 'BatteryLevel',
+        PrintConv => '"$val%"',
+        PrintConvInv => '$val=~s/\s*\%//; $val',
+    },
+    # 0x0008: usually 255 or 0 (ILCE-7/7R), seen other values only for A99V and ILCE-7/7R when 0x0006 not 0.
+    #         A99V with grip can have 3 batteries: => Grip 2;
+    #         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 => '$$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',
+    },
+#    0x0009-0x001a: looks like 9 Int16u values
+#    0x0022: 0 or 1 for A99, NEX-5R, 6
+#    0x0025: 0 or 1 for other SLT and NEX (0x0022, 0x0023, 0x0024 = 255)
+);
+
+# Tag940a (ref PH, decoded mainly from A77)
+%Image::ExifTool::Sony::Tag940a = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'These tags are currently extracted for SLT models only.',
+    # 0x00 - 10(A65,A77,NEX-5N,7,VG20E), 11(A37,A57,A99,NEX-5R,6,F3,RX1,RX100),
+    #        9(HX9V), 4,68,86,110(panoramas) - ref JR
+    0x04 => {
+        Name => 'AFPointsSelected',
+        Format => 'int32u',
+        PrintConvColumns => 2,
+        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)', # ILCA-68/77M2/99M2 always give this
+            0x00007801 => 'Center Zone',
+            0x0001821c => 'Right Zone',
+            0x000605c0 => 'Left Zone',
+            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 => {
+                0 => 'Center',          # (1.04 gave this for Upper-middle and Near Left)
+                1 => 'Top',             # (1.04 didn't give this value)
+                2 => 'Upper-right',     # (1.04 OK)
+                3 => 'Right',           # (1.04 didn't give this value)
+                4 => 'Lower-right',     # (1.04 gave this for Bottom)
+                5 => 'Bottom',          # (1.04 gave this for Lower-middle)
+                6 => 'Lower-left',      # (1.04 gave this for Left and Lower Far Left)
+                7 => 'Left',            # (1.04 gave this for Far Left)
+                8 => 'Upper-left',      # (1.04 OK)
+                9 => 'Far Right',       # (1.04 gave this for Upper Far Right and Right)
+                10 => 'Far Left',       # (1.04 didn't give this value)
+                11 => 'Upper-middle',   # (1.04 gave this for Top)
+                12 => 'Near Right',     # (1.04 gave this for Center)
+                13 => 'Lower-middle',   # (1.04 gave this for Lower-left and Near Right)
+                14 => 'Near Left',      # (1.04 didn't give this value)
+                15 => 'Upper Far Right',# (1.04 didn't give this value)
+                16 => 'Lower Far Right',# (1.04 OK, but gave this for Far Right and Lower-right too)
+                17 => 'Lower Far Left', # (1.04 didn't give this value)
+                18 => 'Upper Far Left', # (1.04 OK)
+                # higher bits may be used in panorama images - ref JR
+            },
+        },
+    },
+    # 0x0a - int16u: 0,1,2,3
+    # 0xa6 - 8 bytes face detection info ?; starts with 1, otherwise all 0
+);
+
+# Tag940c (ref JR)
+%Image::ExifTool::Sony::Tag940c = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    DATAMEMBER => [ 0x0008 ],
+    NOTES => 'NEX and ILCE models only.',
+
+    # 0x0001 - 0 for all NEX and ILCE-3000/3500, 20 for all other ILCE (17 for ILCE samples from Sony.net)
+    # 0x0008 - LensMount, but different values from Tag9405-0x0105 and Tag9050-0x0604.
+    # don't know what difference is between values '1' and '5' ...
+    0x0008 => {
+        Name => 'LensMount2', # ? maybe some other meaning ? (A-mount adapter-only images give 0)
+        RawConv => '$$self{LensMount} = $val',
+        PrintConv => {
+            0 => 'Unknown',     # LA-EA3 with non-SSM/SAM lens will often give this, not 1 or 5
+            1 => 'A-mount (1)',
+            4 => 'E-mount',
+            5 => 'A-mount (5)',
+        },
+    },
+    # 0x0009 - LensType3:
+    # This tag appears to also indicate adapter info, similar to CameraSettings3-0x03f7 for the original NEX-3/5.
+    # (Tag9405-0x0605 and Tag9050-0x0107 LensType2 always give '0' for adapters/A-mount lenses.)
+    # - seen a few instances of 0x0009 indicating an E-mount lens, but 0xb027 LensType indicating an A-mount lens:
+    #   possibly due to adapter info not being read/reset correctly ?
+    # August 2015: renamed from LensType2 into Lenstype3 because too often info here relates to previously-mounted-lens
+    0x0009 => {
+        Name => 'LensType3',
+        RawConv => '(($$self{LensMount} != 0) or ($val > 0 and $val < 32784)) ? $val : undef',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x000b => {
+        Name => 'CameraE-mountVersion',
+        Format => 'int16u',
+        PrintConv => 'sprintf("%x.%.2x",$val>>8,$val&0xff)',
+        PrintConvInv => 'my @a=split(/\./,$val);(hex($a[0])<<8)|hex($a[1])',
+        # E-mount versions seen for various cameras / camera-firmware versions:
+        # -   : info not present in CameraSettings3 for NEX-3/5/5C/C3/VG10E
+        # 1.14: NEX-5N/5R/6/7/F3/VG20E/VG30E/VG900 v1.00, NEX-5N v1.01, NEX-3N v0.90
+        # 1.20: NEX-3N v1.00, NEX-6 v1.01, NEX-7 v1.02, ILCE-3000 v1.00, ILCE-3500 v1.01
+        # 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, 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, ILCE-9 v1.00-v4.10
+        # 1.80: ILCE-6100/6400/6600/7RM4/9M2, ILCE-9 v5.00-v6.00
+    },
+    0x000d => {
+        Name => 'LensE-mountVersion',
+        Condition => '$$self{LensMount} != 0',
+        Format => 'int16u',
+        PrintConv => 'sprintf("%x.%.2x",$val>>8,$val&0xff)',
+        PrintConvInv => 'my @a=split(/\./,$val);(hex($a[0])<<8)|hex($a[1])',
+        # E-mount versions seen for various lens models:
+        # 0.00: Unknown lenses/adapters
+        # 1.00: SEL18200LE, Sigma DN, Tamron Di III, Zeiss Touit
+        # 1.07: (Ver.01) original E-lenses (SEL16F28, SEL18200, SEL1855, SEL24F18Z, SEL30M35, SEL50F18, SEL55210) and LA-EA1
+        # 1.08: LA-EA1 (Ver.02), Metabones Smart
+        # 1.14: LA-EA2
+        # 1.20: (Ver.02) firmware-updated E-lenses (SEL1855, SEL24F18Z, SEL30M35, SEL50F18, SEL55210),
+        #       newer E-lenses (SEL1018, SEL1670Z, SEL20F28, SEL35F18, SELP1650, SELP18105G, SELP18200) or LA-EA3 Ver.01
+        # 1.30: LA-EA4
+        # 1.31: original FE-lenses (SEL2470Z, SEL2870, SEL35F28Z, SEL55F18Z), SEL1850
+        # 1.35: SEL70200G, SEL55210 (Black?, seen with ILCE-3500)
+        # 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, 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,
+    #    0x0014 as 3-digit decimal: not confirmed sub-versions
+    #    Some versions as seen with this decoding:
+    #       00.nnn for several pre-production Sony E-mount lenses
+    #       01.000 - 01.009 for various Sony E-mount lenses
+    #       02.nnn, 03.nnn for various Sony E-mount lenses for which a Ver.02 or Ver.03 update is available
+    #       16.001 for Metabones Speed Booster
+    #       19/22/24/30/32/41.001 etc. for Metabones Canon EF Smart adapters
+    0x0014 => {
+        Name => 'LensFirmwareVersion',
+        Condition => '$$self{LensMount} != 0',
+        Format => 'int16u',
+        PrintConv => 'sprintf("Ver.%.2x.%.3d",$val>>8,$val&0xff)',
+    },
+    # 0x0016 - 0x003f: non-0 data present when: 0x0001>0 AND 0x0008=4(E-mount) AND 0x000f<255
+);
+
+
+# AFInfo 0x940e (SLT models only) (ref PH, decoded mainly from A77)
+%Image::ExifTool::Sony::AFInfo = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    WRITABLE => 1,
+    FIRST_ENTRY => 0,
+    PRIORITY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    DATAMEMBER => [ 0x02 ],
+    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
+    #   2 1 1 0  for A65V
+    #   2 1 2 0  for A77V
+    #   0 1 2 0  for A99V
+    #   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-6100/6300/6400/6500/6600/7C/7M3/7RM2/7RM3/7RM4/7SM2/9/9M2
+    #   9 . . .  for ILCE-7SM3
+    #   11 . . . for ILCE-1
+    #   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
+    0x02 => {
+        Name => 'AFType',
+        RawConv => '$$self{AFType} = $val',
+        PrintConv => {
+            # 0 => '?? n.a.', # seen on some A99V images with non-AF (Samyang) lens
+            1 => '15-point',
+            2 => '19-point',
+            3 => '79-point', # ILCA-68/77M2/99M2
+        },
+    },
+
+### decoding for SLT; ILCA-68/77M2/99M2 (AFType == 3) uses different offsets: see below
+
+    0x04 => {
+        Name => 'AFStatusActiveSensor',
+        Condition => '$$self{Model} !~ /^ILCA-/',
+        %Image::ExifTool::Minolta::afStatusInfo,
+    },
+    0x07 => [ # the active AF sensor
+        {
+            Name => 'AFPoint',
+            Condition => '$$self{AFType} == 1',
+            Notes => 'models with 15-point AF',
+            PrintConvColumns => 2,
+            PrintConv => \%afPoint15,
+        },{
+            Name => 'AFPoint',
+            Condition => '$$self{AFType} == 2',
+            Notes => 'models with 19-point AF',
+            PrintConvColumns => 2,
+            PrintConv => \%afPoint19,
+        },
+    ],
+    0x08 => [ # the AF sensor in focus at focus time (shutter release half press)
+        {
+            Name => 'AFPointInFocus',
+            Condition => '$$self{AFType} == 1',
+            Notes => 'models with 15-point AF',
+            PrintConvColumns => 2,
+            PrintConv => {
+                %afPoint15,
+                255 => '(none)',
+            },
+        },{
+            Name => 'AFPointInFocus',
+            Condition => '$$self{AFType} == 2',
+            Notes => 'models with 19-point AF',
+            PrintConvColumns => 2,
+            PrintConv => {
+                %afPoint19,
+                255 => '(none)',
+            },
+        },
+    ],
+    0x09 => [ # the AF sensor in focus at shutter release (shutter release full press)
+        {
+            Name => 'AFPointAtShutterRelease',
+            Condition => '$$self{AFType} == 1',
+            Notes => 'models with 15-point AF',
+            PrintConvColumns => 2,
+            PrintConv => {
+                %afPoint15,
+                30 => '(out of focus)',
+            },
+        },{
+            Name => 'AFPointAtShutterRelease',
+            Condition => '$$self{AFType} == 2',
+            Notes => 'models with 19-point AF',
+            PrintConvColumns => 2,
+            PrintConv => {
+                %afPoint19,
+                30 => '(out of focus)',
+            },
+        },
+    ],
+    0x0a => {
+        Name => 'AFAreaMode',
+        Condition => '$$self{Model} !~ /^ILCA-/',
+        PrintConv => {
+            0 => 'Wide',
+            1 => 'Spot',
+            2 => 'Local',
+            3 => 'Zone',
+        },
+    },
+    0x0b => {
+        Name => 'FocusMode',
+        Condition => '$$self{Model} !~ /^ILCA-/',
+        PrintConvColumns => 2,
+        # validated for A77 firmware 1.03, 1.04 and 1.07 and A99
+        # - not confirmed for A37,A57 and A65 which also write this tag
+        PrintConv => {
+            0 => 'Manual',
+            2 => 'AF-S',
+            3 => 'AF-C',
+            4 => 'AF-A',
+            6 => 'DMF',
+            7 => 'AF-D', # (unique to A99)
+        },
+    },
+    0x11 => [ #JR
+        {
+            Name => 'AFStatus15',
+            Condition => '$$self{AFType} == 1',
+            Format => 'int16s[18]',
+            SubDirectory => { TagTable => 'Image::ExifTool::Sony::AFStatus15' },
+        },{
+            Name => 'AFStatus19',
+            Condition => '$$self{AFType} == 2',
+            Format => 'int16s[30]',
+            SubDirectory => { TagTable => 'Image::ExifTool::Sony::AFStatus19' },
+        },
+    ],
+    # 0x004d - 18 or 30 int16 values
+    # 0x0089 - 18 or 30 int16 values
+    # 0x00b1 - 18 or 30 int16 values
+    # 0x0121 - 18 or 30 int16s values, similar to 0x11 AFStatus
+    # 0x016e - SLT: 4 bytes indicating 'AFPointsUsed', identical to first 4 bytes of 0x2020 for A58/A99V
+    0x016e => {
+        Name => 'AFPointsUsed',
+        Condition => '$$self{Model} !~ /^ILCA-/',
+        Notes => 'SLT models only',
+        Format => 'int32u',
+        PrintConvColumns => 2,
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => {
+                0 => 'Center',
+                1 => 'Top',
+                2 => 'Upper-right',
+                3 => 'Right',
+                4 => 'Lower-right',
+                5 => 'Bottom',
+                6 => 'Lower-left',
+                7 => 'Left',
+                8 => 'Upper-left',
+                9 => 'Far Right',
+                10 => 'Far Left',
+                11 => 'Upper-middle',
+                12 => 'Near Right',
+                13 => 'Lower-middle',
+                14 => 'Near Left',
+                15 => 'Upper Far Right',
+                16 => 'Lower Far Right',
+                17 => 'Lower Far Left',
+                18 => 'Upper Far Left',
+            },
+        },
+    },
+    # 0x017b: int16s: also has to do with AFMicroAdj: value equals -AFMA * 4 * MaxApertureValue (ref JR)
+    0x017d => { #PH (verified for the SLT-A77/A99; other SLT models don't have this setting - ref JR)
+        # (different from AFMicroAdjValue because it is 0 when the adjustment is off)
+        Name => 'AFMicroAdj',
+        Condition => '$$self{Model} !~ /^ILCA-/',
+        Format => 'int8s',
+    },
+    0x017e => { #JR
+        Name => 'ExposureProgram',
+        Condition => '$$self{Model} !~ /^ILCA-/',
+        Priority => 0,
+        SeparateTable => 'ExposureProgram3',
+        PrintConv => \%sonyExposureProgram3,
+    },
+    # 0x01b8 - 65 AF Info blocks of 180 bytes each for SLT (ref JR)
+    # In each block, the 9th, 10th and 11th byte appear to relate to AFPoint as at offsets 0x07, 0x08, 0x09 above..
+    # Possibly, these blocks relate to sequential focusing attempts and/or object tracking,
+    # the first byte being an Index or Counter.
+    # The last block before the block with index 0, appears to relate to the AF data at ShutterRelease.
+
+    # 0xf38,0x1208,0x14d8,0x158c,0x1640,(and more) - 0 if AFMicroAdj is On, 1 if Off
+    # 0x1ab6 - 0x80 if AFMicroAdj is On, 0 if Off
+    # tags also related to AFPoint (PH, A77):
+    #   0x11ec, 0x122a, 0x1408, 0x1446, 0x14bc, 0x1f86,
+    #   0x14fa, 0x1570, 0x1572, 0x15ae, 0x1f48
+
+### decoding for ILCA-68/77M2/99M2, AFType == 3
+
+    0x0005 => { #JR
+        Name => 'FocusMode',
+        Condition => '$$self{Model} =~ /^ILCA-/',
+        Notes => 'ILCA models only',
+        Writable => 'int8u',
+        Priority => 0,
+        PrintConv => {
+            0 => 'Manual',
+            2 => 'AF-S',
+            3 => 'AF-C',
+            4 => 'AF-A',
+            6 => 'DMF',
+            # 7 => 'AF-D', # not yet seen
+        },
+    },
+    # 0x0010 - for ILCA-68/77M2/99M2: 10 bytes identical to 0x2020, and probably indicating 'AFPointsUsed' (ref JR)
+    0x0010 => {
+        Name => 'AFPointsUsed',
+        Condition => '$$self{Model} =~ /^ILCA-/',
+        Format => 'int8u[10]',
+        BitsPerWord => 8,
+        BitsTotal => 80,
+        PrintConv => {
+            0 => '(none)',
+            BITMASK => { %afPoints79 },
+        },
+    },
+    # 0x0037, 0x0038, 0x0039 similar to 0x07, 0x08, 0x09, but using numbers from 0-94 for ILCA-68/77M2/99M2
+    0x0037 => { # the active AF sensor
+        Name => 'AFPoint',
+        Condition => '$$self{AFType} == 3',
+        PrintConv => {
+            %afPoints79_940e,
+            255 => '(none)',
+        },
+    },
+    0x0038 => { # the AF sensor in focus at focus time (shutter release half press)
+        Name => 'AFPointInFocus',
+        Condition => '$$self{AFType} == 3',
+        PrintConv => {
+            %afPoints79_940e,
+            255 => '(none)',
+        },
+    },
+    0x0039 => { # the AF sensor in focus at shutter release (shutter release full press)
+        Name => 'AFPointAtShutterRelease',
+        Condition => '$$self{AFType} == 3',
+        PrintConv => {
+            %afPoints79_940e,
+            95 => '(none)',
+        },
+    },
+    0x003a => { #JR
+        Name => 'AFAreaMode',
+        Condition => '$$self{Model} =~ /^ILCA-/',
+        PrintConv => {
+            0 => 'Wide',
+            1 => 'Center',
+            2 => 'Flexible Spot',
+            3 => 'Zone',
+            4 => 'Expanded Flexible Spot', #(NC)
+        },
+    },
+    0x003b => {
+        Name => 'AFStatusActiveSensor',
+        Condition => '$$self{Model} =~ /^ILCA-/',
+        %Image::ExifTool::Minolta::afStatusInfo,
+    },
+    0x0043 => {
+        Name => 'ExposureProgram',
+        Condition => '$$self{Model} =~ /^ILCA-/',
+        Priority => 0,
+        SeparateTable => 'ExposureProgram3',
+        PrintConv => \%sonyExposureProgram3,
+    },
+    # 0x004e: int16s: also has to do with AFMicroAdj: value equals -AFMA * 4 * MaxApertureValue (ref JR)
+    0x0050 => { #PH (ILCA-A77M2, to be confirmed for other ILCA models)
+        Name => 'AFMicroAdj',
+        Condition => '$$self{Model} =~ /^ILCA-/',
+        Format => 'int8s',
+    },
+    # 0x007d - AFStatus79 - 95 int16s values for the ILCA-68/77M2/99M2: 79 AF points + 15 cross + 1 F2.8
+    0x007d => {
+        Name => 'AFStatus79',
+        Condition => '$$self{AFType} == 3',
+        Format => 'int16s[95]',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::AFStatus79' },
+    },
+    # 0x013b - 95 int8u values
+    # 0x01ab - 95 int8u values
+    # 0x021b - 95 int16s values, similar to 0x007d AFStatus79, but not sure if this is valid for ILCA-99M2
+    # 0x04c0 - 45 AF Info blocks of 244 bytes each for ILCA-68/77M2
+    # 0x12a0 - 30 AF Info blocks of 244 bytes each for ILCA-99M2
+);
+
+%Image::ExifTool::Sony::Tag940e = ( #JR
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    NOTES => 'E-mount models.',
+
+    # (see comment in AFInfo for deciphered values of first 4 bytes for various models)
+
+    # 0x0004 - if 0x0001 == 2: LA-EA2/EA4 15-point SLT Phase-detect AF adapter used:
+    #          start of 164-byte AF Info Blocks, possibly the 11th byte might be the AFPoint.
+    #          ILCE-7M2/7RM2/7SM2: 40 Blocks of 164 bytes
+    #          other NEX/ILCE: 74 blocks of 164 bytes
+
+    # 0x1a06 onwards - first seen for ILCE-7RM2: appears to be some kind of metering image
+    # 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/ 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
+            16-bit TIFF image
+        },
+        ValueConv => sub {
+            my ($val, $et) = @_;
+            return undef unless length $val >= 2640;
+            return \ "Binary data 2640 bytes" unless $et->Options('Binary');
+            my @dat = unpack('v*', $val);
+            # TIFF header for a 16-bit RGB 10dpi 44x30 image
+            $val = Image::ExifTool::MakeTiffHeader(44,30,3,16,10);
+            # re-order data to RGB pixels - use same value for R, G and B
+            my ($i, @val);
+            for ($i=0; $i<44*30; ++$i) {
+                # data is 13-bit (max 8191), shift left to fill 16 bits
+                push @val, int(5041.1*log($dat[$i]+1)/log(2)), int(5041.1*log($dat[$i]+1)/log(2)), int(5041.1*log($dat[$i]+1)/log(2));
+            }
+            $val .= pack('v*', @val);   # add TIFF strip data
+            return \$val;
+        },
+    },
+);
+
+# AF Point Status (ref JR)
+%Image::ExifTool::Sony::AFStatus15 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'AF Status information for models with 15-point AF.',
+    0x00 => { Name => 'AFStatusUpper-left',           %Image::ExifTool::Minolta::afStatusInfo },
+    0x02 => { Name => 'AFStatusLeft',                 %Image::ExifTool::Minolta::afStatusInfo },
+    0x04 => { Name => 'AFStatusLower-left',           %Image::ExifTool::Minolta::afStatusInfo },
+    0x06 => { Name => 'AFStatusFarLeft',              %Image::ExifTool::Minolta::afStatusInfo },
+    0x08 => { Name => 'AFStatusTopHorizontal',        %Image::ExifTool::Minolta::afStatusInfo },
+    0x0a => { Name => 'AFStatusNearRight',            %Image::ExifTool::Minolta::afStatusInfo },
+    0x0c => { Name => 'AFStatusCenterHorizontal',     %Image::ExifTool::Minolta::afStatusInfo },
+    0x0e => { Name => 'AFStatusNearLeft',             %Image::ExifTool::Minolta::afStatusInfo },
+    0x10 => { Name => 'AFStatusBottomHorizontal',     %Image::ExifTool::Minolta::afStatusInfo },
+    0x12 => { Name => 'AFStatusTopVertical',          %Image::ExifTool::Minolta::afStatusInfo },
+    0x14 => { Name => 'AFStatusCenterVertical',       %Image::ExifTool::Minolta::afStatusInfo },
+    0x16 => { Name => 'AFStatusBottomVertical',       %Image::ExifTool::Minolta::afStatusInfo },
+    0x18 => { Name => 'AFStatusFarRight',             %Image::ExifTool::Minolta::afStatusInfo },
+    0x1a => { Name => 'AFStatusUpper-right',          %Image::ExifTool::Minolta::afStatusInfo },
+    0x1c => { Name => 'AFStatusRight',                %Image::ExifTool::Minolta::afStatusInfo },
+    0x1e => { Name => 'AFStatusLower-right',          %Image::ExifTool::Minolta::afStatusInfo },
+    0x20 => { Name => 'AFStatusUpper-middle',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x22 => { Name => 'AFStatusLower-middle',         %Image::ExifTool::Minolta::afStatusInfo },
+);
+
+# AF Point Status (ref JR)
+%Image::ExifTool::Sony::AFStatus19 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'AF Status information for models with 19-point AF.',
+    0x00 => { Name => 'AFStatusUpperFarLeft',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x02 => { Name => 'AFStatusUpper-leftHorizontal', %Image::ExifTool::Minolta::afStatusInfo },
+    0x04 => { Name => 'AFStatusFarLeftHorizontal',    %Image::ExifTool::Minolta::afStatusInfo },
+    0x06 => { Name => 'AFStatusLeftHorizontal',       %Image::ExifTool::Minolta::afStatusInfo },
+    0x08 => { Name => 'AFStatusLowerFarLeft',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x0a => { Name => 'AFStatusLower-leftHorizontal', %Image::ExifTool::Minolta::afStatusInfo },
+    0x0c => { Name => 'AFStatusUpper-leftVertical',   %Image::ExifTool::Minolta::afStatusInfo },
+    0x0e => { Name => 'AFStatusLeftVertical',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x10 => { Name => 'AFStatusLower-leftVertical',   %Image::ExifTool::Minolta::afStatusInfo },
+    0x12 => { Name => 'AFStatusFarLeftVertical',      %Image::ExifTool::Minolta::afStatusInfo },
+    0x14 => { Name => 'AFStatusTopHorizontal',        %Image::ExifTool::Minolta::afStatusInfo },
+    0x16 => { Name => 'AFStatusNearRight',            %Image::ExifTool::Minolta::afStatusInfo },
+    0x18 => { Name => 'AFStatusCenterHorizontal',     %Image::ExifTool::Minolta::afStatusInfo },
+    0x1a => { Name => 'AFStatusNearLeft',             %Image::ExifTool::Minolta::afStatusInfo },
+    0x1c => { Name => 'AFStatusBottomHorizontal',     %Image::ExifTool::Minolta::afStatusInfo },
+    0x1e => { Name => 'AFStatusTopVertical',          %Image::ExifTool::Minolta::afStatusInfo },
+    0x20 => { Name => 'AFStatusUpper-middle',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x22 => { Name => 'AFStatusCenterVertical',       %Image::ExifTool::Minolta::afStatusInfo },
+    0x24 => { Name => 'AFStatusLower-middle',         %Image::ExifTool::Minolta::afStatusInfo },
+    0x26 => { Name => 'AFStatusBottomVertical',       %Image::ExifTool::Minolta::afStatusInfo },
+    0x28 => { Name => 'AFStatusUpperFarRight',        %Image::ExifTool::Minolta::afStatusInfo },
+    0x2a => { Name => 'AFStatusUpper-rightHorizontal',%Image::ExifTool::Minolta::afStatusInfo },
+    0x2c => { Name => 'AFStatusFarRightHorizontal',   %Image::ExifTool::Minolta::afStatusInfo },
+    0x2e => { Name => 'AFStatusRightHorizontal',      %Image::ExifTool::Minolta::afStatusInfo },
+    0x30 => { Name => 'AFStatusLowerFarRight',        %Image::ExifTool::Minolta::afStatusInfo },
+    0x32 => { Name => 'AFStatusLower-rightHorizontal',%Image::ExifTool::Minolta::afStatusInfo },
+    0x34 => { Name => 'AFStatusFarRightVertical',     %Image::ExifTool::Minolta::afStatusInfo },
+    0x36 => { Name => 'AFStatusUpper-rightVertical',  %Image::ExifTool::Minolta::afStatusInfo },
+    0x38 => { Name => 'AFStatusRightVertical',        %Image::ExifTool::Minolta::afStatusInfo },
+    0x3a => { Name => 'AFStatusLower-rightVertical',  %Image::ExifTool::Minolta::afStatusInfo },
+);
+
+# AF Point Status (ref JR)
+%Image::ExifTool::Sony::AFStatus79 = (
+    %binaryDataAttrs,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => 'AF Status information for models with 79-point AF.',
+#
+# ILCA-68/77M2 AF sensor layout:
+#                           A5*  A6*  A7*
+#         B2   B3   B4      B5   B6   B7      B8   B9   B10
+#    C1   C2   C3   C4      C5*  C6*  C7*     C8   C9   C10   C11
+#    D1   D2   D3   D4      D5   D6   D7      D8   D9   D10   D11
+#    E1   E2   E3   E4      E5*  E6*  E7*     E8   E9   E10   E11
+#    F1   F2   F3   F4      F5   F6   F7      F8   F9   F10   F11
+#    G1   G2   G3   G4      G5*  G6*  G7*     G8   G9   G10   G11
+#         H2   H3   H4      H5   H6   H7      H8   H9   H10
+#                           I5*  I6*  I7*
+# left section, from top to bottom, from right to left
+    0x00 => { Name => 'AFStatus_00_B4', %Image::ExifTool::Minolta::afStatusInfo },
+    0x02 => { Name => 'AFStatus_01_C4', %Image::ExifTool::Minolta::afStatusInfo },
+    0x04 => { Name => 'AFStatus_02_D4', %Image::ExifTool::Minolta::afStatusInfo },
+    0x06 => { Name => 'AFStatus_03_E4', %Image::ExifTool::Minolta::afStatusInfo },
+    0x08 => { Name => 'AFStatus_04_F4', %Image::ExifTool::Minolta::afStatusInfo },
+    0x0a => { Name => 'AFStatus_05_G4', %Image::ExifTool::Minolta::afStatusInfo },
+    0x0c => { Name => 'AFStatus_06_H4', %Image::ExifTool::Minolta::afStatusInfo },
+    0x0e => { Name => 'AFStatus_07_B3', %Image::ExifTool::Minolta::afStatusInfo },
+    0x10 => { Name => 'AFStatus_08_C3', %Image::ExifTool::Minolta::afStatusInfo },
+    0x12 => { Name => 'AFStatus_09_D3', %Image::ExifTool::Minolta::afStatusInfo },
+    0x14 => { Name => 'AFStatus_10_E3', %Image::ExifTool::Minolta::afStatusInfo },
+    0x16 => { Name => 'AFStatus_11_F3', %Image::ExifTool::Minolta::afStatusInfo },
+    0x18 => { Name => 'AFStatus_12_G3', %Image::ExifTool::Minolta::afStatusInfo },
+    0x1a => { Name => 'AFStatus_13_H3', %Image::ExifTool::Minolta::afStatusInfo },
+    0x1c => { Name => 'AFStatus_14_B2', %Image::ExifTool::Minolta::afStatusInfo },
+    0x1e => { Name => 'AFStatus_15_C2', %Image::ExifTool::Minolta::afStatusInfo },
+    0x20 => { Name => 'AFStatus_16_D2', %Image::ExifTool::Minolta::afStatusInfo },
+    0x22 => { Name => 'AFStatus_17_E2', %Image::ExifTool::Minolta::afStatusInfo },
+    0x24 => { Name => 'AFStatus_18_F2', %Image::ExifTool::Minolta::afStatusInfo },
+    0x26 => { Name => 'AFStatus_19_G2', %Image::ExifTool::Minolta::afStatusInfo },
+    0x28 => { Name => 'AFStatus_20_H2', %Image::ExifTool::Minolta::afStatusInfo },
+    0x2a => { Name => 'AFStatus_21_C1', %Image::ExifTool::Minolta::afStatusInfo },
+    0x2c => { Name => 'AFStatus_22_D1', %Image::ExifTool::Minolta::afStatusInfo },
+    0x2e => { Name => 'AFStatus_23_E1', %Image::ExifTool::Minolta::afStatusInfo },
+    0x30 => { Name => 'AFStatus_24_F1', %Image::ExifTool::Minolta::afStatusInfo },
+    0x32 => { Name => 'AFStatus_25_G1', %Image::ExifTool::Minolta::afStatusInfo },
+# center section, cross-sensors *, from right to left, from top to bottom
+# These are presumably Vertical, as all others are default Horizontal (ref Sony ILCA-77M2 brochure).
+    0x34 => { Name => 'AFStatus_26_A7_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x36 => { Name => 'AFStatus_27_A6_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x38 => { Name => 'AFStatus_28_A5_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x3a => { Name => 'AFStatus_29_C7_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x3c => { Name => 'AFStatus_30_C6_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x3e => { Name => 'AFStatus_31_C5_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x40 => { Name => 'AFStatus_32_E7_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x42 => { Name => 'AFStatus_33_E6_Center_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x44 => { Name => 'AFStatus_34_E5_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x46 => { Name => 'AFStatus_35_G7_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x48 => { Name => 'AFStatus_36_G6_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x4a => { Name => 'AFStatus_37_G5_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x4c => { Name => 'AFStatus_38_I7_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x4e => { Name => 'AFStatus_39_I6_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+    0x50 => { Name => 'AFStatus_40_I5_Vertical', %Image::ExifTool::Minolta::afStatusInfo },
+# center section, all sensors, from top to bottom, from right to left
+    0x52 => { Name => 'AFStatus_41_A7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x54 => { Name => 'AFStatus_42_B7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x56 => { Name => 'AFStatus_43_C7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x58 => { Name => 'AFStatus_44_D7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x5a => { Name => 'AFStatus_45_E7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x5c => { Name => 'AFStatus_46_F7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x5e => { Name => 'AFStatus_47_G7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x60 => { Name => 'AFStatus_48_H7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x62 => { Name => 'AFStatus_49_I7', %Image::ExifTool::Minolta::afStatusInfo },
+    0x64 => { Name => 'AFStatus_50_A6', %Image::ExifTool::Minolta::afStatusInfo },
+    0x66 => { Name => 'AFStatus_51_B6', %Image::ExifTool::Minolta::afStatusInfo },
+    0x68 => { Name => 'AFStatus_52_C6', %Image::ExifTool::Minolta::afStatusInfo },
+    0x6a => { Name => 'AFStatus_53_D6', %Image::ExifTool::Minolta::afStatusInfo },
+    0x6c => { Name => 'AFStatus_54_E6_Center', %Image::ExifTool::Minolta::afStatusInfo },
+    0x6e => { Name => 'AFStatus_55_F6', %Image::ExifTool::Minolta::afStatusInfo },
+    0x70 => { Name => 'AFStatus_56_G6', %Image::ExifTool::Minolta::afStatusInfo },
+    0x72 => { Name => 'AFStatus_57_H6', %Image::ExifTool::Minolta::afStatusInfo },
+    0x74 => { Name => 'AFStatus_58_I6', %Image::ExifTool::Minolta::afStatusInfo },
+    0x76 => { Name => 'AFStatus_59_A5', %Image::ExifTool::Minolta::afStatusInfo },
+    0x78 => { Name => 'AFStatus_60_B5', %Image::ExifTool::Minolta::afStatusInfo },
+    0x7a => { Name => 'AFStatus_61_C5', %Image::ExifTool::Minolta::afStatusInfo },
+    0x7c => { Name => 'AFStatus_62_D5', %Image::ExifTool::Minolta::afStatusInfo },
+    0x7e => { Name => 'AFStatus_63_E5', %Image::ExifTool::Minolta::afStatusInfo },
+    0x80 => { Name => 'AFStatus_64_F5', %Image::ExifTool::Minolta::afStatusInfo },
+    0x82 => { Name => 'AFStatus_65_G5', %Image::ExifTool::Minolta::afStatusInfo },
+    0x84 => { Name => 'AFStatus_66_H5', %Image::ExifTool::Minolta::afStatusInfo },
+    0x86 => { Name => 'AFStatus_67_I5', %Image::ExifTool::Minolta::afStatusInfo },
+# right section, from top to bottom, from right to left
+    0x88 => { Name => 'AFStatus_68_C11', %Image::ExifTool::Minolta::afStatusInfo },
+    0x8a => { Name => 'AFStatus_69_D11', %Image::ExifTool::Minolta::afStatusInfo },
+    0x8c => { Name => 'AFStatus_70_E11', %Image::ExifTool::Minolta::afStatusInfo },
+    0x8e => { Name => 'AFStatus_71_F11', %Image::ExifTool::Minolta::afStatusInfo },
+    0x90 => { Name => 'AFStatus_72_G11', %Image::ExifTool::Minolta::afStatusInfo },
+    0x92 => { Name => 'AFStatus_73_B10', %Image::ExifTool::Minolta::afStatusInfo },
+    0x94 => { Name => 'AFStatus_74_C10', %Image::ExifTool::Minolta::afStatusInfo },
+    0x96 => { Name => 'AFStatus_75_D10', %Image::ExifTool::Minolta::afStatusInfo },
+    0x98 => { Name => 'AFStatus_76_E10', %Image::ExifTool::Minolta::afStatusInfo },
+    0x9a => { Name => 'AFStatus_77_F10', %Image::ExifTool::Minolta::afStatusInfo },
+    0x9c => { Name => 'AFStatus_78_G10', %Image::ExifTool::Minolta::afStatusInfo },
+    0x9e => { Name => 'AFStatus_79_H10', %Image::ExifTool::Minolta::afStatusInfo },
+    0xa0 => { Name => 'AFStatus_80_B9', %Image::ExifTool::Minolta::afStatusInfo },
+    0xa2 => { Name => 'AFStatus_81_C9', %Image::ExifTool::Minolta::afStatusInfo },
+    0xa4 => { Name => 'AFStatus_82_D9', %Image::ExifTool::Minolta::afStatusInfo },
+    0xa6 => { Name => 'AFStatus_83_E9', %Image::ExifTool::Minolta::afStatusInfo },
+    0xa8 => { Name => 'AFStatus_84_F9', %Image::ExifTool::Minolta::afStatusInfo },
+    0xaa => { Name => 'AFStatus_85_G9', %Image::ExifTool::Minolta::afStatusInfo },
+    0xac => { Name => 'AFStatus_86_H9', %Image::ExifTool::Minolta::afStatusInfo },
+    0xae => { Name => 'AFStatus_87_B8', %Image::ExifTool::Minolta::afStatusInfo },
+    0xb0 => { Name => 'AFStatus_88_C8', %Image::ExifTool::Minolta::afStatusInfo },
+    0xb2 => { Name => 'AFStatus_89_D8', %Image::ExifTool::Minolta::afStatusInfo },
+    0xb4 => { Name => 'AFStatus_90_E8', %Image::ExifTool::Minolta::afStatusInfo },
+    0xb6 => { Name => 'AFStatus_91_F8', %Image::ExifTool::Minolta::afStatusInfo },
+    0xb8 => { Name => 'AFStatus_92_G8', %Image::ExifTool::Minolta::afStatusInfo },
+    0xba => { Name => 'AFStatus_93_H8', %Image::ExifTool::Minolta::afStatusInfo },
+# central F2.8 sensor
+    0xbc => { Name => 'AFStatus_94_E6_Center_F2-8', %Image::ExifTool::Minolta::afStatusInfo },
+);
+
+# tag 0x9416 decoding (ref JR)
+%Image::ExifTool::Sony::Tag9416 = (
+    PROCESS_PROC => \&ProcessEnciphered,
+    WRITE_PROC => \&WriteEnciphered,
+    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
+    FORMAT => 'int8u',
+    NOTES => 'Valid for the ILCE-1/7SM3.',
+    FIRST_ENTRY => 0,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+    0x0000 => { Name => 'Tag9416_0000', PrintConv => 'sprintf("%3d",$val)', RawConv => '$$self{TagVersion} = $val' },
+    0x0004 => {
+        Name => 'SonyISO',
+        Format => 'int16u',
+        ValueConv => '100 * 2**(16 - $val/256)',
+        ValueConvInv => '256 * (16 - log($val/100)/log(2))',
+        PrintConv => 'sprintf("%.0f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0006 => { %gain2010 },
+    0x000a => { # appr. same value as Exif ExposureTime, but shorter in HDR-modes
+        Name => 'SonyExposureTime2',
+        Format => 'int16u',
+        ValueConv => '$val ? 2 ** (16 - $val/256) : 0',
+        ValueConvInv => '$val ? int((16 - log($val) / log(2)) * 256 + 0.5) : 0',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"',
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : Image::ExifTool::Exif::ConvertFraction($val)',
+    },
+    0x000c => {
+        Name => 'ExposureTime',
+        Format => 'rational32u',
+        PrintConv => '$val ? Image::ExifTool::Exif::PrintExposureTime($val) : "Bulb"', # (Bulb NC)
+        PrintConvInv => 'lc($val) eq "bulb" ? 0 : $val',
+    },
+    0x0010 => { # but sometimes deviating results
+        Name => 'SonyFNumber2',
+        Format => 'int16u',
+        ValueConv => '2 ** (($val/256 - 16) / 2)',
+        ValueConvInv => '(log($val)*2/log(2)+16)*256',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x0012 => {
+        Name => 'SonyMaxApertureValue', # (at current focal length)
+        Format => 'int16u',
+        ValueConv => '2 ** (($val/256 - 16) / 2)',
+        ValueConvInv => '(log($val)*2/log(2)+16)*256',
+        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConvInv => '$val',
+    },
+    0x001d => { %sequenceImageNumber },
+    0x0035 => {
+        Name => 'ExposureProgram',
+        Priority => 0,
+        SeparateTable => 'ExposureProgram3',
+        PrintConv => \%sonyExposureProgram3,
+    },
+    0x0048 => {
+        Name => 'LensMount',
+        Condition => '$$self{Model} !~ /^(DSC-)/',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+            3 => 'A-mount (3)',
+        },
+    },
+    0x0049 => {
+        Name => 'LensFormat',
+        Condition => '$$self{Model} !~ /^(DSC-)/',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'APS-C',
+            2 => 'Full-frame',
+        },
+    },
+    0x004a => {
+        Name => 'LensMount',
+        DataMember => 'LensMount',
+        RawConv => '$$self{LensMount} = $val; $$self{Model} =~ /^(DSC-)/ ? undef : $val',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'A-mount',
+            2 => 'E-mount',
+        },
+    },
+    0x004b => {
+        Name => 'LensType2',
+        Condition => '$$self{LensMount} == 2',
+        Format => 'int16u',
+        SeparateTable => 'LensType2',
+        PrintConv => \%sonyLensTypes2,
+    },
+    0x004d => {
+        Name => 'LensType',
+        Condition => '$$self{LensMount} == 1',
+        Priority => 0, #PH (just to be safe)
+        Format => 'int16u', #PH
+        SeparateTable => 1,
+        ValueConvInv => '($val & 0xff00) == 0x8000 ? 0 : int($val)',
+        PrintConv => \%sonyLensTypes,
+    },
+    0x004f => {
+        Name => 'DistortionCorrParams',
+        Format => 'int16s[16]',
+    },
+    0x0070 => { %pictureProfile2010 }, #IB
+    0x0071 => {
+        Name => 'FocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x0073 => {
+        Name => 'MinFocalLength',
+        Format => 'int16u',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x0075 => { # may give 0 for fixed focal length lenses
+        Name => 'MaxFocalLength',
+        Format => 'int16u',
+        RawConv => '$val || undef',
+        ValueConv => '$val / 10',
+        ValueConvInv => '$val * 10',
+        PrintConv => 'sprintf("%.1f mm",$val)',
+        PrintConvInv => '$val =~ s/ ?mm//; $val',
+    },
+    0x088f => {
+        Name => 'VignettingCorrParams',
+        Format => 'int16s[16]',
+    },
+    0x0914 => {
+        Name => 'ChromaticAberrationCorrParams',
+        Format => 'int16s[32]',
+    },
+);
+
 %Image::ExifTool::Sony::FaceInfo1 = (
     %binaryDataAttrs,
@@ -1122,9 +9555,9 @@
         Name => 'Face1Position',
         Format => 'int16u[4]',
-        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
         Notes => q{
             top, left, height and width of detected face.  Coordinates are relative to
             the full-sized unrotated image, with increasing Y downwards
         },
+        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
     },
     0x20 => {
@@ -1171,9 +9604,9 @@
         Name => 'Face1Position',
         Format => 'int16u[4]',
-        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
         Notes => q{
             top, left, height and width of detected face.  Coordinates are relative to
             the full-sized unrotated image, with increasing Y downwards
         },
+        RawConv => '$$self{FacesDetected} < 1 ? undef : $val',
     },
     0x25 => {
@@ -1220,19 +9653,19 @@
     FORMAT => 'int32u',
     NOTES => q{
-        Tags found only in panorama images from Sony cameras such as the HX1, HX5
-        and TX7.  The width/height values of these tags are not affected by camera
+        Tags found in panorama images from various Sony DSC, NEX, SLT and DSLR
+        cameras.  The width/height values of these tags are not affected by camera
         rotation -- the width is always the longer dimension.
     },
-    # 0: 257
-    1 => 'PanoramaFullWidth', # (including black/grey borders)
+    # 0: 257 for panorama images, 0 for all other images (ref JR)
+    1 => 'PanoramaFullWidth', # (including black/gray borders)
     2 => 'PanoramaFullHeight',
     3 => {
         Name => 'PanoramaDirection',
         PrintConv => {
-            0 => 'Right to Left',
-            1 => 'Left to Right',
-        },
-    },
-    # crop area to remove black/grey borders from full image
+            0 => 'Left or Up',
+            1 => 'Right or Down',
+        },
+    },
+    # crop area to remove black/gray borders from full image
     4 => 'PanoramaCropLeft',
     5 => 'PanoramaCropTop', #PH guess (NC)
@@ -1266,10 +9699,10 @@
         Name => 'SRF2Key',
         Notes => 'key to decrypt maker notes from the start of SRF2',
-        RawConv => '$self->{SRF2Key} = $val',
+        RawConv => '$$self{SRF2Key} = $val',
     },
     1 => {
         Name => 'DataKey',
         Notes => 'key to decrypt the rest of the file from the end of the maker notes',
-        RawConv => '$self->{SRFDataKey} = $val',
+        RawConv => '$$self{SRFDataKey} = $val',
     },
     # SRF0 contains a single unknown tag with TagID 0x0003
@@ -1287,4 +9720,32 @@
     4 => { Name => 'RawDataOffset' }, #PH
     5 => { Name => 'RawDataLength' }, #PH
+    0x0043 => 'MaxApertureAtMaxFocal', #IB
+    0x0044 => 'MaxApertureAtMinFocal', #IB
+    0x0045 => { #IB
+        Name => 'MinFocalLength',
+        PrintConv => '"$val mm"',
+    },
+    0x0046 => { #IB
+        Name => 'MaxFocalLength',
+        PrintConv => '"$val mm"',
+    },
+    0x00c0 => 'WBRedDaylight', #IB
+    0x00c1 => 'WBGreenDaylight', #IB
+    0x00c2 => 'WBBlueDaylight', #IB
+    0x00c3 => 'WBRedCloudy', #IB
+    0x00c4 => 'WBGreenCloudy', #IB
+    0x00c5 => 'WBBlueCloudy', #IB
+    0x00c6 => 'WBRedFluorescent', #IB
+    0x00c7 => 'WBGreenFluorescent', #IB
+    0x00c8 => 'WBBlueFluorescent', #IB
+    0x00c9 => 'WBRedTungsten', #IB
+    0x00ca => 'WBGreenTungsten', #IB
+    0x00cb => 'WBBlueTungsten', #IB
+    0x00cc => 'WBRedFlash', #IB
+    0x00cd => 'WBGreenFlash', #IB
+    0x00ce => 'WBBlueFlash', #IB
+    0x00d0 => 'WBRedAsShot', #IB
+    0x00d1 => 'WBGreenAsShot', #IB
+    0x00d2 => 'WBBlueAsShot', #IB
 );
 
@@ -1363,5 +9824,26 @@
     SET_GROUP1 => 1, # set group1 name to directory name for all tags in table
     NOTES => 'Tags in the encrypted SR2SubIFD',
-    0x7303 => 'WB_GRBGLevels', #1
+    0x7300 => 'BlackLevel', #IB (R1)
+    0x7302 => 'WB_GRBGLevelsAuto', #IB (R1)
+    0x7303 => 'WB_GRBGLevels', #1 (R1 "as shot", ref IB)
+    0x7310 => 'BlackLevel', #IB (divide by 4)
+    0x7312 => 'WB_RGGBLevelsAuto', #IB
+    0x7313 => 'WB_RGGBLevels', #6
+    0x7480 => 'WB_RGBLevelsDaylight', #IB (R1)
+    0x7481 => 'WB_RGBLevelsCloudy', #IB (R1)
+    0x7482 => 'WB_RGBLevelsTungsten', #IB (R1)
+    0x7483 => 'WB_RGBLevelsFlash', #IB (R1)
+    0x7484 => 'WB_RGBLevels4500K', #IB (R1)
+    0x7486 => 'WB_RGBLevelsFluorescent', #IB (R1)
+    0x74a0 => 'MaxApertureAtMaxFocal', #PH
+    0x74a1 => 'MaxApertureAtMinFocal', #PH
+    0x74a2 => { #IB (R1)
+        Name => 'MaxFocalLength',
+        PrintConv => '"$val mm"',
+    },
+    0x74a3 => { #IB (R1)
+        Name => 'MinFocalLength',
+        PrintConv => '"$val mm"',
+    },
     0x74c0 => { #PH
         Name => 'SR2DataIFD',
@@ -1374,13 +9856,23 @@
         },
     },
-    0x7313 => 'WB_RGGBLevels', #6
-    0x74a0 => 'MaxApertureAtMaxFocal', #PH
-    0x74a1 => 'MaxApertureAtMinFocal', #PH
-    0x7820 => 'WB_RGBLevelsDaylight', #6
-    0x7821 => 'WB_RGBLevelsCloudy', #6
+    0x7800 => 'ColorMatrix', #IB (divide by 1024)
+    0x7820 => 'WB_RGBLevelsDaylight', #6 (or 5300K, ref IB)
+    0x7821 => 'WB_RGBLevelsCloudy', #6 (or 6100K, ref IB)
     0x7822 => 'WB_RGBLevelsTungsten', #6
-    0x7825 => 'WB_RGBLevelsShade', #6
-    0x7826 => 'WB_RGBLevelsFluorescent', #6
-    0x7828 => 'WB_RGBLevelsFlash', #6
+    0x7823 => 'WB_RGBLevelsFlash', #IB
+    0x7824 => 'WB_RGBLevels4500K', #IB
+    0x7825 => 'WB_RGBLevelsShade', #6 (or 7500K, ref IB)
+    0x7826 => 'WB_RGBLevelsFluorescent', #6 (~4000K)
+    0x7827 => 'WB_RGBLevelsFluorescentP1', #IB (~5000K)
+    0x7828 => 'WB_RGBLevelsFluorescentP2', #IB (~6500K) (was Flash, ref 6)
+    0x7829 => 'WB_RGBLevelsFluorescentM1', #IB (~3500K)
+    0x782a => 'WB_RGBLevels8500K', #IB
+    0x782b => 'WB_RGBLevels6000K', #IB
+    0x782c => 'WB_RGBLevels3200K', #IB
+    0x782d => 'WB_RGBLevels2500K', #IB
+    0x787f => 'WhiteLevel', #IB (divide by 4)
+    0x797d => 'VignettingCorrParams', #forum7640
+    0x7980 => 'ChromaticAberrationCorrParams', #forum6509 (Sony A7 ARW)
+    0x7982 => 'DistortionCorrParams', #forum6509 (Sony A7 ARW)
 );
 
@@ -1397,9 +9889,48 @@
 );
 
+# extract information from "SONY PIC\0" maker notes (ref PH)
+%Image::ExifTool::Sony::PIC = (
+    PROCESS_PROC => \&ProcessSonyPIC,
+    GROUPS => { 0 => 'MakerNotes', 2 => 'Camera' },
+    NOTES => q{
+        The TextInfo data is extracted as a block to preserve the formatting, and
+        some of the more interesting information is extracted as separate tags.
+    },
+    TextInfo1 => { Binary => 1 },
+    TextInfo2 => { Binary => 1 },
+    # tags extracted from TextInfo blocks (ID's must end with ':')
+    'Temp:' => {
+        Name => 'CameraTemperature',
+        RawConv => '$val =~ /^-?\d+/ ? $val : undef',
+        PrintConv => '"$val C"',
+    },
+    'Temp:Clbt:' => { Name => 'BoardTemperature', PrintConv => '"$val C"' }, #(NC)
+    'Capt:' => { Name => 'SensorTemperature', PrintConv => '"$val C"' }, #(NC)
+    'VR Enable C:' => {
+        Name => 'VibrationReduction',
+        PrintConv => { 0 => 'Off', 1 => 'On' }, #(NC)
+    },
+    'FWVer:' => 'FirmwareVersion',
+    'BC:' => {
+        Name => 'Barcode',
+        Condition => 'not $$self{VALUE}{Barcode}',
+        ValueConv => '$val=~s/IP1.*//; $val',
+    },
+    'barcode:' => 'Barcode',
+    'BarCode:' => {
+        Name => 'Barcode',
+        ValueConv => 'length($val) > 12 ? substr($val,0,12) : $val',
+    },
+    # 'EvA:' - exposure compensation * 10 (ref JR)
+    # IFD: for documentation only -- this IFD is handled manually
+    IFD => {
+        Name => 'PIC_IFD',
+        SubDirectory => { TagTable => 'Image::ExifTool::Sony::Main' },
+    },
+);
+
 # tags found in DSC-F1 PMP header (ref 10)
 %Image::ExifTool::Sony::PMP = (
     PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
-    WRITE_PROC => \&Image::ExifTool::WriteBinaryData,
-    CHECK_PROC => \&Image::ExifTool::CheckBinaryData,
     GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
     FIRST_ENTRY => 0,
@@ -1416,7 +9947,7 @@
         },
     },
-    12 => { Name => 'JpgFromRawLength',Format => 'int32u' },
-    22 => { Name => 'SonyImageWidth',  Format => 'int16u' },
-    24 => { Name => 'SonyImageHeight', Format => 'int16u' },
+    12 => { Name => 'JpgFromRawLength', Format => 'int32u' },
+    22 => { Name => 'SonyImageWidth',   Format => 'int16u' },
+    24 => { Name => 'SonyImageHeight',  Format => 'int16u' },
     27 => {
         Name => 'Orientation',
@@ -1496,13 +10027,189 @@
 );
 
+# tags found in 'rtmd' timed metadata in ILCE-7S/DSC-RX100M6 MP4 videos (ref PH)
+%Image::ExifTool::Sony::rtmd = (
+    PROCESS_PROC => \&Process_rtmd,
+    GROUPS => { 2 => 'Video' },
+    NOTES => q{
+        These tags are extracted from the 'rtmd' timed metadata of MP4 videos from
+        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 },
+  # 0x32xx - 16 bytes starting with 0x060e2b340401
+    0x3210 => { Name => 'Sony_rtmd_0x3210', Format => 'int8u',  %hidUnk },
+    0x3219 => { Name => 'Sony_rtmd_0x3219', Format => 'int8u',  %hidUnk },
+    0x321a => { Name => 'Sony_rtmd_0x321a', Format => 'int8u',  %hidUnk },
+    0x8000 => { Name => 'Sony_rtmd_0x8000', Format => 'int16u', %hidUnk },
+    0x8001 => { Name => 'Sony_rtmd_0x8001', Format => 'int16u', %hidUnk },
+  # 0x8100 - 16 bytes starting with 0x060e2b340401
+    0x8100 => { Name => 'Sony_rtmd_0x8100', Format => 'int8u',  %hidUnk },
+    0x8101 => { Name => 'Sony_rtmd_0x8101', Format => 'int8u',  %hidUnk }, # seen: 0,1
+    0x8106 => { Name => 'Sony_rtmd_0x8106', Format => 'int32u', %hidUnk }, # seen: "25 1"
+    0x8109 => { Name => 'Sony_rtmd_0x8109', Format => 'int32u', %hidUnk }, # seen: "1 50"
+    0x810a => { Name => 'Sony_rtmd_0x810a', Format => 'int16u', %hidUnk }, # seen: 0
+    0x810b => { Name => 'Sony_rtmd_0x810b', Format => 'int16u', %hidUnk }, # seen: 100
+    0x810c => { Name => 'Sony_rtmd_0x810c', Format => 'int16u', %hidUnk }, # seen: 100
+    0x810d => { Name => 'Sony_rtmd_0x810d', Format => 'int8u',  %hidUnk }, # seen: 1
+    0x8115 => { Name => 'Sony_rtmd_0x8115', Format => 'int16u', %hidUnk }, # seen: 100
+  # 0x8300 - container for other tags in this format
+    0x8500 => {
+        Name => 'GPSVersionID',
+        Groups => { 2 => 'Location' },
+        Format => 'int8u',
+        PrintConv => '$val =~ tr/ /./; $val',
+    },
+    0x8501 => {
+        Name => 'GPSLatitudeRef',
+        Groups => { 2 => 'Location' },
+        Format => 'string',
+        PrintConv => {
+            N => 'North',
+            S => 'South',
+        },
+    },
+    0x8502 => {
+        Name => 'GPSLatitude',
+        Groups => { 2 => 'Location' },
+        Format => 'rational64u',
+        ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ToDegrees($val)',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+    },
+    0x8503 => {
+        Name => 'GPSLongitudeRef',
+        Groups => { 2 => 'Location' },
+        Format => 'string',
+        PrintConv => {
+            E => 'East',
+            W => 'West',
+        },
+    },
+    0x8504 => {
+        Name => 'GPSLongitude',
+        Groups => { 2 => 'Location' },
+        Format => 'rational64u',
+        ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ToDegrees($val)',
+        PrintConv => 'Image::ExifTool::GPS::ToDMS($self, $val, 1)',
+    },
+    0x8507 => {
+        Name => 'GPSTimeStamp',
+        Groups => { 2 => 'Time' },
+        Format => 'rational64u',
+        ValueConv => 'require Image::ExifTool::GPS;Image::ExifTool::GPS::ConvertTimeStamp($val)',
+        PrintConv => 'Image::ExifTool::GPS::PrintTimeStamp($val)',
+    },
+    0x8509 => {
+        Name => 'GPSStatus',
+        Groups => { 2 => 'Location' },
+        Format => 'string',
+        PrintConv => {
+            A => 'Measurement Active',
+            V => 'Measurement Void',
+        },
+    },
+    0x850a => {
+        Name => 'GPSMeasureMode',
+        Groups => { 2 => 'Location' },
+        Format => 'string',
+        PrintConv => {
+            2 => '2-Dimensional Measurement',
+            3 => '3-Dimensional Measurement',
+        },
+    },
+    0x8512 => {
+        Name => 'GPSMapDatum',
+        Groups => { 2 => 'Location' },
+        Format => 'string',
+    },
+    0x851d => {
+        Name => 'GPSDateStamp',
+        Groups => { 2 => 'Time' },
+        Format => 'string',
+        ValueConv => 'Image::ExifTool::Exif::ExifDate($val)',
+    },
+    0xe000 => { Name => 'Sony_rtmd_0xe000', Format => 'int8u',  %hidUnk }, # (16 bytes)
+    0xe300 => { Name => 'Sony_rtmd_0xe300', Format => 'int8u',  %hidUnk }, # seen: 0,1
+    0xe301 => { Name => 'Sony_rtmd_0xe301', Format => 'int32u', %hidUnk }, # seen: 100
+    0xe302 => { Name => 'Sony_rtmd_0xe302', Format => 'int8u',  %hidUnk }, # seen: 1
+    0xe303 => { Name => 'Sony_rtmd_0xe303', Format => 'int8u',  %hidUnk }, # seen: 255
+    0xe304 => {
+        Name => 'DateTime',
+        Groups => { 2 => 'Time' },
+        Format => 'undef',
+        ValueConv => 'my @a=unpack("x1H4H2H2H2H2H2",$val); "$a[0]:$a[1]:$a[2] $a[3]:$a[4]:$a[5]"',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    # f010 - 2048 bytes
+    # f020 - 543 bytes
+);
+
+# Composite Sony tags
+%Image::ExifTool::Sony::Composite = (
+    GROUPS => { 2 => 'Camera' },
+    FocusDistance => {
+        Require => {
+            0 => 'Sony:FocusPosition',
+            1 => 'FocalLength',
+        },
+        Notes => 'distance in metres = FocusPosition * FocalLength / 1000',
+        ValueConv => '$val >= 128 ? "inf" : $val * $val[1] / 1000',
+        PrintConv => '$val eq "inf" ? $val : "$val m"',
+    },
+    FocusDistance2 => {
+        # 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.
+            # (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)
+            # modified 16-10-2014 based on A99V measurements: use FocalLengthIn35mmFormat and leave out the "1.5*" factor.
+        Require => {
+            0 => 'Sony:FocusPosition2',
+            1 => 'FocalLengthIn35mmFormat',
+        },
+        ValueConv => q{
+            return undef unless $val;
+            return 'inf' if $val >= 255;
+            return (2**($val/16-5) + 1) * $val[1] / 1000;
+        },
+        PrintConv => '$val eq "inf" ? $val : sprintf("%.2f m",$val)',
+    },
+    GPSDateTime => {
+        Description => 'GPS Date/Time',
+        Groups => { 2 => 'Time' },
+        SubDoc => 1,    # generate for all sub-documents
+        Require => {
+            0 => 'Sony:GPSDateStamp',
+            1 => 'Sony:GPSTimeStamp',
+        },
+        ValueConv => '"$val[0] $val[1]Z"',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Sony');
+
+sub SortLensTypes
+{
+    return $a <=> $b unless $a =~ /\./ and $b =~ /\./;
+    my @a = split /\./, $a;
+    my @b = split /\./, $b;
+    # must compare the decimal part separately to sort in proper order
+    return $a[0] <=> $b[0] || $a[1] <=> $b[1];
+}
+
 # fill in Sony LensType lookup based on Minolta values
 {
     my $minoltaTypes = \%Image::ExifTool::Minolta::minoltaLensTypes;
     %sonyLensTypes = %$minoltaTypes;
-    my $notes = $$minoltaTypes{Notes};
-    delete $$minoltaTypes{Notes};
+    my $other = $$minoltaTypes{OTHER};
+    delete $$minoltaTypes{Notes};   # (temporarily)
+    delete $$minoltaTypes{OTHER};   # (temporarily)
     my $id;
-    foreach $id (sort { $a <=> $b } keys %$minoltaTypes) {
-        # higher numbered lenses are missing last digit of ID for some Sony models
+    # 5-digit lens ID's are missing the last digit (usually "1") in the metadata for
+    # some Sony models, so generate corresponding 4-digit entries for these cameras
+    foreach $id (sort SortLensTypes keys %$minoltaTypes) {
         next if $id < 10000;
         my $sid = int($id/10);
@@ -1524,5 +10231,303 @@
         $sonyLensTypes{$sid} = $lens;
     }
-    $$minoltaTypes{Notes} = $sonyLensTypes{Notes} = $notes;
+    $$minoltaTypes{Notes} = $sonyLensTypes{Notes}; # (restore original Notes)
+    $$minoltaTypes{OTHER} = $other;
+}
+
+#------------------------------------------------------------------------------
+# Process "SONY PIC\0" maker notes (DSC-H200/J10/W370/W510, MHS-TS20, ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1
+sub ProcessSonyPIC($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart} || 0;
+    my $len = $$dirInfo{DirLen} || (length($$dataPt) - $start);
+    my $data = substr($$dataPt, $start, $len);
+
+    # H200 panorama images have an IFD at offset 12 (non-panoramas have 0's here)
+    # - assume other images could too, but do a bit of validation to check
+    # - MHS-TS20 images have some other data here
+    if ($len >= 26) {
+        my $count = Get16u($dataPt, $start + 12);
+        if ($count > 256) {
+            ToggleByteOrder();
+            $count = Get16u($dataPt, $start + 12);
+        }
+        if ($count and $count < 256) {
+            my $format = Get16u($dataPt, $start + 16);
+            if ($format >= 1 and $format <= 10) {
+                $$dirInfo{DirStart} = $start + 12;
+                $$dirInfo{DirLen} = $len - 12;
+                my $sonyTable = GetTagTable('Image::ExifTool::Sony::Main');
+                Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $sonyTable);
+            }
+        }
+    }
+    # Do a brute force search for text data:
+    # For the DSC-J10/W370/W510 the first text block is at offset 0x1ec and
+    # starts with "BarCode:".  For the H200 it is at 0x1f0 and starts with "BC:".
+    # For the TS20 it is at 0x5b and starts with "V400 AELOG\nbarcode:".
+    # The second text block starts with "AFLOG" (Auto-Focus log) and is at
+    # 0x600 for all models, except for the TS20 it is at 0x45b.
+    my $i = 0;
+    while ($data =~ /(\w[\x09\x0a\x0d\x20-\x7e]+)/sg) {
+        next unless length $1 > 32;
+        my ($tag, $val) = ('TextInfo' . (++$i), $1);
+        $$tagTablePtr{$tag} or AddTagToTable($tagTablePtr, $tag, { Name => $tag, Binary => 1 });
+        $et->HandleTag($tagTablePtr, $tag, $val);
+        # extract interesting tags separately (might want to speed this up)
+        foreach $tag (sort { lc $a cmp lc $b } keys %$tagTablePtr) {
+            next unless $tag =~ /:$/ and $val =~ /\b$tag\s*([^\s;,:]+)/;
+            $et->HandleTag($tagTablePtr, $tag, $1);
+        }
+    }
+    return 1;
+}
+
+#------------------------------------------------------------------------------
+# MeterInfo value conversions
+# Inputs: 0) value
+# Returns: converted value
+sub ConvMeter1($)
+{
+    my $val = shift;
+    return \$val unless length($val) == 90;
+    my @a = unpack("SLLSLLSLLSLLSLLSLLSLLSLLSLL",$val);
+    return join ' ', @a;
+}
+sub ConvMeter2($)
+{
+    my $val = shift;
+    return \$val unless length($val) == 110;
+    my @a = unpack("SLLSLLSLLSLLSLLSLLSLLSLLSLLSLLSLL",$val);
+    return join ' ', @a;
+}
+
+#------------------------------------------------------------------------------
+# LensSpec value conversions
+# Inputs: 0) value
+# Returns: converted value
+# Notes: unpacks in format compatible with LensInfo, with extra flags bytes at start and end
+sub ConvLensSpec($)
+{
+    my $val = shift;
+    return \$val unless length($val) == 8;
+    my @a = unpack("H2H4H4H2H2H2",$val);
+    $a[1] += 0;  $a[2] += 0;    # remove leading zeros from focal lengths
+    s/([a-f])/hex($1)/e foreach @a[3,4]; # convert hex digits (ie. "b0" = f11)
+    $a[3] /= 10; $a[4] /= 10;   # divide f-numbers by 10
+    return join ' ', @a;
+}
+sub ConvInvLensSpec($)
+{
+    my $val = shift;
+    my @a=split(" ", $val);
+    return $val unless @a == 6;
+    $a[3] *= 10; $a[4] *= 10;   # f-numbers are multiplied by 10
+    s/^(\d{2})0$/sprintf('%x0',$1)/e foreach @a[3,4];
+    $_ = hex foreach @a;        # convert from hex
+    return pack 'CnnCCC', @a;
+}
+
+#------------------------------------------------------------------------------
+# Print Sony LensSpec value
+# Inputs: 0) LensSpec numerical value
+# Returns: converted LensSpec string (eg. "DT 18-55mm F3.5-5.6 SAM")
+# Refs: http://equational.org/importphotos/alphalensinfo.html
+#       http://www.dyxum.com/dforum/the-lens-information-different-from-lensid_topic37682.html
+my @lensFeatures = (
+    # lens features in the order they are added to the LensSpec string
+    # (high byte of Mask/Bits represents byte 0 of LensSpec, low byte is byte 7)
+    #  Mask   {  Bits     Name    Bits     Name  } Prefix flag
+    # ------    ------    -----  ------    -----   -----------
+    [ 0x4000, { 0x4000 => 'PZ'                   }, 1 ],
+    [ 0x0300, { 0x0100 => 'DT',  0x0200 => 'FE', 0x0300 => 'E'   }, 1 ], # (will come before preceding prefix), FE added (ref JR)
+    [ 0x00e0, { 0x0020 => 'STF', 0x0040 => 'Reflex', 0x0060 => 'Macro', 0x0080 => 'Fisheye' } ],
+    [ 0x000c, { 0x0004 => 'ZA',  0x0008 => 'G'   } ],
+    [ 0x0003, { 0x0001 => 'SSM', 0x0002 => 'SAM' } ],
+    [ 0x8000, { 0x8000 => 'OSS' } ],
+    [ 0x2000, { 0x2000 => 'LE' } ], #JR
+    [ 0x0800, { 0x0800 => 'II' } ], #JR
+);
+sub PrintLensSpec($)
+{
+    my $val = shift;
+    my ($rtnVal, $feature, $f1, $sf, $lf, $sa, $la, $f2);
+    # 0=flags1, 1=short focal, 2=long focal, 3=max aperture at short focal,
+    # 4=max aperture at long focal, 5=flags2
+    my @a = split ' ', $val;
+    if (@a == 2) {  # LensSpecFeatures patch
+        ($f1, $f2) = @a;
+        $rtnVal = '';
+    } elsif (@a >= 6) {
+        ($f1, $sf, $lf, $sa, $la, $f2) = @a;
+        # crude validation of focal length and aperture values
+        if ($sf != 0 and $sa != 0 and ($lf == 0 or $lf >= $sf) and ($la == 0 or $la >= $sa)) {
+            # use focal and aperture range if this is a zoom lens
+            $sf .= '-' . $lf if $lf != $sf and $lf != 0;
+            $sa .= '-' . $la if $sa != $la and $la != 0;
+            $rtnVal = "${sf}mm F$sa";     # heart of LensSpec is a LensInfo string
+        }
+    }
+    if (defined $rtnVal) {
+        # loop through available lens features
+        my $flags = hex($f1 . $f2);
+        foreach $feature (@lensFeatures) {
+            my $bits = $$feature[0] & $flags;
+            next unless $bits or $$feature[1]{$bits};
+            # add feature name as a prefix or suffix to the LensSpec
+            my $str = $$feature[1]{$bits} || sprintf('Unknown(%.4x)',$bits);
+            $rtnVal = $rtnVal ? ($$feature[2] ? "$str $rtnVal" : "$rtnVal $str") : $str;
+        }
+    } else {
+        $rtnVal = "Unknown ($val)";
+    }
+    return $rtnVal;
+}
+# inverse conversion
+sub PrintInvLensSpec($;$$)
+{
+    my ($val, $self, $features) = @_;
+    return $1 if $val =~ /Unknown \((.*)\)/i;
+    my ($sf, $lf, $sa, $la) = Image::ExifTool::Exif::GetLensInfo($val);
+    my $str;
+    if ($features) {
+        $str = '';
+    } elsif ($sf) {
+        # fixed focal length and aperture have zero for 2nd number
+        $lf = 0 if $lf == $sf;
+        $la = 0 if $la == $sa;
+        $str = " $sf $lf $sa $la";
+    } else {
+        return undef;
+    }
+    my $flags = 0;
+    my ($feature, $bits);
+    foreach $feature (@lensFeatures) {
+        foreach $bits (keys %{$$feature[1]}) {
+            # set corresponding flag bits for each feature name found
+            my $name = $$feature[1]{$bits};
+            $val =~ /\b$name\b/i and $flags |= $bits;
+        }
+    }
+    return sprintf "%.2x$str %.2x", $flags>>8, $flags&0xff;
+}
+
+#------------------------------------------------------------------------------
+# Read/Write MoreInfo information (tag 0x0020, count 20480)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success when reading, or new directory when writing (IsWriting set)
+sub ProcessMoreInfo($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to write routine
+    my $dataPt = $$dirInfo{DataPt};
+    my $start = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || length($$dataPt);
+    my $isWriting = $$dirInfo{IsWriting};
+    my $rtnVal = $isWriting ? undef : 0;
+    return $rtnVal if $dirLen < 4;
+
+    my $num = Get16u($dataPt, $start);      # number of entries
+    my $len = Get16u($dataPt, $start + 2);  # total data length
+
+    if ($dirLen < 4 + $num * 4) {
+        $et->Warn('Truncated MoreInfo data', 1);
+        return $rtnVal;
+    }
+    if ($num > 50) {
+        $et->Warn('Possibly corrupted MoreInfo data', 1);
+        return $rtnVal;
+    }
+
+    $et->VerboseDir('MoreInfo', $num, $len) unless $isWriting;
+
+    if ($len > $dirLen) {
+        $et->Warn('MoreInfo data length too large', 1);
+        $len = $dirLen;
+    }
+    # loop through the MoreInfo index section to get the block offsets and tag ID's
+    # (in case they are out of order, even though this may never happen)
+    my ($i, @offset, @tagID, %blockSize);
+    for ($i=0; $i<$num; ++$i) {
+        my $entry = $start + 4 + $i * 4;
+        push @tagID, Get16u($dataPt, $entry);
+        push @offset, Get16u($dataPt, $entry + 2);
+        if ($offset[-1] > $len and $offset[-1] <= $dirLen) {
+            $et->Warn('MoreInfo data length too small', 1);
+            $len = $dirLen;
+        }
+    }
+    # generate a lookup table of block sizes
+    my @sorted = sort { $a <=> $b } @offset;
+    push @sorted, 0xffff;   # (simplifies logic in loop below)
+    for ($i=0; $i<$num; ++$i) {
+        my $offset = $sorted[$i];
+        my $size = $sorted[$i+1] - $offset;
+        # note that block size will be negative for blocks with starting
+        # offsets greater than $dirLen, but we will ignore these below
+        $size = $len - $offset if $size > $len - $offset;
+        # (if blockSize is already defined for this offset, then there
+        #  are 2 blocks with the same starting offset and the existing
+        #  size must be zero.  Since we can't know which block is
+        #  actually non-zero size, the reasonable thing to do is
+        #  assume that both have a size of zero)
+        $blockSize{$offset} = $size unless defined $blockSize{$offset};
+    }
+    # initialize successful return value
+    $rtnVal = $isWriting ? substr($$dataPt, $start, $dirLen) : 1;
+    # now process each block
+    my $unknown = $$et{OPTIONS}{Unknown};
+    for ($i=0; $i<$num; ++$i) {
+        next if $offset[$i] > $dirLen;  # ignore bad offsets
+        my $tag = $tagID[$i];
+        if ($isWriting) {
+            # write new tags
+            my $tagInfo = $$tagTablePtr{$tag};
+            next unless ref $tagInfo eq 'HASH' and $$tagInfo{SubDirectory};
+            my $offset = $offset[$i];
+            my $size = $blockSize{$offset};
+            next unless $size;  # ignore zero-length blocks
+            my %dirInfo = (
+                DirName  => $$tagInfo{Name},
+                Parent   => $$dirInfo{DirName},
+                DataPt   => \$rtnVal,
+                DirStart => $offset,
+                DirLen   => $size,
+            );
+            my $subTable = GetTagTable($$tagInfo{SubDirectory}{TagTable});
+            my $val = $et->WriteDirectory(\%dirInfo, $subTable);
+            # update this block in the returned MoreInfo data
+            substr($rtnVal, $offset, $size) = $val if defined $val;
+            next;
+        }
+        # generate binary tables for unknown tags if -U option used
+        if (not defined $$tagTablePtr{$tag} and $unknown > 1) {
+            my $name = sprintf('MoreInfo%.4x', $tag);
+            my $table = "Image::ExifTool::Sony::$name";
+            no strict 'refs';
+            %$table = (
+                PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+                FIRST_ENTRY => 0,
+                GROUPS => { 0 => 'MakerNotes', 2 => 'Image' },
+            );
+            use strict 'refs';
+            my %tagInfo = (
+                Name => $name,
+                SubDirectory => { TagTable => $table },
+            );
+            AddTagToTable($tagTablePtr, $tag, \%tagInfo);
+        }
+        $et->HandleTag($tagTablePtr, $tag, undef,
+            Index   => $i,
+            DataPt  => $dataPt,
+            DataPos => $$dirInfo{DataPos},
+            Start   => $start + $offset[$i],
+            Size    => $blockSize{$offset[$i]},
+        );
+    }
+    return $rtnVal;
 }
 
@@ -1533,5 +10538,5 @@
 sub ProcessPMP($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $buff;
@@ -1539,21 +10544,118 @@
     # validate header length (124 bytes)
     $buff =~ /^.{8}\0{3}\x7c.{112}\xff\xd8\xff\xdb$/s or return 0;
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('MM');
-    $exifTool->FoundTag(Make => 'Sony');
-    $exifTool->FoundTag(Model => 'DSC-F1');
+    $et->FoundTag(Make => 'Sony');
+    $et->FoundTag(Model => 'DSC-F1');
     # extract information from 124-byte header
     my $tagTablePtr = GetTagTable('Image::ExifTool::Sony::PMP');
     my %dirInfo = ( DataPt => \$buff, DirName => 'PMP' );
-    $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
     # process JPEG image
     $raf->Seek(124, 0);
     $$dirInfo{Base} = 124;
-    $exifTool->ProcessJPEG($dirInfo);
+    $et->ProcessJPEG($dirInfo);
     return 1;
 }
 
 #------------------------------------------------------------------------------
-# Decrypt Sony data (ref 1)
+# Set the ARW file type and decide between SubIFD and A100DataOffset
+# Inputs: 0) ExifTool object ref, 1) reference to tag 0x14a raw data
+# Returns: true if tag 0x14a is a SubIFD, false otherwise
+sub SetARW($$)
+{
+    my ($et, $valPt) = @_;
+
+    # assume ARW for now -- SR2's get identified when FileFormat is parsed
+    $et->OverrideFileType($$et{TIFF_TYPE} = 'ARW');
+
+    # this should always be a SubIFD for models other than the A100
+    return 1 unless $$et{Model} eq 'DSLR-A100' and length $$valPt == 4;
+
+    # for the A100, IFD0 tag 0x14a is either a pointer to the raw data if this is
+    # an original image, or a SubIFD offset if the image was edited by Sony IDC,
+    # so assume it points to the raw data if it isn't a valid IFD (this assumption
+    # will be checked later when we try to parse the SR2Private directory)
+    my %subdir = (
+        DirStart => Get32u($valPt, 0),
+        Base     => 0,
+        RAF      => $$et{RAF},
+        AllowOutOfOrderTags => 1, # doh!
+    );
+    return Image::ExifTool::Exif::ValidateIFD(\%subdir);
+}
+
+#------------------------------------------------------------------------------
+# Finish writing ARW image, patching necessary Sony quirks, etc
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) EXIF data ref, 3) image data reference
+# Returns: undef on success, error string otherwise
+# Notes: (it turns that all of this is for the A100 only)
+sub FinishARW($$$$)
+{
+    my ($et, $dirInfo, $dataPt, $imageData) = @_;
+
+    # pre-scan IFD0 to get IFD entry offsets for each tag
+    my $dataLen = length $$dataPt;
+    return 'Truncated IFD0' if $dataLen < 2;
+    my $n = Get16u($dataPt, 0);
+    return 'Truncated IFD0' if $dataLen < 2 + 12 * $n;
+    my ($i, %entry, $dataBlock, $pad, $dataOffset);
+    for ($i=0; $i<$n; ++$i) {
+        my $entry = 2 + $i * 12;
+        $entry{Get16u($dataPt, $entry)} = $entry;
+    }
+    # fix up SR2Private offset and A100DataOffset (A100 only)
+    if ($entry{0xc634} and $$et{MRWDirData}) {
+        return 'Unexpected MRW block' unless $$et{Model} eq 'DSLR-A100';
+        return 'Missing A100DataOffset' unless $entry{0x14a} and $$et{A100DataOffset};
+        # account for total length of image data
+        my $totalLen = 8 + $dataLen;
+        if (ref $imageData) {
+            foreach $dataBlock (@$imageData) {
+                my ($pos, $size, $pad) = @$dataBlock;
+                $totalLen += $size + $pad;
+            }
+        }
+        # align MRW block on an even 4-byte boundary
+        my $remain = $totalLen & 0x03;
+        $pad = 4 - $remain and $totalLen += $pad if $remain;
+        # set offset for the MRW directory data
+        Set32u($totalLen, $dataPt, $entry{0xc634} + 8);
+        # also pad MRWDirData data to an even 4 bytes (just to be safe)
+        $remain = length($$et{MRWDirData}) & 0x03;
+        $$et{MRWDirData} .= "\0" x (4 - $remain) if $remain;
+        $totalLen += length $$et{MRWDirData};
+        # fix up A100DataOffset
+        $dataOffset = $$et{A100DataOffset};
+        Set32u($totalLen, $dataPt, $entry{0x14a} + 8);
+    }
+    # patch double-referenced and incorrectly-sized A100 PreviewImage
+    if ($entry{0x201} and $$et{A100PreviewStart} and
+        $entry{0x202} and $$et{A100PreviewLength})
+    {
+        Set32u($$et{A100PreviewStart}, $dataPt, $entry{0x201} + 8);
+        Set32u($$et{A100PreviewLength}, $dataPt, $entry{0x202} + 8);
+    }
+    # write TIFF IFD structure
+    my $outfile = $$dirInfo{OutFile};
+    my $header = GetByteOrder() . Set16u(0x2a) . Set32u(8);
+    Write($outfile, $header, $$dataPt) or return 'Error writing';
+    # copy over image data
+    if (ref $imageData) {
+        $et->CopyImageData($imageData, $outfile) or return 'Error copying image data';
+    }
+    # write MRW data if necessary
+    if ($$et{MRWDirData}) {
+        Write($outfile, "\0" x $pad) if $pad;   # write padding if necessary
+        Write($outfile, $$et{MRWDirData});
+        delete $$et{MRWDirData};
+        # set TIFF_END to copy over the MRW image data
+        $$et{TIFF_END} = $dataOffset if $dataOffset;
+    }
+    return undef;
+}
+
+#------------------------------------------------------------------------------
+# Decrypt/Encrypt Sony data (ref 1) (reversible encryption)
 # Inputs: 0) data reference, 1) start offset, 2) data length, 3) decryption key
 # Returns: nothing (original data buffer is updated with decrypted data)
@@ -1583,99 +10685,132 @@
 
 #------------------------------------------------------------------------------
-# Set the ARW file type and decide between SubIFD and A100DataOffset
-# Inputs: 0) ExifTool object ref, 1) reference to tag 0x14a raw data
-# Returns: true if tag 0x14a is a SubIFD, false otherwise
-sub SetARW($$)
+# Decipher/encipher Sony tag 0x2010, 0x900b, 0x9050 and 0x940x data (ref PH)
+# Inputs: 0) data reference, 1) true to encipher the data
+sub Decipher($;$)
 {
-    my ($exifTool, $valPt) = @_;
-
-    # assume ARW for now -- SR2's get identified when FileFormat is parsed
-    $exifTool->OverrideFileType($$exifTool{TIFF_TYPE} = 'ARW');
-
-    # this should always be a SubIFD for models other than the A100
-    return 1 unless $$exifTool{Model} eq 'DSLR-A100' and length $$valPt == 4;
-
-    # for the A100, IFD0 tag 0x14a is either a pointer to the raw data if this is
-    # an original image, or a SubIFD offset if the image was edited by Sony IDC,
-    # so assume it points to the raw data if it isn't a valid IFD (this assumption
-    # will be checked later when we try to parse the SR2Private directory)
-    my %subdir = (
-        DirStart => Get32u($valPt, 0),
-        Base     => 0,
-        RAF      => $$exifTool{RAF},
-        AllowOutOfOrderTags => 1, # doh!
+    my ($dataPt, $encipher) = @_;
+    # This is a simple substitution cipher, so use a hardcoded translation table for speed.
+    # The formula is: $c = ($b*$b*$b) % 249, where $c is the enciphered data byte
+    # (note that bytes with values 249-255 are not translated, and 0-1, 82-84,
+    #  165-167 and 248 have the same enciphered value)
+    if ($encipher) {    # encipher
+        $$dataPt =~ tr/\x02-\xf7/\x08\x1b\x40\x7d\xd8\x5e\x0e\xe7\x04V\xea\xcd\x05\x8ap\xb6i\x88\x200\xbe\xd7\x81\xbb\x92\x0c\x28\xecl\xa0\x95Q\xd3\x2f\x5dj\x5c9\x07\xc5\x87L\x1a\xf0\xe2\xef\x24y\x02\xb7\xac\xe0\x60\x2bG\xba\x91\xcbu\x8e\x233\xc4\xe3\x96\xdc\xc2N\x7fb\xf6OeE\xeet\xcf\x138KRST\x5bn\x93\xd02\xb1aAW\xa9D\x27X\xdd\xc3\x10\xbc\xdbs\x83\x181\xd4\x15\xe5_\x7bF\xbf\xf3\xe8\xa4\x2d\x82\xb0\xbd\xaf\x8cZ\x1f\xda\x9fmJ\x3cIw\xccU\x11\x06\x3a\xb3\x7e\x9a\x14\xe4\x25\xc8\xe1v\x86\x1e\x3d\xe96\x1c\xa1\xd2\xb5P\xa2\xb8\x98H\xc7\x29f\x8b\x9e\xa5\xa6\xa7\xae\xc1\xe6\x2a\x85\x0b\xb4\x94\xaa\x03\x97z\xab7\x1dc\x165\xc6\xd6k\x84\x2eh\x3f\xb2\xce\x99\x19MB\xf7\x80\xd5\x0a\x17\x09\xdf\xadr4\xf2\xc0\x9d\x8f\x9c\xca\x26\xa8dY\x8d\x0d\xd1\xedg\x3ex\x22\x3b\xc9\xd9q\x90C\x89o\xf4\x2c\x0f\xa3\xf5\x12\xeb\x9b\x21\x7c\xb9\xde\xf1/;
+    } else {            # decipher
+        $$dataPt =~ tr/\x08\x1b\x40\x7d\xd8\x5e\x0e\xe7\x04V\xea\xcd\x05\x8ap\xb6i\x88\x200\xbe\xd7\x81\xbb\x92\x0c\x28\xecl\xa0\x95Q\xd3\x2f\x5dj\x5c9\x07\xc5\x87L\x1a\xf0\xe2\xef\x24y\x02\xb7\xac\xe0\x60\x2bG\xba\x91\xcbu\x8e\x233\xc4\xe3\x96\xdc\xc2N\x7fb\xf6OeE\xeet\xcf\x138KRST\x5bn\x93\xd02\xb1aAW\xa9D\x27X\xdd\xc3\x10\xbc\xdbs\x83\x181\xd4\x15\xe5_\x7bF\xbf\xf3\xe8\xa4\x2d\x82\xb0\xbd\xaf\x8cZ\x1f\xda\x9fmJ\x3cIw\xccU\x11\x06\x3a\xb3\x7e\x9a\x14\xe4\x25\xc8\xe1v\x86\x1e\x3d\xe96\x1c\xa1\xd2\xb5P\xa2\xb8\x98H\xc7\x29f\x8b\x9e\xa5\xa6\xa7\xae\xc1\xe6\x2a\x85\x0b\xb4\x94\xaa\x03\x97z\xab7\x1dc\x165\xc6\xd6k\x84\x2eh\x3f\xb2\xce\x99\x19MB\xf7\x80\xd5\x0a\x17\x09\xdf\xadr4\xf2\xc0\x9d\x8f\x9c\xca\x26\xa8dY\x8d\x0d\xd1\xedg\x3ex\x22\x3b\xc9\xd9q\x90C\x89o\xf4\x2c\x0f\xa3\xf5\x12\xeb\x9b\x21\x7c\xb9\xde\xf1/\x02-\xf7/;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Process Sony 0x94xx cipherdata directory
+# Inputs: 0) ExifTool object ref, 1) directory information ref, 2) tag table ref
+# Returns: 1 on success
+# Notes:
+# 1) dirInfo may contain VarFormatData (reference to empty list) to return
+#    details about any variable-length-format tags in the table (used when writing)
+# 2) A bug in ExifTool 9.04-9.10 could have double-enciphered these blocks
+sub ProcessEnciphered($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
+    my $data = substr($$dataPt, $dirStart, $dirLen);
+    my %dirInfo = (
+        %$dirInfo,
+        DataPt => \$data,
+        DataPos => $$dirInfo{DataPos} + $dirStart,
+        DirStart => 0,
     );
-    return Image::ExifTool::Exif::ValidateIFD(\%subdir);
+    Decipher(\$data);
+    if ($$et{DoubleCipher}) {
+        Decipher(\$data);
+        $et->WarnOnce('Some Sony metadata is double-enciphered. Write any tag to fix',1);
+    }
+    if ($et->Options('Verbose') > 2) {
+        my $tagInfo = $$dirInfo{TagInfo} || { Name => 'data' };
+        my $str = $$et{DoubleCipher} ? 'ouble-d' : '';
+        $et->VerboseDir("D${str}eciphered $$tagInfo{Name}");
+        $et->VerboseDump(\$data,
+            Prefix  => $$et{INDENT} . '  ',
+            DataPos => $$dirInfo{DirStart} + $$dirInfo{DataPos} + ($$dirInfo{Base} || 0),
+        );
+    }
+    return $et->ProcessBinaryData(\%dirInfo, $tagTablePtr);
 }
 
 #------------------------------------------------------------------------------
-# Finish writing ARW image, patching necessary Sony quirks, etc
-# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) EXIF data ref, 3) image data reference
-# Returns: undef on success, error string otherwise
-# Notes: (it turns that all of this is for the A100 only)
-sub FinishARW($$$$)
+# Write Sony 0x94xx cipherdata directory
+# Inputs: 0) ExifTool object ref, 1) source dirInfo ref, 2) tag table ref
+# Returns: cipherdata block or undefined on error
+sub WriteEnciphered($$$)
 {
-    my ($exifTool, $dirInfo, $dataPt, $imageData) = @_;
-
-    # pre-scan IFD0 to get IFD entry offsets for each tag
-    my $dataLen = length $$dataPt;
-    return 'Truncated IFD0' if $dataLen < 2;
-    my $n = Get16u($dataPt, 0);
-    return 'Truncated IFD0' if $dataLen < 2 + 12 * $n;
-    my ($i, %entry, $dataBlock, $pad, $dataOffset);
-    for ($i=0; $i<$n; ++$i) {
-        my $entry = 2 + $i * 12;
-        $entry{Get16u($dataPt, $entry)} = $entry;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dirStart = $$dirInfo{DirStart} || 0;
+    my $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
+    my $data = substr($$dataPt, $dirStart, $dirLen);
+    my $changed = $$et{CHANGED};
+    Decipher(\$data);
+    # fix double-enciphered data (due to bug in ExifTool 9.04-9.10)
+    if ($$et{DoubleCipher}) {
+        Decipher(\$data);
+        ++$$et{CHANGED};
+        $et->WarnOnce('Fixed double-enciphered Sony metadata',1);
     }
-    # fix up SR2Private offset and A100DataOffset (A100 only)
-    if ($entry{0xc634} and $$exifTool{MRWDirData}) {
-        return 'Unexpected MRW block' unless $$exifTool{Model} eq 'DSLR-A100';
-        return 'Missing A100DataOffset' unless $entry{0x14a} and $$exifTool{A100DataOffset};
-        # account for total length of image data
-        my $totalLen = 8 + $dataLen;
-        if (ref $imageData) {
-            foreach $dataBlock (@$imageData) {
-                my ($pos, $size, $pad) = @$dataBlock;
-                $totalLen += $size + $pad;
-            }
+    my %dirInfo = (
+        %$dirInfo,
+        DataPt => \$data,
+        DataPos => $$dirInfo{DataPos} + $dirStart,
+        DirStart => 0,
+    );
+    $data = $et->WriteBinaryData(\%dirInfo, $tagTablePtr);
+    if ($changed == $$et{CHANGED}) {
+        # nothing changed, so recover original data
+        $data = substr($$dataPt, $dirStart, $dirLen);
+    } elsif (defined $data) {
+        Decipher(\$data,1);     # re-encipher
+    }
+    return $data;
+}
+
+#------------------------------------------------------------------------------
+# Process "rtmd" timed metadata embedded in Sony MP4 videos (ref PH)
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
+# Returns: 1 on success
+sub Process_rtmd($$$)
+{
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $dataPt = $$dirInfo{DataPt};
+    my $dataPos = ($$dirInfo{DataPos} || 0) + ($$dirInfo{Base} || 0);
+    my $end = length $$dataPt;
+    return 0 if $end < 2;
+    $et->VerboseDir('Sony rtmd', undef, $end);
+    # Note:  The 0x1c-byte header contains some as-yet unextracted information:
+    #  offset 0x0e: int8u some minutes
+    #         0x0f: int8u some seconds
+    #         0x11: int8u frame number? (0-24 or 0-25)
+    my $pos = Get16u($dataPt, 0);   # get header length (= 0x1c)
+    while ($pos + 4 < $end) {
+        my $tag = Get16u($dataPt, $pos);
+        last if $tag == 0;
+        my $len = Get16u($dataPt, $pos+2);
+        if ($tag == 0x060e) {
+            $len = 0x10;    # (unknown 16 bytes starting with 0x060e2b340253)
+        } else {
+            $pos += 4;      # skip tag id/size
+            next if $tag == 0x8300; # descend into contents of 0x8300 (container)
         }
-        # align MRW block on an even 4-byte boundary
-        my $remain = $totalLen & 0x03;
-        $pad = 4 - $remain and $totalLen += $pad if $remain;
-        # set offset for the MRW directory data
-        Set32u($totalLen, $dataPt, $entry{0xc634} + 8);
-        # also pad MRWDirData data to an even 4 bytes (just to be safe)
-        $remain = length($$exifTool{MRWDirData}) & 0x03;
-        $$exifTool{MRWDirData} .= "\0" x (4 - $remain) if $remain;
-        $totalLen += length $$exifTool{MRWDirData};
-        # fix up A100DataOffset
-        $dataOffset = $$exifTool{A100DataOffset};
-        Set32u($totalLen, $dataPt, $entry{0x14a} + 8);
+        last if $pos + $len > $end;
+        $et->HandleTag($tagTablePtr, $tag, undef,
+            DataPt  => $dataPt,
+            DataPos => $dataPos,
+            Start   => $pos,
+            Size    => $len,
+        );
+        $pos += $len;       # step to next tag
     }
-    # patch double-referenced and incorrectly-sized A100 PreviewImage
-    if ($entry{0x201} and $$exifTool{A100PreviewStart} and
-        $entry{0x202} and $$exifTool{A100PreviewLength})
-    {
-        Set32u($$exifTool{A100PreviewStart}, $dataPt, $entry{0x201} + 8);
-        Set32u($$exifTool{A100PreviewLength}, $dataPt, $entry{0x202} + 8);
-    }
-    # write TIFF IFD structure
-    my $outfile = $$dirInfo{OutFile};
-    my $header = GetByteOrder() . Set16u(0x2a) . Set32u(8);
-    Write($outfile, $header, $$dataPt) or return 'Error writing';
-    # copy over image data
-    if (ref $imageData) {
-        $exifTool->CopyImageData($imageData, $outfile) or return 'Error copying image data';
-    }
-    # write MRW data if necessary
-    if ($$exifTool{MRWDirData}) {
-        Write($outfile, "\0" x $pad) if $pad;   # write padding if necessary
-        Write($outfile, $$exifTool{MRWDirData});
-        delete $$exifTool{MRWDirData};
-        # set TIFF_END to copy over the MRW image data
-        $$exifTool{TIFF_END} = $dataOffset if $dataOffset;
-    }
-    return undef;
-}
+    return 1;
+};
 
 #------------------------------------------------------------------------------
@@ -1685,8 +10820,8 @@
 sub ProcessSRF($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $start = $$dirInfo{DirStart};
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
 
     # process IFD chain
@@ -1701,7 +10836,7 @@
         }
         my $srf = $$dirInfo{DirName} = "SRF$ifd";
-        $exifTool->{SET_GROUP1} = $srf;
-        $success = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
-        delete $exifTool->{SET_GROUP1};
+        $$et{SET_GROUP1} = $srf;
+        $success = Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
+        delete $$et{SET_GROUP1};
         last unless $success;
 #
@@ -1723,10 +10858,12 @@
             # get the key to decrypt IFD1
             my $cp = $start + 0x8ddc;    # why?
+            last if $cp + 1 > length($$dataPt);
             my $ip = $cp + 4 * unpack("x$cp C", $$dataPt);
+            last if $ip + 4 > length($$dataPt);
             $key = unpack("x$ip N", $$dataPt);
             $len = $cp + $nextIFD;  # decrypt up to $cp
         } elsif ($ifd == 2) {
             # get the key to decrypt IFD2
-            $key = $exifTool->{SRF2Key};
+            $key = $$et{SRF2Key};
             $len = length($$dataPt) - $nextIFD; # decrypt rest of maker notes
         } else {
@@ -1737,7 +10874,7 @@
         next unless $verbose > 2;
         # display decrypted data in verbose mode
-        $exifTool->VerboseDir("Decrypted SRF$ifd", 0, $nextIFD + $len);
-        $exifTool->VerboseDump($dataPt,
-            Prefix => "$exifTool->{INDENT}  ",
+        $et->VerboseDir("Decrypted SRF$ifd", 0, $nextIFD + $len);
+        $et->VerboseDump($dataPt,
+            Prefix => "$$et{INDENT}  ",
             Start => $nextIFD,
             DataPos => $$dirInfo{DataPos},
@@ -1752,9 +10889,9 @@
 sub WriteSR2($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;      # allow dummy access
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;      # allow dummy access
     my $buff = '';
     $$dirInfo{OutFile} = \$buff;
-    return ProcessSR2($exifTool, $dirInfo, $tagTablePtr);
+    return ProcessSR2($et, $dirInfo, $tagTablePtr);
 }
 
@@ -1765,5 +10902,5 @@
 sub ProcessSR2($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $raf = $$dirInfo{RAF};
     my $dataPt = $$dirInfo{DataPt};
@@ -1774,7 +10911,7 @@
 
     # clear SR2 member variables to be safe
-    delete $$exifTool{SR2SubIFDOffset};
-    delete $$exifTool{SR2SubIFDLength};
-    delete $$exifTool{SR2SubIFDKey};
+    delete $$et{SR2SubIFDOffset};
+    delete $$et{SR2SubIFDLength};
+    delete $$et{SR2SubIFDKey};
 
     # make sure we have the first 4 bytes available to test directory type
@@ -1793,8 +10930,8 @@
     if ($dataPt and $$dataPt =~ /^\0MR[IM]/) {
         my ($err, $srfPos, $srfLen, $dataOffset);
-        $dataOffset = $$exifTool{A100DataOffset};
+        $dataOffset = $$et{A100DataOffset};
         if ($dataOffset) {
             # save information about the RAW data trailer so it will be preserved
-            $$exifTool{KnownTrailer} = { Name => 'A100 RAW Data', Start => $dataOffset };
+            $$et{KnownTrailer} = { Name => 'A100 RAW Data', Start => $dataOffset };
         } else {
             $err = 'A100DataOffset tag is missing from A100 ARW image';
@@ -1809,6 +10946,6 @@
         }
         if ($err) {
-            $outfile and $exifTool->Error($err), return undef;
-            $exifTool->Warn($err);
+            $outfile and $et->Error($err), return undef;
+            $et->Warn($err);
             return 0;
         }
@@ -1817,34 +10954,34 @@
         if ($outfile) {
             # save MRW data to be written last
-            $$exifTool{MRWDirData} = Image::ExifTool::MinoltaRaw::WriteMRW($exifTool, \%dirInfo);
-            return $$exifTool{MRWDirData} ? "\0\0\0\0\0\0" : undef;
+            $$et{MRWDirData} = Image::ExifTool::MinoltaRaw::WriteMRW($et, \%dirInfo);
+            return $$et{MRWDirData} ? "\0\0\0\0\0\0" : undef;
         } else {
-            if (not $outfile and $$exifTool{HTML_DUMP}) {
-                $exifTool->HDump($srfPos, $srfLen, '[A100 SRF Data]');
+            if (not $outfile and $$et{HTML_DUMP}) {
+                $et->HDump($srfPos, $srfLen, '[A100 SRF Data]');
             }
-            return Image::ExifTool::MinoltaRaw::ProcessMRW($exifTool, \%dirInfo);
+            return Image::ExifTool::MinoltaRaw::ProcessMRW($et, \%dirInfo);
         }
-    } elsif ($$exifTool{A100DataOffset}) {
+    } elsif ($$et{A100DataOffset}) {
         my $err = 'Unexpected A100DataOffset tag';
-        $outfile and $exifTool->Error($err), return undef;
-        $exifTool->Warn($err);
+        $outfile and $et->Error($err), return undef;
+        $et->Warn($err);
         return 0;
     }
-    my $verbose = $exifTool->Options('Verbose');
+    my $verbose = $et->Options('Verbose');
     my $result;
     if ($outfile) {
-        $result = Image::ExifTool::Exif::WriteExif($exifTool, $dirInfo, $tagTablePtr);
+        $result = Image::ExifTool::Exif::WriteExif($et, $dirInfo, $tagTablePtr);
         return undef unless $result;
         $$outfile .= $result;
 
     } else {
-        $result = Image::ExifTool::Exif::ProcessExif($exifTool, $dirInfo, $tagTablePtr);
+        $result = Image::ExifTool::Exif::ProcessExif($et, $dirInfo, $tagTablePtr);
     }
-    return $result unless $result and $$exifTool{SR2SubIFDOffset};
+    return $result unless $result and $$et{SR2SubIFDOffset};
     # only take first offset value if more than one!
-    my @offsets = split ' ', $exifTool->{SR2SubIFDOffset};
+    my @offsets = split ' ', $$et{SR2SubIFDOffset};
     my $offset = shift @offsets;
-    my $length = $exifTool->{SR2SubIFDLength};
-    my $key = $exifTool->{SR2SubIFDKey};
+    my $length = $$et{SR2SubIFDLength};
+    my $key = $$et{SR2SubIFDKey};
     my @subifdPos;
     if ($offset and $length and defined $key) {
@@ -1860,6 +10997,6 @@
             # display decrypted data in verbose mode
             if ($verbose > 2 and not $outfile) {
-                $exifTool->VerboseDir("Decrypted SR2SubIFD", 0, $length);
-                $exifTool->VerboseDump(\$buff, Addr => $offset + $base);
+                $et->VerboseDir("Decrypted SR2SubIFD", 0, $length);
+                $et->VerboseDump(\$buff, Addr => $offset + $base);
             }
             my $num = '';
@@ -1878,5 +11015,5 @@
                     my $fixup = new Image::ExifTool::Fixup;
                     $dirInfo{Fixup} = $fixup;
-                    $result = $exifTool->WriteDirectory(\%dirInfo, $subTable);
+                    $result = $et->WriteDirectory(\%dirInfo, $subTable);
                     return undef unless $result;
                     # save position of this SubIFD
@@ -1885,7 +11022,7 @@
                     $$fixup{Start} += length($$outfile);
                     $$outfile .= $result;
-                    $dirInfo->{Fixup}->AddFixup($fixup);
+                    $$dirInfo{Fixup}->AddFixup($fixup);
                 } else {
-                    $result = $exifTool->ProcessDirectory(\%dirInfo, $subTable);
+                    $result = $et->ProcessDirectory(\%dirInfo, $subTable);
                 }
                 last unless @offsets;
@@ -1895,5 +11032,5 @@
 
         } else {
-            $exifTool->Warn('Error reading SR2 data');
+            $et->Warn('Error reading SR2 data');
         }
     }
@@ -1907,7 +11044,7 @@
         }
         # save the new SR2SubIFD Length and Key to be used later for encryption
-        $$exifTool{SR2SubIFDLength} = $sr2Len;
-        my $newKey = $$exifTool{VALUE}{SR2SubIFDKey};
-        $$exifTool{SR2SubIFDKey} = $newKey if defined $newKey;
+        $$et{SR2SubIFDLength} = $sr2Len;
+        my $newKey = $$et{VALUE}{SR2SubIFDKey};
+        $$et{SR2SubIFDKey} = $newKey if defined $newKey;
         # update SubIFD pointers manually and add to fixup, and set SR2SubIFDLength
         my $n = Get16u($outfile, 0);
@@ -1921,5 +11058,5 @@
             my $fmt = Get16u($outfile, $entry + 2);
             if ($fmt != 0x04) { # must be int32u
-                $exifTool->Error("Unexpected format ($fmt) for SR2SubIFD tag");
+                $et->Error("Unexpected format ($fmt) for SR2SubIFD tag");
                 return undef;
             }
@@ -1933,5 +11070,5 @@
             foreach $pos (@subifdPos) {
                 Set32u($pos, $outfile, $valuePtr);
-                $dirInfo->{Fixup}->AddFixup($valuePtr, $tag);
+                $$dirInfo{Fixup}->AddFixup($valuePtr, $tag);
                 undef $tag;
                 $valuePtr += 4;
@@ -1939,5 +11076,5 @@
         }
         unless ($found{0x7200} and $found{0x7201}) {
-            $exifTool->Error('Missing SR2SubIFD tag');
+            $et->Error('Missing SR2SubIFD tag');
             return undef;
         }
@@ -1970,5 +11107,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -1985,4 +11122,6 @@
 =item L<http://www.klingebiel.com/tempest/hd/pmp.html>
 
+=item (...plus lots of testing with my RX100!)
+
 =back
 
@@ -1990,6 +11129,6 @@
 
 Thanks to Thomas Bodenmann, Philippe Devaux, Jens Duttke, Marcus
-Holland-Moritz, Andrey Tverdokhleb, Rudiger Lange, Igal Milchtaich and
-Michael Reitinger for help decoding some tags.
+Holland-Moritz, Andrey Tverdokhleb, Rudiger Lange, Igal Milchtaich, Michael
+Reitinger and Jos Roost for help decoding some tags.
 
 =head1 SEE ALSO
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/SonyIDC.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/SonyIDC.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/SonyIDC.pm	(revision 34921)
@@ -12,6 +12,7 @@
 use vars qw($VERSION);
 use Image::ExifTool qw(:DataAccess :Utils);
-
-$VERSION = '1.02';
+use Image::ExifTool::Exif;
+
+$VERSION = '1.08';
 
 # Sony IDC tags (ref PH)
@@ -92,5 +93,10 @@
     0x8016 => { Name => 'SaturationAdj',        Writable => 'int32s' },
     0x8017 => { Name => 'ContrastAdj',          Writable => 'int32s' },
-    0x8018 => { Name => 'BrightnessAdj',        Writable => 'int32s' },
+    0x8018 => {
+        Name => 'BrightnessAdj',
+        Writable => 'int32s',
+        PrintConv => 'sprintf("%.2f", $val/300)', #JR
+        PrintConvInv => '$val * 300',
+    },
     0x8019 => { Name => 'HueAdj',               Writable => 'int32s' },
     0x801a => { Name => 'SharpnessAdj',         Writable => 'int32s' },
@@ -152,4 +158,13 @@
     0x8031 => { Name => 'PeripheralIllumCentralValue',  Writable => 'int32s' },
     0x8032 => { Name => 'PeripheralIllumPeriphValue',   Writable => 'int32s' },
+    0x8040 => { #JR
+        Name => 'DistortionCompensation',
+        Writable => 'int32s',
+        PrintConv => {
+            -1 => 'n/a', # (fixed by lens)
+            1 => 'On',
+            2 => 'Off',
+        },
+    },
     0x9000 => {
         Name => 'ToneCurveBrightnessX',
@@ -192,4 +207,50 @@
         Count => -1,
     },
+    0x900d => { #JR
+        Name => 'ChromaticAberrationCorrection', # "Magnification Chromatic Aberration"
+        Writable => 'int32s',
+        PrintConv => { 1 => 'On', 2 => 'Off' },
+    },
+    0x900e => { #JR
+        Name => 'InclinationCorrection',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x900f => { #JR
+        Name => 'InclinationAngle',
+        Writable => 'int32s',
+        PrintConv => 'sprintf("%.1f deg", $val/1000)',
+        PrintConvInv => 'ToFloat($val) * 1000',
+    },
+    0x9010 => { #JR
+        Name => 'Cropping',
+        Writable => 'int32u',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x9011 => { #JR
+        Name => 'CropArea',
+        Writable => 'int32u',
+        Count => 4,
+    },
+    0x9012 => { #JR
+        Name => 'PreviewImageSize',
+        Writable => 'int32u',
+        Count => 2,
+    },
+    0x9013 => { #JR (ARQ images)
+        Name => 'PxShiftPeriphEdgeNR',
+        Writable => 'int32s',
+        PrintConv => { 0 => 'Off', 1 => 'On' },
+    },
+    0x9014 => { #JR (ARQ images)
+        Name => 'PxShiftPeriphEdgeNRValue',
+        Writable => 'int32s',
+        PrintConv => 'sprintf("%.1f", $val/10)',
+        PrintConvInv => '$val * 10',
+    },
+    0x9017 => { Name => 'WhitesAdj',        Writable => 'int32s' }, #JR
+    0x9018 => { Name => 'BlacksAdj',        Writable => 'int32s' }, #JR
+    0x9019 => { Name => 'HighlightsAdj',    Writable => 'int32s' }, #JR
+    0x901a => { Name => 'ShadowsAdj',       Writable => 'int32s' }, #JR
     0xd000 => { Name => 'CurrentVersion',   Writable => 'int32u' },
     0xd001 => {
@@ -230,4 +291,5 @@
     GROUPS => { 2 => 'Image' },
     IDCPreviewImage => {
+        Groups => { 2 => 'Preview' },
         Require => {
             0 => 'IDCPreviewStart',
@@ -236,4 +298,5 @@
         # extract all preview images (not just one)
         RawConv => q{
+            @grps = $self->GetGroup($$val{0});
             require Image::ExifTool::SonyIDC;
             Image::ExifTool::SonyIDC::ExtractPreviews($self);
@@ -260,5 +323,5 @@
 sub ExtractPreviews($)
 {
-    my $exifTool = shift;
+    my $et = shift;
     my $i = 1;
     my $xtra = ' (1)';
@@ -267,5 +330,5 @@
     for (;;) {
         my $key = "IDCPreviewStart$xtra";
-        unless (defined $$exifTool{VALUE}{$key}) {
+        unless (defined $$et{VALUE}{$key}) {
             last unless $xtra;
             $xtra = ''; # do the last tag extracted last
@@ -273,20 +336,20 @@
         }
         # run through IDC preview images in the same order they were extracted
-        my $off = $exifTool->GetValue($key) or last;
-        my $len = $exifTool->GetValue("IDCPreviewLength$xtra") or last;
+        my $off = $et->GetValue($key, 'ValueConv') or last;
+        my $len = $et->GetValue("IDCPreviewLength$xtra", 'ValueConv') or last;
         # get stack version from number in group 1 name
-        my $grp1 = $exifTool->GetGroup($key, 1);
+        my $grp1 = $et->GetGroup($key, 1);
         if ($grp1 =~ /(\d+)$/) {
             my $tag = "IDCPreviewImage$1";
             unless ($Image::ExifTool::Extra{$tag}) {
-                Image::ExifTool::AddTagToTable(\%Image::ExifTool::Extra, $tag, {
+                AddTagToTable(\%Image::ExifTool::Extra, $tag, {
                     Name => $tag,
-                    Groups => { 0 => 'Composite', 1 => 'Composite', 2 => 'Image'},
+                    Groups => { 0 => 'Composite', 1 => 'Composite', 2 => 'Preview'},
                 });
             }
-            my $val = Image::ExifTool::Exif::ExtractImage($exifTool, $off, $len, $tag);
-            $exifTool->FoundTag($tag, $val);
+            my $val = Image::ExifTool::Exif::ExtractImage($et, $off, $len, $tag);
+            $et->FoundTag($tag, $val, $et->GetGroup($key));
         } else {
-            $preview = Image::ExifTool::Exif::ExtractImage($exifTool, $off, $len, 'IDCPreviewImage');
+            $preview = Image::ExifTool::Exif::ExtractImage($et, $off, $len, 'IDCPreviewImage');
         }
         # step to next set of tags unless we are done
@@ -313,9 +376,9 @@
 
 This module contains definitions required by Image::ExifTool to read and
-write Sony Image Data Converter verson 3.0 metadata in ARW images.
+write Sony Image Data Converter version 3.0 metadata in ARW images.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Stim.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Stim.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Stim.pm	(revision 34921)
@@ -6,5 +6,5 @@
 # Revisions:    06/12/2009 - P. Harvey Created
 #
-# References:   1) http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-006_E.pdf
+# References:   1) http://www.cipa.jp/std/documents/e/DC-006_E.pdf
 #------------------------------------------------------------------------------
 
@@ -14,7 +14,7 @@
 use vars qw($VERSION);
 
-$VERSION = '1.00';
+$VERSION = '1.01';
 
-# Tags found in Stim APP3 segment in JPEG images
+# Tags found in APP3 Stim segment in JPEG images
 %Image::ExifTool::Stim::Main = (
     GROUPS => { 0 => 'Stim', 1 => 'Stim', 2 => 'Image'},
@@ -22,6 +22,6 @@
         These tags are part of the CIPA Stereo Still Image specification, and are
         found in the APP3 "Stim" segment of JPEG images.  See
-        L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-006_E.pdf> for the
-        official specification.
+        L<https://web.archive.org/web/20190718152459/http://www.cipa.jp/std/documents/e/DC-006_E.pdf>
+        for the official specification.
     },
     0 => 'StimVersion',
@@ -175,5 +175,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -184,5 +184,5 @@
 =over 4
 
-=item L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-006_E.pdf>
+=item L<http://www.cipa.jp/std/documents/e/DC-006_E.pdf>
 
 =back
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagInfoXML.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagInfoXML.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagInfoXML.pm	(revision 34921)
@@ -12,18 +12,15 @@
 require Exporter;
 
-use vars qw($VERSION @ISA);
+use vars qw($VERSION @ISA $makeMissing);
 use Image::ExifTool qw(:Utils :Vars);
 use Image::ExifTool::XMP;
 
-$VERSION = '1.15';
+$VERSION = '1.31';
 @ISA = qw(Exporter);
 
 # set this to a language code to generate Lang module with 'MISSING' entries
-my $makeMissing = '';
-
-# set this to true to override existing different descriptions/values
-my $overrideDifferent;
-
-sub LoadLangModules($);
+$makeMissing = '';
+
+sub LoadLangModules($;$);
 sub WriteLangModule($$;$);
 sub NumbersFirst;
@@ -32,13 +29,14 @@
 my %credits = (
     cs   => 'Jens Duttke and Petr MichE<aacute>lek',
-    de   => 'Jens Duttke and Herbert Kauer',
-    es   => 'Jens Duttke and Santiago del BrE<iacute>o GonzE<aacute>lez',
-    fr   => 'Jens Duttke, Bernard Guillotin, Jean Glasser, Jean Piquemal and Harry Nizard',
-    it   => 'Jens Duttke, Ferdinando Agovino and Emilio Dati',
+    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',
+    it   => 'Jens Duttke, Ferdinando Agovino, Emilio Dati and Michele Locati',
     ja   => 'Jens Duttke and Kazunari Nishina',
     ko   => 'Jens Duttke and Jeong Beom Kim',
-    nl   => 'Jens Duttke, Peter Moonen and Herman Beld',
-    pl   => 'Jens Duttke and Przemyslaw Sulek',
-    ru   => 'Jens Duttke, Sergey Shemetov, Dmitry Yerokhin and Anton Sukhinov',
+    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, Anton Sukhinov and Alexander',
     sv   => 'Jens Duttke and BjE<ouml>rn SE<ouml>derstrE<ouml>m',
    'tr'  => 'Jens Duttke, Hasan Yildirim and Cihan Ulusoy',
@@ -58,4 +56,5 @@
 );
 
+my $numbersFirst = 1;   # set to -1 to sort numbers last, or 2 to put negative numbers last
 my $caseInsensitive;    # used internally by sort routine
 
@@ -63,5 +62,5 @@
 # Utility to print tag information database as an XML list
 # Inputs: 0) output file name (undef to send to console),
-#         1) group name (may be undef), 2) options hash ('Flags','NoDesc')
+#         1) group name (may be undef), 2) options hash ('Flags','NoDesc','Lang')
 # Returns: true on success
 sub Write(;$$%)
@@ -69,13 +68,17 @@
     local ($_, *PTIFILE);
     my ($file, $group, %opts) = @_;
-    my @groups = split ':', $group if $group;
-    my $exifTool = new Image::ExifTool;
-    my ($fp, $tableName, %langInfo, @langs, $defaultLang);
+    my $et = new Image::ExifTool;
+    my ($fp, $tableName, %langInfo, @langs, $defaultLang, @groups);
+    @groups = split ':', $group if $group;
 
     Image::ExifTool::LoadAllTables();   # first load all our tables
     unless ($opts{NoDesc}) {
-        LoadLangModules(\%langInfo);    # load all existing Lang modules
-        @langs = sort keys %langInfo;
         $defaultLang = $Image::ExifTool::defaultLang;
+        LoadLangModules(\%langInfo, $opts{Lang}); # load necessary Lang modules
+        if ($opts{Lang}) {
+            @langs = grep /^$opts{Lang}$/i, keys %langInfo;
+        } else {
+            @langs = sort keys %langInfo;
+        }
     }
     if (defined $file) {
@@ -86,4 +89,5 @@
     }
     print $fp "<?xml version='1.0' encoding='UTF-8'?>\n";
+    print $fp "<!-- Generated by Image::ExifTool $Image::ExifTool::VERSION -->\n";
     print $fp "<taginfo>\n\n";
 
@@ -95,9 +99,16 @@
         # sort in same order as tag name documentation
         $caseInsensitive = ($tableName =~ /::XMP::/);
-        my @keys = sort NumbersFirst TagTableKeys($table);
         # get list of languages defining elements in this table
         my $isBinary = ($$table{PROCESS_PROC} and
                         $$table{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData);
-        # loop throug all tag ID's in this table
+        # generate flattened tag names for structure fields if this is an XMP table
+        if ($$table{GROUPS} and $$table{GROUPS}{0} eq 'XMP') {
+            Image::ExifTool::XMP::AddFlattenedTags($table);
+        }
+        $numbersFirst = 2;
+        $numbersFirst = -1 if $$table{VARS} and $$table{VARS}{ALPHA_FIRST};
+        my @keys = sort NumbersFirst TagTableKeys($table);
+        $numbersFirst = 1;
+        # loop through all tag ID's in this table
         foreach $tagID (@keys) {
             my @infoArray = GetTagInfoList($table, $tagID);
@@ -110,5 +121,5 @@
                 next unless $$tagInfo{Writable} or not $$tagInfo{SubDirectory};
                 if (@groups) {
-                    my @tg = $exifTool->GetGroup($tagInfo);
+                    my @tg = $et->GetGroup($tagInfo);
                     foreach $group (@groups) {
                         next PTILoop unless grep /^$group$/i, @tg;
@@ -117,5 +128,5 @@
                 unless ($didTag) {
                     my $tname = $$table{SHORT_NAME};
-                    print $fp "<table name='$tname' g0='$$grps{0}' g1='$$grps{1}' g2='$$grps{2}'>\n";
+                    print $fp "<table name='${tname}' g0='$$grps{0}' g1='$$grps{1}' g2='$$grps{2}'>\n";
                     unless ($opts{NoDesc}) {
                         # print table description
@@ -130,5 +141,5 @@
                             $desc = $langInfo{$_}{$tableName} or next;
                             $desc = Image::ExifTool::XMP::EscapeXML($desc);
-                            print $fp " <desc lang='$_'>$desc</desc>\n";
+                            print $fp " <desc lang='${_}'>$desc</desc>\n";
                         }
                     }
@@ -136,5 +147,5 @@
                 }
                 my $name = $$tagInfo{Name};
-                my $ind = @infoArray > 1 ? " index='$index'" : '';
+                my $ind = @infoArray > 1 ? " index='${index}'" : '';
                 my $format = $$tagInfo{Writable} || $$table{WRITABLE};
                 my $writable = $format ? 'true' : 'false';
@@ -151,4 +162,5 @@
                 }
                 $format = $$tagInfo{Format} || $$table{FORMAT} if not defined $format or $format eq '1';
+                $format = 'struct' if $$tagInfo{Struct};
                 if (defined $format) {
                     $format =~ s/\[.*\$.*\]//;   # remove expressions from format
@@ -160,7 +172,9 @@
                 my $count = '';
                 if ($format =~ s/\[.*?(\d*)\]$//) {
-                    $count = " count='$1'" if length $1;
-                }
-                my @groups = $exifTool->GetGroup($tagInfo);
+                    $count = " count='${1}'" if length $1;
+                } elsif ($$tagInfo{Count} and $$tagInfo{Count} > 1) {
+                    $count = " count='$$tagInfo{Count}'";
+                }
+                my @groups = $et->GetGroup($tagInfo);
                 my $writeGroup = $$tagInfo{WriteGroup} || $$table{WRITE_GROUP};
                 if ($writeGroup and $writeGroup ne 'Comment') {
@@ -179,4 +193,5 @@
                     }
                     push @flags, $$tagInfo{List} if $$tagInfo{List} and $$tagInfo{List} =~ /^(Alt|Bag|Seq)$/;
+                    push @flags, 'Flattened' if defined $$tagInfo{Flat};
                     push @flags, 'Unsafe' if $$tagInfo{Protected} and $$tagInfo{Protected} & 0x01;
                     push @flags, 'Protected' if $$tagInfo{Protected} and $$tagInfo{Protected} & 0x02;
@@ -185,9 +200,11 @@
                     $grp = " flags='" . join(',', sort @flags) . "'$grp" if @flags;
                 }
-                print $fp " <tag id='$xmlID' name='$name'$ind type='$format'$count writable='$writable'$grp";
+                print $fp " <tag id='${xmlID}' name='${name}'$ind type='${format}'$count writable='${writable}'$grp";
                 if ($opts{NoDesc}) {
                     # short output format
                     print $fp "/>\n";   # empty tag element
                     next;               # no descriptions or values
+                } else {
+                    print $fp ">";
                 }
                 my $desc = $$tagInfo{Description};
@@ -206,9 +223,12 @@
                     next if $ld eq $desc;
                     $ld = Image::ExifTool::XMP::EscapeXML($ld);
-                    $altDescr .= "\n  <desc lang='$_'>$ld</desc>";
+                    $altDescr .= "\n  <desc lang='${_}'>$ld</desc>";
                 }
                 # print tag descriptions
                 $desc = Image::ExifTool::XMP::EscapeXML($desc);
-                print $fp ">\n  <desc lang='$defaultLang'>$desc</desc>$altDescr\n";
+                unless ($opts{Lang} and $altDescr) {
+                    print $fp "\n  <desc lang='${defaultLang}'>$desc</desc>";
+                }
+                print $fp "$altDescr\n";
                 for (my $i=0; ; ++$i) {
                     my $conv = $$tagInfo{PrintConv};
@@ -217,5 +237,5 @@
                         last unless $i < @$conv;
                         $conv = $$conv[$i];
-                        $idx = " index='$i'";
+                        $idx = " index='${i}'";
                     } else {
                         last if $i;
@@ -231,5 +251,5 @@
                         foreach $key (keys %{$$conv{BITMASK}}) {
                             my $mask = 0x01 << $key;
-                            next if $$conv{$mask};
+                            next if not $mask or $$conv{$mask};
                             $$conv{$mask} = $$conv{BITMASK}{$key};
                         }
@@ -240,7 +260,7 @@
                         my $xmlVal = Image::ExifTool::XMP::EscapeXML($val);
                         my $xmlKey = Image::ExifTool::XMP::FullEscapeXML($key);
-                        print $fp "   <key id='$xmlKey'>";
-                        print $fp "\n    <val lang='$defaultLang'>$xmlVal</val>\n";
+                        print $fp "   <key id='${xmlKey}'>\n";
                         # add alternate language values
+                        my $altConv = '';
                         foreach (@langConv) {
                             my $lv = $langConv{$_};
@@ -251,7 +271,10 @@
                             next unless defined $lv and $lv ne $val;
                             $lv = Image::ExifTool::XMP::EscapeXML($lv);
-                            print $fp "    <val lang='$_'>$lv</val>\n";
+                            $altConv .= "    <val lang='${_}'>$lv</val>\n";
                         }
-                        print $fp "   </key>\n";
+                        unless ($opts{Lang} and $altConv) {
+                            print $fp "    <val lang='${defaultLang}'>$xmlVal</val>\n"
+                        }
+                        print $fp "$altConv   </key>\n";
                     }
                     print $fp "  </values>\n";
@@ -266,30 +289,4 @@
     close $fp or $success = 0 if defined $file;
     return $success;
-}
-
-#------------------------------------------------------------------------------
-# Perl-ize this constant
-# Inputs: string
-# Returns: constant string for Perl
-sub Perlize($)
-{
-    my $str = shift;
-    unless (($str =~ /^[+-]?(?=\d|\.\d)\d*(\.\d*)?$/ and # int or float
-             not $str =~ /^[+-]?0\d+$/) or # not octal
-            $str =~ /^0x[0-9a-f]+$/i) # hexadecimal
-    {
-        # translate unprintable characters
-        $str =~ s/\\/\\\\/g; # escape backslashes
-        if ($str =~ /([\x00-\x1f\x80-\xff])/) {
-            $str =~ s/"/\\"/g; # escape double quotes
-            # escape unprintable characters
-            $str =~ s/([\x00-\x1f\x80-\xff])/sprintf("\\x%.2x",ord $1)/eg;
-            $str = qq{"$str"};
-        } else {
-            $str =~ s/'/\\'/g; # escape single quotes
-            $str = qq{'$str'};
-        }
-    }
-    return $str;
 }
 
@@ -308,9 +305,9 @@
 #------------------------------------------------------------------------------
 # Generate Lang modules from input tag info XML database
-# Inputs: 0) XML filename, 1) update flag:
-#       undef = default (update changed modules only)
-#       0 = (update changed modules only, but preserve version numbers)
-#       1 = (update all, but preserve version numbers)
-#       2 = (update all from scratch, but preserve version numbers)
+# Inputs: 0) XML filename, 1) update flags:
+#       0x01 = preserve version numbers
+#       0x02 = update all modules, even if they didn't change
+#       0x04 = update from scratch, ignoring existing definitions
+#       0x08 = override existing different descriptions and values
 # Returns: Count of updated Lang modules, or -1 on error
 # Notes: Must be run from the directory containing 'lib'
@@ -318,11 +315,19 @@
 {
     local ($_, *XFILE);
-    my ($file, $forceUpdate) = @_;
-    my ($table, $tableName, $id, $index, $valIndex, $name, $key, $lang);
-    my (%langInfo, %different, %changed);
+    my ($file, $updateFlag) = @_;
+    my ($table, $tableName, $id, $index, $valIndex, $name, $key, $lang, $defDesc);
+    my (%langInfo, %different, %changed, $overrideDifferent);
 
     Image::ExifTool::LoadAllTables();   # first load all our tables
+    # generate our flattened tags
+    foreach $tableName (sort keys %allTables) {
+        my $table = GetTagTable($tableName);
+        next unless $$table{GROUPS} and $$table{GROUPS}{0} eq 'XMP';
+        Image::ExifTool::XMP::AddFlattenedTags($table);
+    }
     LoadLangModules(\%langInfo);        # load all existing Lang modules
-    %langInfo = () if $forceUpdate and $forceUpdate eq '2';
+    $updateFlag = 0 unless $updateFlag;
+    %langInfo = () if $updateFlag & 0x04;
+    $overrideDifferent = 1 if $updateFlag & 0x08;
 
     if (defined $file) {
@@ -337,4 +342,5 @@
                     undef $index;
                     undef $name;
+                    undef $defDesc;
                 } elsif ($tok eq 'values') {
                     undef $key;
@@ -361,5 +367,10 @@
                 $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;
             }
@@ -381,8 +392,10 @@
                 my $tval = Image::ExifTool::XMP::UnescapeXML($3);
                 my $val = ucfirst $tval;
+                $val = $tval if $tval =~ /^(cRAW|iTun)/; # special-case non-capitalized values
                 my $cap = ($tval ne $val);
                 if ($makeMissing and $lang eq 'en') {
                     $lang = $makeMissing;
                     $val = 'MISSING';
+                    undef $cap;
                 }
                 my $isDefault = ($lang eq $Image::ExifTool::defaultLang);
@@ -399,11 +412,11 @@
                     $langInfo{$lang}{$tableName} = $val;
                     $changed{$lang} = 1;
-                    warn("Capitalized '$lang' val for $name: $val\n") if $cap;
+                    warn("Capitalized '${lang}' val for $name: $val\n") if $cap;
                     next;
                 }
                 my @infoArray = GetTagInfoList($table, $id);
-    
+
                 # this will fail for UserDefined tags and tags without ID's
-                @infoArray or warn("Error loading tag for $tableName ID='$id'\n"), next;
+                @infoArray or warn("Error loading tag for $tableName ID='${id}'\n"), next;
                 my ($tagInfo, $langInfo);
                 if (defined $index) {
@@ -419,4 +432,5 @@
                         $$tagInfo{Description} = Image::ExifTool::MakeDescription($tagName);
                     }
+                    $defDesc = $$tagInfo{Description};
                     $langInfo = $tagInfo;
                 } else {
@@ -438,5 +452,5 @@
                         unless (defined $different{$t} and $different{$t} eq $val) {
                             my $a = defined $different{$t} ? 'ANOTHER ' : '';
-                            warn "${a}Different '$lang' desc for $tagName: $val (was $$langInfo{Description})\n";
+                            warn "${a}Different '${lang}' desc for $tagName: $val (was $$langInfo{Description})\n";
                             next if defined $different{$t}; # don't change back again
                             $different{$t} = $val;
@@ -445,5 +459,9 @@
                     }
                     next if $isDefault;
-                    $$langInfo{Description} = $val;
+                    if (defined $defDesc and $defDesc eq $val) {
+                        delete $$langInfo{Description}; # delete if same as default language
+                    } else {
+                        $$langInfo{Description} = $val;
+                    }
                 } else {
                     defined $key or warn("No key for $$tagInfo{Name}"), next;
@@ -458,10 +476,15 @@
                         if ($$printConv{BITMASK} and $key =~ /^\d+$/) {
                             my $i;
-                            for ($i=0; $i<32; ++$i) {
-                                next unless $key == (0x01 << $i);
+                            for ($i=0; $i<64; ++$i) {
+                                my $mask = (0x01 << $i) or last;
+                                next unless $key == $mask;
                                 $convVal = $$printConv{BITMASK}{$i};
                             }
                         }
-                        warn("Missing PrintConv entry for $key") and next unless defined $convVal;
+                        warn("Missing PrintConv entry for $tableName $$tagInfo{Name} $key\n") and next unless defined $convVal;
+                    }
+                    if ($cap and $convVal =~ /^[a-z]/) {
+                        $val = lcfirst $val;    # change back to lower case
+                        undef $cap;
                     }
                     my $lc = $$langInfo{PrintConv};
@@ -476,5 +499,5 @@
                         unless (defined $different{$t} and $different{$t} eq $val) {
                             my $a = defined $different{$t} ? 'ANOTHER ' : '';
-                            warn "${a}Different '$lang' val for $tagName '$convVal': $val (was $oldVal)\n";
+                            warn "${a}Different '${lang}' val for $tagName '${convVal}': $val (was $oldVal)\n";
                             next if defined $different{$t}; # don't change back again
                             $different{$t} = $val;
@@ -483,5 +506,5 @@
                     }
                     next if $isDefault;
-                    warn("Capitalized '$lang' val for $tagName: $tval\n") if $cap;
+                    warn("Capitalized '${lang}' val for $tagName: $tval\n") if $cap;
                     $$lc{$convVal} = $val;
                 }
@@ -493,9 +516,9 @@
     # rewrite all changed Lang modules
     my $rtnVal = 0;
-    foreach $lang ($forceUpdate ? @Image::ExifTool::langs : sort keys %changed) {
+    foreach $lang ($updateFlag & 0x02 ? @Image::ExifTool::langs : sort keys %changed) {
         next if $lang eq $Image::ExifTool::defaultLang;
         ++$rtnVal;
         # write this module (only increment version number if not forced)
-        WriteLangModule($lang, $langInfo{$lang}, not defined $forceUpdate) or $rtnVal = -1, last;
+        WriteLangModule($lang, $langInfo{$lang}, not $updateFlag & 0x01) or $rtnVal = -1, last;
     }
     return $rtnVal;
@@ -541,5 +564,5 @@
 use vars qw(\$VERSION);
 
-\$VERSION = '$ver';
+\$VERSION = '${ver}';
 
 HEADER
@@ -570,11 +593,11 @@
             next unless $conv;
         }
-        print XOUT "   '$tag' => ";
+        print XOUT "   '${tag}' => ";
         unless ($conv) {
-            print XOUT "'$desc',\n";
+            print XOUT "'${desc}',\n";
             next;
         }
         print XOUT "{\n";
-        print XOUT "      Description => '$desc',\n" if defined $desc;
+        print XOUT "      Description => '${desc}',\n" if defined $desc;
         if ($conv) {
             print XOUT "      PrintConv => {\n";
@@ -582,5 +605,5 @@
                 my $str = EscapePerl($_);
                 my $val = EscapePerl($$conv{$_});
-                print XOUT "        '$str' => '$val',\n";
+                print XOUT "        '${str}' => '${val}',\n";
             }
             print XOUT "      },\n";
@@ -602,5 +625,4 @@
 1;  # end
 
-
 __END__
 
@@ -616,5 +638,5 @@
 ~head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -641,11 +663,11 @@
 #------------------------------------------------------------------------------
 # load all lang modules into hash
-# Inputs: 0) Hash reference
-sub LoadLangModules($)
+# Inputs: 0) Hash reference, 1) specific language to load (undef for all)
+sub LoadLangModules($;$)
 {
-    my $langHash = shift;
-    my $lang;
+    my ($langHash, $lang) = @_;
     require Image::ExifTool;
-    foreach $lang (@Image::ExifTool::langs) {
+    my @langs = $lang ? ($lang) : @Image::ExifTool::langs;
+    foreach $lang (@langs) {
         next if $lang eq $Image::ExifTool::defaultLang;
         eval "require Image::ExifTool::Lang::$lang" or warn("Can't load Lang::$lang\n"), next;
@@ -663,14 +685,30 @@
 {
     my $rtnVal;
-    my $bNum = ($b =~ /^-?[0-9]+(\.\d*)?$/);
-    if ($a =~ /^-?[0-9]+(\.\d*)?$/) {
-        $rtnVal = ($bNum ? $a <=> $b : -1);
-    } elsif ($bNum) {
-        $rtnVal = 1;
+    my ($bNum, $bDec);
+    ($bNum, $bDec) = ($1, $3) if $b =~ /^(-?[0-9]+)(\.(\d*))?$/;
+    if ($a =~ /^(-?[0-9]+)(\.(\d*))?$/) {
+        if (defined $bNum) {
+            $bNum += 1e9 if $numbersFirst == 2 and $bNum < 0;
+            my $aInt = $1;
+            $aInt += 1e9 if $numbersFirst == 2 and $aInt < 0;
+            # compare integer part as a number
+            $rtnVal = $aInt <=> $bNum;
+            unless ($rtnVal) {
+                my $aDec = $3 || 0;
+                $bDec or $bDec = 0;
+                # compare decimal part as an integer too
+                # (so that "1.10" comes after "1.9")
+                $rtnVal = $aDec <=> $bDec;
+            }
+        } else {
+            $rtnVal = -$numbersFirst;
+        }
+    } elsif (defined $bNum) {
+        $rtnVal = $numbersFirst;
     } else {
         my ($a2, $b2) = ($a, $b);
         # expand numbers to 3 digits (with restrictions to avoid messing up ascii-hex tags)
-        $a2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $a2 =~ /^(APP)?[.0-9 ]*$/ and length($a2)<16;
-        $b2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $b2 =~ /^(APP)?[.0-9 ]*$/ and length($b2)<16;
+        $a2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $a2 =~ /^(APP|DMC-\w+ )?[.0-9 ]*$/ and length($a2)<16;
+        $b2 =~ s/(\d+)/sprintf("%.3d",$1)/eg if $b2 =~ /^(APP|DMC-\w+ )?[.0-9 ]*$/ and length($b2)<16;
         $caseInsensitive and $rtnVal = (lc($a2) cmp lc($b2));
         $rtnVal or $rtnVal = ($a2 cmp $b2);
@@ -724,4 +762,5 @@
     Flags   - Set to output 'flags' attribute
     NoDesc  - Set to suppress output of descriptions
+    Lang    - Select a single language for output
 
 =item Return Value:
@@ -768,4 +807,11 @@
 0) XML file name
 
+1) Update flags:
+
+    0x01 = preserve version numbers
+    0x02 = update all modules, even if they didn't change
+    0x04 = update from scratch, ignoring existing definitions
+    0x08 = override existing different descriptions and values
+
 =item Return Value:
 
@@ -776,5 +822,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagLookup.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagLookup.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagLookup.pm	(revision 34921)
@@ -6,5 +6,6 @@
 # Notes:        This lookup is used to look up tag names for writing
 #
-# Revisions:    12/31/2004  - P. Harvey Created
+# Revisions:    2004-12-31 - P. Harvey Created
+#               2013-01-06 - PH Allow wildcards in FindTagInfo()
 #------------------------------------------------------------------------------
 
@@ -17,5 +18,5 @@
 use Image::ExifTool qw(:Utils);
 
-$VERSION = '1.07';
+$VERSION = '1.18';
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(FindTagInfo TagExists);
@@ -33,9 +34,13 @@
 my @tableList = (
 	'Image::ExifTool::APP12::Ducky',
+	'Image::ExifTool::Apple::Main',
+	'Image::ExifTool::Canon::AFConfig',
 	'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',
 	'Image::ExifTool::Canon::CameraInfo1DmkII',
 	'Image::ExifTool::Canon::CameraInfo1DmkIII',
@@ -49,16 +54,25 @@
 	'Image::ExifTool::Canon::CameraInfo5D',
 	'Image::ExifTool::Canon::CameraInfo5DmkII',
-	'Image::ExifTool::Canon::CameraInfo5DmkII_2',
+	'Image::ExifTool::Canon::CameraInfo5DmkIII',
+	'Image::ExifTool::Canon::CameraInfo600D',
 	'Image::ExifTool::Canon::CameraInfo60D',
+	'Image::ExifTool::Canon::CameraInfo650D',
+	'Image::ExifTool::Canon::CameraInfo6D',
+	'Image::ExifTool::Canon::CameraInfo70D',
+	'Image::ExifTool::Canon::CameraInfo750D',
 	'Image::ExifTool::Canon::CameraInfo7D',
-	'Image::ExifTool::Canon::CameraInfo7D_2',
+	'Image::ExifTool::Canon::CameraInfo80D',
 	'Image::ExifTool::Canon::CameraInfoPowerShot',
 	'Image::ExifTool::Canon::CameraInfoPowerShot2',
+	'Image::ExifTool::Canon::CameraInfoUnknown',
 	'Image::ExifTool::Canon::CameraInfoUnknown32',
 	'Image::ExifTool::Canon::CameraSettings',
 	'Image::ExifTool::Canon::ColorBalance',
 	'Image::ExifTool::Canon::ColorCalib',
+	'Image::ExifTool::Canon::ColorCalib2',
 	'Image::ExifTool::Canon::ColorCoefs',
+	'Image::ExifTool::Canon::ColorCoefs2',
 	'Image::ExifTool::Canon::ColorData1',
+	'Image::ExifTool::Canon::ColorData10',
 	'Image::ExifTool::Canon::ColorData2',
 	'Image::ExifTool::Canon::ColorData3',
@@ -66,11 +80,17 @@
 	'Image::ExifTool::Canon::ColorData5',
 	'Image::ExifTool::Canon::ColorData6',
+	'Image::ExifTool::Canon::ColorData7',
+	'Image::ExifTool::Canon::ColorData8',
+	'Image::ExifTool::Canon::ColorData9',
 	'Image::ExifTool::Canon::ColorInfo',
+	'Image::ExifTool::Canon::ContrastInfo',
 	'Image::ExifTool::Canon::CropInfo',
 	'Image::ExifTool::Canon::FaceDetect1',
 	'Image::ExifTool::Canon::FaceDetect2',
+	'Image::ExifTool::Canon::FaceDetect3',
 	'Image::ExifTool::Canon::FileInfo',
 	'Image::ExifTool::Canon::Flags',
 	'Image::ExifTool::Canon::FocalLength',
+	'Image::ExifTool::Canon::HDRInfo',
 	'Image::ExifTool::Canon::LensInfo',
 	'Image::ExifTool::Canon::LightingOpt',
@@ -79,4 +99,5 @@
 	'Image::ExifTool::Canon::ModifiedInfo',
 	'Image::ExifTool::Canon::MovieInfo',
+	'Image::ExifTool::Canon::MultiExp',
 	'Image::ExifTool::Canon::MyColors',
 	'Image::ExifTool::Canon::PSInfo',
@@ -85,8 +106,11 @@
 	'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',
@@ -108,5 +132,11 @@
 	'Image::ExifTool::CanonRaw::RawJpgInfo',
 	'Image::ExifTool::CanonRaw::TimeStamp',
+	'Image::ExifTool::CanonVRD::CropInfo',
+	'Image::ExifTool::CanonVRD::DLOInfo',
+	'Image::ExifTool::CanonVRD::DR4',
+	'Image::ExifTool::CanonVRD::DR4Header',
+	'Image::ExifTool::CanonVRD::GammaInfo',
 	'Image::ExifTool::CanonVRD::Main',
+	'Image::ExifTool::CanonVRD::ToneCurve',
 	'Image::ExifTool::CanonVRD::Ver1',
 	'Image::ExifTool::CanonVRD::Ver2',
@@ -116,10 +146,18 @@
 	'Image::ExifTool::Casio::Type2',
 	'Image::ExifTool::Composite',
+	'Image::ExifTool::DJI::Main',
+	'Image::ExifTool::DJI::XMP',
 	'Image::ExifTool::DNG::AdobeData',
+	'Image::ExifTool::DarwinCore::Main',
 	'Image::ExifTool::Exif::Main',
 	'Image::ExifTool::Extra',
+	'Image::ExifTool::FLIR::Main',
 	'Image::ExifTool::FotoStation::Main',
 	'Image::ExifTool::FotoStation::SoftEdit',
+	'Image::ExifTool::FujiFilm::AFCSettings',
+	'Image::ExifTool::FujiFilm::DriveSettings',
+	'Image::ExifTool::FujiFilm::FocusSettings',
 	'Image::ExifTool::FujiFilm::Main',
+	'Image::ExifTool::FujiFilm::PrioritySettings',
 	'Image::ExifTool::GE::Main',
 	'Image::ExifTool::GPS::Main',
@@ -128,4 +166,5 @@
 	'Image::ExifTool::IPTC::NewsPhoto',
 	'Image::ExifTool::JFIF::Main',
+	'Image::ExifTool::Jpeg2000::Main',
 	'Image::ExifTool::Kodak::CameraInfo',
 	'Image::ExifTool::Kodak::IFD',
@@ -142,4 +181,6 @@
 	'Image::ExifTool::Kodak::Type3',
 	'Image::ExifTool::Kodak::Type4',
+	'Image::ExifTool::Kodak::Type5',
+	'Image::ExifTool::Kodak::Type6',
 	'Image::ExifTool::Kodak::Type7',
 	'Image::ExifTool::Kodak::Type9',
@@ -159,12 +200,19 @@
 	'Image::ExifTool::MIE::UTM',
 	'Image::ExifTool::MIE::Video',
+	'Image::ExifTool::MWG::Collections',
+	'Image::ExifTool::MWG::Keywords',
+	'Image::ExifTool::MWG::Regions',
+	'Image::ExifTool::MacOS::MDItem',
+	'Image::ExifTool::MacOS::XAttr',
 	'Image::ExifTool::Microsoft::MP',
 	'Image::ExifTool::Microsoft::MP1',
 	'Image::ExifTool::Microsoft::Stitch',
 	'Image::ExifTool::Microsoft::XMP',
+	'Image::ExifTool::Minolta::CameraInfoA100',
 	'Image::ExifTool::Minolta::CameraSettings',
 	'Image::ExifTool::Minolta::CameraSettings5D',
 	'Image::ExifTool::Minolta::CameraSettings7D',
 	'Image::ExifTool::Minolta::CameraSettingsA100',
+	'Image::ExifTool::Minolta::ISInfoA100',
 	'Image::ExifTool::Minolta::Main',
 	'Image::ExifTool::Minolta::WBInfoA100',
@@ -172,7 +220,9 @@
 	'Image::ExifTool::MinoltaRaw::RIF',
 	'Image::ExifTool::MinoltaRaw::WBG',
+	'Image::ExifTool::Motorola::Main',
 	'Image::ExifTool::Nikon::AFInfo',
 	'Image::ExifTool::Nikon::AFInfo2',
 	'Image::ExifTool::Nikon::AFTune',
+	'Image::ExifTool::Nikon::BarometerInfo',
 	'Image::ExifTool::Nikon::CaptureOutput',
 	'Image::ExifTool::Nikon::ColorBalance1',
@@ -181,4 +231,7 @@
 	'Image::ExifTool::Nikon::ColorBalance4',
 	'Image::ExifTool::Nikon::ColorBalanceA',
+	'Image::ExifTool::Nikon::ColorBalanceB',
+	'Image::ExifTool::Nikon::ColorBalanceC',
+	'Image::ExifTool::Nikon::ColorBalanceUnknown',
 	'Image::ExifTool::Nikon::DistortInfo',
 	'Image::ExifTool::Nikon::FaceDetect',
@@ -187,14 +240,26 @@
 	'Image::ExifTool::Nikon::FlashInfo0102',
 	'Image::ExifTool::Nikon::FlashInfo0103',
+	'Image::ExifTool::Nikon::FlashInfo0106',
+	'Image::ExifTool::Nikon::FlashInfo0107',
+	'Image::ExifTool::Nikon::FlashInfo0300',
 	'Image::ExifTool::Nikon::GEM',
+	'Image::ExifTool::Nikon::HDRInfo',
 	'Image::ExifTool::Nikon::ISOInfo',
 	'Image::ExifTool::Nikon::LensData00',
 	'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',
 	'Image::ExifTool::Nikon::Scan',
 	'Image::ExifTool::Nikon::ShotInfo',
@@ -207,9 +272,18 @@
 	'Image::ExifTool::Nikon::ShotInfoD3b',
 	'Image::ExifTool::Nikon::ShotInfoD40',
+	'Image::ExifTool::Nikon::ShotInfoD4S',
+	'Image::ExifTool::Nikon::ShotInfoD500',
 	'Image::ExifTool::Nikon::ShotInfoD5000',
+	'Image::ExifTool::Nikon::ShotInfoD5100',
+	'Image::ExifTool::Nikon::ShotInfoD5200',
+	'Image::ExifTool::Nikon::ShotInfoD6',
 	'Image::ExifTool::Nikon::ShotInfoD700',
 	'Image::ExifTool::Nikon::ShotInfoD7000',
 	'Image::ExifTool::Nikon::ShotInfoD80',
+	'Image::ExifTool::Nikon::ShotInfoD800',
+	'Image::ExifTool::Nikon::ShotInfoD810',
+	'Image::ExifTool::Nikon::ShotInfoD850',
 	'Image::ExifTool::Nikon::ShotInfoD90',
+	'Image::ExifTool::Nikon::ShotInfoZ7_2',
 	'Image::ExifTool::Nikon::Type2',
 	'Image::ExifTool::Nikon::VRInfo',
@@ -230,10 +304,20 @@
 	'Image::ExifTool::NikonCapture::WBAdjData',
 	'Image::ExifTool::NikonCustom::SettingsD3',
+	'Image::ExifTool::NikonCustom::SettingsD4',
 	'Image::ExifTool::NikonCustom::SettingsD40',
+	'Image::ExifTool::NikonCustom::SettingsD5',
+	'Image::ExifTool::NikonCustom::SettingsD500',
 	'Image::ExifTool::NikonCustom::SettingsD5000',
+	'Image::ExifTool::NikonCustom::SettingsD5100',
+	'Image::ExifTool::NikonCustom::SettingsD5200',
+	'Image::ExifTool::NikonCustom::SettingsD610',
 	'Image::ExifTool::NikonCustom::SettingsD700',
 	'Image::ExifTool::NikonCustom::SettingsD7000',
 	'Image::ExifTool::NikonCustom::SettingsD80',
+	'Image::ExifTool::NikonCustom::SettingsD800',
+	'Image::ExifTool::NikonCustom::SettingsD810',
+	'Image::ExifTool::NikonCustom::SettingsD850',
 	'Image::ExifTool::NikonCustom::SettingsD90',
+	'Image::ExifTool::Nintendo::CameraInfo',
 	'Image::ExifTool::Olympus::CameraSettings',
 	'Image::ExifTool::Olympus::Equipment',
@@ -246,19 +330,30 @@
 	'Image::ExifTool::Olympus::RawInfo',
 	'Image::ExifTool::PDF::Info',
+	'Image::ExifTool::PLUS::XMP',
 	'Image::ExifTool::PNG::Main',
+	'Image::ExifTool::PNG::PhysicalPixel',
 	'Image::ExifTool::PNG::TextualData',
 	'Image::ExifTool::Panasonic::Data1',
 	'Image::ExifTool::Panasonic::FaceDetInfo',
 	'Image::ExifTool::Panasonic::FaceRecInfo',
+	'Image::ExifTool::Panasonic::FocusInfo',
 	'Image::ExifTool::Panasonic::Leica2',
 	'Image::ExifTool::Panasonic::Leica3',
 	'Image::ExifTool::Panasonic::Leica5',
 	'Image::ExifTool::Panasonic::Leica6',
-	'Image::ExifTool::Panasonic::LensInfo',
+	'Image::ExifTool::Panasonic::Leica9',
 	'Image::ExifTool::Panasonic::Main',
+	'Image::ExifTool::Panasonic::ShotInfo',
 	'Image::ExifTool::Panasonic::Subdir',
+	'Image::ExifTool::Panasonic::TimeInfo',
+	'Image::ExifTool::PanasonicRaw::DistortionInfo',
 	'Image::ExifTool::PanasonicRaw::Main',
+	'Image::ExifTool::PanasonicRaw::WBInfo',
+	'Image::ExifTool::PanasonicRaw::WBInfo2',
 	'Image::ExifTool::Pentax::AEInfo',
+	'Image::ExifTool::Pentax::AEInfo2',
+	'Image::ExifTool::Pentax::AEInfo3',
 	'Image::ExifTool::Pentax::AFInfo',
+	'Image::ExifTool::Pentax::AFPointInfo',
 	'Image::ExifTool::Pentax::AWBInfo',
 	'Image::ExifTool::Pentax::BatteryInfo',
@@ -272,4 +367,5 @@
 	'Image::ExifTool::Pentax::FilterInfo',
 	'Image::ExifTool::Pentax::FlashInfo',
+	'Image::ExifTool::Pentax::KelvinWB',
 	'Image::ExifTool::Pentax::LensCorr',
 	'Image::ExifTool::Pentax::LensData',
@@ -278,11 +374,19 @@
 	'Image::ExifTool::Pentax::LensInfo3',
 	'Image::ExifTool::Pentax::LensInfo4',
+	'Image::ExifTool::Pentax::LensInfo5',
+	'Image::ExifTool::Pentax::LensInfoQ',
+	'Image::ExifTool::Pentax::LensRec',
 	'Image::ExifTool::Pentax::LevelInfo',
 	'Image::ExifTool::Pentax::Main',
+	'Image::ExifTool::Pentax::PixelShiftInfo',
 	'Image::ExifTool::Pentax::SRInfo',
+	'Image::ExifTool::Pentax::SRInfo2',
 	'Image::ExifTool::Pentax::ShotInfo',
-	'Image::ExifTool::Pentax::TempInfoK5',
+	'Image::ExifTool::Pentax::TempInfo',
 	'Image::ExifTool::Pentax::TimeInfo',
 	'Image::ExifTool::Pentax::Type2',
+	'Image::ExifTool::Pentax::WBLevels',
+	'Image::ExifTool::PhaseOne::Main',
+	'Image::ExifTool::PhaseOne::SensorCalibration',
 	'Image::ExifTool::PhotoMechanic::SoftEdit',
 	'Image::ExifTool::PhotoMechanic::XMP',
@@ -291,5 +395,16 @@
 	'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',
@@ -298,26 +413,93 @@
 	'Image::ExifTool::Ricoh::SerialInfo',
 	'Image::ExifTool::Ricoh::Subdir',
-	'Image::ExifTool::Samsung::Type1',
+	'Image::ExifTool::Ricoh::ThetaSubdir',
+	'Image::ExifTool::Samsung::Main',
+	'Image::ExifTool::Samsung::OrientationInfo',
+	'Image::ExifTool::Samsung::PictureWizard',
 	'Image::ExifTool::Samsung::Type2',
 	'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',
+	'Image::ExifTool::Sony::AFStatus79',
+	'Image::ExifTool::Sony::CameraInfo',
+	'Image::ExifTool::Sony::CameraInfo2',
+	'Image::ExifTool::Sony::CameraInfo3',
 	'Image::ExifTool::Sony::CameraSettings',
 	'Image::ExifTool::Sony::CameraSettings2',
+	'Image::ExifTool::Sony::CameraSettings3',
 	'Image::ExifTool::Sony::Ericsson',
+	'Image::ExifTool::Sony::ExtraInfo',
+	'Image::ExifTool::Sony::ExtraInfo2',
+	'Image::ExifTool::Sony::ExtraInfo3',
+	'Image::ExifTool::Sony::FaceInfo',
 	'Image::ExifTool::Sony::FaceInfo1',
 	'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',
+	'Image::ExifTool::Sony::MoreInfo0201',
+	'Image::ExifTool::Sony::MoreInfo0401',
+	'Image::ExifTool::Sony::MoreSettings',
 	'Image::ExifTool::Sony::Panorama',
 	'Image::ExifTool::Sony::ShotInfo',
+	'Image::ExifTool::Sony::Tag2010a',
+	'Image::ExifTool::Sony::Tag2010b',
+	'Image::ExifTool::Sony::Tag2010c',
+	'Image::ExifTool::Sony::Tag2010d',
+	'Image::ExifTool::Sony::Tag2010e',
+	'Image::ExifTool::Sony::Tag2010f',
+	'Image::ExifTool::Sony::Tag2010g',
+	'Image::ExifTool::Sony::Tag2010h',
+	'Image::ExifTool::Sony::Tag2010i',
+	'Image::ExifTool::Sony::Tag202a',
+	'Image::ExifTool::Sony::Tag9050a',
+	'Image::ExifTool::Sony::Tag9050b',
+	'Image::ExifTool::Sony::Tag9050c',
+	'Image::ExifTool::Sony::Tag9400a',
+	'Image::ExifTool::Sony::Tag9400b',
+	'Image::ExifTool::Sony::Tag9400c',
+	'Image::ExifTool::Sony::Tag9402',
+	'Image::ExifTool::Sony::Tag9403',
+	'Image::ExifTool::Sony::Tag9404a',
+	'Image::ExifTool::Sony::Tag9404b',
+	'Image::ExifTool::Sony::Tag9404c',
+	'Image::ExifTool::Sony::Tag9405a',
+	'Image::ExifTool::Sony::Tag9405b',
+	'Image::ExifTool::Sony::Tag9406',
+	'Image::ExifTool::Sony::Tag940a',
+	'Image::ExifTool::Sony::Tag940c',
 	'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',
+	'Image::ExifTool::XMP::GPano',
+	'Image::ExifTool::XMP::GSpherical',
+	'Image::ExifTool::XMP::GettyImages',
+	'Image::ExifTool::XMP::LImage',
 	'Image::ExifTool::XMP::Lightroom',
 	'Image::ExifTool::XMP::MediaPro',
+	'Image::ExifTool::XMP::aas',
 	'Image::ExifTool::XMP::acdsee',
+	'Image::ExifTool::XMP::apple_fi',
 	'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',
@@ -325,14 +507,16 @@
 	'Image::ExifTool::XMP::digiKam',
 	'Image::ExifTool::XMP::exif',
+	'Image::ExifTool::XMP::exifEX',
+	'Image::ExifTool::XMP::extensis',
+	'Image::ExifTool::XMP::fpv',
+	'Image::ExifTool::XMP::ics',
 	'Image::ExifTool::XMP::iptcCore',
 	'Image::ExifTool::XMP::iptcExt',
-	'Image::ExifTool::XMP::mwg_coll',
-	'Image::ExifTool::XMP::mwg_kw',
-	'Image::ExifTool::XMP::mwg_rs',
 	'Image::ExifTool::XMP::pdf',
 	'Image::ExifTool::XMP::photoshop',
-	'Image::ExifTool::XMP::plus',
+	'Image::ExifTool::XMP::pmi',
 	'Image::ExifTool::XMP::prism',
 	'Image::ExifTool::XMP::prl',
+	'Image::ExifTool::XMP::prm',
 	'Image::ExifTool::XMP::pur',
 	'Image::ExifTool::XMP::rdf',
@@ -352,3167 +536,5859 @@
 # lookup for all writable tags
 my %tagLookup = (
-	'aberrationcorrectiondistance' => { 78 => 0x69 },
-	'about' => { 304 => 'about' },
-	'abspeakaudiofilepath' => { 310 => 'absPeakAudioFilePath' },
-	'accessorytype' => { 224 => 0x53 },
-	'actionadvised' => { 92 => 0x2a },
-	'activearea' => { 85 => 0xc68d },
-	'actived-lighting' => { 160 => 0x22, 188 => 0x24 },
-	'actived-lightingmode' => { 188 => 0x25 },
-	'addaspectratioinfo' => { 59 => 0x80e },
-	'additionalmodelinformation' => { 294 => 'AddlModelInfo' },
-	'addoriginaldecisiondata' => { 59 => 0x80f, 60 => 0x11, 61 => 0x13, 64 => 0x14 },
-	'address' => { 118 => 'Address' },
-	'adjustmentmode' => { 270 => 0x15 },
-	'adultcontentwarning' => { 300 => 'AdultContentWarning', 303 => 'adultContentWarning' },
-	'advancedraw' => { 190 => 0x76a43203 },
-	'advancedscenemode' => { 224 => 0x3d },
-	'advisory' => { 308 => 'Advisory' },
-	'ae_iso' => { 227 => 0x2 },
-	'aeaperture' => { 227 => 0x1 },
-	'aebautocancel' => { 59 => 0x104 },
-	'aebbracketvalue' => { 54 => 0x11 },
-	'aebsequence' => { 59 => 0x105 },
-	'aebsequenceautocancel' => { 57 => 0x9, 58 => 0x9, 60 => 0x8, 61 => 0x9, 64 => 0x9, 65 => 0x7 },
-	'aebshotcount' => { 59 => 0x106 },
-	'aebxv' => { 227 => 0x4 },
-	'aeexposuretime' => { 227 => 0x0 },
-	'aelbutton' => { 134 => 0x45 },
-	'aelexposureindicator' => { 134 => 0x51 },
-	'aelock' => { 134 => 0x5b, 198 => '4.2', 202 => '4.2', 204 => 0x201, 247 => 0x48 },
-	'aelockbutton' => { 197 => '16.1', 198 => '4.1', 199 => '15.1', 200 => '30.1', 201 => '16.1', 202 => '4.1', 203 => '17.1' },
-	'aelockbuttonplusdials' => { 197 => '16.2', 200 => '32.1' },
-	'aelockformb-d80' => { 203 => '3.1' },
-	'aemaxaperture' => { 227 => 0x9 },
-	'aemaxaperture2' => { 227 => 0xa },
-	'aemeteringmode' => { 227 => 0xc },
-	'aemeteringsegments' => { 247 => 0x209 },
-	'aemicroadjustment' => { 59 => 0x111 },
-	'aeminaperture' => { 227 => 0xb },
-	'aeminexposuretime' => { 227 => 0x5 },
-	'aeprogrammode' => { 227 => 0x6 },
-	'aesetting' => { 24 => 0x21 },
-	'aexv' => { 227 => 0x3 },
-	'af-cpriorityselection' => { 197 => '1.1', 200 => '1.1', 201 => '0.1' },
-	'af-onformb-d10' => { 197 => '3.3', 200 => '3.2' },
-	'af-onformb-d11' => { 201 => '2.2' },
-	'af-spriorityselection' => { 197 => '1.2', 200 => '1.2', 201 => '0.2' },
-	'afactivation' => { 197 => '2.1', 200 => '2.1' },
-	'afadjustment' => { 247 => 0x72 },
-	'afandmeteringbuttons' => { 59 => 0x701 },
-	'afaperture' => { 158 => 0x5, 159 => 0x5 },
-	'afareaheight' => { 141 => 0x1a },
-	'afareaillumination' => { 134 => 0x4b, 202 => '15.3' },
-	'afareamode' => { 134 => 0xe, 140 => 0x0, 141 => 0x5, 224 => 0xf, 271 => 0x11, 272 => 0x11 },
-	'afareamodesetting' => { 198 => '11.1', 199 => '0.1', 202 => '16.1', 203 => '2.1' },
-	'afareas' => { 204 => 0x304 },
-	'afareawidth' => { 141 => 0x18 },
-	'afareaxposition' => { 141 => 0x14 },
-	'afareayposition' => { 141 => 0x16 },
-	'afassist' => { 57 => 0x5, 65 => 0x5, 134 => 0x48, 197 => '2.5', 198 => '0.2', 199 => '0.2', 200 => '2.4', 201 => '1.4', 202 => '0.2', 203 => '2.3' },
-	'afassistbeam' => { 59 => 0x50e, 60 => 0x4, 61 => 0x5, 62 => 0x4, 63 => 0x4, 64 => 0x5 },
-	'afassistlamp' => { 224 => 0x31 },
-	'afdefocus' => { 228 => 0x6 },
-	'afduringliveview' => { 59 => 0x511 },
-	'affinetune' => { 142 => 0x0 },
-	'affinetuneadj' => { 142 => 0x2, 168 => 0x2d1, 169 => 0x2dc, 204 => 0x307 },
-	'affinetuneindex' => { 142 => 0x1 },
-	'afilluminator' => { 271 => 0x29, 276 => 0xb044 },
-	'afimageheight' => { 141 => 0x12 },
-	'afimagewidth' => { 141 => 0x10 },
-	'afintegrationtime' => { 228 => 0x7 },
-	'afmicroadjactive' => { 1 => 0x1 },
-	'afmicroadjustment' => { 59 => 0x507 },
-	'afmicroadjvalue' => { 1 => 0x2 },
-	'afmode' => { 82 => 0x3009, 270 => 0x5, 276 => 0xb043 },
-	'afonaelockbuttonswitch' => { 59 => 0x702 },
-	'afonbutton' => { 197 => '3.1' },
-	'afpoint' => { 24 => 0x13, 81 => 0x18, 140 => 0x1, 207 => 0x308, 270 => 0x1f },
-	'afpointactivationarea' => { 58 => 0x11, 64 => 0x11 },
-	'afpointareaexpansion' => { 59 => 0x508 },
-	'afpointautoselection' => { 59 => 0x50b },
-	'afpointbrightness' => { 59 => 0x50d, 197 => '2.4' },
-	'afpointdisplayduringfocus' => { 59 => 0x50c },
-	'afpointillumination' => { 58 => 0xa, 197 => '2.3', 200 => '2.3', 201 => '1.3', 203 => '2.4' },
-	'afpointmode' => { 232 => 0x3 },
-	'afpointposition' => { 82 => 0x2021, 224 => 0x4d },
-	'afpointregistration' => { 57 => 0x7 },
-	'afpoints' => { 133 => 0x10 },
-	'afpointselected' => { 204 => 0x305, 247 => 0xe },
-	'afpointselected2' => { 232 => 0x4 },
-	'afpointselection' => { 58 => 0xb, 197 => '1.3', 200 => '1.3' },
-	'afpointselectionmethod' => { 59 => 0x50f, 60 => 0xc, 61 => 0xd, 64 => 0xd },
-	'afpointsinfocus' => { 54 => 0xe, 140 => 0x2, 228 => 0xb, 247 => [0xf,0x3c] },
-	'afpointsinfocus5d' => { 15 => 0x38 },
-	'afpointspotmetering' => { 58 => 0xd },
-	'afpointsunknown1' => { 228 => 0x0 },
-	'afpointsunknown2' => { 228 => 0x2 },
-	'afpointsused' => { 141 => 0x8 },
-	'afpredictor' => { 228 => 0x4 },
-	'afresponse' => { 160 => 0xad },
-	'afresult' => { 209 => 0x1038 },
-	'afsearch' => { 204 => 0x303 },
-	'afwithshutter' => { 271 => 0x2a },
-	'aggregationtype' => { 301 => 'aggregationType' },
-	'agreement' => { 303 => 'agreement' },
-	'aiservocontinuousshooting' => { 58 => 0x15 },
-	'aiservoimagepriority' => { 59 => 0x503 },
-	'aiservotrackingmethod' => { 59 => 0x504 },
-	'aiservotrackingsensitivity' => { 58 => 0x14, 59 => 0x502 },
-	'album' => { 310 => 'album' },
-	'alreadyapplied' => { 288 => 'AlreadyApplied' },
-	'alternatetitle' => { 301 => 'alternateTitle' },
-	'alttapename' => { 310 => 'altTapeName' },
-	'alttimecode' => { 310 => 'altTimecode' },
-	'alttimecodetimeformat' => { 310 => [\'altTimecode','altTimecodeTimeFormat'] },
-	'alttimecodetimevalue' => { 310 => [\'altTimecode','altTimecodeTimeValue'] },
-	'alttimecodevalue' => { 310 => [\'altTimecode','altTimecodeValue'] },
-	'ambienceselection' => { 2 => 0x1 },
-	'ambienttemperature' => { 259 => 0x14 },
-	'ambienttemperaturefahrenheit' => { 259 => 0x13 },
-	'analogbalance' => { 85 => 0xc627 },
-	'angleadj' => { 78 => 0x8b },
-	'anti-blur' => { 276 => 0xb04b },
-	'antialiasstrength' => { 85 => 0xc632 },
-	'aperturerange' => { 59 => 0x10d },
-	'apertureringuse' => { 232 => '1.4' },
-	'aperturevalue' => { 68 => 0x2, 85 => 0x9202, 209 => 0x1002, 292 => 'ApertureValue' },
-	'applekeywords' => { 213 => 'AAPL:Keywords' },
-	'applicationnotes' => { 85 => 0x2bc, 226 => 0x2bc },
-	'applicationrecordversion' => { 92 => 0x0 },
-	'applyshootingmeteringmode' => { 59 => 0x10e },
-	'approximatefnumber' => { 219 => 0x313, 225 => 0x3406 },
-	'approximatefocusdistance' => { 285 => 'ApproximateFocusDistance' },
-	'armidentifier' => { 93 => 0x78 },
-	'armversion' => { 93 => 0x7a },
-	'artfilter' => { 204 => 0x529 },
-	'artist' => { 85 => 0x13b, 215 => 'Artist', 247 => 0x22e, 306 => 'Artist', 310 => 'artist' },
-	'artworkcopyrightnotice' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOCopyrightNotice'] },
-	'artworkcreator' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOCreator'] },
-	'artworkdatecreated' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAODateCreated'] },
-	'artworkorobject' => { 294 => 'ArtworkOrObject' },
-	'artworksource' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOSource'] },
-	'artworksourceinventoryno' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOSourceInvNo'] },
-	'artworktitle' => { 294 => [\'ArtworkOrObject','ArtworkOrObjectAOTitle'] },
-	'aspectframe' => { 208 => 0x1113 },
-	'aspectratio' => { 3 => 0x0, 208 => 0x1112, 271 => 0x55 },
-	'asshoticcprofile' => { 85 => 0xc68f },
-	'asshotneutral' => { 85 => 0xc628 },
-	'asshotpreprofilematrix' => { 85 => 0xc690 },
-	'asshotprofilename' => { 85 => 0xc6f6 },
-	'asshotwhitexy' => { 85 => 0xc629 },
-	'assignbktbutton' => { 197 => '4.2' },
-	'assignfuncbutton' => { 59 => 0x70b },
-	'assistbuttonfunction' => { 57 => 0xd },
-	'attributionname' => { 286 => 'attributionName' },
-	'attributionurl' => { 286 => 'attributionURL' },
-	'audio' => { 224 => 0x20 },
-	'audiobitrate' => { 46 => 0x6c },
-	'audiochannels' => { 46 => 0x70 },
-	'audiochanneltype' => { 310 => 'audioChannelType' },
-	'audiocompression' => { 112 => 'Compression' },
-	'audiocompressor' => { 310 => 'audioCompressor' },
-	'audioduration' => { 92 => 0x99 },
-	'audiomoddate' => { 310 => 'audioModDate' },
-	'audiooutcue' => { 92 => 0x9a },
-	'audiosamplerate' => { 46 => 0x6e, 310 => 'audioSampleRate' },
-	'audiosampletype' => { 310 => 'audioSampleType' },
-	'audiosamplingrate' => { 92 => 0x97 },
-	'audiosamplingresolution' => { 92 => 0x98 },
-	'audiotype' => { 92 => 0x96 },
-	'author' => { 114 => 'Author', 213 => 'Author', 215 => 'Author', 258 => 'Author', 284 => 'author', 298 => 'Author' },
-	'authorsposition' => { 299 => 'AuthorsPosition' },
-	'autoaperture' => { 241 => '0.1' },
-	'autobracket' => { 270 => 0x19 },
-	'autobracketing' => { 89 => 0x1100, 247 => 0x18 },
-	'autobracketmodem' => { 197 => '21.2', 200 => '26.2' },
-	'autobracketorder' => { 134 => 0x43, 197 => '21.3', 200 => '26.3', 201 => '12.2', 202 => '2.2', 203 => '13.2' },
-	'autobracketset' => { 197 => '21.1', 199 => '11.1', 200 => '26.1', 201 => '12.1', 202 => '2.1', 203 => '13.1' },
-	'autobrightness' => { 288 => 'AutoBrightness' },
-	'autocontrast' => { 288 => 'AutoContrast' },
-	'autodistortioncontrol' => { 149 => 0x4 },
-	'autodynamicrange' => { 89 => 0x140b },
-	'autoexposure' => { 288 => 'AutoExposure' },
-	'autoexposurebracketing' => { 54 => 0x10 },
-	'autofocus' => { 207 => 0x209 },
-	'autofp' => { 202 => '7.3', 203 => '31.4' },
-	'autoiso' => { 54 => 0x1, 82 => 0x3008, 198 => '1.1', 202 => '1.1' },
-	'autoisomax' => { 198 => '1.2', 202 => '1.2' },
-	'autoisominshutterspeed' => { 198 => '1.3', 202 => '1.3' },
-	'autolightingoptimizer' => { 12 => 0xbe, 13 => 0xbf, 16 => 0xbf, 42 => 0x2, 59 => 0x204, 78 => 0x6f },
-	'autolightingoptimizeron' => { 78 => 0x6e },
-	'autoredeye' => { 190 => 0xfe28a44f },
-	'autorotate' => { 54 => 0x1b },
-	'autoshadows' => { 288 => 'AutoShadows' },
-	'auxiliarylens' => { 160 => 0x82 },
-	'avaperturesetting' => { 232 => 0x13 },
-	'avsettingwithoutlens' => { 59 => 0x707 },
-	'azimuth' => { 122 => 'Azimuth' },
-	'babyage' => { 224 => [0x8010,0x33] },
-	'babyname' => { 224 => 0x66 },
-	'backgroundalpha' => { 305 => 'bgalpha' },
-	'baseexposurecompensation' => { 232 => 0x15 },
-	'baseiso' => { 54 => 0x2, 72 => 0x101c, 225 => 0x312a },
-	'baselineexposure' => { 85 => 0xc62a },
-	'baselinenoise' => { 85 => 0xc62b },
-	'baselinesharpness' => { 85 => 0xc62c },
-	'baseurl' => { 308 => 'BaseURL' },
-	'batterylevel' => { 134 => 0x60 },
-	'batteryorder' => { 197 => '12.5', 200 => '13.2', 201 => '2.1' },
-	'batteryvoltage' => { 259 => 0x2a },
-	'bayergreensplit' => { 85 => 0xc62d },
-	'bayerpattern' => { 96 => 0xf902, 137 => 0x17 },
-	'beatspliceparams' => { 310 => 'beatSpliceParams' },
-	'beatspliceparamsriseindecibel' => { 310 => [\'beatSpliceParams','beatSpliceParamsRiseInDecibel'] },
-	'beatspliceparamsriseintimeduration' => { 310 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDuration'] },
-	'beatspliceparamsriseintimedurationscale' => { 310 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationScale'] },
-	'beatspliceparamsriseintimedurationvalue' => { 310 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationValue'] },
-	'beatspliceparamsusefilebeatsmarker' => { 310 => [\'beatSpliceParams','beatSpliceParamsUseFileBeatsMarker'] },
-	'beep' => { 197 => '13.1', 198 => '0.1', 199 => '2.1', 200 => '10.1', 202 => '0.1', 203 => '4.1' },
-	'beeppitch' => { 201 => '3.1' },
-	'beepvolume' => { 201 => '4.5' },
-	'bestqualityscale' => { 85 => 0xc65c },
-	'bestshotmode' => { 82 => 0x3007 },
-	'bitdepth' => { 119 => 'BitDepth', 137 => 0x11, 165 => 0x41 },
-	'bitspercomponent' => { 94 => 0x87 },
-	'bitspersample' => { 85 => 0x102, 306 => 'BitsPerSample' },
-	'blacklevel' => { 85 => 0xc61a, 209 => 0x1012 },
-	'blacklevel2' => { 208 => 0x600, 212 => 0x600 },
-	'blacklevelrepeatdim' => { 85 => 0xc619 },
-	'blackpoint' => { 247 => 0x200 },
-	'bleachbypasstoning' => { 247 => 0x7f },
-	'bluebalance' => { 148 => 0x271, 209 => 0x1018, 226 => 0x12, 247 => 0x1b },
-	'bluecurvelimits' => { 77 => 0x1fe },
-	'bluecurvepoints' => { 77 => 0x1d4 },
-	'bluehue' => { 288 => 'BlueHue' },
-	'bluesaturation' => { 288 => 'BlueSaturation' },
-	'blurwarning' => { 89 => 0x1300 },
-	'bodybatteryadload' => { 230 => 0x3 },
-	'bodybatteryadnoload' => { 230 => 0x2 },
-	'bodybatterystate' => { 230 => '1.1' },
-	'bodybatteryvoltage1' => { 230 => 0x2 },
-	'bodybatteryvoltage2' => { 230 => 0x4 },
-	'bodybatteryvoltage3' => { 230 => 0x6 },
-	'bodybatteryvoltage4' => { 230 => 0x8 },
-	'bodyfirmware' => { 264 => 0x0 },
-	'bodyfirmwareversion' => { 205 => 0x104, 206 => 0x100, 209 => 0x104 },
-	'bodyserialnumber' => { 264 => 0x10 },
-	'bracketmode' => { 38 => 0x3 },
-	'bracketsequence' => { 82 => 0x301d },
-	'bracketshotnumber' => { 38 => 0x5, 232 => 0x9 },
-	'bracketstep' => { 131 => 0xe },
-	'bracketvalue' => { 38 => 0x4 },
-	'brightness' => { 85 => 0xfe53, 113 => 'Brightness', 131 => 0x2c, 162 => 0x34, 259 => 0x25, 271 => 0x22, 276 => 0x2007, 288 => 'Brightness' },
-	'brightnessadj' => { 77 => 0x114, 183 => 0x0, 193 => 0x2d, 279 => 0x8018 },
-	'brightnessvalue' => { 85 => 0x9203, 209 => 0x1003, 292 => 'BrightnessValue' },
-	'bulbduration' => { 54 => 0x18 },
-	'burstmode' => { 99 => 0xa, 224 => 0x2a },
-	'burstmode2' => { 99 => 0x18 },
-	'burstshot' => { 270 => 0x34 },
-	'buttonfunctioncontroloff' => { 59 => 0x70a },
-	'bwfilter' => { 131 => 0x2a, 138 => 0x39 },
-	'bwmode' => { 209 => 0x203 },
-	'by-line' => { 92 => 0x50 },
-	'by-linetitle' => { 92 => 0x55 },
-	'bytecount' => { 301 => 'byteCount' },
-	'calibration' => { 270 => 0x24 },
-	'calibrationilluminant1' => { 85 => 0xc65a },
-	'calibrationilluminant2' => { 85 => 0xc65b },
-	'cameraangle' => { 310 => 'cameraAngle' },
-	'cameracalibration1' => { 85 => 0xc623 },
-	'cameracalibration2' => { 85 => 0xc624 },
-	'cameracalibrationsig' => { 85 => 0xc6f3 },
-	'cameracolorcalibration01' => { 26 => 0x0, 32 => 0xba },
-	'cameracolorcalibration02' => { 26 => 0x4, 32 => 0xbf },
-	'cameracolorcalibration03' => { 26 => 0x8, 32 => 0xc4 },
-	'cameracolorcalibration04' => { 26 => 0xc, 32 => 0xc9 },
-	'cameracolorcalibration05' => { 26 => 0x10, 32 => 0xce },
-	'cameracolorcalibration06' => { 26 => 0x14, 32 => 0xd3 },
-	'cameracolorcalibration07' => { 26 => 0x18, 32 => 0xd8 },
-	'cameracolorcalibration08' => { 26 => 0x1c, 32 => 0xdd },
-	'cameracolorcalibration09' => { 26 => 0x20, 32 => 0xe2 },
-	'cameracolorcalibration10' => { 26 => 0x24, 32 => 0xe7 },
-	'cameracolorcalibration11' => { 26 => 0x28, 32 => 0xec },
-	'cameracolorcalibration12' => { 26 => 0x2c, 32 => 0xf1 },
-	'cameracolorcalibration13' => { 26 => 0x30, 32 => 0xf6 },
-	'cameracolorcalibration14' => { 26 => 0x34, 32 => 0xfb },
-	'cameracolorcalibration15' => { 26 => 0x38, 32 => 0x100 },
-	'cameraid' => { 209 => 0x209, 269 => 0x209 },
-	'cameraiso' => { 24 => 0x10 },
-	'cameralabel' => { 310 => 'cameraLabel' },
-	'cameramodel' => { 310 => 'cameraModel' },
-	'cameramove' => { 310 => 'cameraMove' },
-	'cameraorientation' => { 4 => 0x30, 7 => 0x30, 9 => 0x35, 10 => 0x30, 11 => 0x30, 12 => 0x31, 13 => 0x31, 14 => 0x35, 15 => 0x27, 16 => 0x31, 18 => 0x36, 20 => 0x11, 249 => 0x1 },
-	'cameraowner' => { 100 => 0xc353 },
-	'cameraparameters' => { 209 => 0x2050 },
-	'cameraprofile' => { 288 => 'CameraProfile' },
-	'cameraprofiledigest' => { 288 => 'CameraProfileDigest' },
-	'cameraserialnumber' => { 85 => 0xc62f, 130 => 'CameraSerialNumber' },
-	'camerasettingsversion' => { 204 => 0x0 },
-	'cameratemperature' => { 4 => 0x18, 7 => 0x18, 9 => 0x19, 10 => 0x18, 11 => 0x18, 12 => 0x19, 13 => 0x19, 14 => 0x19, 15 => 0x17, 16 => 0x19, 18 => 0x19, 19 => 0x19, 21 => [0x87,0x91], 22 => [0x99,0x9f,0xa4,0xa8,0x105], 23 => [0x64,0x1d2,0x1f7,0x1fa,0x47,0x53,0x5b,0x5c], 54 => 0xc, 219 => 0x320, 225 => 0x3402, 247 => 0x47, 267 => 0x43 },
-	'cameratemperature2' => { 250 => 0xc },
-	'cameratemperature3' => { 250 => 0xe },
-	'cameratemperature4' => { 250 => 0x14 },
-	'cameratemperature5' => { 250 => 0x16 },
-	'cameratype' => { 54 => 0x1a, 209 => 0x207 },
-	'cameratype2' => { 205 => 0x100 },
-	'canonexposuremode' => { 24 => 0x14 },
-	'canonfiledescription' => { 72 => 0x805 },
-	'canonfilelength' => { 43 => 0xe },
-	'canonfirmwareversion' => { 43 => 0x7, 72 => 0x80b },
-	'canonflashinfo' => { 72 => 0x1028 },
-	'canonflashmode' => { 24 => 0x4 },
-	'canonimagesize' => { 6 => 0x39, 24 => 0xa },
-	'canonimagetype' => { 43 => 0x6, 72 => 0x815 },
-	'canonmodelid' => { 43 => 0x10, 72 => 0x1834 },
-	'canonvrd' => { 86 => 'CanonVRD' },
-	'caption' => { 284 => 'caption' },
-	'caption-abstract' => { 92 => 0x78 },
-	'captionsauthornames' => { 291 => 'CaptionsAuthorNames' },
-	'captionsdatetimestamps' => { 291 => 'CaptionsDateTimeStamps' },
-	'captionwriter' => { 299 => 'CaptionWriter' },
-	'captureframerate' => { 82 => 0x4001 },
-	'cardshutterlock' => { 134 => 0x49 },
-	'casioimagesize' => { 82 => 0x9 },
-	'catalogsets' => { 92 => 0xff, 283 => 'CatalogSets' },
-	'categories' => { 43 => 0x23, 284 => 'categories' },
-	'category' => { 92 => 0xf, 299 => 'Category' },
-	'ccdboardversion' => { 219 => 0x331 },
-	'ccdscanmode' => { 209 => 0x1039 },
-	'ccdsensitivity' => { 180 => 0x6 },
-	'ccdversion' => { 219 => 0x330 },
-	'cellglobalid' => { 287 => 'cgi' },
-	'celllength' => { 85 => 0x109 },
-	'cellr' => { 287 => 'r' },
-	'celltowerid' => { 287 => 'cellid' },
-	'cellwidth' => { 85 => 0x108 },
-	'centerafarea' => { 202 => '15.1' },
-	'centerfocuspoint' => { 203 => '2.2' },
-	'centerweightedareasize' => { 197 => '7.1', 200 => '5.1', 201 => '7.1', 202 => '6.3', 203 => '8.1' },
-	'certificate' => { 314 => 'Certificate' },
-	'cfapattern' => { 85 => 0xa302, 292 => 'CFAPattern' },
-	'cfapatterncolumns' => { 292 => [\'CFAPattern','CFAPatternColumns'] },
-	'cfapatternrows' => { 292 => [\'CFAPattern','CFAPatternRows'] },
-	'cfapatternvalues' => { 292 => [\'CFAPattern','CFAPatternValues'] },
-	'channel' => { 301 => 'channel' },
-	'channels' => { 112 => 'Channels' },
-	'checkmark' => { 77 => 0x26a },
-	'checkmark2' => { 78 => 0x8e },
-	'childfontfiles' => { 315 => [\'Fonts','FontsChildFontFiles'] },
-	'chmodeshootingspeed' => { 197 => '10.3' },
-	'chromablurradius' => { 85 => 0xc631 },
-	'chromaticaberration' => { 78 => 0x66 },
-	'chromaticaberrationb' => { 288 => 'ChromaticAberrationB' },
-	'chromaticaberrationblue' => { 78 => 0x6b },
-	'chromaticaberrationcorrection' => { 240 => 0x1 },
-	'chromaticaberrationon' => { 78 => 0x62 },
-	'chromaticaberrationr' => { 288 => 'ChromaticAberrationR' },
-	'chromaticaberrationred' => { 78 => 0x6a },
-	'chrominancenoisereduction' => { 78 => 0x5e, 270 => 0x1a },
-	'chrominancenr_tiff_jpeg' => { 78 => 0x60 },
-	'city' => { 92 => 0x5a, 118 => 'City', 224 => 0x6d, 299 => 'City' },
-	'clarity' => { 288 => 'Clarity' },
-	'classifystate' => { 92 => 0xe1 },
-	'client' => { 310 => 'client' },
-	'clmodeshootingspeed' => { 197 => '10.2', 200 => '11.2', 201 => '10.2', 203 => '11.1' },
-	'cmcontrast' => { 212 => 0x2022 },
-	'cmexposurecompensation' => { 212 => 0x2000 },
-	'cmhue' => { 212 => 0x2021 },
-	'cmsaturation' => { 212 => 0x2020 },
-	'cmsharpness' => { 212 => 0x2023 },
-	'cmwhitebalance' => { 212 => 0x2001 },
-	'cmwhitebalancecomp' => { 212 => 0x2002 },
-	'cmwhitebalancegraypoint' => { 212 => 0x2010 },
-	'codec' => { 126 => 'Codec' },
-	'codedcharacterset' => { 93 => 0x5a },
-	'collectionname' => { 295 => [\'Collections','CollectionsCollectionName'] },
-	'collections' => { 295 => 'Collections' },
-	'collectionuri' => { 295 => [\'Collections','CollectionsCollectionURI'] },
-	'coloraberrationcontrol' => { 190 => 0xc89224b },
-	'coloradjustment' => { 270 => 0x14 },
-	'coloradjustmentmode' => { 269 => 0x210 },
-	'coloranta' => { 315 => [\'Colorants','ColorantsA'] },
-	'colorantb' => { 315 => [\'Colorants','ColorantsB'] },
-	'colorantblack' => { 315 => [\'Colorants','ColorantsBlack'] },
-	'colorantblue' => { 315 => [\'Colorants','ColorantsBlue'] },
-	'colorantcyan' => { 315 => [\'Colorants','ColorantsCyan'] },
-	'colorantgreen' => { 315 => [\'Colorants','ColorantsGreen'] },
-	'colorantl' => { 315 => [\'Colorants','ColorantsL'] },
-	'colorantmagenta' => { 315 => [\'Colorants','ColorantsMagenta'] },
-	'colorantmode' => { 315 => [\'Colorants','ColorantsMode'] },
-	'colorantred' => { 315 => [\'Colorants','ColorantsRed'] },
-	'colorants' => { 315 => 'Colorants' },
-	'colorantswatchname' => { 315 => [\'Colorants','ColorantsSwatchName'] },
-	'coloranttype' => { 315 => [\'Colorants','ColorantsType'] },
-	'colorantyellow' => { 315 => [\'Colorants','ColorantsYellow'] },
-	'colorbalance' => { 113 => 'ColorBalance' },
-	'colorbalanceadj' => { 190 => 0x76a43202 },
-	'colorbalanceblue' => { 131 => 0x1e },
-	'colorbalancegreen' => { 131 => 0x1d },
-	'colorbalancered' => { 131 => 0x1c },
-	'colorblur' => { 78 => 0x65 },
-	'colorbooster' => { 190 => 0x5f0e7d23 },
-	'colorboostlevel' => { 184 => 0x1 },
-	'colorboosttype' => { 184 => 0x0 },
-	'colorclass' => { 253 => 0xde },
-	'colorcompensationfilter' => { 134 => [0x3a,0x5f], 135 => 0x111, 276 => 0xb022 },
-	'colorcontrol' => { 209 => 0x102b },
-	'colorcorrection' => { 279 => 0x8015 },
-	'colordataversion' => { 30 => 0x0, 31 => 0x0, 33 => 0x0 },
-	'coloreffect' => { 224 => 0x28 },
-	'colorfilter' => { 81 => 0x17, 82 => 0x3017, 131 => 0x29, 138 => [0x38,0x4d,0x4f], 252 => 0x17 },
-	'colorgain' => { 165 => 0x51 },
-	'colorhue' => { 160 => 0x8d },
-	'colorimetricreference' => { 85 => 0xc6bf },
-	'colormatrix' => { 208 => 0x200, 209 => 0x1011, 267 => 0xa030 },
-	'colormatrix1' => { 85 => 0xc621 },
-	'colormatrix2' => { 85 => 0xc622, 212 => 0x200 },
-	'colormatrixa' => { 247 => 0x203 },
-	'colormatrixadobergb' => { 267 => 0xa032 },
-	'colormatrixb' => { 247 => 0x204 },
-	'colormatrixnumber' => { 209 => 0x1019 },
-	'colormatrixsrgb' => { 267 => 0xa031 },
-	'colormode' => { 82 => 0x3015, 89 => 0x1210, 99 => 0x66, 131 => 0x28, 134 => 0x16, 135 => 0x101, 138 => 0x7, 160 => 0x3, 180 => 0x4, 224 => 0x32, 270 => 0x2c, 276 => 0xb029, 299 => 'ColorMode' },
-	'colormoirereduction' => { 191 => 0x15 },
-	'colormoirereductionmode' => { 191 => 0x5 },
-	'colornoisereduction' => { 279 => 0x8029, 288 => 'ColorNoiseReduction' },
-	'colornoisereductiondetail' => { 288 => 'ColorNoiseReductionDetail' },
-	'colornoisereductionintensity' => { 191 => 0x18 },
-	'colornoisereductionsharpness' => { 191 => 0x1c },
-	'colorplanes' => { 88 => 0x2 },
-	'colorprofile' => { 131 => 0x33 },
-	'colorrepresentation' => { 94 => 0x3c },
-	'colorreproduction' => { 276 => 0xb020 },
-	'colorsequence' => { 94 => 0x41 },
-	'colorspace' => { 34 => 0x3, 43 => 0xb4, 72 => 0x10b4, 85 => 0xa001, 119 => 'ColorSpace', 132 => 0x2f, 133 => 0x25, 134 => 0x17, 160 => 0x1e, 204 => 0x507, 247 => 0x37, 267 => 0xa011, 270 => 0xb, 292 => 'ColorSpace' },
-	'colortempasshot' => { 27 => 0x4, 28 => 0x1d, 29 => 0x26, 30 => 0x43, 33 => 0x43 },
-	'colortempauto' => { 27 => 0x9, 28 => 0x22, 29 => 0x1c, 30 => 0x48, 33 => 0x48 },
-	'colortempcloudy' => { 27 => 0x22, 28 => 0x31, 29 => 0x35, 30 => 0x5c, 33 => 0x75 },
-	'colortempcustom' => { 30 => 0x84 },
-	'colortempcustom1' => { 28 => 0x45 },
-	'colortempcustom2' => { 28 => 0x4a },
-	'colortempdaylight' => { 27 => 0x18, 28 => 0x27, 29 => 0x2b, 30 => 0x52, 33 => 0x6b },
-	'colortemperature' => { 4 => 0x73, 5 => [0x48,0x4e], 6 => 0x37, 7 => 0x62, 8 => 0x37, 9 => [0x7b,0x7c], 10 => 0x73, 11 => 0x73, 12 => 0x77, 13 => 0x73, 14 => 0x7c, 15 => 0x58, 16 => 0x73, 18 => 0x7d, 20 => 0x57, 43 => 0xae, 52 => 0x9, 72 => 0x10ae, 89 => 0x1005, 97 => 0x846, 113 => 'ColorTemperature', 132 => [0x6e,0x49], 133 => 0x3f, 134 => [0x39,0x5e], 135 => 0x10b, 138 => [0x3c,0x4c,0x4e], 219 => 0x321, 247 => 0x50, 276 => 0xb021, 288 => 'Temperature' },
-	'colortemperatureadj' => { 279 => 0x8013 },
-	'colortemperaturebg' => { 209 => 0x1013 },
-	'colortemperaturerg' => { 209 => 0x1014 },
-	'colortemperaturesetting' => { 134 => 0x25 },
-	'colortempflash' => { 27 => 0x36, 28 => 0x40, 29 => 0x49, 30 => 0x70, 33 => 0x89 },
-	'colortempflashdata' => { 30 => 0x24a },
-	'colortempfluorescent' => { 27 => 0x2c, 28 => 0x3b, 29 => 0x3f, 30 => 0x66, 33 => 0x7f },
-	'colortempkelvin' => { 27 => 0x31, 29 => 0x44, 30 => 0x6b, 33 => 0x84 },
-	'colortempmeasured' => { 27 => 0xe, 30 => 0x4d, 33 => 0x4d },
-	'colortemppc1' => { 29 => 0x94, 30 => 0x75 },
-	'colortemppc2' => { 29 => 0x99, 30 => 0x7a },
-	'colortemppc3' => { 29 => 0x9e, 30 => 0x7f },
-	'colortempshade' => { 27 => 0x1d, 28 => 0x2c, 29 => 0x30, 30 => 0x57, 33 => 0x70 },
-	'colortemptungsten' => { 27 => 0x27, 28 => 0x36, 29 => 0x3a, 30 => 0x61, 33 => 0x7a },
-	'colortempunknown' => { 27 => 0x13, 29 => 0x21, 33 => 0x52 },
-	'colortempunknown10' => { 27 => 0x63, 29 => 0x76, 33 => 0xa2 },
-	'colortempunknown11' => { 27 => 0x68, 29 => 0x7b, 33 => 0xa7 },
-	'colortempunknown12' => { 27 => 0x6d, 29 => 0x80, 33 => 0xac },
-	'colortempunknown13' => { 27 => 0x72, 29 => 0x85, 33 => 0xb1 },
-	'colortempunknown14' => { 29 => 0x8a, 33 => 0xb6 },
-	'colortempunknown15' => { 29 => 0x8f, 33 => 0xbb },
-	'colortempunknown16' => { 29 => 0xa3 },
-	'colortempunknown2' => { 27 => 0x3b, 29 => 0x4e, 33 => 0x57 },
-	'colortempunknown3' => { 27 => 0x40, 29 => 0x53, 33 => 0x5c },
-	'colortempunknown4' => { 27 => 0x45, 29 => 0x58, 33 => 0x61 },
-	'colortempunknown5' => { 27 => 0x4a, 29 => 0x5d, 33 => 0x66 },
-	'colortempunknown6' => { 27 => 0x4f, 29 => 0x62, 33 => 0x8e },
-	'colortempunknown7' => { 27 => 0x54, 29 => 0x67, 33 => 0x93 },
-	'colortempunknown8' => { 27 => 0x59, 29 => 0x6c, 33 => 0x98 },
-	'colortempunknown9' => { 27 => 0x5e, 29 => 0x71, 33 => 0x9d },
-	'colortone' => { 6 => 0x6f, 8 => 0x77, 24 => 0x2a, 34 => 0x2 },
-	'colortoneadj' => { 77 => 0x11e },
-	'colortonefaithful' => { 15 => 0x107, 48 => 0x6c, 49 => 0x6c },
-	'colortonelandscape' => { 15 => 0x105, 48 => 0x3c, 49 => 0x3c },
-	'colortonemonochrome' => { 48 => 0x84, 49 => 0x84 },
-	'colortoneneutral' => { 15 => 0x106, 48 => 0x54, 49 => 0x54 },
-	'colortoneportrait' => { 15 => 0x104, 48 => 0x24, 49 => 0x24 },
-	'colortonestandard' => { 15 => 0x103, 48 => 0xc, 49 => 0xc },
-	'colortoneunknown' => { 49 => 0x9c },
-	'colortoneuserdef1' => { 15 => 0x109, 48 => 0x9c, 49 => 0xb4 },
-	'colortoneuserdef2' => { 15 => 0x10a, 48 => 0xb4, 49 => 0xcc },
-	'colortoneuserdef3' => { 15 => 0x10b, 48 => 0xcc, 49 => 0xe4 },
-	'commanddials' => { 202 => '5.1' },
-	'commanddialsaperturesetting' => { 197 => '17.3', 200 => '33.3', 201 => '17.3' },
-	'commanddialschangemainsub' => { 197 => '17.2', 200 => '33.2', 201 => '17.2' },
-	'commanddialsmenuandplayback' => { 197 => '17.4', 200 => '33.4', 201 => '17.4' },
-	'commanddialsreverserotation' => { 197 => '17.1', 199 => '16.2', 200 => '33.1', 201 => '17.1', 203 => '18.1' },
-	'commanderchannel' => { 202 => '10.2' },
-	'commandergroupa_ttl-aacomp' => { 202 => '13.1' },
-	'commandergroupa_ttlcomp' => { 203 => '32.1' },
-	'commandergroupamanualoutput' => { 202 => '13.2' },
-	'commandergroupamode' => { 202 => '11.2' },
-	'commandergroupb_ttl-aacomp' => { 202 => '14.1' },
-	'commandergroupb_ttlcomp' => { 203 => '33.1' },
-	'commandergroupbmanualoutput' => { 202 => '14.2' },
-	'commandergroupbmode' => { 202 => '11.3' },
-	'commanderinternalflash' => { 202 => '11.1' },
-	'commanderinternalmanualoutput' => { 202 => '12.2' },
-	'commanderinternalttlchannel' => { 200 => '18.2' },
-	'commanderinternalttlcomp' => { 202 => '12.1', 203 => '31.2' },
-	'commanderinternalttlcompbuiltin' => { 200 => '20.1', 201 => '26.1' },
-	'commanderinternalttlcompgroupa' => { 200 => '21.1', 201 => '27.1' },
-	'commanderinternalttlcompgroupb' => { 200 => '22.1', 201 => '28.1' },
-	'comment' => { 0 => 0x2, 86 => 'Comment', 114 => 'Comment', 215 => 'Comment' },
-	'complianceprofile' => { 301 => 'complianceProfile' },
-	'componentsconfiguration' => { 85 => 0x9101, 119 => 'Components', 292 => 'ComponentsConfiguration' },
-	'componentversion' => { 72 => 0x80c },
-	'composer' => { 310 => 'composer' },
-	'compositionadjust' => { 246 => '0.1' },
-	'compositionadjustrotation' => { 246 => 0x7 },
-	'compositionadjustx' => { 246 => 0x5 },
-	'compositionadjusty' => { 246 => 0x6 },
-	'compressedbitsperpixel' => { 85 => 0x9102, 292 => 'CompressedBitsPerPixel' },
-	'compressedimagesize' => { 135 => 0x40, 209 => 0x40 },
-	'compression' => { 85 => 0x103, 306 => 'Compression' },
-	'compressionfactor' => { 204 => 0x50d },
-	'compressionratio' => { 119 => 'Compression', 209 => 0x1034 },
-	'constrainedcropheight' => { 77 => 0x266, 253 => 0xd6 },
-	'constrainedcropwidth' => { 77 => 0x262, 253 => 0xd5 },
-	'contact' => { 92 => 0x76 },
-	'contentlocationcode' => { 92 => 0x1a },
-	'contentlocationname' => { 92 => 0x1b },
-	'continuousbracketing' => { 134 => 0x20 },
-	'continuousdrive' => { 24 => 0x5 },
-	'continuousshootingspeed' => { 59 => 0x610 },
-	'continuousshotlimit' => { 59 => 0x611 },
-	'contrast' => { 6 => 0x73, 8 => 0x75, 24 => 0xd, 81 => 0xc, 82 => [0x3012,0x20], 85 => [0xa408,0xfe54], 89 => [0x1004,0x1006], 113 => 'Contrast', 131 => 0x20, 132 => 0x31, 133 => 0x27, 134 => 0x19, 138 => 0x2, 162 => 0x33, 209 => 0x1029, 224 => 0x39, 225 => 0x300a, 247 => 0x20, 252 => 0xc, 259 => 0x24, 270 => 0xd, 271 => 0x1d, 272 => 0x1a, 276 => 0x2004, 288 => 'Contrast', 292 => 'Contrast' },
-	'contrastadj' => { 77 => 0x115, 193 => 0x2c, 279 => 0x8017 },
-	'contrastdetectaf' => { 141 => 0x4 },
-	'contrastdetectafarea' => { 247 => 0x231 },
-	'contrastdetectafinfocus' => { 141 => 0x1c },
-	'contrastfaithful' => { 15 => 0xec, 48 => 0x60, 49 => 0x60 },
-	'contrasthighlight' => { 247 => 0x6d },
-	'contrasthighlightshadowadj' => { 247 => 0x6f },
-	'contrastlandscape' => { 15 => 0xea, 48 => 0x30, 49 => 0x30 },
-	'contrastmode' => { 224 => 0x2c },
-	'contrastmonochrome' => { 15 => 0xed, 48 => 0x78, 49 => 0x78 },
-	'contrastneutral' => { 15 => 0xeb, 48 => 0x48, 49 => 0x48 },
-	'contrastportrait' => { 15 => 0xe9, 48 => 0x18, 49 => 0x18 },
-	'contrastsetting' => { 204 => 0x505, 212 => 0x1012 },
-	'contrastshadow' => { 247 => 0x6e },
-	'contraststandard' => { 15 => 0xe8, 48 => 0x0, 49 => 0x0 },
-	'contrastunknown' => { 49 => 0x90 },
-	'contrastuserdef1' => { 15 => 0xee, 48 => 0x90, 49 => 0xa8 },
-	'contrastuserdef2' => { 15 => 0xef, 48 => 0xa8, 49 => 0xc0 },
-	'contrastuserdef3' => { 15 => 0xf0, 48 => 0xc0, 49 => 0xd8 },
-	'contributedmedia' => { 310 => 'contributedMedia' },
-	'contributedmediaduration' => { 310 => [\'contributedMedia','contributedMediaDuration'] },
-	'contributedmediadurationscale' => { 310 => [\'contributedMedia','contributedMediaDurationScale'] },
-	'contributedmediadurationvalue' => { 310 => [\'contributedMedia','contributedMediaDurationValue'] },
-	'contributedmediamanaged' => { 310 => [\'contributedMedia','contributedMediaManaged'] },
-	'contributedmediapath' => { 310 => [\'contributedMedia','contributedMediaPath'] },
-	'contributedmediastarttime' => { 310 => [\'contributedMedia','contributedMediaStartTime'] },
-	'contributedmediastarttimescale' => { 310 => [\'contributedMedia','contributedMediaStartTimeScale'] },
-	'contributedmediastarttimevalue' => { 310 => [\'contributedMedia','contributedMediaStartTimeValue'] },
-	'contributedmediatrack' => { 310 => [\'contributedMedia','contributedMediaTrack'] },
-	'contributedmediawebstatement' => { 310 => [\'contributedMedia','contributedMediaWebStatement'] },
-	'contributor' => { 289 => 'contributor' },
-	'contributors' => { 114 => 'Contributors' },
-	'controldialset' => { 134 => 0x46 },
-	'controlledvocabularyterm' => { 294 => 'CVterm' },
-	'controllerboardversion' => { 219 => 0x332 },
-	'controlmode' => { 54 => 0x12 },
-	'conversionlens' => { 224 => 0x35 },
-	'converter' => { 85 => 0xfe4d, 180 => 0xb, 288 => 'Converter' },
-	'converttograyscale' => { 288 => 'ConvertToGrayscale' },
-	'copyright' => { 0 => 0x3, 85 => 0x8298, 114 => 'Copyright', 215 => 'Copyright', 247 => 0x22f, 258 => 'Copyright', 298 => 'Copyright', 301 => 'copyright', 303 => 'copyright', 306 => 'Copyright', 310 => 'copyright' },
-	'copyrightflag' => { 256 => 0x40a },
-	'copyrightnotice' => { 92 => 0x74 },
-	'copyrightowner' => { 300 => 'CopyrightOwner' },
-	'copyrightownerid' => { 300 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerID'] },
-	'copyrightownerimageid' => { 300 => 'CopyrightOwnerImageID' },
-	'copyrightownername' => { 300 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerName'] },
-	'copyrightregistrationnumber' => { 300 => 'CopyrightRegistrationNumber' },
-	'copyrightstatus' => { 300 => 'CopyrightStatus' },
-	'coringfilter' => { 208 => 0x310, 209 => 0x102d, 212 => 0x310 },
-	'coringvalues' => { 208 => 0x311, 212 => 0x311 },
-	'corporateentity' => { 301 => 'corporateEntity' },
-	'country' => { 118 => 'Country', 224 => 0x69, 299 => 'Country' },
-	'country-primarylocationcode' => { 92 => 0x64 },
-	'country-primarylocationname' => { 92 => 0x65 },
-	'countrycode' => { 254 => 'CountryCode', 293 => 'CountryCode' },
-	'coverage' => { 289 => 'coverage' },
-	'coverdate' => { 301 => 'coverDate' },
-	'coverdisplaydate' => { 301 => 'coverDisplayDate' },
-	'cpufirmwareversion' => { 247 => 0x28 },
-	'crc32' => { 290 => 'crc32' },
-	'createdate' => { 85 => 0x9004, 114 => 'CreateDate', 213 => 'CreationDate', 215 => 'create-date', 258 => 'CreationDate', 308 => 'CreateDate' },
-	'creationdate' => { 298 => 'CreationDate', 301 => 'creationDate' },
-	'creationtime' => { 215 => 'Creation Time' },
-	'creativestyle' => { 271 => 0x1a, 272 => 0x18 },
-	'creativestylewaschanged' => { 279 => 0x8001 },
-	'creator' => { 213 => 'Creator', 258 => 'Creator', 289 => 'creator', 298 => 'Creator' },
-	'creatoraddress' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrExtadr'] },
-	'creatorcity' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCity'] },
-	'creatorcontactinfo' => { 293 => 'CreatorContactInfo' },
-	'creatorcountry' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCtry'] },
-	'creatorpostalcode' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrPcode'] },
-	'creatorregion' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiAdrRegion'] },
-	'creatortool' => { 308 => 'CreatorTool' },
-	'creatorworkemail' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiEmailWork'] },
-	'creatorworktelephone' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiTelWork'] },
-	'creatorworkurl' => { 293 => [\'CreatorContactInfo','CreatorContactInfoCiUrlWork'] },
-	'credit' => { 92 => 0x6e, 299 => 'Credit' },
-	'creditline' => { 303 => 'creditLine' },
-	'creditlinereq' => { 313 => 'CreditLineReq' },
-	'creditlinerequired' => { 300 => 'CreditLineRequired' },
-	'cropactive' => { 77 => 0x244 },
-	'cropangle' => { 288 => 'CropAngle' },
-	'cropaspectratio' => { 77 => 0x260 },
-	'cropbottom' => { 88 => 0x9, 185 => 0x36, 253 => 0xdc, 288 => 'CropBottom' },
-	'cropbottommargin' => { 35 => 0x3 },
-	'cropconstraintowarp' => { 288 => 'CropConstrainToWarp' },
-	'cropheight' => { 77 => 0x24c, 208 => 0x615, 212 => 0x615, 288 => 'CropHeight' },
-	'crophispeed' => { 160 => 0x1b },
-	'cropleft' => { 77 => 0x246, 88 => 0x6, 185 => 0x1e, 208 => 0x612, 212 => 0x612, 253 => 0xd9, 288 => 'CropLeft' },
-	'cropleftmargin' => { 35 => 0x0 },
-	'cropoutputheight' => { 185 => 0xce },
-	'cropoutputheightinches' => { 185 => 0x96 },
-	'cropoutputpixels' => { 185 => 0xd6 },
-	'cropoutputresolution' => { 185 => 0xb6 },
-	'cropoutputscale' => { 185 => 0xbe },
-	'cropoutputwidth' => { 185 => 0xc6 },
-	'cropoutputwidthinches' => { 185 => 0x8e },
-	'croppedimageheight' => { 3 => 0x2 },
-	'croppedimagewidth' => { 3 => 0x1 },
-	'cropright' => { 88 => 0x8, 185 => 0x2e, 253 => 0xdb, 288 => 'CropRight' },
-	'croprightmargin' => { 35 => 0x1 },
-	'croprotation' => { 88 => 0xb },
-	'cropscaledresolution' => { 185 => 0x9e },
-	'cropsourceresolution' => { 185 => 0xae },
-	'croptop' => { 77 => 0x248, 88 => 0x7, 185 => 0x26, 208 => 0x613, 212 => 0x613, 253 => 0xda, 288 => 'CropTop' },
-	'croptopmargin' => { 35 => 0x2 },
-	'cropunit' => { 288 => 'CropUnit' },
-	'cropunits' => { 288 => 'CropUnits' },
-	'cropwidth' => { 77 => 0x24a, 208 => 0x614, 212 => 0x614, 288 => 'CropWidth' },
-	'crossprocess' => { 247 => 0x7b },
-	'crossprocessparams' => { 247 => 0x235 },
-	'currenticcprofile' => { 85 => 0xc691 },
-	'currentpreprofilematrix' => { 85 => 0xc692 },
-	'currentversion' => { 279 => 0xd000 },
-	'curves' => { 190 => 0x76a43201 },
-	'custom1' => { 300 => 'Custom1' },
-	'custom10' => { 300 => 'Custom10' },
-	'custom2' => { 300 => 'Custom2' },
-	'custom3' => { 300 => 'Custom3' },
-	'custom4' => { 300 => 'Custom4' },
-	'custom5' => { 300 => 'Custom5' },
-	'custom6' => { 300 => 'Custom6' },
-	'custom7' => { 300 => 'Custom7' },
-	'custom8' => { 300 => 'Custom8' },
-	'custom9' => { 300 => 'Custom9' },
-	'customcontrast' => { 78 => 0x4e },
-	'customcontrols' => { 59 => 0x70c },
-	'customlinear' => { 78 => 0x4f },
-	'customoutputhighlightpoint' => { 78 => 0x53 },
-	'customoutputshadowpoint' => { 78 => 0x54 },
-	'custompicturestylefilename' => { 43 => 0x4010 },
-	'customrawhighlight' => { 78 => 0x7c },
-	'customrawhighlightpoint' => { 78 => 0x51 },
-	'customrawshadow' => { 78 => 0x85 },
-	'customrawshadowpoint' => { 78 => 0x52 },
-	'customrendered' => { 85 => 0xa401, 292 => 'CustomRendered' },
-	'customsaturation' => { 204 => 0x503 },
-	'customsettingsalldefault' => { 197 => '0.2', 200 => '0.2' },
-	'customsettingsbank' => { 197 => '0.1', 200 => '0.1' },
-	'customsharpness' => { 78 => 0x50 },
-	'customwbbluelevel' => { 134 => 0x36 },
-	'customwberror' => { 134 => 0x37 },
-	'customwbgreenlevel' => { 134 => 0x35 },
-	'customwbredlevel' => { 134 => 0x34 },
-	'customwbsetting' => { 134 => 0x26 },
-	'd-lightinghq' => { 190 => 0x2175eb78 },
-	'd-lightinghqcolorboost' => { 186 => 0x2 },
-	'd-lightinghqhighlight' => { 186 => 0x1 },
-	'd-lightinghqselected' => { 190 => 0x6a6e36b6 },
-	'd-lightinghqshadow' => { 186 => 0x0 },
-	'd-lightinghs' => { 190 => 0xce5554aa },
-	'd-lightinghsadjustment' => { 187 => 0x0 },
-	'd-lightinghscolorboost' => { 187 => 0x1 },
-	'd-rangeoptimizerhighlight' => { 279 => 0x8024 },
-	'd-rangeoptimizermode' => { 279 => 0x8022 },
-	'd-rangeoptimizershadow' => { 279 => 0x802d },
-	'd-rangeoptimizervalue' => { 279 => 0x8023 },
-	'datacompressionmethod' => { 94 => 0x6e },
-	'dataimprint' => { 131 => 0x34 },
-	'date' => { 247 => 0x6, 289 => 'date' },
-	'dateacquired' => { 130 => 'DateAcquired' },
-	'datecreated' => { 92 => 0x37, 299 => 'DateCreated' },
-	'datedisplayformat' => { 182 => 0x3 },
-	'dateimprint' => { 199 => '4.2' },
-	'daterecieved' => { 301 => 'dateRecieved' },
-	'datesent' => { 93 => 0x46 },
-	'datestampmode' => { 43 => 0x1c },
-	'datetime' => { 284 => 'datetime', 306 => 'DateTime' },
-	'datetimedigitized' => { 292 => 'DateTimeDigitized' },
-	'datetimeoriginal' => { 75 => 0x0, 85 => 0x9003, 111 => 0x14, 114 => 'OriginalDate', 259 => 0xb, 292 => 'DateTimeOriginal' },
-	'datetimestamp' => { 99 => 0x64 },
-	'daylightsavings' => { 182 => 0x2 },
-	'declination' => { 122 => 'Declination' },
-	'decposition' => { 131 => 0x32 },
-	'defaultcroporigin' => { 85 => 0xc61f },
-	'defaultcropsize' => { 85 => 0xc620 },
-	'defaultscale' => { 85 => 0xc61e },
-	'defringe' => { 288 => 'Defringe' },
-	'deletedimagecount' => { 160 => 0xa6, 166 => 0x6e },
-	'derivedfrom' => { 311 => 'DerivedFrom' },
-	'derivedfromalternatepaths' => { 311 => [\'DerivedFrom','DerivedFromAlternatePaths'] },
-	'derivedfromdocumentid' => { 311 => [\'DerivedFrom','DerivedFromDocumentID'] },
-	'derivedfromfilepath' => { 311 => [\'DerivedFrom','DerivedFromFilePath'] },
-	'derivedfromfrompart' => { 311 => [\'DerivedFrom','DerivedFromFromPart'] },
-	'derivedfrominstanceid' => { 311 => [\'DerivedFrom','DerivedFromInstanceID'] },
-	'derivedfromlastmodifydate' => { 311 => [\'DerivedFrom','DerivedFromLastModifyDate'] },
-	'derivedfrommanager' => { 311 => [\'DerivedFrom','DerivedFromManager'] },
-	'derivedfrommanagervariant' => { 311 => [\'DerivedFrom','DerivedFromManagerVariant'] },
-	'derivedfrommanageto' => { 311 => [\'DerivedFrom','DerivedFromManageTo'] },
-	'derivedfrommanageui' => { 311 => [\'DerivedFrom','DerivedFromManageUI'] },
-	'derivedfrommaskmarkers' => { 311 => [\'DerivedFrom','DerivedFromMaskMarkers'] },
-	'derivedfromoriginaldocumentid' => { 311 => [\'DerivedFrom','DerivedFromOriginalDocumentID'] },
-	'derivedfrompartmapping' => { 311 => [\'DerivedFrom','DerivedFromPartMapping'] },
-	'derivedfromrenditionclass' => { 311 => [\'DerivedFrom','DerivedFromRenditionClass'] },
-	'derivedfromrenditionparams' => { 311 => [\'DerivedFrom','DerivedFromRenditionParams'] },
-	'derivedfromtopart' => { 311 => [\'DerivedFrom','DerivedFromToPart'] },
-	'derivedfromversionid' => { 311 => [\'DerivedFrom','DerivedFromVersionID'] },
-	'description' => { 215 => 'Description', 289 => 'description' },
-	'destination' => { 93 => 0x5 },
-	'destinationcity' => { 247 => 0x24, 251 => 0x3 },
-	'destinationcitycode' => { 252 => 0x1001 },
-	'destinationdst' => { 247 => 0x26, 251 => '0.3' },
-	'developmentdynamicrange' => { 89 => 0x1403 },
-	'devicesettingdescription' => { 292 => 'DeviceSettingDescription' },
-	'devicesettingdescriptioncolumns' => { 292 => [\'DeviceSettingDescription','DeviceSettingDescriptionColumns'] },
-	'devicesettingdescriptionrows' => { 292 => [\'DeviceSettingDescription','DeviceSettingDescriptionRows'] },
-	'devicesettingdescriptionsettings' => { 292 => [\'DeviceSettingDescription','DeviceSettingDescriptionSettings'] },
-	'dialdirectiontvav' => { 59 => 0x706 },
-	'digitalcreationdate' => { 92 => 0x3e },
-	'digitalcreationtime' => { 92 => 0x3f },
-	'digitaldeehighlightadj' => { 165 => 0x202 },
-	'digitaldeeshadowadj' => { 165 => 0x200 },
-	'digitaldeethreshold' => { 165 => 0x201 },
-	'digitalfilter01' => { 238 => 0x5 },
-	'digitalfilter02' => { 238 => 0x16 },
-	'digitalfilter03' => { 238 => 0x27 },
-	'digitalfilter04' => { 238 => 0x38 },
-	'digitalfilter05' => { 238 => 0x49 },
-	'digitalfilter06' => { 238 => 0x5a },
-	'digitalfilter07' => { 238 => 0x6b },
-	'digitalfilter08' => { 238 => 0x7c },
-	'digitalfilter09' => { 238 => 0x8d },
-	'digitalfilter10' => { 238 => 0x9e },
-	'digitalfilter11' => { 238 => 0xaf },
-	'digitalfilter12' => { 238 => 0xc0 },
-	'digitalfilter13' => { 238 => 0xd1 },
-	'digitalfilter14' => { 238 => 0xe2 },
-	'digitalfilter15' => { 238 => 0xf3 },
-	'digitalfilter16' => { 238 => 0x104 },
-	'digitalfilter17' => { 238 => 0x115 },
-	'digitalfilter18' => { 238 => 0x126 },
-	'digitalfilter19' => { 238 => 0x137 },
-	'digitalfilter20' => { 238 => 0x148 },
-	'digitalgain' => { 52 => 0xb },
-	'digitalgem' => { 155 => 0x0 },
-	'digitalice' => { 165 => 0x100 },
-	'digitalimageguid' => { 294 => 'DigImageGUID' },
-	'digitalroc' => { 164 => 0x0 },
-	'digitalsourcefiletype' => { 294 => 'DigitalSourcefileType' },
-	'digitalsourcetype' => { 294 => 'DigitalSourceType' },
-	'digitalzoom' => { 24 => 0xc, 81 => 0xa, 99 => 0x68, 113 => 'DigitalZoom', 131 => 0xc, 160 => 0x86, 180 => 0xa, 209 => 0x204, 247 => 0x1e, 252 => 0xa, 269 => 0x204 },
-	'digitalzoomon' => { 269 => 0x21b },
-	'digitalzoomratio' => { 85 => 0xa404, 292 => 'DigitalZoomRatio' },
-	'director' => { 310 => 'director' },
-	'directorphotography' => { 310 => 'directorPhotography' },
-	'directory' => { 86 => 'Directory' },
-	'directoryindex' => { 4 => 0x137, 7 => 0x17e, 9 => [0x233,0x238], 10 => 0x13f, 11 => 0x133, 12 => 0x1df, 13 => [0x1a3,0x1a7], 14 => 0x1f0, 17 => 0x49, 18 => 0x1e5, 20 => 0x1d3 },
-	'directorynumber' => { 151 => 0x6 },
-	'disclaimer' => { 215 => 'Disclaimer' },
-	'displayallafpoints' => { 59 => 0x514 },
-	'displayaperture' => { 24 => 0x23 },
-	'displayedunitsx' => { 257 => 0x2 },
-	'displayedunitsy' => { 257 => 0x6 },
-	'distance1' => { 99 => 0x28 },
-	'distance2' => { 99 => 0x2c },
-	'distance3' => { 99 => 0x30 },
-	'distance4' => { 99 => 0x34 },
-	'distortioncontrol' => { 166 => 0x10 },
-	'distortioncorrection' => { 78 => 0x67, 204 => 0x50b, 240 => 0x0 },
-	'distortioncorrection2' => { 208 => 0x1011 },
-	'distortioncorrectionon' => { 78 => 0x63 },
-	'distributor' => { 301 => 'distributor' },
-	'dmcomment' => { 310 => 'comment' },
-	'dngbackwardversion' => { 85 => 0xc613 },
-	'dnglensinfo' => { 85 => 0xc630 },
-	'dngversion' => { 85 => 0xc612 },
-	'document' => { 215 => 'Document' },
-	'documentancestorid' => { 299 => [\'DocumentAncestors','DocumentAncestorsAncestorID'] },
-	'documentancestors' => { 299 => 'DocumentAncestors' },
-	'documenthistory' => { 92 => 0xe7 },
-	'documentid' => { 311 => 'DocumentID' },
-	'documentname' => { 85 => 0x10d },
-	'documentnotes' => { 92 => 0xe6 },
-	'doi' => { 301 => 'doi' },
-	'dotrange' => { 85 => 0x150 },
-	'drivemode' => { 82 => 0x3103, 131 => 0x6, 134 => 0x1e, 204 => 0x600, 247 => 0x34, 270 => 0x3, 271 => 0x4 },
-	'drivemode2' => { 134 => 0xa, 232 => 0x7 },
-	'dspfirmwareversion' => { 247 => 0x27 },
-	'duration' => { 46 => 0x6a, 112 => 'Duration', 126 => 'Duration', 310 => 'duration' },
-	'durationscale' => { 310 => [\'duration','durationScale'] },
-	'durationvalue' => { 310 => [\'duration','durationValue'] },
-	'dustremovaldata' => { 43 => 0x97 },
-	'dynamicafarea' => { 197 => '1.4', 200 => '1.4' },
-	'dynamicrange' => { 89 => 0x1400 },
-	'dynamicrangeexpansion' => { 247 => 0x69 },
-	'dynamicrangemax' => { 77 => 0x7c },
-	'dynamicrangemin' => { 77 => 0x7a },
-	'dynamicrangeoptimizer' => { 134 => 0x15, 276 => [0xb025,0xb04f] },
-	'dynamicrangeoptimizerlevel' => { 271 => 0x19, 272 => 0x17 },
-	'dynamicrangeoptimizermode' => { 271 => 0x18, 272 => 0x16 },
-	'dynamicrangeoptimizersetting' => { 134 => 0x27 },
-	'dynamicrangesetting' => { 89 => 0x1402 },
-	'e-dialinprogram' => { 232 => '1.3' },
-	'easyexposurecomp' => { 203 => '6.1' },
-	'easyexposurecompensation' => { 197 => '6.4', 200 => '4.4', 201 => '5.2' },
-	'easymode' => { 24 => 0xb },
-	'edgenoisereduction' => { 191 => 0x4, 279 => 0x8028 },
-	'edition' => { 301 => 'edition' },
-	'editorialupdate' => { 92 => 0x8 },
-	'editstatus' => { 92 => 0x7, 254 => 'EditStatus' },
-	'editversionname' => { 190 => 0x3d136244 },
-	'effectivelv' => { 247 => 0x2d },
-	'effectivemaxaperture' => { 158 => 0x12, 159 => 0x13 },
-	'eissn' => { 301 => 'eIssn' },
-	'elevation' => { 122 => 'Elevation' },
-	'email' => { 114 => 'EMail' },
-	'embargodate' => { 301 => 'embargoDate', 303 => 'embargoDate' },
-	'encryptionkey' => { 267 => 0xa020 },
-	'endingpage' => { 301 => 'endingPage' },
-	'enduser' => { 300 => 'EndUser' },
-	'enduserid' => { 300 => [\'EndUser','EndUserEndUserID'] },
-	'endusername' => { 300 => [\'EndUser','EndUserEndUserName'] },
-	'engineer' => { 310 => 'engineer' },
-	'enhancedarktones' => { 183 => 0x8 },
-	'enhancement' => { 81 => 0x16, 82 => 0x3016 },
-	'enhancer' => { 208 => 0x300 },
-	'enhancervalues' => { 208 => 0x301 },
-	'envelopenumber' => { 93 => 0x28 },
-	'envelopepriority' => { 93 => 0x3c },
-	'enveloperecordversion' => { 93 => 0x0 },
-	'epsonimageheight' => { 209 => 0x20c },
-	'epsonimagewidth' => { 209 => 0x20b },
-	'epsonsoftware' => { 209 => 0x20d },
-	'equipmentinstitution' => { 281 => 'EquipmentInstitution' },
-	'equipmentmanufacturer' => { 281 => 'EquipmentManufacturer' },
-	'equipmentversion' => { 205 => 0x0 },
-	'ettlii' => { 59 => 0x304, 60 => 0xd, 61 => 0xe, 62 => 0x7, 63 => 0x7, 64 => 0xe },
-	'event' => { 283 => 'Event', 294 => 'Event', 301 => 'event' },
-	'eventnumber' => { 259 => 0x9 },
-	'evsteps' => { 232 => '1.2', 234 => 0x0 },
-	'evstepsize' => { 199 => '5.1', 202 => '0.7' },
-	'exclusivityenddate' => { 303 => 'exclusivityEndDate' },
-	'excursiontolerance' => { 94 => 0x82 },
-	'exif' => { 86 => 'EXIF' },
-	'exifbyteorder' => { 86 => 'ExifByteOrder' },
-	'exifcamerainfo' => { 92 => 0xe8 },
-	'exifimageheight' => { 85 => 0xa003, 292 => 'PixelYDimension' },
-	'exifimagewidth' => { 85 => 0xa002, 292 => 'PixelXDimension' },
-	'exifunicodebyteorder' => { 86 => 'ExifUnicodeByteOrder' },
-	'exifversion' => { 85 => 0x9000, 292 => 'ExifVersion' },
-	'exitpupilposition' => { 158 => 0x4, 159 => 0x4 },
-	'expirationdate' => { 92 => 0x25, 301 => 'expirationDate', 303 => 'expirationDate' },
-	'expirationtime' => { 92 => 0x26 },
-	'exposure' => { 85 => 0xfe51, 288 => 'Exposure' },
-	'exposureadj' => { 188 => 0x0 },
-	'exposureadj2' => { 188 => 0x12 },
-	'exposureadjust' => { 270 => 0xc },
-	'exposurebracketingindicatorlast' => { 134 => 0x52 },
-	'exposurebracketstepsize' => { 232 => 0x8 },
-	'exposurebracketvalue' => { 160 => 0x19 },
-	'exposurecompensation' => { 54 => 0x6, 68 => 0x0, 85 => 0x9204, 99 => 0x24, 113 => 'ExposureComp', 131 => 0xd, 132 => 0x53, 133 => 0x1e, 209 => 0x1006, 247 => 0x16, 267 => 0xa013, 270 => [0xc,0x35], 292 => 'ExposureBiasValue' },
-	'exposurecompensationmode' => { 134 => 0x47 },
-	'exposurecompensationsetting' => { 134 => 0x1 },
-	'exposurecompstepsize' => { 197 => '6.3', 200 => '4.3' },
-	'exposurecontrolstep' => { 201 => '6.1' },
-	'exposurecontrolstepsize' => { 197 => '6.2', 200 => '4.2', 203 => '7.1' },
-	'exposuredelaymode' => { 197 => '10.1', 199 => '9.1', 200 => '10.4', 201 => '10.1', 202 => '6.4', 203 => '11.2' },
-	'exposuredifference' => { 160 => 0xe },
-	'exposureindex' => { 85 => 0xa215, 292 => 'ExposureIndex' },
-	'exposureindicator' => { 134 => 0x50 },
-	'exposurelevelincrements' => { 57 => 0x6, 58 => 0x6, 59 => 0x101, 60 => 0x5, 61 => 0x6, 62 => 0x5, 63 => 0x5, 64 => 0x6, 65 => 0x4, 271 => 0x58 },
-	'exposuremode' => { 85 => 0xa402, 113 => 'ExposureMode', 131 => 0x1, 132 => 0xa, 133 => 0x0, 134 => 0x0, 204 => 0x200, 221 => 0x40d, 270 => 0x8, 276 => 0xb041, 292 => 'ExposureMode' },
-	'exposuremodeinmanual' => { 59 => 0x10b },
-	'exposureprogram' => { 85 => 0x8822, 271 => 0x3c, 272 => 0x3c, 292 => 'ExposureProgram' },
-	'exposureshift' => { 204 => 0x203 },
-	'exposuretime' => { 4 => 0x4, 5 => 0x4, 6 => 0x4, 7 => 0x4, 8 => 0x4, 9 => 0x4, 10 => 0x4, 11 => 0x4, 12 => 0x4, 13 => 0x4, 14 => 0x4, 15 => 0x4, 16 => 0x4, 18 => 0x4, 19 => 0x4, 21 => 0x6, 22 => 0x7, 54 => 0x16, 85 => 0x829a, 96 => 0xfd05, 99 => 0x20, 101 => 0xfa24, 103 => 0xf104, 106 => 0x12, 108 => 0x38, 111 => 0x10, 113 => 'ExposureTime', 131 => 0x9, 132 => 0x35, 133 => 0x48, 134 => 0x8, 247 => 0x12, 267 => 0xa018, 270 => 0x32, 292 => 'ExposureTime' },
-	'exposuretime2' => { 270 => 0x33 },
-	'exposuretuning' => { 160 => 0x1c },
-	'exposurevalue' => { 97 => 0x3 },
-	'exposurewarning' => { 89 => 0x1302 },
-	'exrauto' => { 89 => 0x1033 },
-	'exrmode' => { 89 => 0x1034 },
-	'extendedwbdetect' => { 204 => 0x902 },
-	'extender' => { 205 => 0x301 },
-	'extenderfirmwareversion' => { 205 => 0x304 },
-	'extendermagnification' => { 115 => 'Magnification' },
-	'extendermake' => { 115 => 'Make' },
-	'extendermodel' => { 115 => 'Model', 205 => 0x303 },
-	'extenderserialnumber' => { 115 => 'SerialNumber', 205 => 0x302 },
-	'externalflash' => { 207 => 0x1201 },
-	'externalflashae1' => { 209 => 0x101f },
-	'externalflashae1_0' => { 209 => 0x101b },
-	'externalflashae2' => { 209 => 0x1020 },
-	'externalflashae2_0' => { 209 => 0x101c },
-	'externalflashbounce' => { 207 => 0x1204, 209 => 0x1026, 239 => 0x1a },
-	'externalflashexposurecomp' => { 160 => 0x17, 239 => 0x19 },
-	'externalflashfirmware' => { 152 => 0x6, 153 => 0x6, 154 => 0x6 },
-	'externalflashflags' => { 152 => 0x8, 153 => 0x8, 154 => 0x8 },
-	'externalflashguidenumber' => { 207 => 0x1203, 239 => '24.1' },
-	'externalflashgvalue' => { 209 => 0x1025 },
-	'externalflashmode' => { 209 => 0x1028, 239 => 0x2 },
-	'externalflashzoom' => { 207 => 0x1205, 209 => 0x1027 },
-	'externalsensorbrightnessvalue' => { 219 => 0x311, 225 => 0x3408 },
-	'eyestartaf' => { 134 => 0x40 },
-	'face10position' => { 79 => 0x3f4, 80 => 0x1ec, 150 => 0x28, 236 => 0x12 },
-	'face10size' => { 237 => 0x12 },
-	'face11position' => { 150 => 0x2c, 236 => 0x14 },
-	'face11size' => { 237 => 0x14 },
-	'face12position' => { 150 => 0x30, 236 => 0x16 },
-	'face12size' => { 237 => 0x16 },
-	'face13position' => { 236 => 0x18 },
-	'face13size' => { 237 => 0x18 },
-	'face14position' => { 236 => 0x1a },
-	'face14size' => { 237 => 0x1a },
-	'face15position' => { 236 => 0x1c },
-	'face15size' => { 237 => 0x1c },
-	'face16position' => { 236 => 0x1e },
-	'face16size' => { 237 => 0x1e },
-	'face17position' => { 236 => 0x20 },
-	'face17size' => { 237 => 0x20 },
-	'face18position' => { 236 => 0x22 },
-	'face18size' => { 237 => 0x22 },
-	'face19position' => { 236 => 0x24 },
-	'face19size' => { 237 => 0x24 },
-	'face1position' => { 36 => 0x8, 79 => 0xd, 80 => 0x18, 150 => 0x4, 217 => 0x1, 236 => 0x0, 260 => 0xbc, 274 => 0x0, 275 => 0x0 },
-	'face1size' => { 237 => 0x0 },
-	'face20position' => { 236 => 0x26 },
-	'face20size' => { 237 => 0x26 },
-	'face21position' => { 236 => 0x28 },
-	'face21size' => { 237 => 0x28 },
-	'face22position' => { 236 => 0x2a },
-	'face22size' => { 237 => 0x2a },
-	'face23position' => { 236 => 0x2c },
-	'face23size' => { 237 => 0x2c },
-	'face24position' => { 236 => 0x2e },
-	'face24size' => { 237 => 0x2e },
-	'face25position' => { 236 => 0x30 },
-	'face25size' => { 237 => 0x30 },
-	'face26position' => { 236 => 0x32 },
-	'face26size' => { 237 => 0x32 },
-	'face27position' => { 236 => 0x34 },
-	'face27size' => { 237 => 0x34 },
-	'face28position' => { 236 => 0x36 },
-	'face28size' => { 237 => 0x36 },
-	'face29position' => { 236 => 0x38 },
-	'face29size' => { 237 => 0x38 },
-	'face2position' => { 36 => 0xa, 79 => 0x7c, 80 => 0x4c, 150 => 0x8, 217 => 0x5, 236 => 0x2, 260 => 0xc8, 274 => 0x20, 275 => 0x25 },
-	'face2size' => { 237 => 0x2 },
-	'face30position' => { 236 => 0x3a },
-	'face30size' => { 237 => 0x3a },
-	'face31position' => { 236 => 0x3c },
-	'face31size' => { 237 => 0x3c },
-	'face32position' => { 236 => 0x3e },
-	'face32size' => { 237 => 0x3e },
-	'face3position' => { 36 => 0xc, 79 => 0xeb, 80 => 0x80, 150 => 0xc, 217 => 0x9, 236 => 0x4, 260 => 0xd4, 274 => 0x40, 275 => 0x4a },
-	'face3size' => { 237 => 0x4 },
-	'face4position' => { 36 => 0xe, 79 => 0x15a, 80 => 0xb4, 150 => 0x10, 217 => 0xd, 236 => 0x6, 260 => 0xe0, 274 => 0x60, 275 => 0x6f },
-	'face4size' => { 237 => 0x6 },
-	'face5position' => { 36 => 0x10, 79 => 0x1c9, 80 => 0xe8, 150 => 0x14, 217 => 0x11, 236 => 0x8, 260 => 0xec, 274 => 0x80, 275 => 0x94 },
-	'face5size' => { 237 => 0x8 },
-	'face6position' => { 36 => 0x12, 79 => 0x238, 80 => 0x11c, 150 => 0x18, 236 => 0xa, 260 => 0xf8, 274 => 0xa0, 275 => 0xb9 },
-	'face6size' => { 237 => 0xa },
-	'face7position' => { 36 => 0x14, 79 => 0x2a7, 80 => 0x150, 150 => 0x1c, 236 => 0xc, 260 => 0x104, 274 => 0xc0, 275 => 0xde },
-	'face7size' => { 237 => 0xc },
-	'face8position' => { 36 => 0x16, 79 => 0x316, 80 => 0x184, 150 => 0x20, 236 => 0xe, 260 => 0x110, 274 => 0xe0, 275 => 0x103 },
-	'face8size' => { 237 => 0xe },
-	'face9position' => { 36 => 0x18, 79 => 0x385, 80 => 0x1b8, 150 => 0x24, 236 => 0x10 },
-	'face9size' => { 237 => 0x10 },
-	'facedetect' => { 247 => 0x76 },
-	'facedetectarea' => { 208 => 0x1201 },
-	'facedetectframecrop' => { 208 => 0x1207 },
-	'facedetectframesize' => { 36 => 0x3, 79 => 0x1, 80 => 0x4, 150 => 0x1, 208 => 0x1203, 247 => 0x77, 260 => 0xb6 },
-	'faceinfounknown' => { 82 => 0x2089 },
-	'faceorientation' => { 80 => 0x8 },
-	'faceposition' => { 235 => 0x2, 268 => 0x4 },
-	'facepositions' => { 89 => 0x4103 },
-	'facesdetected' => { 36 => 0x2, 37 => 0x2, 79 => 0x0, 80 => 0x2, 82 => 0x211c, 89 => 0x4100, 150 => 0x3, 208 => 0x1200, 224 => 0x3f, 235 => 0x0, 260 => 0xb5, 268 => 0x0, 278 => 0x30 },
-	'facesrecognized' => { 218 => 0x0 },
-	'facewidth' => { 37 => 0x1 },
-	'faithfuloutputhighlightpoint' => { 78 => 0x38 },
-	'faithfuloutputshadowpoint' => { 78 => 0x39 },
-	'faithfulrawcolortone' => { 78 => 0x31 },
-	'faithfulrawcontrast' => { 78 => 0x33 },
-	'faithfulrawhighlight' => { 78 => 0x79 },
-	'faithfulrawhighlightpoint' => { 78 => 0x36 },
-	'faithfulrawlinear' => { 78 => 0x34 },
-	'faithfulrawsaturation' => { 78 => 0x32 },
-	'faithfulrawshadow' => { 78 => 0x82 },
-	'faithfulrawshadowpoint' => { 78 => 0x37 },
-	'faithfulrawsharpness' => { 78 => 0x35 },
-	'femicroadjustment' => { 59 => 0x110 },
-	'ffid' => { 290 => 'ffid' },
-	'fieldcount' => { 209 => 0x103f },
-	'filedatarate' => { 310 => 'fileDataRate' },
-	'fileformat' => { 70 => 0x0, 93 => 0x14, 270 => 0x22, 276 => 0xb000 },
-	'fileindex' => { 4 => 0x143, 7 => 0x172, 9 => [0x227,0x22c], 10 => 0x133, 11 => 0x13f, 12 => 0x1d3, 13 => [0x197,0x19b], 14 => 0x1e4, 17 => 0x3d, 18 => 0x1d9, 20 => 0x1c7 },
-	'filemodifydate' => { 86 => 'FileModifyDate' },
-	'filename' => { 86 => 'FileName' },
-	'filenameasdelivered' => { 300 => 'FileNameAsDelivered' },
-	'filenumber' => { 38 => 0x1, 43 => 0x8, 72 => 0x1817, 83 => 'FileNumber', 151 => 0x8 },
-	'filenumbermemory' => { 131 => 0x1a },
-	'filenumbersequence' => { 197 => '12.2', 199 => '3.1', 200 => '11.1', 201 => '4.3', 203 => '5.2' },
-	'filesource' => { 85 => 0xa300, 89 => 0x8000, 292 => 'FileSource' },
-	'fileversion' => { 93 => 0x16 },
-	'fillflashautoreduction' => { 57 => 0xe, 58 => 0xe, 65 => 0xa },
-	'filllight' => { 288 => 'FillLight' },
-	'fillorder' => { 85 => 0x10a },
-	'filmmode' => { 89 => 0x1401, 221 => 0x412, 224 => 0x42 },
-	'filmtype' => { 165 => 0x2 },
-	'filtereffect' => { 38 => 0xe, 162 => 0x37 },
-	'filtereffectfaithful' => { 48 => 0x70, 49 => 0x70 },
-	'filtereffectlandscape' => { 48 => 0x40, 49 => 0x40 },
-	'filtereffectmonochrome' => { 15 => 0xff, 48 => 0x88, 49 => 0x88 },
-	'filtereffectneutral' => { 48 => 0x58, 49 => 0x58 },
-	'filtereffectportrait' => { 48 => 0x28, 49 => 0x28 },
-	'filtereffectstandard' => { 48 => 0x10, 49 => 0x10 },
-	'filtereffectunknown' => { 49 => 0xa0 },
-	'filtereffectuserdef1' => { 48 => 0xa0, 49 => 0xb8 },
-	'filtereffectuserdef2' => { 48 => 0xb8, 49 => 0xd0 },
-	'filtereffectuserdef3' => { 48 => 0xd0, 49 => 0xe8 },
-	'finderdisplayduringexposure' => { 58 => 0x1 },
-	'finesharpness' => { 247 => 0x70 },
-	'finetuneoptcenterweighted' => { 197 => '7.2', 203 => '9.1' },
-	'finetuneoptmatrixmetering' => { 197 => '8.1', 200 => '6.1', 203 => '8.2' },
-	'finetuneoptspotmetering' => { 197 => '8.2', 200 => '6.2', 203 => '9.2' },
-	'firmware' => { 209 => 0x405, 270 => [0x17,0x3b], 285 => 'Firmware' },
-	'firmwaredate' => { 81 => 0x15, 82 => 0x2001, 259 => 0x4 },
-	'firmwareid' => { 137 => 0x0 },
-	'firmwarename' => { 267 => 0xa001 },
-	'firmwarerevision' => { 15 => 0xa4, 43 => 0x1e, 261 => 0x0 },
-	'firmwarerevision2' => { 261 => 0xc },
-	'firmwareversion' => { 4 => 0x10b, 7 => 0x136, 10 => 0xff, 11 => 0x107, 97 => 0xce5, 111 => 0x57, 113 => 'FirmwareVersion', 224 => 0x2, 225 => 0x3109, 247 => 0x230, 263 => 0x2 },
-	'firstpublicationdate' => { 300 => 'FirstPublicationDate' },
-	'fixtureidentifier' => { 92 => 0x16 },
-	'flash' => { 85 => 0x9209, 132 => 0x1f, 133 => 0x15, 292 => 'Flash' },
-	'flashactivity' => { 24 => 0x1c },
-	'flashbatterylevel' => { 30 => 0x249 },
-	'flashbias' => { 224 => 0x24 },
-	'flashbits' => { 24 => 0x1d },
-	'flashchargelevel' => { 209 => 0x1010 },
-	'flashcolorfilter' => { 154 => 0x10 },
-	'flashcommandermode' => { 152 => '9.1', 153 => '9.1', 154 => '9.1' },
-	'flashcompensation' => { 152 => 0xa, 153 => 0xa, 154 => 0xa, 285 => 'FlashCompensation' },
-	'flashcontrolbuilt-in' => { 200 => '16.1', 201 => '23.1' },
-	'flashcontrolmode' => { 152 => '9.2', 153 => '9.2', 154 => '9.2', 204 => 0x404 },
-	'flashdefault' => { 134 => 0x42 },
-	'flashdevice' => { 209 => 0x1005 },
-	'flashdistance' => { 82 => 0x2034 },
-	'flashenergy' => { 85 => 0xa20b, 292 => 'FlashEnergy' },
-	'flashexposurebracketvalue' => { 160 => 0x18 },
-	'flashexposurecomp' => { 54 => 0xf, 89 => 0x1011, 116 => 'ExposureComp', 131 => 0x23, 135 => 0x104, 160 => 0x12, 204 => 0x401, 209 => 0x1023, 247 => 0x4d, 270 => 0x3a, 276 => 0x104 },
-	'flashexposurecompset' => { 227 => 0xe },
-	'flashexposurecompsetting' => { 134 => 0x10 },
-	'flashexposureindicator' => { 134 => 0x54 },
-	'flashexposureindicatorlast' => { 134 => 0x56 },
-	'flashexposureindicatornext' => { 134 => 0x55 },
-	'flashexposurelock' => { 38 => 0x19 },
-	'flashfired' => { 99 => 0x5d, 116 => 'Fired', 131 => 0x14, 178 => '590.3', 224 => 0x8007, 292 => [\'Flash','FlashFired'] },
-	'flashfiring' => { 59 => 0x306, 60 => 0x6, 61 => 0x7, 64 => 0x7 },
-	'flashfirmwareversion' => { 205 => 0x1002 },
-	'flashfocallength' => { 152 => 0xb, 153 => 0xc, 154 => 0xc },
-	'flashfunction' => { 292 => [\'Flash','FlashFunction'] },
-	'flashgndistance' => { 152 => 0xe, 153 => 0xf, 154 => 0xf },
-	'flashgroupacompensation' => { 152 => 0x11, 153 => 0x12, 154 => 0x13 },
-	'flashgroupacontrolmode' => { 152 => 0xf, 153 => '16.1', 154 => '17.1' },
-	'flashgroupaoutput' => { 152 => 0x11, 153 => 0x12, 154 => 0x13 },
-	'flashgroupbcompensation' => { 152 => 0x12, 153 => 0x13, 154 => 0x14 },
-	'flashgroupbcontrolmode' => { 152 => 0x10, 153 => '17.1', 154 => '18.1' },
-	'flashgroupboutput' => { 152 => 0x12, 153 => 0x13, 154 => 0x14 },
-	'flashgroupccompensation' => { 153 => 0x14, 154 => 0x15 },
-	'flashgroupccontrolmode' => { 153 => '17.2', 154 => '18.2' },
-	'flashgroupcoutput' => { 153 => 0x14, 154 => 0x15 },
-	'flashguidenumber' => { 54 => 0xd, 69 => 0x0, 116 => 'GuideNumber' },
-	'flashintensity' => { 81 => [0x19,0x5], 204 => 0x405 },
-	'flashlevel' => { 198 => 0x9, 276 => 0xb048 },
-	'flashmake' => { 116 => 'Make' },
-	'flashmanufacturer' => { 130 => 'FlashManufacturer' },
-	'flashmetering' => { 131 => 0x3f, 134 => 0x1c },
-	'flashmeteringmode' => { 4 => 0x15, 9 => 0x15, 10 => 0x15, 11 => 0x15, 12 => 0x15, 13 => 0x15, 14 => 0x15, 16 => 0x15, 19 => 0x15 },
-	'flashmeteringsegments' => { 247 => 0x20a },
-	'flashmode' => { 81 => 0x4, 99 => 0x5c, 116 => 'Mode', 131 => 0x2, 132 => 0x20, 133 => 0x16, 134 => 0xf, 160 => 0x87, 204 => 0x400, 209 => 0x1004, 247 => 0xc, 252 => 0x4, 262 => 0x20, 269 => 0x225, 271 => 0x23, 272 => 0x23, 292 => [\'Flash','FlashMode'] },
-	'flashmodel' => { 116 => 'Model', 130 => 'FlashModel', 205 => 0x1001 },
-	'flashoptions' => { 232 => 0x2 },
-	'flashoptions2' => { 232 => 0x10 },
-	'flashoutput' => { 30 => 0x248, 54 => 0x21, 152 => 0xa, 153 => 0xa, 154 => 0xa },
-	'flashpixversion' => { 85 => 0xa000, 292 => 'FlashpixVersion' },
-	'flashredeyemode' => { 292 => [\'Flash','FlashRedEyeMode'] },
-	'flashremotecontrol' => { 204 => 0x403 },
-	'flashreturn' => { 292 => [\'Flash','FlashReturn'] },
-	'flashserialnumber' => { 116 => 'SerialNumber', 205 => 0x1003 },
-	'flashsetting' => { 160 => 0x8 },
-	'flashshutterspeed' => { 197 => '20.2', 200 => '15.2', 201 => '22.2', 202 => '7.2', 203 => '23.1' },
-	'flashsource' => { 152 => 0x4, 153 => 0x4, 154 => 0x4 },
-	'flashstatus' => { 239 => 0x0 },
-	'flashsyncspeed' => { 197 => '20.1', 200 => '15.1', 201 => '22.1' },
-	'flashsyncspeedav' => { 57 => 0x3, 59 => 0x10f, 60 => 0x2, 61 => 0x3, 62 => 0x2, 63 => 0x2, 64 => 0x3, 65 => 0x6 },
-	'flashthreshold' => { 69 => 0x1 },
-	'flashtype' => { 116 => 'Type', 134 => 0x59, 160 => 0x9, 205 => 0x1000 },
-	'flashwarning' => { 201 => '30.1', 202 => '7.1', 203 => '31.1', 224 => 0x62 },
-	'flickerreduce' => { 269 => 0x218 },
-	'fliphorizontal' => { 190 => 0x76a43206 },
-	'fnumber' => { 4 => 0x3, 7 => 0x3, 9 => 0x3, 10 => 0x3, 11 => 0x3, 12 => 0x3, 13 => 0x3, 14 => 0x3, 15 => 0x3, 16 => 0x3, 18 => 0x3, 19 => 0x3, 21 => 0x5, 22 => 0x6, 54 => 0x15, 85 => 0x829d, 96 => 0xfd04, 99 => 0x1e, 101 => 0xfa23, 103 => 0xf103, 106 => 0x13, 108 => 0x3c, 111 => 0xc, 120 => 'FNumber', 131 => 0xa, 132 => 0x36, 133 => 0x47, 134 => 0x9, 247 => 0x13, 267 => 0xa019, 270 => 0x31, 292 => 'FNumber' },
-	'focallength' => { 4 => 0x1d, 5 => 0xa, 6 => 0x9, 7 => 0x1d, 8 => 0x9, 9 => 0x1e, 10 => 0x1d, 11 => 0x1d, 12 => 0x1e, 13 => 0x1e, 14 => 0x1e, 15 => 0x28, 16 => 0x1e, 18 => 0x1e, 19 => 0x1e, 40 => 0x1, 82 => 0x1d, 85 => 0x920a, 106 => 0x1d, 120 => 'FocalLength', 131 => 0x12, 158 => 0xa, 159 => 0xb, 241 => 0x9, 247 => 0x1d, 292 => 'FocalLength' },
-	'focallengthin35mmformat' => { 85 => 0xa405, 267 => 0xa01a, 292 => 'FocalLengthIn35mmFilm' },
-	'focalplanediagonal' => { 205 => 0x103, 209 => 0x205 },
-	'focalplaneresolutionunit' => { 85 => 0xa210, 292 => 'FocalPlaneResolutionUnit' },
-	'focalplanexresolution' => { 85 => 0xa20e, 292 => 'FocalPlaneXResolution' },
-	'focalplanexsize' => { 40 => 0x2 },
-	'focalplanexunknown' => { 40 => 0x2 },
-	'focalplaneyresolution' => { 85 => 0xa20f, 292 => 'FocalPlaneYResolution' },
-	'focalplaneysize' => { 40 => 0x3 },
-	'focalplaneyunknown' => { 40 => 0x3 },
-	'focaltype' => { 6 => 0x2d, 40 => 0x0 },
-	'focalunits' => { 24 => 0x19 },
-	'focus' => { 180 => 0x8 },
-	'focusarea' => { 131 => 0x31 },
-	'focusareaselection' => { 202 => '15.2' },
-	'focuscontinuous' => { 24 => 0x20 },
-	'focusdisplayaiservoandmf' => { 59 => 0x515 },
-	'focusdistance' => { 120 => 'FocusDistance', 131 => 0x13, 158 => 0x9, 159 => 0xa, 207 => 0x305 },
-	'focusdistancelower' => { 4 => 0x45, 7 => 0x45, 9 => 0x56, 10 => 0x45, 11 => 0x45, 12 => 0x52, 13 => 0x52, 14 => 0x56, 16 => 0x52, 18 => 0x57, 20 => 0x32, 54 => 0x14 },
-	'focusdistanceupper' => { 4 => 0x43, 7 => 0x43, 9 => 0x54, 10 => 0x43, 11 => 0x43, 12 => 0x50, 13 => 0x50, 14 => 0x54, 16 => 0x50, 18 => 0x55, 20 => 0x30, 54 => 0x13 },
-	'focusholdbutton' => { 134 => 0x44 },
-	'focusinfoversion' => { 207 => 0x0 },
-	'focusingscreen' => { 58 => 0x0, 59 => 0x80b, 64 => 0x0 },
-	'focusmode' => { 24 => 0x7, 81 => 0x3, 82 => [0x3003,0xd], 89 => 0x1021, 99 => 0x38, 113 => 'FocusMode', 131 => 0x30, 133 => 0xe, 134 => 0xc, 160 => 0x7, 204 => 0x301, 209 => 0x100b, 224 => 0x7, 247 => 0xd, 252 => 0x3, 271 => 0x10, 272 => 0x10, 276 => 0xb042 },
-	'focusmode2' => { 232 => '3.1' },
-	'focusmodesetting' => { 198 => '10.1' },
-	'focusmodeswitch' => { 134 => 0x58 },
-	'focuspixel' => { 89 => 0x1023 },
-	'focuspointwrap' => { 197 => '2.2', 200 => '2.2', 201 => '1.2', 203 => '2.5' },
-	'focusposition' => { 158 => 0x8, 159 => 0x8, 247 => 0x10 },
-	'focusprocess' => { 204 => 0x302 },
-	'focusrange' => { 24 => 0x12, 209 => 0x100a },
-	'focussetting' => { 270 => 0x6 },
-	'focusstepcount' => { 207 => 0x301, 209 => 0x100e },
-	'focusstepinfinity' => { 207 => 0x303, 209 => 0x103b },
-	'focusstepnear' => { 207 => 0x304, 209 => 0x103c },
-	'focustrackinglockon' => { 197 => ['1.5','4.1'], 200 => '3.1', 201 => '0.4' },
-	'focuswarning' => { 89 => 0x1301 },
-	'foldername' => { 131 => 0x27 },
-	'fontcomposite' => { 315 => [\'Fonts','FontsComposite'] },
-	'fontface' => { 315 => [\'Fonts','FontsFontFace'] },
-	'fontfamily' => { 315 => [\'Fonts','FontsFontFamily'] },
-	'fontfilename' => { 315 => [\'Fonts','FontsFontFileName'] },
-	'fontname' => { 315 => [\'Fonts','FontsFontName'] },
-	'fonts' => { 315 => 'Fonts' },
-	'fonttype' => { 315 => [\'Fonts','FontsFontType'] },
-	'fontversion' => { 315 => [\'Fonts','FontsVersionString'] },
-	'for' => { 258 => 'For' },
-	'format' => { 289 => 'format' },
-	'forwardlock' => { 305 => 'forwardlock' },
-	'forwardmatrix1' => { 85 => 0xc714 },
-	'forwardmatrix2' => { 85 => 0xc715 },
-	'framecount' => { 46 => [0x2,0x4] },
-	'framenum' => { 253 => 0xd7 },
-	'framenumber' => { 89 => 0x8003, 247 => 0x29 },
-	'framerate' => { 46 => [0x1,0x6] },
-	'frameselector' => { 223 => '0.1' },
-	'freebytes' => { 72 => 0x1 },
-	'freememorycardimages' => { 132 => [0x37,0x54], 133 => [0x2d,0x4a], 134 => 0x32 },
-	'fujiflashmode' => { 89 => 0x1010 },
-	'fullimagesize' => { 276 => 0xb02b },
-	'fullsizeimage' => { 119 => 'data' },
-	'fullsizeimagename' => { 119 => '1Name' },
-	'fullsizeimagetype' => { 119 => '0Type' },
-	'funcbutton' => { 197 => ['14.1','15.1'], 200 => '28.1', 201 => '13.1', 203 => '14.1' },
-	'funcbuttonplusdials' => { 197 => ['14.2','15.2'], 200 => '31.1' },
-	'functionbutton' => { 202 => '5.2' },
-	'gainbase' => { 208 => 0x610 },
-	'gaincontrol' => { 85 => 0xa407, 292 => 'GainControl' },
-	'gamma' => { 85 => 0xa500 },
-	'gammacompensatedvalue' => { 94 => 0x91 },
-	'geimagesize' => { 89 => 0x1304 },
-	'gemake' => { 90 => 0x300 },
-	'gemodel' => { 90 => 0x207 },
-	'genre' => { 301 => 'genre', 310 => 'genre' },
-	'geography' => { 302 => 'geography' },
-	'geosync' => { 86 => 'Geosync' },
-	'geotag' => { 86 => 'Geotag' },
-	'geotime' => { 86 => 'Geotime' },
-	'globalaltitude' => { 256 => 0x419 },
-	'globalangle' => { 256 => 0x40d },
-	'good' => { 310 => 'good' },
-	'gpsaltitude' => { 91 => 0x6, 117 => 'Altitude', 292 => 'GPSAltitude' },
-	'gpsaltituderef' => { 91 => 0x5, 292 => 'GPSAltitudeRef' },
-	'gpsareainformation' => { 91 => 0x1c, 292 => 'GPSAreaInformation' },
-	'gpsdatestamp' => { 91 => 0x1d },
-	'gpsdatetime' => { 117 => 'DateTime', 292 => 'GPSTimeStamp' },
-	'gpsdestbearing' => { 91 => 0x18, 117 => 'Bearing', 292 => 'GPSDestBearing' },
-	'gpsdestbearingref' => { 91 => 0x17, 292 => 'GPSDestBearingRef' },
-	'gpsdestdistance' => { 91 => 0x1a, 117 => 'Distance', 292 => 'GPSDestDistance' },
-	'gpsdestdistanceref' => { 91 => 0x19, 292 => 'GPSDestDistanceRef' },
-	'gpsdestlatitude' => { 91 => 0x14, 292 => 'GPSDestLatitude' },
-	'gpsdestlatituderef' => { 91 => 0x13 },
-	'gpsdestlongitude' => { 91 => 0x16, 292 => 'GPSDestLongitude' },
-	'gpsdestlongituderef' => { 91 => 0x15 },
-	'gpsdifferential' => { 91 => 0x1e, 117 => 'Differential', 292 => 'GPSDifferential' },
-	'gpsdop' => { 91 => 0xb, 292 => 'GPSDOP' },
-	'gpshpositioningerror' => { 91 => 0x1f },
-	'gpsimgdirection' => { 91 => 0x11, 292 => 'GPSImgDirection' },
-	'gpsimgdirectionref' => { 91 => 0x10, 292 => 'GPSImgDirectionRef' },
-	'gpslatitude' => { 91 => 0x2, 117 => 'Latitude', 292 => 'GPSLatitude' },
-	'gpslatituderef' => { 91 => 0x1 },
-	'gpslongitude' => { 91 => 0x4, 117 => 'Longitude', 292 => 'GPSLongitude' },
-	'gpslongituderef' => { 91 => 0x3 },
-	'gpsmapdatum' => { 91 => 0x12, 117 => 'Datum', 292 => 'GPSMapDatum' },
-	'gpsmeasuremode' => { 91 => 0xa, 117 => 'MeasureMode', 292 => 'GPSMeasureMode' },
-	'gpsprocessingmethod' => { 91 => 0x1b, 292 => 'GPSProcessingMethod' },
-	'gpssatellites' => { 91 => 0x8, 117 => 'Satellites', 292 => 'GPSSatellites' },
-	'gpsspeed' => { 91 => 0xd, 117 => 'Speed', 292 => 'GPSSpeed' },
-	'gpsspeedref' => { 91 => 0xc, 292 => 'GPSSpeedRef' },
-	'gpsstatus' => { 91 => 0x9, 292 => 'GPSStatus' },
-	'gpstimestamp' => { 91 => 0x7 },
-	'gpstrack' => { 91 => 0xf, 117 => 'Heading', 292 => 'GPSTrack' },
-	'gpstrackref' => { 91 => 0xe, 292 => 'GPSTrackRef' },
-	'gpsversionid' => { 91 => 0x0, 292 => 'GPSVersionID' },
-	'gradation' => { 204 => 0x50f },
-	'gradientbasedcorractive' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionActive'] },
-	'gradientbasedcorramount' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionAmount'] },
-	'gradientbasedcorrbrightness' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBrightness'] },
-	'gradientbasedcorrclarity' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity'] },
-	'gradientbasedcorrcontrast' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast'] },
-	'gradientbasedcorrections' => { 288 => 'GradientBasedCorrections' },
-	'gradientbasedcorrexposure' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure'] },
-	'gradientbasedcorrhue' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalToningHue'] },
-	'gradientbasedcorrmaskcenterweight' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterWeight'] },
-	'gradientbasedcorrmaskdabs' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksDabs'] },
-	'gradientbasedcorrmaskflow' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlow'] },
-	'gradientbasedcorrmaskfullx' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullX'] },
-	'gradientbasedcorrmaskfully' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullY'] },
-	'gradientbasedcorrmaskradius' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRadius'] },
-	'gradientbasedcorrmasks' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasks'] },
-	'gradientbasedcorrmaskvalue' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMaskValue'] },
-	'gradientbasedcorrmaskwhat' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksWhat'] },
-	'gradientbasedcorrmaskzerox' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroX'] },
-	'gradientbasedcorrmaskzeroy' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroY'] },
-	'gradientbasedcorrsaturation' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSaturation','GradientBasedCorrectionsLocalToningSaturation'] },
-	'gradientbasedcorrsharpness' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSharpness'] },
-	'gradientbasedcorrwhat' => { 288 => [\'GradientBasedCorrections','GradientBasedCorrectionsWhat'] },
-	'grainamount' => { 288 => 'GrainAmount' },
-	'grainfrequency' => { 288 => 'GrainFrequency' },
-	'grainsize' => { 288 => 'GrainSize' },
-	'graymixeraqua' => { 288 => 'GrayMixerAqua' },
-	'graymixerblue' => { 288 => 'GrayMixerBlue' },
-	'graymixergreen' => { 288 => 'GrayMixerGreen' },
-	'graymixermagenta' => { 288 => 'GrayMixerMagenta' },
-	'graymixerorange' => { 288 => 'GrayMixerOrange' },
-	'graymixerpurple' => { 288 => 'GrayMixerPurple' },
-	'graymixerred' => { 288 => 'GrayMixerRed' },
-	'graymixeryellow' => { 288 => 'GrayMixerYellow' },
-	'graypoint' => { 279 => 0x8021 },
-	'grayresponseunit' => { 85 => 0x122 },
-	'greencurvelimits' => { 77 => 0x1c4 },
-	'greencurvepoints' => { 77 => 0x19a },
-	'greenhue' => { 288 => 'GreenHue' },
-	'greensaturation' => { 288 => 'GreenSaturation' },
-	'griddisplay' => { 197 => '13.3', 199 => '2.2', 200 => '10.5', 201 => '3.4', 202 => '6.1', 203 => '4.2' },
-	'gripbatteryadload' => { 230 => 0x5 },
-	'gripbatteryadnoload' => { 230 => 0x4 },
-	'gripbatterystate' => { 230 => '1.2' },
-	'halftonehints' => { 85 => 0x141 },
-	'hasalternative' => { 301 => 'hasAlternative' },
-	'hascorrection' => { 301 => 'hasCorrection' },
-	'hascrop' => { 288 => 'HasCrop' },
-	'hasextendedxmp' => { 312 => 'HasExtendedXMP' },
-	'haspreviousversion' => { 301 => 'hasPreviousVersion' },
-	'hassettings' => { 288 => 'HasSettings' },
-	'hastranslation' => { 301 => 'hasTranslation' },
-	'hdr' => { 276 => 0x200a },
-	'headline' => { 92 => 0x69, 299 => 'Headline' },
-	'hierarchicalkeywords' => { 296 => [\'Keywords','KeywordsHierarchy'] },
-	'hierarchicalkeywords1' => { 296 => [\'Keywords','KeywordsHierarchyKeyword'] },
-	'hierarchicalkeywords1applied' => { 296 => [\'Keywords','KeywordsHierarchyApplied'] },
-	'hierarchicalkeywords1children' => { 296 => [\'Keywords','KeywordsHierarchyChildren'] },
-	'hierarchicalkeywords2' => { 296 => [\'Keywords','KeywordsHierarchyChildrenKeyword'] },
-	'hierarchicalkeywords2applied' => { 296 => [\'Keywords','KeywordsHierarchyChildrenApplied'] },
-	'hierarchicalkeywords2children' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildren'] },
-	'hierarchicalkeywords3' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenKeyword'] },
-	'hierarchicalkeywords3applied' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenApplied'] },
-	'hierarchicalkeywords3children' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildren'] },
-	'hierarchicalkeywords4' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenKeyword'] },
-	'hierarchicalkeywords4applied' => { 296 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenApplied'] },
-	'hierarchicalsubject' => { 282 => 'hierarchicalSubject' },
-	'highisonoisereduction' => { 12 => 0xbc, 13 => 0xbd, 16 => 0xbd, 20 => 0xa5, 59 => 0x202, 89 => 0x100e, 160 => 0xb1, 247 => 0x71, 271 => 0x2c, 276 => 0x2009 },
-	'highlight' => { 270 => 0xf },
-	'highlightcolordistortreduct' => { 279 => 0x8026 },
-	'highlightprotection' => { 189 => 0x6 },
-	'highlightrecovery' => { 288 => 'HighlightRecovery' },
-	'highlighttonepriority' => { 9 => 0x7, 12 => 0x7, 13 => 0x7, 14 => 0x7, 16 => 0x7, 19 => 0x7, 59 => 0x203 },
-	'highlowkeyadj' => { 247 => 0x6c },
-	'highspeedsync' => { 134 => 0x5 },
-	'histogramxml' => { 190 => 0x83a1a25 },
-	'history' => { 299 => 'History', 311 => 'History' },
-	'historyaction' => { 311 => [\'History','HistoryAction'] },
-	'historychanged' => { 311 => [\'History','HistoryChanged'] },
-	'historyinstanceid' => { 311 => [\'History','HistoryInstanceID'] },
-	'historyparameters' => { 311 => [\'History','HistoryParameters'] },
-	'historysoftwareagent' => { 311 => [\'History','HistorySoftwareAgent'] },
-	'historywhen' => { 311 => [\'History','HistoryWhen'] },
-	'hometowncity' => { 82 => 0x3006, 247 => 0x23, 251 => 0x2 },
-	'hometowncitycode' => { 252 => 0x1000 },
-	'hometowndst' => { 247 => 0x25, 251 => '0.2' },
-	'hostcomputer' => { 85 => 0x13c },
-	'hue' => { 138 => 0x3b, 247 => 0x67 },
-	'hueadj' => { 193 => 0x2f, 279 => 0x8019 },
-	'hueadjustment' => { 132 => 0x4a, 133 => 0x40, 160 => 0x92, 162 => 0x36 },
-	'hueadjustmentaqua' => { 288 => 'HueAdjustmentAqua' },
-	'hueadjustmentblue' => { 288 => 'HueAdjustmentBlue' },
-	'hueadjustmentgreen' => { 288 => 'HueAdjustmentGreen' },
-	'hueadjustmentmagenta' => { 288 => 'HueAdjustmentMagenta' },
-	'hueadjustmentorange' => { 288 => 'HueAdjustmentOrange' },
-	'hueadjustmentpurple' => { 288 => 'HueAdjustmentPurple' },
-	'hueadjustmentred' => { 288 => 'HueAdjustmentRed' },
-	'hueadjustmentyellow' => { 288 => 'HueAdjustmentYellow' },
-	'huesetting' => { 212 => 0x1011 },
-	'icc_profile' => { 86 => 'ICC_Profile' },
-	'iccprofilename' => { 299 => 'ICCProfile' },
-	'idccreativestyle' => { 279 => 0x8000 },
-	'idcpreviewlength' => { 279 => 0x202 },
-	'idcpreviewstart' => { 279 => 0x201 },
-	'identifier' => { 289 => 'identifier', 308 => 'Identifier' },
-	'illumination' => { 202 => '0.5' },
-	'imageadjustment' => { 160 => 0x80, 180 => 0x5 },
-	'imagealterationconstraints' => { 300 => 'ImageAlterationConstraints' },
-	'imagearea' => { 170 => 0x10, 173 => 0x10 },
-	'imageareaoffset' => { 247 => 0x38 },
-	'imageauthentication' => { 160 => 0x20 },
-	'imageboundary' => { 160 => 0x16 },
-	'imagecount' => { 160 => 0xa5 },
-	'imagecreator' => { 300 => 'ImageCreator' },
-	'imagecreatorid' => { 300 => [\'ImageCreator','ImageCreatorImageCreatorID'] },
-	'imagecreatorimageid' => { 300 => 'ImageCreatorImageID' },
-	'imagecreatorname' => { 300 => [\'ImageCreator','ImageCreatorImageCreatorName'] },
-	'imagedatasize' => { 160 => 0xa2 },
-	'imagedescription' => { 85 => 0x10e, 306 => 'ImageDescription' },
-	'imageduplicationconstraints' => { 300 => 'ImageDuplicationConstraints' },
-	'imagedustoff' => { 190 => 0xfe443a45 },
-	'imageeditcount' => { 247 => 0x41 },
-	'imageediting' => { 247 => 0x32 },
-	'imagefileconstraints' => { 300 => 'ImageFileConstraints' },
-	'imagefileformatasdelivered' => { 300 => 'ImageFileFormatAsDelivered' },
-	'imagefilesizeasdelivered' => { 300 => 'ImageFileSizeAsDelivered' },
-	'imageheight' => { 85 => 0x101, 137 => 0xc, 306 => 'ImageLength' },
-	'imagehistory' => { 85 => 0x9213 },
-	'imageidnumber' => { 219 => 0x340 },
-	'imagenumber' => { 15 => 0xd0, 85 => 0x9211, 113 => 'ImageNumber', 132 => 0xae, 133 => 0x5e, 285 => 'ImageNumber' },
-	'imagenumber2' => { 133 => 0x62 },
-	'imageoptimization' => { 160 => 0xa9 },
-	'imageorientation' => { 92 => 0x83 },
-	'imageprocessing' => { 160 => 0x1a },
-	'imageprocessingversion' => { 208 => 0x0 },
-	'imagequality' => { 113 => 'ImageQuality', 172 => '723.2', 173 => '732.2', 178 => '708.1', 224 => 0x1 },
-	'imagequality2' => { 204 => 0x603 },
-	'imagereview' => { 198 => '0.4', 202 => '0.4' },
-	'imagereviewtime' => { 198 => '2.1', 199 => '19.1', 200 => '9.2', 201 => '20.1', 203 => '21.2' },
-	'imagesize' => { 119 => 'ImageSize' },
-	'imagesizerestriction' => { 303 => 'imageSizeRestriction' },
-	'imagesourcedata' => { 85 => 0x935c },
-	'imagestabilization' => { 24 => 0x22, 82 => 0x3020, 113 => 'ImageStabilization', 132 => 0xbd, 133 => 0x71, 134 => 0x57, 135 => [0x18,0x107,0x113], 160 => 0xac, 204 => 0x604, 207 => 0x1600, 224 => 0x1a, 271 => 0x3d, 276 => 0xb026 },
-	'imagestyle' => { 271 => 0x2d },
-	'imagesupplier' => { 300 => 'ImageSupplier' },
-	'imagesupplierid' => { 300 => [\'ImageSupplier','ImageSupplierImageSupplierID'] },
-	'imagesupplierimageid' => { 300 => 'ImageSupplierImageID' },
-	'imagesuppliername' => { 300 => [\'ImageSupplier','ImageSupplierImageSupplierName'] },
-	'imagetone' => { 247 => 0x4f },
-	'imagetype' => { 92 => 0x82, 300 => 'ImageType' },
-	'imageuniqueid' => { 43 => 0x28, 85 => 0xa420, 292 => 'ImageUniqueID' },
-	'imagewidth' => { 85 => 0x100, 137 => 0xe, 306 => 'ImageWidth' },
-	'incrementaltemperature' => { 288 => 'IncrementalTemperature' },
-	'incrementaltint' => { 288 => 'IncrementalTint' },
-	'industry' => { 301 => 'industry', 302 => 'industry' },
-	'infobuttonwhenshooting' => { 59 => 0x409 },
-	'infraredilluminator' => { 259 => 0x28 },
-	'ingredients' => { 311 => 'Ingredients' },
-	'ingredientsalternatepaths' => { 311 => [\'Ingredients','IngredientsAlternatePaths'] },
-	'ingredientsdocumentid' => { 311 => [\'Ingredients','IngredientsDocumentID'] },
-	'ingredientsfilepath' => { 311 => [\'Ingredients','IngredientsFilePath'] },
-	'ingredientsfrompart' => { 311 => [\'Ingredients','IngredientsFromPart'] },
-	'ingredientsinstanceid' => { 311 => [\'Ingredients','IngredientsInstanceID'] },
-	'ingredientslastmodifydate' => { 311 => [\'Ingredients','IngredientsLastModifyDate'] },
-	'ingredientsmanager' => { 311 => [\'Ingredients','IngredientsManager'] },
-	'ingredientsmanagervariant' => { 311 => [\'Ingredients','IngredientsManagerVariant'] },
-	'ingredientsmanageto' => { 311 => [\'Ingredients','IngredientsManageTo'] },
-	'ingredientsmanageui' => { 311 => [\'Ingredients','IngredientsManageUI'] },
-	'ingredientsmaskmarkers' => { 311 => [\'Ingredients','IngredientsMaskMarkers'] },
-	'ingredientsoriginaldocumentid' => { 311 => [\'Ingredients','IngredientsOriginalDocumentID'] },
-	'ingredientspartmapping' => { 311 => [\'Ingredients','IngredientsPartMapping'] },
-	'ingredientsrenditionclass' => { 311 => [\'Ingredients','IngredientsRenditionClass'] },
-	'ingredientsrenditionparams' => { 311 => [\'Ingredients','IngredientsRenditionParams'] },
-	'ingredientstopart' => { 311 => [\'Ingredients','IngredientsToPart'] },
-	'ingredientsversionid' => { 311 => [\'Ingredients','IngredientsVersionID'] },
-	'initialzoomliveview' => { 197 => '4.4' },
-	'initialzoomsetting' => { 197 => '9.3', 200 => '27.3' },
-	'inkset' => { 85 => 0x14c },
-	'instanceid' => { 311 => 'InstanceID' },
-	'instantplaybacksetup' => { 134 => 0x3e },
-	'instantplaybacktime' => { 134 => 0x3d },
-	'instructions' => { 299 => 'Instructions' },
-	'instrument' => { 310 => 'instrument' },
-	'intellectualgenre' => { 293 => 'IntellectualGenre' },
-	'intelligentauto' => { 276 => 0xb052 },
-	'intelligentd-range' => { 224 => 0x79 },
-	'intelligentexposure' => { 224 => 0x5d },
-	'intelligentresolution' => { 224 => 0x70 },
-	'interchangecolorspace' => { 94 => 0x40 },
-	'internalflash' => { 131 => 0x2b, 197 => '23.1', 198 => '8.1', 199 => '22.1', 202 => '8.1', 203 => '24.1', 207 => 0x1208 },
-	'internalflashae1' => { 209 => 0x1021 },
-	'internalflashae1_0' => { 209 => 0x101d },
-	'internalflashae2' => { 209 => 0x1022 },
-	'internalflashae2_0' => { 209 => 0x101e },
-	'internalflashmode' => { 239 => 0x1 },
-	'internalflashstrength' => { 239 => 0x3 },
-	'internalflashtable' => { 209 => 0x1024 },
-	'internalserialnumber' => { 43 => 0x96, 53 => 0x9, 89 => 0x10, 136 => 0x49dc, 205 => 0x102, 224 => 0x25, 231 => 0x4, 263 => 0x5 },
-	'interopindex' => { 85 => 0x1 },
-	'interopversion' => { 85 => 0x2 },
-	'intervallength' => { 131 => 0x10 },
-	'intervalmode' => { 131 => 0x26 },
-	'intervalnumber' => { 131 => 0x11 },
-	'introtime' => { 310 => 'introTime' },
-	'introtimescale' => { 310 => [\'introTime','introTimeScale'] },
-	'introtimevalue' => { 310 => [\'introTime','introTimeValue'] },
-	'iptc-naa' => { 85 => 0x83bb, 226 => 0x83bb },
-	'iptcbitspersample' => { 94 => 0x56 },
-	'iptcdigest' => { 256 => 0x425 },
-	'iptcimageheight' => { 94 => 0x1e },
-	'iptcimagerotation' => { 94 => 0x66 },
-	'iptcimagewidth' => { 94 => 0x14 },
-	'iptclastedited' => { 294 => 'IptcLastEdited' },
-	'iptcpicturenumber' => { 94 => 0xa },
-	'iptcpixelheight' => { 94 => 0x32 },
-	'iptcpixelwidth' => { 94 => 0x28 },
-	'isbn' => { 301 => 'isbn' },
-	'iscorrectionof' => { 301 => 'isCorrectionOf' },
-	'iscustompicturestyle' => { 78 => 0x3 },
-	'iso' => { 4 => 0x6, 6 => 0x75, 7 => 0x6, 8 => 0x79, 9 => 0x6, 10 => 0x6, 11 => 0x6, 12 => 0x6, 13 => 0x6, 14 => 0x6, 15 => 0x6, 16 => 0x6, 18 => 0x6, 19 => 0x6, 21 => 0x0, 22 => 0x1, 81 => 0x14, 82 => [0x3014,0x14], 85 => 0x8827, 96 => 0xfd06, 97 => 0x1784, 99 => 0x60, 101 => [0xfa2e,0xfa46], 102 => [0x27,0x28], 103 => 0xf105, 106 => 0x14, 108 => 0x4e, 111 => 0x34, 113 => 'ISO', 131 => 0x8, 156 => 0x0, 160 => 0x2, 226 => 0x17, 247 => 0x14, 252 => 0x14, 267 => 0xa014, 292 => 'ISOSpeedRatings' },
-	'iso2' => { 156 => 0x6, 167 => 0x265, 168 => 0x25c, 169 => 0x265, 170 => 0x221, 171 => 0x25d, 172 => 0x256, 173 => 0x25d, 175 => 0x2b5, 176 => 0x265, 179 => 0x2b5 },
-	'isoauto' => { 232 => '14.4' },
-	'isoautoparameters' => { 247 => 0x7a },
-	'isodisplay' => { 199 => '2.3', 201 => '3.3', 203 => '4.3' },
-	'isoexpansion' => { 59 => 0x103, 60 => 0x7, 61 => 0x8, 64 => 0x8, 156 => 0x4 },
-	'isoexpansion2' => { 156 => 0xa },
-	'isofloor' => { 232 => 0x6 },
-	'isoselection' => { 160 => 0xf },
-	'isosensitivitystep' => { 201 => '6.2' },
-	'isosetting' => { 99 => 0x5e, 113 => 'ISOSetting', 131 => 0x24, 132 => 0x26, 133 => 0x1c, 134 => 0x13, 138 => 0x6, 160 => 0x13, 232 => '17.3', 262 => 0x27, 271 => 0x16, 272 => 0x14 },
-	'isospeed' => { 85 => 0x8833 },
-	'isospeedexpansion' => { 58 => 0x3 },
-	'isospeedincrements' => { 59 => 0x102 },
-	'isospeedlatitudeyyy' => { 85 => 0x8834 },
-	'isospeedlatitudezzz' => { 85 => 0x8835 },
-	'isospeedrange' => { 59 => 0x103 },
-	'isostepsize' => { 197 => '6.1', 200 => '4.1' },
-	'isovalue' => { 209 => 0x1001 },
-	'issn' => { 301 => 'issn' },
-	'issueidentifier' => { 301 => 'issueIdentifier' },
-	'issuename' => { 301 => 'issueName' },
-	'istranslationof' => { 301 => 'isTranslationOf' },
-	'jobid' => { 92 => 0xb8 },
-	'jobref' => { 309 => 'JobRef' },
-	'jobrefid' => { 309 => [\'JobRef','JobRefId'] },
-	'jobrefname' => { 309 => [\'JobRef','JobRefName'] },
-	'jobrefurl' => { 309 => [\'JobRef','JobRefUrl'] },
-	'jpegquality' => { 6 => 0x66, 225 => 0x3034 },
-	'jpegsize' => { 225 => 0x303a },
-	'jpgfromraw' => { 72 => 0x2007, 83 => 'JpgFromRaw', 226 => 0x2e },
-	'jpgfromrawlength' => { 85 => [0x117,0x202] },
-	'jpgfromrawstart' => { 85 => [0x111,0x201] },
-	'jpgrecordedpixels' => { 232 => '14.1' },
-	'key' => { 310 => 'key' },
-	'keyword' => { 301 => 'keyword' },
-	'keywordinfo' => { 296 => 'Keywords' },
-	'keywords' => { 92 => 0x19, 114 => 'Keywords', 213 => 'Keywords', 258 => 'Keywords', 284 => 'keywords', 298 => 'Keywords' },
-	'killdate' => { 301 => 'killDate' },
-	'kodakimageheight' => { 96 => 0xf908, 99 => 0xe, 101 => [0xfa1e,0xfa52], 107 => 0x70 },
-	'kodakimagewidth' => { 96 => 0xf907, 99 => 0xc, 101 => [0xfa1d,0xfa51], 107 => 0x6c },
-	'kodakinfotype' => { 96 => 0xfa00 },
-	'kodakmaker' => { 107 => 0x8 },
-	'kodakmodel' => { 99 => 0x0, 107 => 0x28 },
-	'label' => { 215 => 'Label', 308 => 'Label' },
-	'landmark' => { 224 => 0x6f },
-	'landscapeoutputhighlightpoint' => { 78 => 0x26 },
-	'landscapeoutputshadowpoint' => { 78 => 0x27 },
-	'landscaperawcolortone' => { 78 => 0x1f },
-	'landscaperawcontrast' => { 78 => 0x21 },
-	'landscaperawhighlight' => { 78 => 0x77 },
-	'landscaperawhighlightpoint' => { 78 => 0x24 },
-	'landscaperawlinear' => { 78 => 0x22 },
-	'landscaperawsaturation' => { 78 => 0x20 },
-	'landscaperawshadow' => { 78 => 0x80 },
-	'landscaperawshadowpoint' => { 78 => 0x25 },
-	'landscaperawsharpness' => { 78 => 0x23 },
-	'language' => { 289 => 'language' },
-	'languageidentifier' => { 92 => 0x87 },
-	'lastfilenumber' => { 131 => 0x1b },
-	'lastkeywordiptc' => { 130 => 'LastKeywordIPTC' },
-	'lastkeywordxmp' => { 130 => 'LastKeywordXMP' },
-	'lasturl' => { 311 => 'LastURL' },
-	'lc1' => { 241 => 0x2 },
-	'lc10' => { 241 => 0xb },
-	'lc11' => { 241 => 0xc },
-	'lc12' => { 241 => 0xd },
-	'lc14' => { 241 => 0xf },
-	'lc15' => { 241 => 0x10 },
-	'lc2' => { 241 => 0x3 },
-	'lc3' => { 241 => 0x4 },
-	'lc4' => { 241 => 0x5 },
-	'lc5' => { 241 => 0x6 },
-	'lc6' => { 241 => 0x7 },
-	'lc7' => { 241 => 0x8 },
-	'lcddisplayatpoweron' => { 59 => 0x811, 63 => 0xa },
-	'lcddisplayreturntoshoot' => { 64 => 0x12 },
-	'lcdillumination' => { 197 => '17.5', 200 => '10.3', 201 => '4.2', 203 => '5.4' },
-	'lcdilluminationduringbulb' => { 59 => 0x408 },
-	'lcdpanels' => { 58 => 0x8 },
-	'lcheditor' => { 190 => 0x8ae85e },
-	'legacyiptcdigest' => { 299 => 'LegacyIPTCDigest' },
-	'lens' => { 85 => 0xfdea, 160 => 0x84, 285 => 'Lens' },
-	'lensafstopbutton' => { 57 => 0x11, 58 => 0x13, 59 => 0x506, 60 => 0x10, 61 => 0x12, 64 => 0x13, 65 => 0x9 },
-	'lensaperturerange' => { 270 => 0x30 },
-	'lensdistortionparams' => { 209 => 0x206 },
-	'lensdrivenoaf' => { 59 => 0x505 },
-	'lensfirmware' => { 264 => 0x20, 267 => 0xa004 },
-	'lensfirmwareversion' => { 205 => 0x204 },
-	'lensfocalrange' => { 270 => 0xa },
-	'lensfstops' => { 157 => 0x7, 158 => 0xc, 159 => 0xd, 160 => 0x8b, 241 => '0.3' },
-	'lensid' => { 285 => 'LensID' },
-	'lensidnumber' => { 157 => 0x6, 158 => 0xb, 159 => 0xc },
-	'lensinfo' => { 85 => 0xa432, 285 => 'LensInfo' },
-	'lenskind' => { 241 => 0x1 },
-	'lensmake' => { 85 => 0xa433, 120 => 'Make' },
-	'lensmanualdistortionamount' => { 288 => 'LensManualDistortionAmount' },
-	'lensmanufacturer' => { 130 => 'LensManufacturer' },
-	'lensmodel' => { 4 => 0x937, 10 => 0x92b, 11 => 0x933, 43 => 0x95, 85 => 0xa434, 120 => 'Model', 130 => 'LensModel', 205 => 0x203 },
-	'lensprofilechromaticaberrationscale' => { 288 => 'LensProfileChromaticAberrationScale' },
-	'lensprofiledigest' => { 288 => 'LensProfileDigest' },
-	'lensprofiledistortionscale' => { 288 => 'LensProfileDistortionScale' },
-	'lensprofileenable' => { 288 => 'LensProfileEnable' },
-	'lensprofilefilename' => { 288 => 'LensProfileFilename' },
-	'lensprofilename' => { 288 => 'LensProfileName' },
-	'lensprofilesetup' => { 288 => 'LensProfileSetup' },
-	'lensprofilevignettingscale' => { 288 => 'LensProfileVignettingScale' },
-	'lensproperties' => { 205 => 0x20b },
-	'lensserialnumber' => { 41 => 0x0, 85 => 0xa435, 120 => 'SerialNumber', 205 => 0x202, 224 => 0x52, 264 => 0x30 },
-	'lensshutterlock' => { 134 => 0x4a },
-	'lenstemperature' => { 209 => 0x1008 },
-	'lenstype' => { 4 => 0xe2, 5 => 0xd, 6 => 0xc, 7 => 0x111, 8 => 0xc, 9 => [0x14e,0x14f], 10 => 0xd6, 11 => 0xde, 12 => 0xf6, 13 => 0xea, 14 => 0xff, 15 => [0xc,0x97], 16 => 0xe6, 18 => 0xe8, 20 => 0xee, 24 => 0x16, 135 => 0x10c, 160 => 0x83, 205 => 0x201, 216 => 0x16, 222 => 0x303, 223 => 0x0, 224 => 0x51, 225 => 0x3405, 242 => 0x0, 243 => 0x0, 244 => 0x1, 245 => 0x1, 247 => 0x3f, 267 => 0xa003, 276 => 0xb027 },
-	'levelgaugepitch' => { 204 => 0x904 },
-	'levelgaugeroll' => { 204 => 0x903 },
-	'levelorientation' => { 246 => 0x0 },
-	'license' => { 286 => 'license' },
-	'licensee' => { 300 => 'Licensee' },
-	'licenseeid' => { 300 => [\'Licensee','LicenseeLicenseeID'] },
-	'licenseeimageid' => { 300 => 'LicenseeImageID' },
-	'licenseeimagenotes' => { 300 => 'LicenseeImageNotes' },
-	'licenseename' => { 300 => [\'Licensee','LicenseeLicenseeName'] },
-	'licenseenddate' => { 300 => 'LicenseEndDate' },
-	'licenseeprojectreference' => { 300 => 'LicenseeProjectReference' },
-	'licenseetransactionid' => { 300 => 'LicenseeTransactionID' },
-	'licenseid' => { 300 => 'LicenseID' },
-	'licensestartdate' => { 300 => 'LicenseStartDate' },
-	'licensetransactiondate' => { 300 => 'LicenseTransactionDate' },
-	'licensetype' => { 290 => 'licensetype' },
-	'licensor' => { 300 => 'Licensor' },
-	'licensorcity' => { 300 => [\'Licensor','LicensorLicensorCity'] },
-	'licensorcountry' => { 300 => [\'Licensor','LicensorLicensorCountry'] },
-	'licensoremail' => { 300 => [\'Licensor','LicensorLicensorEmail'] },
-	'licensorextendedaddress' => { 300 => [\'Licensor','LicensorLicensorExtendedAddress'] },
-	'licensorid' => { 300 => [\'Licensor','LicensorLicensorID'] },
-	'licensorimageid' => { 300 => 'LicensorImageID' },
-	'licensorname' => { 300 => [\'Licensor','LicensorLicensorName'] },
-	'licensornotes' => { 300 => 'LicensorNotes' },
-	'licensorpostalcode' => { 300 => [\'Licensor','LicensorLicensorPostalCode'] },
-	'licensorregion' => { 300 => [\'Licensor','LicensorLicensorRegion'] },
-	'licensorstreetaddress' => { 300 => [\'Licensor','LicensorLicensorStreetAddress'] },
-	'licensortelephone1' => { 300 => [\'Licensor','LicensorLicensorTelephone1'] },
-	'licensortelephone2' => { 300 => [\'Licensor','LicensorLicensorTelephone2'] },
-	'licensortelephonetype1' => { 300 => [\'Licensor','LicensorLicensorTelephoneType1'] },
-	'licensortelephonetype2' => { 300 => [\'Licensor','LicensorLicensorTelephoneType2'] },
-	'licensortransactionid' => { 300 => 'LicensorTransactionID' },
-	'licensorurl' => { 300 => [\'Licensor','LicensorLicensorURL'] },
-	'lightcondition' => { 209 => 0x1009 },
-	'lightingmode' => { 82 => 0x302a },
-	'lightreading' => { 247 => 0x15 },
-	'lightsource' => { 85 => 0x9208, 160 => 0x90, 212 => 0x1000, 292 => 'LightSource' },
-	'lightsourcespecial' => { 269 => 0x21d },
-	'lightswitch' => { 203 => '0.1' },
-	'lightvaluecenter' => { 209 => 0x103d },
-	'lightvalueperiphery' => { 209 => 0x103e },
-	'linearresponselimit' => { 85 => 0xc62e },
-	'linkaetoafpoint' => { 232 => '14.2' },
-	'liveviewaf' => { 199 => '32.1', 203 => '34.1' },
-	'liveviewafareamode' => { 201 => '34.1' },
-	'liveviewafmode' => { 201 => '34.2' },
-	'liveviewexposuresimulation' => { 59 => 0x810 },
-	'liveviewmonitorofftime' => { 201 => '20.2' },
-	'liveviewshooting' => { 38 => 0x13 },
-	'localafareapoint' => { 134 => 0xd, 271 => 0x12, 272 => 0x12 },
-	'localcaption' => { 92 => 0x79 },
-	'localizedcameramodel' => { 85 => 0xc615 },
-	'locallocationname' => { 267 => 0x30 },
-	'location' => { 224 => 0x67, 283 => 'Location', 293 => 'Location', 301 => 'location' },
-	'locationareacode' => { 287 => 'lac' },
-	'locationcreated' => { 294 => 'LocationCreated' },
-	'locationcreatedcity' => { 294 => [\'LocationCreated','LocationCreatedCity'] },
-	'locationcreatedcountrycode' => { 294 => [\'LocationCreated','LocationCreatedCountryCode'] },
-	'locationcreatedcountryname' => { 294 => [\'LocationCreated','LocationCreatedCountryName'] },
-	'locationcreatedprovincestate' => { 294 => [\'LocationCreated','LocationCreatedProvinceState'] },
-	'locationcreatedsublocation' => { 294 => [\'LocationCreated','LocationCreatedSublocation'] },
-	'locationcreatedworldregion' => { 294 => [\'LocationCreated','LocationCreatedWorldRegion'] },
-	'locationname' => { 267 => 0x31 },
-	'locationshown' => { 294 => 'LocationShown' },
-	'locationshowncity' => { 294 => [\'LocationShown','LocationShownCity'] },
-	'locationshowncountrycode' => { 294 => [\'LocationShown','LocationShownCountryCode'] },
-	'locationshowncountryname' => { 294 => [\'LocationShown','LocationShownCountryName'] },
-	'locationshownprovincestate' => { 294 => [\'LocationShown','LocationShownProvinceState'] },
-	'locationshownsublocation' => { 294 => [\'LocationShown','LocationShownSublocation'] },
-	'locationshownworldregion' => { 294 => [\'LocationShown','LocationShownWorldRegion'] },
-	'lockmicrophonebutton' => { 59 => 0x709 },
-	'logcomment' => { 310 => 'logComment' },
-	'longexposurenoisereduction' => { 59 => 0x201, 60 => 0x1, 61 => 0x2, 62 => 0x1, 63 => 0x1, 64 => 0x2, 65 => 0x1, 271 => 0x2b, 276 => [0xb04e,0x2008] },
-	'longexposurenoisereduction2' => { 38 => 0x8 },
-	'longfocal' => { 5 => 0x10, 6 => 0x13, 7 => 0x115, 8 => 0x13, 9 => [0x152,0x153], 10 => 0xda, 12 => 0xfa, 13 => 0xee, 14 => 0x103, 15 => 0x95, 16 => 0xea, 18 => 0xec, 20 => 0xf2, 24 => 0x17 },
-	'loop' => { 310 => 'loop' },
-	'luminanceadjustmentaqua' => { 288 => 'LuminanceAdjustmentAqua' },
-	'luminanceadjustmentblue' => { 288 => 'LuminanceAdjustmentBlue' },
-	'luminanceadjustmentgreen' => { 288 => 'LuminanceAdjustmentGreen' },
-	'luminanceadjustmentmagenta' => { 288 => 'LuminanceAdjustmentMagenta' },
-	'luminanceadjustmentorange' => { 288 => 'LuminanceAdjustmentOrange' },
-	'luminanceadjustmentpurple' => { 288 => 'LuminanceAdjustmentPurple' },
-	'luminanceadjustmentred' => { 288 => 'LuminanceAdjustmentRed' },
-	'luminanceadjustmentyellow' => { 288 => 'LuminanceAdjustmentYellow' },
-	'luminancecurvelimits' => { 77 => 0x150 },
-	'luminancecurvepoints' => { 77 => 0x126 },
-	'luminancenoisereduction' => { 78 => 0x5f, 270 => 0x1b },
-	'luminancenoisereductioncontrast' => { 288 => 'LuminanceNoiseReductionContrast' },
-	'luminancenoisereductiondetail' => { 288 => 'LuminanceNoiseReductionDetail' },
-	'luminancenr_tiff_jpeg' => { 78 => 0x6d },
-	'luminancesmoothing' => { 288 => 'LuminanceSmoothing' },
-	'm16cversion' => { 219 => 0x333 },
-	'macro' => { 89 => 0x1020, 90 => 0x202, 209 => 0x202, 262 => 0x21, 269 => 0x202, 276 => 0xb040 },
-	'macromagnification' => { 4 => 0x1b, 7 => 0x1b, 10 => 0x1b, 11 => 0x1b, 15 => 0x1b, 16 => 0x1b, 38 => 0x10 },
-	'macromode' => { 24 => 0x1, 131 => 0xb, 204 => 0x300, 224 => 0x1c },
-	'magicfilter' => { 204 => 0x52c },
-	'magnifiedview' => { 61 => 0x11, 63 => 0x9 },
-	'maindialexposurecomp' => { 202 => '0.6' },
-	'make' => { 73 => 0x0, 85 => 0x10f, 113 => 'Make', 215 => 'Make', 226 => 0x10f, 306 => 'Make' },
-	'makernote' => { 292 => 'MakerNote' },
-	'makernotecanon' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotecasio' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotecasio2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotefujifilm' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotege' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotege2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotehp' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotehp2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotehp4' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotehp6' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteisl' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotejvc' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotejvctext' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak10' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak1a' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak1b' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak3' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak4' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak5' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak6a' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak6b' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak7' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak8a' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak8b' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodak9' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekodakunknown' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotekyocera' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteleica' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteleica2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteleica3' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteleica4' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteleica5' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteleica6' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteminolta' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteminolta2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteminolta3' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotenikon' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotenikon2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotenikon3' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteoffset' => { 269 => 0xff },
-	'makernoteolympus' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteolympus2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotepanasonic' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotepanasonic2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotepentax' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotepentax2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotepentax3' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotepentax4' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotepentax5' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotephaseone' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotereconyx' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotericoh' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotericohtext' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesafety' => { 85 => 0xc635 },
-	'makernotesamsung1a' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesamsung1b' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesamsung2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesanyo' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesanyoc4' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesanyopatch' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesigma' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesony' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesony2' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesony3' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesony4' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesonyericsson' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotesonysrf' => { 84 => 'MakN', 85 => 0x927c },
-	'makernotetype' => { 263 => 0x1 },
-	'makernoteunknown' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteunknowntext' => { 84 => 'MakN', 85 => 0x927c },
-	'makernoteversion' => { 135 => 0x0, 160 => 0x1, 209 => 0x0, 224 => 0x8000, 266 => 0x0, 267 => 0x1, 270 => 0x1d, 273 => 0x2000 },
-	'managedfrom' => { 311 => 'ManagedFrom' },
-	'managedfromalternatepaths' => { 311 => [\'ManagedFrom','ManagedFromAlternatePaths'] },
-	'managedfromdocumentid' => { 311 => [\'ManagedFrom','ManagedFromDocumentID'] },
-	'managedfromfilepath' => { 311 => [\'ManagedFrom','ManagedFromFilePath'] },
-	'managedfromfrompart' => { 311 => [\'ManagedFrom','ManagedFromFromPart'] },
-	'managedfrominstanceid' => { 311 => [\'ManagedFrom','ManagedFromInstanceID'] },
-	'managedfromlastmodifydate' => { 311 => [\'ManagedFrom','ManagedFromLastModifyDate'] },
-	'managedfrommanager' => { 311 => [\'ManagedFrom','ManagedFromManager'] },
-	'managedfrommanagervariant' => { 311 => [\'ManagedFrom','ManagedFromManagerVariant'] },
-	'managedfrommanageto' => { 311 => [\'ManagedFrom','ManagedFromManageTo'] },
-	'managedfrommanageui' => { 311 => [\'ManagedFrom','ManagedFromManageUI'] },
-	'managedfrommaskmarkers' => { 311 => [\'ManagedFrom','ManagedFromMaskMarkers'] },
-	'managedfromoriginaldocumentid' => { 311 => [\'ManagedFrom','ManagedFromOriginalDocumentID'] },
-	'managedfrompartmapping' => { 311 => [\'ManagedFrom','ManagedFromPartMapping'] },
-	'managedfromrenditionclass' => { 311 => [\'ManagedFrom','ManagedFromRenditionClass'] },
-	'managedfromrenditionparams' => { 311 => [\'ManagedFrom','ManagedFromRenditionParams'] },
-	'managedfromtopart' => { 311 => [\'ManagedFrom','ManagedFromToPart'] },
-	'managedfromversionid' => { 311 => [\'ManagedFrom','ManagedFromVersionID'] },
-	'manager' => { 311 => 'Manager' },
-	'managervariant' => { 311 => 'ManagerVariant' },
-	'manageto' => { 311 => 'ManageTo' },
-	'manageui' => { 311 => 'ManageUI' },
-	'manifest' => { 311 => 'Manifest' },
-	'manifestlinkform' => { 311 => [\'Manifest','ManifestLinkForm'] },
-	'manifestplacedresolutionunit' => { 311 => [\'Manifest','ManifestPlacedResolutionUnit'] },
-	'manifestplacedxresolution' => { 311 => [\'Manifest','ManifestPlacedXResolution'] },
-	'manifestplacedyresolution' => { 311 => [\'Manifest','ManifestPlacedYResolution'] },
-	'manifestreference' => { 311 => [\'Manifest','ManifestReference'] },
-	'manifestreferencealternatepaths' => { 311 => [\'Manifest','ManifestReferenceAlternatePaths'] },
-	'manifestreferencedocumentid' => { 311 => [\'Manifest','ManifestReferenceDocumentID'] },
-	'manifestreferencefilepath' => { 311 => [\'Manifest','ManifestReferenceFilePath'] },
-	'manifestreferencefrompart' => { 311 => [\'Manifest','ManifestReferenceFromPart'] },
-	'manifestreferenceinstanceid' => { 311 => [\'Manifest','ManifestReferenceInstanceID'] },
-	'manifestreferencelastmodifydate' => { 311 => [\'Manifest','ManifestReferenceLastModifyDate'] },
-	'manifestreferencemanager' => { 311 => [\'Manifest','ManifestReferenceManager'] },
-	'manifestreferencemanagervariant' => { 311 => [\'Manifest','ManifestReferenceManagerVariant'] },
-	'manifestreferencemanageto' => { 311 => [\'Manifest','ManifestReferenceManageTo'] },
-	'manifestreferencemanageui' => { 311 => [\'Manifest','ManifestReferenceManageUI'] },
-	'manifestreferencemaskmarkers' => { 311 => [\'Manifest','ManifestReferenceMaskMarkers'] },
-	'manifestreferenceoriginaldocumentid' => { 311 => [\'Manifest','ManifestReferenceOriginalDocumentID'] },
-	'manifestreferencepartmapping' => { 311 => [\'Manifest','ManifestReferencePartMapping'] },
-	'manifestreferencerenditionclass' => { 311 => [\'Manifest','ManifestReferenceRenditionClass'] },
-	'manifestreferencerenditionparams' => { 311 => [\'Manifest','ManifestReferenceRenditionParams'] },
-	'manifestreferencetopart' => { 311 => [\'Manifest','ManifestReferenceToPart'] },
-	'manifestreferenceversionid' => { 311 => [\'Manifest','ManifestReferenceVersionID'] },
-	'manometerpressure' => { 204 => 0x900 },
-	'manometerreading' => { 204 => 0x901 },
-	'manualafpointselectpattern' => { 59 => 0x513 },
-	'manualexposuretime' => { 134 => 0x6 },
-	'manualflash' => { 207 => 0x1209 },
-	'manualflashoutput' => { 24 => 0x29, 198 => '8.2', 199 => '22.2', 200 => '16.2', 201 => '23.2', 202 => '8.2', 203 => '24.2' },
-	'manualflashstrength' => { 204 => 0x406 },
-	'manualfnumber' => { 134 => 0x7 },
-	'manualfocusdistance' => { 160 => 0x85, 209 => 0x100c, 269 => 0x223 },
-	'manualtv' => { 58 => 0x5, 59 => 0x705 },
-	'manufacturedate' => { 231 => 0x1 },
-	'manufacturedate1' => { 265 => 0x4 },
-	'manufacturedate2' => { 265 => 0x5 },
-	'marked' => { 298 => 'Marked', 314 => 'Marked' },
-	'markers' => { 310 => 'markers' },
-	'markerscomment' => { 310 => [\'markers','markersComment'] },
-	'markerscuepointparams' => { 310 => [\'markers','markersCuePointParams'] },
-	'markerscuepointparamskey' => { 310 => [\'markers','markersCuePointParamsKey'] },
-	'markerscuepointparamsvalue' => { 310 => [\'markers','markersCuePointParamsValue'] },
-	'markerscuepointtype' => { 310 => [\'markers','markersCuePointType'] },
-	'markersduration' => { 310 => [\'markers','markersDuration'] },
-	'markerslocation' => { 310 => [\'markers','markersLocation'] },
-	'markersname' => { 310 => [\'markers','markersName'] },
-	'markersprobability' => { 310 => [\'markers','markersProbability'] },
-	'markersspeaker' => { 310 => [\'markers','markersSpeaker'] },
-	'markersstarttime' => { 310 => [\'markers','markersStartTime'] },
-	'markerstarget' => { 310 => [\'markers','markersTarget'] },
-	'markerstype' => { 310 => [\'markers','markersType'] },
-	'maskedareas' => { 85 => 0xc68e },
-	'masterdocumentid' => { 92 => 0xb9 },
-	'mastergain' => { 165 => 0x50 },
-	'maxaperture' => { 24 => 0x1a, 103 => 0x6103, 120 => 'MaxAperture', 131 => 0x17, 241 => '14.1' },
-	'maxapertureatcurrentfocal' => { 205 => 0x20a },
-	'maxapertureatmaxfocal' => { 89 => 0x1407, 120 => 'MaxApertureAtMaxFocal', 157 => 0xb, 158 => 0x10, 159 => 0x11, 205 => 0x206 },
-	'maxapertureatminfocal' => { 89 => 0x1406, 157 => 0xa, 158 => 0xf, 159 => 0x10, 205 => 0x205 },
-	'maxaperturevalue' => { 85 => 0x9205, 292 => 'MaxApertureValue' },
-	'maxavailheight' => { 294 => 'MaxAvailHeight' },
-	'maxavailwidth' => { 294 => 'MaxAvailWidth' },
-	'maxcontinuousrelease' => { 197 => 0xb, 200 => 0xc, 201 => 0xb },
-	'maxfaces' => { 208 => 0x1202 },
-	'maxfocallength' => { 89 => 0x1405, 120 => 'MaxFocalLength', 157 => 0x9, 158 => 0xe, 159 => 0xf, 205 => 0x208 },
-	'maximumdensityrange' => { 94 => 0x8c },
-	'maxpagesize' => { 315 => 'MaxPageSize' },
-	'maxpagesizeh' => { 315 => [\'MaxPageSize','MaxPageSizeH'] },
-	'maxpagesizeunit' => { 315 => [\'MaxPageSize','MaxPageSizeUnit'] },
-	'maxpagesizew' => { 315 => [\'MaxPageSize','MaxPageSizeW'] },
-	'maxsamplevalue' => { 85 => 0x119 },
-	'maxstorage' => { 305 => 'maxstorage' },
-	'mb-d10batteries' => { 197 => '12.6' },
-	'mb-d10batterytype' => { 200 => '13.3' },
-	'mb-d11batterytype' => { 201 => '2.3' },
-	'mb-d80batteries' => { 202 => '6.5' },
-	'mb-d80batterytype' => { 203 => '3.2' },
-	'mcuversion' => { 157 => 0xc, 158 => 0x11, 159 => 0x12 },
-	'md5digest' => { 121 => 'zmd5' },
-	'measuredev' => { 19 => 0x9, 54 => 0x3, 72 => 0x1814, 113 => 'MeasuredEV' },
-	'measuredev2' => { 9 => 0x8, 19 => 0x8, 54 => 0x17 },
-	'measuredev3' => { 9 => 0x9 },
-	'measuredlv' => { 219 => 0x312, 225 => 0x3407 },
-	'measuredrggb' => { 44 => 0x1 },
-	'measuredrggbdata' => { 30 => 0x287 },
-	'mediaconstraints' => { 300 => 'MediaConstraints' },
-	'mediasummarycode' => { 300 => 'MediaSummaryCode' },
-	'menubuttondisplayposition' => { 57 => 0xb, 60 => 0xa, 61 => 0xb, 64 => 0xb },
-	'menubuttonreturn' => { 65 => 0xb },
-	'menumonitorofftime' => { 200 => '8.2', 201 => '21.1', 203 => '22.1' },
-	'metadatadate' => { 308 => 'MetadataDate' },
-	'metadatamoddate' => { 310 => 'metadataModDate' },
-	'metering' => { 198 => '6.1' },
-	'meteringmode' => { 24 => 0x11, 85 => 0x9207, 99 => 0x1c, 131 => 0x7, 132 => 0x25, 134 => 0x12, 204 => 0x202, 247 => 0x17, 270 => 0x9, 271 => 0x15, 272 => 0x13, 292 => 'MeteringMode' },
-	'meteringmode2' => { 232 => '2.1' },
-	'meteringmode3' => { 232 => '16.1' },
-	'meteringoffscaleindicator' => { 134 => 0x53 },
-	'meteringtime' => { 197 => '22.2', 198 => '3.2', 199 => '17.1', 200 => '7.3', 201 => '18.1', 202 => '3.2', 203 => '19.1' },
-	'mieversion' => { 121 => '0Vers' },
-	'minaperture' => { 24 => 0x1b, 120 => 'MinAperture', 241 => '0.2' },
-	'minfocallength' => { 89 => 0x1404, 120 => 'MinFocalLength', 157 => 0x8, 158 => 0xd, 159 => 0xe, 205 => 0x207 },
-	'minoltadate' => { 131 => 0x15 },
-	'minoltaimagesize' => { 131 => 0x4, 132 => 0xc, 133 => 0x2, 135 => 0x103 },
-	'minoltamodelid' => { 131 => 0x25 },
-	'minoltaquality' => { 131 => 0x5, 132 => 0xd, 133 => 0x3, 135 => [0x102,0x103] },
-	'minoltatime' => { 131 => 0x16 },
-	'minormodelagedisclosure' => { 300 => 'MinorModelAgeDisclosure' },
-	'minsamplevalue' => { 85 => 0x118 },
-	'mirrorlockup' => { 57 => 0xc, 58 => 0xc, 59 => 0x60f, 60 => 0xb, 61 => 0xc, 62 => 0x6, 63 => 0x6, 64 => 0xc, 65 => 0x3 },
-	'mobilecountrycode' => { 287 => 'mcc' },
-	'mobilenetworkcode' => { 287 => 'mnc' },
-	'moddate' => { 215 => 'modify-date', 298 => 'ModDate' },
-	'model' => { 73 => 0x6, 85 => 0x110, 113 => 'Model', 215 => 'Model', 226 => 0x110, 306 => 'Model' },
-	'modelage' => { 294 => 'ModelAge' },
-	'modelingflash' => { 197 => '21.4', 200 => '26.4', 201 => '30.2', 202 => '7.4', 203 => '31.3' },
-	'modelreleaseid' => { 300 => 'ModelReleaseID' },
-	'modelreleasestatus' => { 300 => 'ModelReleaseStatus' },
-	'modificationdate' => { 301 => 'modificationDate' },
-	'modifiedcolortemp' => { 45 => 0x9 },
-	'modifieddigitalgain' => { 45 => 0xb },
-	'modifiedparamflag' => { 39 => 0x1 },
-	'modifiedpicturestyle' => { 45 => 0xa },
-	'modifiedsaturation' => { 204 => 0x504 },
-	'modifiedsensorbluelevel' => { 45 => 0x5 },
-	'modifiedsensorredlevel' => { 45 => 0x4 },
-	'modifiedsharpness' => { 45 => 0x2 },
-	'modifiedsharpnessfreq' => { 45 => 0x3 },
-	'modifiedtonecurve' => { 45 => 0x1 },
-	'modifiedwhitebalance' => { 45 => 0x8 },
-	'modifiedwhitebalanceblue' => { 45 => 0x7 },
-	'modifiedwhitebalancered' => { 45 => 0x6 },
-	'modifydate' => { 85 => 0x132, 114 => 'ModifyDate', 213 => 'ModDate', 214 => 'tIME', 258 => 'ModDate', 308 => 'ModifyDate' },
-	'moirefilter' => { 85 => 0xfe58, 288 => 'MoireFilter' },
-	'monitordisplayoff' => { 134 => 0x4c },
-	'monitorofftime' => { 197 => '18.2', 198 => '3.1', 202 => '3.1' },
-	'monochromecontrast' => { 78 => 0x3c },
-	'monochromefiltereffect' => { 78 => 0x3a, 247 => 0x73 },
-	'monochromelinear' => { 78 => 0x3d },
-	'monochromeoutputhighlightpoint' => { 78 => 0x41 },
-	'monochromeoutputshadowpoint' => { 78 => 0x42 },
-	'monochromerawhighlight' => { 78 => 0x7a },
-	'monochromerawhighlightpoint' => { 78 => 0x3f },
-	'monochromerawshadow' => { 78 => 0x83 },
-	'monochromerawshadowpoint' => { 78 => 0x40 },
-	'monochromesharpness' => { 78 => 0x3e },
-	'monochrometoning' => { 247 => 0x74 },
-	'monochrometoningeffect' => { 78 => 0x3b },
-	'monthdaycreated' => { 99 => 0x12, 108 => 0xe },
-	'moonphase' => { 259 => 0x12 },
-	'morepermissions' => { 286 => 'morePermissions' },
-	'motionsensitivity' => { 259 => 0x29 },
-	'multiburstimageheight' => { 276 => 0x1002 },
-	'multiburstimagewidth' => { 276 => 0x1001 },
-	'multiburstmode' => { 276 => 0x1000 },
-	'multicontrollerwhilemetering' => { 59 => 0x517 },
-	'multiexposureautogain' => { 161 => 0x3 },
-	'multiexposuremode' => { 161 => 0x1 },
-	'multiexposureshots' => { 161 => 0x2 },
-	'multiframenoisereduction' => { 276 => 0x200b },
-	'multipleexposuremode' => { 208 => 0x101c },
-	'multipleexposureset' => { 232 => '10.1' },
-	'multisample' => { 165 => 0x40 },
-	'multiselector' => { 197 => '9.4', 200 => '27.4' },
-	'multiselectorliveview' => { 197 => '4.3' },
-	'multiselectorplaybackmode' => { 197 => ['13.5','9.2'], 200 => '27.2' },
-	'multiselectorshootmode' => { 197 => '9.1', 200 => '27.1' },
-	'mycolormode' => { 47 => 0x2 },
-	'nativedigest' => { 292 => 'NativeDigest', 306 => 'NativeDigest' },
-	'ncdfileinfo' => { 97 => 0x414 },
-	'ndfilter' => { 54 => 0x1c },
-	'nefbitdepth' => { 160 => 0xe22 },
-	'nefcompression' => { 160 => 0x93 },
-	'neutraloutputhighlightpoint' => { 78 => 0x2f },
-	'neutraloutputshadowpoint' => { 78 => 0x30 },
-	'neutralrawcolortone' => { 78 => 0x28 },
-	'neutralrawcontrast' => { 78 => 0x2a },
-	'neutralrawhighlight' => { 78 => 0x78 },
-	'neutralrawhighlightpoint' => { 78 => 0x2d },
-	'neutralrawlinear' => { 78 => 0x2b },
-	'neutralrawsaturation' => { 78 => 0x29 },
-	'neutralrawshadow' => { 78 => 0x81 },
-	'neutralrawshadowpoint' => { 78 => 0x2e },
-	'neutralrawsharpness' => { 78 => 0x2c },
-	'newsphotoversion' => { 94 => 0x0 },
-	'nickname' => { 308 => 'Nickname' },
-	'nikoncapturedata' => { 160 => 0xe01 },
-	'nikoncaptureeditversions' => { 160 => 0xe13 },
-	'nikoncaptureoutput' => { 160 => 0xe1e },
-	'nikoncaptureversion' => { 160 => 0xe09 },
-	'nikoniccprofile' => { 160 => 0xe1d },
-	'nikonimagesize' => { 172 => '723.1', 173 => '732.1', 178 => 0x2c4 },
-	'noisefilter' => { 204 => 0x527 },
-	'noisereduction' => { 89 => 0x100b, 132 => 0xb0, 133 => 0x60, 134 => 0x3f, 160 => 0x95, 190 => 0x753dcbc0, 191 => 0x17, 204 => 0x50a, 209 => 0x103a, 224 => 0x2d, 247 => 0x49, 265 => 0x2a },
-	'noisereduction2' => { 208 => 0x1010 },
-	'noisereductionapplied' => { 85 => 0xc6f7 },
-	'noisereductionintensity' => { 191 => 0x9 },
-	'noisereductionmethod' => { 191 => 0x11 },
-	'noisereductionmode' => { 279 => 0x801e },
-	'noisereductionsharpness' => { 191 => 0xd },
-	'noisereductionvalue' => { 279 => 0x8027 },
-	'nomemorycard' => { 197 => '22.1', 198 => '0.3', 199 => '2.4', 200 => '33.7', 201 => '3.2', 202 => '0.3', 203 => '4.5' },
-	'nominalmaxaperture' => { 241 => 0xa },
-	'nominalminaperture' => { 241 => '10.1' },
-	'notes' => { 280 => 'Notes', 284 => 'notes' },
-	'npages' => { 315 => 'NPages' },
-	'nrwdata' => { 160 => 0x14 },
-	'nullrecord' => { 72 => 0x0 },
-	'number' => { 301 => 'number' },
-	'numberofbeats' => { 310 => 'numberOfBeats' },
-	'numberoffocuspoints' => { 201 => '0.3' },
-	'numfacepositions' => { 217 => 0x0 },
-	'numindexentries' => { 94 => 0x54 },
-	'object' => { 301 => 'object' },
-	'objectattributereference' => { 92 => 0x4 },
-	'objectcycle' => { 92 => 0x4b },
-	'objectdistance' => { 81 => 0x6, 82 => 0x2022 },
-	'objectname' => { 92 => 0x5 },
-	'objectpreviewdata' => { 92 => 0xca },
-	'objectpreviewfileformat' => { 92 => 0xc8 },
-	'objectpreviewfileversion' => { 92 => 0xc9 },
-	'objecttypereference' => { 92 => 0x3 },
-	'oecfcolumns' => { 292 => [\'OECF','OECFColumns'] },
-	'oecfnames' => { 292 => [\'OECF','OECFNames'] },
-	'oecfrows' => { 292 => [\'OECF','OECFRows'] },
-	'oecfvalues' => { 292 => [\'OECF','OECFValues'] },
-	'offsetschema' => { 85 => 0xea1d },
-	'okbutton' => { 201 => '15.1', 203 => '16.1' },
-	'oldsubfiletype' => { 85 => 0xff },
-	'olympusimageheight' => { 209 => 0x102f },
-	'olympusimagewidth' => { 209 => 0x102e },
-	'onetouchwb' => { 209 => 0x302 },
-	'opticalzoom' => { 101 => 0xfa3d, 103 => [0x6006,0xf006], 104 => 0x1000, 105 => 0xf, 108 => 0x1e, 120 => 'OpticalZoom' },
-	'opticalzoomcode' => { 54 => 0xa },
-	'opticalzoommode' => { 224 => 0x34 },
-	'opticalzoomon' => { 269 => 0x219 },
-	'optionenddate' => { 303 => 'optionEndDate' },
-	'opto-electricconvfactor' => { 292 => 'OECF' },
-	'ordernumber' => { 89 => 0x8002 },
-	'organisationinimagecode' => { 294 => 'OrganisationInImageCode' },
-	'organisationinimagename' => { 294 => 'OrganisationInImageName' },
-	'organization' => { 301 => 'organization' },
-	'orientation' => { 85 => 0x112, 226 => 0x112, 306 => 'Orientation' },
-	'orientationlinkedafpoint' => { 59 => 0x516 },
-	'originaldecisiondata' => { 83 => 'OriginalDecisionData' },
-	'originaldecisiondataoffset' => { 43 => 0x83 },
-	'originaldirectory' => { 221 => 0x408 },
-	'originaldocumentid' => { 311 => 'OriginalDocumentID' },
-	'originalfilename' => { 72 => 0x816, 97 => 0x3e9, 109 => 0x20, 221 => 0x407 },
-	'originalimageheight' => { 55 => 0xc, 88 => 0x1 },
-	'originalimagewidth' => { 55 => 0xb, 88 => 0x0 },
-	'originalrawfiledata' => { 85 => 0xc68c },
-	'originalrawfiledigest' => { 85 => 0xc71d },
-	'originalrawfilename' => { 85 => 0xc68b },
-	'originaltransmissionreference' => { 92 => 0x67 },
-	'originatingprogram' => { 92 => 0x41 },
-	'originplatform' => { 301 => 'originPlatform' },
-	'os' => { 290 => 'os' },
-	'otherconditions' => { 300 => 'OtherConditions' },
-	'otherconstraints' => { 300 => 'OtherConstraints' },
-	'otherimageinfo' => { 300 => 'OtherImageInfo' },
-	'otherlicensedocuments' => { 300 => 'OtherLicenseDocuments' },
-	'otherlicenseinfo' => { 300 => 'OtherLicenseInfo' },
-	'otherlicenserequirements' => { 300 => 'OtherLicenseRequirements' },
-	'outcue' => { 310 => 'outCue' },
-	'outcuescale' => { 310 => [\'outCue','outCueScale'] },
-	'outcuevalue' => { 310 => [\'outCue','outCueValue'] },
-	'outputimageheight' => { 143 => 0x3 },
-	'outputimagewidth' => { 143 => 0x2 },
-	'outputresolution' => { 143 => 0x4 },
-	'owner' => { 314 => 'Owner' },
-	'ownerid' => { 92 => 0xbc },
-	'ownername' => { 11 => 0x10f, 43 => 0x9, 72 => 0x810, 85 => [0xa430,0xfde8], 113 => 'OwnerName', 285 => 'OwnerName' },
-	'padding' => { 85 => 0xea1c },
-	'pageimage' => { 308 => [\'PageInfo','PageInfoImage'] },
-	'pageimageformat' => { 308 => [\'PageInfo','PageInfoFormat'] },
-	'pageimageheight' => { 308 => [\'PageInfo','PageInfoHeight'] },
-	'pageimagepagenumber' => { 308 => [\'PageInfo','PageInfoPageNumber'] },
-	'pageimagewidth' => { 308 => [\'PageInfo','PageInfoWidth'] },
-	'pageinfo' => { 308 => 'PageInfo' },
-	'pagename' => { 85 => 0x11d },
-	'pagenumber' => { 85 => 0x129 },
-	'pagerange' => { 301 => 'pageRange' },
-	'paintbasedcorrectionmasks' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasks'] },
-	'paintbasedcorrections' => { 288 => 'PaintBasedCorrections' },
-	'paintcorrectionactive' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionActive'] },
-	'paintcorrectionamount' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionAmount'] },
-	'paintcorrectionbrightness' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBrightness'] },
-	'paintcorrectionclarity' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity'] },
-	'paintcorrectioncontrast' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast'] },
-	'paintcorrectionexposure' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure'] },
-	'paintcorrectionhue' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalToningHue'] },
-	'paintcorrectionmaskcenterweight' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterWeight'] },
-	'paintcorrectionmaskdabs' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksDabs'] },
-	'paintcorrectionmaskflow' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlow'] },
-	'paintcorrectionmaskfullx' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullX'] },
-	'paintcorrectionmaskfully' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullY'] },
-	'paintcorrectionmaskradius' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRadius'] },
-	'paintcorrectionmaskvalue' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMaskValue'] },
-	'paintcorrectionmaskwhat' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksWhat'] },
-	'paintcorrectionmaskzerox' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroX'] },
-	'paintcorrectionmaskzeroy' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroY'] },
-	'paintcorrectionsaturation' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSaturation','PaintBasedCorrectionsLocalToningSaturation'] },
-	'paintcorrectionsharpness' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSharpness'] },
-	'paintcorrectionwhat' => { 288 => [\'PaintBasedCorrections','PaintBasedCorrectionsWhat'] },
-	'panasonicexifversion' => { 224 => 0x26 },
-	'panasonicimageheight' => { 224 => 0x4c },
-	'panasonicimagewidth' => { 224 => 0x4b },
-	'panasonicrawversion' => { 226 => 0x1 },
-	'panasonictitle' => { 85 => 0xc6d2 },
-	'panasonictitle2' => { 85 => 0xc6d3 },
-	'panoramacropbottom' => { 277 => 0x7 },
-	'panoramacropleft' => { 277 => 0x4 },
-	'panoramacropright' => { 277 => 0x6 },
-	'panoramacroptop' => { 277 => 0x5 },
-	'panoramadirection' => { 50 => 0x5, 277 => 0x3 },
-	'panoramaframeheight' => { 277 => 0x9 },
-	'panoramaframenumber' => { 50 => 0x2 },
-	'panoramaframewidth' => { 277 => 0x8 },
-	'panoramafullheight' => { 277 => 0x2 },
-	'panoramafullwidth' => { 277 => 0x1 },
-	'panoramamode' => { 99 => 0x3c, 204 => 0x601 },
-	'panoramasourceheight' => { 277 => 0xb },
-	'panoramasourcewidth' => { 277 => 0xa },
-	'panoramicstitchcameramotion' => { 128 => 'PanoramicStitchCameraMotion', 129 => 0x1 },
-	'panoramicstitchmaptype' => { 128 => 'PanoramicStitchMapType', 129 => 0x2 },
-	'panoramicstitchphi0' => { 128 => 'PanoramicStitchPhi0', 129 => 0x5 },
-	'panoramicstitchphi1' => { 128 => 'PanoramicStitchPhi1', 129 => 0x6 },
-	'panoramicstitchtheta0' => { 128 => 'PanoramicStitchTheta0', 129 => 0x3 },
-	'panoramicstitchtheta1' => { 128 => 'PanoramicStitchTheta1', 129 => 0x4 },
-	'panoramicstitchversion' => { 129 => 0x0 },
-	'pantry' => { 311 => 'Pantry' },
-	'parallax' => { 89 => 0xb211 },
-	'parametricdarks' => { 288 => 'ParametricDarks' },
-	'parametrichighlights' => { 288 => 'ParametricHighlights' },
-	'parametrichighlightsplit' => { 288 => 'ParametricHighlightSplit' },
-	'parametriclights' => { 288 => 'ParametricLights' },
-	'parametricmidtonesplit' => { 288 => 'ParametricMidtoneSplit' },
-	'parametricshadows' => { 288 => 'ParametricShadows' },
-	'parametricshadowsplit' => { 288 => 'ParametricShadowSplit' },
-	'patientbirthdate' => { 281 => 'PatientDOB' },
-	'patientid' => { 281 => 'PatientID' },
-	'patientname' => { 281 => 'PatientName' },
-	'patientsex' => { 281 => 'PatientSex' },
-	'pdfversion' => { 298 => 'PDFVersion' },
-	'pentaximagesize' => { 247 => 0x9 },
-	'pentaxmodelid' => { 231 => 0x0, 247 => 0x5 },
-	'pentaxmodeltype' => { 247 => 0x1 },
-	'pentaxversion' => { 247 => 0x0 },
-	'people' => { 283 => 'People' },
-	'peripheralillumcentralradius' => { 279 => 0x8030 },
-	'peripheralillumcentralvalue' => { 279 => 0x8031 },
-	'peripheralillumination' => { 78 => 0x68 },
-	'peripheralilluminationon' => { 78 => 0x64 },
-	'peripheralillumperiphvalue' => { 279 => 0x8032 },
-	'peripherallighting' => { 55 => 0x2 },
-	'peripherallightingsetting' => { 56 => 0x5 },
-	'peripherallightingvalue' => { 55 => 0x6 },
-	'permissions' => { 303 => 'permissions' },
-	'person' => { 301 => 'person' },
-	'personinimage' => { 294 => 'PersonInImage' },
-	'perspectivehorizontal' => { 288 => 'PerspectiveHorizontal' },
-	'perspectiverotate' => { 288 => 'PerspectiveRotate' },
-	'perspectivescale' => { 288 => 'PerspectiveScale' },
-	'perspectivevertical' => { 288 => 'PerspectiveVertical' },
-	'pf0customfuncregistration' => { 67 => 0x1 },
-	'pf10retainprogramshift' => { 67 => 0xb },
-	'pf13drivepriority' => { 67 => 0xe },
-	'pf14disablefocussearch' => { 67 => 0xf },
-	'pf15disableafassistbeam' => { 67 => 0x10 },
-	'pf16autofocuspointshoot' => { 67 => 0x11 },
-	'pf17disableafpointsel' => { 67 => 0x12 },
-	'pf18enableautoafpointsel' => { 67 => 0x13 },
-	'pf19continuousshootspeed' => { 67 => 0x14 },
-	'pf19shootingspeedhigh' => { 66 => 0xa },
-	'pf19shootingspeedlow' => { 66 => 0x9 },
-	'pf1disableshootingmodes' => { 67 => 0x2 },
-	'pf1value' => { 66 => 0x1 },
-	'pf20limitcontinousshots' => { 67 => 0x15 },
-	'pf20maxcontinousshots' => { 66 => 0xb },
-	'pf21enablequietoperation' => { 67 => 0x16 },
-	'pf23felocktime' => { 66 => 0xd },
-	'pf23postreleasetime' => { 66 => 0xe },
-	'pf23settimerlengths' => { 67 => 0x18 },
-	'pf23shutterbuttontime' => { 66 => 0xc },
-	'pf24lightlcdduringbulb' => { 67 => 0x19 },
-	'pf25aemode' => { 66 => 0xf },
-	'pf25afmode' => { 66 => 0x12 },
-	'pf25afpointsel' => { 66 => 0x13 },
-	'pf25colormatrix' => { 66 => 0x17 },
-	'pf25defaultclearsettings' => { 67 => 0x1a },
-	'pf25drivemode' => { 66 => 0x11 },
-	'pf25imagesize' => { 66 => 0x14 },
-	'pf25meteringmode' => { 66 => 0x10 },
-	'pf25parameters' => { 66 => 0x16 },
-	'pf25wbmode' => { 66 => 0x15 },
-	'pf26shortenreleaselag' => { 67 => 0x1b },
-	'pf27reversedialrotation' => { 67 => 0x1c },
-	'pf27value' => { 66 => 0x18 },
-	'pf28noquickdialexpcomp' => { 67 => 0x1d },
-	'pf29quickdialswitchoff' => { 67 => 0x1e },
-	'pf2disablemeteringmodes' => { 67 => 0x3 },
-	'pf2value' => { 66 => 0x2 },
-	'pf30enlargementmode' => { 67 => 0x1f },
-	'pf31originaldecisiondata' => { 67 => 0x20 },
-	'pf3manualexposuremetering' => { 67 => 0x4 },
-	'pf3value' => { 66 => 0x3 },
-	'pf4exposuretimelimits' => { 67 => 0x5 },
-	'pf4exposuretimemax' => { 66 => 0x5 },
-	'pf4exposuretimemin' => { 66 => 0x4 },
-	'pf5aperturelimits' => { 67 => 0x6 },
-	'pf5aperturemax' => { 66 => 0x7 },
-	'pf5aperturemin' => { 66 => 0x6 },
-	'pf6presetshootingmodes' => { 67 => 0x7 },
-	'pf7bracketcontinuousshoot' => { 67 => 0x8 },
-	'pf8bracketshots' => { 66 => 0x8 },
-	'pf8setbracketshots' => { 67 => 0x9 },
-	'pf9changebracketsequence' => { 67 => 0xa },
-	'phasedetectaf' => { 141 => 0x6 },
-	'phonenumber' => { 114 => 'Phone' },
-	'photoeffect' => { 24 => 0x28 },
-	'photoeffecthistoryxml' => { 190 => 0xe9651831 },
-	'photoeffects' => { 190 => 0xab5eca5e },
-	'photoeffectsblue' => { 192 => 0x8 },
-	'photoeffectsgreen' => { 192 => 0x6 },
-	'photoeffectsred' => { 192 => 0x4 },
-	'photoeffectstype' => { 192 => 0x0 },
-	'photoinfoplayback' => { 197 => '17.6', 200 => '33.6' },
-	'photometricinterpretation' => { 85 => 0x106, 306 => 'PhotometricInterpretation' },
-	'photoshopquality' => { 255 => 0x0 },
-	'pictinfo' => { 269 => 0x208 },
-	'picturecontrol' => { 190 => 0xe2173c47 },
-	'picturecontrolactive' => { 193 => 0x0 },
-	'picturecontroladjust' => { 162 => 0x30 },
-	'picturecontrolbase' => { 162 => 0x18 },
-	'picturecontroldata' => { 160 => [0xbd,0x23] },
-	'picturecontrolmode' => { 193 => 0x13 },
-	'picturecontrolname' => { 162 => 0x4 },
-	'picturecontrolquickadjust' => { 162 => 0x31 },
-	'picturefinish' => { 132 => 0x71 },
-	'picturemode' => { 89 => 0x1031, 204 => 0x520, 247 => [0xb,0x33], 270 => 0x3d },
-	'picturemode2' => { 232 => 0x0 },
-	'picturemodebwfilter' => { 204 => 0x525 },
-	'picturemodecontrast' => { 204 => 0x523 },
-	'picturemodehue' => { 204 => 0x522 },
-	'picturemodesaturation' => { 204 => 0x521 },
-	'picturemodesharpness' => { 204 => 0x524 },
-	'picturemodetone' => { 204 => 0x526 },
-	'picturestyle' => { 5 => [0x4b,0x51], 6 => 0x6c, 7 => 0x86, 8 => 0x73, 12 => 0xab, 13 => 0xa7, 14 => 0xb0, 15 => 0x6c, 16 => 0xa7, 52 => 0xa, 78 => 0x2 },
-	'picturewizard' => { 267 => 0x21 },
-	'pitchangle' => { 246 => 0x2 },
-	'planarconfiguration' => { 85 => 0x11c, 306 => 'PlanarConfiguration' },
-	'platenames' => { 315 => 'PlateNames' },
-	'playbackmenustime' => { 199 => '20.1' },
-	'playbackmonitorofftime' => { 200 => '8.1', 201 => '35.1', 203 => '21.1' },
-	'playdisplay' => { 134 => 0x4e },
-	'plusversion' => { 300 => 'Version' },
-	'pngwarning' => { 215 => 'Warning' },
-	'portraitoutputhighlightpoint' => { 78 => 0x1d },
-	'portraitoutputshadowpoint' => { 78 => 0x1e },
-	'portraitrawcolortone' => { 78 => 0x16 },
-	'portraitrawcontrast' => { 78 => 0x18 },
-	'portraitrawhighlight' => { 78 => 0x76 },
-	'portraitrawhighlightpoint' => { 78 => 0x1b },
-	'portraitrawlinear' => { 78 => 0x19 },
-	'portraitrawsaturation' => { 78 => 0x17 },
-	'portraitrawshadow' => { 78 => 0x7f },
-	'portraitrawshadowpoint' => { 78 => 0x1c },
-	'portraitrawsharpness' => { 78 => 0x1a },
-	'portraitrefiner' => { 82 => 0x302b },
-	'postalcode' => { 118 => 'PostalCode' },
-	'postcropvignetteamount' => { 288 => 'PostCropVignetteAmount' },
-	'postcropvignettefeather' => { 288 => 'PostCropVignetteFeather' },
-	'postcropvignettemidpoint' => { 288 => 'PostCropVignetteMidpoint' },
-	'postcropvignetteroundness' => { 288 => 'PostCropVignetteRoundness' },
-	'postcropvignettestyle' => { 288 => 'PostCropVignetteStyle' },
-	'powersource' => { 230 => '0.1' },
-	'poweruptime' => { 160 => 0xb6 },
-	'precaptureframes' => { 209 => 0x300 },
-	'predictor' => { 85 => 0x13d },
-	'preflashreturnstrength' => { 173 => 0x28a },
-	'prefs' => { 92 => 0xdd, 254 => 'Prefs' },
-	'preservedfilename' => { 311 => 'PreservedFileName' },
-	'presetwhitebalance' => { 134 => 0x24, 279 => 0x8002 },
-	'presetwhitebalanceadj' => { 279 => 0x8014 },
-	'previewapplicationname' => { 85 => 0xc716 },
-	'previewapplicationversion' => { 85 => 0xc717 },
-	'previewbutton' => { 197 => ['14.1','15.1'], 200 => '29.1', 201 => '14.1' },
-	'previewbuttonplusdials' => { 197 => ['14.2','15.2'], 200 => '31.2' },
-	'previewcolorspace' => { 85 => 0xc71a },
-	'previewcropbottom' => { 253 => 0xef },
-	'previewcropleft' => { 253 => 0xec },
-	'previewcropright' => { 253 => 0xee },
-	'previewcroptop' => { 253 => 0xed },
-	'previewdatetime' => { 85 => 0xc71b },
-	'previewheight' => { 101 => 0xfa58 },
-	'previewimage' => { 82 => 0x2000, 83 => 'PreviewImage', 86 => 'PreviewImage', 87 => 0x4, 123 => 'data', 135 => 0x81, 209 => 0x280, 222 => 0x300, 276 => 0x2001 },
-	'previewimageborders' => { 247 => 0x3e },
-	'previewimageheight' => { 51 => 0x4 },
-	'previewimagelength' => { 51 => 0x2, 82 => 0x3, 85 => [0x117,0x202], 135 => 0x89, 163 => 0x202, 204 => 0x102, 209 => 0x1037, 247 => 0x3, 262 => 0x1e, 266 => 0x3, 270 => 0x1b, 273 => 0x202 },
-	'previewimagename' => { 123 => '1Name' },
-	'previewimagesize' => { 82 => 0x2, 106 => 0x2, 123 => 'ImageSize', 247 => 0x2, 270 => 0x1c, 276 => 0xb02c },
-	'previewimagestart' => { 51 => 0x5, 82 => 0x4, 85 => [0x111,0x201], 135 => 0x88, 163 => 0x201, 204 => 0x101, 209 => 0x1036, 247 => 0x4, 262 => 0x1c, 266 => 0x2, 270 => 0x1a, 273 => 0x201 },
-	'previewimagetype' => { 123 => '0Type' },
-	'previewimagevalid' => { 204 => 0x100, 209 => 0x1035 },
-	'previewimagewidth' => { 51 => 0x3 },
-	'previewquality' => { 51 => 0x1 },
-	'previewsettingsdigest' => { 85 => 0xc719 },
-	'previewsettingsname' => { 85 => 0xc718 },
-	'previewwidth' => { 101 => 0xfa57 },
-	'primaryafpoint' => { 141 => 0x7 },
-	'primarychromaticities' => { 85 => 0x13f, 306 => 'PrimaryChromaticities' },
-	'printim' => { 85 => 0xc4a5 },
-	'prioritysetupshutterrelease' => { 134 => 0x1d, 271 => 0x28 },
-	'privatertkinfo' => { 282 => 'privateRTKInfo' },
-	'processingsoftware' => { 85 => 0xb },
-	'processversion' => { 288 => 'ProcessVersion' },
-	'producer' => { 213 => 'Producer', 298 => 'Producer' },
-	'productid' => { 93 => 0x32 },
-	'productioncode' => { 231 => 0x2 },
-	'productorserviceconstraints' => { 300 => 'ProductOrServiceConstraints' },
-	'profilecalibrationsig' => { 85 => 0xc6f4 },
-	'profilecopyright' => { 85 => 0xc6fe },
-	'profileembedpolicy' => { 85 => 0xc6fd },
-	'profilehuesatmapdata1' => { 85 => 0xc6fa },
-	'profilehuesatmapdata2' => { 85 => 0xc6fb },
-	'profilehuesatmapdims' => { 85 => 0xc6f9 },
-	'profilelooktabledata' => { 85 => 0xc726 },
-	'profilelooktabledims' => { 85 => 0xc725 },
-	'profilename' => { 85 => 0xc6f8 },
-	'profiletonecurve' => { 85 => 0xc6fc },
-	'programiso' => { 224 => 0x3c },
-	'programline' => { 232 => '1.1' },
-	'programmode' => { 138 => 0x5 },
-	'programshift' => { 160 => 0xd },
-	'programversion' => { 92 => 0x46 },
-	'projectname' => { 310 => 'projectName' },
-	'projectref' => { 310 => 'projectRef' },
-	'projectrefpath' => { 310 => [\'projectRef','projectRefPath'] },
-	'projectreftype' => { 310 => [\'projectRef','projectRefType'] },
-	'propertyreleaseid' => { 300 => 'PropertyReleaseID' },
-	'propertyreleasestatus' => { 300 => 'PropertyReleaseStatus' },
-	'province-state' => { 92 => 0x5f },
-	'publicationdate' => { 301 => 'publicationDate' },
-	'publicationname' => { 301 => 'publicationName' },
-	'publisher' => { 289 => 'publisher' },
-	'pulldown' => { 310 => 'pullDown' },
-	'quality' => { 0 => 0x1, 24 => 0x3, 81 => 0x2, 82 => 0x3002, 89 => 0x1000, 99 => 0x9, 160 => 0x4, 180 => 0x3, 209 => 0x201, 219 => 0x300, 247 => 0x8, 252 => 0x2, 270 => 0x16, 271 => 0x56, 276 => [0x102,0xb047] },
-	'qualitymode' => { 82 => 0x8 },
-	'quantizationmethod' => { 94 => 0x78 },
-	'quickadjust' => { 193 => 0x2a },
-	'quickcontroldialinmeter' => { 59 => 0x703 },
-	'quickshot' => { 269 => 0x213 },
-	'rangefinder' => { 199 => '4.1' },
-	'rasterizedcaption' => { 92 => 0x7d },
-	'rating' => { 85 => 0x4746, 253 => 0xdf, 284 => 'rating', 290 => 'rating', 308 => 'Rating' },
-	'ratingpercent' => { 85 => 0x4749, 130 => 'Rating' },
-	'rawandjpgrecording' => { 57 => 0x8, 135 => 0x109, 232 => 0xd },
-	'rawbrightnessadj' => { 77 => 0x38 },
-	'rawcoloradj' => { 77 => 0x2e },
-	'rawcropbottom' => { 253 => 0xd4 },
-	'rawcropleft' => { 253 => 0xd1 },
-	'rawcropright' => { 253 => 0xd3 },
-	'rawcroptop' => { 253 => 0xd2 },
-	'rawcustomsaturation' => { 77 => 0x30 },
-	'rawcustomtone' => { 77 => 0x34 },
-	'rawdatauniqueid' => { 85 => 0xc65d },
-	'rawdepth' => { 137 => 0x10 },
-	'rawdevautogradation' => { 211 => 0x119 },
-	'rawdevcolorspace' => { 210 => 0x108, 211 => 0x109 },
-	'rawdevcontrastvalue' => { 210 => 0x106, 211 => 0x105 },
-	'rawdeveditstatus' => { 210 => 0x10b },
-	'rawdevengine' => { 210 => 0x109, 211 => 0x10b },
-	'rawdevexposurebiasvalue' => { 210 => 0x100, 211 => 0x100 },
-	'rawdevgradation' => { 211 => 0x112 },
-	'rawdevgraypoint' => { 210 => 0x103, 211 => 0x104 },
-	'rawdevmemorycoloremphasis' => { 210 => 0x105, 211 => 0x108 },
-	'rawdevnoisereduction' => { 210 => 0x10a, 211 => 0x10a },
-	'rawdevpicturemode' => { 211 => 0x10c },
-	'rawdevpm_bwfilter' => { 211 => 0x110 },
-	'rawdevpmcontrast' => { 211 => 0x10e },
-	'rawdevpmnoisefilter' => { 211 => 0x120 },
-	'rawdevpmpicturetone' => { 211 => 0x111 },
-	'rawdevpmsaturation' => { 211 => 0x10d },
-	'rawdevpmsharpness' => { 211 => 0x10f },
-	'rawdevsaturation3' => { 211 => 0x113 },
-	'rawdevsaturationemphasis' => { 210 => 0x104, 211 => 0x107 },
-	'rawdevsettings' => { 210 => 0x10c },
-	'rawdevsharpnessvalue' => { 210 => 0x107, 211 => 0x106 },
-	'rawdevversion' => { 210 => 0x0, 211 => 0x0 },
-	'rawdevwbfineadjustment' => { 210 => 0x102, 211 => 0x103 },
-	'rawdevwhitebalance' => { 211 => 0x101 },
-	'rawdevwhitebalancevalue' => { 210 => 0x101, 211 => 0x102 },
-	'rawfile' => { 85 => 0xfe4c },
-	'rawfilename' => { 288 => 'RawFileName' },
-	'rawimagecenter' => { 160 => 0x99 },
-	'rawimagedigest' => { 85 => 0xc71c },
-	'rawimagesize' => { 247 => 0x39 },
-	'rawinfoversion' => { 212 => 0x0 },
-	'rawjpgheight' => { 74 => 0x4 },
-	'rawjpgquality' => { 38 => 0x6, 74 => 0x1 },
-	'rawjpgsize' => { 38 => 0x7, 74 => 0x2 },
-	'rawjpgwidth' => { 74 => 0x3 },
-	'rawmeasuredrggb' => { 29 => 0x26a, 31 => 0x280, 33 => 0x194 },
-	'reardisplay' => { 197 => '12.3' },
-	'recognizedface1age' => { 218 => 0x20 },
-	'recognizedface1name' => { 218 => 0x4 },
-	'recognizedface1position' => { 218 => 0x18 },
-	'recognizedface2age' => { 218 => 0x50 },
-	'recognizedface2name' => { 218 => 0x34 },
-	'recognizedface2position' => { 218 => 0x48 },
-	'recognizedface3age' => { 218 => 0x80 },
-	'recognizedface3name' => { 218 => 0x64 },
-	'recognizedface3position' => { 218 => 0x78 },
-	'recognizedfaceflags' => { 224 => 0x63 },
-	'recommendedexposureindex' => { 85 => 0x8832 },
-	'recorddisplay' => { 134 => 0x4d },
-	'recordid' => { 72 => 0x1804 },
-	'recordingmode' => { 81 => 0x1, 252 => 0x1 },
-	'recordmode' => { 24 => 0x9, 82 => 0x3000 },
-	'recordshutterrelease' => { 269 => 0x217 },
-	'redbalance' => { 148 => 0x270, 209 => 0x1017, 226 => 0x11, 247 => 0x1c },
-	'redcurvelimits' => { 77 => 0x18a },
-	'redcurvepoints' => { 77 => 0x160 },
-	'redeyecorrection' => { 194 => 0x0 },
-	'redeyeinfo' => { 288 => 'RedEyeInfo' },
-	'redeyereduction' => { 134 => 0x41 },
-	'redhue' => { 288 => 'RedHue' },
-	'redsaturation' => { 288 => 'RedSaturation' },
-	'reductionmatrix1' => { 85 => 0xc625 },
-	'reductionmatrix2' => { 85 => 0xc626 },
-	'referenceblackwhite' => { 85 => 0x214, 306 => 'ReferenceBlackWhite' },
-	'referencedate' => { 92 => 0x2f },
-	'referencenumber' => { 92 => 0x32 },
-	'references' => { 114 => 'References' },
-	'referenceservice' => { 92 => 0x2d },
-	'regionappliedtodimensions' => { 297 => [\'Regions','RegionsAppliedToDimensions'] },
-	'regionappliedtodimensionsh' => { 297 => [\'Regions','RegionsAppliedToDimensionsH'] },
-	'regionappliedtodimensionsunit' => { 297 => [\'Regions','RegionsAppliedToDimensionsUnit'] },
-	'regionappliedtodimensionsw' => { 297 => [\'Regions','RegionsAppliedToDimensionsW'] },
-	'regionarea' => { 297 => [\'Regions','RegionsRegionListArea'] },
-	'regionaread' => { 297 => [\'Regions','RegionsRegionListAreaD'] },
-	'regionareah' => { 297 => [\'Regions','RegionsRegionListAreaH'] },
-	'regionareaunit' => { 297 => [\'Regions','RegionsRegionListAreaUnit'] },
-	'regionareaw' => { 297 => [\'Regions','RegionsRegionListAreaW'] },
-	'regionareax' => { 297 => [\'Regions','RegionsRegionListAreaX'] },
-	'regionareay' => { 297 => [\'Regions','RegionsRegionListAreaY'] },
-	'regionbarcodevalue' => { 297 => [\'Regions','RegionsRegionListBarCodeValue'] },
-	'regionconstraints' => { 300 => 'RegionConstraints' },
-	'regiondescription' => { 297 => [\'Regions','RegionsRegionListDescription'] },
-	'regionextensions' => { 297 => [\'Regions','RegionsRegionListExtensions'] },
-	'regionfocususage' => { 297 => [\'Regions','RegionsRegionListFocusUsage'] },
-	'regioninfo' => { 297 => 'Regions' },
-	'regioninfomp' => { 127 => 'RegionInfo' },
-	'regioninfompregions' => { 127 => [\'RegionInfo','RegionInfoRegions'] },
-	'regionlist' => { 297 => [\'Regions','RegionsRegionList'] },
-	'regionname' => { 297 => [\'Regions','RegionsRegionListName'] },
-	'regionpersondisplayname' => { 127 => [\'RegionInfo','RegionInfoRegionsPersonDisplayName'] },
-	'regionrectangle' => { 127 => [\'RegionInfo','RegionInfoRegionsRectangle'] },
-	'regionseealso' => { 297 => [\'Regions','RegionsRegionListSeeAlso'] },
-	'regiontype' => { 297 => [\'Regions','RegionsRegionListType'] },
-	'registryid' => { 294 => 'RegistryId' },
-	'registryitemid' => { 294 => [\'RegistryId','RegistryIdRegItemId'] },
-	'registryorganisationid' => { 294 => [\'RegistryId','RegistryIdRegOrgId'] },
-	'relatedaudiofile' => { 112 => 'data' },
-	'relatedaudiofilename' => { 112 => '1Name' },
-	'relatedaudiofiletype' => { 112 => '0Type' },
-	'relatedimagefileformat' => { 85 => 0x1000 },
-	'relatedimageheight' => { 85 => 0x1002 },
-	'relatedimagewidth' => { 85 => 0x1001 },
-	'relatedsoundfile' => { 85 => 0xa004, 292 => 'RelatedSoundFile' },
-	'relatedvideofile' => { 126 => 'data' },
-	'relatedvideofilename' => { 126 => '1Name' },
-	'relatedvideofiletype' => { 126 => '0Type' },
-	'relation' => { 289 => 'relation' },
-	'relativepeakaudiofilepath' => { 310 => 'relativePeakAudioFilePath' },
-	'relativetimestamp' => { 310 => 'relativeTimestamp' },
-	'relativetimestampscale' => { 310 => [\'relativeTimestamp','relativeTimestampScale'] },
-	'relativetimestampvalue' => { 310 => [\'relativeTimestamp','relativeTimestampValue'] },
-	'releasebuttontousedial' => { 197 => '17.8', 200 => '33.8', 201 => '17.6' },
-	'releasedate' => { 92 => 0x1e, 310 => 'releaseDate' },
-	'releasemode' => { 82 => 0x3001, 276 => 0xb049 },
-	'releasesetting' => { 72 => 0x1016 },
-	'releasetime' => { 92 => 0x23 },
-	'remoteonduration' => { 198 => '3.4', 199 => '17.2', 201 => '18.2', 202 => '4.3', 203 => '19.2' },
-	'renditionclass' => { 311 => 'RenditionClass' },
-	'renditionof' => { 311 => 'RenditionOf' },
-	'renditionofalternatepaths' => { 311 => [\'RenditionOf','RenditionOfAlternatePaths'] },
-	'renditionofdocumentid' => { 311 => [\'RenditionOf','RenditionOfDocumentID'] },
-	'renditionoffilepath' => { 311 => [\'RenditionOf','RenditionOfFilePath'] },
-	'renditionoffrompart' => { 311 => [\'RenditionOf','RenditionOfFromPart'] },
-	'renditionofinstanceid' => { 311 => [\'RenditionOf','RenditionOfInstanceID'] },
-	'renditionoflastmodifydate' => { 311 => [\'RenditionOf','RenditionOfLastModifyDate'] },
-	'renditionofmanager' => { 311 => [\'RenditionOf','RenditionOfManager'] },
-	'renditionofmanagervariant' => { 311 => [\'RenditionOf','RenditionOfManagerVariant'] },
-	'renditionofmanageto' => { 311 => [\'RenditionOf','RenditionOfManageTo'] },
-	'renditionofmanageui' => { 311 => [\'RenditionOf','RenditionOfManageUI'] },
-	'renditionofmaskmarkers' => { 311 => [\'RenditionOf','RenditionOfMaskMarkers'] },
-	'renditionoforiginaldocumentid' => { 311 => [\'RenditionOf','RenditionOfOriginalDocumentID'] },
-	'renditionofpartmapping' => { 311 => [\'RenditionOf','RenditionOfPartMapping'] },
-	'renditionofrenditionclass' => { 311 => [\'RenditionOf','RenditionOfRenditionClass'] },
-	'renditionofrenditionparams' => { 311 => [\'RenditionOf','RenditionOfRenditionParams'] },
-	'renditionoftopart' => { 311 => [\'RenditionOf','RenditionOfToPart'] },
-	'renditionofversionid' => { 311 => [\'RenditionOf','RenditionOfVersionID'] },
-	'renditionparams' => { 311 => 'RenditionParams' },
-	'repeatingflashcount' => { 152 => 0xd, 153 => 0xe, 154 => 0xe, 200 => '17.2', 201 => '24.2', 202 => '9.2', 203 => '25.2' },
-	'repeatingflashoutput' => { 200 => '17.1', 201 => '24.1', 202 => '9.1', 203 => '25.1' },
-	'repeatingflashrate' => { 152 => 0xc, 153 => 0xd, 154 => 0xd, 200 => '18.1', 201 => '25.1', 202 => '10.1', 203 => '26.1' },
-	'resampleparams' => { 310 => 'resampleParams' },
-	'resampleparamsquality' => { 310 => [\'resampleParams','resampleParamsQuality'] },
-	'resaved' => { 269 => 0x21e },
-	'resolution' => { 119 => 'Resolution' },
-	'resolutionmode' => { 270 => 0x4 },
-	'resolutionunit' => { 85 => 0x128, 95 => 0x2, 306 => 'ResolutionUnit' },
-	'restrictions' => { 303 => 'restrictions' },
-	'retouchhistory' => { 160 => 0x9e },
-	'retouchinfo' => { 288 => 'RetouchInfo' },
-	'reuse' => { 300 => 'Reuse' },
-	'reuseallowed' => { 313 => 'ReuseAllowed' },
-	'reuseprohibited' => { 303 => 'reuseProhibited' },
-	'reverseindicators' => { 197 => '12.1', 199 => '4.3', 200 => '33.5', 201 => '5.1', 203 => '6.2' },
-	'revision' => { 290 => 'revision' },
-	'rgbcurvelimits' => { 77 => 0x238 },
-	'rgbcurvepoints' => { 77 => 0x20e },
-	'ricohdate' => { 262 => 0x6 },
-	'ricohimageheight' => { 262 => 0x2 },
-	'ricohimagewidth' => { 262 => 0x0 },
-	'rightascension' => { 122 => 'RightAscension' },
-	'rights' => { 289 => 'rights' },
-	'rightsagent' => { 301 => 'rightsAgent', 303 => 'rightsAgent' },
-	'rightsowner' => { 303 => 'rightsOwner' },
-	'rollangle' => { 246 => 0x1 },
-	'romoperationmode' => { 72 => 0x80d },
-	'rotation' => { 21 => 0x17, 22 => 0x18, 71 => 0x3, 77 => 0x26e, 88 => 0x4, 122 => 'Rotation', 132 => [0x65,0x50], 133 => 0x46, 134 => 0x5a, 178 => '590.1', 190 => 0x76a43207, 224 => 0x30, 232 => '17.2', 253 => 0xd8, 271 => 0x3f, 272 => 0x3f },
-	'routing' => { 258 => 'Routing' },
-	'rowsperstrip' => { 85 => 0x116 },
-	'rpp' => { 284 => 'rpp' },
-	'safetyshift' => { 59 => 0x108 },
-	'safetyshiftinavortv' => { 57 => 0x10, 58 => 0x10, 60 => 0xf, 61 => 0x10, 64 => 0x10 },
-	'samplebits' => { 112 => 'SampleBits' },
-	'samplerate' => { 112 => 'SampleRate' },
-	'samplesperpixel' => { 85 => 0x115, 306 => 'SamplesPerPixel' },
-	'samplestructure' => { 94 => 0x5a },
-	'sanyoquality' => { 269 => 0x201 },
-	'sanyothumbnail' => { 269 => 0x100 },
-	'saturation' => { 6 => 0x6e, 8 => 0x76, 24 => 0xe, 34 => 0x1, 81 => 0xd, 82 => [0x3013,0x1f], 85 => [0xa409,0xfe55], 89 => 0x1003, 113 => 'Saturation', 131 => 0x1f, 132 => 0x32, 133 => 0x28, 134 => 0x1a, 138 => 0x1, 160 => [0x94,0xaa], 162 => 0x35, 224 => 0x40, 225 => 0x300d, 247 => 0x1f, 252 => 0xd, 259 => 0x27, 262 => 0x28, 270 => 0x10, 271 => 0x1e, 272 => 0x1b, 276 => 0x2005, 288 => 'Saturation', 292 => 'Saturation' },
-	'saturationadj' => { 77 => 0x116, 189 => 0x1, 193 => 0x2e, 279 => 0x8016 },
-	'saturationadjustmentaqua' => { 288 => 'SaturationAdjustmentAqua' },
-	'saturationadjustmentblue' => { 288 => 'SaturationAdjustmentBlue' },
-	'saturationadjustmentgreen' => { 288 => 'SaturationAdjustmentGreen' },
-	'saturationadjustmentmagenta' => { 288 => 'SaturationAdjustmentMagenta' },
-	'saturationadjustmentorange' => { 288 => 'SaturationAdjustmentOrange' },
-	'saturationadjustmentpurple' => { 288 => 'SaturationAdjustmentPurple' },
-	'saturationadjustmentred' => { 288 => 'SaturationAdjustmentRed' },
-	'saturationadjustmentyellow' => { 288 => 'SaturationAdjustmentYellow' },
-	'saturationfaithful' => { 15 => 0xfe, 48 => 0x68, 49 => 0x68 },
-	'saturationlandscape' => { 15 => 0xfc, 48 => 0x38, 49 => 0x38 },
-	'saturationmonochrome' => { 48 => 0x80, 49 => 0x80 },
-	'saturationneutral' => { 15 => 0xfd, 48 => 0x50, 49 => 0x50 },
-	'saturationportrait' => { 15 => 0xfb, 48 => 0x20, 49 => 0x20 },
-	'saturationsetting' => { 212 => 0x1010 },
-	'saturationstandard' => { 15 => 0xfa, 48 => 0x8, 49 => 0x8 },
-	'saturationunknown' => { 49 => 0x98 },
-	'saturationuserdef1' => { 15 => 0x100, 48 => 0x98, 49 => 0xb0 },
-	'saturationuserdef2' => { 15 => 0x101, 48 => 0xb0, 49 => 0xc8 },
-	'saturationuserdef3' => { 15 => 0x102, 48 => 0xc8, 49 => 0xe0 },
-	'saveid' => { 311 => 'SaveID' },
-	'scaletype' => { 310 => 'scaleType' },
-	'scanimageenhancer' => { 165 => 0x60 },
-	'scanningdirection' => { 94 => 0x64 },
-	'scene' => { 293 => 'Scene', 310 => 'scene' },
-	'scenearea' => { 207 => 0x211, 209 => 0x1031 },
-	'sceneassist' => { 160 => 0x9c },
-	'scenecapturetype' => { 85 => 0xa406, 292 => 'SceneCaptureType' },
-	'scenedetect' => { 207 => 0x210, 209 => 0x1030 },
-	'scenedetectdata' => { 207 => 0x212, 209 => 0x1033 },
-	'scenemode' => { 101 => 0xfa02, 135 => 0x100, 160 => 0x8f, 204 => 0x509, 209 => 0x403, 224 => 0x8001, 276 => 0xb023 },
-	'scenemodeused' => { 103 => [0x6002,0xf002] },
-	'sceneselect' => { 269 => 0x21f },
-	'scenetype' => { 85 => 0xa301, 292 => 'SceneType' },
-	'screentips' => { 197 => '12.7', 200 => '13.1', 201 => '4.4', 203 => '5.1' },
-	'section' => { 301 => 'section' },
-	'securityclassification' => { 85 => 0x9212 },
-	'selectableafpoint' => { 59 => 0x509 },
-	'selectafareaselectmode' => { 59 => 0x512 },
-	'selftimer' => { 24 => 0x2, 224 => 0x2e, 269 => 0x214 },
-	'selftimer2' => { 54 => 0x1d },
-	'selftimerinterval' => { 201 => '19.2' },
-	'selftimermode' => { 85 => 0x882b },
-	'selftimershotcount' => { 199 => '18.2', 201 => '19.3', 203 => '20.2' },
-	'selftimertime' => { 72 => 0x1806, 134 => 0x1f, 197 => '18.1', 198 => '3.3', 199 => '18.1', 200 => '7.2', 201 => '19.1', 202 => '3.3', 203 => '20.1' },
-	'seminfo' => { 85 => 0x8546 },
-	'sensingmethod' => { 85 => 0xa217, 292 => 'SensingMethod' },
-	'sensitivityadjust' => { 247 => 0x40 },
-	'sensitivitysteps' => { 232 => ['14.3','17.4'], 234 => 0x1 },
-	'sensitivitytype' => { 85 => 0x8830 },
-	'sensorareas' => { 267 => 0xa010 },
-	'sensorbitdepth' => { 225 => 0x312d },
-	'sensorbluelevel' => { 52 => 0x5 },
-	'sensorcleaning' => { 65 => 0xd },
-	'sensorfullheight' => { 96 => 0xf904 },
-	'sensorfullwidth' => { 96 => 0xf903 },
-	'sensorheight' => { 96 => 0xf901, 101 => 0xfa21, 137 => 0x8, 225 => 0x312c },
-	'sensorpixelsize' => { 160 => 0x9a },
-	'sensorredlevel' => { 52 => 0x4 },
-	'sensorsize' => { 113 => 'SensorSize', 247 => 0x35 },
-	'sensortemperature' => { 207 => 0x1500, 209 => 0x1007, 270 => 0x39 },
-	'sensorwidth' => { 96 => 0xf900, 101 => 0xfa20, 137 => 0xa, 225 => 0x312b },
-	'sequence' => { 259 => 0x7 },
-	'sequencenumber' => { 54 => 0x9, 82 => 0x301c, 89 => 0x1101, 99 => 0x1d, 224 => 0x2b, 276 => 0xb04a },
-	'sequenceshotinterval' => { 269 => 0x224 },
-	'sequentialshot' => { 269 => 0x20e },
-	'serialnumber' => { 43 => 0xc, 72 => 0x180b, 85 => [0xa431,0xfde9], 96 => 0xfa04, 98 => 0xfa00, 100 => 0xc354, 101 => 0xfa19, 110 => 0x0, 111 => 0xa8, 113 => 'SerialNumber', 160 => [0xa0,0x1d], 205 => 0x101, 209 => [0x404,0x101a], 219 => 0x303, 225 => 0x3103, 247 => 0x229, 259 => 0x15, 263 => 0x5, 270 => 0x2, 285 => 'SerialNumber' },
-	'serialnumberformat' => { 43 => 0x15, 72 => 0x183b },
-	'seriesdatetime' => { 281 => 'SeriesDateTime' },
-	'seriesdescription' => { 281 => 'SeriesDescription' },
-	'seriesmodality' => { 281 => 'SeriesModality' },
-	'seriesnumber' => { 281 => 'SeriesNumber' },
-	'serviceidentifier' => { 93 => 0x1e },
-	'setbuttoncrosskeysfunc' => { 62 => 0x0, 63 => 0x0 },
-	'setbuttonwhenshooting' => { 57 => 0x1, 59 => 0x704, 65 => 0xc },
-	'setfunctionwhenshooting' => { 60 => 0x0, 61 => 0x1, 64 => 0x1 },
-	'shadingcompensation' => { 204 => 0x50c },
-	'shadingcompensation2' => { 208 => 0x1012 },
-	'shadow' => { 270 => 0xe },
-	'shadowcompensation' => { 247 => 0x79 },
-	'shadowprotection' => { 189 => 0x0 },
-	'shadows' => { 85 => 0xfe52, 288 => 'Shadows' },
-	'shadowscale' => { 85 => 0xc633 },
-	'shadowtint' => { 288 => 'ShadowTint' },
-	'shakereduction' => { 248 => 0x1 },
-	'sharpendetail' => { 288 => 'SharpenDetail' },
-	'sharpenedgemasking' => { 288 => 'SharpenEdgeMasking' },
-	'sharpening' => { 225 => 0x300b },
-	'sharpeningadj' => { 193 => 0x2b },
-	'sharpenradius' => { 288 => 'SharpenRadius' },
-	'sharpness' => { 5 => [0x42,0x48], 6 => 0x72, 8 => 0x74, 24 => 0xf, 52 => 0x2, 81 => 0xb, 82 => [0x3011,0x21], 85 => [0xa40a,0xfe56], 89 => 0x1001, 99 => 0x6b, 108 => 0x37, 113 => 'Sharpness', 131 => 0x21, 132 => 0x30, 133 => 0x26, 134 => 0x18, 138 => 0x3, 160 => 0x6, 162 => 0x32, 209 => 0x100f, 224 => 0x41, 247 => 0x21, 252 => 0xb, 259 => 0x26, 262 => 0x22, 263 => 0x1003, 270 => 0x11, 271 => 0x1c, 272 => 0x19, 276 => 0x2006, 288 => 'Sharpness', 292 => 'Sharpness' },
-	'sharpnessadj' => { 77 => 0x25a, 279 => 0x801a },
-	'sharpnessfactor' => { 209 => 0x102a },
-	'sharpnessfaithful' => { 15 => 0xf5, 48 => 0x64, 49 => 0x64 },
-	'sharpnessfrequency' => { 5 => [0x41,0x47], 52 => 0x3 },
-	'sharpnesslandscape' => { 15 => 0xf3, 48 => 0x34, 49 => 0x34 },
-	'sharpnessmonochrome' => { 15 => 0xf6, 48 => 0x7c, 49 => 0x7c },
-	'sharpnessneutral' => { 15 => 0xf4, 48 => 0x4c, 49 => 0x4c },
-	'sharpnessovershoot' => { 279 => 0x801b },
-	'sharpnessportrait' => { 15 => 0xf2, 48 => 0x1c, 49 => 0x1c },
-	'sharpnesssetting' => { 204 => 0x506, 212 => 0x1013 },
-	'sharpnessstandard' => { 15 => 0xf1, 48 => 0x4, 49 => 0x4 },
-	'sharpnessthreshold' => { 279 => 0x801d },
-	'sharpnessundershoot' => { 279 => 0x801c },
-	'sharpnessunknown' => { 49 => 0x94 },
-	'sharpnessuserdef1' => { 15 => 0xf7, 48 => 0x94, 49 => 0xac },
-	'sharpnessuserdef2' => { 15 => 0xf8, 48 => 0xac, 49 => 0xc4 },
-	'sharpnessuserdef3' => { 15 => 0xf9, 48 => 0xc4, 49 => 0xdc },
-	'shootinginfodisplay' => { 197 => '13.2', 200 => '10.2', 201 => '4.1', 203 => '5.3' },
-	'shootinginfomonitorofftime' => { 200 => '9.1', 201 => '21.2', 203 => '22.2' },
-	'shootingmode' => { 113 => 'ShootingMode', 160 => 0x89, 224 => 0x1f },
-	'shootingmodesetting' => { 198 => '5.1' },
-	'shortdescription' => { 290 => 'shortdescription' },
-	'shortdocumentid' => { 92 => 0xba },
-	'shortfocal' => { 5 => 0xe, 6 => 0x11, 7 => 0x113, 8 => 0x11, 9 => [0x150,0x151], 10 => 0xd8, 12 => 0xf8, 13 => 0xec, 14 => 0x101, 15 => 0x93, 16 => 0xe8, 18 => 0xea, 20 => 0xf0, 24 => 0x18 },
-	'shortownername' => { 15 => 0xac },
-	'shortreleasetimelag' => { 59 => 0x80d },
-	'shotdate' => { 310 => 'shotDate' },
-	'shotday' => { 310 => 'shotDay' },
-	'shotlocation' => { 310 => 'shotLocation' },
-	'shotname' => { 310 => 'shotName' },
-	'shotnumber' => { 310 => 'shotNumber' },
-	'shotsize' => { 310 => 'shotSize' },
-	'shutter-aelock' => { 57 => 0x4, 59 => 0x701, 60 => 0x3, 61 => 0x4, 62 => 0x3, 63 => 0x3, 64 => 0x4, 65 => 0x2 },
-	'shutteraelbutton' => { 58 => 0x4 },
-	'shutterbuttonafonbutton' => { 59 => 0x701 },
-	'shuttercount' => { 7 => 0x176, 38 => 0x1, 160 => 0xa7, 166 => [0x6a,0x157,0x24d], 167 => 0x286, 168 => 0x279, 169 => 0x284, 170 => 0x242, 171 => 0x280, 172 => 0x276, 173 => [0x27d,0x27f], 174 => 0x246, 175 => 0x2d6, 176 => 0x287, 177 => 0x320, 178 => 0x24a, 179 => 0x2d5, 247 => 0x5d },
-	'shuttercurtainsync' => { 57 => 0xf, 58 => 0xf, 59 => 0x305, 60 => 0xe, 61 => 0xf, 62 => 0x8, 63 => 0x8, 64 => 0xf, 65 => 0x8 },
-	'shuttermode' => { 99 => 0x1b },
-	'shutterreleasebuttonae-l' => { 197 => '17.7', 199 => '16.1', 200 => '7.1', 201 => '17.5', 203 => '18.2' },
-	'shutterreleasemethod' => { 72 => 0x1010 },
-	'shutterreleasenocfcard' => { 57 => 0x2, 58 => 0x2, 65 => 0xf },
-	'shutterreleasetiming' => { 72 => 0x1011 },
-	'shutterspeedrange' => { 59 => 0x10c },
-	'shutterspeedvalue' => { 68 => 0x1, 85 => 0x9201, 209 => 0x1000, 292 => 'ShutterSpeedValue' },
-	'sidecarforextension' => { 299 => 'SidecarForExtension' },
-	'similarityindex' => { 92 => 0xe4 },
-	'singleframebracketing' => { 134 => 0x21 },
-	'slaveflashmeteringsegments' => { 247 => 0x20b },
-	'slowshutter' => { 54 => 0x8 },
-	'slowsync' => { 89 => 0x1030 },
-	'smartrange' => { 267 => 0xa012 },
-	'smoothness' => { 85 => 0xfe57, 288 => 'Smoothness' },
-	'software' => { 85 => 0x131, 114 => 'Software', 215 => 'Software', 270 => 0x18, 306 => 'Software' },
-	'softwareversion' => { 269 => 0x207 },
-	'sonydatetime' => { 278 => 0x6 },
-	'sonyimagesize' => { 134 => 0x3b, 271 => 0x54, 272 => 0x54 },
-	'sonymodelid' => { 276 => 0xb001 },
-	'sonyquality' => { 134 => 0x3c },
-	'source' => { 92 => 0x73, 215 => 'Source', 289 => 'source', 290 => 'source', 299 => 'Source' },
-	'sourcedirectoryindex' => { 238 => 0x0 },
-	'sourcefileindex' => { 238 => 0x2 },
-	'spatialfrequencyresponse' => { 292 => 'SpatialFrequencyResponse' },
-	'spatialfrequencyresponsecolumns' => { 292 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseColumns'] },
-	'spatialfrequencyresponsenames' => { 292 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseNames'] },
-	'spatialfrequencyresponserows' => { 292 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseRows'] },
-	'spatialfrequencyresponsevalues' => { 292 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseValues'] },
-	'speakerplacement' => { 310 => 'speakerPlacement' },
-	'specialeffectlevel' => { 82 => 0x3030 },
-	'specialeffectmode' => { 82 => 0x2076 },
-	'specialeffectsetting' => { 82 => 0x3031 },
-	'specialinstructions' => { 92 => 0x28 },
-	'specialmode' => { 209 => 0x200, 269 => 0x200 },
-	'spectralsensitivity' => { 85 => 0x8824, 292 => 'SpectralSensitivity' },
-	'splittoningbalance' => { 288 => 'SplitToningBalance' },
-	'splittoninghighlighthue' => { 288 => 'SplitToningHighlightHue' },
-	'splittoninghighlightsaturation' => { 288 => 'SplitToningHighlightSaturation' },
-	'splittoningshadowhue' => { 288 => 'SplitToningShadowHue' },
-	'splittoningshadowsaturation' => { 288 => 'SplitToningShadowSaturation' },
-	'spotfocuspointx' => { 131 => 0x2d },
-	'spotfocuspointy' => { 131 => 0x2e },
-	'spotmeteringmode' => { 24 => 0x27 },
-	'spotmeterlinktoafpoint' => { 59 => 0x107 },
-	'sractive' => { 232 => '17.1' },
-	'srawquality' => { 24 => 0x2e },
-	'srfocallength' => { 248 => 0x3 },
-	'srhalfpresstime' => { 248 => 0x2 },
-	'srresult' => { 248 => 0x0 },
-	'standardoutputhighlightpoint' => { 78 => 0x14 },
-	'standardoutputsensitivity' => { 85 => 0x8831 },
-	'standardoutputshadowpoint' => { 78 => 0x15 },
-	'standardrawcolortone' => { 78 => 0xd },
-	'standardrawcontrast' => { 78 => 0xf },
-	'standardrawhighlight' => { 78 => 0x75 },
-	'standardrawhighlightpoint' => { 78 => 0x12 },
-	'standardrawlinear' => { 78 => 0x10 },
-	'standardrawsaturation' => { 78 => 0xe },
-	'standardrawshadow' => { 78 => 0x7e },
-	'standardrawshadowpoint' => { 78 => 0x13 },
-	'standardrawsharpness' => { 78 => 0x11 },
-	'startingpage' => { 301 => 'startingPage' },
-	'startmovieshooting' => { 59 => 0x70d },
-	'starttimecode' => { 310 => 'startTimecode' },
-	'starttimecodetimeformat' => { 310 => [\'startTimecode','startTimecodeTimeFormat'] },
-	'starttimecodetimevalue' => { 310 => [\'startTimecode','startTimecodeTimeValue'] },
-	'starttimecodevalue' => { 310 => [\'startTimecode','startTimecodeValue'] },
-	'state' => { 118 => 'State', 224 => 0x6b, 299 => 'State' },
-	'status' => { 283 => 'Status' },
-	'storagemethod' => { 137 => 0x12 },
-	'straightenangle' => { 190 => 0x2fc08431 },
-	'stretchmode' => { 310 => 'stretchMode' },
-	'studydatetime' => { 281 => 'StudyDateTime' },
-	'studydescription' => { 281 => 'StudyDescription' },
-	'studyid' => { 281 => 'StudyID' },
-	'studyphysician' => { 281 => 'StudyPhysician' },
-	'sub-location' => { 92 => 0x5c },
-	'subfiledata' => { 121 => 'data' },
-	'subfiledirectory' => { 121 => '1Directory' },
-	'subfilemimetype' => { 121 => '2MIME' },
-	'subfilename' => { 121 => '1Name' },
-	'subfileresource' => { 121 => 'rsrc' },
-	'subfiletype' => { 85 => 0xfe, 121 => '0Type' },
-	'subject' => { 213 => 'Subject', 258 => 'Subject', 289 => 'subject', 298 => 'Subject' },
-	'subjectarea' => { 85 => 0x9214, 292 => 'SubjectArea' },
-	'subjectcode' => { 293 => 'SubjectCode' },
-	'subjectdistance' => { 85 => 0x9206, 99 => 0x3e, 292 => 'SubjectDistance' },
-	'subjectdistancerange' => { 85 => 0xa40c, 292 => 'SubjectDistanceRange' },
-	'subjectlocation' => { 85 => 0xa214, 292 => 'SubjectLocation' },
-	'subjectprogram' => { 131 => 0x22 },
-	'subjectreference' => { 92 => 0xc },
-	'subsectime' => { 85 => 0x9290 },
-	'subsectimedigitized' => { 85 => 0x9292 },
-	'subsectimeoriginal' => { 85 => 0x9291 },
-	'subsection1' => { 301 => 'subsection1' },
-	'subsection2' => { 301 => 'subsection2' },
-	'subsection3' => { 301 => 'subsection3' },
-	'subsection4' => { 301 => 'subsection4' },
-	'superimposeddisplay' => { 57 => 0xa, 59 => 0x510, 60 => 0x9, 61 => 0xa, 64 => 0xa, 65 => 0xe },
-	'supermacro' => { 43 => 0x1a },
-	'supplementalcategories' => { 92 => 0x14, 299 => 'SupplementalCategories' },
-	'supplementaltype' => { 94 => 0x37 },
-	'svisosetting' => { 232 => 0x14 },
-	'switchtoregisteredafpoint' => { 58 => 0x12, 59 => 0x50a },
-	'tagged' => { 253 => 0xdd, 284 => 'tagged' },
-	'tagslist' => { 291 => 'TagsList' },
-	'takenumber' => { 310 => 'takeNumber' },
-	'tapename' => { 310 => 'tapeName' },
-	'targetaperture' => { 54 => 0x4 },
-	'targetcompressionratio' => { 70 => 0x1 },
-	'targetdistancesetting' => { 72 => 0x1807 },
-	'targetexposuretime' => { 54 => 0x5 },
-	'targetimagetype' => { 72 => 0x100a },
-	'teaser' => { 301 => 'teaser' },
-	'teleconverter' => { 135 => 0x105, 276 => 0x105 },
-	'tempo' => { 310 => 'tempo' },
-	'termsandconditionstext' => { 300 => 'TermsAndConditionsText' },
-	'termsandconditionsurl' => { 300 => 'TermsAndConditionsURL' },
-	'textlayername' => { 299 => [\'TextLayers','TextLayersLayerName'] },
-	'textlayers' => { 299 => 'TextLayers' },
-	'textlayertext' => { 299 => [\'TextLayers','TextLayersLayerText'] },
-	'textstamp' => { 224 => [0x8008,0x8009,0x3b,0x3e] },
-	'thresholding' => { 85 => 0x107 },
-	'thumbnailfilename' => { 72 => 0x817 },
-	'thumbnailformat' => { 308 => [\'Thumbnails','ThumbnailsFormat'] },
-	'thumbnailheight' => { 101 => 0xfa55, 308 => [\'Thumbnails','ThumbnailsHeight'] },
-	'thumbnailimage' => { 72 => 0x2008, 83 => 'ThumbnailImage', 87 => 0x3, 124 => 'data', 209 => 0x100, 308 => [\'Thumbnails','ThumbnailsImage'] },
-	'thumbnailimagename' => { 124 => '1Name' },
-	'thumbnailimagesize' => { 124 => 'ImageSize' },
-	'thumbnailimagetype' => { 124 => '0Type' },
-	'thumbnailimagevalidarea' => { 43 => 0x13 },
-	'thumbnaillength' => { 85 => 0x202 },
-	'thumbnailoffset' => { 85 => 0x201 },
-	'thumbnails' => { 308 => 'Thumbnails' },
-	'thumbnailwidth' => { 101 => 0xfa54, 308 => [\'Thumbnails','ThumbnailsWidth'] },
-	'ticker' => { 301 => 'ticker' },
-	'tilelength' => { 85 => 0x143 },
-	'tilewidth' => { 85 => 0x142 },
-	'time' => { 97 => 0x401, 247 => 0x7 },
-	'timecreated' => { 92 => 0x3c, 99 => 0x14, 108 => 0x10, 254 => 'TimeCreated' },
-	'timeperiod' => { 301 => 'timePeriod' },
-	'timerfunctionbutton' => { 198 => '5.2', 199 => '12.1' },
-	'timerlength' => { 59 => 0x80c },
-	'timescaleparams' => { 310 => 'timeScaleParams' },
-	'timescaleparamsframeoverlappingpercentage' => { 310 => [\'timeScaleParams','timeScaleParamsFrameOverlappingPercentage'] },
-	'timescaleparamsframesize' => { 310 => [\'timeScaleParams','timeScaleParamsFrameSize'] },
-	'timescaleparamsquality' => { 310 => [\'timeScaleParams','timeScaleParamsQuality'] },
-	'timesent' => { 93 => 0x50 },
-	'timesignature' => { 310 => 'timeSignature' },
-	'timesincepoweron' => { 224 => 0x29 },
-	'timestamp' => { 7 => 0x45e, 15 => 0x11c, 215 => 'TimeStamp' },
-	'timestamp1' => { 7 => 0x45a },
-	'timezone' => { 182 => 0x0 },
-	'timezonecode' => { 75 => 0x1 },
-	'timezoneinfo' => { 75 => 0x2 },
-	'timezoneoffset' => { 85 => 0x882a },
-	'tint' => { 288 => 'Tint' },
-	'title' => { 114 => 'Title', 213 => 'Title', 215 => 'Title', 224 => 0x65, 258 => 'Title', 289 => 'title', 298 => 'Title' },
-	'tonecomp' => { 160 => 0x81 },
-	'tonecurve' => { 52 => 0x1, 247 => 0x402, 288 => 'ToneCurve' },
-	'tonecurve1' => { 267 => 0xa040 },
-	'tonecurve2' => { 267 => 0xa041 },
-	'tonecurve3' => { 267 => 0xa042 },
-	'tonecurve4' => { 267 => 0xa043 },
-	'tonecurveactive' => { 77 => 0x110 },
-	'tonecurvebluex' => { 279 => 0x9003 },
-	'tonecurvebluey' => { 279 => 0x9007 },
-	'tonecurvebrightnessx' => { 279 => 0x9000 },
-	'tonecurvebrightnessy' => { 279 => 0x9004 },
-	'tonecurvefilename' => { 97 => 0x1391 },
-	'tonecurvegreenx' => { 279 => 0x9002 },
-	'tonecurvegreeny' => { 279 => 0x9006 },
-	'tonecurveinterpolation' => { 77 => 0x159 },
-	'tonecurvemode' => { 77 => 0x113 },
-	'tonecurvename' => { 288 => 'ToneCurveName' },
-	'tonecurveproperty' => { 77 => 0x3c },
-	'tonecurveredx' => { 279 => 0x9001 },
-	'tonecurveredy' => { 279 => 0x9005 },
-	'tonecurves' => { 247 => 0x403 },
-	'toningeffect' => { 38 => 0xf, 160 => 0xb3, 162 => 0x38 },
-	'toningeffectfaithful' => { 48 => 0x74, 49 => 0x74 },
-	'toningeffectlandscape' => { 48 => 0x44, 49 => 0x44 },
-	'toningeffectmonochrome' => { 15 => 0x108, 48 => 0x8c, 49 => 0x8c },
-	'toningeffectneutral' => { 48 => 0x5c, 49 => 0x5c },
-	'toningeffectportrait' => { 48 => 0x2c, 49 => 0x2c },
-	'toningeffectstandard' => { 48 => 0x14, 49 => 0x14 },
-	'toningeffectunknown' => { 49 => 0xa4 },
-	'toningeffectuserdef1' => { 48 => 0xa4, 49 => 0xbc },
-	'toningeffectuserdef2' => { 48 => 0xbc, 49 => 0xd4 },
-	'toningeffectuserdef3' => { 48 => 0xd4, 49 => 0xec },
-	'toningsaturation' => { 162 => 0x39 },
-	'totalzoom' => { 99 => 0x62 },
-	'tracknumber' => { 310 => 'trackNumber' },
-	'tracks' => { 310 => 'Tracks' },
-	'tracksframerate' => { 310 => [\'Tracks','TracksFrameRate'] },
-	'tracksmarkers' => { 310 => [\'Tracks','TracksMarkers'] },
-	'tracksmarkerscomment' => { 310 => [\'Tracks','TracksMarkersComment'] },
-	'tracksmarkerscuepointparams' => { 310 => [\'Tracks','TracksMarkersCuePointParams'] },
-	'tracksmarkerscuepointparamskey' => { 310 => [\'Tracks','TracksMarkersCuePointParamsKey'] },
-	'tracksmarkerscuepointparamsvalue' => { 310 => [\'Tracks','TracksMarkersCuePointParamsValue'] },
-	'tracksmarkerscuepointtype' => { 310 => [\'Tracks','TracksMarkersCuePointType'] },
-	'tracksmarkersduration' => { 310 => [\'Tracks','TracksMarkersDuration'] },
-	'tracksmarkerslocation' => { 310 => [\'Tracks','TracksMarkersLocation'] },
-	'tracksmarkersname' => { 310 => [\'Tracks','TracksMarkersName'] },
-	'tracksmarkersprobability' => { 310 => [\'Tracks','TracksMarkersProbability'] },
-	'tracksmarkersspeaker' => { 310 => [\'Tracks','TracksMarkersSpeaker'] },
-	'tracksmarkersstarttime' => { 310 => [\'Tracks','TracksMarkersStartTime'] },
-	'tracksmarkerstarget' => { 310 => [\'Tracks','TracksMarkersTarget'] },
-	'tracksmarkerstype' => { 310 => [\'Tracks','TracksMarkersType'] },
-	'trackstrackname' => { 310 => [\'Tracks','TracksTrackName'] },
-	'trackstracktype' => { 310 => [\'Tracks','TracksTrackType'] },
-	'trailersignature' => { 121 => 'zmie' },
-	'transferfunction' => { 85 => 0x12d, 306 => 'TransferFunction' },
-	'transform' => { 224 => [0x8012,0x59] },
-	'transmissionreference' => { 299 => 'TransmissionReference' },
-	'trapped' => { 213 => 'Trapped', 298 => 'Trapped' },
-	'travelday' => { 224 => 0x36 },
-	'triggermode' => { 259 => 0x6 },
-	'ttl_da_adown' => { 239 => 0x5 },
-	'ttl_da_aup' => { 239 => 0x4 },
-	'ttl_da_bdown' => { 239 => 0x7 },
-	'ttl_da_bup' => { 239 => 0x6 },
-	'tungstenawb' => { 229 => 0x1 },
-	'tvexposuretimesetting' => { 232 => 0x12 },
-	'type' => { 289 => 'type', 305 => 'type' },
-	'uniquecameramodel' => { 85 => 0xc614 },
-	'uniquedocumentid' => { 92 => 0xbb },
-	'uniqueobjectname' => { 93 => 0x64 },
-	'unknownblock' => { 208 => 0x1103 },
-	'unknowncontrast' => { 78 => 0x45 },
-	'unknownev' => { 97 => 0x1 },
-	'unknownlinear' => { 78 => 0x46 },
-	'unknownmode' => { 82 => 0x301b },
-	'unknownnumber' => { 72 => 0x180b },
-	'unknownoutputhighlightpoint' => { 78 => 0x4a },
-	'unknownoutputshadowpoint' => { 78 => 0x4b },
-	'unknownrawhighlight' => { 78 => 0x7b },
-	'unknownrawhighlightpoint' => { 78 => 0x48 },
-	'unknownrawshadow' => { 78 => 0x84 },
-	'unknownrawshadowpoint' => { 78 => 0x49 },
-	'unknownsharpness' => { 78 => 0x47 },
-	'unsharp1color' => { 195 => 0x13 },
-	'unsharp1halowidth' => { 195 => 0x19 },
-	'unsharp1intensity' => { 195 => 0x17 },
-	'unsharp1threshold' => { 195 => 0x1b },
-	'unsharp2color' => { 195 => 0x2e },
-	'unsharp2halowidth' => { 195 => 0x34 },
-	'unsharp2intensity' => { 195 => 0x32 },
-	'unsharp2threshold' => { 195 => 0x36 },
-	'unsharp3color' => { 195 => 0x49 },
-	'unsharp3halowidth' => { 195 => 0x4f },
-	'unsharp3intensity' => { 195 => 0x4d },
-	'unsharp3threshold' => { 195 => 0x51 },
-	'unsharp4color' => { 195 => 0x64 },
-	'unsharp4halowidth' => { 195 => 0x6a },
-	'unsharp4intensity' => { 195 => 0x68 },
-	'unsharp4threshold' => { 195 => 0x6c },
-	'unsharpcount' => { 195 => 0x0 },
-	'unsharpmask' => { 78 => 0x90, 190 => 0x76a43200 },
-	'unsharpmaskfineness' => { 78 => 0x94 },
-	'unsharpmaskstrength' => { 78 => 0x92 },
-	'unsharpmaskthreshold' => { 78 => 0x96 },
-	'urgency' => { 92 => 0xa, 299 => 'Urgency' },
-	'url' => { 114 => 'URL', 215 => 'URL', 256 => 0x40b, 301 => 'url' },
-	'usablemeteringmodes' => { 59 => 0x10a },
-	'usableshootingmodes' => { 59 => 0x109 },
-	'usage' => { 302 => 'usage' },
-	'usagefee' => { 303 => 'usageFee' },
-	'usageterms' => { 314 => 'UsageTerms' },
-	'usercomment' => { 72 => 0x805, 85 => 0x9286, 292 => 'UserComment' },
-	'userdef1picturestyle' => { 15 => 0x10c, 48 => 0xd8, 49 => 0xf0 },
-	'userdef2picturestyle' => { 15 => 0x10e, 48 => 0xda, 49 => 0xf2 },
-	'userdef3picturestyle' => { 15 => 0x110, 48 => 0xdc, 49 => 0xf4 },
-	'userfields' => { 283 => 'UserFields' },
-	'userlabel' => { 259 => 0x2b },
-	'userprofile' => { 219 => 0x302, 225 => 0x3038 },
-	'usmlenselectronicmf' => { 58 => 0x7, 59 => 0x501 },
-	'utmeasting' => { 125 => 'Easting' },
-	'utmmapdatum' => { 125 => 'Datum' },
-	'utmnorthing' => { 125 => 'Northing' },
-	'utmzone' => { 125 => 'Zone' },
-	'uv-irfiltercorrection' => { 219 => 0x325 },
-	'validbits' => { 208 => 0x611, 209 => 0x102c },
-	'validpixeldepth' => { 212 => 0x611 },
-	'variousmodes' => { 99 => 0x26 },
-	'variousmodes2' => { 99 => 0x3a },
-	'variprogram' => { 160 => 0xab },
-	'version' => { 89 => 0x0, 258 => 'Version', 288 => 'Version' },
-	'versioncreatedate' => { 279 => 0xd100 },
-	'versionid' => { 311 => 'VersionID' },
-	'versionidentifier' => { 301 => 'versionIdentifier' },
-	'versionmodifydate' => { 279 => 0xd101 },
-	'versions' => { 311 => 'Versions' },
-	'versionscomments' => { 311 => [\'Versions','VersionsComments'] },
-	'versionsevent' => { 311 => [\'Versions','VersionsEvent'] },
-	'versionseventaction' => { 311 => [\'Versions','VersionsEventAction'] },
-	'versionseventchanged' => { 311 => [\'Versions','VersionsEventChanged'] },
-	'versionseventinstanceid' => { 311 => [\'Versions','VersionsEventInstanceID'] },
-	'versionseventparameters' => { 311 => [\'Versions','VersionsEventParameters'] },
-	'versionseventsoftwareagent' => { 311 => [\'Versions','VersionsEventSoftwareAgent'] },
-	'versionseventwhen' => { 311 => [\'Versions','VersionsEventWhen'] },
-	'versionsmodifier' => { 311 => [\'Versions','VersionsModifier'] },
-	'versionsmodifydate' => { 311 => [\'Versions','VersionsModifyDate'] },
-	'versionsversion' => { 311 => [\'Versions','VersionsVersion'] },
-	'verticalafonbutton' => { 197 => '3.2' },
-	'vfdisplayillumination' => { 59 => 0x510 },
-	'vibrance' => { 288 => 'Vibrance' },
-	'vibrationreduction' => { 166 => [0x75,0x82,0x1ae], 174 => '586.1', 178 => '590.2', 181 => 0x4 },
-	'videoalphamode' => { 310 => 'videoAlphaMode' },
-	'videoalphapremultiplecolor' => { 310 => 'videoAlphaPremultipleColor' },
-	'videoalphapremultiplecolora' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorA'] },
-	'videoalphapremultiplecolorb' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorB'] },
-	'videoalphapremultiplecolorblack' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlack'] },
-	'videoalphapremultiplecolorblue' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlue'] },
-	'videoalphapremultiplecolorcyan' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorCyan'] },
-	'videoalphapremultiplecolorgreen' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorGreen'] },
-	'videoalphapremultiplecolorl' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorL'] },
-	'videoalphapremultiplecolormagenta' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMagenta'] },
-	'videoalphapremultiplecolormode' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMode'] },
-	'videoalphapremultiplecolorred' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorRed'] },
-	'videoalphapremultiplecolorswatchname' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorSwatchName'] },
-	'videoalphapremultiplecolortype' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorType'] },
-	'videoalphapremultiplecoloryellow' => { 310 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorYellow'] },
-	'videoalphaunityistransparent' => { 310 => 'videoAlphaUnityIsTransparent' },
-	'videocodec' => { 46 => 0x74 },
-	'videocolorspace' => { 310 => 'videoColorSpace' },
-	'videocompressor' => { 310 => 'videoCompressor' },
-	'videofieldorder' => { 310 => 'videoFieldOrder' },
-	'videoframerate' => { 310 => 'videoFrameRate' },
-	'videoframesize' => { 310 => 'videoFrameSize' },
-	'videoframesizeh' => { 310 => [\'videoFrameSize','videoFrameSizeH'] },
-	'videoframesizeunit' => { 310 => [\'videoFrameSize','videoFrameSizeUnit'] },
-	'videoframesizew' => { 310 => [\'videoFrameSize','videoFrameSizeW'] },
-	'videomoddate' => { 310 => 'videoModDate' },
-	'videopixelaspectratio' => { 310 => 'videoPixelAspectRatio' },
-	'videopixeldepth' => { 310 => 'videoPixelDepth' },
-	'videoquality' => { 82 => 0x4003 },
-	'viewfinderdisplay' => { 197 => '12.4' },
-	'viewfinderwarning' => { 197 => '13.4', 201 => '3.5', 202 => '6.2', 203 => '4.4' },
-	'viewinfoduringexposure' => { 59 => 0x407 },
-	'vignetteamount' => { 288 => 'VignetteAmount' },
-	'vignettecontrol' => { 160 => 0x2a, 190 => 0x76a43205 },
-	'vignettecontrolintensity' => { 190 => 0xac6bd5c0 },
-	'vignettemidpoint' => { 288 => 'VignetteMidpoint' },
-	'voicememo' => { 269 => 0x216 },
-	'volume' => { 301 => 'volume' },
-	'vr_0x66' => { 166 => 0x66 },
-	'vrdoffset' => { 43 => 0xd0 },
-	'wb_bluepresetsfluorescent' => { 136 => 0x40a },
-	'wb_gbrglevels' => { 136 => 0xae, 139 => 0x4 },
-	'wb_glevel' => { 208 => 0x11f },
-	'wb_glevel3000k' => { 208 => 0x113 },
-	'wb_glevel3300k' => { 208 => 0x114 },
-	'wb_glevel3600k' => { 208 => 0x115 },
-	'wb_glevel3900k' => { 208 => 0x116 },
-	'wb_glevel4000k' => { 208 => 0x117 },
-	'wb_glevel4300k' => { 208 => 0x118 },
-	'wb_glevel4500k' => { 208 => 0x119 },
-	'wb_glevel4800k' => { 208 => 0x11a },
-	'wb_glevel5300k' => { 208 => 0x11b },
-	'wb_glevel6000k' => { 208 => 0x11c },
-	'wb_glevel6600k' => { 208 => 0x11d },
-	'wb_glevel7500k' => { 208 => 0x11e },
-	'wb_grbglevels' => { 147 => 0x0 },
-	'wb_rbgglevels' => { 144 => 0x0 },
-	'wb_rblevels' => { 160 => 0xc, 208 => 0x100 },
-	'wb_rblevels3000k' => { 208 => 0x102 },
-	'wb_rblevels3300k' => { 208 => 0x103 },
-	'wb_rblevels3600k' => { 208 => 0x104 },
-	'wb_rblevels3900k' => { 208 => 0x105 },
-	'wb_rblevels4000k' => { 208 => 0x106 },
-	'wb_rblevels4300k' => { 208 => 0x107 },
-	'wb_rblevels4500k' => { 208 => 0x108 },
-	'wb_rblevels4800k' => { 208 => 0x109 },
-	'wb_rblevels5300k' => { 208 => 0x10a },
-	'wb_rblevels6000k' => { 208 => 0x10b },
-	'wb_rblevels6600k' => { 208 => 0x10c },
-	'wb_rblevels7500k' => { 208 => 0x10d },
-	'wb_rblevelsauto' => { 212 => 0x110 },
-	'wb_rblevelscloudy' => { 138 => 0x10, 212 => 0x121 },
-	'wb_rblevelscoolwhitef' => { 138 => 0x14 },
-	'wb_rblevelscoolwhitefluor' => { 212 => 0x132 },
-	'wb_rblevelscwb1' => { 208 => 0x10e },
-	'wb_rblevelscwb2' => { 208 => 0x10f },
-	'wb_rblevelscwb3' => { 208 => 0x110 },
-	'wb_rblevelscwb4' => { 208 => 0x111 },
-	'wb_rblevelsdaylight' => { 138 => 0xc },
-	'wb_rblevelsdaylightf' => { 138 => 0x24 },
-	'wb_rblevelsdaylightfluor' => { 212 => 0x130 },
-	'wb_rblevelsdaywhitef' => { 138 => 0x28 },
-	'wb_rblevelsdaywhitefluor' => { 212 => 0x131 },
-	'wb_rblevelseveningsunlight' => { 212 => 0x124 },
-	'wb_rblevelsfineweather' => { 212 => 0x122 },
-	'wb_rblevelsflash' => { 138 => 0x18 },
-	'wb_rblevelsshade' => { 138 => 0x20, 212 => 0x120 },
-	'wb_rblevelstungsten' => { 138 => 0x8, 212 => 0x123 },
-	'wb_rblevelsunknown' => { 138 => 0x1c },
-	'wb_rblevelsused' => { 212 => 0x100 },
-	'wb_rblevelswhitef' => { 138 => 0x2c },
-	'wb_rblevelswhitefluorescent' => { 212 => 0x133 },
-	'wb_rbpresetcloudy' => { 136 => 0x3f0 },
-	'wb_rbpresetcoolwhitef' => { 136 => 0x308 },
-	'wb_rbpresetcustom' => { 136 => 0x424 },
-	'wb_rbpresetdaylight' => { 136 => 0x3ec },
-	'wb_rbpresetflash' => { 136 => [0x3f4,0x304] },
-	'wb_rbpresetshade' => { 136 => 0x418 },
-	'wb_rbpresettungsten' => { 136 => 0x3e8 },
-	'wb_redpresetsfluorescent' => { 136 => 0x3fc },
-	'wb_rgbglevels' => { 146 => 0x0 },
-	'wb_rgblevels' => { 136 => 0x96, 220 => 0xd, 221 => 0x413, 225 => 0x3036 },
-	'wb_rggblevels' => { 139 => 0x4, 145 => 0x0 },
-	'wb_rggblevelsasshot' => { 27 => 0x0, 28 => 0x19, 29 => 0x22, 30 => 0x3f, 33 => 0x3f },
-	'wb_rggblevelsauto' => { 25 => 0x0, 27 => 0x5, 28 => 0x1e, 29 => 0x18, 30 => 0x44, 33 => 0x44, 267 => 0xa022 },
-	'wb_rggblevelsblack' => { 267 => 0xa028 },
-	'wb_rggblevelscloudy' => { 25 => 0xc, 27 => 0x1e, 28 => 0x2d, 29 => 0x31, 30 => 0x58, 33 => 0x71, 247 => 0x20f },
-	'wb_rggblevelscustom' => { 25 => 0x1c, 30 => 0x80 },
-	'wb_rggblevelscustom1' => { 28 => 0x41 },
-	'wb_rggblevelscustom2' => { 28 => 0x46 },
-	'wb_rggblevelsdaylight' => { 25 => 0x4, 27 => 0x14, 28 => 0x23, 29 => 0x27, 30 => 0x4e, 33 => 0x67, 247 => 0x20d },
-	'wb_rggblevelsflash' => { 25 => 0x18, 27 => 0x32, 28 => 0x3c, 29 => 0x45, 30 => 0x6c, 33 => 0x85, 247 => 0x214 },
-	'wb_rggblevelsfluorescent' => { 25 => 0x14, 27 => 0x28, 28 => 0x37, 29 => 0x3b, 30 => 0x62, 33 => 0x7b },
-	'wb_rggblevelsfluorescentd' => { 247 => 0x211 },
-	'wb_rggblevelsfluorescentn' => { 247 => 0x212 },
-	'wb_rggblevelsfluorescentw' => { 247 => 0x213 },
-	'wb_rggblevelsilluminator1' => { 267 => 0xa023 },
-	'wb_rggblevelsilluminator2' => { 267 => 0xa024 },
-	'wb_rggblevelskelvin' => { 25 => 0x20, 27 => 0x2d, 29 => 0x40, 30 => 0x67, 33 => 0x80 },
-	'wb_rggblevelsmeasured' => { 27 => 0xa, 30 => 0x49, 33 => 0x49 },
-	'wb_rggblevelspc1' => { 29 => 0x90, 30 => 0x71 },
-	'wb_rggblevelspc2' => { 29 => 0x95, 30 => 0x76 },
-	'wb_rggblevelspc3' => { 29 => 0x9a, 30 => 0x7b },
-	'wb_rggblevelsshade' => { 25 => 0x8, 27 => 0x19, 28 => 0x28, 29 => 0x2c, 30 => 0x53, 33 => 0x6c, 247 => 0x20e },
-	'wb_rggblevelstungsten' => { 25 => 0x10, 27 => 0x23, 28 => 0x32, 29 => 0x36, 30 => 0x5d, 33 => 0x76, 247 => 0x210 },
-	'wb_rggblevelsuncorrected' => { 267 => 0xa021 },
-	'wb_rggblevelsunknown' => { 27 => 0xf, 29 => 0x1d, 33 => 0x4e },
-	'wb_rggblevelsunknown10' => { 27 => 0x5f, 29 => 0x72, 33 => 0x9e },
-	'wb_rggblevelsunknown11' => { 27 => 0x64, 29 => 0x77, 33 => 0xa3 },
-	'wb_rggblevelsunknown12' => { 27 => 0x69, 29 => 0x7c, 33 => 0xa8 },
-	'wb_rggblevelsunknown13' => { 27 => 0x6e, 29 => 0x81, 33 => 0xad },
-	'wb_rggblevelsunknown14' => { 29 => 0x86, 33 => 0xb2 },
-	'wb_rggblevelsunknown15' => { 29 => 0x8b, 33 => 0xb7 },
-	'wb_rggblevelsunknown16' => { 29 => 0x9f },
-	'wb_rggblevelsunknown2' => { 27 => 0x37, 29 => 0x4a, 33 => 0x53 },
-	'wb_rggblevelsunknown3' => { 27 => 0x3c, 29 => 0x4f, 33 => 0x58 },
-	'wb_rggblevelsunknown4' => { 27 => 0x41, 29 => 0x54, 33 => 0x5d },
-	'wb_rggblevelsunknown5' => { 27 => 0x46, 29 => 0x59, 33 => 0x62 },
-	'wb_rggblevelsunknown6' => { 27 => 0x4b, 29 => 0x5e, 33 => 0x8a },
-	'wb_rggblevelsunknown7' => { 27 => 0x50, 29 => 0x63, 33 => 0x8f },
-	'wb_rggblevelsunknown8' => { 27 => 0x55, 29 => 0x68, 33 => 0x94 },
-	'wb_rggblevelsunknown9' => { 27 => 0x5a, 29 => 0x6d, 33 => 0x99 },
-	'wbadjbluebalance' => { 196 => 0x8 },
-	'wbadjcolortemp' => { 77 => 0x1a },
-	'wbadjlighting' => { 196 => 0x15 },
-	'wbadjlightingsubtype' => { 196 => 0x14 },
-	'wbadjmode' => { 196 => 0x10 },
-	'wbadjredbalance' => { 196 => 0x0 },
-	'wbadjrgblevels' => { 77 => 0x8 },
-	'wbadjtemperature' => { 196 => 0x18 },
-	'wbadjtint' => { 196 => 0x25 },
-	'wbadjustab' => { 224 => 0x46 },
-	'wbadjustgm' => { 224 => 0x47 },
-	'wbbluelevel' => { 219 => 0x324, 224 => 0x8006, 226 => 0x26 },
-	'wbbracketmode' => { 38 => 0x9 },
-	'wbbracketvalueab' => { 38 => 0xc },
-	'wbbracketvaluegm' => { 38 => 0xd },
-	'wbfinetuneactive' => { 77 => 0x24 },
-	'wbfinetunesaturation' => { 77 => 0x28 },
-	'wbfinetunetone' => { 77 => 0x2c },
-	'wbgreenlevel' => { 219 => 0x323, 224 => 0x8005, 226 => 0x25 },
-	'wbmediaimagesizesetting' => { 59 => 0x708 },
-	'wbmode' => { 138 => 0x4, 209 => 0x1015 },
-	'wbredlevel' => { 219 => 0x322, 224 => 0x8004, 226 => 0x24 },
-	'wbscale' => { 139 => 0x0 },
-	'wbshiftab' => { 52 => 0xc, 233 => 0x10 },
-	'wbshiftgm' => { 52 => 0xd },
-	'wbshiftmg' => { 233 => 0x11 },
-	'webstatement' => { 314 => 'WebStatement' },
-	'whitebalance' => { 4 => 0x6f, 5 => [0x44,0x4a], 6 => 0x36, 7 => 0x5e, 8 => 0x36, 9 => [0x77,0x78], 10 => 0x6f, 11 => 0x6f, 12 => 0x73, 13 => 0x6f, 14 => 0x78, 15 => 0x54, 16 => 0x6f, 20 => 0x53, 52 => 0x8, 54 => 0x7, 81 => 0x7, 82 => [0x19,0x2012], 85 => [0xa403,0xfe4e], 89 => 0x1002, 97 => 0x3fc, 98 => 0xfa0d, 99 => 0x40, 131 => 0x3, 132 => 0xe, 133 => 0x4, 134 => 0xb, 135 => 0x115, 160 => 0x5, 180 => 0x7, 219 => 0x304, 224 => 0x3, 225 => 0x3033, 247 => 0x19, 252 => 0x7, 262 => 0x26, 270 => [0x3c,0x7], 276 => [0x115,0xb054], 288 => 'WhiteBalance', 292 => 'WhiteBalance' },
-	'whitebalance2' => { 204 => 0x500 },
-	'whitebalanceadj' => { 77 => 0x18, 190 => 0x76a43204 },
-	'whitebalanceautoadjustment' => { 229 => 0x0 },
-	'whitebalancebias' => { 82 => 0x2011, 209 => 0x304, 224 => 0x23 },
-	'whitebalanceblue' => { 52 => 0x7 },
-	'whitebalancebracket' => { 204 => 0x502, 209 => 0x303 },
-	'whitebalancebracketing' => { 134 => 0x22 },
-	'whitebalancecomp' => { 212 => 0x1001 },
-	'whitebalancefinetune' => { 89 => 0x100a, 134 => 0x38, 135 => 0x112, 160 => 0xb, 271 => 0x6, 276 => 0x112 },
-	'whitebalancemode' => { 247 => 0x1a },
-	'whitebalancered' => { 52 => 0x6 },
-	'whitebalanceset' => { 232 => 0xa },
-	'whitebalancesetting' => { 134 => 0x23 },
-	'whitebalancetemperature' => { 204 => 0x501 },
-	'whiteboard' => { 209 => 0x301 },
-	'whitelevel' => { 85 => 0xc61d },
-	'whitepoint' => { 85 => 0x13e, 247 => 0x201, 306 => 'WhitePoint' },
-	'widefocuszone' => { 131 => 0x2f },
-	'widerange' => { 269 => 0x20f },
-	'wordcount' => { 301 => 'wordCount' },
-	'workcolorspace' => { 77 => 0x270 },
-	'worldtimelocation' => { 224 => 0x3a, 247 => 0x22, 251 => '0.1' },
-	'writer-editor' => { 92 => 0x7a },
-	'x3filllight' => { 270 => 0x12 },
-	'xmp' => { 76 => 0xffff00f6, 86 => 'XMP' },
-	'xmptoolkit' => { 307 => 'xmptk' },
-	'xpauthor' => { 85 => 0x9c9d },
-	'xpcomment' => { 85 => 0x9c9c },
-	'xpkeywords' => { 85 => 0x9c9e },
-	'xposition' => { 85 => 0x11e },
-	'xpsubject' => { 85 => 0x9c9f },
-	'xptitle' => { 85 => 0x9c9b },
-	'xresolution' => { 85 => 0x11a, 95 => 0x3, 257 => 0x0, 306 => 'XResolution' },
-	'xyresolution' => { 88 => 0x3 },
-	'ycbcrcoefficients' => { 85 => 0x211, 306 => 'YCbCrCoefficients' },
-	'ycbcrpositioning' => { 85 => 0x213, 306 => 'YCbCrPositioning' },
-	'ycbcrsubsampling' => { 85 => 0x212, 306 => 'YCbCrSubSampling' },
-	'yearcreated' => { 99 => 0x10, 108 => 0xc },
-	'yposition' => { 85 => 0x11f },
-	'yresolution' => { 85 => 0x11b, 95 => 0x5, 257 => 0x4, 306 => 'YResolution' },
-	'zonematching' => { 135 => 0x10a, 138 => [0x3a,0x4a], 276 => 0xb024 },
-	'zonematchingmode' => { 134 => 0x14 },
-	'zonematchingon' => { 133 => 0x75 },
-	'zonematchingvalue' => { 271 => 0x1f },
-	'zoomedpreviewlength' => { 209 => 0xf05 },
-	'zoomedpreviewsize' => { 209 => 0xf06 },
-	'zoomedpreviewstart' => { 209 => 0xf04 },
-	'zoomsourcewidth' => { 24 => 0x24 },
-	'zoomstepcount' => { 207 => 0x300, 209 => 0x100d },
-	'zoomtargetwidth' => { 24 => 0x25 },
+	'aberrationcorrectiondistance' => { 107 => 0x69 },
+	'about' => { 487 => 'about' },
+	'aboutcvterm' => { 479 => 'AboutCvTerm' },
+	'aboutcvtermcvid' => { 479 => [\'AboutCvTerm','AboutCvTermCvId'] },
+	'aboutcvtermid' => { 479 => [\'AboutCvTerm','AboutCvTermCvTermId'] },
+	'aboutcvtermname' => { 479 => [\'AboutCvTerm','AboutCvTermCvTermName'] },
+	'aboutcvtermrefinedabout' => { 479 => [\'AboutCvTerm','AboutCvTermCvTermRefinedAbout'] },
+	'absolutealtitude' => { 114 => 'AbsoluteAltitude' },
+	'abspeakaudiofilepath' => { 493 => 'absPeakAudioFilePath' },
+	'academicfield' => { 483 => 'academicField' },
+	'acceleration' => { 117 => 0x9404, 474 => 'Acceleration' },
+	'accelerationtracking' => { 82 => 0x518 },
+	'accelerationvector' => { 1 => 0x8 },
+	'accelerometer' => { 380 => 0x3 },
+	'accelerometerdata' => { 370 => 'vrot' },
+	'accelerometerx' => { 310 => 0x8d },
+	'accelerometery' => { 310 => 0x8e },
+	'accelerometerz' => { 310 => 0x8c },
+	'accessoryserialnumber' => { 310 => 0x54 },
+	'accessorytype' => { 310 => 0x53 },
+	'actionadvised' => { 129 => 0x2a },
+	'activearea' => { 117 => 0xc68d },
+	'actived-lighting' => { 221 => 0x22, 261 => 0x24 },
+	'actived-lightingmode' => { 261 => 0x25 },
+	'adaptervoltage' => { 135 => 0x407 },
+	'addaspectratioinfo' => { 82 => 0x80e },
+	'addiptcinformation' => { 82 => 0x815 },
+	'additionalmodelinformation' => { 479 => 'AddlModelInfo' },
+	'addoriginaldecisiondata' => { 82 => 0x80f, 83 => 0x11, 84 => 0x13, 87 => 0x14 },
+	'address' => { 158 => 'Address' },
+	'adjustmentmode' => { 387 => 0x15 },
+	'adlbracketingstep' => { 240 => 0x883 },
+	'adlbracketingtype' => { 240 => 0x884 },
+	'adobe' => { 118 => 'Adobe' },
+	'adultcontentwarning' => { 297 => 'AdultContentWarning', 486 => 'adultContentWarning' },
+	'advancedfilter' => { 125 => 0x1201 },
+	'advancedraw' => { 263 => 0x76a43203 },
+	'advancedscenetype' => { 310 => 0x3d },
+	'advisory' => { 491 => 'Advisory' },
+	'ae_iso' => { 318 => 0x2, 319 => 0x4, 320 => 0x12 },
+	'aeaperture' => { 318 => 0x1, 319 => 0x3, 320 => 0x11 },
+	'aeaperturesteps' => { 318 => 0x8, 319 => 0xb },
+	'aebautocancel' => { 82 => 0x104 },
+	'aebbracketvalue' => { 75 => 0x11 },
+	'aebracketingsteps' => { 239 => 0x174c, 240 => 0x87b, 249 => 0x1756 },
+	'aebsequence' => { 82 => 0x105 },
+	'aebsequenceautocancel' => { 80 => 0x9, 81 => 0x9, 83 => 0x8, 84 => 0x9, 87 => 0x9, 88 => 0x7 },
+	'aebshotcount' => { 82 => 0x106 },
+	'aebxv' => { 318 => 0x4, 319 => 0x6 },
+	'aeerror' => { 319 => 0x8 },
+	'aeexposuretime' => { 318 => 0x0, 319 => 0x2, 320 => 0x10 },
+	'aelbutton' => { 180 => 0x45 },
+	'aelexposureindicator' => { 180 => 0x51 },
+	'aelock' => { 180 => 0x5b, 272 => '4.2', 281 => '4.2', 287 => 0x201, 345 => 0x48, 397 => 0x40, 398 => 0x40, 399 => [0x86,0x286] },
+	'aelockbutton' => { 270 => '16.1', 272 => '4.1', 275 => '15.1', 276 => '16.1', 277 => '16.1', 279 => '30.1', 280 => '16.1', 281 => '4.1', 283 => '17.1', 285 => '17.1' },
+	'aelockbuttonplusdials' => { 270 => '16.2', 279 => '32.1', 283 => '44.1' },
+	'aelockformb-d80' => { 285 => '3.1' },
+	'aelockmetermodeafterfocus' => { 82 => 0x114 },
+	'aemaxaperture' => { 318 => 0x9, 319 => 0x10, 320 => 0x1c },
+	'aemaxaperture2' => { 318 => 0xa, 319 => 0x11, 320 => 0x1d },
+	'aemeteringmode' => { 318 => 0xc },
+	'aemeteringmode2' => { 318 => '13.1' },
+	'aemeteringsegments' => { 183 => 0x628, 345 => 0x209 },
+	'aemicroadjustment' => { 82 => 0x110 },
+	'aeminaperture' => { 318 => 0xb, 319 => 0x12, 320 => 0x1e },
+	'aeminexposuretime' => { 318 => 0x5, 319 => 0x13, 320 => 0x1f },
+	'aeprogrammode' => { 318 => 0x6 },
+	'aeprojectlink' => { 468 => 'aeProjectLink' },
+	'aeprojectlinkcompositionid' => { 468 => [\'aeProjectLink','aeProjectLinkCompositionID'] },
+	'aeprojectlinkfullpath' => { 468 => [\'aeProjectLink','aeProjectLinkFullPath'] },
+	'aeprojectlinkrenderoutputmoduleindex' => { 468 => [\'aeProjectLink','aeProjectLinkRenderOutputModuleIndex'] },
+	'aeprojectlinkrenderqueueitemid' => { 468 => [\'aeProjectLink','aeProjectLinkRenderQueueItemID'] },
+	'aeprojectlinkrendertimestamp' => { 468 => [\'aeProjectLink','aeProjectLinkRenderTimeStamp'] },
+	'aesetting' => { 34 => 0x21 },
+	'aewhitebalance' => { 318 => 0xd },
+	'aexv' => { 318 => 0x3, 319 => 0x5 },
+	'af-cpriority' => { 126 => '0.2' },
+	'af-cpriorityselection' => { 270 => '1.1', 271 => '1.1', 273 => '1.1', 274 => '1.1', 276 => '0.1', 277 => '0.1', 278 => '0.1', 279 => '1.1', 280 => '0.1', 283 => '1.1', 284 => '1.1' },
+	'af-csetting' => { 122 => 0x0 },
+	'af-cspeedtrackingsensitivity' => { 122 => '0.2' },
+	'af-ctrackingsensitivity' => { 122 => '0.1' },
+	'af-czoneareaswitching' => { 122 => '0.3' },
+	'af-onbutton' => { 273 => '70.1', 274 => '70.1', 284 => '70.1' },
+	'af-onformb-d10' => { 270 => '3.3', 279 => '3.2' },
+	'af-onformb-d11' => { 280 => '2.2' },
+	'af-onformb-d12' => { 283 => '50.1' },
+	'af-spriority' => { 126 => '0.1' },
+	'af-spriorityselection' => { 270 => '1.2', 271 => '1.2', 273 => '1.2', 274 => '1.2', 278 => '0.2', 279 => '1.2', 280 => '0.2', 283 => '1.2', 284 => '1.2' },
+	'afacceldeceltracking' => { 2 => 0x3 },
+	'afactivation' => { 270 => '2.1', 271 => '2.1', 273 => '78.3', 274 => '78.3', 279 => '2.1', 283 => '2.1', 284 => '78.3' },
+	'afadjustment' => { 345 => 0x72, 354 => 0x267 },
+	'afandmeteringbuttons' => { 82 => 0x701 },
+	'afaperture' => { 214 => 0x5, 215 => 0x5, 219 => 0x5 },
+	'afareaheight' => { 189 => [0x1a,0x34,0x50] },
+	'afareaillumination' => { 180 => 0x4b, 281 => '15.3' },
+	'afareamode' => { 124 => '0.2', 176 => 0x33, 180 => 0xe, 188 => 0x0, 189 => 0x5, 310 => 0xf, 377 => 0x1205, 390 => [0xa,0x3a], 397 => 0x11, 398 => 0x10, 399 => 0x24, 410 => 0xb043, 434 => 0x17 },
+	'afareamodesetting' => { 272 => '11.1', 275 => '0.1', 281 => '16.1', 285 => '2.1', 410 => 0x201c },
+	'afareapointsize' => { 124 => '0.3' },
+	'afareas' => { 287 => 0x304 },
+	'afareaselectionmethod' => { 2 => 0xd },
+	'afareaselectmethod' => { 82 => 0x51b },
+	'afareawidth' => { 189 => [0x18,0x32,0x4e] },
+	'afareaxposition' => { 189 => [0x14,0x2e,0x4a], 377 => 0x1203 },
+	'afareaxposition1' => { 377 => 0x1201 },
+	'afareayposition' => { 189 => [0x16,0x30,0x4c], 377 => 0x1204 },
+	'afareayposition1' => { 377 => 0x1202 },
+	'afareazonesize' => { 124 => '0.4' },
+	'afassist' => { 80 => 0x5, 88 => 0x5, 180 => 0x48, 270 => '2.5', 272 => '0.2', 275 => '0.2', 276 => '1.1', 277 => '1.1', 278 => '1.3', 279 => '2.4', 280 => '1.3', 281 => '0.2', 283 => '2.4', 285 => '2.3' },
+	'afassistbeam' => { 2 => 0x8, 82 => 0x50e, 83 => 0x4, 84 => 0x5, 85 => 0x4, 86 => 0x4, 87 => 0x5 },
+	'afassistlamp' => { 310 => 0x31 },
+	'afbuttonpressed' => { 399 => [0x83,0x283] },
+	'afconfigtool' => { 2 => 0x1 },
+	'afdefocus' => { 321 => 0x6 },
+	'afduringliveview' => { 82 => 0x511 },
+	'affinea' => { 461 => 'AffineA' },
+	'affineb' => { 461 => 'AffineB' },
+	'affinec' => { 461 => 'AffineC' },
+	'affined' => { 461 => 'AffineD' },
+	'affinetune' => { 190 => 0x0, 287 => 0x306 },
+	'affinetuneadj' => { 190 => 0x2, 232 => 0x2d1, 233 => 0x2dc, 287 => 0x307 },
+	'affinetuneadjtele' => { 190 => 0x3 },
+	'affinetuneindex' => { 190 => 0x1 },
+	'affinex' => { 461 => 'AffineX' },
+	'affiney' => { 461 => 'AffineY' },
+	'affocuspointxposition' => { 189 => 0x2f },
+	'affocuspointyposition' => { 189 => 0x31 },
+	'afhold' => { 321 => 0x1fd },
+	'afilluminator' => { 397 => 0x29, 410 => 0xb044 },
+	'afimageheight' => { 189 => [0x12,0x2c,0x48] },
+	'afimagewidth' => { 189 => [0x10,0x2a,0x46] },
+	'afintegrationtime' => { 321 => 0x7 },
+	'afmicroadj' => { 390 => [0x17d,0x50] },
+	'afmicroadjmode' => { 3 => 0x1, 394 => 0x131 },
+	'afmicroadjregisteredlenses' => { 394 => '305.1' },
+	'afmicroadjustment' => { 82 => 0x507 },
+	'afmicroadjvalue' => { 3 => 0x2, 394 => 0x130 },
+	'afmode' => { 111 => 0x3009, 125 => 0x1022, 176 => 0x16, 387 => 0x5 },
+	'afmoderestrictions' => { 271 => '50.3', 273 => '48.3', 274 => '48.3', 283 => '48.3', 284 => '48.3' },
+	'afonaelockbuttonswitch' => { 82 => 0x702 },
+	'afonbutton' => { 270 => '3.1', 271 => '47.1' },
+	'afpoint' => { 34 => 0x13, 110 => 0x18, 176 => 0x15, 188 => 0x1, 290 => 0x308, 387 => 0x1f, 390 => [0x37,0x7], 394 => 0x19, 395 => 0x18, 396 => [0x18,0x20] },
+	'afpointactivationarea' => { 81 => 0x11, 87 => 0x11 },
+	'afpointareaexpansion' => { 82 => 0x508 },
+	'afpointatshutterrelease' => { 390 => [0x39,0x9] },
+	'afpointautoselection' => { 82 => 0x50b },
+	'afpointbrightness' => { 82 => 0x50d, 270 => '2.4', 271 => '46.5', 273 => '2.2', 274 => '2.2', 283 => '2.3', 284 => '2.2' },
+	'afpointdisplayduringfocus' => { 2 => 0x10, 82 => 0x50c },
+	'afpointillumination' => { 81 => 0xa, 270 => '2.3', 271 => '46.2', 273 => '47.2', 274 => '47.2', 278 => '1.2', 279 => '2.3', 280 => '1.2', 283 => '47.2', 284 => '47.2', 285 => '2.4' },
+	'afpointinfocus' => { 390 => [0x38,0x8] },
+	'afpointmode' => { 326 => 0x3 },
+	'afpointposition' => { 111 => 0x2021, 310 => 0x4d },
+	'afpointregistration' => { 80 => 0x7 },
+	'afpoints' => { 179 => 0x10 },
+	'afpointselected' => { 180 => 0xd, 287 => 0x305, 345 => 0xe, 394 => 0x15, 395 => 0x14, 396 => [0x14,0x1c], 410 => 0x201e },
+	'afpointselected2' => { 326 => 0x4 },
+	'afpointselection' => { 81 => 0xb, 270 => '1.3', 271 => '1.3', 279 => '1.3', 283 => '1.3', 284 => '1.3' },
+	'afpointselectionmethod' => { 82 => 0x50f, 83 => 0xc, 84 => 0xd, 87 => 0xd },
+	'afpointsetting' => { 397 => 0x12, 398 => 0x11 },
+	'afpointsinfocus' => { 75 => 0xe, 188 => 0x2, 189 => 0x30, 321 => 0xb, 322 => 0x4, 345 => [0xf,0x3c] },
+	'afpointsinfocus5d' => { 19 => 0x38 },
+	'afpointspotmetering' => { 81 => 0xd },
+	'afpointsselected' => { 189 => 0x1c, 322 => '4.1', 442 => 0x4 },
+	'afpointsspecial' => { 322 => '4.2' },
+	'afpointsunknown1' => { 321 => 0x0 },
+	'afpointsunknown2' => { 321 => 0x2 },
+	'afpointsused' => { 189 => [0xa,0x8], 390 => [0x10,0x16e] },
+	'afpointswitching' => { 2 => 0x4 },
+	'afpredictor' => { 321 => 0x4 },
+	'afresponse' => { 221 => 0xad },
+	'afresult' => { 292 => 0x1038 },
+	'afsearch' => { 287 => 0x303 },
+	'afsensoractive' => { 176 => 0x1 },
+	'afstatus' => { 377 => 0x1200 },
+	'afstatus_00_b4' => { 393 => 0x0 },
+	'afstatus_01_c4' => { 393 => 0x2 },
+	'afstatus_02_d4' => { 393 => 0x4 },
+	'afstatus_03_e4' => { 393 => 0x6 },
+	'afstatus_04_f4' => { 393 => 0x8 },
+	'afstatus_05_g4' => { 393 => 0xa },
+	'afstatus_06_h4' => { 393 => 0xc },
+	'afstatus_07_b3' => { 393 => 0xe },
+	'afstatus_08_c3' => { 393 => 0x10 },
+	'afstatus_09_d3' => { 393 => 0x12 },
+	'afstatus_10_e3' => { 393 => 0x14 },
+	'afstatus_11_f3' => { 393 => 0x16 },
+	'afstatus_12_g3' => { 393 => 0x18 },
+	'afstatus_13_h3' => { 393 => 0x1a },
+	'afstatus_14_b2' => { 393 => 0x1c },
+	'afstatus_15_c2' => { 393 => 0x1e },
+	'afstatus_16_d2' => { 393 => 0x20 },
+	'afstatus_17_e2' => { 393 => 0x22 },
+	'afstatus_18_f2' => { 393 => 0x24 },
+	'afstatus_19_g2' => { 393 => 0x26 },
+	'afstatus_20_h2' => { 393 => 0x28 },
+	'afstatus_21_c1' => { 393 => 0x2a },
+	'afstatus_22_d1' => { 393 => 0x2c },
+	'afstatus_23_e1' => { 393 => 0x2e },
+	'afstatus_24_f1' => { 393 => 0x30 },
+	'afstatus_25_g1' => { 393 => 0x32 },
+	'afstatus_26_a7_vertical' => { 393 => 0x34 },
+	'afstatus_27_a6_vertical' => { 393 => 0x36 },
+	'afstatus_28_a5_vertical' => { 393 => 0x38 },
+	'afstatus_29_c7_vertical' => { 393 => 0x3a },
+	'afstatus_30_c6_vertical' => { 393 => 0x3c },
+	'afstatus_31_c5_vertical' => { 393 => 0x3e },
+	'afstatus_32_e7_vertical' => { 393 => 0x40 },
+	'afstatus_33_e6_center_vertical' => { 393 => 0x42 },
+	'afstatus_34_e5_vertical' => { 393 => 0x44 },
+	'afstatus_35_g7_vertical' => { 393 => 0x46 },
+	'afstatus_36_g6_vertical' => { 393 => 0x48 },
+	'afstatus_37_g5_vertical' => { 393 => 0x4a },
+	'afstatus_38_i7_vertical' => { 393 => 0x4c },
+	'afstatus_39_i6_vertical' => { 393 => 0x4e },
+	'afstatus_40_i5_vertical' => { 393 => 0x50 },
+	'afstatus_41_a7' => { 393 => 0x52 },
+	'afstatus_42_b7' => { 393 => 0x54 },
+	'afstatus_43_c7' => { 393 => 0x56 },
+	'afstatus_44_d7' => { 393 => 0x58 },
+	'afstatus_45_e7' => { 393 => 0x5a },
+	'afstatus_46_f7' => { 393 => 0x5c },
+	'afstatus_47_g7' => { 393 => 0x5e },
+	'afstatus_48_h7' => { 393 => 0x60 },
+	'afstatus_49_i7' => { 393 => 0x62 },
+	'afstatus_50_a6' => { 393 => 0x64 },
+	'afstatus_51_b6' => { 393 => 0x66 },
+	'afstatus_52_c6' => { 393 => 0x68 },
+	'afstatus_53_d6' => { 393 => 0x6a },
+	'afstatus_54_e6_center' => { 393 => 0x6c },
+	'afstatus_55_f6' => { 393 => 0x6e },
+	'afstatus_56_g6' => { 393 => 0x70 },
+	'afstatus_57_h6' => { 393 => 0x72 },
+	'afstatus_58_i6' => { 393 => 0x74 },
+	'afstatus_59_a5' => { 393 => 0x76 },
+	'afstatus_60_b5' => { 393 => 0x78 },
+	'afstatus_61_c5' => { 393 => 0x7a },
+	'afstatus_62_d5' => { 393 => 0x7c },
+	'afstatus_63_e5' => { 393 => 0x7e },
+	'afstatus_64_f5' => { 393 => 0x80 },
+	'afstatus_65_g5' => { 393 => 0x82 },
+	'afstatus_66_h5' => { 393 => 0x84 },
+	'afstatus_67_i5' => { 393 => 0x86 },
+	'afstatus_68_c11' => { 393 => 0x88 },
+	'afstatus_69_d11' => { 393 => 0x8a },
+	'afstatus_70_e11' => { 393 => 0x8c },
+	'afstatus_71_f11' => { 393 => 0x8e },
+	'afstatus_72_g11' => { 393 => 0x90 },
+	'afstatus_73_b10' => { 393 => 0x92 },
+	'afstatus_74_c10' => { 393 => 0x94 },
+	'afstatus_75_d10' => { 393 => 0x96 },
+	'afstatus_76_e10' => { 393 => 0x98 },
+	'afstatus_77_f10' => { 393 => 0x9a },
+	'afstatus_78_g10' => { 393 => 0x9c },
+	'afstatus_79_h10' => { 393 => 0x9e },
+	'afstatus_80_b9' => { 393 => 0xa0 },
+	'afstatus_81_c9' => { 393 => 0xa2 },
+	'afstatus_82_d9' => { 393 => 0xa4 },
+	'afstatus_83_e9' => { 393 => 0xa6 },
+	'afstatus_84_f9' => { 393 => 0xa8 },
+	'afstatus_85_g9' => { 393 => 0xaa },
+	'afstatus_86_h9' => { 393 => 0xac },
+	'afstatus_87_b8' => { 393 => 0xae },
+	'afstatus_88_c8' => { 393 => 0xb0 },
+	'afstatus_89_d8' => { 393 => 0xb2 },
+	'afstatus_90_e8' => { 393 => 0xb4 },
+	'afstatus_91_f8' => { 393 => 0xb6 },
+	'afstatus_92_g8' => { 393 => 0xb8 },
+	'afstatus_93_h8' => { 393 => 0xba },
+	'afstatus_94_e6_center_f2-8' => { 393 => 0xbc },
+	'afstatusactivesensor' => { 176 => 0x2, 390 => [0x4,0x3b], 394 => 0x1e, 395 => 0x1b, 396 => [0x1b,0x21] },
+	'afstatusbottom' => { 176 => 0x8, 394 => 0x2a, 395 => 0x21, 396 => 0x21 },
+	'afstatusbottom-left' => { 176 => 0x12, 395 => 0x2b, 396 => 0x2b },
+	'afstatusbottom-right' => { 176 => 0x6, 395 => 0x1f, 396 => 0x1f },
+	'afstatusbottomassist-left' => { 394 => 0x28 },
+	'afstatusbottomassist-right' => { 394 => 0x2c },
+	'afstatusbottomhorizontal' => { 391 => 0x10, 392 => 0x1c },
+	'afstatusbottomvertical' => { 391 => 0x16, 392 => 0x26 },
+	'afstatuscenter-10' => { 394 => 0x34 },
+	'afstatuscenter-11' => { 394 => 0x36 },
+	'afstatuscenter-12' => { 394 => 0x38 },
+	'afstatuscenter-14' => { 394 => 0x3c },
+	'afstatuscenter-7' => { 394 => 0x2e },
+	'afstatuscenter-9' => { 394 => 0x32 },
+	'afstatuscenter-horizontal' => { 394 => 0x30 },
+	'afstatuscenter-vertical' => { 394 => 0x3a },
+	'afstatuscenterf2-8' => { 394 => 0x4c },
+	'afstatuscenterhorizontal' => { 176 => 0x2f, 391 => 0xc, 392 => 0x18, 395 => 0x2f, 396 => 0x2f },
+	'afstatuscentervertical' => { 176 => 0xc, 391 => 0x14, 392 => 0x22, 395 => 0x25, 396 => 0x25 },
+	'afstatusfarleft' => { 391 => 0x6, 394 => 0x26 },
+	'afstatusfarlefthorizontal' => { 392 => 0x4 },
+	'afstatusfarleftvertical' => { 392 => 0x12 },
+	'afstatusfarright' => { 391 => 0x18, 394 => 0x44 },
+	'afstatusfarrighthorizontal' => { 392 => 0x2c },
+	'afstatusfarrightvertical' => { 392 => 0x34 },
+	'afstatusleft' => { 176 => 0x2d, 391 => 0x2, 394 => 0x22, 395 => 0x2d, 396 => 0x2d },
+	'afstatuslefthorizontal' => { 392 => 0x6 },
+	'afstatusleftvertical' => { 392 => 0xe },
+	'afstatuslower-left' => { 391 => 0x4, 394 => 0x24 },
+	'afstatuslower-lefthorizontal' => { 392 => 0xa },
+	'afstatuslower-leftvertical' => { 392 => 0x10 },
+	'afstatuslower-middle' => { 391 => 0x22, 392 => 0x24 },
+	'afstatuslower-right' => { 391 => 0x1e, 394 => 0x4a },
+	'afstatuslower-righthorizontal' => { 392 => 0x32 },
+	'afstatuslower-rightvertical' => { 392 => 0x3a },
+	'afstatuslowerfarleft' => { 392 => 0x8 },
+	'afstatuslowerfarright' => { 392 => 0x30 },
+	'afstatusmiddlehorizontal' => { 176 => 0xa, 395 => 0x23, 396 => 0x23 },
+	'afstatusnearleft' => { 391 => 0xe, 392 => 0x1a },
+	'afstatusnearright' => { 391 => 0xa, 392 => 0x16 },
+	'afstatusright' => { 176 => 0x31, 391 => 0x1c, 394 => 0x48, 395 => 0x31, 396 => 0x31 },
+	'afstatusrighthorizontal' => { 392 => 0x2e },
+	'afstatusrightvertical' => { 392 => 0x38 },
+	'afstatustop' => { 176 => 0xe, 394 => 0x40, 395 => 0x27, 396 => 0x27 },
+	'afstatustop-left' => { 176 => 0x10, 395 => 0x29, 396 => 0x29 },
+	'afstatustop-right' => { 176 => 0x4, 395 => 0x1d, 396 => 0x1d },
+	'afstatustopassist-left' => { 394 => 0x3e },
+	'afstatustopassist-right' => { 394 => 0x42 },
+	'afstatustophorizontal' => { 391 => 0x8, 392 => 0x14 },
+	'afstatustopvertical' => { 391 => 0x12, 392 => 0x1e },
+	'afstatusupper-left' => { 391 => 0x0, 394 => 0x20 },
+	'afstatusupper-lefthorizontal' => { 392 => 0x2 },
+	'afstatusupper-leftvertical' => { 392 => 0xc },
+	'afstatusupper-middle' => { 391 => 0x20, 392 => 0x20 },
+	'afstatusupper-right' => { 391 => 0x1a, 394 => 0x46 },
+	'afstatusupper-righthorizontal' => { 392 => 0x2a },
+	'afstatusupper-rightvertical' => { 392 => 0x36 },
+	'afstatusupperfarleft' => { 392 => 0x0 },
+	'afstatusupperfarright' => { 392 => 0x28 },
+	'afstatusviewfinder' => { 2 => 0x12 },
+	'aftracking' => { 410 => 0x2021 },
+	'aftrackingsensitivity' => { 2 => 0x2 },
+	'aftype' => { 390 => 0x2 },
+	'afwithshutter' => { 397 => 0x2a },
+	'aggregateissuenumber' => { 483 => 'aggregateIssueNumber' },
+	'aggregationtype' => { 483 => 'aggregationType' },
+	'agreement' => { 486 => 'agreement' },
+	'ah2greeninterpolationthreshold' => { 135 => 0xe4e },
+	'aiservocontinuousshooting' => { 81 => 0x15 },
+	'aiservofirstimage' => { 2 => 0x5 },
+	'aiservofirstimagepriority' => { 82 => 0x519 },
+	'aiservoimagepriority' => { 82 => 0x503 },
+	'aiservosecondimage' => { 2 => 0x6 },
+	'aiservosecondimagepriority' => { 82 => 0x51a },
+	'aiservotrackingmethod' => { 82 => 0x504 },
+	'aiservotrackingsensitivity' => { 81 => 0x14, 82 => 0x502 },
+	'album' => { 362 => ['albm',"\xa9alb"], 364 => 'album', 370 => ['albm',"\xa9alb"], 493 => 'album' },
+	'albumartist' => { 362 => 'aART', 370 => 'albr' },
+	'albumtitleid' => { 362 => 'atID' },
+	'alreadyapplied' => { 467 => 'AlreadyApplied', 469 => 'AlreadyApplied' },
+	'alternatetitle' => { 483 => 'alternateTitle' },
+	'alternatetitlea-lang' => { 483 => [\'alternateTitle','alternateTitleA-lang'] },
+	'alternatetitlea-platform' => { 483 => [\'alternateTitle','alternateTitleA-platform'] },
+	'alternatetitletext' => { 483 => [\'alternateTitle','alternateTitleText'] },
+	'altitude' => { 191 => 0x6 },
+	'alttapename' => { 493 => 'altTapeName' },
+	'alttimecode' => { 493 => 'altTimecode' },
+	'alttimecodetimeformat' => { 493 => [\'altTimecode','altTimecodeTimeFormat'] },
+	'alttimecodetimevalue' => { 493 => [\'altTimecode','altTimecodeTimeValue'] },
+	'alttimecodevalue' => { 493 => [\'altTimecode','altTimecodeValue'] },
+	'ambienceselection' => { 4 => 0x1 },
+	'ambientinfrared' => { 373 => 0x5c },
+	'ambientlight' => { 373 => 0x5e },
+	'ambienttemperature' => { 117 => 0x9400, 371 => 0x14, 372 => 0x46, 373 => 0x50, 434 => 0x4, 474 => 'Temperature' },
+	'ambienttemperaturefahrenheit' => { 371 => 0x13, 372 => 0x44, 373 => 0x4e },
+	'analogbalance' => { 117 => 0xc627 },
+	'analogcaptureiso' => { 135 => 0x89e },
+	'analogisotable' => { 135 => 0x89d },
+	'androidversion' => { 364 => 'com.android.version' },
+	'angleadj' => { 101 => 0x10003, 107 => 0x8b },
+	'angleinforoll' => { 463 => 'AngleInfoRoll' },
+	'angleinfoyaw' => { 463 => 'AngleInfoYaw' },
+	'anti-blur' => { 410 => 0xb04b },
+	'antialiasstrength' => { 117 => 0xc632 },
+	'aperturelock' => { 271 => '38.2', 273 => '38.2', 274 => '38.2', 283 => '38.2', 284 => '38.2' },
+	'aperturemode' => { 370 => 'apmd' },
+	'aperturerange' => { 82 => 0x10d },
+	'apertureringuse' => { 326 => '1.4' },
+	'aperturesetting' => { 180 => 0x7, 397 => 0x30, 398 => 0x29, 399 => 0x1 },
+	'aperturevalue' => { 91 => 0x2, 117 => 0x9202, 292 => 0x1002, 354 => 0x401, 473 => 'ApertureValue' },
+	'appinfo' => { 447 => 'AppInfo' },
+	'appinfoapplication' => { 447 => [\'AppInfo','AppInfoApplication'] },
+	'appinfoitemuri' => { 447 => [\'AppInfo','AppInfoItemURI'] },
+	'appinfoversion' => { 447 => [\'AppInfo','AppInfoVersion'] },
+	'applekeywords' => { 296 => 'AAPL:Keywords' },
+	'applestoreaccount' => { 362 => 'apID' },
+	'applestoreaccounttype' => { 362 => 'akID' },
+	'applestorecatalogid' => { 362 => 'cnID' },
+	'applestorecountry' => { 362 => 'sfID' },
+	'applicationkeystring' => { 135 => 0x400 },
+	'applicationnotes' => { 117 => 0x2bc, 315 => 0x2bc },
+	'applicationrecordversion' => { 129 => 0x0 },
+	'applyshootingmeteringmode' => { 82 => 0x10e },
+	'approved' => { 475 => 'Approved' },
+	'approvedby' => { 475 => 'ApprovedBy' },
+	'approximatefnumber' => { 305 => 0x313, 312 => 0x3406 },
+	'approximatefocusdistance' => { 464 => 'ApproximateFocusDistance' },
+	'appversion' => { 477 => 'AppVersion' },
+	'aps-csizecapture' => { 428 => 0x114, 429 => [0x114,0x1eb,0x1ee,0x21a,0x21c] },
+	'aquahsl' => { 101 => 0x20914 },
+	'armidentifier' => { 130 => 0x78 },
+	'armversion' => { 130 => 0x7a },
+	'arranger' => { 362 => "\xa9arg", 370 => "\xa9arg" },
+	'arrangerkeywords' => { 370 => "\xa9ark" },
+	'artdirector' => { 362 => "\xa9ard" },
+	'artfilter' => { 287 => 0x529 },
+	'artfiltereffect' => { 287 => 0x52f },
+	'artist' => { 117 => 0x13b, 300 => 'Artist', 345 => 0x22e, 362 => "\xa9ART", 364 => 'artist', 370 => "\xa9ART", 489 => 'Artist', 493 => 'artist' },
+	'artmode' => { 111 => 0x301b },
+	'artmodeparameters' => { 111 => 0x310b },
+	'artwork' => { 364 => 'artwork' },
+	'artworkcircadatecreated' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOCircaDateCreated'] },
+	'artworkcontentdescription' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOContentDescription'] },
+	'artworkcontributiondescription' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOContributionDescription'] },
+	'artworkcopyrightnotice' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOCopyrightNotice'] },
+	'artworkcopyrightownerid' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentCopyrightOwnerId'] },
+	'artworkcopyrightownername' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentCopyrightOwnerName'] },
+	'artworkcreator' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOCreator'] },
+	'artworkcreatorid' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOCreatorId'] },
+	'artworkdatecreated' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAODateCreated'] },
+	'artworklicensorid' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentLicensorId'] },
+	'artworklicensorname' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOCurrentLicensorName'] },
+	'artworkorobject' => { 479 => 'ArtworkOrObject' },
+	'artworkphysicaldescription' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOPhysicalDescription'] },
+	'artworksource' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOSource'] },
+	'artworksourceinventoryno' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOSourceInvNo'] },
+	'artworksourceinvurl' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOSourceInvURL'] },
+	'artworkstyleperiod' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOStylePeriod'] },
+	'artworktitle' => { 479 => [\'ArtworkOrObject','ArtworkOrObjectAOTitle'] },
+	'aspectframe' => { 291 => 0x1113 },
+	'aspectratio' => { 5 => 0x0, 291 => 0x1112, 345 => 0x80, 397 => 0x55, 398 => 0x55, 399 => 0xa },
+	'assetid' => { 457 => 'AssetID' },
+	'asshoticcprofile' => { 117 => 0xc68f },
+	'asshotneutral' => { 117 => 0xc628 },
+	'asshotpreprofilematrix' => { 117 => 0xc690 },
+	'asshotprofilename' => { 117 => 0xc6f6 },
+	'asshotwhitexy' => { 117 => 0xc629 },
+	'assignbktbutton' => { 270 => '4.2', 271 => '16.1', 273 => '16.1', 274 => '16.1', 283 => '16.1', 284 => '16.1' },
+	'assignfuncbutton' => { 82 => 0x70b },
+	'assignmb-d17af-onbutton' => { 274 => '79.1' },
+	'assignmb-d17funcbutton' => { 274 => '67.1' },
+	'assignmb-d17funcbuttonplusdials' => { 274 => '68.1' },
+	'assignmb-d18af-onbutton' => { 284 => '79.1' },
+	'assignmb-d18funcbutton' => { 284 => '67.1' },
+	'assignmb-d18funcbuttonplusdials' => { 284 => '68.1' },
+	'assignmoviefunc1buttonplusdials' => { 273 => '75.1', 274 => '75.1', 284 => '75.1' },
+	'assignmoviefunc2button' => { 273 => '82.1', 274 => '82.1', 284 => '82.1' },
+	'assignmoviepreviewbuttonplusdials' => { 273 => '75.2', 274 => '75.2', 284 => '75.2' },
+	'assignmovierecordbutton' => { 271 => '43.2', 283 => '45.1' },
+	'assignmovierecordbuttonplusdials' => { 273 => '45.1', 274 => '45.1', 284 => '45.1' },
+	'assignmoviesubselector' => { 273 => '74.1', 274 => '74.1', 284 => '74.1' },
+	'assignmoviesubselectorplusdials' => { 273 => '76.1', 274 => '76.1', 284 => '76.1' },
+	'assignremotefnbutton' => { 271 => '54.1', 283 => '51.1' },
+	'assistbuttonfunction' => { 80 => 0xd },
+	'atcaptureusercrop' => { 135 => 0x943 },
+	'attributionname' => { 465 => 'attributionName' },
+	'attributionurl' => { 465 => 'attributionURL' },
+	'audio' => { 310 => 0x20 },
+	'audiobitrate' => { 65 => 0x6c, 479 => 'audioBitRate' },
+	'audiobitratemode' => { 479 => 'audioBitRateMode' },
+	'audiobitspersample' => { 479 => 'audioBitsPerSample' },
+	'audiochannelcount' => { 479 => 'audioChannelCount' },
+	'audiochannels' => { 65 => 0x70 },
+	'audiochanneltype' => { 493 => 'audioChannelType' },
+	'audiocompression' => { 82 => 0x816, 152 => 'Compression' },
+	'audiocompressor' => { 493 => 'audioCompressor' },
+	'audiodata' => { 449 => 'Data' },
+	'audioduration' => { 129 => 0x99 },
+	'audiogain' => { 364 => 'player.movie.audio.gain' },
+	'audiomimetype' => { 449 => 'Mime' },
+	'audiomoddate' => { 493 => 'audioModDate' },
+	'audiooutcue' => { 129 => 0x9a },
+	'audiosamplerate' => { 65 => 0x6e, 493 => 'audioSampleRate' },
+	'audiosampletype' => { 493 => 'audioSampleType' },
+	'audiosamplingrate' => { 129 => 0x97 },
+	'audiosamplingresolution' => { 129 => 0x98 },
+	'audiotype' => { 129 => 0x96 },
+	'author' => { 154 => 'Author', 296 => 'Author', 300 => 'Author', 361 => 'Author', 362 => ['auth',"\xa9aut"], 364 => 'author', 370 => 'auth', 462 => 'author', 480 => 'Author', 491 => 'Author' },
+	'authorsposition' => { 481 => 'AuthorsPosition' },
+	'autoafpointcolortracking' => { 82 => 0x51c },
+	'autoafpointseleositraf' => { 2 => 0xa },
+	'autoaperture' => { 336 => '0.1' },
+	'autobracket' => { 387 => 0x19 },
+	'autobracketing' => { 125 => 0x1100, 345 => 0x18, 377 => 0x1007 },
+	'autobracketingmode' => { 282 => '12.3' },
+	'autobracketingset' => { 282 => '12.1' },
+	'autobracketmodem' => { 270 => '21.2', 271 => '13.3', 273 => '13.2', 274 => '13.2', 279 => '26.2', 283 => '13.3', 284 => '13.2' },
+	'autobracketorder' => { 180 => 0x43, 270 => '21.3', 271 => '13.2', 273 => '13.1', 274 => '13.1', 279 => '26.3', 280 => '12.2', 281 => '2.2', 282 => '12.2', 283 => '13.2', 284 => '13.1', 285 => '13.2' },
+	'autobracketset' => { 270 => '21.1', 271 => '13.1', 275 => '11.1', 276 => '12.1', 277 => '12.1', 279 => '26.1', 280 => '12.1', 281 => '2.1', 283 => '13.1', 285 => '13.1' },
+	'autobrightness' => { 467 => 'AutoBrightness', 469 => 'AutoBrightness' },
+	'autocontrast' => { 467 => 'AutoContrast', 469 => 'AutoContrast' },
+	'autodistortioncontrol' => { 201 => 0x4 },
+	'autodynamicrange' => { 125 => 0x140b },
+	'autoexposure' => { 467 => 'AutoExposure', 469 => 'AutoExposure' },
+	'autoexposurebracketing' => { 75 => 0x10 },
+	'autoflashisosensitivity' => { 273 => '38.5', 274 => '38.5', 284 => '38.5' },
+	'autofocus' => { 290 => 0x209 },
+	'autofp' => { 281 => '7.3', 285 => '31.4' },
+	'autoiso' => { 75 => 0x1, 111 => 0x3008, 272 => '1.1', 281 => '1.1' },
+	'autoisomax' => { 272 => '1.2', 281 => '1.2' },
+	'autoisominshutterspeed' => { 272 => '1.3', 281 => '1.3' },
+	'autolateralca' => { 467 => 'AutoLateralCA', 469 => 'AutoLateralCA' },
+	'autolightingoptimizer' => { 16 => 0xbe, 17 => 0xbf, 20 => 0xbf, 61 => 0x2, 82 => 0x204, 101 => 0x20500, 107 => 0x6f },
+	'autolightingoptimizeron' => { 101 => '0x20500.0', 107 => 0x6e },
+	'autoportraitframed' => { 410 => 0x2016 },
+	'autoredeye' => { 263 => 0xfe28a44f },
+	'autorotate' => { 75 => 0x1b },
+	'autoshadows' => { 467 => 'AutoShadows', 469 => 'AutoShadows' },
+	'autotone' => { 467 => 'AutoTone', 469 => 'AutoTone' },
+	'autotonedigest' => { 467 => 'AutoToneDigest', 469 => 'AutoToneDigest' },
+	'autotonedigestnosat' => { 467 => 'AutoToneDigestNoSat', 469 => 'AutoToneDigestNoSat' },
+	'autowhiteversion' => { 467 => 'AutoWhiteVersion', 469 => 'AutoWhiteVersion' },
+	'auxiliarylens' => { 221 => 0x82 },
+	'avaperturesetting' => { 326 => 0x13 },
+	'averageblacklevel' => { 44 => 0xe7, 46 => 0xfb, 47 => 0x114, 48 => 0x146 },
+	'averagelv' => { 183 => 0x38 },
+	'avsettingwithoutlens' => { 82 => 0x707 },
+	'azimuth' => { 162 => 'Azimuth' },
+	'babyage' => { 310 => [0x8010,0x33] },
+	'babyname' => { 310 => 0x66 },
+	'backgroundalpha' => { 488 => 'bgalpha' },
+	'balance' => { 364 => 'player.movie.audio.balance' },
+	'baseexposurecompensation' => { 326 => 0x15 },
+	'baseiso' => { 75 => 0x2, 95 => 0x101c, 135 => 0x903, 312 => 0x312a, 440 => 0x6 },
+	'baseisodaylight' => { 135 => 0x910 },
+	'baseisoflash' => { 135 => 0x913 },
+	'baseisofluorescent' => { 135 => 0x912 },
+	'baseisotungsten' => { 135 => 0x911 },
+	'baselineexposure' => { 117 => 0xc62a },
+	'baselineexposureoffset' => { 117 => 0xc7a5 },
+	'baselinenoise' => { 117 => 0xc62b },
+	'baselinesharpness' => { 117 => 0xc62c },
+	'baseurl' => { 491 => 'BaseURL' },
+	'bass' => { 364 => 'player.movie.audio.bass' },
+	'batterylevel' => { 310 => 0x38, 397 => 0x51, 401 => 0xc, 402 => 0x4, 403 => 0x4, 441 => 0x7 },
+	'batterylevelgrip1' => { 441 => 0x6 },
+	'batterylevelgrip2' => { 441 => 0x8 },
+	'batteryorder' => { 270 => '12.5', 279 => '13.2', 280 => '2.1', 283 => '3.1' },
+	'batterystate' => { 180 => 0x60, 397 => 0x50, 403 => 0x14 },
+	'batterytemperature' => { 401 => 0x1, 403 => 0x2, 441 => 0x5 },
+	'batterytype' => { 62 => 0x38, 373 => 0x66 },
+	'batteryunknown' => { 401 => 0x2, 403 => 0x0 },
+	'batteryvoltage' => { 135 => 0x408, 371 => 0x2a, 372 => 0x49, 373 => 0x62, 401 => 0x8 },
+	'batteryvoltage1' => { 403 => 0x6 },
+	'batteryvoltage2' => { 403 => 0x8 },
+	'batteryvoltageavg' => { 373 => 0x64 },
+	'bayergreensplit' => { 117 => 0xc62d },
+	'bayerpattern' => { 134 => 0xf902, 184 => 0x17 },
+	'beatsperminute' => { 362 => 'tmpo' },
+	'beatspliceparams' => { 493 => 'beatSpliceParams' },
+	'beatspliceparamsriseindecibel' => { 493 => [\'beatSpliceParams','beatSpliceParamsRiseInDecibel'] },
+	'beatspliceparamsriseintimeduration' => { 493 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDuration'] },
+	'beatspliceparamsriseintimedurationscale' => { 493 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationScale'] },
+	'beatspliceparamsriseintimedurationvalue' => { 493 => [\'beatSpliceParams','beatSpliceParamsRiseInTimeDurationValue'] },
+	'beatspliceparamsusefilebeatsmarker' => { 493 => [\'beatSpliceParams','beatSpliceParamsUseFileBeatsMarker'] },
+	'beep' => { 270 => '13.1', 271 => '5.4', 272 => '0.1', 275 => '2.1', 276 => '3.1', 277 => '3.1', 279 => '10.1', 281 => '0.1', 283 => '5.5', 285 => '4.1' },
+	'beeppitch' => { 280 => '3.1' },
+	'beepvolume' => { 280 => '4.5' },
+	'bestqualityscale' => { 117 => 0xc65c },
+	'bestshotmode' => { 111 => 0x3007 },
+	'bitdepth' => { 159 => 'BitDepth', 184 => 0x11, 229 => 0x41 },
+	'bitspercomponent' => { 131 => 0x87 },
+	'bitspersample' => { 117 => 0x102, 315 => 0xa, 489 => 'BitsPerSample' },
+	'blackacquirerows' => { 135 => 0x18ba },
+	'blacklevel' => { 117 => 0xc61a, 199 => 0x20, 221 => 0x3d, 292 => [0x401,0x1012], 354 => 0x21d },
+	'blacklevel2' => { 291 => 0x600, 295 => 0x600 },
+	'blacklevelblue' => { 315 => 0x1e },
+	'blacklevelbottom' => { 135 => 0x3f0 },
+	'blackleveldata' => { 354 => 0x223 },
+	'blackleveldeltah' => { 117 => 0xc61b },
+	'blackleveldeltav' => { 117 => 0xc61c },
+	'blacklevelgreen' => { 315 => 0x1d },
+	'blacklevelred' => { 315 => 0x1c },
+	'blacklevelrepeatdim' => { 117 => 0xc619 },
+	'blacklevelrough' => { 135 => 0x40e },
+	'blacklevelroughafter' => { 135 => 0x416 },
+	'blacklevels' => { 35 => 0x1d },
+	'blackleveltop' => { 135 => 0x3ef },
+	'blackpoint' => { 345 => 0x200 },
+	'blacks2012' => { 467 => 'Blacks2012', 469 => 'Blacks2012' },
+	'blacksadj' => { 444 => 0x9018 },
+	'bleachbypasstoning' => { 345 => 0x7f },
+	'blockshotafresponse' => { 273 => '1.5', 274 => '1.5', 284 => '1.5' },
+	'blogtitle' => { 483 => 'blogTitle' },
+	'blogurl' => { 483 => 'blogURL' },
+	'bluebalance' => { 292 => 0x1018, 315 => 0x12, 345 => 0x1b },
+	'bluecurvelimits' => { 106 => 0x1fe },
+	'bluecurvepoints' => { 105 => 0x79, 106 => 0x1d4 },
+	'bluehsl' => { 101 => 0x20915 },
+	'bluehue' => { 467 => 'BlueHue', 469 => 'BlueHue' },
+	'bluesaturation' => { 467 => 'BlueSaturation', 469 => 'BlueSaturation' },
+	'bluratinfinity' => { 453 => 'BlurAtInfinity' },
+	'blurcontrol' => { 345 => 0x82 },
+	'blurwarning' => { 125 => 0x1300 },
+	'bodybatteryadload' => { 324 => 0x3 },
+	'bodybatteryadnoload' => { 324 => 0x2 },
+	'bodybatterystate' => { 324 => '1.1' },
+	'bodybatteryvoltage1' => { 324 => 0x2 },
+	'bodybatteryvoltage2' => { 324 => 0x4 },
+	'bodybatteryvoltage3' => { 324 => 0x6 },
+	'bodybatteryvoltage4' => { 324 => 0x8 },
+	'bodyfirmware' => { 378 => 0x0 },
+	'bodyfirmwareversion' => { 288 => 0x104, 289 => 0x100, 292 => 0x104 },
+	'bodyserialnumber' => { 378 => 0x10 },
+	'bookedition' => { 483 => 'bookEdition' },
+	'bootloaderversion' => { 372 => 0x26 },
+	'bracketmode' => { 56 => 0x3 },
+	'bracketsequence' => { 111 => 0x301d },
+	'bracketsettings' => { 310 => 0x45 },
+	'bracketshotnumber' => { 56 => 0x5, 326 => 0x9, 408 => 0x2b },
+	'bracketshotnumber2' => { 408 => 0x2d },
+	'bracketstep' => { 177 => 0xe },
+	'bracketvalue' => { 56 => 0x4 },
+	'brightness' => { 117 => 0xfe53, 153 => 'Brightness', 173 => 'Brightness', 177 => 0x2c, 223 => 0x34, 224 => 0x39, 225 => 0x41, 364 => 'player.movie.visual.brightness', 371 => 0x25, 373 => 0x54, 397 => 0x22, 410 => 0x2007, 467 => 'Brightness', 469 => 'Brightness' },
+	'brightnessadj' => { 106 => 0x114, 256 => 0x0, 266 => 0x2d, 444 => 0x8018 },
+	'brightnessvalue' => { 117 => 0x9203, 183 => [0x691,0x49c3], 292 => 0x1003, 415 => 0x1e, 418 => 0x1140, 419 => 0x1140, 420 => 0x111c, 421 => 0x1198, 422 => 0x1174, 423 => 0x102c, 424 => 0x224, 425 => 0x224, 426 => 0x219, 473 => 'BrightnessValue' },
+	'buildnumber' => { 187 => 0x5500 },
+	'bulbduration' => { 75 => 0x18 },
+	'burstcount' => { 135 => 0x40d },
+	'burstid' => { 450 => 'BurstID' },
+	'burstmode' => { 137 => 0xa, 310 => 0x2a },
+	'burstmode2' => { 137 => 0x18 },
+	'burstprimary' => { 450 => 'BurstPrimary' },
+	'burstshot' => { 387 => 0x34 },
+	'burstspeed' => { 310 => 0x77 },
+	'burstuuid' => { 1 => 0xb },
+	'buttonfunctioncontroloff' => { 82 => 0x70a },
+	'bwadjustment' => { 125 => 0x1049 },
+	'bwfilter' => { 177 => 0x2a, 185 => 0x39 },
+	'bwmode' => { 292 => 0x203 },
+	'by-line' => { 129 => 0x50 },
+	'by-linetitle' => { 129 => 0x55 },
+	'bytecount' => { 483 => 'byteCount' },
+	'c14configuration' => { 135 => 0x1964 },
+	'cacheversion' => { 117 => 0xc7aa },
+	'calibratedfocallength' => { 114 => 'CalibratedFocalLength' },
+	'calibratedopticalcenterx' => { 114 => 'CalibratedOpticalCenterX' },
+	'calibratedopticalcentery' => { 114 => 'CalibratedOpticalCenterY' },
+	'calibration' => { 387 => [0x24,0x30] },
+	'calibrationhistory' => { 135 => 0x9c9 },
+	'calibrationilluminant1' => { 117 => 0xc65a },
+	'calibrationilluminant2' => { 117 => 0xc65b },
+	'calibrationversion' => { 135 => 0x9c6 },
+	'callforimage' => { 457 => 'CallForImage' },
+	'camera' => { 447 => [\'Cameras','CamerasCamera'] },
+	'cameraangle' => { 370 => 'angl', 493 => 'cameraAngle' },
+	'cameraappinfo' => { 447 => [\'Cameras','CamerasCameraAppInfo'] },
+	'cameraappinfoapplication' => { 447 => [\'Cameras','CamerasCameraAppInfoApplication'] },
+	'cameraappinfoitemuri' => { 447 => [\'Cameras','CamerasCameraAppInfoItemURI'] },
+	'cameraappinfoversion' => { 447 => [\'Cameras','CamerasCameraAppInfoVersion'] },
+	'cameraburstid' => { 451 => 'CameraBurstID' },
+	'cameracalibration' => { 387 => 0x11f },
+	'cameracalibration1' => { 117 => 0xc623 },
+	'cameracalibration2' => { 117 => 0xc624 },
+	'cameracalibrationsig' => { 117 => 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' => { 447 => [\'Cameras','CamerasCameraDepthMap'] },
+	'cameradepthmapconfidenceuri' => { 447 => [\'Cameras','CamerasCameraDepthMapConfidenceURI'] },
+	'cameradepthmapdepthuri' => { 447 => [\'Cameras','CamerasCameraDepthMapDepthURI'] },
+	'cameradepthmapfar' => { 447 => [\'Cameras','CamerasCameraDepthMapFar'] },
+	'cameradepthmapfocaltable' => { 447 => [\'Cameras','CamerasCameraDepthMapFocalTable'] },
+	'cameradepthmapfocaltableentrycount' => { 447 => [\'Cameras','CamerasCameraDepthMapFocalTableEntryCount'] },
+	'cameradepthmapformat' => { 447 => [\'Cameras','CamerasCameraDepthMapFormat'] },
+	'cameradepthmapitemsemantic' => { 447 => [\'Cameras','CamerasCameraDepthMapItemSemantic'] },
+	'cameradepthmapmeasuretype' => { 447 => [\'Cameras','CamerasCameraDepthMapMeasureType'] },
+	'cameradepthmapnear' => { 447 => [\'Cameras','CamerasCameraDepthMapNear'] },
+	'cameradepthmapsoftware' => { 447 => [\'Cameras','CamerasCameraDepthMapSoftware'] },
+	'cameradepthmapunits' => { 447 => [\'Cameras','CamerasCameraDepthMapUnits'] },
+	'cameradirection' => { 364 => 'direction.facing' },
+	'camerae-mountversion' => { 443 => 0xb },
+	'cameraelevationangle' => { 117 => 0x9405, 474 => 'CameraElevationAngle' },
+	'camerafilename' => { 457 => 'CameraFilename' },
+	'cameraid' => { 292 => 0x209, 370 => 'cmid', 386 => 0x209 },
+	'cameraidentifier' => { 364 => 'camera.identifier' },
+	'cameraimage' => { 447 => [\'Cameras','CamerasCameraImage'] },
+	'cameraimageitemsemantic' => { 447 => [\'Cameras','CamerasCameraImageItemSemantic'] },
+	'cameraimageitemuri' => { 447 => [\'Cameras','CamerasCameraImageItemURI'] },
+	'cameraimagingmodel' => { 447 => [\'Cameras','CamerasCameraImagingModel'] },
+	'cameraimagingmodeldistortion' => { 447 => [\'Cameras','CamerasCameraImagingModelDistortion'] },
+	'cameraimagingmodeldistortioncount' => { 447 => [\'Cameras','CamerasCameraImagingModelDistortionCount'] },
+	'cameraimagingmodelfocallengthx' => { 447 => [\'Cameras','CamerasCameraImagingModelFocalLengthX'] },
+	'cameraimagingmodelfocallengthy' => { 447 => [\'Cameras','CamerasCameraImagingModelFocalLengthY'] },
+	'cameraimagingmodelimageheight' => { 447 => [\'Cameras','CamerasCameraImagingModelImageHeight'] },
+	'cameraimagingmodelimagewidth' => { 447 => [\'Cameras','CamerasCameraImagingModelImageWidth'] },
+	'cameraimagingmodelpixelaspectratio' => { 447 => [\'Cameras','CamerasCameraImagingModelPixelAspectRatio'] },
+	'cameraimagingmodelprincipalpointx' => { 447 => [\'Cameras','CamerasCameraImagingModelPrincipalPointX'] },
+	'cameraimagingmodelprincipalpointy' => { 447 => [\'Cameras','CamerasCameraImagingModelPrincipalPointY'] },
+	'cameraimagingmodelskew' => { 447 => [\'Cameras','CamerasCameraImagingModelSkew'] },
+	'cameraiso' => { 34 => 0x10 },
+	'cameralabel' => { 117 => 0xc7a1, 493 => 'cameraLabel' },
+	'cameralightestimate' => { 447 => [\'Cameras','CamerasCameraLightEstimate'] },
+	'cameralightestimatecolorcorrectionb' => { 447 => [\'Cameras','CamerasCameraLightEstimateColorCorrectionB'] },
+	'cameralightestimatecolorcorrectiong' => { 447 => [\'Cameras','CamerasCameraLightEstimateColorCorrectionG'] },
+	'cameralightestimatecolorcorrectionr' => { 447 => [\'Cameras','CamerasCameraLightEstimateColorCorrectionR'] },
+	'cameralightestimatepixelintensity' => { 447 => [\'Cameras','CamerasCameraLightEstimatePixelIntensity'] },
+	'cameramakemodel' => { 457 => 'CameraMakeModel' },
+	'cameramodel' => { 354 => 0x410, 493 => 'cameraModel' },
+	'cameramodelid' => { 173 => 'CameraModelID' },
+	'cameramodelrestriction' => { 467 => 'CameraModelRestriction', 469 => 'CameraModelRestriction' },
+	'cameramotion' => { 364 => 'direction.motion' },
+	'cameramove' => { 493 => '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,0x3a], 24 => 0x7d, 25 => 0x83, 26 => 0x84, 27 => 0x96, 28 => 0x35, 29 => 0x96, 310 => 0x8f, 349 => 0x1, 354 => 0x100, 403 => [0x16,0x18], 431 => 0x28, 432 => 0x24, 433 => 0x29 },
+	'cameraowner' => { 138 => 0xc353 },
+	'cameraparameters' => { 292 => 0x2050 },
+	'camerapicturestyle' => { 28 => 0xaf },
+	'camerapitch' => { 113 => 0x9, 370 => "\xa9gpt" },
+	'camerapointcloud' => { 447 => [\'Cameras','CamerasCameraPointCloud'] },
+	'camerapointcloudmetric' => { 447 => [\'Cameras','CamerasCameraPointCloudMetric'] },
+	'camerapointcloudpointcloud' => { 447 => [\'Cameras','CamerasCameraPointCloudPointCloud'] },
+	'camerapointcloudpoints' => { 447 => [\'Cameras','CamerasCameraPointCloudPoints'] },
+	'camerapose' => { 447 => [\'Cameras','CamerasCameraPose'] },
+	'cameraposepositionx' => { 447 => [\'Cameras','CamerasCameraPosePositionX'] },
+	'cameraposepositiony' => { 447 => [\'Cameras','CamerasCameraPosePositionY'] },
+	'cameraposepositionz' => { 447 => [\'Cameras','CamerasCameraPosePositionZ'] },
+	'cameraposerotationw' => { 447 => [\'Cameras','CamerasCameraPoseRotationW'] },
+	'cameraposerotationx' => { 447 => [\'Cameras','CamerasCameraPoseRotationX'] },
+	'cameraposerotationy' => { 447 => [\'Cameras','CamerasCameraPoseRotationY'] },
+	'cameraposerotationz' => { 447 => [\'Cameras','CamerasCameraPoseRotationZ'] },
+	'cameraposetimestamp' => { 447 => [\'Cameras','CamerasCameraPoseTimestamp'] },
+	'cameraprofile' => { 467 => 'CameraProfile', 469 => 'CameraProfile' },
+	'cameraprofiledigest' => { 467 => 'CameraProfileDigest', 469 => 'CameraProfileDigest' },
+	'camerarawcolortone' => { 107 => 0xe1 },
+	'camerarawcontrast' => { 107 => 0xe3 },
+	'camerarawhighlightpoint' => { 107 => 0xe6 },
+	'camerarawlinear' => { 107 => 0xe4 },
+	'camerarawoutputhighlightpoint' => { 107 => 0xe8 },
+	'camerarawoutputshadowpoint' => { 107 => 0xe9 },
+	'camerarawsaturation' => { 107 => 0xe2 },
+	'camerarawshadowpoint' => { 107 => 0xe7 },
+	'camerarawsharpness' => { 107 => 0xe5 },
+	'cameraroll' => { 113 => 0xb, 370 => "\xa9grl" },
+	'cameras' => { 447 => 'Cameras' },
+	'cameraserialnumber' => { 117 => 0xc62f, 175 => 'CameraSerialNumber', 457 => 'CameraSerialNumber' },
+	'camerasettingsversion' => { 287 => 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], 75 => 0xc, 135 => 0x406, 291 => 0x1306, 305 => 0x320, 312 => 0x3402, 345 => 0x47, 384 => 0x43, 435 => 0x5 },
+	'cameratemperature4' => { 350 => 0x14 },
+	'cameratemperature5' => { 350 => 0x16 },
+	'cameratemperaturerangemax' => { 119 => 0x5 },
+	'cameratemperaturerangemin' => { 119 => 0x6 },
+	'cameratrait' => { 447 => [\'Cameras','CamerasCameraTrait'] },
+	'cameratype' => { 75 => 0x1a, 292 => 0x207 },
+	'cameratype2' => { 288 => 0x100 },
+	'cameravendorinfo' => { 447 => [\'Cameras','CamerasCameraVendorInfo'] },
+	'cameravendorinfomanufacturer' => { 447 => [\'Cameras','CamerasCameraVendorInfoManufacturer'] },
+	'cameravendorinfomodel' => { 447 => [\'Cameras','CamerasCameraVendorInfoModel'] },
+	'cameravendorinfonotes' => { 447 => [\'Cameras','CamerasCameraVendorInfoNotes'] },
+	'camerayaw' => { 113 => 0xa, 370 => "\xa9gyw" },
+	'camreverse' => { 114 => 'CamReverse' },
+	'canondr4' => { 118 => 'CanonDR4' },
+	'canonexposuremode' => { 34 => 0x14 },
+	'canonfiledescription' => { 95 => 0x805 },
+	'canonfilelength' => { 62 => 0xe },
+	'canonfirmwareversion' => { 62 => 0x7, 95 => 0x80b },
+	'canonflashinfo' => { 95 => 0x1028 },
+	'canonflashmode' => { 34 => 0x4 },
+	'canonimagesize' => { 10 => 0x39, 34 => 0xa },
+	'canonimagetype' => { 62 => 0x6, 95 => 0x815 },
+	'canonmodelid' => { 62 => 0x10, 95 => 0x1834 },
+	'canonvrd' => { 118 => 'CanonVRD' },
+	'caption' => { 462 => 'caption' },
+	'caption-abstract' => { 129 => 0x78 },
+	'captionsauthornames' => { 472 => 'CaptionsAuthorNames' },
+	'captionsdatetimestamps' => { 472 => 'CaptionsDateTimeStamps' },
+	'captionwriter' => { 481 => 'CaptionWriter' },
+	'captureframerate' => { 111 => 0x4001 },
+	'captureheightnormal' => { 135 => 0x1839 },
+	'capturelook' => { 135 => 0xc48 },
+	'capturemode' => { 364 => 'com.apple.photos.captureMode' },
+	'capturesoftware' => { 455 => 'CaptureSoftware' },
+	'capturewidthnormal' => { 135 => 0x1838 },
+	'capturewidthtest' => { 135 => 0x1842 },
+	'cardshutterlock' => { 180 => 0x49 },
+	'casioimagesize' => { 111 => 0x9 },
+	'catalogsets' => { 129 => 0xff, 448 => 'CatalogSets', 460 => 'CatalogSets' },
+	'categories' => { 62 => 0x23, 462 => 'categories' },
+	'category' => { 129 => 0xf, 286 => 0x30, 362 => 'catg', 481 => 'Category' },
+	'cbcrgain' => { 384 => 0xa036 },
+	'cbcrgaindefault' => { 384 => 0xa035 },
+	'cbcrmatrix' => { 384 => 0xa034 },
+	'cbcrmatrixdefault' => { 384 => 0xa033 },
+	'ccdboardversion' => { 305 => 0x331 },
+	'ccdscanmode' => { 292 => 0x1039 },
+	'ccdsensitivity' => { 253 => 0x6 },
+	'ccdversion' => { 305 => 0x330 },
+	'cellglobalid' => { 466 => 'cgi' },
+	'celllength' => { 117 => 0x109 },
+	'cellr' => { 466 => 'r' },
+	'celltowerid' => { 466 => 'cellid' },
+	'cellwidth' => { 117 => 0x108 },
+	'centerafarea' => { 281 => '15.1' },
+	'centerfocuspoint' => { 285 => '2.2' },
+	'centerpixel' => { 135 => 0x40c },
+	'centerweightedareasize' => { 270 => '7.1', 271 => '8.1', 273 => '8.1', 274 => '8.1', 278 => '7.1', 279 => '5.1', 280 => '7.1', 281 => '6.3', 283 => '8.1', 284 => '8.1', 285 => '8.1' },
+	'certificate' => { 497 => 'Certificate' },
+	'cfainterpolationalgorithm' => { 135 => 0xe60 },
+	'cfainterpolationmetric' => { 135 => 0xe61 },
+	'cfaoffsetcols' => { 135 => 0xc71 },
+	'cfaoffsetrows' => { 135 => 0xc6f },
+	'cfapattern' => { 117 => 0xa302, 315 => 0x9, 473 => 'CFAPattern' },
+	'cfapattern2' => { 117 => 0x828e },
+	'cfapatterncolumns' => { 473 => [\'CFAPattern','CFAPatternColumns'] },
+	'cfapatternrows' => { 473 => [\'CFAPattern','CFAPatternRows'] },
+	'cfapatternvalues' => { 473 => [\'CFAPattern','CFAPatternValues'] },
+	'cfarepeatpatterndim' => { 117 => 0x828d },
+	'cfazipperfixthreshold' => { 135 => 0xe62 },
+	'channel' => { 483 => 'channel' },
+	'channela-lang' => { 483 => [\'channel','channelA-lang'] },
+	'channelchannel' => { 483 => [\'channel','channelChannel'] },
+	'channels' => { 152 => 'Channels' },
+	'channelsubchannel1' => { 483 => [\'channel','channelSubchannel1'] },
+	'channelsubchannel2' => { 483 => [\'channel','channelSubchannel2'] },
+	'channelsubchannel3' => { 483 => [\'channel','channelSubchannel3'] },
+	'channelsubchannel4' => { 483 => [\'channel','channelSubchannel4'] },
+	'chapterlist' => { 370 => 'chpl' },
+	'checkmark' => { 101 => 0x10101, 106 => 0x26a },
+	'checkmark2' => { 107 => 0x8e },
+	'childfontfiles' => { 498 => [\'Fonts','FontsChildFontFiles'] },
+	'chmodeshootingspeed' => { 270 => '10.3', 271 => '11.2' },
+	'chromablurradius' => { 117 => 0xc631 },
+	'chromanoisecolorspace' => { 135 => 0xe6d },
+	'chromanoiseedgemapthresh' => { 135 => 0xe6c },
+	'chromanoisehighfthresh' => { 135 => 0xe6a },
+	'chromanoiselowfthresh' => { 135 => 0xe6b },
+	'chromaticaberration' => { 101 => 0x20703, 107 => 0x66, 384 => 0xa051 },
+	'chromaticaberrationb' => { 467 => 'ChromaticAberrationB', 469 => 'ChromaticAberrationB' },
+	'chromaticaberrationblue' => { 101 => 0x20708, 107 => 0x6b },
+	'chromaticaberrationcorr' => { 77 => [0x4,0x5] },
+	'chromaticaberrationcorrection' => { 117 => 0x7034, 335 => 0x1, 444 => 0x900d },
+	'chromaticaberrationcorrparams' => { 117 => 0x7035, 439 => 0x66a, 440 => [0x37c,0x384,0x39c,0x3b0,0x3b8] },
+	'chromaticaberrationon' => { 101 => '0x20703.0', 107 => 0x62 },
+	'chromaticaberrationr' => { 467 => 'ChromaticAberrationR', 469 => 'ChromaticAberrationR' },
+	'chromaticaberrationred' => { 101 => 0x20707, 107 => 0x6a },
+	'chromaticaberrationsetting' => { 78 => 0x6 },
+	'chrominancenoisereduction' => { 101 => 0x20601, 107 => 0x5e, 387 => 0x1a },
+	'chrominancenr_tiff_jpeg' => { 107 => 0x60 },
+	'circadatecreated' => { 479 => 'CircaDateCreated' },
+	'circgradbasedcorractive' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionActive'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionActive'] },
+	'circgradbasedcorramount' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionAmount'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionAmount'] },
+	'circgradbasedcorrblacks2012' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalBlacks2012'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalBlacks2012'] },
+	'circgradbasedcorrbrightness' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalBrightness'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalBrightness'] },
+	'circgradbasedcorrclarity' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity'] },
+	'circgradbasedcorrclarity2012' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity2012'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalClarity2012'] },
+	'circgradbasedcorrcontrast' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast'] },
+	'circgradbasedcorrcontrast2012' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast2012'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalContrast2012'] },
+	'circgradbasedcorrdefringe' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalDefringe'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalDefringe'] },
+	'circgradbasedcorrdehaze' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalDehaze'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalDehaze'] },
+	'circgradbasedcorrexposure' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure'] },
+	'circgradbasedcorrexposure2012' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure2012'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalExposure2012'] },
+	'circgradbasedcorrhighlights2012' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalHighlights2012'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalHighlights2012'] },
+	'circgradbasedcorrhue' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalHue','CircularGradientBasedCorrectionsLocalToningHue'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalHue','CircularGradientBasedCorrectionsLocalToningHue'] },
+	'circgradbasedcorrluminancenoise' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalLuminanceNoise'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalLuminanceNoise'] },
+	'circgradbasedcorrmaskalpha' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAlpha'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAlpha'] },
+	'circgradbasedcorrmaskangle' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAngle'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksAngle'] },
+	'circgradbasedcorrmaskbottom' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksBottom'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksBottom'] },
+	'circgradbasedcorrmaskcentervalue' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterValue'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterValue'] },
+	'circgradbasedcorrmaskcenterweight' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterWeight'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksCenterWeight'] },
+	'circgradbasedcorrmaskdabs' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksDabs'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksDabs'] },
+	'circgradbasedcorrmaskfeather' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFeather'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFeather'] },
+	'circgradbasedcorrmaskflipped' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlipped'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlipped'] },
+	'circgradbasedcorrmaskflow' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlow'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFlow'] },
+	'circgradbasedcorrmaskfullx' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullX'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullX'] },
+	'circgradbasedcorrmaskfully' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullY'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksFullY'] },
+	'circgradbasedcorrmaskleft' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksLeft'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksLeft'] },
+	'circgradbasedcorrmaskmidpoint' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMidpoint'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMidpoint'] },
+	'circgradbasedcorrmaskperimetervalue' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksPerimeterValue'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksPerimeterValue'] },
+	'circgradbasedcorrmaskradius' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRadius'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRadius'] },
+	'circgradbasedcorrmaskright' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRight'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRight'] },
+	'circgradbasedcorrmaskroundness' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRoundness'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksRoundness'] },
+	'circgradbasedcorrmasks' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasks'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasks'] },
+	'circgradbasedcorrmasksizex' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeX'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeX'] },
+	'circgradbasedcorrmasksizey' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeY'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksSizeY'] },
+	'circgradbasedcorrmasktop' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksTop'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksTop'] },
+	'circgradbasedcorrmaskvalue' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMaskValue'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksMaskValue'] },
+	'circgradbasedcorrmaskversion' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksVersion'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksVersion'] },
+	'circgradbasedcorrmaskwhat' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksWhat'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksWhat'] },
+	'circgradbasedcorrmaskx' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksX'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksX'] },
+	'circgradbasedcorrmasky' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksY'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksY'] },
+	'circgradbasedcorrmaskzerox' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroX'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroX'] },
+	'circgradbasedcorrmaskzeroy' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroY'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionMasksZeroY'] },
+	'circgradbasedcorrmoire' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalMoire'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalMoire'] },
+	'circgradbasedcorrrangemask' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMask'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMask'] },
+	'circgradbasedcorrrangemaskcoloramount' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskColorAmount'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskColorAmount'] },
+	'circgradbasedcorrrangemaskdepthfeather' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskDepthFeather'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskDepthFeather'] },
+	'circgradbasedcorrrangemaskdepthmax' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskDepthMax'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskDepthMax'] },
+	'circgradbasedcorrrangemaskdepthmin' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskDepthMin'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskDepthMin'] },
+	'circgradbasedcorrrangemasklumfeather' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskLumFeather'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskLumFeather'] },
+	'circgradbasedcorrrangemasklummax' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskLumMax'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskLumMax'] },
+	'circgradbasedcorrrangemasklummin' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskLumMin'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskLumMin'] },
+	'circgradbasedcorrrangemasktype' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskType'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskType'] },
+	'circgradbasedcorrrangemaskversion' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskVersion'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsCorrectionRangeMaskVersion'] },
+	'circgradbasedcorrsaturation' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSaturation','CircularGradientBasedCorrectionsLocalToningSaturation'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSaturation','CircularGradientBasedCorrectionsLocalToningSaturation'] },
+	'circgradbasedcorrshadows2012' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalShadows2012'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalShadows2012'] },
+	'circgradbasedcorrsharpness' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSharpness'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalSharpness'] },
+	'circgradbasedcorrtemperature' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTemperature'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTemperature'] },
+	'circgradbasedcorrtexture' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTexture'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTexture'] },
+	'circgradbasedcorrtint' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTint'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalTint'] },
+	'circgradbasedcorrwhat' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsWhat'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsWhat'] },
+	'circgradbasedcorrwhites2012' => { 467 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalWhites2012'], 469 => [\'CircularGradientBasedCorrections','CircularGradientBasedCorrectionsLocalWhites2012'] },
+	'circulargradientbasedcorrections' => { 467 => 'CircularGradientBasedCorrections', 469 => 'CircularGradientBasedCorrections' },
+	'city' => { 129 => 0x5a, 158 => 'City', 310 => 0x6d, 481 => 'City' },
+	'city2' => { 310 => 0x80 },
+	'clarity' => { 224 => 0x35, 225 => 0x3d, 467 => 'Clarity', 469 => 'Clarity' },
+	'clarity2012' => { 467 => 'Clarity2012', 469 => 'Clarity2012' },
+	'claritycontrol' => { 345 => 0x96 },
+	'classifystate' => { 129 => 0xe1 },
+	'clearretouch' => { 310 => 0x7c },
+	'clearretouchvalue' => { 310 => 0xa3 },
+	'client' => { 493 => 'client' },
+	'clientname' => { 475 => 'ClientName' },
+	'clipboardaspectratio' => { 467 => 'ClipboardAspectRatio', 469 => 'ClipboardAspectRatio' },
+	'clipboardorientation' => { 467 => 'ClipboardOrientation', 469 => 'ClipboardOrientation' },
+	'clipfilename' => { 370 => 'clfn' },
+	'clipid' => { 370 => 'clid' },
+	'clmodeshootingspeed' => { 270 => '10.2', 271 => '11.3', 273 => '11.2', 274 => '11.2', 279 => '11.2', 280 => '10.2', 283 => '11.2', 284 => '11.2', 285 => '11.1' },
+	'cluster' => { 467 => 'Cluster', 469 => 'Cluster' },
+	'cmcontrast' => { 295 => 0x2022 },
+	'cmexposurecompensation' => { 295 => 0x2000 },
+	'cmhue' => { 295 => 0x2021 },
+	'cmsaturation' => { 295 => 0x2020 },
+	'cmsharpness' => { 295 => 0x2023 },
+	'cmwhitebalance' => { 295 => 0x2001 },
+	'cmwhitebalancecomp' => { 295 => 0x2002 },
+	'cmwhitebalancegraypoint' => { 295 => 0x2010 },
+	'codec' => { 166 => 'Codec' },
+	'codedcharacterset' => { 130 => 0x5a },
+	'codeversion' => { 370 => 'cver' },
+	'collection' => { 300 => 'Collection' },
+	'collectionname' => { 167 => [\'Collections','CollectionsCollectionName'], 370 => 'coll' },
+	'collections' => { 167 => 'Collections', 462 => 'collections' },
+	'collectionuri' => { 167 => [\'Collections','CollectionsCollectionURI'] },
+	'color' => { 364 => 'player.movie.visual.color', 482 => 'color' },
+	'coloraberrationcontrol' => { 263 => 0xc89224b },
+	'coloradjustment' => { 387 => 0x14 },
+	'coloradjustmentmode' => { 386 => 0x210 },
+	'coloranta' => { 498 => [\'Colorants','ColorantsA'] },
+	'colorantb' => { 498 => [\'Colorants','ColorantsB'] },
+	'colorantblack' => { 498 => [\'Colorants','ColorantsBlack'] },
+	'colorantblue' => { 498 => [\'Colorants','ColorantsBlue'] },
+	'colorantcyan' => { 498 => [\'Colorants','ColorantsCyan'] },
+	'colorantgray' => { 498 => [\'Colorants','ColorantsGray'] },
+	'colorantgreen' => { 498 => [\'Colorants','ColorantsGreen'] },
+	'colorantl' => { 498 => [\'Colorants','ColorantsL'] },
+	'colorantmagenta' => { 498 => [\'Colorants','ColorantsMagenta'] },
+	'colorantmode' => { 498 => [\'Colorants','ColorantsMode'] },
+	'colorantred' => { 498 => [\'Colorants','ColorantsRed'] },
+	'colorants' => { 498 => 'Colorants' },
+	'colorantswatchname' => { 498 => [\'Colorants','ColorantsSwatchName'] },
+	'coloranttint' => { 498 => [\'Colorants','ColorantsTint'] },
+	'coloranttype' => { 498 => [\'Colorants','ColorantsType'] },
+	'colorantyellow' => { 498 => [\'Colorants','ColorantsYellow'] },
+	'colorbalance' => { 153 => 'ColorBalance' },
+	'colorbalanceadj' => { 263 => 0x76a43202 },
+	'colorbalanceblue' => { 177 => 0x1e },
+	'colorbalancegreen' => { 177 => 0x1d },
+	'colorbalancered' => { 177 => 0x1c },
+	'colorbalanceversion' => { 198 => 0x4, 199 => 0x4, 200 => 0x0 },
+	'colorblur' => { 107 => 0x65 },
+	'colorbluron' => { 101 => 0x20704 },
+	'colorbooster' => { 263 => 0x5f0e7d23 },
+	'colorboostlevel' => { 257 => 0x1 },
+	'colorboosttype' => { 257 => 0x0 },
+	'colorchromeeffect' => { 125 => 0x1048 },
+	'colorchromefxblue' => { 125 => 0x104e },
+	'colorclass' => { 356 => 0xde, 357 => 'ColorClass' },
+	'colorcompensationfilter' => { 180 => [0x3a,0x5f], 182 => 0x111, 410 => 0xb022 },
+	'colorcompensationfiltercustom' => { 397 => 0xd, 398 => 0xc },
+	'colorcompensationfilterset' => { 397 => 0x8, 398 => 0x7, 399 => 0x18, 415 => 0xf },
+	'colorcontrol' => { 292 => 0x102b },
+	'colorcorrection' => { 444 => 0x8015 },
+	'colorcreatoreffect' => { 287 => 0x532 },
+	'colordataversion' => { 41 => 0x0, 43 => 0x0, 44 => 0x0, 45 => 0x0, 46 => 0x0, 47 => 0x0, 48 => 0x0, 49 => 0x0 },
+	'coloreffect' => { 310 => 0x28 },
+	'colorfilter' => { 110 => 0x17, 111 => 0x3017, 177 => 0x29, 185 => [0x38,0x4d,0x4f], 352 => 0x17 },
+	'colorgain' => { 229 => 0x51 },
+	'colorgradeblending' => { 467 => 'ColorGradeBlending', 469 => 'ColorGradeBlending' },
+	'colorgradeglobalhue' => { 467 => 'ColorGradeGlobalHue', 469 => 'ColorGradeGlobalHue' },
+	'colorgradegloballum' => { 467 => 'ColorGradeGlobalLum', 469 => 'ColorGradeGlobalLum' },
+	'colorgradeglobalsat' => { 467 => 'ColorGradeGlobalSat', 469 => 'ColorGradeGlobalSat' },
+	'colorgradehighlightlum' => { 467 => 'ColorGradeHighlightLum', 469 => 'ColorGradeHighlightLum' },
+	'colorgrademidtonehue' => { 467 => 'ColorGradeMidtoneHue', 469 => 'ColorGradeMidtoneHue' },
+	'colorgrademidtonelum' => { 467 => 'ColorGradeMidtoneLum', 469 => 'ColorGradeMidtoneLum' },
+	'colorgrademidtonesat' => { 467 => 'ColorGradeMidtoneSat', 469 => 'ColorGradeMidtoneSat' },
+	'colorgradeshadowlum' => { 467 => 'ColorGradeShadowLum', 469 => 'ColorGradeShadowLum' },
+	'colorhue' => { 101 => 0x20900, 221 => 0x8d },
+	'colorimetricreference' => { 117 => 0xc6bf },
+	'colorlabel' => { 472 => 'ColorLabel' },
+	'colormatrix' => { 291 => 0x200, 292 => 0x1011, 384 => 0xa030 },
+	'colormatrix1' => { 117 => 0xc621, 354 => 0x106 },
+	'colormatrix2' => { 117 => 0xc622, 295 => 0x200, 354 => 0x226 },
+	'colormatrixa' => { 345 => 0x203 },
+	'colormatrixadobergb' => { 384 => 0xa032 },
+	'colormatrixb' => { 345 => 0x204 },
+	'colormatrixnumber' => { 292 => 0x1019 },
+	'colormatrixsrgb' => { 384 => 0xa031 },
+	'colormode' => { 111 => 0x3015, 125 => 0x1210, 137 => 0x66, 177 => 0x28, 180 => 0x16, 182 => 0x101, 183 => 0x36, 185 => 0x7, 221 => 0x3, 253 => 0x4, 310 => 0x32, 387 => 0x2c, 410 => 0xb029, 481 => 'ColorMode' },
+	'colormoirereduction' => { 101 => 0x20670, 264 => 0x15 },
+	'colormoirereductionmode' => { 264 => 0x5 },
+	'colormoirereductionon' => { 101 => '0x20670.0' },
+	'colornoisereduction' => { 444 => 0x8029, 467 => 'ColorNoiseReduction', 469 => 'ColorNoiseReduction' },
+	'colornoisereductiondetail' => { 467 => 'ColorNoiseReductionDetail', 469 => 'ColorNoiseReductionDetail' },
+	'colornoisereductionintensity' => { 264 => 0x18 },
+	'colornoisereductionsharpness' => { 264 => 0x1c },
+	'colornoisereductionsmoothness' => { 467 => 'ColorNoiseReductionSmoothness', 469 => 'ColorNoiseReductionSmoothness' },
+	'colorplanes' => { 121 => 0x2 },
+	'colorprofile' => { 177 => 0x33 },
+	'colorprofilesettings' => { 287 => 0x539 },
+	'colorrepresentation' => { 131 => 0x3c },
+	'colorsaturationadj' => { 101 => 0x20305 },
+	'colorsequence' => { 131 => 0x41 },
+	'colorspace' => { 50 => 0x3, 62 => 0xb4, 95 => 0x10b4, 117 => 0xa001, 159 => 'ColorSpace', 178 => 0x2f, 179 => 0x25, 180 => 0x17, 221 => 0x1e, 287 => 0x507, 345 => 0x37, 384 => 0xa011, 387 => 0xb, 397 => 0x1b, 398 => 0x83, 399 => 0xe, 415 => 0x6, 473 => 'ColorSpace' },
+	'colortempasshot' => { 38 => 0x4, 39 => 0x7, 40 => 0x1d, 41 => 0x59, 42 => 0x26, 43 => 0x43, 46 => 0x43, 47 => 0x43, 48 => 0x43, 49 => 0x4b },
+	'colortempauto' => { 38 => 0x9, 39 => 0xf, 40 => 0x22, 41 => 0x5e, 42 => 0x1c, 43 => 0x48, 46 => 0x48, 47 => 0x48, 48 => 0x48, 49 => 0x50 },
+	'colortempcloudy' => { 38 => 0x22, 39 => 0x37, 40 => 0x31, 41 => 0xa4, 42 => 0x35, 43 => 0x5c, 46 => 0x75, 47 => 0x8e, 48 => 0x93, 49 => 0x96, 345 => 0x55 },
+	'colortempcustom' => { 43 => 0x84 },
+	'colortempcustom1' => { 40 => 0x45 },
+	'colortempcustom2' => { 40 => 0x4a },
+	'colortempdaylight' => { 38 => 0x18, 39 => 0x27, 40 => 0x27, 41 => 0x9a, 42 => 0x2b, 43 => 0x52, 46 => 0x6b, 47 => 0x84, 48 => 0x89, 49 => 0x8c, 345 => 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, 62 => 0xae, 72 => 0x9, 95 => 0x10ae, 125 => 0x1005, 135 => 0x846, 153 => 'ColorTemperature', 178 => [0x6e,0x49], 179 => 0x3f, 180 => [0x39,0x5e], 182 => 0x10b, 185 => [0x3c,0x4c,0x4e], 305 => 0x321, 345 => 0x50, 377 => 0x1308, 410 => 0xb021, 467 => 'Temperature', 469 => 'Temperature' },
+	'colortemperatureadj' => { 444 => 0x8013 },
+	'colortemperatureauto' => { 221 => 0x4f },
+	'colortemperaturebg' => { 292 => 0x1013 },
+	'colortemperaturecustom' => { 397 => 0xc, 398 => 0xb },
+	'colortemperaturerg' => { 292 => 0x1014 },
+	'colortemperatureset' => { 397 => 0x7, 398 => 0x6 },
+	'colortemperaturesetting' => { 180 => 0x25, 399 => 0x17, 415 => 0xe },
+	'colortempflash' => { 38 => 0x36, 39 => 0x57, 40 => 0x40, 41 => 0xb8, 42 => 0x49, 43 => 0x70, 46 => 0x89, 47 => 0xa2, 48 => 0xa7, 49 => 0xaa, 345 => 0x5a },
+	'colortempflashdata' => { 43 => 0x24a },
+	'colortempfluorescent' => { 38 => 0x2c, 39 => 0x47, 40 => 0x3b, 41 => 0xae, 42 => 0x3f, 43 => 0x66, 46 => 0x7f, 47 => 0x98, 48 => 0x9d, 49 => 0xa0 },
+	'colortempfluorescentd' => { 345 => 0x57 },
+	'colortempfluorescentn' => { 345 => 0x58 },
+	'colortempfluorescentw' => { 345 => 0x59 },
+	'colortempkelvin' => { 38 => 0x31, 39 => 0x4f, 41 => 0xb3, 42 => 0x44, 43 => 0x6b, 46 => 0x84, 47 => 0x9d, 48 => 0xa2, 49 => 0xa5, 310 => 0x44, 377 => 0x1307 },
+	'colortempmeasured' => { 38 => 0xe, 39 => 0x17, 41 => 0x63, 43 => 0x4d, 46 => 0x4d, 47 => 0x4d, 48 => 0x4d, 49 => 0x55 },
+	'colortemppc1' => { 42 => 0x94, 43 => 0x75 },
+	'colortemppc2' => { 42 => 0x99, 43 => 0x7a },
+	'colortemppc3' => { 42 => 0x9e, 43 => 0x7f },
+	'colortempshade' => { 38 => 0x1d, 39 => 0x2f, 40 => 0x2c, 41 => 0x9f, 42 => 0x30, 43 => 0x57, 46 => 0x70, 47 => 0x89, 48 => 0x8e, 49 => 0x91, 345 => 0x54 },
+	'colortemptungsten' => { 38 => 0x27, 39 => 0x3f, 40 => 0x36, 41 => 0xa9, 42 => 0x3a, 43 => 0x61, 46 => 0x7a, 47 => 0x93, 48 => 0x98, 49 => 0x9b, 345 => 0x56 },
+	'colortempunknown' => { 38 => 0x13, 39 => 0x1f, 41 => 0x68, 42 => 0x21, 46 => 0x52, 47 => 0x52, 48 => 0x52, 49 => 0x5a },
+	'colortempunknown10' => { 38 => 0x63, 39 => 0x9f, 41 => 0x95, 42 => 0x76, 46 => 0xa2, 47 => 0x7f, 48 => 0x7f, 49 => 0x87 },
+	'colortempunknown11' => { 38 => 0x68, 39 => 0xa7, 41 => 0xbd, 42 => 0x7b, 46 => 0xa7, 47 => 0xa7, 48 => 0x84, 49 => 0xaf },
+	'colortempunknown12' => { 38 => 0x6d, 39 => 0xaf, 41 => 0xc2, 42 => 0x80, 46 => 0xac, 47 => 0xac, 48 => 0xac, 49 => 0xb4 },
+	'colortempunknown13' => { 38 => 0x72, 39 => 0xb7, 41 => 0xc7, 42 => 0x85, 46 => 0xb1, 47 => 0xb1, 48 => 0xb1, 49 => 0xb9 },
+	'colortempunknown14' => { 41 => 0xcc, 42 => 0x8a, 46 => 0xb6, 47 => 0xb6, 48 => 0xb6, 49 => 0xbe },
+	'colortempunknown15' => { 41 => 0xd1, 42 => 0x8f, 46 => 0xbb, 47 => 0xbb, 48 => 0xbb, 49 => 0xc3 },
+	'colortempunknown16' => { 41 => 0xd6, 42 => 0xa3, 47 => 0xc0, 48 => 0xc0, 49 => 0xc8 },
+	'colortempunknown17' => { 41 => 0xdb, 47 => 0xc5, 48 => 0xc5, 49 => 0xcd },
+	'colortempunknown18' => { 41 => 0xe0, 47 => 0xca, 48 => 0xca, 49 => 0xd2 },
+	'colortempunknown19' => { 41 => 0xe5, 47 => 0xcf, 48 => 0xcf, 49 => 0xd7 },
+	'colortempunknown2' => { 38 => 0x3b, 39 => 0x5f, 41 => 0x6d, 42 => 0x4e, 46 => 0x57, 47 => 0x57, 48 => 0x57, 49 => 0x5f },
+	'colortempunknown20' => { 41 => 0xea, 47 => 0xd4, 48 => 0xd4, 49 => 0xdc },
+	'colortempunknown21' => { 41 => 0xef, 48 => 0xd9, 49 => 0xe1 },
+	'colortempunknown22' => { 41 => 0xf4, 48 => 0xde, 49 => 0xe6 },
+	'colortempunknown23' => { 41 => 0xf9, 48 => 0xe3, 49 => 0xeb },
+	'colortempunknown24' => { 41 => 0xfe, 48 => 0xe8, 49 => 0xf0 },
+	'colortempunknown25' => { 41 => 0x103, 48 => 0xed, 49 => 0xf5 },
+	'colortempunknown26' => { 41 => 0x108, 48 => 0xf2, 49 => 0xfa },
+	'colortempunknown27' => { 41 => 0x10d, 48 => 0xf7, 49 => 0xff },
+	'colortempunknown28' => { 41 => 0x112, 48 => 0xfc, 49 => 0x104 },
+	'colortempunknown29' => { 41 => 0x117, 48 => 0x101, 49 => 0x109 },
+	'colortempunknown3' => { 38 => 0x40, 39 => 0x67, 41 => 0x72, 42 => 0x53, 46 => 0x5c, 47 => 0x5c, 48 => 0x5c, 49 => 0x64 },
+	'colortempunknown30' => { 48 => 0x106 },
+	'colortempunknown4' => { 38 => 0x45, 39 => 0x6f, 41 => 0x77, 42 => 0x58, 46 => 0x61, 47 => 0x61, 48 => 0x61, 49 => 0x69 },
+	'colortempunknown5' => { 38 => 0x4a, 39 => 0x77, 41 => 0x7c, 42 => 0x5d, 46 => 0x66, 47 => 0x66, 48 => 0x66, 49 => 0x6e },
+	'colortempunknown6' => { 38 => 0x4f, 39 => 0x7f, 41 => 0x81, 42 => 0x62, 46 => 0x8e, 47 => 0x6b, 48 => 0x6b, 49 => 0x73 },
+	'colortempunknown7' => { 38 => 0x54, 39 => 0x87, 41 => 0x86, 42 => 0x67, 46 => 0x93, 47 => 0x70, 48 => 0x70, 49 => 0x78 },
+	'colortempunknown8' => { 38 => 0x59, 39 => 0x8f, 41 => 0x8b, 42 => 0x6c, 46 => 0x98, 47 => 0x75, 48 => 0x75, 49 => 0x7d },
+	'colortempunknown9' => { 38 => 0x5e, 39 => 0x97, 41 => 0x90, 42 => 0x71, 46 => 0x9d, 47 => 0x7a, 48 => 0x7a, 49 => 0x82 },
+	'colortone' => { 10 => 0x6f, 12 => 0x77, 34 => 0x2a, 50 => 0x2 },
+	'colortoneadj' => { 101 => 0x20304, 106 => 0x11e },
+	'colortoneauto' => { 69 => 0x9c },
+	'colortonefaithful' => { 19 => 0x107, 68 => 0x6c, 69 => 0x6c },
+	'colortonelandscape' => { 19 => 0x105, 68 => 0x3c, 69 => 0x3c },
+	'colortonemonochrome' => { 68 => 0x84, 69 => 0x84 },
+	'colortoneneutral' => { 19 => 0x106, 68 => 0x54, 69 => 0x54 },
+	'colortoneportrait' => { 19 => 0x104, 68 => 0x24, 69 => 0x24 },
+	'colortonestandard' => { 19 => 0x103, 68 => 0xc, 69 => 0xc },
+	'colortoneuserdef1' => { 19 => 0x109, 68 => 0x9c, 69 => 0xb4 },
+	'colortoneuserdef2' => { 19 => 0x10a, 68 => 0xb4, 69 => 0xcc },
+	'colortoneuserdef3' => { 19 => 0x10b, 68 => 0xcc, 69 => 0xe4 },
+	'comlenblksize' => { 135 => 0xfde8 },
+	'commanddials' => { 281 => '5.1' },
+	'commanddialsaperturesetting' => { 270 => '17.3', 271 => '18.3', 273 => '18.3', 274 => '18.3', 279 => '33.3', 280 => '17.3', 283 => '18.3', 284 => '18.3' },
+	'commanddialschangemainsub' => { 270 => '17.2', 271 => '18.1', 273 => '18.1', 274 => '18.1', 279 => '33.2', 280 => '17.2', 283 => '18.1', 284 => '18.1' },
+	'commanddialsmenuandplayback' => { 270 => '17.4', 271 => '18.2', 273 => '18.2', 274 => '18.2', 279 => '33.4', 280 => '17.4', 283 => '18.2', 284 => '18.2' },
+	'commanddialsreverserotation' => { 270 => '17.1', 271 => '6.4', 273 => '6.2', 274 => '6.2', 275 => '16.2', 276 => '17.2', 279 => '33.1', 280 => '17.1', 283 => '6.2', 284 => '6.2', 285 => '18.1' },
+	'commanderchannel' => { 281 => '10.2', 282 => '25.2' },
+	'commandergroupa_ttl-aacomp' => { 281 => '13.1', 282 => '31.1' },
+	'commandergroupa_ttlcomp' => { 285 => '32.1' },
+	'commandergroupamanualoutput' => { 281 => '13.2', 282 => '28.2' },
+	'commandergroupamode' => { 281 => '11.2', 282 => '28.1' },
+	'commandergroupb_ttl-aacomp' => { 281 => '14.1', 282 => '32.1' },
+	'commandergroupb_ttlcomp' => { 285 => '33.1' },
+	'commandergroupbmanualoutput' => { 281 => '14.2', 282 => '29.2' },
+	'commandergroupbmode' => { 281 => '11.3', 282 => '29.1' },
+	'commanderinternalflash' => { 281 => '11.1', 282 => '27.1' },
+	'commanderinternalmanualoutput' => { 281 => '12.2', 282 => '27.2' },
+	'commanderinternalttlchannel' => { 279 => '18.2' },
+	'commanderinternalttlcomp' => { 281 => '12.1', 282 => '30.2', 285 => '31.2' },
+	'commanderinternalttlcompbuiltin' => { 279 => '20.1', 280 => '26.1' },
+	'commanderinternalttlcompgroupa' => { 279 => '21.1', 280 => '27.1' },
+	'commanderinternalttlcompgroupb' => { 279 => '22.1', 280 => '28.1' },
+	'comment' => { 0 => 0x2, 118 => 'Comment', 154 => 'Comment', 300 => 'Comment', 362 => "\xa9cmt", 364 => 'comment', 370 => "\xa9cmt" },
+	'compass' => { 380 => 0x4 },
+	'compilation' => { 362 => 'cpil' },
+	'compimageimagespersequence' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesNumberOfImagesInSequences'] },
+	'compimagemaxexposureall' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesMaxExposureTimesOfAll'] },
+	'compimagemaxexposureused' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesMaxExposureTimesOfUsed'] },
+	'compimageminexposureall' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesMinExposureTimesOfAll'] },
+	'compimageminexposureused' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesMinExposureTimesOfUsed'] },
+	'compimagenumsequences' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesNumberOfSequences'] },
+	'compimagesumexposureall' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesSumOfExposureTimesOfAll'] },
+	'compimagesumexposureused' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesSumOfExposureTimesOfUsed'] },
+	'compimagetotalexposureperiod' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesTotalExposurePeriod'] },
+	'compimagevalues' => { 474 => [\'CompositeImageExposureTimes','CompositeImageExposureTimesValues'] },
+	'complianceprofile' => { 483 => 'complianceProfile' },
+	'componentsconfiguration' => { 117 => 0x9101, 159 => 'Components', 473 => 'ComponentsConfiguration' },
+	'componentversion' => { 95 => 0x80c },
+	'composer' => { 362 => ["\xa9com","\xa9wrt"], 370 => ["\xa9com","\xa9wrt"], 493 => 'composer' },
+	'composerkeywords' => { 370 => "\xa9cok" },
+	'compositeimage' => { 117 => 0xa460, 474 => 'CompositeImage' },
+	'compositeimagecount' => { 117 => 0xa461, 474 => 'CompositeImageCount' },
+	'compositeimageexposuretimes' => { 117 => 0xa462, 474 => 'CompositeImageExposureTimes' },
+	'composition' => { 457 => 'Composition' },
+	'compositionadjust' => { 344 => '0.1' },
+	'compositionadjustrotation' => { 344 => 0x7 },
+	'compositionadjustx' => { 344 => 0x5 },
+	'compositionadjusty' => { 344 => 0x6 },
+	'compressedbitsperpixel' => { 117 => 0x9102, 473 => 'CompressedBitsPerPixel' },
+	'compressedimagesize' => { 182 => 0x40, 292 => 0x40 },
+	'compression' => { 117 => 0x103, 315 => 0xb, 489 => 'Compression' },
+	'compressionfactor' => { 287 => 0x50d },
+	'compressionratio' => { 159 => 'Compression', 292 => 0x1034 },
+	'compressorversion' => { 370 => 'CNCV' },
+	'condadobvfactor' => { 135 => 0xf3e },
+	'condadodaybvthresh' => { 135 => 0xf3c },
+	'condadodayoffsets' => { 135 => 0xf42 },
+	'condadofluoffsets' => { 135 => 0xf44 },
+	'condadofluthresh' => { 135 => 0xf41 },
+	'condadoillfactor' => { 135 => 0xf3f },
+	'condadoneurange' => { 135 => 0xf3d },
+	'condadotunoffsets' => { 135 => 0xf43 },
+	'condadotunthresh' => { 135 => 0xf40 },
+	'conductor' => { 362 => "\xa9con" },
+	'confidence' => { 452 => 'Confidence' },
+	'confidencelevel' => { 463 => 'ConfidenceLevel' },
+	'confidencemime' => { 452 => 'ConfidenceMime' },
+	'constrainedcropheight' => { 106 => 0x266, 356 => 0xd6 },
+	'constrainedcropwidth' => { 106 => 0x262, 356 => 0xd5 },
+	'contact' => { 129 => 0x76 },
+	'contactinfo' => { 467 => 'ContactInfo', 469 => 'ContactInfo', 482 => 'contactInfo' },
+	'container' => { 447 => 'Container' },
+	'containerdirectory' => { 447 => [\'Container','ContainerDirectory'] },
+	'containerdirectoryitem' => { 447 => [\'Container','ContainerDirectoryItem'] },
+	'containerdirectoryitemdatauri' => { 447 => [\'Container','ContainerDirectoryItemDataURI'] },
+	'containerdirectoryitemlength' => { 447 => [\'Container','ContainerDirectoryItemLength'] },
+	'containerdirectoryitemmime' => { 447 => [\'Container','ContainerDirectoryItemMime'] },
+	'containerdirectoryitempadding' => { 447 => [\'Container','ContainerDirectoryItemPadding'] },
+	'containerformat' => { 479 => 'ContainerFormat' },
+	'containerformatidentifier' => { 479 => [\'ContainerFormat','ContainerFormatIdentifier'] },
+	'containerformatname' => { 479 => [\'ContainerFormat','ContainerFormatName'] },
+	'contentcreatedate' => { 362 => "\xa9day", 370 => ['@day',"\xa9day"] },
+	'contentdistributorid' => { 370 => 'cdis' },
+	'contentid' => { 370 => 'ccid' },
+	'contentlocationcode' => { 129 => 0x1a },
+	'contentlocationname' => { 129 => 0x1b },
+	'contenttype' => { 483 => 'contentType' },
+	'continuousbracketing' => { 180 => 0x20 },
+	'continuousdrive' => { 34 => 0x5 },
+	'continuousmodeliveview' => { 284 => '77.2' },
+	'continuousshootingspeed' => { 82 => 0x610 },
+	'continuousshotlimit' => { 82 => 0x611 },
+	'contrast' => { 10 => 0x73, 12 => 0x75, 34 => 0xd, 110 => 0xc, 111 => [0x3012,0x20], 117 => [0xa408,0xfe54], 125 => [0x1004,0x1006], 153 => 'Contrast', 173 => 'Contrast', 177 => 0x20, 178 => 0x31, 179 => 0x27, 180 => 0x19, 185 => 0x2, 223 => 0x33, 224 => 0x37, 225 => 0x3f, 292 => 0x1029, 310 => 0x39, 312 => 0x300a, 345 => 0x20, 352 => 0xc, 364 => 'player.movie.visual.contrast', 371 => 0x24, 373 => 0x52, 377 => 0x1012, 387 => 0xd, 397 => 0x1d, 398 => 0x1a, 410 => 0x2004, 467 => 'Contrast', 469 => 'Contrast', 473 => 'Contrast' },
+	'contrast2012' => { 467 => 'Contrast2012', 469 => 'Contrast2012' },
+	'contrastadj' => { 101 => 0x20303, 106 => 0x115, 266 => 0x2c, 444 => 0x8017 },
+	'contrastauto' => { 69 => 0x90 },
+	'contrastcurve' => { 221 => 0x8c },
+	'contrastdetectaf' => { 189 => 0x4 },
+	'contrastdetectafarea' => { 345 => 0x231 },
+	'contrastdetectafinfocus' => { 189 => [0x1c,0x52] },
+	'contrastfaithful' => { 19 => 0xec, 68 => 0x60, 69 => 0x60 },
+	'contrasthighlight' => { 345 => 0x6d },
+	'contrasthighlightshadowadj' => { 345 => 0x6f },
+	'contrastlandscape' => { 19 => 0xea, 68 => 0x30, 69 => 0x30 },
+	'contrastmode' => { 310 => 0x2c },
+	'contrastmonochrome' => { 19 => 0xed, 68 => 0x78, 69 => 0x78 },
+	'contrastneutral' => { 19 => 0xeb, 68 => 0x48, 69 => 0x48 },
+	'contrastportrait' => { 19 => 0xe9, 68 => 0x18, 69 => 0x18 },
+	'contrastsetting' => { 287 => 0x505, 295 => 0x1012, 399 => 0x10, 415 => 0x8 },
+	'contrastshadow' => { 345 => 0x6e },
+	'contraststandard' => { 19 => 0xe8, 68 => 0x0, 69 => 0x0 },
+	'contrastuserdef1' => { 19 => 0xee, 68 => 0x90, 69 => 0xa8 },
+	'contrastuserdef2' => { 19 => 0xef, 68 => 0xa8, 69 => 0xc0 },
+	'contrastuserdef3' => { 19 => 0xf0, 68 => 0xc0, 69 => 0xd8 },
+	'contributedmedia' => { 493 => 'contributedMedia' },
+	'contributedmediaduration' => { 493 => [\'contributedMedia','contributedMediaDuration'] },
+	'contributedmediadurationscale' => { 493 => [\'contributedMedia','contributedMediaDurationScale'] },
+	'contributedmediadurationvalue' => { 493 => [\'contributedMedia','contributedMediaDurationValue'] },
+	'contributedmediamanaged' => { 493 => [\'contributedMedia','contributedMediaManaged'] },
+	'contributedmediapath' => { 493 => [\'contributedMedia','contributedMediaPath'] },
+	'contributedmediastarttime' => { 493 => [\'contributedMedia','contributedMediaStartTime'] },
+	'contributedmediastarttimescale' => { 493 => [\'contributedMedia','contributedMediaStartTimeScale'] },
+	'contributedmediastarttimevalue' => { 493 => [\'contributedMedia','contributedMediaStartTimeValue'] },
+	'contributedmediatrack' => { 493 => [\'contributedMedia','contributedMediaTrack'] },
+	'contributedmediawebstatement' => { 493 => [\'contributedMedia','contributedMediaWebStatement'] },
+	'contributor' => { 470 => 'contributor', 479 => 'Contributor' },
+	'contributoridentifier' => { 479 => [\'Contributor','ContributorIdentifier'] },
+	'contributorname' => { 479 => [\'Contributor','ContributorName'] },
+	'contributorrole' => { 479 => [\'Contributor','ContributorRole'] },
+	'contributors' => { 154 => 'Contributors' },
+	'controldialset' => { 180 => 0x46 },
+	'controlledvocabularyterm' => { 479 => 'CVterm' },
+	'controllerboardversion' => { 305 => 0x332 },
+	'controlmode' => { 75 => 0x12 },
+	'controlringrotation' => { 82 => 0x712 },
+	'conversionlens' => { 288 => 0x403, 310 => 0x35 },
+	'converter' => { 117 => 0xfe4d, 253 => 0xb, 467 => 'Converter', 469 => 'Converter' },
+	'converttograyscale' => { 467 => 'ConvertToGrayscale', 469 => 'ConvertToGrayscale' },
+	'cookingequipment' => { 485 => 'cookingEquipment' },
+	'cookingmethod' => { 485 => 'cookingMethod' },
+	'copyright' => { 0 => 0x3, 117 => 0x8298, 154 => 'Copyright', 300 => 'Copyright', 345 => 0x22f, 361 => 'Copyright', 362 => ['cprt',"\xa9cpy"], 364 => 'copyright', 370 => ['cprt',"\xa9cpy"], 467 => 'Copyright', 469 => 'Copyright', 480 => 'Copyright', 486 => 'copyright', 489 => 'Copyright', 493 => 'copyright' },
+	'copyrightflag' => { 359 => 0x40a },
+	'copyrightnotice' => { 129 => 0x74 },
+	'copyrightowner' => { 297 => 'CopyrightOwner' },
+	'copyrightownerid' => { 297 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerID'] },
+	'copyrightownerimageid' => { 297 => 'CopyrightOwnerImageID' },
+	'copyrightownername' => { 297 => [\'CopyrightOwner','CopyrightOwnerCopyrightOwnerName'] },
+	'copyrightregistrationnumber' => { 297 => 'CopyrightRegistrationNumber' },
+	'copyrightstatus' => { 297 => 'CopyrightStatus' },
+	'copyrightyear' => { 479 => 'CopyrightYear', 483 => 'copyrightYear' },
+	'coringfilter' => { 291 => 0x310, 292 => 0x102d, 295 => 0x310 },
+	'coringvalues' => { 291 => 0x311, 295 => 0x311 },
+	'corporateentity' => { 483 => 'corporateEntity' },
+	'country' => { 158 => 'Country', 310 => 0x69, 481 => 'Country' },
+	'country-primarylocationcode' => { 129 => 0x64 },
+	'country-primarylocationname' => { 129 => 0x65 },
+	'countrycode' => { 220 => 0x5, 357 => 'CountryCode', 478 => 'CountryCode' },
+	'course' => { 485 => 'course' },
+	'coverage' => { 470 => 'coverage' },
+	'coverart' => { 362 => 'covr' },
+	'coverdate' => { 483 => 'coverDate' },
+	'coverdisplaydate' => { 483 => 'coverDisplayDate' },
+	'coveruri' => { 370 => 'cvru' },
+	'cpufirmwareversion' => { 345 => 0x28 },
+	'crc32' => { 471 => 'crc32' },
+	'createdate' => { 117 => 0x9004, 154 => 'CreateDate', 296 => 'CreationDate', 300 => 'create-date', 361 => 'CreationDate', 367 => 0x1, 491 => 'CreateDate' },
+	'creationdate' => { 364 => 'creationdate', 480 => 'CreationDate', 483 => 'creationDate' },
+	'creationtime' => { 300 => 'Creation Time' },
+	'creativestyle' => { 397 => 0x1a, 398 => 0x18, 408 => 0x41, 410 => 0xb020, 440 => 0x4a },
+	'creativestylesetting' => { 399 => 0xf, 415 => 0x7 },
+	'creativestylewaschanged' => { 444 => 0x8001 },
+	'creator' => { 296 => 'Creator', 361 => 'Creator', 470 => 'creator', 479 => 'Creator', 480 => 'Creator' },
+	'creatoraddress' => { 478 => [\'CreatorContactInfo','CreatorContactInfoCiAdrExtadr'] },
+	'creatorappid' => { 175 => 'CreatorAppId' },
+	'creatorcity' => { 478 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCity'] },
+	'creatorcontactinfo' => { 478 => 'CreatorContactInfo' },
+	'creatorcountry' => { 478 => [\'CreatorContactInfo','CreatorContactInfoCiAdrCtry'] },
+	'creatoridentifier' => { 479 => [\'Creator','CreatorIdentifier'] },
+	'creatorname' => { 479 => [\'Creator','CreatorName'] },
+	'creatoropenwithuioptions' => { 175 => 'CreatorOpenWithUIOptions' },
+	'creatorpostalcode' => { 478 => [\'CreatorContactInfo','CreatorContactInfoCiAdrPcode'] },
+	'creatorregion' => { 478 => [\'CreatorContactInfo','CreatorContactInfoCiAdrRegion'] },
+	'creatorrole' => { 479 => [\'Creator','CreatorRole'] },
+	'creatortool' => { 491 => 'CreatorTool' },
+	'creatorworkemail' => { 478 => [\'CreatorContactInfo','CreatorContactInfoCiEmailWork'] },
+	'creatorworktelephone' => { 478 => [\'CreatorContactInfo','CreatorContactInfoCiTelWork'] },
+	'creatorworkurl' => { 478 => [\'CreatorContactInfo','CreatorContactInfoCiUrlWork'] },
+	'credit' => { 129 => 0x6e, 481 => 'Credit' },
+	'creditline' => { 486 => 'creditLine' },
+	'creditlinereq' => { 496 => 'CreditLineReq' },
+	'creditlinerequired' => { 297 => 'CreditLineRequired' },
+	'cropactive' => { 99 => 0x0, 106 => 0x244 },
+	'cropangle' => { 467 => 'CropAngle', 469 => 'CropAngle' },
+	'croparea' => { 221 => 0x45, 444 => 0x9011 },
+	'cropaspectratio' => { 101 => 0x30101, 106 => 0x260 },
+	'cropaspectratiocustom' => { 101 => 0x30102 },
+	'cropbottom' => { 121 => 0x9, 258 => 0x36, 315 => 0x31, 356 => 0xdc, 467 => 'CropBottom', 469 => 'CropBottom' },
+	'cropbottommargin' => { 52 => 0x3 },
+	'cropcircleactive' => { 107 => 0xd6 },
+	'cropcircleradius' => { 107 => 0xd9 },
+	'cropcirclex' => { 107 => 0xd7 },
+	'cropcircley' => { 107 => 0xd8 },
+	'cropconstraintowarp' => { 467 => 'CropConstrainToWarp', 469 => 'CropConstrainToWarp' },
+	'croph' => { 461 => 'CropH' },
+	'cropheight' => { 99 => 0x6, 106 => 0x24c, 291 => 0x615, 295 => 0x615, 467 => 'CropHeight', 469 => 'CropHeight' },
+	'crophispeed' => { 221 => 0x1b },
+	'cropleft' => { 106 => 0x246, 121 => 0x6, 258 => 0x1e, 291 => 0x612, 295 => 0x612, 315 => 0x30, 356 => 0xd9, 467 => 'CropLeft', 469 => 'CropLeft' },
+	'cropleftmargin' => { 52 => 0x0 },
+	'cropmode' => { 125 => 0x104d, 377 => 0x1018 },
+	'croporiginalheight' => { 99 => 0xb },
+	'croporiginalwidth' => { 99 => 0xa },
+	'cropoutputheight' => { 258 => 0xce },
+	'cropoutputheightinches' => { 258 => 0x96 },
+	'cropoutputpixels' => { 258 => 0xd6 },
+	'cropoutputresolution' => { 258 => 0xb6 },
+	'cropoutputscale' => { 258 => 0xbe },
+	'cropoutputwidth' => { 258 => 0xc6 },
+	'cropoutputwidthinches' => { 258 => 0x8e },
+	'croppedareaimageheightpixels' => { 455 => 'CroppedAreaImageHeightPixels', 456 => 'CroppedAreaImageHeightPixels' },
+	'croppedareaimagewidthpixels' => { 455 => 'CroppedAreaImageWidthPixels', 456 => 'CroppedAreaImageWidthPixels' },
+	'croppedarealeftpixels' => { 455 => 'CroppedAreaLeftPixels', 456 => 'CroppedAreaLeftPixels' },
+	'croppedareatoppixels' => { 455 => 'CroppedAreaTopPixels', 456 => 'CroppedAreaTopPixels' },
+	'croppedimageheight' => { 5 => 0x2, 377 => 0x1604 },
+	'croppedimageleft' => { 5 => 0x3 },
+	'croppedimagetop' => { 5 => 0x4 },
+	'croppedimagewidth' => { 5 => 0x1, 377 => 0x1603 },
+	'cropping' => { 444 => 0x9010 },
+	'cropright' => { 121 => 0x8, 258 => 0x2e, 315 => 0x32, 356 => 0xdb, 467 => 'CropRight', 469 => 'CropRight' },
+	'croprightmargin' => { 52 => 0x1 },
+	'croprotatedoriginalheight' => { 99 => 0x2 },
+	'croprotatedoriginalwidth' => { 99 => 0x1 },
+	'croprotation' => { 99 => 0x8, 121 => 0xb },
+	'cropscaledresolution' => { 258 => 0x9e },
+	'cropsourceresolution' => { 258 => 0xae },
+	'croptop' => { 106 => 0x248, 121 => 0x7, 258 => 0x26, 291 => 0x613, 295 => 0x613, 315 => 0x2f, 356 => 0xda, 467 => 'CropTop', 469 => 'CropTop' },
+	'croptopmargin' => { 52 => 0x2 },
+	'cropunit' => { 467 => 'CropUnit', 469 => 'CropUnit' },
+	'cropunits' => { 467 => 'CropUnits', 469 => 'CropUnits' },
+	'cropw' => { 461 => 'CropW' },
+	'cropwidth' => { 99 => 0x5, 106 => 0x24a, 291 => 0x614, 295 => 0x614, 467 => 'CropWidth', 469 => 'CropWidth' },
+	'cropx' => { 99 => 0x3, 461 => 'CropX' },
+	'cropy' => { 99 => 0x4, 461 => 'CropY' },
+	'crossprocess' => { 345 => 0x7b },
+	'crossprocessparams' => { 345 => 0x235 },
+	'cuisine' => { 485 => 'cuisine' },
+	'currenticcprofile' => { 117 => 0xc691 },
+	'currentpreprofilematrix' => { 117 => 0xc692 },
+	'currentversion' => { 444 => 0xd000 },
+	'curve0x' => { 461 => 'Curve0x' },
+	'curve0y' => { 461 => 'Curve0y' },
+	'curve1x' => { 461 => 'Curve1x' },
+	'curve1y' => { 461 => 'Curve1y' },
+	'curve2x' => { 461 => 'Curve2x' },
+	'curve2y' => { 461 => 'Curve2y' },
+	'curve3x' => { 461 => 'Curve3x' },
+	'curve3y' => { 461 => 'Curve3y' },
+	'curve4x' => { 461 => 'Curve4x' },
+	'curve4y' => { 461 => 'Curve4y' },
+	'curves' => { 263 => 0x76a43201 },
+	'custom1' => { 297 => 'Custom1' },
+	'custom10' => { 297 => 'Custom10' },
+	'custom2' => { 297 => 'Custom2' },
+	'custom3' => { 297 => 'Custom3' },
+	'custom4' => { 297 => 'Custom4' },
+	'custom5' => { 297 => 'Custom5' },
+	'custom6' => { 297 => 'Custom6' },
+	'custom7' => { 297 => 'Custom7' },
+	'custom8' => { 297 => 'Custom8' },
+	'custom9' => { 297 => 'Custom9' },
+	'customcolortone' => { 107 => 0x4c },
+	'customcontrast' => { 107 => 0x4e },
+	'customcontrols' => { 82 => 0x70c },
+	'customdefaultunsharpfineness' => { 107 => 0xbe },
+	'customdefaultunsharpstrength' => { 107 => 0xbc },
+	'customdefaultunsharpthreshold' => { 107 => 0xc0 },
+	'customilluminant' => { 135 => 0x405 },
+	'customizedials' => { 82 => 0x715 },
+	'customlinear' => { 107 => 0x4f },
+	'customoutputhighlightpoint' => { 107 => 0x53 },
+	'customoutputshadowpoint' => { 107 => 0x54 },
+	'custompicturestyle' => { 101 => 0x10021 },
+	'custompicturestyledata' => { 101 => 0xf0500 },
+	'custompicturestylefilename' => { 62 => 0x4010 },
+	'customrawhighlight' => { 107 => 0x7c },
+	'customrawhighlightpoint' => { 107 => 0x51 },
+	'customrawshadow' => { 107 => 0x85 },
+	'customrawshadowpoint' => { 107 => 0x52 },
+	'customrendered' => { 117 => 0xa401, 473 => 'CustomRendered' },
+	'customsaturation' => { 107 => 0x4d, 287 => 0x503 },
+	'customsettingsalldefault' => { 270 => '0.2', 279 => '0.2' },
+	'customsettingsbank' => { 270 => '0.1', 271 => '0.1', 273 => '0.1', 274 => '0.1', 279 => '0.1', 283 => '0.2', 284 => '0.2' },
+	'customsharpness' => { 107 => 0x50 },
+	'customunsharpmaskfineness' => { 107 => 0xb8 },
+	'customunsharpmaskstrength' => { 107 => 0xb6 },
+	'customunsharpmaskthreshold' => { 107 => 0xba },
+	'customwb_rblevels' => { 415 => 0x1a },
+	'customwb_rgblevels' => { 398 => 0x8, 399 => 0x19 },
+	'customwbbluelevel' => { 180 => 0x36 },
+	'customwberror' => { 180 => 0x37 },
+	'customwbgreenlevel' => { 180 => 0x35 },
+	'customwbredlevel' => { 180 => 0x34 },
+	'customwbsetting' => { 180 => 0x26 },
+	'cx' => { 370 => '_cx_' },
+	'cy' => { 370 => '_cy_' },
+	'd-lightinghq' => { 263 => 0x2175eb78 },
+	'd-lightinghqcolorboost' => { 259 => 0x2 },
+	'd-lightinghqhighlight' => { 259 => 0x1 },
+	'd-lightinghqselected' => { 263 => 0x6a6e36b6 },
+	'd-lightinghqshadow' => { 259 => 0x0 },
+	'd-lightinghs' => { 263 => 0xce5554aa },
+	'd-lightinghsadjustment' => { 260 => 0x0 },
+	'd-lightinghscolorboost' => { 260 => 0x1 },
+	'd-rangeoptimizerhighlight' => { 444 => 0x8024 },
+	'd-rangeoptimizermode' => { 444 => 0x8022 },
+	'd-rangeoptimizershadow' => { 444 => 0x802d },
+	'd-rangeoptimizervalue' => { 444 => 0x8023 },
+	'darkblacksegrows' => { 135 => 0x18d8 },
+	'darkfocusenvironment' => { 310 => 0x8003 },
+	'darkframecountfactor' => { 135 => 0xc85 },
+	'darkframelongexposure' => { 135 => 0xc84 },
+	'darkframeshortexposure' => { 135 => 0xc83 },
+	'darkpedestal' => { 135 => 0xc7f },
+	'datacompressionmethod' => { 131 => 0x6e },
+	'dataimprint' => { 177 => 0x34 },
+	'dataonscreen' => { 479 => 'DataOnScreen' },
+	'dataonscreenregion' => { 479 => [\'DataOnScreen','DataOnScreenRegion'] },
+	'dataonscreenregiond' => { 479 => [\'DataOnScreen','DataOnScreenRegionD'] },
+	'dataonscreenregionh' => { 479 => [\'DataOnScreen','DataOnScreenRegionH'] },
+	'dataonscreenregiontext' => { 479 => [\'DataOnScreen','DataOnScreenRegionText'] },
+	'dataonscreenregionunit' => { 479 => [\'DataOnScreen','DataOnScreenRegionUnit'] },
+	'dataonscreenregionw' => { 479 => [\'DataOnScreen','DataOnScreenRegionW'] },
+	'dataonscreenregionx' => { 479 => [\'DataOnScreen','DataOnScreenRegionX'] },
+	'dataonscreenregiony' => { 479 => [\'DataOnScreen','DataOnScreenRegionY'] },
+	'datascaling' => { 345 => 0x3d },
+	'date' => { 345 => 0x6, 470 => 'date' },
+	'dateacquired' => { 175 => 'DateAcquired' },
+	'datecreated' => { 129 => 0x37, 481 => 'DateCreated' },
+	'datedisplayformat' => { 255 => 0x3 },
+	'dateidentified' => { 116 => [\'Identification','IdentificationDateIdentified'] },
+	'dateimprint' => { 275 => '4.2' },
+	'daterecieved' => { 483 => 'dateRecieved' },
+	'datesent' => { 130 => 0x46 },
+	'datestampmode' => { 62 => 0x1c, 221 => 0x9d },
+	'datetime' => { 462 => 'datetime', 489 => 'DateTime' },
+	'datetimedigitized' => { 473 => 'DateTimeDigitized' },
+	'datetimeoriginal' => { 98 => 0x0, 117 => 0x9003, 151 => 0x14, 154 => 'OriginalDate', 365 => 'IDIT', 370 => 'date', 371 => 0xb, 372 => 0x3b, 373 => 0x3e, 473 => 'DateTimeOriginal' },
+	'datetimestamp' => { 137 => 0x64 },
+	'datetimeutc' => { 287 => 0x908 },
+	'daylightsavings' => { 76 => 0x3, 255 => 0x2 },
+	'dayofweek' => { 372 => 0x42, 373 => 0x4a },
+	'dccontinent' => { 116 => [\'dctermsLocation','dctermsLocationContinent'] },
+	'dccoordinateprecision' => { 116 => [\'dctermsLocation','dctermsLocationCoordinatePrecision'] },
+	'dccoordinateuncertaintyinmeters' => { 116 => [\'dctermsLocation','dctermsLocationCoordinateUncertaintyInMeters'] },
+	'dccountry' => { 116 => [\'dctermsLocation','dctermsLocationCountry'] },
+	'dccountrycode' => { 116 => [\'dctermsLocation','dctermsLocationCountryCode'] },
+	'dccounty' => { 116 => [\'dctermsLocation','dctermsLocationCounty'] },
+	'dcdecimallatitude' => { 116 => [\'dctermsLocation','dctermsLocationDecimalLatitude'] },
+	'dcdecimallongitude' => { 116 => [\'dctermsLocation','dctermsLocationDecimalLongitude'] },
+	'dcevent' => { 116 => 'Event' },
+	'dcfootprintspatialfit' => { 116 => [\'dctermsLocation','dctermsLocationFootprintSpatialFit'] },
+	'dcfootprintsrs' => { 116 => [\'dctermsLocation','dctermsLocationFootprintSRS'] },
+	'dcfootprintwkt' => { 116 => [\'dctermsLocation','dctermsLocationFootprintWKT'] },
+	'dcgeodeticdatum' => { 116 => [\'dctermsLocation','dctermsLocationGeodeticDatum'] },
+	'dcgeoreferencedby' => { 116 => [\'dctermsLocation','dctermsLocationGeoreferencedBy'] },
+	'dcgeoreferenceddate' => { 116 => [\'dctermsLocation','dctermsLocationGeoreferencedDate'] },
+	'dcgeoreferenceprotocol' => { 116 => [\'dctermsLocation','dctermsLocationGeoreferenceProtocol'] },
+	'dcgeoreferenceremarks' => { 116 => [\'dctermsLocation','dctermsLocationGeoreferenceRemarks'] },
+	'dcgeoreferencesources' => { 116 => [\'dctermsLocation','dctermsLocationGeoreferenceSources'] },
+	'dcgeoreferenceverificationstatus' => { 116 => [\'dctermsLocation','dctermsLocationGeoreferenceVerificationStatus'] },
+	'dchighergeography' => { 116 => [\'dctermsLocation','dctermsLocationHigherGeography'] },
+	'dchighergeographyid' => { 116 => [\'dctermsLocation','dctermsLocationHigherGeographyID'] },
+	'dcisland' => { 116 => [\'dctermsLocation','dctermsLocationIsland'] },
+	'dcislandgroup' => { 116 => [\'dctermsLocation','dctermsLocationIslandGroup'] },
+	'dclocality' => { 116 => [\'dctermsLocation','dctermsLocationLocality'] },
+	'dclocationaccordingto' => { 116 => [\'dctermsLocation','dctermsLocationLocationAccordingTo'] },
+	'dclocationid' => { 116 => [\'dctermsLocation','dctermsLocationLocationID'] },
+	'dclocationremarks' => { 116 => [\'dctermsLocation','dctermsLocationLocationRemarks'] },
+	'dcmaximumdepthinmeters' => { 116 => [\'dctermsLocation','dctermsLocationMaximumDepthInMeters'] },
+	'dcmaximumdistanceabovesurfaceinmeters' => { 116 => [\'dctermsLocation','dctermsLocationMaximumDistanceAboveSurfaceInMeters'] },
+	'dcmaximumelevationinmeters' => { 116 => [\'dctermsLocation','dctermsLocationMaximumElevationInMeters'] },
+	'dcminimumdepthinmeters' => { 116 => [\'dctermsLocation','dctermsLocationMinimumDepthInMeters'] },
+	'dcminimumdistanceabovesurfaceinmeters' => { 116 => [\'dctermsLocation','dctermsLocationMinimumDistanceAboveSurfaceInMeters'] },
+	'dcminimumelevationinmeters' => { 116 => [\'dctermsLocation','dctermsLocationMinimumElevationInMeters'] },
+	'dcmunicipality' => { 116 => [\'dctermsLocation','dctermsLocationMunicipality'] },
+	'dcpointradiusspatialfit' => { 116 => [\'dctermsLocation','dctermsLocationPointRadiusSpatialFit'] },
+	'dcstateprovince' => { 116 => [\'dctermsLocation','dctermsLocationStateProvince'] },
+	'dctermslocation' => { 116 => 'dctermsLocation' },
+	'dcverbatimcoordinates' => { 116 => [\'dctermsLocation','dctermsLocationVerbatimCoordinates'] },
+	'dcverbatimcoordinatesystem' => { 116 => [\'dctermsLocation','dctermsLocationVerbatimCoordinateSystem'] },
+	'dcverbatimdepth' => { 116 => [\'dctermsLocation','dctermsLocationVerbatimDepth'] },
+	'dcverbatimelevation' => { 116 => [\'dctermsLocation','dctermsLocationVerbatimElevation'] },
+	'dcverbatimlatitude' => { 116 => [\'dctermsLocation','dctermsLocationVerbatimLatitude'] },
+	'dcverbatimlocality' => { 116 => [\'dctermsLocation','dctermsLocationVerbatimLocality'] },
+	'dcverbatimlongitude' => { 116 => [\'dctermsLocation','dctermsLocationVerbatimLongitude'] },
+	'dcverbatimsrs' => { 116 => [\'dctermsLocation','dctermsLocationVerbatimSRS'] },
+	'dcwaterbody' => { 116 => [\'dctermsLocation','dctermsLocationWaterBody'] },
+	'declination' => { 162 => 'Declination' },
+	'decposition' => { 177 => 0x32 },
+	'defaultautogray' => { 467 => 'DefaultAutoGray', 469 => 'DefaultAutoGray' },
+	'defaultautotone' => { 467 => 'DefaultAutoTone', 469 => 'DefaultAutoTone' },
+	'defaultblackrender' => { 117 => 0xc7a6 },
+	'defaultcroporigin' => { 117 => 0xc61f },
+	'defaultcropsize' => { 117 => 0xc620 },
+	'defaulteraseoption' => { 82 => 0x813 },
+	'defaultscale' => { 117 => 0xc61e },
+	'defaultsspecifictoiso' => { 467 => 'DefaultsSpecificToISO', 469 => 'DefaultsSpecificToISO' },
+	'defaultsspecifictoserial' => { 467 => 'DefaultsSpecificToSerial', 469 => 'DefaultsSpecificToSerial' },
+	'defaultusercrop' => { 117 => 0xc7b5 },
+	'defectisocode' => { 135 => 0x90f },
+	'defringe' => { 467 => 'Defringe', 469 => 'Defringe' },
+	'defringegreenamount' => { 467 => 'DefringeGreenAmount', 469 => 'DefringeGreenAmount' },
+	'defringegreenhuehi' => { 467 => 'DefringeGreenHueHi', 469 => 'DefringeGreenHueHi' },
+	'defringegreenhuelo' => { 467 => 'DefringeGreenHueLo', 469 => 'DefringeGreenHueLo' },
+	'defringepurpleamount' => { 467 => 'DefringePurpleAmount', 469 => 'DefringePurpleAmount' },
+	'defringepurplehuehi' => { 467 => 'DefringePurpleHueHi', 469 => 'DefringePurpleHueHi' },
+	'defringepurplehuelo' => { 467 => 'DefringePurpleHueLo', 469 => 'DefringePurpleHueLo' },
+	'dehaze' => { 467 => 'Dehaze', 469 => 'Dehaze' },
+	'deletedimagecount' => { 221 => 0xa6, 230 => 0x6e },
+	'deprecatedon' => { 465 => 'deprecatedOn' },
+	'depthfar' => { 117 => 0xc7eb },
+	'depthformat' => { 117 => 0xc7e9 },
+	'depthimage' => { 452 => 'Data' },
+	'depthmeasuretype' => { 117 => 0xc7ed },
+	'depthnear' => { 117 => 0xc7ea },
+	'depthunits' => { 117 => 0xc7ec },
+	'derivedfrom' => { 494 => 'DerivedFrom' },
+	'derivedfromalternatepaths' => { 494 => [\'DerivedFrom','DerivedFromAlternatePaths'] },
+	'derivedfromdocumentid' => { 494 => [\'DerivedFrom','DerivedFromDocumentID'] },
+	'derivedfromfilepath' => { 494 => [\'DerivedFrom','DerivedFromFilePath'] },
+	'derivedfromfrompart' => { 494 => [\'DerivedFrom','DerivedFromFromPart'] },
+	'derivedfrominstanceid' => { 494 => [\'DerivedFrom','DerivedFromInstanceID'] },
+	'derivedfromlastmodifydate' => { 494 => [\'DerivedFrom','DerivedFromLastModifyDate'] },
+	'derivedfromlasturl' => { 494 => [\'DerivedFrom','DerivedFromLastURL'] },
+	'derivedfromlinkcategory' => { 494 => [\'DerivedFrom','DerivedFromLinkCategory'] },
+	'derivedfromlinkform' => { 494 => [\'DerivedFrom','DerivedFromLinkForm'] },
+	'derivedfrommanager' => { 494 => [\'DerivedFrom','DerivedFromManager'] },
+	'derivedfrommanagervariant' => { 494 => [\'DerivedFrom','DerivedFromManagerVariant'] },
+	'derivedfrommanageto' => { 494 => [\'DerivedFrom','DerivedFromManageTo'] },
+	'derivedfrommanageui' => { 494 => [\'DerivedFrom','DerivedFromManageUI'] },
+	'derivedfrommaskmarkers' => { 494 => [\'DerivedFrom','DerivedFromMaskMarkers'] },
+	'derivedfromoriginaldocumentid' => { 494 => [\'DerivedFrom','DerivedFromOriginalDocumentID'] },
+	'derivedfrompartmapping' => { 494 => [\'DerivedFrom','DerivedFromPartMapping'] },
+	'derivedfromplacedresolutionunit' => { 494 => [\'DerivedFrom','DerivedFromPlacedResolutionUnit'] },
+	'derivedfromplacedxresolution' => { 494 => [\'DerivedFrom','DerivedFromPlacedXResolution'] },
+	'derivedfromplacedyresolution' => { 494 => [\'DerivedFrom','DerivedFromPlacedYResolution'] },
+	'derivedfromrenditionclass' => { 494 => [\'DerivedFrom','DerivedFromRenditionClass'] },
+	'derivedfromrenditionparams' => { 494 => [\'DerivedFrom','DerivedFromRenditionParams'] },
+	'derivedfromtopart' => { 494 => [\'DerivedFrom','DerivedFromToPart'] },
+	'derivedfromversionid' => { 494 => [\'DerivedFrom','DerivedFromVersionID'] },
+	'description' => { 300 => 'Description', 362 => ['desc','dscp',"\xa9des"], 364 => 'description', 370 => 'dscp', 467 => 'Description', 469 => 'Description', 470 => 'description', 491 => 'Description' },
+	'destination' => { 130 => 0x5 },
+	'destinationcity' => { 345 => 0x24, 351 => 0x3 },
+	'destinationcitycode' => { 352 => 0x1001 },
+	'destinationdst' => { 345 => 0x26, 351 => '0.3' },
+	'developmentdynamicrange' => { 125 => 0x1403 },
+	'deviantmatrixcustom' => { 135 => 0x7de },
+	'deviantmatrixdaylight' => { 135 => 0x7da },
+	'deviantmatrixflash' => { 135 => 0x7dd },
+	'deviantmatrixfluorescent' => { 135 => 0x7dc },
+	'deviantmatrixtungsten' => { 135 => 0x7db },
+	'deviantwhitecustom' => { 135 => 0x842 },
+	'deviantwhitedaylight' => { 135 => 0x83e },
+	'deviantwhiteflash' => { 135 => 0x841 },
+	'deviantwhitefluorescent' => { 135 => 0x840 },
+	'deviantwhitetungsten' => { 135 => 0x83f },
+	'device' => { 483 => 'device' },
+	'devicesettingdescription' => { 473 => 'DeviceSettingDescription' },
+	'devicesettingdescriptioncolumns' => { 473 => [\'DeviceSettingDescription','DeviceSettingDescriptionColumns'] },
+	'devicesettingdescriptionrows' => { 473 => [\'DeviceSettingDescription','DeviceSettingDescriptionRows'] },
+	'devicesettingdescriptionsettings' => { 473 => [\'DeviceSettingDescription','DeviceSettingDescriptionSettings'] },
+	'devicetype' => { 384 => 0x2 },
+	'dewarpdata' => { 114 => 'DewarpData' },
+	'dewarpflag' => { 114 => 'DewarpFlag' },
+	'dialdirectiontvav' => { 82 => 0x706 },
+	'dietaryneeds' => { 485 => 'dietaryNeeds' },
+	'diffractioncorrection' => { 310 => 0xbc, 335 => 0x3 },
+	'diffractioncorrectionon' => { 101 => 0x2070b },
+	'digitalcreationdate' => { 129 => 0x3e },
+	'digitalcreationtime' => { 129 => 0x3f },
+	'digitaldeehighlightadj' => { 229 => 0x202 },
+	'digitaldeeshadowadj' => { 229 => 0x200 },
+	'digitaldeethreshold' => { 229 => 0x201 },
+	'digitalfilter' => { 387 => 0x59 },
+	'digitalfilter01' => { 332 => 0x5 },
+	'digitalfilter02' => { 332 => 0x16 },
+	'digitalfilter03' => { 332 => 0x27 },
+	'digitalfilter04' => { 332 => 0x38 },
+	'digitalfilter05' => { 332 => 0x49 },
+	'digitalfilter06' => { 332 => 0x5a },
+	'digitalfilter07' => { 332 => 0x6b },
+	'digitalfilter08' => { 332 => 0x7c },
+	'digitalfilter09' => { 332 => 0x8d },
+	'digitalfilter10' => { 332 => 0x9e },
+	'digitalfilter11' => { 332 => 0xaf },
+	'digitalfilter12' => { 332 => 0xc0 },
+	'digitalfilter13' => { 332 => 0xd1 },
+	'digitalfilter14' => { 332 => 0xe2 },
+	'digitalfilter15' => { 332 => 0xf3 },
+	'digitalfilter16' => { 332 => 0x104 },
+	'digitalfilter17' => { 332 => 0x115 },
+	'digitalfilter18' => { 332 => 0x126 },
+	'digitalfilter19' => { 332 => 0x137 },
+	'digitalfilter20' => { 332 => 0x148 },
+	'digitalgain' => { 72 => 0xb },
+	'digitalgem' => { 210 => 0x0 },
+	'digitalice' => { 229 => 0x100 },
+	'digitalimageguid' => { 479 => 'DigImageGUID' },
+	'digitalroc' => { 227 => 0x0 },
+	'digitalsourcefiletype' => { 479 => 'DigitalSourcefileType' },
+	'digitalsourcetype' => { 479 => 'DigitalSourceType' },
+	'digitalzoom' => { 34 => 0xc, 110 => 0xa, 125 => 0x1044, 137 => 0x68, 148 => 0x22, 149 => 0x1e, 153 => 'DigitalZoom', 177 => 0xc, 221 => 0x86, 253 => 0xa, 292 => 0x204, 345 => 0x1e, 352 => 0xa, 386 => 0x204, 431 => 0x12, 432 => 0x12 },
+	'digitalzoomon' => { 386 => 0x21b },
+	'digitalzoomratio' => { 117 => 0xa404, 420 => 0x200, 422 => 0x21c, 473 => 'DigitalZoomRatio' },
+	'director' => { 362 => "\xa9dir", 364 => 'director', 370 => "\xa9dir", 493 => 'director' },
+	'directorphotography' => { 493 => 'directorPhotography' },
+	'directory' => { 118 => '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' => { 203 => 0x3, 373 => 0x12 },
+	'disableautocreation' => { 450 => 'DisableAutoCreation' },
+	'disclaimer' => { 300 => 'Disclaimer' },
+	'discnumber' => { 493 => 'discNumber' },
+	'dishtype' => { 485 => 'dishType' },
+	'disknumber' => { 362 => 'disk' },
+	'displayallafpoints' => { 82 => 0x514 },
+	'displayaperture' => { 34 => 0x23 },
+	'displayedunitsx' => { 360 => 0x2 },
+	'displayedunitsy' => { 360 => 0x6 },
+	'displayname' => { 364 => 'displayname', 482 => 'displayName' },
+	'distance1' => { 137 => 0x28 },
+	'distance2' => { 137 => 0x2c },
+	'distance3' => { 137 => 0x30 },
+	'distance4' => { 137 => 0x34 },
+	'distortion' => { 384 => 0xa050 },
+	'distortioncompensation' => { 444 => 0x8040 },
+	'distortioncontrol' => { 230 => 0x10 },
+	'distortioncorrection' => { 77 => 0x3, 101 => 0x20705, 107 => 0x67, 117 => 0x7036, 287 => 0x50b, 314 => '7.1', 335 => 0x0, 439 => 0x601, 440 => 0x5b },
+	'distortioncorrection2' => { 291 => 0x1011 },
+	'distortioncorrectionalreadyapplied' => { 464 => 'DistortionCorrectionAlreadyApplied' },
+	'distortioncorrectionon' => { 101 => '0x20705.0', 107 => 0x63 },
+	'distortioncorrectionsetting' => { 78 => 0x7, 410 => 0x2013 },
+	'distortioncorrectionvalue' => { 77 => 0x9 },
+	'distortioncorrparams' => { 117 => 0x7037, 419 => 0x1a23, 422 => 0x1870, 424 => 0x189c, 425 => 0x18cc, 426 => 0x17d0, 439 => 0x6ca, 440 => 0x64 },
+	'distortioncorrparamsnumber' => { 422 => 0x1899, 424 => 0x18c5, 425 => 0x18f5, 426 => 0x17f9 },
+	'distortioncorrparamspresent' => { 422 => 0x1898, 424 => 0x18c4, 425 => 0x18f4, 426 => 0x17f8, 428 => 0x10b, 429 => 0x10b, 439 => 0x600, 440 => 0x5a },
+	'distortioneffect' => { 101 => 0x20709 },
+	'distortionn' => { 314 => 0xc },
+	'distortionparam02' => { 314 => 0x2 },
+	'distortionparam04' => { 314 => 0x4 },
+	'distortionparam08' => { 314 => 0x8 },
+	'distortionparam09' => { 314 => 0x9 },
+	'distortionparam11' => { 314 => 0xb },
+	'distortionscale' => { 314 => 0x5 },
+	'distributor' => { 483 => 'distributor' },
+	'distributorproductid' => { 482 => 'distributorProductID' },
+	'dloon' => { 101 => '0x20706.0', 107 => 0xdc },
+	'dlosetting' => { 101 => 0x20706, 107 => 0xdd },
+	'dlosettingapplied' => { 100 => 0x4 },
+	'dloshootingdistance' => { 107 => 0xde },
+	'dloversion' => { 100 => 0x5 },
+	'dmcomment' => { 493 => 'comment' },
+	'dmdithermatrix' => { 135 => 0xc7a },
+	'dmdithermatrixheight' => { 135 => 0xc7c },
+	'dmdithermatrixwidth' => { 135 => 0xc7b },
+	'dngadobedata' => { 117 => 0xc634 },
+	'dngbackwardversion' => { 117 => 0xc613 },
+	'dngignoresidecars' => { 467 => 'DNGIgnoreSidecars', 469 => 'DNGIgnoreSidecars' },
+	'dnglensinfo' => { 117 => 0xc630 },
+	'dngprivatedata' => { 117 => 0xc634 },
+	'dngversion' => { 117 => 0xc612 },
+	'document' => { 300 => 'Document' },
+	'documentancestors' => { 481 => 'DocumentAncestors' },
+	'documenthistory' => { 129 => 0xe7 },
+	'documentid' => { 494 => 'DocumentID' },
+	'documentname' => { 117 => 0x10d },
+	'documentnotes' => { 129 => 0xe6 },
+	'doi' => { 483 => 'doi' },
+	'dopesheet' => { 479 => 'Dopesheet' },
+	'dopesheetlink' => { 479 => 'DopesheetLink' },
+	'dopesheetlinklink' => { 479 => [\'DopesheetLink','DopesheetLinkLink'] },
+	'dopesheetlinklinkqualifier' => { 479 => [\'DopesheetLink','DopesheetLinkLinkQualifier'] },
+	'doublingmicrovolts' => { 135 => 0xc82 },
+	'dpp' => { 462 => 'dpp' },
+	'dr4cameramodel' => { 102 => 0x3 },
+	'drangepriority' => { 125 => 0x1443 },
+	'drangepriorityauto' => { 125 => 0x1444 },
+	'drangepriorityfixed' => { 125 => 0x1445 },
+	'drivemode' => { 111 => 0x3103, 123 => '0.1', 177 => 0x6, 180 => 0x1e, 183 => 0xe, 287 => 0x600, 345 => 0x34, 377 => 0x1002, 387 => 0x3, 397 => 0x4, 398 => 0x7e, 399 => 0x34 },
+	'drivemode2' => { 180 => 0xa, 326 => 0x7, 408 => 0xe, 415 => 0x1 },
+	'drivemodesetting' => { 399 => 0x4 },
+	'drivespeed' => { 123 => '0.2' },
+	'dspfirmwareversion' => { 345 => 0x27 },
+	'duration' => { 65 => 0x6a, 152 => 'Duration', 166 => 'Duration', 485 => 'duration', 493 => 'duration' },
+	'durationscale' => { 493 => [\'duration','durationScale'] },
+	'durationvalue' => { 493 => [\'duration','durationValue'] },
+	'dustremovaldata' => { 62 => 0x97 },
+	'dynamicafarea' => { 270 => '1.4', 279 => '1.4' },
+	'dynamicareaafdisplay' => { 271 => '46.1', 273 => '47.1', 274 => '47.1', 283 => '47.1', 284 => '47.1' },
+	'dynamicrange' => { 125 => 0x1400 },
+	'dynamicrangeexpansion' => { 345 => 0x69, 377 => 0x100e },
+	'dynamicrangemax' => { 106 => 0x7c },
+	'dynamicrangemin' => { 106 => 0x7a },
+	'dynamicrangeoptimizer' => { 180 => 0x15, 410 => [0xb025,0xb04f], 418 => 0x1144, 419 => [0x1144,0x324], 420 => [0x1120,0x300], 421 => [0x119c,0x37c], 422 => [0x1178,0x328], 423 => [0x1030,0x50], 424 => [0x228,0x50], 425 => [0x228,0x50], 426 => [0x21b,0x4e] },
+	'dynamicrangeoptimizerbracket' => { 408 => 0x2e },
+	'dynamicrangeoptimizerlevel' => { 397 => 0x19, 398 => 0x17, 399 => 0xd, 408 => 0x79, 415 => 0x5 },
+	'dynamicrangeoptimizermode' => { 183 => 0x15, 397 => 0x18, 398 => 0x16, 408 => [0x77,0x15] },
+	'dynamicrangeoptimizersetting' => { 180 => 0x27, 399 => 0xc, 415 => 0x4 },
+	'dynamicrangesetting' => { 125 => 0x1402 },
+	'e-dialinprogram' => { 326 => '1.3' },
+	'earliestageorloweststage' => { 116 => [\'GeologicalContext','GeologicalContextEarliestAgeOrLowestStage'] },
+	'earliesteonorlowesteonothem' => { 116 => [\'GeologicalContext','GeologicalContextEarliestEonOrLowestEonothem'] },
+	'earliestepochorlowestseries' => { 116 => [\'GeologicalContext','GeologicalContextEarliestEpochOrLowestSeries'] },
+	'earliesteraorlowesterathem' => { 116 => [\'GeologicalContext','GeologicalContextEarliestEraOrLowestErathem'] },
+	'earliestperiodorlowestsystem' => { 116 => [\'GeologicalContext','GeologicalContextEarliestPeriodOrLowestSystem'] },
+	'earthpos' => { 447 => 'EarthPos' },
+	'earthposaltitude' => { 447 => [\'EarthPos','EarthPosAltitude'] },
+	'earthposlatitude' => { 447 => [\'EarthPos','EarthPosLatitude'] },
+	'earthposlongitude' => { 447 => [\'EarthPos','EarthPosLongitude'] },
+	'earthposrotationw' => { 447 => [\'EarthPos','EarthPosRotationW'] },
+	'earthposrotationx' => { 447 => [\'EarthPos','EarthPosRotationX'] },
+	'earthposrotationy' => { 447 => [\'EarthPos','EarthPosRotationY'] },
+	'earthposrotationz' => { 447 => [\'EarthPos','EarthPosRotationZ'] },
+	'earthpostimestamp' => { 447 => [\'EarthPos','EarthPosTimestamp'] },
+	'easyexposurecomp' => { 285 => '6.1' },
+	'easyexposurecompensation' => { 270 => '6.4', 271 => '6.5', 273 => '6.3', 274 => '6.3', 278 => '5.1', 279 => '4.4', 280 => '5.2', 283 => '6.3', 284 => '6.3' },
+	'easymode' => { 34 => 0xb },
+	'edgemapslope' => { 135 => 0x930 },
+	'edgemapx1' => { 135 => 0x931 },
+	'edgemapx2' => { 135 => 0x932 },
+	'edgemapx3' => { 135 => 0x934 },
+	'edgemapx4' => { 135 => 0x935 },
+	'edgenoisereduction' => { 264 => 0x4, 444 => 0x8028 },
+	'edit1' => { 370 => "\xa9ed1" },
+	'edit2' => { 370 => "\xa9ed2" },
+	'edit3' => { 370 => "\xa9ed3" },
+	'edit4' => { 370 => "\xa9ed4" },
+	'edit5' => { 370 => "\xa9ed5" },
+	'edit6' => { 370 => "\xa9ed6" },
+	'edit7' => { 370 => "\xa9ed7" },
+	'edit8' => { 370 => "\xa9ed8" },
+	'edit9' => { 370 => "\xa9ed9" },
+	'edition' => { 483 => 'edition' },
+	'editorialupdate' => { 129 => 0x8 },
+	'editstatus' => { 129 => 0x7, 357 => 'EditStatus', 462 => 'EditStatus' },
+	'editversionname' => { 263 => 0x3d136244 },
+	'effectivelv' => { 345 => 0x2d },
+	'effectivemaxaperture' => { 214 => 0x12, 215 => 0x13, 219 => 0x14 },
+	'eissn' => { 483 => 'eIssn' },
+	'electricalblackcolumns' => { 135 => 0x1810 },
+	'electronicfront-curtainshutter' => { 273 => '5.2', 274 => '5.2', 283 => '5.3', 284 => '5.2' },
+	'electronicfrontcurtainshutter' => { 410 => 0x201a },
+	'elevation' => { 162 => 'Elevation' },
+	'email' => { 154 => 'EMail' },
+	'embargodate' => { 486 => 'embargoDate' },
+	'embdencrightsexpr' => { 479 => 'EmbdEncRightsExpr' },
+	'embeddedencodedrightsexpr' => { 479 => [\'EmbdEncRightsExpr','EmbdEncRightsExprEncRightsExpr'] },
+	'embeddedencodedrightsexprlangid' => { 479 => [\'EmbdEncRightsExpr','EmbdEncRightsExprRightsExprLangId'] },
+	'embeddedencodedrightsexprtype' => { 479 => [\'EmbdEncRightsExpr','EmbdEncRightsExprRightsExprEncType'] },
+	'embeddedxmpdigest' => { 481 => 'EmbeddedXMPDigest' },
+	'emissivity' => { 119 => 0x3 },
+	'enablechromanoisereduction' => { 135 => 0xe6e },
+	'enablesharpening' => { 135 => 0x92e },
+	'encodedby' => { 362 => "\xa9enc" },
+	'encodedwith' => { 364 => 'Encoded_With' },
+	'encoder' => { 362 => "\xa9too", 370 => "\xa9too" },
+	'encoderid' => { 370 => "\xa9enc" },
+	'encryptionkey' => { 384 => 0xa020 },
+	'endingpage' => { 483 => 'endingPage' },
+	'enduser' => { 297 => 'EndUser' },
+	'enduserid' => { 297 => [\'EndUser','EndUserEndUserID'] },
+	'endusername' => { 297 => [\'EndUser','EndUserEndUserName'] },
+	'engineer' => { 493 => 'engineer' },
+	'enhancedarktones' => { 256 => 0x8 },
+	'enhancement' => { 110 => 0x16, 111 => 0x3016 },
+	'enhanceparams' => { 117 => 0xc7ee },
+	'enhancer' => { 291 => 0x300 },
+	'enhancervalues' => { 291 => 0x301 },
+	'envelopenumber' => { 130 => 0x28 },
+	'envelopepriority' => { 130 => 0x3c },
+	'enveloperecordversion' => { 130 => 0x0 },
+	'episode' => { 479 => 'Episode' },
+	'episodeglobaluniqueid' => { 362 => 'egid' },
+	'episodeidentifier' => { 479 => [\'Episode','EpisodeIdentifier'] },
+	'episodename' => { 479 => [\'Episode','EpisodeName'] },
+	'episodenumber' => { 479 => [\'Episode','EpisodeNumber'] },
+	'epsonimageheight' => { 292 => 0x20c },
+	'epsonimagewidth' => { 292 => 0x20b },
+	'epsonsoftware' => { 292 => 0x20d },
+	'equipmentinstitution' => { 446 => 'EquipmentInstitution' },
+	'equipmentmanufacturer' => { 446 => 'EquipmentManufacturer' },
+	'equipmentversion' => { 288 => 0x0 },
+	'ettlii' => { 82 => 0x304, 83 => 0xd, 84 => 0xe, 85 => 0x7, 86 => 0x7, 87 => 0xe },
+	'event' => { 448 => 'Event', 460 => 'Event', 479 => 'Event', 483 => 'event' },
+	'eventalias' => { 482 => 'eventAlias' },
+	'eventdate' => { 116 => [\'Event','EventEventDate'] },
+	'eventday' => { 116 => [\'Event','EventDay'] },
+	'eventearliestdate' => { 116 => [\'Event','EventEarliestDate'] },
+	'eventend' => { 482 => 'eventEnd' },
+	'eventenddayofyear' => { 116 => [\'Event','EventEndDayOfYear'] },
+	'eventfieldnotes' => { 116 => [\'Event','EventFieldNotes'] },
+	'eventfieldnumber' => { 116 => [\'Event','EventFieldNumber'] },
+	'eventhabitat' => { 116 => [\'Event','EventHabitat'] },
+	'eventid' => { 116 => [\'Event','EventEventID'] },
+	'eventlatestdate' => { 116 => [\'Event','EventLatestDate'] },
+	'eventmonth' => { 116 => [\'Event','EventMonth'] },
+	'eventnumber' => { 371 => 0x9, 372 => 0x37, 373 => 0x3a },
+	'eventparenteventid' => { 116 => [\'Event','EventParentEventID'] },
+	'eventremarks' => { 116 => [\'Event','EventEventRemarks'] },
+	'eventsamplesizeunit' => { 116 => [\'Event','EventSampleSizeUnit'] },
+	'eventsamplesizevalue' => { 116 => [\'Event','EventSampleSizeValue'] },
+	'eventsamplingeffort' => { 116 => [\'Event','EventSamplingEffort'] },
+	'eventsamplingprotocol' => { 116 => [\'Event','EventSamplingProtocol'] },
+	'eventstart' => { 482 => 'eventStart' },
+	'eventstartdayofyear' => { 116 => [\'Event','EventStartDayOfYear'] },
+	'eventsubtype' => { 482 => 'eventSubtype' },
+	'eventtime' => { 116 => [\'Event','EventEventTime'] },
+	'eventtype' => { 482 => 'eventType' },
+	'eventverbatimeventdate' => { 116 => [\'Event','EventVerbatimEventDate'] },
+	'eventyear' => { 116 => [\'Event','EventYear'] },
+	'evsteps' => { 326 => '1.2', 328 => 0x0 },
+	'evstepsize' => { 275 => '5.1', 276 => '6.1', 277 => '6.1', 281 => '0.7' },
+	'exclusivecoverage' => { 457 => 'ExclusiveCoverage' },
+	'exclusivityenddate' => { 486 => 'exclusivityEndDate' },
+	'excursiontolerance' => { 131 => 0x82 },
+	'executiveproducer' => { 362 => "\xa9xpd" },
+	'exif' => { 118 => 'EXIF' },
+	'exifbyteorder' => { 118 => 'ExifByteOrder' },
+	'exifcamerainfo' => { 129 => 0xe8 },
+	'exifimageheight' => { 117 => 0xa003, 473 => 'PixelYDimension' },
+	'exifimagewidth' => { 117 => 0xa002, 473 => 'PixelXDimension' },
+	'exifunicodebyteorder' => { 118 => 'ExifUnicodeByteOrder' },
+	'exifversion' => { 117 => 0x9000, 473 => 'ExifVersion' },
+	'exitpupilposition' => { 214 => 0x4, 215 => 0x4, 219 => 0x4 },
+	'expirationdate' => { 129 => 0x25, 486 => 'expirationDate' },
+	'expirationtime' => { 129 => 0x26 },
+	'exposure' => { 117 => 0xfe51, 467 => 'Exposure', 469 => 'Exposure' },
+	'exposure2012' => { 467 => 'Exposure2012', 469 => 'Exposure2012' },
+	'exposureadj' => { 261 => 0x0 },
+	'exposureadj2' => { 261 => 0x12 },
+	'exposureadjust' => { 387 => 0xc },
+	'exposurebracketingindicatorlast' => { 180 => 0x52 },
+	'exposurebracketshotnumber' => { 183 => 0x2d, 408 => 0x2f },
+	'exposurebracketstepsize' => { 326 => 0x8 },
+	'exposurebracketvalue' => { 221 => 0x19 },
+	'exposurecompautocancel' => { 82 => 0x113 },
+	'exposurecompensation' => { 75 => 0x6, 91 => 0x0, 117 => 0x9204, 137 => 0x24, 153 => 'ExposureComp', 173 => 'ExposureCompensation', 177 => 0xd, 178 => 0x53, 179 => 0x1e, 183 => 0x49c0, 292 => 0x1006, 345 => 0x16, 354 => 0x402, 384 => 0xa013, 387 => [0xc,0x35,0x4d], 418 => 0x114c, 419 => 0x114c, 420 => 0x1128, 422 => 0x1180, 423 => 0x1038, 424 => 0x230, 425 => 0x230, 426 => 0x223, 473 => 'ExposureBiasValue' },
+	'exposurecompensation2' => { 415 => [0x24,0x26,0x2a] },
+	'exposurecompensationmode' => { 180 => 0x47, 183 => 0x2a },
+	'exposurecompensationset' => { 397 => 0x3, 398 => 0x3, 399 => 0x3, 415 => 0x1e },
+	'exposurecompensationsetting' => { 180 => 0x1 },
+	'exposurecompstepsize' => { 270 => '6.3', 271 => '7.3', 273 => '7.3', 274 => '7.3', 279 => '4.3', 283 => '7.3', 284 => '7.3' },
+	'exposurecontrolstep' => { 278 => '6.1', 280 => '6.1' },
+	'exposurecontrolstepsize' => { 270 => '6.2', 271 => '7.1', 273 => '7.1', 274 => '7.1', 279 => '4.2', 283 => '7.1', 284 => '7.1', 285 => '7.1' },
+	'exposurecount' => { 125 => 0x1032 },
+	'exposuredelaymode' => { 270 => '10.1', 271 => '11.1', 273 => '11.1', 274 => '11.1', 275 => '9.1', 276 => '10.1', 277 => '10.1', 279 => '10.4', 280 => '10.1', 281 => '6.4', 283 => '11.1', 284 => '11.1', 285 => '11.2' },
+	'exposuredifference' => { 221 => 0xe },
+	'exposuregaincustom' => { 135 => 0x89c },
+	'exposuregaindaylight' => { 135 => 0x898 },
+	'exposuregainflash' => { 135 => 0x89b },
+	'exposuregainfluorescent' => { 135 => 0x89a },
+	'exposuregaintungsten' => { 135 => 0x899 },
+	'exposureindex' => { 117 => 0xa215, 473 => 'ExposureIndex' },
+	'exposureindicator' => { 180 => 0x50 },
+	'exposurelevelincrements' => { 80 => 0x6, 81 => 0x6, 82 => 0x101, 83 => 0x5, 84 => 0x6, 85 => 0x5, 86 => 0x5, 87 => 0x6, 88 => 0x4, 397 => 0x58, 398 => 0x58 },
+	'exposurelockused' => { 455 => 'ExposureLockUsed' },
+	'exposuremode' => { 117 => 0xa402, 153 => 'ExposureMode', 177 => 0x1, 178 => 0xa, 179 => 0x0, 180 => 0x0, 183 => 0x34, 287 => 0x200, 307 => 0x40d, 387 => 0x8, 410 => 0xb041, 473 => 'ExposureMode' },
+	'exposuremodeinmanual' => { 82 => 0x10b },
+	'exposureprogram' => { 117 => 0x8822, 377 => 0x1001, 390 => [0x17e,0x43], 397 => 0x3c, 398 => 0x3c, 399 => 0x5, 403 => 0x14, 408 => 0x3f, 415 => 0x2, 418 => 0x1175, 419 => 0x1179, 420 => 0x1155, 421 => 0x11d1, 422 => 0x11ad, 423 => 0x1065, 424 => 0x25d, 425 => 0x25d, 426 => 0x24c, 436 => 0xb, 437 => 0xc, 438 => 0xb, 440 => 0x48, 473 => 'ExposureProgram' },
+	'exposureshift' => { 287 => 0x203 },
+	'exposurestandardadjustment' => { 410 => 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, 75 => 0x16, 117 => 0x829a, 134 => 0xfd05, 137 => 0x20, 139 => 0xfa24, 141 => 0xf104, 144 => 0x12, 146 => 0x38, 148 => 0x14, 149 => 0x10, 151 => 0x10, 153 => 'ExposureTime', 177 => 0x9, 178 => 0x35, 179 => 0x48, 180 => 0x8, 183 => 0x49b8, 345 => 0x12, 384 => 0xa018, 387 => [0x32,0x4a], 397 => 0x0, 398 => 0x0, 415 => [0x21,0x23,0x27], 440 => 0x10, 473 => 'ExposureTime' },
+	'exposuretime2' => { 387 => [0x33,0x4b] },
+	'exposuretuning' => { 221 => 0x1c },
+	'exposurevalue' => { 135 => 0x3 },
+	'exposurewarning' => { 125 => 0x1302 },
+	'exrauto' => { 125 => 0x1033 },
+	'exrmode' => { 125 => 0x1034 },
+	'extendedwbdetect' => { 287 => 0x902 },
+	'extender' => { 288 => 0x301 },
+	'extenderfirmwareversion' => { 288 => 0x304 },
+	'extendermagnification' => { 155 => 'Magnification' },
+	'extendermake' => { 155 => 'Make' },
+	'extendermodel' => { 155 => 'Model', 288 => 0x303 },
+	'extenderserialnumber' => { 155 => 'SerialNumber', 288 => 0x302 },
+	'extenderstatus' => { 343 => 0x3 },
+	'externalflash' => { 290 => 0x1201 },
+	'externalflashae1' => { 292 => 0x101f },
+	'externalflashae1_0' => { 292 => 0x101b },
+	'externalflashae2' => { 292 => 0x1020 },
+	'externalflashae2_0' => { 292 => 0x101c },
+	'externalflashbounce' => { 290 => 0x1204, 292 => 0x1026, 333 => 0x1a },
+	'externalflashcompensation' => { 206 => 0x1b },
+	'externalflashexposurecomp' => { 221 => 0x17, 333 => 0x19 },
+	'externalflashfirmware' => { 204 => 0x6, 205 => 0x6, 206 => 0x6, 207 => 0x6, 208 => 0x6, 209 => 0x6 },
+	'externalflashflags' => { 204 => 0x8, 205 => 0x8, 206 => 0x8, 207 => 0x8 },
+	'externalflashguidenumber' => { 290 => 0x1203, 333 => '24.1' },
+	'externalflashgvalue' => { 292 => 0x1025 },
+	'externalflashmode' => { 292 => 0x1028, 333 => 0x2 },
+	'externalflashreadystate' => { 208 => '9.1' },
+	'externalflashstatus' => { 208 => '8.2' },
+	'externalflashzoom' => { 290 => 0x1205, 292 => 0x1027 },
+	'externalflashzoomoverride' => { 208 => '8.1' },
+	'externalmetadatalink' => { 479 => 'ExternalMetadataLink' },
+	'externalsensorbrightnessvalue' => { 305 => 0x311, 308 => 0x311, 309 => 0x311, 312 => 0x3408 },
+	'extrainfoversion' => { 401 => 0x1a },
+	'eyestartaf' => { 180 => 0x40 },
+	'fac100per' => { 135 => 0xe94 },
+	'fac170per' => { 135 => 0xe93 },
+	'fac18per' => { 135 => 0xe92 },
+	'face10position' => { 108 => 0x3f4, 109 => 0x1ec, 202 => 0x28, 330 => 0x12 },
+	'face10size' => { 331 => 0x12 },
+	'face11position' => { 202 => 0x2c, 330 => 0x14 },
+	'face11size' => { 331 => 0x14 },
+	'face12position' => { 202 => 0x30, 330 => 0x16 },
+	'face12size' => { 331 => 0x16 },
+	'face13position' => { 330 => 0x18 },
+	'face13size' => { 331 => 0x18 },
+	'face14position' => { 330 => 0x1a },
+	'face14size' => { 331 => 0x1a },
+	'face15position' => { 330 => 0x1c },
+	'face15size' => { 331 => 0x1c },
+	'face16position' => { 330 => 0x1e },
+	'face16size' => { 331 => 0x1e },
+	'face17position' => { 330 => 0x20 },
+	'face17size' => { 331 => 0x20 },
+	'face18position' => { 330 => 0x22 },
+	'face18size' => { 331 => 0x22 },
+	'face19position' => { 330 => 0x24 },
+	'face19size' => { 331 => 0x24 },
+	'face1position' => { 53 => 0x8, 108 => 0xd, 109 => 0x18, 202 => 0x4, 302 => 0x1, 330 => 0x0, 374 => 0xbc, 404 => 0x1, 405 => 0x0, 406 => 0x0, 407 => 0x5b },
+	'face1size' => { 331 => 0x0 },
+	'face20position' => { 330 => 0x26 },
+	'face20size' => { 331 => 0x26 },
+	'face21position' => { 330 => 0x28 },
+	'face21size' => { 331 => 0x28 },
+	'face22position' => { 330 => 0x2a },
+	'face22size' => { 331 => 0x2a },
+	'face23position' => { 330 => 0x2c },
+	'face23size' => { 331 => 0x2c },
+	'face24position' => { 330 => 0x2e },
+	'face24size' => { 331 => 0x2e },
+	'face25position' => { 330 => 0x30 },
+	'face25size' => { 331 => 0x30 },
+	'face26position' => { 330 => 0x32 },
+	'face26size' => { 331 => 0x32 },
+	'face27position' => { 330 => 0x34 },
+	'face27size' => { 331 => 0x34 },
+	'face28position' => { 330 => 0x36 },
+	'face28size' => { 331 => 0x36 },
+	'face29position' => { 330 => 0x38 },
+	'face29size' => { 331 => 0x38 },
+	'face2position' => { 53 => 0xa, 108 => 0x7c, 109 => 0x4c, 202 => 0x8, 302 => 0x5, 330 => 0x2, 374 => 0xc8, 404 => 0x6, 405 => 0x20, 406 => 0x25, 407 => 0x65 },
+	'face2size' => { 331 => 0x2 },
+	'face30position' => { 330 => 0x3a },
+	'face30size' => { 331 => 0x3a },
+	'face31position' => { 330 => 0x3c },
+	'face31size' => { 331 => 0x3c },
+	'face32position' => { 330 => 0x3e },
+	'face32size' => { 331 => 0x3e },
+	'face3position' => { 53 => 0xc, 108 => 0xeb, 109 => 0x80, 202 => 0xc, 302 => 0x9, 330 => 0x4, 374 => 0xd4, 404 => 0xb, 405 => 0x40, 406 => 0x4a, 407 => 0x6f },
+	'face3size' => { 331 => 0x4 },
+	'face4position' => { 53 => 0xe, 108 => 0x15a, 109 => 0xb4, 202 => 0x10, 302 => 0xd, 330 => 0x6, 374 => 0xe0, 404 => 0x10, 405 => 0x60, 406 => 0x6f, 407 => 0x79 },
+	'face4size' => { 331 => 0x6 },
+	'face5position' => { 53 => 0x10, 108 => 0x1c9, 109 => 0xe8, 202 => 0x14, 302 => 0x11, 330 => 0x8, 374 => 0xec, 404 => 0x15, 405 => 0x80, 406 => 0x94 },
+	'face5size' => { 331 => 0x8 },
+	'face6position' => { 53 => 0x12, 108 => 0x238, 109 => 0x11c, 202 => 0x18, 330 => 0xa, 374 => 0xf8, 404 => 0x1a, 405 => 0xa0, 406 => 0xb9 },
+	'face6size' => { 331 => 0xa },
+	'face7position' => { 53 => 0x14, 108 => 0x2a7, 109 => 0x150, 202 => 0x1c, 330 => 0xc, 374 => 0x104, 404 => 0x1f, 405 => 0xc0, 406 => 0xde },
+	'face7size' => { 331 => 0xc },
+	'face8position' => { 53 => 0x16, 108 => 0x316, 109 => 0x184, 202 => 0x20, 330 => 0xe, 374 => 0x110, 404 => 0x24, 405 => 0xe0, 406 => 0x103 },
+	'face8size' => { 331 => 0xe },
+	'face9position' => { 53 => 0x18, 108 => 0x385, 109 => 0x1b8, 202 => 0x24, 330 => 0x10 },
+	'face9size' => { 331 => 0x10 },
+	'facebalanceorigi' => { 461 => 'FaceBalanceOrigI' },
+	'facebalanceorigq' => { 461 => 'FaceBalanceOrigQ' },
+	'facebalancestrength' => { 461 => 'FaceBalanceStrength' },
+	'facebalancewarmth' => { 461 => 'FaceBalanceWarmth' },
+	'facedetect' => { 345 => 0x76, 384 => 0x100 },
+	'facedetectarea' => { 291 => 0x1201 },
+	'facedetectframecrop' => { 291 => 0x1207 },
+	'facedetectframesize' => { 53 => 0x3, 108 => 0x1, 109 => 0x4, 202 => 0x1, 291 => 0x1203, 345 => 0x77, 374 => 0xb6 },
+	'facedetection' => { 399 => 0x30, 415 => 0x19 },
+	'faceelementpositions' => { 125 => 0x4203 },
+	'faceelementselected' => { 125 => 0x4005 },
+	'faceelementtypes' => { 125 => 0x4201 },
+	'faceid' => { 463 => 'FaceID' },
+	'faceinfounknown' => { 111 => 0x2089 },
+	'facename' => { 384 => 0x123 },
+	'faceorientation' => { 109 => 0x8 },
+	'faceposition' => { 329 => 0x2, 385 => 0x4 },
+	'facepositions' => { 125 => 0x4103 },
+	'facerecognition' => { 384 => 0x120 },
+	'facesdetected' => { 53 => 0x2, 54 => 0x2, 55 => 0x3, 108 => 0x0, 109 => 0x2, 111 => 0x211c, 125 => 0x4100, 202 => 0x3, 291 => 0x1200, 310 => 0x3f, 329 => 0x0, 374 => 0xb5, 385 => 0x0, 404 => 0x0, 407 => 0x3, 417 => 0x30 },
+	'facesrecognized' => { 303 => 0x0 },
+	'facewidth' => { 54 => 0x1 },
+	'faithfuloutputhighlightpoint' => { 107 => 0x38 },
+	'faithfuloutputshadowpoint' => { 107 => 0x39 },
+	'faithfulrawcolortone' => { 107 => 0x31 },
+	'faithfulrawcontrast' => { 107 => 0x33 },
+	'faithfulrawhighlight' => { 107 => 0x79 },
+	'faithfulrawhighlightpoint' => { 107 => 0x36 },
+	'faithfulrawlinear' => { 107 => 0x34 },
+	'faithfulrawsaturation' => { 107 => 0x32 },
+	'faithfulrawshadow' => { 107 => 0x82 },
+	'faithfulrawshadowpoint' => { 107 => 0x37 },
+	'faithfulrawsharpness' => { 107 => 0x35 },
+	'faithfulunsharpmaskfineness' => { 107 => 0xac },
+	'faithfulunsharpmaskstrength' => { 107 => 0xaa },
+	'faithfulunsharpmaskthreshold' => { 107 => 0xae },
+	'far' => { 452 => 'Far' },
+	'fastresetlinetime' => { 135 => 0x1860 },
+	'feedidentifier' => { 479 => 'FeedIdentifier' },
+	'femicroadjustment' => { 82 => 0x111 },
+	'ffid' => { 471 => 'ffid' },
+	'field' => { 482 => 'field' },
+	'fieldcount' => { 292 => 0x103f },
+	'fieldofview' => { 370 => "FOV\x00" },
+	'fifoenonepixeldelay' => { 135 => 0x1901 },
+	'filecreatedate' => { 118 => 'FileCreateDate' },
+	'filedatarate' => { 493 => 'fileDataRate' },
+	'fileformat' => { 93 => 0x0, 130 => 0x14, 387 => [0x22,0x26], 410 => 0xb000 },
+	'filegroupid' => { 118 => '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, 311 => 0x0 },
+	'fileindex2' => { 21 => 0x290 },
+	'filemodifydate' => { 118 => 'FileModifyDate' },
+	'filename' => { 118 => 'FileName' },
+	'filenameasdelivered' => { 297 => 'FileNameAsDelivered' },
+	'filenumber' => { 56 => 0x1, 62 => 0x8, 95 => 0x1817, 112 => 'Canon-FileNumber', 203 => 0x4, 373 => 0x10 },
+	'filenumbermemory' => { 177 => 0x1a },
+	'filenumbersequence' => { 270 => '12.2', 275 => '3.1', 276 => '4.1', 277 => '4.1', 279 => '11.1', 280 => '4.3', 285 => '5.2' },
+	'filepermissions' => { 118 => 'FilePermissions' },
+	'filesource' => { 117 => 0xa300, 125 => 0x8000, 473 => 'FileSource' },
+	'fileuserid' => { 118 => 'FileUserID' },
+	'fileversion' => { 130 => 0x16 },
+	'fillflashautoreduction' => { 80 => 0xe, 81 => 0xe, 88 => 0xa },
+	'filllight' => { 467 => 'FillLight', 469 => 'FillLight' },
+	'fillorder' => { 117 => 0x10a },
+	'filmgraineffect' => { 287 => 0x538 },
+	'filmmode' => { 125 => 0x1401, 307 => 0x412, 310 => 0x42 },
+	'filmtype' => { 229 => 0x2 },
+	'filtereffect' => { 56 => 0xe, 223 => 0x37, 224 => 0x3f, 225 => 0x47, 310 => 0xa1 },
+	'filtereffectauto' => { 69 => 0xa0 },
+	'filtereffectfaithful' => { 68 => 0x70, 69 => 0x70 },
+	'filtereffectlandscape' => { 68 => 0x40, 69 => 0x40 },
+	'filtereffectmonochrome' => { 19 => 0xff, 68 => 0x88, 69 => 0x88 },
+	'filtereffectneutral' => { 68 => 0x58, 69 => 0x58 },
+	'filtereffectportrait' => { 68 => 0x28, 69 => 0x28 },
+	'filtereffectstandard' => { 68 => 0x10, 69 => 0x10 },
+	'filtereffectuserdef1' => { 68 => 0xa0, 69 => 0xb8 },
+	'filtereffectuserdef2' => { 68 => 0xb8, 69 => 0xd0 },
+	'filtereffectuserdef3' => { 68 => 0xd0, 69 => 0xe8 },
+	'finderdisplayduringexposure' => { 81 => 0x1 },
+	'finesharpness' => { 345 => 0x70 },
+	'finetuneoptcenterweighted' => { 270 => '7.2', 271 => '9.1', 273 => '9.1', 274 => '9.1', 278 => '8.1', 283 => '9.1', 284 => '9.1', 285 => '9.1' },
+	'finetuneopthighlightweighted' => { 273 => '46.1', 274 => '46.1', 283 => '46.1', 284 => '46.1' },
+	'finetuneoptmatrixmetering' => { 270 => '8.1', 271 => '8.2', 273 => '8.2', 274 => '8.2', 278 => '7.2', 279 => '6.1', 283 => '8.2', 284 => '8.2', 285 => '8.2' },
+	'finetuneoptspotmetering' => { 270 => '8.2', 271 => '9.2', 273 => '9.2', 274 => '9.2', 278 => '8.2', 279 => '6.2', 283 => '9.2', 284 => '9.2', 285 => '9.2' },
+	'finishexposure' => { 135 => 0xdbd },
+	'finishfiletype' => { 135 => 0xdb8 },
+	'finishlook' => { 135 => 0xdbc },
+	'finishnoise' => { 135 => 0xdba },
+	'finishresolution' => { 135 => 0xdb9 },
+	'finishsharpening' => { 135 => 0xdbb },
+	'firmware' => { 292 => 0x405, 387 => [0x8c,0x17,0x3b], 464 => 'Firmware' },
+	'firmware2' => { 387 => 0x57 },
+	'firmwaredate' => { 110 => 0x15, 111 => 0x2001, 371 => 0x4, 373 => 0x30 },
+	'firmwareid' => { 184 => 0x0 },
+	'firmwarename' => { 384 => 0xa001 },
+	'firmwarerevision' => { 19 => 0xa4, 62 => 0x1e, 375 => 0x0 },
+	'firmwarerevision2' => { 375 => 0xc },
+	'firmwareversion' => { 7 => 0x10b, 11 => 0x136, 14 => 0xff, 15 => 0x107, 135 => [0x415,0xce5], 151 => 0x57, 153 => 'FirmwareVersion', 308 => 0x320, 310 => 0x2, 312 => 0x3109, 345 => 0x230, 370 => ['CNFV','FIRM'], 372 => 0x18, 373 => 0x2a, 377 => 0x2 },
+	'firmwareversions' => { 354 => 0x301 },
+	'firstphotodate' => { 455 => 'FirstPhotoDate' },
+	'firstpublicationdate' => { 297 => 'FirstPublicationDate' },
+	'fixtureidentifier' => { 129 => 0x16, 462 => 'FixtureIdentifier' },
+	'flash' => { 112 => 'XMP-Flash', 117 => 0x9209, 149 => 0x22, 178 => 0x1f, 179 => 0x15, 373 => 0x5a, 473 => 'Flash' },
+	'flashaction' => { 397 => 0x3e, 398 => 0x3e, 410 => 0x2017, 415 => [0x2a,0x2c,0x30] },
+	'flashaction2' => { 397 => 0x4c, 398 => 0x4c, 415 => 0x77 },
+	'flashactionexternal' => { 415 => [0x78,0x7c] },
+	'flashactivity' => { 34 => 0x1c },
+	'flashbatterylevel' => { 43 => 0x249 },
+	'flashbias' => { 310 => 0x24 },
+	'flashbits' => { 34 => 0x1d },
+	'flashbuttonfunction' => { 82 => 0x70e },
+	'flashchargelevel' => { 292 => 0x1010 },
+	'flashcolorfilter' => { 206 => 0x10, 207 => 0x10 },
+	'flashcommandermode' => { 204 => '9.1', 205 => '9.1', 206 => '9.1', 207 => '9.1' },
+	'flashcompensation' => { 135 => 0x3f3, 204 => 0xa, 205 => 0xa, 206 => 0xa, 207 => 0x27, 208 => 0xa, 209 => 0x1b, 464 => 'FlashCompensation' },
+	'flashcontrol' => { 397 => 0x23, 398 => 0x1f, 399 => 0x21 },
+	'flashcontrolbuilt-in' => { 279 => '16.1', 280 => '23.1', 282 => '23.1', 283 => '24.1' },
+	'flashcontrolmode' => { 204 => '9.2', 205 => '9.2', 206 => '9.2', 207 => '9.2', 287 => 0x404 },
+	'flashcurtain' => { 310 => 0x48 },
+	'flashdefault' => { 180 => 0x42 },
+	'flashdevice' => { 292 => 0x1005 },
+	'flashdistance' => { 111 => 0x2034 },
+	'flashenergy' => { 117 => 0xa20b, 473 => 'FlashEnergy' },
+	'flashexposurebracketvalue' => { 221 => 0x18 },
+	'flashexposurecomp' => { 75 => 0xf, 125 => 0x1011, 156 => 'ExposureComp', 177 => 0x23, 182 => 0x104, 183 => 0x49c1, 221 => 0x12, 287 => 0x401, 292 => 0x1023, 345 => 0x4d, 377 => 0x100b, 387 => [0x3a,0x56], 410 => 0x104 },
+	'flashexposurecomp2' => { 248 => 0x4d2 },
+	'flashexposurecomp3' => { 206 => 0x1d },
+	'flashexposurecomp4' => { 206 => 0x27 },
+	'flashexposurecomparea' => { 271 => '38.4', 273 => '38.4', 274 => '38.4', 283 => '38.4', 284 => '38.4' },
+	'flashexposurecompset' => { 180 => 0x10, 318 => 0xe, 397 => 0x14, 398 => 0x12, 399 => 0x23, 415 => 0x1f },
+	'flashexposurecompset2' => { 415 => [0x26,0x2c] },
+	'flashexposureindicator' => { 180 => 0x54 },
+	'flashexposureindicatorlast' => { 180 => 0x56 },
+	'flashexposureindicatornext' => { 180 => 0x55 },
+	'flashexposurelock' => { 56 => 0x19 },
+	'flashfired' => { 137 => 0x5d, 156 => 'Fired', 177 => 0x14, 247 => '590.3', 473 => [\'Flash','FlashFired'] },
+	'flashfiring' => { 82 => 0x306, 83 => 0x6, 84 => 0x7, 87 => 0x7 },
+	'flashfirmwareversion' => { 288 => 0x1002 },
+	'flashfocallength' => { 204 => 0xb, 205 => 0xc, 206 => 0xc, 207 => 0xc, 208 => 0xc },
+	'flashfunction' => { 183 => 0x31, 473 => [\'Flash','FlashFunction'] },
+	'flashgndistance' => { 204 => 0xe, 205 => 0xf, 206 => 0xf, 207 => 0xf, 208 => 0xf },
+	'flashgroupacompensation' => { 204 => 0x11, 205 => 0x12, 206 => 0x13, 207 => 0x28, 208 => 0x28 },
+	'flashgroupacontrolmode' => { 204 => 0xf, 205 => '16.1', 206 => '17.1', 207 => '17.1', 208 => '17.1' },
+	'flashgroupaoutput' => { 204 => 0x11, 205 => 0x12, 206 => 0x13, 207 => 0x28, 208 => 0x28 },
+	'flashgroupbcompensation' => { 204 => 0x12, 205 => 0x13, 206 => 0x14, 207 => 0x29, 208 => 0x29 },
+	'flashgroupbcontrolmode' => { 204 => 0x10, 205 => '17.1', 206 => '18.1', 207 => '18.1', 208 => '18.1' },
+	'flashgroupboutput' => { 204 => 0x12, 205 => 0x13, 206 => 0x14, 207 => 0x29, 208 => 0x29 },
+	'flashgroupccompensation' => { 205 => 0x14, 206 => 0x15, 207 => 0x2a, 208 => 0x2a },
+	'flashgroupccontrolmode' => { 205 => '17.2', 206 => '18.2', 207 => '18.2', 208 => '18.2' },
+	'flashgroupcoutput' => { 205 => 0x14, 206 => 0x15, 207 => 0x2a, 208 => 0x2a },
+	'flashguidenumber' => { 75 => 0xd, 92 => 0x0, 156 => 'GuideNumber' },
+	'flashintensity' => { 110 => [0x19,0x5], 287 => 0x405 },
+	'flashlevel' => { 272 => 0x9, 410 => 0xb048 },
+	'flashmake' => { 156 => 'Make' },
+	'flashmanufacturer' => { 175 => 'FlashManufacturer' },
+	'flashmetering' => { 177 => 0x3f, 180 => 0x1c },
+	'flashmeteringmode' => { 7 => 0x15, 13 => 0x15, 14 => 0x15, 15 => 0x15, 16 => 0x15, 17 => 0x15, 18 => 0x15, 20 => 0x15, 22 => 0x15, 28 => 0x15 },
+	'flashmeteringsegments' => { 345 => 0x20a },
+	'flashmode' => { 110 => 0x4, 135 => 0x3f2, 137 => 0x5c, 148 => 0x27, 156 => 'Mode', 177 => 0x2, 178 => 0x20, 179 => 0x16, 180 => 0xf, 221 => 0x87, 287 => 0x400, 292 => 0x1004, 345 => 0xc, 352 => 0x4, 376 => 0x20, 377 => 0x100a, 386 => 0x225, 397 => 0x13, 398 => 0x7f, 399 => 0x20, 415 => 0x10, 418 => 0x1138, 419 => 0x1138, 420 => 0x1114, 421 => 0x1190, 422 => 0x116c, 423 => 0x1024, 424 => 0x21c, 425 => 0x21c, 426 => 0x211, 473 => [\'Flash','FlashMode'] },
+	'flashmodel' => { 156 => 'Model', 175 => 'FlashModel', 288 => 0x1001 },
+	'flashoptions' => { 326 => 0x2 },
+	'flashoptions2' => { 326 => 0x10 },
+	'flashoutput' => { 43 => 0x248, 75 => 0x21, 204 => 0xa, 205 => 0xa, 206 => 0xa, 207 => 0x27 },
+	'flashpixversion' => { 117 => 0xa000, 473 => 'FlashpixVersion' },
+	'flashredeyemode' => { 473 => [\'Flash','FlashRedEyeMode'] },
+	'flashremotecontrol' => { 287 => 0x403 },
+	'flashreturn' => { 473 => [\'Flash','FlashReturn'] },
+	'flashserialnumber' => { 156 => 'SerialNumber', 288 => 0x1003 },
+	'flashsetting' => { 221 => 0x8 },
+	'flashshutterspeed' => { 270 => '20.2', 271 => '23.2', 273 => '23.2', 274 => '23.2', 279 => '15.2', 280 => '22.2', 281 => '7.2', 282 => '22.2', 283 => '23.2', 284 => '23.2', 285 => '23.1' },
+	'flashsource' => { 204 => 0x4, 205 => 0x4, 206 => 0x4, 207 => 0x4, 208 => 0x4, 209 => 0x4 },
+	'flashstatus' => { 333 => 0x0, 415 => [0x82,0x86], 428 => 0x31, 429 => 0x39, 430 => 0x39 },
+	'flashstatusbuilt-in' => { 399 => [0x87,0x287] },
+	'flashstatusexternal' => { 399 => [0x88,0x288] },
+	'flashsyncspeed' => { 270 => '20.1', 271 => '23.1', 273 => '23.1', 274 => '23.1', 279 => '15.1', 280 => '22.1', 282 => '22.1', 283 => '23.1', 284 => '23.1' },
+	'flashsyncspeedav' => { 80 => 0x3, 82 => 0x10f, 83 => 0x2, 84 => 0x3, 85 => 0x2, 86 => 0x2, 87 => 0x3, 88 => 0x6 },
+	'flashthreshold' => { 92 => 0x1 },
+	'flashtype' => { 156 => 'Type', 180 => 0x59, 221 => 0x9, 288 => 0x1000 },
+	'flashwarning' => { 280 => '30.1', 281 => '7.1', 285 => '31.1', 310 => 0x62 },
+	'flexiblespotposition' => { 410 => 0x201d },
+	'flickerreduce' => { 386 => 0x218 },
+	'flickerreduction' => { 125 => 0x1446, 240 => 0xe84 },
+	'flickerreductionindicator' => { 240 => 0x5e2 },
+	'flightpitchdegree' => { 114 => 'FlightPitchDegree' },
+	'flightrolldegree' => { 114 => 'FlightRollDegree' },
+	'flightxspeed' => { 114 => 'FlightXSpeed' },
+	'flightyawdegree' => { 114 => 'FlightYawDegree' },
+	'flightyspeed' => { 114 => 'FlightYSpeed' },
+	'flightzspeed' => { 114 => 'FlightZSpeed' },
+	'fliphorizontal' => { 263 => 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, 75 => 0x15, 117 => 0x829d, 134 => 0xfd04, 137 => 0x1e, 139 => 0xfa23, 141 => 0xf103, 144 => 0x13, 146 => 0x3c, 148 => 0x1c, 149 => 0x18, 151 => 0xc, 160 => 'FNumber', 177 => 0xa, 178 => 0x36, 179 => 0x47, 180 => 0x9, 183 => 0x49c7, 219 => 0x38, 309 => 0x35a, 345 => 0x13, 384 => 0xa019, 387 => [0x31,0x49], 397 => 0x1, 398 => 0x1, 415 => [0x20,0x22,0x26], 473 => 'FNumber' },
+	'focaldistance' => { 453 => '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, 58 => 0x1, 111 => 0x1d, 117 => 0x920a, 144 => 0x1d, 160 => 'FocalLength', 177 => 0x12, 214 => 0xa, 215 => 0xb, 219 => [0xc,0x3c], 304 => 0x1, 345 => 0x1d, 354 => 0x403, 377 => 0x1500, 396 => 0xe, 422 => 0x1278, 423 => 0x1134, 424 => 0x32c, 425 => 0x32c, 426 => 0x30a, 473 => 'FocalLength' },
+	'focallength2' => { 415 => [0x23,0x25,0x29] },
+	'focallengthin35mmformat' => { 117 => 0xa405, 384 => 0xa01a, 473 => 'FocalLengthIn35mmFilm' },
+	'focallengthtelezoom' => { 396 => 0x10 },
+	'focalplaneafpointarea' => { 427 => 0x2 },
+	'focalplaneafpointlocation1' => { 427 => 0x6 },
+	'focalplaneafpointlocation10' => { 427 => 0x2a },
+	'focalplaneafpointlocation11' => { 427 => 0x2e },
+	'focalplaneafpointlocation12' => { 427 => 0x32 },
+	'focalplaneafpointlocation13' => { 427 => 0x36 },
+	'focalplaneafpointlocation14' => { 427 => 0x3a },
+	'focalplaneafpointlocation15' => { 427 => 0x3e },
+	'focalplaneafpointlocation2' => { 427 => 0xa },
+	'focalplaneafpointlocation3' => { 427 => 0xe },
+	'focalplaneafpointlocation4' => { 427 => 0x12 },
+	'focalplaneafpointlocation5' => { 427 => 0x16 },
+	'focalplaneafpointlocation6' => { 427 => 0x1a },
+	'focalplaneafpointlocation7' => { 427 => 0x1e },
+	'focalplaneafpointlocation8' => { 427 => 0x22 },
+	'focalplaneafpointlocation9' => { 427 => 0x26 },
+	'focalplaneafpointsused' => { 427 => 0x1 },
+	'focalplanediagonal' => { 288 => 0x103, 292 => 0x205 },
+	'focalplaneresolutionunit' => { 117 => 0xa210, 473 => 'FocalPlaneResolutionUnit' },
+	'focalplanexresolution' => { 117 => 0xa20e, 473 => 'FocalPlaneXResolution' },
+	'focalplanexsize' => { 58 => 0x2 },
+	'focalplanexunknown' => { 58 => 0x2 },
+	'focalplaneyresolution' => { 117 => 0xa20f, 473 => 'FocalPlaneYResolution' },
+	'focalplaneysize' => { 58 => 0x3 },
+	'focalplaneyunknown' => { 58 => 0x3 },
+	'focalpointx' => { 453 => 'FocalPointX' },
+	'focalpointy' => { 453 => 'FocalPointY' },
+	'focaltype' => { 10 => 0x2d, 58 => 0x0 },
+	'focalunits' => { 34 => 0x19 },
+	'focus' => { 253 => 0x8 },
+	'focusarea' => { 177 => 0x31 },
+	'focusareaselection' => { 281 => '15.2' },
+	'focusbracket' => { 310 => 0xbd },
+	'focusbracketstepsize' => { 287 => 0x308 },
+	'focuscontinuous' => { 34 => 0x20 },
+	'focusdisplayaiservoandmf' => { 82 => 0x515 },
+	'focusdistance' => { 160 => 'FocusDistance', 177 => 0x13, 183 => 0x49bb, 214 => 0x9, 215 => 0xa, 219 => [0xb,0x4f], 290 => 0x305, 304 => 0x0, 308 => 0x304, 309 => 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, 56 => 0x15, 75 => 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, 56 => 0x14, 75 => 0x13 },
+	'focusholdbutton' => { 180 => 0x44 },
+	'focusinfoversion' => { 290 => 0x0 },
+	'focusingscreen' => { 81 => 0x0, 82 => 0x80b, 87 => 0x0 },
+	'focuslocation' => { 410 => 0x2027 },
+	'focuslocked' => { 176 => 0x14 },
+	'focusmode' => { 34 => 0x7, 110 => 0x3, 111 => [0x3003,0xd], 125 => 0x1021, 135 => 0x3f5, 137 => 0x38, 153 => 'FocusMode', 177 => 0x30, 179 => 0xe, 180 => 0xc, 221 => 0x7, 287 => 0x301, 292 => 0x100b, 310 => 0x7, 345 => 0xd, 352 => 0x3, 377 => 0x1006, 390 => [0xb,0x5], 396 => [0x15,0x1d], 397 => 0x4d, 398 => 0x4d, 410 => [0xb042,0xb04e,0x201b], 415 => 0x13, 434 => 0x16 },
+	'focusmode2' => { 124 => '0.1', 326 => '3.1', 415 => [0x2c,0x2e,0x32] },
+	'focusmodesetting' => { 272 => '10.1', 394 => 0x14, 395 => 0x15, 397 => 0x10, 398 => 0xf, 399 => 0x6 },
+	'focusmodeswitch' => { 180 => 0x58, 397 => 0x2e },
+	'focuspixel' => { 125 => 0x1023 },
+	'focuspointwrap' => { 270 => '2.2', 271 => '2.2', 273 => '2.1', 274 => '2.1', 278 => '1.1', 279 => '2.2', 280 => '1.1', 283 => '2.2', 284 => '2.1', 285 => '2.5' },
+	'focusposition' => { 214 => 0x8, 215 => 0x8, 219 => 0x9, 345 => 0x10, 408 => 0x9bb },
+	'focusposition2' => { 415 => [0x29,0x2b,0x2f], 434 => 0x2d, 437 => 0x20 },
+	'focusprocess' => { 287 => 0x302 },
+	'focusrange' => { 34 => 0x12, 292 => 0x100a },
+	'focusrangeindex' => { 336 => '3.1' },
+	'focusringrotation' => { 82 => 0x713 },
+	'focussetting' => { 387 => 0x6 },
+	'focusstatus' => { 396 => 0x19, 397 => 0x53, 398 => 0x53 },
+	'focusstepcount' => { 290 => 0x301, 292 => 0x100e },
+	'focusstepinfinity' => { 290 => 0x303, 292 => 0x103b },
+	'focusstepnear' => { 290 => 0x304, 292 => 0x103c },
+	'focustrackinglockon' => { 270 => ['1.5','4.1'], 271 => '1.4', 278 => '0.4', 279 => '3.1', 280 => '0.4', 283 => '1.4' },
+	'focuswarning' => { 125 => 0x1301 },
+	'foldername' => { 177 => 0x27 },
+	'foldernumber' => { 397 => 0x9a, 399 => [0x402,0x114,0x316] },
+	'fontcomposite' => { 498 => [\'Fonts','FontsComposite'] },
+	'fontface' => { 498 => [\'Fonts','FontsFontFace'] },
+	'fontfamily' => { 498 => [\'Fonts','FontsFontFamily'] },
+	'fontfilename' => { 498 => [\'Fonts','FontsFontFileName'] },
+	'fontname' => { 498 => [\'Fonts','FontsFontName'] },
+	'fonts' => { 498 => 'Fonts' },
+	'fonttype' => { 498 => [\'Fonts','FontsFontType'] },
+	'fontversion' => { 498 => [\'Fonts','FontsVersionString'] },
+	'for' => { 361 => 'For' },
+	'forcewrite' => { 118 => 'ForceWrite' },
+	'format' => { 370 => "\xa9fmt", 452 => 'Format', 470 => 'format', 491 => 'Format' },
+	'forwardlock' => { 488 => 'forwardlock' },
+	'forwardmatrix1' => { 117 => 0xc714 },
+	'forwardmatrix2' => { 117 => 0xc715 },
+	'fossilspecimen' => { 116 => 'FossilSpecimen' },
+	'fossilspecimenmaterialsampleid' => { 116 => [\'FossilSpecimen','FossilSpecimenMaterialSampleID'] },
+	'framecount' => { 65 => [0x2,0x4] },
+	'frameheight' => { 125 => 0x3822 },
+	'framenum' => { 356 => 0xd7 },
+	'framenumber' => { 125 => 0x8003, 183 => 0x3c, 345 => 0x29 },
+	'framerate' => { 65 => [0x1,0x6], 117 => 0xc764, 125 => 0x3820 },
+	'framereadouttime' => { 364 => 'camera.framereadouttimeinmicroseconds' },
+	'framewidth' => { 125 => 0x3821 },
+	'framing' => { 482 => 'framing' },
+	'freebytes' => { 95 => 0x1 },
+	'freememorycardimages' => { 178 => [0x37,0x54], 179 => [0x2d,0x4a], 180 => 0x32 },
+	'fujiflashmode' => { 125 => 0x1010 },
+	'fullhdhighspeedrec' => { 125 => 0x3824 },
+	'fullimagesize' => { 410 => 0xb02b },
+	'fullpanoheightpixels' => { 455 => 'FullPanoHeightPixels', 456 => 'FullPanoHeightPixels' },
+	'fullpanowidthpixels' => { 455 => 'FullPanoWidthPixels', 456 => 'FullPanoWidthPixels' },
+	'fullpresssnap' => { 377 => 0x100d },
+	'fullsizeimage' => { 159 => 'data' },
+	'fullsizeimagename' => { 159 => '1Name' },
+	'fullsizeimagetype' => { 159 => '0Type' },
+	'func1button' => { 273 => '14.1', 274 => '14.1', 284 => '14.1' },
+	'func1buttonplusdials' => { 273 => '42.1', 274 => '42.1', 284 => '42.1' },
+	'func2button' => { 273 => '80.1', 274 => '80.1', 284 => '80.1' },
+	'func2buttonplusdials' => { 273 => '81.1' },
+	'func3button' => { 273 => '83.1' },
+	'funcbutton' => { 270 => ['14.1','15.1'], 271 => '14.1', 279 => '28.1', 280 => '13.1', 283 => '14.1', 285 => '14.1' },
+	'funcbuttonplusdials' => { 270 => ['14.2','15.2'], 271 => '14.2', 279 => '31.1', 283 => '42.1' },
+	'functionbutton' => { 277 => '13.1', 281 => '5.2' },
+	'gainbase' => { 291 => 0x610 },
+	'gaincontrol' => { 117 => 0xa407, 473 => 'GainControl' },
+	'gamma' => { 117 => 0xa500, 135 => 0x8fe, 315 => 0x11c, 474 => 'Gamma' },
+	'gammablackpoint' => { 103 => 0xc },
+	'gammacolortone' => { 103 => 0x3 },
+	'gammacompensatedvalue' => { 131 => 0x91 },
+	'gammacontrast' => { 103 => 0x2 },
+	'gammacurveoutputrange' => { 103 => 0xf },
+	'gammahighlight' => { 103 => 0xa },
+	'gammalinear' => { 101 => 0x20200 },
+	'gammamidpoint' => { 103 => 0xe },
+	'gammasaturation' => { 103 => 0x4 },
+	'gammashadow' => { 103 => 0x9 },
+	'gammasharpnessstrength' => { 103 => 0x8 },
+	'gammaunsharpmaskfineness' => { 103 => 0x6 },
+	'gammaunsharpmaskstrength' => { 103 => 0x5 },
+	'gammaunsharpmaskthreshold' => { 103 => 0x7 },
+	'gammawhitepoint' => { 103 => 0xd },
+	'garminsettings' => { 370 => 'pmcc' },
+	'garminsoftware' => { 370 => 'uuid' },
+	'gdalmetadata' => { 117 => 0xa480 },
+	'gdalnodata' => { 117 => 0xa481 },
+	'geimagesize' => { 125 => 0x1304 },
+	'gemake' => { 127 => 0x300 },
+	'gemodel' => { 127 => 0x207 },
+	'genre' => { 362 => ['gnre',"\xa9gen"], 364 => 'genre', 370 => ['gnre',"\xa9gen"], 479 => 'Genre', 483 => 'genre', 493 => 'genre' },
+	'genrecvid' => { 479 => [\'Genre','GenreCvId'] },
+	'genrecvtermid' => { 479 => [\'Genre','GenreCvTermId'] },
+	'genrecvtermname' => { 479 => [\'Genre','GenreCvTermName'] },
+	'genrecvtermrefinedabout' => { 479 => [\'Genre','GenreCvTermRefinedAbout'] },
+	'genreid' => { 362 => 'geID' },
+	'geography' => { 484 => 'geography' },
+	'geologicalcontext' => { 116 => 'GeologicalContext' },
+	'geologicalcontextbed' => { 116 => [\'GeologicalContext','GeologicalContextBed'] },
+	'geologicalcontextformation' => { 116 => [\'GeologicalContext','GeologicalContextFormation'] },
+	'geologicalcontextgroup' => { 116 => [\'GeologicalContext','GeologicalContextGroup'] },
+	'geologicalcontextid' => { 116 => [\'GeologicalContext','GeologicalContextGeologicalContextID'] },
+	'geologicalcontextmember' => { 116 => [\'GeologicalContext','GeologicalContextMember'] },
+	'geosync' => { 118 => 'Geosync' },
+	'geotag' => { 118 => 'Geotag' },
+	'geotiffasciiparams' => { 117 => 0x87b1 },
+	'geotiffdirectory' => { 117 => 0x87af },
+	'geotiffdoubleparams' => { 117 => 0x87b0 },
+	'geotime' => { 118 => 'Geotime' },
+	'giftftppriority' => { 457 => 'GIFTFtpPriority' },
+	'gimbalpitchdegree' => { 114 => 'GimbalPitchDegree' },
+	'gimbalreverse' => { 114 => 'GimbalReverse' },
+	'gimbalrolldegree' => { 114 => 'GimbalRollDegree' },
+	'gimbalyawdegree' => { 114 => 'GimbalYawDegree' },
+	'globalaltitude' => { 359 => 0x419 },
+	'globalangle' => { 359 => 0x40d },
+	'good' => { 493 => 'good' },
+	'googlehostheader' => { 362 => 'gshh' },
+	'googlepingmessage' => { 362 => 'gspm' },
+	'googlepingurl' => { 362 => 'gspu' },
+	'googleplusuploadcode' => { 117 => 0x9009 },
+	'googlesourcedata' => { 362 => 'gssd' },
+	'googlestarttime' => { 362 => 'gsst' },
+	'googletrackduration' => { 362 => 'gstd' },
+	'goprotype' => { 370 => 'GoPr' },
+	'gpsaltitude' => { 128 => 0x6, 157 => 'Altitude', 473 => 'GPSAltitude' },
+	'gpsaltituderef' => { 128 => 0x5, 473 => 'GPSAltitudeRef' },
+	'gpsareainformation' => { 128 => 0x1c, 473 => 'GPSAreaInformation' },
+	'gpscoordinates' => { 362 => "\xa9xyz", 364 => 'location.ISO6709', 370 => ['@xyz',"\xa9xyz"] },
+	'gpsdatestamp' => { 128 => 0x1d },
+	'gpsdatetime' => { 157 => 'DateTime', 473 => 'GPSTimeStamp' },
+	'gpsdestbearing' => { 128 => 0x18, 157 => 'Bearing', 473 => 'GPSDestBearing' },
+	'gpsdestbearingref' => { 128 => 0x17, 473 => 'GPSDestBearingRef' },
+	'gpsdestdistance' => { 128 => 0x1a, 157 => 'Distance', 473 => 'GPSDestDistance' },
+	'gpsdestdistanceref' => { 128 => 0x19, 473 => 'GPSDestDistanceRef' },
+	'gpsdestlatitude' => { 128 => 0x14, 473 => 'GPSDestLatitude' },
+	'gpsdestlatituderef' => { 128 => 0x13 },
+	'gpsdestlongitude' => { 128 => 0x16, 473 => 'GPSDestLongitude' },
+	'gpsdestlongituderef' => { 128 => 0x15 },
+	'gpsdifferential' => { 128 => 0x1e, 157 => 'Differential', 473 => 'GPSDifferential' },
+	'gpsdop' => { 128 => 0xb, 473 => 'GPSDOP' },
+	'gpshpositioningerror' => { 128 => 0x1f, 473 => 'GPSHPositioningError' },
+	'gpsimgdirection' => { 128 => 0x11, 473 => 'GPSImgDirection' },
+	'gpsimgdirectionref' => { 128 => 0x10, 473 => 'GPSImgDirectionRef' },
+	'gpslatitude' => { 114 => 'GpsLatitude', 128 => 0x2, 157 => 'Latitude', 473 => 'GPSLatitude' },
+	'gpslatituderef' => { 128 => 0x1 },
+	'gpslongitude' => { 114 => 'GpsLongitude', 128 => 0x4, 157 => 'Longitude', 473 => 'GPSLongitude' },
+	'gpslongituderef' => { 128 => 0x3 },
+	'gpslongtitude' => { 114 => 'GpsLongtitude' },
+	'gpsmapdatum' => { 128 => 0x12, 157 => 'Datum', 473 => 'GPSMapDatum' },
+	'gpsmeasuremode' => { 128 => 0xa, 157 => 'MeasureMode', 473 => 'GPSMeasureMode' },
+	'gpsprocessingmethod' => { 128 => 0x1b, 473 => 'GPSProcessingMethod' },
+	'gpssatellites' => { 128 => 0x8, 157 => 'Satellites', 473 => 'GPSSatellites' },
+	'gpsspeed' => { 128 => 0xd, 157 => 'Speed', 473 => 'GPSSpeed' },
+	'gpsspeedref' => { 128 => 0xc, 473 => 'GPSSpeedRef' },
+	'gpsstatus' => { 128 => 0x9, 473 => 'GPSStatus' },
+	'gpsstring' => { 135 => 0x402 },
+	'gpstimestamp' => { 128 => 0x7 },
+	'gpstrack' => { 128 => 0xf, 157 => 'Heading', 473 => 'GPSTrack' },
+	'gpstrackref' => { 128 => 0xe, 473 => 'GPSTrackRef' },
+	'gpsversionid' => { 128 => 0x0, 473 => 'GPSVersionID' },
+	'gradation' => { 287 => 0x50f },
+	'gradientbasedcorractive' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionActive'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionActive'] },
+	'gradientbasedcorramount' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionAmount'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionAmount'] },
+	'gradientbasedcorrblacks2012' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBlacks2012'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBlacks2012'] },
+	'gradientbasedcorrbrightness' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBrightness'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalBrightness'] },
+	'gradientbasedcorrclarity' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity'] },
+	'gradientbasedcorrclarity2012' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity2012'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalClarity2012'] },
+	'gradientbasedcorrcontrast' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast'] },
+	'gradientbasedcorrcontrast2012' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast2012'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalContrast2012'] },
+	'gradientbasedcorrdefringe' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalDefringe'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalDefringe'] },
+	'gradientbasedcorrdehaze' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalDehaze'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalDehaze'] },
+	'gradientbasedcorrections' => { 467 => 'GradientBasedCorrections', 469 => 'GradientBasedCorrections' },
+	'gradientbasedcorrexposure' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure'] },
+	'gradientbasedcorrexposure2012' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure2012'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalExposure2012'] },
+	'gradientbasedcorrhighlights2012' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalHighlights2012'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalHighlights2012'] },
+	'gradientbasedcorrhue' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalHue','GradientBasedCorrectionsLocalToningHue'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalHue','GradientBasedCorrectionsLocalToningHue'] },
+	'gradientbasedcorrluminancenoise' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalLuminanceNoise'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalLuminanceNoise'] },
+	'gradientbasedcorrmaskalpha' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAlpha'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAlpha'] },
+	'gradientbasedcorrmaskangle' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAngle'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksAngle'] },
+	'gradientbasedcorrmaskbottom' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksBottom'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksBottom'] },
+	'gradientbasedcorrmaskcentervalue' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterValue'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterValue'] },
+	'gradientbasedcorrmaskcenterweight' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterWeight'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksCenterWeight'] },
+	'gradientbasedcorrmaskdabs' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksDabs'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksDabs'] },
+	'gradientbasedcorrmaskfeather' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFeather'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFeather'] },
+	'gradientbasedcorrmaskflipped' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlipped'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlipped'] },
+	'gradientbasedcorrmaskflow' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlow'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFlow'] },
+	'gradientbasedcorrmaskfullx' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullX'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullX'] },
+	'gradientbasedcorrmaskfully' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullY'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksFullY'] },
+	'gradientbasedcorrmaskleft' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksLeft'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksLeft'] },
+	'gradientbasedcorrmaskmidpoint' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMidpoint'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMidpoint'] },
+	'gradientbasedcorrmaskperimetervalue' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksPerimeterValue'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksPerimeterValue'] },
+	'gradientbasedcorrmaskradius' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRadius'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRadius'] },
+	'gradientbasedcorrmaskright' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRight'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRight'] },
+	'gradientbasedcorrmaskroundness' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRoundness'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksRoundness'] },
+	'gradientbasedcorrmasks' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasks'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasks'] },
+	'gradientbasedcorrmasksizex' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeX'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeX'] },
+	'gradientbasedcorrmasksizey' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeY'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksSizeY'] },
+	'gradientbasedcorrmasktop' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksTop'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksTop'] },
+	'gradientbasedcorrmaskvalue' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMaskValue'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksMaskValue'] },
+	'gradientbasedcorrmaskversion' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksVersion'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksVersion'] },
+	'gradientbasedcorrmaskwhat' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksWhat'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksWhat'] },
+	'gradientbasedcorrmaskx' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksX'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksX'] },
+	'gradientbasedcorrmasky' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksY'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksY'] },
+	'gradientbasedcorrmaskzerox' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroX'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroX'] },
+	'gradientbasedcorrmaskzeroy' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroY'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionMasksZeroY'] },
+	'gradientbasedcorrmoire' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalMoire'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalMoire'] },
+	'gradientbasedcorrrangemask' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMask'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMask'] },
+	'gradientbasedcorrrangemaskcoloramount' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskColorAmount'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskColorAmount'] },
+	'gradientbasedcorrrangemaskdepthfeather' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskDepthFeather'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskDepthFeather'] },
+	'gradientbasedcorrrangemaskdepthmax' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskDepthMax'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskDepthMax'] },
+	'gradientbasedcorrrangemaskdepthmin' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskDepthMin'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskDepthMin'] },
+	'gradientbasedcorrrangemasklumfeather' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskLumFeather'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskLumFeather'] },
+	'gradientbasedcorrrangemasklummax' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskLumMax'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskLumMax'] },
+	'gradientbasedcorrrangemasklummin' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskLumMin'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskLumMin'] },
+	'gradientbasedcorrrangemasktype' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskType'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskType'] },
+	'gradientbasedcorrrangemaskversion' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskVersion'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsCorrectionRangeMaskVersion'] },
+	'gradientbasedcorrsaturation' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSaturation','GradientBasedCorrectionsLocalToningSaturation'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSaturation','GradientBasedCorrectionsLocalToningSaturation'] },
+	'gradientbasedcorrshadows2012' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalShadows2012'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalShadows2012'] },
+	'gradientbasedcorrsharpness' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSharpness'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalSharpness'] },
+	'gradientbasedcorrtemperature' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTemperature'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTemperature'] },
+	'gradientbasedcorrtexture' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTexture'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTexture'] },
+	'gradientbasedcorrtint' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTint'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalTint'] },
+	'gradientbasedcorrwhat' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsWhat'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsWhat'] },
+	'gradientbasedcorrwhites2012' => { 467 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalWhites2012'], 469 => [\'GradientBasedCorrections','GradientBasedCorrectionsLocalWhites2012'] },
+	'grainamount' => { 467 => 'GrainAmount', 469 => 'GrainAmount' },
+	'graineffect' => { 125 => 0x1047 },
+	'grainfrequency' => { 467 => 'GrainFrequency', 469 => 'GrainFrequency' },
+	'grainseed' => { 467 => 'GrainSeed', 469 => 'GrainSeed' },
+	'grainsize' => { 467 => 'GrainSize', 469 => 'GrainSize' },
+	'graymixeraqua' => { 467 => 'GrayMixerAqua', 469 => 'GrayMixerAqua' },
+	'graymixerblue' => { 467 => 'GrayMixerBlue', 469 => 'GrayMixerBlue' },
+	'graymixergreen' => { 467 => 'GrayMixerGreen', 469 => 'GrayMixerGreen' },
+	'graymixermagenta' => { 467 => 'GrayMixerMagenta', 469 => 'GrayMixerMagenta' },
+	'graymixerorange' => { 467 => 'GrayMixerOrange', 469 => 'GrayMixerOrange' },
+	'graymixerpurple' => { 467 => 'GrayMixerPurple', 469 => 'GrayMixerPurple' },
+	'graymixerred' => { 467 => 'GrayMixerRed', 469 => 'GrayMixerRed' },
+	'graymixeryellow' => { 467 => 'GrayMixerYellow', 469 => 'GrayMixerYellow' },
+	'graypoint' => { 444 => 0x8021 },
+	'grayresponseunit' => { 117 => 0x122 },
+	'greencurvelimits' => { 106 => 0x1c4 },
+	'greencurvepoints' => { 105 => 0x53, 106 => 0x19a },
+	'greenhsl' => { 101 => 0x20913 },
+	'greenhue' => { 467 => 'GreenHue', 469 => 'GreenHue' },
+	'greensaturation' => { 467 => 'GreenSaturation', 469 => 'GreenSaturation' },
+	'griddisplay' => { 270 => '13.3', 271 => '4.3', 273 => '4.2', 274 => '4.2', 275 => '2.2', 279 => '10.5', 280 => '3.4', 281 => '6.1', 283 => '4.4', 284 => '4.2', 285 => '4.2' },
+	'gripbatteryadload' => { 324 => 0x5 },
+	'gripbatteryadnoload' => { 324 => 0x4 },
+	'gripbatterystate' => { 324 => '1.2' },
+	'group' => { 467 => 'Group', 469 => 'Group' },
+	'groupareaafillumination' => { 271 => '46.4', 274 => '47.4', 283 => '47.4' },
+	'grouping' => { 362 => ['grup',"\xa9grp"], 370 => "\xa9grp" },
+	'guid' => { 362 => 'GUID' },
+	'h2resetblackpixels' => { 135 => 0x18a6 },
+	'h3resetblackcolumns' => { 135 => 0x18ce },
+	'h3resetblackpixels' => { 135 => 0x18b0 },
+	'halftonehints' => { 117 => 0x141 },
+	'hardlink' => { 118 => 'HardLink' },
+	'hasalternative' => { 483 => 'hasAlternative' },
+	'hascorrection' => { 483 => 'hasCorrection' },
+	'hascorrectiona-lang' => { 483 => [\'hasCorrection','hasCorrectionA-lang'] },
+	'hascorrectiona-platform' => { 483 => [\'hasCorrection','hasCorrectionA-platform'] },
+	'hascorrectiontext' => { 483 => [\'hasCorrection','hasCorrectionText'] },
+	'hascrop' => { 467 => 'HasCrop', 469 => 'HasCrop' },
+	'hasextendedxmp' => { 495 => 'HasExtendedXMP' },
+	'hassettings' => { 467 => 'HasSettings', 469 => 'HasSettings' },
+	'hastranslation' => { 483 => 'hasTranslation' },
+	'hasvisibleoverprint' => { 498 => 'HasVisibleOverprint' },
+	'hasvisibletransparency' => { 498 => 'HasVisibleTransparency' },
+	'hdr' => { 59 => 0x1, 211 => 0x4, 310 => 0x9e, 345 => 0x85, 410 => 0x200a },
+	'hdreffect' => { 59 => 0x2 },
+	'hdrimagetype' => { 1 => 0xa },
+	'hdrinfoversion' => { 211 => 0x0 },
+	'hdrlevel' => { 211 => 0x5, 399 => 0x2e, 415 => 0x17 },
+	'hdrlevel2' => { 211 => 0x7 },
+	'hdrpmakernote' => { 450 => 'hdrp_makernote' },
+	'hdrsetting' => { 399 => 0x2d, 415 => 0x16, 418 => 0x1148, 419 => 0x1148, 420 => 0x1124, 421 => 0x11a0, 422 => 0x117c, 423 => 0x1034, 424 => 0x22c, 425 => 0x22c, 426 => 0x21f },
+	'hdrshot' => { 310 => 0x76 },
+	'hdrsmoothing' => { 211 => 0x6 },
+	'hdvideo' => { 362 => 'hdvd' },
+	'headline' => { 129 => 0x69, 479 => 'Headline', 481 => 'Headline' },
+	'hierarchicalkeywords' => { 168 => [\'Keywords','KeywordsHierarchy'] },
+	'hierarchicalkeywords1' => { 168 => [\'Keywords','KeywordsHierarchyKeyword'] },
+	'hierarchicalkeywords1applied' => { 168 => [\'Keywords','KeywordsHierarchyApplied'] },
+	'hierarchicalkeywords1children' => { 168 => [\'Keywords','KeywordsHierarchyChildren'] },
+	'hierarchicalkeywords2' => { 168 => [\'Keywords','KeywordsHierarchyChildrenKeyword'] },
+	'hierarchicalkeywords2applied' => { 168 => [\'Keywords','KeywordsHierarchyChildrenApplied'] },
+	'hierarchicalkeywords2children' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildren'] },
+	'hierarchicalkeywords3' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenKeyword'] },
+	'hierarchicalkeywords3applied' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenApplied'] },
+	'hierarchicalkeywords3children' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildren'] },
+	'hierarchicalkeywords4' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenKeyword'] },
+	'hierarchicalkeywords4applied' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenApplied'] },
+	'hierarchicalkeywords4children' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildren'] },
+	'hierarchicalkeywords5' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenKeyword'] },
+	'hierarchicalkeywords5applied' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenApplied'] },
+	'hierarchicalkeywords5children' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildren'] },
+	'hierarchicalkeywords6' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenKeyword'] },
+	'hierarchicalkeywords6applied' => { 168 => [\'Keywords','KeywordsHierarchyChildrenChildrenChildrenChildrenChildrenApplied'] },
+	'hierarchicalsubject' => { 459 => 'hierarchicalSubject' },
+	'highestbiostratigraphiczone' => { 116 => [\'GeologicalContext','GeologicalContextHighestBiostratigraphicZone'] },
+	'highisomultiplierblue' => { 315 => 0x1a },
+	'highisomultipliergreen' => { 315 => 0x19 },
+	'highisomultiplierred' => { 315 => 0x18 },
+	'highisonoisereduction' => { 16 => 0xbc, 17 => 0xbd, 20 => 0xbd, 28 => 0xc9, 61 => 0x5, 82 => 0x202, 221 => 0xb1, 345 => 0x71, 397 => 0x2c, 398 => 0x26, 399 => 0x26, 410 => 0x2009, 415 => 0x12, 440 => 0x42 },
+	'highisonoisereduction2' => { 410 => 0xb050 },
+	'highlight' => { 387 => 0xf },
+	'highlight2012' => { 467 => 'Highlight2012', 469 => 'Highlight2012' },
+	'highlightadj' => { 101 => 0x2030c },
+	'highlightcolordistortreduct' => { 444 => 0x8026 },
+	'highlightlinearitylimit' => { 384 => 0xa025 },
+	'highlightprotection' => { 262 => 0x6 },
+	'highlightrecovery' => { 467 => 'HighlightRecovery', 469 => 'HighlightRecovery' },
+	'highlights' => { 461 => 'Highlights' },
+	'highlights2012' => { 467 => 'Highlights2012', 469 => 'Highlights2012' },
+	'highlightsadj' => { 444 => 0x9019 },
+	'highlightshadow' => { 310 => 0xad },
+	'highlighttone' => { 125 => 0x1041 },
+	'highlighttonepriority' => { 13 => 0x7, 16 => 0x7, 17 => 0x7, 18 => 0x7, 20 => 0x7, 22 => 0x7, 28 => 0x7, 61 => 0x3, 82 => 0x203 },
+	'highlightwarning' => { 310 => 0x8002 },
+	'highlowkeyadj' => { 345 => 0x6c },
+	'highspeedsync' => { 180 => 0x5, 397 => 0x2, 398 => 0x2 },
+	'hintversion' => { 370 => 'hinv' },
+	'histogramxml' => { 263 => 0x83a1a25 },
+	'history' => { 481 => 'History', 494 => 'History' },
+	'historyaction' => { 494 => [\'History','HistoryAction'] },
+	'historychanged' => { 494 => [\'History','HistoryChanged'] },
+	'historyinstanceid' => { 494 => [\'History','HistoryInstanceID'] },
+	'historyparameters' => { 494 => [\'History','HistoryParameters'] },
+	'historysoftwareagent' => { 494 => [\'History','HistorySoftwareAgent'] },
+	'historywhen' => { 494 => [\'History','HistoryWhen'] },
+	'holefilldarkdeltathreshold' => { 135 => 0xc88 },
+	'holefilldeltathreshold' => { 135 => 0xc7e },
+	'hometowncity' => { 111 => 0x3006, 345 => 0x23, 351 => 0x2 },
+	'hometowncitycode' => { 352 => 0x1000 },
+	'hometowndst' => { 345 => 0x25, 351 => '0.2' },
+	'hostcomputer' => { 117 => 0x13c },
+	'hostsoftwarerendering' => { 135 => 0xce7 },
+	'hue' => { 185 => 0x3b, 224 => 0x3d, 225 => 0x45, 345 => 0x67 },
+	'hueadj' => { 266 => 0x2f, 444 => 0x8019 },
+	'hueadjust' => { 377 => 0x1016 },
+	'hueadjustment' => { 178 => 0x4a, 179 => 0x40, 221 => 0x92, 223 => 0x36 },
+	'hueadjustmentaqua' => { 467 => 'HueAdjustmentAqua', 469 => 'HueAdjustmentAqua' },
+	'hueadjustmentblue' => { 467 => 'HueAdjustmentBlue', 469 => 'HueAdjustmentBlue' },
+	'hueadjustmentgreen' => { 467 => 'HueAdjustmentGreen', 469 => 'HueAdjustmentGreen' },
+	'hueadjustmentmagenta' => { 467 => 'HueAdjustmentMagenta', 469 => 'HueAdjustmentMagenta' },
+	'hueadjustmentorange' => { 467 => 'HueAdjustmentOrange', 469 => 'HueAdjustmentOrange' },
+	'hueadjustmentpurple' => { 467 => 'HueAdjustmentPurple', 469 => 'HueAdjustmentPurple' },
+	'hueadjustmentred' => { 467 => 'HueAdjustmentRed', 469 => 'HueAdjustmentRed' },
+	'hueadjustmentyellow' => { 467 => 'HueAdjustmentYellow', 469 => 'HueAdjustmentYellow' },
+	'huesetting' => { 295 => 0x1011 },
+	'humanobservation' => { 116 => 'HumanObservation' },
+	'humanobservationday' => { 116 => [\'HumanObservation','HumanObservationDay'] },
+	'humanobservationearliestdate' => { 116 => [\'HumanObservation','HumanObservationEarliestDate'] },
+	'humanobservationenddayofyear' => { 116 => [\'HumanObservation','HumanObservationEndDayOfYear'] },
+	'humanobservationeventdate' => { 116 => [\'HumanObservation','HumanObservationEventDate'] },
+	'humanobservationeventid' => { 116 => [\'HumanObservation','HumanObservationEventID'] },
+	'humanobservationeventremarks' => { 116 => [\'HumanObservation','HumanObservationEventRemarks'] },
+	'humanobservationeventtime' => { 116 => [\'HumanObservation','HumanObservationEventTime'] },
+	'humanobservationfieldnotes' => { 116 => [\'HumanObservation','HumanObservationFieldNotes'] },
+	'humanobservationfieldnumber' => { 116 => [\'HumanObservation','HumanObservationFieldNumber'] },
+	'humanobservationhabitat' => { 116 => [\'HumanObservation','HumanObservationHabitat'] },
+	'humanobservationlatestdate' => { 116 => [\'HumanObservation','HumanObservationLatestDate'] },
+	'humanobservationmonth' => { 116 => [\'HumanObservation','HumanObservationMonth'] },
+	'humanobservationparenteventid' => { 116 => [\'HumanObservation','HumanObservationParentEventID'] },
+	'humanobservationsamplesizeunit' => { 116 => [\'HumanObservation','HumanObservationSampleSizeUnit'] },
+	'humanobservationsamplesizevalue' => { 116 => [\'HumanObservation','HumanObservationSampleSizeValue'] },
+	'humanobservationsamplingeffort' => { 116 => [\'HumanObservation','HumanObservationSamplingEffort'] },
+	'humanobservationsamplingprotocol' => { 116 => [\'HumanObservation','HumanObservationSamplingProtocol'] },
+	'humanobservationstartdayofyear' => { 116 => [\'HumanObservation','HumanObservationStartDayOfYear'] },
+	'humanobservationverbatimeventdate' => { 116 => [\'HumanObservation','HumanObservationVerbatimEventDate'] },
+	'humanobservationyear' => { 116 => [\'HumanObservation','HumanObservationYear'] },
+	'humidity' => { 117 => 0x9401, 474 => 'Humidity' },
+	'icc_profile' => { 118 => 'ICC_Profile' },
+	'iccprofilename' => { 481 => 'ICCProfile' },
+	'iconuri' => { 370 => 'icnu' },
+	'idccreativestyle' => { 444 => 0x8000 },
+	'idcpreviewlength' => { 444 => 0x202 },
+	'idcpreviewstart' => { 444 => 0x201 },
+	'identification' => { 116 => 'Identification' },
+	'identificationid' => { 116 => [\'Identification','IdentificationIdentificationID'] },
+	'identificationqualifier' => { 116 => [\'Identification','IdentificationIdentificationQualifier'] },
+	'identificationreferences' => { 116 => [\'Identification','IdentificationIdentificationReferences'] },
+	'identificationremarks' => { 116 => [\'Identification','IdentificationIdentificationRemarks'] },
+	'identificationverificationstatus' => { 116 => [\'Identification','IdentificationIdentificationVerificationStatus'] },
+	'identifiedby' => { 116 => [\'Identification','IdentificationIdentifiedBy'] },
+	'identifier' => { 470 => 'identifier', 491 => 'Identifier' },
+	'ifcameramodel' => { 135 => 0x9c8 },
+	'illumination' => { 281 => '0.5', 372 => 0x48 },
+	'imageabsolutex' => { 135 => 0x3fe },
+	'imageabsolutey' => { 135 => 0x3ff },
+	'imageadjustment' => { 221 => 0x80, 253 => 0x5 },
+	'imagealterationconstraints' => { 297 => 'ImageAlterationConstraints' },
+	'imagearea' => { 234 => 0x10, 237 => 0x10 },
+	'imageareaoffset' => { 345 => 0x38 },
+	'imageauthentication' => { 221 => 0x20 },
+	'imageboundary' => { 221 => 0x16 },
+	'imagecount' => { 125 => 0x1438, 221 => 0xa5, 413 => 0x11b },
+	'imagecreator' => { 297 => 'ImageCreator' },
+	'imagecreatorid' => { 297 => [\'ImageCreator','ImageCreatorImageCreatorID'] },
+	'imagecreatorimageid' => { 297 => 'ImageCreatorImageID' },
+	'imagecreatorname' => { 297 => [\'ImageCreator','ImageCreatorImageCreatorName'] },
+	'imagecropx' => { 135 => 0x41f },
+	'imagecropy' => { 135 => 0x420 },
+	'imagedata' => { 454 => 'Data' },
+	'imagedatasize' => { 221 => 0xa2 },
+	'imagedescription' => { 117 => 0x10e, 489 => 'ImageDescription' },
+	'imageduplicationconstraints' => { 297 => 'ImageDuplicationConstraints' },
+	'imagedustoff' => { 263 => 0xfe443a45 },
+	'imageeditcount' => { 345 => 0x41 },
+	'imageediting' => { 345 => 0x32 },
+	'imageeffects' => { 377 => 0x1010 },
+	'imagefileconstraints' => { 297 => 'ImageFileConstraints' },
+	'imagefileformatasdelivered' => { 297 => 'ImageFileFormatAsDelivered' },
+	'imagefilesizeasdelivered' => { 297 => 'ImageFileSizeAsDelivered' },
+	'imagegeneration' => { 125 => 0x1436 },
+	'imageheight' => { 117 => 0x101, 184 => 0xc, 354 => 0x10d, 452 => 'ImageHeight', 489 => 'ImageLength' },
+	'imagehistory' => { 117 => 0x9213, 472 => 'ImageHistory' },
+	'imageidnumber' => { 305 => 0x340 },
+	'imagemimetype' => { 454 => 'Mime' },
+	'imagenumber' => { 117 => 0x9211, 153 => 'ImageNumber', 178 => 0xae, 179 => 0x5e, 354 => 0x113, 397 => 0x9b, 399 => [0x400,'276.1',0x314], 464 => 'ImageNumber' },
+	'imagenumber2' => { 179 => 0x62 },
+	'imageoptimization' => { 221 => 0xa9 },
+	'imageorientation' => { 129 => 0x83 },
+	'imageprocessing' => { 221 => 0x1a },
+	'imageprocessingfiledatecreated' => { 135 => 0xc81 },
+	'imageprocessingfiletagsversionnumber' => { 135 => 0xc80 },
+	'imageprocessingversion' => { 291 => 0x0 },
+	'imagequality' => { 153 => 'ImageQuality', 236 => '723.2', 237 => '732.2', 247 => '708.1', 310 => 0x1 },
+	'imagequality2' => { 287 => 0x603 },
+	'imagerank' => { 457 => 'ImageRank' },
+	'imagerbiassettlingdelaymsec' => { 135 => 0x600 },
+	'imagerboardversion' => { 135 => 0x439 },
+	'imagercols' => { 135 => 0x17d4 },
+	'imageref' => { 477 => 'ImageRef' },
+	'imageregion' => { 479 => 'ImageRegion' },
+	'imageregionboundary' => { 479 => [\'ImageRegion','ImageRegionRegionBoundary'] },
+	'imageregionboundaryh' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbH'] },
+	'imageregionboundaryrx' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbRx'] },
+	'imageregionboundaryshape' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbShape'] },
+	'imageregionboundaryunit' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbUnit'] },
+	'imageregionboundaryvertices' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbVertices'] },
+	'imageregionboundaryverticesx' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbVerticesRbX'] },
+	'imageregionboundaryverticesy' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbVerticesRbY'] },
+	'imageregionboundaryw' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbW'] },
+	'imageregionboundaryx' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbX'] },
+	'imageregionboundaryy' => { 479 => [\'ImageRegion','ImageRegionRegionBoundaryRbY'] },
+	'imageregionctype' => { 479 => [\'ImageRegion','ImageRegionRCtype'] },
+	'imageregionctypeidentifier' => { 479 => [\'ImageRegion','ImageRegionRCtypeIdentifier'] },
+	'imageregionctypename' => { 479 => [\'ImageRegion','ImageRegionRCtypeName'] },
+	'imageregionid' => { 479 => [\'ImageRegion','ImageRegionRId'] },
+	'imageregionname' => { 479 => [\'ImageRegion','ImageRegionName'] },
+	'imageregionrole' => { 479 => [\'ImageRegion','ImageRegionRRole'] },
+	'imageregionroleidentifier' => { 479 => [\'ImageRegion','ImageRegionRRoleIdentifier'] },
+	'imageregionrolename' => { 479 => [\'ImageRegion','ImageRegionRRoleName'] },
+	'imageresolution' => { 135 => 0x944 },
+	'imageresolutionjpg' => { 135 => 0x945 },
+	'imagereview' => { 272 => '0.4', 281 => '0.4' },
+	'imagereviewmonitorofftime' => { 271 => '21.1', 273 => '21.1', 274 => '21.1', 278 => '20.1', 283 => '21.1', 284 => '21.1' },
+	'imagereviewtime' => { 270 => '25.1', 272 => '2.1', 275 => '19.1', 276 => '20.1', 277 => '20.1', 279 => '9.2', 280 => '20.1', 285 => '21.2' },
+	'imagerfiledatecreated' => { 135 => 0x9c5 },
+	'imagerfileproductionlevel' => { 135 => 0x9c4 },
+	'imagerfiletagsversionstandard' => { 135 => 0x9c7 },
+	'imagerotated' => { 148 => 0x2a },
+	'imagerpowerondelaymsec' => { 135 => 0x5fd },
+	'imagerrows' => { 135 => 0x17de },
+	'imagesegmentlines' => { 135 => 0x184d },
+	'imagesegmentstartline' => { 135 => 0x184c },
+	'imagesize' => { 159 => 'ImageSize' },
+	'imagesizeraw' => { 221 => 0x3e },
+	'imagesizerestriction' => { 486 => 'imageSizeRestriction' },
+	'imagesourcedata' => { 117 => 0x935c },
+	'imagespace' => { 135 => 0x909 },
+	'imagestabilization' => { 34 => 0x22, 111 => 0x3020, 125 => 0x1422, 153 => 'ImageStabilization', 178 => 0xbd, 179 => 0x71, 180 => 0x57, 181 => 0x0, 182 => [0x18,0x107,0x113], 183 => 0x49c2, 221 => 0xac, 287 => 0x604, 290 => 0x1600, 310 => 0x1a, 402 => 0x12, 403 => 0x11, 410 => 0xb026 },
+	'imagestabilization2' => { 401 => 0xa },
+	'imagestabilizationsetting' => { 183 => 0x14, 397 => 0x3d, 398 => 0x3d, 408 => 0x14 },
+	'imagestyle' => { 397 => 0x2d, 398 => 0x27 },
+	'imagesupplier' => { 297 => 'ImageSupplier' },
+	'imagesupplierid' => { 297 => [\'ImageSupplier','ImageSupplierImageSupplierID'] },
+	'imagesupplierimageid' => { 297 => 'ImageSupplierImageID' },
+	'imagesuppliername' => { 297 => [\'ImageSupplier','ImageSupplierImageSupplierName'] },
+	'imagetemperaturemax' => { 119 => 0x1 },
+	'imagetemperaturemin' => { 119 => 0x2 },
+	'imagetone' => { 345 => 0x4f },
+	'imagetype' => { 129 => 0x82, 297 => 'ImageType' },
+	'imageuniqueid' => { 1 => 0x15, 62 => 0x28, 117 => 0xa420, 472 => 'ImageUniqueID', 473 => 'ImageUniqueID' },
+	'imagewidth' => { 117 => 0x100, 184 => 0xe, 354 => 0x10c, 452 => 'ImageWidth', 489 => 'ImageWidth' },
+	'inclinationangle' => { 444 => 0x900f },
+	'inclinationcorrection' => { 444 => 0x900e },
+	'incrementaltemperature' => { 467 => 'IncrementalTemperature', 469 => 'IncrementalTemperature' },
+	'incrementaltint' => { 467 => 'IncrementalTint', 469 => 'IncrementalTint' },
+	'industry' => { 483 => 'industry', 484 => 'industry' },
+	'infobuttonwhenshooting' => { 82 => 0x409 },
+	'information' => { 364 => 'information', 370 => "\xa9inf" },
+	'infourl' => { 370 => 'infu' },
+	'infraredilluminator' => { 371 => 0x28 },
+	'ingredientexclusion' => { 485 => 'ingredientExclusion' },
+	'ingredients' => { 494 => 'Ingredients' },
+	'ingredientsalternatepaths' => { 494 => [\'Ingredients','IngredientsAlternatePaths'] },
+	'ingredientsdocumentid' => { 494 => [\'Ingredients','IngredientsDocumentID'] },
+	'ingredientsfilepath' => { 494 => [\'Ingredients','IngredientsFilePath'] },
+	'ingredientsfrompart' => { 494 => [\'Ingredients','IngredientsFromPart'] },
+	'ingredientsinstanceid' => { 494 => [\'Ingredients','IngredientsInstanceID'] },
+	'ingredientslastmodifydate' => { 494 => [\'Ingredients','IngredientsLastModifyDate'] },
+	'ingredientslasturl' => { 494 => [\'Ingredients','IngredientsLastURL'] },
+	'ingredientslinkcategory' => { 494 => [\'Ingredients','IngredientsLinkCategory'] },
+	'ingredientslinkform' => { 494 => [\'Ingredients','IngredientsLinkForm'] },
+	'ingredientsmanager' => { 494 => [\'Ingredients','IngredientsManager'] },
+	'ingredientsmanagervariant' => { 494 => [\'Ingredients','IngredientsManagerVariant'] },
+	'ingredientsmanageto' => { 494 => [\'Ingredients','IngredientsManageTo'] },
+	'ingredientsmanageui' => { 494 => [\'Ingredients','IngredientsManageUI'] },
+	'ingredientsmaskmarkers' => { 494 => [\'Ingredients','IngredientsMaskMarkers'] },
+	'ingredientsoriginaldocumentid' => { 494 => [\'Ingredients','IngredientsOriginalDocumentID'] },
+	'ingredientspartmapping' => { 494 => [\'Ingredients','IngredientsPartMapping'] },
+	'ingredientsplacedresolutionunit' => { 494 => [\'Ingredients','IngredientsPlacedResolutionUnit'] },
+	'ingredientsplacedxresolution' => { 494 => [\'Ingredients','IngredientsPlacedXResolution'] },
+	'ingredientsplacedyresolution' => { 494 => [\'Ingredients','IngredientsPlacedYResolution'] },
+	'ingredientsrenditionclass' => { 494 => [\'Ingredients','IngredientsRenditionClass'] },
+	'ingredientsrenditionparams' => { 494 => [\'Ingredients','IngredientsRenditionParams'] },
+	'ingredientstopart' => { 494 => [\'Ingredients','IngredientsToPart'] },
+	'ingredientsversionid' => { 494 => [\'Ingredients','IngredientsVersionID'] },
+	'initialafpointaiservoaf' => { 82 => 0x51e },
+	'initialafpointinservo' => { 2 => 0x13 },
+	'initialcameradolly' => { 455 => 'InitialCameraDolly' },
+	'initialhorizontalfovdegrees' => { 455 => 'InitialHorizontalFOVDegrees' },
+	'initialverticalfovdegrees' => { 455 => 'InitialVerticalFOVDegrees' },
+	'initialviewheadingdegrees' => { 455 => 'InitialViewHeadingDegrees', 456 => 'InitialViewHeadingDegrees' },
+	'initialviewpitchdegrees' => { 455 => 'InitialViewPitchDegrees', 456 => 'InitialViewPitchDegrees' },
+	'initialviewrolldegrees' => { 455 => 'InitialViewRollDegrees', 456 => 'InitialViewRollDegrees' },
+	'initialzoomliveview' => { 270 => '4.4' },
+	'initialzoomsetting' => { 270 => '9.3', 279 => '27.3' },
+	'inkset' => { 117 => 0x14c },
+	'inputprofile' => { 135 => 0x1389 },
+	'instanceid' => { 494 => 'InstanceID' },
+	'instantplaybacksetup' => { 180 => 0x3e },
+	'instantplaybacktime' => { 180 => 0x3d },
+	'instructions' => { 481 => 'Instructions' },
+	'instrument' => { 493 => 'instrument' },
+	'integrationtime' => { 135 => 0x423 },
+	'intellectualgenre' => { 478 => 'IntellectualGenre' },
+	'intelligentauto' => { 410 => 0xb052, 436 => 0xd, 437 => 0xe, 438 => 0xd },
+	'intelligentcontrast' => { 51 => 0x4 },
+	'intelligentd-range' => { 310 => 0x79 },
+	'intelligentexposure' => { 310 => 0x5d },
+	'intelligentresolution' => { 310 => 0x70 },
+	'interchangecolorspace' => { 131 => 0x40 },
+	'intergraphmatrix' => { 117 => 0x8480 },
+	'internalflash' => { 177 => 0x2b, 270 => '23.1', 272 => '8.1', 275 => '22.1', 277 => '23.1', 281 => '8.1', 285 => '24.1', 290 => 0x1208 },
+	'internalflashae1' => { 292 => 0x1021 },
+	'internalflashae1_0' => { 292 => 0x101d },
+	'internalflashae2' => { 292 => 0x1022 },
+	'internalflashae2_0' => { 292 => 0x101e },
+	'internalflashmode' => { 333 => 0x1 },
+	'internalflashstrength' => { 333 => 0x3 },
+	'internalflashtable' => { 292 => 0x1024 },
+	'internallensserialnumber' => { 384 => 0xa005 },
+	'internalndfilter' => { 310 => 0x9d },
+	'internalserialnumber' => { 62 => 0x96, 74 => 0x9, 125 => 0x10, 183 => 0x49dc, 286 => 0x18, 288 => 0x102, 307 => 0x500, 310 => 0x25, 325 => 0x4, 377 => 0x5, 428 => [0x7c,0xf0], 429 => 0x88, 430 => 0x88 },
+	'interopindex' => { 117 => 0x1, 474 => 'InteroperabilityIndex' },
+	'interopversion' => { 117 => 0x2 },
+	'intervallength' => { 177 => 0x10 },
+	'intervalmode' => { 177 => 0x26 },
+	'intervalnumber' => { 177 => 0x11 },
+	'intervalshooting' => { 345 => 0x92 },
+	'introtime' => { 493 => 'introTime' },
+	'introtimescale' => { 493 => [\'introTime','introTimeScale'] },
+	'introtimevalue' => { 493 => [\'introTime','introTimeValue'] },
+	'ipaversion' => { 135 => 0xdae },
+	'ipfcameramodel' => { 135 => 0xe4d },
+	'iptc' => { 118 => 'IPTC' },
+	'iptc-naa' => { 117 => 0x83bb, 315 => 0x83bb },
+	'iptcbitspersample' => { 131 => 0x56 },
+	'iptcdigest' => { 359 => 0x425 },
+	'iptcimageheight' => { 131 => 0x1e },
+	'iptcimagerotation' => { 131 => 0x66 },
+	'iptcimagewidth' => { 131 => 0x14 },
+	'iptclastedited' => { 479 => 'IptcLastEdited' },
+	'iptcpicturenumber' => { 131 => 0xa },
+	'iptcpixelheight' => { 131 => 0x32 },
+	'iptcpixelwidth' => { 131 => 0x28 },
+	'isalternativeof' => { 483 => 'isAlternativeOf' },
+	'isbn' => { 483 => 'isbn' },
+	'iscorrectionof' => { 483 => 'isCorrectionOf' },
+	'iscustompicturestyle' => { 107 => 0x3 },
+	'ismergedhdr' => { 464 => 'IsMergedHDR' },
+	'ismergedpanorama' => { 464 => '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, 110 => 0x14, 111 => [0x3014,0x14], 117 => 0x8827, 134 => 0xfd06, 135 => 0x1784, 137 => 0x60, 139 => [0xfa2e,0xfa46], 140 => [0x27,0x28], 141 => 0xf105, 144 => 0x14, 146 => 0x4e, 148 => 0x1e, 149 => 0x1a, 151 => 0x34, 153 => 'ISO', 177 => 0x8, 183 => 0x49ba, 212 => 0x0, 221 => 0x2, 310 => 0xd1, 315 => 0x17, 345 => [0x8b,0x14], 352 => 0x14, 354 => 0x105, 384 => 0xa014, 387 => 0x86, 408 => 0x6f, 415 => [0x1f,0x21,0x25], 473 => 'ISOSpeedRatings' },
+	'iso2' => { 212 => 0x6, 231 => 0x265, 232 => 0x25c, 233 => 0x265, 234 => 0x221, 235 => 0x25d, 236 => 0x256, 237 => 0x25d, 241 => 0x2b5, 245 => 0x265, 251 => 0x2b5 },
+	'isoauto' => { 326 => '14.4' },
+	'isoautohilimit' => { 239 => 0x18eb, 240 => 0xe82, 249 => 0x185d },
+	'isoautomax' => { 409 => 0x4 },
+	'isoautomin' => { 409 => 0x2 },
+	'isoautoparameters' => { 345 => 0x7a },
+	'isoautoshuttertime' => { 239 => 0x18ea, 240 => 0xe81, 249 => 0x185c },
+	'isocalibrationgain' => { 135 => 0x89f },
+	'isodisplay' => { 273 => '4.1', 274 => '4.1', 275 => '2.3', 276 => '3.3', 277 => '3.3', 280 => '3.3', 283 => '4.3', 284 => '4.1', 285 => '4.3' },
+	'isoexpansion' => { 82 => 0x103, 83 => 0x7, 84 => 0x8, 87 => 0x8, 212 => 0x4 },
+	'isoexpansion2' => { 212 => 0xa },
+	'isofloor' => { 326 => 0x6 },
+	'isoselected' => { 309 => 0x359 },
+	'isoselection' => { 221 => 0xf },
+	'isosensitivitystep' => { 278 => '6.2', 280 => '6.2' },
+	'isosetting' => { 137 => 0x5e, 149 => 0x14, 153 => 'ISOSetting', 177 => 0x24, 178 => 0x26, 179 => 0x1c, 180 => 0x13, 185 => 0x6, 221 => 0x13, 326 => '17.3', 376 => 0x27, 397 => 0x16, 398 => 0x14, 399 => 0x2, 408 => 0x6d, 409 => 0x0 },
+	'isospeed' => { 117 => 0x8833, 474 => 'ISOSpeed' },
+	'isospeedexpansion' => { 81 => 0x3 },
+	'isospeedincrements' => { 82 => 0x102 },
+	'isospeedlatitudeyyy' => { 117 => 0x8834, 474 => 'ISOSpeedLatitudeyyy' },
+	'isospeedlatitudezzz' => { 117 => 0x8835, 474 => 'ISOSpeedLatitudezzz' },
+	'isospeedrange' => { 82 => 0x103 },
+	'isostepsize' => { 270 => '6.1', 271 => '7.2', 273 => '7.2', 274 => '7.2', 279 => '4.1', 283 => '7.2', 284 => '7.2' },
+	'isovalue' => { 292 => 0x1001 },
+	'isrccode' => { 370 => "\xa9isr" },
+	'issn' => { 483 => 'issn' },
+	'issueidentifier' => { 483 => 'issueIdentifier' },
+	'issuename' => { 483 => 'issueName' },
+	'issueteaser' => { 483 => 'issueTeaser' },
+	'issuetype' => { 483 => 'issueType' },
+	'istranslationof' => { 483 => 'isTranslationOf' },
+	'itemsubtype' => { 175 => 'ItemSubType' },
+	'itunesu' => { 362 => 'itnu' },
+	'jobid' => { 129 => 0xb8 },
+	'jobname' => { 475 => 'JobName' },
+	'jobref' => { 492 => 'JobRef' },
+	'jobrefid' => { 492 => [\'JobRef','JobRefId'] },
+	'jobrefname' => { 492 => [\'JobRef','JobRefName'] },
+	'jobrefurl' => { 492 => [\'JobRef','JobRefUrl'] },
+	'jobstatus' => { 475 => 'JobStatus' },
+	'jpeghandling' => { 467 => 'JPEGHandling', 469 => 'JPEGHandling' },
+	'jpegquality' => { 10 => 0x66, 310 => 0x43, 312 => 0x3034, 410 => 0xb047 },
+	'jpegsize' => { 312 => 0x303a },
+	'jpgcompression' => { 240 => 0x7d4 },
+	'jpgfromraw' => { 95 => 0x2007, 112 => 'Exif-JpgFromRaw', 315 => 0x2e },
+	'jpgfromrawlength' => { 117 => [0x117,0x202] },
+	'jpgfromrawstart' => { 117 => [0x111,0x201] },
+	'jpgrecordedpixels' => { 326 => '14.1' },
+	'jurisdiction' => { 465 => 'jurisdiction' },
+	'kelvinwb_01' => { 334 => 0x5 },
+	'kelvinwb_02' => { 334 => 0x9 },
+	'kelvinwb_03' => { 334 => 0xd },
+	'kelvinwb_04' => { 334 => 0x11 },
+	'kelvinwb_05' => { 334 => 0x15 },
+	'kelvinwb_06' => { 334 => 0x19 },
+	'kelvinwb_07' => { 334 => 0x1d },
+	'kelvinwb_08' => { 334 => 0x21 },
+	'kelvinwb_09' => { 334 => 0x25 },
+	'kelvinwb_10' => { 334 => 0x29 },
+	'kelvinwb_11' => { 334 => 0x2d },
+	'kelvinwb_12' => { 334 => 0x31 },
+	'kelvinwb_13' => { 334 => 0x35 },
+	'kelvinwb_14' => { 334 => 0x39 },
+	'kelvinwb_15' => { 334 => 0x3d },
+	'kelvinwb_16' => { 334 => 0x41 },
+	'kelvinwb_daylight' => { 334 => 0x1 },
+	'kerneldenominators' => { 135 => 0x933 },
+	'key' => { 493 => 'key' },
+	'keystonecompensation' => { 291 => 0x1900 },
+	'keystonedirection' => { 291 => 0x1901 },
+	'keystonevalue' => { 291 => 0x1906 },
+	'keyword' => { 362 => 'keyw', 483 => 'keyword' },
+	'keywordinfo' => { 168 => 'Keywords' },
+	'keywords' => { 129 => 0x19, 154 => 'Keywords', 296 => 'Keywords', 361 => 'Keywords', 364 => 'keywords', 462 => 'keywords', 480 => 'Keywords', 491 => 'Keywords' },
+	'killdate' => { 483 => 'killDate' },
+	'killdatea-platform' => { 483 => [\'killDate','killDateA-platform'] },
+	'killdatedate' => { 483 => [\'killDate','killDateDate'] },
+	'kodakimageheight' => { 134 => 0xf908, 137 => 0xe, 139 => [0xfa1e,0xfa52], 145 => 0x70 },
+	'kodakimagewidth' => { 134 => 0xf907, 137 => 0xc, 139 => [0xfa1d,0xfa51], 145 => 0x6c },
+	'kodakinfotype' => { 134 => 0xfa00 },
+	'kodaklook' => { 135 => 0xe4c },
+	'kodaklookprofile' => { 135 => 0x138a },
+	'kodakmaker' => { 145 => 0x8 },
+	'kodakmodel' => { 137 => 0x0, 145 => 0x28 },
+	'kodaktag' => { 135 => 0x3ea },
+	'kodakversion' => { 135 => 0x0 },
+	'label' => { 300 => 'Label', 491 => 'Label' },
+	'labelname1' => { 477 => [\'TagStructure','TagStructureLabelName'] },
+	'labelname2' => { 477 => [\'TagStructure','TagStructureSubLabelsLabelName'] },
+	'labelname3' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsLabelName'] },
+	'labelname4' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsLabelName'] },
+	'labelname5' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsLabelName'] },
+	'labelname6' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsLabelName'] },
+	'landmark' => { 310 => 0x6f },
+	'landscapeoutputhighlightpoint' => { 107 => 0x26 },
+	'landscapeoutputshadowpoint' => { 107 => 0x27 },
+	'landscaperawcolortone' => { 107 => 0x1f },
+	'landscaperawcontrast' => { 107 => 0x21 },
+	'landscaperawhighlight' => { 107 => 0x77 },
+	'landscaperawhighlightpoint' => { 107 => 0x24 },
+	'landscaperawlinear' => { 107 => 0x22 },
+	'landscaperawsaturation' => { 107 => 0x20 },
+	'landscaperawshadow' => { 107 => 0x80 },
+	'landscaperawshadowpoint' => { 107 => 0x25 },
+	'landscaperawsharpness' => { 107 => 0x23 },
+	'landscapeunsharpmaskfineness' => { 107 => 0xa0 },
+	'landscapeunsharpmaskstrength' => { 107 => 0x9e },
+	'landscapeunsharpmaskthreshold' => { 107 => 0xa2 },
+	'language' => { 470 => 'language' },
+	'languageidentifier' => { 129 => 0x87 },
+	'largestvalidinteriorrectheight' => { 455 => 'LargestValidInteriorRectHeight' },
+	'largestvalidinteriorrectleft' => { 455 => 'LargestValidInteriorRectLeft' },
+	'largestvalidinteriorrecttop' => { 455 => 'LargestValidInteriorRectTop' },
+	'largestvalidinteriorrectwidth' => { 455 => 'LargestValidInteriorRectWidth' },
+	'lastfilenumber' => { 177 => 0x1b },
+	'lastkeywordiptc' => { 175 => 'LastKeywordIPTC' },
+	'lastkeywordxmp' => { 175 => 'LastKeywordXMP' },
+	'lastphotodate' => { 455 => 'LastPhotoDate' },
+	'lasturl' => { 494 => 'LastURL' },
+	'lateralchromaticaberration' => { 410 => 0x2012 },
+	'lateralchromaticaberrationcorrectionalreadyapplied' => { 464 => 'LateralChromaticAberrationCorrectionAlreadyApplied' },
+	'latestageorhigheststage' => { 116 => [\'GeologicalContext','GeologicalContextLatestAgeOrHighestStage'] },
+	'latesteonorhighesteonothem' => { 116 => [\'GeologicalContext','GeologicalContextLatestEonOrHighestEonothem'] },
+	'latestepochorhighestseries' => { 116 => [\'GeologicalContext','GeologicalContextLatestEpochOrHighestSeries'] },
+	'latesteraorhighesterathem' => { 116 => [\'GeologicalContext','GeologicalContextLatestEraOrHighestErathem'] },
+	'latestperiodorhighestsystem' => { 116 => [\'GeologicalContext','GeologicalContextLatestPeriodOrHighestSystem'] },
+	'latitude' => { 114 => 'Latitude' },
+	'lc1' => { 336 => 0x2 },
+	'lc10' => { 336 => 0xb },
+	'lc11' => { 336 => 0xc },
+	'lc12' => { 336 => 0xd },
+	'lc14' => { 336 => 0xf },
+	'lc15' => { 336 => 0x10 },
+	'lc3' => { 336 => 0x4 },
+	'lc4' => { 336 => 0x5 },
+	'lc5' => { 336 => 0x6 },
+	'lc6' => { 336 => 0x7 },
+	'lc7' => { 336 => 0x8 },
+	'lc8' => { 336 => 0x9 },
+	'lcddisplayatpoweron' => { 82 => 0x811, 86 => 0xa },
+	'lcddisplayreturntoshoot' => { 87 => 0x12 },
+	'lcdillumination' => { 270 => '17.5', 271 => '5.2', 273 => '5.1', 274 => '5.1', 279 => '10.3', 280 => '4.2', 283 => '5.2', 284 => '5.1', 285 => '5.4' },
+	'lcdilluminationduringbulb' => { 82 => 0x408 },
+	'lcdmatrix' => { 135 => 0xe74 },
+	'lcdmatrixchickfix' => { 135 => 0xe75 },
+	'lcdmatrixmarvin' => { 135 => 0xe76 },
+	'lcdpanels' => { 81 => 0x8 },
+	'lcheditor' => { 263 => 0x8ae85e },
+	'legacyiptcdigest' => { 481 => 'LegacyIPTCDigest' },
+	'legalcode' => { 465 => 'legalcode' },
+	'lens' => { 117 => 0xfdea, 221 => 0x84, 464 => 'Lens' },
+	'lensafstopbutton' => { 80 => 0x11, 81 => 0x13, 82 => 0x506, 83 => 0x10, 84 => 0x12, 87 => 0x13, 88 => 0x9 },
+	'lensaperturerange' => { 387 => [0x30,0x48] },
+	'lenscorrectionsettings' => { 472 => 'LensCorrectionSettings' },
+	'lensdistortinfo' => { 464 => 'LensDistortInfo' },
+	'lensdistortionparams' => { 292 => 0x206 },
+	'lensdrivenoaf' => { 82 => 0x505 },
+	'lensdrivewhenafimpossible' => { 2 => 0xb },
+	'lense-mountversion' => { 399 => 0x3f0, 443 => 0xd },
+	'lensfirmware' => { 378 => 0x20, 384 => 0xa004 },
+	'lensfirmwareversion' => { 288 => 0x204, 310 => 0x60, 399 => 0x3f3, 443 => 0x14 },
+	'lensfocallength' => { 101 => 0xf0512, 336 => 0x9 },
+	'lensfocalrange' => { 387 => [0xa,0x2a] },
+	'lensfocusfunctionbuttons' => { 271 => '55.1', 273 => '52.1', 274 => '52.1', 283 => '52.1', 284 => '52.1' },
+	'lensformat' => { 422 => 0x1891, 424 => 0x18bd, 425 => 0x18ed, 426 => 0x17f1, 428 => 0x106, 429 => 0x106, 439 => 0x603, 440 => 0x5d },
+	'lensfstops' => { 213 => 0x7, 214 => 0xc, 215 => 0xd, 219 => 0xe, 221 => 0x8b, 336 => '0.3' },
+	'lensid' => { 219 => 0x30, 464 => 'LensID' },
+	'lensidnumber' => { 213 => 0x6, 214 => 0xb, 215 => 0xc, 219 => 0xd },
+	'lensinfo' => { 117 => 0xa432, 342 => 0x2a, 464 => 'LensInfo', 474 => 'LensSpecification' },
+	'lenskind' => { 336 => 0x1 },
+	'lensmake' => { 117 => 0xa433, 160 => 'Make', 474 => 'LensMake' },
+	'lensmanualdistortionamount' => { 467 => 'LensManualDistortionAmount', 469 => 'LensManualDistortionAmount' },
+	'lensmanufacturer' => { 175 => 'LensManufacturer' },
+	'lensmaxaperturerange' => { 387 => 0x2b },
+	'lensmodel' => { 7 => 0x937, 14 => 0x92b, 15 => 0x933, 62 => 0x95, 117 => 0xa434, 160 => 'Model', 175 => 'LensModel', 216 => 0x18a, 217 => 0x18b, 218 => 0x2ac, 288 => 0x203, 342 => 0xc, 354 => 0x412, 474 => 'LensModel' },
+	'lensmodulationoptimizer' => { 125 => 0x1045 },
+	'lensmount' => { 399 => 0x99, 422 => 0x1892, 424 => 0x18be, 425 => 0x18ee, 426 => 0x17f2, 428 => 0x105, 429 => 0x105, 439 => 0x604, 440 => 0x5e },
+	'lensmount2' => { 443 => 0x8 },
+	'lensprofilechromaticaberrationscale' => { 467 => 'LensProfileChromaticAberrationScale', 469 => 'LensProfileChromaticAberrationScale' },
+	'lensprofiledigest' => { 467 => 'LensProfileDigest', 469 => 'LensProfileDigest' },
+	'lensprofiledistortionscale' => { 467 => 'LensProfileDistortionScale', 469 => 'LensProfileDistortionScale' },
+	'lensprofileenable' => { 467 => 'LensProfileEnable', 469 => 'LensProfileEnable' },
+	'lensprofilefilename' => { 467 => 'LensProfileFilename', 469 => 'LensProfileFilename' },
+	'lensprofileisembedded' => { 467 => 'LensProfileIsEmbedded', 469 => 'LensProfileIsEmbedded' },
+	'lensprofilematchkeycameramodelname' => { 467 => 'LensProfileMatchKeyCameraModelName', 469 => 'LensProfileMatchKeyCameraModelName' },
+	'lensprofilematchkeyexifmake' => { 467 => 'LensProfileMatchKeyExifMake', 469 => 'LensProfileMatchKeyExifMake' },
+	'lensprofilematchkeyexifmodel' => { 467 => 'LensProfileMatchKeyExifModel', 469 => 'LensProfileMatchKeyExifModel' },
+	'lensprofilematchkeyisraw' => { 467 => 'LensProfileMatchKeyIsRaw', 469 => 'LensProfileMatchKeyIsRaw' },
+	'lensprofilematchkeylensid' => { 467 => 'LensProfileMatchKeyLensID', 469 => 'LensProfileMatchKeyLensID' },
+	'lensprofilematchkeylensinfo' => { 467 => 'LensProfileMatchKeyLensInfo', 469 => 'LensProfileMatchKeyLensInfo' },
+	'lensprofilematchkeylensname' => { 467 => 'LensProfileMatchKeyLensName', 469 => 'LensProfileMatchKeyLensName' },
+	'lensprofilematchkeysensorformatfactor' => { 467 => 'LensProfileMatchKeySensorFormatFactor', 469 => 'LensProfileMatchKeySensorFormatFactor' },
+	'lensprofilename' => { 467 => 'LensProfileName', 469 => 'LensProfileName' },
+	'lensprofilesetup' => { 467 => 'LensProfileSetup', 469 => 'LensProfileSetup' },
+	'lensprofilevignettingscale' => { 467 => 'LensProfileVignettingScale', 469 => 'LensProfileVignettingScale' },
+	'lensproperties' => { 288 => 0x20b },
+	'lensserialnumber' => { 21 => 0x164, 32 => 0x16b, 60 => 0x0, 117 => 0xa435, 160 => 'SerialNumber', 288 => 0x202, 308 => 0x321, 310 => 0x52, 370 => 'LENS', 378 => 0x30, 464 => 'LensSerialNumber', 474 => 'LensSerialNumber' },
+	'lensshutterlock' => { 180 => 0x4a },
+	'lensspec' => { 394 => 0x0, 395 => 0x0, 396 => 0x0, 410 => 0xb02a },
+	'lensspecfeatures' => { 428 => [0x115,0x116], 429 => [0x116,0x1ed,0x1f0,0x21c,0x21e] },
+	'lenstemperature' => { 292 => 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, 182 => 0x10c, 183 => 0x49bd, 221 => 0x83, 288 => 0x201, 301 => 0x16, 305 => 0x310, 307 => 0x303, 308 => 0x303, 310 => 0x51, 312 => 0x3405, 337 => 0x0, 338 => 0x0, 339 => 0x1, 340 => 0x1, 341 => 0x1, 343 => 0x0, 384 => 0xa003, 387 => 0x27, 410 => 0xb027, 422 => 0x1896, 424 => 0x18c2, 425 => 0x18f2, 426 => 0x17f6, 428 => 0x109, 429 => 0x109, 439 => 0x608, 440 => 0x62 },
+	'lenstype2' => { 399 => 0x3f7, 422 => 0x1893, 424 => 0x18bf, 425 => 0x18ef, 426 => 0x17f3, 428 => 0x107, 429 => 0x107, 439 => 0x605, 440 => 0x60 },
+	'lenstype3' => { 443 => 0x9 },
+	'lenstypemake' => { 310 => 0xc4 },
+	'lenstypemodel' => { 310 => 0xc5 },
+	'lenszoomposition' => { 436 => 0x19, 437 => 0x1e, 440 => [0x342,0x34e,0x35a] },
+	'levelindicator' => { 318 => 0x15 },
+	'levelmeter' => { 370 => ['Lvlm','lvlm'] },
+	'levelorientation' => { 344 => 0x0 },
+	'license' => { 465 => 'license' },
+	'licensee' => { 297 => 'Licensee' },
+	'licenseeid' => { 297 => [\'Licensee','LicenseeLicenseeID'] },
+	'licenseeimageid' => { 297 => 'LicenseeImageID' },
+	'licenseeimagenotes' => { 297 => 'LicenseeImageNotes' },
+	'licenseename' => { 297 => [\'Licensee','LicenseeLicenseeName'] },
+	'licenseenddate' => { 297 => 'LicenseEndDate' },
+	'licenseeprojectreference' => { 297 => 'LicenseeProjectReference' },
+	'licenseetransactionid' => { 297 => 'LicenseeTransactionID' },
+	'licenseid' => { 297 => 'LicenseID' },
+	'licensestartdate' => { 297 => 'LicenseStartDate' },
+	'licensetransactiondate' => { 297 => 'LicenseTransactionDate' },
+	'licensetype' => { 471 => 'licensetype' },
+	'licensor' => { 297 => 'Licensor' },
+	'licensorcity' => { 297 => [\'Licensor','LicensorLicensorCity'] },
+	'licensorcountry' => { 297 => [\'Licensor','LicensorLicensorCountry'] },
+	'licensoremail' => { 297 => [\'Licensor','LicensorLicensorEmail'] },
+	'licensorextendedaddress' => { 297 => [\'Licensor','LicensorLicensorExtendedAddress'] },
+	'licensorid' => { 297 => [\'Licensor','LicensorLicensorID'] },
+	'licensorimageid' => { 297 => 'LicensorImageID' },
+	'licensorname' => { 297 => [\'Licensor','LicensorLicensorName'] },
+	'licensornotes' => { 297 => 'LicensorNotes' },
+	'licensorpostalcode' => { 297 => [\'Licensor','LicensorLicensorPostalCode'] },
+	'licensorregion' => { 297 => [\'Licensor','LicensorLicensorRegion'] },
+	'licensorstreetaddress' => { 297 => [\'Licensor','LicensorLicensorStreetAddress'] },
+	'licensortelephone1' => { 297 => [\'Licensor','LicensorLicensorTelephone1'] },
+	'licensortelephone2' => { 297 => [\'Licensor','LicensorLicensorTelephone2'] },
+	'licensortelephonetype1' => { 297 => [\'Licensor','LicensorLicensorTelephoneType1'] },
+	'licensortelephonetype2' => { 297 => [\'Licensor','LicensorLicensorTelephoneType2'] },
+	'licensortransactionid' => { 297 => 'LicensorTransactionID' },
+	'licensorurl' => { 297 => [\'Licensor','LicensorLicensorURL'] },
+	'lightcondition' => { 292 => 0x1009 },
+	'lightingmode' => { 111 => 0x302a },
+	'lightreading' => { 345 => 0x15 },
+	'lightsource' => { 117 => 0x9208, 221 => 0x90, 295 => 0x1000, 473 => 'LightSource' },
+	'lightsourcespecial' => { 386 => 0x21d },
+	'lightswitch' => { 283 => '0.1', 285 => '0.1' },
+	'lightvaluecenter' => { 292 => 0x103d },
+	'lightvalueperiphery' => { 292 => 0x103e },
+	'limitafareamodeselection' => { 271 => '51.1', 273 => '49.1', 274 => '49.1', 283 => '49.1', 284 => '49.1' },
+	'linearitylimitblue' => { 315 => 0x10 },
+	'linearitylimitgreen' => { 315 => 0xf },
+	'linearitylimitred' => { 315 => 0xe },
+	'linearityuppermargin' => { 41 => 0x32c, 44 => [0x2ba,0x2d1,0x2d5], 46 => 0x1e5, 47 => [0x1fe,0x2de], 48 => [0x232,0x310], 49 => 0x31e },
+	'linearizationtable' => { 117 => 0xc618 },
+	'linearresponselimit' => { 117 => 0xc62e },
+	'link' => { 483 => 'link' },
+	'linkaetoafpoint' => { 326 => '14.2' },
+	'linkedencodedrightsexpr' => { 479 => [\'LinkedEncRightsExpr','LinkedEncRightsExprLinkedRightsExpr'] },
+	'linkedencodedrightsexprlangid' => { 479 => [\'LinkedEncRightsExpr','LinkedEncRightsExprRightsExprLangId'] },
+	'linkedencodedrightsexprtype' => { 479 => [\'LinkedEncRightsExpr','LinkedEncRightsExprRightsExprEncType'] },
+	'linkedencrightsexpr' => { 479 => 'LinkedEncRightsExpr' },
+	'linlogcoring' => { 135 => 0x904 },
+	'lithostratigraphicterms' => { 116 => [\'GeologicalContext','GeologicalContextLithostratigraphicTerms'] },
+	'liveviewaf' => { 275 => '32.1', 285 => '34.1' },
+	'liveviewafareamode' => { 280 => '34.1' },
+	'liveviewafmethod' => { 415 => 0x20 },
+	'liveviewafmode' => { 280 => '34.2' },
+	'liveviewafsetting' => { 399 => 0x36 },
+	'liveviewbuttonoptions' => { 271 => '50.2', 273 => '48.2', 274 => '48.2', 283 => '48.2', 284 => '48.2' },
+	'liveviewexposuresimulation' => { 82 => 0x810 },
+	'liveviewfocusmode' => { 399 => [0x8b,0x28b] },
+	'liveviewmetering' => { 399 => [0x84,0x284] },
+	'liveviewmonitorofftime' => { 271 => '21.2', 273 => '21.2', 274 => '21.2', 276 => '20.2', 277 => '20.2', 278 => '20.2', 280 => '20.2', 283 => '21.2', 284 => '21.2' },
+	'liveviewshooting' => { 56 => 0x13 },
+	'livingspecimen' => { 116 => 'LivingSpecimen' },
+	'livingspecimenmaterialsampleid' => { 116 => [\'LivingSpecimen','LivingSpecimenMaterialSampleID'] },
+	'localcaption' => { 129 => 0x79 },
+	'localizedcameramodel' => { 117 => 0xc615 },
+	'locallocationname' => { 384 => 0x30 },
+	'location' => { 220 => 0x9, 310 => 0x67, 460 => 'Location', 478 => 'Location', 482 => 'location', 483 => 'location' },
+	'locationareacode' => { 466 => 'lac' },
+	'locationbody' => { 364 => 'location.body' },
+	'locationcreated' => { 479 => 'LocationCreated' },
+	'locationcreatedcity' => { 479 => [\'LocationCreated','LocationCreatedCity'] },
+	'locationcreatedcountrycode' => { 479 => [\'LocationCreated','LocationCreatedCountryCode'] },
+	'locationcreatedcountryname' => { 479 => [\'LocationCreated','LocationCreatedCountryName'] },
+	'locationcreatedgpsaltitude' => { 479 => [\'LocationCreated','LocationCreatedGPSAltitude'] },
+	'locationcreatedgpslatitude' => { 479 => [\'LocationCreated','LocationCreatedGPSLatitude'] },
+	'locationcreatedgpslongitude' => { 479 => [\'LocationCreated','LocationCreatedGPSLongitude'] },
+	'locationcreatedidentifier' => { 479 => [\'LocationCreated','LocationCreatedIdentifier'] },
+	'locationcreatedlocationid' => { 479 => [\'LocationCreated','LocationCreatedLocationId'] },
+	'locationcreatedlocationname' => { 479 => [\'LocationCreated','LocationCreatedLocationName'] },
+	'locationcreatedprovincestate' => { 479 => [\'LocationCreated','LocationCreatedProvinceState'] },
+	'locationcreatedsublocation' => { 479 => [\'LocationCreated','LocationCreatedSublocation'] },
+	'locationcreatedworldregion' => { 479 => [\'LocationCreated','LocationCreatedWorldRegion'] },
+	'locationdate' => { 364 => 'location.date' },
+	'locationinfoversion' => { 220 => 0x0 },
+	'locationname' => { 364 => 'location.name', 384 => 0x31 },
+	'locationnote' => { 364 => 'location.note' },
+	'locationrole' => { 364 => 'location.role' },
+	'locationshown' => { 479 => 'LocationShown' },
+	'locationshowncity' => { 479 => [\'LocationShown','LocationShownCity'] },
+	'locationshowncountrycode' => { 479 => [\'LocationShown','LocationShownCountryCode'] },
+	'locationshowncountryname' => { 479 => [\'LocationShown','LocationShownCountryName'] },
+	'locationshowngpsaltitude' => { 479 => [\'LocationShown','LocationShownGPSAltitude'] },
+	'locationshowngpslatitude' => { 479 => [\'LocationShown','LocationShownGPSLatitude'] },
+	'locationshowngpslongitude' => { 479 => [\'LocationShown','LocationShownGPSLongitude'] },
+	'locationshownidentifier' => { 479 => [\'LocationShown','LocationShownIdentifier'] },
+	'locationshownlocationid' => { 479 => [\'LocationShown','LocationShownLocationId'] },
+	'locationshownlocationname' => { 479 => [\'LocationShown','LocationShownLocationName'] },
+	'locationshownprovincestate' => { 479 => [\'LocationShown','LocationShownProvinceState'] },
+	'locationshownsublocation' => { 479 => [\'LocationShown','LocationShownSublocation'] },
+	'locationshownworldregion' => { 479 => [\'LocationShown','LocationShownWorldRegion'] },
+	'lockmicrophonebutton' => { 82 => 0x709 },
+	'logcomment' => { 493 => 'logComment' },
+	'logscale' => { 135 => 0x902 },
+	'longdescription' => { 362 => 'ldes' },
+	'longexposurenoisereduction' => { 61 => 0x4, 82 => 0x201, 83 => 0x1, 84 => 0x2, 85 => 0x1, 86 => 0x1, 87 => 0x2, 88 => 0x1, 310 => 0x49, 397 => 0x2b, 398 => 0x25, 399 => 0x25, 410 => 0x2008, 415 => 0x11, 440 => 0x44 },
+	'longexposurenoisereduction2' => { 56 => 0x8 },
+	'longexposurenrused' => { 310 => 0xbe },
+	'longitude' => { 114 => 'Longitude' },
+	'look' => { 467 => 'Look', 469 => 'Look' },
+	'lookamount' => { 467 => [\'Look','LookAmount'], 469 => [\'Look','LookAmount'] },
+	'lookcluster' => { 467 => [\'Look','LookCluster'], 469 => [\'Look','LookCluster'] },
+	'lookcopyright' => { 467 => [\'Look','LookCopyright'], 469 => [\'Look','LookCopyright'] },
+	'lookgroup' => { 467 => [\'Look','LookGroup'], 469 => [\'Look','LookGroup'] },
+	'lookname' => { 467 => 'LookName', 469 => 'LookName' },
+	'lookparameters' => { 467 => [\'Look','LookParameters'], 469 => [\'Look','LookParameters'] },
+	'lookparameterscameraprofile' => { 467 => [\'Look','LookParametersCameraProfile'], 469 => [\'Look','LookParametersCameraProfile'] },
+	'lookparametersclarity2012' => { 467 => [\'Look','LookParametersClarity2012'], 469 => [\'Look','LookParametersClarity2012'] },
+	'lookparametersconverttograyscale' => { 467 => [\'Look','LookParametersConvertToGrayscale'], 469 => [\'Look','LookParametersConvertToGrayscale'] },
+	'lookparameterslooktable' => { 467 => [\'Look','LookParametersLookTable'], 469 => [\'Look','LookParametersLookTable'] },
+	'lookparametersprocessversion' => { 467 => [\'Look','LookParametersProcessVersion'], 469 => [\'Look','LookParametersProcessVersion'] },
+	'lookparameterstonecurvepv2012' => { 467 => [\'Look','LookParametersToneCurvePV2012'], 469 => [\'Look','LookParametersToneCurvePV2012'] },
+	'lookparametersversion' => { 467 => [\'Look','LookParametersVersion'], 469 => [\'Look','LookParametersVersion'] },
+	'looksupportsamount' => { 467 => [\'Look','LookSupportsAmount'], 469 => [\'Look','LookSupportsAmount'] },
+	'looksupportsmonochrome' => { 467 => [\'Look','LookSupportsMonochrome'], 469 => [\'Look','LookSupportsMonochrome'] },
+	'looksupportsoutputreferred' => { 467 => [\'Look','LookSupportsOutputReferred'], 469 => [\'Look','LookSupportsOutputReferred'] },
+	'lookuuid' => { 467 => [\'Look','LookUUID'], 469 => [\'Look','LookUUID'] },
+	'loop' => { 493 => 'loop' },
+	'loopstyle' => { 370 => 'LOOP' },
+	'lowestbiostratigraphiczone' => { 116 => [\'GeologicalContext','GeologicalContextLowestBiostratigraphicZone'] },
+	'luminanceadjustmentaqua' => { 467 => 'LuminanceAdjustmentAqua', 469 => 'LuminanceAdjustmentAqua' },
+	'luminanceadjustmentblue' => { 467 => 'LuminanceAdjustmentBlue', 469 => 'LuminanceAdjustmentBlue' },
+	'luminanceadjustmentgreen' => { 467 => 'LuminanceAdjustmentGreen', 469 => 'LuminanceAdjustmentGreen' },
+	'luminanceadjustmentmagenta' => { 467 => 'LuminanceAdjustmentMagenta', 469 => 'LuminanceAdjustmentMagenta' },
+	'luminanceadjustmentorange' => { 467 => 'LuminanceAdjustmentOrange', 469 => 'LuminanceAdjustmentOrange' },
+	'luminanceadjustmentpurple' => { 467 => 'LuminanceAdjustmentPurple', 469 => 'LuminanceAdjustmentPurple' },
+	'luminanceadjustmentred' => { 467 => 'LuminanceAdjustmentRed', 469 => 'LuminanceAdjustmentRed' },
+	'luminanceadjustmentyellow' => { 467 => 'LuminanceAdjustmentYellow', 469 => 'LuminanceAdjustmentYellow' },
+	'luminancecurvelimits' => { 106 => 0x150 },
+	'luminancecurvepoints' => { 106 => 0x126 },
+	'luminancenoisereduction' => { 101 => 0x20600, 107 => 0x5f, 387 => 0x1b },
+	'luminancenoisereductioncontrast' => { 467 => 'LuminanceNoiseReductionContrast', 469 => 'LuminanceNoiseReductionContrast' },
+	'luminancenoisereductiondetail' => { 467 => 'LuminanceNoiseReductionDetail', 469 => 'LuminanceNoiseReductionDetail' },
+	'luminancenr_tiff_jpeg' => { 107 => 0x6d },
+	'luminancesmoothing' => { 467 => 'LuminanceSmoothing', 469 => 'LuminanceSmoothing' },
+	'lvshootingareadisplay' => { 82 => [0x40b,0x40c] },
+	'lyrics' => { 362 => "\xa9lyr", 370 => "\xa9lyr", 493 => 'lyrics' },
+	'lyricsuri' => { 370 => 'lrcu' },
+	'm16cversion' => { 305 => 0x333 },
+	'macatom' => { 468 => 'macAtom' },
+	'macatomapplicationcode' => { 468 => [\'macAtom','macAtomApplicationCode'] },
+	'macatominvocationappleevent' => { 468 => [\'macAtom','macAtomInvocationAppleEvent'] },
+	'macatomposixprojectpath' => { 468 => [\'macAtom','macAtomPosixProjectPath'] },
+	'machineobservation' => { 116 => 'MachineObservation' },
+	'machineobservationday' => { 116 => [\'MachineObservation','MachineObservationDay'] },
+	'machineobservationearliestdate' => { 116 => [\'MachineObservation','MachineObservationEarliestDate'] },
+	'machineobservationenddayofyear' => { 116 => [\'MachineObservation','MachineObservationEndDayOfYear'] },
+	'machineobservationeventdate' => { 116 => [\'MachineObservation','MachineObservationEventDate'] },
+	'machineobservationeventid' => { 116 => [\'MachineObservation','MachineObservationEventID'] },
+	'machineobservationeventremarks' => { 116 => [\'MachineObservation','MachineObservationEventRemarks'] },
+	'machineobservationeventtime' => { 116 => [\'MachineObservation','MachineObservationEventTime'] },
+	'machineobservationfieldnotes' => { 116 => [\'MachineObservation','MachineObservationFieldNotes'] },
+	'machineobservationfieldnumber' => { 116 => [\'MachineObservation','MachineObservationFieldNumber'] },
+	'machineobservationhabitat' => { 116 => [\'MachineObservation','MachineObservationHabitat'] },
+	'machineobservationlatestdate' => { 116 => [\'MachineObservation','MachineObservationLatestDate'] },
+	'machineobservationmonth' => { 116 => [\'MachineObservation','MachineObservationMonth'] },
+	'machineobservationparenteventid' => { 116 => [\'MachineObservation','MachineObservationParentEventID'] },
+	'machineobservationsamplesizeunit' => { 116 => [\'MachineObservation','MachineObservationSampleSizeUnit'] },
+	'machineobservationsamplesizevalue' => { 116 => [\'MachineObservation','MachineObservationSampleSizeValue'] },
+	'machineobservationsamplingeffort' => { 116 => [\'MachineObservation','MachineObservationSamplingEffort'] },
+	'machineobservationsamplingprotocol' => { 116 => [\'MachineObservation','MachineObservationSamplingProtocol'] },
+	'machineobservationstartdayofyear' => { 116 => [\'MachineObservation','MachineObservationStartDayOfYear'] },
+	'machineobservationverbatimeventdate' => { 116 => [\'MachineObservation','MachineObservationVerbatimEventDate'] },
+	'machineobservationyear' => { 116 => [\'MachineObservation','MachineObservationYear'] },
+	'macro' => { 125 => 0x1020, 127 => 0x202, 148 => 0x2b, 292 => 0x202, 376 => 0x21, 386 => 0x202, 410 => 0xb040 },
+	'macroled' => { 290 => 0x120a },
+	'macromagnification' => { 7 => 0x1b, 11 => 0x1b, 14 => 0x1b, 15 => 0x1b, 19 => 0x1b, 20 => 0x1b, 56 => 0x10 },
+	'macromode' => { 34 => 0x1, 177 => 0xb, 287 => 0x300, 310 => 0x1c, 377 => 0x1009 },
+	'magentahsl' => { 101 => 0x20917 },
+	'magicfilter' => { 287 => 0x52c },
+	'magnifiedview' => { 84 => 0x11, 86 => 0x9 },
+	'mainboardversion' => { 135 => 0x438 },
+	'maindialexposurecomp' => { 281 => '0.6' },
+	'mainingredient' => { 485 => 'mainIngredient' },
+	'majorversion' => { 458 => 'MajorVersion' },
+	'make' => { 96 => 0x0, 113 => 0x1, 117 => 0x10f, 153 => 'Make', 300 => 'Make', 315 => 0x10f, 364 => 'make', 370 => ['@mak',"\xa9mak"], 482 => 'make', 489 => 'Make' },
+	'makernote' => { 473 => 'MakerNote' },
+	'makernoteapple' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotecanon' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotecasio' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotecasio2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotedji' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteflir' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotefujifilm' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotege' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotege2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotehasselblad' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotehp' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotehp2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotehp4' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotehp6' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteisl' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotejvc' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotejvctext' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak10' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak11' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak12' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak1a' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak1b' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak3' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak4' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak5' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak6a' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak6b' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak7' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak8a' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak8b' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak8c' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodak9' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekodakunknown' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotekyocera' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica10' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica3' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica4' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica5' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica6' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica7' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica8' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteleica9' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteminolta' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteminolta2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteminolta3' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotemotorola' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotenikon' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotenikon2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotenikon3' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotenintendo' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteoffset' => { 386 => 0xff },
+	'makernoteolympus' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteolympus2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepanasonic' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepanasonic2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepanasonic3' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepentax' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepentax2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepentax3' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepentax4' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepentax5' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepentax6' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotepentaxunknown' => { 370 => 'PXMN' },
+	'makernotephaseone' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotereconyx' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotereconyx2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotereconyx3' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotericoh' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotericoh2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotericohpentax' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotericohtext' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesafety' => { 117 => 0xc635 },
+	'makernotesamsung1a' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesamsung1b' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesamsung2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesanyo' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesanyoc4' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesanyopatch' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesigma' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesony' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesony2' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesony3' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesony4' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesony5' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesonyericsson' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotesonysrf' => { 115 => 'MakN', 117 => 0x927c },
+	'makernotetype' => { 377 => 0x1 },
+	'makernoteunknown' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteunknownbinary' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteunknowntext' => { 115 => 'MakN', 117 => 0x927c },
+	'makernoteversion' => { 182 => 0x0, 221 => 0x1, 292 => 0x0, 310 => 0x8000, 381 => 0x0, 384 => 0x1, 387 => [0x1d,0x1f], 400 => 0x2000 },
+	'makerurl' => { 370 => "\xa9mal" },
+	'managedfrom' => { 494 => 'ManagedFrom' },
+	'managedfromalternatepaths' => { 494 => [\'ManagedFrom','ManagedFromAlternatePaths'] },
+	'managedfromdocumentid' => { 494 => [\'ManagedFrom','ManagedFromDocumentID'] },
+	'managedfromfilepath' => { 494 => [\'ManagedFrom','ManagedFromFilePath'] },
+	'managedfromfrompart' => { 494 => [\'ManagedFrom','ManagedFromFromPart'] },
+	'managedfrominstanceid' => { 494 => [\'ManagedFrom','ManagedFromInstanceID'] },
+	'managedfromlastmodifydate' => { 494 => [\'ManagedFrom','ManagedFromLastModifyDate'] },
+	'managedfromlasturl' => { 494 => [\'ManagedFrom','ManagedFromLastURL'] },
+	'managedfromlinkcategory' => { 494 => [\'ManagedFrom','ManagedFromLinkCategory'] },
+	'managedfromlinkform' => { 494 => [\'ManagedFrom','ManagedFromLinkForm'] },
+	'managedfrommanager' => { 494 => [\'ManagedFrom','ManagedFromManager'] },
+	'managedfrommanagervariant' => { 494 => [\'ManagedFrom','ManagedFromManagerVariant'] },
+	'managedfrommanageto' => { 494 => [\'ManagedFrom','ManagedFromManageTo'] },
+	'managedfrommanageui' => { 494 => [\'ManagedFrom','ManagedFromManageUI'] },
+	'managedfrommaskmarkers' => { 494 => [\'ManagedFrom','ManagedFromMaskMarkers'] },
+	'managedfromoriginaldocumentid' => { 494 => [\'ManagedFrom','ManagedFromOriginalDocumentID'] },
+	'managedfrompartmapping' => { 494 => [\'ManagedFrom','ManagedFromPartMapping'] },
+	'managedfromplacedresolutionunit' => { 494 => [\'ManagedFrom','ManagedFromPlacedResolutionUnit'] },
+	'managedfromplacedxresolution' => { 494 => [\'ManagedFrom','ManagedFromPlacedXResolution'] },
+	'managedfromplacedyresolution' => { 494 => [\'ManagedFrom','ManagedFromPlacedYResolution'] },
+	'managedfromrenditionclass' => { 494 => [\'ManagedFrom','ManagedFromRenditionClass'] },
+	'managedfromrenditionparams' => { 494 => [\'ManagedFrom','ManagedFromRenditionParams'] },
+	'managedfromtopart' => { 494 => [\'ManagedFrom','ManagedFromToPart'] },
+	'managedfromversionid' => { 494 => [\'ManagedFrom','ManagedFromVersionID'] },
+	'manager' => { 494 => 'Manager' },
+	'managervariant' => { 494 => 'ManagerVariant' },
+	'manageto' => { 494 => 'ManageTo' },
+	'manageui' => { 494 => 'ManageUI' },
+	'manifest' => { 494 => 'Manifest' },
+	'manifestlinkform' => { 494 => [\'Manifest','ManifestLinkForm'] },
+	'manifestplacedresolutionunit' => { 494 => [\'Manifest','ManifestPlacedResolutionUnit'] },
+	'manifestplacedxresolution' => { 494 => [\'Manifest','ManifestPlacedXResolution'] },
+	'manifestplacedyresolution' => { 494 => [\'Manifest','ManifestPlacedYResolution'] },
+	'manifestreference' => { 494 => [\'Manifest','ManifestReference'] },
+	'manifestreferencealternatepaths' => { 494 => [\'Manifest','ManifestReferenceAlternatePaths'] },
+	'manifestreferencedocumentid' => { 494 => [\'Manifest','ManifestReferenceDocumentID'] },
+	'manifestreferencefilepath' => { 494 => [\'Manifest','ManifestReferenceFilePath'] },
+	'manifestreferencefrompart' => { 494 => [\'Manifest','ManifestReferenceFromPart'] },
+	'manifestreferenceinstanceid' => { 494 => [\'Manifest','ManifestReferenceInstanceID'] },
+	'manifestreferencelastmodifydate' => { 494 => [\'Manifest','ManifestReferenceLastModifyDate'] },
+	'manifestreferencelasturl' => { 494 => [\'Manifest','ManifestReferenceLastURL'] },
+	'manifestreferencelinkcategory' => { 494 => [\'Manifest','ManifestReferenceLinkCategory'] },
+	'manifestreferencelinkform' => { 494 => [\'Manifest','ManifestReferenceLinkForm'] },
+	'manifestreferencemanager' => { 494 => [\'Manifest','ManifestReferenceManager'] },
+	'manifestreferencemanagervariant' => { 494 => [\'Manifest','ManifestReferenceManagerVariant'] },
+	'manifestreferencemanageto' => { 494 => [\'Manifest','ManifestReferenceManageTo'] },
+	'manifestreferencemanageui' => { 494 => [\'Manifest','ManifestReferenceManageUI'] },
+	'manifestreferencemaskmarkers' => { 494 => [\'Manifest','ManifestReferenceMaskMarkers'] },
+	'manifestreferenceoriginaldocumentid' => { 494 => [\'Manifest','ManifestReferenceOriginalDocumentID'] },
+	'manifestreferencepartmapping' => { 494 => [\'Manifest','ManifestReferencePartMapping'] },
+	'manifestreferenceplacedresolutionunit' => { 494 => [\'Manifest','ManifestReferencePlacedResolutionUnit'] },
+	'manifestreferenceplacedxresolution' => { 494 => [\'Manifest','ManifestReferencePlacedXResolution'] },
+	'manifestreferenceplacedyresolution' => { 494 => [\'Manifest','ManifestReferencePlacedYResolution'] },
+	'manifestreferencerenditionclass' => { 494 => [\'Manifest','ManifestReferenceRenditionClass'] },
+	'manifestreferencerenditionparams' => { 494 => [\'Manifest','ManifestReferenceRenditionParams'] },
+	'manifestreferencetopart' => { 494 => [\'Manifest','ManifestReferenceToPart'] },
+	'manifestreferenceversionid' => { 494 => [\'Manifest','ManifestReferenceVersionID'] },
+	'manometerpressure' => { 287 => 0x900, 310 => 0x86 },
+	'manometerreading' => { 287 => 0x901 },
+	'manualafpointselectpattern' => { 82 => 0x513 },
+	'manualafpointselpattern' => { 2 => 0xf },
+	'manualflash' => { 290 => 0x1209 },
+	'manualflashoutput' => { 34 => 0x29, 272 => '8.2', 275 => '22.2', 276 => '23.1', 277 => '23.2', 279 => '16.2', 280 => '23.2', 281 => '8.2', 282 => '23.2', 285 => '24.2', 377 => 0x100c },
+	'manualflashstrength' => { 287 => 0x406 },
+	'manualfocusdistance' => { 221 => 0x85, 292 => 0x100c, 386 => 0x223 },
+	'manualtv' => { 81 => 0x5, 82 => 0x705 },
+	'manufacturedate' => { 187 => 0x6705, 325 => 0x1 },
+	'manufacturedate1' => { 379 => 0x4 },
+	'manufacturedate2' => { 379 => 0x5 },
+	'manufacturer' => { 452 => 'Manufacturer', 482 => 'manufacturer' },
+	'mariahchromablursize' => { 135 => 0xf0d },
+	'mariahmaphithreshold' => { 135 => 0xf0c },
+	'mariahmaplothreshold' => { 135 => 0xf0b },
+	'mariahsigmathreshold' => { 135 => 0xf0e },
+	'mariahtexturethreshold' => { 135 => 0xf0a },
+	'marked' => { 480 => 'Marked', 497 => 'Marked' },
+	'markers' => { 493 => 'markers' },
+	'markerscomment' => { 493 => [\'markers','markersComment'] },
+	'markerscuepointparams' => { 493 => [\'markers','markersCuePointParams'] },
+	'markerscuepointparamskey' => { 493 => [\'markers','markersCuePointParamsKey'] },
+	'markerscuepointparamsvalue' => { 493 => [\'markers','markersCuePointParamsValue'] },
+	'markerscuepointtype' => { 493 => [\'markers','markersCuePointType'] },
+	'markersduration' => { 493 => [\'markers','markersDuration'] },
+	'markerslocation' => { 493 => [\'markers','markersLocation'] },
+	'markersname' => { 493 => [\'markers','markersName'] },
+	'markersprobability' => { 493 => [\'markers','markersProbability'] },
+	'markersspeaker' => { 493 => [\'markers','markersSpeaker'] },
+	'markersstarttime' => { 493 => [\'markers','markersStartTime'] },
+	'markerstarget' => { 493 => [\'markers','markersTarget'] },
+	'markerstype' => { 493 => [\'markers','markersType'] },
+	'maskedareas' => { 117 => 0xc68e },
+	'masterdocumentid' => { 129 => 0xb9 },
+	'mastergain' => { 229 => 0x50 },
+	'materialsample' => { 116 => 'MaterialSample' },
+	'materialsampleid' => { 116 => [\'MaterialSample','MaterialSampleMaterialSampleID'] },
+	'matrixmetering' => { 271 => '50.1', 273 => '48.1', 274 => '48.1', 283 => '48.1', 284 => '48.1' },
+	'matrixselectk' => { 135 => 0x91b },
+	'matrixselectthreshold' => { 135 => 0x91a },
+	'matrixselectthreshold1' => { 135 => 0x91e },
+	'matrixselectthreshold2' => { 135 => 0x91f },
+	'matrixstructure' => { 369 => 0xa },
+	'maxaperture' => { 34 => 0x1a, 135 => 0x3f9, 141 => 0x6103, 160 => 'MaxAperture', 177 => 0x17, 183 => 0x49c5, 219 => 0x36, 288 => 0x20a, 336 => '14.1' },
+	'maxapertureatmaxfocal' => { 125 => 0x1407, 160 => 'MaxApertureAtMaxFocal', 213 => 0xb, 214 => 0x10, 215 => 0x11, 219 => 0x12, 288 => 0x206 },
+	'maxapertureatminfocal' => { 125 => 0x1406, 213 => 0xa, 214 => 0xf, 215 => 0x10, 219 => 0x11, 288 => 0x205 },
+	'maxaperturevalue' => { 117 => 0x9205, 354 => 0x414, 473 => 'MaxApertureValue' },
+	'maxavailheight' => { 479 => 'MaxAvailHeight' },
+	'maxavailwidth' => { 479 => 'MaxAvailWidth' },
+	'maxcontinuousrelease' => { 270 => 0xb, 271 => 0xc, 273 => '12.1', 274 => '12.1', 279 => 0xc, 280 => 0xb, 283 => '12.1', 284 => '12.1' },
+	'maxfaces' => { 291 => 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, 125 => 0x1405, 160 => 'MaxFocalLength', 213 => 0x9, 214 => 0xe, 215 => 0xf, 219 => 0x10, 288 => 0x208, 422 => 0x127c, 423 => 0x1138, 424 => 0x330, 425 => 0x330, 426 => 0x30e },
+	'maximumdensityrange' => { 131 => 0x8c },
+	'maxpagesize' => { 498 => 'MaxPageSize' },
+	'maxpagesizeh' => { 498 => [\'MaxPageSize','MaxPageSizeH'] },
+	'maxpagesizeunit' => { 498 => [\'MaxPageSize','MaxPageSizeUnit'] },
+	'maxpagesizew' => { 498 => [\'MaxPageSize','MaxPageSizeW'] },
+	'maxpixelvaluethreshold' => { 135 => 0xc7d },
+	'maxsamplevalue' => { 117 => 0x119 },
+	'maxstorage' => { 488 => 'maxstorage' },
+	'mb-d10batteries' => { 270 => '12.6' },
+	'mb-d10batterytype' => { 279 => '13.3' },
+	'mb-d11batterytype' => { 280 => '2.3' },
+	'mb-d12batterytype' => { 283 => '3.2' },
+	'mb-d80batteries' => { 281 => '6.5' },
+	'mb-d80batterytype' => { 285 => '3.2' },
+	'mcuversion' => { 213 => 0xc, 214 => 0x11, 215 => 0x12, 219 => 0x13 },
+	'md5digest' => { 161 => 'zmd5' },
+	'mditemfindercomment' => { 170 => 'MDItemFinderComment' },
+	'mditemfscreationdate' => { 170 => 'MDItemFSCreationDate' },
+	'mditemfslabel' => { 170 => 'MDItemFSLabel' },
+	'mditemusertags' => { 170 => 'MDItemUserTags' },
+	'meal' => { 485 => 'meal' },
+	'measuredev' => { 28 => 0x9, 75 => 0x3, 95 => 0x1814, 153 => 'MeasuredEV' },
+	'measuredev2' => { 13 => 0x8, 28 => 0x8, 75 => 0x17 },
+	'measuredev3' => { 13 => 0x9 },
+	'measuredlv' => { 183 => 0x690, 305 => 0x312, 308 => 0x312, 309 => 0x312, 312 => 0x3407 },
+	'measuredrggb' => { 63 => 0x1 },
+	'measuredrggbdata' => { 43 => 0x287 },
+	'measurementaccuracy' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementAccuracy'] },
+	'measurementdeterminedby' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementDeterminedBy'] },
+	'measurementdetermineddate' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementDeterminedDate'] },
+	'measurementid' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementID'] },
+	'measurementmethod' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementMethod'] },
+	'measurementorfact' => { 116 => 'MeasurementOrFact' },
+	'measurementremarks' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementRemarks'] },
+	'measurementtype' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementType'] },
+	'measurementunit' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementUnit'] },
+	'measurementvalue' => { 116 => [\'MeasurementOrFact','MeasurementOrFactMeasurementValue'] },
+	'measuretype' => { 452 => 'MeasureType' },
+	'mechanicalshuttercount' => { 221 => 0x37 },
+	'mediaconstraints' => { 297 => 'MediaConstraints' },
+	'mediacreatedate' => { 366 => 0x1 },
+	'mediaeventiddate' => { 457 => 'MediaEventIdDate' },
+	'mediagroupuuid' => { 1 => 0x11 },
+	'mediamodifydate' => { 366 => 0x2 },
+	'mediasummarycode' => { 297 => 'MediaSummaryCode' },
+	'mediatype' => { 362 => 'stik' },
+	'memoaudioquality' => { 82 => 0x812 },
+	'memorycardconfiguration' => { 403 => 0x16 },
+	'memorycardnumber' => { 203 => 0x2 },
+	'menubuttondisplayposition' => { 80 => 0xb, 83 => 0xa, 84 => 0xb, 87 => 0xb },
+	'menubuttonreturn' => { 88 => 0xb },
+	'menumonitorofftime' => { 270 => '26.1', 271 => '22.1', 273 => '22.1', 274 => '22.1', 278 => '21.1', 279 => '8.2', 280 => '21.1', 283 => '22.1', 284 => '22.1', 285 => '22.1' },
+	'metadatadate' => { 491 => 'MetadataDate' },
+	'metadatamoddate' => { 493 => 'metadataModDate' },
+	'metaversion' => { 417 => 0x34 },
+	'meterinfo1row1' => { 411 => 0x0, 412 => 0x0 },
+	'meterinfo1row2' => { 411 => 0x6c, 412 => 0x5a },
+	'meterinfo1row3' => { 411 => 0xd8, 412 => 0xb4 },
+	'meterinfo1row4' => { 411 => 0x144, 412 => 0x10e },
+	'meterinfo1row5' => { 411 => 0x1b0, 412 => 0x168 },
+	'meterinfo1row6' => { 411 => 0x21c, 412 => 0x1c2 },
+	'meterinfo1row7' => { 411 => 0x288, 412 => 0x21c },
+	'meterinfo2row1' => { 411 => 0x2f4, 412 => 0x276 },
+	'meterinfo2row2' => { 411 => 0x378, 412 => 0x2e4 },
+	'meterinfo2row3' => { 411 => 0x3fc, 412 => 0x352 },
+	'meterinfo2row4' => { 411 => 0x480, 412 => 0x3c0 },
+	'meterinfo2row5' => { 411 => 0x504, 412 => 0x42e },
+	'meterinfo2row6' => { 411 => 0x588, 412 => 0x49c },
+	'meterinfo2row7' => { 411 => 0x60c, 412 => 0x50a },
+	'meterinfo2row8' => { 411 => 0x690, 412 => 0x578 },
+	'meterinfo2row9' => { 411 => 0x714, 412 => 0x5e6 },
+	'metering' => { 272 => '6.1' },
+	'meteringmode' => { 34 => 0x11, 117 => 0x9207, 137 => 0x1c, 177 => 0x7, 178 => 0x25, 180 => 0x12, 287 => 0x202, 345 => 0x17, 387 => 0x9, 397 => 0x15, 398 => 0x13, 399 => 0x7, 415 => 0x3, 418 => 0x1174, 419 => 0x1178, 420 => 0x1154, 421 => 0x11d0, 422 => 0x11ac, 423 => 0x1064, 424 => 0x25c, 425 => 0x25c, 426 => 0x24b, 473 => 'MeteringMode' },
+	'meteringmode2' => { 326 => '2.1', 410 => 0x202c },
+	'meteringmode3' => { 326 => '16.1' },
+	'meteringoffscaleindicator' => { 180 => 0x53 },
+	'meteringtime' => { 270 => '22.2', 272 => '3.2', 275 => '17.1', 276 => '18.1', 279 => '7.3', 280 => '18.1', 281 => '3.2', 285 => '19.1' },
+	'micro1version' => { 372 => 0x1f },
+	'micro2version' => { 372 => 0x2d },
+	'microvideo' => { 450 => 'MicroVideo' },
+	'microvideooffset' => { 450 => 'MicroVideoOffset' },
+	'microvideopresentationtimestampus' => { 450 => 'MicroVideoPresentationTimestampUs' },
+	'microvideoversion' => { 450 => 'MicroVideoVersion' },
+	'midrangesharpness' => { 225 => 0x3b },
+	'mieversion' => { 161 => '0Vers' },
+	'mime' => { 452 => 'Mime' },
+	'minaperture' => { 34 => 0x1b, 135 => 0x3f8, 160 => 'MinAperture', 336 => '0.2' },
+	'minaperturevalue' => { 354 => 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, 125 => 0x1404, 160 => 'MinFocalLength', 213 => 0x8, 214 => 0xd, 215 => 0xe, 219 => 0xf, 288 => 0x207, 422 => 0x127a, 423 => 0x1136, 424 => 0x32e, 425 => 0x32e, 426 => 0x30c },
+	'minfocusdistance' => { 336 => 0x3 },
+	'minintegrationrows' => { 135 => 0x1874 },
+	'minoltadate' => { 177 => 0x15 },
+	'minoltaimagesize' => { 177 => 0x4, 178 => 0xc, 179 => 0x2, 182 => 0x103 },
+	'minoltamodelid' => { 177 => 0x25 },
+	'minoltaquality' => { 177 => 0x5, 178 => 0xd, 179 => 0x3, 182 => [0x102,0x103] },
+	'minoltatime' => { 177 => 0x16 },
+	'minormodelagedisclosure' => { 297 => 'MinorModelAgeDisclosure' },
+	'minorversion' => { 458 => 'MinorVersion' },
+	'minsamplevalue' => { 117 => 0x118 },
+	'mirrorlockup' => { 80 => 0xc, 81 => 0xc, 82 => 0x60f, 83 => 0xb, 84 => 0xc, 85 => 0x6, 86 => 0x6, 87 => 0xc, 88 => 0x3 },
+	'mobilecountrycode' => { 466 => 'mcc' },
+	'mobilenetworkcode' => { 466 => 'mnc' },
+	'moddate' => { 300 => 'modify-date', 480 => 'ModDate' },
+	'modedialposition' => { 403 => 0x14 },
+	'model' => { 96 => 0x6, 117 => 0x110, 153 => 'Model', 300 => 'Model', 315 => 0x110, 345 => 0x23f, 364 => 'model', 370 => ['@mod','CNMN','cmnm',"\xa9mdl","\xa9mod"], 387 => 0x84, 452 => 'Model', 482 => 'model', 489 => 'Model' },
+	'modelage' => { 479 => 'ModelAge' },
+	'modelid' => { 286 => 0x0 },
+	'modelingflash' => { 270 => '21.4', 271 => '31.1', 273 => '31.1', 274 => '31.1', 279 => '26.4', 280 => '30.2', 281 => '7.4', 282 => '30.1', 283 => '31.1', 284 => '31.1', 285 => '31.3' },
+	'modelreleaseid' => { 297 => 'ModelReleaseID' },
+	'modelreleasestatus' => { 297 => 'ModelReleaseStatus' },
+	'modelreleaseyear' => { 431 => 0x52, 432 => 0x46, 433 => 0x53 },
+	'modeltiepoint' => { 117 => 0x8482 },
+	'modeltransform' => { 117 => 0x85d8 },
+	'modelyear' => { 482 => 'modelYear' },
+	'modificationdate' => { 483 => 'modificationDate' },
+	'modifiedcolortemp' => { 64 => 0x9 },
+	'modifieddigitalgain' => { 64 => 0xb },
+	'modifiedparamflag' => { 57 => 0x1 },
+	'modifiedpicturestyle' => { 64 => 0xa },
+	'modifiedsaturation' => { 287 => 0x504 },
+	'modifiedsensorbluelevel' => { 64 => 0x5 },
+	'modifiedsensorredlevel' => { 64 => 0x4 },
+	'modifiedsharpness' => { 64 => 0x2 },
+	'modifiedsharpnessfreq' => { 64 => 0x3 },
+	'modifiedtonecurve' => { 64 => 0x1 },
+	'modifiedwhitebalance' => { 64 => 0x8 },
+	'modifiedwhitebalanceblue' => { 64 => 0x7 },
+	'modifiedwhitebalancered' => { 64 => 0x6 },
+	'modifydate' => { 117 => 0x132, 154 => 'ModifyDate', 296 => 'ModDate', 298 => 'tIME', 361 => 'ModDate', 367 => 0x2, 491 => 'ModifyDate' },
+	'moirefilter' => { 117 => 0xfe58, 467 => 'MoireFilter', 469 => 'MoireFilter' },
+	'monitordisplayoff' => { 180 => 0x4c },
+	'monitormatrix' => { 135 => 0x8fc },
+	'monitorofftime' => { 270 => '18.2', 272 => '3.1', 281 => '3.1' },
+	'monochromecolor' => { 287 => 0x53b },
+	'monochromecontrast' => { 107 => 0x3c },
+	'monochromefiltereffect' => { 101 => 0x20307, 107 => 0x3a, 310 => 0xac, 345 => 0x73 },
+	'monochromegraineffect' => { 310 => 0xd2 },
+	'monochromelinear' => { 107 => 0x3d },
+	'monochromeoutputhighlightpoint' => { 107 => 0x41 },
+	'monochromeoutputshadowpoint' => { 107 => 0x42 },
+	'monochromeprofilesettings' => { 287 => 0x537 },
+	'monochromerawhighlight' => { 107 => 0x7a },
+	'monochromerawhighlightpoint' => { 107 => 0x3f },
+	'monochromerawshadow' => { 107 => 0x83 },
+	'monochromerawshadowpoint' => { 107 => 0x40 },
+	'monochromesharpness' => { 107 => 0x3e },
+	'monochrometoning' => { 345 => 0x74 },
+	'monochrometoningeffect' => { 101 => 0x20306, 107 => 0x3b },
+	'monochromeunsharpmaskfineness' => { 107 => 0xb2 },
+	'monochromeunsharpmaskstrength' => { 107 => 0xb0 },
+	'monochromeunsharpmaskthreshold' => { 107 => 0xb4 },
+	'monochromevignetting' => { 287 => 0x53a },
+	'monthdaycreated' => { 137 => 0x12, 146 => 0xe },
+	'moonphase' => { 371 => 0x12, 372 => 0x43, 373 => 0x4c },
+	'morepermissions' => { 465 => 'morePermissions' },
+	'motionsensitivity' => { 371 => 0x29, 373 => 0x60 },
+	'movementcount' => { 362 => "\xa9mvc" },
+	'movementname' => { 362 => "\xa9mvn" },
+	'movementnumber' => { 362 => "\xa9mvi" },
+	'movieaelockbuttonassignment' => { 283 => '40.1' },
+	'moviefunc1button' => { 273 => '41.1', 274 => '41.1', 284 => '41.1' },
+	'moviefunctionbutton' => { 271 => '41.1', 283 => '41.1' },
+	'moviefunctionbuttonplusdials' => { 271 => '52.1' },
+	'moviepreviewbutton' => { 271 => '41.2', 273 => '41.2', 274 => '41.2', 283 => '41.2', 284 => '41.2' },
+	'moviepreviewbuttonplusdials' => { 271 => '52.2' },
+	'movieshutterbutton' => { 271 => '38.3', 273 => '38.3', 274 => '38.3', 283 => '38.3', 284 => '38.3' },
+	'moviesubselectorassignment' => { 271 => '48.2' },
+	'moviesubselectorassignmentplusdials' => { 271 => '53.1' },
+	'multiburstimageheight' => { 410 => 0x1002 },
+	'multiburstimagewidth' => { 410 => 0x1001 },
+	'multiburstmode' => { 410 => 0x1000 },
+	'multicontrollerwhilemetering' => { 82 => 0x517 },
+	'multiexposure' => { 66 => 0x1, 310 => 0xb4 },
+	'multiexposureautogain' => { 222 => 0x3 },
+	'multiexposurecontrol' => { 66 => 0x2 },
+	'multiexposuremode' => { 222 => 0x1 },
+	'multiexposureshots' => { 66 => 0x3, 222 => 0x2 },
+	'multiframenoisereduction' => { 399 => 0x35, 410 => 0x200b, 415 => 0x15 },
+	'multiframenreffect' => { 410 => 0x2023 },
+	'multifunctionlock' => { 82 => 0x70f },
+	'multipleexposuremode' => { 291 => 0x101c },
+	'multipleexposureset' => { 326 => '10.1' },
+	'multisample' => { 229 => 0x40 },
+	'multiselector' => { 270 => '9.4', 271 => '10.3', 273 => '10.3', 274 => '10.3', 279 => '27.4', 283 => '10.3', 284 => '10.3' },
+	'multiselectorliveview' => { 270 => '4.3', 273 => '37.1', 274 => '37.1', 283 => '37.1', 284 => '37.1' },
+	'multiselectorliveviewmode' => { 239 => 0x18c2 },
+	'multiselectorplaybackmode' => { 270 => ['13.5','9.2'], 271 => '10.2', 274 => '10.2', 279 => '27.2', 283 => '10.2', 284 => '10.2' },
+	'multiselectorshootmode' => { 270 => '9.1', 271 => '10.1', 273 => '10.1', 274 => '10.1', 279 => '27.1', 283 => '10.1', 284 => '10.1' },
+	'multishot' => { 315 => 0x121 },
+	'mute' => { 364 => 'player.movie.audio.mute' },
+	'mycolormode' => { 67 => 0x2 },
+	'name' => { 370 => 'name', 467 => 'Name', 469 => 'Name' },
+	'narrator' => { 362 => "\xa9nrt" },
+	'nationalcatalognumber' => { 483 => 'nationalCatalogNumber' },
+	'nativedigest' => { 473 => 'NativeDigest', 489 => 'NativeDigest' },
+	'ndfilter' => { 75 => 0x1c, 287 => 0x204, 377 => 0x1019 },
+	'near' => { 452 => 'Near' },
+	'nefbitdepth' => { 221 => 0xe22 },
+	'nefcompression' => { 221 => 0x93 },
+	'neflinearizationtable' => { 221 => 0x96 },
+	'negativecachelargepreviewsize' => { 467 => 'NegativeCacheLargePreviewSize', 469 => 'NegativeCacheLargePreviewSize' },
+	'negativecachemaximumsize' => { 467 => 'NegativeCacheMaximumSize', 469 => 'NegativeCacheMaximumSize' },
+	'negativecachepath' => { 467 => 'NegativeCachePath', 469 => 'NegativeCachePath' },
+	'neutraldensityfilter' => { 345 => 0x88 },
+	'neutraloutputhighlightpoint' => { 107 => 0x2f },
+	'neutraloutputshadowpoint' => { 107 => 0x30 },
+	'neutralrawcolortone' => { 107 => 0x28 },
+	'neutralrawcontrast' => { 107 => 0x2a },
+	'neutralrawhighlight' => { 107 => 0x78 },
+	'neutralrawhighlightpoint' => { 107 => 0x2d },
+	'neutralrawlinear' => { 107 => 0x2b },
+	'neutralrawsaturation' => { 107 => 0x29 },
+	'neutralrawshadow' => { 107 => 0x81 },
+	'neutralrawshadowpoint' => { 107 => 0x2e },
+	'neutralrawsharpness' => { 107 => 0x2c },
+	'neutralunsharpmaskfineness' => { 107 => 0xa6 },
+	'neutralunsharpmaskthreshold' => { 107 => 0xa8 },
+	'neutraunsharpmaskstrength' => { 107 => 0xa4 },
+	'newrawimagedigest' => { 117 => 0xc7a7 },
+	'newsphotoversion' => { 131 => 0x0 },
+	'nickname' => { 491 => 'Nickname' },
+	'nikoncapturedata' => { 221 => 0xe01 },
+	'nikoncaptureeditversions' => { 221 => 0xe13 },
+	'nikoncaptureoffsets' => { 221 => 0xe0e },
+	'nikoncaptureoutput' => { 221 => 0xe1e },
+	'nikoncaptureversion' => { 221 => 0xe09 },
+	'nikoniccprofile' => { 221 => 0xe1d },
+	'nikonimagesize' => { 236 => '723.1', 237 => '732.1', 247 => 0x2c4 },
+	'nikonmeteringmode' => { 240 => 0x2ea4, 249 => 0x175e },
+	'nikonsettings' => { 221 => 0x4e },
+	'noisefilter' => { 287 => 0x527 },
+	'noiseprofile' => { 117 => 0xc761 },
+	'noisereduction' => { 125 => [0x100b,0x100e], 178 => 0xb0, 179 => 0x60, 180 => 0x3f, 221 => 0x95, 263 => 0x753dcbc0, 264 => 0x17, 287 => 0x50a, 292 => 0x103a, 310 => 0x2d, 345 => 0x49, 377 => 0x100f, 379 => 0x2a },
+	'noisereduction2' => { 291 => 0x1010 },
+	'noisereductionapplied' => { 117 => 0xc6f7 },
+	'noisereductionintensity' => { 264 => 0x9 },
+	'noisereductionmethod' => { 264 => 0x11 },
+	'noisereductionmode' => { 444 => 0x801e },
+	'noisereductionparametersatcapture' => { 135 => 0xe73 },
+	'noisereductionparameterscamera' => { 135 => 0xe72 },
+	'noisereductionparametershost3mp' => { 135 => 0xe71 },
+	'noisereductionparametershost6mp' => { 135 => 0xe70 },
+	'noisereductionparametershostrgb' => { 135 => 0xe6f },
+	'noisereductionparameterskhufu3mp' => { 135 => 0xe65 },
+	'noisereductionparameterskhufu6mp' => { 135 => 0xe64 },
+	'noisereductionparameterskhufurgb' => { 135 => 0xe63 },
+	'noisereductionparams' => { 315 => 0x1b },
+	'noisereductionsharpness' => { 264 => 0xd },
+	'noisereductionstrength' => { 310 => 0xd6 },
+	'noisereductionvalue' => { 444 => 0x8027 },
+	'nomemorycard' => { 270 => '22.1', 271 => '4.2', 272 => '0.3', 275 => '2.4', 276 => '3.2', 277 => '3.2', 279 => '33.7', 280 => '3.2', 281 => '0.3', 283 => '4.2', 285 => '4.5' },
+	'nominalmaxaperture' => { 336 => 0xa },
+	'nominalminaperture' => { 336 => '10.1' },
+	'normallinetime' => { 135 => 0x186a },
+	'normalwhitelevel' => { 41 => 0x32a, 44 => [0x2b8,0x2cf,0x2d3], 45 => 0x569, 46 => 0x1e3, 47 => [0x1fc,0x2dc], 48 => [0x230,0x30e], 49 => 0x31c },
+	'notes' => { 445 => 'Notes', 462 => 'notes' },
+	'npages' => { 498 => 'NPages' },
+	'nullrecord' => { 95 => 0x0 },
+	'numafpoints' => { 322 => 0x2 },
+	'number' => { 483 => 'number' },
+	'numberofbeats' => { 493 => 'numberOfBeats' },
+	'numberoffocuspoints' => { 273 => '1.3', 274 => '1.3', 277 => '0.2', 278 => '0.3', 280 => '0.3' },
+	'numfaceelements' => { 125 => 0x4200 },
+	'numfacepositions' => { 302 => 0x0 },
+	'numindexentries' => { 131 => 0x54 },
+	'numwbentries' => { 316 => 0x0, 317 => 0x0 },
+	'object' => { 483 => 'object' },
+	'objectattributereference' => { 129 => 0x4 },
+	'objectcycle' => { 129 => 0x4b, 462 => 'ObjectCycle' },
+	'objectdescription' => { 482 => 'objectDescription' },
+	'objectdistance' => { 110 => 0x6, 111 => 0x2022 },
+	'objectname' => { 129 => 0x5 },
+	'objectpreviewdata' => { 129 => 0xca },
+	'objectpreviewfileformat' => { 129 => 0xc8 },
+	'objectpreviewfileversion' => { 129 => 0xc9 },
+	'objectsubtype' => { 482 => 'objectSubtype' },
+	'objecttype' => { 482 => 'objectType' },
+	'objecttypereference' => { 129 => 0x3 },
+	'occurrence' => { 116 => 'Occurrence' },
+	'occurrenceassociatedmedia' => { 116 => [\'Occurrence','OccurrenceAssociatedMedia'] },
+	'occurrenceassociatedoccurrences' => { 116 => [\'Occurrence','OccurrenceAssociatedOccurrences'] },
+	'occurrenceassociatedreferences' => { 116 => [\'Occurrence','OccurrenceAssociatedReferences'] },
+	'occurrenceassociatedsequences' => { 116 => [\'Occurrence','OccurrenceAssociatedSequences'] },
+	'occurrenceassociatedtaxa' => { 116 => [\'Occurrence','OccurrenceAssociatedTaxa'] },
+	'occurrencebehavior' => { 116 => [\'Occurrence','OccurrenceBehavior'] },
+	'occurrencecatalognumber' => { 116 => [\'Occurrence','OccurrenceCatalogNumber'] },
+	'occurrencedetails' => { 116 => [\'Occurrence','OccurrenceOccurrenceDetails'] },
+	'occurrencedisposition' => { 116 => [\'Occurrence','OccurrenceDisposition'] },
+	'occurrenceestablishmentmeans' => { 116 => [\'Occurrence','OccurrenceEstablishmentMeans'] },
+	'occurrenceid' => { 116 => [\'Occurrence','OccurrenceOccurrenceID'] },
+	'occurrenceindividualcount' => { 116 => [\'Occurrence','OccurrenceIndividualCount'] },
+	'occurrenceindividualid' => { 116 => [\'Occurrence','OccurrenceIndividualID'] },
+	'occurrencelifestage' => { 116 => [\'Occurrence','OccurrenceLifeStage'] },
+	'occurrenceorganismquantity' => { 116 => [\'Occurrence','OccurrenceOrganismQuantity'] },
+	'occurrenceorganismquantitytype' => { 116 => [\'Occurrence','OccurrenceOrganismQuantityType'] },
+	'occurrenceothercatalognumbers' => { 116 => [\'Occurrence','OccurrenceOtherCatalogNumbers'] },
+	'occurrencepreparations' => { 116 => [\'Occurrence','OccurrencePreparations'] },
+	'occurrencepreviousidentifications' => { 116 => [\'Occurrence','OccurrencePreviousIdentifications'] },
+	'occurrencerecordedby' => { 116 => [\'Occurrence','OccurrenceRecordedBy'] },
+	'occurrencerecordnumber' => { 116 => [\'Occurrence','OccurrenceRecordNumber'] },
+	'occurrenceremarks' => { 116 => [\'Occurrence','OccurrenceOccurrenceRemarks'] },
+	'occurrencereproductivecondition' => { 116 => [\'Occurrence','OccurrenceReproductiveCondition'] },
+	'occurrencesex' => { 116 => [\'Occurrence','OccurrenceSex'] },
+	'occurrencestatus' => { 116 => [\'Occurrence','OccurrenceOccurrenceStatus'] },
+	'oecfcolumns' => { 473 => [\'OECF','OECFColumns'] },
+	'oecfnames' => { 473 => [\'OECF','OECFNames'] },
+	'oecfrows' => { 473 => [\'OECF','OECFRows'] },
+	'oecfvalues' => { 473 => [\'OECF','OECFValues'] },
+	'offsaledate' => { 483 => 'offSaleDate' },
+	'offsaledatea-platform' => { 483 => [\'offSaleDate','offSaleDateA-platform'] },
+	'offsaledatedate' => { 483 => [\'offSaleDate','offSaleDateDate'] },
+	'offsetdacvalue' => { 135 => 0x190a },
+	'offsetschema' => { 117 => 0xea1d },
+	'offsettime' => { 117 => 0x9010 },
+	'offsettimedigitized' => { 117 => 0x9012 },
+	'offsettimeoriginal' => { 117 => 0x9011 },
+	'okbutton' => { 280 => '15.1', 285 => '16.1' },
+	'oldsubfiletype' => { 117 => 0xff },
+	'olympusimageheight' => { 292 => 0x102f },
+	'olympusimagewidth' => { 292 => 0x102e },
+	'omenatcapturestrength' => { 135 => 0xa60 },
+	'omenautostrength' => { 135 => 0xa5f },
+	'omenearlystrength' => { 135 => 0xa5e },
+	'omenfocallengthlimit' => { 135 => 0xa62 },
+	'omeninitialipfstrength' => { 135 => 0xa5d },
+	'omensurfaceindex' => { 135 => 0xa64 },
+	'oneshotafrelease' => { 2 => 0x9 },
+	'onetouchwb' => { 292 => 0x302 },
+	'onsaledate' => { 483 => 'onSaleDate' },
+	'onsaledatea-platform' => { 483 => [\'onSaleDate','onSaleDateA-platform'] },
+	'onsaledatedate' => { 483 => [\'onSaleDate','onSaleDateDate'] },
+	'onsaleday' => { 483 => 'onSaleDay' },
+	'onsaledaya-platform' => { 483 => [\'onSaleDay','onSaleDayA-platform'] },
+	'onsaledayday' => { 483 => [\'onSaleDay','onSaleDayDay'] },
+	'opcodelist1' => { 117 => 0xc740 },
+	'opcodelist2' => { 117 => 0xc741 },
+	'opcodelist3' => { 117 => 0xc74e },
+	'opticalzoom' => { 139 => 0xfa3d, 141 => [0x6006,0xf006], 142 => 0x1000, 143 => 0xf, 146 => 0x1e, 148 => 0x20, 149 => 0x1c, 160 => 'OpticalZoom' },
+	'opticalzoomcode' => { 75 => 0xa },
+	'opticalzoommode' => { 310 => 0x34 },
+	'opticalzoomon' => { 386 => 0x219 },
+	'optionenddate' => { 486 => 'optionEndDate' },
+	'opto-electricconvfactor' => { 473 => 'OECF' },
+	'orangehsl' => { 101 => 0x20911 },
+	'ordernumber' => { 125 => 0x8002 },
+	'organisationinimagecode' => { 479 => 'OrganisationInImageCode' },
+	'organisationinimagename' => { 479 => 'OrganisationInImageName' },
+	'organism' => { 116 => 'Organism' },
+	'organismassociatedoccurrences' => { 116 => [\'Organism','OrganismAssociatedOccurrences'] },
+	'organismassociatedorganisms' => { 116 => [\'Organism','OrganismAssociatedOrganisms'] },
+	'organismid' => { 116 => [\'Organism','OrganismOrganismID'] },
+	'organismname' => { 116 => [\'Organism','OrganismOrganismName'] },
+	'organismpreviousidentifications' => { 116 => [\'Organism','OrganismPreviousIdentifications'] },
+	'organismremarks' => { 116 => [\'Organism','OrganismOrganismRemarks'] },
+	'organismscope' => { 116 => [\'Organism','OrganismOrganismScope'] },
+	'organization' => { 483 => 'organization' },
+	'orientation' => { 117 => 0x112, 315 => 0x112, 482 => 'orientation', 489 => 'Orientation' },
+	'orientation2' => { 415 => [0x28,0x2e] },
+	'orientationlinkedaf' => { 2 => 0xe },
+	'orientationlinkedafpoint' => { 82 => 0x516 },
+	'originalartist' => { 362 => "\xa9ope" },
+	'originalbestqualitysize' => { 117 => 0xc792 },
+	'originalcreatedatetime' => { 457 => 'OriginalCreateDateTime' },
+	'originaldecisiondata' => { 112 => 'Canon-OriginalDecisionData' },
+	'originaldecisiondataoffset' => { 62 => 0x83 },
+	'originaldefaultcropsize' => { 117 => 0xc793 },
+	'originaldefaultfinalsize' => { 117 => 0xc791 },
+	'originaldirectory' => { 307 => 0x408 },
+	'originaldocumentid' => { 494 => 'OriginalDocumentID' },
+	'originalfilename' => { 95 => 0x816, 135 => 0x3e9, 147 => 0x20, 307 => 0x407, 457 => 'OriginalFilename' },
+	'originalimageheight' => { 77 => 0xc, 121 => 0x1 },
+	'originalimagewidth' => { 77 => 0xb, 121 => 0x0 },
+	'originalrawfiledata' => { 117 => 0xc68c },
+	'originalrawfiledigest' => { 117 => 0xc71d },
+	'originalrawfilename' => { 117 => 0xc68b },
+	'originaltransmissionreference' => { 129 => 0x67 },
+	'originatingprogram' => { 129 => 0x41, 462 => 'OriginatingProgram' },
+	'originplatform' => { 483 => 'originPlatform' },
+	'os' => { 471 => 'os' },
+	'otherconditions' => { 297 => 'OtherConditions' },
+	'otherconstraints' => { 297 => 'OtherConstraints' },
+	'otherimage' => { 112 => 'Exif-OtherImage' },
+	'otherimageinfo' => { 297 => 'OtherImageInfo' },
+	'otherimagelength' => { 117 => 0x202 },
+	'otherimagestart' => { 117 => 0x201 },
+	'otherlicensedocuments' => { 297 => 'OtherLicenseDocuments' },
+	'otherlicenseinfo' => { 297 => 'OtherLicenseInfo' },
+	'otherlicenserequirements' => { 297 => 'OtherLicenseRequirements' },
+	'outcue' => { 493 => 'outCue' },
+	'outcuescale' => { 493 => [\'outCue','outCueScale'] },
+	'outcuevalue' => { 493 => [\'outCue','outCueValue'] },
+	'outputimageheight' => { 192 => 0x3 },
+	'outputimagewidth' => { 192 => 0x2 },
+	'outputlut' => { 310 => 0xa7 },
+	'outputprofile' => { 135 => 0x138b },
+	'outputresolution' => { 192 => 0x4 },
+	'overclockcols' => { 135 => 0x189c },
+	'overclockrows' => { 135 => 0x18c4 },
+	'overridelookvignette' => { 467 => 'OverrideLookVignette', 469 => 'OverrideLookVignette' },
+	'owner' => { 497 => 'Owner' },
+	'ownerid' => { 129 => 0xbc },
+	'ownername' => { 15 => 0x10f, 62 => 0x9, 95 => 0x810, 117 => [0xa430,0xfde8], 153 => 'OwnerName', 464 => 'OwnerName', 474 => 'CameraOwnerName' },
+	'padding' => { 117 => 0xea1c },
+	'pagecount' => { 483 => 'pageCount' },
+	'pageimage' => { 491 => [\'PageInfo','PageInfoImage'] },
+	'pageimageformat' => { 491 => [\'PageInfo','PageInfoFormat'] },
+	'pageimageheight' => { 491 => [\'PageInfo','PageInfoHeight'] },
+	'pageimagepagenumber' => { 491 => [\'PageInfo','PageInfoPageNumber'] },
+	'pageimagewidth' => { 491 => [\'PageInfo','PageInfoWidth'] },
+	'pageinfo' => { 491 => 'PageInfo' },
+	'pagename' => { 117 => 0x11d },
+	'pagenumber' => { 117 => 0x129 },
+	'pageprogressiondirection' => { 483 => 'pageProgressionDirection' },
+	'pagerange' => { 483 => 'pageRange' },
+	'paintbasedcorrectionmasks' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasks'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasks'] },
+	'paintbasedcorrections' => { 467 => 'PaintBasedCorrections', 469 => 'PaintBasedCorrections' },
+	'paintcorrectionactive' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionActive'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionActive'] },
+	'paintcorrectionamount' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionAmount'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionAmount'] },
+	'paintcorrectionblacks2012' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBlacks2012'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBlacks2012'] },
+	'paintcorrectionbrightness' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBrightness'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalBrightness'] },
+	'paintcorrectionclarity' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity'] },
+	'paintcorrectionclarity2012' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity2012'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalClarity2012'] },
+	'paintcorrectioncontrast' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast'] },
+	'paintcorrectioncontrast2012' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast2012'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalContrast2012'] },
+	'paintcorrectiondefringe' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalDefringe'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalDefringe'] },
+	'paintcorrectiondehaze' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalDehaze'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalDehaze'] },
+	'paintcorrectionexposure' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure'] },
+	'paintcorrectionexposure2012' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure2012'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalExposure2012'] },
+	'paintcorrectionhighlights2012' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalHighlights2012'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalHighlights2012'] },
+	'paintcorrectionhue' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalHue','PaintBasedCorrectionsLocalToningHue'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalHue','PaintBasedCorrectionsLocalToningHue'] },
+	'paintcorrectionluminancenoise' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalLuminanceNoise'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalLuminanceNoise'] },
+	'paintcorrectionmaskalpha' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAlpha'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAlpha'] },
+	'paintcorrectionmaskangle' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAngle'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksAngle'] },
+	'paintcorrectionmaskbottom' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksBottom'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksBottom'] },
+	'paintcorrectionmaskcentervalue' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterValue'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterValue'] },
+	'paintcorrectionmaskcenterweight' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterWeight'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksCenterWeight'] },
+	'paintcorrectionmaskdabs' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksDabs'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksDabs'] },
+	'paintcorrectionmaskfeather' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFeather'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFeather'] },
+	'paintcorrectionmaskflipped' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlipped'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlipped'] },
+	'paintcorrectionmaskflow' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlow'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFlow'] },
+	'paintcorrectionmaskfullx' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullX'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullX'] },
+	'paintcorrectionmaskfully' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullY'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksFullY'] },
+	'paintcorrectionmaskleft' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksLeft'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksLeft'] },
+	'paintcorrectionmaskmidpoint' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMidpoint'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMidpoint'] },
+	'paintcorrectionmaskperimetervalue' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksPerimeterValue'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksPerimeterValue'] },
+	'paintcorrectionmaskradius' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRadius'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRadius'] },
+	'paintcorrectionmaskright' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRight'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRight'] },
+	'paintcorrectionmaskroundness' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRoundness'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksRoundness'] },
+	'paintcorrectionmasksizex' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeX'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeX'] },
+	'paintcorrectionmasksizey' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeY'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksSizeY'] },
+	'paintcorrectionmasktop' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksTop'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksTop'] },
+	'paintcorrectionmaskvalue' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMaskValue'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksMaskValue'] },
+	'paintcorrectionmaskversion' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksVersion'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksVersion'] },
+	'paintcorrectionmaskwhat' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksWhat'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksWhat'] },
+	'paintcorrectionmaskx' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksX'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksX'] },
+	'paintcorrectionmasky' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksY'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksY'] },
+	'paintcorrectionmaskzerox' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroX'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroX'] },
+	'paintcorrectionmaskzeroy' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroY'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionMasksZeroY'] },
+	'paintcorrectionmoire' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalMoire'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalMoire'] },
+	'paintcorrectionrangemask' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMask'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMask'] },
+	'paintcorrectionrangemaskcoloramount' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskColorAmount'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskColorAmount'] },
+	'paintcorrectionrangemaskdepthfeather' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskDepthFeather'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskDepthFeather'] },
+	'paintcorrectionrangemaskdepthmax' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskDepthMax'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskDepthMax'] },
+	'paintcorrectionrangemaskdepthmin' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskDepthMin'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskDepthMin'] },
+	'paintcorrectionrangemasklumfeather' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskLumFeather'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskLumFeather'] },
+	'paintcorrectionrangemasklummax' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskLumMax'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskLumMax'] },
+	'paintcorrectionrangemasklummin' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskLumMin'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskLumMin'] },
+	'paintcorrectionrangemasktype' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskType'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskType'] },
+	'paintcorrectionrangemaskversion' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskVersion'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsCorrectionRangeMaskVersion'] },
+	'paintcorrectionsaturation' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSaturation','PaintBasedCorrectionsLocalToningSaturation'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSaturation','PaintBasedCorrectionsLocalToningSaturation'] },
+	'paintcorrectionshadows2012' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalShadows2012'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalShadows2012'] },
+	'paintcorrectionsharpness' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSharpness'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalSharpness'] },
+	'paintcorrectiontemperature' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTemperature'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTemperature'] },
+	'paintcorrectiontexture' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTexture'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTexture'] },
+	'paintcorrectiontint' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTint'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalTint'] },
+	'paintcorrectionwhat' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsWhat'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsWhat'] },
+	'paintcorrectionwhites2012' => { 467 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalWhites2012'], 469 => [\'PaintBasedCorrections','PaintBasedCorrectionsLocalWhites2012'] },
+	'panasonicdatetime' => { 313 => 0x0 },
+	'panasonicexifversion' => { 310 => 0x26 },
+	'panasonicimageheight' => { 310 => 0x4c },
+	'panasonicimagewidth' => { 310 => 0x4b },
+	'panasonicrawversion' => { 315 => 0x1 },
+	'panasonictitle' => { 117 => 0xc6d2 },
+	'panasonictitle2' => { 117 => 0xc6d3 },
+	'panoramaangle' => { 125 => 0x1153 },
+	'panoramacropbottom' => { 416 => 0x7 },
+	'panoramacropleft' => { 416 => 0x4 },
+	'panoramacropright' => { 416 => 0x6 },
+	'panoramacroptop' => { 416 => 0x5 },
+	'panoramadirection' => { 70 => 0x5, 125 => 0x1154, 416 => 0x3 },
+	'panoramaframeheight' => { 416 => 0x9 },
+	'panoramaframenumber' => { 70 => 0x2 },
+	'panoramaframewidth' => { 416 => 0x8 },
+	'panoramafullheight' => { 416 => 0x2 },
+	'panoramafullwidth' => { 416 => 0x1 },
+	'panoramamode' => { 137 => 0x3c, 287 => 0x601 },
+	'panoramasize3d' => { 399 => 0x38 },
+	'panoramasourceheight' => { 416 => 0xb },
+	'panoramasourcewidth' => { 416 => 0xa },
+	'panoramicstitchcameramotion' => { 173 => 'PanoramicStitchCameraMotion', 174 => 0x1 },
+	'panoramicstitchmaptype' => { 173 => 'PanoramicStitchMapType', 174 => 0x2 },
+	'panoramicstitchphi0' => { 173 => 'PanoramicStitchPhi0', 174 => 0x5 },
+	'panoramicstitchphi1' => { 173 => 'PanoramicStitchPhi1', 174 => 0x6 },
+	'panoramicstitchtheta0' => { 173 => 'PanoramicStitchTheta0', 174 => 0x3 },
+	'panoramicstitchtheta1' => { 173 => 'PanoramicStitchTheta1', 174 => 0x4 },
+	'panoramicstitchversion' => { 174 => 0x0 },
+	'pantry' => { 494 => 'Pantry' },
+	'pantryinstanceid' => { 494 => [\'Pantry','PantryInstanceID'] },
+	'parallax' => { 125 => 0xb211, 286 => 0x28 },
+	'parametricdarks' => { 467 => 'ParametricDarks', 469 => 'ParametricDarks' },
+	'parametrichighlights' => { 467 => 'ParametricHighlights', 469 => 'ParametricHighlights' },
+	'parametrichighlightsplit' => { 467 => 'ParametricHighlightSplit', 469 => 'ParametricHighlightSplit' },
+	'parametriclights' => { 467 => 'ParametricLights', 469 => 'ParametricLights' },
+	'parametricmidtonesplit' => { 467 => 'ParametricMidtoneSplit', 469 => 'ParametricMidtoneSplit' },
+	'parametricshadows' => { 467 => 'ParametricShadows', 469 => 'ParametricShadows' },
+	'parametricshadowsplit' => { 467 => 'ParametricShadowSplit', 469 => 'ParametricShadowSplit' },
+	'parentmediaeventid' => { 457 => 'ParentMediaEventID' },
+	'parentmeid' => { 457 => 'ParentMEID' },
+	'parentproductid' => { 362 => '@ppi' },
+	'parentreference1' => { 477 => [\'TagStructure','TagStructureParentReference'] },
+	'parentreference2' => { 477 => [\'TagStructure','TagStructureSubLabelsParentReference'] },
+	'parentreference3' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsParentReference'] },
+	'parentreference4' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsParentReference'] },
+	'parentreference5' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsParentReference'] },
+	'parentreference6' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsParentReference'] },
+	'parentshorttitle' => { 362 => '@PST' },
+	'parenttitle' => { 362 => '@pti' },
+	'partialactivecols1' => { 135 => 0x17e8 },
+	'partialactivecols2' => { 135 => 0x17f2 },
+	'partialactiverows1' => { 135 => 0x17fc },
+	'partialactiverows2' => { 135 => 0x1806 },
+	'partofcompilation' => { 493 => 'partOfCompilation' },
+	'patientbirthdate' => { 446 => 'PatientDOB' },
+	'patientid' => { 446 => 'PatientID' },
+	'patientname' => { 446 => 'PatientName' },
+	'patientsex' => { 446 => 'PatientSex' },
+	'patternareaheight' => { 135 => 0x963 },
+	'patternareawidth' => { 135 => 0x962 },
+	'patterncorrectionfactorscale' => { 135 => 0x969 },
+	'patterncropcols1' => { 135 => 0x96c },
+	'patterncropcols2' => { 135 => 0x96d },
+	'patterncroprows1' => { 135 => 0x96a },
+	'patterncroprows2' => { 135 => 0x96b },
+	'patternimagerheight' => { 135 => 0x961 },
+	'patternimagerwidth' => { 135 => 0x960 },
+	'patternx' => { 135 => 0x966 },
+	'patterny' => { 135 => 0x967 },
+	'pdfversion' => { 480 => 'PDFVersion' },
+	'pentaximagesize' => { 345 => 0x9 },
+	'pentaxmodelid' => { 325 => 0x0, 345 => 0x5 },
+	'pentaxmodeltype' => { 345 => 0x1 },
+	'pentaxversion' => { 345 => 0x0 },
+	'people' => { 448 => 'People', 460 => 'People' },
+	'perchannelblacklevel' => { 41 => 0x157, 43 => 0xc4, 44 => [0x2b4,0x2cb,0x2cf], 45 => [0x108,0x14d], 46 => 0x1df, 47 => [0x1f8,0x2d8], 48 => [0x22c,0x30a], 49 => 0x149 },
+	'performer' => { 362 => 'perf', 370 => 'perf' },
+	'performerkeywords' => { 370 => "\xa9prk" },
+	'performers' => { 370 => "\xa9prf" },
+	'performerurl' => { 370 => "\xa9prl" },
+	'peripheralillumcentralradius' => { 444 => 0x8030 },
+	'peripheralillumcentralvalue' => { 444 => 0x8031 },
+	'peripheralillumination' => { 101 => 0x20702, 107 => 0x68 },
+	'peripheralilluminationcorr' => { 61 => 0x1, 335 => 0x2 },
+	'peripheralilluminationon' => { 101 => '0x20702.0', 107 => 0x64 },
+	'peripheralillumperiphvalue' => { 444 => 0x8032 },
+	'peripherallighting' => { 77 => 0x2, 125 => 0x3804 },
+	'peripherallightingsetting' => { 78 => 0x5 },
+	'peripherallightingvalue' => { 77 => 0x6 },
+	'permissions' => { 486 => 'permissions' },
+	'permits' => { 465 => 'permits' },
+	'person' => { 483 => 'person' },
+	'personality' => { 457 => 'Personality' },
+	'personheard' => { 479 => 'PersonHeard' },
+	'personheardidentifier' => { 479 => [\'PersonHeard','PersonHeardIdentifier'] },
+	'personheardname' => { 479 => [\'PersonHeard','PersonHeardName'] },
+	'personinimage' => { 479 => 'PersonInImage' },
+	'personinimagecharacteristic' => { 479 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristic'] },
+	'personinimagecvtermcvid' => { 479 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvId'] },
+	'personinimagecvtermid' => { 479 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermId'] },
+	'personinimagecvtermname' => { 479 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermName'] },
+	'personinimagecvtermrefinedabout' => { 479 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonCharacteristicCvTermRefinedAbout'] },
+	'personinimagedescription' => { 479 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonDescription'] },
+	'personinimageid' => { 479 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonId'] },
+	'personinimagename' => { 479 => [\'PersonInImageWDetails','PersonInImageWDetailsPersonName'] },
+	'personinimagewdetails' => { 479 => 'PersonInImageWDetails' },
+	'perspectiveaspect' => { 467 => 'PerspectiveAspect', 469 => 'PerspectiveAspect' },
+	'perspectivehorizontal' => { 467 => 'PerspectiveHorizontal', 469 => 'PerspectiveHorizontal' },
+	'perspectiverotate' => { 467 => 'PerspectiveRotate', 469 => 'PerspectiveRotate' },
+	'perspectivescale' => { 467 => 'PerspectiveScale', 469 => 'PerspectiveScale' },
+	'perspectiveupright' => { 467 => 'PerspectiveUpright', 469 => 'PerspectiveUpright' },
+	'perspectivevertical' => { 467 => 'PerspectiveVertical', 469 => 'PerspectiveVertical' },
+	'perspectivex' => { 467 => 'PerspectiveX', 469 => 'PerspectiveX' },
+	'perspectivey' => { 467 => 'PerspectiveY', 469 => 'PerspectiveY' },
+	'pf0customfuncregistration' => { 90 => 0x1 },
+	'pf10retainprogramshift' => { 90 => 0xb },
+	'pf13drivepriority' => { 90 => 0xe },
+	'pf14disablefocussearch' => { 90 => 0xf },
+	'pf15disableafassistbeam' => { 90 => 0x10 },
+	'pf16autofocuspointshoot' => { 90 => 0x11 },
+	'pf17disableafpointsel' => { 90 => 0x12 },
+	'pf18enableautoafpointsel' => { 90 => 0x13 },
+	'pf19continuousshootspeed' => { 90 => 0x14 },
+	'pf19shootingspeedhigh' => { 89 => 0xa },
+	'pf19shootingspeedlow' => { 89 => 0x9 },
+	'pf1disableshootingmodes' => { 90 => 0x2 },
+	'pf1value' => { 89 => 0x1 },
+	'pf20limitcontinousshots' => { 90 => 0x15 },
+	'pf20maxcontinousshots' => { 89 => 0xb },
+	'pf21enablequietoperation' => { 90 => 0x16 },
+	'pf23felocktime' => { 89 => 0xd },
+	'pf23postreleasetime' => { 89 => 0xe },
+	'pf23settimerlengths' => { 90 => 0x18 },
+	'pf23shutterbuttontime' => { 89 => 0xc },
+	'pf24lightlcdduringbulb' => { 90 => 0x19 },
+	'pf25aemode' => { 89 => 0xf },
+	'pf25afmode' => { 89 => 0x12 },
+	'pf25afpointsel' => { 89 => 0x13 },
+	'pf25colormatrix' => { 89 => 0x17 },
+	'pf25defaultclearsettings' => { 90 => 0x1a },
+	'pf25drivemode' => { 89 => 0x11 },
+	'pf25imagesize' => { 89 => 0x14 },
+	'pf25meteringmode' => { 89 => 0x10 },
+	'pf25parameters' => { 89 => 0x16 },
+	'pf25wbmode' => { 89 => 0x15 },
+	'pf26shortenreleaselag' => { 90 => 0x1b },
+	'pf27reversedialrotation' => { 90 => 0x1c },
+	'pf27value' => { 89 => 0x18 },
+	'pf28noquickdialexpcomp' => { 90 => 0x1d },
+	'pf29quickdialswitchoff' => { 90 => 0x1e },
+	'pf2disablemeteringmodes' => { 90 => 0x3 },
+	'pf2value' => { 89 => 0x2 },
+	'pf30enlargementmode' => { 90 => 0x1f },
+	'pf31originaldecisiondata' => { 90 => 0x20 },
+	'pf3manualexposuremetering' => { 90 => 0x4 },
+	'pf3value' => { 89 => 0x3 },
+	'pf4exposuretimelimits' => { 90 => 0x5 },
+	'pf4exposuretimemax' => { 89 => 0x5 },
+	'pf4exposuretimemin' => { 89 => 0x4 },
+	'pf5aperturelimits' => { 90 => 0x6 },
+	'pf5aperturemax' => { 89 => 0x7 },
+	'pf5aperturemin' => { 89 => 0x6 },
+	'pf6presetshootingmodes' => { 90 => 0x7 },
+	'pf7bracketcontinuousshoot' => { 90 => 0x8 },
+	'pf8bracketshots' => { 89 => 0x8 },
+	'pf8setbracketshots' => { 90 => 0x9 },
+	'pf9changebracketsequence' => { 90 => 0xa },
+	'phasedetectaf' => { 189 => 0x6 },
+	'phonenumber' => { 154 => 'Phone' },
+	'photoeffect' => { 34 => 0x28 },
+	'photoeffecthistoryxml' => { 263 => 0xe9651831 },
+	'photoeffects' => { 263 => 0xab5eca5e },
+	'photoeffectsblue' => { 265 => 0x8 },
+	'photoeffectsgreen' => { 265 => 0x6 },
+	'photoeffectsred' => { 265 => 0x4 },
+	'photoeffectstype' => { 265 => 0x0 },
+	'photographicsensitivity' => { 474 => 'PhotographicSensitivity' },
+	'photoinfoplayback' => { 270 => '17.6', 279 => '33.6' },
+	'photometricinterpretation' => { 117 => 0x106, 489 => 'PhotometricInterpretation' },
+	'photoshootingmenubank' => { 240 => 0xe7d, 250 => 0xfbd },
+	'photoshootingmenubankimagearea' => { 240 => '3716.1', 250 => 0x791 },
+	'photoshopbgrthumbnail' => { 359 => 0x409 },
+	'photoshopquality' => { 358 => 0x0 },
+	'photoshopthumbnail' => { 359 => 0x40c },
+	'photostyle' => { 310 => 0x89 },
+	'picklabel' => { 472 => 'PickLabel' },
+	'pictinfo' => { 386 => 0x208 },
+	'picturecontrol' => { 263 => 0xe2173c47 },
+	'picturecontrolactive' => { 266 => 0x0 },
+	'picturecontroladjust' => { 223 => 0x30, 224 => 0x30, 225 => 0x36 },
+	'picturecontrolbase' => { 223 => 0x18, 224 => 0x18, 225 => 0x1c },
+	'picturecontroldata' => { 221 => [0xbd,0x23] },
+	'picturecontrolmode' => { 266 => 0x13 },
+	'picturecontrolname' => { 223 => 0x4, 224 => 0x4, 225 => 0x8 },
+	'picturecontrolquickadjust' => { 223 => 0x31, 224 => 0x31, 225 => 0x37 },
+	'pictureeffect' => { 410 => 0x200e },
+	'pictureeffect2' => { 418 => 0x1163, 419 => 0x1167, 420 => 0x1143, 421 => 0x11bf, 422 => 0x119b, 423 => 0x1053, 424 => 0x24b, 425 => 0x24b, 426 => 0x23c, 440 => 0x46 },
+	'picturefinish' => { 178 => 0x71 },
+	'picturemode' => { 125 => 0x1031, 287 => 0x520, 345 => [0xb,0x33], 387 => 0x3d },
+	'picturemode2' => { 326 => 0x0 },
+	'picturemodebwfilter' => { 287 => 0x525 },
+	'picturemodecontrast' => { 287 => 0x523 },
+	'picturemodeeffect' => { 287 => 0x52d },
+	'picturemodehue' => { 287 => 0x522 },
+	'picturemodesaturation' => { 287 => 0x521 },
+	'picturemodesharpness' => { 287 => 0x524 },
+	'picturemodetone' => { 287 => 0x526 },
+	'pictureprofile' => { 418 => [0x115e,0x115f], 419 => [0x1162,0x1163], 420 => [0x113e,0x113f], 421 => [0x11ba,0x11bb], 422 => [0x1196,0x1197], 423 => [0x104e,0x104f], 424 => [0x246,0x247], 425 => [0x246,0x247], 426 => [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, 72 => 0xa, 101 => 0x20301, 107 => 0x2 },
+	'picturestylepc' => { 62 => 0x4009 },
+	'picturestyleuserdef' => { 62 => 0x4008 },
+	'picturewizard' => { 384 => 0x21 },
+	'picturewizardcolor' => { 383 => 0x1 },
+	'picturewizardcontrast' => { 383 => 0x4 },
+	'picturewizardmode' => { 383 => 0x0 },
+	'picturewizardsaturation' => { 383 => 0x2 },
+	'picturewizardsharpness' => { 383 => 0x3 },
+	'pipelineversion' => { 173 => 'PipelineVersion' },
+	'pitch' => { 113 => 0x6, 271 => '4.1', 283 => '4.1', 370 => ['ptch',"\xa9fpt"] },
+	'pitchangle' => { 239 => 0x350f, 240 => 0x2c28, 244 => 0xc21e, 249 => 0x36f8, 250 => 0x2eff, 252 => 0xce36, 287 => 0x904, 310 => 0x91, 344 => 0x2, 382 => 0x1 },
+	'pitchshift' => { 364 => 'player.movie.audio.pitchshift' },
+	'pixelaspectratio' => { 363 => 'pasp' },
+	'pixelclockfrequency' => { 135 => 0x40b },
+	'pixelcorrectionoffset' => { 135 => 0x972 },
+	'pixelcorrectionscale' => { 135 => 0x971 },
+	'pixelscale' => { 117 => 0x830e },
+	'pixelshiftinfo' => { 410 => 0x202f },
+	'pixelshiftresolution' => { 346 => 0x0 },
+	'pixelsperunitx' => { 299 => 0x0 },
+	'pixelsperunity' => { 299 => 0x4 },
+	'pixelunits' => { 299 => 0x8 },
+	'planarconfiguration' => { 117 => 0x11c, 489 => 'PlanarConfiguration' },
+	'plane' => { 447 => [\'Planes','PlanesPlane'] },
+	'planeboundary' => { 447 => [\'Planes','PlanesPlaneBoundary'] },
+	'planeboundaryvertexcount' => { 447 => [\'Planes','PlanesPlaneBoundaryVertexCount'] },
+	'planeextentx' => { 447 => [\'Planes','PlanesPlaneExtentX'] },
+	'planeextentz' => { 447 => [\'Planes','PlanesPlaneExtentZ'] },
+	'planepose' => { 447 => [\'Planes','PlanesPlanePose'] },
+	'planeposepositionx' => { 447 => [\'Planes','PlanesPlanePosePositionX'] },
+	'planeposepositiony' => { 447 => [\'Planes','PlanesPlanePosePositionY'] },
+	'planeposepositionz' => { 447 => [\'Planes','PlanesPlanePosePositionZ'] },
+	'planeposerotationw' => { 447 => [\'Planes','PlanesPlanePoseRotationW'] },
+	'planeposerotationx' => { 447 => [\'Planes','PlanesPlanePoseRotationX'] },
+	'planeposerotationy' => { 447 => [\'Planes','PlanesPlanePoseRotationY'] },
+	'planeposerotationz' => { 447 => [\'Planes','PlanesPlanePoseRotationZ'] },
+	'planeposetimestamp' => { 447 => [\'Planes','PlanesPlanePoseTimestamp'] },
+	'planes' => { 447 => 'Planes' },
+	'planningref' => { 479 => 'PlanningRef' },
+	'planningrefidentifier' => { 479 => [\'PlanningRef','PlanningRefIdentifier'] },
+	'planningrefname' => { 479 => [\'PlanningRef','PlanningRefName'] },
+	'planningrefrole' => { 479 => [\'PlanningRef','PlanningRefRole'] },
+	'platenames' => { 498 => 'PlateNames' },
+	'platform' => { 483 => 'platform' },
+	'playallframes' => { 370 => 'AllF' },
+	'playbackmenustime' => { 275 => '20.1', 276 => '21.1', 277 => '21.1' },
+	'playbackmonitorofftime' => { 270 => '25.2', 271 => '36.1', 273 => '36.1', 274 => '36.1', 278 => '35.1', 279 => '8.1', 280 => '35.1', 283 => '36.1', 284 => '36.1', 285 => '21.1' },
+	'playbackzoom' => { 271 => '37.1' },
+	'playdisplay' => { 180 => 0x4e },
+	'playerversion' => { 364 => 'player.version' },
+	'playgap' => { 362 => 'pgap' },
+	'playlistid' => { 362 => 'plID' },
+	'playmode' => { 370 => 'SDLN' },
+	'playselection' => { 370 => 'SelO' },
+	'plusversion' => { 297 => 'Version' },
+	'pmversion' => { 357 => 'PMVersion' },
+	'pngwarning' => { 300 => 'Warning' },
+	'podcast' => { 362 => 'pcst' },
+	'podcasturl' => { 362 => 'purl' },
+	'poilevel' => { 220 => 0x8 },
+	'portraitnote' => { 450 => 'PortraitNote' },
+	'portraitoutputhighlightpoint' => { 107 => 0x1d },
+	'portraitoutputshadowpoint' => { 107 => 0x1e },
+	'portraitrawcolortone' => { 107 => 0x16 },
+	'portraitrawcontrast' => { 107 => 0x18 },
+	'portraitrawhighlight' => { 107 => 0x76 },
+	'portraitrawhighlightpoint' => { 107 => 0x1b },
+	'portraitrawlinear' => { 107 => 0x19 },
+	'portraitrawsaturation' => { 107 => 0x17 },
+	'portraitrawshadow' => { 107 => 0x7f },
+	'portraitrawshadowpoint' => { 107 => 0x1c },
+	'portraitrawsharpness' => { 107 => 0x1a },
+	'portraitrefiner' => { 111 => 0x302b },
+	'portraitrequest' => { 450 => 'PortraitRequest' },
+	'portraitunsharpmaskfineness' => { 107 => 0x9a },
+	'portraitunsharpmaskstrength' => { 107 => 0x98 },
+	'portraitunsharpmaskthreshold' => { 107 => 0x9c },
+	'portraitversion' => { 450 => 'PortraitVersion' },
+	'pose' => { 447 => 'Pose' },
+	'poseheadingdegrees' => { 455 => 'PoseHeadingDegrees' },
+	'posepitchdegrees' => { 455 => 'PosePitchDegrees' },
+	'posepositionx' => { 447 => [\'Pose','PosePositionX'] },
+	'posepositiony' => { 447 => [\'Pose','PosePositionY'] },
+	'posepositionz' => { 447 => [\'Pose','PosePositionZ'] },
+	'poserolldegrees' => { 455 => 'PoseRollDegrees' },
+	'poserotationw' => { 447 => [\'Pose','PoseRotationW'] },
+	'poserotationx' => { 447 => [\'Pose','PoseRotationX'] },
+	'poserotationy' => { 447 => [\'Pose','PoseRotationY'] },
+	'poserotationz' => { 447 => [\'Pose','PoseRotationZ'] },
+	'posetimestamp' => { 447 => [\'Pose','PoseTimestamp'] },
+	'positiondescriptor' => { 482 => 'positionDescriptor' },
+	'postalcode' => { 158 => 'PostalCode' },
+	'postcropvignetteamount' => { 467 => 'PostCropVignetteAmount', 469 => 'PostCropVignetteAmount' },
+	'postcropvignettefeather' => { 467 => 'PostCropVignetteFeather', 469 => 'PostCropVignetteFeather' },
+	'postcropvignettehighlightcontrast' => { 467 => 'PostCropVignetteHighlightContrast', 469 => 'PostCropVignetteHighlightContrast' },
+	'postcropvignettemidpoint' => { 467 => 'PostCropVignetteMidpoint', 469 => 'PostCropVignetteMidpoint' },
+	'postcropvignetteroundness' => { 467 => 'PostCropVignetteRoundness', 469 => 'PostCropVignetteRoundness' },
+	'postcropvignettestyle' => { 467 => 'PostCropVignetteStyle', 469 => 'PostCropVignetteStyle' },
+	'postfocusmerging' => { 310 => 0xbf },
+	'potentialface1position' => { 407 => 0xb },
+	'potentialface2position' => { 407 => 0x15 },
+	'potentialface3position' => { 407 => 0x1f },
+	'potentialface4position' => { 407 => 0x29 },
+	'potentialface5position' => { 407 => 0x33 },
+	'potentialface6position' => { 407 => 0x3d },
+	'potentialface7position' => { 407 => 0x47 },
+	'potentialface8position' => { 407 => 0x51 },
+	'powersource' => { 324 => '0.1' },
+	'poweruptime' => { 221 => 0xb6 },
+	'precaptureframes' => { 292 => 0x300 },
+	'predictor' => { 117 => 0x13d },
+	'preflashreturnstrength' => { 237 => 0x28a },
+	'prefs' => { 129 => 0xdd, 357 => 'Prefs' },
+	'prereadfastresetcount' => { 135 => 0x187e },
+	'preservedfilename' => { 494 => 'PreservedFileName' },
+	'preservedspecimen' => { 116 => 'PreservedSpecimen' },
+	'preservedspecimenmaterialsampleid' => { 116 => [\'PreservedSpecimen','PreservedSpecimenMaterialSampleID'] },
+	'presettype' => { 467 => 'PresetType', 469 => 'PresetType' },
+	'presetwhitebalance' => { 180 => 0x24, 444 => 0x8002 },
+	'presetwhitebalanceadj' => { 444 => 0x8014 },
+	'pressure' => { 117 => 0x9402, 474 => 'Pressure' },
+	'previewapplicationname' => { 117 => 0xc716 },
+	'previewapplicationversion' => { 117 => 0xc717 },
+	'previewbutton' => { 270 => ['14.1','15.1'], 271 => '15.1', 273 => '15.1', 274 => '15.1', 279 => '29.1', 280 => '14.1', 283 => '15.1', 284 => '15.1' },
+	'previewbuttonplusdials' => { 270 => ['14.2','15.2'], 271 => '15.2', 273 => '43.1', 274 => '43.1', 279 => '31.2', 283 => '43.1', 284 => '43.1' },
+	'previewcolorspace' => { 117 => 0xc71a },
+	'previewcropbottom' => { 356 => 0xef },
+	'previewcropleft' => { 356 => 0xec },
+	'previewcropright' => { 356 => 0xee },
+	'previewcroptop' => { 356 => 0xed },
+	'previewdate' => { 368 => 0x0 },
+	'previewdatetime' => { 117 => 0xc71b },
+	'previewimage' => { 111 => 0x2000, 112 => 'Exif-PreviewImage', 118 => 'PreviewImage', 120 => 0x4, 163 => 'data', 182 => 0x81, 292 => 0x280, 308 => 0x300, 410 => 0x2001 },
+	'previewimageborders' => { 345 => 0x3e },
+	'previewimageheight' => { 71 => 0x4, 139 => 0xfa58 },
+	'previewimagelength' => { 71 => 0x2, 111 => 0x3, 117 => [0x117,0x202], 182 => 0x89, 226 => 0x202, 287 => 0x102, 292 => 0x1037, 345 => 0x3, 376 => 0x1e, 381 => 0x3, 387 => [0x1b,0x1d], 400 => 0x202 },
+	'previewimagename' => { 163 => '1Name' },
+	'previewimagesize' => { 111 => 0x2, 144 => 0x2, 163 => 'ImageSize', 345 => 0x2, 387 => [0x1c,0x1e], 410 => 0xb02c, 444 => 0x9012 },
+	'previewimagestart' => { 71 => 0x5, 111 => 0x4, 117 => [0x111,0x201], 182 => 0x88, 226 => 0x201, 287 => 0x101, 292 => 0x1036, 345 => 0x4, 376 => 0x1c, 381 => 0x2, 387 => [0x1a,0x1c], 400 => 0x201 },
+	'previewimagetype' => { 163 => '0Type' },
+	'previewimagevalid' => { 287 => 0x100, 292 => 0x1035 },
+	'previewimagewidth' => { 71 => 0x3, 139 => 0xfa57 },
+	'previewquality' => { 71 => 0x1 },
+	'previewsettingsdigest' => { 117 => 0xc719 },
+	'previewsettingsname' => { 117 => 0xc718 },
+	'primaryafpoint' => { 189 => [0x38,0x44,0x7] },
+	'primarychromaticities' => { 117 => 0x13f, 489 => 'PrimaryChromaticities' },
+	'primaryftp' => { 457 => 'PrimaryFTP' },
+	'primaryslot' => { 240 => 0xe7f, 250 => 0xfbf },
+	'printim' => { 117 => 0xc4a5 },
+	'prioritysetinawb' => { 410 => 0x202b },
+	'prioritysetupshutterrelease' => { 180 => 0x1d, 397 => 0x28 },
+	'privatertkinfo' => { 459 => 'privateRTKInfo' },
+	'processbordercolsleft' => { 135 => 0xc61 },
+	'processbordercolsright' => { 135 => 0xc62 },
+	'processborderrowsbottom' => { 135 => 0xc64 },
+	'processborderrowstop' => { 135 => 0xc63 },
+	'processingsoftware' => { 117 => 0xb },
+	'processversion' => { 467 => 'ProcessVersion', 469 => 'ProcessVersion' },
+	'producer' => { 296 => 'Producer', 362 => "\xa9prd", 364 => 'producer', 370 => "\xa9prd", 480 => 'Producer' },
+	'producerkeywords' => { 370 => "\xa9pdk" },
+	'productcode' => { 483 => 'productCode' },
+	'productid' => { 130 => 0x32, 362 => 'prID', 482 => 'productID' },
+	'productidtype' => { 482 => 'productIDType' },
+	'productinimage' => { 479 => 'ProductInImage' },
+	'productinimagedescription' => { 479 => [\'ProductInImage','ProductInImageProductDescription'] },
+	'productinimagegtin' => { 479 => [\'ProductInImage','ProductInImageProductGTIN'] },
+	'productinimagename' => { 479 => [\'ProductInImage','ProductInImageProductName'] },
+	'productioncode' => { 325 => 0x2 },
+	'productorserviceconstraints' => { 297 => 'ProductOrServiceConstraints' },
+	'productversion' => { 362 => 'VERS' },
+	'profession' => { 483 => 'profession' },
+	'profile' => { 447 => [\'Profiles','ProfilesProfile'] },
+	'profilecalibrationsig' => { 117 => 0xc6f4 },
+	'profilecameraindices' => { 447 => [\'Profiles','ProfilesProfileCameraIndices'] },
+	'profilecopyright' => { 117 => 0xc6fe },
+	'profileembedpolicy' => { 117 => 0xc6fd },
+	'profilehuesatmapdata1' => { 117 => 0xc6fa },
+	'profilehuesatmapdata2' => { 117 => 0xc6fb },
+	'profilehuesatmapdims' => { 117 => 0xc6f9 },
+	'profilehuesatmapencoding' => { 117 => 0xc7a3 },
+	'profilelooktabledata' => { 117 => 0xc726 },
+	'profilelooktabledims' => { 117 => 0xc725 },
+	'profilelooktableencoding' => { 117 => 0xc7a4 },
+	'profilename' => { 117 => 0xc6f8 },
+	'profiles' => { 447 => 'Profiles' },
+	'profiletonecurve' => { 117 => 0xc6fc },
+	'profiletype' => { 447 => [\'Profiles','ProfilesProfileType'] },
+	'programiso' => { 310 => 0x3c },
+	'programline' => { 326 => '1.1' },
+	'programmode' => { 185 => 0x5 },
+	'programshift' => { 221 => 0xd },
+	'programversion' => { 129 => 0x46 },
+	'prohibits' => { 465 => 'prohibits' },
+	'projectiontype' => { 455 => 'ProjectionType', 456 => 'ProjectionType' },
+	'projectname' => { 493 => 'projectName' },
+	'projectref' => { 493 => 'projectRef' },
+	'projectrefpath' => { 493 => [\'projectRef','projectRefPath'] },
+	'projectreftype' => { 493 => [\'projectRef','projectRefType'] },
+	'propertyreleaseid' => { 297 => 'PropertyReleaseID' },
+	'propertyreleasestatus' => { 297 => 'PropertyReleaseStatus' },
+	'province-state' => { 129 => 0x5f },
+	'publicationdate' => { 483 => 'publicationDate' },
+	'publicationdatea-platform' => { 483 => [\'publicationDate','publicationDateA-platform'] },
+	'publicationdatedate' => { 483 => [\'publicationDate','publicationDateDate'] },
+	'publicationdisplaydate' => { 483 => 'publicationDisplayDate' },
+	'publicationdisplaydatea-platform' => { 483 => [\'publicationDisplayDate','publicationDisplayDateA-platform'] },
+	'publicationdisplaydatedate' => { 483 => [\'publicationDisplayDate','publicationDisplayDateDate'] },
+	'publicationevent' => { 479 => 'PublicationEvent' },
+	'publicationeventdate' => { 479 => [\'PublicationEvent','PublicationEventDate'] },
+	'publicationeventidentifier' => { 479 => [\'PublicationEvent','PublicationEventIdentifier'] },
+	'publicationeventname' => { 479 => [\'PublicationEvent','PublicationEventName'] },
+	'publicationname' => { 483 => 'publicationName' },
+	'publisher' => { 362 => "\xa9pub", 364 => 'publisher', 470 => 'publisher' },
+	'publishingfrequency' => { 483 => 'publishingFrequency' },
+	'pulldown' => { 493 => 'pullDown' },
+	'purchasedate' => { 362 => 'purd' },
+	'purplehsl' => { 101 => 0x20916 },
+	'pxshiftperiphedgenr' => { 444 => 0x9013 },
+	'pxshiftperiphedgenrvalue' => { 444 => 0x9014 },
+	'quality' => { 0 => 0x1, 34 => 0x3, 110 => 0x2, 111 => 0x3002, 125 => 0x1000, 137 => 0x9, 221 => 0x4, 253 => 0x3, 292 => 0x201, 305 => 0x300, 345 => 0x8, 352 => 0x2, 387 => 0x16, 397 => 0x56, 398 => 0x56, 399 => 0xb, 410 => [0x102,0x202e] },
+	'quality2' => { 418 => 0x1170, 419 => 0x1174, 420 => 0x1150, 422 => 0x11a8, 423 => 0x1060, 424 => 0x258, 425 => 0x258, 426 => 0x247, 431 => 0x29, 432 => 0x25, 433 => 0x2a },
+	'qualitymode' => { 111 => 0x8 },
+	'quantizationmethod' => { 131 => 0x78 },
+	'quickadjust' => { 266 => 0x2a },
+	'quickcontroldialinmeter' => { 82 => 0x703 },
+	'quickfix' => { 263 => 0x416391c6 },
+	'quickshot' => { 386 => 0x213 },
+	'quiettime' => { 135 => 0x188a },
+	'rads' => { 370 => 'rads' },
+	'rangefinder' => { 275 => '4.1', 276 => '5.1', 277 => '5.1' },
+	'rasterizedcaption' => { 129 => 0x7d },
+	'rating' => { 117 => 0x4746, 125 => 0x1431, 356 => 0xdf, 362 => 'rtng', 410 => 0x2002, 462 => 'rating', 471 => 'rating', 479 => 'Rating', 483 => 'rating', 491 => 'Rating' },
+	'ratingpercent' => { 117 => 0x4749, 175 => 'Rating', 362 => 'rate', 491 => 'RatingPercent' },
+	'ratingregion' => { 479 => [\'Rating','RatingRatingRegion'] },
+	'ratingregioncity' => { 479 => [\'Rating','RatingRatingRegionCity'] },
+	'ratingregioncountrycode' => { 479 => [\'Rating','RatingRatingRegionCountryCode'] },
+	'ratingregioncountryname' => { 479 => [\'Rating','RatingRatingRegionCountryName'] },
+	'ratingregiongpsaltitude' => { 479 => [\'Rating','RatingRatingRegionGPSAltitude'] },
+	'ratingregiongpslatitude' => { 479 => [\'Rating','RatingRatingRegionGPSLatitude'] },
+	'ratingregiongpslongitude' => { 479 => [\'Rating','RatingRatingRegionGPSLongitude'] },
+	'ratingregionidentifier' => { 479 => [\'Rating','RatingRatingRegionIdentifier'] },
+	'ratingregionlocationid' => { 479 => [\'Rating','RatingRatingRegionLocationId'] },
+	'ratingregionlocationname' => { 479 => [\'Rating','RatingRatingRegionLocationName'] },
+	'ratingregionprovincestate' => { 479 => [\'Rating','RatingRatingRegionProvinceState'] },
+	'ratingregionsublocation' => { 479 => [\'Rating','RatingRatingRegionSublocation'] },
+	'ratingregionworldregion' => { 479 => [\'Rating','RatingRatingRegionWorldRegion'] },
+	'ratingscalemaxvalue' => { 479 => [\'Rating','RatingRatingScaleMaxValue'] },
+	'ratingscaleminvalue' => { 479 => [\'Rating','RatingRatingScaleMinValue'] },
+	'ratingsourcelink' => { 479 => [\'Rating','RatingRatingSourceLink'] },
+	'ratingvalue' => { 479 => [\'Rating','RatingRatingValue'] },
+	'ratingvaluelogolink' => { 479 => [\'Rating','RatingRatingValueLogoLink'] },
+	'rawandjpgrecording' => { 80 => 0x8, 182 => 0x109, 326 => 0xd },
+	'rawbrightnessadj' => { 101 => 0x20001, 106 => 0x38 },
+	'rawburstimagecount' => { 73 => 0x2 },
+	'rawburstimagenum' => { 73 => 0x1 },
+	'rawcoloradj' => { 106 => 0x2e },
+	'rawcropbottom' => { 356 => 0xd4 },
+	'rawcropleft' => { 356 => 0xd1 },
+	'rawcropright' => { 356 => 0xd3 },
+	'rawcroptop' => { 356 => 0xd2 },
+	'rawcustomsaturation' => { 106 => 0x30 },
+	'rawcustomtone' => { 106 => 0x34 },
+	'rawdata' => { 384 => 0xa048 },
+	'rawdatabyteorder' => { 384 => 0x40 },
+	'rawdatacfapattern' => { 384 => 0x50 },
+	'rawdatauniqueid' => { 117 => 0xc65d },
+	'rawdepth' => { 184 => 0x10 },
+	'rawdevartfilter' => { 294 => 0x121 },
+	'rawdevautogradation' => { 294 => 0x119 },
+	'rawdevcolorspace' => { 293 => 0x108, 294 => 0x109 },
+	'rawdevcontrastvalue' => { 293 => 0x106, 294 => 0x105 },
+	'rawdeveditstatus' => { 293 => 0x10b },
+	'rawdevelopmentprocess' => { 345 => 0x62 },
+	'rawdevengine' => { 293 => 0x109, 294 => 0x10b },
+	'rawdevexposurebiasvalue' => { 293 => 0x100, 294 => 0x100 },
+	'rawdevgradation' => { 294 => 0x112 },
+	'rawdevgraypoint' => { 293 => 0x103, 294 => 0x104 },
+	'rawdevmemorycoloremphasis' => { 293 => 0x105, 294 => 0x108 },
+	'rawdevnoisereduction' => { 293 => 0x10a, 294 => 0x10a },
+	'rawdevpicturemode' => { 294 => 0x10c },
+	'rawdevpm_bwfilter' => { 294 => 0x110 },
+	'rawdevpmcontrast' => { 294 => 0x10e },
+	'rawdevpmnoisefilter' => { 294 => 0x120 },
+	'rawdevpmpicturetone' => { 294 => 0x111 },
+	'rawdevpmsaturation' => { 294 => 0x10d },
+	'rawdevpmsharpness' => { 294 => 0x10f },
+	'rawdevsaturation3' => { 294 => 0x113 },
+	'rawdevsaturationemphasis' => { 293 => 0x104, 294 => 0x107 },
+	'rawdevsettings' => { 293 => 0x10c },
+	'rawdevsharpnessvalue' => { 293 => 0x107, 294 => 0x106 },
+	'rawdevversion' => { 293 => 0x0, 294 => 0x0 },
+	'rawdevwbfineadjustment' => { 293 => 0x102, 294 => 0x103 },
+	'rawdevwhitebalance' => { 294 => 0x101 },
+	'rawdevwhitebalancevalue' => { 293 => 0x101, 294 => 0x102 },
+	'rawfile' => { 117 => 0xfe4c },
+	'rawfilename' => { 467 => 'RawFileName', 469 => 'RawFileName' },
+	'rawfiletype' => { 410 => 0x2029 },
+	'rawformat' => { 315 => 0x2d, 354 => 0x10e },
+	'rawimagecenter' => { 221 => 0x99 },
+	'rawimagedigest' => { 117 => 0xc71c },
+	'rawimagesize' => { 345 => 0x39 },
+	'rawinfoversion' => { 295 => 0x0 },
+	'rawjpgheight' => { 97 => 0x4 },
+	'rawjpgquality' => { 56 => 0x6, 97 => 0x1 },
+	'rawjpgsize' => { 56 => 0x7, 97 => 0x2 },
+	'rawjpgwidth' => { 97 => 0x3 },
+	'rawmeasuredrggb' => { 42 => 0x26a, 44 => 0x280, 46 => 0x194, 47 => [0x1ad,0x26b] },
+	'rawrppused' => { 462 => 'rawrppused' },
+	'rawtopreviewgain' => { 117 => 0xc7a8 },
+	'readouttypeactual' => { 135 => 0x1903 },
+	'readouttyperequested' => { 135 => 0x1902 },
+	'reardisplay' => { 270 => '12.3', 271 => '6.2' },
+	'recdevice' => { 479 => 'RecDevice' },
+	'recdeviceattlensdescription' => { 479 => [\'RecDevice','RecDeviceAttLensDescription'] },
+	'recdevicemanufacturer' => { 479 => [\'RecDevice','RecDeviceManufacturer'] },
+	'recdevicemodelname' => { 479 => [\'RecDevice','RecDeviceModelName'] },
+	'recdeviceownersdeviceid' => { 479 => [\'RecDevice','RecDeviceOwnersDeviceId'] },
+	'recdeviceserialnumber' => { 479 => [\'RecDevice','RecDeviceSerialNumber'] },
+	'recipeendingpage' => { 485 => 'recipeEndingPage' },
+	'recipepagerange' => { 485 => 'recipePageRange' },
+	'recipesource' => { 485 => 'recipeSource' },
+	'recipestartingpage' => { 485 => 'recipeStartingPage' },
+	'recipetitle' => { 485 => 'recipeTitle' },
+	'recognizedface1age' => { 303 => 0x20 },
+	'recognizedface1name' => { 303 => 0x4 },
+	'recognizedface1position' => { 303 => 0x18 },
+	'recognizedface2age' => { 303 => 0x50 },
+	'recognizedface2name' => { 303 => 0x34 },
+	'recognizedface2position' => { 303 => 0x48 },
+	'recognizedface3age' => { 303 => 0x80 },
+	'recognizedface3name' => { 303 => 0x64 },
+	'recognizedface3position' => { 303 => 0x78 },
+	'recognizedfaceflags' => { 310 => 0x63 },
+	'recommendedexposureindex' => { 117 => 0x8832, 474 => 'RecommendedExposureIndex' },
+	'record' => { 116 => 'Record' },
+	'recordbasisofrecord' => { 116 => [\'Record','RecordBasisOfRecord'] },
+	'recordcollectioncode' => { 116 => [\'Record','RecordCollectionCode'] },
+	'recordcollectionid' => { 116 => [\'Record','RecordCollectionID'] },
+	'recorddatageneralizations' => { 116 => [\'Record','RecordDataGeneralizations'] },
+	'recorddatasetid' => { 116 => [\'Record','RecordDatasetID'] },
+	'recorddatasetname' => { 116 => [\'Record','RecordDatasetName'] },
+	'recorddisplay' => { 180 => 0x4d },
+	'recorddynamicproperties' => { 116 => [\'Record','RecordDynamicProperties'] },
+	'recordid' => { 95 => 0x1804 },
+	'recordinformationwithheld' => { 116 => [\'Record','RecordInformationWithheld'] },
+	'recordingcopyright' => { 370 => "\xa9phg" },
+	'recordingformat' => { 377 => 0x1000 },
+	'recordingmode' => { 110 => 0x1, 352 => 0x1 },
+	'recordinstitutioncode' => { 116 => [\'Record','RecordInstitutionCode'] },
+	'recordinstitutionid' => { 116 => [\'Record','RecordInstitutionID'] },
+	'recordlabelname' => { 370 => "\xa9lab" },
+	'recordlabelurl' => { 370 => "\xa9lal" },
+	'recordmode' => { 34 => 0x9, 111 => 0x3000 },
+	'recordownerinstitutioncode' => { 116 => [\'Record','RecordOwnerInstitutionCode'] },
+	'recordshutterrelease' => { 386 => 0x217 },
+	'redbalance' => { 292 => 0x1017, 315 => 0x11, 345 => 0x1c },
+	'redcurvelimits' => { 106 => 0x18a },
+	'redcurvepoints' => { 105 => 0x2d, 106 => 0x160 },
+	'redeyecorrection' => { 267 => 0x0 },
+	'redeyeinfo' => { 467 => 'RedEyeInfo', 469 => 'RedEyeInfo' },
+	'redeyereduction' => { 180 => 0x41, 397 => 0x6a, 399 => 0x28 },
+	'redeyeremoval' => { 310 => 0xb9 },
+	'redhsl' => { 101 => 0x20910 },
+	'redhue' => { 467 => 'RedHue', 469 => 'RedHue' },
+	'redsaturation' => { 467 => 'RedSaturation', 469 => 'RedSaturation' },
+	'reductionmatrix1' => { 117 => 0xc625 },
+	'reductionmatrix2' => { 117 => 0xc626 },
+	'reelname' => { 117 => 0xc789, 370 => 'reel' },
+	'reference1' => { 477 => [\'TagStructure','TagStructureReference'] },
+	'reference2' => { 477 => [\'TagStructure','TagStructureSubLabelsReference'] },
+	'reference3' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsReference'] },
+	'reference4' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsReference'] },
+	'reference5' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsReference'] },
+	'reference6' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsReference'] },
+	'referenceblackwhite' => { 117 => 0x214, 489 => 'ReferenceBlackWhite' },
+	'referencedate' => { 129 => 0x2f },
+	'referencenumber' => { 129 => 0x32 },
+	'references' => { 154 => 'References' },
+	'referenceservice' => { 129 => 0x2d },
+	'regionappliedtodimensions' => { 169 => [\'Regions','RegionsAppliedToDimensions'] },
+	'regionappliedtodimensionsh' => { 169 => [\'Regions','RegionsAppliedToDimensionsH'] },
+	'regionappliedtodimensionsunit' => { 169 => [\'Regions','RegionsAppliedToDimensionsUnit'] },
+	'regionappliedtodimensionsw' => { 169 => [\'Regions','RegionsAppliedToDimensionsW'] },
+	'regionarea' => { 169 => [\'Regions','RegionsRegionListArea'] },
+	'regionaread' => { 169 => [\'Regions','RegionsRegionListAreaD'] },
+	'regionareah' => { 169 => [\'Regions','RegionsRegionListAreaH'] },
+	'regionareaunit' => { 169 => [\'Regions','RegionsRegionListAreaUnit'] },
+	'regionareaw' => { 169 => [\'Regions','RegionsRegionListAreaW'] },
+	'regionareax' => { 169 => [\'Regions','RegionsRegionListAreaX'] },
+	'regionareay' => { 169 => [\'Regions','RegionsRegionListAreaY'] },
+	'regionbarcodevalue' => { 169 => [\'Regions','RegionsRegionListBarCodeValue'] },
+	'regionconstraints' => { 297 => 'RegionConstraints' },
+	'regiondescription' => { 169 => [\'Regions','RegionsRegionListDescription'] },
+	'regionextensions' => { 169 => [\'Regions','RegionsRegionListExtensions'] },
+	'regionfocususage' => { 169 => [\'Regions','RegionsRegionListFocusUsage'] },
+	'regioninfo' => { 169 => 'Regions' },
+	'regioninfodateregionsvalid' => { 172 => [\'RegionInfo','RegionInfoDateRegionsValid'] },
+	'regioninfomp' => { 172 => 'RegionInfo' },
+	'regioninforegions' => { 172 => [\'RegionInfo','RegionInfoRegions'] },
+	'regionlist' => { 169 => [\'Regions','RegionsRegionList'] },
+	'regionname' => { 169 => [\'Regions','RegionsRegionListName'] },
+	'regionpersondisplayname' => { 172 => [\'RegionInfo','RegionInfoRegionsPersonDisplayName'] },
+	'regionpersonemaildigest' => { 172 => [\'RegionInfo','RegionInfoRegionsPersonEmailDigest'] },
+	'regionpersonliveidcid' => { 172 => [\'RegionInfo','RegionInfoRegionsPersonLiveIdCID'] },
+	'regionpersonsourceid' => { 172 => [\'RegionInfo','RegionInfoRegionsPersonSourceID'] },
+	'regionrectangle' => { 172 => [\'RegionInfo','RegionInfoRegionsRectangle'] },
+	'regionrotation' => { 169 => [\'Regions','RegionsRegionListRotation'] },
+	'regionseealso' => { 169 => [\'Regions','RegionsRegionListSeeAlso'] },
+	'regiontype' => { 169 => [\'Regions','RegionsRegionListType'] },
+	'registryentryrole' => { 479 => [\'RegistryId','RegistryIdRegEntryRole'] },
+	'registryid' => { 479 => 'RegistryId' },
+	'registryitemid' => { 479 => [\'RegistryId','RegistryIdRegItemId'] },
+	'registryorganisationid' => { 479 => [\'RegistryId','RegistryIdRegOrgId'] },
+	'relatedaudiofile' => { 152 => 'data' },
+	'relatedaudiofilename' => { 152 => '1Name' },
+	'relatedaudiofiletype' => { 152 => '0Type' },
+	'relatedimagefileformat' => { 117 => 0x1000 },
+	'relatedimageheight' => { 117 => 0x1002 },
+	'relatedimagewidth' => { 117 => 0x1001 },
+	'relatedresourceid' => { 116 => [\'ResourceRelationship','ResourceRelationshipRelatedResourceID'] },
+	'relatedsoundfile' => { 117 => 0xa004, 473 => 'RelatedSoundFile' },
+	'relatedvideofile' => { 166 => 'data' },
+	'relatedvideofilename' => { 166 => '1Name' },
+	'relatedvideofiletype' => { 166 => '0Type' },
+	'relation' => { 470 => 'relation' },
+	'relationshipaccordingto' => { 116 => [\'ResourceRelationship','ResourceRelationshipRelationshipAccordingTo'] },
+	'relationshipestablisheddate' => { 116 => [\'ResourceRelationship','ResourceRelationshipRelationshipEstablishedDate'] },
+	'relationshipofresource' => { 116 => [\'ResourceRelationship','ResourceRelationshipRelationshipOfResource'] },
+	'relationshipremarks' => { 116 => [\'ResourceRelationship','ResourceRelationshipRelationshipRemarks'] },
+	'relativealtitude' => { 114 => 'RelativeAltitude' },
+	'relativepeakaudiofilepath' => { 493 => 'relativePeakAudioFilePath' },
+	'relativetimestamp' => { 493 => 'relativeTimestamp' },
+	'relativetimestampscale' => { 493 => [\'relativeTimestamp','relativeTimestampScale'] },
+	'relativetimestampvalue' => { 493 => [\'relativeTimestamp','relativeTimestampValue'] },
+	'releasebuttontousedial' => { 270 => '17.8', 271 => '18.5', 273 => '18.4', 274 => '18.4', 279 => '33.8', 280 => '17.6', 283 => '18.5', 284 => '18.4' },
+	'releasedate' => { 129 => 0x1e, 362 => 'rldt', 462 => 'ReleaseDate', 493 => 'releaseDate' },
+	'releasemode' => { 111 => 0x3001, 239 => 0x184d, 410 => 0xb049 },
+	'releasemode2' => { 418 => 0x112c, 419 => [0x112c,0x8], 420 => [0x1108,0x8], 421 => [0x1184,0x8], 422 => [0x1160,0x8], 423 => [0x4,0x1018], 424 => [0x4,0x210], 425 => [0x4,0x210], 426 => [0x4,0x208], 428 => [0x67,0x3f], 429 => [0x6b,0x6d,0x73,0x4b], 430 => [0x6b,0x4b], 431 => 0x10, 432 => 0x10, 433 => 0x9, 440 => 0x34 },
+	'releasemode3' => { 418 => 0x1128, 419 => 0x1128, 420 => 0x1104, 421 => 0x1180, 422 => 0x115c, 423 => 0x1014, 424 => 0x20c, 425 => 0x20c, 426 => 0x204 },
+	'releaseready' => { 479 => 'ReleaseReady' },
+	'releasesetting' => { 95 => 0x1016 },
+	'releasetime' => { 129 => 0x23, 462 => 'ReleaseTime' },
+	'remoteonduration' => { 272 => '3.4', 275 => '17.2', 276 => '18.2', 277 => '18.2', 278 => '18.2', 280 => '18.2', 281 => '4.3', 285 => '19.2' },
+	'renditionclass' => { 494 => 'RenditionClass' },
+	'renditionof' => { 494 => 'RenditionOf' },
+	'renditionofalternatepaths' => { 494 => [\'RenditionOf','RenditionOfAlternatePaths'] },
+	'renditionofdocumentid' => { 494 => [\'RenditionOf','RenditionOfDocumentID'] },
+	'renditionoffilepath' => { 494 => [\'RenditionOf','RenditionOfFilePath'] },
+	'renditionoffrompart' => { 494 => [\'RenditionOf','RenditionOfFromPart'] },
+	'renditionofinstanceid' => { 494 => [\'RenditionOf','RenditionOfInstanceID'] },
+	'renditionoflastmodifydate' => { 494 => [\'RenditionOf','RenditionOfLastModifyDate'] },
+	'renditionoflasturl' => { 494 => [\'RenditionOf','RenditionOfLastURL'] },
+	'renditionoflinkcategory' => { 494 => [\'RenditionOf','RenditionOfLinkCategory'] },
+	'renditionoflinkform' => { 494 => [\'RenditionOf','RenditionOfLinkForm'] },
+	'renditionofmanager' => { 494 => [\'RenditionOf','RenditionOfManager'] },
+	'renditionofmanagervariant' => { 494 => [\'RenditionOf','RenditionOfManagerVariant'] },
+	'renditionofmanageto' => { 494 => [\'RenditionOf','RenditionOfManageTo'] },
+	'renditionofmanageui' => { 494 => [\'RenditionOf','RenditionOfManageUI'] },
+	'renditionofmaskmarkers' => { 494 => [\'RenditionOf','RenditionOfMaskMarkers'] },
+	'renditionoforiginaldocumentid' => { 494 => [\'RenditionOf','RenditionOfOriginalDocumentID'] },
+	'renditionofpartmapping' => { 494 => [\'RenditionOf','RenditionOfPartMapping'] },
+	'renditionofplacedresolutionunit' => { 494 => [\'RenditionOf','RenditionOfPlacedResolutionUnit'] },
+	'renditionofplacedxresolution' => { 494 => [\'RenditionOf','RenditionOfPlacedXResolution'] },
+	'renditionofplacedyresolution' => { 494 => [\'RenditionOf','RenditionOfPlacedYResolution'] },
+	'renditionofrenditionclass' => { 494 => [\'RenditionOf','RenditionOfRenditionClass'] },
+	'renditionofrenditionparams' => { 494 => [\'RenditionOf','RenditionOfRenditionParams'] },
+	'renditionoftopart' => { 494 => [\'RenditionOf','RenditionOfToPart'] },
+	'renditionofversionid' => { 494 => [\'RenditionOf','RenditionOfVersionID'] },
+	'renditionparams' => { 494 => 'RenditionParams' },
+	'repeatingflashcount' => { 204 => 0xd, 205 => 0xe, 206 => 0xe, 207 => 0xe, 208 => 0xe, 279 => '17.2', 280 => '24.2', 281 => '9.2', 282 => '24.2', 285 => '25.2' },
+	'repeatingflashcountbuilt-in' => { 248 => 0x4db },
+	'repeatingflashcountexternal' => { 248 => 0x4c3 },
+	'repeatingflashoutput' => { 279 => '17.1', 280 => '24.1', 281 => '9.1', 282 => '24.1', 285 => '25.1' },
+	'repeatingflashoutputexternal' => { 248 => 0x4c0 },
+	'repeatingflashrate' => { 204 => 0xc, 205 => 0xd, 206 => 0xd, 207 => 0xd, 208 => 0xd, 279 => '18.1', 280 => '25.1', 281 => '10.1', 282 => '25.1', 285 => '26.1' },
+	'repeatingflashratebuilt-in' => { 248 => 0x4da },
+	'repeatingflashrateexternal' => { 248 => 0x4c2 },
+	'requirements' => { 370 => "\xa9req" },
+	'requires' => { 465 => 'requires' },
+	'resampleparams' => { 493 => 'resampleParams' },
+	'resampleparamsquality' => { 493 => [\'resampleParams','resampleParamsQuality'] },
+	'resamplingkerneldenominators050' => { 135 => 0xe50 },
+	'resamplingkerneldenominators067' => { 135 => 0xe4f },
+	'resamplingkerneldenominators100' => { 135 => 0xe51 },
+	'resaved' => { 386 => 0x21e },
+	'resetblacksegrows' => { 135 => 0x181a },
+	'resolution' => { 159 => 'Resolution' },
+	'resolutionmode' => { 387 => [0x87,0x4] },
+	'resolutionunit' => { 117 => 0x128, 132 => 0x2, 489 => 'ResolutionUnit' },
+	'resourceid' => { 116 => [\'ResourceRelationship','ResourceRelationshipResourceID'] },
+	'resourcerelationship' => { 116 => 'ResourceRelationship' },
+	'resourcerelationshipid' => { 116 => [\'ResourceRelationship','ResourceRelationshipResourceRelationshipID'] },
+	'restrictdrivemodes' => { 82 => 0x612 },
+	'restrictions' => { 486 => 'restrictions' },
+	'retouchareafeather' => { 467 => [\'RetouchAreas','RetouchAreasFeather'], 469 => [\'RetouchAreas','RetouchAreasFeather'] },
+	'retouchareamaskalpha' => { 467 => [\'RetouchAreas','RetouchAreasMasksAlpha'], 469 => [\'RetouchAreas','RetouchAreasMasksAlpha'] },
+	'retouchareamaskangle' => { 467 => [\'RetouchAreas','RetouchAreasMasksAngle'], 469 => [\'RetouchAreas','RetouchAreasMasksAngle'] },
+	'retouchareamaskbottom' => { 467 => [\'RetouchAreas','RetouchAreasMasksBottom'], 469 => [\'RetouchAreas','RetouchAreasMasksBottom'] },
+	'retouchareamaskcentervalue' => { 467 => [\'RetouchAreas','RetouchAreasMasksCenterValue'], 469 => [\'RetouchAreas','RetouchAreasMasksCenterValue'] },
+	'retouchareamaskcenterweight' => { 467 => [\'RetouchAreas','RetouchAreasMasksCenterWeight'], 469 => [\'RetouchAreas','RetouchAreasMasksCenterWeight'] },
+	'retouchareamaskdabs' => { 467 => [\'RetouchAreas','RetouchAreasMasksDabs'], 469 => [\'RetouchAreas','RetouchAreasMasksDabs'] },
+	'retouchareamaskfeather' => { 467 => [\'RetouchAreas','RetouchAreasMasksFeather'], 469 => [\'RetouchAreas','RetouchAreasMasksFeather'] },
+	'retouchareamaskflipped' => { 467 => [\'RetouchAreas','RetouchAreasMasksFlipped'], 469 => [\'RetouchAreas','RetouchAreasMasksFlipped'] },
+	'retouchareamaskflow' => { 467 => [\'RetouchAreas','RetouchAreasMasksFlow'], 469 => [\'RetouchAreas','RetouchAreasMasksFlow'] },
+	'retouchareamaskfullx' => { 467 => [\'RetouchAreas','RetouchAreasMasksFullX'], 469 => [\'RetouchAreas','RetouchAreasMasksFullX'] },
+	'retouchareamaskfully' => { 467 => [\'RetouchAreas','RetouchAreasMasksFullY'], 469 => [\'RetouchAreas','RetouchAreasMasksFullY'] },
+	'retouchareamaskleft' => { 467 => [\'RetouchAreas','RetouchAreasMasksLeft'], 469 => [\'RetouchAreas','RetouchAreasMasksLeft'] },
+	'retouchareamaskmidpoint' => { 467 => [\'RetouchAreas','RetouchAreasMasksMidpoint'], 469 => [\'RetouchAreas','RetouchAreasMasksMidpoint'] },
+	'retouchareamaskperimetervalue' => { 467 => [\'RetouchAreas','RetouchAreasMasksPerimeterValue'], 469 => [\'RetouchAreas','RetouchAreasMasksPerimeterValue'] },
+	'retouchareamaskradius' => { 467 => [\'RetouchAreas','RetouchAreasMasksRadius'], 469 => [\'RetouchAreas','RetouchAreasMasksRadius'] },
+	'retouchareamaskright' => { 467 => [\'RetouchAreas','RetouchAreasMasksRight'], 469 => [\'RetouchAreas','RetouchAreasMasksRight'] },
+	'retouchareamaskroundness' => { 467 => [\'RetouchAreas','RetouchAreasMasksRoundness'], 469 => [\'RetouchAreas','RetouchAreasMasksRoundness'] },
+	'retouchareamasks' => { 467 => [\'RetouchAreas','RetouchAreasMasks'], 469 => [\'RetouchAreas','RetouchAreasMasks'] },
+	'retouchareamasksizex' => { 467 => [\'RetouchAreas','RetouchAreasMasksSizeX'], 469 => [\'RetouchAreas','RetouchAreasMasksSizeX'] },
+	'retouchareamasksizey' => { 467 => [\'RetouchAreas','RetouchAreasMasksSizeY'], 469 => [\'RetouchAreas','RetouchAreasMasksSizeY'] },
+	'retouchareamasktop' => { 467 => [\'RetouchAreas','RetouchAreasMasksTop'], 469 => [\'RetouchAreas','RetouchAreasMasksTop'] },
+	'retouchareamaskvalue' => { 467 => [\'RetouchAreas','RetouchAreasMasksMaskValue'], 469 => [\'RetouchAreas','RetouchAreasMasksMaskValue'] },
+	'retouchareamaskversion' => { 467 => [\'RetouchAreas','RetouchAreasMasksVersion'], 469 => [\'RetouchAreas','RetouchAreasMasksVersion'] },
+	'retouchareamaskwhat' => { 467 => [\'RetouchAreas','RetouchAreasMasksWhat'], 469 => [\'RetouchAreas','RetouchAreasMasksWhat'] },
+	'retouchareamaskx' => { 467 => [\'RetouchAreas','RetouchAreasMasksX'], 469 => [\'RetouchAreas','RetouchAreasMasksX'] },
+	'retouchareamasky' => { 467 => [\'RetouchAreas','RetouchAreasMasksY'], 469 => [\'RetouchAreas','RetouchAreasMasksY'] },
+	'retouchareamaskzerox' => { 467 => [\'RetouchAreas','RetouchAreasMasksZeroX'], 469 => [\'RetouchAreas','RetouchAreasMasksZeroX'] },
+	'retouchareamaskzeroy' => { 467 => [\'RetouchAreas','RetouchAreasMasksZeroY'], 469 => [\'RetouchAreas','RetouchAreasMasksZeroY'] },
+	'retouchareamethod' => { 467 => [\'RetouchAreas','RetouchAreasMethod'], 469 => [\'RetouchAreas','RetouchAreasMethod'] },
+	'retouchareaoffsety' => { 467 => [\'RetouchAreas','RetouchAreasOffsetY'], 469 => [\'RetouchAreas','RetouchAreasOffsetY'] },
+	'retouchareaopacity' => { 467 => [\'RetouchAreas','RetouchAreasOpacity'], 469 => [\'RetouchAreas','RetouchAreasOpacity'] },
+	'retouchareas' => { 467 => 'RetouchAreas', 469 => 'RetouchAreas' },
+	'retouchareaseed' => { 467 => [\'RetouchAreas','RetouchAreasSeed'], 469 => [\'RetouchAreas','RetouchAreasSeed'] },
+	'retouchareasourcestate' => { 467 => [\'RetouchAreas','RetouchAreasSourceState'], 469 => [\'RetouchAreas','RetouchAreasSourceState'] },
+	'retouchareasourcex' => { 467 => [\'RetouchAreas','RetouchAreasSourceX'], 469 => [\'RetouchAreas','RetouchAreasSourceX'] },
+	'retouchareaspottype' => { 467 => [\'RetouchAreas','RetouchAreasSpotType'], 469 => [\'RetouchAreas','RetouchAreasSpotType'] },
+	'retouchhistory' => { 221 => 0x9e },
+	'retouchinfo' => { 467 => 'RetouchInfo', 469 => 'RetouchInfo' },
+	'retouchnefprocessing' => { 228 => 0x5 },
+	'retractlensonpoweroff' => { 82 => 0x814 },
+	'reuse' => { 297 => 'Reuse' },
+	'reuseallowed' => { 496 => 'ReuseAllowed' },
+	'reuseprohibited' => { 486 => 'reuseProhibited' },
+	'reverseexposurecompdial' => { 277 => '5.2' },
+	'reverseindicators' => { 270 => '12.1', 271 => '6.1', 273 => '6.1', 274 => '6.1', 275 => '4.3', 276 => '5.2', 277 => '5.4', 279 => '33.5', 280 => '5.1', 283 => '6.1', 284 => '6.1', 285 => '6.2' },
+	'reverseshutterspeedaperture' => { 277 => '5.3' },
+	'revision' => { 471 => 'revision' },
+	'rflensmffocusringsensitivity' => { 82 => 0x714 },
+	'rflenstype' => { 56 => 0x3d },
+	'rgbcurvelimits' => { 106 => 0x238 },
+	'rgbcurvepoints' => { 105 => 0x7, 106 => 0x20e },
+	'richtextcomment' => { 476 => 'RichTextComment' },
+	'ricohdate' => { 376 => 0x6 },
+	'ricohimageheight' => { 376 => 0x2 },
+	'ricohimagewidth' => { 376 => 0x0 },
+	'rightalbedo' => { 458 => 'RightAlbedo' },
+	'rightascension' => { 162 => 'RightAscension' },
+	'rights' => { 470 => 'rights' },
+	'rightsagent' => { 486 => 'rightsAgent' },
+	'rightsowner' => { 486 => 'rightsOwner' },
+	'roll' => { 113 => 0x8, 370 => ['roll',"\xa9frl"] },
+	'rollangle' => { 239 => 0x350b, 240 => 0x2c24, 244 => 0xc21a, 249 => 0x36f4, 250 => 0x2efb, 252 => 0xce32, 287 => 0x903, 310 => 0x90, 344 => 0x1, 382 => 0x2 },
+	'romoperationmode' => { 95 => 0x80d },
+	'rotation' => { 30 => 0x17, 31 => 0x18, 94 => 0x3, 101 => 0x10002, 106 => 0x26e, 112 => 'QuickTime-Rotation', 121 => 0x4, 162 => 'Rotation', 178 => [0x65,0x50], 179 => 0x46, 180 => 0x5a, 183 => 0x10, 239 => 0x3693, 240 => 0xca, 247 => '590.1', 263 => 0x76a43207, 310 => 0x30, 326 => '17.2', 356 => 0xd8, 363 => 'irot', 397 => 0x3f, 398 => 0x3f, 408 => 0x10 },
+	'routedto' => { 475 => 'RoutedTo' },
+	'routing' => { 361 => 'Routing' },
+	'routingdestinations' => { 457 => 'RoutingDestinations' },
+	'routingexclusions' => { 457 => 'RoutingExclusions' },
+	'routingnotes' => { 475 => 'RoutingNotes' },
+	'rowsperstrip' => { 117 => 0x116 },
+	'rpp' => { 462 => 'rpp' },
+	'rtkflag' => { 114 => 'RtkFlag' },
+	'rtkstdhgt' => { 114 => 'RtkStdHgt' },
+	'rtkstdlat' => { 114 => 'RtkStdLat' },
+	'rtkstdlon' => { 114 => 'RtkStdLon' },
+	'safetyshift' => { 82 => 0x108 },
+	'safetyshiftinavortv' => { 80 => 0x10, 81 => 0x10, 83 => 0xf, 84 => 0x10, 87 => 0x10 },
+	'sameexposurefornewaperture' => { 82 => 0x112 },
+	'samplebits' => { 152 => 'SampleBits' },
+	'samplepagerange' => { 483 => 'samplePageRange' },
+	'samplerate' => { 152 => 'SampleRate' },
+	'samplesperpixel' => { 117 => 0x115, 315 => 0x8, 489 => 'SamplesPerPixel' },
+	'samplestructure' => { 131 => 0x5a },
+	'samsungmodelid' => { 384 => 0x3 },
+	'sanyoquality' => { 386 => 0x201 },
+	'sanyothumbnail' => { 386 => 0x100 },
+	'saturation' => { 10 => 0x6e, 12 => 0x76, 34 => 0xe, 50 => 0x1, 110 => 0xd, 111 => [0x3013,0x1f], 117 => [0xa409,0xfe55], 125 => 0x1003, 153 => 'Saturation', 177 => 0x1f, 178 => 0x32, 179 => 0x28, 180 => 0x1a, 185 => 0x1, 221 => 0xaa, 223 => 0x35, 224 => 0x3b, 225 => 0x43, 310 => 0x40, 312 => 0x300d, 345 => 0x1f, 352 => 0xd, 371 => 0x27, 373 => 0x58, 376 => 0x28, 377 => 0x1013, 387 => 0x10, 397 => 0x1e, 398 => 0x1b, 410 => 0x2005, 467 => 'Saturation', 469 => 'Saturation', 473 => 'Saturation' },
+	'saturationadj' => { 101 => 0x20901, 106 => 0x116, 221 => 0x94, 262 => 0x1, 266 => 0x2e, 444 => 0x8016 },
+	'saturationadjustmentaqua' => { 467 => 'SaturationAdjustmentAqua', 469 => 'SaturationAdjustmentAqua' },
+	'saturationadjustmentblue' => { 467 => 'SaturationAdjustmentBlue', 469 => 'SaturationAdjustmentBlue' },
+	'saturationadjustmentgreen' => { 467 => 'SaturationAdjustmentGreen', 469 => 'SaturationAdjustmentGreen' },
+	'saturationadjustmentmagenta' => { 467 => 'SaturationAdjustmentMagenta', 469 => 'SaturationAdjustmentMagenta' },
+	'saturationadjustmentorange' => { 467 => 'SaturationAdjustmentOrange', 469 => 'SaturationAdjustmentOrange' },
+	'saturationadjustmentpurple' => { 467 => 'SaturationAdjustmentPurple', 469 => 'SaturationAdjustmentPurple' },
+	'saturationadjustmentred' => { 467 => 'SaturationAdjustmentRed', 469 => 'SaturationAdjustmentRed' },
+	'saturationadjustmentyellow' => { 467 => 'SaturationAdjustmentYellow', 469 => 'SaturationAdjustmentYellow' },
+	'saturationauto' => { 69 => 0x98 },
+	'saturationfaithful' => { 19 => 0xfe, 68 => 0x68, 69 => 0x68 },
+	'saturationlandscape' => { 19 => 0xfc, 68 => 0x38, 69 => 0x38 },
+	'saturationmonochrome' => { 68 => 0x80, 69 => 0x80 },
+	'saturationneutral' => { 19 => 0xfd, 68 => 0x50, 69 => 0x50 },
+	'saturationportrait' => { 19 => 0xfb, 68 => 0x20, 69 => 0x20 },
+	'saturationsetting' => { 295 => 0x1010, 399 => 0x11, 415 => 0x9 },
+	'saturationstandard' => { 19 => 0xfa, 68 => 0x8, 69 => 0x8 },
+	'saturationuserdef1' => { 19 => 0x100, 68 => 0x98, 69 => 0xb0 },
+	'saturationuserdef2' => { 19 => 0x101, 68 => 0xb0, 69 => 0xc8 },
+	'saturationuserdef3' => { 19 => 0x102, 68 => 0xc8, 69 => 0xe0 },
+	'saveid' => { 494 => 'SaveID' },
+	'sbaanalysiscomplete' => { 135 => 0xc35 },
+	'sbablack' => { 135 => 0xc25 },
+	'sbagmoffset' => { 135 => 0xc4a },
+	'sbagray' => { 135 => 0xc26 },
+	'sbagreenmagentabal' => { 135 => 0xc33 },
+	'sbahighgray' => { 135 => 0xc46 },
+	'sbailloffset' => { 135 => 0xc49 },
+	'sbailluminantbal' => { 135 => 0xc34 },
+	'sbalowgray' => { 135 => 0xc47 },
+	'sbaneutralbal' => { 135 => 0xc32 },
+	'sbawhite' => { 135 => 0xc27 },
+	'scaletype' => { 493 => 'scaleType' },
+	'scanimageenhancer' => { 229 => 0x60 },
+	'scanningdirection' => { 131 => 0x64 },
+	'scene' => { 370 => 'scen', 478 => 'Scene', 493 => 'scene' },
+	'scenearea' => { 290 => 0x211, 292 => 0x1031 },
+	'sceneassist' => { 221 => 0x9c },
+	'scenecapturetype' => { 117 => 0xa406, 473 => 'SceneCaptureType' },
+	'scenedetect' => { 290 => 0x210, 292 => 0x1030 },
+	'scenedetectdata' => { 290 => 0x212, 292 => 0x1033 },
+	'scenemode' => { 139 => 0xfa02, 182 => 0x100, 221 => 0x8f, 287 => 0x509, 292 => 0x403, 310 => 0x8001, 319 => 0xf, 410 => 0xb023 },
+	'scenemodeused' => { 141 => [0x6002,0xf002] },
+	'scenerecognition' => { 125 => 0x1425 },
+	'sceneselect' => { 386 => 0x21f },
+	'scenetype' => { 117 => 0xa301, 473 => 'SceneType' },
+	'screentips' => { 270 => '12.7', 271 => '5.3', 279 => '13.1', 280 => '4.4', 283 => '5.4', 285 => '5.1' },
+	'scriptversion' => { 135 => 0x1770 },
+	'season' => { 479 => 'Season', 482 => 'season' },
+	'seasonidentifier' => { 479 => [\'Season','SeasonIdentifier'] },
+	'seasonname' => { 479 => [\'Season','SeasonName'] },
+	'seasonnumber' => { 479 => [\'Season','SeasonNumber'] },
+	'secondaryftp' => { 457 => 'SecondaryFTP' },
+	'secondaryslotfunction' => { 239 => 0x1d0, 249 => 0x1d0 },
+	'section' => { 483 => 'section' },
+	'securityclassification' => { 117 => 0x9212 },
+	'selectableafpoint' => { 82 => 0x509 },
+	'selectafareaselectionmode' => { 2 => 0xc },
+	'selectafareaselectmode' => { 82 => 0x512 },
+	'selfdata' => { 114 => 'SelfData' },
+	'selftimer' => { 34 => 0x2, 310 => 0x2e, 386 => 0x214, 418 => 0x1134, 419 => 0x1134, 420 => 0x1110, 421 => 0x118c, 422 => 0x1168, 423 => 0x1020, 424 => 0x218, 425 => 0x218, 426 => 0x210 },
+	'selftimer2' => { 75 => 0x1d },
+	'selftimerinterval' => { 280 => '19.2' },
+	'selftimermode' => { 117 => 0x882b },
+	'selftimershotcount' => { 271 => '20.2', 273 => '20.3', 274 => '20.3', 275 => '18.2', 276 => '19.2', 277 => '19.2', 278 => '19.3', 280 => '19.3', 283 => '20.3', 284 => '20.3', 285 => '20.2' },
+	'selftimershotinterval' => { 271 => '20.3', 273 => '20.2', 274 => '20.2', 278 => '19.2', 283 => '20.2', 284 => '20.2' },
+	'selftimertime' => { 95 => 0x1806, 180 => 0x1f, 270 => '18.1', 271 => '20.1', 272 => '3.3', 273 => '20.1', 274 => '20.1', 275 => '18.1', 276 => '19.1', 277 => '19.1', 278 => '19.1', 279 => '7.2', 280 => '19.1', 281 => '3.3', 283 => '20.1', 284 => '20.1', 285 => '20.1' },
+	'sellingagency' => { 483 => 'sellingAgency' },
+	'seminfo' => { 117 => 0x8546 },
+	'sensingmethod' => { 117 => 0xa217, 473 => 'SensingMethod' },
+	'sensitivityadjust' => { 345 => 0x40 },
+	'sensitivitysteps' => { 326 => ['14.3','17.4'], 328 => 0x1 },
+	'sensitivitytype' => { 117 => 0x8830, 474 => 'SensitivityType' },
+	'sensor' => { 187 => 0x665e },
+	'sensorarea' => { 292 => 0x400 },
+	'sensorareas' => { 384 => 0xa010 },
+	'sensorbitdepth' => { 312 => 0x312d },
+	'sensorbluelevel' => { 72 => 0x5 },
+	'sensorcalibration' => { 291 => 0x805 },
+	'sensorcleaning' => { 88 => 0xd },
+	'sensorfullheight' => { 134 => 0xf904 },
+	'sensorfullwidth' => { 134 => 0xf903 },
+	'sensorheight' => { 134 => 0xf901, 139 => 0xfa21, 184 => 0x8, 312 => 0x312c, 354 => 0x109, 377 => 0x1602 },
+	'sensorimageheight' => { 135 => 0x3ee },
+	'sensorimagewidth' => { 135 => 0x3ed },
+	'sensorleftborder' => { 135 => 0x3eb },
+	'sensorleftmargin' => { 354 => 0x10a },
+	'sensorpixelsize' => { 221 => 0x9a },
+	'sensorredlevel' => { 72 => 0x4 },
+	'sensorserialnumber' => { 135 => 0x9ce },
+	'sensorsize' => { 153 => 'SensorSize', 345 => 0x35 },
+	'sensortemperature' => { 290 => 0x1500, 292 => 0x1007, 350 => 0xc, 354 => 0x210, 387 => [0x39,0x55] },
+	'sensortemperature2' => { 350 => 0xe, 354 => 0x211 },
+	'sensortopborder' => { 135 => 0x3ec },
+	'sensortopmargin' => { 354 => 0x10b },
+	'sensortype' => { 310 => 0xca },
+	'sensorwidth' => { 134 => 0xf900, 139 => 0xfa20, 184 => 0xa, 312 => 0x312b, 354 => 0x108, 377 => 0x1601 },
+	'sequence' => { 371 => 0x7, 372 => 0x35, 373 => 0x36 },
+	'sequencefilenumber' => { 419 => 0x4, 420 => 0x4, 421 => 0x4, 422 => 0x4, 431 => 0xc, 432 => 0xc, 433 => 0x1a },
+	'sequenceimagenumber' => { 419 => 0x0, 420 => 0x0, 421 => 0x0, 422 => 0x0, 431 => 0x8, 432 => 0x8, 433 => 0x12, 440 => 0x24 },
+	'sequencelength' => { 431 => 0x22, 432 => 0x1e, 433 => [0x16,0x1e] },
+	'sequencename' => { 482 => 'sequenceName' },
+	'sequencenumber' => { 75 => 0x9, 111 => 0x301c, 125 => 0x1101, 137 => 0x1d, 248 => 0x51c, 310 => 0x2b, 399 => [0x10c,0x30c], 410 => 0xb04a, 482 => 'sequenceNumber' },
+	'sequenceshotinterval' => { 386 => 0x224 },
+	'sequencetotalnumber' => { 482 => 'sequenceTotalNumber' },
+	'sequentialshot' => { 386 => 0x20e },
+	'serialnumber' => { 62 => 0xc, 95 => 0x180b, 117 => [0xa431,0xfde9], 134 => 0xfa04, 136 => 0xfa00, 138 => 0xc354, 139 => 0xfa19, 150 => 0x0, 153 => 'SerialNumber', 187 => 0x5501, 221 => [0xa0,0x1d], 288 => 0x101, 292 => [0x404,0x101a], 305 => 0x303, 307 => 0x305, 312 => 0x3103, 345 => 0x229, 354 => 0x102, 355 => 0x407, 370 => ['SNum','slno'], 371 => 0x15, 372 => 0x4b, 373 => 0x7e, 377 => 0x5, 384 => 0xa002, 387 => 0x2, 410 => 0x2031, 464 => 'SerialNumber', 474 => 'BodySerialNumber' },
+	'serialnumberformat' => { 62 => 0x15, 95 => 0x183b },
+	'serialnumberhash' => { 370 => 'CAME' },
+	'series' => { 479 => 'Series' },
+	'seriesdatetime' => { 446 => 'SeriesDateTime' },
+	'seriesdescription' => { 446 => 'SeriesDescription' },
+	'seriesidentifier' => { 479 => [\'Series','SeriesIdentifier'] },
+	'seriesmodality' => { 446 => 'SeriesModality' },
+	'seriesname' => { 479 => [\'Series','SeriesName'] },
+	'seriesnumber' => { 446 => 'SeriesNumber', 483 => 'seriesNumber' },
+	'seriestitle' => { 483 => 'seriesTitle' },
+	'serviceidentifier' => { 130 => 0x1e },
+	'servingsize' => { 485 => 'servingSize' },
+	'setbuttoncrosskeysfunc' => { 85 => 0x0, 86 => 0x0 },
+	'setbuttonwhenshooting' => { 80 => 0x1, 82 => 0x704, 88 => 0xc },
+	'setfunctionwhenshooting' => { 83 => 0x0, 84 => 0x1, 87 => 0x1 },
+	'setting' => { 482 => 'setting' },
+	'shadingcompensation' => { 287 => 0x50c, 310 => 0x8a },
+	'shadingcompensation2' => { 291 => 0x1012 },
+	'shadow' => { 387 => 0xe },
+	'shadowadj' => { 101 => 0x2030b },
+	'shadowcorrection' => { 345 => 0x79 },
+	'shadowprotection' => { 262 => 0x0 },
+	'shadows' => { 117 => 0xfe52, 461 => 'Shadows', 467 => 'Shadows', 469 => 'Shadows' },
+	'shadows2012' => { 467 => 'Shadows2012', 469 => 'Shadows2012' },
+	'shadowsadj' => { 444 => 0x901a },
+	'shadowscale' => { 117 => 0xc633 },
+	'shadowtint' => { 467 => 'ShadowTint', 469 => 'ShadowTint' },
+	'shadowtone' => { 125 => 0x1040 },
+	'shakereduction' => { 347 => 0x1, 348 => 0x1 },
+	'sharpendetail' => { 467 => 'SharpenDetail', 469 => 'SharpenDetail' },
+	'sharpenedgemasking' => { 467 => 'SharpenEdgeMasking', 469 => 'SharpenEdgeMasking' },
+	'sharpening' => { 312 => 0x300b },
+	'sharpeningadj' => { 266 => 0x2b },
+	'sharpeningkernel' => { 135 => 0x92f },
+	'sharpenradius' => { 467 => 'SharpenRadius', 469 => 'SharpenRadius' },
+	'sharpness' => { 8 => [0x42,0x48], 10 => 0x72, 12 => 0x74, 34 => 0xf, 72 => 0x2, 110 => 0xb, 111 => [0x3011,0x21], 117 => [0xa40a,0xfe56], 125 => 0x1001, 137 => 0x6b, 146 => 0x37, 153 => 'Sharpness', 177 => 0x21, 178 => 0x30, 179 => 0x26, 180 => 0x18, 185 => 0x3, 221 => 0x6, 223 => 0x32, 224 => 0x33, 225 => 0x39, 292 => 0x100f, 310 => 0x41, 345 => 0x21, 352 => 0xb, 371 => 0x26, 373 => 0x56, 376 => 0x22, 377 => [0x1003,0x1014], 387 => 0x11, 397 => 0x1c, 398 => 0x19, 410 => 0x2006, 440 => 0x52, 467 => 'Sharpness', 469 => 'Sharpness', 473 => 'Sharpness' },
+	'sharpnessadj' => { 101 => 0x20310, 106 => 0x25a, 444 => 0x801a },
+	'sharpnessadjon' => { 101 => '0x20310.0' },
+	'sharpnessauto' => { 69 => 0x94 },
+	'sharpnessfactor' => { 292 => 0x102a },
+	'sharpnessfaithful' => { 19 => 0xf5, 68 => 0x64, 69 => 0x64 },
+	'sharpnessfrequency' => { 8 => [0x41,0x47], 72 => 0x3 },
+	'sharpnesslandscape' => { 19 => 0xf3, 68 => 0x34, 69 => 0x34 },
+	'sharpnessmonochrome' => { 19 => 0xf6, 68 => 0x7c, 69 => 0x7c },
+	'sharpnessneutral' => { 19 => 0xf4, 68 => 0x4c, 69 => 0x4c },
+	'sharpnessovershoot' => { 444 => 0x801b },
+	'sharpnessportrait' => { 19 => 0xf2, 68 => 0x1c, 69 => 0x1c },
+	'sharpnesssetting' => { 287 => 0x506, 295 => 0x1013, 399 => 0x12, 415 => 0xa },
+	'sharpnessstandard' => { 19 => 0xf1, 68 => 0x4, 69 => 0x4 },
+	'sharpnessstrength' => { 101 => 0x20311 },
+	'sharpnessthreshold' => { 444 => 0x801d },
+	'sharpnessundershoot' => { 444 => 0x801c },
+	'sharpnessuserdef1' => { 19 => 0xf7, 68 => 0x94, 69 => 0xac },
+	'sharpnessuserdef2' => { 19 => 0xf8, 68 => 0xac, 69 => 0xc4 },
+	'sharpnessuserdef3' => { 19 => 0xf9, 68 => 0xc4, 69 => 0xdc },
+	'shiftcols' => { 135 => 0xc70 },
+	'shootid' => { 482 => 'shootID' },
+	'shootingdistance' => { 101 => 0x20701 },
+	'shootinginfodisplay' => { 270 => '13.2', 271 => '5.1', 279 => '10.2', 280 => '4.1', 283 => '5.1', 285 => '5.3' },
+	'shootinginfomonitorofftime' => { 270 => '26.2', 271 => '22.2', 273 => '22.2', 274 => '22.2', 278 => '21.2', 279 => '9.1', 280 => '21.2', 283 => '22.2', 284 => '22.2', 285 => '22.2' },
+	'shootingmode' => { 153 => 'ShootingMode', 221 => 0x89, 310 => 0x1f },
+	'shootingmodesetting' => { 272 => '5.1' },
+	'shortdescription' => { 471 => 'shortdescription' },
+	'shortdocumentid' => { 129 => 0xba },
+	'shortname' => { 467 => 'ShortName', 469 => 'ShortName' },
+	'shortownername' => { 19 => 0xac },
+	'shortreleasetimelag' => { 82 => 0x80d },
+	'shorttitle' => { 362 => '@sti' },
+	'shotdate' => { 493 => 'shotDate' },
+	'shotday' => { 493 => 'shotDay' },
+	'shotlocation' => { 493 => 'shotLocation' },
+	'shotname' => { 370 => 'shot', 493 => 'shotName' },
+	'shotnumber' => { 493 => 'shotNumber' },
+	'shotnumbersincepowerup' => { 414 => 0x44e, 431 => 0x1a, 432 => 0x16, 433 => 0xa },
+	'shotnumbersincepowerup2' => { 399 => 0x200 },
+	'shotsize' => { 493 => 'shotSize' },
+	'showmovement' => { 362 => 'shwm' },
+	'shownevent' => { 479 => 'EventExt' },
+	'showneventidentifier' => { 479 => [\'EventExt','EventExtIdentifier'] },
+	'showneventname' => { 479 => [\'EventExt','EventExtName'] },
+	'shutter' => { 428 => 0x20, 429 => 0x26, 430 => 0x26 },
+	'shutter-aelock' => { 80 => 0x4, 82 => 0x701, 83 => 0x3, 84 => 0x4, 85 => 0x3, 86 => 0x3, 87 => 0x4, 88 => 0x2 },
+	'shutteraelbutton' => { 81 => 0x4 },
+	'shutterbuttonafonbutton' => { 82 => 0x701 },
+	'shuttercount' => { 11 => 0x176, 56 => 0x1, 221 => 0xa7, 230 => [0x6a,0x157,0x24d], 231 => 0x286, 232 => 0x279, 233 => 0x284, 234 => 0x242, 235 => 0x280, 236 => 0x276, 237 => [0x27d,0x27f], 238 => 0x246, 241 => 0x2d6, 242 => 0x321, 243 => 0xbd8, 245 => 0x287, 246 => 0x320, 247 => 0x24a, 248 => 0x5fb, 251 => 0x2d5, 345 => 0x5d, 408 => 0x846, 413 => [0x125,0x14a], 428 => 0x32, 429 => 0x3a, 430 => 0x3a },
+	'shuttercount2' => { 428 => 0x4c, 429 => [0x50,0x52,0x58], 430 => 0x50 },
+	'shuttercount3' => { 428 => [0x1a0,0x1aa,0x1bd], 429 => [0x19f,0x1cb,0x1cd] },
+	'shuttercurtainsync' => { 80 => 0xf, 81 => 0xf, 82 => 0x305, 83 => 0xe, 84 => 0xf, 85 => 0x8, 86 => 0x8, 87 => 0xf, 88 => 0x8 },
+	'shuttermode' => { 137 => 0x1b, 221 => 0x34 },
+	'shutterreleasebuttonae-l' => { 270 => '17.7', 271 => '18.4', 273 => '78.4', 274 => '78.4', 275 => '16.1', 276 => '17.1', 277 => '17.1', 278 => '17.1', 279 => '7.1', 280 => '17.5', 283 => '18.4', 284 => '78.4', 285 => '18.2' },
+	'shutterreleasemethod' => { 95 => 0x1010 },
+	'shutterreleasenocfcard' => { 80 => 0x2, 81 => 0x2, 88 => 0xf },
+	'shutterreleasetiming' => { 95 => 0x1011 },
+	'shutterreleasewithoutlens' => { 82 => 0x711 },
+	'shutterspeedlock' => { 271 => '38.1', 273 => '38.1', 274 => '38.1', 283 => '38.1', 284 => '38.1' },
+	'shutterspeedrange' => { 82 => 0x10c },
+	'shutterspeedsetting' => { 180 => 0x6, 397 => 0x2f, 398 => 0x28, 399 => 0x0 },
+	'shutterspeedvalue' => { 91 => 0x1, 117 => 0x9201, 292 => 0x1000, 354 => 0x400, 473 => 'ShutterSpeedValue' },
+	'shuttertype' => { 125 => 0x1050, 310 => 0x9f, 345 => 0x87 },
+	'sidecarforextension' => { 481 => 'SidecarForExtension' },
+	'sigmaimpulseparameters' => { 135 => 0xe0d },
+	'sigmascalingfactorcamera' => { 135 => 0xe0c },
+	'sigmascalingfactorlowres' => { 135 => 0xe0b },
+	'sigmasizetable' => { 135 => 0xe0f },
+	'similarityindex' => { 129 => 0xe4 },
+	'singleframebracketing' => { 180 => 0x21 },
+	'skilllevel' => { 485 => 'skillLevel' },
+	'skintonecorrection' => { 345 => 0x95 },
+	'skiplinetime' => { 135 => 0x184e },
+	'slaveflashmeteringsegments' => { 345 => 0x20b },
+	'slideshowname' => { 482 => 'slideshowName' },
+	'slideshownumber' => { 482 => 'slideshowNumber' },
+	'slideshowtotalnumber' => { 482 => 'slideshowTotalNumber' },
+	'slowshutter' => { 75 => 0x8 },
+	'slowsync' => { 125 => 0x1030 },
+	'smartalbumcolor' => { 384 => 0x20 },
+	'smartrange' => { 384 => 0xa012 },
+	'smileshutter' => { 399 => 0x31 },
+	'smileshuttermode' => { 399 => 0x27 },
+	'smoothness' => { 117 => 0xfe57, 467 => 'Smoothness', 469 => 'Smoothness' },
+	'snapshot' => { 479 => 'SnapshotLink' },
+	'snapshotformat' => { 479 => [\'SnapshotLink','SnapshotLinkFormat'] },
+	'snapshotheightpixels' => { 479 => [\'SnapshotLink','SnapshotLinkHeightPixels'] },
+	'snapshotimagerole' => { 479 => [\'SnapshotLink','SnapshotLinkImageRole'] },
+	'snapshotlink' => { 479 => [\'SnapshotLink','SnapshotLinkLink'] },
+	'snapshotlinkqualifier' => { 479 => [\'SnapshotLink','SnapshotLinkLinkQualifier'] },
+	'snapshots' => { 462 => 'Snapshots' },
+	'snapshotusedvideoframe' => { 479 => [\'SnapshotLink','SnapshotLinkUsedVideoFrame'] },
+	'snapshotusedvideoframetimeformat' => { 479 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameTimeFormat'] },
+	'snapshotusedvideoframetimevalue' => { 479 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameTimeValue'] },
+	'snapshotusedvideoframevalue' => { 479 => [\'SnapshotLink','SnapshotLinkUsedVideoFrameValue'] },
+	'snapshotwidthpixels' => { 479 => [\'SnapshotLink','SnapshotLinkWidthPixels'] },
+	'softskineffect' => { 410 => 0x200f },
+	'software' => { 117 => 0x131, 154 => 'Software', 300 => 'Software', 354 => 0x203, 364 => 'software', 387 => 0x18, 452 => 'Software', 489 => 'Software' },
+	'softwareversion' => { 370 => ['@swr',"\xa9swr"], 386 => 0x207 },
+	'soloist' => { 362 => "\xa9sol" },
+	'songwriter' => { 370 => "\xa9swf" },
+	'songwriterkeywords' => { 370 => "\xa9swk" },
+	'sonycropsize' => { 117 => 0x74c8 },
+	'sonycroptopleft' => { 117 => 0x74c7 },
+	'sonydatetime' => { 417 => 0x6, 419 => 0x1b6, 420 => 0x210, 421 => 0x1fe, 422 => 0x22c },
+	'sonydatetime2' => { 428 => 0x51 },
+	'sonyexposuretime' => { 428 => 0x3a, 429 => 0x46, 430 => [0x66,0x46] },
+	'sonyexposuretime2' => { 440 => 0xe },
+	'sonyfnumber' => { 428 => 0x3c, 429 => 0x48, 430 => [0x68,0x48], 440 => 0x14 },
+	'sonyimageheight' => { 417 => 0x1a, 431 => 0x44, 432 => 0x3f, 433 => 0x47 },
+	'sonyimageheightmax' => { 440 => 0x40 },
+	'sonyimagesize' => { 180 => 0x3b, 397 => 0x54, 398 => 0x54, 399 => 0x9 },
+	'sonyimagewidth' => { 417 => 0x1c },
+	'sonyimagewidthmax' => { 440 => 0x3e },
+	'sonyiso' => { 419 => 0x1218, 420 => 0x11f4, 421 => 0x1270, 422 => [0x1254,0x1258,0x1280], 423 => 0x113c, 424 => 0x344, 425 => 0x346, 426 => 0x320, 440 => 0x4 },
+	'sonymaxaperture' => { 428 => 0x0, 429 => 0x0 },
+	'sonymaxaperturevalue' => { 440 => 0x16 },
+	'sonyminaperture' => { 428 => 0x1, 429 => 0x1 },
+	'sonymodelid' => { 410 => 0xb001 },
+	'sonyquality' => { 180 => 0x3c },
+	'sonytimeminsec' => { 429 => 0x61 },
+	'sortalbum' => { 362 => 'soal' },
+	'sortalbumartist' => { 362 => 'soaa' },
+	'sortartist' => { 362 => 'soar' },
+	'sortcomposer' => { 362 => 'soco' },
+	'sortname' => { 362 => 'sonm', 467 => 'SortName', 469 => 'SortName' },
+	'sortshow' => { 362 => 'sosn' },
+	'soundengineer' => { 362 => "\xa9sne" },
+	'source' => { 129 => 0x73, 300 => 'Source', 470 => 'source', 471 => 'source', 481 => 'Source' },
+	'sourcecount' => { 456 => 'SourceCount' },
+	'sourcecredits' => { 370 => "\xa9src" },
+	'sourcedirectoryindex' => { 332 => 0x0 },
+	'sourcefileindex' => { 332 => 0x2 },
+	'sourcephotoscount' => { 455 => 'SourcePhotosCount' },
+	'sourceprofileprefix' => { 135 => 0x1390 },
+	'spatialfrequencyresponse' => { 473 => 'SpatialFrequencyResponse' },
+	'spatialfrequencyresponsecolumns' => { 473 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseColumns'] },
+	'spatialfrequencyresponsenames' => { 473 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseNames'] },
+	'spatialfrequencyresponserows' => { 473 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseRows'] },
+	'spatialfrequencyresponsevalues' => { 473 => [\'SpatialFrequencyResponse','SpatialFrequencyResponseValues'] },
+	'speakerplacement' => { 493 => 'speakerPlacement' },
+	'specialeffectlevel' => { 111 => 0x3030 },
+	'specialeffectmode' => { 111 => 0x2076 },
+	'specialeffectsetting' => { 111 => 0x3031 },
+	'specialinstructions' => { 129 => 0x28 },
+	'specialmode' => { 292 => 0x200, 386 => 0x200 },
+	'specialoccasion' => { 485 => 'specialOccasion' },
+	'specialtypeid' => { 450 => 'SpecialTypeID' },
+	'spectralsensitivity' => { 117 => 0x8824, 473 => 'SpectralSensitivity' },
+	'specularwhitelevel' => { 41 => 0x32b, 44 => [0x2b9,0x2d0,0x2d4], 45 => 0x56a, 46 => 0x1e4, 47 => [0x1fd,0x2dd], 48 => [0x231,0x30f], 49 => 0x31d },
+	'speedx' => { 113 => 0x3, 370 => "\xa9xsp" },
+	'speedy' => { 113 => 0x4, 370 => "\xa9ysp" },
+	'speedz' => { 113 => 0x5, 370 => "\xa9zsp" },
+	'spherical' => { 456 => 'Spherical' },
+	'splitcolumn' => { 354 => 0x222 },
+	'splittoningbalance' => { 467 => 'SplitToningBalance', 469 => 'SplitToningBalance' },
+	'splittoninghighlighthue' => { 467 => 'SplitToningHighlightHue', 469 => 'SplitToningHighlightHue' },
+	'splittoninghighlightsaturation' => { 467 => 'SplitToningHighlightSaturation', 469 => 'SplitToningHighlightSaturation' },
+	'splittoningshadowhue' => { 467 => 'SplitToningShadowHue', 469 => 'SplitToningShadowHue' },
+	'splittoningshadowsaturation' => { 467 => 'SplitToningShadowSaturation', 469 => 'SplitToningShadowSaturation' },
+	'sport' => { 483 => 'sport' },
+	'spotfocuspointx' => { 177 => 0x2d },
+	'spotfocuspointy' => { 177 => 0x2e },
+	'spotmeteringmode' => { 34 => 0x27 },
+	'spotmeterlinktoafpoint' => { 82 => 0x107 },
+	'sractive' => { 326 => '17.1' },
+	'srawquality' => { 34 => 0x2e },
+	'srfocallength' => { 347 => 0x3 },
+	'srhalfpresstime' => { 347 => 0x2 },
+	'srresult' => { 347 => 0x0, 348 => 0x0 },
+	'stackedimage' => { 287 => 0x804 },
+	'standardmatrixcustom' => { 135 => 0x7d4 },
+	'standardmatrixdaylight' => { 135 => 0x7d0 },
+	'standardmatrixflash' => { 135 => 0x7d3 },
+	'standardmatrixfluorescent' => { 135 => 0x7d2 },
+	'standardmatrixtungsten' => { 135 => 0x7d1 },
+	'standardoutputhighlightpoint' => { 107 => 0x14 },
+	'standardoutputsensitivity' => { 117 => 0x8831, 474 => 'StandardOutputSensitivity' },
+	'standardoutputshadowpoint' => { 107 => 0x15 },
+	'standardrawcolortone' => { 107 => 0xd },
+	'standardrawcontrast' => { 107 => 0xf },
+	'standardrawhighlight' => { 107 => 0x75 },
+	'standardrawhighlightpoint' => { 107 => 0x12 },
+	'standardrawlinear' => { 107 => 0x10 },
+	'standardrawsaturation' => { 107 => 0xe },
+	'standardrawshadow' => { 107 => 0x7e },
+	'standardrawshadowpoint' => { 107 => 0x13 },
+	'standardrawsharpness' => { 107 => 0x11 },
+	'standardunsharpmaskfineness' => { 107 => 0x94 },
+	'standardunsharpmaskstrength' => { 107 => 0x92 },
+	'standardunsharpmaskthreshold' => { 107 => 0x96 },
+	'standardwhitecustom' => { 135 => 0x838 },
+	'standardwhitedaylight' => { 135 => 0x834 },
+	'standardwhiteflash' => { 135 => 0x837 },
+	'standardwhitefluorescent' => { 135 => 0x836 },
+	'standardwhitetungsten' => { 135 => 0x835 },
+	'standbytimer' => { 271 => '19.1', 273 => '19.1', 274 => '19.1', 277 => '18.1', 278 => '18.1', 283 => '19.1', 284 => '19.1' },
+	'startingpage' => { 483 => 'startingPage' },
+	'startmovieshooting' => { 82 => 0x70d },
+	'starttimecode' => { 370 => "\xa9TIM", 493 => 'startTimecode' },
+	'starttimecodetimeformat' => { 493 => [\'startTimecode','startTimecodeTimeFormat'] },
+	'starttimecodetimevalue' => { 493 => [\'startTimecode','startTimecodeTimeValue'] },
+	'starttimecodevalue' => { 493 => [\'startTimecode','startTimecodeValue'] },
+	'starttimesamplesize' => { 370 => "\xa9TSZ", 493 => 'startTimeSampleSize' },
+	'starttimescale' => { 370 => "\xa9TSC", 493 => 'startTimeScale' },
+	'state' => { 158 => 'State', 310 => 0x6b, 481 => 'State' },
+	'status' => { 448 => 'Status', 460 => 'Status' },
+	'stereomode' => { 456 => 'StereoMode' },
+	'stitched' => { 456 => 'Stitched' },
+	'stitchingsoftware' => { 455 => 'StitchingSoftware', 456 => 'StitchingSoftware' },
+	'stopsabovebaseiso' => { 418 => 0x113e, 419 => 0x113e, 420 => 0x111a, 421 => 0x1196, 422 => 0x1172, 423 => 0x102a, 424 => 0x222, 425 => 0x222, 426 => 0x217, 440 => 0xa },
+	'storagemethod' => { 184 => 0x12 },
+	'storebyorientation' => { 271 => '46.3', 273 => '47.3', 274 => '47.3', 283 => '47.3', 284 => '47.3' },
+	'storedescription' => { 362 => 'sdes' },
+	'storylineidentifier' => { 479 => 'StorylineIdentifier' },
+	'straightenangle' => { 263 => 0x2fc08431 },
+	'streamready' => { 479 => 'StreamReady' },
+	'streamtype' => { 173 => 'StreamType' },
+	'stretchmode' => { 493 => 'stretchMode' },
+	'studydatetime' => { 446 => 'StudyDateTime' },
+	'studydescription' => { 446 => 'StudyDescription' },
+	'studyid' => { 446 => 'StudyID' },
+	'studyphysician' => { 446 => 'StudyPhysician' },
+	'styleperiod' => { 479 => 'StylePeriod' },
+	'sub-location' => { 129 => 0x5c },
+	'subfiledata' => { 161 => 'data' },
+	'subfiledirectory' => { 161 => '1Directory' },
+	'subfilemimetype' => { 161 => '2MIME' },
+	'subfilename' => { 161 => '1Name' },
+	'subfileresource' => { 161 => 'rsrc' },
+	'subfiletype' => { 117 => 0xfe, 161 => '0Type' },
+	'subject' => { 296 => 'Subject', 361 => 'Subject', 470 => 'subject', 480 => 'Subject', 494 => 'subject' },
+	'subjectarea' => { 117 => 0x9214, 473 => 'SubjectArea' },
+	'subjectcode' => { 478 => 'SubjectCode' },
+	'subjectdistance' => { 117 => 0x9206, 137 => 0x3e, 473 => 'SubjectDistance' },
+	'subjectdistancerange' => { 117 => 0xa40c, 473 => 'SubjectDistanceRange' },
+	'subjectlocation' => { 117 => 0xa214, 473 => 'SubjectLocation' },
+	'subjectmotion' => { 273 => '78.2', 274 => '78.2', 284 => '78.2' },
+	'subjectprogram' => { 177 => 0x22 },
+	'subjectreference' => { 129 => 0xc },
+	'sublabels1' => { 477 => [\'TagStructure','TagStructureSubLabels'] },
+	'sublabels2' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabels'] },
+	'sublabels3' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabels'] },
+	'sublabels4' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabels'] },
+	'sublabels5' => { 477 => [\'TagStructure','TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabels'] },
+	'subseccreatedate' => { 112 => 'Exif-SubSecCreateDate' },
+	'subsecdatetimeoriginal' => { 112 => 'Exif-SubSecDateTimeOriginal' },
+	'subsecmodifydate' => { 112 => 'Exif-SubSecModifyDate' },
+	'subsectime' => { 117 => 0x9290 },
+	'subsectimedigitized' => { 117 => 0x9292 },
+	'subsectimeoriginal' => { 117 => 0x9291 },
+	'subsection1' => { 483 => 'subsection1' },
+	'subsection2' => { 483 => 'subsection2' },
+	'subsection3' => { 483 => 'subsection3' },
+	'subsection4' => { 483 => 'subsection4' },
+	'subselector' => { 271 => '49.1', 273 => '71.1', 274 => '71.1', 284 => '71.1' },
+	'subselectorassignment' => { 271 => '48.1' },
+	'subselectorcenter' => { 273 => '72.1', 274 => '72.1', 284 => '72.1' },
+	'subselectorplusdials' => { 271 => '49.2', 273 => '73.1', 274 => '73.1', 284 => '73.1' },
+	'subtitle' => { 362 => "\xa9st3", 370 => "\xa9snm", 483 => 'subtitle' },
+	'subtitlekeywords' => { 370 => "\xa9snk" },
+	'subversionfilename' => { 477 => [\'SubVersions','SubVersionsFileName'] },
+	'subversionreference' => { 477 => [\'SubVersions','SubVersionsVersRef'] },
+	'subversions' => { 477 => 'SubVersions' },
+	'superimposeddisplay' => { 80 => 0xa, 82 => 0x510, 83 => 0x9, 84 => 0xa, 87 => 0xa, 88 => 0xe },
+	'supermacro' => { 62 => 0x1a },
+	'supplementalcategories' => { 129 => 0x14, 481 => 'SupplementalCategories' },
+	'supplementaltype' => { 131 => 0x37 },
+	'supplementdisplayid' => { 483 => 'supplementDisplayID' },
+	'supplementstartingpage' => { 483 => 'supplementStartingPage' },
+	'supplementtitle' => { 483 => 'supplementTitle' },
+	'supplychainsource' => { 479 => 'SupplyChainSource' },
+	'supplychainsourceidentifier' => { 479 => [\'SupplyChainSource','SupplyChainSourceIdentifier'] },
+	'supplychainsourcename' => { 479 => [\'SupplyChainSource','SupplyChainSourceName'] },
+	'supportsamount' => { 467 => 'SupportsAmount', 469 => 'SupportsAmount' },
+	'supportscolor' => { 467 => 'SupportsColor', 469 => 'SupportsColor' },
+	'supportshighdynamicrange' => { 467 => 'SupportsHighDynamicRange', 469 => 'SupportsHighDynamicRange' },
+	'supportsmonochrome' => { 467 => 'SupportsMonochrome', 469 => 'SupportsMonochrome' },
+	'supportsnormaldynamicrange' => { 467 => 'SupportsNormalDynamicRange', 469 => 'SupportsNormalDynamicRange' },
+	'supportsoutputreferred' => { 467 => 'SupportsOutputReferred', 469 => 'SupportsOutputReferred' },
+	'supportsscenereferred' => { 467 => 'SupportsSceneReferred', 469 => 'SupportsSceneReferred' },
+	'svisosetting' => { 326 => 0x14 },
+	'swatchcoloranta' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsA'] },
+	'swatchcolorantb' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsB'] },
+	'swatchcolorantblack' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsBlack'] },
+	'swatchcolorantblue' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsBlue'] },
+	'swatchcolorantcyan' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsCyan'] },
+	'swatchcolorantgray' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsGray'] },
+	'swatchcolorantgreen' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsGreen'] },
+	'swatchcolorantl' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsL'] },
+	'swatchcolorantmagenta' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsMagenta'] },
+	'swatchcolorantmode' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsMode'] },
+	'swatchcolorantred' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsRed'] },
+	'swatchcolorantswatchname' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsSwatchName'] },
+	'swatchcoloranttint' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsTint'] },
+	'swatchcoloranttype' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsType'] },
+	'swatchcolorantyellow' => { 498 => [\'SwatchGroups','SwatchGroupsColorantsYellow'] },
+	'swatchgroupname' => { 498 => [\'SwatchGroups','SwatchGroupsGroupName'] },
+	'swatchgroups' => { 498 => 'SwatchGroups' },
+	'swatchgroupscolorants' => { 498 => [\'SwatchGroups','SwatchGroupsColorants'] },
+	'swatchgrouptype' => { 498 => [\'SwatchGroups','SwatchGroupsGroupType'] },
+	'sweeppanoramadirection' => { 310 => 0x93, 399 => 0x33 },
+	'sweeppanoramafieldofview' => { 310 => 0x94 },
+	'sweeppanoramasize' => { 399 => 0x32 },
+	'switchtoregisteredafpoint' => { 81 => 0x12, 82 => 0x50a },
+	'symlink' => { 118 => 'SymLink' },
+	'syncreleasemode' => { 273 => '77.1', 274 => '77.1', 284 => '77.1' },
+	'system' => { 354 => 0x204 },
+	'tagged' => { 356 => 0xdd, 357 => 'Tagged', 462 => 'tagged' },
+	'tagslist' => { 472 => 'TagsList' },
+	'tagstructure' => { 477 => 'TagStructure' },
+	'takenumber' => { 493 => 'takeNumber' },
+	'tapename' => { 493 => 'tapeName' },
+	'targetaperture' => { 75 => 0x4 },
+	'targetcompressionratio' => { 93 => 0x1 },
+	'targetdistancesetting' => { 95 => 0x1807 },
+	'targetexposuretime' => { 75 => 0x5 },
+	'targetimagetype' => { 95 => 0x100a },
+	'targetprinter' => { 117 => 0x151 },
+	'taxon' => { 116 => 'Taxon' },
+	'taxonacceptednameusage' => { 116 => [\'Taxon','TaxonAcceptedNameUsage'] },
+	'taxonacceptednameusageid' => { 116 => [\'Taxon','TaxonAcceptedNameUsageID'] },
+	'taxonclass' => { 116 => [\'Taxon','TaxonClass'] },
+	'taxonconceptid' => { 116 => [\'Taxon','TaxonTaxonConceptID'] },
+	'taxonfamily' => { 116 => [\'Taxon','TaxonFamily'] },
+	'taxongenus' => { 116 => [\'Taxon','TaxonGenus'] },
+	'taxonhigherclassification' => { 116 => [\'Taxon','TaxonHigherClassification'] },
+	'taxonid' => { 116 => [\'Taxon','TaxonTaxonID'] },
+	'taxoninfraspecificepithet' => { 116 => [\'Taxon','TaxonInfraspecificEpithet'] },
+	'taxonkingdom' => { 116 => [\'Taxon','TaxonKingdom'] },
+	'taxonnameaccordingto' => { 116 => [\'Taxon','TaxonNameAccordingTo'] },
+	'taxonnameaccordingtoid' => { 116 => [\'Taxon','TaxonNameAccordingToID'] },
+	'taxonnamepublishedin' => { 116 => [\'Taxon','TaxonNamePublishedIn'] },
+	'taxonnamepublishedinid' => { 116 => [\'Taxon','TaxonNamePublishedInID'] },
+	'taxonnamepublishedinyear' => { 116 => [\'Taxon','TaxonNamePublishedInYear'] },
+	'taxonnomenclaturalcode' => { 116 => [\'Taxon','TaxonNomenclaturalCode'] },
+	'taxonnomenclaturalstatus' => { 116 => [\'Taxon','TaxonNomenclaturalStatus'] },
+	'taxonorder' => { 116 => [\'Taxon','TaxonOrder'] },
+	'taxonoriginalnameusage' => { 116 => [\'Taxon','TaxonOriginalNameUsage'] },
+	'taxonoriginalnameusageid' => { 116 => [\'Taxon','TaxonOriginalNameUsageID'] },
+	'taxonparentnameusage' => { 116 => [\'Taxon','TaxonParentNameUsage'] },
+	'taxonparentnameusageid' => { 116 => [\'Taxon','TaxonParentNameUsageID'] },
+	'taxonphylum' => { 116 => [\'Taxon','TaxonPhylum'] },
+	'taxonrank' => { 116 => [\'Taxon','TaxonTaxonRank'] },
+	'taxonremarks' => { 116 => [\'Taxon','TaxonTaxonRemarks'] },
+	'taxonscientificname' => { 116 => [\'Taxon','TaxonScientificName'] },
+	'taxonscientificnameauthorship' => { 116 => [\'Taxon','TaxonScientificNameAuthorship'] },
+	'taxonscientificnameid' => { 116 => [\'Taxon','TaxonScientificNameID'] },
+	'taxonspecificepithet' => { 116 => [\'Taxon','TaxonSpecificEpithet'] },
+	'taxonsubgenus' => { 116 => [\'Taxon','TaxonSubgenus'] },
+	'taxontaxonomicstatus' => { 116 => [\'Taxon','TaxonTaxonomicStatus'] },
+	'taxonverbatimtaxonrank' => { 116 => [\'Taxon','TaxonVerbatimTaxonRank'] },
+	'taxonvernacularname' => { 116 => [\'Taxon','TaxonVernacularName'] },
+	'tda1bandwidth' => { 135 => 0x196f },
+	'tda1edgepolarity' => { 135 => 0x1971 },
+	'tda1gain' => { 135 => 0x1970 },
+	'tda1offset' => { 135 => 0x196e },
+	'tda2bandwidth' => { 135 => 0x1979 },
+	'tda2edgepolarity' => { 135 => 0x197b },
+	'tda2gain' => { 135 => 0x197a },
+	'tda2offset' => { 135 => 0x1978 },
+	'tda3bandwidth' => { 135 => 0x1983 },
+	'tda3edgepolarity' => { 135 => 0x1985 },
+	'tda3gain' => { 135 => 0x1984 },
+	'tda3offset' => { 135 => 0x1982 },
+	'tda4bandwidth' => { 135 => 0x198d },
+	'tda4edgepolarity' => { 135 => 0x198f },
+	'tda4gain' => { 135 => 0x198e },
+	'tda4offset' => { 135 => 0x198c },
+	'teaser' => { 483 => 'teaser' },
+	'teleconverter' => { 182 => 0x105, 410 => 0x105 },
+	'tempampgainx100' => { 135 => 0x1914 },
+	'tempo' => { 493 => 'tempo' },
+	'temporalcoverage' => { 479 => 'TemporalCoverage' },
+	'temporalcoveragefrom' => { 479 => [\'TemporalCoverage','TemporalCoverageTempCoverageFrom'] },
+	'temporalcoverageto' => { 479 => [\'TemporalCoverage','TemporalCoverageTempCoverageTo'] },
+	'termsandconditionstext' => { 297 => 'TermsAndConditionsText' },
+	'termsandconditionsurl' => { 297 => 'TermsAndConditionsURL' },
+	'testname' => { 118 => 'TestName' },
+	'textencoding' => { 220 => 0x4 },
+	'textlayername' => { 481 => [\'TextLayers','TextLayersLayerName'] },
+	'textlayers' => { 481 => 'TextLayers' },
+	'textlayertext' => { 481 => [\'TextLayers','TextLayersLayerText'] },
+	'textstamp' => { 310 => [0x8008,0x8009,0x3b,0x3e] },
+	'texture' => { 467 => 'Texture', 469 => 'Texture' },
+	'three-dtrackingfacedetection' => { 273 => '1.4', 274 => '1.4', 284 => '1.4' },
+	'three-dtrackingwatcharea' => { 273 => '78.1', 274 => '78.1', 284 => '78.1' },
+	'thresholding' => { 117 => 0x107 },
+	'thumbnailfilename' => { 95 => 0x817 },
+	'thumbnailformat' => { 491 => [\'Thumbnails','ThumbnailsFormat'] },
+	'thumbnailheight' => { 139 => 0xfa55, 491 => [\'Thumbnails','ThumbnailsHeight'] },
+	'thumbnailimage' => { 6 => 'CNDA', 95 => 0x2008, 112 => 'Exif-ThumbnailImage', 120 => 0x3, 164 => 'data', 292 => 0x100, 370 => 'thmb', 491 => [\'Thumbnails','ThumbnailsImage'] },
+	'thumbnailimagename' => { 164 => '1Name' },
+	'thumbnailimagesize' => { 164 => 'ImageSize' },
+	'thumbnailimagetype' => { 164 => '0Type' },
+	'thumbnailimagevalidarea' => { 62 => 0x13 },
+	'thumbnaillength' => { 117 => 0x202 },
+	'thumbnailoffset' => { 117 => 0x201 },
+	'thumbnailpng' => { 370 => 'thmb' },
+	'thumbnails' => { 491 => 'Thumbnails' },
+	'thumbnailwidth' => { 139 => 0xfa54, 491 => [\'Thumbnails','ThumbnailsWidth'] },
+	'ticker' => { 483 => 'ticker' },
+	'tiffhandling' => { 467 => 'TIFFHandling', 469 => 'TIFFHandling' },
+	'tiffmeteringimage' => { 183 => 0x104c, 408 => 0x1110 },
+	'tilelength' => { 117 => 0x143 },
+	'tilewidth' => { 117 => 0x142 },
+	'time' => { 135 => 0x401, 345 => 0x7 },
+	'timecodes' => { 117 => 0xc763 },
+	'timecreated' => { 129 => 0x3c, 137 => 0x14, 146 => 0x10, 357 => 'TimeCreated' },
+	'timelapseshotnumber' => { 313 => 0x10 },
+	'timeperiod' => { 483 => 'timePeriod' },
+	'timerfunctionbutton' => { 272 => '5.2', 275 => '12.1', 276 => '13.1' },
+	'timerlength' => { 82 => 0x80c },
+	'timerrecording' => { 310 => 0x96 },
+	'timescaleparams' => { 493 => 'timeScaleParams' },
+	'timescaleparamsframeoverlappingpercentage' => { 493 => [\'timeScaleParams','timeScaleParamsFrameOverlappingPercentage'] },
+	'timescaleparamsframesize' => { 493 => [\'timeScaleParams','timeScaleParamsFrameSize'] },
+	'timescaleparamsquality' => { 493 => [\'timeScaleParams','timeScaleParamsQuality'] },
+	'timesent' => { 130 => 0x50 },
+	'timeshot' => { 457 => 'TimeShot' },
+	'timesignature' => { 493 => 'timeSignature' },
+	'timesincepoweron' => { 310 => 0x29 },
+	'timestamp' => { 11 => 0x45e, 19 => 0x11c, 286 => 0x8, 300 => 'TimeStamp', 310 => 0xaf, 456 => 'Timestamp', 463 => 'Timestamp', 477 => 'TimeStamp' },
+	'timestamp1' => { 11 => 0x45a },
+	'timezone' => { 76 => 0x1, 255 => 0x0, 380 => 0xa },
+	'timezonecity' => { 76 => 0x2 },
+	'timezonecode' => { 98 => 0x1 },
+	'timezoneinfo' => { 98 => 0x2 },
+	'timezoneoffset' => { 117 => 0x882a },
+	'tint' => { 364 => 'player.movie.visual.tint', 467 => 'Tint', 469 => 'Tint' },
+	'title' => { 154 => 'Title', 296 => 'Title', 300 => 'Title', 310 => 0x65, 361 => 'Title', 362 => ['titl',"\xa9nam"], 364 => 'title', 370 => ['titl',"\xa9nam"], 470 => 'title', 480 => 'Title', 491 => 'Title' },
+	'togglestyleamount' => { 467 => 'ToggleStyleAmount', 469 => 'ToggleStyleAmount' },
+	'togglestyledigest' => { 467 => 'ToggleStyleDigest', 469 => 'ToggleStyleDigest' },
+	'tonecomp' => { 221 => 0x81 },
+	'tonecurve' => { 72 => 0x1, 345 => 0x402, 467 => 'ToneCurve', 469 => 'ToneCurve' },
+	'tonecurveactive' => { 106 => 0x110 },
+	'tonecurveadobergb' => { 384 => 0xa043 },
+	'tonecurveadobergbdefault' => { 384 => 0xa041 },
+	'tonecurveblue' => { 467 => 'ToneCurveBlue', 469 => 'ToneCurveBlue' },
+	'tonecurvebluex' => { 444 => 0x9003 },
+	'tonecurvebluey' => { 444 => 0x9007 },
+	'tonecurvebrightness' => { 101 => 0x20410 },
+	'tonecurvebrightnessx' => { 444 => 0x9000 },
+	'tonecurvebrightnessy' => { 444 => 0x9004 },
+	'tonecurvecolorspace' => { 105 => 0x0 },
+	'tonecurvecontrast' => { 101 => 0x20411 },
+	'tonecurvegreen' => { 467 => 'ToneCurveGreen', 469 => 'ToneCurveGreen' },
+	'tonecurvegreenx' => { 444 => 0x9002 },
+	'tonecurvegreeny' => { 444 => 0x9006 },
+	'tonecurveinputrange' => { 105 => 0x3 },
+	'tonecurveinterpolation' => { 106 => 0x159 },
+	'tonecurvemode' => { 106 => 0x113 },
+	'tonecurvename' => { 467 => 'ToneCurveName', 469 => 'ToneCurveName' },
+	'tonecurvename2012' => { 467 => 'ToneCurveName2012', 469 => 'ToneCurveName2012' },
+	'tonecurveoriginal' => { 101 => '0x20400.1' },
+	'tonecurveoutputrange' => { 105 => 0x5 },
+	'tonecurveprofilename' => { 135 => 0x1391 },
+	'tonecurveproperty' => { 106 => 0x3c },
+	'tonecurvepv2012' => { 467 => 'ToneCurvePV2012', 469 => 'ToneCurvePV2012' },
+	'tonecurvepv2012blue' => { 467 => 'ToneCurvePV2012Blue', 469 => 'ToneCurvePV2012Blue' },
+	'tonecurvepv2012green' => { 467 => 'ToneCurvePV2012Green', 469 => 'ToneCurvePV2012Green' },
+	'tonecurvepv2012red' => { 467 => 'ToneCurvePV2012Red', 469 => 'ToneCurvePV2012Red' },
+	'tonecurvered' => { 467 => 'ToneCurveRed', 469 => 'ToneCurveRed' },
+	'tonecurveredx' => { 444 => 0x9001 },
+	'tonecurveredy' => { 444 => 0x9005 },
+	'tonecurves' => { 345 => 0x403 },
+	'tonecurveshape' => { 105 => 0x1 },
+	'tonecurvesrgb' => { 384 => 0xa042 },
+	'tonecurvesrgbdefault' => { 384 => 0xa040 },
+	'tonecurvex' => { 105 => 0xa },
+	'tonecurvey' => { 105 => 0xb },
+	'tonelevel' => { 287 => 0x52e },
+	'tonemapstrength' => { 467 => 'ToneMapStrength', 469 => 'ToneMapStrength' },
+	'toningeffect' => { 56 => 0xf, 221 => 0xb3, 223 => 0x38, 224 => 0x40, 225 => 0x48, 377 => 0x1015 },
+	'toningeffectauto' => { 69 => 0xa4 },
+	'toningeffectfaithful' => { 68 => 0x74, 69 => 0x74 },
+	'toningeffectlandscape' => { 68 => 0x44, 69 => 0x44 },
+	'toningeffectmonochrome' => { 19 => 0x108, 68 => 0x8c, 69 => 0x8c },
+	'toningeffectneutral' => { 68 => 0x5c, 69 => 0x5c },
+	'toningeffectportrait' => { 68 => 0x2c, 69 => 0x2c },
+	'toningeffectstandard' => { 68 => 0x14, 69 => 0x14 },
+	'toningeffectuserdef1' => { 68 => 0xa4, 69 => 0xbc },
+	'toningeffectuserdef2' => { 68 => 0xbc, 69 => 0xd4 },
+	'toningeffectuserdef3' => { 68 => 0xd4, 69 => 0xec },
+	'toningsaturation' => { 223 => 0x39, 224 => 0x41, 225 => 0x49 },
+	'totalzoom' => { 137 => 0x62 },
+	'touchae' => { 310 => 0xab },
+	'track' => { 362 => "\xa9trk", 370 => "\xa9trk" },
+	'trackcreatedate' => { 369 => 0x1 },
+	'trackmodifydate' => { 369 => 0x2 },
+	'tracknumber' => { 362 => 'trkn', 493 => 'trackNumber' },
+	'tracks' => { 493 => 'Tracks' },
+	'tracksframerate' => { 493 => [\'Tracks','TracksFrameRate'] },
+	'tracksmarkers' => { 493 => [\'Tracks','TracksMarkers'] },
+	'tracksmarkerscomment' => { 493 => [\'Tracks','TracksMarkersComment'] },
+	'tracksmarkerscuepointparams' => { 493 => [\'Tracks','TracksMarkersCuePointParams'] },
+	'tracksmarkerscuepointparamskey' => { 493 => [\'Tracks','TracksMarkersCuePointParamsKey'] },
+	'tracksmarkerscuepointparamsvalue' => { 493 => [\'Tracks','TracksMarkersCuePointParamsValue'] },
+	'tracksmarkerscuepointtype' => { 493 => [\'Tracks','TracksMarkersCuePointType'] },
+	'tracksmarkersduration' => { 493 => [\'Tracks','TracksMarkersDuration'] },
+	'tracksmarkerslocation' => { 493 => [\'Tracks','TracksMarkersLocation'] },
+	'tracksmarkersname' => { 493 => [\'Tracks','TracksMarkersName'] },
+	'tracksmarkersprobability' => { 493 => [\'Tracks','TracksMarkersProbability'] },
+	'tracksmarkersspeaker' => { 493 => [\'Tracks','TracksMarkersSpeaker'] },
+	'tracksmarkersstarttime' => { 493 => [\'Tracks','TracksMarkersStartTime'] },
+	'tracksmarkerstarget' => { 493 => [\'Tracks','TracksMarkersTarget'] },
+	'tracksmarkerstype' => { 493 => [\'Tracks','TracksMarkersType'] },
+	'trackstrackname' => { 493 => [\'Tracks','TracksTrackName'] },
+	'trackstracktype' => { 493 => [\'Tracks','TracksTrackType'] },
+	'tracktype' => { 370 => 'kgtt' },
+	'trailer' => { 118 => 'Trailer' },
+	'trailersignature' => { 161 => 'zmie' },
+	'transcript' => { 479 => 'Transcript' },
+	'transcriptlink' => { 479 => 'TranscriptLink' },
+	'transcriptlinklink' => { 479 => [\'TranscriptLink','TranscriptLinkLink'] },
+	'transcriptlinklinkqualifier' => { 479 => [\'TranscriptLink','TranscriptLinkLinkQualifier'] },
+	'transferfunction' => { 117 => 0x12d, 489 => 'TransferFunction' },
+	'transfertimenormal' => { 135 => 0x1888 },
+	'transfertimetest' => { 135 => 0x1889 },
+	'transform' => { 310 => [0x8012,0x59] },
+	'transmissionreference' => { 481 => 'TransmissionReference' },
+	'trapped' => { 296 => 'Trapped', 480 => 'Trapped' },
+	'trashbuttonfunction' => { 82 => 0x710 },
+	'travelday' => { 310 => 0x36 },
+	'trebel' => { 364 => 'player.movie.audio.treble' },
+	'triggermode' => { 371 => 0x6, 372 => 0x34, 373 => 0x34 },
+	'tstop' => { 117 => 0xc772 },
+	'ttl_da_adown' => { 333 => 0x5 },
+	'ttl_da_aup' => { 333 => 0x4 },
+	'ttl_da_bdown' => { 333 => 0x7 },
+	'ttl_da_bup' => { 333 => 0x6 },
+	'tungstenawb' => { 323 => 0x1 },
+	'tvepisode' => { 362 => 'tves' },
+	'tvepisodeid' => { 362 => 'tven' },
+	'tvexposuretimesetting' => { 326 => 0x12 },
+	'tvnetworkname' => { 362 => 'tvnn' },
+	'tvseason' => { 362 => 'tvsn' },
+	'tvshow' => { 362 => 'tvsh' },
+	'type' => { 470 => 'type', 488 => 'type' },
+	'typestatus' => { 116 => [\'Identification','IdentificationTypeStatus'] },
+	'uniquecameramodel' => { 117 => 0xc614 },
+	'uniquedocumentid' => { 129 => 0xbb },
+	'uniquematrixauto' => { 135 => 0x7e9 },
+	'uniquematrixcustom' => { 135 => 0x7e8 },
+	'uniquematrixdaylight' => { 135 => 0x7e4 },
+	'uniquematrixflash' => { 135 => 0x7e7 },
+	'uniquematrixfluorescent' => { 135 => 0x7e6 },
+	'uniquematrixtungsten' => { 135 => 0x7e5 },
+	'uniqueobjectname' => { 130 => 0x64 },
+	'units' => { 452 => 'Units' },
+	'unknown_aacr' => { 362 => 'AACR' },
+	'unknown_cdek' => { 362 => 'CDEK' },
+	'unknown_cdet' => { 362 => 'CDET' },
+	'unknownblock' => { 345 => 0x405 },
+	'unknownblock1' => { 291 => 0x635 },
+	'unknownblock2' => { 291 => 0x636 },
+	'unknownblock3' => { 291 => 0x1103 },
+	'unknownblock4' => { 291 => 0x1104 },
+	'unknowncontrast' => { 107 => 0x45 },
+	'unknowndate' => { 354 => 0x212 },
+	'unknownev' => { 135 => 0x1 },
+	'unknownlinear' => { 107 => 0x46 },
+	'unknownnumber' => { 95 => 0x180b },
+	'unknownoutputhighlightpoint' => { 107 => 0x4a },
+	'unknownoutputshadowpoint' => { 107 => 0x4b },
+	'unknownrawhighlight' => { 107 => 0x7b },
+	'unknownrawhighlightpoint' => { 107 => 0x48 },
+	'unknownrawshadow' => { 107 => 0x84 },
+	'unknownrawshadowpoint' => { 107 => 0x49 },
+	'unknownsharpness' => { 107 => 0x47 },
+	'unknowntags' => { 370 => 'TAGS' },
+	'unknowntemperature' => { 119 => 0x4 },
+	'unknownthumbnail' => { 370 => 'thmb' },
+	'unsharp1color' => { 268 => 0x13 },
+	'unsharp1halowidth' => { 268 => 0x19 },
+	'unsharp1intensity' => { 268 => 0x17 },
+	'unsharp1threshold' => { 268 => 0x1b },
+	'unsharp2color' => { 268 => 0x2e },
+	'unsharp2halowidth' => { 268 => 0x34 },
+	'unsharp2intensity' => { 268 => 0x32 },
+	'unsharp2threshold' => { 268 => 0x36 },
+	'unsharp3color' => { 268 => 0x49 },
+	'unsharp3halowidth' => { 268 => 0x4f },
+	'unsharp3intensity' => { 268 => 0x4d },
+	'unsharp3threshold' => { 268 => 0x51 },
+	'unsharp4color' => { 268 => 0x64 },
+	'unsharp4halowidth' => { 268 => 0x6a },
+	'unsharp4intensity' => { 268 => 0x68 },
+	'unsharp4threshold' => { 268 => 0x6c },
+	'unsharpcount' => { 268 => 0x0 },
+	'unsharpmask' => { 107 => 0x90, 263 => 0x76a43200 },
+	'unsharpmaskfineness' => { 101 => 0x20309 },
+	'unsharpmaskstrength' => { 101 => 0x20308 },
+	'unsharpmaskthreshold' => { 101 => 0x2030a },
+	'uprightcentermode' => { 467 => 'UprightCenterMode', 469 => 'UprightCenterMode' },
+	'uprightcenternormx' => { 467 => 'UprightCenterNormX', 469 => 'UprightCenterNormX' },
+	'uprightcenternormy' => { 467 => 'UprightCenterNormY', 469 => 'UprightCenterNormY' },
+	'uprightdependentdigest' => { 467 => 'UprightDependentDigest', 469 => 'UprightDependentDigest' },
+	'uprightfocallength35mm' => { 467 => 'UprightFocalLength35mm', 469 => 'UprightFocalLength35mm' },
+	'uprightfocalmode' => { 467 => 'UprightFocalMode', 469 => 'UprightFocalMode' },
+	'uprightfoursegmentscount' => { 467 => 'UprightFourSegmentsCount', 469 => 'UprightFourSegmentsCount' },
+	'uprightpreview' => { 467 => 'UprightPreview', 469 => 'UprightPreview' },
+	'uprighttransform_0' => { 467 => 'UprightTransform_0', 469 => 'UprightTransform_0' },
+	'uprighttransform_1' => { 467 => 'UprightTransform_1', 469 => 'UprightTransform_1' },
+	'uprighttransform_2' => { 467 => 'UprightTransform_2', 469 => 'UprightTransform_2' },
+	'uprighttransform_3' => { 467 => 'UprightTransform_3', 469 => 'UprightTransform_3' },
+	'uprighttransform_4' => { 467 => 'UprightTransform_4', 469 => 'UprightTransform_4' },
+	'uprighttransform_5' => { 467 => 'UprightTransform_5', 469 => 'UprightTransform_5' },
+	'uprighttransformcount' => { 467 => 'UprightTransformCount', 469 => 'UprightTransformCount' },
+	'uprightversion' => { 467 => 'UprightVersion', 469 => 'UprightVersion' },
+	'urgency' => { 129 => 0xa, 481 => 'Urgency' },
+	'url' => { 154 => 'URL', 300 => 'URL', 359 => 0x40b, 483 => 'url' },
+	'url_list' => { 359 => 0x41e },
+	'urla-platform' => { 483 => [\'url','urlA-platform'] },
+	'urlurl' => { 483 => [\'url','urlUrl'] },
+	'usablemeteringmodes' => { 82 => 0x10a },
+	'usableshootingmodes' => { 82 => 0x109 },
+	'usage' => { 484 => 'usage' },
+	'usageterms' => { 497 => 'UsageTerms' },
+	'useguidelines' => { 465 => 'useGuidelines' },
+	'usepanoramaviewer' => { 455 => 'UsePanoramaViewer' },
+	'usercollection' => { 364 => 'collection.user' },
+	'usercomment' => { 95 => 0x805, 117 => 0x9286, 473 => 'UserComment' },
+	'userdef1picturestyle' => { 19 => 0x10c, 68 => 0xd8, 69 => 0xf0 },
+	'userdef2picturestyle' => { 19 => 0x10e, 68 => 0xda, 69 => 0xf2 },
+	'userdef3picturestyle' => { 19 => 0x110, 68 => 0xdc, 69 => 0xf4 },
+	'userfields' => { 460 => 'UserFields' },
+	'userlabel' => { 371 => 0x2b, 372 => 0x5a, 373 => 0x68 },
+	'userprofile' => { 305 => 0x302, 309 => 0x34c, 312 => 0x3038 },
+	'userrating' => { 364 => 'rating.user' },
+	'usmlenselectronicmf' => { 2 => 0x7, 81 => 0x7, 82 => 0x501 },
+	'uspsnumber' => { 483 => 'uspsNumber' },
+	'utmeasting' => { 165 => 'Easting' },
+	'utmmapdatum' => { 165 => 'Datum' },
+	'utmnorthing' => { 165 => 'Northing' },
+	'utmzone' => { 165 => 'Zone' },
+	'uuid' => { 467 => 'UUID', 469 => 'UUID' },
+	'uv-irfiltercorrection' => { 305 => 0x325 },
+	'validbits' => { 291 => 0x611, 292 => 0x102c },
+	'validpixeldepth' => { 295 => 0x611 },
+	'variablelowpassfilter' => { 410 => 0x2028 },
+	'variousmodes' => { 137 => 0x26 },
+	'variousmodes2' => { 137 => 0x3a },
+	'variprogram' => { 221 => 0xab },
+	'varraydacnominalvalues' => { 135 => 0x191e },
+	'vendor' => { 370 => 'vndr' },
+	'vendorinfo' => { 447 => 'VendorInfo' },
+	'vendorinfomanufacturer' => { 447 => [\'VendorInfo','VendorInfoManufacturer'] },
+	'vendorinfomodel' => { 447 => [\'VendorInfo','VendorInfoModel'] },
+	'vendorinfonotes' => { 447 => [\'VendorInfo','VendorInfoNotes'] },
+	'version' => { 125 => 0x0, 361 => 'Version', 364 => 'version', 467 => 'Version', 469 => 'Version' },
+	'versioncreatedate' => { 444 => 0xd100 },
+	'versionid' => { 494 => 'VersionID' },
+	'versionidentifier' => { 483 => 'versionIdentifier' },
+	'versionmodifydate' => { 444 => 0xd101 },
+	'versions' => { 494 => 'Versions' },
+	'versionscomments' => { 494 => [\'Versions','VersionsComments'] },
+	'versionsevent' => { 494 => [\'Versions','VersionsEvent'] },
+	'versionseventaction' => { 494 => [\'Versions','VersionsEventAction'] },
+	'versionseventchanged' => { 494 => [\'Versions','VersionsEventChanged'] },
+	'versionseventinstanceid' => { 494 => [\'Versions','VersionsEventInstanceID'] },
+	'versionseventparameters' => { 494 => [\'Versions','VersionsEventParameters'] },
+	'versionseventsoftwareagent' => { 494 => [\'Versions','VersionsEventSoftwareAgent'] },
+	'versionseventwhen' => { 494 => [\'Versions','VersionsEventWhen'] },
+	'versionsmodifier' => { 494 => [\'Versions','VersionsModifier'] },
+	'versionsmodifydate' => { 494 => [\'Versions','VersionsModifyDate'] },
+	'versionsversion' => { 494 => [\'Versions','VersionsVersion'] },
+	'verticalafonbutton' => { 270 => '3.2', 271 => '47.2', 273 => '79.1' },
+	'verticalclockoverlaps' => { 135 => 0x412 },
+	'verticalfuncbutton' => { 271 => '42.2', 273 => '67.1' },
+	'verticalfuncbuttonplusdials' => { 271 => '43.1' },
+	'verticalfuncplusdials' => { 273 => '68.1' },
+	'verticalmultiselector' => { 271 => '42.1', 273 => '66.1', 274 => '66.1', 284 => '66.1' },
+	'vfdisplayillumination' => { 2 => 0x11, 82 => [0x510,0x51d] },
+	'vibrance' => { 461 => 'Vibrance', 467 => 'Vibrance', 469 => 'Vibrance' },
+	'vibrationreduction' => { 230 => [0x75,0x82,0x1ae], 238 => '586.1', 247 => '590.2', 254 => 0x4 },
+	'videoalphamode' => { 493 => 'videoAlphaMode' },
+	'videoalphapremultiplecolor' => { 493 => 'videoAlphaPremultipleColor' },
+	'videoalphapremultiplecolora' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorA'] },
+	'videoalphapremultiplecolorb' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorB'] },
+	'videoalphapremultiplecolorblack' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlack'] },
+	'videoalphapremultiplecolorblue' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorBlue'] },
+	'videoalphapremultiplecolorcyan' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorCyan'] },
+	'videoalphapremultiplecolorgray' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorGray'] },
+	'videoalphapremultiplecolorgreen' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorGreen'] },
+	'videoalphapremultiplecolorl' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorL'] },
+	'videoalphapremultiplecolormagenta' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMagenta'] },
+	'videoalphapremultiplecolormode' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorMode'] },
+	'videoalphapremultiplecolorred' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorRed'] },
+	'videoalphapremultiplecolorswatchname' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorSwatchName'] },
+	'videoalphapremultiplecolortint' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorTint'] },
+	'videoalphapremultiplecolortype' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorType'] },
+	'videoalphapremultiplecoloryellow' => { 493 => [\'videoAlphaPremultipleColor','videoAlphaPremultipleColorYellow'] },
+	'videoalphaunityistransparent' => { 493 => 'videoAlphaUnityIsTransparent' },
+	'videobitrate' => { 479 => 'videoBitRate' },
+	'videobitratemode' => { 479 => 'videoBitRateMode' },
+	'videoburstmode' => { 310 => 0xbb },
+	'videoburstresolution' => { 310 => 0xb3 },
+	'videocodec' => { 65 => 0x74 },
+	'videocolorspace' => { 493 => 'videoColorSpace' },
+	'videocompression' => { 125 => 0x3806 },
+	'videocompressor' => { 493 => 'videoCompressor' },
+	'videodisplayaspectratio' => { 479 => 'videoDisplayAspectRatio' },
+	'videoencodingprofile' => { 479 => 'videoEncodingProfile' },
+	'videofieldorder' => { 493 => 'videoFieldOrder' },
+	'videoframerate' => { 310 => 0x27, 493 => 'videoFrameRate' },
+	'videoframesize' => { 493 => 'videoFrameSize' },
+	'videoframesizeh' => { 493 => [\'videoFrameSize','videoFrameSizeH'] },
+	'videoframesizeunit' => { 493 => [\'videoFrameSize','videoFrameSizeUnit'] },
+	'videoframesizew' => { 493 => [\'videoFrameSize','videoFrameSizeW'] },
+	'videomoddate' => { 493 => 'videoModDate' },
+	'videopixelaspectratio' => { 493 => 'videoPixelAspectRatio' },
+	'videopixeldepth' => { 493 => 'videoPixelDepth' },
+	'videopreburst' => { 310 => 0xc1 },
+	'videoquality' => { 111 => 0x4003 },
+	'videorecordingmode' => { 125 => 0x3803 },
+	'videoshottype' => { 479 => 'VideoShotType' },
+	'videoshottypeidentifier' => { 479 => [\'VideoShotType','VideoShotTypeIdentifier'] },
+	'videoshottypename' => { 479 => [\'VideoShotType','VideoShotTypeName'] },
+	'videostreamscount' => { 479 => 'videoStreamsCount' },
+	'viewfinder' => { 354 => 0x455 },
+	'viewfinderdisplay' => { 270 => '12.4', 271 => '6.3' },
+	'viewfinderwarning' => { 270 => '13.4', 280 => '3.5', 281 => '6.2', 285 => '4.4' },
+	'viewfinderwarnings' => { 82 => 0x40a },
+	'viewinfoduringexposure' => { 82 => 0x407 },
+	'viewingmode' => { 399 => 0x2f, 415 => 0x18 },
+	'viewingmode2' => { 399 => [0x85,0x285] },
+	'viewpoint' => { 482 => 'viewpoint' },
+	'vignetteamount' => { 467 => 'VignetteAmount', 469 => 'VignetteAmount' },
+	'vignettecontrol' => { 221 => 0x2a, 263 => 0x76a43205 },
+	'vignettecontrolintensity' => { 263 => 0xac6bd5c0 },
+	'vignettecorrectionalreadyapplied' => { 464 => 'VignetteCorrectionAlreadyApplied' },
+	'vignettemidpoint' => { 467 => 'VignetteMidpoint', 469 => 'VignetteMidpoint' },
+	'vignetting' => { 377 => 0x1011, 384 => 0xa052 },
+	'vignettingcorrection' => { 117 => 0x7031, 384 => 0xa053, 410 => 0x2011 },
+	'vignettingcorrparams' => { 117 => 0x7032, 439 => 0x64a, 440 => [0x34a,0x350,0x35c,0x368] },
+	'vignettingsetting' => { 384 => 0xa054 },
+	'visualcolor' => { 479 => 'VisualColour' },
+	'visualtechnique' => { 482 => 'visualTechnique' },
+	'voicememo' => { 386 => 0x216 },
+	'volume' => { 483 => 'volume' },
+	'vr_0x66' => { 230 => 0x66 },
+	'vrdoffset' => { 62 => 0xd0 },
+	'vrmode' => { 254 => 0x6 },
+	'waterdepth' => { 117 => 0x9403, 474 => 'WaterDepth' },
+	'wb_bluelevel3500k' => { 183 => 0x19a },
+	'wb_bluelevel6500k' => { 183 => 0x18a },
+	'wb_bluelevelcustom' => { 183 => 0x18e },
+	'wb_bluelevelscloudy' => { 183 => 0x106 },
+	'wb_bluelevelsdaylight' => { 183 => 0xea },
+	'wb_bluelevelsflash' => { 183 => 0x122 },
+	'wb_bluelevelsfluorescent' => { 183 => [0x40a,0x15a] },
+	'wb_bluelevelskelvin' => { 183 => 0x254 },
+	'wb_bluelevelsshade' => { 183 => 0x176 },
+	'wb_bluelevelstungsten' => { 183 => 0xce },
+	'wb_gbrglevels' => { 183 => 0xae, 186 => 0x4 },
+	'wb_glevel' => { 291 => 0x11f },
+	'wb_glevel3000k' => { 291 => 0x113 },
+	'wb_glevel3300k' => { 291 => 0x114 },
+	'wb_glevel3600k' => { 291 => 0x115 },
+	'wb_glevel3900k' => { 291 => 0x116 },
+	'wb_glevel4000k' => { 291 => 0x117 },
+	'wb_glevel4300k' => { 291 => 0x118 },
+	'wb_glevel4500k' => { 291 => 0x119 },
+	'wb_glevel4800k' => { 291 => 0x11a },
+	'wb_glevel5300k' => { 291 => 0x11b },
+	'wb_glevel6000k' => { 291 => 0x11c },
+	'wb_glevel6600k' => { 291 => 0x11d },
+	'wb_glevel7500k' => { 291 => 0x11e },
+	'wb_grbglevels' => { 196 => 0x0 },
+	'wb_grgblevelsauto' => { 79 => 0x2 },
+	'wb_grgblevelscloudy' => { 79 => 0x12 },
+	'wb_grgblevelscustom1' => { 79 => 0x42 },
+	'wb_grgblevelscustom2' => { 79 => 0x4a },
+	'wb_grgblevelsdaylight' => { 79 => 0xa },
+	'wb_grgblevelsflash' => { 79 => 0x32 },
+	'wb_grgblevelsfluorescent' => { 79 => 0x22 },
+	'wb_grgblevelsfluorhigh' => { 79 => 0x2a },
+	'wb_grgblevelstungsten' => { 79 => 0x1a },
+	'wb_grgblevelsunderwater' => { 79 => 0x3a },
+	'wb_rbgglevels' => { 193 => 0x0 },
+	'wb_rblevels' => { 197 => 0x270, 221 => 0xc, 291 => 0x100 },
+	'wb_rblevels1' => { 316 => 0x2 },
+	'wb_rblevels2' => { 316 => 0x5 },
+	'wb_rblevels3' => { 316 => 0x8 },
+	'wb_rblevels3000k' => { 291 => 0x102 },
+	'wb_rblevels3300k' => { 291 => 0x103 },
+	'wb_rblevels3500k' => { 183 => 0x430 },
+	'wb_rblevels3600k' => { 291 => 0x104 },
+	'wb_rblevels3900k' => { 291 => 0x105 },
+	'wb_rblevels4' => { 316 => 0xb },
+	'wb_rblevels4000k' => { 291 => 0x106 },
+	'wb_rblevels4300k' => { 291 => 0x107 },
+	'wb_rblevels4500k' => { 291 => 0x108 },
+	'wb_rblevels4800k' => { 291 => 0x109 },
+	'wb_rblevels5' => { 316 => 0xe },
+	'wb_rblevels5300k' => { 291 => 0x10a },
+	'wb_rblevels6' => { 316 => 0x11 },
+	'wb_rblevels6000k' => { 291 => 0x10b },
+	'wb_rblevels6500k' => { 183 => 0x420 },
+	'wb_rblevels6600k' => { 291 => 0x10c },
+	'wb_rblevels7' => { 316 => 0x14 },
+	'wb_rblevels7500k' => { 291 => 0x10d },
+	'wb_rblevelsauto' => { 197 => 0x272, 295 => 0x110 },
+	'wb_rblevelscloudy' => { 183 => 0x3f0, 185 => 0x10, 197 => 0x296, 295 => 0x121 },
+	'wb_rblevelscoolwhitef' => { 183 => 0x308, 185 => 0x14 },
+	'wb_rblevelscoolwhitefluor' => { 295 => 0x132 },
+	'wb_rblevelscustom' => { 183 => 0x424, 185 => 0x1c },
+	'wb_rblevelscwb1' => { 291 => 0x10e },
+	'wb_rblevelscwb2' => { 291 => 0x10f },
+	'wb_rblevelscwb3' => { 291 => 0x110 },
+	'wb_rblevelscwb4' => { 291 => 0x111 },
+	'wb_rblevelsdaylight' => { 183 => [0x3ec,0x528], 185 => 0xc, 197 => 0x274 },
+	'wb_rblevelsdaylightf' => { 185 => 0x24 },
+	'wb_rblevelsdaylightfluor' => { 295 => 0x130 },
+	'wb_rblevelsdaywhitef' => { 185 => 0x28 },
+	'wb_rblevelsdaywhitefluor' => { 295 => 0x131 },
+	'wb_rblevelseveningsunlight' => { 295 => 0x124 },
+	'wb_rblevelsfineweather' => { 295 => 0x122 },
+	'wb_rblevelsflash' => { 183 => [0x3f4,0x304], 185 => 0x18, 197 => 0x2a4 },
+	'wb_rblevelsfluorescent' => { 197 => 0x290 },
+	'wb_rblevelsincandescent' => { 197 => 0x282 },
+	'wb_rblevelsshade' => { 183 => 0x418, 185 => 0x20, 197 => 0x2b2, 295 => 0x120 },
+	'wb_rblevelstungsten' => { 183 => 0x3e8, 185 => 0x8, 295 => 0x123 },
+	'wb_rblevelsused' => { 295 => 0x100 },
+	'wb_rblevelswhitef' => { 185 => 0x2c },
+	'wb_rblevelswhitefluorescent' => { 295 => 0x133 },
+	'wb_redlevel3500k' => { 183 => 0x198 },
+	'wb_redlevel6500k' => { 183 => 0x188 },
+	'wb_redlevelcustom' => { 183 => 0x18c },
+	'wb_redlevelscloudy' => { 183 => 0xf8 },
+	'wb_redlevelsdaylight' => { 183 => 0xdc },
+	'wb_redlevelsflash' => { 183 => 0x114 },
+	'wb_redlevelsfluorescent' => { 183 => [0x3fc,0x14c] },
+	'wb_redlevelskelvin' => { 183 => 0x1be },
+	'wb_redlevelsshade' => { 183 => 0x168 },
+	'wb_redlevelstungsten' => { 183 => 0xc0 },
+	'wb_rgbglevels' => { 195 => 0x0 },
+	'wb_rgblevels' => { 183 => [0x546,0x96], 306 => 0xd, 307 => 0x413, 312 => 0x3036, 354 => 0x107, 418 => 0x117c, 419 => 0x1180, 420 => 0x115c, 421 => 0x11d8, 422 => 0x11b4, 423 => 0x106c, 424 => 0x264, 425 => 0x264, 426 => 0x252 },
+	'wb_rgblevels1' => { 317 => 0x2 },
+	'wb_rgblevels2' => { 317 => 0x6 },
+	'wb_rgblevels3' => { 317 => 0xa },
+	'wb_rgblevels4' => { 317 => 0xe },
+	'wb_rgblevels5' => { 317 => 0x12 },
+	'wb_rgblevels6' => { 317 => 0x16 },
+	'wb_rgblevels7' => { 317 => 0x1a },
+	'wb_rgblevelsauto' => { 388 => 0x0 },
+	'wb_rgblevelscustom1' => { 388 => 0x15 },
+	'wb_rgblevelscustom2' => { 388 => 0x18 },
+	'wb_rgblevelscustom3' => { 388 => 0x1b },
+	'wb_rgblevelsdaylight' => { 388 => 0x3 },
+	'wb_rgblevelsflash' => { 388 => 0x12 },
+	'wb_rgblevelsfluorescent' => { 388 => 0xf },
+	'wb_rgblevelsincandescent' => { 388 => 0xc },
+	'wb_rgblevelsovercast' => { 388 => 0x9 },
+	'wb_rgblevelsshade' => { 388 => 0x6 },
+	'wb_rgblevelsunknown0' => { 389 => 0x0 },
+	'wb_rgblevelsunknown1' => { 389 => 0x3 },
+	'wb_rgblevelsunknown2' => { 389 => 0x6 },
+	'wb_rgblevelsunknown3' => { 389 => 0x9 },
+	'wb_rgblevelsunknown4' => { 389 => 0xc },
+	'wb_rgblevelsunknown5' => { 389 => 0xf },
+	'wb_rgblevelsunknown6' => { 389 => 0x12 },
+	'wb_rgblevelsunknown7' => { 389 => 0x15 },
+	'wb_rgblevelsunknown8' => { 389 => 0x18 },
+	'wb_rgblevelsunknown9' => { 389 => 0x1b },
+	'wb_rgbmuldaylight' => { 135 => 0x852 },
+	'wb_rgbmulflash' => { 135 => 0x855 },
+	'wb_rgbmulfluorescent' => { 135 => 0x854 },
+	'wb_rgbmultungsten' => { 135 => 0x853 },
+	'wb_rggbblacklevels' => { 35 => 0x25 },
+	'wb_rggblevels' => { 186 => 0x4, 194 => 0x0, 198 => 0x13e8, 199 => 0x38 },
+	'wb_rggblevelsasshot' => { 38 => 0x0, 39 => 0x0, 40 => 0x19, 41 => 0x55, 42 => 0x22, 43 => 0x3f, 46 => 0x3f, 47 => 0x3f, 48 => 0x3f, 49 => 0x47 },
+	'wb_rggblevelsauto' => { 35 => 0x1, 38 => 0x5, 39 => 0x8, 40 => 0x1e, 41 => 0x5a, 42 => 0x18, 43 => 0x44, 46 => 0x44, 47 => 0x44, 48 => 0x44, 49 => 0x4c, 198 => 0x1478, 199 => 0x114, 384 => 0xa022 },
+	'wb_rggblevelsblack' => { 384 => 0xa028 },
+	'wb_rggblevelscloudy' => { 35 => 0xd, 38 => 0x1e, 39 => 0x30, 40 => 0x2d, 41 => 0xa0, 42 => 0x31, 43 => 0x58, 46 => 0x71, 47 => 0x8a, 48 => 0x8f, 49 => 0x92, 198 => 0x1408, 199 => 0x60, 345 => 0x20f, 353 => 0x14 },
+	'wb_rggblevelscustom' => { 35 => 0x1d, 43 => 0x80, 198 => 0x1468, 199 => 0x100 },
+	'wb_rggblevelscustom1' => { 40 => 0x41 },
+	'wb_rggblevelscustom2' => { 40 => 0x46 },
+	'wb_rggblevelsdaylight' => { 35 => 0x5, 38 => 0x14, 39 => 0x20, 40 => 0x23, 41 => 0x96, 42 => 0x27, 43 => 0x4e, 46 => 0x67, 47 => 0x80, 48 => 0x85, 49 => 0x88, 198 => 0x13f8, 199 => 0x4c, 345 => 0x20d, 353 => 0x2 },
+	'wb_rggblevelsflash' => { 35 => 0x19, 38 => 0x32, 39 => 0x50, 40 => 0x3c, 41 => 0xb4, 42 => 0x45, 43 => 0x6c, 46 => 0x85, 47 => 0x9e, 48 => 0xa3, 49 => 0xa6, 198 => 0x1448, 345 => 0x214, 353 => 0x41 },
+	'wb_rggblevelsfluorescent' => { 35 => 0x15, 38 => 0x28, 39 => 0x40, 40 => 0x37, 41 => 0xaa, 42 => 0x3b, 43 => 0x62, 46 => 0x7b, 47 => 0x94, 48 => 0x99, 49 => 0x9c },
+	'wb_rggblevelsfluorescentd' => { 199 => 0xc4, 345 => 0x211, 353 => 0x26 },
+	'wb_rggblevelsfluorescentl' => { 353 => 0x4a },
+	'wb_rggblevelsfluorescentn' => { 199 => 0xb0, 345 => 0x212, 353 => 0x2f },
+	'wb_rggblevelsfluorescentw' => { 198 => 0x1438, 199 => 0x9c, 345 => 0x213, 353 => 0x38 },
+	'wb_rggblevelshtmercury' => { 199 => 0xd8 },
+	'wb_rggblevelsilluminator1' => { 384 => 0xa023 },
+	'wb_rggblevelsilluminator2' => { 384 => 0xa024 },
+	'wb_rggblevelskelvin' => { 35 => 0x21, 38 => 0x2d, 39 => 0x48, 41 => 0xaf, 42 => 0x40, 43 => 0x67, 46 => 0x80, 47 => 0x99, 48 => 0x9e, 49 => 0xa1 },
+	'wb_rggblevelsmeasured' => { 38 => 0xa, 39 => 0x10, 41 => 0x5f, 43 => 0x49, 46 => 0x49, 47 => 0x49, 48 => 0x49, 49 => 0x51 },
+	'wb_rggblevelspc1' => { 42 => 0x90, 43 => 0x71 },
+	'wb_rggblevelspc2' => { 42 => 0x95, 43 => 0x76 },
+	'wb_rggblevelspc3' => { 42 => 0x9a, 43 => 0x7b },
+	'wb_rggblevelsshade' => { 35 => 0x9, 38 => 0x19, 39 => 0x28, 40 => 0x28, 41 => 0x9b, 42 => 0x2c, 43 => 0x53, 46 => 0x6c, 47 => 0x85, 48 => 0x8a, 49 => 0x8d, 199 => 0x74, 345 => 0x20e, 353 => 0xb },
+	'wb_rggblevelstungsten' => { 35 => 0x11, 38 => 0x23, 39 => 0x38, 40 => 0x32, 41 => 0xa5, 42 => 0x36, 43 => 0x5d, 46 => 0x76, 47 => 0x8f, 48 => 0x94, 49 => 0x97, 198 => 0x1428, 199 => 0x88, 345 => 0x210, 353 => 0x1d },
+	'wb_rggblevelsuncorrected' => { 384 => 0xa021 },
+	'wb_rggblevelsunknown' => { 38 => 0xf, 39 => 0x18, 41 => 0x64, 42 => 0x1d, 46 => 0x4e, 47 => 0x4e, 48 => 0x4e, 49 => 0x56, 353 => 0x53 },
+	'wb_rggblevelsunknown10' => { 38 => 0x5f, 39 => 0x98, 41 => 0x91, 42 => 0x72, 46 => 0x9e, 47 => 0x7b, 48 => 0x7b, 49 => 0x83 },
+	'wb_rggblevelsunknown11' => { 38 => 0x64, 39 => 0xa0, 41 => 0xb9, 42 => 0x77, 46 => 0xa3, 47 => 0xa3, 48 => 0x80, 49 => 0xab },
+	'wb_rggblevelsunknown12' => { 38 => 0x69, 39 => 0xa8, 41 => 0xbe, 42 => 0x7c, 46 => 0xa8, 47 => 0xa8, 48 => 0xa8, 49 => 0xb0 },
+	'wb_rggblevelsunknown13' => { 38 => 0x6e, 39 => 0xb0, 41 => 0xc3, 42 => 0x81, 46 => 0xad, 47 => 0xad, 48 => 0xad, 49 => 0xb5 },
+	'wb_rggblevelsunknown14' => { 41 => 0xc8, 42 => 0x86, 46 => 0xb2, 47 => 0xb2, 48 => 0xb2, 49 => 0xba },
+	'wb_rggblevelsunknown15' => { 41 => 0xcd, 42 => 0x8b, 46 => 0xb7, 47 => 0xb7, 48 => 0xb7, 49 => 0xbf },
+	'wb_rggblevelsunknown16' => { 41 => 0xd2, 42 => 0x9f, 47 => 0xbc, 48 => 0xbc, 49 => 0xc4 },
+	'wb_rggblevelsunknown17' => { 41 => 0xd7, 47 => 0xc1, 48 => 0xc1, 49 => 0xc9 },
+	'wb_rggblevelsunknown18' => { 41 => 0xdc, 47 => 0xc6, 48 => 0xc6, 49 => 0xce },
+	'wb_rggblevelsunknown19' => { 41 => 0xe1, 47 => 0xcb, 48 => 0xcb, 49 => 0xd3 },
+	'wb_rggblevelsunknown2' => { 38 => 0x37, 39 => 0x58, 41 => 0x69, 42 => 0x4a, 46 => 0x53, 47 => 0x53, 48 => 0x53, 49 => 0x5b },
+	'wb_rggblevelsunknown20' => { 41 => 0xe6, 47 => 0xd0, 48 => 0xd0, 49 => 0xd8 },
+	'wb_rggblevelsunknown21' => { 41 => 0xeb, 48 => 0xd5, 49 => 0xdd },
+	'wb_rggblevelsunknown22' => { 41 => 0xf0, 48 => 0xda, 49 => 0xe2 },
+	'wb_rggblevelsunknown23' => { 41 => 0xf5, 48 => 0xdf, 49 => 0xe7 },
+	'wb_rggblevelsunknown24' => { 41 => 0xfa, 48 => 0xe4, 49 => 0xec },
+	'wb_rggblevelsunknown25' => { 41 => 0xff, 48 => 0xe9, 49 => 0xf1 },
+	'wb_rggblevelsunknown26' => { 41 => 0x104, 48 => 0xee, 49 => 0xf6 },
+	'wb_rggblevelsunknown27' => { 41 => 0x109, 48 => 0xf3, 49 => 0xfb },
+	'wb_rggblevelsunknown28' => { 41 => 0x10e, 48 => 0xf8, 49 => 0x100 },
+	'wb_rggblevelsunknown29' => { 41 => 0x113, 48 => 0xfd, 49 => 0x105 },
+	'wb_rggblevelsunknown3' => { 38 => 0x3c, 39 => 0x60, 41 => 0x6e, 42 => 0x4f, 46 => 0x58, 47 => 0x58, 48 => 0x58, 49 => 0x60 },
+	'wb_rggblevelsunknown30' => { 48 => 0x102 },
+	'wb_rggblevelsunknown4' => { 38 => 0x41, 39 => 0x68, 41 => 0x73, 42 => 0x54, 46 => 0x5d, 47 => 0x5d, 48 => 0x5d, 49 => 0x65 },
+	'wb_rggblevelsunknown5' => { 38 => 0x46, 39 => 0x70, 41 => 0x78, 42 => 0x59, 46 => 0x62, 47 => 0x62, 48 => 0x62, 49 => 0x6a },
+	'wb_rggblevelsunknown6' => { 38 => 0x4b, 39 => 0x78, 41 => 0x7d, 42 => 0x5e, 46 => 0x8a, 47 => 0x67, 48 => 0x67, 49 => 0x6f },
+	'wb_rggblevelsunknown7' => { 38 => 0x50, 39 => 0x80, 41 => 0x82, 42 => 0x63, 46 => 0x8f, 47 => 0x6c, 48 => 0x6c, 49 => 0x74 },
+	'wb_rggblevelsunknown8' => { 38 => 0x55, 39 => 0x88, 41 => 0x87, 42 => 0x68, 46 => 0x94, 47 => 0x71, 48 => 0x71, 49 => 0x79 },
+	'wb_rggblevelsunknown9' => { 38 => 0x5a, 39 => 0x90, 41 => 0x8c, 42 => 0x6d, 46 => 0x99, 47 => 0x76, 48 => 0x76, 49 => 0x7e },
+	'wb_rggblevelsuserselected' => { 353 => 0x5c },
+	'wbadjblueamber' => { 101 => 0x20106 },
+	'wbadjbluebalance' => { 269 => 0x8 },
+	'wbadjcolortemp' => { 101 => 0x20102, 106 => 0x1a },
+	'wbadjlighting' => { 269 => 0x14 },
+	'wbadjmagentagreen' => { 101 => 0x20105 },
+	'wbadjmode' => { 269 => 0x10 },
+	'wbadjredbalance' => { 269 => 0x0 },
+	'wbadjrggblevels' => { 101 => 0x20125, 106 => 0x6 },
+	'wbadjtemperature' => { 269 => 0x18 },
+	'wbadjtint' => { 269 => 0x25 },
+	'wbbluelevel' => { 305 => 0x324, 310 => 0x8006, 315 => 0x26 },
+	'wbbracketingsteps' => { 239 => 0x174d, 240 => 0x87c, 249 => 0x1757 },
+	'wbbracketmode' => { 56 => 0x9 },
+	'wbbracketshotnumber' => { 183 => 0x2b, 377 => 0x101a },
+	'wbbracketvalueab' => { 56 => 0xc },
+	'wbbracketvaluegm' => { 56 => 0xd },
+	'wbfinetuneactive' => { 106 => 0x24 },
+	'wbfinetunesaturation' => { 106 => 0x28 },
+	'wbfinetunetone' => { 106 => 0x2c },
+	'wbgreenlevel' => { 305 => 0x323, 310 => 0x8005, 315 => 0x25 },
+	'wbmediaimagesizesetting' => { 82 => 0x708 },
+	'wbmode' => { 185 => 0x4, 292 => 0x1015 },
+	'wbredlevel' => { 305 => 0x322, 310 => 0x8004, 315 => 0x24 },
+	'wbscale' => { 186 => 0x0 },
+	'wbshiftab' => { 72 => 0xc, 310 => 0x46, 327 => 0x10 },
+	'wbshiftab_gm' => { 410 => 0x2014 },
+	'wbshiftab_gm_precise' => { 410 => 0x2026 },
+	'wbshiftcreativecontrol' => { 310 => 0x92 },
+	'wbshiftgm' => { 72 => 0xd, 310 => 0x47, 327 => 0x11 },
+	'wbshiftintelligentauto' => { 310 => 0x8b },
+	'wbtype1' => { 316 => 0x1, 317 => 0x1 },
+	'wbtype2' => { 316 => 0x4, 317 => 0x5 },
+	'wbtype3' => { 316 => 0x7, 317 => 0x9 },
+	'wbtype4' => { 316 => 0xa, 317 => 0xd },
+	'wbtype5' => { 316 => 0xd, 317 => 0x11 },
+	'wbtype6' => { 316 => 0x10, 317 => 0x15 },
+	'wbtype7' => { 316 => 0x13, 317 => 0x19 },
+	'webstatement' => { 497 => 'WebStatement' },
+	'what' => { 467 => 'What', 469 => '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, 72 => 0x8, 75 => 0x7, 110 => 0x7, 111 => [0x19,0x2012], 117 => [0xa403,0xfe4e], 125 => 0x1002, 135 => 0x3fc, 136 => 0xfa0d, 137 => 0x40, 148 => 0x1a, 177 => 0x3, 178 => 0xe, 179 => 0x4, 180 => 0xb, 182 => 0x115, 221 => 0x5, 253 => 0x7, 305 => 0x304, 310 => 0x3, 312 => 0x3033, 345 => 0x19, 352 => 0x7, 376 => 0x26, 377 => 0x1003, 387 => [0x88,0x3c,0x7,0x58], 397 => 0xf, 398 => 0xe, 410 => [0x115,0xb054], 467 => 'WhiteBalance', 469 => 'WhiteBalance', 473 => 'WhiteBalance' },
+	'whitebalance0' => { 173 => 'WhiteBalance0' },
+	'whitebalance1' => { 173 => 'WhiteBalance1' },
+	'whitebalance2' => { 173 => 'WhiteBalance2', 287 => 0x500 },
+	'whitebalanceadj' => { 101 => 0x20101, 106 => 0x18, 263 => 0x76a43204 },
+	'whitebalanceautoadjustment' => { 323 => 0x0 },
+	'whitebalancebias' => { 111 => 0x2011, 292 => 0x304, 310 => 0x23 },
+	'whitebalanceblue' => { 72 => 0x7 },
+	'whitebalancebracket' => { 287 => 0x502, 292 => 0x303 },
+	'whitebalancebracketing' => { 180 => 0x22, 183 => 0x2c, 408 => 0x2c },
+	'whitebalancecomp' => { 295 => 0x1001 },
+	'whitebalancedetected' => { 135 => 0x3fb },
+	'whitebalancefinetune' => { 125 => 0x100a, 180 => 0x38, 182 => 0x112, 221 => 0xb, 377 => 0x1004, 397 => 0x6, 398 => 0x5, 410 => 0x112 },
+	'whitebalancemode' => { 135 => 0x3fa, 345 => 0x1a },
+	'whitebalancered' => { 72 => 0x6 },
+	'whitebalanceset' => { 326 => 0xa },
+	'whitebalancesetting' => { 180 => 0x23, 397 => 0x5, 398 => 0x4, 399 => 0x16, 415 => 0xd },
+	'whitebalancesetup' => { 384 => 0x41 },
+	'whitebalancetemperature' => { 287 => 0x501 },
+	'whiteboard' => { 292 => 0x301 },
+	'whitelevel' => { 117 => 0xc61d, 345 => 0x7e },
+	'whitepoint' => { 117 => 0x13e, 345 => 0x201, 489 => 'WhitePoint' },
+	'whites2012' => { 467 => 'Whites2012', 469 => 'Whites2012' },
+	'whitesadj' => { 444 => 0x9017 },
+	'wideadapter' => { 377 => 0x1017 },
+	'widefocuszone' => { 177 => 0x2f },
+	'widerange' => { 386 => 0x20f },
+	'windmode' => { 135 => 0x3f4 },
+	'windowlocation' => { 370 => 'WLOC' },
+	'windowsatom' => { 468 => 'windowsAtom' },
+	'windowsatomextension' => { 468 => [\'windowsAtom','windowsAtomExtension'] },
+	'windowsatominvocationflags' => { 468 => [\'windowsAtom','windowsAtomInvocationFlags'] },
+	'windowsatomuncprojectpath' => { 468 => [\'windowsAtom','windowsAtomUncProjectPath'] },
+	'wordcount' => { 483 => 'wordCount' },
+	'work' => { 362 => "\xa9wrk" },
+	'workcolorspace' => { 101 => 0x10200, 106 => 0x270 },
+	'workflowtag' => { 479 => 'WorkflowTag' },
+	'workflowtagcvid' => { 479 => [\'WorkflowTag','WorkflowTagCvId'] },
+	'workflowtagcvtermid' => { 479 => [\'WorkflowTag','WorkflowTagCvTermId'] },
+	'workflowtagcvtermname' => { 479 => [\'WorkflowTag','WorkflowTagCvTermName'] },
+	'workflowtagcvtermrefinedabout' => { 479 => [\'WorkflowTag','WorkflowTagCvTermRefinedAbout'] },
+	'worktodo' => { 475 => 'WorkToDo' },
+	'worldtimelocation' => { 310 => 0x3a, 345 => 0x22, 351 => '0.1' },
+	'writer-editor' => { 129 => 0x7a },
+	'x3filllight' => { 387 => 0x12 },
+	'xattrquarantine' => { 171 => 'com.apple.quarantine' },
+	'xilinxversion' => { 135 => 0x414 },
+	'xml' => { 133 => 'xml ' },
+	'xmp' => { 104 => 0xffff00f6, 118 => 'XMP' },
+	'xmptoolkit' => { 490 => 'xmptk' },
+	'xpauthor' => { 117 => 0x9c9d },
+	'xpcomment' => { 117 => 0x9c9c },
+	'xpkeywords' => { 117 => 0x9c9e },
+	'xposition' => { 117 => 0x11e },
+	'xpsubject' => { 117 => 0x9c9f },
+	'xptitle' => { 117 => 0x9c9b },
+	'xresolution' => { 117 => 0x11a, 132 => 0x3, 360 => 0x0, 489 => 'XResolution' },
+	'xyresolution' => { 121 => 0x3 },
+	'yaw' => { 113 => 0x7, 370 => ['_yaw',"\xa9fyw"] },
+	'yawangle' => { 239 => 0x3513, 240 => 0x2c2c, 244 => 0xc222, 249 => 0x36fc, 250 => 0x2f03, 252 => 0xce3a, 382 => 0x0 },
+	'ycbcrcoefficients' => { 117 => 0x211, 489 => 'YCbCrCoefficients' },
+	'ycbcrpositioning' => { 117 => 0x213, 489 => 'YCbCrPositioning' },
+	'ycbcrsubsampling' => { 117 => 0x212, 489 => 'YCbCrSubSampling' },
+	'year' => { 362 => 'yrrc', 364 => 'year' },
+	'yearcreated' => { 137 => 0x10, 146 => 0xc },
+	'yellowhsl' => { 101 => 0x20912 },
+	'yield' => { 485 => 'yield' },
+	'yposition' => { 117 => 0x11f },
+	'yresolution' => { 117 => 0x11b, 132 => 0x5, 360 => 0x4, 489 => 'YResolution' },
+	'zonematching' => { 182 => 0x10a, 185 => [0x3a,0x4a], 410 => 0xb024 },
+	'zonematchingmode' => { 180 => 0x14 },
+	'zonematchingon' => { 179 => 0x75 },
+	'zonematchingvalue' => { 397 => 0x1f },
+	'zoomedpreviewlength' => { 292 => 0xf05 },
+	'zoomedpreviewsize' => { 292 => 0xf06 },
+	'zoomedpreviewstart' => { 292 => 0xf04 },
+	'zoomsourcewidth' => { 34 => 0x24 },
+	'zoomstepcount' => { 290 => 0x300, 292 => 0x100d },
+	'zoomtargetwidth' => { 34 => 0x25 },
 );
 
@@ -3523,9 +6399,41 @@
 	'_stream' => 1,
 	'a100dataoffset' => 1,
+	'aas' => 1,
+	'abovecolor' => 1,
 	'abstract' => 1,
+	'abstractfilename' => 1,
+	'accel360fly' => 1,
+	'acceldata' => 1,
+	'accelerometertime' => 1,
+	'accelmode' => 1,
+	'accelypr' => 1,
 	'accessdate' => 1,
+	'accountname' => 1,
 	'acdsee' => 1,
+	'acquisitiontime' => 1,
+	'acquisitiontimeday' => 1,
+	'acquisitiontimemonth' => 1,
+	'acquisitiontimeyear' => 1,
+	'acquisitiontimeyearmonth' => 1,
+	'acquisitiontimeyearmonthday' => 1,
+	'acroform' => 1,
+	'activebuf1cols' => 1,
+	'activebuf1rows' => 1,
+	'activebuf2cols' => 1,
+	'activebuf2rows' => 1,
+	'activecols' => 1,
+	'activectemonitor1cols' => 1,
+	'activectemonitor2cols' => 1,
+	'activectemonitorrows' => 1,
+	'activerows' => 1,
+	'actor' => 1,
 	'actualcompensation' => 1,
-	'adobe' => 1,
+	'actualscalemax' => 1,
+	'actualscalemin' => 1,
+	'actualsoftpostpadding' => 1,
+	'actualsoftprepadding' => 1,
+	'additionalinfo' => 1,
+	'adjustedtbnimageheight' => 1,
+	'adjustedtbnimagewidth' => 1,
 	'adobe_cm' => 1,
 	'adobecmtype' => 1,
@@ -3538,11 +6446,19 @@
 	'adoberaf' => 1,
 	'adobesr2' => 1,
+	'adoptedneutral' => 1,
+	'adult' => 1,
 	'advancedcontentencryption' => 1,
 	'advancedmutualexcl' => 1,
+	'advancedscenemode' => 1,
 	'adventrevision' => 1,
 	'adventscale' => 1,
 	'aeflags' => 1,
 	'aeinfo' => 1,
-	'aeunknown' => 1,
+	'aeinfo2' => 1,
+	'aeinfo3' => 1,
+	'aeinfounknown' => 1,
+	'af-assistilluminator' => 1,
+	'af-cprioritysel' => 1,
+	'af-sprioritysel' => 1,
 	'afarea' => 1,
 	'afareaheights' => 1,
@@ -3550,26 +6466,55 @@
 	'afareaxpositions' => 1,
 	'afareaypositions' => 1,
+	'afconfig' => 1,
 	'afcp' => 1,
 	'afcp_iptc' => 1,
+	'afcsettings' => 1,
+	'aff1' => 1,
+	'aff5' => 1,
+	'affheader' => 1,
+	'affinetransformmat' => 1,
 	'afinfo' => 1,
 	'afinfo2' => 1,
 	'afinfo2version' => 1,
+	'afinfo3' => 1,
 	'afinfocus' => 1,
 	'afinfosize' => 1,
 	'afm' => 1,
-	'afmicroadj' => 1,
+	'afpointinfo' => 1,
+	'afpointsel' => 1,
 	'afpointsinfocus1d' => 1,
-	'afpointsselected' => 1,
+	'afsp' => 1,
+	'afstatus15' => 1,
+	'afstatus19' => 1,
+	'afstatus79' => 1,
 	'aftune' => 1,
+	'aibuildnumber' => 1,
+	'aicolormodel' => 1,
+	'aicolorusage' => 1,
+	'aicreatorversion' => 1,
+	'aifileformat' => 1,
 	'aimetadata' => 1,
+	'ainumlayers' => 1,
+	'aipdfprivatedata' => 1,
 	'aiprivatedata' => 1,
+	'airspeed' => 1,
+	'airulerunits' => 1,
+	'aitargetresolution' => 1,
 	'album2' => 1,
-	'albumartist' => 1,
+	'albumartistsortorder' => 1,
 	'albumcoverurl' => 1,
+	'albumid' => 1,
+	'albumidalbumartist' => 1,
 	'albumname' => 1,
 	'albumsortorder' => 1,
 	'albumtitle' => 1,
-	'albumtitleid' => 1,
+	'albumtitlesortorder' => 1,
 	'aliaslayermetadata' => 1,
+	'alignment' => 1,
+	'allcolorflatfield1' => 1,
+	'allcolorflatfield2' => 1,
+	'allcolorflatfield3' => 1,
+	'alph' => 1,
+	'alpha' => 1,
 	'alphabitdepth' => 1,
 	'alphabytecount' => 1,
@@ -3578,41 +6523,62 @@
 	'alphadatadiscard' => 1,
 	'alphafilter' => 1,
+	'alphafiltering' => 1,
 	'alphaidentifiers' => 1,
 	'alphainterlace' => 1,
+	'alphamask' => 1,
 	'alphaoffset' => 1,
+	'alphapreprocessing' => 1,
 	'alphasample' => 1,
 	'alternateduotonecolors' => 1,
+	'alternatesourceurl' => 1,
 	'alternatespotcolors' => 1,
+	'altitudefromtakeoff' => 1,
 	'ambienceinfo' => 1,
-	'animationextension' => 1,
+	'angleaxis' => 1,
+	'angularvelocity' => 1,
+	'anim' => 1,
+	'animation' => 1,
+	'animationcontrol' => 1,
+	'animationframes' => 1,
 	'animationiterations' => 1,
+	'animationloopcount' => 1,
+	'animationplays' => 1,
+	'anmf' => 1,
+	'anniversary' => 1,
 	'annotation' => 1,
 	'annotations' => 1,
 	'annotationusagerights' => 1,
+	'announce' => 1,
+	'announcelist1' => 1,
+	'anoiselines' => 1,
 	'anta' => 1,
 	'aperture' => 1,
 	'aperturedisplayed' => 1,
-	'aperturesetting' => 1,
 	'apeversion' => 1,
 	'app14flags0' => 1,
 	'app14flags1' => 1,
 	'app1_profile' => 1,
-	'applestoreaccount' => 1,
-	'applestoreaccounttype' => 1,
-	'applestorecatalogid' => 1,
-	'applestorecountry' => 1,
+	'apple-fi' => 1,
+	'appledataoffsets' => 1,
+	'applemaildatereceived' => 1,
+	'applemaildatesent' => 1,
+	'applemailflagged' => 1,
+	'applemailisremoteattachment' => 1,
+	'applemailmessageid' => 1,
+	'applemailpriority' => 1,
+	'applemailread' => 1,
+	'applemailrepliedto' => 1,
 	'application' => 1,
 	'applicationdata' => 1,
 	'applicationmissingmsg' => 1,
 	'applicationversion' => 1,
-	'appversion' => 1,
+	'applysettingstoliveview' => 1,
 	'archivallocation' => 1,
 	'archivedfilename' => 1,
-	'arranger' => 1,
-	'arrangerkeywords' => 1,
+	'ardronefile' => 1,
+	'ardronetelemetry' => 1,
 	'artist2' => 1,
 	'artistlen' => 1,
 	'artisturl' => 1,
-	'artwork' => 1,
 	'ascender' => 1,
 	'ascent' => 1,
@@ -3620,27 +6586,44 @@
 	'asfpacketcount' => 1,
 	'asfsecurityobjectssize' => 1,
+	'asin' => 1,
+	'asin2' => 1,
 	'aspectinfo' => 1,
-	'aspectratiotype' => 1,
 	'aspectratiox' => 1,
 	'aspectratioy' => 1,
+	'assistantsname' => 1,
+	'assistantsphone' => 1,
+	'associatedimagefile' => 1,
 	'association' => 1,
 	'assumeddisplaysize' => 1,
 	'assumeddistanceview' => 1,
+	'atmospherictemperature' => 1,
+	'atmospherictransalpha1' => 1,
+	'atmospherictransalpha2' => 1,
+	'atmospherictransbeta1' => 1,
+	'atmospherictransbeta2' => 1,
+	'atmospherictransx' => 1,
 	'atob0' => 1,
 	'atob1' => 1,
 	'atob2' => 1,
-	'attachedfile' => 1,
-	'attachedfiledata' => 1,
-	'attachedfiledescription' => 1,
-	'attachedfilemimetype' => 1,
-	'attachedfilename' => 1,
-	'attachedfilereferral' => 1,
-	'attachedfileuid' => 1,
+	'atsccontent' => 1,
 	'attachments' => 1,
+	'attitude' => 1,
+	'attitudetarget' => 1,
+	'attr' => 1,
+	'attributes' => 1,
+	'audible_cvrx' => 1,
+	'audible_meta' => 1,
+	'audible_meta2' => 1,
+	'audible_tags' => 1,
+	'audible_tseg' => 1,
 	'audiences' => 1,
 	'audioattributes' => 1,
+	'audioavailablebitraterange' => 1,
+	'audioavailablenumberchannels' => 1,
 	'audioavgbitrate' => 1,
-	'audiobitspersample' => 1,
+	'audiobitratecontrolmode' => 1,
 	'audiobytes' => 1,
+	'audiochannellayout' => 1,
+	'audiochanneltypes' => 1,
 	'audiocodec' => 1,
 	'audiocodecdescription' => 1,
@@ -3648,21 +6631,38 @@
 	'audiocodecinfo' => 1,
 	'audiocodecname' => 1,
+	'audiocodecprimemethod' => 1,
+	'audiocomponentversion' => 1,
+	'audiocurrenttargetbitrate' => 1,
 	'audiodelay' => 1,
+	'audiodoessamplerateconversion' => 1,
 	'audioencoding' => 1,
+	'audioencodingparamsversion' => 1,
+	'audioextendfrequencies' => 1,
 	'audiofilesize' => 1,
 	'audiofileurl' => 1,
 	'audioformat' => 1,
 	'audioframesize' => 1,
-	'audiogain' => 1,
+	'audiohasvariablepacketbytesizes' => 1,
 	'audioheader' => 1,
 	'audioinfo' => 1,
+	'audioinputbuffersize' => 1,
+	'audioisinitialized' => 1,
 	'audiolayer' => 1,
 	'audiomaxbitrate' => 1,
+	'audiomaximumpacketbytesize' => 1,
+	'audiominimumdelaymode' => 1,
+	'audiominimumnumberinputpackets' => 1,
+	'audiominimumnumberoutputpackets' => 1,
 	'audiomode' => 1,
+	'audiooutputprecedence' => 1,
+	'audiopacketframesize' => 1,
 	'audioprofile' => 1,
 	'audioprofileversion' => 1,
+	'audioqualitysetting' => 1,
+	'audiorequirespacketdescription' => 1,
 	'audiosamplecount' => 1,
 	'audiosampledesc' => 1,
 	'audiosamplesize' => 1,
+	'audiosetting' => 1,
 	'audiosize' => 1,
 	'audiosourceurl' => 1,
@@ -3670,11 +6670,34 @@
 	'audiostreamtype' => 1,
 	'audiotrackid' => 1,
+	'audiousedinputbuffersize' => 1,
+	'audiouserecommendedsamplerate' => 1,
+	'audiovbrquality' => 1,
 	'audiovendorid' => 1,
+	'audiozeroframespadded' => 1,
 	'authenticationtime' => 1,
 	'authenticationtype' => 1,
+	'authoringsoftwarerelease' => 1,
 	'authorlen' => 1,
 	'authorship' => 1,
+	'authorsortorder' => 1,
 	'authorurl' => 1,
+	'autoareaafstartingpoint' => 1,
+	'autofocusmoderestrictions' => 1,
+	'autoisomin' => 1,
+	'autolowlightduration' => 1,
+	'automationanimation' => 1,
+	'automationflags' => 1,
+	'autorotation' => 1,
+	'autosavefilepath' => 1,
+	'autosaveformat' => 1,
+	'autosummary' => 1,
 	'aux' => 1,
+	'auxiliaryimageref' => 1,
+	'auxiliaryimagetype' => 1,
+	'av1configuration' => 1,
+	'av1configurationversion' => 1,
+	'avcconfiguration' => 1,
+	'averagebitrate' => 1,
+	'averageframerate' => 1,
 	'averagelevel' => 1,
 	'avgbitrate' => 1,
@@ -3690,4 +6713,7 @@
 	'axisdistancey' => 1,
 	'axisdistancez' => 1,
+	'axml' => 1,
+	'b1' => 1,
+	'b2' => 1,
 	'background' => 1,
 	'backgroundcolor' => 1,
@@ -3700,5 +6726,6 @@
 	'backuptime' => 1,
 	'badfaxlines' => 1,
-	'balance' => 1,
+	'bahpver' => 1,
+	'balpver' => 1,
 	'band' => 1,
 	'bandwidthsharing' => 1,
@@ -3707,32 +6734,58 @@
 	'bannerimagetype' => 1,
 	'bannerimageurl' => 1,
+	'barcode' => 1,
+	'barcodes' => 1,
+	'barometerinfo' => 1,
+	'barometerinfoversion' => 1,
 	'baselinelength' => 1,
 	'baseviewpointnum' => 1,
 	'basisobject' => 1,
-	'bass' => 1,
+	'battery' => 1,
+	'batterycapacity' => 1,
+	'batterycurrent' => 1,
 	'batteryinfo' => 1,
-	'beatsperminute' => 1,
+	'batterystatus' => 1,
+	'batterytime' => 1,
+	'batteryvoltage3' => 1,
+	'batteryvoltage4' => 1,
+	'bavpver' => 1,
+	'bccaddresses' => 1,
+	'bccnames' => 1,
+	'beats-per-minute' => 1,
+	'beautycolorlevel' => 1,
+	'beautyretouchlevel' => 1,
+	'belowcolor' => 1,
+	'beta' => 1,
+	'bibligraphicfilename' => 1,
+	'bikebroaccel' => 1,
+	'bikebrogps' => 1,
+	'billinginformation' => 1,
 	'binaryfilter' => 1,
 	'binaryxml' => 1,
+	'binning' => 1,
+	'birthday' => 1,
+	'bitdepthchroma' => 1,
+	'bitdepthluma' => 1,
 	'bitrate' => 1,
+	'bitrateinfo' => 1,
 	'bitratemutualexclusion' => 1,
 	'bitsperextendedrunlength' => 1,
 	'bitsperpixel' => 1,
 	'bitsperrunlength' => 1,
-	'blackleveldeltah' => 1,
-	'blackleveldeltav' => 1,
+	'blackadcountsperdacvolt' => 1,
+	'blackclamp' => 1,
+	'blackclampoffset' => 1,
+	'blackcolsleft' => 1,
+	'blackcolsright' => 1,
+	'blackdacchannel' => 1,
+	'blackdacsettlingmsec' => 1,
 	'blackmaskbottomborder' => 1,
 	'blackmaskleftborder' => 1,
 	'blackmaskrightborder' => 1,
 	'blackmasktopborder' => 1,
-	'block' => 1,
-	'blockaddid' => 1,
-	'blockadditional' => 1,
-	'blockadditionalid' => 1,
-	'blockadditions' => 1,
-	'blockduration' => 1,
-	'blockgroup' => 1,
+	'blackrowsbottom' => 1,
+	'blackrowstop' => 1,
+	'blacktarget' => 1,
 	'blocklocation' => 1,
-	'blockmore' => 1,
 	'blocksize' => 1,
 	'blocksizemax' => 1,
@@ -3741,7 +6794,11 @@
 	'blocksperframe' => 1,
 	'blocksperrow' => 1,
-	'blockvirtual' => 1,
 	'blueadjust' => 1,
+	'blueendpoint' => 1,
 	'bluegain' => 1,
+	'bluegrassscale1' => 1,
+	'bluegrassscale2' => 1,
+	'bluegrasstable' => 1,
+	'bluemask' => 1,
 	'bluematrixcolumn' => 1,
 	'blueprimary' => 1,
@@ -3750,5 +6807,15 @@
 	'bluex' => 1,
 	'bluey' => 1,
+	'blurstrength' => 1,
+	'bmpversion' => 1,
+	'boardtemperature' => 1,
+	'bokehshape' => 1,
+	'bookname' => 1,
 	'booktitle' => 1,
+	'booktype' => 1,
+	'bookversion' => 1,
+	'bootidentifier' => 1,
+	'bootrecord' => 1,
+	'bootsystem' => 1,
 	'bordercolor' => 1,
 	'borderid' => 1,
@@ -3758,11 +6825,28 @@
 	'bordersversion' => 1,
 	'bordertype' => 1,
+	'bottomdarkrow1' => 1,
+	'bottomdarkrow2' => 1,
 	'bottommag' => 1,
 	'boundaryorigin' => 1,
 	'boundingbox' => 1,
+	'bracketincrement' => 1,
+	'bracketingburstoptions' => 1,
+	'bracketingcounter' => 1,
+	'bracketingmode' => 1,
+	'bracketingstep' => 1,
+	'bracketprogram' => 1,
+	'bracketset' => 1,
 	'bracketshot' => 1,
+	'brain' => 1,
+	'brandingimageid' => 1,
+	'brandingname' => 1,
 	'breakchar' => 1,
+	'brightdefectintegrationms' => 1,
+	'brightdefectisocode' => 1,
+	'brightdefectthreshold' => 1,
 	'brightnessdata' => 1,
+	'brightrowstop' => 1,
 	'broadcast' => 1,
+	'broadcastdate' => 1,
 	'broadcastextension' => 1,
 	'btoa0' => 1,
@@ -3774,17 +6858,39 @@
 	'btod3' => 1,
 	'bufferaverage' => 1,
+	'buffersize' => 1,
 	'builddate' => 1,
 	'buildversion' => 1,
+	'businessaddress' => 1,
+	'businesscity' => 1,
+	'businesscountry-region' => 1,
+	'businessfax' => 1,
+	'businesshomepage' => 1,
+	'businessphone' => 1,
+	'businesspobox' => 1,
+	'businesspostalcode' => 1,
+	'businessstateorprovince' => 1,
+	'businessstreet' => 1,
+	'buynow' => 1,
+	'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,
 	'cachedimagewidth' => 1,
+	'calculatedscalemax' => 1,
+	'calculatedscalemin' => 1,
 	'calibrationdatetime' => 1,
-	'camera' => 1,
+	'calibrationlog' => 1,
+	'callbacknumber' => 1,
+	'callletters' => 1,
+	'camcore' => 1,
 	'camera1' => 1,
 	'camera2' => 1,
@@ -3794,12 +6900,12 @@
 	'camerabyteorder' => 1,
 	'cameradatetime' => 1,
-	'cameradirection' => 1,
-	'cameraidentifier' => 1,
+	'cameraifd' => 1,
 	'camerainfo' => 1,
-	'camerainfo5dmkii_2a' => 1,
-	'camerainfo5dmkii_2b' => 1,
-	'camerainfo7d_2a' => 1,
-	'camerainfo7d_2b' => 1,
-	'cameramotion' => 1,
+	'camerainfo2' => 1,
+	'camerainfo3' => 1,
+	'camerainfoa100' => 1,
+	'camerainfounknown' => 1,
+	'cameramaker' => 1,
+	'cameramanufacturer' => 1,
 	'cameraname' => 1,
 	'cameraobjbacktype' => 1,
@@ -3808,12 +6914,34 @@
 	'cameraobjtype' => 1,
 	'cameraobjversion' => 1,
+	'cameraoperator' => 1,
+	'camerapan' => 1,
+	'camerapartnumber' => 1,
 	'cameraprofileversion' => 1,
+	'camerascalemax' => 1,
+	'camerascalemin' => 1,
 	'camerasettings' => 1,
 	'camerasettings2' => 1,
+	'camerasettings3' => 1,
 	'camerasettingsa100' => 1,
 	'camerasettingsifd' => 1,
 	'camerasettingsunknown' => 1,
 	'camerasetup' => 1,
+	'camerasoftware' => 1,
 	'cameraspecification' => 1,
+	'cameratemperaturemaxclip' => 1,
+	'cameratemperaturemaxsaturated' => 1,
+	'cameratemperaturemaxwarn' => 1,
+	'cameratemperatureminclip' => 1,
+	'cameratemperatureminsaturated' => 1,
+	'cameratemperatureminwarn' => 1,
+	'cameratilt' => 1,
+	'camm0' => 1,
+	'camm1' => 1,
+	'camm2' => 1,
+	'camm3' => 1,
+	'camm4' => 1,
+	'camm5' => 1,
+	'camm6' => 1,
+	'camm7' => 1,
 	'can_skip_backward' => 1,
 	'can_skip_forward' => 1,
@@ -3824,4 +6952,6 @@
 	'canonafinfo2' => 1,
 	'canoncamerainfo1000d' => 1,
+	'canoncamerainfo1100d' => 1,
+	'canoncamerainfo1200d' => 1,
 	'canoncamerainfo1d' => 1,
 	'canoncamerainfo1dmkii' => 1,
@@ -3829,4 +6959,5 @@
 	'canoncamerainfo1dmkiin' => 1,
 	'canoncamerainfo1dmkiv' => 1,
+	'canoncamerainfo1dx' => 1,
 	'canoncamerainfo40d' => 1,
 	'canoncamerainfo450d' => 1,
@@ -3836,6 +6967,15 @@
 	'canoncamerainfo5d' => 1,
 	'canoncamerainfo5dmkii' => 1,
+	'canoncamerainfo5dmkiii' => 1,
+	'canoncamerainfo600d' => 1,
 	'canoncamerainfo60d' => 1,
+	'canoncamerainfo650d' => 1,
+	'canoncamerainfo6d' => 1,
+	'canoncamerainfo700d' => 1,
+	'canoncamerainfo70d' => 1,
+	'canoncamerainfo750d' => 1,
+	'canoncamerainfo760d' => 1,
 	'canoncamerainfo7d' => 1,
+	'canoncamerainfo80d' => 1,
 	'canoncamerainfopowershot' => 1,
 	'canoncamerainfopowershot2' => 1,
@@ -3844,4 +6984,6 @@
 	'canoncamerainfounknown32' => 1,
 	'canoncamerasettings' => 1,
+	'canoncctp' => 1,
+	'canoncnop' => 1,
 	'canoncnth' => 1,
 	'canoncolorinfo1' => 1,
@@ -3855,4 +6997,5 @@
 	'canonrawmakemodel' => 1,
 	'canonshotinfo' => 1,
+	'canonskip' => 1,
 	'canseekontime' => 1,
 	'canseektoend' => 1,
@@ -3865,4 +7008,7 @@
 	'captureconditionspar' => 1,
 	'capturedevicefid' => 1,
+	'captureheightresetblacksegnormal' => 1,
+	'captureheightresetblacksegtest' => 1,
+	'captureheighttest' => 1,
 	'captureobjbacktype' => 1,
 	'captureobjname' => 1,
@@ -3873,8 +7019,12 @@
 	'captureserial' => 1,
 	'capturesetup' => 1,
+	'capturewidthresetblacksegnormal' => 1,
+	'capturewidthresetblacksegtest' => 1,
 	'capturexresolution' => 1,
 	'capturexresolutionunit' => 1,
 	'captureyresolution' => 1,
 	'captureyresolutionunit' => 1,
+	'car' => 1,
+	'carphone' => 1,
 	'casio' => 1,
 	'casiodata' => 1,
@@ -3882,44 +7032,64 @@
 	'casioquality' => 1,
 	'casioqvmi' => 1,
+	'cast' => 1,
 	'cc' => 1,
+	'ccaddresses' => 1,
 	'ccdrect' => 1,
 	'ccdvalidrect' => 1,
 	'ccdvideorect' => 1,
+	'ccnames' => 1,
+	'cddb1info' => 1,
+	'cddbdiscplaytime' => 1,
+	'cddbdisctracks' => 1,
+	'cddbtracknumber' => 1,
+	'cdetype' => 1,
+	'cdi1' => 1,
+	'cdtrackenabled' => 1,
 	'cell' => 1,
+	'cellphone' => 1,
 	'centerdarkrect' => 1,
+	'cfagreenthreshold1' => 1,
+	'cfagreenthreshold2' => 1,
 	'cfalayout' => 1,
-	'cfapattern2' => 1,
 	'cfaplanecolor' => 1,
-	'cfarepeatpatterndim' => 1,
+	'channel0lagkernel' => 1,
+	'channel1coordinates' => 1,
+	'channel1flags' => 1,
+	'channel1label' => 1,
+	'channel1lagkernel' => 1,
+	'channel2coordinates' => 1,
+	'channel2flags' => 1,
+	'channel2label' => 1,
+	'channel2lagkernel' => 1,
+	'channel3coordinates' => 1,
+	'channel3flags' => 1,
+	'channel3label' => 1,
+	'channel3lagkernel' => 1,
+	'channel4coordinates' => 1,
+	'channel4flags' => 1,
+	'channel4label' => 1,
+	'channel5coordinates' => 1,
+	'channel5flags' => 1,
+	'channel5label' => 1,
+	'channel6coordinates' => 1,
+	'channel6flags' => 1,
+	'channel6label' => 1,
+	'channel7coordinates' => 1,
+	'channel7flags' => 1,
+	'channel7label' => 1,
+	'channel8coordinates' => 1,
+	'channel8flags' => 1,
+	'channel8label' => 1,
+	'channelcoarsegainadjust' => 1,
 	'channelmode' => 1,
-	'channelpositions' => 1,
+	'channelnumber' => 1,
+	'channelusage' => 1,
 	'chapter' => 1,
-	'chapteratom' => 1,
-	'chaptercountry' => 1,
-	'chapterdisplay' => 1,
-	'chapterflagenabled' => 1,
-	'chapterflaghidden' => 1,
-	'chapterlanguage' => 1,
-	'chapterlist' => 1,
-	'chapterphysicalequivalent' => 1,
-	'chapterprocess' => 1,
-	'chapterprocesscodecid' => 1,
-	'chapterprocesscommand' => 1,
-	'chapterprocessdata' => 1,
-	'chapterprocessprivate' => 1,
-	'chapterprocesstime' => 1,
-	'chapters' => 1,
-	'chaptersegmenteditionuid' => 1,
-	'chaptersegmentuid' => 1,
-	'chapterstring' => 1,
-	'chaptertimeend' => 1,
-	'chaptertimestart' => 1,
-	'chaptertrack' => 1,
-	'chaptertracknumber' => 1,
-	'chaptertranslate' => 1,
-	'chaptertranslatecodec' => 1,
-	'chaptertranslateeditionuid' => 1,
-	'chaptertranslateid' => 1,
-	'chapteruid' => 1,
+	'chaptercount' => 1,
+	'chapterlisttrackid' => 1,
+	'chaptername' => 1,
+	'chapternum' => 1,
+	'chapternumber' => 1,
+	'characterescapesequence' => 1,
 	'characters' => 1,
 	'characterset' => 1,
@@ -3927,6 +7097,26 @@
 	'charcountwithspaces' => 1,
 	'chartarget' => 1,
+	'chartcontourinterval' => 1,
+	'chartcorrdate' => 1,
+	'chartcountryorigin' => 1,
+	'chartdepthunits' => 1,
+	'chartformat' => 1,
+	'chartmagvar' => 1,
+	'chartmagvarannchange' => 1,
+	'chartmagvaryear' => 1,
+	'chartrasteredition' => 1,
+	'chartsoundingdatum' => 1,
+	'chartsource' => 1,
+	'chartsourcedate' => 1,
+	'chartsourceedition' => 1,
+	'chartwgsnsshift' => 1,
 	'checkedby' => 1,
+	'children' => 1,
+	'chmversion' => 1,
+	'chromaformat' => 1,
+	'chromasampleposition' => 1,
+	'chromaticaberrationparams' => 1,
 	'chromaticadaptation' => 1,
+	'chromaticities' => 1,
 	'chromaticity' => 1,
 	'chromaticitychannel1' => 1,
@@ -3946,27 +7136,38 @@
 	'class' => 1,
 	'classification' => 1,
+	'cleanaperture' => 1,
+	'cleanaperturedimensions' => 1,
+	'cleanapertureheight' => 1,
+	'cleanapertureoffsetx' => 1,
+	'cleanapertureoffsety' => 1,
+	'cleanaperturewidth' => 1,
 	'cleanfaxdata' => 1,
+	'clientid' => 1,
 	'clipboundary' => 1,
 	'clipobjects' => 1,
 	'clippath' => 1,
 	'clippingboundary' => 1,
+	'clippinglimit' => 1,
 	'clippingpathname' => 1,
 	'cloneid' => 1,
 	'cloneobject' => 1,
 	'clonetype' => 1,
-	'cluster' => 1,
-	'clusterduration' => 1,
+	'closedcaptioning' => 1,
+	'cmddialsaperturesetting' => 1,
+	'cmddialschangemainsub' => 1,
+	'cmddialschangemainsubexposure' => 1,
+	'cmddialsmenuandplayback' => 1,
+	'cmddialsreverserotation' => 1,
+	'cmddialsreverserotexposurecomp' => 1,
 	'cmmflags' => 1,
+	'cmp1' => 1,
 	'cmykequivalent' => 1,
-	'codecdecodeall' => 1,
-	'codecdownloadurl' => 1,
+	'coarsedata' => 1,
+	'coarsemapimage' => 1,
+	'coarsemapimageheight' => 1,
+	'coarsemapimagetype' => 1,
+	'coarsemapimagewidth' => 1,
 	'codecflavorid' => 1,
-	'codecid' => 1,
-	'codecinfourl' => 1,
 	'codeclist' => 1,
-	'codecname' => 1,
-	'codecprivate' => 1,
-	'codecsettings' => 1,
-	'codecstate' => 1,
 	'codedframesize' => 1,
 	'codepage' => 1,
@@ -3976,5 +7177,5 @@
 	'codinghistory' => 1,
 	'codingmethods' => 1,
-	'color' => 1,
+	'codirectors' => 1,
 	'colorant1coordinates' => 1,
 	'colorant1name' => 1,
@@ -3994,16 +7195,24 @@
 	'colorbalance0205' => 1,
 	'colorbalance0209' => 1,
+	'colorbalance0211' => 1,
+	'colorbalance0213' => 1,
+	'colorbalance0215' => 1,
 	'colorbalancea' => 1,
 	'colorbalanceunknown' => 1,
+	'colorbalanceunknown02' => 1,
+	'colorbalanceunknown04' => 1,
 	'colorbitdepth' => 1,
 	'colorboostdata' => 1,
 	'colorbw' => 1,
 	'colorcalib' => 1,
+	'colorcalib2' => 1,
 	'colorcalibrationmatrix' => 1,
 	'colorcasts' => 1,
 	'colorcharacterization' => 1,
 	'colorcoefs' => 1,
+	'colorcoefs2' => 1,
 	'colorcomponents' => 1,
 	'colordata1' => 1,
+	'colordata10' => 1,
 	'colordata2' => 1,
 	'colordata3' => 1,
@@ -4011,8 +7220,12 @@
 	'colordata5' => 1,
 	'colordata6' => 1,
+	'colordata7' => 1,
+	'colordata8' => 1,
+	'colordata9' => 1,
 	'colordataunknown' => 1,
 	'colorgroup' => 1,
 	'colorhalftoninginfo' => 1,
 	'colorimetricintentimagestate' => 1,
+	'colorimetricspecification' => 1,
 	'colorimetry' => 1,
 	'colorinfo' => 1,
@@ -4023,17 +7236,30 @@
 	'colorobjversion' => 1,
 	'colorpalette' => 1,
+	'colorpopstrength' => 1,
+	'colorprimaries' => 1,
 	'colorresolutiondepth' => 1,
 	'colorresponseunit' => 1,
 	'colors' => 1,
 	'colorsamplersresource' => 1,
+	'colorsamplersresource2' => 1,
 	'colorsetup' => 1,
 	'colorspacedata' => 1,
+	'colorspecapproximation' => 1,
+	'colorspecdata' => 1,
 	'colorspecification' => 1,
+	'colorspecmethod' => 1,
+	'colorspecprecedence' => 1,
 	'colortable' => 1,
+	'colortemperatures' => 1,
 	'colortransferfuncs' => 1,
 	'colortransform' => 1,
 	'colortwistmatrix' => 1,
 	'colortype' => 1,
+	'columncount' => 1,
+	'columngainfactors' => 1,
+	'columnresetoffsets' => 1,
+	'command' => 1,
 	'commandlinearguments' => 1,
+	'commentby' => 1,
 	'commentlen' => 1,
 	'comments' => 1,
@@ -4046,9 +7272,10 @@
 	'compactsamplesizes' => 1,
 	'company' => 1,
+	'companymainphone' => 1,
 	'companyname' => 1,
 	'compatibility' => 1,
 	'compatiblebrands' => 1,
 	'compatiblefontname' => 1,
-	'compilation' => 1,
+	'complete' => 1,
 	'compobj' => 1,
 	'compobjusertype' => 1,
@@ -4057,7 +7284,8 @@
 	'componentdefinition' => 1,
 	'componentmapping' => 1,
-	'composerkeywords' => 1,
+	'componenttable' => 1,
+	'composers' => 1,
+	'composersortorder' => 1,
 	'compositinglayerheader' => 1,
-	'composition' => 1,
 	'compositionmode' => 1,
 	'compositionoptions' => 1,
@@ -4068,15 +7296,18 @@
 	'compresseddatalength' => 1,
 	'compresseddataoffset' => 1,
+	'compressedmovie' => 1,
 	'compressedsize' => 1,
 	'compressedtext' => 1,
+	'compressionclass' => 1,
 	'compressionlevel' => 1,
 	'compressiontype' => 1,
 	'compressorid' => 1,
 	'compressorname' => 1,
-	'compressorversion' => 1,
+	'computedatmospherictrans' => 1,
+	'computer' => 1,
 	'concreteflag' => 1,
 	'condition' => 1,
 	'conditionalfec' => 1,
-	'conductor' => 1,
+	'conductors' => 1,
 	'confirmedobjectsize' => 1,
 	'connectionspaceilluminant' => 1,
@@ -4084,46 +7315,51 @@
 	'consoledata' => 1,
 	'consolefedata' => 1,
+	'constantframerate' => 1,
+	'constraintindicatorflags' => 1,
 	'cont' => 1,
-	'containerformat' => 1,
+	'contactnames' => 1,
 	'containerversion' => 1,
 	'contake' => 1,
 	'contentbranding' => 1,
-	'contentcompression' => 1,
-	'contentcompressionalgorithm' => 1,
-	'contentcompressionsettings' => 1,
+	'contentdescribes' => 1,
 	'contentdescription' => 1,
 	'contentdescriptionnotes' => 1,
 	'contentdisposition' => 1,
 	'contentdistributor' => 1,
-	'contentencoding' => 1,
-	'contentencodingorder' => 1,
-	'contentencodings' => 1,
-	'contentencodingscope' => 1,
-	'contentencodingtype' => 1,
+	'contentdistributorduration' => 1,
+	'contentdistributortype' => 1,
 	'contentencryption' => 1,
-	'contentencryptionalgorithm' => 1,
-	'contentencryptionkeyid' => 1,
 	'contentgroupdescription' => 1,
 	'contentlanguage' => 1,
+	'contentprotected' => 1,
+	'contentprotectedpercent' => 1,
 	'contentrating' => 1,
 	'contents' => 1,
 	'contentscripttype' => 1,
-	'contentsignature' => 1,
-	'contentsignaturealgorithm' => 1,
-	'contentsignaturehashalgorithm' => 1,
-	'contentsignaturekeyid' => 1,
 	'contentstyletype' => 1,
-	'contenttype' => 1,
 	'contiguouscodestream' => 1,
+	'continuousmodedisplay' => 1,
 	'contrastadjustment' => 1,
-	'contrastcurve' => 1,
+	'contrastinfo' => 1,
+	'controller' => 1,
 	'convergenceangle' => 1,
 	'convergencebaseimage' => 1,
 	'convergencedistance' => 1,
+	'conversationid' => 1,
+	'copyrightfilename' => 1,
 	'copyrightlen' => 1,
 	'copyrighturl' => 1,
+	'coringtablebest' => 1,
+	'coringtablebetter' => 1,
+	'coringtablegood' => 1,
+	'correctionmethod' => 1,
 	'costumedesigner' => 1,
-	'coverart' => 1,
+	'count' => 1,
+	'countinfo' => 1,
+	'country-region' => 1,
 	'coverartmimetype' => 1,
+	'coverarttype' => 1,
+	'coyotesense' => 1,
+	'coyotestatus' => 1,
 	'cpuarchitecture' => 1,
 	'cpubyteorder' => 1,
@@ -4132,6 +7368,8 @@
 	'cputype' => 1,
 	'cpuversions' => 1,
-	'crc-32' => 1,
+	'cr2cfapattern' => 1,
+	'crc' => 1,
 	'crcdevelparams' => 1,
+	'crd' => 1,
 	'crdinfo' => 1,
 	'createdby' => 1,
@@ -4139,13 +7377,27 @@
 	'creatingtransform' => 1,
 	'creationpathvector' => 1,
-	'creatorappid' => 1,
 	'creatorapplication' => 1,
 	'creatorappversion' => 1,
+	'creatoratom' => 1,
+	'creatorbuildnumber' => 1,
+	'creatorbuildnumber2' => 1,
 	'creatorinfo' => 1,
+	'creatormajorversion' => 1,
+	'creatorminorversion' => 1,
+	'creatorsoftware' => 1,
 	'creatorversion' => 1,
+	'crgbtoerimm0spline' => 1,
+	'crgbtoerimm1spline' => 1,
+	'crgbtoerimm2spline' => 1,
+	'crgbtoerimm3spline' => 1,
+	'crgbtoerimm4spline' => 1,
+	'crgbtoerimm5spline' => 1,
+	'crgbtoerimm6spline' => 1,
+	'crgbtoerimm7spline' => 1,
+	'crgbtoerimm8spline' => 1,
+	'crgbtoerimm9spline' => 1,
 	'cropdata' => 1,
 	'cropinfo' => 1,
 	'cropped' => 1,
-	'cropx' => 1,
 	'cropxcommonoffset' => 1,
 	'cropxoffset' => 1,
@@ -4154,5 +7406,4 @@
 	'cropxviewpointnumber' => 1,
 	'cropxviewpointnumber2' => 1,
-	'cropy' => 1,
 	'cropycommonoffset' => 1,
 	'cropyoffset' => 1,
@@ -4162,20 +7413,14 @@
 	'cropyviewpointnumber2' => 1,
 	'cross-reference' => 1,
+	'crossbarenable' => 1,
 	'crossref' => 1,
 	'crs' => 1,
 	'crwparam' => 1,
-	'cueblocknumber' => 1,
-	'cueclusterposition' => 1,
-	'cuecodecstate' => 1,
+	'cs1' => 1,
+	'ctmd' => 1,
+	'cubemapproj' => 1,
 	'cuepoint' => 1,
-	'cuerefcluster' => 1,
-	'cuerefcodecstate' => 1,
-	'cuereference' => 1,
-	'cuerefnumber' => 1,
-	'cuereftime' => 1,
-	'cues' => 1,
-	'cuetime' => 1,
-	'cuetrack' => 1,
-	'cuetrackpositions' => 1,
+	'cuepoints' => 1,
+	'cuesheet' => 1,
 	'currentbitrate' => 1,
 	'currentiptcdigest' => 1,
@@ -4194,5 +7439,4 @@
 	'customfunctionsd60' => 1,
 	'customfunctionsunknown' => 1,
-	'custompicturestyledata' => 1,
 	'customsettingsd3' => 1,
 	'customsettingsd300' => 1,
@@ -4200,22 +7444,43 @@
 	'customsettingsd3s' => 1,
 	'customsettingsd3x' => 1,
+	'customsettingsd4' => 1,
 	'customsettingsd40' => 1,
+	'customsettingsd4s' => 1,
+	'customsettingsd5' => 1,
+	'customsettingsd500' => 1,
 	'customsettingsd5000' => 1,
+	'customsettingsd5100' => 1,
+	'customsettingsd5200' => 1,
+	'customsettingsd610' => 1,
 	'customsettingsd700' => 1,
 	'customsettingsd7000' => 1,
 	'customsettingsd80' => 1,
+	'customsettingsd800' => 1,
+	'customsettingsd810' => 1,
+	'customsettingsd850' => 1,
 	'customsettingsd90' => 1,
 	'd-lightinghqdata' => 1,
 	'd-lightinghsdata' => 1,
+	'd2' => 1,
+	'daccountspervolt' => 1,
+	'dacgainscoarse' => 1,
+	'dacgainscoarseadjpreif41' => 1,
+	'dacgainsfine' => 1,
+	'dacvoltages' => 1,
+	'dacvoltagesflush' => 1,
 	'darkcorrectiontype' => 1,
+	'darkmapscale' => 1,
+	'darkrefoffsetnormal' => 1,
+	'darkrefoffsettest' => 1,
+	'darkthreshold' => 1,
 	'darwindata' => 1,
 	'data' => 1,
 	'data1' => 1,
 	'data2' => 1,
+	'databasename' => 1,
 	'datacreatedate' => 1,
 	'datadump' => 1,
 	'datadump2' => 1,
 	'datainfo' => 1,
-	'datainformation' => 1,
 	'datakey' => 1,
 	'datalen' => 1,
@@ -4230,16 +7495,46 @@
 	'dataoffsets' => 1,
 	'datapackets' => 1,
+	'datapreparer' => 1,
+	'datarate' => 1,
 	'dataref' => 1,
 	'datareference' => 1,
+	'datasign' => 1,
 	'datasize' => 1,
+	'datasize64' => 1,
 	'datatype' => 1,
+	'datawindow' => 1,
+	'dateaccessed' => 1,
+	'datearchived' => 1,
 	'datecompleted' => 1,
+	'dateimported' => 1,
+	'datelastsaved' => 1,
+	'datemodified' => 1,
+	'datepicturetaken' => 1,
+	'datereceived' => 1,
+	'datereleased' => 1,
 	'datetime1' => 1,
 	'datetime2' => 1,
 	'datetimecreated' => 1,
 	'datetimeend' => 1,
+	'datetimegenerated' => 1,
+	'datevisited' => 1,
+	'daymat0' => 1,
+	'daymat1' => 1,
+	'daymat2' => 1,
+	'daymat3' => 1,
+	'daymat4' => 1,
+	'daymat5' => 1,
+	'daymat6' => 1,
+	'daymat7' => 1,
+	'daymat8' => 1,
+	'daymat9' => 1,
+	'db' => 1,
+	'dblcoldcacthres1' => 1,
+	'dblcoldcacthres2' => 1,
 	'dc' => 1,
-	'dcmd' => 1,
+	'dcem' => 1,
 	'dcme' => 1,
+	'dcs3xxprocessinginfo' => 1,
+	'dcs3xxprocessinginfoifd' => 1,
 	'dctencodeversion' => 1,
 	'dealeridnumber' => 1,
@@ -4247,17 +7542,29 @@
 	'decimationprefilterwidth' => 1,
 	'decode' => 1,
+	'decodeconfig' => 1,
 	'decodertable' => 1,
 	'decodertablenumber' => 1,
+	'decoderversion' => 1,
 	'defaultaudiostream' => 1,
 	'defaultchar' => 1,
+	'defaultcmyk' => 1,
 	'defaultdisplayheight' => 1,
 	'defaultdisplaywidth' => 1,
-	'defaultduration' => 1,
 	'defaultimagecolor' => 1,
 	'defaultrgb' => 1,
 	'defaultstyle' => 1,
+	'defectconcealartcorrectthres' => 1,
+	'defectconcealthrestable' => 1,
+	'defectcount' => 1,
+	'defectlist' => 1,
+	'defectlistpacked' => 1,
 	'defineobject' => 1,
 	'definequantizationtable' => 1,
 	'delay' => 1,
+	'delaycols' => 1,
+	'delaytime' => 1,
+	'delimiter' => 1,
+	'delta12to8spline' => 1,
+	'delta8to12spline' => 1,
 	'deltapngheader' => 1,
 	'deltatype' => 1,
@@ -4267,4 +7574,14 @@
 	'dependentimage2entrynumber' => 1,
 	'depth' => 1,
+	'depthhwheight' => 1,
+	'depthhwwidth' => 1,
+	'depthmapdata' => 1,
+	'depthmapheight' => 1,
+	'depthmapname' => 1,
+	'depthmaptiff' => 1,
+	'depthmapwidth' => 1,
+	'depthswheight' => 1,
+	'depthswwidth' => 1,
+	'derivedimageref' => 1,
 	'descender' => 1,
 	'designer' => 1,
@@ -4272,5 +7589,13 @@
 	'desiredreproductions' => 1,
 	'destinationid' => 1,
+	'detectedfacebounds' => 1,
+	'detectedfaceid' => 1,
+	'detectedfacerollangle' => 1,
+	'detectedfaceyawangle' => 1,
+	'detector' => 1,
+	'detectorboard' => 1,
 	'deviceattributes' => 1,
+	'devicecontainer' => 1,
+	'deviceid' => 1,
 	'devicemanufacturer' => 1,
 	'devicemfgdesc' => 1,
@@ -4278,8 +7603,13 @@
 	'devicemodeldesc' => 1,
 	'devicename' => 1,
+	'deviceorientation' => 1,
 	'devicesettings' => 1,
 	'dex' => 1,
+	'dialect' => 1,
 	'dicom' => 1,
 	'dictionary' => 1,
+	'dictionaryshortname' => 1,
+	'difftilegains24t852822' => 1,
+	'difftilegains602832' => 1,
 	'digikam' => 1,
 	'digitalcreationdatetime' => 1,
@@ -4287,16 +7617,18 @@
 	'digitaleffectstype' => 1,
 	'digitaleffectsversion' => 1,
+	'digitalexposurebiases' => 1,
+	'digitalexposuregains' => 1,
 	'digitalimagebroker' => 1,
 	'digitalsignature' => 1,
 	'dimensions' => 1,
+	'directors' => 1,
+	'disableflagspresent' => 1,
 	'discardobjects' => 1,
-	'disknumber' => 1,
-	'displayheight' => 1,
+	'displayartist' => 1,
 	'displayinfo' => 1,
 	'displayresolution' => 1,
 	'displaysize' => 1,
-	'displayunit' => 1,
 	'displayunits' => 1,
-	'displaywidth' => 1,
+	'displaywindow' => 1,
 	'displayxresolution' => 1,
 	'displayxresolutionunit' => 1,
@@ -4305,19 +7637,34 @@
 	'dispose' => 1,
 	'disposition' => 1,
+	'distance' => 1,
+	'distancefromhome' => 1,
 	'distortinfo' => 1,
+	'distortioninfo' => 1,
 	'distortionversion' => 1,
 	'distributedby' => 1,
 	'distribution' => 1,
+	'dittokey' => 1,
 	'division' => 1,
+	'dji_dtat' => 1,
 	'djvuversion' => 1,
-	'dngadobedata' => 1,
-	'dngprivatedata' => 1,
+	'dlnaserverudn' => 1,
+	'dlnasourceuri' => 1,
+	'dlodata' => 1,
+	'dlodatalength' => 1,
+	'dloinfo' => 1,
+	'dmeroderadius' => 1,
+	'dmfillrejthresh' => 1,
+	'dmnoisescale' => 1,
+	'dmnumpatches' => 1,
+	'dmpixelthresholdfactor' => 1,
+	'dmsmoothrejthresh' => 1,
+	'dmtrimfraction' => 1,
+	'dmwindowthresholdfactor' => 1,
 	'docclass' => 1,
+	'docflags' => 1,
 	'docmdp' => 1,
 	'docrights' => 1,
 	'docsecurity' => 1,
 	'doctype' => 1,
-	'doctypereadversion' => 1,
-	'doctypeversion' => 1,
 	'documentinfo' => 1,
 	'documentnumber' => 1,
@@ -4325,6 +7672,22 @@
 	'dof' => 1,
 	'donotshow' => 1,
+	'dop' => 1,
+	'dotrange' => 1,
 	'dotsperinch' => 1,
+	'downsampleby2hor' => 1,
+	'downsampleby2hor3mpdcr' => 1,
+	'downsampleby2ver' => 1,
+	'downsampleby2ver3mpdcr' => 1,
+	'downsampleby3hor' => 1,
+	'downsampleby3ver' => 1,
+	'downsampleby4hor' => 1,
+	'downsampleby4ver' => 1,
+	'downsampleby6hor' => 1,
+	'downsampleby6ver' => 1,
+	'dpxfilesize' => 1,
+	'dr4' => 1,
+	'dr4header' => 1,
 	'driveserialnumber' => 1,
+	'drivesettings' => 1,
 	'drivetype' => 1,
 	'drm' => 1,
@@ -4337,4 +7700,5 @@
 	'drm_drmheader_licenseacqurl' => 1,
 	'drm_drmheader_subscriptioncontentid' => 1,
+	'drm_e-bookbaseid' => 1,
 	'drm_individualizedversion' => 1,
 	'drm_keyid' => 1,
@@ -4345,52 +7709,89 @@
 	'drm_licenseacqurl' => 1,
 	'drm_v1licenseacqurl' => 1,
+	'drmcommerceid' => 1,
+	'drmindividualizedversion' => 1,
+	'drmkeyid' => 1,
+	'drmserverid' => 1,
+	'drone-dji' => 1,
+	'dronepitch' => 1,
+	'dronequaternion' => 1,
+	'droneroll' => 1,
+	'droneyaw' => 1,
 	'dropbykeyword' => 1,
 	'dropchunks' => 1,
+	'dtcpiphost' => 1,
+	'dtcpipport' => 1,
 	'dtob0' => 1,
 	'dtob1' => 1,
 	'dtob2' => 1,
 	'dtob3' => 1,
+	'dtvcontent' => 1,
+	'dualcameraimage' => 1,
+	'dualcameraimagename' => 1,
+	'dualshotextra' => 1,
 	'ducky' => 1,
+	'duedate' => 1,
+	'dummycolsleft' => 1,
+	'dummycolsright' => 1,
 	'duotonehalftoninginfo' => 1,
 	'duotoneimageinfo' => 1,
 	'duotonetransferfuncs' => 1,
+	'dustdeleteapplied' => 1,
+	'dustinfo' => 1,
 	'dvdid' => 1,
-	'ebmlheader' => 1,
-	'ebmlmaxidlength' => 1,
-	'ebmlmaxsizelength' => 1,
-	'ebmlreadversion' => 1,
-	'ebmlversion' => 1,
-	'edit1' => 1,
-	'edit2' => 1,
-	'edit3' => 1,
-	'edit4' => 1,
-	'edit5' => 1,
-	'edit6' => 1,
-	'edit7' => 1,
-	'edit8' => 1,
-	'edit9' => 1,
+	'dwc' => 1,
+	'dynamicareaafassist' => 1,
+	'e-mail2' => 1,
+	'e-mail3' => 1,
+	'e-mailaddress' => 1,
+	'e-maildisplayname' => 1,
+	'e-maillist' => 1,
+	'edgespline' => 1,
+	'edgesplinehigh' => 1,
+	'edgesplinelow' => 1,
+	'edgesplinemed' => 1,
+	'edit4data' => 1,
 	'editdata' => 1,
 	'editedby' => 1,
-	'editionentry' => 1,
-	'editionflagdefault' => 1,
-	'editionflaghidden' => 1,
-	'editionflagordered' => 1,
-	'editionuid' => 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,
+	'embeddedaudiofilename' => 1,
 	'embeddedfile' => 1,
 	'embeddedfilename' => 1,
 	'embeddedfileusagerights' => 1,
+	'embeddedimage' => 1,
+	'embeddedimagecolorspace' => 1,
+	'embeddedimagefilter' => 1,
+	'embeddedimageheight' => 1,
+	'embeddedimagename' => 1,
+	'embeddedimagetype' => 1,
+	'embeddedimagewidth' => 1,
+	'embeddedjpg' => 1,
+	'embeddedpng' => 1,
+	'embeddedvideo' => 1,
+	'embeddedvideofile' => 1,
+	'embeddedvideotype' => 1,
 	'emphasis' => 1,
-	'encodedby' => 1,
+	'empty' => 1,
+	'encodedpixelsdimensions' => 1,
 	'encodedusing' => 1,
-	'encoder' => 1,
+	'encoderoptions' => 1,
 	'encodersettings' => 1,
+	'encodervendor' => 1,
 	'encoderversion' => 1,
+	'encodetime' => 1,
 	'encoding' => 1,
+	'encodingparams' => 1,
 	'encodingprocess' => 1,
 	'encodingscheme' => 1,
@@ -4398,12 +7799,14 @@
 	'encodingtime' => 1,
 	'encrypt' => 1,
-	'encryptedblock' => 1,
 	'encryption' => 1,
+	'enddate' => 1,
+	'endianness' => 1,
 	'endpoints' => 1,
 	'endtime' => 1,
 	'endtimecode' => 1,
 	'entrypoint' => 1,
+	'entrytype' => 1,
+	'environmentmap' => 1,
 	'envvardata' => 1,
-	'episodeglobaluniqueid' => 1,
 	'eppim' => 1,
 	'eprint' => 1,
@@ -4411,15 +7814,46 @@
 	'equipment' => 1,
 	'equipmentifd' => 1,
+	'equirectangularproj' => 1,
+	'erimmnonlinearityspline' => 1,
+	'erimmtocrgb0spline' => 1,
+	'erimmtocrgb1spline' => 1,
+	'erimmtocrgb2spline' => 1,
+	'erimmtocrgb3spline' => 1,
+	'erimmtocrgb4spline' => 1,
+	'erimmtocrgb5spline' => 1,
+	'erimmtocrgb6spline' => 1,
+	'erimmtocrgb7spline' => 1,
+	'erimmtocrgb8spline' => 1,
+	'erimmtocrgb9spline' => 1,
+	'erimmtonescale0spline' => 1,
+	'erimmtonescale1spline' => 1,
+	'erimmtonescale2spline' => 1,
+	'erimmtonescale3spline' => 1,
+	'erimmtonescale4spline' => 1,
+	'erimmtonescale5spline' => 1,
+	'erimmtonescale6spline' => 1,
+	'erimmtonescale7spline' => 1,
+	'erimmtonescale8spline' => 1,
+	'erimmtonescale9spline' => 1,
 	'error' => 1,
 	'errorcorrection' => 1,
 	'errorcorrectiontype' => 1,
+	'escapestatus' => 1,
 	'escchar' => 1,
+	'estimatedatmospherictrans' => 1,
 	'evalstate' => 1,
+	'eventlogcapture' => 1,
+	'eventlogprocess' => 1,
 	'events' => 1,
 	'evstepinfo' => 1,
 	'exif_profile' => 1,
 	'exifdata' => 1,
+	'exifex' => 1,
+	'exififd' => 1,
 	'exifinfo' => 1,
 	'exifinfo2' => 1,
+	'exifinfo7' => 1,
+	'exifinfo8' => 1,
+	'exifinfo9' => 1,
 	'exifinformation' => 1,
 	'exifoffset' => 1,
@@ -4431,17 +7865,27 @@
 	'expandscanner' => 1,
 	'expandsoftware' => 1,
+	'expirationspan' => 1,
 	'expires' => 1,
 	'exportimage' => 1,
 	'exposurebias' => 1,
+	'exposureheadroomfactor' => 1,
 	'exposureinfo' => 1,
+	'exposurereferencegain' => 1,
+	'exposurereferenceoffset' => 1,
+	'exposuretimes' => 1,
 	'exposureunknown' => 1,
+	'expressionmedia' => 1,
+	'exrversion' => 1,
 	'extcache' => 1,
+	'extendedalbumname' => 1,
+	'extendedartistname' => 1,
 	'extendedaviheader' => 1,
 	'extendedcontentdescr' => 1,
 	'extendedcontentencryption' => 1,
 	'extendedinfo' => 1,
+	'extendedshutterspeeds' => 1,
 	'extendedstreamprops' => 1,
+	'extendedtracktitle' => 1,
 	'extendedxmp' => 1,
-	'extenderstatus' => 1,
 	'extensionclassid' => 1,
 	'extensioncreatedate' => 1,
@@ -4451,7 +7895,14 @@
 	'extensionpersistence' => 1,
 	'extensions' => 1,
+	'extensis' => 1,
 	'externalleading' => 1,
+	'externaltriggercount' => 1,
 	'extraflags' => 1,
+	'extrainfo' => 1,
+	'extrainfo2' => 1,
+	'extrainfo3' => 1,
 	'extrasamples' => 1,
+	'extraticklocations' => 1,
+	'f-stop' => 1,
 	'face1birthday' => 1,
 	'face1category' => 1,
@@ -4480,13 +7931,22 @@
 	'facedetect1' => 1,
 	'facedetect2' => 1,
+	'facedetect3' => 1,
+	'facedetected' => 1,
 	'facedetinfo' => 1,
 	'faceinfo' => 1,
 	'faceinfo1' => 1,
 	'faceinfo2' => 1,
+	'faceinfoa' => 1,
 	'faceinfolength' => 1,
 	'faceinfooffset' => 1,
+	'faceitem' => 1,
+	'facenumbers' => 1,
 	'facepos' => 1,
+	'facerec' => 1,
 	'facerecinfo' => 1,
 	'facesize' => 1,
+	'factorywhitegainsdaylight' => 1,
+	'factorywhiteoffsetsdaylight' => 1,
+	'farklewhitethreshold' => 1,
 	'fastseek' => 1,
 	'faxprofile' => 1,
@@ -4494,13 +7954,31 @@
 	'faxrecvtime' => 1,
 	'faxsubaddress' => 1,
+	'fdsc' => 1,
+	'fedexedr' => 1,
+	'fffheader' => 1,
 	'fieldmdp' => 1,
 	'fieldpermissions' => 1,
 	'fifthlanguage' => 1,
+	'file1duration' => 1,
+	'file1length' => 1,
+	'file1md5sum' => 1,
+	'file1media' => 1,
+	'file1path' => 1,
+	'file1pathutf-8' => 1,
+	'fileaccessdate' => 1,
+	'fileas' => 1,
 	'fileattributes' => 1,
+	'fileblockcount' => 1,
+	'fileblocksize' => 1,
+	'filecount' => 1,
 	'filedescription' => 1,
+	'filedeviceid' => 1,
+	'filedevicenumber' => 1,
 	'fileflags' => 1,
 	'fileflagsmask' => 1,
 	'filefunctionflags' => 1,
 	'fileglobalprofile' => 1,
+	'fileguid' => 1,
+	'filehardlinks' => 1,
 	'fileid' => 1,
 	'fileinfo' => 1,
@@ -4509,15 +7987,19 @@
 	'fileinfoproperties' => 1,
 	'fileinfoversion' => 1,
+	'fileinodechangedate' => 1,
+	'fileinodenumber' => 1,
 	'filelength' => 1,
 	'fileos' => 1,
 	'fileowner' => 1,
-	'filepermissions' => 1,
+	'filepath' => 1,
 	'fileprofileversion' => 1,
 	'fileproperties' => 1,
 	'files' => 1,
+	'filesequence' => 1,
 	'filesize' => 1,
 	'filesizebytes' => 1,
 	'filesubtype' => 1,
 	'filetype' => 1,
+	'filetypeextension' => 1,
 	'fileurl' => 1,
 	'fileversionnumber' => 1,
@@ -4534,11 +8016,28 @@
 	'filterinfo' => 1,
 	'filtering' => 1,
+	'filtermodel' => 1,
+	'filterpartnumber' => 1,
+	'filterserialnumber' => 1,
+	'finalflushsequence' => 1,
 	'finalframeblocks' => 1,
+	'finishedfileprocessingrequest' => 1,
+	'finishipaversion' => 1,
+	'finishipfversion' => 1,
 	'firmwareinfo' => 1,
 	'firstchar' => 1,
+	'firstflushsequence' => 1,
 	'firstlanguage' => 1,
+	'firstlines' => 1,
+	'firstlinetransfertiming' => 1,
+	'firstname' => 1,
 	'firstobject' => 1,
 	'firstobjectid' => 1,
+	'fisheyefilter' => 1,
+	'flac' => 1,
+	'flagcolor' => 1,
 	'flags' => 1,
+	'flagstatus' => 1,
+	'flashattributes' => 1,
+	'flashburstpriority' => 1,
 	'flashexpcomp' => 1,
 	'flashinfo' => 1,
@@ -4546,7 +8045,19 @@
 	'flashinfo0102' => 1,
 	'flashinfo0103' => 1,
-	'flashinfo0104' => 1,
+	'flashinfo0106' => 1,
+	'flashinfo0107' => 1,
+	'flashinfo0300' => 1,
 	'flashinfounknown' => 1,
 	'flashinfoversion' => 1,
+	'flashmat0' => 1,
+	'flashmat1' => 1,
+	'flashmat2' => 1,
+	'flashmat3' => 1,
+	'flashmat4' => 1,
+	'flashmat5' => 1,
+	'flashmat6' => 1,
+	'flashmat7' => 1,
+	'flashmat8' => 1,
+	'flashmat9' => 1,
 	'flashpixstreamfieldoffset' => 1,
 	'flashpixstreampathname' => 1,
@@ -4554,27 +8065,68 @@
 	'flashsyncmode' => 1,
 	'flashttlmode' => 1,
+	'flashused' => 1,
 	'flashversion' => 1,
 	'flavor' => 1,
+	'flickadvancedirection' => 1,
+	'flickerreductionshooting' => 1,
+	'flipstatus' => 1,
+	'flir' => 1,
+	'flir_gps' => 1,
+	'flir_moreinfo' => 1,
+	'flir_params' => 1,
+	'flir_parts' => 1,
+	'flir_serial' => 1,
+	'flir_unknown' => 1,
+	'flir_unknownuuid' => 1,
+	'fluormat0' => 1,
+	'fluormat1' => 1,
+	'fluormat2' => 1,
+	'fluormat3' => 1,
+	'fluormat4' => 1,
+	'fluormat5' => 1,
+	'fluormat6' => 1,
+	'fluormat7' => 1,
+	'fluormat8' => 1,
+	'fluormat9' => 1,
+	'flushtiming' => 1,
+	'flyingstate' => 1,
+	'focalinfo' => 1,
 	'focallength35efl' => 1,
+	'focallength35mm' => 1,
 	'focalplanecolorimetryestimates' => 1,
 	'focalrange' => 1,
+	'focusdistance2' => 1,
+	'focusedgemap' => 1,
 	'focusinfo' => 1,
 	'focusinfoifd' => 1,
+	'focuspeakinghighlightcolor' => 1,
+	'focuspeakinglevel' => 1,
+	'focuspointbrightness' => 1,
+	'focuspointpersistence' => 1,
 	'focuspos' => 1,
+	'focussettings' => 1,
+	'folder' => 1,
+	'folderpath' => 1,
+	'follow-meanimation' => 1,
+	'follow-memode' => 1,
 	'font' => 1,
 	'fontsize' => 1,
 	'fontsubfamily' => 1,
 	'fontsubfamilyid' => 1,
+	'fonttable' => 1,
 	'fontweight' => 1,
 	'footerposition' => 1,
 	'footnotes' => 1,
 	'form' => 1,
+	'formattag' => 1,
 	'formatter' => 1,
 	'formatversion' => 1,
 	'formatversiontime' => 1,
+	'formextrausagerights' => 1,
 	'formfields' => 1,
 	'formusagerights' => 1,
 	'forwardto' => 1,
 	'fotostation' => 1,
+	'fourcc' => 1,
 	'fourcc1' => 1,
 	'fourcc2' => 1,
@@ -4584,4 +8136,7 @@
 	'fourthlanguage' => 1,
 	'fov' => 1,
+	'fovcot' => 1,
+	'fpfversion' => 1,
+	'fpv' => 1,
 	'fpxr' => 1,
 	'fractalparameters' => 1,
@@ -4589,30 +8144,61 @@
 	'fragmenttable' => 1,
 	'frame' => 1,
-	'frameheight' => 1,
+	'framebaseview' => 1,
+	'frameexposuretime' => 1,
+	'frameid' => 1,
 	'frameinfo' => 1,
 	'framepriority' => 1,
-	'framereadouttime' => 1,
 	'framesize' => 1,
 	'framesizemax' => 1,
 	'framesizemin' => 1,
-	'framewidth' => 1,
+	'framespersecond' => 1,
+	'frameview' => 1,
+	'framinggriddisplay' => 1,
 	'free' => 1,
+	'free-busystatus' => 1,
 	'freebytecounts' => 1,
 	'freeoffsets' => 1,
+	'frequency' => 1,
+	'fromaddresses' => 1,
+	'fromnames' => 1,
 	'fstype' => 1,
 	'fujifilm' => 1,
 	'fujifilmffmv' => 1,
 	'fujifilmmvtg' => 1,
+	'fujifilmtags' => 1,
+	'fujiifd' => 1,
 	'fujilayout' => 1,
 	'fullname' => 1,
 	'fullscreen' => 1,
+	'fusion360fly' => 1,
+	'fusionmode' => 1,
+	'fusionypr' => 1,
 	'gain' => 1,
+	'gaindeaddata' => 1,
+	'gaindeadmapimage' => 1,
+	'gaindeadmapimageheight' => 1,
+	'gaindeadmapimagetype' => 1,
+	'gaindeadmapimagewidth' => 1,
+	'gammablue' => 1,
+	'gammagreen' => 1,
+	'gammainfo' => 1,
+	'gammared' => 1,
+	'gammatable' => 1,
 	'gamut' => 1,
 	'gapless' => 1,
-	'gdalmetadata' => 1,
-	'gdalnodata' => 1,
+	'gaudio' => 1,
+	'gaussianweights' => 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,
 	'gengraphicsmode' => 1,
@@ -4621,6 +8207,6 @@
 	'genmediaversion' => 1,
 	'genopcolor' => 1,
+	'genprofilecompatibilityflags' => 1,
 	'genr' => 1,
-	'genreid' => 1,
 	'geo' => 1,
 	'geogangularunits' => 1,
@@ -4638,20 +8224,67 @@
 	'geogsemimajoraxis' => 1,
 	'geogsemiminoraxis' => 1,
-	'geotiffasciiparams' => 1,
-	'geotiffdirectory' => 1,
-	'geotiffdoubleparams' => 1,
+	'geogtowgs84' => 1,
+	'geometricdistortionparams' => 1,
 	'geotiffversion' => 1,
+	'getty' => 1,
+	'gfocus' => 1,
+	'gidcver' => 1,
+	'gidpver' => 1,
 	'gifapplicationextension' => 1,
 	'gifgraphiccontrolextension' => 1,
 	'gifplaintextextension' => 1,
 	'gifversion' => 1,
+	'gimage' => 1,
+	'gimbalpitch' => 1,
+	'gimbalroll' => 1,
+	'gimbalyaw' => 1,
+	'gipc_cpld' => 1,
+	'gipcver' => 1,
+	'givenname' => 1,
+	'gixiver' => 1,
 	'globalinfo' => 1,
 	'globalparametersifd' => 1,
 	'globalpixelsize' => 1,
 	'googlebot' => 1,
+	'gopro' => 1,
+	'goprogpmf' => 1,
+	'gpano' => 1,
+	'gpmd_gopro' => 1,
+	'gpmd_rove' => 1,
 	'gps' => 1,
-	'gpscoordinates' => 1,
+	'gps360fly' => 1,
+	'gpsaltituderaw' => 1,
+	'gpsdatalist' => 1,
+	'gpsdatalist2' => 1,
+	'gpsdatetimeraw' => 1,
+	'gpsdestaltitude' => 1,
+	'gpsframingaltitude' => 1,
+	'gpsframinglatitude' => 1,
+	'gpsframinglongitude' => 1,
+	'gpshorizontalaccuracy' => 1,
 	'gpsinfo' => 1,
+	'gpslatituderaw' => 1,
+	'gpslog' => 1,
+	'gpslongituderaw' => 1,
+	'gpsmode' => 1,
+	'gpspos' => 1,
 	'gpsposition' => 1,
+	'gpsraw' => 1,
+	'gpsspeed3d' => 1,
+	'gpsspeedaccuracy' => 1,
+	'gpsspeedraw' => 1,
+	'gpsspeedx' => 1,
+	'gpsspeedy' => 1,
+	'gpsspeedz' => 1,
+	'gpstargetaltitude' => 1,
+	'gpstargetlatitude' => 1,
+	'gpstargetlongitude' => 1,
+	'gpstrackraw' => 1,
+	'gpsvalid' => 1,
+	'gpsvelocitydown' => 1,
+	'gpsvelocityeast' => 1,
+	'gpsvelocitynorth' => 1,
+	'gpsvelocityup' => 1,
+	'gpsverticalaccuracy' => 1,
 	'grainybwfilter' => 1,
 	'graphicconverter' => 1,
@@ -4661,5 +8294,7 @@
 	'graytrc' => 1,
 	'greenadjust' => 1,
+	'greenendpoint' => 1,
 	'greengain' => 1,
+	'greenmask' => 1,
 	'greenmatrixcolumn' => 1,
 	'greenprimary' => 1,
@@ -4669,11 +8304,18 @@
 	'greeny' => 1,
 	'gridguidesinfo' => 1,
-	'group' => 1,
+	'groupareac1' => 1,
+	'groupareac2' => 1,
 	'groupcaption' => 1,
-	'grouping' => 1,
 	'groupmutualexclusion' => 1,
+	'groups' => 1,
+	'gsensor' => 1,
+	'gspherical' => 1,
 	'gtcitation' => 1,
 	'gtmodeltype' => 1,
 	'gtrastertype' => 1,
+	'gyro360fly' => 1,
+	'gyromode' => 1,
+	'gyroscope' => 1,
+	'gyroypr' => 1,
 	'handler' => 1,
 	'handlerclass' => 1,
@@ -4681,26 +8323,42 @@
 	'handlertype' => 1,
 	'handlervendorid' => 1,
+	'hardpostpadding' => 1,
+	'hardprepadding' => 1,
 	'hasarbitrarydatastream' => 1,
 	'hasattachedimages' => 1,
+	'hasattachments' => 1,
 	'hasaudio' => 1,
 	'hascolormap' => 1,
 	'hascuepoints' => 1,
 	'hasfiletransferstream' => 1,
+	'hasflag' => 1,
 	'hasicc' => 1,
 	'hasimage' => 1,
 	'haskeyframes' => 1,
 	'hasmetadata' => 1,
+	'hasrealmergeddata' => 1,
 	'hasscript' => 1,
+	'hasselbladexif' => 1,
+	'hasselbladrawimage' => 1,
 	'hasvideo' => 1,
+	'hasxfa' => 1,
 	'hcusage' => 1,
+	'hdcontent' => 1,
+	'hdrinfo' => 1,
 	'hdrl' => 1,
-	'hdvideo' => 1,
+	'hdrtoninginfo' => 1,
 	'header' => 1,
+	'header4' => 1,
 	'headerext' => 1,
 	'headerextension' => 1,
 	'headersize' => 1,
+	'headerversion' => 1,
 	'headingpairs' => 1,
 	'heightresolution' => 1,
+	'hevcconfiguration' => 1,
+	'hevcconfigurationversion' => 1,
 	'hiddenslides' => 1,
+	'highbitdepth' => 1,
+	'highisomode' => 1,
 	'highlightdata' => 1,
 	'highlightendpoints' => 1,
@@ -4710,15 +8368,43 @@
 	'hintsampledesc' => 1,
 	'hinttrackinfo' => 1,
+	'hinttrackversion' => 1,
+	'histogram' => 1,
 	'historybuffersize' => 1,
+	'hmaphandling' => 1,
+	'hmcolrejthresh' => 1,
+	'hmcolthresh' => 1,
+	'hmpixthresh' => 1,
+	'hmwsize' => 1,
+	'hobbies' => 1,
+	'homeaddress' => 1,
+	'homecity' => 1,
+	'homecountry-region' => 1,
+	'homefax' => 1,
+	'homephone' => 1,
+	'homepobox' => 1,
+	'homepostalcode' => 1,
+	'homestateorprovince' => 1,
+	'homestreet' => 1,
+	'horizontalresolution' => 1,
+	'horizontalscale' => 1,
+	'hostsoftwareexportversion' => 1,
 	'hotkey' => 1,
 	'howpublished' => 1,
 	'hp_tdhd' => 1,
+	'hrnoiselines' => 1,
+	'htcbinary' => 1,
+	'htcinfo' => 1,
+	'htctrack' => 1,
 	'http-equiv' => 1,
 	'httphostheader' => 1,
+	'huawei' => 1,
 	'huffmantable' => 1,
+	'huffmantablelength' => 1,
+	'huffmantablevalue' => 1,
 	'hyperfocaldistance' => 1,
 	'hyperlinkbase' => 1,
 	'hyperlinks' => 1,
 	'hyperlinkschanged' => 1,
+	'iad1' => 1,
 	'icc_untagged' => 1,
 	'iccbased' => 1,
@@ -4726,4 +8412,5 @@
 	'iconfilename' => 1,
 	'iconindex' => 1,
+	'ics' => 1,
 	'id' => 1,
 	'id3' => 1,
@@ -4737,12 +8424,25 @@
 	'idc_ifd' => 1,
 	'idcpreviewimage' => 1,
-	'identification' => 1,
 	'idependentanddisposablesamples' => 1,
+	'idlesequence' => 1,
+	'idletiming' => 1,
 	'idsbasevalue' => 1,
+	'ifd0' => 1,
 	'ifd0_offset' => 1,
 	'ihl_exif' => 1,
 	'ihldata' => 1,
+	'illuminantdetectordata' => 1,
+	'illuminantdetecttable' => 1,
 	'illustrator' => 1,
+	'im' => 1,
+	'imaddresses' => 1,
 	'image' => 1,
+	'image2description' => 1,
+	'image3description' => 1,
+	'image4description' => 1,
+	'image5description' => 1,
+	'image6description' => 1,
+	'image7description' => 1,
+	'image8description' => 1,
 	'imagearrangement' => 1,
 	'imageboardid' => 1,
@@ -4753,9 +8453,16 @@
 	'imagecolorindicator' => 1,
 	'imagecolorvalue' => 1,
-	'imagedata' => 1,
+	'imagecompressiontable' => 1,
 	'imagedatadiscard' => 1,
+	'imagedataoffset' => 1,
 	'imagedepth' => 1,
+	'imageelements' => 1,
+	'imageexpansiontable' => 1,
 	'imagefields' => 1,
+	'imagefilecharacteristics' => 1,
+	'imagefilename' => 1,
 	'imageformat' => 1,
+	'imagefullheight' => 1,
+	'imagefullwidth' => 1,
 	'imageheader' => 1,
 	'imageid' => 1,
@@ -4763,5 +8470,11 @@
 	'imagelayer' => 1,
 	'imagelength' => 1,
+	'imagelimitexposurebias' => 1,
+	'imagemagnificationdescriptor' => 1,
+	'imagemedium' => 1,
+	'imagemodulationexposurebias' => 1,
 	'imageoffset' => 1,
+	'imagepixeldepth' => 1,
+	'imagepixelformat' => 1,
 	'imageprintstatus' => 1,
 	'imageprocessingifd' => 1,
@@ -4769,14 +8482,21 @@
 	'imageprops' => 1,
 	'imagerboardid' => 1,
-	'imageresolution' => 1,
+	'imagereadydatasets' => 1,
+	'imagereadyvariables' => 1,
+	'imagereferencepoints' => 1,
 	'imageresources' => 1,
-	'imagerotated' => 1,
+	'imagerinitialtimingcode' => 1,
+	'imagerlogicprogram' => 1,
 	'imagerotation' => 1,
 	'imagerotationstatus' => 1,
+	'imagertimingdata' => 1,
+	'imagesensorgain' => 1,
 	'imagesourceek' => 1,
+	'imagespatialextent' => 1,
 	'imagestatus' => 1,
 	'imagetoolbar' => 1,
 	'imageuidlist' => 1,
 	'imageversion' => 1,
+	'imageworkstationmake' => 1,
 	'imgprofbacktype' => 1,
 	'imgprofname' => 1,
@@ -4784,5 +8504,11 @@
 	'imgprofversion' => 1,
 	'immediatedatabytes' => 1,
+	'importance' => 1,
+	'imprint' => 1,
+	'inbandratingattributes' => 1,
+	'inbandratinglevel' => 1,
+	'inbandratingsystem' => 1,
 	'includedfileid' => 1,
+	'incomplete' => 1,
 	'index' => 1,
 	'index01' => 1,
@@ -4804,26 +8530,35 @@
 	'indexable' => 1,
 	'indexed' => 1,
-	'indexedcolourtablecount' => 1,
+	'indexedcolortablecount' => 1,
 	'indexoffset' => 1,
 	'indexparameters' => 1,
+	'indications' => 1,
 	'info' => 1,
-	'information' => 1,
 	'ingrreserved' => 1,
+	'initialdelaysamples' => 1,
 	'initialdisplayeffect' => 1,
+	'initializationvector' => 1,
 	'initializeddatasize' => 1,
 	'initialkey' => 1,
 	'initialobjectdescriptor' => 1,
+	'initials' => 1,
 	'inknames' => 1,
 	'inputdataobjectlist' => 1,
-	'inputprofile' => 1,
+	'inputdevicename' => 1,
+	'inputdeviceserialnumber' => 1,
+	'inputheight' => 1,
+	'inputwidth' => 1,
 	'insertmode' => 1,
+	'insetnwpixelx' => 1,
+	'insetnwpixely' => 1,
+	'insta360' => 1,
 	'institution' => 1,
 	'instructionset' => 1,
-	'integrationtime' => 1,
+	'insv' => 1,
+	'integratetiming' => 1,
 	'intellectualproperty' => 1,
 	'intellectualpropertynotes' => 1,
 	'intensitystereo' => 1,
 	'intergraphflagregisters' => 1,
-	'intergraphmatrix' => 1,
 	'intergraphpacketdata' => 1,
 	'interlace' => 1,
@@ -4838,8 +8573,15 @@
 	'internetradiostationurl' => 1,
 	'interopoffset' => 1,
+	'interpolationcoefficients' => 1,
+	'interpolationcoefficients3mp' => 1,
+	'interpolationcoefficients6mp' => 1,
 	'interpretedby' => 1,
+	'inversemonitormatrix' => 1,
+	'inverserimnonlinearity' => 1,
+	'inversesbalog12transform' => 1,
+	'inversesbalogtransform' => 1,
+	'invnifnonlinearity' => 1,
 	'involvedpeople' => 1,
 	'ipmpcontrol' => 1,
-	'iptc' => 1,
 	'iptc_profile' => 1,
 	'iptcapplication' => 1,
@@ -4853,13 +8595,28 @@
 	'iptcpostobjectdata' => 1,
 	'iptcpreobjectdata' => 1,
+	'irwindowtemperature' => 1,
+	'irwindowtransmission' => 1,
 	'is_protected' => 1,
 	'is_trusted' => 1,
+	'isartbokeh' => 1,
+	'isattachment' => 1,
 	'isbasefont' => 1,
+	'iscompleted' => 1,
+	'isdeleted' => 1,
 	'isfixedpitch' => 1,
 	'isfixedv' => 1,
+	'isinfoa100' => 1,
+	'isnetworkfeed' => 1,
+	'isoautoflashlimit' => 1,
+	'isocalibrationgaintable' => 1,
 	'isoinfo' => 1,
+	'isonline' => 1,
+	'isospeeds' => 1,
+	'isotherm1color' => 1,
+	'isotherm2color' => 1,
+	'isprotected' => 1,
 	'isrc' => 1,
-	'isrccode' => 1,
 	'isrcnumber' => 1,
+	'isrecurring' => 1,
 	'isvbr' => 1,
 	'it8header' => 1,
@@ -4870,8 +8627,15 @@
 	'item0032' => 1,
 	'itemid' => 1,
+	'iteminfoentry' => 1,
 	'iteminformation' => 1,
 	'itemlist' => 1,
 	'itemlocation' => 1,
+	'itemproperties' => 1,
+	'itempropertyassociation' => 1,
+	'itempropertycontainer' => 1,
 	'itemprotection' => 1,
+	'itemreference' => 1,
+	'itemtool' => 1,
+	'itemvendorid' => 1,
 	'iterationcount' => 1,
 	'iterationendaction' => 1,
@@ -4880,11 +8644,21 @@
 	'iterations' => 1,
 	'itunesinfo' => 1,
+	'itunesmediatype' => 1,
+	'itunmovi' => 1,
+	'itunsmpb' => 1,
+	'ituntool' => 1,
+	'ixml' => 1,
+	'jbigoptions' => 1,
 	'jfif' => 1,
 	'jfifversion' => 1,
 	'jfxx' => 1,
 	'jngheader' => 1,
+	'jobtitle' => 1,
 	'journal' => 1,
 	'jp2header' => 1,
 	'jp2signature' => 1,
+	'jpeg-hdr' => 1,
+	'jpeg-hdrversion' => 1,
+	'jpeg-likedata' => 1,
 	'jpeg_quality' => 1,
 	'jpegactables' => 1,
@@ -4892,28 +8666,74 @@
 	'jpegdigest' => 1,
 	'jpegexifdata' => 1,
+	'jpegimagelength' => 1,
+	'jpeginfo' => 1,
 	'jpeglosslesspredictors' => 1,
 	'jpegpointtransforms' => 1,
 	'jpegproc' => 1,
 	'jpegprocess' => 1,
+	'jpegqtablebest' => 1,
+	'jpegqtablebetter' => 1,
+	'jpegqtablegood' => 1,
 	'jpegqtables' => 1,
+	'jpegqualityestimate' => 1,
 	'jpegrestartinterval' => 1,
 	'jpegtables' => 1,
+	'jplcartoifd' => 1,
+	'jsonmetadata' => 1,
 	'jumptoxpep' => 1,
 	'junk' => 1,
+	'k1' => 1,
+	'k2' => 1,
+	'k3' => 1,
+	'k4' => 1,
 	'kbytesize' => 1,
 	'kdc_ifd' => 1,
+	'keepuntil' => 1,
+	'kelvinwb' => 1,
+	'keycode' => 1,
 	'keyframepositions' => 1,
 	'keyframestimes' => 1,
+	'keyid' => 1,
 	'keys' => 1,
+	'kf' => 1,
+	'kf8coveruri' => 1,
+	'khufui0thresholds' => 1,
+	'khufui1thresholds' => 1,
+	'khufui2thresholds' => 1,
+	'khufui3thresholds' => 1,
+	'khufui4thresholds' => 1,
+	'khufui5thresholds' => 1,
+	'khufulinearbluemixingcoefficient' => 1,
+	'khufulineargreenmixingcoefficient' => 1,
+	'khufulinearredmixingcoefficient' => 1,
+	'khufusigmagaussianweights' => 1,
+	'khufusigmascalingfactors14mp' => 1,
+	'khufusigmascalingfactors3mp' => 1,
+	'khufusigmascalingfactors6mp' => 1,
+	'khufuuspacec2mixingcoefficient' => 1,
 	'kids' => 1,
+	'kinds' => 1,
+	'kj' => 1,
+	'kk' => 1,
+	'klut' => 1,
+	'klut12tolin12' => 1,
 	'knownfolderdata' => 1,
 	'kodak' => 1,
+	'kodak_frea' => 1,
 	'kodakbordersifd' => 1,
+	'kodakdcmd' => 1,
 	'kodakeffectsifd' => 1,
+	'kodakfree' => 1,
 	'kodakifd' => 1,
+	'kodakmake' => 1,
 	'kodaktags' => 1,
 	'konicaminolta' => 1,
 	'konicaminoltatags' => 1,
-	'lacenumber' => 1,
+	'label0' => 1,
+	'label1' => 1,
+	'label2' => 1,
+	'label3' => 1,
+	'labelid' => 1,
+	'labeltext' => 1,
 	'lamebitrate' => 1,
 	'lameheader' => 1,
@@ -4928,15 +8748,60 @@
 	'largestpacketsize' => 1,
 	'lastauthor' => 1,
+	'lastbackupdate' => 1,
 	'lastchar' => 1,
 	'lastkeyframetime' => 1,
 	'lastmodifiedby' => 1,
 	'lastmodifier' => 1,
+	'lastname' => 1,
 	'lastobject' => 1,
 	'lastobjectid' => 1,
 	'lastprinted' => 1,
+	'lastsavedby' => 1,
 	'lasttimestamp' => 1,
+	'lastupdate' => 1,
+	'lastupdatetime' => 1,
+	'layerblendmodes' => 1,
 	'layercomps' => 1,
+	'layercount' => 1,
+	'layergroupsenabledid' => 1,
+	'layerids' => 1,
+	'layermodifydates' => 1,
+	'layernames' => 1,
+	'layeropacities' => 1,
+	'layerrectangles' => 1,
+	'layers' => 1,
+	'layerselectionids' => 1,
 	'layersgroupinfo' => 1,
-	'layerstateinfo' => 1,
+	'layerunicodenames' => 1,
+	'layout' => 1,
+	'layoutflags' => 1,
+	'lcdedgemapslope' => 1,
+	'lcdedgemapx1' => 1,
+	'lcdedgemapx2' => 1,
+	'lcdedgemapx3' => 1,
+	'lcdedgemapx4' => 1,
+	'lcdedgespline' => 1,
+	'lcdgammatable' => 1,
+	'lcdgammatablechickfix' => 1,
+	'lcdgammatablemarvin' => 1,
+	'lcdhistlut0' => 1,
+	'lcdhistlut1' => 1,
+	'lcdhistlut2' => 1,
+	'lcdhistlut3' => 1,
+	'lcdhistlut4' => 1,
+	'lcdhistlut5' => 1,
+	'lcdhistlut6' => 1,
+	'lcdhistlut7' => 1,
+	'lcdhistlut8' => 1,
+	'lcdhistlut9' => 1,
+	'lcdlinearclipvalue' => 1,
+	'lcdsharpeningf1' => 1,
+	'lcdsharpeningf2' => 1,
+	'lcdsharpeningf3' => 1,
+	'lcdsharpeningf4' => 1,
+	'lcdstepyvalues' => 1,
+	'lcdstepyvalueschickfix' => 1,
+	'lcdstepyvaluesmarvin' => 1,
+	'leadperformer' => 1,
 	'leafautoactive' => 1,
 	'leafautobasename' => 1,
@@ -4947,10 +8812,16 @@
 	'leafsaveselection' => 1,
 	'leafsubifd' => 1,
+	'leftdarkcol1' => 1,
+	'leftdarkcol2' => 1,
 	'leftdarkrect' => 1,
 	'leftmag' => 1,
+	'leftmargin' => 1,
 	'legalcopyright' => 1,
 	'legaltrademarks' => 1,
+	'leicaleic' => 1,
 	'length' => 1,
 	'lens35efl' => 1,
+	'lensattached' => 1,
+	'lenscontrolring' => 1,
 	'lenscorr' => 1,
 	'lensdata' => 1,
@@ -4959,34 +8830,90 @@
 	'lensdata0201' => 1,
 	'lensdata0204' => 1,
+	'lensdata0400' => 1,
+	'lensdata0402' => 1,
+	'lensdata0403' => 1,
+	'lensdata0800' => 1,
 	'lensdataunknown' => 1,
 	'lensdataversion' => 1,
+	'lensfacing' => 1,
+	'lensfunc1button' => 1,
+	'lensfunc2button' => 1,
+	'lensinfoq' => 1,
+	'lensmaker' => 1,
+	'lensnumber' => 1,
+	'lenspartnumber' => 1,
+	'lensrec' => 1,
 	'lensshading' => 1,
-	'lensspec' => 1,
+	'lenstableindex' => 1,
 	'levelinfo' => 1,
 	'libraryid' => 1,
+	'libraryname' => 1,
 	'licenseinfourl' => 1,
 	'lightingopt' => 1,
 	'lightness' => 1,
+	'lightroomworkflow' => 1,
 	'lights' => 1,
 	'lightvalue' => 1,
-	'linearizationtable' => 1,
+	'limage' => 1,
+	'limitaf-areamodeselautoanimals' => 1,
+	'limitaf-areamodeselautopeople' => 1,
+	'limitaf-areamodeseldynamic' => 1,
+	'limitaf-areamodeselpinpoint' => 1,
+	'limitaf-areamodeselwideaf_l' => 1,
+	'limitaf-areamodeselwideaf_s' => 1,
+	'limitaf-areamodeselwidelanimals' => 1,
+	'limitaf-areamodeselwidelpeople' => 1,
+	'limitafareamodesel3d' => 1,
+	'limitafareamodeselauto' => 1,
+	'limitafareamodeseld105' => 1,
+	'limitafareamodeseld25' => 1,
+	'limitafareamodeseld49' => 1,
+	'limitafareamodeseld9' => 1,
+	'limitafareamodeselgroup' => 1,
+	'limitafareamodeselgroupc1' => 1,
+	'limitafareamodeselgroupc2' => 1,
+	'limitreleasemodeselch' => 1,
+	'limitreleasemodeselcl' => 1,
+	'limitreleasemodeselmirror-up' => 1,
+	'limitreleasemodeselq' => 1,
+	'limitreleasemodeseltimer' => 1,
+	'limitselectableimagearea16to9' => 1,
+	'limitselectableimagearea1to1' => 1,
+	'limitselectableimagearea5to4' => 1,
+	'limitselectableimageareadx' => 1,
+	'lin12toklut12' => 1,
+	'lin12toklut8' => 1,
+	'linearitysplinetags' => 1,
+	'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,
-	'locationbody' => 1,
-	'locationdate' => 1,
-	'locationnote' => 1,
-	'locationrole' => 1,
+	'localpositionned' => 1,
+	'locationinfo' => 1,
+	'locationinformation' => 1,
 	'lockedpropertylist' => 1,
 	'locks' => 1,
+	'loglintable' => 1,
 	'logoiconurl' => 1,
 	'logourl' => 1,
-	'longdescription' => 1,
 	'lookheadbacktype' => 1,
 	'lookheader' => 1,
@@ -4994,20 +8921,39 @@
 	'lookheadtype' => 1,
 	'lookheadversion' => 1,
+	'lookmat0' => 1,
+	'lookmat1' => 1,
+	'lookmat2' => 1,
+	'lookmat3' => 1,
+	'lookmat4' => 1,
+	'lookmat5' => 1,
+	'lookmat6' => 1,
+	'lookmat7' => 1,
+	'lookmat8' => 1,
+	'lookmat9' => 1,
+	'lookmodtransform' => 1,
 	'lookuptable' => 1,
-	'loopstyle' => 1,
 	'lotus' => 1,
+	'lowlightaf' => 1,
 	'lr' => 1,
 	'lslv' => 1,
+	'lucasjunk' => 1,
 	'luminance' => 1,
 	'luminanceconsts' => 1,
 	'lyricist' => 1,
-	'lyrics' => 1,
 	'lyrics_synchronised' => 1,
 	'machineid' => 1,
 	'machinetype' => 1,
+	'macintoshnsprintinfo' => 1,
 	'macintoshprintinfo' => 1,
+	'mag360fly' => 1,
+	'magmode' => 1,
+	'magneticfield' => 1,
+	'magnetometer' => 1,
+	'magnetometerxyz' => 1,
 	'magnification' => 1,
 	'magnifyobject' => 1,
+	'mailingaddress' => 1,
 	'mailstop' => 1,
+	'mainboard' => 1,
 	'maininfo' => 1,
 	'maininfoifd' => 1,
@@ -5015,17 +8961,26 @@
 	'makeandmodel' => 1,
 	'makemodel' => 1,
+	'makernotepentax5a' => 1,
+	'makernotepentax5b' => 1,
+	'makernotepentax5c' => 1,
 	'makernotes' => 1,
-	'makerurl' => 1,
 	'mandatorybackground' => 1,
+	'manualfocuspointillumination' => 1,
 	'manufacturecode' => 1,
 	'manufactureindex' => 1,
-	'manufacturer' => 1,
 	'manufacturername' => 1,
 	'mappingscheme' => 1,
+	'mapscale' => 1,
+	'mariahthresholds' => 1,
+	'mariahthresholdslow' => 1,
+	'mariahthresholdsnormal' => 1,
+	'mariahthresholdsstrong' => 1,
 	'markbits' => 1,
 	'marker' => 1,
 	'markerid' => 1,
 	'markinfo' => 1,
-	'matrixstructure' => 1,
+	'marl' => 1,
+	'matrixworldtocamera' => 1,
+	'matrixworldtoscreen' => 1,
 	'mattcolor' => 1,
 	'matte' => 1,
@@ -5034,6 +8989,4 @@
 	'maxband' => 1,
 	'maxbitrate' => 1,
-	'maxblockadditionid' => 1,
-	'maxcache' => 1,
 	'maxdatarate' => 1,
 	'maximumbitrate' => 1,
@@ -5050,8 +9003,130 @@
 	'maxval' => 1,
 	'maxwidth' => 1,
+	'mc' => 1,
 	'mcdi' => 1,
+	'md5signature' => 1,
+	'md5sum' => 1,
 	'mdcolortable' => 1,
 	'mdfiletag' => 1,
 	'mdfileunits' => 1,
+	'mditemaccounthandles' => 1,
+	'mditemaccountidentifier' => 1,
+	'mditemacquisitionmake' => 1,
+	'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,
+	'mditemcontributors' => 1,
+	'mditemcopyright' => 1,
+	'mditemcountry' => 1,
+	'mditemcreator' => 1,
+	'mditemdateadded' => 1,
+	'mditemdateadded_ranking' => 1,
+	'mditemdescription' => 1,
+	'mditemdisplayname' => 1,
+	'mditemdownloadeddate' => 1,
+	'mditemdurationseconds' => 1,
+	'mditememailconversationid' => 1,
+	'mditemencodingapplications' => 1,
+	'mditemexifgpsversion' => 1,
+	'mditemexifversion' => 1,
+	'mditemexposuremode' => 1,
+	'mditemexposureprogram' => 1,
+	'mditemexposuretimeseconds' => 1,
+	'mditemflashonoff' => 1,
+	'mditemfnumber' => 1,
+	'mditemfocallength' => 1,
+	'mditemfscontentchangedate' => 1,
+	'mditemfscreatorcode' => 1,
+	'mditemfsfinderflags' => 1,
+	'mditemfshascustomicon' => 1,
+	'mditemfsinvisible' => 1,
+	'mditemfsisextensionhidden' => 1,
+	'mditemfsisstationery' => 1,
+	'mditemfsname' => 1,
+	'mditemfsnodecount' => 1,
+	'mditemfsownergroupid' => 1,
+	'mditemfsowneruserid' => 1,
+	'mditemfssize' => 1,
+	'mditemfstypecode' => 1,
+	'mditemgpsdatestamp' => 1,
+	'mditemgpsstatus' => 1,
+	'mditemgpstrack' => 1,
+	'mditemhasalphachannel' => 1,
+	'mditemidentifier' => 1,
+	'mditemimagedirection' => 1,
+	'mditeminterestingdate_ranking' => 1,
+	'mditeminterestingdateranking' => 1,
+	'mditemisapplicationmanaged' => 1,
+	'mditemisexistingthread' => 1,
+	'mditemislikelyjunk' => 1,
+	'mditemisospeed' => 1,
+	'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,
+	'mditemoriginmessageid' => 1,
+	'mditemoriginsenderdisplayname' => 1,
+	'mditemoriginsenderhandle' => 1,
+	'mditemoriginsubject' => 1,
+	'mditempageheight' => 1,
+	'mditempagewidth' => 1,
+	'mditemphysicalsize' => 1,
+	'mditempixelcount' => 1,
+	'mditempixelheight' => 1,
+	'mditempixelwidth' => 1,
+	'mditemprimaryrecipientemailaddresses' => 1,
+	'mditemprofilename' => 1,
+	'mditemrecipients' => 1,
+	'mditemredeyeonoff' => 1,
+	'mditemresolutionheightdpi' => 1,
+	'mditemresolutionwidthdpi' => 1,
+	'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,
 	'mdpm' => 1,
@@ -5061,5 +9136,7 @@
 	'mdsampleinfo' => 1,
 	'mdscalepixel' => 1,
-	'mean' => 1,
+	'meas1label' => 1,
+	'meas1params' => 1,
+	'meas1type' => 1,
 	'measuredcolor' => 1,
 	'measuredinfo' => 1,
@@ -5069,5 +9146,8 @@
 	'measurementgeometry' => 1,
 	'measurementilluminant' => 1,
+	'measurementinfo' => 1,
 	'measurementobserver' => 1,
+	'measurementscale' => 1,
+	'mebx' => 1,
 	'media' => 1,
 	'mediablackpoint' => 1,
@@ -5075,8 +9155,12 @@
 	'mediaclasssecondaryid' => 1,
 	'mediacolor' => 1,
-	'mediacreatedate' => 1,
+	'mediacontenttypes' => 1,
+	'mediacreated' => 1,
 	'mediacredits' => 1,
 	'mediadata' => 1,
+	'mediadataoffset' => 1,
+	'mediadatasize' => 1,
 	'mediaduration' => 1,
+	'mediaflags' => 1,
 	'mediaheader' => 1,
 	'mediaheaderversion' => 1,
@@ -5086,24 +9170,39 @@
 	'mediaisfinale' => 1,
 	'mediaislive' => 1,
+	'mediaismovie' => 1,
 	'mediaispremiere' => 1,
 	'mediaisrepeat' => 1,
 	'mediaissap' => 1,
+	'mediaissport' => 1,
 	'mediaisstereo' => 1,
 	'mediaissubtitled' => 1,
 	'mediaistape' => 1,
+	'mediajukebox' => 1,
 	'medialanguagecode' => 1,
-	'mediamodifydate' => 1,
 	'medianetworkaffiliation' => 1,
 	'mediaoriginalbroadcastdatetime' => 1,
 	'mediaoriginalchannel' => 1,
+	'mediaoriginalchannelsubnumber' => 1,
+	'mediaoriginalruntime' => 1,
 	'mediapro' => 1,
 	'mediastationcallsign' => 1,
 	'mediastationname' => 1,
+	'mediathumbaspectratiox' => 1,
+	'mediathumbaspectratioy' => 1,
+	'mediathumbheight' => 1,
+	'mediathumbratingattributes' => 1,
+	'mediathumbratinglevel' => 1,
+	'mediathumbratingsystem' => 1,
+	'mediathumbret' => 1,
+	'mediathumbstride' => 1,
+	'mediathumbtimestamp' => 1,
+	'mediathumbwidth' => 1,
 	'mediatimescale' => 1,
 	'mediatrackbytes' => 1,
-	'mediatype' => 1,
 	'mediaweight' => 1,
 	'mediawhitepoint' => 1,
 	'medium' => 1,
+	'megapixels' => 1,
+	'melodicpolyphony' => 1,
 	'message' => 1,
 	'meta' => 1,
@@ -5113,13 +9212,33 @@
 	'metadatalibrary' => 1,
 	'metadatanumber' => 1,
+	'metadatasource' => 1,
+	'metadataversion' => 1,
+	'metaformat' => 1,
+	'metaimagesize' => 1,
+	'metarelation' => 1,
+	'metasampledesc' => 1,
+	'metdata' => 1,
+	'meterinfo' => 1,
+	'meteringbutton' => 1,
+	'meterlink' => 1,
 	'metermode' => 1,
+	'mett' => 1,
 	'microsoft' => 1,
+	'microsoftxtra' => 1,
+	'middlename' => 1,
+	'midicontrol' => 1,
+	'midicontrolversion' => 1,
+	'midisong' => 1,
 	'mie' => 1,
+	'mileage' => 1,
+	'mimeencoding' => 1,
 	'mimetype' => 1,
-	'mincache' => 1,
 	'miniaturefilter' => 1,
 	'miniaturefilterorientation' => 1,
+	'miniaturefilterparameter' => 1,
 	'miniaturefilterposition' => 1,
 	'minimumbitrate' => 1,
+	'minimumflushrows' => 1,
+	'minimumversion' => 1,
 	'minoltacamerasettings' => 1,
 	'minoltacamerasettings2' => 1,
@@ -5135,34 +9254,58 @@
 	'minoltattw' => 1,
 	'minoltawbg' => 1,
-	'minorversion' => 1,
 	'minpacketsize' => 1,
+	'minspatialsegmentationidc' => 1,
 	'mintransmissiontime' => 1,
 	'mmclips' => 1,
 	'mngheader' => 1,
+	'mobitype' => 1,
+	'mobiversion' => 1,
 	'modeextension' => 1,
+	'modeflags' => 1,
 	'model2' => 1,
 	'modelandversion' => 1,
-	'modeltiepoint' => 1,
-	'modeltransform' => 1,
 	'modeltype' => 1,
 	'modenumber' => 1,
+	'modificationnumber' => 1,
 	'modificationpermissions' => 1,
 	'modifiedby' => 1,
 	'modifiedinfo' => 1,
+	'moiversion' => 1,
+	'monomonitormatrix' => 1,
+	'monostrength' => 1,
+	'monotonescaletable' => 1,
+	'monouniquematrix' => 1,
 	'montage' => 1,
 	'month' => 1,
 	'mood' => 1,
+	'moreinfo' => 1,
+	'moreinfo0201' => 1,
+	'moreinfo0401' => 1,
 	'moreinfobannerimage' => 1,
 	'moreinfobannerurl' => 1,
 	'moreinfotext' => 1,
 	'moreinfourl' => 1,
+	'moresettings' => 1,
 	'mosaicpattern' => 1,
+	'movableinfo' => 1,
 	'moveobjects' => 1,
 	'movie' => 1,
-	'moviedata' => 1,
-	'moviedatasize' => 1,
+	'movieaf-onbutton' => 1,
+	'movieafspeed' => 1,
+	'movieafspeedapply' => 1,
+	'movieaftrackingsensitivity' => 1,
+	'moviefragment' => 1,
+	'moviefragmentheader' => 1,
+	'moviefragmentsequence' => 1,
+	'moviefunc2button' => 1,
+	'moviefunc3button' => 1,
 	'movieheader' => 1,
 	'movieheaderversion' => 1,
+	'moviehighlightdisplaypattern' => 1,
+	'moviehighlightdisplaythreshold' => 1,
 	'movieinfo' => 1,
+	'movieisoautocontrolmanualmode' => 1,
+	'movieisoautohilimit' => 1,
+	'moviemultiselector' => 1,
 	'moviestreamname' => 1,
 	'mp' => 1,
@@ -5185,14 +9328,14 @@
 	'mspropertysetstorage' => 1,
 	'msstereo' => 1,
-	'multiexposure' => 1,
+	'multiexp' => 1,
 	'multiexposureversion' => 1,
 	'multimediatype' => 1,
 	'multiprofiles' => 1,
 	'multiquality' => 1,
+	'multishoton' => 1,
+	'multiview' => 1,
 	'musicby' => 1,
 	'musiccdidentifier' => 1,
 	'musiciancredits' => 1,
-	'mute' => 1,
-	'muxingapp' => 1,
 	'mwg-coll' => 1,
 	'mwg-kw' => 1,
@@ -5200,9 +9343,8 @@
 	'mxfversion' => 1,
 	'mycolors' => 1,
-	'name' => 1,
 	'namedcolor' => 1,
 	'namedcolor2' => 1,
 	'nametableversion' => 1,
-	'narrator' => 1,
+	'nameutf-8' => 1,
 	'nativedisplayinfo' => 1,
 	'nativeresolutionunit' => 1,
@@ -5210,4 +9352,10 @@
 	'nativeyresolution' => 1,
 	'ncc' => 1,
+	'nemoblurkernel' => 1,
+	'nemodarklimit' => 1,
+	'nemogainfactors' => 1,
+	'nemohighlight12limit' => 1,
+	'nemotilesize' => 1,
+	'nestedsignalstream' => 1,
 	'nestlevel' => 1,
 	'netexposurecompensation' => 1,
@@ -5222,11 +9370,18 @@
 	'newbitdepth' => 1,
 	'newcolortype' => 1,
-	'nextfilename' => 1,
+	'newguid' => 1,
+	'newlines' => 1,
 	'nexttrackid' => 1,
-	'nextuid' => 1,
+	'nifnonlinearity' => 1,
+	'nifnonlinearity12bit' => 1,
+	'nifnonlinearity12to16' => 1,
+	'nifnonlinearity16bit' => 1,
+	'nifnonlinearityext' => 1,
 	'nikon' => 1,
-	'nikoncaptureoffsets' => 1,
 	'nikondata' => 1,
+	'nikondatetime' => 1,
+	'nikonncdb' => 1,
 	'nikonncdt' => 1,
+	'nikonnefinfo' => 1,
 	'nikonscanifd' => 1,
 	'nikontags' => 1,
@@ -5236,15 +9391,21 @@
 	'nitfversion' => 1,
 	'noise' => 1,
-	'noiseprofile' => 1,
 	'noisereductiondata' => 1,
+	'noisereductionkernel' => 1,
+	'noisereductionparametershostlow' => 1,
+	'noisereductionparametershostnormal' => 1,
+	'noisereductionparametershoststrong' => 1,
 	'nominalbitrate' => 1,
 	'nominalframecount' => 1,
 	'nominallayercount' => 1,
 	'nominalplaytime' => 1,
+	'nominalvideobitrate' => 1,
 	'nomssmarttags' => 1,
+	'normallinetransfertiming' => 1,
 	'note' => 1,
 	'notice' => 1,
 	'now' => 1,
 	'npts' => 1,
+	'nrwdata' => 1,
 	'nsc_address' => 1,
 	'nsc_description' => 1,
@@ -5253,5 +9414,4 @@
 	'nsc_phone' => 1,
 	'nullmediaheader' => 1,
-	'numafpoints' => 1,
 	'numberlist' => 1,
 	'numberofcomponents' => 1,
@@ -5262,4 +9422,7 @@
 	'numberofplanes' => 1,
 	'numberofresolutions' => 1,
+	'numberofsamples' => 1,
+	'numberofsamples64' => 1,
+	'numchanneldescriptions' => 1,
 	'numchannels' => 1,
 	'numcolors' => 1,
@@ -5271,9 +9434,17 @@
 	'numrules' => 1,
 	'numsampleframes' => 1,
+	'numslices' => 1,
 	'numstreams' => 1,
+	'numtemporallayers' => 1,
 	'objectfiletype' => 1,
+	'objectflags' => 1,
 	'objectid' => 1,
+	'objectorientation' => 1,
 	'objectsizeannounced' => 1,
-	'objecttype' => 1,
+	'observationdate' => 1,
+	'observationdateend' => 1,
+	'observationtime' => 1,
+	'observationtimeend' => 1,
+	'observer' => 1,
 	'obsoletephotoshoptag1' => 1,
 	'obsoletephotoshoptag2' => 1,
@@ -5286,6 +9457,13 @@
 	'ocescanjobdesc' => 1,
 	'office' => 1,
+	'officelocation' => 1,
+	'offlineavailability' => 1,
+	'offlinestatus' => 1,
+	'offsetmaphorizontal' => 1,
+	'offsetmapvertical' => 1,
 	'offsetorigin' => 1,
+	'offsetx' => 1,
 	'offsetxy' => 1,
+	'offsety' => 1,
 	'oldxmp' => 1,
 	'olym' => 1,
@@ -5309,12 +9487,46 @@
 	'olympus2900' => 1,
 	'olympus2900ifd' => 1,
+	'olympusatom' => 1,
+	'olympusdss' => 1,
 	'olympusjunk' => 1,
+	'olympusolym' => 1,
+	'olympuspreview' => 1,
 	'olympustags1' => 1,
 	'olympustags2' => 1,
 	'olympustags3' => 1,
+	'olympustags4' => 1,
+	'olympusthumbnail' => 1,
+	'omenatcapturemode' => 1,
+	'omenearlygobcolumns' => 1,
+	'omenearlygobrows' => 1,
+	'omenearlygobsurface' => 1,
+	'omengradientexclusionlimits' => 1,
+	'omengradientkernel' => 1,
+	'omengradientkerneltaps' => 1,
+	'omengradientoffset' => 1,
+	'omeninitialcolumns' => 1,
+	'omeninitialrows' => 1,
+	'omeninitialscaling' => 1,
+	'omenmeantostrength' => 1,
+	'omenpercenttorationallimitsblue' => 1,
+	'omenpercenttorationallimitsgob' => 1,
+	'omenpercenttorationallimitsgor' => 1,
+	'omenpercenttorationallimitsred' => 1,
+	'omenrangeweighting' => 1,
+	'omenratioclipfactors' => 1,
+	'omenratioexclusionfactors' => 1,
+	'omenroicoefficients' => 1,
+	'omenroicoordinates' => 1,
+	'omensmoothingkernel' => 1,
+	'on1_settingsdata' => 1,
+	'on1_settingsmetadatacreated' => 1,
+	'on1_settingsmetadatamodified' => 1,
+	'on1_settingsmetadataname' => 1,
+	'on1_settingsmetadatapluginid' => 1,
+	'on1_settingsmetadatatimestamp' => 1,
+	'on1_settingsmetadatausage' => 1,
+	'on1_settingsmetadatavisibletouser' => 1,
+	'onionskins' => 1,
 	'opacity' => 1,
-	'opcodelist1' => 1,
-	'opcodelist2' => 1,
-	'opcodelist3' => 1,
 	'opcolor' => 1,
 	'opendml' => 1,
@@ -5326,12 +9538,22 @@
 	'operationnumber' => 1,
 	'opiproxy' => 1,
+	'opticalvr' => 1,
+	'optics' => 1,
 	'optimalbitrate' => 1,
+	'optionalattendeeaddresses' => 1,
+	'optionalattendees' => 1,
+	'opus' => 1,
+	'opusversion' => 1,
 	'orderingrestrictions' => 1,
+	'organizeraddress' => 1,
+	'organizername' => 1,
+	'orientationinfo' => 1,
 	'originalalbum' => 1,
 	'originalalbumtitle' => 1,
-	'originalartist' => 1,
 	'originaldocumentsize' => 1,
 	'originalfilesize' => 1,
 	'originalfiletype' => 1,
+	'originalformat' => 1,
+	'originalframerate' => 1,
 	'originalimagebroker' => 1,
 	'originallyricist' => 1,
@@ -5345,4 +9567,6 @@
 	'originalreleaseyear' => 1,
 	'originalscannedimagesize' => 1,
+	'originalsoftpostpadding' => 1,
+	'originalsoftprepadding' => 1,
 	'originalthmcreator' => 1,
 	'originalthmfiletype' => 1,
@@ -5351,21 +9575,37 @@
 	'originator' => 1,
 	'originatorreference' => 1,
+	'originpathinfo' => 1,
 	'osversion' => 1,
+	'otheraddress' => 1,
+	'othercity' => 1,
 	'othercodecdescription' => 1,
 	'othercodecname' => 1,
+	'othercountry-region' => 1,
+	'otherdate1' => 1,
+	'otherdate2' => 1,
+	'otherdate3' => 1,
+	'otherfirmware' => 1,
 	'otherformat' => 1,
-	'otherimage' => 1,
-	'otherimagelength' => 1,
-	'otherimagestart' => 1,
 	'otherinfo' => 1,
+	'othermeta' => 1,
+	'othername' => 1,
+	'otherpobox' => 1,
+	'otherpostalcode' => 1,
 	'othersampledesc' => 1,
-	'outputaudiosamplerate' => 1,
+	'otherserialnumber' => 1,
+	'otherstateorprovince' => 1,
+	'otherstreet' => 1,
 	'outputdataobjectlist' => 1,
-	'outputprofile' => 1,
+	'outputgain' => 1,
+	'outputheight' => 1,
 	'outputresponse' => 1,
+	'outputwidth' => 1,
+	'overclockcolsright' => 1,
+	'overclockrowsbottom' => 1,
+	'overflowcolor' => 1,
+	'ownership' => 1,
 	'packets' => 1,
 	'packingmethod' => 1,
 	'page' => 1,
-	'pagecount' => 1,
 	'pageenter' => 1,
 	'pageexit' => 1,
@@ -5374,9 +9614,24 @@
 	'pagemode' => 1,
 	'pagenormal' => 1,
+	'pager' => 1,
 	'pages' => 1,
 	'pagespecial' => 1,
+	'paintdata' => 1,
+	'paintimage' => 1,
+	'paintimageheight' => 1,
+	'paintimagetype' => 1,
+	'paintimagewidth' => 1,
+	'paintingfilter' => 1,
 	'palette' => 1,
+	'palettecolors' => 1,
+	'palettefilename' => 1,
 	'palettehistogram' => 1,
+	'paletteinfo' => 1,
+	'palettemethod' => 1,
+	'palettename' => 1,
+	'palettestretch' => 1,
+	'palmfiletype' => 1,
 	'panasonic' => 1,
+	'panasonicpana' => 1,
 	'panorama' => 1,
 	'panorientation' => 1,
@@ -5384,14 +9639,42 @@
 	'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,
+	'parrotautomation' => 1,
+	'parrotfollowme' => 1,
+	'parrottimestamp' => 1,
+	'parrotv1' => 1,
+	'parrotv2' => 1,
+	'parrotv3' => 1,
 	'part' => 1,
+	'partialactivecolsleft' => 1,
+	'partialactivecolsright' => 1,
+	'partialactiverowsbottom' => 1,
+	'partialactiverowstop' => 1,
 	'partialpalette' => 1,
+	'partialsyncsamples' => 1,
+	'participants' => 1,
+	'partnumber' => 1,
 	'partofset' => 1,
 	'pastclippingboundary' => 1,
 	'pasteimage' => 1,
+	'path' => 1,
+	'pathselectionstate' => 1,
+	'pathtablelocation' => 1,
+	'pathtablesize' => 1,
 	'patternangle' => 1,
+	'patterncorrectionfactors' => 1,
+	'patterncorrectiongains' => 1,
+	'patterncorrectionoffsets' => 1,
+	'patterngainconversiontable' => 1,
 	'payloadtype' => 1,
 	'paymenturl' => 1,
@@ -5401,16 +9684,20 @@
 	'pdfx' => 1,
 	'peakbitrate' => 1,
+	'peakspectralsensitivity' => 1,
 	'peakvalue' => 1,
 	'pefversion' => 1,
 	'pentax' => 1,
 	'pentaxdata' => 1,
+	'pentaxdata2' => 1,
 	'pentaxjunk' => 1,
+	'pentaxjunk2' => 1,
+	'pentaxpent' => 1,
+	'pentaxpreview' => 1,
 	'pentaxtags' => 1,
+	'perceivedtype' => 1,
 	'perceptualrenderingintentgamut' => 1,
-	'performer' => 1,
-	'performerkeywords' => 1,
-	'performers' => 1,
+	'percussivepolyphony' => 1,
+	'perfmode' => 1,
 	'performersortorder' => 1,
-	'performerurl' => 1,
 	'period' => 1,
 	'perms' => 1,
@@ -5418,4 +9705,5 @@
 	'personalfunctions' => 1,
 	'personalfunctionvalues' => 1,
+	'personaltitle' => 1,
 	'petype' => 1,
 	'pfmheader' => 1,
@@ -5423,19 +9711,21 @@
 	'pgfversion' => 1,
 	'photoeffectsdata' => 1,
+	'photofinishername' => 1,
 	'photomech' => 1,
 	'photomechanic' => 1,
+	'photoresolution' => 1,
 	'photoshop' => 1,
 	'photoshop2colortable' => 1,
 	'photoshop2info' => 1,
-	'photoshopbgrthumbnail' => 1,
+	'photoshop_profile' => 1,
 	'photoshopdata' => 1,
 	'photoshopformat' => 1,
 	'photoshopinfo' => 1,
 	'photoshopsettings' => 1,
-	'photoshopthumbnail' => 1,
 	'physicalpixel' => 1,
 	'physicalstreamnumbermap' => 1,
 	'physicalstreamnumbers' => 1,
 	'physicalstreams' => 1,
+	'pic_ifd' => 1,
 	'picslabel' => 1,
 	'picture' => 1,
@@ -5451,41 +9741,58 @@
 	'picturemimetype' => 1,
 	'picturestyleinfo' => 1,
-	'picturestyleinfo2' => 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,
+	'pixelcorrectiongains' => 1,
+	'pixelexposuretime' => 1,
 	'pixelformat' => 1,
+	'pixelinfo' => 1,
 	'pixelintensityrange' => 1,
 	'pixellive' => 1,
 	'pixelmagicjbigoptions' => 1,
-	'pixelscale' => 1,
 	'pixelspermeterx' => 1,
 	'pixelspermetery' => 1,
-	'pixelsperunitx' => 1,
-	'pixelsperunity' => 1,
-	'pixelunits' => 1,
 	'pixheight' => 1,
 	'pixwidth' => 1,
 	'places' => 1,
-	'planes' => 1,
-	'playallframes' => 1,
+	'planckb' => 1,
+	'planckf' => 1,
+	'plancko' => 1,
+	'planckr1' => 1,
+	'planckr2' => 1,
+	'playbackflickdown' => 1,
+	'playbackflickdownrating' => 1,
+	'playbackflickup' => 1,
+	'playbackflickuprating' => 1,
 	'playcounter' => 1,
-	'playduration' => 1,
-	'playerversion' => 1,
-	'playgap' => 1,
 	'playlistdelay' => 1,
-	'playlistid' => 1,
-	'playmode' => 1,
-	'playselection' => 1,
+	'playlistindex' => 1,
 	'plus' => 1,
-	'podcast' => 1,
-	'podcasturl' => 1,
+	'pmi' => 1,
+	'pobox' => 1,
+	'podcastcategory' => 1,
+	'podcastdescription' => 1,
+	'podcastid' => 1,
+	'podcastkeywords' => 1,
 	'pointsize' => 1,
+	'popularimeter' => 1,
 	'popupfillattributes' => 1,
 	'popupflash' => 1,
+	'portraitmatrix' => 1,
+	'portraittonescaletable' => 1,
+	'poseyawdegrees' => 1,
 	'position' => 1,
 	'postertime' => 1,
@@ -5493,5 +9800,7 @@
 	'postscript2crd1' => 1,
 	'postscript2crd2' => 1,
+	'postscript2crd3' => 1,
 	'postscript2csa' => 1,
+	'postscriptfont' => 1,
 	'postscriptfontname' => 1,
 	'pragma' => 1,
@@ -5503,5 +9812,4 @@
 	'presentationformat' => 1,
 	'presentationtarget' => 1,
-	'prevfilename' => 1,
 	'preview' => 1,
 	'preview0' => 1,
@@ -5510,32 +9818,48 @@
 	'previewatomindex' => 1,
 	'previewatomtype' => 1,
-	'previewdate' => 1,
 	'previewduration' => 1,
 	'previewifd' => 1,
 	'previewifd_offset' => 1,
+	'previewimage1' => 1,
+	'previewimage2' => 1,
 	'previewimagedata' => 1,
 	'previewimageinfo' => 1,
 	'previewinfo' => 1,
+	'previewpdf' => 1,
 	'previewpict' => 1,
 	'previewpng' => 1,
+	'previewtiff' => 1,
 	'previewtime' => 1,
 	'previewversion' => 1,
-	'prevsize' => 1,
-	'prevuid' => 1,
+	'previewwmf' => 1,
+	'primarye-mail' => 1,
+	'primaryfileguid' => 1,
 	'primaryitemreference' => 1,
+	'primaryphone' => 1,
 	'primaryplatform' => 1,
+	'primaryvolume' => 1,
 	'printflags' => 1,
 	'printflagsinfo' => 1,
 	'printimversion' => 1,
+	'printinfo' => 1,
+	'printinfo2' => 1,
+	'printposition' => 1,
 	'printquality' => 1,
 	'printscale' => 1,
+	'printscaleinfo' => 1,
+	'printstyle' => 1,
 	'printtovideo' => 1,
 	'priority' => 1,
+	'prioritysettings' => 1,
 	'prism' => 1,
 	'private' => 1,
 	'privatebuild' => 1,
 	'prl' => 1,
+	'prm' => 1,
 	'processing' => 1,
 	'processinginfo' => 1,
+	'processingparameters' => 1,
+	'processingtime' => 1,
+	'processparametersv2' => 1,
 	'prod' => 1,
 	'prodnotes' => 1,
@@ -5543,17 +9867,22 @@
 	'produceddate' => 1,
 	'producednotice' => 1,
-	'producerkeywords' => 1,
+	'producers' => 1,
 	'product' => 1,
+	'productionaperturedimensions' => 1,
 	'productiondate' => 1,
 	'productiondesigner' => 1,
 	'productionstudio' => 1,
 	'productname' => 1,
-	'productversion' => 1,
+	'producttype' => 1,
 	'productversionnumber' => 1,
-	'profile' => 1,
+	'profile1audiocodec' => 1,
+	'profile1height' => 1,
+	'profile1videocodec' => 1,
+	'profile1width' => 1,
 	'profileclass' => 1,
 	'profilecmmtype' => 1,
 	'profileconnectionspace' => 1,
 	'profilecreator' => 1,
+	'profiledataoffset' => 1,
 	'profiledatetime' => 1,
 	'profiledescription' => 1,
@@ -5565,7 +9894,10 @@
 	'profilesequencedesc' => 1,
 	'profilesequenceidentifier' => 1,
-	'profiletype' => 1,
+	'profilesize' => 1,
 	'profileversion' => 1,
 	'progid' => 1,
+	'programdescription' => 1,
+	'programid' => 1,
+	'programname' => 1,
 	'progressivescans' => 1,
 	'projazimuthangle' => 1,
@@ -5578,4 +9910,9 @@
 	'projectedcstype' => 1,
 	'projection' => 1,
+	'projectionboundsbottom' => 1,
+	'projectionboundsleft' => 1,
+	'projectionboundsright' => 1,
+	'projectionboundstop' => 1,
+	'projectionheader' => 1,
 	'projects' => 1,
 	'projfalseeasting' => 1,
@@ -5604,32 +9941,63 @@
 	'propertyvectorelements' => 1,
 	'protect' => 1,
+	'protected' => 1,
+	'protectioninfo' => 1,
 	'protectiontype' => 1,
+	'protune' => 1,
 	'provider' => 1,
 	'providercopyright' => 1,
+	'providerlogourl' => 1,
 	'providerrating' => 1,
 	'providerstyle' => 1,
+	'providerurl' => 1,
 	'ps2crdvmsize' => 1,
 	'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,
 	'pyramidlevels' => 1,
+	'qtablelarge100pct' => 1,
+	'qtablelarge25pct' => 1,
+	'qtablelarge50pct' => 1,
+	'qtablelarge67pct' => 1,
+	'qtablemedium100pct' => 1,
+	'qtablemedium25pct' => 1,
+	'qtablemedium50pct' => 1,
+	'qtablemedium67pct' => 1,
+	'qtablesmall100pct' => 1,
+	'qtablesmall25pct' => 1,
+	'qtablesmall50pct' => 1,
+	'qtablesmall67pct' => 1,
+	'qualcomm' => 1,
 	'quickedit' => 1,
 	'quickmaskinfo' => 1,
+	'quietshuttershootingspeed' => 1,
+	'quoting' => 1,
 	'qvci' => 1,
 	'ra3' => 1,
 	'ra4' => 1,
 	'ra5' => 1,
+	'radioband' => 1,
+	'radioformat' => 1,
 	'radiostationname' => 1,
 	'radiostationowner' => 1,
+	'rafdata' => 1,
 	'rafversion' => 1,
 	'rasterpadding' => 1,
 	'rate' => 1,
 	'rated' => 1,
+	'ratingorg' => 1,
+	'ratioimage' => 1,
+	'rawburstmoderoll' => 1,
+	'rawcfacomponentaverages' => 1,
 	'rawcodecversion' => 1,
-	'rawdata' => 1,
 	'rawdatalength' => 1,
 	'rawdataoffset' => 1,
@@ -5639,15 +10007,63 @@
 	'rawdevelopment' => 1,
 	'rawdevelopmentifd' => 1,
+	'rawexposurebias' => 1,
+	'rawgsensor' => 1,
+	'rawhistogram' => 1,
+	'rawimageaspectratio' => 1,
+	'rawimagecroppedsize' => 1,
+	'rawimagecroptopleft' => 1,
+	'rawimagefullheight' => 1,
 	'rawimagefullsize' => 1,
+	'rawimagefullwidth' => 1,
+	'rawimageheight' => 1,
 	'rawimagemode' => 1,
 	'rawimagesegmentation' => 1,
+	'rawimagewidth' => 1,
 	'rawinfo' => 1,
 	'rawinfoifd' => 1,
 	'rawjpginfo' => 1,
+	'rawthermalimage' => 1,
+	'rawthermalimageheight' => 1,
+	'rawthermalimagetype' => 1,
+	'rawthermalimagewidth' => 1,
+	'rawvaluemedian' => 1,
+	'rawvaluerange' => 1,
+	'rawvaluerangemax' => 1,
+	'rawvaluerangemin' => 1,
 	'rawzorcreatorversion' => 1,
 	'rawzorrequiredversion' => 1,
 	'rdf' => 1,
+	'readername' => 1,
 	'readerrequirements' => 1,
+	'reading1description' => 1,
+	'reading1device' => 1,
+	'reading1units' => 1,
+	'reading1value' => 1,
+	'reading2description' => 1,
+	'reading2device' => 1,
+	'reading2units' => 1,
+	'reading2value' => 1,
+	'reading3description' => 1,
+	'reading3device' => 1,
+	'reading3units' => 1,
+	'reading3value' => 1,
+	'reading4description' => 1,
+	'reading4device' => 1,
+	'reading4units' => 1,
+	'reading4value' => 1,
+	'readstatus' => 1,
+	'real2ir' => 1,
 	'realtimestreamingprotocol' => 1,
+	'rearcontropaneldisplay' => 1,
+	'recallshootfuncaf-on' => 1,
+	'recallshootfuncafareamode' => 1,
+	'recallshootfuncaperture' => 1,
+	'recallshootfuncexposurecomp' => 1,
+	'recallshootfuncexposuremode' => 1,
+	'recallshootfuncfocustracking' => 1,
+	'recallshootfunciso' => 1,
+	'recallshootfuncmeteringmode' => 1,
+	'recallshootfuncshutterspeed' => 1,
+	'recallshootfuncwhitebalance' => 1,
 	'receivedfrom' => 1,
 	'recengineer' => 1,
@@ -5657,14 +10073,22 @@
 	'recordedby' => 1,
 	'recordeddate' => 1,
-	'recordingcopyright' => 1,
 	'recordingdates' => 1,
 	'recordingtime' => 1,
-	'recordlabelname' => 1,
-	'recordlabelurl' => 1,
+	'recordingtimeday' => 1,
+	'recordingtimemonth' => 1,
+	'recordingtimeyear' => 1,
+	'recordingtimeyearmonth' => 1,
+	'recordingtimeyearmonthday' => 1,
 	'rect' => 1,
 	'rectangleofinterest' => 1,
+	'red1header' => 1,
+	'red2header' => 1,
 	'redadjust' => 1,
+	'redblueflatfield' => 1,
+	'redcodeversion' => 1,
+	'redendpoint' => 1,
 	'redeyedata' => 1,
 	'redgain' => 1,
+	'redmask' => 1,
 	'redmatrixcolumn' => 1,
 	'redprimary' => 1,
@@ -5673,15 +10097,36 @@
 	'redx' => 1,
 	'redy' => 1,
+	'reelnumber' => 1,
+	'reeltimecode' => 1,
 	'reference' => 1,
-	'referenceblock' => 1,
-	'referencepriority' => 1,
-	'referencevirtual' => 1,
+	'referencetemperature' => 1,
+	'reflectedapparenttemperature' => 1,
+	'reflection' => 1,
 	'reflectionhardcopyorigcolorimetry' => 1,
 	'reflectionprintoutputcolorimetry' => 1,
 	'refresh' => 1,
+	'regionxformtackpoint' => 1,
+	'registerreadtiming' => 1,
 	'relatedimagefile' => 1,
+	'relativeexposure' => 1,
+	'relativehumidity' => 1,
+	'relativelocation' => 1,
 	'relativepath' => 1,
+	'relativevolumeadjustment' => 1,
+	'releasedateday' => 1,
+	'releasedatemonth' => 1,
+	'releasedateyear' => 1,
+	'releasedateyearmonth' => 1,
+	'releasedateyearmonthday' => 1,
+	'rembrandtconsumertonescale' => 1,
+	'rembrandtportraittonescale' => 1,
+	'rembrandttonescale' => 1,
+	'remindertime' => 1,
+	'remotefuncbutton' => 1,
 	'removehistoryduplicates' => 1,
 	'renderingintent' => 1,
+	'renderingtransform' => 1,
+	'rentalexpirationdate' => 1,
+	'rentalflag' => 1,
 	'repeateddatabytes' => 1,
 	'replaygainalbumgain' => 1,
@@ -5693,7 +10138,21 @@
 	'representativedisparitynear' => 1,
 	'representativeimage' => 1,
-	'requirements' => 1,
+	'requestid' => 1,
+	'requeststate' => 1,
+	'requiredattendeeaddresses' => 1,
+	'requiredattendees' => 1,
+	'rerun' => 1,
 	'reserved1' => 1,
+	'reserved5' => 1,
+	'reservedblob2' => 1,
+	'reservedblob3' => 1,
+	'reservedblob4' => 1,
+	'reservedblob5' => 1,
+	'reservedblob6' => 1,
+	'reservedblob7' => 1,
+	'reservedblob8' => 1,
+	'reservedblob9' => 1,
 	'resolutioninfo' => 1,
+	'resourcecount' => 1,
 	'resourceforksize' => 1,
 	'resources' => 1,
@@ -5701,28 +10160,91 @@
 	'resourcetype' => 1,
 	'resultaspectratio' => 1,
+	'retailprice' => 1,
+	'retailpricecurrency' => 1,
+	'retouchinfoversion' => 1,
+	'reversefocusring' => 1,
+	'review' => 1,
 	'revisiondate' => 1,
 	'revisionnumber' => 1,
 	'revisitafter' => 1,
 	'rgb_profile' => 1,
+	'rgbcurves' => 1,
+	'rgbtoev0' => 1,
+	'rgbtoev1' => 1,
+	'rgbtoev2' => 1,
+	'rgbtoev3' => 1,
+	'rgbtoev4' => 1,
+	'rgbtoev5' => 1,
+	'rgbtoev6' => 1,
+	'rgbtoev7' => 1,
+	'rgbtoev8' => 1,
+	'rgbtoev9' => 1,
+	'rgtable' => 1,
 	'ricoh' => 1,
 	'ricohjunk' => 1,
+	'ricohmake' => 1,
+	'ricohmodel' => 1,
+	'ricohpitch' => 1,
 	'ricohrdc2' => 1,
+	'ricohrmkn' => 1,
+	'ricohroll' => 1,
 	'ricohrr1subdir' => 1,
 	'ricohsubdir' => 1,
+	'ricohsubdirifd' => 1,
+	'riffsize64' => 1,
+	'rightdarkcol1' => 1,
+	'rightdarkcol2' => 1,
 	'rightdarkrect' => 1,
 	'rightmag' => 1,
+	'rimm13toerimm12spline' => 1,
+	'rimmtocrgb0spline' => 1,
+	'rimmtocrgb1spline' => 1,
+	'rimmtocrgb2spline' => 1,
+	'rimmtocrgb3spline' => 1,
+	'rimmtocrgb4spline' => 1,
+	'rimmtocrgb5spline' => 1,
+	'rimmtocrgb6spline' => 1,
+	'rimmtocrgb7spline' => 1,
+	'rimmtocrgb8spline' => 1,
+	'rimmtocrgb9spline' => 1,
+	'rimnonlinearity' => 1,
+	'rimtonifcolortransform' => 1,
+	'rimtonifscalefactor' => 1,
 	'rippedby' => 1,
 	'rjmd' => 1,
 	'rmeta' => 1,
+	'rnoiselines' => 1,
 	'robots' => 1,
 	'rocinfo' => 1,
 	'roidescription' => 1,
 	'rollguidelements' => 1,
+	'rollingshutterskewtime' => 1,
 	'root' => 1,
+	'rootdirectorycreatedate' => 1,
+	'rot360fly' => 1,
 	'rotationangle' => 1,
+	'rotationxyz' => 1,
+	'rotmode' => 1,
 	'roundtripversion' => 1,
+	'rowcount' => 1,
 	'rowinterleavefactor' => 1,
+	'rsrc' => 1,
+	'rtmd' => 1,
+	'rtptimescale' => 1,
+	'runtime' => 1,
+	'runtimeepoch' => 1,
+	'runtimeflags' => 1,
+	'runtimescale' => 1,
+	'runtimesincepowerup' => 1,
+	'runtimevalue' => 1,
 	'runwindow' => 1,
+	'rvmi_grev' => 1,
+	'rvmi_srev' => 1,
+	's2n' => 1,
+	'sampleblacksequence' => 1,
+	'sampledatetime' => 1,
 	'sampledegradationpriority' => 1,
+	'sampleduration' => 1,
+	'sampleflag' => 1,
 	'sampleformat' => 1,
 	'samplegroupdescription' => 1,
@@ -5733,10 +10255,22 @@
 	'sampletable' => 1,
 	'sampletext' => 1,
+	'sampletime' => 1,
 	'sampletochunk' => 1,
 	'sampletogroup' => 1,
+	'samsung' => 1,
+	'samsungifd' => 1,
 	'samsunginfo' => 1,
+	'samsungrawbyteorder' => 1,
+	'samsungrawpointerslength' => 1,
+	'samsungrawpointersoffset' => 1,
+	'samsungrawunknown' => 1,
+	'samsungsec' => 1,
+	'samsungsmta' => 1,
+	'samsungsvss' => 1,
 	'samsungtags' => 1,
+	'samsunguniqueid' => 1,
 	'sanyomov' => 1,
 	'sanyomp4' => 1,
+	'sap' => 1,
 	'saturationinfo' => 1,
 	'saturationrenderingintentgamut' => 1,
@@ -5748,42 +10282,67 @@
 	'savesetup' => 1,
 	'sba_rgbshifts' => 1,
+	'sbabluebalancelut' => 1,
 	'sbaexposurerecord' => 1,
+	'sbagreenbalancelut' => 1,
 	'sbainputimagebitdepth' => 1,
 	'sbainputimagecolorspace' => 1,
+	'sbalog12transform' => 1,
+	'sbalogtransform' => 1,
+	'sbaredbalancelut' => 1,
 	'scalado' => 1,
 	'scale' => 1,
 	'scalecrop' => 1,
+	'scaledimu' => 1,
+	'scaledpressure' => 1,
+	'scalefactor' => 1,
 	'scalefactor35efl' => 1,
 	'scalingfactor' => 1,
 	'scandate' => 1,
+	'scannerfirmwaredate' => 1,
+	'scannerfirmwareversion' => 1,
 	'scannermake' => 1,
 	'scannermodel' => 1,
 	'scannerpixelsize' => 1,
+	'scannerproductid' => 1,
 	'scannerserialnumber' => 1,
+	'scannervendorid' => 1,
 	'scanoperatorid' => 1,
 	'scansoftware' => 1,
 	'scansoftwarerevisiondate' => 1,
+	'scav11cols' => 1,
+	'scav12cols' => 1,
+	'scav21cols' => 1,
+	'scav22cols' => 1,
 	'sceneappearanceestimates' => 1,
+	'scenebalancealgorithmcommand' => 1,
+	'scenebalancealgorithmfilmid' => 1,
+	'scenebalancealgorithmrevision' => 1,
 	'scenecolorimetryestimates' => 1,
+	'scheduleitemid' => 1,
+	'schemeinfo' => 1,
+	'schemetype' => 1,
+	'schemeurl' => 1,
+	'schemeversion' => 1,
 	'school' => 1,
 	'screenbuffersize' => 1,
 	'screendescriptor' => 1,
+	'screenheight' => 1,
 	'screening' => 1,
 	'screeningdesc' => 1,
 	'screennail' => 1,
+	'screenwidth' => 1,
+	'screenwindowcenter' => 1,
+	'screenwindowwidth' => 1,
+	'screenwriters' => 1,
 	'scriptcommand' => 1,
+	'searchranking' => 1,
 	'secondarygenre' => 1,
 	'secondlanguage' => 1,
 	'security' => 1,
-	'seek' => 1,
 	'seekable' => 1,
-	'seekhead' => 1,
-	'seekid' => 1,
 	'seekpoint' => 1,
-	'seekposition' => 1,
-	'segmentfamily' => 1,
-	'segmentfilename' => 1,
-	'segmentheader' => 1,
-	'segmentuid' => 1,
+	'seektable' => 1,
+	'segheight' => 1,
+	'segwidth' => 1,
 	'selection' => 1,
 	'selectionduration' => 1,
@@ -5794,14 +10353,22 @@
 	'selobjversion' => 1,
 	'sendduration' => 1,
+	'senderaddress' => 1,
+	'sendername' => 1,
+	'sensitivity' => 1,
+	'sensitivityvalue' => 1,
 	'sensorbottomborder' => 1,
+	'sensordata' => 1,
+	'sensordefects' => 1,
 	'sensorid' => 1,
-	'sensorimageheight' => 1,
-	'sensorimagewidth' => 1,
 	'sensorinfo' => 1,
-	'sensorleftborder' => 1,
 	'sensorrightborder' => 1,
-	'sensortopborder' => 1,
+	'seqlevelidx0' => 1,
+	'seqprofile' => 1,
+	'seqtier0' => 1,
+	'sequenceframenumber' => 1,
+	'sequencenumberrandomoffset' => 1,
 	'serialinfo' => 1,
-	'series' => 1,
+	'seriesuid' => 1,
+	'serviceid' => 1,
 	'serviceorganizationname' => 1,
 	'setcookie' => 1,
@@ -5809,10 +10376,19 @@
 	'setsubtitle' => 1,
 	'seventhlanguage' => 1,
+	'sfsboundary' => 1,
+	'sglcoldcacthres1' => 1,
+	'sglcoldcacthres2' => 1,
+	'sglcoldcacthres3' => 1,
 	'shadowendpoints' => 1,
+	'shadowfilepath' => 1,
 	'shadowsyncsampletable' => 1,
 	'shakereductioninfo' => 1,
+	'shared' => 1,
 	'shareddata' => 1,
 	'shareddoc' => 1,
 	'shareduserrating' => 1,
+	'sharedwith' => 1,
+	'sharpenforthumbnail' => 1,
+	'sharpeningon' => 1,
 	'sharpinfo' => 1,
 	'sharpmethod' => 1,
@@ -5824,4 +10400,6 @@
 	'sharpobjtype' => 1,
 	'sharpobjversion' => 1,
+	'sheetdisclosure' => 1,
+	'shifttiming' => 1,
 	'shimdata' => 1,
 	'shootingcount' => 1,
@@ -5841,31 +10419,41 @@
 	'shotinfod3s' => 1,
 	'shotinfod3x' => 1,
+	'shotinfod4' => 1,
 	'shotinfod40' => 1,
+	'shotinfod4s' => 1,
+	'shotinfod5' => 1,
+	'shotinfod500' => 1,
 	'shotinfod5000' => 1,
+	'shotinfod5100' => 1,
+	'shotinfod5200' => 1,
+	'shotinfod6' => 1,
+	'shotinfod610' => 1,
 	'shotinfod700' => 1,
 	'shotinfod7000' => 1,
 	'shotinfod80' => 1,
+	'shotinfod800' => 1,
+	'shotinfod810' => 1,
+	'shotinfod850' => 1,
 	'shotinfod90' => 1,
 	'shotinfounknown' => 1,
 	'shotinfoversion' => 1,
+	'shotinfoz7_2' => 1,
 	'showmode' => 1,
 	'showobjects' => 1,
-	'shutter' => 1,
+	'shutterangle' => 1,
 	'shuttercurtainhack' => 1,
 	'shutterspeed' => 1,
 	'shutterspeeddisplayed' => 1,
 	'sidebars' => 1,
+	'sidelightstrength' => 1,
 	'sigma' => 1,
+	'sigmanoisefiltercaltablev1' => 1,
+	'sigmanoisefiltertablev1' => 1,
+	'sigmanoisefiltertablev1version' => 1,
+	'sigmanoisethreshtablev2' => 1,
 	'signalnumber' => 1,
 	'signature' => 1,
 	'signature_name' => 1,
-	'signaturealgo' => 1,
-	'signatureelementlist' => 1,
-	'signatureelements' => 1,
-	'signaturehash' => 1,
-	'signaturepublickey' => 1,
-	'signatureslot' => 1,
 	'signatureusagerights' => 1,
-	'signedelement' => 1,
 	'signercontactinfo' => 1,
 	'significantbits' => 1,
@@ -5875,19 +10463,22 @@
 	'signingreason' => 1,
 	'signtype' => 1,
-	'silenttracknumber' => 1,
-	'silenttracks' => 1,
-	'simpleblock' => 1,
+	'silentphotography' => 1,
 	'simpleindex' => 1,
-	'simpletag' => 1,
 	'simplicityprofile' => 1,
 	'singlequality' => 1,
+	'singleshotdepthmap' => 1,
+	'singleshotdepthmaptiff' => 1,
+	'singleshotmeta' => 1,
 	'site' => 1,
 	'siteenter' => 1,
 	'siteexit' => 1,
+	'siunits' => 1,
 	'sixthlanguage' => 1,
 	'size' => 1,
 	'sizemode' => 1,
 	'skip' => 1,
-	'slices' => 1,
+	'slateinformation' => 1,
+	'sliceinfo' => 1,
+	'slicesgroupname' => 1,
 	'slides' => 1,
 	'slideshow' => 1,
@@ -5896,23 +10487,21 @@
 	'snapshotid' => 1,
 	'snapshotname' => 1,
+	'soctemperature' => 1,
 	'softedit' => 1,
 	'softfocusfilter' => 1,
+	'softwarecomponents' => 1,
 	'softwarerelease' => 1,
-	'songwriter' => 1,
-	'songwriterkeywords' => 1,
 	'sony' => 1,
-	'sonyimageheight' => 1,
-	'sonyimagewidth' => 1,
-	'sortalbum' => 1,
-	'sortalbumartist' => 1,
-	'sortartist' => 1,
-	'sortcomposer' => 1,
-	'sortname' => 1,
-	'sortshow' => 1,
+	'sony_0x9416' => 1,
+	'sonyfnumber2' => 1,
+	'sonyrawfiletype' => 1,
+	'sonytonecurve' => 1,
+	'soundfile' => 1,
 	'soundschemetitle' => 1,
-	'sourcecredits' => 1,
+	'sourcecreatedate' => 1,
 	'sourcedata' => 1,
 	'sourcedate' => 1,
 	'sourceedition' => 1,
+	'sourcefilename' => 1,
 	'sourceform' => 1,
 	'sourceid' => 1,
@@ -5926,4 +10515,6 @@
 	'sourcetitle' => 1,
 	'sourceurl' => 1,
+	'spacefree' => 1,
+	'spaceused' => 1,
 	'spatialorientation' => 1,
 	'spatialresolution' => 1,
@@ -5931,8 +10522,13 @@
 	'specialeffectsopticalfilter' => 1,
 	'specialfolderdata' => 1,
+	'specificationversion' => 1,
 	'speed' => 1,
+	'sphericalvideo' => 1,
+	'sphericalvideoxml' => 1,
 	'spiff' => 1,
 	'spiffversion' => 1,
+	'spinstrength' => 1,
 	'spothalftone' => 1,
+	'spouse' => 1,
 	'sr2dataifd' => 1,
 	'sr2private' => 1,
@@ -5940,12 +10536,21 @@
 	'sr2subifdlength' => 1,
 	'sr2subifdoffset' => 1,
+	'srawtype' => 1,
 	'srf2key' => 1,
 	'srf6offset' => 1,
 	'srfdataoffset' => 1,
 	'srgbrendering' => 1,
+	'stampinfo' => 1,
 	'stamptoolcount' => 1,
+	'standbymonitorofftime' => 1,
 	'starring' => 1,
+	'startdate' => 1,
+	'startedgecode' => 1,
 	'startofframe' => 1,
+	'startreading' => 1,
 	'starttime' => 1,
+	'stateorprovince' => 1,
+	'stationcallsign' => 1,
+	'stationname' => 1,
 	'statistics' => 1,
 	'stdautoactive' => 1,
@@ -5961,12 +10566,20 @@
 	'stdsharpenoutput' => 1,
 	'stereo' => 1,
-	'stereo3dmode' => 1,
 	'stereoimage' => 1,
-	'stereomode' => 1,
+	'stereoscopic3d' => 1,
+	'stillimagetime' => 1,
 	'stim' => 1,
 	'stimversion' => 1,
+	'stitchcolumns' => 1,
 	'stitchinfo' => 1,
+	'stitchrows' => 1,
 	'stonits' => 1,
 	'storage-streampathname' => 1,
+	'storageformatdate' => 1,
+	'storageformattime' => 1,
+	'storagemodel' => 1,
+	'storageserialnumber' => 1,
+	'storagetype' => 1,
+	'store' => 1,
 	'stream' => 1,
 	'streamavgbitrate' => 1,
@@ -5994,6 +10607,6 @@
 	'streamsamplerate' => 1,
 	'streamstarttime' => 1,
-	'streamtype' => 1,
 	'streamtypeinfo' => 1,
+	'street' => 1,
 	'stridable' => 1,
 	'strikeout' => 1,
@@ -6003,5 +10616,14 @@
 	'strobe' => 1,
 	'strobetime' => 1,
+	'structuretype' => 1,
+	'studio' => 1,
 	'sub-sampleinformation' => 1,
+	'subdialframeadvance' => 1,
+	'subdialframeadvancerating0' => 1,
+	'subdialframeadvancerating1' => 1,
+	'subdialframeadvancerating2' => 1,
+	'subdialframeadvancerating3' => 1,
+	'subdialframeadvancerating4' => 1,
+	'subdialframeadvancerating5' => 1,
 	'subdir3000' => 1,
 	'subdir3100' => 1,
@@ -6036,46 +10658,88 @@
 	'subpacketsize' => 1,
 	'subscriptioncontentid' => 1,
-	'subseccreatedate' => 1,
-	'subsecdatetimeoriginal' => 1,
-	'subsecmodifydate' => 1,
 	'subsystem' => 1,
 	'subsystemversion' => 1,
 	'subtileblocksize' => 1,
-	'subtitle' => 1,
 	'subtitledescription' => 1,
-	'subtitlekeywords' => 1,
+	'suffix' => 1,
 	'suggestedpalette' => 1,
+	'summary' => 1,
 	'summaryinfo' => 1,
 	'surroundmode' => 1,
+	'surroundshotvideo' => 1,
+	'surroundshotvideoname' => 1,
 	'svgversion' => 1,
 	'swf' => 1,
-	'synchronizedlyrictext' => 1,
+	'sync01' => 1,
+	'sync02' => 1,
+	'sync03' => 1,
+	'sync04' => 1,
+	'sync05' => 1,
+	'sync06' => 1,
+	'sync07' => 1,
+	'sync08' => 1,
+	'sync09' => 1,
+	'sync10' => 1,
+	'sync11' => 1,
+	'sync12' => 1,
+	'sync13' => 1,
+	'sync14' => 1,
+	'sync15' => 1,
+	'sync16' => 1,
+	'synchronizedlyricsdescription' => 1,
+	'synchronizedlyricstext' => 1,
+	'synchronizedlyricstype' => 1,
+	'synconly' => 1,
 	'syncsampletable' => 1,
+	'syncstate' => 1,
+	'synlyrics' => 1,
+	'systemtime' => 1,
 	't4options' => 1,
 	't6options' => 1,
 	't82options' => 1,
 	't88options' => 1,
-	'tag' => 1,
-	'tagattachmentuid' => 1,
-	'tagbinary' => 1,
-	'tagchapteruid' => 1,
-	'tagdefault' => 1,
-	'tageditionuid' => 1,
+	'tag2010a' => 1,
+	'tag2010b' => 1,
+	'tag2010c' => 1,
+	'tag2010d' => 1,
+	'tag2010e' => 1,
+	'tag2010f' => 1,
+	'tag2010g' => 1,
+	'tag2010h' => 1,
+	'tag2010i' => 1,
+	'tag202a' => 1,
+	'tag900b' => 1,
+	'tag9050a' => 1,
+	'tag9050b' => 1,
+	'tag9050c' => 1,
+	'tag9400a' => 1,
+	'tag9400b' => 1,
+	'tag9400c' => 1,
+	'tag9401' => 1,
+	'tag9402' => 1,
+	'tag9403' => 1,
+	'tag9404a' => 1,
+	'tag9404b' => 1,
+	'tag9404c' => 1,
+	'tag9405a' => 1,
+	'tag9405b' => 1,
+	'tag9406' => 1,
+	'tag940a' => 1,
+	'tag940c' => 1,
+	'tag940e' => 1,
+	'tag9416_0000' => 1,
 	'taggedpdf' => 1,
 	'taggingtime' => 1,
-	'taglanguage' => 1,
-	'tagname' => 1,
-	'tags' => 1,
-	'tagstring' => 1,
-	'tagtrackuid' => 1,
+	'take' => 1,
+	'tamper-proofkeys' => 1,
 	'targetaudiences' => 1,
 	'targetdeltatype' => 1,
 	'targetfiledosname' => 1,
 	'targetfilesize' => 1,
-	'targetprinter' => 1,
-	'targets' => 1,
-	'targettype' => 1,
-	'targettypevalue' => 1,
+	'targetlayerid' => 1,
 	'targetxy' => 1,
+	'taskowner' => 1,
+	'tattoo' => 1,
+	'tcmediainfo' => 1,
 	'tdat' => 1,
 	'tdhd' => 1,
@@ -6083,44 +10747,84 @@
 	'technology' => 1,
 	'telephonenumber' => 1,
+	'telescope' => 1,
+	'telex' => 1,
 	'temperature' => 1,
-	'tempinfok5' => 1,
+	'tempinfo' => 1,
 	'template' => 1,
+	'temporalidnested' => 1,
+	'temporary' => 1,
 	'terminationaction' => 1,
 	'terminationcondition' => 1,
 	'termsofuse' => 1,
 	'testtarget' => 1,
+	'testtransfertiming' => 1,
 	'text' => 1,
+	'textcolor' => 1,
+	'textface' => 1,
+	'textfont' => 1,
 	'textinfo' => 1,
+	'textinfo1' => 1,
+	'textinfo2' => 1,
 	'textjunk' => 1,
+	'textsize' => 1,
+	'texttospeech' => 1,
 	'textualdata' => 1,
 	'textualinfo' => 1,
+	'textureformat' => 1,
+	'theora' => 1,
+	'theoraversion' => 1,
+	'thermalcalibration' => 1,
+	'thermaldata' => 1,
+	'thermalparams' => 1,
+	'thetasubdir' => 1,
 	'things' => 1,
 	'thirdlanguage' => 1,
+	'thumbinfo' => 1,
 	'thumbnail' => 1,
+	'thumbnailbpg' => 1,
 	'thumbnailclip' => 1,
+	'thumbnailcompressiontable' => 1,
+	'thumbnailexpansiontable' => 1,
+	'thumbnailref' => 1,
+	'thumbnailresizeratio' => 1,
+	'thumbnailtiff' => 1,
 	'tickspersecond' => 1,
 	'tiff' => 1,
 	'tiff-epstandardid' => 1,
 	'tiff_fxextensions' => 1,
+	'tiffmeteringimageheight' => 1,
+	'tiffmeteringimagewidth' => 1,
 	'tiffpreview' => 1,
 	'tilebytecounts' => 1,
 	'tiledepth' => 1,
+	'tilegaindeterminationtable' => 1,
 	'tileoffsets' => 1,
+	'tiles' => 1,
 	'timecode' => 1,
 	'timecodeindex' => 1,
 	'timecodeindexparms' => 1,
-	'timecodescale' => 1,
 	'timeinfo' => 1,
+	'timelineinfo' => 1,
 	'timeoffset' => 1,
 	'timereference' => 1,
 	'timescale' => 1,
-	'timeslice' => 1,
+	'timestamprandomoffset' => 1,
 	'timetosampletable' => 1,
 	'title2' => 1,
 	'titlelen' => 1,
+	'titlenum' => 1,
 	'titleofparts' => 1,
 	'titlesofparts' => 1,
 	'titlesortorder' => 1,
+	'toaddresses' => 1,
 	'tocitems' => 1,
+	'todotitle' => 1,
+	'tomtomad' => 1,
+	'tomtomhl' => 1,
+	'tomtomid' => 1,
+	'tomtommetadata' => 1,
+	'tomtomvd' => 1,
+	'tomtomvi' => 1,
+	'tonames' => 1,
 	'tonecurvematching' => 1,
 	'tonecurvetable' => 1,
@@ -6131,8 +10835,34 @@
 	'toneobjversion' => 1,
 	'tones' => 1,
+	'tonescale0' => 1,
+	'tonescale0spline' => 1,
+	'tonescale1' => 1,
+	'tonescale1spline' => 1,
+	'tonescale2' => 1,
+	'tonescale2spline' => 1,
+	'tonescale3' => 1,
+	'tonescale3spline' => 1,
+	'tonescale4' => 1,
+	'tonescale4spline' => 1,
+	'tonescale5' => 1,
+	'tonescale5spline' => 1,
+	'tonescale6' => 1,
+	'tonescale6spline' => 1,
+	'tonescale7' => 1,
+	'tonescale7spline' => 1,
+	'tonescale8' => 1,
+	'tonescale8spline' => 1,
+	'tonescale9' => 1,
+	'tonescale9spline' => 1,
 	'tonespaceflow' => 1,
+	'tonscaletable' => 1,
+	'tool_name' => 1,
+	'tool_version' => 1,
 	'toolname' => 1,
 	'toolversion' => 1,
+	'topdarkrow1' => 1,
+	'topdarkrow2' => 1,
 	'topmag' => 1,
+	'topmargin' => 1,
 	'totalbitrate' => 1,
 	'totalbytes' => 1,
@@ -6140,43 +10870,32 @@
 	'totaldatarate' => 1,
 	'totalduration' => 1,
+	'totaleditingtime' => 1,
 	'totaledittime' => 1,
+	'totalfilesize' => 1,
 	'totalframecount' => 1,
 	'totalframes' => 1,
 	'totalsamples' => 1,
+	'totalsize' => 1,
 	'toycamerafilter' => 1,
-	'track' => 1,
-	'trackattachmentuid' => 1,
+	'trackaperture' => 1,
 	'trackcategory' => 1,
 	'trackcomments' => 1,
-	'trackcreatedate' => 1,
-	'trackdefault' => 1,
 	'trackduration' => 1,
-	'trackentry' => 1,
 	'trackerdata' => 1,
-	'trackforced' => 1,
+	'trackfragment' => 1,
 	'trackheader' => 1,
 	'trackheaderversion' => 1,
 	'trackid' => 1,
-	'tracklacing' => 1,
-	'tracklanguage' => 1,
+	'trackingid' => 1,
 	'tracklayer' => 1,
 	'tracklyrics' => 1,
-	'trackmodifydate' => 1,
-	'trackname' => 1,
-	'trackoffset' => 1,
-	'trackoverlay' => 1,
 	'trackproperty' => 1,
 	'trackref' => 1,
-	'tracktimecodescale' => 1,
-	'tracktranslate' => 1,
-	'tracktranslatecodec' => 1,
-	'tracktranslateeditionuid' => 1,
-	'tracktranslatetrackid' => 1,
-	'tracktype' => 1,
-	'trackuid' => 1,
-	'trackused' => 1,
 	'trackvolume' => 1,
 	'trademark' => 1,
+	'transactionid' => 1,
+	'transfercharacteristic' => 1,
 	'transferrange' => 1,
+	'transfersequence' => 1,
 	'transformation' => 1,
 	'transformcreatedate' => 1,
@@ -6190,10 +10909,19 @@
 	'transparentindex' => 1,
 	'trapindicator' => 1,
-	'trebel' => 1,
-	'tvepisode' => 1,
-	'tvepisodeid' => 1,
-	'tvnetworkname' => 1,
-	'tvseason' => 1,
-	'tvshow' => 1,
+	'trashcolsright' => 1,
+	'trashrowsbottom' => 1,
+	'tty-ttdphone' => 1,
+	'tungmat0' => 1,
+	'tungmat1' => 1,
+	'tungmat2' => 1,
+	'tungmat3' => 1,
+	'tungmat4' => 1,
+	'tungmat5' => 1,
+	'tungmat6' => 1,
+	'tungmat7' => 1,
+	'tungmat8' => 1,
+	'tungmat9' => 1,
+	'twelvebit' => 1,
+	'tx3g' => 1,
 	'typeoforiginal' => 1,
 	'typist' => 1,
@@ -6205,4 +10933,6 @@
 	'uncompressed' => 1,
 	'uncompressedsize' => 1,
+	'uncompressedtextlength' => 1,
+	'underflowcolor' => 1,
 	'underline' => 1,
 	'underlineposition' => 1,
@@ -6211,8 +10941,15 @@
 	'uninitializeddatasize' => 1,
 	'uniquefileidentifier' => 1,
-	'units' => 1,
+	'uniqueid' => 1,
 	'unknown' => 1,
+	'unknown00' => 1,
+	'unknown01' => 1,
+	'unknown02' => 1,
+	'unknown03' => 1,
+	'unknown_cndb' => 1,
+	'unknown_slmt' => 1,
 	'unknownd30' => 1,
 	'unknowndata' => 1,
+	'unknownexif' => 1,
 	'unknowninfo' => 1,
 	'unknowninfo2' => 1,
@@ -6220,28 +10957,74 @@
 	'unknowninfoifd' => 1,
 	'unknowninfoversion' => 1,
-	'unknowntags' => 1,
+	'unknownserial1' => 1,
+	'unknownserial2' => 1,
+	'unknownserial3' => 1,
+	'unknownserial4' => 1,
+	'unknowntemperature1' => 1,
+	'unknowntemperature2' => 1,
 	'unsharpdata' => 1,
+	'untitled0' => 1,
+	'untitled1' => 1,
+	'untitled2' => 1,
 	'unused' => 1,
+	'unusedblackcolsleftin' => 1,
+	'unusedblackcolsleftout' => 1,
+	'unusedblackcolsrightin' => 1,
+	'unusedblackcolsrightout' => 1,
+	'unusedblackrowsbottomin' => 1,
+	'unusedblackrowsbottomout' => 1,
+	'unusedblackrowstopin' => 1,
+	'unusedblackrowstopout' => 1,
+	'updatedtitle' => 1,
 	'ur3' => 1,
-	'url_list' => 1,
+	'urllist1' => 1,
 	'urn' => 1,
 	'usagerightsmessage' => 1,
+	'usbpowerdelivery' => 1,
 	'usedextensionnumbers' => 1,
 	'useraccess' => 1,
 	'useradjsba_rgbshifts' => 1,
+	'usercustom1' => 1,
+	'usercustom2' => 1,
 	'userdata' => 1,
 	'userdefinedid' => 1,
 	'userdefinedtext' => 1,
 	'userdefinedurl' => 1,
+	'usereffectiverating' => 1,
+	'userid' => 1,
+	'userlastplayedtime' => 1,
+	'usermetadata' => 1,
+	'username' => 1,
+	'userplaycount' => 1,
+	'userplaycountafternoon' => 1,
+	'userplaycountevening' => 1,
+	'userplaycountmorning' => 1,
+	'userplaycountnight' => 1,
+	'userplaycountweekday' => 1,
+	'userplaycountweekend' => 1,
 	'userselectgrouptitle' => 1,
+	'userservicerating' => 1,
+	'usertext' => 1,
 	'userweburl' => 1,
 	'usingtransforms' => 1,
+	'usmparametershigh' => 1,
+	'usmparametershost' => 1,
+	'usmparametershost3mp' => 1,
+	'usmparametershost6mp' => 1,
+	'usmparameterslow' => 1,
+	'usmparametersmed' => 1,
 	'usptomiscellaneous' => 1,
 	'usptooriginalcontenttype' => 1,
 	'utm' => 1,
+	'uuid-canon' => 1,
+	'uuid-canon2' => 1,
 	'uuid-exif' => 1,
+	'uuid-exif2' => 1,
+	'uuid-exif_bad' => 1,
 	'uuid-flip' => 1,
 	'uuid-geojp2' => 1,
 	'uuid-iptc' => 1,
+	'uuid-iptc2' => 1,
+	'uuid-photoshop' => 1,
 	'uuid-prof' => 1,
 	'uuid-unknown' => 1,
@@ -6251,4 +11034,9 @@
 	'uuidlist' => 1,
 	'validafpoints' => 1,
+	'validate' => 1,
+	'value0' => 1,
+	'value1' => 1,
+	'value2' => 1,
+	'value3' => 1,
 	'vary' => 1,
 	'vbrbytes' => 1,
@@ -6256,19 +11044,27 @@
 	'vbrpeak' => 1,
 	'vbrscale' => 1,
+	'vddimdacnominalvalues' => 1,
 	'vegasversionmajor' => 1,
 	'vegasversionminor' => 1,
-	'vendor' => 1,
 	'vendorid' => 1,
 	'vendorname' => 1,
 	'vendorurl' => 1,
+	'version1' => 1,
 	'version2' => 1,
 	'versionbf' => 1,
 	'versionifd' => 1,
 	'versioninfo' => 1,
+	'versionrestrictions' => 1,
 	'versionyear' => 1,
+	'verticalaf-onbutton' => 1,
 	'verticalcitation' => 1,
 	'verticalcstype' => 1,
 	'verticaldatum' => 1,
 	'verticaldivergence' => 1,
+	'verticalmovieafonbutton' => 1,
+	'verticalmoviefuncbutton' => 1,
+	'verticalresolution' => 1,
+	'verticalscale' => 1,
+	'verticalspeed' => 1,
 	'verticalunits' => 1,
 	'video' => 1,
@@ -6276,5 +11072,4 @@
 	'videoavgbitrate' => 1,
 	'videoavgframerate' => 1,
-	'videobitrate' => 1,
 	'videocardgamma' => 1,
 	'videoclosedcaptioning' => 1,
@@ -6291,4 +11086,5 @@
 	'videomaxframerate' => 1,
 	'videomode' => 1,
+	'videoorientation' => 1,
 	'videoprofile' => 1,
 	'videoprofileversion' => 1,
@@ -6297,6 +11093,8 @@
 	'videosize' => 1,
 	'videostreamtype' => 1,
+	'videotimestamp' => 1,
 	'videotrackid' => 1,
 	'videowidth' => 1,
+	'view' => 1,
 	'viewable' => 1,
 	'viewingconddesc' => 1,
@@ -6308,4 +11106,9 @@
 	'vignettingcorr' => 1,
 	'vignettingcorr2' => 1,
+	'vignettingcorrunknown1' => 1,
+	'vignettingcorrunknown2' => 1,
+	'vignettingcorrversion' => 1,
+	'vignettingparams' => 1,
+	'vintagestrength' => 1,
 	'virtualimageheight' => 1,
 	'virtualimagewidth' => 1,
@@ -6314,9 +11117,33 @@
 	'visibleoutputs' => 1,
 	'vistaidlistdata' => 1,
-	'void' => 1,
+	'visualflightruleshud' => 1,
+	'vmaphandling' => 1,
+	'vmcoldropthresh' => 1,
+	'vmcolthresh' => 1,
+	'vmnbands' => 1,
+	'vmpatchreslimit' => 1,
+	'vmpixthresh' => 1,
+	'vmwsize' => 1,
+	'volumeblockcount' => 1,
+	'volumeblocksize' => 1,
+	'volumecreatedate' => 1,
+	'volumeeffectivedate' => 1,
+	'volumeexpirationdate' => 1,
 	'volumeid' => 1,
 	'volumelabel' => 1,
+	'volumemodifydate' => 1,
+	'volumename' => 1,
+	'volumenormalization' => 1,
+	'volumesetdiskcount' => 1,
+	'volumesetdisknumber' => 1,
+	'volumesetname' => 1,
+	'volumesize' => 1,
+	'vorbis' => 1,
 	'vorbiscomment' => 1,
 	'vorbisversion' => 1,
+	'vp8bitstream' => 1,
+	'vp8l' => 1,
+	'vp8version' => 1,
+	'vp8x' => 1,
 	'vrd1' => 1,
 	'vrd2' => 1,
@@ -6331,29 +11158,75 @@
 	'wangtag4' => 1,
 	'warning' => 1,
+	'warpquadrilateral' => 1,
+	'watched' => 1,
+	'watercolorfilter' => 1,
 	'watermark' => 1,
 	'watermarktype' => 1,
 	'watermarkurl' => 1,
+	'wave' => 1,
+	'wb_bluelevelauto' => 1,
+	'wb_cfa0_leveldaylight' => 1,
+	'wb_cfa1_leveldaylight' => 1,
+	'wb_cfa2_leveldaylight' => 1,
+	'wb_cfa3_leveldaylight' => 1,
+	'wb_grbglevelsauto' => 1,
+	'wb_grblevels' => 1,
+	'wb_grblevelsauto' => 1,
+	'wb_grblevelsstandard' => 1,
 	'wb_grgblevels' => 1,
-	'wb_rgbcoeffs0' => 1,
-	'wb_rgbcoeffs1' => 1,
-	'wb_rgbcoeffs2' => 1,
-	'wb_rgbcoeffs3' => 1,
-	'wb_rgblevelsauto' => 1,
+	'wb_grgblevelsdaylightfluor' => 1,
+	'wb_grgblevelsdaywhitefluor' => 1,
+	'wb_grgblevelslivingroomwarmwhitefluor' => 1,
+	'wb_grgblevelswarmwhitefluor' => 1,
+	'wb_grgblevelswhitefluorescent' => 1,
+	'wb_redlevelauto' => 1,
+	'wb_rgbcoeffsdaylight' => 1,
+	'wb_rgbcoeffsflash' => 1,
+	'wb_rgbcoeffsfluorescent' => 1,
+	'wb_rgbcoeffstungsten' => 1,
+	'wb_rgblevels2500k' => 1,
+	'wb_rgblevels3200k' => 1,
+	'wb_rgblevels4500k' => 1,
+	'wb_rgblevels6000k' => 1,
+	'wb_rgblevels8500k' => 1,
+	'wb_rgblevelsasshot' => 1,
 	'wb_rgblevelscloudy' => 1,
-	'wb_rgblevelsdaylight' => 1,
-	'wb_rgblevelsflash' => 1,
-	'wb_rgblevelsfluorescent' => 1,
-	'wb_rgblevelsshade' => 1,
+	'wb_rgblevelscustom' => 1,
+	'wb_rgblevelsfluorescentm1' => 1,
+	'wb_rgblevelsfluorescentp1' => 1,
+	'wb_rgblevelsfluorescentp2' => 1,
 	'wb_rgblevelstungsten' => 1,
-	'wb_rgbmul0' => 1,
-	'wb_rgbmul1' => 1,
-	'wb_rgbmul2' => 1,
-	'wb_rgbmul3' => 1,
 	'wbadjdata' => 1,
+	'wbblueasshot' => 1,
+	'wbbluecloudy' => 1,
+	'wbbluedaylight' => 1,
+	'wbblueflash' => 1,
+	'wbbluefluorescent' => 1,
+	'wbbluetungsten' => 1,
+	'wbgreenasshot' => 1,
+	'wbgreencloudy' => 1,
+	'wbgreendaylight' => 1,
+	'wbgreenflash' => 1,
+	'wbgreenfluorescent' => 1,
+	'wbgreentungsten' => 1,
+	'wbinfo' => 1,
+	'wbinfo2' => 1,
 	'wbinfoa100' => 1,
+	'wblevels' => 1,
+	'wbredasshot' => 1,
+	'wbredcloudy' => 1,
+	'wbreddaylight' => 1,
+	'wbredflash' => 1,
+	'wbredfluorescent' => 1,
+	'wbredtungsten' => 1,
+	'wbsettings' => 1,
+	'wbsettings2' => 1,
 	'wcsprofiles' => 1,
+	'webpage' => 1,
 	'weight' => 1,
 	'whitebalancematching' => 1,
+	'whitebalancergb' => 1,
 	'whitebalancetable' => 1,
+	'whiteluminance' => 1,
 	'whitepointx' => 1,
 	'whitepointy' => 1,
@@ -6367,9 +11240,17 @@
 	'widthbytes' => 1,
 	'widthresolution' => 1,
-	'windowlocation' => 1,
+	'wifirssi' => 1,
 	'windoworigin' => 1,
 	'windoworiginauto' => 1,
+	'windowsdevmode' => 1,
+	'windowsfilename' => 1,
 	'windowsize' => 1,
 	'windowtarget' => 1,
+	'wm_collectiongroupid' => 1,
+	'wm_collectionid' => 1,
+	'wm_contentid' => 1,
+	'wm_mediaclassprimaryid' => 1,
+	'wm_mediaclasssecondaryid' => 1,
+	'wm_provider' => 1,
 	'wmadrcaveragereference' => 1,
 	'wmadrcaveragetarget' => 1,
@@ -6379,4 +11260,8 @@
 	'wmcollectionid' => 1,
 	'wmcontentid' => 1,
+	'wmshadowfilesourcedrmtype' => 1,
+	'wmshadowfilesourcefiletype' => 1,
+	'word97' => 1,
+	'worddocument' => 1,
 	'words' => 1,
 	'workflowurl' => 1,
@@ -6384,10 +11269,24 @@
 	'workingpath' => 1,
 	'worldtime' => 1,
+	'worldtocamera' => 1,
+	'worldtondc' => 1,
+	'wrapmodes' => 1,
 	'writer' => 1,
-	'writingapp' => 1,
+	'writername' => 1,
+	'writers' => 1,
 	'writtenby' => 1,
 	'wwsfamilyname' => 1,
 	'wwssubfamilyname' => 1,
 	'x' => 1,
+	'xattrapplemaildatereceived' => 1,
+	'xattrapplemaildatesent' => 1,
+	'xattrapplemailisremoteattachment' => 1,
+	'xattrfinderinfo' => 1,
+	'xattrlastuseddate' => 1,
+	'xattrmditemdownloadeddate' => 1,
+	'xattrmditemfindercomment' => 1,
+	'xattrmditemwherefroms' => 1,
+	'xattrmdlabel' => 1,
+	'xattrresourcefork' => 1,
 	'xcfversion' => 1,
 	'xclippathunits' => 1,
@@ -6395,10 +11294,9 @@
 	'xmag' => 1,
 	'xmethod' => 1,
-	'xml' => 1,
 	'xmldata' => 1,
+	'xmlfiletype' => 1,
 	'xmp_profile' => 1,
 	'xmpbj' => 1,
 	'xmpdm' => 1,
-	'xmpextension' => 1,
 	'xmpmm' => 1,
 	'xmpnote' => 1,
@@ -6406,13 +11304,16 @@
 	'xmprights' => 1,
 	'xmptpg' => 1,
+	'xobject' => 1,
+	'xoffset' => 1,
 	'xp_dip_xml' => 1,
+	'xtranslayout' => 1,
 	'xylocation' => 1,
 	'xyoffsetinfo' => 1,
-	'yawangle' => 1,
 	'yclippathunits' => 1,
-	'year' => 1,
+	'ycrcbmatrix' => 1,
 	'ylevel' => 1,
 	'ymag' => 1,
 	'ymethod' => 1,
+	'yoffset' => 1,
 	'ytarget' => 1,
 	'zipbitflag' => 1,
@@ -6424,7 +11325,11 @@
 	'ziprequiredversion' => 1,
 	'zipuncompressedsize' => 1,
+	'zisrawversion' => 1,
 	'zoom' => 1,
 	'zoomedpreviewimage' => 1,
 	'zoompos' => 1,
+	'zoomposition' => 1,
+	'zoomstrength' => 1,
+	'zxif' => 1,
 );
 
@@ -6432,7 +11337,13 @@
 my %compositeModules = (
 	'filenumber' => 'Image::ExifTool::Canon',
+	'flash' => 'Image::ExifTool::XMP',
 	'jpgfromraw' => 'Image::ExifTool::Exif',
 	'originaldecisiondata' => 'Image::ExifTool::Canon',
+	'otherimage' => 'Image::ExifTool::Exif',
 	'previewimage' => 'Image::ExifTool::Exif',
+	'rotation' => 'Image::ExifTool::QuickTime',
+	'subseccreatedate' => 'Image::ExifTool::Exif',
+	'subsecdatetimeoriginal' => 'Image::ExifTool::Exif',
+	'subsecmodifydate' => 'Image::ExifTool::Exif',
 	'thumbnailimage' => 'Image::ExifTool::Exif',
 );
@@ -6445,4 +11356,5 @@
     TYPE        => 1,
     NOTES       => 1,
+    GROUPS      => 1,
 );
 
@@ -6471,9 +11383,10 @@
 #         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($$$$$$;$$)
 {
     my ($tagTablePtr, $tagID, $lcTag, $tagIDs, $lcTags, $tnum, $tagInfo, $baseID) = @_;
+    return if length($tagID) > 500;    # avoid deep recursion
     unless ($tagInfo) {
         $tagInfo = $$tagTablePtr{$tagID};
@@ -6484,6 +11397,6 @@
         my $strName = $strTable;
         $strTable = $Image::ExifTool::UserDefined::xmpStruct{$strTable};
-        $strTable or warn("No definition for structure '$strName'\n"), return;
-        $$strTable{STRUCT_NAME} or $$strTable{STRUCT_NAME} = $strName;
+        $strTable or warn("No definition for structure '${strName}'\n"), return;
+        $$strTable{STRUCT_NAME} or $$strTable{STRUCT_NAME} = "XMP $strName";
         $$tagInfo{Struct} = $strTable;  # replace name with hash ref
         delete $$tagInfo{SubDirectory}; # deprecated use of SubDirectory in Struct tags
@@ -6496,9 +11409,13 @@
         my $id = $tagID . ucfirst($field);
         # use name of existing flattened tag if already defined
-        my $lc = $$tagTablePtr{$id} ? lc $$tagTablePtr{$id}{Name} : $lcTag . lc($field);
+        my $flatInfo = $$tagTablePtr{$id};
+        my $fieldInfo = $$strTable{$field};
+        my $flatName;
+        $flatName = $$fieldInfo{FlatName} if ref $fieldInfo eq 'HASH';
+        $flatName or ($flatName = $field) =~ tr/-_a-zA-Z0-9//dc;    # remove illegal characters
+        my $lc = ($flatInfo and $$flatInfo{Name}) ? lc $$flatInfo{Name} : $lcTag . lc($flatName);
         my $copyID = $baseID;
         push @$tagIDs, \$copyID, $id;
         push @$lcTags, $lc, $lc;
-        my $fieldInfo = $$strTable{$field};
         next unless ref $fieldInfo eq 'HASH' and $$fieldInfo{Struct};
         # recursively add flattened tags for all sub-fields
@@ -6535,5 +11452,5 @@
             my $newInfo = $$tagTablePtr{$tagID};
             if (ref $newInfo eq 'HASH') {
-                $$newInfo{Name} or $$newInfo{Name} = ucfirst($tagID);
+                $$newInfo{Name} or $$newInfo{Name} = Image::ExifTool::MakeTagName($tagID);
                 # use new ID of tag in Composite table in case it changed
                 $tagID = $$newInfo{NewTagID} if defined $$newInfo{NewTagID};
@@ -6619,8 +11536,19 @@
     my $tag = shift;
     my $lcTag = lc($tag);
-    my ($tableNum, @tagInfoList);
+    my ($tableNum, @tagInfoList, @lookups);
     my $lookup = $tagLookup{$lcTag};
-    if ($lookup) {
-        foreach $tableNum (keys %$lookup) {
+    if (not $lookup and $lcTag =~ /[?*]/) {
+        # allow wildcards in tag name
+        my $pat = $lcTag;
+        $pat =~ s/\*/[-\\w]*/g;
+        $pat =~ s/\?/[-\\w]/g;
+        my @tags = grep(/^$pat$/, keys %tagLookup);
+        if (@tags) {
+            push @lookups, $tagLookup{$_} foreach sort @tags;
+            $lookup = shift @lookups;
+        }
+    }
+    while ($lookup) {
+        foreach $tableNum (sort { $a <=> $b } keys %$lookup) {
             my $table = GetTagTable($tableList[$tableNum]);
             my $le = $$lookup{$tableNum};
@@ -6646,5 +11574,8 @@
                     # 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};
@@ -6664,4 +11595,5 @@
             }
         }
+        $lookup = shift @lookups;
     }
     if (wantarray) {
@@ -6691,5 +11623,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagNames.pod
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagNames.pod	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/TagNames.pod	(revision 34921)
@@ -13,10 +13,16 @@
 
 The tables listed below give the names of all tags recognized by ExifTool.
-
-B<Tag ID>, B<Index> or B<Sequence> is given in the first column of each
+They contain a total of 24079 tags, with 15589 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
-is the identifier that is actually stored in the file.  An B<Index> refers
-to the location of a value when found at a fixed position within a data
-block, and B<Sequence> gives the order of values for a serial data stream.
+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 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
@@ -32,38 +38,41 @@
 
 The B<Writable> column indicates whether the tag is writable by ExifTool.
-Anything but an C<N> in this column means the tag is writable.  A C<Y>
+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
-"list" tag which supports multiple values and allows individual values to be
-added and deleted.  A slash (C</>) indicates an "avoided" tag that is not
-created when writing if another same-named tag may be created instead.  To
-write 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 point (C<!>) indicates a tag that is considered
-unsafe to write under normal circumstances.  These "unsafe" tags are not set
-when calling SetNewValuesFromFile() or copied with the exiftool
--tagsFromFile option unless specified explicitly, and care should be taken
-when editing them manually since they may affect the way an image is
-rendered.  An asterisk (C<*>) indicates a "protected" tag which is not
+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 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
+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
+taken when editing them manually since they may affect the way an image is
+rendered.  An asterisk (C<*>) indicates a I<Protected> tag which is not
 writable directly, but is written automatically by ExifTool (often when a
-corresponding Composite or Extra tag is written).  A colon (C<:>) indicates
-a mandatory tag which may be added automatically when writing.
+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.  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
-in the API, or or on a per-tag basis by appending a number symbol (C<#>) to
-the tag name.
+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.
 
 B<Note>: If you are familiar with common meta-information tag names, you may
@@ -74,7 +83,17 @@
 question.
 
+I<(This documentation is the result of years of research, testing and
+reverse engineering, and is the most complete metadata tag list available
+anywhere on the internet.  It is provided not only for ExifTool users, but
+more importantly as a public service to help augment the collective
+knowledge, and is often used as a primary source of information in the
+development of other metadata software.  Please help keep this documentation
+as accurate and complete as possible, and feed any new discoveries back to
+ExifTool.  A big thanks to everyone who has helped with this so far!)>
+
 =head2 JPEG Tags
 
-This table lists information extracted by ExifTool from JPEG images.
+This table lists information extracted by ExifTool from JPEG images. See
+L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JPEG specification.
 
   Tag ID       Tag Name                         Writable
@@ -89,20 +108,34 @@
                XMP                              XMP
                QVCI                             Casio QVCI
+               FLIR                             FLIR FFF
+               RawThermalImage                  no
   'APP2'       ICC_Profile                      ICC_Profile
                FPXR                             FlashPix
                MPF                              MPF
-               PreviewImage                     N
+               PreviewImage                     no
   'APP3'       Meta                             Kodak Meta
                Stim                             Stim
-               PreviewImage                     N
-  'APP4'       Scalado                          JPEG Scalado
+               ThermalData                      no
+               PreviewImage                     no
+  'APP4'       Scalado                          Scalado
                FPXR                             FlashPix
-               PreviewImage                     N
+               ThermalParams                    DJI ThermalParams
+               PreviewImage                     no
   'APP5'       RMETA                            Ricoh RMETA
+               SamsungUniqueID                  Samsung APP5
+               ThermalCalibration               no
+               PreviewImage                     no
   'APP6'       EPPIM                            JPEG EPPIM
                NITF                             JPEG NITF
                HP_TDHD                          HP TDHD
+               GoPro                            GoPro GPMF
+               DJI_DTAT                         no
+  'APP7'       Pentax                           Pentax
+               Huawei                           Unknown
+               Qualcomm                         Qualcomm
   'APP8'       SPIFF                            JPEG SPIFF
-  'APP10'      Comment                          N
+  'APP9'       MediaJukebox                     JPEG MediaJukebox
+  'APP10'      Comment                          no
+  'APP11'      JPEG-HDR                         JPEG HDR
   'APP12'      PictureInfo                      APP12 PictureInfo
                Ducky                            APP12 Ducky
@@ -111,6 +144,6 @@
   'APP14'      Adobe                            JPEG Adobe
   'APP15'      GraphicConverter                 JPEG GraphConv
-  'COM'        Comment                          Y
-  'DQT'        DefineQuantizationTable          N
+  'COM'        Comment                          yes
+  'DQT'        DefineQuantizationTable          no
   'SOF'        StartOfFrame                     JPEG SOF
   'Trailer'    AFCP                             AFCP
@@ -119,5 +152,8 @@
                PhotoMechanic                    PhotoMechanic
                MIE                              MIE
-               PreviewImage                     Y
+               Samsung                          Samsung Trailer
+               EmbeddedVideo                    no
+               Insta360                         no
+               PreviewImage                     yes
 
 =head3 JPEG AVI1 Tags
@@ -125,7 +161,7 @@
 This information may be found in APP0 of JPEG image data from AVI videos.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    InterleavedField                     N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    InterleavedField                     no
 
 =head3 JPEG Ocad Tags
@@ -136,17 +172,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'Rev'    OcadRevision                         N
-
-=head3 JPEG Scalado Tags
-
-Tags extracted from the JPEG APP4 "SCALADO" segment (presumably written by
-Scalado mobile software, L<http://www.scalado.com/>).
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  'HGHT'   PreviewImageHeight                   N
-  'QUAL'   PreviewQuality                       N
-  'SPMO'   DataLength                           N
-  'WDTH'   PreviewImageWidth                    N
+  'Rev'    OcadRevision                         no
 
 =head3 JPEG EPPIM Tags
@@ -165,18 +189,18 @@
 the official specification.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    NITFVersion                          N
-      2    ImageFormat                          N
-      3    BlocksPerRow                         N
-      5    BlocksPerColumn                      N
-      7    ImageColor                           N
-      8    BitDepth                             N
-      9    ImageClass                           N
-     10    JPEGProcess                          N
-     11    Quality                              N
-     12    StreamColor                          N
-     13    StreamBitDepth                       N
-     14    Flags                                N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    NITFVersion                          no
+      2    ImageFormat                          no
+      3    BlocksPerRow                         no
+      5    BlocksPerColumn                      no
+      7    ImageColor                           no
+      8    BitDepth                             no
+      9    ImageClass                           no
+     10    JPEGProcess                          no
+     11    Quality                              no
+     12    StreamColor                          no
+     13    StreamBitDepth                       no
+     14    Flags                                no
 
 =head3 JPEG SPIFF Tags
@@ -187,38 +211,72 @@
 specification.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    SPIFFVersion                         N
-      2    ProfileID                            N
-      3    ColorComponents                      N
-      6    ImageHeight                          N
-     10    ImageWidth                           N
-     14    ColorSpace                           N
-     15    BitsPerSample                        N
-     16    Compression                          N
-     17    ResolutionUnit                       N
-     18    YResolution                          N
-     22    XResolution                          N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    SPIFFVersion                         no
+      2    ProfileID                            no
+      3    ColorComponents                      no
+      6    ImageHeight                          no
+     10    ImageWidth                           no
+     14    ColorSpace                           no
+     15    BitsPerSample                        no
+     16    Compression                          no
+     17    ResolutionUnit                       no
+     18    YResolution                          no
+     22    XResolution                          no
+
+=head3 JPEG MediaJukebox Tags
+
+Tags found in the XML metadata of the APP9 "Media Jukebox" segment.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Album                                         no
+  Caption                                       no
+  Date                                          no
+  Keywords                                      no
+  Name                                          no
+  People                                        no
+  Places                                        no
+  Tool_Name                                     no
+  Tool_Version                                  no
+
+=head3 JPEG HDR Tags
+
+Information extracted from APP11 of a JPEG-HDR image.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'RatioImage'         RatioImage               no
+  'alp'                Alpha                    no
+  'bet'                Beta                     no
+  'cor'                CorrectionMethod         no
+  'ln0'                Ln0                      no
+  'ln1'                Ln1                      no
+  's2n'                S2n                      no
+  'ver'                JPEG-HDRVersion          no
 
 =head3 JPEG AdobeCM Tags
 
-The "Adobe_CM" APP13 segment presumably contains color management
+The APP13 "Adobe_CM" segment presumably contains color management
 information, but the meaning of the data is currently unknown.  If anyone
 has an idea about what this means, please let me know.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    AdobeCMType                          N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    AdobeCMType                          no
 
 =head3 JPEG Adobe Tags
 
-The "Adobe" APP14 segment stores image encoding information for DCT filters.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    DCTEncodeVersion                     N
-      1    APP14Flags0                          N
-      2    APP14Flags1                          N
-      3    ColorTransform                       N
+The APP14 "Adobe" segment stores image encoding information for DCT filters.
+This segment may be copied or deleted as a block using the Extra "Adobe"
+tag, but note that it is not deleted by default when deleting all metadata
+because it may affect the appearance of the image.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    DCTEncodeVersion                     no
+      1    APP14Flags0                          no
+      2    APP14Flags1                          no
+      3    ColorTransform                       no
 
 =head3 JPEG GraphConv Tags
@@ -228,5 +286,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'Q'      Quality                              N
+  'Q'      Quality                              no
 
 =head3 JPEG SOF Tags
@@ -236,10 +294,10 @@
   Tag Name                                      Writable
   --------                                      --------
-  BitsPerSample                                 N
-  ColorComponents                               N
-  EncodingProcess                               N
-  ImageHeight                                   N
-  ImageWidth                                    N
-  YCbCrSubSampling                              N
+  BitsPerSample                                 no
+  ColorComponents                               no
+  EncodingProcess                               no
+  ImageHeight                                   no
+  ImageWidth                                    no
+  YCbCrSubSampling                              no
 
 =head2 EXIF Tags
@@ -247,6 +305,6 @@
 EXIF stands for "Exchangeable Image File Format".  This type of information
 is formatted according to the TIFF specification, and may be found in JPG,
-TIFF, PNG, PGF, MIFF, HDP, PSP and XCF images, as well as many TIFF-based
-RAW images, and even some AVI and MOV videos.
+TIFF, PNG, JP2, PGF, MIFF, HDP, PSP and XCF images, as well as many
+TIFF-based RAW images, and even some AVI and MOV videos.
 
 The EXIF meta information is organized into different Image File Directories
@@ -255,11 +313,16 @@
 B<Group> listed below is used unless another group is specified.
 
+Mandatory tags (indicated by a colon after the B<Writable> type) may be
+added automatically with default values when creating a new IFD, and the IFD
+is removed automatically when deleting tags if only default-valued mandatory
+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.3
+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/english/hyoujunka/kikaku/pdf/DC-008-2010_E.pdf> for the
-official EXIF 2.3 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
@@ -283,14 +346,14 @@
   0x010f   Make                      IFD0       string
   0x0110   Model                     IFD0       string
-  0x0111   StripOffsets              -          N
+  0x0111   StripOffsets              -          no
            PreviewImageStart         IFD0       int32u*
-           PreviewImageStart         SubIFD1    int32u*
+           PreviewImageStart         All        int32u*
            JpgFromRawStart           SubIFD2    int32u*
   0x0112   Orientation               IFD0       int16u
   0x0115   SamplesPerPixel           IFD0       int16u!
   0x0116   RowsPerStrip              IFD0       int32u!
-  0x0117   StripByteCounts           -          N
+  0x0117   StripByteCounts           -          no
            PreviewImageLength        IFD0       int32u*
-           PreviewImageLength        SubIFD1    int32u*
+           PreviewImageLength        All        int32u*
            JpgFromRawLength          SubIFD2    int32u*
   0x0118   MinSampleValue            IFD0       int16u
@@ -302,13 +365,13 @@
   0x011e   XPosition                 IFD0       rational64u
   0x011f   YPosition                 IFD0       rational64u
-  0x0120   FreeOffsets               -          N
-  0x0121   FreeByteCounts            -          N
+  0x0120   FreeOffsets               -          no
+  0x0121   FreeByteCounts            -          no
   0x0122   GrayResponseUnit          IFD0       int16u
-  0x0123   GrayResponseCurve         -          N
-  0x0124   T4Options                 -          N
-  0x0125   T6Options                 -          N
+  0x0123   GrayResponseCurve         -          no
+  0x0124   T4Options                 -          no
+  0x0125   T6Options                 -          no
   0x0128   ResolutionUnit            IFD0       int16u:
   0x0129   PageNumber                IFD0       int16u[2]
-  0x012c   ColorResponseUnit         -          N
+  0x012c   ColorResponseUnit         -          no
   0x012d   TransferFunction          IFD0       int16u[768]!
   0x0131   Software                  IFD0       string
@@ -319,42 +382,42 @@
   0x013e   WhitePoint                IFD0       rational64u[2]
   0x013f   PrimaryChromaticities     IFD0       rational64u[6]
-  0x0140   ColorMap                  -          N
+  0x0140   ColorMap                  -          no
   0x0141   HalftoneHints             IFD0       int16u[2]
   0x0142   TileWidth                 IFD0       int32u!
   0x0143   TileLength                IFD0       int32u!
-  0x0144   TileOffsets               -          N
-  0x0145   TileByteCounts            -          N
-  0x0146   BadFaxLines               -          N
-  0x0147   CleanFaxData              -          N
-  0x0148   ConsecutiveBadFaxLines    -          N
+  0x0144   TileOffsets               -          no
+  0x0145   TileByteCounts            -          no
+  0x0146   BadFaxLines               -          no
+  0x0147   CleanFaxData              -          no
+  0x0148   ConsecutiveBadFaxLines    -          no
   0x014a   SubIFD                    -          EXIF
-           A100DataOffset            -          N
+           A100DataOffset            IFD0       no
   0x014c   InkSet                    IFD0       int16u
-  0x014d   InkNames                  -          N
-  0x014e   NumberofInks              -          N
-  0x0150   DotRange                  IFD0       string
-  0x0151   TargetPrinter             -          N
-  0x0152   ExtraSamples              -          N
-  0x0153   SampleFormat              -          N
-  0x0154   SMinSampleValue           -          N
-  0x0155   SMaxSampleValue           -          N
-  0x0156   TransferRange             -          N
-  0x0157   ClipPath                  -          N
-  0x0158   XClipPathUnits            -          N
-  0x0159   YClipPathUnits            -          N
-  0x015a   Indexed                   -          N
-  0x015b   JPEGTables                -          N
-  0x015f   OPIProxy                  -          N
+  0x014d   InkNames                  -          no
+  0x014e   NumberofInks              -          no
+  0x0150   DotRange                  -          no
+  0x0151   TargetPrinter             IFD0       string
+  0x0152   ExtraSamples              -          no
+  0x0153   SampleFormat              SubIFD     no
+  0x0154   SMinSampleValue           -          no
+  0x0155   SMaxSampleValue           -          no
+  0x0156   TransferRange             -          no
+  0x0157   ClipPath                  -          no
+  0x0158   XClipPathUnits            -          no
+  0x0159   YClipPathUnits            -          no
+  0x015a   Indexed                   -          no
+  0x015b   JPEGTables                -          no
+  0x015f   OPIProxy                  -          no
   0x0190   GlobalParametersIFD       -          EXIF
-  0x0191   ProfileType               -          N
-  0x0192   FaxProfile                -          N
-  0x0193   CodingMethods             -          N
-  0x0194   VersionYear               -          N
-  0x0195   ModeNumber                -          N
-  0x01b1   Decode                    -          N
-  0x01b2   DefaultImageColor         -          N
-  0x01b3   T82Options                -          N
-  0x01b5   JPEGTables                -          N
-  0x0200   JPEGProc                  -          N
+  0x0191   ProfileType               -          no
+  0x0192   FaxProfile                -          no
+  0x0193   CodingMethods             -          no
+  0x0194   VersionYear               -          no
+  0x0195   ModeNumber                -          no
+  0x01b1   Decode                    -          no
+  0x01b2   DefaultImageColor         -          no
+  0x01b3   T82Options                -          no
+  0x01b5   JPEGTables                -          no
+  0x0200   JPEGProc                  -          no
   0x0201   ThumbnailOffset           IFD1       int32u*
            ThumbnailOffset           IFD0       int32u*
@@ -364,5 +427,7 @@
            JpgFromRawStart           SubIFD     int32u*
            JpgFromRawStart           IFD2       int32u*
-           OtherImageStart           -          N
+           OtherImageStart           SubIFD1    int32u*
+           OtherImageStart           SubIFD2    int32u*
+           OtherImageStart           -          no
   0x0202   ThumbnailLength           IFD1       int32u*
            ThumbnailLength           IFD0       int32u*
@@ -372,103 +437,128 @@
            JpgFromRawLength          SubIFD     int32u*
            JpgFromRawLength          IFD2       int32u*
-           OtherImageLength          -          N
-  0x0203   JPEGRestartInterval       -          N
-  0x0205   JPEGLosslessPredictors    -          N
-  0x0206   JPEGPointTransforms       -          N
-  0x0207   JPEGQTables               -          N
-  0x0208   JPEGDCTables              -          N
-  0x0209   JPEGACTables              -          N
+           OtherImageLength          SubIFD1    int32u*
+           OtherImageLength          SubIFD2    int32u*
+           OtherImageLength          -          no
+  0x0203   JPEGRestartInterval       -          no
+  0x0205   JPEGLosslessPredictors    -          no
+  0x0206   JPEGPointTransforms       -          no
+  0x0207   JPEGQTables               -          no
+  0x0208   JPEGDCTables              -          no
+  0x0209   JPEGACTables              -          no
   0x0211   YCbCrCoefficients         IFD0       rational64u[3]!
   0x0212   YCbCrSubSampling          IFD0       int16u[2]!
   0x0213   YCbCrPositioning          IFD0       int16u!:
   0x0214   ReferenceBlackWhite       IFD0       rational64u[6]
-  0x022f   StripRowCounts            -          N
-  0x02bc   ApplicationNotes          ExifIFD    XMP
-  0x03e7   USPTOMiscellaneous        -          N
+  0x022f   StripRowCounts            -          no
+  0x02bc   ApplicationNotes          IFD0       XMP
+  0x03e7   USPTOMiscellaneous        -          no
   0x1000   RelatedImageFileFormat    InteropIFD string!
   0x1001   RelatedImageWidth         InteropIFD int16u!
   0x1002   RelatedImageHeight        InteropIFD int16u!
   0x4746   Rating                    IFD0       int16u/
-  0x4747   XP_DIP_XML                -          N
+  0x4747   XP_DIP_XML                -          no
   0x4748   StitchInfo                -          Microsoft Stitch
   0x4749   RatingPercent             IFD0       int16u/
-  0x800d   ImageID                   -          N
-  0x80a3   WangTag1                  -          N
-  0x80a4   WangAnnotation            -          N
-  0x80a5   WangTag3                  -          N
-  0x80a6   WangTag4                  -          N
-  0x80e3   Matteing                  -          N
-  0x80e4   DataType                  -          N
-  0x80e5   ImageDepth                -          N
-  0x80e6   TileDepth                 -          N
-  0x827d   Model2                    -          N
-  0x828d   CFARepeatPatternDim       -          N
-  0x828e   CFAPattern2               -          N
-  0x828f   BatteryLevel              -          N
+  0x7000   SonyRawFileType           -          no
+  0x7010   SonyToneCurve             -          no
+  0x7031   VignettingCorrection      SubIFD     int16s!
+  0x7032   VignettingCorrParams      SubIFD     int16s[17]!
+  0x7034   ChromaticAberrationCorrection SubIFD int16s!
+  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
+  0x80a5   WangTag3                  -          no
+  0x80a6   WangTag4                  -          no
+  0x80b9   ImageReferencePoints      -          no
+  0x80ba   RegionXformTackPoint      -          no
+  0x80bb   WarpQuadrilateral         -          no
+  0x80bc   AffineTransformMat        -          no
+  0x80e3   Matteing                  -          no
+  0x80e4   DataType                  -          no
+  0x80e5   ImageDepth                -          no
+  0x80e6   TileDepth                 -          no
+  0x8214   ImageFullWidth            -          no
+  0x8215   ImageFullHeight           -          no
+  0x8216   TextureFormat             -          no
+  0x8217   WrapModes                 -          no
+  0x8218   FovCot                    -          no
+  0x8219   MatrixWorldToScreen       -          no
+  0x821a   MatrixWorldToCamera       -          no
+  0x827d   Model2                    -          no
+  0x828d   CFARepeatPatternDim       SubIFD     int16u[2]!
+  0x828e   CFAPattern2               SubIFD     int8u[n]!
+  0x828f   BatteryLevel              -          no
   0x8290   KodakIFD                  -          Kodak IFD
   0x8298   Copyright                 IFD0       string
   0x829a   ExposureTime              ExifIFD    rational64u
   0x829d   FNumber                   ExifIFD    rational64u
-  0x82a5   MDFileTag                 -          N
-  0x82a6   MDScalePixel              -          N
-  0x82a7   MDColorTable              -          N
-  0x82a8   MDLabName                 -          N
-  0x82a9   MDSampleInfo              -          N
-  0x82aa   MDPrepDate                -          N
-  0x82ab   MDPrepTime                -          N
-  0x82ac   MDFileUnits               -          N
-  0x830e   PixelScale                -          N
-  0x8335   AdventScale               -          N
-  0x8336   AdventRevision            -          N
-  0x835c   UIC1Tag                   -          N
-  0x835d   UIC2Tag                   -          N
-  0x835e   UIC3Tag                   -          N
-  0x835f   UIC4Tag                   -          N
+  0x82a5   MDFileTag                 -          no
+  0x82a6   MDScalePixel              -          no
+  0x82a7   MDColorTable              -          no
+  0x82a8   MDLabName                 -          no
+  0x82a9   MDSampleInfo              -          no
+  0x82aa   MDPrepDate                -          no
+  0x82ab   MDPrepTime                -          no
+  0x82ac   MDFileUnits               -          no
+  0x830e   PixelScale                IFD0       double[3]
+  0x8335   AdventScale               -          no
+  0x8336   AdventRevision            -          no
+  0x835c   UIC1Tag                   -          no
+  0x835d   UIC2Tag                   -          no
+  0x835e   UIC3Tag                   -          no
+  0x835f   UIC4Tag                   -          no
   0x83bb   IPTC-NAA                  IFD0       IPTC
-  0x847e   IntergraphPacketData      -          N
-  0x847f   IntergraphFlagRegisters   -          N
-  0x8480   IntergraphMatrix          -          N
-  0x8481   INGRReserved              -          N
-  0x8482   ModelTiePoint             -          N
-  0x84e0   Site                      -          N
-  0x84e1   ColorSequence             -          N
-  0x84e2   IT8Header                 -          N
-  0x84e3   RasterPadding             -          N
-  0x84e4   BitsPerRunLength          -          N
-  0x84e5   BitsPerExtendedRunLength  -          N
-  0x84e6   ColorTable                -          N
-  0x84e7   ImageColorIndicator       -          N
-  0x84e8   BackgroundColorIndicator  -          N
-  0x84e9   ImageColorValue           -          N
-  0x84ea   BackgroundColorValue      -          N
-  0x84eb   PixelIntensityRange       -          N
-  0x84ec   TransparencyIndicator     -          N
-  0x84ed   ColorCharacterization     -          N
-  0x84ee   HCUsage                   -          N
-  0x84ef   TrapIndicator             -          N
-  0x84f0   CMYKEquivalent            -          N
+  0x847e   IntergraphPacketData      -          no
+  0x847f   IntergraphFlagRegisters   -          no
+  0x8480   IntergraphMatrix          IFD0       double[n]
+  0x8481   INGRReserved              -          no
+  0x8482   ModelTiePoint             IFD0       double[n]
+  0x84e0   Site                      -          no
+  0x84e1   ColorSequence             -          no
+  0x84e2   IT8Header                 -          no
+  0x84e3   RasterPadding             -          no
+  0x84e4   BitsPerRunLength          -          no
+  0x84e5   BitsPerExtendedRunLength  -          no
+  0x84e6   ColorTable                -          no
+  0x84e7   ImageColorIndicator       -          no
+  0x84e8   BackgroundColorIndicator  -          no
+  0x84e9   ImageColorValue           -          no
+  0x84ea   BackgroundColorValue      -          no
+  0x84eb   PixelIntensityRange       -          no
+  0x84ec   TransparencyIndicator     -          no
+  0x84ed   ColorCharacterization     -          no
+  0x84ee   HCUsage                   -          no
+  0x84ef   TrapIndicator             -          no
+  0x84f0   CMYKEquivalent            -          no
   0x8546   SEMInfo                   IFD0       string
   0x8568   AFCP_IPTC                 -          IPTC
-  0x85b8   PixelMagicJBIGOptions     -          N
-  0x85d8   ModelTransform            -          N
-  0x8602   WB_GRGBLevels             -          N
+  0x85b8   PixelMagicJBIGOptions     -          no
+  0x85d7   JPLCartoIFD               -          no
+  0x85d8   ModelTransform            IFD0       double[16]
+  0x8602   WB_GRGBLevels             -          no
   0x8606   LeafData                  -          Leaf
-  0x8649   PhotoshopSettings         -          Photoshop
-  0x8769   ExifOffset                -          EXIF
-  0x8773   ICC_Profile               -          ICC_Profile
-  0x877f   TIFF_FXExtensions         -          N
-  0x8780   MultiProfiles             -          N
-  0x8781   SharedData                -          N
-  0x8782   T88Options                -          N
-  0x87ac   ImageLayer                -          N
-  0x87af   GeoTiffDirectory          -          N
-  0x87b0   GeoTiffDoubleParams       -          N
-  0x87b1   GeoTiffAsciiParams        -          N
+  0x8649   PhotoshopSettings         IFD0       Photoshop
+  0x8769   ExifOffset                IFD0       EXIF
+  0x8773   ICC_Profile               IFD0       ICC_Profile
+  0x877f   TIFF_FXExtensions         -          no
+  0x8780   MultiProfiles             -          no
+  0x8781   SharedData                -          no
+  0x8782   T88Options                -          no
+  0x87ac   ImageLayer                -          no
+  0x87af   GeoTiffDirectory          IFD0       int16u[0.5]
+  0x87b0   GeoTiffDoubleParams       IFD0       double[0.125]
+  0x87b1   GeoTiffAsciiParams        IFD0       string
+  0x87be   JBIGOptions               -          no
   0x8822   ExposureProgram           ExifIFD    int16u
   0x8824   SpectralSensitivity       ExifIFD    string
-  0x8825   GPSInfo                   -          GPS
+  0x8825   GPSInfo                   IFD0       GPS
   0x8827   ISO                       ExifIFD    int16u[n]
-  0x8828   Opto-ElectricConvFactor   -          N
-  0x8829   Interlace                 -          N
+  0x8828   Opto-ElectricConvFactor   -          no
+  0x8829   Interlace                 -          no
   0x882a   TimeZoneOffset            ExifIFD    int16s[n]
   0x882b   SelfTimerMode             ExifIFD    int16u
@@ -479,11 +569,16 @@
   0x8834   ISOSpeedLatitudeyyy       ExifIFD    int32u
   0x8835   ISOSpeedLatitudezzz       ExifIFD    int32u
-  0x885c   FaxRecvParams             -          N
-  0x885d   FaxSubAddress             -          N
-  0x885e   FaxRecvTime               -          N
+  0x885c   FaxRecvParams             -          no
+  0x885d   FaxSubAddress             -          no
+  0x885e   FaxRecvTime               -          no
+  0x8871   FedexEDR                  -          no
   0x888a   LeafSubIFD                -          Leaf SubIFD
   0x9000   ExifVersion               ExifIFD    undef:
   0x9003   DateTimeOriginal          ExifIFD    string
   0x9004   CreateDate                ExifIFD    string
+  0x9009   GooglePlusUploadCode      ExifIFD    undef[n]
+  0x9010   OffsetTime                ExifIFD    string
+  0x9011   OffsetTimeOriginal        ExifIFD    string
+  0x9012   OffsetTimeDigitized       ExifIFD    string
   0x9101   ComponentsConfiguration   ExifIFD    undef[4]!:
   0x9102   CompressedBitsPerPixel    ExifIFD    rational64u!
@@ -498,27 +593,32 @@
   0x9209   Flash                     ExifIFD    int16u
   0x920a   FocalLength               ExifIFD    rational64u
-  0x920b   FlashEnergy               -          N
-  0x920c   SpatialFrequencyResponse  -          N
-  0x920d   Noise                     -          N
-  0x920e   FocalPlaneXResolution     -          N
-  0x920f   FocalPlaneYResolution     -          N
-  0x9210   FocalPlaneResolutionUnit  -          N
+  0x920b   FlashEnergy               -          no
+  0x920c   SpatialFrequencyResponse  -          no
+  0x920d   Noise                     -          no
+  0x920e   FocalPlaneXResolution     -          no
+  0x920f   FocalPlaneYResolution     -          no
+  0x9210   FocalPlaneResolutionUnit  -          no
   0x9211   ImageNumber               ExifIFD    int32u
   0x9212   SecurityClassification    ExifIFD    string
   0x9213   ImageHistory              ExifIFD    string
   0x9214   SubjectArea               ExifIFD    int16u[n]
-  0x9215   ExposureIndex             -          N
-  0x9216   TIFF-EPStandardID         -          N
-  0x9217   SensingMethod             -          N
-  0x923a   CIP3DataFile              -          N
-  0x923b   CIP3Sheet                 -          N
-  0x923c   CIP3Side                  -          N
-  0x923f   StoNits                   -          N
-  0x927c   MakerNoteCanon            ExifIFD    Canon
+  0x9215   ExposureIndex             -          no
+  0x9216   TIFF-EPStandardID         -          no
+  0x9217   SensingMethod             -          no
+  0x923a   CIP3DataFile              -          no
+  0x923b   CIP3Sheet                 -          no
+  0x923c   CIP3Side                  -          no
+  0x923f   StoNits                   -          no
+  0x927c   MakerNoteApple            ExifIFD    Apple
+           MakerNoteNikon            ExifIFD    Nikon
+           MakerNoteCanon            ExifIFD    Canon
            MakerNoteCasio            ExifIFD    Casio
            MakerNoteCasio2           ExifIFD    Casio Type2
+           MakerNoteDJI              ExifIFD    DJI
+           MakerNoteFLIR             ExifIFD    FLIR
            MakerNoteFujiFilm         ExifIFD    FujiFilm
            MakerNoteGE               ExifIFD    GE
            MakerNoteGE2              ExifIFD    FujiFilm
+           MakerNoteHasselblad       ExifIFD    Unknown
            MakerNoteHP               ExifIFD    HP
            MakerNoteHP2              ExifIFD    HP Type2
@@ -539,6 +639,9 @@
            MakerNoteKodak8a          ExifIFD    Kodak Type8
            MakerNoteKodak8b          ExifIFD    Kodak Type8
+           MakerNoteKodak8c          ExifIFD    Kodak Type8
            MakerNoteKodak9           ExifIFD    Kodak Type9
            MakerNoteKodak10          ExifIFD    Kodak Type10
+           MakerNoteKodak11          ExifIFD    Kodak Type11
+           MakerNoteKodak12          ExifIFD    Kodak Type11
            MakerNoteKodakUnknown     ExifIFD    Kodak Unknown
            MakerNoteKyocera          ExifIFD    Unknown
@@ -546,7 +649,8 @@
            MakerNoteMinolta2         ExifIFD    Olympus
            MakerNoteMinolta3         ExifIFD    undef
-           MakerNoteNikon            ExifIFD    Nikon
+           MakerNoteMotorola         ExifIFD    Motorola
            MakerNoteNikon2           ExifIFD    Nikon Type2
            MakerNoteNikon3           ExifIFD    Nikon
+           MakerNoteNintendo         ExifIFD    Nintendo
            MakerNoteOlympus          ExifIFD    Olympus
            MakerNoteOlympus2         ExifIFD    Olympus
@@ -557,6 +661,11 @@
            MakerNoteLeica5           ExifIFD    Panasonic Leica5
            MakerNoteLeica6           ExifIFD    Panasonic Leica6
+           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
            MakerNotePentax           ExifIFD    Pentax
            MakerNotePentax2          ExifIFD    Pentax Type2
@@ -564,10 +673,15 @@
            MakerNotePentax4          ExifIFD    Pentax Type4
            MakerNotePentax5          ExifIFD    Pentax
-           MakerNotePhaseOne         ExifIFD    undef
+           MakerNotePentax6          ExifIFD    Pentax S1
+           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
            MakerNoteSamsung1a        ExifIFD    undef
-           MakerNoteSamsung1b        ExifIFD    Samsung Type1
+           MakerNoteSamsung1b        ExifIFD    Samsung
            MakerNoteSamsung2         ExifIFD    Samsung Type2
            MakerNoteSanyo            ExifIFD    Sanyo
@@ -578,8 +692,10 @@
            MakerNoteSony2            ExifIFD    Olympus
            MakerNoteSony3            ExifIFD    Olympus
-           MakerNoteSony4            ExifIFD    Sony
+           MakerNoteSony4            ExifIFD    Sony PIC
+           MakerNoteSony5            ExifIFD    Sony
            MakerNoteSonyEricsson     ExifIFD    Sony Ericsson
            MakerNoteSonySRF          ExifIFD    Sony SRF
            MakerNoteUnknownText      ExifIFD    undef
+           MakerNoteUnknownBinary    ExifIFD    undef
            MakerNoteUnknown          ExifIFD    Unknown
   0x9286   UserComment               ExifIFD    undef
@@ -587,8 +703,14 @@
   0x9291   SubSecTimeOriginal        ExifIFD    string
   0x9292   SubSecTimeDigitized       ExifIFD    string
-  0x932f   MSDocumentText            -          N
-  0x9330   MSPropertySetStorage      -          N
-  0x9331   MSDocumentTextPosition    -          N
-  0x935c   ImageSourceData           IFD0       undef!
+  0x932f   MSDocumentText            -          no
+  0x9330   MSPropertySetStorage      -          no
+  0x9331   MSDocumentTextPosition    -          no
+  0x935c   ImageSourceData           IFD0       Photoshop DocumentData
+  0x9400   AmbientTemperature        ExifIFD    rational64s
+  0x9401   Humidity                  ExifIFD    rational64u
+  0x9402   Pressure                  ExifIFD    rational64u
+  0x9403   WaterDepth                ExifIFD    rational64s
+  0x9404   Acceleration              ExifIFD    rational64u
+  0x9405   CameraElevationAngle      ExifIFD    rational64s
   0x9c9b   XPTitle                   IFD0       int8u
   0x9c9c   XPComment                 IFD0       int8u
@@ -602,16 +724,20 @@
   0xa004   RelatedSoundFile          ExifIFD    string
   0xa005   InteropOffset             -          EXIF
-  0xa20b   FlashEnergy               ExifIFD    rational64u[n]
-  0xa20c   SpatialFrequencyResponse  -          N
-  0xa20d   Noise                     -          N
+  0xa010   SamsungRawPointersOffset  -          no
+  0xa011   SamsungRawPointersLength  -          no
+  0xa101   SamsungRawByteOrder       -          no
+  0xa102   SamsungRawUnknown?        -          no
+  0xa20b   FlashEnergy               ExifIFD    rational64u
+  0xa20c   SpatialFrequencyResponse  -          no
+  0xa20d   Noise                     -          no
   0xa20e   FocalPlaneXResolution     ExifIFD    rational64u
   0xa20f   FocalPlaneYResolution     ExifIFD    rational64u
   0xa210   FocalPlaneResolutionUnit  ExifIFD    int16u
-  0xa211   ImageNumber               -          N
-  0xa212   SecurityClassification    -          N
-  0xa213   ImageHistory              -          N
+  0xa211   ImageNumber               -          no
+  0xa212   SecurityClassification    -          no
+  0xa213   ImageHistory              -          no
   0xa214   SubjectLocation           ExifIFD    int16u[2]
   0xa215   ExposureIndex             ExifIFD    rational64u
-  0xa216   TIFF-EPStandardID         -          N
+  0xa216   TIFF-EPStandardID         -          no
   0xa217   SensingMethod             ExifIFD    int16u
   0xa300   FileSource                ExifIFD    undef
@@ -628,5 +754,5 @@
   0xa409   Saturation                ExifIFD    int16u
   0xa40a   Sharpness                 ExifIFD    int16u
-  0xa40b   DeviceSettingDescription  -          N
+  0xa40b   DeviceSettingDescription  -          no
   0xa40c   SubjectDistanceRange      ExifIFD    int16u
   0xa420   ImageUniqueID             ExifIFD    string
@@ -637,45 +763,52 @@
   0xa434   LensModel                 ExifIFD    string
   0xa435   LensSerialNumber          ExifIFD    string
-  0xa480   GDALMetadata              -          N
-  0xa481   GDALNoData                -          N
+  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            -          N
-  0xafc1   ExpandLens                -          N
-  0xafc2   ExpandFilm                -          N
-  0xafc3   ExpandFilterLens          -          N
-  0xafc4   ExpandScanner             -          N
-  0xafc5   ExpandFlashLamp           -          N
-  0xbc01   PixelFormat               -          N
-  0xbc02   Transformation            -          N
-  0xbc03   Uncompressed              -          N
-  0xbc04   ImageType                 -          N
-  0xbc80   ImageWidth                -          N
-  0xbc81   ImageHeight               -          N
-  0xbc82   WidthResolution           -          N
-  0xbc83   HeightResolution          -          N
-  0xbcc0   ImageOffset               -          N
-  0xbcc1   ImageByteCount            -          N
-  0xbcc2   AlphaOffset               -          N
-  0xbcc3   AlphaByteCount            -          N
-  0xbcc4   ImageDataDiscard          -          N
-  0xbcc5   AlphaDataDiscard          -          N
-  0xc427   OceScanjobDesc            -          N
-  0xc428   OceApplicationSelector    -          N
-  0xc429   OceIDNumber               -          N
-  0xc42a   OceImageLogic             -          N
-  0xc44f   Annotations               -          N
+  0xafc0   ExpandSoftware            -          no
+  0xafc1   ExpandLens                -          no
+  0xafc2   ExpandFilm                -          no
+  0xafc3   ExpandFilterLens          -          no
+  0xafc4   ExpandScanner             -          no
+  0xafc5   ExpandFlashLamp           -          no
+  0xb4c3   HasselbladRawImage        -          no
+  0xbc01   PixelFormat               -          no
+  0xbc02   Transformation            -          no
+  0xbc03   Uncompressed              -          no
+  0xbc04   ImageType                 -          no
+  0xbc80   ImageWidth                -          no
+  0xbc81   ImageHeight               -          no
+  0xbc82   WidthResolution           -          no
+  0xbc83   HeightResolution          -          no
+  0xbcc0   ImageOffset               -          no
+  0xbcc1   ImageByteCount            -          no
+  0xbcc2   AlphaOffset               -          no
+  0xbcc3   AlphaByteCount            -          no
+  0xbcc4   ImageDataDiscard          -          no
+  0xbcc5   AlphaDataDiscard          -          no
+  0xc427   OceScanjobDesc            -          no
+  0xc428   OceApplicationSelector    -          no
+  0xc429   OceIDNumber               -          no
+  0xc42a   OceImageLogic             -          no
+  0xc44f   Annotations               -          no
   0xc4a5   PrintIM                   IFD0       PrintIM
-  0xc580   USPTOOriginalContentType  -          N
+  0xc51b   HasselbladExif            -          no
+  0xc573   OriginalFileName          -          no
+  0xc580   USPTOOriginalContentType  -          no
+  0xc5e0   CR2CFAPattern             -          no
   0xc612   DNGVersion                IFD0       int8u[4]!
   0xc613   DNGBackwardVersion        IFD0       int8u[4]!
   0xc614   UniqueCameraModel         IFD0       string
   0xc615   LocalizedCameraModel      IFD0       string
-  0xc616   CFAPlaneColor             -          N
-  0xc617   CFALayout                 -          N
-  0xc618   LinearizationTable        -          N
+  0xc616   CFAPlaneColor             SubIFD     no
+  0xc617   CFALayout                 SubIFD     no
+  0xc618   LinearizationTable        SubIFD     int16u[n]!
   0xc619   BlackLevelRepeatDim       SubIFD     int16u[2]!
   0xc61a   BlackLevel                SubIFD     rational64u[n]!
-  0xc61b   BlackLevelDeltaH          -          N
-  0xc61c   BlackLevelDeltaV          -          N
+  0xc61b   BlackLevelDeltaH          SubIFD     rational64s[n]!
+  0xc61c   BlackLevelDeltaV          SubIFD     rational64s[n]!
   0xc61d   WhiteLevel                SubIFD     int32u[n]!
   0xc61e   DefaultScale              SubIFD     rational64u[2]!
@@ -701,19 +834,21 @@
   0xc632   AntiAliasStrength         SubIFD     rational64u!
   0xc633   ShadowScale               IFD0       rational64u!
-  0xc634   SR2Private                -          Sony SR2Private
-           DNGAdobeData              -          DNG AdobeData
-           MakerNotePentax           -          Pentax
-           DNGPrivateData            -          N
+  0xc634   SR2Private                IFD0       Sony SR2Private
+           DNGAdobeData              IFD0       DNG AdobeData
+           MakerNotePentax           IFD0       Pentax
+           MakerNotePentax5          IFD0       Pentax
+           MakerNoteRicohPentax      IFD0       Pentax
+           DNGPrivateData            IFD0       int8u!
   0xc635   MakerNoteSafety           IFD0       int16u
-  0xc640   RawImageSegmentation      -          N
+  0xc640   RawImageSegmentation      -          no
   0xc65a   CalibrationIlluminant1    IFD0       int16u!
   0xc65b   CalibrationIlluminant2    IFD0       int16u!
   0xc65c   BestQualityScale          SubIFD     rational64u!
   0xc65d   RawDataUniqueID           IFD0       int8u[16]!
-  0xc660   AliasLayerMetadata        -          N
+  0xc660   AliasLayerMetadata        -          no
   0xc68b   OriginalRawFileName       IFD0       string!
   0xc68c   OriginalRawFileData       IFD0       DNG OriginalRaw
   0xc68d   ActiveArea                SubIFD     int32u[4]!
-  0xc68e   MaskedAreas               SubIFD     int32u[4]!
+  0xc68e   MaskedAreas               SubIFD     int32u[n]!
   0xc68f   AsShotICCProfile          IFD0       ICC_Profile
   0xc690   AsShotPreProfileMatrix    IFD0       rational64s[n]!
@@ -721,9 +856,10 @@
   0xc692   CurrentPreProfileMatrix   IFD0       rational64s[n]!
   0xc6bf   ColorimetricReference     IFD0       int16u!
+  0xc6c5   SRawType                  IFD0       no
   0xc6d2   PanasonicTitle            IFD0       undef
   0xc6d3   PanasonicTitle2           IFD0       undef
   0xc6f3   CameraCalibrationSig      IFD0       string!
   0xc6f4   ProfileCalibrationSig     IFD0       string!
-  0xc6f5   ProfileIFD                -          EXIF
+  0xc6f5   ProfileIFD                IFD0       EXIF
   0xc6f6   AsShotProfileName         IFD0       string!
   0xc6f7   NoiseReductionApplied     SubIFD     rational64u!
@@ -743,16 +879,39 @@
   0xc71a   PreviewColorSpace         IFD0       int32u!
   0xc71b   PreviewDateTime           IFD0       string!
-  0xc71c   RawImageDigest            IFD0       int8u!
-  0xc71d   OriginalRawFileDigest     IFD0       int8u!
-  0xc71e   SubTileBlockSize          -          N
-  0xc71f   RowInterleaveFactor       -          N
+  0xc71c   RawImageDigest            IFD0       int8u[16]!
+  0xc71d   OriginalRawFileDigest     IFD0       int8u[16]!
+  0xc71e   SubTileBlockSize          -          no
+  0xc71f   RowInterleaveFactor       -          no
   0xc725   ProfileLookTableDims      IFD0       int32u[3]!
   0xc726   ProfileLookTableData      IFD0       float[n]!
-  0xc740   OpcodeList1               -          N
-  0xc741   OpcodeList2               -          N
-  0xc74e   OpcodeList3               -          N
-  0xc761   NoiseProfile              -          N
-  0xea1c   Padding                   ExifIFD    undef
-  0xea1d   OffsetSchema              ExifIFD    int32s
+  0xc740   OpcodeList1               SubIFD     undef!
+  0xc741   OpcodeList2               SubIFD     undef!
+  0xc74e   OpcodeList3               SubIFD     undef!
+  0xc761   NoiseProfile              SubIFD     double[n]!
+  0xc763   TimeCodes                 IFD0       int8u[n]
+  0xc764   FrameRate                 IFD0       rational64s
+  0xc772   TStop                     IFD0       rational64u[n]
+  0xc789   ReelName                  IFD0       string
+  0xc791   OriginalDefaultFinalSize  IFD0       int32u[2]!
+  0xc792   OriginalBestQualitySize   IFD0       int32u[2]!
+  0xc793   OriginalDefaultCropSize   IFD0       rational64u[2]!
+  0xc7a1   CameraLabel               IFD0       string
+  0xc7a3   ProfileHueSatMapEncoding  IFD0       int32u!
+  0xc7a4   ProfileLookTableEncoding  IFD0       int32u!
+  0xc7a5   BaselineExposureOffset    IFD0       rational64s!
+  0xc7a6   DefaultBlackRender        IFD0       int32u!
+  0xc7a7   NewRawImageDigest         IFD0       int8u[16]!
+  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/
   0xfde9   SerialNumber              ExifIFD    string/
@@ -776,12 +935,12 @@
 Council (IPTC) and the Newspaper Association of America (NAA) Information
 Interchange Model (IIM).  This is an older meta information format, slowly
-being phased out in favor of XMP.  (In fact, the newer IPTCCore
-specification actually uses XMP format!)  IPTC information may be embedded
-in JPG, TIFF, PNG, MIFF, PS, PDF, PSD, XCF and DNG images.
+being phased out in favor of XMP -- the newer IPTCCore specification uses
+XMP format.  IPTC information may be found in JPG, TIFF, PNG, MIFF, PS, PDF,
+PSD, XCF and DNG images.
 
 IPTC information is separated into different records, each of which has its
 own set of tags.  See
 L<http://www.iptc.org/std/IIM/4.1/specification/IIMV4.1.pdf> for the
-official specification.
+official IPTC IIM specification.
 
 This specification dictates a length for ASCII (C<string> or C<digits>) and
@@ -789,9 +948,10 @@
 the B<Writable> format name.  For tags where a range of lengths is allowed,
 the minimum and maximum lengths are separated by a comma within the
-brackets.  IPTC strings are not null terminated.  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 values to be written, but
-beware that values like this may cause problems for some other IPTC readers.
+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
+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.
 
 Separate IPTC date and time tags may be written with a combined date/time
@@ -806,4 +966,11 @@
 offset at the specified date/time is used, which may be different due to
 changes in daylight savings time).
+
+Note that it is not uncommon for IPTC to be found in non-standard locations
+in JPEG and TIFF-based images.  When reading, the family 1 group name has a
+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.
 
   Record   Tag Name                             Writable
@@ -925,9 +1092,9 @@
      64    InterchangeColorSpace                int8u
      65    ColorSequence                        int8u
-     66    ICC_Profile                          N
-     70    ColorCalibrationMatrix               N
-     80    LookupTable                          N
+     66    ICC_Profile                          no
+     70    ColorCalibrationMatrix               no
+     80    LookupTable                          no
      84    NumIndexEntries                      int16u
-     85    ColorPalette                         N
+     85    ColorPalette                         no
      86    IPTCBitsPerSample                    int8u
      90    SampleStructure                      int8u
@@ -936,5 +1103,5 @@
     110    DataCompressionMethod                int32u
     120    QuantizationMethod                   int8u
-    125    EndPoints                            N
+    125    EndPoints                            no
     130    ExcursionTolerance                   int8u
     135    BitsPerComponent                     int8u
@@ -946,8 +1113,8 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-     10    SizeMode                             N
-     20    MaxSubfileSize                       N
-     90    ObjectSizeAnnounced                  N
-     95    MaximumObjectSize                    N
+     10    SizeMode                             no
+     20    MaxSubfileSize                       no
+     90    ObjectSizeAnnounced                  no
+     95    MaximumObjectSize                    no
 
 =head3 IPTC ObjectData Tags
@@ -955,5 +1122,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-     10    SubFile                              N+
+     10    SubFile                              no+
 
 =head3 IPTC PostObjectData Tags
@@ -961,5 +1128,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-     10    ConfirmedObjectSize                  N
+     10    ConfirmedObjectSize                  no
 
 =head3 IPTC FotoStation Tags
@@ -974,7 +1141,8 @@
 format which is being pushed by Adobe.  Information in this format can be
 embedded in many different image file types including JPG, JP2, TIFF, GIF,
-EPS, PDF, PSD, IND, PNG, DJVU, SVG, PGF, MIFF, XCF, CRW, DNG and a variety
-of proprietary TIFF-based RAW images, as well as MOV, AVI, ASF, WMV, FLV,
-SWF and MP4 videos, and WMA and audio formats supporting ID3v2 information.
+EPS, PDF, PSD, IND, INX, PNG, DJVU, SVG, PGF, MIFF, XCF, CRW, DNG and a
+variety of proprietary TIFF-based RAW images, as well as MOV, AVI, ASF, WMV,
+FLV, SWF and MP4 videos, and WMA and audio formats supporting ID3v2
+information.
 
 The XMP B<Tag ID>'s aren't listed because in most cases they are identical
@@ -989,32 +1157,45 @@
 point number but stored as two C<integer> strings separated by a '/'
 character, C<date> is a date/time string entered in the format "YYYY:mm:dd
-HH:MM:SS[.ss][+/-HH:MM]", C<boolean> is either "True" or "False",
-C<lang-alt> indicates that the tag supports alternate languages (see below),
-and C<struct> is an XMP structure.  When reading, structures are extracted
-only if the Struct (-struct) option is used.  Otherwise the corresponding
-"flattened" tags, indicated by an underline (C<_>) after the B<Writable>
-type, are extracted.  When copying information, the Struct option is in
-effect by default.  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.
+HH:MM:SS[.ss][+/-HH:MM]", C<boolean> is either "True" or "False" (but "true"
+and "false" may be written as a ValueConv value for compatibility with
+non-conforming applications), C<struct> indicates a structured tag, and
+C<lang-alt> is a tag that supports alternate languages.
+
+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 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<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 (ie. "XMP:Title-fr",
+name with a '-', followed by an RFC 3066 language code (eg. "XMP:Title-fr",
 or "Rights-en-US").  (See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC
 3066 specification.)  A C<lang-alt> tag with no language code accesses the
 "x-default" language, but causes other languages for this tag to be deleted
 when writing.  The "x-default" language code may be specified when writing
-to preserve other existing languages (ie. "XMP-dc:Description-x-default"). 
+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.  Note that a few of the longer namespace prefixes given below have
-been shortened for convenience (since the family 1 group names are derived
-from these by adding a leading "XMP-").  In cases where a tag name exists in
-more than one namespace, less common namespaces are avoided when writing.
-However, any namespace may be written by specifying a family 1 group name
-for the tag, ie) XMP-exif:Contrast or XMP-crs:Contrast.  When deciding on
-which tags to add to an image, using standard schemas such as
-L<dc|/XMP dc Tags>, L<xmp|/XMP xmp Tags> or L<iptc|/XMP iptcCore Tags> is
+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
+written by providing a family 1 group name for the tag (eg. XMP-crs:Contrast
+or XMP-exif:Contrast).  When deciding on which tags to add to an image,
+using standard schemas such as L<dc|/XMP dc Tags>, L<xmp|/XMP xmp Tags>,
+L<iptcCore|/XMP iptcCore Tags> and L<iptcExt|/XMP iptcExt Tags> is
 recommended if possible.
 
@@ -1022,29 +1203,56 @@
 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
-tables.  For example, the C<pdfx> namespace doesn't have a predefined set of
-tag names because it is used to store application-defined PDF information,
-but this information is extracted by ExifTool.
-
-See L<http://www.adobe.com/devnet/xmp/> for the official XMP specification.
+tables, but other tags are not writable unless added as user-defined tags in
+the ExifTool config file.  For example, the C<pdfx> namespace doesn't have a
+predefined set of tag names because it is used to store application-defined
+PDF information, so although this information will be extracted, it is only
+writable if the corresponding user-defined tags have been created.
+
+The tables below list tags from the official XMP specification (with an
+underlined B<Namespace> in the HTML version of this documentation), as well
+as extensions from various other sources.  See
+L<http://www.adobe.com/devnet/xmp/> for the official XMP specification.
 
   Namespace                                     Writable
   ---------                                     --------
+  aas                                           XMP aas
   acdsee                                        XMP acdsee
   album                                         XMP Album
+  apple-fi                                      XMP apple_fi
   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
+  drone-dji                                     DJI XMP
+  dwc                                           DarwinCore
   exif                                          XMP exif
+  exifEX                                        XMP exifEX
+  expressionmedia                               XMP ExpressionMedia
+  extensis                                      XMP extensis
+  fpv                                           XMP fpv
+  GAudio                                        XMP GAudio
+  GCamera                                       XMP GCamera
+  GCreations                                    XMP GCreations
+  GDepth                                        XMP GDepth
+  getty                                         XMP GettyImages
+  GFocus                                        XMP GFocus
+  GImage                                        XMP GImage
+  GPano                                         XMP GPano
+  GSpherical                                    XMP GSpherical
+  ics                                           XMP ics
   iptcCore                                      XMP iptcCore
   iptcExt                                       XMP iptcExt
+  LImage                                        XMP LImage
   lr                                            XMP Lightroom
   mediapro                                      XMP MediaPro
@@ -1052,7 +1260,7 @@
   MP                                            Microsoft MP
   MP1                                           Microsoft MP1
-  mwg-coll                                      XMP mwg_coll
-  mwg-kw                                        XMP mwg_kw
-  mwg-rs                                        XMP mwg_rs
+  mwg-coll                                      MWG Collections
+  mwg-kw                                        MWG Keywords
+  mwg-rs                                        MWG Regions
   pdf                                           XMP pdf
   pdfx                                          XMP pdfx
@@ -1060,7 +1268,9 @@
   photoshop                                     XMP photoshop
   PixelLive                                     XMP PixelLive
-  plus                                          XMP plus
+  plus                                          PLUS XMP
+  pmi                                           XMP pmi
   prism                                         XMP prism
   prl                                           XMP prl
+  prm                                           XMP prm
   pur                                           XMP pur
   rdf                                           XMP rdf
@@ -1077,12 +1287,51 @@
   xmpTPg                                        XMP xmpTPg
 
+=head3 XMP aas Tags
+
+Apple Adjustment Settings used by iPhone/iPad.
+
+These tags belong to the ExifTool XMP-aas family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AffineA                                       real
+  AffineB                                       real
+  AffineC                                       real
+  AffineD                                       real
+  AffineX                                       real
+  AffineY                                       real
+  CropH                                         integer/
+  CropW                                         integer/
+  CropX                                         integer/
+  CropY                                         integer/
+  Curve0x                                       real
+  Curve0y                                       real
+  Curve1x                                       real
+  Curve1y                                       real
+  Curve2x                                       real
+  Curve2y                                       real
+  Curve3x                                       real
+  Curve3y                                       real
+  Curve4x                                       real
+  Curve4y                                       real
+  FaceBalanceOrigI                              real
+  FaceBalanceOrigQ                              real
+  FaceBalanceStrength                           real
+  FaceBalanceWarmth                             real
+  Highlights                                    real/
+  Shadows                                       real/
+  Vibrance                                      real/
+
 =head3 XMP acdsee Tags
 
-ACD Systems ACDSee schema tags.
+ACD Systems ACDSee namespace tags.
 
 (A note to software developers: Re-inventing your own private tags instead
-of using the equivalent tags in standard XMP schemas defeats one of the most
-valuable features of metadata: interoperability.  Your applications mumble
-to themselves instead of speaking out for the rest of the world to hear.)
+of using the equivalent tags in standard XMP namespaces defeats one of the
+most valuable features of metadata: interoperability.  Your applications
+mumble to themselves instead of speaking out for the rest of the world to
+hear.)
+
+These tags belong to the ExifTool XMP-acdsee family 1 group.
 
   Tag Name                                      Writable
@@ -1091,14 +1340,26 @@
   Caption                                       string/
   Categories                                    string/
-  Datetime                                      date/
+  Collections                                   string/
+  DateTime                                      date/
+  DPP                                           lang-alt/
+  EditStatus                                    string/
+  FixtureIdentifier                             string/
   Keywords                                      string/+
   Notes                                         string/
+  ObjectCycle                                   string/
+  OriginatingProgram                            string/
   Rating                                        real/
-  RPP                                           lang-alt
+  Rawrppused                                    boolean/
+  ReleaseDate                                   string/
+  ReleaseTime                                   string/
+  RPP                                           lang-alt/
+  Snapshots                                     string/+
   Tagged                                        boolean/
 
 =head3 XMP Album Tags
 
-Adobe Album schema tags.
+Adobe Album namespace tags.
+
+These tags belong to the ExifTool XMP-album family 1 group.
 
   Tag Name                                      Writable
@@ -1106,24 +1367,55 @@
   Notes                                         string
 
+=head3 XMP apple_fi Tags
+
+Face information tags written by the Apple iPhone 5 inside the mwg-rs
+RegionExtensions.
+
+These tags belong to the ExifTool XMP-apple-fi family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AngleInfoRoll                                 integer
+  AngleInfoYaw                                  integer
+  ConfidenceLevel                               integer
+  FaceID                                        integer
+  TimeStamp                                     integer
+
 =head3 XMP aux Tags
 
-Photoshop Auxiliary schema tags.
+Adobe-defined auxiliary EXIF tags.  This namespace existed in the XMP
+specification until it was dropped in 2012, presumably due to the
+introduction of the EXIF 2.3 for XMP specification and the exifEX namespace
+at this time.  For this reason, tags below with equivalents in the
+L<exifEX namespace|/XMP exifEX Tags> are avoided when writing.
+
+These tags belong to the ExifTool XMP-aux family 1 group.
 
   Tag Name                                      Writable
   --------                                      --------
   ApproximateFocusDistance                      rational
+  DistortionCorrectionAlreadyApplied            boolean
   Firmware                                      string
   FlashCompensation                             rational
   ImageNumber                                   string
+  IsMergedHDR                                   boolean
+  IsMergedPanorama                              boolean
+  LateralChromaticAberrationCorrectionAlreadyApplied boolean
   Lens                                          string
+  LensDistortInfo                               string
   LensID                                        string
-  LensInfo                                      string
-  OwnerName                                     string
-  SerialNumber                                  string
+  LensInfo                                      string/
+  LensSerialNumber                              string/
+  OwnerName                                     string/
+  SerialNumber                                  string/
+  VignetteCorrectionAlreadyApplied              boolean
 
 =head3 XMP cc Tags
 
-Creative Commons schema tags.  (see
-L<http://creativecommons.org/technology/xmp>)
+Creative Commons namespace tags.  Note that the CC specification for XMP is
+non-existent, so ExifTool must make some assumptions about the format of the
+specific properties in XMP (see L<http://creativecommons.org/ns>).
+
+These tags belong to the ExifTool XMP-cc family 1 group.
 
   Tag Name                                      Writable
@@ -1131,10 +1423,19 @@
   AttributionName                               string
   AttributionURL                                string
+  DeprecatedOn                                  date
+  Jurisdiction                                  string
+  LegalCode                                     string
   License                                       string
   MorePermissions                               string
+  Permits                                       string+
+  Prohibits                                     string+
+  Requires                                      string+
+  UseGuidelines                                 string
 
 =head3 XMP cell Tags
 
 Location tags written by some Sony Ericsson phones.
+
+These tags belong to the ExifTool XMP-cell family 1 group.
 
   Tag Name                                      Writable
@@ -1147,7 +1448,673 @@
   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/
+  AutoToneDigest                                string/
+  AutoToneDigestNoSat                           string/
+  AutoWhiteVersion                              integer/
+  Blacks2012                                    integer/
+  BlueHue                                       integer/
+  BlueSaturation                                integer/
+  Brightness                                    integer/
+  CameraModelRestriction                        string/
+  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/_
+  CircGradBasedCorrRangeMask                    CorrectionRangeMask Struct_+
+  CircGradBasedCorrRangeMaskColorAmount         real/_+
+  CircGradBasedCorrRangeMaskDepthFeather        real/_+
+  CircGradBasedCorrRangeMaskDepthMax            real/_+
+  CircGradBasedCorrRangeMaskDepthMin            real/_+
+  CircGradBasedCorrRangeMaskLumFeather          real/_+
+  CircGradBasedCorrRangeMaskLumMax              real/_+
+  CircGradBasedCorrRangeMaskLumMin              real/_+
+  CircGradBasedCorrRangeMaskType                string/_+
+  CircGradBasedCorrRangeMaskVersion             string/_+
+  CircGradBasedCorrBlacks2012                   real/_
+  CircGradBasedCorrBrightness                   real/_
+  CircGradBasedCorrClarity                      real/_
+  CircGradBasedCorrClarity2012                  real/_
+  CircGradBasedCorrContrast                     real/_
+  CircGradBasedCorrContrast2012                 real/_
+  CircGradBasedCorrDefringe                     real/_
+  CircGradBasedCorrDehaze                       real/_
+  CircGradBasedCorrExposure                     real/_
+  CircGradBasedCorrExposure2012                 real/_
+  CircGradBasedCorrHighlights2012               real/_
+  CircGradBasedCorrHue                          real/_
+  CircGradBasedCorrLuminanceNoise               real/_
+  CircGradBasedCorrMoire                        real/_
+  CircGradBasedCorrSaturation                   real/_
+  CircGradBasedCorrShadows2012                  real/_
+  CircGradBasedCorrSharpness                    real/_
+  CircGradBasedCorrTemperature                  real/_
+  CircGradBasedCorrTexture                      real/_
+  CircGradBasedCorrTint                         real/_
+  CircGradBasedCorrHue                          real/_
+  CircGradBasedCorrSaturation                   real/_
+  CircGradBasedCorrWhites2012                   real/_
+  CircGradBasedCorrWhat                         string/_
+  Clarity                                       integer/
+  Clarity2012                                   integer/
+  ClipboardAspectRatio                          integer/
+  ClipboardOrientation                          integer/
+  Cluster                                       string/
+  ColorGradeBlending                            integer/
+  ColorGradeGlobalHue                           integer/
+  ColorGradeGlobalLum                           integer/
+  ColorGradeGlobalSat                           integer/
+  ColorGradeHighlightLum                        integer/
+  ColorGradeMidtoneHue                          integer/
+  ColorGradeMidtoneLum                          integer/
+  ColorGradeMidtoneSat                          integer/
+  ColorGradeShadowLum                           integer/
+  ColorNoiseReduction                           integer/
+  ColorNoiseReductionDetail                     integer/
+  ColorNoiseReductionSmoothness                 integer/
+  ContactInfo                                   string/
+  Contrast                                      integer/
+  Contrast2012                                  integer/
+  Converter                                     string/
+  ConvertToGrayscale                            boolean/
+  Copyright                                     string/
+  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/
+  Description                                   lang-alt/
+  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/_
+  GradientBasedCorrRangeMask                    CorrectionRangeMask Struct_+
+  GradientBasedCorrRangeMaskColorAmount         real/_+
+  GradientBasedCorrRangeMaskDepthFeather        real/_+
+  GradientBasedCorrRangeMaskDepthMax            real/_+
+  GradientBasedCorrRangeMaskDepthMin            real/_+
+  GradientBasedCorrRangeMaskLumFeather          real/_+
+  GradientBasedCorrRangeMaskLumMax              real/_+
+  GradientBasedCorrRangeMaskLumMin              real/_+
+  GradientBasedCorrRangeMaskType                string/_+
+  GradientBasedCorrRangeMaskVersion             string/_+
+  GradientBasedCorrBlacks2012                   real/_
+  GradientBasedCorrBrightness                   real/_
+  GradientBasedCorrClarity                      real/_
+  GradientBasedCorrClarity2012                  real/_
+  GradientBasedCorrContrast                     real/_
+  GradientBasedCorrContrast2012                 real/_
+  GradientBasedCorrDefringe                     real/_
+  GradientBasedCorrDehaze                       real/_
+  GradientBasedCorrExposure                     real/_
+  GradientBasedCorrExposure2012                 real/_
+  GradientBasedCorrHighlights2012               real/_
+  GradientBasedCorrHue                          real/_
+  GradientBasedCorrLuminanceNoise               real/_
+  GradientBasedCorrMoire                        real/_
+  GradientBasedCorrSaturation                   real/_
+  GradientBasedCorrShadows2012                  real/_
+  GradientBasedCorrSharpness                    real/_
+  GradientBasedCorrTemperature                  real/_
+  GradientBasedCorrTexture                      real/_
+  GradientBasedCorrTint                         real/_
+  GradientBasedCorrHue                          real/_
+  GradientBasedCorrSaturation                   real/_
+  GradientBasedCorrWhites2012                   real/_
+  GradientBasedCorrWhat                         string/_
+  GrainAmount                                   integer/
+  GrainFrequency                                integer/
+  GrainSeed                                     integer/
+  GrainSize                                     integer/
+  GrayMixerAqua                                 integer/
+  GrayMixerBlue                                 integer/
+  GrayMixerGreen                                integer/
+  GrayMixerMagenta                              integer/
+  GrayMixerOrange                               integer/
+  GrayMixerPurple                               integer/
+  GrayMixerRed                                  integer/
+  GrayMixerYellow                               integer/
+  GreenHue                                      integer/
+  GreenSaturation                               integer/
+  Group                                         lang-alt/
+  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/
+  LensProfileIsEmbedded                         boolean/
+  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
+  LookAmount                                    string/_
+  LookCluster                                   string/_
+  LookCopyright                                 string/_
+  LookGroup                                     lang-alt/_
+  LookName                                      string/
+  LookParameters                                LookParms Struct_
+  LookParametersCameraProfile                   string/_
+  LookParametersClarity2012                     string/_
+  LookParametersConvertToGrayscale              string/_
+  LookParametersLookTable                       string/_
+  LookParametersProcessVersion                  string/_
+  LookParametersToneCurvePV2012                 string/_+
+  LookParametersVersion                         string/_
+  LookSupportsAmount                            string/_
+  LookSupportsMonochrome                        string/_
+  LookSupportsOutputReferred                    string/_
+  LookUUID                                      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/
+  Name                                          lang-alt/
+  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/_
+  PaintCorrectionRangeMask                      CorrectionRangeMask Struct_+
+  PaintCorrectionRangeMaskColorAmount           real/_+
+  PaintCorrectionRangeMaskDepthFeather          real/_+
+  PaintCorrectionRangeMaskDepthMax              real/_+
+  PaintCorrectionRangeMaskDepthMin              real/_+
+  PaintCorrectionRangeMaskLumFeather            real/_+
+  PaintCorrectionRangeMaskLumMax                real/_+
+  PaintCorrectionRangeMaskLumMin                real/_+
+  PaintCorrectionRangeMaskType                  string/_+
+  PaintCorrectionRangeMaskVersion               string/_+
+  PaintCorrectionBlacks2012                     real/_
+  PaintCorrectionBrightness                     real/_
+  PaintCorrectionClarity                        real/_
+  PaintCorrectionClarity2012                    real/_
+  PaintCorrectionContrast                       real/_
+  PaintCorrectionContrast2012                   real/_
+  PaintCorrectionDefringe                       real/_
+  PaintCorrectionDehaze                         real/_
+  PaintCorrectionExposure                       real/_
+  PaintCorrectionExposure2012                   real/_
+  PaintCorrectionHighlights2012                 real/_
+  PaintCorrectionHue                            real/_
+  PaintCorrectionLuminanceNoise                 real/_
+  PaintCorrectionMoire                          real/_
+  PaintCorrectionSaturation                     real/_
+  PaintCorrectionShadows2012                    real/_
+  PaintCorrectionSharpness                      real/_
+  PaintCorrectionTemperature                    real/_
+  PaintCorrectionTexture                        real/_
+  PaintCorrectionTint                           real/_
+  PaintCorrectionHue                            real/_
+  PaintCorrectionSaturation                     real/_
+  PaintCorrectionWhites2012                     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/
+  PresetType                                    string/
+  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/
+  ShortName                                     lang-alt/
+  Smoothness                                    integer/
+  SortName                                      lang-alt/
+  SplitToningBalance                            integer/
+  SplitToningHighlightHue                       integer/
+  SplitToningHighlightSaturation                integer/
+  SplitToningShadowHue                          integer/
+  SplitToningShadowSaturation                   integer/
+  SupportsAmount                                boolean/
+  SupportsColor                                 boolean/
+  SupportsHighDynamicRange                      boolean/
+  SupportsMonochrome                            boolean/
+  SupportsNormalDynamicRange                    boolean/
+  SupportsOutputReferred                        boolean/
+  SupportsSceneReferred                         boolean/
+  ColorTemperature                              integer/
+  Texture                                       integer/
+  TIFFHandling                                  string/
+  Tint                                          integer/
+  ToggleStyleAmount                             integer/
+  ToggleStyleDigest                             string/
+  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/
+  UUID                                          string/
+  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+
+  CorrectionRangeMask                           CorrectionRangeMask Struct
+  LocalBlacks2012                               real
+  LocalBrightness                               real
+  LocalClarity                                  real
+  LocalClarity2012                              real
+  LocalContrast                                 real
+  LocalContrast2012                             real
+  LocalDefringe                                 real
+  LocalDehaze                                   real
+  LocalExposure                                 real
+  LocalExposure2012                             real
+  LocalHighlights2012                           real
+  LocalHue                                      real
+  LocalLuminanceNoise                           real
+  LocalMoire                                    real
+  LocalSaturation                               real
+  LocalShadows2012                              real
+  LocalSharpness                                real
+  LocalTemperature                              real
+  LocalTexture                                  real
+  LocalTint                                     real
+  LocalToningHue                                real
+  LocalToningSaturation                         real
+  LocalWhites2012                               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 CorrectionRangeMask Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  ColorAmount                                   real
+  DepthFeather                                  real
+  DepthMax                                      real
+  DepthMin                                      real
+  LumFeather                                    real
+  LumMax                                        real
+  LumMin                                        real
+  Type                                          string
+  Version                                       string
+
+=head3 XMP Look Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Amount                                        string
+  Cluster                                       string
+  Copyright                                     string
+  Group                                         lang-alt
+  Name                                          string
+  Parameters                                    LookParms Struct
+  SupportsAmount                                string
+  SupportsMonochrome                            string
+  SupportsOutputReferred                        string
+  UUID                                          string
+
+=head3 XMP LookParms Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  CameraProfile                                 string
+  Clarity2012                                   string
+  ConvertToGrayscale                            string
+  LookTable                                     string
+  ProcessVersion                                string
+  ToneCurvePV2012                               string+
+  Version                                       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.
+
+These tags belong to the ExifTool XMP-creatorAtom family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AeProjectLink                                 AEProjectLink Struct
+  AeProjectLinkCompositionID                    string_
+  AeProjectLinkFullPath                         string_
+  AeProjectLinkRenderOutputModuleIndex          string_
+  AeProjectLinkRenderQueueItemID                string_
+  AeProjectLinkRenderTimeStamp                  integer_
+  MacAtom                                       MacAtom Struct
+  MacAtomApplicationCode                        string_
+  MacAtomInvocationAppleEvent                   string_
+  MacAtomPosixProjectPath                       string_
+  WindowsAtom                                   WindowsAtom Struct
+  WindowsAtomExtension                          string_
+  WindowsAtomInvocationFlags                    string_
+  WindowsAtomUncProjectPath                     string_
+
+=head3 XMP AEProjectLink Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  CompositionID                                 string
+  FullPath                                      string
+  RenderOutputModuleIndex                       string
+  RenderQueueItemID                             string
+  RenderTimeStamp                               integer
+
+=head3 XMP MacAtom Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  ApplicationCode                               string
+  InvocationAppleEvent                          string
+  PosixProjectPath                              string
+
+=head3 XMP WindowsAtom Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Extension                                     string
+  InvocationFlags                               string
+  UncProjectPath                                string
+
 =head3 XMP crs Tags
 
-Photoshop Camera Raw Schema tags.
+Photoshop Camera Raw namespace tags.  It is a shame that Adobe pollutes the
+metadata space with these incredibly bulky image editing parameters.
+
+These tags belong to the ExifTool XMP-crs family 1 group.
 
   Tag Name                                      Writable
@@ -1157,18 +2124,107 @@
   AutoContrast                                  boolean
   AutoExposure                                  boolean
+  AutoLateralCA                                 integer
   AutoShadows                                   boolean
+  AutoTone                                      boolean
+  AutoToneDigest                                string
+  AutoToneDigestNoSat                           string
+  AutoWhiteVersion                              integer
+  Blacks2012                                    integer
   BlueHue                                       integer
   BlueSaturation                                integer
   Brightness                                    integer
+  CameraModelRestriction                        string
   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_
+  CircGradBasedCorrRangeMask                    CorrectionRangeMask Struct_+
+  CircGradBasedCorrRangeMaskColorAmount         real_+
+  CircGradBasedCorrRangeMaskDepthFeather        real_+
+  CircGradBasedCorrRangeMaskDepthMax            real_+
+  CircGradBasedCorrRangeMaskDepthMin            real_+
+  CircGradBasedCorrRangeMaskLumFeather          real_+
+  CircGradBasedCorrRangeMaskLumMax              real_+
+  CircGradBasedCorrRangeMaskLumMin              real_+
+  CircGradBasedCorrRangeMaskType                string_+
+  CircGradBasedCorrRangeMaskVersion             string_+
+  CircGradBasedCorrBlacks2012                   real_
+  CircGradBasedCorrBrightness                   real_
+  CircGradBasedCorrClarity                      real_
+  CircGradBasedCorrClarity2012                  real_
+  CircGradBasedCorrContrast                     real_
+  CircGradBasedCorrContrast2012                 real_
+  CircGradBasedCorrDefringe                     real_
+  CircGradBasedCorrDehaze                       real_
+  CircGradBasedCorrExposure                     real_
+  CircGradBasedCorrExposure2012                 real_
+  CircGradBasedCorrHighlights2012               real_
+  CircGradBasedCorrHue                          real_
+  CircGradBasedCorrLuminanceNoise               real_
+  CircGradBasedCorrMoire                        real_
+  CircGradBasedCorrSaturation                   real_
+  CircGradBasedCorrShadows2012                  real_
+  CircGradBasedCorrSharpness                    real_
+  CircGradBasedCorrTemperature                  real_
+  CircGradBasedCorrTexture                      real_
+  CircGradBasedCorrTint                         real_
+  CircGradBasedCorrHue                          real_
+  CircGradBasedCorrSaturation                   real_
+  CircGradBasedCorrWhites2012                   real_
+  CircGradBasedCorrWhat                         string_
   Clarity                                       integer
+  Clarity2012                                   integer
+  ClipboardAspectRatio                          integer
+  ClipboardOrientation                          integer
+  Cluster                                       string
+  ColorGradeBlending                            integer
+  ColorGradeGlobalHue                           integer
+  ColorGradeGlobalLum                           integer
+  ColorGradeGlobalSat                           integer
+  ColorGradeHighlightLum                        integer
+  ColorGradeMidtoneHue                          integer
+  ColorGradeMidtoneLum                          integer
+  ColorGradeMidtoneSat                          integer
+  ColorGradeShadowLum                           integer
   ColorNoiseReduction                           integer
   ColorNoiseReductionDetail                     integer
+  ColorNoiseReductionSmoothness                 integer
+  ContactInfo                                   string
   Contrast                                      integer/
+  Contrast2012                                  integer
   Converter                                     string
   ConvertToGrayscale                            boolean
+  Copyright                                     string/
   CropAngle                                     real
   CropBottom                                    real
@@ -1181,6 +2237,20 @@
   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
+  Description                                   lang-alt/
+  DNGIgnoreSidecars                             boolean
   Exposure                                      real
+  Exposure2012                                  real
   FillLight                                     integer
   GradientBasedCorrections                      Correction Struct+
@@ -1188,25 +2258,68 @@
   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_
+  GradientBasedCorrRangeMask                    CorrectionRangeMask Struct_+
+  GradientBasedCorrRangeMaskColorAmount         real_+
+  GradientBasedCorrRangeMaskDepthFeather        real_+
+  GradientBasedCorrRangeMaskDepthMax            real_+
+  GradientBasedCorrRangeMaskDepthMin            real_+
+  GradientBasedCorrRangeMaskLumFeather          real_+
+  GradientBasedCorrRangeMaskLumMax              real_+
+  GradientBasedCorrRangeMaskLumMin              real_+
+  GradientBasedCorrRangeMaskType                string_+
+  GradientBasedCorrRangeMaskVersion             string_+
+  GradientBasedCorrBlacks2012                   real_
   GradientBasedCorrBrightness                   real_
   GradientBasedCorrClarity                      real_
+  GradientBasedCorrClarity2012                  real_
   GradientBasedCorrContrast                     real_
+  GradientBasedCorrContrast2012                 real_
+  GradientBasedCorrDefringe                     real_
+  GradientBasedCorrDehaze                       real_
   GradientBasedCorrExposure                     real_
+  GradientBasedCorrExposure2012                 real_
+  GradientBasedCorrHighlights2012               real_
+  GradientBasedCorrHue                          real_
+  GradientBasedCorrLuminanceNoise               real_
+  GradientBasedCorrMoire                        real_
   GradientBasedCorrSaturation                   real_
+  GradientBasedCorrShadows2012                  real_
   GradientBasedCorrSharpness                    real_
+  GradientBasedCorrTemperature                  real_
+  GradientBasedCorrTexture                      real_
+  GradientBasedCorrTint                         real_
   GradientBasedCorrHue                          real_
   GradientBasedCorrSaturation                   real_
+  GradientBasedCorrWhites2012                   real_
   GradientBasedCorrWhat                         string_
   GrainAmount                                   integer
   GrainFrequency                                integer
+  GrainSeed                                     integer
   GrainSize                                     integer
   GrayMixerAqua                                 integer
@@ -1220,7 +2333,10 @@
   GreenHue                                      integer
   GreenSaturation                               integer
+  Group                                         lang-alt/
   HasCrop                                       boolean
   HasSettings                                   boolean
+  Highlight2012                                 integer
   HighlightRecovery                             integer
+  Highlights2012                                integer
   HueAdjustmentAqua                             integer
   HueAdjustmentBlue                             integer
@@ -1233,4 +2349,5 @@
   IncrementalTemperature                        integer
   IncrementalTint                               integer
+  JPEGHandling                                  string
   LensManualDistortionAmount                    integer
   LensProfileChromaticAberrationScale           integer
@@ -1239,7 +2356,34 @@
   LensProfileEnable                             integer
   LensProfileFilename                           string
+  LensProfileIsEmbedded                         boolean
+  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
+  LookAmount                                    string_
+  LookCluster                                   string_
+  LookCopyright                                 string_
+  LookGroup                                     lang-alt_
+  LookName                                      string
+  LookParameters                                LookParms Struct_
+  LookParametersCameraProfile                   string_
+  LookParametersClarity2012                     string_
+  LookParametersConvertToGrayscale              string_
+  LookParametersLookTable                       string_
+  LookParametersProcessVersion                  string_
+  LookParametersToneCurvePV2012                 string_+
+  LookParametersVersion                         string_
+  LookSupportsAmount                            string_
+  LookSupportsMonochrome                        string_
+  LookSupportsOutputReferred                    string_
+  LookUUID                                      string_
   LuminanceAdjustmentAqua                       integer
   LuminanceAdjustmentBlue                       integer
@@ -1254,26 +2398,73 @@
   LuminanceSmoothing                            integer
   MoireFilter                                   string
+  Name                                          lang-alt/
+  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_
+  PaintCorrectionRangeMask                      CorrectionRangeMask Struct_+
+  PaintCorrectionRangeMaskColorAmount           real_+
+  PaintCorrectionRangeMaskDepthFeather          real_+
+  PaintCorrectionRangeMaskDepthMax              real_+
+  PaintCorrectionRangeMaskDepthMin              real_+
+  PaintCorrectionRangeMaskLumFeather            real_+
+  PaintCorrectionRangeMaskLumMax                real_+
+  PaintCorrectionRangeMaskLumMin                real_+
+  PaintCorrectionRangeMaskType                  string_+
+  PaintCorrectionRangeMaskVersion               string_+
+  PaintCorrectionBlacks2012                     real_
   PaintCorrectionBrightness                     real_
   PaintCorrectionClarity                        real_
+  PaintCorrectionClarity2012                    real_
   PaintCorrectionContrast                       real_
+  PaintCorrectionContrast2012                   real_
+  PaintCorrectionDefringe                       real_
+  PaintCorrectionDehaze                         real_
   PaintCorrectionExposure                       real_
+  PaintCorrectionExposure2012                   real_
+  PaintCorrectionHighlights2012                 real_
+  PaintCorrectionHue                            real_
+  PaintCorrectionLuminanceNoise                 real_
+  PaintCorrectionMoire                          real_
   PaintCorrectionSaturation                     real_
+  PaintCorrectionShadows2012                    real_
   PaintCorrectionSharpness                      real_
+  PaintCorrectionTemperature                    real_
+  PaintCorrectionTexture                        real_
+  PaintCorrectionTint                           real_
   PaintCorrectionHue                            real_
   PaintCorrectionSaturation                     real_
+  PaintCorrectionWhites2012                     real_
   PaintCorrectionWhat                           string_
   ParametricDarks                               integer
@@ -1284,13 +2475,19 @@
   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
+  PresetType                                    string
   ProcessVersion                                string
   RawFileName                                   string
@@ -1298,4 +2495,41 @@
   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/
@@ -1309,4 +2543,5 @@
   SaturationAdjustmentYellow                    integer
   Shadows                                       integer
+  Shadows2012                                   integer
   ShadowTint                                    integer
   SharpenDetail                                 integer
@@ -1314,5 +2549,7 @@
   SharpenRadius                                 real
   Sharpness                                     integer/
+  ShortName                                     lang-alt
   Smoothness                                    integer
+  SortName                                      lang-alt
   SplitToningBalance                            integer
   SplitToningHighlightHue                       integer
@@ -1320,49 +2557,58 @@
   SplitToningShadowHue                          integer
   SplitToningShadowSaturation                   integer
-  ColorTemperature                              integer/
+  SupportsAmount                                boolean
+  SupportsColor                                 boolean
+  SupportsHighDynamicRange                      boolean
+  SupportsMonochrome                            boolean
+  SupportsNormalDynamicRange                    boolean
+  SupportsOutputReferred                        boolean
+  SupportsSceneReferred                         boolean
+  ColorTemperature                              integer
+  Texture                                       integer
+  TIFFHandling                                  string
   Tint                                          integer
+  ToggleStyleAmount                             integer
+  ToggleStyleDigest                             string
   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
+  UUID                                          string/
   Version                                       string
   Vibrance                                      integer
   VignetteAmount                                integer
   VignetteMidpoint                              integer
+  What                                          string
   WhiteBalance                                  string/
-
-=head3 XMP Correction Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  CorrectionActive                              boolean
-  CorrectionAmount                              real
-  CorrectionMasks                               CorrectionMask Struct+
-  LocalBrightness                               real
-  LocalClarity                                  real
-  LocalContrast                                 real
-  LocalExposure                                 real
-  LocalSaturation                               real
-  LocalSharpness                                real
-  LocalToningHue                                real
-  LocalToningSaturation                         real
-  What                                          string
-
-=head3 XMP CorrectionMask Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  CenterWeight                                  real
-  Dabs                                          string+
-  Flow                                          real
-  FullX                                         real
-  FullY                                         real
-  MaskValue                                     real
-  Radius                                        real
-  What                                          string
-  ZeroX                                         real
-  ZeroY                                         real
+  Whites2012                                    integer
 
 =head3 XMP dc Tags
 
-Dublin Core schema tags.
+Dublin Core namespace tags.
+
+These tags belong to the ExifTool XMP-dc family 1 group.
 
   Tag Name                                      Writable
@@ -1384,9 +2630,296 @@
   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
+  ----------                                    --------
+  Application                                   string
+  ItemURI                                       string
+  Version                                       string
+
+=head3 XMP DeviceCameras Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Camera                                        DeviceCamera Struct
+
+=head3 XMP DeviceCamera Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  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 DevicePlane Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Boundary                                      string
+  BoundaryVertexCount                           integer
+  ExtentX                                       real
+  ExtentZ                                       real
+  Pose                                          Pose Struct
+
+=head3 XMP DeviceProfiles Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Profile                                       DeviceProfile Struct
+
+=head3 XMP DeviceProfile Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  CameraIndices                                 integer+
+  Type                                          string
+
 =head3 XMP dex Tags
 
-Description Explorer schema tags.  These tags are not very common.  The
+Description Explorer namespace tags.  These tags are not very common.  The
 Source and Rating tags are avoided when writing due to name conflicts with
 other XMP tags.  (see L<http://www.optimasc.com/products/fileid/>)
+
+These tags belong to the ExifTool XMP-dex family 1 group.
 
   Tag Name                                      Writable
@@ -1403,5 +2936,10 @@
 =head3 XMP DICOM Tags
 
-DICOM schema tags.
+DICOM namespace tags.  These XMP tags allow some DICOM information to be
+stored in files of other than DICOM format.  See the
+L<DICOM Tags documentation|Image::ExifTool::TagNames/DICOM Tags> for a list
+of tags available in DICOM-format files.
+
+These tags belong to the ExifTool XMP-DICOM family 1 group.
 
   Tag Name                                      Writable
@@ -1424,5 +2962,7 @@
 =head3 XMP digiKam Tags
 
-DigiKam schema tags.
+DigiKam namespace tags.
+
+These tags belong to the ExifTool XMP-digiKam family 1 group.
 
   Tag Name                                      Writable
@@ -1430,9 +2970,18 @@
   CaptionsAuthorNames                           lang-alt
   CaptionsDateTimeStamps                        lang-alt
+  ColorLabel                                    string
+  ImageHistory                                  string/
+  ImageUniqueID                                 string/
+  LensCorrectionSettings                        string
+  PickLabel                                     string
   TagsList                                      string+
 
 =head3 XMP exif Tags
 
-EXIF schema for EXIF tags.
+EXIF namespace for EXIF tags.  See
+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.
 
   Tag Name                                      Writable
@@ -1489,4 +3038,5 @@
   GPSDifferential                               integer
   GPSDOP                                        rational
+  GPSHPositioningError                          rational
   GPSImgDirection                               rational
   GPSImgDirectionRef                            string
@@ -1573,10 +3123,352 @@
   Values                                        rational+
 
+=head3 XMP exifEX Tags
+
+EXIF tags added by the EXIF 2.31 for XMP specification (see
+L<http://www.cipa.jp/std/documents/e/DC-X010-2017.pdf>).
+
+These tags belong to the ExifTool XMP-exifEX family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Acceleration                                  rational
+  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
+  ISOSpeed                                      integer
+  ISOSpeedLatitudeyyy                           integer
+  ISOSpeedLatitudezzz                           integer
+  LensMake                                      string
+  LensModel                                     string
+  LensSerialNumber                              string
+  LensInfo                                      rational+
+  PhotographicSensitivity                       integer
+  Pressure                                      rational
+  RecommendedExposureIndex                      integer
+  SensitivityType                               integer
+  StandardOutputSensitivity                     integer
+  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
+writing due to name conflicts with tags in other schemas.
+
+These tags belong to the ExifTool XMP-expressionmedia family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CatalogSets                                   string/+
+  Event                                         string/
+  People                                        string/+
+  Status                                        string/
+
+=head3 XMP extensis Tags
+
+Tags used by Extensis Portfolio.
+
+These tags belong to the ExifTool XMP-extensis family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Approved                                      boolean
+  ApprovedBy                                    string
+  ClientName                                    string
+  JobName                                       string
+  JobStatus                                     string
+  RoutedTo                                      string
+  RoutingNotes                                  string
+  WorkToDo                                      string
+
+=head3 XMP fpv Tags
+
+Fast Picture Viewer tags (see
+L<http://www.fastpictureviewer.com/help/#rtfcomments>).
+
+These tags belong to the ExifTool XMP-fpv family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  RichTextComment                               string
+
+=head3 XMP GAudio Tags
+
+These tags belong to the ExifTool XMP-GAudio family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  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
+  MicroVideo                                    integer
+  MicroVideoOffset                              integer
+  MicroVideoPresentationTimestampUs             integer
+  MicroVideoVersion                             integer
+  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
+L<https://developers.google.com/depthmap-metadata/> for the specification.
+
+These tags belong to the ExifTool XMP-GDepth family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Confidence                                    string/
+  ConfidenceMime                                string/
+  DepthImage                                    string/
+  Far                                           real/
+  Format                                        string/
+  ImageHeight                                   real/
+  ImageWidth                                    real/
+  Manufacturer                                  string/
+  MeasureType                                   string/
+  Mime                                          string/
+  Model                                         string/
+  Near                                          real/
+  Software                                      string/
+  Units                                         string/
+
+=head3 XMP GettyImages Tags
+
+The actual Getty Images namespace prefix is "GettyImagesGIFT", which is the
+prefix recorded in the file, but ExifTool shortens this for the family 1
+group name.
+
+These tags belong to the ExifTool XMP-getty family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AssetID                                       string
+  CallForImage                                  string
+  CameraFilename                                string
+  CameraMakeModel                               string/
+  CameraSerialNumber                            string/
+  Composition                                   string
+  ExclusiveCoverage                             string
+  GIFTFtpPriority                               string
+  ImageRank                                     string
+  MediaEventIdDate                              string
+  OriginalCreateDateTime                        date/
+  OriginalFileName                              string
+  ParentMediaEventID                            string
+  ParentMEID                                    string
+  Personality                                   string+
+  PrimaryFTP                                    string+
+  RoutingDestinations                           string+
+  RoutingExclusions                             string+
+  SecondaryFTP                                  string+
+  TimeShot                                      string
+
+=head3 XMP GFocus Tags
+
+Focus information found in Google depthmap images.
+
+These tags belong to the ExifTool XMP-GFocus family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  BlurAtInfinity                                real
+  FocalDistance                                 real
+  FocalPointX                                   real
+  FocalPointY                                   real
+
+=head3 XMP GImage Tags
+
+These tags belong to the ExifTool XMP-GImage family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  ImageData                                     string
+  ImageMimeType                                 string
+
+=head3 XMP GPano Tags
+
+Panorama tags written by Google Photosphere. See
+L<https://developers.google.com/panorama/metadata/> for the specification.
+
+These tags belong to the ExifTool XMP-GPano family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CaptureSoftware                               string
+  CroppedAreaImageHeightPixels                  real
+  CroppedAreaImageWidthPixels                   real
+  CroppedAreaLeftPixels                         real
+  CroppedAreaTopPixels                          real
+  ExposureLockUsed                              boolean
+  FirstPhotoDate                                date
+  FullPanoHeightPixels                          real
+  FullPanoWidthPixels                           real
+  InitialCameraDolly                            real
+  InitialHorizontalFOVDegrees                   real
+  InitialVerticalFOVDegrees                     real
+  InitialViewHeadingDegrees                     real
+  InitialViewPitchDegrees                       real
+  InitialViewRollDegrees                        real
+  LargestValidInteriorRectHeight                real
+  LargestValidInteriorRectLeft                  real
+  LargestValidInteriorRectTop                   real
+  LargestValidInteriorRectWidth                 real
+  LastPhotoDate                                 date
+  PoseHeadingDegrees                            real
+  PosePitchDegrees                              real
+  PoseRollDegrees                               real
+  ProjectionType                                string
+  SourcePhotosCount                             integer
+  StitchingSoftware                             string
+  UsePanoramaViewer                             boolean
+
+=head3 XMP GSpherical Tags
+
+Not actually XMP.  These RDF/XML tags are used in Google spherical MP4
+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.
+
+These tags belong to the ExifTool XMP-GSpherical family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CroppedAreaImageHeightPixels                  integer/
+  CroppedAreaImageWidthPixels                   integer/
+  CroppedAreaLeftPixels                         integer/
+  CroppedAreaTopPixels                          integer/
+  FullPanoHeightPixels                          integer/
+  FullPanoWidthPixels                           integer/
+  InitialViewHeadingDegrees                     real/
+  InitialViewPitchDegrees                       real/
+  InitialViewRollDegrees                        real/
+  ProjectionType                                string/
+  SourceCount                                   integer/
+  Spherical                                     boolean/
+  StereoMode                                    string/
+  Stitched                                      boolean/
+  StitchingSoftware                             string/
+  TimeStamp                                     integer/
+
+=head3 XMP ics Tags
+
+Tags used by IDimager.  Nested TagStructure structures are unrolled to an
+arbitrary depth of 6 to avoid infinite recursion.
+
+These tags belong to the ExifTool XMP-ics family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AppVersion                                    string/
+  ImageRef                                      string
+  SubVersions                                   SubVersion Struct+
+  SubVersionFileName                            string_+
+  SubVersionReference                           string_+
+  TagStructure                                  TagStructure Struct+
+  LabelName1                                    string_+
+  ParentReference1                              string_+
+  Reference1                                    string_+
+  SubLabels1                                    TagStructure Struct_+
+  LabelName2                                    string_+
+  ParentReference2                              string_+
+  Reference2                                    string_+
+  SubLabels2                                    TagStructure Struct_+
+  LabelName3                                    string_+
+  ParentReference3                              string_+
+  Reference3                                    string_+
+  SubLabels3                                    TagStructure Struct_+
+  LabelName4                                    string_+
+  ParentReference4                              string_+
+  Reference4                                    string_+
+  SubLabels4                                    TagStructure Struct_+
+  LabelName5                                    string_+
+  ParentReference5                              string_+
+  Reference5                                    string_+
+  SubLabels5                                    TagStructure Struct_+
+  LabelName6                                    string_+
+  ParentReference6                              string_+
+  Reference6                                    string_+
+  TimeStamp                                     date/
+
+=head3 XMP SubVersion Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  FileName                                      string
+  VersRef                                       string
+
+=head3 XMP TagStructure Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  LabelName                                     string
+  ParentReference                               string
+  Reference                                     string
+  SubLabels                                     TagStructure Struct+
+
 =head3 XMP iptcCore Tags
 
-IPTC Core schema tags.  The actual IPTC Core namespace prefix is
+IPTC Core namespace tags.  The actual IPTC Core namespace prefix is
 "Iptc4xmpCore", which is the prefix recorded in the file, but ExifTool
-shortens this for the "XMP-iptcCore" family 1 group name. (see
+shortens this for the family 1 group name. (see
 L<http://www.iptc.org/IPTC4XMP/>)
+
+These tags belong to the ExifTool XMP-iptcCore family 1 group.
 
   Tag Name                                      Writable
@@ -1612,28 +3504,125 @@
 =head3 XMP iptcExt Tags
 
-IPTC Extension schema tags.  The actual namespace prefix is "Iptc4xmpExt",
-but ExifTool shortens this for the "XMP-iptcExt" 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.
 
   Tag Name                                      Writable
   --------                                      --------
+  AboutCvTerm                                   CVTermDetails Struct+
+  AboutCvTermCvId                               string_+
+  AboutCvTermId                                 string_+
+  AboutCvTermName                               lang-alt_+
+  AboutCvTermRefinedAbout                       string_+
   AdditionalModelInformation                    string
   ArtworkOrObject                               ArtworkOrObjectDetails Struct+
+  ArtworkCircaDateCreated                       string!_+
+  ArtworkContentDescription                     lang-alt_+
+  ArtworkContributionDescription                lang-alt_+
   ArtworkCopyrightNotice                        string_+
   ArtworkCreator                                string_+
+  ArtworkCreatorID                              string_+
+  ArtworkCopyrightOwnerID                       string_+
+  ArtworkCopyrightOwnerName                     string_+
+  ArtworkLicensorID                             string_+
+  ArtworkLicensorName                           string_+
   ArtworkDateCreated                            date_+
+  ArtworkPhysicalDescription                    lang-alt_+
   ArtworkSource                                 string_+
   ArtworkSourceInventoryNo                      string_+
+  ArtworkSourceInvURL                           string_+
+  ArtworkStylePeriod                            string_+
   ArtworkTitle                                  lang-alt_+
+  AudioBitrate                                  integer
+  AudioBitrateMode                              string
+  AudioBitsPerSample                            integer
+  AudioChannelCount                             integer
+  CircaDateCreated                              string
+  ContainerFormat                               Entity Struct
+  ContainerFormatIdentifier                     string_+
+  ContainerFormatName                           lang-alt_
+  Contributor                                   EntityWithRole Struct+
+  ContributorIdentifier                         string_+
+  ContributorName                               lang-alt_+
+  ContributorRole                               string_+
+  CopyrightYear                                 integer
+  Creator                                       EntityWithRole Struct+
+  CreatorIdentifier                             string_+
+  CreatorName                                   lang-alt_+
+  CreatorRole                                   string_+
   ControlledVocabularyTerm                      string+
+  DataOnScreen                                  TextRegion Struct+
+  DataOnScreenRegion                            Area Struct_+
+  DataOnScreenRegionD                           real_+
+  DataOnScreenRegionH                           real_+
+  DataOnScreenRegionText                        string_+
+  DataOnScreenRegionUnit                        string_+
+  DataOnScreenRegionW                           real_+
+  DataOnScreenRegionX                           real_+
+  DataOnScreenRegionY                           real_+
   DigitalImageGUID                              string
   DigitalSourceFileType                         string
   DigitalSourceType                             string
+  Dopesheet                                     lang-alt
+  DopesheetLink                                 QualifiedLink Struct+
+  DopesheetLinkLink                             string_+
+  DopesheetLinkLinkQualifier                    string_+
+  EmbdEncRightsExpr                             EEREDetails Struct+
+  EmbeddedEncodedRightsExpr                     string_+
+  EmbeddedEncodedRightsExprType                 string_+
+  EmbeddedEncodedRightsExprLangID               string_+
+  Episode                                       EpisodeOrSeason Struct
+  EpisodeIdentifier                             string_
+  EpisodeName                                   string_
+  EpisodeNumber                                 string_
   Event                                         lang-alt
-  IptcLastEdited                                date
+  ShownEvent                                    Entity Struct+
+  ShownEventIdentifier                          string_+
+  ShownEventName                                lang-alt_+
+  ExternalMetadataLink                          string+
+  FeedIdentifier                                string
+  Genre                                         CVTermDetails Struct+
+  GenreCvId                                     string_+
+  GenreCvTermId                                 string_+
+  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_+
+  LinkedEncodedRightsExprType                   string_+
+  LinkedEncodedRightsExprLangID                 string_+
   LocationCreated                               LocationDetails Struct+
   LocationCreatedCity                           string_+
   LocationCreatedCountryCode                    string_+
   LocationCreatedCountryName                    string_+
+  LocationCreatedGPSAltitude                    rational_+
+  LocationCreatedGPSLatitude                    string_+
+  LocationCreatedGPSLongitude                   string_+
+  LocationCreatedIdentifier                     string_+
+  LocationCreatedLocationId                     string_+
+  LocationCreatedLocationName                   lang-alt_+
   LocationCreatedProvinceState                  string_+
   LocationCreatedSublocation                    string_+
@@ -1643,4 +3632,10 @@
   LocationShownCountryCode                      string_+
   LocationShownCountryName                      string_+
+  LocationShownGPSAltitude                      rational_+
+  LocationShownGPSLatitude                      string_+
+  LocationShownGPSLongitude                     string_+
+  LocationShownIdentifier                       string_+
+  LocationShownLocationId                       string_+
+  LocationShownLocationName                     lang-alt_+
   LocationShownProvinceState                    string_+
   LocationShownSublocation                      string_+
@@ -1651,194 +3646,157 @@
   OrganisationInImageCode                       string+
   OrganisationInImageName                       string+
+  PersonHeard                                   Entity Struct+
+  PersonHeardIdentifier                         string_+
+  PersonHeardName                               lang-alt_+
   PersonInImage                                 string+
-  RegistryId                                    RegistryEntryDetails Struct+
+  PersonInImageWDetails                         PersonDetails Struct+
+  PersonInImageCharacteristic                   CVTermDetails Struct_+
+  PersonInImageCvTermCvId                       string_+
+  PersonInImageCvTermId                         string_+
+  PersonInImageCvTermName                       lang-alt_+
+  PersonInImageCvTermRefinedAbout               string_+
+  PersonInImageDescription                      lang-alt_+
+  PersonInImageId                               string_+
+  PersonInImageName                             lang-alt_+
+  PlanningRef                                   EntityWithRole Struct+
+  PlanningRefIdentifier                         string_+
+  PlanningRefName                               lang-alt_+
+  PlanningRefRole                               string_+
+  ProductInImage                                ProductDetails Struct+
+  ProductInImageDescription                     lang-alt_+
+  ProductInImageGTIN                            string_+
+  ProductInImageName                            lang-alt_+
+  PublicationEvent                              PublicationEvent Struct+
+  PublicationEventDate                          date_+
+  PublicationEventIdentifier                    string_+
+  PublicationEventName                          string_+
+  Rating                                        Rating Struct+
+  RatingRegion                                  LocationDetails Struct_+
+  RatingRegionCity                              string_+
+  RatingRegionCountryCode                       string_+
+  RatingRegionCountryName                       string_+
+  RatingRegionGPSAltitude                       rational_+
+  RatingRegionGPSLatitude                       string_+
+  RatingRegionGPSLongitude                      string_+
+  RatingRegionIdentifier                        string_+
+  RatingRegionLocationId                        string_+
+  RatingRegionLocationName                      lang-alt_+
+  RatingRegionProvinceState                     string_+
+  RatingRegionSublocation                       string_+
+  RatingRegionWorldRegion                       string_+
+  RatingScaleMaxValue                           string_+
+  RatingScaleMinValue                           string_+
+  RatingSourceLink                              string_+
+  RatingValue                                   string_+
+  RatingValueLogoLink                           string_+
+  RecDevice                                     Device Struct
+  RecDeviceAttLensDescription                   string_
+  RecDeviceManufacturer                         string_
+  RecDeviceModelName                            string_
+  RecDeviceOwnersDeviceId                       string_
+  RecDeviceSerialNumber                         string_
+  RegistryID                                    RegistryEntryDetails Struct+
+  RegistryEntryRole                             string_+
   RegistryItemID                                string_+
   RegistryOrganisationID                        string_+
-
-=head3 XMP ArtworkOrObjectDetails Struct
+  ReleaseReady                                  boolean
+  Season                                        EpisodeOrSeason Struct
+  SeasonIdentifier                              string_
+  SeasonName                                    string_
+  SeasonNumber                                  string_
+  Series                                        Series Struct
+  SeriesIdentifier                              string_
+  SeriesName                                    string_
+  Snapshot                                      LinkedImage Struct+
+  SnapshotFormat                                string_+
+  SnapshotHeightPixels                          integer_+
+  SnapshotImageRole                             string_+
+  SnapshotLink                                  string_+
+  SnapshotLinkQualifier                         string_+
+  SnapshotUsedVideoFrame                        Timecode Struct_+
+  SnapshotUsedVideoFrameTimeFormat              string_+
+  SnapshotUsedVideoFrameTimeValue               string_+
+  SnapshotUsedVideoFrameValue                   integer_+
+  SnapshotWidthPixels                           integer_+
+  StorylineIdentifier                           string+
+  StreamReady                                   string
+  StylePeriod                                   string
+  SupplyChainSource                             Entity Struct+
+  SupplyChainSourceIdentifier                   string_+
+  SupplyChainSourceName                         lang-alt_+
+  TemporalCoverage                              TemporalCoverage Struct
+  TemporalCoverageFrom                          date_
+  TemporalCoverageTo                            date_
+  Transcript                                    lang-alt
+  TranscriptLink                                QualifiedLink Struct+
+  TranscriptLinkLink                            string_+
+  TranscriptLinkLinkQualifier                   string_+
+  VideoBitrate                                  integer
+  VideoBitrateMode                              string
+  VideoDisplayAspectRatio                       rational
+  VideoEncodingProfile                          string
+  VideoShotType                                 Entity Struct+
+  VideoShotTypeIdentifier                       string_+
+  VideoShotTypeName                             lang-alt_+
+  VideoStreamsCount                             integer
+  VisualColor                                   string
+  WorkflowTag                                   CVTermDetails Struct
+  WorkflowTagCvId                               string_
+  WorkflowTagCvTermId                           string_
+  WorkflowTagCvTermName                         lang-alt_
+  WorkflowTagCvTermRefinedAbout                 string_
+
+=head3 XMP CVTermDetails Struct
 
   Field Name                                    Writable
   ----------                                    --------
+  CvId                                          string
+  CvTermId                                      string
+  CvTermName                                    lang-alt
+  CvTermRefinedAbout                            string
+
+=head3 XMP ArtworkOrObjectDetails Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  AOCircaDateCreated                            string
+  AOContentDescription                          lang-alt
+  AOContributionDescription                     lang-alt
   AOCopyrightNotice                             string
   AOCreator                                     string+
+  AOCreatorId                                   string+
+  AOCurrentCopyrightOwnerId                     string
+  AOCurrentCopyrightOwnerName                   string
+  AOCurrentLicensorId                           string
+  AOCurrentLicensorName                         string
   AODateCreated                                 date
+  AOPhysicalDescription                         lang-alt
   AOSource                                      string
   AOSourceInvNo                                 string
+  AOSourceInvURL                                string
+  AOStylePeriod                                 string+
   AOTitle                                       lang-alt
 
-=head3 XMP LocationDetails Struct
+=head3 XMP Entity Struct
 
   Field Name                                    Writable
   ----------                                    --------
-  City                                          string
-  CountryCode                                   string
-  CountryName                                   string
-  ProvinceState                                 string
-  Sublocation                                   string
-  WorldRegion                                   string
-
-=head3 XMP RegistryEntryDetails Struct
+  Identifier                                    string+
+  Name                                          lang-alt
+
+=head3 XMP EntityWithRole Struct
 
   Field Name                                    Writable
   ----------                                    --------
-  RegItemId                                     string
-  RegOrgId                                      string
-
-=head3 XMP Lightroom Tags
-
-Adobe Lightroom "lr" schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  HierarchicalSubject                           string+
-  PrivateRTKInfo                                string
-
-=head3 XMP MediaPro Tags
-
-iView MediaPro schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  CatalogSets                                   string+
-  Event                                         string
-  Location                                      string/
-  People                                        string+
-  Status                                        string
-  UserFields                                    string+
-
-=head3 XMP mwg_coll Tags
-
-Collections metadata defined by the MWG 2.0 specification.  See
-L<http://www.metadataworkinggroup.org/> for the official specification.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  Collections                                   CollectionInfo Struct+
-  CollectionName                                string_+
-  CollectionURI                                 string_+
-
-=head3 XMP CollectionInfo Struct
+  Identifier                                    string+
+  Name                                          lang-alt
+  Role                                          string+
+
+=head3 XMP TextRegion Struct
 
   Field Name                                    Writable
   ----------                                    --------
-  CollectionName                                string
-  CollectionURI                                 string
-
-=head3 XMP mwg_kw Tags
-
-Hierarchical keywords metadata defined by the MWG 2.0 specification.
-ExifTool unrolls keyword structures to an arbitrary depth of 4 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.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  KeywordInfo                                   KeywordInfo Struct
-  HierarchicalKeywords                          KeywordStruct1 Struct_+
-  HierarchicalKeywords1Applied                  boolean_+
-  HierarchicalKeywords1Children                 KeywordStruct2 Struct_+
-  HierarchicalKeywords2Applied                  boolean_+
-  HierarchicalKeywords2Children                 KeywordStruct3 Struct_+
-  HierarchicalKeywords3Applied                  boolean_+
-  HierarchicalKeywords3Children                 KeywordStruct4 Struct_+
-  HierarchicalKeywords4Applied                  boolean_+
-  HierarchicalKeywords4                         string_+
-  HierarchicalKeywords3                         string_+
-  HierarchicalKeywords2                         string_+
-  HierarchicalKeywords1                         string_+
-
-=head3 XMP KeywordInfo Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Hierarchy                                     KeywordStruct1 Struct+
-
-=head3 XMP KeywordStruct1 Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Applied                                       boolean
-  Children                                      KeywordStruct2 Struct+
-  Keyword                                       string
-
-=head3 XMP KeywordStruct2 Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Applied                                       boolean
-  Children                                      KeywordStruct3 Struct+
-  Keyword                                       string
-
-=head3 XMP KeywordStruct3 Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Applied                                       boolean
-  Children                                      KeywordStruct4 Struct+
-  Keyword                                       string
-
-=head3 XMP KeywordStruct4 Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Applied                                       boolean
-  Keyword                                       string
-
-=head3 XMP mwg_rs Tags
-
-Image region metadata defined by the MWG 2.0 specification.  See
-L<http://www.metadataworkinggroup.org/> for the official specification.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  RegionInfo                                    RegionInfo Struct
-  RegionAppliedToDimensions                     Dimensions Struct_
-  RegionAppliedToDimensionsH                    real_
-  RegionAppliedToDimensionsUnit                 string_
-  RegionAppliedToDimensionsW                    real_
-  RegionList                                    RegionStruct Struct_+
-  RegionArea                                    Area Struct_+
-  RegionAreaD                                   real_+
-  RegionAreaH                                   real_+
-  RegionAreaUnit                                string_+
-  RegionAreaW                                   real_+
-  RegionAreaX                                   real_+
-  RegionAreaY                                   real_+
-  RegionBarCodeValue                            string_+
-  RegionDescription                             string_+
-  RegionExtensions                              Extensions Struct_+
-  RegionFocusUsage                              string_+
-  RegionName                                    string_+
-  RegionSeeAlso                                 string_+
-  RegionType                                    string_+
-
-=head3 XMP RegionInfo Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  AppliedToDimensions                           Dimensions Struct
-  RegionList                                    RegionStruct Struct+
-
-=head3 XMP Dimensions Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  H                                             real
-  Unit                                          string
-  W                                             real
-
-=head3 XMP RegionStruct Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Area                                          Area Struct
-  BarCodeValue                                  string
-  Description                                   string
-  Extensions                                    Extensions Struct
-  FocusUsage                                    string
-  Name                                          string
-  Type                                          string
-  SeeAlso                                       string
+  Region                                        Area Struct
+  RegionText                                    string
 
 =head3 XMP Area Struct
@@ -1853,24 +3811,221 @@
   Y                                             real
 
-=head3 XMP Extensions Struct
-
-This structure may contain any top-level XMP tags, but none have been
-pre-defined in ExifTool.  Without pre-defined flattened tag names,
-RegionExtensions may be written only as a structure (ie.
-C<{xmp-dc:creator=me,rating=5}>).  Fields for this structure are identified
-using the standard ExifTool tag name (with optional leading group name,
-and/or trailing language code, and/or trailing C<#> symbol to disable print
-conversion).
+=head3 XMP QualifiedLink Struct
 
   Field Name                                    Writable
   ----------                                    --------
-  [no tags known]
+  Link                                          string
+  LinkQualifier                                 string
+
+=head3 XMP EEREDetails Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  EncRightsExpr                                 string
+  RightsExprEncType                             string
+  RightsExprLangId                              string
+
+=head3 XMP EpisodeOrSeason Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Identifier                                    string
+  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
+  ----------                                    --------
+  LinkedRightsExpr                              string
+  RightsExprEncType                             string
+  RightsExprLangId                              string
+
+=head3 XMP LocationDetails Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  City                                          string
+  CountryCode                                   string
+  CountryName                                   string
+  GPSAltitude                                   rational
+  GPSLatitude                                   string
+  GPSLongitude                                  string
+  Identifier                                    string+
+  LocationId                                    string+
+  LocationName                                  lang-alt
+  ProvinceState                                 string
+  Sublocation                                   string
+  WorldRegion                                   string
+
+=head3 XMP PersonDetails Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  PersonCharacteristic                          CVTermDetails Struct+
+  PersonDescription                             lang-alt
+  PersonId                                      string+
+  PersonName                                    lang-alt
+
+=head3 XMP ProductDetails Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  ProductDescription                            lang-alt
+  ProductGTIN                                   string
+  ProductName                                   lang-alt
+
+=head3 XMP PublicationEvent Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Date                                          date
+  Identifier                                    string
+  Name                                          string
+
+=head3 XMP Rating Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  RatingRegion                                  LocationDetails Struct+
+  RatingScaleMaxValue                           string
+  RatingScaleMinValue                           string
+  RatingSourceLink                              string
+  RatingValue                                   string
+  RatingValueLogoLink                           string
+
+=head3 XMP Device Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  AttLensDescription                            string
+  Manufacturer                                  string
+  ModelName                                     string
+  OwnersDeviceId                                string
+  SerialNumber                                  string
+
+=head3 XMP RegistryEntryDetails Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  RegEntryRole                                  string
+  RegItemId                                     string
+  RegOrgId                                      string
+
+=head3 XMP Series Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Identifier                                    string
+  Name                                          string
+
+=head3 XMP LinkedImage Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  HeightPixels                                  integer
+  ImageRole                                     string
+  Link                                          string
+  LinkQualifier                                 string+
+  UsedVideoFrame                                Timecode Struct
+  WidthPixels                                   integer
+  Format                                        string
+
+=head3 XMP Timecode Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  TimeFormat                                    string
+  TimeValue                                     string
+  Value                                         integer
+
+=head3 XMP TemporalCoverage Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  TempCoverageFrom                              date
+  TempCoverageTo                                date
+
+=head3 XMP LImage Tags
+
+Tags written by RED smartphones.
+
+These tags belong to the ExifTool XMP-LImage family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  MajorVersion                                  string
+  MinorVersion                                  string
+  RightAlbedo                                   string
+
+=head3 XMP Lightroom Tags
+
+Adobe Lightroom "lr" namespace tags.
+
+These tags belong to the ExifTool XMP-lr family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  HierarchicalSubject                           string+
+  PrivateRTKInfo                                string
+
+=head3 XMP MediaPro Tags
+
+iView MediaPro namespace tags.
+
+These tags belong to the ExifTool XMP-mediapro family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CatalogSets                                   string+
+  Event                                         string/
+  Location                                      string/
+  People                                        string+
+  Status                                        string
+  UserFields                                    string+
 
 =head3 XMP pdf Tags
 
-Adobe PDF schema tags.  The official XMP specification defines only
+Adobe PDF namespace tags.  The official XMP specification defines only
 Keywords, PDFVersion, Producer and Trapped.  The other tags are included
 because they have been observed in PDF files, but some are avoided when
 writing due to name conflicts with other XMP namespaces.
+
+These tags belong to the ExifTool XMP-pdf family 1 group.
 
   Tag Name                                      Writable
@@ -1895,4 +4050,6 @@
 created to enable writing of XMP-pdfx information.
 
+These tags belong to the ExifTool XMP-pdfx family 1 group.
+
   Tag Name                                      Writable
   --------                                      --------
@@ -1901,5 +4058,7 @@
 =head3 XMP photoshop Tags
 
-Adobe Photoshop schema tags.
+Adobe Photoshop namespace tags.
+
+These tags belong to the ExifTool XMP-photoshop family 1 group.
 
   Tag Name                                      Writable
@@ -1913,6 +4072,6 @@
   Credit                                        string
   DateCreated                                   date
-  DocumentAncestors                             Ancestor Struct+
-  DocumentAncestorID                            string_+
+  DocumentAncestors                             string+
+  EmbeddedXMPDigest                             string
   Headline                                      string
   History                                       string
@@ -1930,10 +4089,4 @@
   Urgency                                       integer
 
-=head3 XMP Ancestor Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  AncestorID                                    string
-
 =head3 XMP Layer Struct
 
@@ -1945,24 +4098,1277 @@
 =head3 XMP PixelLive Tags
 
-PixelLive schema 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.
 
+These tags belong to the ExifTool XMP-PixelLive family 1 group.
+
   Tag Name                                      Writable
   --------                                      --------
-  Author                                        N
-  Comments                                      N
-  Copyright                                     N
-  Date                                          N
-  Genre                                         N
-  Title                                         N
-
-=head3 XMP plus Tags
-
-PLUS License Data Format 1.2.0 schema 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/>)
+  Author                                        no
+  Comments                                      no
+  Copyright                                     no
+  Date                                          no
+  Genre                                         no
+  Title                                         no
+
+=head3 XMP pmi Tags
+
+PRISM Metadata for Images 3.0 namespace tags.  (see
+L<http://www.prismstandard.org/>)
+
+These tags belong to the ExifTool XMP-pmi family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Color                                         string/
+  ContactInfo                                   string/
+  DisplayName                                   string/
+  DistributorProductID                          string/
+  EventAlias                                    string/
+  EventEnd                                      string/
+  EventStart                                    string/
+  EventSubtype                                  string/
+  EventType                                     string/
+  Field                                         string/
+  Framing                                       string/
+  Location                                      string/
+  Make                                          string/
+  Manufacturer                                  string/
+  Model                                         string/
+  ModelYear                                     string/
+  ObjectDescription                             string/
+  ObjectSubtype                                 string/
+  ObjectType                                    string/
+  Orientation                                   string/
+  PositionDescriptor                            string/
+  ProductID                                     string/
+  ProductIDType                                 string/
+  Season                                        string/
+  SequenceName                                  string/
+  SequenceNumber                                string/
+  SequenceTotalNumber                           string/
+  Setting                                       string/
+  ShootID                                       string/
+  SlideshowName                                 string/
+  SlideshowNumber                               integer/
+  SlideshowTotalNumber                          integer/
+  Viewpoint                                     string/
+  VisualTechnique                               string/
+
+=head3 XMP prism Tags
+
+Publishing Requirements for Industry Standard Metadata 3.0 namespace
+tags.  (see L<http://www.prismstandard.org/>)
+
+These tags belong to the ExifTool XMP-prism family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AcademicField                                 string/
+  AggregateIssueNumber                          integer/
+  AggregationType                               string/+
+  AlternateTitle                                prismAlternateTitle Struct+
+  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/_+
+  ComplianceProfile                             string/
+  ContentType                                   string/
+  CopyrightYear                                 string/
+  CorporateEntity                               string/+
+  CoverDate                                     date/
+  CoverDisplayDate                              string/
+  CreationDate                                  date/
+  DateRecieved                                  date/
+  Device                                        string/
+  Distributor                                   string/
+  DOI                                           string/
+  Edition                                       string/
+  EIssn                                         string/
+  EndingPage                                    string/
+  Event                                         string/+
+  Genre                                         string/+
+  HasAlternative                                string/+
+  HasCorrection                                 prismHasCorrection Struct
+  HasCorrectionA-lang                           string/_
+  HasCorrectionA-platform                       string/_
+  HasCorrectionText                             string/_
+  HasTranslation                                string/+
+  Industry                                      string/+
+  IsAlternativeOf                               string/+
+  ISBN                                          string/+
+  IsCorrectionOf                                string/+
+  ISSN                                          string/
+  IssueIdentifier                               string/
+  IssueName                                     string/
+  IssueTeaser                                   string/
+  IssueType                                     string/
+  IsTranslationOf                               string/
+  Keyword                                       string/+
+  KillDate                                      prismKillDate Struct
+  KillDateA-platform                            string/_
+  KillDateDate                                  date/_
+  Link                                          string/+
+  Location                                      string/+
+  ModificationDate                              date/
+  NationalCatalogNumber                         string/
+  Number                                        string/
+  Object                                        string/+
+  OffSaleDate                                   prismOffSaleDate Struct+
+  OffSaleDateA-platform                         string/_+
+  OffSaleDateDate                               date/_+
+  OnSaleDate                                    prismOnSaleDate Struct+
+  OnSaleDateA-platform                          string/_+
+  OnSaleDateDate                                date/_+
+  OnSaleDay                                     prismOnSaleDay Struct+
+  OnSaleDayA-platform                           string/_+
+  OnSaleDayDay                                  string/_+
+  Organization                                  string/+
+  OriginPlatform                                string/+
+  PageCount                                     integer/
+  PageProgressionDirection                      string/
+  PageRange                                     string/+
+  Person                                        string/
+  Platform                                      string/
+  ProductCode                                   string/
+  Profession                                    string/
+  PublicationDate                               prismPublicationDate Struct+
+  PublicationDateA-platform                     string/_+
+  PublicationDateDate                           date/_+
+  PublicationDisplayDate                        prismPublicationDate Struct+
+  PublicationDisplayDateA-platform              string/_+
+  PublicationDisplayDateDate                    date/_+
+  PublicationName                               string/
+  PublishingFrequency                           string/
+  Rating                                        string/
+  SamplePageRange                               string/
+  Section                                       string/
+  SellingAgency                                 string/
+  SeriesNumber                                  integer/
+  SeriesTitle                                   string/
+  Sport                                         string/
+  StartingPage                                  string/
+  Subsection1                                   string/
+  Subsection2                                   string/
+  Subsection3                                   string/
+  Subsection4                                   string/
+  Subtitle                                      string/
+  SupplementDisplayID                           string/
+  SupplementStartingPage                        string/
+  SupplementTitle                               string/
+  Teaser                                        string/+
+  Ticker                                        string/+
+  TimePeriod                                    string/
+  URL                                           prismUrl Struct+
+  URLA-platform                                 string/_+
+  URLUrl                                        string/_+
+  UspsNumber                                    string/
+  VersionIdentifier                             string/
+  Volume                                        string/
+  WordCount                                     integer/
+
+=head3 XMP prismAlternateTitle Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-lang                                        string
+  A-platform                                    string
+  Text                                          string
+
+=head3 XMP prismChannel Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-lang                                        string
+  Channel                                       string
+  Subchannel1                                   string
+  Subchannel2                                   string
+  Subchannel3                                   string
+  Subchannel4                                   string
+
+=head3 XMP prismHasCorrection Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-lang                                        string
+  A-platform                                    string
+  Text                                          string
+
+=head3 XMP prismKillDate Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-platform                                    string
+  Date                                          date
+
+=head3 XMP prismOffSaleDate Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-platform                                    string
+  Date                                          date
+
+=head3 XMP prismOnSaleDate Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-platform                                    string
+  Date                                          date
+
+=head3 XMP prismOnSaleDay Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-platform                                    string
+  Day                                           string
+
+=head3 XMP prismPublicationDate Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-platform                                    string
+  Date                                          date
+
+=head3 XMP prismUrl Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A-platform                                    string
+  Url                                           string
+
+=head3 XMP prl Tags
+
+PRISM Rights Language 2.1 namespace tags.  These tags have been deprecated
+since the release of the PRISM Usage Rights 3.0. (see
+L<http://www.prismstandard.org/>)
+
+These tags belong to the ExifTool XMP-prl family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Geography                                     string/+
+  Industry                                      string/+
+  Usage                                         string/+
+
+=head3 XMP prm Tags
+
+PRISM Recipe Metadata 3.0 namespace tags.  (see
+L<http://www.prismstandard.org/>)
+
+These tags belong to the ExifTool XMP-prm family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CookingEquipment                              string/
+  CookingMethod                                 string/
+  Course                                        string/
+  Cuisine                                       string/
+  DietaryNeeds                                  string/
+  DishType                                      string/
+  Duration                                      string/
+  IngredientExclusion                           string/
+  MainIngredient                                string/
+  Meal                                          string/
+  RecipeEndingPage                              string/
+  RecipePageRange                               string/
+  RecipeSource                                  string/
+  RecipeStartingPage                            string/
+  RecipeTitle                                   string/
+  ServingSize                                   string/
+  SkillLevel                                    string/
+  SpecialOccasion                               string/
+  Yield                                         string/
+
+=head3 XMP pur Tags
+
+PRISM Usage Rights 3.0 namespace tags.  (see
+L<http://www.prismstandard.org/>)
+
+These tags belong to the ExifTool XMP-pur family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AdultContentWarning                           string/+
+  Agreement                                     string/+
+  Copyright                                     lang-alt/
+  CreditLine                                    string/+
+  EmbargoDate                                   date/+
+  ExclusivityEndDate                            date/+
+  ExpirationDate                                date/+
+  ImageSizeRestriction                          string/
+  OptionEndDate                                 date/+
+  Permissions                                   string/+
+  Restrictions                                  string/+
+  ReuseProhibited                               boolean/
+  RightsAgent                                   string/
+  RightsOwner                                   string/
+
+=head3 XMP rdf Tags
+
+Most RDF attributes are handled internally, but the "about" attribute is
+treated specially to allow it to be set to a specific value if required.
+
+These tags belong to the ExifTool XMP-rdf family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  About                                         string!
+
+=head3 XMP swf Tags
+
+Adobe SWF namespace tags.
+
+These tags belong to the ExifTool XMP-swf family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  BackgroundAlpha                               integer
+  ForwardLock                                   boolean
+  MaxStorage                                    integer
+  Type                                          string/
+
+=head3 XMP tiff Tags
+
+EXIF namespace for TIFF tags.  See
+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.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Artist                                        string
+  BitsPerSample                                 integer+
+  Compression                                   integer
+  Copyright                                     lang-alt
+  DateTime                                      date
+  ImageDescription                              lang-alt
+  ImageHeight                                   integer
+  ImageWidth                                    integer
+  Make                                          string
+  Model                                         string
+  NativeDigest                                  string
+  Orientation                                   integer
+  PhotometricInterpretation                     integer
+  PlanarConfiguration                           integer
+  PrimaryChromaticities                         rational+
+  ReferenceBlackWhite                           rational+
+  ResolutionUnit                                integer
+  SamplesPerPixel                               integer
+  Software                                      string
+  TransferFunction                              integer+
+  WhitePoint                                    rational+
+  XResolution                                   rational
+  YCbCrCoefficients                             rational+
+  YCbCrPositioning                              integer
+  YCbCrSubSampling                              integer+
+  YResolution                                   rational
+
+=head3 XMP x Tags
+
+The "x" namespace is used for the "xmpmeta" wrapper, and may contain an
+"xmptk" attribute that is extracted as the XMPToolkit tag.  When writing,
+the XMPToolkit tag is generated automatically by ExifTool unless
+specifically set to another value.
+
+These tags belong to the ExifTool XMP-x family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  XMPToolkit                                    string!
+
+=head3 XMP xmp Tags
+
+XMP namespace tags.  If the older "xap", "xapBJ", "xapMM" or "xapRights"
+namespace prefixes are found, they are translated to the newer "xmp",
+"xmpBJ", "xmpMM" and "xmpRights" prefixes for use in family 1 group names.
+
+These tags belong to the ExifTool XMP-xmp family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Advisory                                      string+
+  Author                                        string/
+  BaseURL                                       string
+  CreateDate                                    date
+  CreatorTool                                   string
+  Description                                   lang-alt/
+  Format                                        string/
+  Identifier                                    string/+
+  Keywords                                      string/
+  Label                                         string
+  MetadataDate                                  date
+  ModifyDate                                    date
+  Nickname                                      string
+  PageInfo                                      PageInfo Struct+
+  PageImageFormat                               string_+
+  PageImageHeight                               integer_+
+  PageImage                                     string_+
+  PageImagePageNumber                           integer_+
+  PageImageWidth                                integer_+
+  Rating                                        real
+  RatingPercent                                 real/
+  Thumbnails                                    Thumbnail Struct+
+  ThumbnailFormat                               string_+
+  ThumbnailHeight                               integer_+
+  ThumbnailImage                                string/_+
+  ThumbnailWidth                                integer_+
+  Title                                         lang-alt/
+
+=head3 XMP PageInfo Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  PageNumber                                    integer
+  Format                                        string
+  Height                                        integer
+  Image                                         string
+  Width                                         integer
+
+=head3 XMP Thumbnail Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Format                                        string
+  Height                                        integer
+  Image                                         string
+  Width                                         integer
+
+=head3 XMP xmpBJ Tags
+
+XMP Basic Job Ticket namespace tags.
+
+These tags belong to the ExifTool XMP-xmpBJ family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  JobRef                                        JobRef Struct+
+  JobRefId                                      string_+
+  JobRefName                                    string_+
+  JobRefUrl                                     string_+
+
+=head3 XMP JobRef Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Id                                            string
+  Name                                          string
+  Url                                           string
+
+=head3 XMP xmpDM Tags
+
+XMP Dynamic Media namespace tags.
+
+These tags belong to the ExifTool XMP-xmpDM family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AbsPeakAudioFilePath                          string
+  Album                                         string
+  AltTapeName                                   string
+  AltTimecode                                   Timecode Struct
+  AltTimecodeTimeFormat                         string_
+  AltTimecodeTimeValue                          string_
+  AltTimecodeValue                              integer_
+  Artist                                        string/
+  AudioChannelType                              string
+  AudioCompressor                               string
+  AudioModDate                                  date
+  AudioSampleRate                               integer
+  AudioSampleType                               string
+  BeatSpliceParams                              BeatSpliceStretch Struct
+  BeatSpliceParamsRiseInDecibel                 real_
+  BeatSpliceParamsRiseInTimeDuration            Time Struct_
+  BeatSpliceParamsRiseInTimeDurationScale       rational_
+  BeatSpliceParamsRiseInTimeDurationValue       integer_
+  BeatSpliceParamsUseFileBeatsMarker            boolean_
+  CameraAngle                                   string
+  CameraLabel                                   string
+  CameraModel                                   string
+  CameraMove                                    string
+  Client                                        string
+  DMComment                                     string
+  Composer                                      string
+  ContributedMedia                              Media Struct+
+  ContributedMediaDuration                      Time Struct_+
+  ContributedMediaDurationScale                 rational_+
+  ContributedMediaDurationValue                 integer_+
+  ContributedMediaManaged                       boolean_+
+  ContributedMediaPath                          string_+
+  ContributedMediaStartTime                     Time Struct_+
+  ContributedMediaStartTimeScale                rational_+
+  ContributedMediaStartTimeValue                integer_+
+  ContributedMediaTrack                         string_+
+  ContributedMediaWebStatement                  string_+
+  Copyright                                     string/
+  Director                                      string
+  DirectorPhotography                           string
+  DiscNumber                                    string
+  Duration                                      Time Struct
+  DurationScale                                 rational_
+  DurationValue                                 integer_
+  Engineer                                      string
+  FileDataRate                                  rational
+  Genre                                         string
+  Good                                          boolean
+  Instrument                                    string
+  IntroTime                                     Time Struct
+  IntroTimeScale                                rational_
+  IntroTimeValue                                integer_
+  Key                                           string
+  LogComment                                    string
+  Loop                                          boolean
+  Lyrics                                        string
+  Markers                                       Marker Struct+
+  MarkersComment                                string_+
+  MarkersCuePointParams                         CuePointParam Struct_+
+  MarkersCuePointParamsKey                      string_+
+  MarkersCuePointParamsValue                    string_+
+  MarkersCuePointType                           string_+
+  MarkersDuration                               string_+
+  MarkersLocation                               string_+
+  MarkersName                                   string_+
+  MarkersProbability                            real_+
+  MarkersSpeaker                                string_+
+  MarkersStartTime                              string_+
+  MarkersTarget                                 string_+
+  MarkersType                                   string_+
+  MetadataModDate                               date
+  NumberOfBeats                                 real
+  OutCue                                        Time Struct
+  OutCueScale                                   rational_
+  OutCueValue                                   integer_
+  PartOfCompilation                             boolean
+  ProjectName                                   string
+  ProjectRef                                    ProjectLink Struct
+  ProjectRefPath                                string_
+  ProjectRefType                                string_
+  PullDown                                      string
+  RelativePeakAudioFilePath                     string
+  RelativeTimestamp                             Time Struct
+  RelativeTimestampScale                        rational_
+  RelativeTimestampValue                        integer_
+  ReleaseDate                                   date
+  ResampleParams                                ResampleStretch Struct
+  ResampleParamsQuality                         string_
+  ScaleType                                     string
+  Scene                                         string/
+  ShotDate                                      date
+  ShotDay                                       string
+  ShotLocation                                  string
+  ShotName                                      string
+  ShotNumber                                    string
+  ShotSize                                      string
+  SpeakerPlacement                              string
+  StartTimecode                                 Timecode Struct
+  StartTimecodeTimeFormat                       string_
+  StartTimecodeTimeValue                        string_
+  StartTimecodeValue                            integer_
+  StartTimeSampleSize                           integer
+  StartTimeScale                                string
+  StretchMode                                   string
+  TakeNumber                                    integer
+  TapeName                                      string
+  Tempo                                         real
+  TimeScaleParams                               TimeScaleStretch Struct
+  TimeScaleParamsFrameOverlappingPercentage     real_
+  TimeScaleParamsFrameSize                      real_
+  TimeScaleParamsQuality                        string_
+  TimeSignature                                 string
+  TrackNumber                                   integer
+  Tracks                                        Track Struct+
+  TracksFrameRate                               string_+
+  TracksMarkers                                 Marker Struct_+
+  TracksMarkersComment                          string_+
+  TracksMarkersCuePointParams                   CuePointParam Struct_+
+  TracksMarkersCuePointParamsKey                string_+
+  TracksMarkersCuePointParamsValue              string_+
+  TracksMarkersCuePointType                     string_+
+  TracksMarkersDuration                         string_+
+  TracksMarkersLocation                         string_+
+  TracksMarkersName                             string_+
+  TracksMarkersProbability                      real_+
+  TracksMarkersSpeaker                          string_+
+  TracksMarkersStartTime                        string_+
+  TracksMarkersTarget                           string_+
+  TracksMarkersType                             string_+
+  TracksTrackName                               string_+
+  TracksTrackType                               string_+
+  VideoAlphaMode                                string
+  VideoAlphaPremultipleColor                    Colorant Struct
+  VideoAlphaPremultipleColorA                   integer_
+  VideoAlphaPremultipleColorB                   integer_
+  VideoAlphaPremultipleColorBlack               real_
+  VideoAlphaPremultipleColorBlue                integer_
+  VideoAlphaPremultipleColorCyan                real_
+  VideoAlphaPremultipleColorGray                integer_
+  VideoAlphaPremultipleColorGreen               integer_
+  VideoAlphaPremultipleColorL                   real_
+  VideoAlphaPremultipleColorMagenta             real_
+  VideoAlphaPremultipleColorMode                string_
+  VideoAlphaPremultipleColorRed                 integer_
+  VideoAlphaPremultipleColorSwatchName          string_
+  VideoAlphaPremultipleColorTint                integer_
+  VideoAlphaPremultipleColorType                string_
+  VideoAlphaPremultipleColorYellow              real_
+  VideoAlphaUnityIsTransparent                  boolean
+  VideoColorSpace                               string
+  VideoCompressor                               string
+  VideoFieldOrder                               string
+  VideoFrameRate                                real
+  VideoFrameSize                                Dimensions Struct
+  VideoFrameSizeH                               real_
+  VideoFrameSizeUnit                            string_
+  VideoFrameSizeW                               real_
+  VideoModDate                                  date
+  VideoPixelAspectRatio                         rational
+  VideoPixelDepth                               string
+
+=head3 XMP BeatSpliceStretch Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  RiseInDecibel                                 real
+  RiseInTimeDuration                            Time Struct
+  UseFileBeatsMarker                            boolean
+
+=head3 XMP Time Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Scale                                         rational
+  Value                                         integer
+
+=head3 XMP Media Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Duration                                      Time Struct
+  Managed                                       boolean
+  Path                                          string
+  StartTime                                     Time Struct
+  Track                                         string
+  WebStatement                                  string
+
+=head3 XMP Marker Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Comment                                       string
+  CuePointParams                                CuePointParam Struct+
+  CuePointType                                  string
+  Duration                                      string
+  Location                                      string
+  Name                                          string
+  Probability                                   real
+  Speaker                                       string
+  StartTime                                     string
+  Target                                        string
+  Type                                          string
+
+=head3 XMP CuePointParam Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Key                                           string
+  Value                                         string
+
+=head3 XMP ProjectLink Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Path                                          string
+  Type                                          string
+
+=head3 XMP ResampleStretch Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Quality                                       string
+
+=head3 XMP TimeScaleStretch Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  FrameOverlappingPercentage                    real
+  FrameSize                                     real
+  Quality                                       string
+
+=head3 XMP Track Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  FrameRate                                     string
+  Markers                                       Marker Struct+
+  TrackName                                     string
+  TrackType                                     string
+
+=head3 XMP Colorant Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  A                                             integer
+  B                                             integer
+  L                                             real
+  Black                                         real
+  Blue                                          integer
+  Cyan                                          real
+  Gray                                          integer
+  Green                                         integer
+  Magenta                                       real
+  Mode                                          string
+  Red                                           integer
+  SwatchName                                    string
+  Tint                                          integer
+  Type                                          string
+  Yellow                                        real
+
+=head3 XMP Dimensions Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  H                                             real
+  Unit                                          string
+  W                                             real
+
+=head3 XMP xmpMM Tags
+
+XMP Media Management namespace tags.
+
+These tags belong to the ExifTool XMP-xmpMM family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  DerivedFrom                                   ResourceRef Struct
+  DerivedFromAlternatePaths                     string_+
+  DerivedFromDocumentID                         string_
+  DerivedFromFilePath                           string_
+  DerivedFromFromPart                           string_
+  DerivedFromInstanceID                         string_
+  DerivedFromLastModifyDate                     date_
+  DerivedFromLastURL                            string_
+  DerivedFromLinkCategory                       string_
+  DerivedFromLinkForm                           string_
+  DerivedFromManager                            string_
+  DerivedFromManagerVariant                     string_
+  DerivedFromManageTo                           string_
+  DerivedFromManageUI                           string_
+  DerivedFromMaskMarkers                        string_
+  DerivedFromOriginalDocumentID                 string_
+  DerivedFromPartMapping                        string_
+  DerivedFromPlacedResolutionUnit               string_
+  DerivedFromPlacedXResolution                  string_
+  DerivedFromPlacedYResolution                  string_
+  DerivedFromRenditionClass                     string_
+  DerivedFromRenditionParams                    string_
+  DerivedFromToPart                             string_
+  DerivedFromVersionID                          string_
+  DocumentID                                    string
+  History                                       ResourceEvent Struct+
+  HistoryAction                                 string_+
+  HistoryChanged                                string_+
+  HistoryInstanceID                             string_+
+  HistoryParameters                             string_+
+  HistorySoftwareAgent                          string_+
+  HistoryWhen                                   date_+
+  Ingredients                                   ResourceRef Struct+
+  IngredientsAlternatePaths                     string_+
+  IngredientsDocumentID                         string_+
+  IngredientsFilePath                           string_+
+  IngredientsFromPart                           string_+
+  IngredientsInstanceID                         string_+
+  IngredientsLastModifyDate                     date_+
+  IngredientsLastURL                            string_+
+  IngredientsLinkCategory                       string_+
+  IngredientsLinkForm                           string_+
+  IngredientsManager                            string_+
+  IngredientsManagerVariant                     string_+
+  IngredientsManageTo                           string_+
+  IngredientsManageUI                           string_+
+  IngredientsMaskMarkers                        string_+
+  IngredientsOriginalDocumentID                 string_+
+  IngredientsPartMapping                        string_+
+  IngredientsPlacedResolutionUnit               string_+
+  IngredientsPlacedXResolution                  string_+
+  IngredientsPlacedYResolution                  string_+
+  IngredientsRenditionClass                     string_+
+  IngredientsRenditionParams                    string_+
+  IngredientsToPart                             string_+
+  IngredientsVersionID                          string_+
+  InstanceID                                    string
+  LastURL                                       string
+  ManagedFrom                                   ResourceRef Struct
+  ManagedFromAlternatePaths                     string_+
+  ManagedFromDocumentID                         string_
+  ManagedFromFilePath                           string_
+  ManagedFromFromPart                           string_
+  ManagedFromInstanceID                         string_
+  ManagedFromLastModifyDate                     date_
+  ManagedFromLastURL                            string_
+  ManagedFromLinkCategory                       string_
+  ManagedFromLinkForm                           string_
+  ManagedFromManager                            string_
+  ManagedFromManagerVariant                     string_
+  ManagedFromManageTo                           string_
+  ManagedFromManageUI                           string_
+  ManagedFromMaskMarkers                        string_
+  ManagedFromOriginalDocumentID                 string_
+  ManagedFromPartMapping                        string_
+  ManagedFromPlacedResolutionUnit               string_
+  ManagedFromPlacedXResolution                  string_
+  ManagedFromPlacedYResolution                  string_
+  ManagedFromRenditionClass                     string_
+  ManagedFromRenditionParams                    string_
+  ManagedFromToPart                             string_
+  ManagedFromVersionID                          string_
+  Manager                                       string
+  ManagerVariant                                string
+  ManageTo                                      string
+  ManageUI                                      string
+  Manifest                                      ManifestItem Struct+
+  ManifestLinkForm                              string_+
+  ManifestPlacedResolutionUnit                  string_+
+  ManifestPlacedXResolution                     real_+
+  ManifestPlacedYResolution                     real_+
+  ManifestReference                             ResourceRef Struct_+
+  ManifestReferenceAlternatePaths               string_+
+  ManifestReferenceDocumentID                   string_+
+  ManifestReferenceFilePath                     string_+
+  ManifestReferenceFromPart                     string_+
+  ManifestReferenceInstanceID                   string_+
+  ManifestReferenceLastModifyDate               date_+
+  ManifestReferenceLastURL                      string_+
+  ManifestReferenceLinkCategory                 string_+
+  ManifestReferenceLinkForm                     string_+
+  ManifestReferenceManager                      string_+
+  ManifestReferenceManagerVariant               string_+
+  ManifestReferenceManageTo                     string_+
+  ManifestReferenceManageUI                     string_+
+  ManifestReferenceMaskMarkers                  string_+
+  ManifestReferenceOriginalDocumentID           string_+
+  ManifestReferencePartMapping                  string_+
+  ManifestReferencePlacedResolutionUnit         string_+
+  ManifestReferencePlacedXResolution            string_+
+  ManifestReferencePlacedYResolution            string_+
+  ManifestReferenceRenditionClass               string_+
+  ManifestReferenceRenditionParams              string_+
+  ManifestReferenceToPart                       string_+
+  ManifestReferenceVersionID                    string_+
+  OriginalDocumentID                            string
+  Pantry                                        PantryItem Struct+
+  PantryInstanceID                              string_
+  PreservedFileName                             string
+  RenditionClass                                string
+  RenditionOf                                   ResourceRef Struct
+  RenditionOfAlternatePaths                     string_+
+  RenditionOfDocumentID                         string_
+  RenditionOfFilePath                           string_
+  RenditionOfFromPart                           string_
+  RenditionOfInstanceID                         string_
+  RenditionOfLastModifyDate                     date_
+  RenditionOfLastURL                            string_
+  RenditionOfLinkCategory                       string_
+  RenditionOfLinkForm                           string_
+  RenditionOfManager                            string_
+  RenditionOfManagerVariant                     string_
+  RenditionOfManageTo                           string_
+  RenditionOfManageUI                           string_
+  RenditionOfMaskMarkers                        string_
+  RenditionOfOriginalDocumentID                 string_
+  RenditionOfPartMapping                        string_
+  RenditionOfPlacedResolutionUnit               string_
+  RenditionOfPlacedXResolution                  string_
+  RenditionOfPlacedYResolution                  string_
+  RenditionOfRenditionClass                     string_
+  RenditionOfRenditionParams                    string_
+  RenditionOfToPart                             string_
+  RenditionOfVersionID                          string_
+  RenditionParams                               string
+  SaveID                                        integer
+  Subject                                       string/+
+  VersionID                                     string
+  Versions                                      Version Struct+
+  VersionsComments                              string_+
+  VersionsEvent                                 ResourceEvent Struct_+
+  VersionsEventAction                           string_+
+  VersionsEventChanged                          string_+
+  VersionsEventInstanceID                       string_+
+  VersionsEventParameters                       string_+
+  VersionsEventSoftwareAgent                    string_+
+  VersionsEventWhen                             date_+
+  VersionsModifier                              string_+
+  VersionsModifyDate                            date_+
+  VersionsVersion                               string_+
+
+=head3 XMP ResourceRef Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  AlternatePaths                                string+
+  DocumentID                                    string
+  FilePath                                      string
+  FromPart                                      string
+  InstanceID                                    string
+  LastModifyDate                                date
+  LastURL                                       string
+  LinkCategory                                  string
+  LinkForm                                      string
+  ManageTo                                      string
+  ManageUI                                      string
+  Manager                                       string
+  ManagerVariant                                string
+  MaskMarkers                                   string
+  OriginalDocumentID                            string
+  PartMapping                                   string
+  PlacedResolutionUnit                          string
+  PlacedXResolution                             string
+  PlacedYResolution                             string
+  RenditionClass                                string
+  RenditionParams                               string
+  ToPart                                        string
+  VersionID                                     string
+
+=head3 XMP ResourceEvent Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Action                                        string
+  Changed                                       string
+  InstanceID                                    string
+  Parameters                                    string
+  SoftwareAgent                                 string
+  When                                          date
+
+=head3 XMP ManifestItem Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  LinkForm                                      string
+  PlacedResolutionUnit                          string
+  PlacedXResolution                             real
+  PlacedYResolution                             real
+  Reference                                     ResourceRef Struct
+
+=head3 XMP PantryItem Struct
+
+This structure must have an InstanceID field, but may also contain any other
+XMP properties.
+
+  Field Name                                    Writable
+  ----------                                    --------
+  InstanceID                                    string
+
+=head3 XMP Version Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Comments                                      string
+  Event                                         ResourceEvent Struct
+  Modifier                                      string
+  ModifyDate                                    date
+  Version                                       string
+
+=head3 XMP xmpNote Tags
+
+XMP Note namespace tags.
+
+These tags belong to the ExifTool XMP-xmpNote family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  HasExtendedXMP                                string*
+
+=head3 XMP xmpPLUS Tags
+
+XMP Picture Licensing Universal System (PLUS) tags as written by some older
+Adobe applications.  See L<PLUS XMP Tags|Image::ExifTool::TagNames/PLUS XMP Tags>
+for the current PLUS tags.
+
+These tags belong to the ExifTool XMP-xmpPLUS family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CreditLineReq                                 boolean/
+  ReuseAllowed                                  boolean/
+
+=head3 XMP xmpRights Tags
+
+XMP Rights Management namespace tags.
+
+These tags belong to the ExifTool XMP-xmpRights family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Certificate                                   string
+  Marked                                        boolean
+  Owner                                         string+
+  UsageTerms                                    lang-alt
+  WebStatement                                  string
+
+=head3 XMP xmpTPg Tags
+
+XMP Paged-Text namespace tags.
+
+These tags belong to the ExifTool XMP-xmpTPg family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Colorants                                     Colorant Struct+
+  ColorantA                                     integer_+
+  ColorantB                                     integer_+
+  ColorantBlack                                 real_+
+  ColorantBlue                                  integer_+
+  ColorantCyan                                  real_+
+  ColorantGray                                  integer_+
+  ColorantGreen                                 integer_+
+  ColorantL                                     real_+
+  ColorantMagenta                               real_+
+  ColorantMode                                  string_+
+  ColorantRed                                   integer_+
+  ColorantSwatchName                            string_+
+  ColorantTint                                  integer_+
+  ColorantType                                  string_+
+  ColorantYellow                                real_+
+  Fonts                                         Font Struct+
+  ChildFontFiles                                string_+
+  FontComposite                                 boolean_+
+  FontFace                                      string_+
+  FontFamily                                    string_+
+  FontFileName                                  string_+
+  FontName                                      string_+
+  FontType                                      string_+
+  FontVersion                                   string_+
+  HasVisibleOverprint                           boolean
+  HasVisibleTransparency                        boolean
+  MaxPageSize                                   Dimensions Struct
+  MaxPageSizeH                                  real_
+  MaxPageSizeUnit                               string_
+  MaxPageSizeW                                  real_
+  NPages                                        integer
+  PlateNames                                    string+
+  SwatchGroups                                  SwatchGroup Struct+
+  SwatchGroupsColorants                         Colorant Struct_+
+  SwatchColorantA                               integer_+
+  SwatchColorantB                               integer_+
+  SwatchColorantBlack                           real_+
+  SwatchColorantBlue                            integer_+
+  SwatchColorantCyan                            real_+
+  SwatchColorantGray                            integer_+
+  SwatchColorantGreen                           integer_+
+  SwatchColorantL                               real_+
+  SwatchColorantMagenta                         real_+
+  SwatchColorantMode                            string_+
+  SwatchColorantRed                             integer_+
+  SwatchColorantSwatchName                      string_+
+  SwatchColorantTint                            integer_+
+  SwatchColorantType                            string_+
+  SwatchColorantYellow                          real_+
+  SwatchGroupName                               string_+
+  SwatchGroupType                               integer_+
+
+=head3 XMP Font Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  ChildFontFiles                                string+
+  Composite                                     boolean
+  FontFace                                      string
+  FontFamily                                    string
+  FontFileName                                  string
+  FontName                                      string
+  FontType                                      string
+  VersionString                                 string
+
+=head3 XMP SwatchGroup Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Colorants                                     Colorant Struct+
+  GroupName                                     string
+  GroupType                                     integer
+
+=head3 XMP XML Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'dc'                 dc                       XMP dc
+  'lastUpdate'         LastUpdate               no
+
+=head3 XMP SVG Tags
+
+SVG (Scalable Vector Graphics) image tags.  By default, only the top-level
+SVG and Metadata tags are extracted from these images, but all graphics tags
+may be extracted by setting the Unknown option to 2 (-U on the command
+line).  The SVG tags are not part of XMP as such, but are included with the
+XMP module for convenience.  (see L<http://www.w3.org/TR/SVG11/>)
+
+These tags belong to the ExifTool XMP-svg family 1 group.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'height'             ImageHeight              no
+  'id'                 ID                       no
+  'metadataId'         MetadataID               no
+  'version'            SVGVersion               no
+  'width'              ImageWidth               no
+
+=head2 GPS Tags
+
+These GPS tags are part of the EXIF standard, and are stored in a separate
+IFD within the EXIF information.
+
+ExifTool is very flexible about the input format when writing lat/long
+coordinates, and will accept from 1 to 3 floating point numbers (for decimal
+degrees, degrees and minutes, or degrees, minutes and seconds) separated by
+just about anything, and will format them properly according to the EXIF
+specification.
+
+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,
+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
+following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,
+and GPSAltitude and GPSAltitudeRef if the altitude is known.  ExifTool will
+write the required GPSVersionID tag automatically if new a GPS IFD is added
+to an image.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   GPSVersionID                         int8u[4]:
+  0x0001   GPSLatitudeRef                       string[2]
+  0x0002   GPSLatitude                          rational64u[3]
+  0x0003   GPSLongitudeRef                      string[2]
+  0x0004   GPSLongitude                         rational64u[3]
+  0x0005   GPSAltitudeRef                       int8u
+  0x0006   GPSAltitude                          rational64u
+  0x0007   GPSTimeStamp                         rational64u[3]
+  0x0008   GPSSatellites                        string
+  0x0009   GPSStatus                            string[2]
+  0x000a   GPSMeasureMode                       string[2]
+  0x000b   GPSDOP                               rational64u
+  0x000c   GPSSpeedRef                          string[2]
+  0x000d   GPSSpeed                             rational64u
+  0x000e   GPSTrackRef                          string[2]
+  0x000f   GPSTrack                             rational64u
+  0x0010   GPSImgDirectionRef                   string[2]
+  0x0011   GPSImgDirection                      rational64u
+  0x0012   GPSMapDatum                          string
+  0x0013   GPSDestLatitudeRef                   string[2]
+  0x0014   GPSDestLatitude                      rational64u[3]
+  0x0015   GPSDestLongitudeRef                  string[2]
+  0x0016   GPSDestLongitude                     rational64u[3]
+  0x0017   GPSDestBearingRef                    string[2]
+  0x0018   GPSDestBearing                       rational64u
+  0x0019   GPSDestDistanceRef                   string[2]
+  0x001a   GPSDestDistance                      rational64u
+  0x001b   GPSProcessingMethod                  undef
+  0x001c   GPSAreaInformation                   undef
+  0x001d   GPSDateStamp                         string[11]
+  0x001e   GPSDifferential                      int16u
+  0x001f   GPSHPositioningError                 rational64u
+
+=head2 GeoTiff Tags
+
+ExifTool extracts the following tags from GeoTIFF images.  See
+L<http://www.remotesensing.org/geotiff/spec/geotiffhome.html> for the
+complete GeoTIFF specification.  Also included in the table below are
+ChartTIFF tags (see L<http://www.charttiff.com/whitepapers.shtml>). GeoTIFF
+tags are not writable individually, but they may be copied en mass via the
+block tags GeoTiffDirectory, GeoTiffDoubleParams and GeoTiffAsciiParams.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   GeoTiffVersion                       no
+  0x0400   GTModelType                          no
+  0x0401   GTRasterType                         no
+  0x0402   GTCitation                           no
+  0x0800   GeographicType                       no
+  0x0801   GeogCitation                         no
+  0x0802   GeogGeodeticDatum                    no
+  0x0803   GeogPrimeMeridian                    no
+  0x0804   GeogLinearUnits                      no
+  0x0805   GeogLinearUnitSize                   no
+  0x0806   GeogAngularUnits                     no
+  0x0807   GeogAngularUnitSize                  no
+  0x0808   GeogEllipsoid                        no
+  0x0809   GeogSemiMajorAxis                    no
+  0x080a   GeogSemiMinorAxis                    no
+  0x080b   GeogInvFlattening                    no
+  0x080c   GeogAzimuthUnits                     no
+  0x080d   GeogPrimeMeridianLong                no
+  0x080e   GeogToWGS84                          no
+  0x0c00   ProjectedCSType                      no
+  0x0c01   PCSCitation                          no
+  0x0c02   Projection                           no
+  0x0c03   ProjCoordTrans                       no
+  0x0c04   ProjLinearUnits                      no
+  0x0c05   ProjLinearUnitSize                   no
+  0x0c06   ProjStdParallel1                     no
+  0x0c07   ProjStdParallel2                     no
+  0x0c08   ProjNatOriginLong                    no
+  0x0c09   ProjNatOriginLat                     no
+  0x0c0a   ProjFalseEasting                     no
+  0x0c0b   ProjFalseNorthing                    no
+  0x0c0c   ProjFalseOriginLong                  no
+  0x0c0d   ProjFalseOriginLat                   no
+  0x0c0e   ProjFalseOriginEasting               no
+  0x0c0f   ProjFalseOriginNorthing              no
+  0x0c10   ProjCenterLong                       no
+  0x0c11   ProjCenterLat                        no
+  0x0c12   ProjCenterEasting                    no
+  0x0c13   ProjCenterNorthing                   no
+  0x0c14   ProjScaleAtNatOrigin                 no
+  0x0c15   ProjScaleAtCenter                    no
+  0x0c16   ProjAzimuthAngle                     no
+  0x0c17   ProjStraightVertPoleLong             no
+  0x0c18   ProjRectifiedGridAngle               no
+  0x1000   VerticalCSType                       no
+  0x1001   VerticalCitation                     no
+  0x1002   VerticalDatum                        no
+  0x1003   VerticalUnits                        no
+  0xb799   ChartFormat                          no
+  0xb79a   ChartSource                          no
+  0xb79b   ChartSourceEdition                   no
+  0xb79c   ChartSourceDate                      no
+  0xb79d   ChartCorrDate                        no
+  0xb79e   ChartCountryOrigin                   no
+  0xb79f   ChartRasterEdition                   no
+  0xb7a0   ChartSoundingDatum                   no
+  0xb7a1   ChartDepthUnits                      no
+  0xb7a2   ChartMagVar                          no
+  0xb7a3   ChartMagVarYear                      no
+  0xb7a4   ChartMagVarAnnChange                 no
+  0xb7a5   ChartWGSNSShift                      no
+  0xb7a7   InsetNWPixelX                        no
+  0xb7a8   InsetNWPixelY                        no
+  0xb7a9   ChartContourInterval                 no
+
+=head2 PLUS Tags
+
+=head3 PLUS XMP Tags
+
+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.
+
+These tags belong to the ExifTool XMP-plus family 1 group.
 
   Tag Name                                      Writable
@@ -2108,904 +5514,4 @@
   LicensorURL                                   string
 
-=head3 XMP prism Tags
-
-Publishing Requirements for Industry Standard Metadata 2.1 schema tags. (see
-L<http://www.prismstandard.org/>)
-
-  Tag Name                                      Writable
-  --------                                      --------
-  AggregationType                               string/+
-  AlternateTitle                                string/+
-  ByteCount                                     integer/
-  Channel                                       string/+
-  ComplianceProfile                             string/
-  Copyright                                     string/
-  CorporateEntity                               string/+
-  CoverDate                                     date/
-  CoverDisplayDate                              string/
-  CreationDate                                  date/
-  DateRecieved                                  date/
-  Distributor                                   string/
-  DOI                                           string/
-  Edition                                       string/
-  EIssn                                         string/
-  EmbargoDate                                   date/+
-  EndingPage                                    string/
-  Event                                         string/+
-  ExpirationDate                                date/+
-  Genre                                         string/+
-  HasAlternative                                string/+
-  HasCorrection                                 string/
-  HasPreviousVersion                            string/
-  HasTranslation                                string/+
-  Industry                                      string/+
-  ISBN                                          string/
-  IsCorrectionOf                                string/+
-  ISSN                                          string/
-  IssueIdentifier                               string/
-  IssueName                                     string/
-  IsTranslationOf                               string/
-  Keyword                                       string/+
-  KillDate                                      date/
-  Location                                      string/+
-  ModificationDate                              date/
-  Number                                        string/
-  Object                                        string/+
-  Organization                                  string/+
-  OriginPlatform                                string/+
-  PageRange                                     string/+
-  Person                                        string/
-  PublicationDate                               date/+
-  PublicationName                               string/
-  RightsAgent                                   string/
-  Section                                       string/
-  StartingPage                                  string/
-  Subsection1                                   string/
-  Subsection2                                   string/
-  Subsection3                                   string/
-  Subsection4                                   string/
-  Teaser                                        string/+
-  Ticker                                        string/+
-  TimePeriod                                    string/
-  URL                                           string/+
-  VersionIdentifier                             string/
-  Volume                                        string/
-  WordCount                                     integer/
-
-=head3 XMP prl Tags
-
-PRISM Rights Language 2.1 schema tags.  (see
-L<http://www.prismstandard.org/>)
-
-  Tag Name                                      Writable
-  --------                                      --------
-  Geography                                     string/+
-  Industry                                      string/+
-  Usage                                         string/+
-
-=head3 XMP pur Tags
-
-Prism Usage Rights 2.1 schema tags.  (see L<http://www.prismstandard.org/>)
-
-  Tag Name                                      Writable
-  --------                                      --------
-  AdultContentWarning                           string/+
-  Agreement                                     string/+
-  Copyright                                     lang-alt/
-  CreditLine                                    string/+
-  EmbargoDate                                   date/+
-  ExclusivityEndDate                            date/+
-  ExpirationDate                                date/+
-  ImageSizeRestriction                          string/
-  OptionEndDate                                 date/+
-  Permissions                                   string/+
-  Restrictions                                  string/+
-  ReuseProhibited                               boolean/
-  RightsAgent                                   string/
-  RightsOwner                                   string/
-  UsageFee                                      string/+
-
-=head3 XMP rdf Tags
-
-Most RDF attributes are handled internally, but the "about" attribute is
-treated specially to allow it to be set to a specific value if required.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  About                                         string!
-
-=head3 XMP swf Tags
-
-Adobe SWF schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  BackgroundAlpha                               integer
-  ForwardLock                                   boolean
-  MaxStorage                                    integer
-  Type                                          string/
-
-=head3 XMP tiff Tags
-
-EXIF schema for TIFF tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  Artist                                        string
-  BitsPerSample                                 integer+
-  Compression                                   integer
-  Copyright                                     lang-alt
-  DateTime                                      date
-  ImageDescription                              lang-alt
-  ImageHeight                                   integer
-  ImageWidth                                    integer
-  Make                                          string
-  Model                                         string
-  NativeDigest                                  string
-  Orientation                                   integer
-  PhotometricInterpretation                     integer
-  PlanarConfiguration                           integer
-  PrimaryChromaticities                         rational+
-  ReferenceBlackWhite                           rational+
-  ResolutionUnit                                integer
-  SamplesPerPixel                               integer
-  Software                                      string
-  TransferFunction                              integer+
-  WhitePoint                                    rational+
-  XResolution                                   rational
-  YCbCrCoefficients                             rational+
-  YCbCrPositioning                              integer
-  YCbCrSubSampling                              string
-  YResolution                                   rational
-
-=head3 XMP x Tags
-
-The "x" namespace is used for the "xmpmeta" wrapper, and may contain an
-"xmptk" attribute that is extracted as the XMPToolkit tag.  When writing,
-the XMPToolkit tag is automatically generated by ExifTool unless
-specifically set to another value.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  XMPToolkit                                    string!
-
-=head3 XMP xmp Tags
-
-XMP Basic schema tags.  If the older "xap", "xapBJ", "xapMM" or "xapRights"
-namespace prefixes are found, they are translated to the newer "xmp",
-"xmpBJ", "xmpMM" and "xmpRights" prefixes for use in family 1 group names.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  Advisory                                      string+
-  BaseURL                                       string
-  CreateDate                                    date
-  CreatorTool                                   string
-  Identifier                                    string/+
-  Label                                         string
-  MetadataDate                                  date
-  ModifyDate                                    date
-  Nickname                                      string
-  PageInfo                                      PageInfo Struct+
-  PageImageFormat                               string_+
-  PageImageHeight                               integer_+
-  PageImage                                     string_+
-  PageImagePageNumber                           integer_+
-  PageImageWidth                                integer_+
-  Rating                                        real
-  Thumbnails                                    Thumbnail Struct+
-  ThumbnailFormat                               string_+
-  ThumbnailHeight                               integer_+
-  ThumbnailImage                                string/_+
-  ThumbnailWidth                                integer_+
-
-=head3 XMP PageInfo Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  PageNumber                                    integer
-  Format                                        string
-  Height                                        integer
-  Image                                         string
-  Width                                         integer
-
-=head3 XMP Thumbnail Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Format                                        string
-  Height                                        integer
-  Image                                         string
-  Width                                         integer
-
-=head3 XMP xmpBJ Tags
-
-XMP Basic Job Ticket schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  JobRef                                        JobRef Struct+
-  JobRefId                                      string_+
-  JobRefName                                    string_+
-  JobRefUrl                                     string_+
-
-=head3 XMP JobRef Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Id                                            string
-  Name                                          string
-  Url                                           string
-
-=head3 XMP xmpDM Tags
-
-XMP Dynamic Media schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  AbsPeakAudioFilePath                          string
-  Album                                         string
-  AltTapeName                                   string
-  AltTimecode                                   Timecode Struct
-  AltTimecodeTimeFormat                         string_
-  AltTimecodeTimeValue                          string_
-  AltTimecodeValue                              integer_
-  Artist                                        string/
-  AudioChannelType                              string
-  AudioCompressor                               string
-  AudioModDate                                  date
-  AudioSampleRate                               integer
-  AudioSampleType                               string
-  BeatSpliceParams                              BeatSpliceStretch Struct
-  BeatSpliceParamsRiseInDecibel                 real_
-  BeatSpliceParamsRiseInTimeDuration            Time Struct_
-  BeatSpliceParamsRiseInTimeDurationScale       rational_
-  BeatSpliceParamsRiseInTimeDurationValue       integer_
-  BeatSpliceParamsUseFileBeatsMarker            boolean_
-  CameraAngle                                   string
-  CameraLabel                                   string
-  CameraModel                                   string
-  CameraMove                                    string
-  Client                                        string
-  DMComment                                     string
-  Composer                                      string
-  ContributedMedia                              Media Struct+
-  ContributedMediaDuration                      Time Struct_+
-  ContributedMediaDurationScale                 rational_+
-  ContributedMediaDurationValue                 integer_+
-  ContributedMediaManaged                       boolean_+
-  ContributedMediaPath                          string_+
-  ContributedMediaStartTime                     Time Struct_+
-  ContributedMediaStartTimeScale                rational_+
-  ContributedMediaStartTimeValue                integer_+
-  ContributedMediaTrack                         string_+
-  ContributedMediaWebStatement                  string_+
-  Copyright                                     string/
-  Director                                      string
-  DirectorPhotography                           string
-  Duration                                      Time Struct
-  DurationScale                                 rational_
-  DurationValue                                 integer_
-  Engineer                                      string
-  FileDataRate                                  rational
-  Genre                                         string
-  Good                                          boolean
-  Instrument                                    string
-  IntroTime                                     Time Struct
-  IntroTimeScale                                rational_
-  IntroTimeValue                                integer_
-  Key                                           string
-  LogComment                                    string
-  Loop                                          boolean
-  Markers                                       Marker Struct+
-  MarkersComment                                string_+
-  MarkersCuePointParams                         CuePointParam Struct_+
-  MarkersCuePointParamsKey                      string_+
-  MarkersCuePointParamsValue                    string_+
-  MarkersCuePointType                           string_+
-  MarkersDuration                               string_+
-  MarkersLocation                               string_+
-  MarkersName                                   string_+
-  MarkersProbability                            real_+
-  MarkersSpeaker                                string_+
-  MarkersStartTime                              string_+
-  MarkersTarget                                 string_+
-  MarkersType                                   string_+
-  MetadataModDate                               date
-  NumberOfBeats                                 real
-  OutCue                                        Time Struct
-  OutCueScale                                   rational_
-  OutCueValue                                   integer_
-  ProjectName                                   string
-  ProjectRef                                    ProjectLink Struct
-  ProjectRefPath                                string_
-  ProjectRefType                                string_
-  PullDown                                      string
-  RelativePeakAudioFilePath                     string
-  RelativeTimestamp                             Time Struct
-  RelativeTimestampScale                        rational_
-  RelativeTimestampValue                        integer_
-  ReleaseDate                                   date
-  ResampleParams                                ResampleStretch Struct
-  ResampleParamsQuality                         string_
-  ScaleType                                     string
-  Scene                                         string/
-  ShotDate                                      date
-  ShotDay                                       string
-  ShotLocation                                  string
-  ShotName                                      string
-  ShotNumber                                    string
-  ShotSize                                      string
-  SpeakerPlacement                              string
-  StartTimecode                                 Timecode Struct
-  StartTimecodeTimeFormat                       string_
-  StartTimecodeTimeValue                        string_
-  StartTimecodeValue                            integer_
-  StretchMode                                   string
-  TakeNumber                                    integer
-  TapeName                                      string
-  Tempo                                         real
-  TimeScaleParams                               TimeScaleStretch Struct
-  TimeScaleParamsFrameOverlappingPercentage     real_
-  TimeScaleParamsFrameSize                      real_
-  TimeScaleParamsQuality                        string_
-  TimeSignature                                 string
-  TrackNumber                                   integer
-  Tracks                                        Track Struct+
-  TracksFrameRate                               string_+
-  TracksMarkers                                 Marker Struct_+
-  TracksMarkersComment                          string_+
-  TracksMarkersCuePointParams                   CuePointParam Struct_+
-  TracksMarkersCuePointParamsKey                string_+
-  TracksMarkersCuePointParamsValue              string_+
-  TracksMarkersCuePointType                     string_+
-  TracksMarkersDuration                         string_+
-  TracksMarkersLocation                         string_+
-  TracksMarkersName                             string_+
-  TracksMarkersProbability                      real_+
-  TracksMarkersSpeaker                          string_+
-  TracksMarkersStartTime                        string_+
-  TracksMarkersTarget                           string_+
-  TracksMarkersType                             string_+
-  TracksTrackName                               string_+
-  TracksTrackType                               string_+
-  VideoAlphaMode                                string
-  VideoAlphaPremultipleColor                    Colorant Struct
-  VideoAlphaPremultipleColorA                   integer_
-  VideoAlphaPremultipleColorB                   integer_
-  VideoAlphaPremultipleColorBlack               real_
-  VideoAlphaPremultipleColorBlue                integer_
-  VideoAlphaPremultipleColorCyan                real_
-  VideoAlphaPremultipleColorGreen               integer_
-  VideoAlphaPremultipleColorL                   real_
-  VideoAlphaPremultipleColorMagenta             real_
-  VideoAlphaPremultipleColorMode                string_
-  VideoAlphaPremultipleColorRed                 integer_
-  VideoAlphaPremultipleColorSwatchName          string_
-  VideoAlphaPremultipleColorType                string_
-  VideoAlphaPremultipleColorYellow              real_
-  VideoAlphaUnityIsTransparent                  boolean
-  VideoColorSpace                               string
-  VideoCompressor                               string
-  VideoFieldOrder                               string
-  VideoFrameRate                                string
-  VideoFrameSize                                Dimensions Struct
-  VideoFrameSizeH                               real_
-  VideoFrameSizeUnit                            string_
-  VideoFrameSizeW                               real_
-  VideoModDate                                  date
-  VideoPixelAspectRatio                         rational
-  VideoPixelDepth                               string
-
-=head3 XMP Timecode Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  TimeFormat                                    string
-  TimeValue                                     string
-  Value                                         integer
-
-=head3 XMP BeatSpliceStretch Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  RiseInDecibel                                 real
-  RiseInTimeDuration                            Time Struct
-  UseFileBeatsMarker                            boolean
-
-=head3 XMP Time Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Scale                                         rational
-  Value                                         integer
-
-=head3 XMP Media Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Duration                                      Time Struct
-  Managed                                       boolean
-  Path                                          string
-  StartTime                                     Time Struct
-  Track                                         string
-  WebStatement                                  string
-
-=head3 XMP Marker Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Comment                                       string
-  CuePointParams                                CuePointParam Struct+
-  CuePointType                                  string
-  Duration                                      string
-  Location                                      string
-  Name                                          string
-  Probability                                   real
-  Speaker                                       string
-  StartTime                                     string
-  Target                                        string
-  Type                                          string
-
-=head3 XMP CuePointParam Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Key                                           string
-  Value                                         string
-
-=head3 XMP ProjectLink Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Path                                          string
-  Type                                          string
-
-=head3 XMP ResampleStretch Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Quality                                       string
-
-=head3 XMP TimeScaleStretch Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  FrameOverlappingPercentage                    real
-  FrameSize                                     real
-  Quality                                       string
-
-=head3 XMP Track Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  FrameRate                                     string
-  Markers                                       Marker Struct+
-  TrackName                                     string
-  TrackType                                     string
-
-=head3 XMP Colorant Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  A                                             integer
-  B                                             integer
-  L                                             real
-  Black                                         real
-  Blue                                          integer
-  Cyan                                          real
-  Green                                         integer
-  Magenta                                       real
-  Mode                                          string
-  Red                                           integer
-  SwatchName                                    string
-  Type                                          string
-  Yellow                                        real
-
-=head3 XMP xmpMM Tags
-
-XMP Media Management schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  DerivedFrom                                   ResourceRef Struct
-  DerivedFromAlternatePaths                     string_+
-  DerivedFromDocumentID                         string_
-  DerivedFromFilePath                           string_
-  DerivedFromFromPart                           string_
-  DerivedFromInstanceID                         string_
-  DerivedFromLastModifyDate                     date_
-  DerivedFromManager                            string_
-  DerivedFromManagerVariant                     string_
-  DerivedFromManageTo                           string_
-  DerivedFromManageUI                           string_
-  DerivedFromMaskMarkers                        string_
-  DerivedFromOriginalDocumentID                 string_
-  DerivedFromPartMapping                        string_
-  DerivedFromRenditionClass                     string_
-  DerivedFromRenditionParams                    string_
-  DerivedFromToPart                             string_
-  DerivedFromVersionID                          string_
-  DocumentID                                    string
-  History                                       ResourceEvent Struct+
-  HistoryAction                                 string_+
-  HistoryChanged                                string_+
-  HistoryInstanceID                             string_+
-  HistoryParameters                             string_+
-  HistorySoftwareAgent                          string_+
-  HistoryWhen                                   date_+
-  Ingredients                                   ResourceRef Struct+
-  IngredientsAlternatePaths                     string_+
-  IngredientsDocumentID                         string_+
-  IngredientsFilePath                           string_+
-  IngredientsFromPart                           string_+
-  IngredientsInstanceID                         string_+
-  IngredientsLastModifyDate                     date_+
-  IngredientsManager                            string_+
-  IngredientsManagerVariant                     string_+
-  IngredientsManageTo                           string_+
-  IngredientsManageUI                           string_+
-  IngredientsMaskMarkers                        string_+
-  IngredientsOriginalDocumentID                 string_+
-  IngredientsPartMapping                        string_+
-  IngredientsRenditionClass                     string_+
-  IngredientsRenditionParams                    string_+
-  IngredientsToPart                             string_+
-  IngredientsVersionID                          string_+
-  InstanceID                                    string
-  LastURL                                       string
-  ManagedFrom                                   ResourceRef Struct
-  ManagedFromAlternatePaths                     string_+
-  ManagedFromDocumentID                         string_
-  ManagedFromFilePath                           string_
-  ManagedFromFromPart                           string_
-  ManagedFromInstanceID                         string_
-  ManagedFromLastModifyDate                     date_
-  ManagedFromManager                            string_
-  ManagedFromManagerVariant                     string_
-  ManagedFromManageTo                           string_
-  ManagedFromManageUI                           string_
-  ManagedFromMaskMarkers                        string_
-  ManagedFromOriginalDocumentID                 string_
-  ManagedFromPartMapping                        string_
-  ManagedFromRenditionClass                     string_
-  ManagedFromRenditionParams                    string_
-  ManagedFromToPart                             string_
-  ManagedFromVersionID                          string_
-  Manager                                       string
-  ManagerVariant                                string
-  ManageTo                                      string
-  ManageUI                                      string
-  Manifest                                      ManifestItem Struct+
-  ManifestLinkForm                              string_+
-  ManifestPlacedResolutionUnit                  string_+
-  ManifestPlacedXResolution                     real_+
-  ManifestPlacedYResolution                     real_+
-  ManifestReference                             ResourceRef Struct_+
-  ManifestReferenceAlternatePaths               string_+
-  ManifestReferenceDocumentID                   string_+
-  ManifestReferenceFilePath                     string_+
-  ManifestReferenceFromPart                     string_+
-  ManifestReferenceInstanceID                   string_+
-  ManifestReferenceLastModifyDate               date_+
-  ManifestReferenceManager                      string_+
-  ManifestReferenceManagerVariant               string_+
-  ManifestReferenceManageTo                     string_+
-  ManifestReferenceManageUI                     string_+
-  ManifestReferenceMaskMarkers                  string_+
-  ManifestReferenceOriginalDocumentID           string_+
-  ManifestReferencePartMapping                  string_+
-  ManifestReferenceRenditionClass               string_+
-  ManifestReferenceRenditionParams              string_+
-  ManifestReferenceToPart                       string_+
-  ManifestReferenceVersionID                    string_+
-  OriginalDocumentID                            string
-  Pantry                                        PantryItem Struct+
-  PreservedFileName                             string
-  RenditionClass                                string
-  RenditionOf                                   ResourceRef Struct
-  RenditionOfAlternatePaths                     string_+
-  RenditionOfDocumentID                         string_
-  RenditionOfFilePath                           string_
-  RenditionOfFromPart                           string_
-  RenditionOfInstanceID                         string_
-  RenditionOfLastModifyDate                     date_
-  RenditionOfManager                            string_
-  RenditionOfManagerVariant                     string_
-  RenditionOfManageTo                           string_
-  RenditionOfManageUI                           string_
-  RenditionOfMaskMarkers                        string_
-  RenditionOfOriginalDocumentID                 string_
-  RenditionOfPartMapping                        string_
-  RenditionOfRenditionClass                     string_
-  RenditionOfRenditionParams                    string_
-  RenditionOfToPart                             string_
-  RenditionOfVersionID                          string_
-  RenditionParams                               string
-  SaveID                                        integer
-  VersionID                                     string
-  Versions                                      Version Struct+
-  VersionsComments                              string_+
-  VersionsEvent                                 ResourceEvent Struct_+
-  VersionsEventAction                           string_+
-  VersionsEventChanged                          string_+
-  VersionsEventInstanceID                       string_+
-  VersionsEventParameters                       string_+
-  VersionsEventSoftwareAgent                    string_+
-  VersionsEventWhen                             date_+
-  VersionsModifier                              string_+
-  VersionsModifyDate                            date_+
-  VersionsVersion                               string_+
-
-=head3 XMP ResourceRef Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  AlternatePaths                                string+
-  DocumentID                                    string
-  FilePath                                      string
-  FromPart                                      string
-  InstanceID                                    string
-  LastModifyDate                                date
-  ManageTo                                      string
-  ManageUI                                      string
-  Manager                                       string
-  ManagerVariant                                string
-  MaskMarkers                                   string
-  OriginalDocumentID                            string
-  PartMapping                                   string
-  RenditionClass                                string
-  RenditionParams                               string
-  ToPart                                        string
-  VersionID                                     string
-
-=head3 XMP ResourceEvent Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Action                                        string
-  Changed                                       string
-  InstanceID                                    string
-  Parameters                                    string
-  SoftwareAgent                                 string
-  When                                          date
-
-=head3 XMP ManifestItem Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  LinkForm                                      string
-  PlacedResolutionUnit                          string
-  PlacedXResolution                             real
-  PlacedYResolution                             real
-  Reference                                     ResourceRef Struct
-
-=head3 XMP PantryItem Struct
-
-This structure must have an InstanceID field, but may also contain any other
-XMP properties.
-
-  Field Name                                    Writable
-  ----------                                    --------
-  InstanceID                                    string
-
-=head3 XMP Version Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  Comments                                      string
-  Event                                         ResourceEvent Struct
-  Modifier                                      string
-  ModifyDate                                    date
-  Version                                       string
-
-=head3 XMP xmpNote Tags
-
-XMP Note schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  HasExtendedXMP                                boolean*
-
-=head3 XMP xmpPLUS Tags
-
-XMP Picture Licensing Universal System (PLUS) schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  CreditLineReq                                 boolean
-  ReuseAllowed                                  boolean
-
-=head3 XMP xmpRights Tags
-
-XMP Rights Management schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  Certificate                                   string
-  Marked                                        boolean
-  Owner                                         string+
-  UsageTerms                                    lang-alt
-  WebStatement                                  string
-
-=head3 XMP xmpTPg Tags
-
-XMP Paged-Text schema tags.
-
-  Tag Name                                      Writable
-  --------                                      --------
-  Colorants                                     Colorant Struct+
-  ColorantA                                     integer_+
-  ColorantB                                     integer_+
-  ColorantBlack                                 real_+
-  ColorantBlue                                  integer_+
-  ColorantCyan                                  real_+
-  ColorantGreen                                 integer_+
-  ColorantL                                     real_+
-  ColorantMagenta                               real_+
-  ColorantMode                                  string_+
-  ColorantRed                                   integer_+
-  ColorantSwatchName                            string_+
-  ColorantType                                  string_+
-  ColorantYellow                                real_+
-  Fonts                                         Font Struct+
-  ChildFontFiles                                string_+
-  FontComposite                                 boolean_+
-  FontFace                                      string_+
-  FontFamily                                    string_+
-  FontFileName                                  string_+
-  FontName                                      string_+
-  FontType                                      string_+
-  FontVersion                                   string_+
-  MaxPageSize                                   Dimensions Struct
-  MaxPageSizeH                                  real_
-  MaxPageSizeUnit                               string_
-  MaxPageSizeW                                  real_
-  NPages                                        integer
-  PlateNames                                    string+
-
-=head3 XMP Font Struct
-
-  Field Name                                    Writable
-  ----------                                    --------
-  ChildFontFiles                                string+
-  Composite                                     boolean
-  FontFace                                      string
-  FontFamily                                    string
-  FontFileName                                  string
-  FontName                                      string
-  FontType                                      string
-  VersionString                                 string
-
-=head3 XMP SVG Tags
-
-SVG (Scalable Vector Graphics) image tags.  By default, only the top-level
-SVG and Metadata tags are extracted from these images, but all graphics tags
-may be extracted by setting the Unknown option to 2 (-U on the command
-line).  The SVG tags are not part of XMP as such, but are included with the
-XMP module for convenience.  (see L<http://www.w3.org/TR/SVG11/>)
-
-  Tag ID               Tag Name                 Writable
-  ------               --------                 --------
-  'height'             ImageHeight              N
-  'id'                 ID                       N
-  'metadataId'         MetadataID               N
-  'version'            SVGVersion               N
-  'width'              ImageWidth               N
-
-=head2 GPS Tags
-
-These GPS tags are part of the EXIF standard, and are stored in a separate
-IFD within the EXIF information.
-
-ExifTool is very flexible about the input format when writing lat/long
-coordinates, and will accept from 1 to 3 floating point numbers (for decimal
-degrees, degrees and minutes, or degrees, minutes and seconds) separated by
-just about anything, and will format them properly according to the EXIF
-specification.
-
-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 (ie. 'Above Sea Level', not '0') unless the print conversion is
-disabled (with '-n' on the command line or the PrintConv 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
-following tags: GPSLatitude, GPSLatitudeRef, GPSLongitude, GPSLongitudeRef,
-GPSAltitude and GPSAltitudeRef.  ExifTool will write the required
-GPSVersionID tag automatically if new a GPS IFD is added to an image.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  0x0000   GPSVersionID                         int8u[4]:
-  0x0001   GPSLatitudeRef                       string[2]
-  0x0002   GPSLatitude                          rational64u[3]
-  0x0003   GPSLongitudeRef                      string[2]
-  0x0004   GPSLongitude                         rational64u[3]
-  0x0005   GPSAltitudeRef                       int8u
-  0x0006   GPSAltitude                          rational64u
-  0x0007   GPSTimeStamp                         rational64u[3]
-  0x0008   GPSSatellites                        string
-  0x0009   GPSStatus                            string[2]
-  0x000a   GPSMeasureMode                       string[2]
-  0x000b   GPSDOP                               rational64u
-  0x000c   GPSSpeedRef                          string[2]
-  0x000d   GPSSpeed                             rational64u
-  0x000e   GPSTrackRef                          string[2]
-  0x000f   GPSTrack                             rational64u
-  0x0010   GPSImgDirectionRef                   string[2]
-  0x0011   GPSImgDirection                      rational64u
-  0x0012   GPSMapDatum                          string
-  0x0013   GPSDestLatitudeRef                   string[2]
-  0x0014   GPSDestLatitude                      rational64u[3]
-  0x0015   GPSDestLongitudeRef                  string[2]
-  0x0016   GPSDestLongitude                     rational64u[3]
-  0x0017   GPSDestBearingRef                    string[2]
-  0x0018   GPSDestBearing                       rational64u
-  0x0019   GPSDestDistanceRef                   string[2]
-  0x001a   GPSDestDistance                      rational64u
-  0x001b   GPSProcessingMethod                  undef
-  0x001c   GPSAreaInformation                   undef
-  0x001d   GPSDateStamp                         string[11]
-  0x001e   GPSDifferential                      int16u
-  0x001f   GPSHPositioningError                 rational64u
-
-=head2 GeoTiff Tags
-
-ExifTool extracts the following tags from GeoTIFF images.  See
-L<http://www.remotesensing.org/geotiff/spec/geotiffhome.html> for the
-complete GeoTIFF specification.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  0x0001   GeoTiffVersion                       N
-  0x0400   GTModelType                          N
-  0x0401   GTRasterType                         N
-  0x0402   GTCitation                           N
-  0x0800   GeographicType                       N
-  0x0801   GeogCitation                         N
-  0x0802   GeogGeodeticDatum                    N
-  0x0803   GeogPrimeMeridian                    N
-  0x0804   GeogLinearUnits                      N
-  0x0805   GeogLinearUnitSize                   N
-  0x0806   GeogAngularUnits                     N
-  0x0807   GeogAngularUnitSize                  N
-  0x0808   GeogEllipsoid                        N
-  0x0809   GeogSemiMajorAxis                    N
-  0x080a   GeogSemiMinorAxis                    N
-  0x080b   GeogInvFlattening                    N
-  0x080c   GeogAzimuthUnits                     N
-  0x080d   GeogPrimeMeridianLong                N
-  0x0c00   ProjectedCSType                      N
-  0x0c01   PCSCitation                          N
-  0x0c02   Projection                           N
-  0x0c03   ProjCoordTrans                       N
-  0x0c04   ProjLinearUnits                      N
-  0x0c05   ProjLinearUnitSize                   N
-  0x0c06   ProjStdParallel1                     N
-  0x0c07   ProjStdParallel2                     N
-  0x0c08   ProjNatOriginLong                    N
-  0x0c09   ProjNatOriginLat                     N
-  0x0c0a   ProjFalseEasting                     N
-  0x0c0b   ProjFalseNorthing                    N
-  0x0c0c   ProjFalseOriginLong                  N
-  0x0c0d   ProjFalseOriginLat                   N
-  0x0c0e   ProjFalseOriginEasting               N
-  0x0c0f   ProjFalseOriginNorthing              N
-  0x0c10   ProjCenterLong                       N
-  0x0c11   ProjCenterLat                        N
-  0x0c12   ProjCenterEasting                    N
-  0x0c13   ProjCenterNorthing                   N
-  0x0c14   ProjScaleAtNatOrigin                 N
-  0x0c15   ProjScaleAtCenter                    N
-  0x0c16   ProjAzimuthAngle                     N
-  0x0c17   ProjStraightVertPoleLong             N
-  0x0c18   ProjRectifiedGridAngle               N
-  0x1000   VerticalCSType                       N
-  0x1001   VerticalCitation                     N
-  0x1002   VerticalDatum                        N
-  0x1003   VerticalUnits                        N
-
 =head2 ICC_Profile Tags
 
@@ -3020,132 +5526,133 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'A2B0'   AToB0                                N
-  'A2B1'   AToB1                                N
-  'A2B2'   AToB2                                N
-  'B2A0'   BToA0                                N
-  'B2A1'   BToA1                                N
-  'B2A2'   BToA2                                N
-  'B2D0'   BToD0                                N
-  'B2D1'   BToD1                                N
-  'B2D2'   BToD2                                N
-  'B2D3'   BToD3                                N
-  'D2B0'   DToB0                                N
-  'D2B1'   DToB1                                N
-  'D2B2'   DToB2                                N
-  'D2B3'   DToB3                                N
+  'A2B0'   AToB0                                no
+  'A2B1'   AToB1                                no
+  'A2B2'   AToB2                                no
+  'B2A0'   BToA0                                no
+  'B2A1'   BToA1                                no
+  'B2A2'   BToA2                                no
+  'B2D0'   BToD0                                no
+  'B2D1'   BToD1                                no
+  'B2D2'   BToD2                                no
+  'B2D3'   BToD3                                no
+  'D2B0'   DToB0                                no
+  'D2B1'   DToB1                                no
+  'D2B2'   DToB2                                no
+  'D2B3'   DToB3                                no
   'Header' ProfileHeader                        ICC_Profile Header
-  'MS00'   WCSProfiles                          N
-  'bTRC'   BlueTRC                              N
-  'bXYZ'   BlueMatrixColumn                     N
-  'bfd '   UCRBG                                N
-  'bkpt'   MediaBlackPoint                      N
-  'calt'   CalibrationDateTime                  N
-  'chad'   ChromaticAdaptation                  N
+  'MS00'   WCSProfiles                          no
+  'bTRC'   BlueTRC                              no
+  'bXYZ'   BlueMatrixColumn                     no
+  'bfd '   UCRBG                                no
+  'bkpt'   MediaBlackPoint                      no
+  'calt'   CalibrationDateTime                  no
+  'chad'   ChromaticAdaptation                  no
   'chrm'   Chromaticity                         ICC_Profile Chromaticity
-  'ciis'   ColorimetricIntentImageState         N
-  'clot'   ColorantTableOut                     N
-  'clro'   ColorantOrder                        N
+  'ciis'   ColorimetricIntentImageState         no
+  'clot'   ColorantTableOut                     no
+  'clro'   ColorantOrder                        no
   'clrt'   ColorantTable                        ICC_Profile ColorantTable
-  'cprt'   ProfileCopyright                     N
-  'crdi'   CRDInfo                              N
-  'desc'   ProfileDescription                   N
-  'devs'   DeviceSettings                       N
-  'dmdd'   DeviceModelDesc                      N
-  'dmnd'   DeviceMfgDesc                        N
-  'dscm'   ProfileDescriptionML                 N
-  'fpce'   FocalPlaneColorimetryEstimates       N
-  'gTRC'   GreenTRC                             N
-  'gXYZ'   GreenMatrixColumn                    N
-  'gamt'   Gamut                                N
-  'kTRC'   GrayTRC                              N
-  'lumi'   Luminance                            N
+  'cprt'   ProfileCopyright                     no
+  'crdi'   CRDInfo                              no
+  'desc'   ProfileDescription                   no
+  'devs'   DeviceSettings                       no
+  'dmdd'   DeviceModelDesc                      no
+  'dmnd'   DeviceMfgDesc                        no
+  'dscm'   ProfileDescriptionML                 no
+  'fpce'   FocalPlaneColorimetryEstimates       no
+  'gTRC'   GreenTRC                             no
+  'gXYZ'   GreenMatrixColumn                    no
+  'gamt'   Gamut                                no
+  'kTRC'   GrayTRC                              no
+  'lumi'   Luminance                            no
   'meas'   Measurement                          ICC_Profile Measurement
   'meta'   Metadata                             ICC_Profile Metadata
-  'mmod'   MakeAndModel                         N
-  'ncl2'   NamedColor2                          N
-  'ncol'   NamedColor                           N
-  'ndin'   NativeDisplayInfo                    N
-  'pre0'   Preview0                             N
-  'pre1'   Preview1                             N
-  'pre2'   Preview2                             N
-  'ps2i'   PS2RenderingIntent                   N
-  'ps2s'   PostScript2CSA                       N
-  'psd0'   PostScript2CRD0                      N
-  'psd1'   PostScript2CRD1                      N
-  'psd2'   PostScript2CRD2                      N
-  'pseq'   ProfileSequenceDesc                  N
-  'psid'   ProfileSequenceIdentifier            N
-  'psvm'   PS2CRDVMSize                         N
-  'rTRC'   RedTRC                               N
-  'rXYZ'   RedMatrixColumn                      N
-  'resp'   OutputResponse                       N
-  'rhoc'   ReflectionHardcopyOrigColorimetry    N
-  'rig0'   PerceptualRenderingIntentGamut       N
-  'rig2'   SaturationRenderingIntentGamut       N
-  'rpoc'   ReflectionPrintOutputColorimetry     N
-  'sape'   SceneAppearanceEstimates             N
-  'scoe'   SceneColorimetryEstimates            N
-  'scrd'   ScreeningDesc                        N
-  'scrn'   Screening                            N
-  'targ'   CharTarget                           N
-  'tech'   Technology                           N
-  'vcgt'   VideoCardGamma                       N
+  'mmod'   MakeAndModel                         no
+  'ncl2'   NamedColor2                          no
+  'ncol'   NamedColor                           no
+  'ndin'   NativeDisplayInfo                    no
+  'pre0'   Preview0                             no
+  'pre1'   Preview1                             no
+  'pre2'   Preview2                             no
+  'ps2i'   PS2RenderingIntent                   no
+  'ps2s'   PostScript2CSA                       no
+  'psd0'   PostScript2CRD0                      no
+  'psd1'   PostScript2CRD1                      no
+  'psd2'   PostScript2CRD2                      no
+  'psd3'   PostScript2CRD3                      no
+  'pseq'   ProfileSequenceDesc                  no
+  'psid'   ProfileSequenceIdentifier            no
+  'psvm'   PS2CRDVMSize                         no
+  'rTRC'   RedTRC                               no
+  'rXYZ'   RedMatrixColumn                      no
+  'resp'   OutputResponse                       no
+  'rhoc'   ReflectionHardcopyOrigColorimetry    no
+  'rig0'   PerceptualRenderingIntentGamut       no
+  'rig2'   SaturationRenderingIntentGamut       no
+  'rpoc'   ReflectionPrintOutputColorimetry     no
+  'sape'   SceneAppearanceEstimates             no
+  'scoe'   SceneColorimetryEstimates            no
+  'scrd'   ScreeningDesc                        no
+  'scrn'   Screening                            no
+  'targ'   CharTarget                           no
+  'tech'   Technology                           no
+  'vcgt'   VideoCardGamma                       no
   'view'   ViewingConditions                    ICC_Profile ViewingConditions
-  'vued'   ViewingCondDesc                      N
-  'wtpt'   MediaWhitePoint                      N
+  'vued'   ViewingCondDesc                      no
+  'wtpt'   MediaWhitePoint                      no
 
 =head3 ICC_Profile Header Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      4    ProfileCMMType                       N
-      8    ProfileVersion                       N
-     12    ProfileClass                         N
-     16    ColorSpaceData                       N
-     20    ProfileConnectionSpace               N
-     24    ProfileDateTime                      N
-     36    ProfileFileSignature                 N
-     40    PrimaryPlatform                      N
-     44    CMMFlags                             N
-     48    DeviceManufacturer                   N
-     52    DeviceModel                          N
-     56    DeviceAttributes                     N
-     64    RenderingIntent                      N
-     68    ConnectionSpaceIlluminant            N
-     80    ProfileCreator                       N
-     84    ProfileID                            N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    ProfileCMMType                       no
+      8    ProfileVersion                       no
+     12    ProfileClass                         no
+     16    ColorSpaceData                       no
+     20    ProfileConnectionSpace               no
+     24    ProfileDateTime                      no
+     36    ProfileFileSignature                 no
+     40    PrimaryPlatform                      no
+     44    CMMFlags                             no
+     48    DeviceManufacturer                   no
+     52    DeviceModel                          no
+     56    DeviceAttributes                     no
+     64    RenderingIntent                      no
+     68    ConnectionSpaceIlluminant            no
+     80    ProfileCreator                       no
+     84    ProfileID                            no
 
 =head3 ICC_Profile Chromaticity Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      8    ChromaticityChannels                 N
-     10    ChromaticityColorant                 N
-     12    ChromaticityChannel1                 N
-     20    ChromaticityChannel2                 N
-     28    ChromaticityChannel3                 N
-     36    ChromaticityChannel4                 N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    ChromaticityChannels                 no
+     10    ChromaticityColorant                 no
+     12    ChromaticityChannel1                 no
+     20    ChromaticityChannel2                 no
+     28    ChromaticityChannel3                 no
+     36    ChromaticityChannel4                 no
 
 =head3 ICC_Profile ColorantTable Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      8    ColorantCount                        N
-     12    Colorant1Name                        N
-     44    Colorant1Coordinates                 N
-     50    Colorant2Name                        N
-     82    Colorant2Coordinates                 N
-     88    Colorant3Name                        N
-    120    Colorant3Coordinates                 N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    ColorantCount                        no
+     12    Colorant1Name                        no
+     44    Colorant1Coordinates                 no
+     50    Colorant2Name                        no
+     82    Colorant2Coordinates                 no
+     88    Colorant3Name                        no
+    120    Colorant3Coordinates                 no
 
 =head3 ICC_Profile Measurement Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      8    MeasurementObserver                  N
-     12    MeasurementBacking                   N
-     24    MeasurementGeometry                  N
-     28    MeasurementFlare                     N
-     32    MeasurementIlluminant                N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    MeasurementObserver                  no
+     12    MeasurementBacking                   no
+     24    MeasurementGeometry                  no
+     28    MeasurementFlare                     no
+     32    MeasurementIlluminant                no
 
 =head3 ICC_Profile Metadata Tags
@@ -3156,15 +5663,15 @@
   Tag Name                                      Writable
   --------                                      --------
-  ManufacturerName                              N
-  MediaColor                                    N
-  MediaWeight                                   N
+  ManufacturerName                              no
+  MediaColor                                    no
+  MediaWeight                                   no
 
 =head3 ICC_Profile ViewingConditions Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      8    ViewingCondIlluminant                N
-     20    ViewingCondSurround                  N
-     32    ViewingCondIlluminantType            N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    ViewingCondIlluminant                no
+     20    ViewingCondSurround                  no
+     32    ViewingCondIlluminantType            no
 
 =head2 PrintIM Tags
@@ -3175,5 +5682,5 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'PrintIMVersion'     PrintIMVersion           N
+  'PrintIMVersion'     PrintIMVersion           no
 
 =head2 Photoshop Tags
@@ -3185,80 +5692,107 @@
 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 I<[and because Adobe denied my application for
-their file format documentation -- apparently open source software is too
-big a concept for them]>.  These unknown tags are not extracted unless the
-Unknown (-u) option is used.
+under normal circumstances.  These unknown tags are not extracted unless the
+Unknown (-u) option is used.  See
+L<http://www.adobe.com/devnet-apps/photoshop/fileformatashtml/> for the
+official specification
+
+Photoshop path tags (Tag ID's 0x7d0 to 0xbb5) are not defined by default,
+but a config file included in the full ExifTool distribution
+(config_files/photoshop_paths.config) contains the tag definitions to allow
+access to this information.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x03e8   Photoshop2Info?                      N
-  0x03e9   MacintoshPrintInfo?                  N
-  0x03ea   XMLData?                             N
-  0x03eb   Photoshop2ColorTable?                N
+  0x03e8   Photoshop2Info?                      no
+  0x03e9   MacintoshPrintInfo?                  no
+  0x03ea   XMLData?                             no
+  0x03eb   Photoshop2ColorTable?                no
   0x03ed   ResolutionInfo                       Photoshop Resolution
-  0x03ee   AlphaChannelsNames                   N
-  0x03ef   DisplayInfo?                         N
-  0x03f0   PStringCaption?                      N
-  0x03f1   BorderInformation?                   N
-  0x03f2   BackgroundColor?                     N
-  0x03f3   PrintFlags?                          N
-  0x03f4   BW_HalftoningInfo?                   N
-  0x03f5   ColorHalftoningInfo?                 N
-  0x03f6   DuotoneHalftoningInfo?               N
-  0x03f7   BW_TransferFunc?                     N
-  0x03f8   ColorTransferFuncs?                  N
-  0x03f9   DuotoneTransferFuncs?                N
-  0x03fa   DuotoneImageInfo?                    N
-  0x03fb   EffectiveBW?                         N
-  0x03fc   ObsoletePhotoshopTag1?               N
-  0x03fd   EPSOptions?                          N
-  0x03fe   QuickMaskInfo?                       N
-  0x03ff   ObsoletePhotoshopTag2?               N
-  0x0400   LayerStateInfo?                      N
-  0x0401   WorkingPath?                         N
-  0x0402   LayersGroupInfo?                     N
-  0x0403   ObsoletePhotoshopTag3?               N
+  0x03ee   AlphaChannelsNames                   no
+  0x03ef   DisplayInfo?                         no
+  0x03f0   PStringCaption?                      no
+  0x03f1   BorderInformation?                   no
+  0x03f2   BackgroundColor?                     no
+  0x03f3   PrintFlags?                          no
+  0x03f4   BW_HalftoningInfo?                   no
+  0x03f5   ColorHalftoningInfo?                 no
+  0x03f6   DuotoneHalftoningInfo?               no
+  0x03f7   BW_TransferFunc?                     no
+  0x03f8   ColorTransferFuncs?                  no
+  0x03f9   DuotoneTransferFuncs?                no
+  0x03fa   DuotoneImageInfo?                    no
+  0x03fb   EffectiveBW?                         no
+  0x03fc   ObsoletePhotoshopTag1?               no
+  0x03fd   EPSOptions?                          no
+  0x03fe   QuickMaskInfo?                       no
+  0x03ff   ObsoletePhotoshopTag2?               no
+  0x0400   TargetLayerID?                       no
+  0x0401   WorkingPath?                         no
+  0x0402   LayersGroupInfo?                     no
+  0x0403   ObsoletePhotoshopTag3?               no
   0x0404   IPTCData                             IPTC
-  0x0405   RawImageMode?                        N
+  0x0405   RawImageMode?                        no
   0x0406   JPEG_Quality                         Photoshop JPEG_Quality
-  0x0408   GridGuidesInfo?                      N
-  0x0409   PhotoshopBGRThumbnail                N
+  0x0408   GridGuidesInfo?                      no
+  0x0409   PhotoshopBGRThumbnail                undef!
   0x040a   CopyrightFlag                        int8u
   0x040b   URL                                  string
-  0x040c   PhotoshopThumbnail                   N
+  0x040c   PhotoshopThumbnail                   undef!
   0x040d   GlobalAngle                          int32u
-  0x040e   ColorSamplersResource?               N
+  0x040e   ColorSamplersResource?               no
   0x040f   ICC_Profile                          ICC_Profile
-  0x0410   Watermark?                           N
-  0x0411   ICC_Untagged?                        N
-  0x0412   EffectsVisible?                      N
-  0x0413   SpotHalftone?                        N
-  0x0414   IDsBaseValue?                        N
-  0x0415   UnicodeAlphaNames?                   N
-  0x0416   IndexedColourTableCount?             N
-  0x0417   TransparentIndex?                    N
+  0x0410   Watermark?                           no
+  0x0411   ICC_Untagged?                        no
+  0x0412   EffectsVisible?                      no
+  0x0413   SpotHalftone?                        no
+  0x0414   IDsBaseValue?                        no
+  0x0415   UnicodeAlphaNames?                   no
+  0x0416   IndexedColorTableCount?              no
+  0x0417   TransparentIndex?                    no
   0x0419   GlobalAltitude                       int32u
-  0x041a   Slices?                              N
-  0x041b   WorkflowURL?                         N
-  0x041c   JumpToXPEP?                          N
-  0x041d   AlphaIdentifiers?                    N
-  0x041e   URL_List?                            N
-  0x0421   VersionInfo?                         N
+  0x041a   SliceInfo                            Photoshop SliceInfo
+  0x041b   WorkflowURL                          no
+  0x041c   JumpToXPEP?                          no
+  0x041d   AlphaIdentifiers?                    no
+  0x041e   URL_List                             no+
+  0x0421   VersionInfo                          Photoshop VersionInfo
   0x0422   EXIFInfo                             EXIF
-  0x0423   ExifInfo2?                           N
+  0x0423   ExifInfo2?                           no
   0x0424   XMP                                  XMP
   0x0425   IPTCDigest                           string!
-  0x0426   PrintScale?                          N
-  0x0428   PixelAspectRatio?                    N
-  0x0429   LayerComps?                          N
-  0x042a   AlternateDuotoneColors?              N
-  0x042b   AlternateSpotColors?                 N
-  0x0bb7   ClippingPathName                     N
-  0x2710   PrintFlagsInfo?                      N
+  0x0426   PrintScaleInfo                       Photoshop PrintScaleInfo
+  0x0428   PixelInfo                            Photoshop PixelInfo
+  0x0429   LayerComps?                          no
+  0x042a   AlternateDuotoneColors?              no
+  0x042b   AlternateSpotColors?                 no
+  0x042d   LayerSelectionIDs?                   no
+  0x042e   HDRToningInfo?                       no
+  0x042f   PrintInfo?                           no
+  0x0430   LayerGroupsEnabledID?                no
+  0x0431   ColorSamplersResource2?              no
+  0x0432   MeasurementScale?                    no
+  0x0433   TimelineInfo?                        no
+  0x0434   SheetDisclosure?                     no
+  0x0435   DisplayInfo?                         no
+  0x0436   OnionSkins?                          no
+  0x0438   CountInfo?                           no
+  0x043a   PrintInfo2?                          no
+  0x043b   PrintStyle?                          no
+  0x043c   MacintoshNSPrintInfo?                no
+  0x043d   WindowsDEVMODE?                      no
+  0x043e   AutoSaveFilePath?                    no
+  0x043f   AutoSaveFormat?                      no
+  0x0440   PathSelectionState?                  no
+  0x0bb7   ClippingPathName                     no
+  0x0bb8   OriginPathInfo?                      no
+  0x1b58   ImageReadyVariables?                 no
+  0x1b59   ImageReadyDataSets?                  no
+  0x1f40   LightroomWorkflow?                   no
+  0x2710   PrintFlagsInfo?                      no
 
 =head3 Photoshop Resolution Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    XResolution                          int32u
       2    DisplayedUnitsX                      int16u
@@ -3268,9 +5802,60 @@
 =head3 Photoshop JPEG_Quality Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    PhotoshopQuality                     int16s
-      1    PhotoshopFormat                      N
-      2    ProgressiveScans                     N
+      1    PhotoshopFormat                      no
+      2    ProgressiveScans                     no
+
+=head3 Photoshop SliceInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     20    SlicesGroupName                      no
+     24    NumSlices                            no
+
+=head3 Photoshop VersionInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    HasRealMergedData                    no
+      5    WriterName                           no
+      9    ReaderName                           no
+
+=head3 Photoshop PrintScaleInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PrintStyle                           no
+      2    PrintPosition                        no
+     10    PrintScale                           no
+
+=head3 Photoshop PixelInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    PixelAspectRatio                     no
+
+=head3 Photoshop DocumentData Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Layr'   Layers                               Photoshop Layers
+  'Lr16'   Layers                               Photoshop Layers
+
+=head3 Photoshop Layers Tags
+
+Tags extracted from Photoshop layer information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  '_xbnd'  LayerBlendModes                      no+
+  '_xcnt'  LayerCount                           no
+  '_xnam'  LayerNames                           no+
+  '_xopc'  LayerOpacities                       no+
+  '_xrct'  LayerRectangles                      no+
+  'luni'   LayerUnicodeNames                    no+
+  'lyid'   LayerIDs?                            no+
+  'shmd'   LayerModifyDates                     no+
 
 =head3 Photoshop Header Tags
@@ -3278,11 +5863,242 @@
 This information is found in the PSD file header.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      6    NumChannels                          N
-      7    ImageHeight                          N
-      9    ImageWidth                           N
-     11    BitDepth                             N
-     12    ColorMode                            N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      6    NumChannels                          no
+      7    ImageHeight                          no
+      9    ImageWidth                           no
+     11    BitDepth                             no
+     12    ColorMode                            no
+
+=head3 Photoshop ImageData Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Compression                          no
+
+=head2 Apple Tags
+
+Tags extracted from the maker notes of iPhone images.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0003   RunTime                              Apple RunTime
+  0x0008   AccelerationVector                   rational64s[3]
+  0x000a   HDRImageType                         int32s
+  0x000b   BurstUUID                            string
+  0x0011   MediaGroupUUID                       string
+  0x0015   ImageUniqueID                        string
+
+=head3 Apple RunTime Tags
+
+This PLIST-format information contains the elements of a CMTime structure
+representing the amount of time the phone has been running since the last
+boot, not including standby time.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'epoch'              RunTimeEpoch             no
+  'flags'              RunTimeFlags             no
+  'timescale'          RunTimeScale             no
+  'value'              RunTimeValue             no
+
+=head2 NikonSettings Tags
+
+User settings for newer Nikon models.  A number of the tags are marked as
+Unknown only to reduce the volume of the normal output.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   ISOAutoHiLimit                       no
+  0x0002   ISOAutoFlashLimit                    no
+  0x0003   ISOAutoShutterTime                   no
+  0x000b   FlickerReductionShooting             no
+  0x000c   FlickerReductionIndicator            no
+  0x000d   MovieISOAutoHiLimit                  no
+  0x000e   MovieISOAutoControlManualMode        no
+  0x001d   AF-CPrioritySel                      no
+  0x001e   AF-SPrioritySel                      no
+  0x0020   AFPointSel                           no
+  0x0022   AFActivation                         no
+  0x0023   FocusPointWrap                       no
+  0x0025   ManualFocusPointIllumination         no
+  0x0026   AF-AssistIlluminator                 no
+  0x0029   ISOStepSize                          no
+  0x002a   ExposureControlStepSize              no
+  0x002b   EasyExposureCompensation             no
+  0x002c   MatrixMetering                       no
+  0x002d   CenterWeightedAreaSize               no
+  0x002f   FineTuneOptMatrixMetering            no
+  0x0030   FineTuneOptCenterWeighted            no
+  0x0031   FineTuneOptSpotMetering              no
+  0x0032   FineTuneOptHighlightWeighted         no
+  0x0033   ShutterReleaseButtonAE-L             no
+  0x0034   StandbyMonitorOffTime                no
+  0x0035   SelfTimerTime                        no
+  0x0036   SelfTimerShotCount                   no
+  0x0037   SelfTimerShotInterval                no
+  0x0038   PlaybackMonitorOffTime               no
+  0x0039   MenuMonitorOffTime                   no
+  0x003a   ShootingInfoMonitorOffTime           no
+  0x003b   ImageReviewMonitorOffTime            no
+  0x003c   LiveViewMonitorOffTime               no
+  0x003e   CLModeShootingSpeed                  no
+  0x003f   MaxContinuousRelease                 no
+  0x0040   ExposureDelayMode                    no
+  0x0041   ElectronicFront-CurtainShutter       no
+  0x0042   FileNumberSequence                   no
+  0x0043   FramingGridDisplay                   no
+  0x0045   LCDIllumination                      no
+  0x0046   OpticalVR                            no
+  0x0047   FlashSyncSpeed                       no
+  0x0048   FlashShutterSpeed                    no
+  0x0049   FlashExposureCompArea                no
+  0x004a   AutoFlashISOSensitivity              no
+  0x0051   AssignBktButton                      no
+  0x0052   AssignMovieRecordButton              no
+  0x0053   MultiSelectorShootMode               no
+  0x0054   MultiSelectorPlaybackMode            no
+  0x0056   MultiSelectorLiveView                no
+  0x0058   CmdDialsReverseRotExposureComp?      no
+  0x0059   CmdDialsChangeMainSubExposure?       no
+  0x005a   CmdDialsChangeMainSub                no
+  0x005b   CmdDialsMenuAndPlayback              no
+  0x005c   SubDialFrameAdvance                  no
+  0x005d   ReleaseButtonToUseDial               no
+  0x005e   ReverseIndicators                    no
+  0x0062   MovieShutterButton                   no
+  0x0063   Language                             no
+  0x006c   ShootingInfoDisplay                  no
+  0x0074   FlickAdvanceDirection                no
+  0x0080   RemoteFuncButton                     no
+  0x008b   CmdDialsReverseRotation              no
+  0x008d   FocusPeakingHighlightColor           no
+  0x008e   ContinuousModeDisplay                no
+  0x008f   ShutterSpeedLock                     no
+  0x0090   ApertureLock                         no
+  0x0091   MovieHighlightDisplayThreshold       no
+  0x0093   BlockShotAFResponse                  no
+  0x0094   SubjectMotion                        no
+  0x0095   Three-DTrackingFaceDetection         no
+  0x0097   StoreByOrientation                   no
+  0x0099   DynamicAreaAFAssist                  no
+  0x009a   ExposureCompStepSize                 no
+  0x009b   SyncReleaseMode                      no
+  0x009c   ModelingFlash                        no
+  0x009d   AutoBracketModeM                     no
+  0x009e   PreviewButton                        no
+  0x00a0   Func1Button                          no
+  0x00a2   Func2Button                          no
+  0x00a3   AF-OnButton                          no
+  0x00a4   SubSelector                          no
+  0x00a5   SubSelectorCenter                    no
+  0x00a7   LensFunc1Button                      no
+  0x00a8   CmdDialsApertureSetting              no
+  0x00a9   MultiSelector                        no
+  0x00aa   LiveViewButtonOptions                no
+  0x00ab   LightSwitch                          no
+  0x00b1   MoviePreviewButton                   no
+           MovieFunc1Button                     no
+  0x00b3   MovieFunc1Button                     no
+           MovieFunc2Button                     no
+  0x00b5   MovieFunc2Button                     no
+  0x00b6   AssignMovieSubselector               no
+  0x00b8   LimitAFAreaModeSelD9?                no
+  0x00b9   LimitAFAreaModeSelD25?               no
+  0x00bc   LimitAFAreaModeSel3D?                no
+  0x00bd   LimitAFAreaModeSelGroup?             no
+  0x00be   LimitAFAreaModeSelAuto?              no
+  0x00c1   LimitSelectableImageArea5To4?        no
+  0x00c2   LimitSelectableImageArea1To1?        no
+  0x00d4   PhotoShootingMenuBank                no
+  0x00d5   CustomSettingsBank                   no
+  0x00d6   LimitAF-AreaModeSelPinpoint?         no
+  0x00d7   LimitAF-AreaModeSelDynamic?          no
+  0x00d8   LimitAF-AreaModeSelWideAF_S?         no
+  0x00d9   LimitAF-AreaModeSelWideAF_L?         no
+  0x00da   LowLightAF                           no
+  0x00db   LimitSelectableImageAreaDX?          no
+  0x00dc   LimitSelectableImageArea5To4?        no
+  0x00dd   LimitSelectableImageArea1To1?        no
+  0x00de   LimitSelectableImageArea16To9?       no
+  0x00df   ApplySettingsToLiveView              no
+  0x00e0   FocusPeakingLevel                    no
+  0x00e9   LensControlRing                      no
+  0x00ed   MovieMultiSelector                   no
+  0x00ee   MovieAFSpeed                         no
+  0x00ef   MovieAFSpeedApply                    no
+  0x00f0   MovieAFTrackingSensitivity           no
+  0x00f1   MovieHighlightDisplayPattern         no
+  0x00f2   SubDialFrameAdvanceRating5?          no
+  0x00f3   SubDialFrameAdvanceRating4?          no
+  0x00f4   SubDialFrameAdvanceRating3?          no
+  0x00f5   SubDialFrameAdvanceRating2?          no
+  0x00f6   SubDialFrameAdvanceRating1?          no
+  0x00f7   SubDialFrameAdvanceRating0?          no
+  0x00f9   MovieAF-OnButton                     no
+  0x00fb   SecondarySlotFunction                no
+  0x00fc   SilentPhotography                    no
+  0x00fd   ExtendedShutterSpeeds                no
+  0x0109   BracketSet                           no
+  0x010a   BracketProgram                       no
+  0x010b   BracketIncrement                     no
+  0x010c   BracketIncrement                     no
+  0x0116   GroupAreaC1                          no
+  0x0117   AutoAreaAFStartingPoint              no
+  0x0118   FocusPointPersistence                no
+  0x0119   LimitAFAreaModeSelD49?               no
+  0x011a   LimitAFAreaModeSelD105?              no
+  0x011b   LimitAFAreaModeSelGroupC1?           no
+  0x011c   LimitAFAreaModeSelGroupC2?           no
+  0x011d   AutoFocusModeRestrictions            no
+  0x011e   FocusPointBrightness                 no
+  0x011f   CHModeShootingSpeed                  no
+  0x0120   CLModeShootingSpeed                  no
+  0x0121   QuietShutterShootingSpeed            no
+  0x0122   LimitReleaseModeSelCL?               no
+  0x0123   LimitReleaseModeSelCH?               no
+  0x0124   LimitReleaseModeSelQ?                no
+  0x0125   LimitReleaseModeSelTimer?            no
+  0x0126   LimitReleaseModeSelMirror-Up?        no
+  0x0127   LimitSelectableImageArea16To9?       no
+  0x0128   RearControPanelDisplay               no
+  0x0129   FlashBurstPriority                   no
+  0x012a   RecallShootFuncExposureMode          no
+  0x012b   RecallShootFuncShutterSpeed          no
+  0x012c   RecallShootFuncAperture              no
+  0x012d   RecallShootFuncExposureComp          no
+  0x012e   RecallShootFuncISO                   no
+  0x012f   RecallShootFuncMeteringMode          no
+  0x0130   RecallShootFuncWhiteBalance          no
+  0x0131   RecallShootFuncAFAreaMode            no
+  0x0132   RecallShootFuncFocusTracking         no
+  0x0133   RecallShootFuncAF-On                 no
+  0x0134   VerticalFuncButton                   no
+  0x0135   Func3Button                          no
+  0x0136   VerticalAF-OnButton                  no
+  0x0137   VerticalMultiSelector                no
+  0x0138   MeteringButton                       no
+  0x0139   PlaybackFlickUp                      no
+  0x013a   PlaybackFlickUpRating                no
+  0x013b   PlaybackFlickDown                    no
+  0x013c   PlaybackFlickDownRating              no
+  0x013d   MovieFunc3Button                     no
+  0x0150   ShutterType                          no
+  0x0151   LensFunc2Button                      no
+  0x0158   USBPowerDelivery                     no
+  0x015b   GroupAreaC2                          no
+  0x015c   BracketingBurstOptions               no
+  0x015e   PrimarySlot                          no
+  0x015f   ReverseFocusRing                     no
+  0x0160   VerticalFuncButton                   no
+  0x0161   VerticalAFOnButton                   no
+  0x0162   VerticalMultiSelector                no
+  0x0164   VerticalMovieFuncButton              no
+  0x0165   VerticalMovieAFOnButton              no
+  0x0169   LimitAF-AreaModeSelAutoPeople?       no
+  0x016a   LimitAF-AreaModeSelAutoAnimals?      no
+  0x016b   LimitAF-AreaModeSelWideLPeople?      no
+  0x016c   LimitAF-AreaModeSelWideLAnimals?     no
+  0x016e   AFAreaMode                           no
 
 =head2 Canon Tags
@@ -3292,5 +6108,5 @@
   0x0001   CanonCameraSettings                  Canon CameraSettings
   0x0002   CanonFocalLength                     Canon FocalLength
-  0x0003   CanonFlashInfo?                      N
+  0x0003   CanonFlashInfo?                      no
   0x0004   CanonShotInfo                        Canon ShotInfo
   0x0005   CanonPanorama                        Canon Panorama
@@ -3306,14 +6122,26 @@
            CanonCameraInfo1DmkIII               Canon CameraInfo1DmkIII
            CanonCameraInfo1DmkIV                Canon CameraInfo1DmkIV
+           CanonCameraInfo1DX                   Canon CameraInfo1DX
            CanonCameraInfo5D                    Canon CameraInfo5D
            CanonCameraInfo5DmkII                Canon CameraInfo5DmkII
+           CanonCameraInfo5DmkIII               Canon CameraInfo5DmkIII
+           CanonCameraInfo6D                    Canon CameraInfo6D
            CanonCameraInfo7D                    Canon CameraInfo7D
            CanonCameraInfo40D                   Canon CameraInfo40D
            CanonCameraInfo50D                   Canon CameraInfo50D
            CanonCameraInfo60D                   Canon CameraInfo60D
+           CanonCameraInfo70D                   Canon CameraInfo70D
+           CanonCameraInfo80D                   Canon CameraInfo80D
            CanonCameraInfo450D                  Canon CameraInfo450D
            CanonCameraInfo500D                  Canon CameraInfo500D
            CanonCameraInfo550D                  Canon CameraInfo550D
+           CanonCameraInfo600D                  Canon CameraInfo600D
+           CanonCameraInfo650D                  Canon CameraInfo650D
+           CanonCameraInfo700D                  Canon CameraInfo650D
+           CanonCameraInfo750D                  Canon CameraInfo750D
+           CanonCameraInfo760D                  Canon CameraInfo750D
            CanonCameraInfo1000D                 Canon CameraInfo1000D
+           CanonCameraInfo1100D                 Canon CameraInfo600D
+           CanonCameraInfo1200D                 Canon CameraInfo60D
            CanonCameraInfoPowerShot             Canon CameraInfoPowerShot
            CanonCameraInfoPowerShot2            Canon CameraInfoPowerShot2
@@ -3345,6 +6173,12 @@
   0x0025   FaceDetect2                          Canon FaceDetect2
   0x0026   CanonAFInfo2                         Canon AFInfo2
+  0x0027   ContrastInfo                         Canon ContrastInfo
   0x0028   ImageUniqueID                        int8u
-  0x0081   RawDataOffset                        N
+  0x0029   WBInfo                               Canon WBInfo
+  0x002f   FaceDetect3                          Canon FaceDetect3
+  0x0035   TimeInfo                             Canon TimeInfo
+  0x0038   BatteryType                          undef
+  0x003c   AFInfo3                              Canon AFInfo2
+  0x0081   RawDataOffset                        no
   0x0083   OriginalDecisionDataOffset           int32u*
   0x0090   CustomFunctions1D                    CanonCustom Functions1D
@@ -3352,5 +6186,5 @@
   0x0092   PersonalFunctionValues               CanonCustom PersonalFuncValues
   0x0093   CanonFileInfo                        Canon FileInfo
-  0x0094   AFPointsInFocus1D                    N
+  0x0094   AFPointsInFocus1D                    no
   0x0095   LensModel                            string
   0x0096   SerialInfo                           Canon SerialInfo
@@ -3361,8 +6195,8 @@
   0x009a   AspectInfo                           Canon AspectInfo
   0x00a0   ProcessingInfo                       Canon Processing
-  0x00a1   ToneCurveTable                       N
-  0x00a2   SharpnessTable                       N
-  0x00a3   SharpnessFreqTable                   N
-  0x00a4   WhiteBalanceTable                    N
+  0x00a1   ToneCurveTable                       no
+  0x00a2   SharpnessTable                       no
+  0x00a3   SharpnessFreqTable                   no
+  0x00a4   WhiteBalanceTable                    no
   0x00a9   ColorBalance                         Canon ColorBalance
   0x00aa   MeasuredColor                        Canon MeasuredColor
@@ -3370,6 +6204,6 @@
   0x00b0   CanonFlags                           Canon Flags
   0x00b1   ModifiedInfo                         Canon ModifiedInfo
-  0x00b2   ToneCurveMatching                    N
-  0x00b3   WhiteBalanceMatching                 N
+  0x00b2   ToneCurveMatching                    no
+  0x00b3   WhiteBalanceMatching                 no
   0x00b4   ColorSpace                           int16u
   0x00b6   PreviewImageInfo                     Canon PreviewImageInfo
@@ -3382,22 +6216,35 @@
            ColorData5                           Canon ColorData5
            ColorData6                           Canon ColorData6
+           ColorData7                           Canon ColorData7
+           ColorData8                           Canon ColorData8
+           ColorData9                           Canon ColorData9
+           ColorData10                          Canon ColorData10
            ColorDataUnknown                     Canon ColorDataUnknown
-  0x4002   CRWParam?                            N
+  0x4002   CRWParam?                            no
   0x4003   ColorInfo                            Canon ColorInfo
-  0x4005   Flavor?                              N
-  0x4008   BlackLevel?                          N
+  0x4005   Flavor?                              no
+  0x4008   PictureStyleUserDef                  [Values 0-2]
+                                                Canon PictureStyle
+  0x4009   PictureStylePC                       [Values 0-2]
+                                                Canon PictureStyle
   0x4010   CustomPictureStyleFileName           string
   0x4013   AFMicroAdj                           Canon AFMicroAdj
   0x4015   VignettingCorr                       Canon VignettingCorr
+           VignettingCorrUnknown1               Canon VignettingCorrUnknown
+           VignettingCorrUnknown2               Canon VignettingCorrUnknown
   0x4016   VignettingCorr2                      Canon VignettingCorr2
   0x4018   LightingOpt                          Canon LightingOpt
   0x4019   LensInfo                             Canon LensInfo
   0x4020   AmbienceInfo                         Canon Ambience
+  0x4021   MultiExp                             Canon MultiExp
   0x4024   FilterInfo                           Canon FilterInfo
+  0x4025   HDRInfo                              Canon HDRInfo
+  0x4028   AFConfig                             Canon AFConfig
+  0x403f   RawBurstModeRoll                     Canon RawBurstInfo
 
 =head3 Canon CameraSettings Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    MacroMode                            int16s
       2    SelfTimer                            int16s
@@ -3418,7 +6265,7 @@
      19    AFPoint                              int16s
      20    CanonExposureMode                    int16s
-     22    LensType                             int16s
-     23    LongFocal                            int16u
-     24    ShortFocal                           int16u
+     22    LensType                             int16u
+     23    MaxFocalLength                       int16u
+     24    MinFocalLength                       int16u
      25    FocalUnits                           int16s
      26    MaxAperture                          int16s
@@ -3440,6 +6287,6 @@
 =head3 Canon FocalLength Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    FocalType                            int16u
       1    FocalLength                          int16u
@@ -3451,6 +6298,6 @@
 =head3 Canon ShotInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    AutoISO                              int16s
       2    BaseISO                              int16s
@@ -3484,6 +6331,6 @@
 =head3 Canon Panorama Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       2    PanoramaFrameNumber                  int16s
       5    PanoramaDirection                    int16s
@@ -3491,6 +6338,6 @@
 =head3 Canon UnknownD30 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
 
@@ -3503,11 +6350,11 @@
 lists CameraInfo tags for the 1D and 1DS.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       4    ExposureTime                         int8u
      10    FocalLength                          int16u
      13    LensType                             int16uRev
-     14    ShortFocal                           int16u
-     16    LongFocal                            int16u
+     14    MinFocalLength                       int16u
+     16    MaxFocalLength                       int16u
      65    SharpnessFrequency                   int8u
      66    Sharpness                            int8s
@@ -3525,11 +6372,11 @@
 CameraInfo tags for the 1DmkII and 1DSmkII.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       4    ExposureTime                         int8u
       9    FocalLength                          int16uRev
      12    LensType                             int16uRev
-     17    ShortFocal                           int16uRev
-     19    LongFocal                            int16uRev
+     17    MinFocalLength                       int16uRev
+     19    MaxFocalLength                       int16uRev
      45    FocalType                            int8u
      54    WhiteBalance                         int8u
@@ -3548,11 +6395,11 @@
 CameraInfo tags for the 1DmkIIN.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       4    ExposureTime                         int8u
       9    FocalLength                          int16uRev
      12    LensType                             int16uRev
-     17    ShortFocal                           int16uRev
-     19    LongFocal                            int16uRev
+     17    MinFocalLength                       int16uRev
+     19    MaxFocalLength                       int16uRev
      54    WhiteBalance                         int8u
      55    ColorTemperature                     int16uRev
@@ -3568,6 +6415,6 @@
 CameraInfo tags for the 1DmkIII and 1DSmkIII.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -3583,6 +6430,6 @@
     134    PictureStyle                         int8u
     273    LensType                             int16uRev
-    275    ShortFocal                           int16uRev
-    277    LongFocal                            int16uRev
+    275    MinFocalLength                       int16uRev
+    277    MaxFocalLength                       int16uRev
     310    FirmwareVersion                      string[6]
     370    FileIndex                            int32u
@@ -3597,6 +6444,6 @@
 Custom picture style information for various models.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    ContrastStandard                     int32s
       4    SharpnessStandard                    int32s
@@ -3659,8 +6506,9 @@
 =head3 Canon CameraInfo1DmkIV Tags
 
-CameraInfo tags for the 1DmkIV.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+CameraInfo tags for the EOS 1D Mark IV.  Indices shown are for firmware
+versions 1.0.x, but they may be different for other firmware versions.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -3675,29 +6523,116 @@
      84    FocusDistanceUpper                   int16uRev
      86    FocusDistanceLower                   int16uRev
-    119    WhiteBalance                         int16u
     120    WhiteBalance                         int16u
-    123    ColorTemperature                     int16u
     124    ColorTemperature                     int16u
-    334    LensType                             int16uRev
     335    LensType                             int16uRev
-    336    ShortFocal                           int16uRev
-    337    ShortFocal                           int16uRev
-    338    LongFocal                            int16uRev
-    339    LongFocal                            int16uRev
-    488    FirmwareVersion                      N
-    493    FirmwareVersion                      N
-    551    FileIndex                            int32u
+    337    MinFocalLength                       int16uRev
+    339    MaxFocalLength                       int16uRev
+    493    FirmwareVersion                      no
     556    FileIndex                            int32u
-    563    DirectoryIndex                       int32u
     568    DirectoryIndex                       int32u
-    867    PictureStyleInfo                     Canon PSInfo
     872    PictureStyleInfo                     Canon PSInfo
 
+=head3 Canon CameraInfo1DX Tags
+
+CameraInfo tags for the EOS 1D X.  Indices shown are for firmware version
+1.0.2, but they may be different for other firmware versions.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+     27    CameraTemperature                    int8u
+     35    FocalLength                          int16uRev
+    125    CameraOrientation                    int8u
+    140    FocusDistanceUpper                   int16uRev
+    142    FocusDistanceLower                   int16uRev
+    188    WhiteBalance                         int16u
+    192    ColorTemperature                     int16u
+    244    PictureStyle                         int8u
+    423    LensType                             int16uRev
+    425    MinFocalLength                       int16uRev
+    427    MaxFocalLength                       int16uRev
+    640    FirmwareVersion                      no
+    720    FileIndex                            int32u
+    732    DirectoryIndex                       int32u
+   1012    PictureStyleInfo                     Canon PSInfo2
+
+=head3 Canon PSInfo2 Tags
+
+Custom picture style information for the EOS 5DmkIII, 60D, 600D and 1100D.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ContrastStandard                     int32s
+      4    SharpnessStandard                    int32s
+      8    SaturationStandard                   int32s
+     12    ColorToneStandard                    int32s
+     16    FilterEffectStandard?                int32s
+     20    ToningEffectStandard?                int32s
+     24    ContrastPortrait                     int32s
+     28    SharpnessPortrait                    int32s
+     32    SaturationPortrait                   int32s
+     36    ColorTonePortrait                    int32s
+     40    FilterEffectPortrait?                int32s
+     44    ToningEffectPortrait?                int32s
+     48    ContrastLandscape                    int32s
+     52    SharpnessLandscape                   int32s
+     56    SaturationLandscape                  int32s
+     60    ColorToneLandscape                   int32s
+     64    FilterEffectLandscape?               int32s
+     68    ToningEffectLandscape?               int32s
+     72    ContrastNeutral                      int32s
+     76    SharpnessNeutral                     int32s
+     80    SaturationNeutral                    int32s
+     84    ColorToneNeutral                     int32s
+     88    FilterEffectNeutral?                 int32s
+     92    ToningEffectNeutral?                 int32s
+     96    ContrastFaithful                     int32s
+    100    SharpnessFaithful                    int32s
+    104    SaturationFaithful                   int32s
+    108    ColorToneFaithful                    int32s
+    112    FilterEffectFaithful?                int32s
+    116    ToningEffectFaithful?                int32s
+    120    ContrastMonochrome                   int32s
+    124    SharpnessMonochrome                  int32s
+    128    SaturationMonochrome?                int32s
+    132    ColorToneMonochrome?                 int32s
+    136    FilterEffectMonochrome               int32s
+    140    ToningEffectMonochrome               int32s
+    144    ContrastAuto                         int32s
+    148    SharpnessAuto                        int32s
+    152    SaturationAuto                       int32s
+    156    ColorToneAuto                        int32s
+    160    FilterEffectAuto                     int32s
+    164    ToningEffectAuto                     int32s
+    168    ContrastUserDef1                     int32s
+    172    SharpnessUserDef1                    int32s
+    176    SaturationUserDef1                   int32s
+    180    ColorToneUserDef1                    int32s
+    184    FilterEffectUserDef1                 int32s
+    188    ToningEffectUserDef1                 int32s
+    192    ContrastUserDef2                     int32s
+    196    SharpnessUserDef2                    int32s
+    200    SaturationUserDef2                   int32s
+    204    ColorToneUserDef2                    int32s
+    208    FilterEffectUserDef2                 int32s
+    212    ToningEffectUserDef2                 int32s
+    216    ContrastUserDef3                     int32s
+    220    SharpnessUserDef3                    int32s
+    224    SaturationUserDef3                   int32s
+    228    ColorToneUserDef3                    int32s
+    232    FilterEffectUserDef3                 int32s
+    236    ToningEffectUserDef3                 int32s
+    240    UserDef1PictureStyle                 int16u
+    242    UserDef2PictureStyle                 int16u
+    244    UserDef3PictureStyle                 int16u
+
 =head3 Canon CameraInfo5D Tags
 
 CameraInfo tags for the EOS 5D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -3712,10 +6647,11 @@
      88    ColorTemperature                     int16u
     108    PictureStyle                         int8u
-    147    ShortFocal                           int16uRev
-    149    LongFocal                            int16uRev
+    147    MinFocalLength                       int16uRev
+    149    MaxFocalLength                       int16uRev
     151    LensType                             int16uRev
     164    FirmwareRevision                     string[8]
     172    ShortOwnerName                       string[16]
-    208    ImageNumber                          int16u
+    204    DirectoryIndex                       int32u
+    208    FileIndex                            int16u
     232    ContrastStandard                     int8s
     233    ContrastPortrait                     int8s
@@ -3761,8 +6697,9 @@
 =head3 Canon CameraInfo5DmkII Tags
 
-CameraInfo tags for the EOS 5D Mark II.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+CameraInfo tags for the EOS 5D Mark II.  Indices shown are for firmware
+version 1.0.6, but they may be different for other firmware versions.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -3782,26 +6719,72 @@
     191    AutoLightingOptimizer                int8u
     230    LensType                             int16uRev
-    232    ShortFocal                           int16uRev
-    234    LongFocal                            int16uRev
-    346    CameraInfo5DmkII_2a                  Canon CameraInfo5DmkII_2
-    382    CameraInfo5DmkII_2b                  Canon CameraInfo5DmkII_2
-
-=head3 Canon CameraInfo5DmkII_2 Tags
-
-More CameraInfo tags for the EOS 5D Mark II.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FirmwareVersion                      N
-     61    FileIndex                            int32u
-     73    DirectoryIndex                       int32u
-    377    PictureStyleInfo                     Canon PSInfo
+    232    MinFocalLength                       int16uRev
+    234    MaxFocalLength                       int16uRev
+    382    FirmwareVersion                      no
+    443    FileIndex                            int32u
+    455    DirectoryIndex                       int32u
+    759    PictureStyleInfo                     Canon PSInfo
+
+=head3 Canon CameraInfo5DmkIII Tags
+
+CameraInfo tags for the EOS 5D Mark III.  Indices shown are for firmware
+versions 1.0.x, but they may be different for other firmware versions.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+     27    CameraTemperature                    int8u
+     35    FocalLength                          int16uRev
+    125    CameraOrientation                    int8u
+    140    FocusDistanceUpper                   int16uRev
+    142    FocusDistanceLower                   int16uRev
+    188    WhiteBalance                         int16u
+    192    ColorTemperature                     int16u
+    244    PictureStyle                         int8u
+    339    LensType                             int16uRev
+    341    MinFocalLength                       int16uRev
+    343    MaxFocalLength                       int16uRev
+    356    LensSerialNumber                     undef[5]
+    572    FirmwareVersion                      no
+    652    FileIndex                            int32u
+    656    FileIndex2                           int32u
+    664    DirectoryIndex                       int32u
+    668    DirectoryIndex2                      int32u
+    944    PictureStyleInfo                     Canon PSInfo2
+
+=head3 Canon CameraInfo6D Tags
+
+CameraInfo tags for the EOS 6D.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+     27    CameraTemperature                    int8u
+     35    FocalLength                          int16uRev
+    131    CameraOrientation                    int8u
+    146    FocusDistanceUpper                   int16uRev
+    148    FocusDistanceLower                   int16uRev
+    194    WhiteBalance                         int16u
+    198    ColorTemperature                     int16u
+    250    PictureStyle                         int8u
+    353    LensType                             int16uRev
+    355    MinFocalLength                       int16uRev
+    357    MaxFocalLength                       int16uRev
+    598    FirmwareVersion                      no
+    682    FileIndex                            int32u
+    694    DirectoryIndex                       int32u
+    966    PictureStyleInfo                     Canon PSInfo2
 
 =head3 Canon CameraInfo7D Tags
 
-CameraInfo tags for the EOS 7D.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+CameraInfo tags for the EOS 7D.  Indices shown are for firmware versions
+1.0.x, but they may be different for other firmware versions.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -3813,26 +6796,18 @@
      25    CameraTemperature                    int8u
      30    FocalLength                          int16uRev
-     32    CameraInfo7D_2a                      Canon CameraInfo7D_2
-     36    CameraInfo7D_2b                      Canon CameraInfo7D_2
-
-=head3 Canon CameraInfo7D_2 Tags
-
-More CameraInfo tags for the EOS 7D.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     17    CameraOrientation                    int8u
-     48    FocusDistanceUpper                   int16uRev
-     50    FocusDistanceLower                   int16uRev
-     83    WhiteBalance                         int16u
-     87    ColorTemperature                     int16u
-    165    HighISONoiseReduction                int8u
-    238    LensType                             int16uRev
-    240    ShortFocal                           int16uRev
-    242    LongFocal                            int16uRev
-    392    FirmwareVersion                      N
-    455    FileIndex                            int32u
-    467    DirectoryIndex                       int32u
-    771    PictureStyleInfo                     Canon PSInfo
+     53    CameraOrientation                    int8u
+     84    FocusDistanceUpper                   int16uRev
+     86    FocusDistanceLower                   int16uRev
+    119    WhiteBalance                         int16u
+    123    ColorTemperature                     int16u
+    175    CameraPictureStyle                   int8u
+    201    HighISONoiseReduction                int8u
+    274    LensType                             int16uRev
+    276    MinFocalLength                       int16uRev
+    278    MaxFocalLength                       int16uRev
+    428    FirmwareVersion                      no
+    491    FileIndex                            int32u
+    503    DirectoryIndex                       int32u
+    807    PictureStyleInfo                     Canon PSInfo
 
 =head3 Canon CameraInfo40D Tags
@@ -3840,6 +6815,6 @@
 CameraInfo tags for the EOS 40D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -3855,6 +6830,6 @@
     115    ColorTemperature                     int16u
     214    LensType                             int16uRev
-    216    ShortFocal                           int16uRev
-    218    LongFocal                            int16uRev
+    216    MinFocalLength                       int16uRev
+    218    MaxFocalLength                       int16uRev
     255    FirmwareVersion                      string[6]
     307    FileIndex                            int32u
@@ -3865,8 +6840,9 @@
 =head3 Canon CameraInfo50D Tags
 
-CameraInfo tags for the EOS 50D.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+CameraInfo tags for the EOS 50D.  Indices shown are for firmware versions
+1.0.x, but they may be different for other firmware versions.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -3885,21 +6861,17 @@
     191    AutoLightingOptimizer                int8u
     234    LensType                             int16uRev
-    236    ShortFocal                           int16uRev
-    238    LongFocal                            int16uRev
-    346    FirmwareVersion                      N
-    350    FirmwareVersion                      N
-    407    FileIndex                            int32u
+    236    MinFocalLength                       int16uRev
+    238    MaxFocalLength                       int16uRev
+    350    FirmwareVersion                      no
     411    FileIndex                            int32u
-    419    DirectoryIndex                       int32u
     423    DirectoryIndex                       int32u
-    723    PictureStyleInfo                     Canon PSInfo
     727    PictureStyleInfo                     Canon PSInfo
 
 =head3 Canon CameraInfo60D Tags
 
-CameraInfo tags for the EOS 60D.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+CameraInfo tags for the EOS 60D and 1200D.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -3908,84 +6880,61 @@
      30    FocalLength                          int16uRev
      54    CameraOrientation                    int8u
+     58    CameraOrientation                    int8u
      85    FocusDistanceUpper                   int16uRev
      87    FocusDistanceLower                   int16uRev
     125    ColorTemperature                     int16u
     232    LensType                             int16uRev
-    234    ShortFocal                           int16uRev
-    236    LongFocal                            int16uRev
-    409    FirmwareVersion                      N
+    234    MinFocalLength                       int16uRev
+    236    MaxFocalLength                       int16uRev
+    409    FirmwareVersion                      no
     473    FileIndex                            int32u
     485    DirectoryIndex                       int32u
-    801    PictureStyleInfo2                    Canon PSInfo2
-
-=head3 Canon PSInfo2 Tags
-
-Custom picture style information for the EOS 60D.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ContrastStandard                     int32s
-      4    SharpnessStandard                    int32s
-      8    SaturationStandard                   int32s
-     12    ColorToneStandard                    int32s
-     16    FilterEffectStandard?                int32s
-     20    ToningEffectStandard?                int32s
-     24    ContrastPortrait                     int32s
-     28    SharpnessPortrait                    int32s
-     32    SaturationPortrait                   int32s
-     36    ColorTonePortrait                    int32s
-     40    FilterEffectPortrait?                int32s
-     44    ToningEffectPortrait?                int32s
-     48    ContrastLandscape                    int32s
-     52    SharpnessLandscape                   int32s
-     56    SaturationLandscape                  int32s
-     60    ColorToneLandscape                   int32s
-     64    FilterEffectLandscape?               int32s
-     68    ToningEffectLandscape?               int32s
-     72    ContrastNeutral                      int32s
-     76    SharpnessNeutral                     int32s
-     80    SaturationNeutral                    int32s
-     84    ColorToneNeutral                     int32s
-     88    FilterEffectNeutral?                 int32s
-     92    ToningEffectNeutral?                 int32s
-     96    ContrastFaithful                     int32s
-    100    SharpnessFaithful                    int32s
-    104    SaturationFaithful                   int32s
-    108    ColorToneFaithful                    int32s
-    112    FilterEffectFaithful?                int32s
-    116    ToningEffectFaithful?                int32s
-    120    ContrastMonochrome                   int32s
-    124    SharpnessMonochrome                  int32s
-    128    SaturationMonochrome?                int32s
-    132    ColorToneMonochrome?                 int32s
-    136    FilterEffectMonochrome               int32s
-    140    ToningEffectMonochrome               int32s
-    144    ContrastUnknown?                     int32s
-    148    SharpnessUnknown?                    int32s
-    152    SaturationUnknown?                   int32s
-    156    ColorToneUnknown?                    int32s
-    160    FilterEffectUnknown?                 int32s
-    164    ToningEffectUnknown?                 int32s
-    168    ContrastUserDef1                     int32s
-    172    SharpnessUserDef1                    int32s
-    176    SaturationUserDef1                   int32s
-    180    ColorToneUserDef1                    int32s
-    184    FilterEffectUserDef1                 int32s
-    188    ToningEffectUserDef1                 int32s
-    192    ContrastUserDef2                     int32s
-    196    SharpnessUserDef2                    int32s
-    200    SaturationUserDef2                   int32s
-    204    ColorToneUserDef2                    int32s
-    208    FilterEffectUserDef2                 int32s
-    212    ToningEffectUserDef2                 int32s
-    216    ContrastUserDef3                     int32s
-    220    SharpnessUserDef3                    int32s
-    224    SaturationUserDef3                   int32s
-    228    ColorToneUserDef3                    int32s
-    232    FilterEffectUserDef3                 int32s
-    236    ToningEffectUserDef3                 int32s
-    240    UserDef1PictureStyle                 int16u
-    242    UserDef2PictureStyle                 int16u
-    244    UserDef3PictureStyle                 int16u
+    761    PictureStyleInfo                     Canon PSInfo2
+    801    PictureStyleInfo                     Canon PSInfo2
+
+=head3 Canon CameraInfo70D Tags
+
+CameraInfo tags for the EOS 70D.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+     27    CameraTemperature                    int8u
+     35    FocalLength                          int16uRev
+    132    CameraOrientation                    int8u
+    147    FocusDistanceUpper                   int16uRev
+    149    FocusDistanceLower                   int16uRev
+    199    ColorTemperature                     int16u
+    358    LensType                             int16uRev
+    360    MinFocalLength                       int16uRev
+    362    MaxFocalLength                       int16uRev
+    606    FirmwareVersion                      no
+    691    FileIndex                            int32u
+    703    DirectoryIndex                       int32u
+    975    PictureStyleInfo                     Canon PSInfo2
+
+=head3 Canon CameraInfo80D Tags
+
+CameraInfo tags for the EOS 80D.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+     27    CameraTemperature                    int8u
+     35    FocalLength                          int16uRev
+    150    CameraOrientation                    int8u
+    165    FocusDistanceUpper                   int16uRev
+    167    FocusDistanceLower                   int16uRev
+    314    ColorTemperature                     int16u
+    393    LensType                             int16uRev
+    395    MinFocalLength                       int16uRev
+    397    MaxFocalLength                       int16uRev
+   1114    FirmwareVersion                      no
+   1198    FileIndex                            int32u
+   1210    DirectoryIndex                       int32u
 
 =head3 Canon CameraInfo450D Tags
@@ -3993,6 +6942,6 @@
 CameraInfo tags for the EOS 450D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -4019,6 +6968,6 @@
 CameraInfo tags for the EOS 500D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -4037,7 +6986,7 @@
     190    AutoLightingOptimizer                int8u
     246    LensType                             int16uRev
-    248    ShortFocal                           int16uRev
-    250    LongFocal                            int16uRev
-    400    FirmwareVersion                      N
+    248    MinFocalLength                       int16uRev
+    250    MaxFocalLength                       int16uRev
+    400    FirmwareVersion                      no
     467    FileIndex                            int32u
     479    DirectoryIndex                       int32u
@@ -4048,6 +6997,6 @@
 CameraInfo tags for the EOS 550D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -4064,17 +7013,95 @@
     176    PictureStyle                         int8u
     255    LensType                             int16uRev
-    257    ShortFocal                           int16uRev
-    259    LongFocal                            int16uRev
-    420    FirmwareVersion                      N
+    257    MinFocalLength                       int16uRev
+    259    MaxFocalLength                       int16uRev
+    420    FirmwareVersion                      no
     484    FileIndex                            int32u
     496    DirectoryIndex                       int32u
     796    PictureStyleInfo                     Canon PSInfo
 
+=head3 Canon CameraInfo600D Tags
+
+CameraInfo tags for the EOS 600D and 1100D.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+      7    HighlightTonePriority                int8u
+     21    FlashMeteringMode                    int8u
+     25    CameraTemperature                    int8u
+     30    FocalLength                          int16uRev
+     56    CameraOrientation                    int8u
+     87    FocusDistanceUpper                   int16uRev
+     89    FocusDistanceLower                   int16uRev
+    123    WhiteBalance                         int16u
+    127    ColorTemperature                     int16u
+    179    PictureStyle                         int8u
+    234    LensType                             int16uRev
+    236    MinFocalLength                       int16uRev
+    238    MaxFocalLength                       int16uRev
+    411    FirmwareVersion                      no
+    475    FileIndex                            int32u
+    487    DirectoryIndex                       int32u
+    763    PictureStyleInfo                     Canon PSInfo2
+
+=head3 Canon CameraInfo650D Tags
+
+CameraInfo tags for the EOS 650D and 700D.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+     27    CameraTemperature                    int8u
+     35    FocalLength                          int16uRev
+    125    CameraOrientation                    int8u
+    140    FocusDistanceUpper                   int16uRev
+    142    FocusDistanceLower                   int16uRev
+    188    WhiteBalance                         int16u
+    192    ColorTemperature                     int16u
+    244    PictureStyle                         int8u
+    295    LensType                             int16uRev
+    297    MinFocalLength                       int16uRev
+    299    MaxFocalLength                       int16uRev
+    539    FirmwareVersion                      no
+    544    FirmwareVersion                      no
+    624    FileIndex                            int32u
+    628    FileIndex                            int32u
+    636    DirectoryIndex                       int32u
+    640    DirectoryIndex                       int32u
+    912    PictureStyleInfo                     Canon PSInfo2
+
+=head3 Canon CameraInfo750D Tags
+
+CameraInfo tags for the EOS 750D and 760D.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    FNumber                              int8u
+      4    ExposureTime                         int8u
+      6    ISO                                  int8u
+     27    CameraTemperature                    int8u
+     35    FocalLength                          int16uRev
+    150    CameraOrientation                    int8u
+    165    FocusDistanceUpper                   int16uRev
+    167    FocusDistanceLower                   int16uRev
+    305    WhiteBalance                         int16u
+    309    ColorTemperature                     int16u
+    361    PictureStyle                         int8u
+    388    LensType                             int16uRev
+    390    MinFocalLength                       int16uRev
+    392    MaxFocalLength                       int16uRev
+   1085    FirmwareVersion                      no
+   1097    FirmwareVersion                      no
+
 =head3 Canon CameraInfo1000D Tags
 
 CameraInfo tags for the EOS 1000D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       3    FNumber                              int8u
       4    ExposureTime                         int8u
@@ -4090,4 +7117,6 @@
     115    ColorTemperature                     int16u
     226    LensType                             int16uRev
+    228    MinFocalLength                       int16uRev
+    230    MaxFocalLength                       int16uRev
     267    FirmwareVersion                      string[6]
     311    DirectoryIndex                       int32u
@@ -4102,6 +7131,6 @@
 SD870, SD900, SD950, SD1000, SX100 and TX1.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    ISO                                  int32s
       5    FNumber                              int32s
@@ -4119,6 +7148,6 @@
 SX20, SX110, SX120, SX130, SX200 and SX210.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       1    ISO                                  int32s
       6    FNumber                              int32s
@@ -4135,6 +7164,6 @@
 Unknown CameraInfo tags are divided into 3 tables based on format size.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
      71    CameraTemperature                    int32s
      83    CameraTemperature                    int32s
@@ -4142,19 +7171,18 @@
      92    CameraTemperature                    int32s
     100    CameraTemperature                    int32s
-    466    CameraTemperature                    int32s
-    503    CameraTemperature                    int32s
-    506    CameraTemperature                    int32s
+     -3    CameraTemperature                    int32s
 
 =head3 Canon CameraInfoUnknown16 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
 
 =head3 Canon CameraInfoUnknown Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-  [no tags known]
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    363    LensSerialNumber                     undef[5]
+   1473    FirmwareVersion                      no
 
 =head3 Canon MovieInfo Tags
@@ -4162,6 +7190,6 @@
 Tags written by some Canon cameras when recording video.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    FrameRate                            int16u
       2    FrameCount                           int16u
@@ -4186,29 +7214,29 @@
   Sequence Tag Name                             Writable
   -------- --------                             --------
-      0    NumAFPoints                          N
-      1    ValidAFPoints                        N
-      2    CanonImageWidth                      N
-      3    CanonImageHeight                     N
-      4    AFImageWidth                         N
-      5    AFImageHeight                        N
-      6    AFAreaWidth                          N
-      7    AFAreaHeight                         N
-      8    AFAreaXPositions                     N
-      9    AFAreaYPositions                     N
-     10    AFPointsInFocus                      N
-     11    PrimaryAFPoint                       N
-           Canon_AFInfo_0x000b?                 N
-     12    PrimaryAFPoint                       N
+      0    NumAFPoints                          no
+      1    ValidAFPoints                        no
+      2    CanonImageWidth                      no
+      3    CanonImageHeight                     no
+      4    AFImageWidth                         no
+      5    AFImageHeight                        no
+      6    AFAreaWidth                          no
+      7    AFAreaHeight                         no
+      8    AFAreaXPositions                     no
+      9    AFAreaYPositions                     no
+     10    AFPointsInFocus                      no
+     11    PrimaryAFPoint                       no
+           Canon_AFInfo_0x000b?                 no
+     12    PrimaryAFPoint                       no
 
 =head3 Canon MyColors Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       2    MyColorMode                          int16u
 
 =head3 Canon FaceDetect1 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       2    FacesDetected                        int16u
       3    FaceDetectFrameSize                  int16u[2]
@@ -4225,6 +7253,6 @@
 =head3 Canon FaceDetect2 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       1    FaceWidth                            int8u
       2    FacesDetected                        int8u
@@ -4233,30 +7261,67 @@
 
 Newer version of the AFInfo record containing much of the same information
-(and coordinate confusion) as the older version.  In this record, values of
-9 and 45 have been observed for NumAFPoints.
+(and coordinate confusion) as the older version.  In this record, NumAFPoints
+may be 7, 9, 11, 19, 31, 45 or 61, depending on the camera model.
 
   Sequence Tag Name                             Writable
   -------- --------                             --------
-      0    AFInfoSize?                          N
-      1    AFAreaMode                           N
-      2    NumAFPoints                          N
-      3    ValidAFPoints                        N
-      4    CanonImageWidth                      N
-      5    CanonImageHeight                     N
-      6    AFImageWidth                         N
-      7    AFImageHeight                        N
-      8    AFAreaWidths                         N
-      9    AFAreaHeights                        N
-     10    AFAreaXPositions                     N
-     11    AFAreaYPositions                     N
-     12    AFPointsInFocus                      N
-     13    AFPointsSelected                     N
-           Canon_AFInfo2_0x000d?                N
-     14    PrimaryAFPoint                       N
+      0    AFInfoSize?                          no
+      1    AFAreaMode                           no
+      2    NumAFPoints                          no
+      3    ValidAFPoints                        no
+      4    CanonImageWidth                      no
+      5    CanonImageHeight                     no
+      6    AFImageWidth                         no
+      7    AFImageHeight                        no
+      8    AFAreaWidths                         no
+      9    AFAreaHeights                        no
+     10    AFAreaXPositions                     no
+     11    AFAreaYPositions                     no
+     12    AFPointsInFocus                      no
+     13    AFPointsSelected                     no
+           Canon_AFInfo2_0x000d?                no
+     14    PrimaryAFPoint                       no
+
+=head3 Canon ContrastInfo Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      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
+  ------   --------                             --------
+      3    FacesDetected                        int16u
+
+=head3 Canon TimeInfo Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    TimeZone                             int32s
+      2    TimeZoneCity                         int32s
+      3    DaylightSavings                      int32s
 
 =head3 Canon FileInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    FileNumber                           int32u
            ShutterCount                         int32u
@@ -4274,16 +7339,19 @@
      16    MacroMagnification                   int16s
      19    LiveViewShooting                     int16s
+     20    FocusDistanceUpper                   int16u
+     21    FocusDistanceLower                   int16u
      25    FlashExposureLock                    int16s
+     61    RFLensType                           int16u
 
 =head3 Canon SerialInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       9    InternalSerialNumber                 string
 
 =head3 Canon CropInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    CropLeftMargin                       int16u
       1    CropRightMargin                      int16u
@@ -4293,14 +7361,16 @@
 =head3 Canon AspectInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    AspectRatio                          int32u
       1    CroppedImageWidth                    int32u
       2    CroppedImageHeight                   int32u
+      3    CroppedImageLeft                     int32u
+      4    CroppedImageTop                      int32u
 
 =head3 Canon Processing Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    ToneCurve                            int16s
       2    Sharpness                            int16s
@@ -4321,32 +7391,34 @@
 These tags are used by the 10D and 300D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    WB_RGGBLevelsAuto                    int16s[4]
-      4    WB_RGGBLevelsDaylight                int16s[4]
-      8    WB_RGGBLevelsShade                   int16s[4]
-     12    WB_RGGBLevelsCloudy                  int16s[4]
-     16    WB_RGGBLevelsTungsten                int16s[4]
-     20    WB_RGGBLevelsFluorescent             int16s[4]
-     24    WB_RGGBLevelsFlash                   int16s[4]
-     28    WB_RGGBLevelsCustom                  int16s[4]
-     32    WB_RGGBLevelsKelvin                  int16s[4]
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    WB_RGGBLevelsAuto                    int16s[4]
+      5    WB_RGGBLevelsDaylight                int16s[4]
+      9    WB_RGGBLevelsShade                   int16s[4]
+     13    WB_RGGBLevelsCloudy                  int16s[4]
+     17    WB_RGGBLevelsTungsten                int16s[4]
+     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]
 
 =head3 Canon MeasuredColor Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    MeasuredRGGB                         int16u[4]
 
 =head3 Canon Flags Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    ModifiedParamFlag                    int16s
 
 =head3 Canon ModifiedInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    ModifiedToneCurve                    int16s
       2    ModifiedSharpness                    int16s
@@ -4363,6 +7435,6 @@
 =head3 Canon PreviewImageInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       1    PreviewQuality                       int32u
       2    PreviewImageLength                   int32u*
@@ -4373,16 +7445,16 @@
 =head3 Canon SensorInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    SensorWidth                          N
-      2    SensorHeight                         N
-      5    SensorLeftBorder                     N
-      6    SensorTopBorder                      N
-      7    SensorRightBorder                    N
-      8    SensorBottomBorder                   N
-      9    BlackMaskLeftBorder                  N
-     10    BlackMaskTopBorder                   N
-     11    BlackMaskRightBorder                 N
-     12    BlackMaskBottomBorder                N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    SensorWidth                          no
+      2    SensorHeight                         no
+      5    SensorLeftBorder                     no
+      6    SensorTopBorder                      no
+      7    SensorRightBorder                    no
+      8    SensorBottomBorder                   no
+      9    BlackMaskLeftBorder                  no
+     10    BlackMaskTopBorder                   no
+     11    BlackMaskRightBorder                 no
+     12    BlackMaskBottomBorder                no
 
 =head3 Canon ColorData1 Tags
@@ -4390,6 +7462,6 @@
 These tags are used by the 20D and 350D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
      25    WB_RGGBLevelsAsShot                  int16s[4]
      29    ColorTempAsShot                      int16s
@@ -4417,10 +7489,10 @@
 
 Camera color calibration data.  For the 20D, 350D, 1DmkII and 1DSmkII the
-order of the cooefficients is A, B, C, Temperature, but for newer models it
+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
 option is used.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    CameraColorCalibration01?            int16s[4]
       4    CameraColorCalibration02?            int16s[4]
@@ -4443,6 +7515,6 @@
 These tags are used by the 1DmkII and 1DSmkII.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
      24    WB_RGGBLevelsAuto                    int16s[4]
      28    ColorTempAuto                        int16s
@@ -4508,6 +7580,6 @@
 These tags are used by the 1DmkIIN, 5D, 30D and 400D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    ColorDataVersion                     int16s
      63    WB_RGGBLevelsAsShot                  int16s[4]
@@ -4540,4 +7612,5 @@
     132    ColorTempCustom                      int16s
     133    ColorCalib?                          Canon ColorCalib
+    196    PerChannelBlackLevel                 int16u[4]
     584    FlashOutput                          int16s
     585    FlashBatteryLevel                    int16s
@@ -4548,17 +7621,30 @@
 
 These tags are used by the 1DmkIII, 1DSmkIII, 1DmkIV, 5DmkII, 7D, 40D, 50D,
-450D, 500D, 550D, 1000D and 1100D.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+60D, 450D, 500D, 550D, 1000D and 1100D.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    ColorDataVersion                     int16s
      63    ColorCoefs                           Canon ColorCoefs
     168    ColorCalib?                          Canon ColorCalib
+    231    AverageBlackLevel                    int16u[4]
     640    RawMeasuredRGGB                      int32u[4]
+    692    PerChannelBlackLevel                 int16u[4]
+    696    NormalWhiteLevel                     int16u
+    697    SpecularWhiteLevel                   int16u
+    698    LinearityUpperMargin                 int16u
+    715    PerChannelBlackLevel                 int16u[4]
+    719    NormalWhiteLevel                     int16u
+           PerChannelBlackLevel                 int16u[4]
+    720    SpecularWhiteLevel                   int16u
+    721    LinearityUpperMargin                 int16u
+    723    NormalWhiteLevel                     int16u
+    724    SpecularWhiteLevel                   int16u
+    725    LinearityUpperMargin                 int16u
 
 =head3 Canon ColorCoefs Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    WB_RGGBLevelsAsShot                  int16s[4]
       4    ColorTempAsShot                      int16s
@@ -4610,31 +7696,97 @@
 =head3 Canon ColorData5 Tags
 
-These tags are used by the PowerShot G10.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+These tags are used by many EOS M and PowerShot models.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    ColorDataVersion                     int16s
      71    ColorCoefs                           Canon ColorCoefs
-    186    CameraColorCalibration01?            int16s[5]
-    191    CameraColorCalibration02?            int16s[5]
-    196    CameraColorCalibration03?            int16s[5]
-    201    CameraColorCalibration04?            int16s[5]
-    206    CameraColorCalibration05?            int16s[5]
-    211    CameraColorCalibration06?            int16s[5]
-    216    CameraColorCalibration07?            int16s[5]
-    221    CameraColorCalibration08?            int16s[5]
-    226    CameraColorCalibration09?            int16s[5]
-    231    CameraColorCalibration10?            int16s[5]
-    236    CameraColorCalibration11?            int16s[5]
-    241    CameraColorCalibration12?            int16s[5]
-    246    CameraColorCalibration13?            int16s[5]
-    251    CameraColorCalibration14?            int16s[5]
-    256    CameraColorCalibration15?            int16s[5]
+           ColorCoefs2                          Canon ColorCoefs2
+    186    ColorCalib2?                         Canon ColorCalib2
+    255    ColorCalib2?                         Canon ColorCalib2
+    264    PerChannelBlackLevel                 int16s[4]
+    333    PerChannelBlackLevel                 int16s[4]
+   1385    NormalWhiteLevel                     int16u
+   1386    SpecularWhiteLevel                   int16u
+
+=head3 Canon ColorCoefs2 Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    WB_RGGBLevelsAsShot                  int16s[4]
+      7    ColorTempAsShot                      int16s
+      8    WB_RGGBLevelsAuto                    int16s[4]
+     15    ColorTempAuto                        int16s
+     16    WB_RGGBLevelsMeasured                int16s[4]
+     23    ColorTempMeasured                    int16s
+     24    WB_RGGBLevelsUnknown?                int16s[4]
+     31    ColorTempUnknown?                    int16s
+     32    WB_RGGBLevelsDaylight                int16s[4]
+     39    ColorTempDaylight                    int16s
+     40    WB_RGGBLevelsShade                   int16s[4]
+     47    ColorTempShade                       int16s
+     48    WB_RGGBLevelsCloudy                  int16s[4]
+     55    ColorTempCloudy                      int16s
+     56    WB_RGGBLevelsTungsten                int16s[4]
+     63    ColorTempTungsten                    int16s
+     64    WB_RGGBLevelsFluorescent             int16s[4]
+     71    ColorTempFluorescent                 int16s
+     72    WB_RGGBLevelsKelvin                  int16s[4]
+     79    ColorTempKelvin                      int16s
+     80    WB_RGGBLevelsFlash                   int16s[4]
+     87    ColorTempFlash                       int16s
+     88    WB_RGGBLevelsUnknown2?               int16s[4]
+     95    ColorTempUnknown2?                   int16s
+     96    WB_RGGBLevelsUnknown3?               int16s[4]
+    103    ColorTempUnknown3?                   int16s
+    104    WB_RGGBLevelsUnknown4?               int16s[4]
+    111    ColorTempUnknown4?                   int16s
+    112    WB_RGGBLevelsUnknown5?               int16s[4]
+    119    ColorTempUnknown5?                   int16s
+    120    WB_RGGBLevelsUnknown6?               int16s[4]
+    127    ColorTempUnknown6?                   int16s
+    128    WB_RGGBLevelsUnknown7?               int16s[4]
+    135    ColorTempUnknown7?                   int16s
+    136    WB_RGGBLevelsUnknown8?               int16s[4]
+    143    ColorTempUnknown8?                   int16s
+    144    WB_RGGBLevelsUnknown9?               int16s[4]
+    151    ColorTempUnknown9?                   int16s
+    152    WB_RGGBLevelsUnknown10?              int16s[4]
+    159    ColorTempUnknown10?                  int16s
+    160    WB_RGGBLevelsUnknown11?              int16s[4]
+    167    ColorTempUnknown11?                  int16s
+    168    WB_RGGBLevelsUnknown12?              int16s[4]
+    175    ColorTempUnknown12?                  int16s
+    176    WB_RGGBLevelsUnknown13?              int16s[4]
+    183    ColorTempUnknown13?                  int16s
+
+=head3 Canon ColorCalib2 Tags
+
+B, C, A, D, Temperature.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    CameraColorCalibration01?            int16s[5]
+      5    CameraColorCalibration02?            int16s[5]
+     10    CameraColorCalibration03?            int16s[5]
+     15    CameraColorCalibration04?            int16s[5]
+     20    CameraColorCalibration05?            int16s[5]
+     25    CameraColorCalibration06?            int16s[5]
+     30    CameraColorCalibration07?            int16s[5]
+     35    CameraColorCalibration08?            int16s[5]
+     40    CameraColorCalibration09?            int16s[5]
+     45    CameraColorCalibration10?            int16s[5]
+     50    CameraColorCalibration11?            int16s[5]
+     55    CameraColorCalibration12?            int16s[5]
+     60    CameraColorCalibration13?            int16s[5]
+     65    CameraColorCalibration14?            int16s[5]
+     70    CameraColorCalibration15?            int16s[5]
 
 =head3 Canon ColorData6 Tags
 
-These tags are used by the EOS 600D.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+These tags are used by the EOS 600D and 1200D.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    ColorDataVersion                     int16s
      63    WB_RGGBLevelsAsShot                  int16s[4]
@@ -4689,16 +7841,375 @@
     187    ColorTempUnknown15?                  int16s
     188    ColorCalib?                          Canon ColorCalib
+    251    AverageBlackLevel                    int16u[4]
     404    RawMeasuredRGGB                      int32u[4]
+    479    PerChannelBlackLevel                 int16u[4]
+    483    NormalWhiteLevel                     int16u
+    484    SpecularWhiteLevel                   int16u
+    485    LinearityUpperMargin                 int16u
+
+=head3 Canon ColorData7 Tags
+
+These tags are used by the EOS 1DX, 5DmkIII, 6D, 100D, 650D, 700D, M and 7DmkII.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    ColorDataVersion                     int16s
+     63    WB_RGGBLevelsAsShot                  int16s[4]
+     67    ColorTempAsShot                      int16s
+     68    WB_RGGBLevelsAuto                    int16s[4]
+     72    ColorTempAuto                        int16s
+     73    WB_RGGBLevelsMeasured                int16s[4]
+     77    ColorTempMeasured                    int16s
+     78    WB_RGGBLevelsUnknown?                int16s[4]
+     82    ColorTempUnknown?                    int16s
+     83    WB_RGGBLevelsUnknown2?               int16s[4]
+     87    ColorTempUnknown2?                   int16s
+     88    WB_RGGBLevelsUnknown3?               int16s[4]
+     92    ColorTempUnknown3?                   int16s
+     93    WB_RGGBLevelsUnknown4?               int16s[4]
+     97    ColorTempUnknown4?                   int16s
+     98    WB_RGGBLevelsUnknown5?               int16s[4]
+    102    ColorTempUnknown5?                   int16s
+    103    WB_RGGBLevelsUnknown6?               int16s[4]
+    107    ColorTempUnknown6?                   int16s
+    108    WB_RGGBLevelsUnknown7?               int16s[4]
+    112    ColorTempUnknown7?                   int16s
+    113    WB_RGGBLevelsUnknown8?               int16s[4]
+    117    ColorTempUnknown8?                   int16s
+    118    WB_RGGBLevelsUnknown9?               int16s[4]
+    122    ColorTempUnknown9?                   int16s
+    123    WB_RGGBLevelsUnknown10?              int16s[4]
+    127    ColorTempUnknown10?                  int16s
+    128    WB_RGGBLevelsDaylight                int16s[4]
+    132    ColorTempDaylight                    int16s
+    133    WB_RGGBLevelsShade                   int16s[4]
+    137    ColorTempShade                       int16s
+    138    WB_RGGBLevelsCloudy                  int16s[4]
+    142    ColorTempCloudy                      int16s
+    143    WB_RGGBLevelsTungsten                int16s[4]
+    147    ColorTempTungsten                    int16s
+    148    WB_RGGBLevelsFluorescent             int16s[4]
+    152    ColorTempFluorescent                 int16s
+    153    WB_RGGBLevelsKelvin                  int16s[4]
+    157    ColorTempKelvin                      int16s
+    158    WB_RGGBLevelsFlash                   int16s[4]
+    162    ColorTempFlash                       int16s
+    163    WB_RGGBLevelsUnknown11?              int16s[4]
+    167    ColorTempUnknown11?                  int16s
+    168    WB_RGGBLevelsUnknown12?              int16s[4]
+    172    ColorTempUnknown12?                  int16s
+    173    WB_RGGBLevelsUnknown13?              int16s[4]
+    177    ColorTempUnknown13?                  int16s
+    178    WB_RGGBLevelsUnknown14?              int16s[4]
+    182    ColorTempUnknown14?                  int16s
+    183    WB_RGGBLevelsUnknown15?              int16s[4]
+    187    ColorTempUnknown15?                  int16s
+    188    WB_RGGBLevelsUnknown16?              int16s[4]
+    192    ColorTempUnknown16?                  int16s
+    193    WB_RGGBLevelsUnknown17?              int16s[4]
+    197    ColorTempUnknown17?                  int16s
+    198    WB_RGGBLevelsUnknown18?              int16s[4]
+    202    ColorTempUnknown18?                  int16s
+    203    WB_RGGBLevelsUnknown19?              int16s[4]
+    207    ColorTempUnknown19?                  int16s
+    208    WB_RGGBLevelsUnknown20?              int16s[4]
+    212    ColorTempUnknown20?                  int16s
+    213    ColorCalib?                          Canon ColorCalib
+    276    AverageBlackLevel                    int16u[4]
+    429    RawMeasuredRGGB                      int32u[4]
+    504    PerChannelBlackLevel                 int16u[4]
+    508    NormalWhiteLevel                     int16u
+    509    SpecularWhiteLevel                   int16u
+    510    LinearityUpperMargin                 int16u
+    619    RawMeasuredRGGB                      int32u[4]
+    728    PerChannelBlackLevel                 int16u[4]
+    732    NormalWhiteLevel                     int16u
+    733    SpecularWhiteLevel                   int16u
+    734    LinearityUpperMargin                 int16u
+
+=head3 Canon ColorData8 Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    ColorDataVersion                     int16s
+     63    WB_RGGBLevelsAsShot                  int16s[4]
+     67    ColorTempAsShot                      int16s
+     68    WB_RGGBLevelsAuto                    int16s[4]
+     72    ColorTempAuto                        int16s
+     73    WB_RGGBLevelsMeasured                int16s[4]
+     77    ColorTempMeasured                    int16s
+     78    WB_RGGBLevelsUnknown?                int16s[4]
+     82    ColorTempUnknown?                    int16s
+     83    WB_RGGBLevelsUnknown2?               int16s[4]
+     87    ColorTempUnknown2?                   int16s
+     88    WB_RGGBLevelsUnknown3?               int16s[4]
+     92    ColorTempUnknown3?                   int16s
+     93    WB_RGGBLevelsUnknown4?               int16s[4]
+     97    ColorTempUnknown4?                   int16s
+     98    WB_RGGBLevelsUnknown5?               int16s[4]
+    102    ColorTempUnknown5?                   int16s
+    103    WB_RGGBLevelsUnknown6?               int16s[4]
+    107    ColorTempUnknown6?                   int16s
+    108    WB_RGGBLevelsUnknown7?               int16s[4]
+    112    ColorTempUnknown7?                   int16s
+    113    WB_RGGBLevelsUnknown8?               int16s[4]
+    117    ColorTempUnknown8?                   int16s
+    118    WB_RGGBLevelsUnknown9?               int16s[4]
+    122    ColorTempUnknown9?                   int16s
+    123    WB_RGGBLevelsUnknown10?              int16s[4]
+    127    ColorTempUnknown10?                  int16s
+    128    WB_RGGBLevelsUnknown11?              int16s[4]
+    132    ColorTempUnknown11?                  int16s
+    133    WB_RGGBLevelsDaylight                int16s[4]
+    137    ColorTempDaylight                    int16s
+    138    WB_RGGBLevelsShade                   int16s[4]
+    142    ColorTempShade                       int16s
+    143    WB_RGGBLevelsCloudy                  int16s[4]
+    147    ColorTempCloudy                      int16s
+    148    WB_RGGBLevelsTungsten                int16s[4]
+    152    ColorTempTungsten                    int16s
+    153    WB_RGGBLevelsFluorescent             int16s[4]
+    157    ColorTempFluorescent                 int16s
+    158    WB_RGGBLevelsKelvin                  int16s[4]
+    162    ColorTempKelvin                      int16s
+    163    WB_RGGBLevelsFlash                   int16s[4]
+    167    ColorTempFlash                       int16s
+    168    WB_RGGBLevelsUnknown12?              int16s[4]
+    172    ColorTempUnknown12?                  int16s
+    173    WB_RGGBLevelsUnknown13?              int16s[4]
+    177    ColorTempUnknown13?                  int16s
+    178    WB_RGGBLevelsUnknown14?              int16s[4]
+    182    ColorTempUnknown14?                  int16s
+    183    WB_RGGBLevelsUnknown15?              int16s[4]
+    187    ColorTempUnknown15?                  int16s
+    188    WB_RGGBLevelsUnknown16?              int16s[4]
+    192    ColorTempUnknown16?                  int16s
+    193    WB_RGGBLevelsUnknown17?              int16s[4]
+    197    ColorTempUnknown17?                  int16s
+    198    WB_RGGBLevelsUnknown18?              int16s[4]
+    202    ColorTempUnknown18?                  int16s
+    203    WB_RGGBLevelsUnknown19?              int16s[4]
+    207    ColorTempUnknown19?                  int16s
+    208    WB_RGGBLevelsUnknown20?              int16s[4]
+    212    ColorTempUnknown20?                  int16s
+    213    WB_RGGBLevelsUnknown21?              int16s[4]
+    217    ColorTempUnknown21?                  int16s
+    218    WB_RGGBLevelsUnknown22?              int16s[4]
+    222    ColorTempUnknown22?                  int16s
+    223    WB_RGGBLevelsUnknown23?              int16s[4]
+    227    ColorTempUnknown23?                  int16s
+    228    WB_RGGBLevelsUnknown24?              int16s[4]
+    232    ColorTempUnknown24?                  int16s
+    233    WB_RGGBLevelsUnknown25?              int16s[4]
+    237    ColorTempUnknown25?                  int16s
+    238    WB_RGGBLevelsUnknown26?              int16s[4]
+    242    ColorTempUnknown26?                  int16s
+    243    WB_RGGBLevelsUnknown27?              int16s[4]
+    247    ColorTempUnknown27?                  int16s
+    248    WB_RGGBLevelsUnknown28?              int16s[4]
+    252    ColorTempUnknown28?                  int16s
+    253    WB_RGGBLevelsUnknown29?              int16s[4]
+    257    ColorTempUnknown29?                  int16s
+    258    WB_RGGBLevelsUnknown30?              int16s[4]
+    262    ColorTempUnknown30?                  int16s
+    263    ColorCalib?                          Canon ColorCalib
+    326    AverageBlackLevel                    int16u[4]
+    556    PerChannelBlackLevel                 int16u[4]
+    560    NormalWhiteLevel                     int16u
+    561    SpecularWhiteLevel                   int16u
+    562    LinearityUpperMargin                 int16u
+    778    PerChannelBlackLevel                 int16u[4]
+    782    NormalWhiteLevel                     int16u
+    783    SpecularWhiteLevel                   int16u
+    784    LinearityUpperMargin                 int16u
+
+=head3 Canon ColorData9 Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    ColorDataVersion                     int16s
+     71    WB_RGGBLevelsAsShot                  int16s[4]
+     75    ColorTempAsShot                      int16s
+     76    WB_RGGBLevelsAuto                    int16s[4]
+     80    ColorTempAuto                        int16s
+     81    WB_RGGBLevelsMeasured                int16s[4]
+     85    ColorTempMeasured                    int16s
+     86    WB_RGGBLevelsUnknown?                int16s[4]
+     90    ColorTempUnknown?                    int16s
+     91    WB_RGGBLevelsUnknown2?               int16s[4]
+     95    ColorTempUnknown2?                   int16s
+     96    WB_RGGBLevelsUnknown3?               int16s[4]
+    100    ColorTempUnknown3?                   int16s
+    101    WB_RGGBLevelsUnknown4?               int16s[4]
+    105    ColorTempUnknown4?                   int16s
+    106    WB_RGGBLevelsUnknown5?               int16s[4]
+    110    ColorTempUnknown5?                   int16s
+    111    WB_RGGBLevelsUnknown6?               int16s[4]
+    115    ColorTempUnknown6?                   int16s
+    116    WB_RGGBLevelsUnknown7?               int16s[4]
+    120    ColorTempUnknown7?                   int16s
+    121    WB_RGGBLevelsUnknown8?               int16s[4]
+    125    ColorTempUnknown8?                   int16s
+    126    WB_RGGBLevelsUnknown9?               int16s[4]
+    130    ColorTempUnknown9?                   int16s
+    131    WB_RGGBLevelsUnknown10?              int16s[4]
+    135    ColorTempUnknown10?                  int16s
+    136    WB_RGGBLevelsDaylight                int16s[4]
+    140    ColorTempDaylight                    int16s
+    141    WB_RGGBLevelsShade                   int16s[4]
+    145    ColorTempShade                       int16s
+    146    WB_RGGBLevelsCloudy                  int16s[4]
+    150    ColorTempCloudy                      int16s
+    151    WB_RGGBLevelsTungsten                int16s[4]
+    155    ColorTempTungsten                    int16s
+    156    WB_RGGBLevelsFluorescent             int16s[4]
+    160    ColorTempFluorescent                 int16s
+    161    WB_RGGBLevelsKelvin                  int16s[4]
+    165    ColorTempKelvin                      int16s
+    166    WB_RGGBLevelsFlash                   int16s[4]
+    170    ColorTempFlash                       int16s
+    171    WB_RGGBLevelsUnknown11?              int16s[4]
+    175    ColorTempUnknown11?                  int16s
+    176    WB_RGGBLevelsUnknown12?              int16s[4]
+    180    ColorTempUnknown12?                  int16s
+    181    WB_RGGBLevelsUnknown13?              int16s[4]
+    185    ColorTempUnknown13?                  int16s
+    186    WB_RGGBLevelsUnknown14?              int16s[4]
+    190    ColorTempUnknown14?                  int16s
+    191    WB_RGGBLevelsUnknown15?              int16s[4]
+    195    ColorTempUnknown15?                  int16s
+    196    WB_RGGBLevelsUnknown16?              int16s[4]
+    200    ColorTempUnknown16?                  int16s
+    201    WB_RGGBLevelsUnknown17?              int16s[4]
+    205    ColorTempUnknown17?                  int16s
+    206    WB_RGGBLevelsUnknown18?              int16s[4]
+    210    ColorTempUnknown18?                  int16s
+    211    WB_RGGBLevelsUnknown19?              int16s[4]
+    215    ColorTempUnknown19?                  int16s
+    216    WB_RGGBLevelsUnknown20?              int16s[4]
+    220    ColorTempUnknown20?                  int16s
+    221    WB_RGGBLevelsUnknown21?              int16s[4]
+    225    ColorTempUnknown21?                  int16s
+    226    WB_RGGBLevelsUnknown22?              int16s[4]
+    230    ColorTempUnknown22?                  int16s
+    231    WB_RGGBLevelsUnknown23?              int16s[4]
+    235    ColorTempUnknown23?                  int16s
+    236    WB_RGGBLevelsUnknown24?              int16s[4]
+    240    ColorTempUnknown24?                  int16s
+    241    WB_RGGBLevelsUnknown25?              int16s[4]
+    245    ColorTempUnknown25?                  int16s
+    246    WB_RGGBLevelsUnknown26?              int16s[4]
+    250    ColorTempUnknown26?                  int16s
+    251    WB_RGGBLevelsUnknown27?              int16s[4]
+    255    ColorTempUnknown27?                  int16s
+    256    WB_RGGBLevelsUnknown28?              int16s[4]
+    260    ColorTempUnknown28?                  int16s
+    261    WB_RGGBLevelsUnknown29?              int16s[4]
+    265    ColorTempUnknown29?                  int16s
+    266    ColorCalib?                          Canon ColorCalib
+    329    PerChannelBlackLevel                 int16u[4]
+    796    NormalWhiteLevel                     int16u
+    797    SpecularWhiteLevel                   int16u
+    798    LinearityUpperMargin                 int16u
+
+=head3 Canon ColorData10 Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    ColorDataVersion                     int16s
+     85    WB_RGGBLevelsAsShot                  int16s[4]
+     89    ColorTempAsShot                      int16s
+     90    WB_RGGBLevelsAuto                    int16s[4]
+     94    ColorTempAuto                        int16s
+     95    WB_RGGBLevelsMeasured                int16s[4]
+     99    ColorTempMeasured                    int16s
+    100    WB_RGGBLevelsUnknown?                int16s[4]
+    104    ColorTempUnknown?                    int16s
+    105    WB_RGGBLevelsUnknown2?               int16s[4]
+    109    ColorTempUnknown2?                   int16s
+    110    WB_RGGBLevelsUnknown3?               int16s[4]
+    114    ColorTempUnknown3?                   int16s
+    115    WB_RGGBLevelsUnknown4?               int16s[4]
+    119    ColorTempUnknown4?                   int16s
+    120    WB_RGGBLevelsUnknown5?               int16s[4]
+    124    ColorTempUnknown5?                   int16s
+    125    WB_RGGBLevelsUnknown6?               int16s[4]
+    129    ColorTempUnknown6?                   int16s
+    130    WB_RGGBLevelsUnknown7?               int16s[4]
+    134    ColorTempUnknown7?                   int16s
+    135    WB_RGGBLevelsUnknown8?               int16s[4]
+    139    ColorTempUnknown8?                   int16s
+    140    WB_RGGBLevelsUnknown9?               int16s[4]
+    144    ColorTempUnknown9?                   int16s
+    145    WB_RGGBLevelsUnknown10?              int16s[4]
+    149    ColorTempUnknown10?                  int16s
+    150    WB_RGGBLevelsDaylight                int16s[4]
+    154    ColorTempDaylight                    int16s
+    155    WB_RGGBLevelsShade                   int16s[4]
+    159    ColorTempShade                       int16s
+    160    WB_RGGBLevelsCloudy                  int16s[4]
+    164    ColorTempCloudy                      int16s
+    165    WB_RGGBLevelsTungsten                int16s[4]
+    169    ColorTempTungsten                    int16s
+    170    WB_RGGBLevelsFluorescent             int16s[4]
+    174    ColorTempFluorescent                 int16s
+    175    WB_RGGBLevelsKelvin                  int16s[4]
+    179    ColorTempKelvin                      int16s
+    180    WB_RGGBLevelsFlash                   int16s[4]
+    184    ColorTempFlash                       int16s
+    185    WB_RGGBLevelsUnknown11?              int16s[4]
+    189    ColorTempUnknown11?                  int16s
+    190    WB_RGGBLevelsUnknown12?              int16s[4]
+    194    ColorTempUnknown12?                  int16s
+    195    WB_RGGBLevelsUnknown13?              int16s[4]
+    199    ColorTempUnknown13?                  int16s
+    200    WB_RGGBLevelsUnknown14?              int16s[4]
+    204    ColorTempUnknown14?                  int16s
+    205    WB_RGGBLevelsUnknown15?              int16s[4]
+    209    ColorTempUnknown15?                  int16s
+    210    WB_RGGBLevelsUnknown16?              int16s[4]
+    214    ColorTempUnknown16?                  int16s
+    215    WB_RGGBLevelsUnknown17?              int16s[4]
+    219    ColorTempUnknown17?                  int16s
+    220    WB_RGGBLevelsUnknown18?              int16s[4]
+    224    ColorTempUnknown18?                  int16s
+    225    WB_RGGBLevelsUnknown19?              int16s[4]
+    229    ColorTempUnknown19?                  int16s
+    230    WB_RGGBLevelsUnknown20?              int16s[4]
+    234    ColorTempUnknown20?                  int16s
+    235    WB_RGGBLevelsUnknown21?              int16s[4]
+    239    ColorTempUnknown21?                  int16s
+    240    WB_RGGBLevelsUnknown22?              int16s[4]
+    244    ColorTempUnknown22?                  int16s
+    245    WB_RGGBLevelsUnknown23?              int16s[4]
+    249    ColorTempUnknown23?                  int16s
+    250    WB_RGGBLevelsUnknown24?              int16s[4]
+    254    ColorTempUnknown24?                  int16s
+    255    WB_RGGBLevelsUnknown25?              int16s[4]
+    259    ColorTempUnknown25?                  int16s
+    260    WB_RGGBLevelsUnknown26?              int16s[4]
+    264    ColorTempUnknown26?                  int16s
+    265    WB_RGGBLevelsUnknown27?              int16s[4]
+    269    ColorTempUnknown27?                  int16s
+    270    WB_RGGBLevelsUnknown28?              int16s[4]
+    274    ColorTempUnknown28?                  int16s
+    275    WB_RGGBLevelsUnknown29?              int16s[4]
+    279    ColorTempUnknown29?                  int16s
+    280    ColorCalib?                          Canon ColorCalib
+    343    PerChannelBlackLevel                 int16u[4]
+    810    NormalWhiteLevel                     int16u
+    811    SpecularWhiteLevel                   int16u
+    812    LinearityUpperMargin                 int16u
 
 =head3 Canon ColorDataUnknown Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-  [no tags known]
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    ColorDataVersion                     no
 
 =head3 Canon ColorInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    Saturation                           int16s
       2    ColorTone                            int16s
@@ -4707,26 +8218,40 @@
 =head3 Canon AFMicroAdj Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    AFMicroAdjActive                     int32s
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    AFMicroAdjMode                       int32s
       2    AFMicroAdjValue                      rational64s
 
 =head3 Canon VignettingCorr Tags
 
-This information is found in images from the 1DmkIV, 5DmkII, 7D, 50D, 500D
-and 550D.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+This information is found in images from newer EOS models.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      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
 
+=head3 Canon VignettingCorrUnknown Tags
+
+Vignetting correction from PowerShot models.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    VignettingCorrVersion                no
+
 =head3 Canon VignettingCorr2 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       5    PeripheralLightingSetting            int32s
+      6    ChromaticAberrationSetting           int32s
+      7    DistortionCorrectionSetting          int32s
 
 =head3 Canon LightingOpt Tags
@@ -4734,20 +8259,32 @@
 This information is new in images from the EOS 7D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    PeripheralIlluminationCorr           int32s
       2    AutoLightingOptimizer                int32s
+      3    HighlightTonePriority                int32s
+      4    LongExposureNoiseReduction           int32s
+      5    HighISONoiseReduction                int32s
 
 =head3 Canon LensInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    LensSerialNumber                     undef[5]
 
 =head3 Canon Ambience Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       1    AmbienceSelection                    int32s
 
+=head3 Canon MultiExp Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    MultiExposure                        int32s
+      2    MultiExposureControl                 int32s
+      3    MultiExposureShots                   int32s
+
 =head3 Canon FilterInfo Tags
 
@@ -4756,19 +8293,159 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0101   GrainyBWFilter                       N
-  0x0201   SoftFocusFilter                      N
-  0x0301   ToyCameraFilter                      N
-  0x0401   MiniatureFilter                      N
-  0x0402   MiniatureFilterOrientation           N
-  0x0403   MiniatureFilterPosition              N
+  0x0101   GrainyBWFilter                       no
+  0x0201   SoftFocusFilter                      no
+  0x0301   ToyCameraFilter                      no
+  0x0401   MiniatureFilter                      no
+  0x0402   MiniatureFilterOrientation           no
+  0x0403   MiniatureFilterPosition              no
+  0x0404   MiniatureFilterParameter             no
+  0x0501   FisheyeFilter                        no
+  0x0601   PaintingFilter                       no
+  0x0701   WatercolorFilter                     no
+
+=head3 Canon HDRInfo Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    HDR                                  int32s
+      2    HDREffect                            int32s
+
+=head3 Canon AFConfig Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    AFConfigTool                         int32s
+      2    AFTrackingSensitivity                int32s
+      3    AFAccelDecelTracking                 int32s
+      4    AFPointSwitching                     int32s
+      5    AIServoFirstImage                    int32s
+      6    AIServoSecondImage                   int32s
+      7    USMLensElectronicMF                  int32s
+      8    AFAssistBeam                         int32s
+      9    OneShotAFRelease                     int32s
+     10    AutoAFPointSelEOSiTRAF               int32s
+     11    LensDriveWhenAFImpossible            int32s
+     12    SelectAFAreaSelectionMode            int32s
+     13    AFAreaSelectionMethod                int32s
+     14    OrientationLinkedAF                  int32s
+     15    ManualAFPointSelPattern              int32s
+     16    AFPointDisplayDuringFocus            int32s
+     17    VFDisplayIllumination                int32s
+     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
+  ------   --------                             --------
+  [no tags known]
 
 =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                       N
+  'CNDA'   ThumbnailImage                       undef
+
+=head3 Canon uuid Tags
+
+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.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'CCTP'   CanonCCTP                            Canon CCTP
+  'CMT1'   IFD0                                 EXIF
+  'CMT2'   ExifIFD                              EXIF
+  'CMT3'   MakerNoteCanon                       Canon
+  'CMT4'   GPSInfo                              GPS
+  'CNCV'   CompressorVersion                    no
+  'CNOP'   CanonCNOP                            Canon CNOP
+  'CNTH'   CanonCNTH                            Canon CNTH
+  'THMB'   ThumbnailImage                       no
+
+=head3 Canon CCTP Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 Canon Skip Tags
+
+Information found in the "skip" atom of Canon MOV videos.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'CNDB'   Unknown_CNDB?                        no
+
+=head3 Canon uuid2 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'CNOP'   CanonVRD                             CanonVRD
 
 =head2 CanonCustom Tags
@@ -4961,6 +8638,6 @@
 Personal function settings for the EOS-1D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    PF0CustomFuncRegistration            int16u
       2    PF1DisableShootingModes              int16u
@@ -4995,6 +8672,6 @@
 =head3 CanonCustom PersonalFuncValues Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    PF1Value                             int16u
       2    PF2Value                             int16u
@@ -5041,16 +8718,24 @@
   0x0104   AEBAutoCancel                        int32s
   0x0105   AEBSequence                          int32s
-  0x0106   AEBShotCount                         int32s[n]
+  0x0106   AEBShotCount                         int32s
+           AEBShotCount                         int32s[2]
   0x0107   SpotMeterLinkToAFPoint               int32s
   0x0108   SafetyShift                          int32s
-  0x0109   UsableShootingModes                  int32s[2]
-  0x010a   UsableMeteringModes                  int32s[2]
+  0x0109   UsableShootingModes                  int32s
+           UsableShootingModes                  int32s[2]
+  0x010a   UsableMeteringModes                  int32s
+           UsableMeteringModes                  int32s[2]
   0x010b   ExposureModeInManual                 int32s
   0x010c   ShutterSpeedRange                    int32s[3]
+           ShutterSpeedRange                    int32s[4]
   0x010d   ApertureRange                        int32s[3]
+           ApertureRange                        int32s[4]
   0x010e   ApplyShootingMeteringMode            int32s[8]
   0x010f   FlashSyncSpeedAv                     int32s
-  0x0110   FEMicroadjustment                    int32s[3]
-  0x0111   AEMicroadjustment                    int32s[3]
+  0x0110   AEMicroadjustment                    int32s[3]
+  0x0111   FEMicroadjustment                    int32s[3]
+  0x0112   SameExposureForNewAperture           int32s
+  0x0113   ExposureCompAutoCancel               int32s
+  0x0114   AELockMeterModeAfterFocus            int32s
   0x0201   LongExposureNoiseReduction           int32s
   0x0202   HighISONoiseReduction                int32s
@@ -5063,4 +8748,7 @@
   0x0408   LCDIlluminationDuringBulb            int32s
   0x0409   InfoButtonWhenShooting               int32s
+  0x040a   ViewfinderWarnings                   int32s
+  0x040b   LVShootingAreaDisplay                int32s
+  0x040c   LVShootingAreaDisplay                int32s
   0x0501   USMLensElectronicMF                  int32s
   0x0502   AIServoTrackingSensitivity           int32s
@@ -5087,7 +8775,18 @@
   0x0516   OrientationLinkedAFPoint             int32s
   0x0517   MultiControllerWhileMetering         int32s
+  0x0518   AccelerationTracking                 int32s
+  0x0519   AIServoFirstImagePriority            int32s
+  0x051a   AIServoSecondImagePriority           int32s
+  0x051b   AFAreaSelectMethod                   int32s
+  0x051c   AutoAFPointColorTracking             int32s
+  0x051d   VFDisplayIllumination                int32s
+  0x051e   InitialAFPointAIServoAF              int32s
   0x060f   MirrorLockup                         int32s
-  0x0610   ContinuousShootingSpeed              int32s[3]
+  0x0610   ContinuousShootingSpeed              int32s[6]
+           ContinuousShootingSpeed              int32s[5]
+           ContinuousShootingSpeed              int32s[3]
   0x0611   ContinuousShotLimit                  int32s[2]
+  0x0612   RestrictDriveModes                   int32s
+           RestrictDriveModes                   int32s[2]
   0x0701   Shutter-AELock                       int32s
            AFAndMeteringButtons                 int32s
@@ -5105,6 +8804,15 @@
   0x070c   CustomControls                       int32s
   0x070d   StartMovieShooting                   int32s
+  0x070e   FlashButtonFunction                  int32s
+  0x070f   MultiFunctionLock                    int32s
+  0x0710   TrashButtonFunction                  int32s
+  0x0711   ShutterReleaseWithoutLens            int32s
+  0x0712   ControlRingRotation                  int32s
+  0x0713   FocusRingRotation                    int32s
+  0x0714   RFLensMFFocusRingSensitivity         int32s
+  0x0715   CustomizeDials                       int32s
   0x080b   FocusingScreen                       int32s
-  0x080c   TimerLength                          int32s[4]
+  0x080c   TimerLength                          int32s[3]
+           TimerLength                          int32s[4]
   0x080d   ShortReleaseTimeLag                  int32s
   0x080e   AddAspectRatioInfo                   int32s
@@ -5112,13 +8820,18 @@
   0x0810   LiveViewExposureSimulation           int32s
   0x0811   LCDDisplayAtPowerOn                  int32s
+  0x0812   MemoAudioQuality                     int32s
+  0x0813   DefaultEraseOption                   int32s
+  0x0814   RetractLensOnPowerOff                int32s
+  0x0815   AddIPTCInformation                   int32s
+  0x0816   AudioCompression                     int32s
 
 =head2 CanonVRD Tags
 
 Canon Digital Photo Professional writes VRD (Recipe Data) information as a
-trailer record to JPEG, TIFF, CRW and CR2 images, or as a stand-alone VRD
-file.  The tags listed below represent information found in this record.
-The complete VRD data record may be accessed as a block using the Extra
-'CanonVRD' tag, but this tag is not extracted or copied unless specified
-explicitly.
+trailer record to JPEG, TIFF, CRW and CR2 images, or as stand-alone VRD or
+DR4 files.  The tags listed below represent information found in these
+records.  The complete VRD/DR4 data record may be accessed as a block using
+the Extra 'CanonVRD' or 'CanonDR4' tag, but this tag is not extracted or
+copied unless specified explicitly.
 
   Tag ID       Tag Name                         Writable
@@ -5127,4 +8840,5 @@
   0xffff00f5   IHLData                          CanonVRD IHL
   0xffff00f6   XMP                              XMP
+  0xffff00f7   Edit4Data                        CanonVRD Edit4
 
 =head3 CanonVRD Edit Tags
@@ -5140,8 +8854,8 @@
 =head3 CanonVRD Ver1 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    VRDVersion                           N
-      8    WBAdjRGBLevels                       int16u[3]
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      2    VRDVersion                           no
+      6    WBAdjRGGBLevels                      int16u[4]
      24    WhiteBalanceAdj                      int16u
      26    WBAdjColorTemp                       int16u
@@ -5188,7 +8902,7 @@
 =head3 CanonVRD StampTool Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    StampToolCount                       N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    StampToolCount                       no
 
 =head3 CanonVRD Ver2 Tags
@@ -5196,6 +8910,6 @@
 Tags added in DPP version 2.0 and later.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       2    PictureStyle                         int16s
       3    IsCustomPictureStyle                 int16s
@@ -5261,4 +8975,6 @@
      74    UnknownOutputHighlightPoint?         int16s
      75    UnknownOutputShadowPoint?            int16s
+     76    CustomColorTone                      int16s
+     77    CustomSaturation                     int16s
      78    CustomContrast                       int16s
      79    CustomLinear                         int16s
@@ -5268,5 +8984,5 @@
      83    CustomOutputHighlightPoint           int16s
      84    CustomOutputShadowPoint              int16s
-     88    CustomPictureStyleData               N
+     88    CustomPictureStyleData               no
      94    ChrominanceNoiseReduction            int16s
      95    LuminanceNoiseReduction              int16s
@@ -5304,7 +9020,56 @@
     142    CheckMark2                           int16u
     144    UnsharpMask                          int16s
-    146    UnsharpMaskStrength                  int16s
-    148    UnsharpMaskFineness                  int16s
-    150    UnsharpMaskThreshold                 int16s
+    146    StandardUnsharpMaskStrength          int16s
+    148    StandardUnsharpMaskFineness          int16s
+    150    StandardUnsharpMaskThreshold         int16s
+    152    PortraitUnsharpMaskStrength          int16s
+    154    PortraitUnsharpMaskFineness          int16s
+    156    PortraitUnsharpMaskThreshold         int16s
+    158    LandscapeUnsharpMaskStrength         int16s
+    160    LandscapeUnsharpMaskFineness         int16s
+    162    LandscapeUnsharpMaskThreshold        int16s
+    164    NeutraUnsharpMaskStrength            int16s
+    166    NeutralUnsharpMaskFineness           int16s
+    168    NeutralUnsharpMaskThreshold          int16s
+    170    FaithfulUnsharpMaskStrength          int16s
+    172    FaithfulUnsharpMaskFineness          int16s
+    174    FaithfulUnsharpMaskThreshold         int16s
+    176    MonochromeUnsharpMaskStrength        int16s
+    178    MonochromeUnsharpMaskFineness        int16s
+    180    MonochromeUnsharpMaskThreshold       int16s
+    182    CustomUnsharpMaskStrength            int16s
+    184    CustomUnsharpMaskFineness            int16s
+    186    CustomUnsharpMaskThreshold           int16s
+    188    CustomDefaultUnsharpStrength         int16s
+    190    CustomDefaultUnsharpFineness         int16s
+    192    CustomDefaultUnsharpThreshold        int16s
+    214    CropCircleActive                     int16s
+    215    CropCircleX                          int16s
+    216    CropCircleY                          int16s
+    217    CropCircleRadius                     int16s
+    220    DLOOn                                int16s
+    221    DLOSetting                           int16s
+    222    DLOShootingDistance                  int16s
+    223    DLODataLength                        no
+    224    DLOInfo                              CanonVRD DLOInfo
+    225    CameraRawColorTone                   int16s
+    226    CameraRawSaturation                  int16s
+    227    CameraRawContrast                    int16s
+    228    CameraRawLinear                      int16s
+    229    CameraRawSharpness                   int16s
+    230    CameraRawHighlightPoint              int16s
+    231    CameraRawShadowPoint                 int16s
+    232    CameraRawOutputHighlightPoint        int16s
+    233    CameraRawOutputShadowPoint           int16s
+
+=head3 CanonVRD DLOInfo Tags
+
+Tags added when DLO (Digital Lens Optimizer) is on.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      4    DLOSettingApplied                    int16s
+      5    DLOVersion                           string[10]
+     10    DLOData                              no
 
 =head3 CanonVRD IHL Tags
@@ -5313,9 +9078,162 @@
   ------   --------                             --------
   0x0001   IHL_EXIF                             EXIF
-           IHL_EXIF?                            N
-  0x0003   ThumbnailImage                       N
-  0x0004   PreviewImage                         N
-  0x0005   RawCodecVersion                      N
-  0x0006   CRCDevelParams?                      N
+           IHL_EXIF?                            no
+  0x0003   ThumbnailImage                       no
+  0x0004   PreviewImage                         no
+  0x0005   RawCodecVersion                      no
+  0x0006   CRCDevelParams?                      no
+
+=head3 CanonVRD Edit4 Tags
+
+Canon DPP version 4 edit information.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    DR4                                  CanonVRD DR4
+
+=head3 CanonVRD DR4 Tags
+
+Tags written by Canon DPP version 4 in CanonVRD trailers and DR4 files. Each
+tag has three associated flag words which are stored with the directory
+entry, some of which are extracted as a separate tag, indicated in the table
+below by a decimal appended to the tag ID (.0, .1 or .2).
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'header'     DR4Header                        CanonVRD DR4Header
+  0x10002      Rotation                         yes
+  0x10003      AngleAdj                         yes
+  0x10021      CustomPictureStyle               yes
+  0x10101      CheckMark                        yes
+  0x10200      WorkColorSpace                   yes
+  0x20001      RawBrightnessAdj                 yes
+  0x20101      WhiteBalanceAdj                  yes
+  0x20102      WBAdjColorTemp                   yes
+  0x20105      WBAdjMagentaGreen                yes
+  0x20106      WBAdjBlueAmber                   yes
+  0x20125      WBAdjRGGBLevels                  yes
+  0x20200      GammaLinear                      yes
+  0x20301      PictureStyle                     yes
+  0x20303      ContrastAdj                      yes
+  0x20304      ColorToneAdj                     yes
+  0x20305      ColorSaturationAdj               yes
+  0x20306      MonochromeToningEffect           yes
+  0x20307      MonochromeFilterEffect           yes
+  0x20308      UnsharpMaskStrength              yes
+  0x20309      UnsharpMaskFineness              yes
+  0x2030a      UnsharpMaskThreshold             yes
+  0x2030b      ShadowAdj                        yes
+  0x2030c      HighlightAdj                     yes
+  0x20310      SharpnessAdj                     yes
+  0x20310.0    SharpnessAdjOn                   yes
+  0x20311      SharpnessStrength                yes
+  0x20400      ToneCurve                        CanonVRD ToneCurve
+  0x20400.1    ToneCurveOriginal                yes
+  0x20410      ToneCurveBrightness              yes
+  0x20411      ToneCurveContrast                yes
+  0x20500      AutoLightingOptimizer            yes
+  0x20500.0    AutoLightingOptimizerOn          yes
+  0x20600      LuminanceNoiseReduction          yes
+  0x20601      ChrominanceNoiseReduction        yes
+  0x20670      ColorMoireReduction              yes
+  0x20670.0    ColorMoireReductionOn            yes
+  0x20701      ShootingDistance                 yes
+  0x20702      PeripheralIllumination           yes
+  0x20702.0    PeripheralIlluminationOn         yes
+  0x20703      ChromaticAberration              yes
+  0x20703.0    ChromaticAberrationOn            yes
+  0x20704      ColorBlurOn                      yes
+  0x20705      DistortionCorrection             yes
+  0x20705.0    DistortionCorrectionOn           yes
+  0x20706      DLOSetting                       yes
+  0x20706.0    DLOOn                            yes
+  0x20707      ChromaticAberrationRed           yes
+  0x20708      ChromaticAberrationBlue          yes
+  0x20709      DistortionEffect                 yes
+  0x2070b      DiffractionCorrectionOn          yes
+  0x20900      ColorHue                         yes
+  0x20901      SaturationAdj                    yes
+  0x20910      RedHSL                           yes
+  0x20911      OrangeHSL                        yes
+  0x20912      YellowHSL                        yes
+  0x20913      GreenHSL                         yes
+  0x20914      AquaHSL                          yes
+  0x20915      BlueHSL                          yes
+  0x20916      PurpleHSL                        yes
+  0x20917      MagentaHSL                       yes
+  0x20a00      GammaInfo                        CanonVRD GammaInfo
+  0x30101      CropAspectRatio                  yes
+  0x30102      CropAspectRatioCustom            yes
+  0xf0100      CropInfo                         CanonVRD CropInfo
+  0xf0500      CustomPictureStyleData           yes
+  0xf0510      StampInfo                        CanonVRD StampInfo
+  0xf0511      DustInfo                         CanonVRD DustInfo
+  0xf0512      LensFocalLength                  yes
+
+=head3 CanonVRD DR4Header Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      3    DR4CameraModel                       int32u
+
+=head3 CanonVRD ToneCurve Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    ToneCurveColorSpace                  int32u
+      1    ToneCurveShape                       int32u
+      3    ToneCurveInputRange                  int32u[2]
+      5    ToneCurveOutputRange                 int32u[2]
+      7    RGBCurvePoints                       int32u[21]
+     10    ToneCurveX                           int32u
+     11    ToneCurveY                           int32u
+     45    RedCurvePoints                       int32u[21]
+     83    GreenCurvePoints                     int32u[21]
+    121    BlueCurvePoints                      int32u[21]
+
+=head3 CanonVRD GammaInfo Tags
+
+  Index8   Tag Name                             Writable
+  ------   --------                             --------
+      2    GammaContrast                        double
+      3    GammaColorTone                       double
+      4    GammaSaturation                      double
+      5    GammaUnsharpMaskStrength             double
+      6    GammaUnsharpMaskFineness             double
+      7    GammaUnsharpMaskThreshold            double
+      8    GammaSharpnessStrength               double
+      9    GammaShadow                          double
+     10    GammaHighlight                       double
+     12    GammaBlackPoint                      double
+     13    GammaWhitePoint                      double
+     14    GammaMidPoint                        double
+     15    GammaCurveOutputRange                double[2]
+
+=head3 CanonVRD CropInfo Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    CropActive                           int32s
+      1    CropRotatedOriginalWidth             int32s
+      2    CropRotatedOriginalHeight            int32s
+      3    CropX                                int32s
+      4    CropY                                int32s
+      5    CropWidth                            int32s
+      6    CropHeight                           int32s
+      8    CropRotation                         double
+     10    CropOriginalWidth                    int32s
+     11    CropOriginalHeight                   int32s
+
+=head3 CanonVRD StampInfo Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      2    StampToolCount                       no
+
+=head3 CanonVRD DustInfo Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      2    DustDeleteApplied                    no
 
 =head2 Casio Tags
@@ -5369,5 +9287,5 @@
   0x2089   FaceInfo1                            Casio FaceInfo1
            FaceInfo2                            Casio FaceInfo2
-           FaceInfoUnknown?                     Y
+           FaceInfoUnknown?                     yes
   0x211c   FacesDetected                        int8u
   0x3000   RecordMode                           int16u
@@ -5386,5 +9304,5 @@
   0x3016   Enhancement                          int16u
   0x3017   ColorFilter                          int16u
-  0x301b   UnknownMode?                         int16u
+  0x301b   ArtMode                              int16u
   0x301c   SequenceNumber                       int16u
   0x301d   BracketSequence                      int16u[2]
@@ -5395,4 +9313,5 @@
   0x3031   SpecialEffectSetting                 int16u
   0x3103   DriveMode                            int16u
+  0x310b   ArtModeParameters                    int8u[3]
   0x4001   CaptureFrameRate                     int16u[n]
   0x4003   VideoQuality                         int16u
@@ -5402,6 +9321,6 @@
 Face-detect tags extracted from models such as the EX-H5.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    FacesDetected                        int8u
       1    FaceDetectFrameSize                  int16u[2]
@@ -5421,6 +9340,6 @@
 Face-detect tags extracted from models such as the EX-H20G and EX-ZR100.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       2    FacesDetected                        int8u
       4    FaceDetectFrameSize                  int16u[2]
@@ -5442,12 +9361,12 @@
 Casio QV-7000SX.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     44    CasioQuality                         N
-     55    FocalRange?                          N
-     77    DateTimeOriginal                     N
-     98    ModelType                            N
-    114    ManufactureIndex                     N
-    124    ManufactureCode                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     44    CasioQuality                         no
+     55    FocalRange?                          no
+     77    DateTimeOriginal                     no
+     98    ModelType                            no
+    114    ManufactureIndex                     no
+    124    ManufactureCode                      no
 
 =head3 Casio AVI Tags
@@ -5455,7 +9374,519 @@
 This information is found in Casio GV-10 AVI videos.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Software                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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
+
+=head3 DJI ThermalParams Tags
+
+Thermal parameters extracted from APP4 of DJI RJPEG files from the ZH20T.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     36    K1                                   no
+     40    K2                                   no
+     44    K3                                   no
+     48    K4                                   no
+     52    KF                                   no
+     56    B1                                   no
+     60    B2                                   no
+     68    ObjectDistance                       no
+     70    RelativeHumidity                     no
+     72    Emissivity                           no
+     74    Reflection                           no
+     76    AmbientTemperature                   no
+     80    D2                                   no
+     84    KJ                                   no
+     86    DB                                   no
+     88    KK                                   no
+
+=head2 FLIR Tags
+
+Information extracted from the maker notes of JPEG images from thermal
+imaging cameras by FLIR Systems Inc.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   ImageTemperatureMax                  rational64u
+  0x0002   ImageTemperatureMin                  rational64u
+  0x0003   Emissivity                           rational64u
+  0x0004   UnknownTemperature?                  rational64u
+  0x0005   CameraTemperatureRangeMax?           rational64u
+  0x0006   CameraTemperatureRangeMin?           rational64u
+
+=head3 FLIR FFF Tags
+
+Information extracted from FLIR FFF images and the APP1 FLIR segment of JPEG
+images.  These tags may also be extracted from the first frame of an FLIR
+SEQ file.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  '_header'    FFFHeader                        FLIR Header
+  0x0001       RawData                          FLIR RawData
+  0x0005       GainDeadData                     FLIR GainDeadData
+  0x0006       CoarseData                       FLIR CoarseData
+  0x000e       EmbeddedImage                    FLIR EmbeddedImage
+  0x0020       CameraInfo                       FLIR CameraInfo
+  0x0021       MeasurementInfo                  FLIR MeasInfo
+  0x0022       PaletteInfo                      FLIR PaletteInfo
+  0x0023       TextInfo                         FLIR TextInfo
+  0x0024       EmbeddedAudioFile                no
+  0x0028       PaintData                        FLIR PaintData
+  0x002a       PiP                              FLIR PiP
+  0x002b       GPSInfo                          FLIR GPSInfo
+  0x002c       MeterLink                        FLIR MeterLink
+  0x002e       ParameterInfo                    FLIR ParamInfo
+
+=head3 FLIR Header Tags
+
+Tags extracted from the FLIR FFF/AFF header.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    CreatorSoftware                      no
+
+=head3 FLIR RawData Tags
+
+The thermal image data may be stored either as raw data, or in PNG format.
+If stored as raw data, ExifTool adds a TIFF header to allow the data to be
+viewed as a TIFF image.  If stored in PNG format, the PNG image is extracted
+as-is.  Note that most FLIR cameras using the PNG format seem to write the
+16-bit raw image data in the wrong byte order.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    RawThermalImageWidth                 no
+      2    RawThermalImageHeight                no
+     16    RawThermalImageType                  no
+   16.1    RawThermalImage                      no
+
+=head3 FLIR GainDeadData Tags
+
+Information found in FFF-format .GAN calibration image files.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    GainDeadMapImageWidth                no
+      2    GainDeadMapImageHeight               no
+     16    GainDeadMapImageType                 no
+   16.1    GainDeadMapImage                     no
+
+=head3 FLIR CoarseData Tags
+
+Information found in FFF-format .CRS correction image files.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    CoarseMapImageWidth                  no
+      2    CoarseMapImageHeight                 no
+     16    CoarseMapImageType                   no
+   16.1    CoarseMapImage                       no
+
+=head3 FLIR EmbeddedImage Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    EmbeddedImageWidth                   no
+      2    EmbeddedImageHeight                  no
+     16    EmbeddedImageType                    no
+   16.1    EmbeddedImage                        no
+
+=head3 FLIR CameraInfo Tags
+
+FLIR camera information.  The Planck tags are variables used in the
+temperature calculation.  See
+L<https://exiftool.org/forum/index.php?topic=4898.msg23972#msg23972>
+for details.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     32    Emissivity                           no
+     36    ObjectDistance                       no
+     40    ReflectedApparentTemperature         no
+     44    AtmosphericTemperature               no
+     48    IRWindowTemperature                  no
+     52    IRWindowTransmission                 no
+     60    RelativeHumidity                     no
+     88    PlanckR1                             no
+     92    PlanckB                              no
+     96    PlanckF                              no
+    112    AtmosphericTransAlpha1               no
+    116    AtmosphericTransAlpha2               no
+    120    AtmosphericTransBeta1                no
+    124    AtmosphericTransBeta2                no
+    128    AtmosphericTransX                    no
+    144    CameraTemperatureRangeMax            no
+    148    CameraTemperatureRangeMin            no
+    152    CameraTemperatureMaxClip             no
+    156    CameraTemperatureMinClip             no
+    160    CameraTemperatureMaxWarn             no
+    164    CameraTemperatureMinWarn             no
+    168    CameraTemperatureMaxSaturated        no
+    172    CameraTemperatureMinSaturated        no
+    212    CameraModel                          no
+    244    CameraPartNumber                     no
+    260    CameraSerialNumber                   no
+    276    CameraSoftware                       no
+    368    LensModel                            no
+    400    LensPartNumber                       no
+    416    LensSerialNumber                     no
+    436    FieldOfView                          no
+    492    FilterModel                          no
+    508    FilterPartNumber                     no
+    540    FilterSerialNumber                   no
+    776    PlanckO                              no
+    780    PlanckR2                             no
+    784    RawValueRangeMin                     no
+    786    RawValueRangeMax                     no
+    824    RawValueMedian                       no
+    828    RawValueRange                        no
+    900    DateTimeOriginal                     no
+    912    FocusStepCount                       no
+   1116    FocusDistance                        no
+   1124    FrameRate                            no
+
+=head3 FLIR MeasInfo Tags
+
+Tags listed below are only for the first measurement tool, however multiple
+measurements may be added, and information is extracted for all of them.
+Tags for subsequent measurements are generated as required with the prefixes
+"Meas2", "Meas3", etc.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Meas1Label                                    no
+  Meas1Params                                   no
+  Meas1Type                                     no
+
+=head3 FLIR PaletteInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PaletteColors                        no
+      6    AboveColor                           no
+      9    BelowColor                           no
+     12    OverflowColor                        no
+     15    UnderflowColor                       no
+     18    Isotherm1Color                       no
+     21    Isotherm2Color                       no
+     26    PaletteMethod                        no
+     27    PaletteStretch                       no
+     48    PaletteFileName                      no
+     80    PaletteName                          no
+    112    Palette                              no
+
+=head3 FLIR TextInfo Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Label0                                        no
+  Label1                                        no
+  Label2                                        no
+  Label3                                        no
+  Value0                                        no
+  Value1                                        no
+  Value2                                        no
+  Value3                                        no
+
+=head3 FLIR PaintData Tags
+
+Information generated by FLIR Tools "Paint colors" tool.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      5    PaintImageWidth                      no
+      6    PaintImageHeight                     no
+     20    PaintImageType                       no
+   20.1    PaintImage                           no
+
+=head3 FLIR PiP Tags
+
+FLIR Picture in Picture tags.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    Real2IR                              no
+      2    OffsetX                              no
+      3    OffsetY                              no
+      4    PiPX1                                no
+      5    PiPX2                                no
+      6    PiPY1                                no
+      7    PiPY2                                no
+
+=head3 FLIR GPSInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    GPSValid                             no
+      4    GPSVersionID                         no
+      8    GPSLatitudeRef                       no
+     10    GPSLongitudeRef                      no
+     16    GPSLatitude                          no
+     24    GPSLongitude                         no
+     32    GPSAltitude                          no
+     64    GPSDOP                               no
+     68    GPSSpeedRef                          no
+     70    GPSTrackRef                          no
+     76    GPSSpeed                             no
+     80    GPSTrack                             no
+     88    GPSMapDatum                          no
+
+=head3 FLIR MeterLink Tags
+
+Tags containing Meterlink humidity meter information.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     26    Reading1Units                        no
+     28    Reading1Description                  no
+     32    Reading1Device                       no
+     96    Reading1Value                        no
+    126    Reading2Units                        no
+    128    Reading2Description                  no
+    132    Reading2Device                       no
+    196    Reading2Value                        no
+    226    Reading3Units                        no
+    228    Reading3Description                  no
+    232    Reading3Device                       no
+    296    Reading3Value                        no
+    326    Reading4Units                        no
+    328    Reading4Description                  no
+    332    Reading4Device                       no
+    396    Reading4Value                        no
+
+=head3 FLIR ParamInfo Tags
+
+  Tag Name                                      Writable
+  --------                                      --------
+  DateTimeGenerated                             no
+  Param0                                        no
+  Param1                                        no
+  Param2                                        no
+  Param3                                        no
+
+=head3 FLIR UserData Tags
+
+Tags written by some FLIR cameras in a top-level (!) "udta" atom of MP4
+videos.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'uuid'   FLIR_Parts                           FLIR Parts
+           FLIR_Serial                          FLIR SerialNums
+           FLIR_Params                          FLIR Params
+           FLIR_UnknownUUID                     FLIR UnknownUUID
+           FLIR_GPS                             FLIR GPS_UUID
+           FLIR_MoreInfo                        FLIR MoreInfo
+           SoftwareComponents?                  no
+           FLIR_Unknown?                        no
+           Units                                no+
+           ThumbnailImage                       no
+
+=head3 FLIR Parts Tags
+
+Tags extracted from the "uuid" box with ID 43c3993b0f94424b82056b66513f485d
+in FLIR MP4 videos.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    BAHPVer                              no
+           BALPVer                              no
+           Battery                              no
+           BAVPVer                              no
+           CamCore                              no
+           DetectorBoard                        no
+           Detector                             no
+           GIDCVer                              no
+           GIDPVer                              no
+           GIPC_CPLD                            no
+           GIPCVer                              no
+           GIXIVer                              no
+           MainBoard                            no
+           Optics                               no
+           PartNumber                           no
+
+=head3 FLIR SerialNums Tags
+
+Tags extracted from the "uuid" box with ID 57f5b93e51e448afa0d9c3ef1b37f712
+in FLIR MP4 videos.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    UnknownSerial1?                      no
+     45    UnknownSerial2?                      no
+     78    UnknownSerial3?                      no
+    111    UnknownSerial4?                      no
+    123    UnknownNumber?                       no
+    126    CameraSerialNumber                   no
+
+=head3 FLIR Params Tags
+
+Tags extracted from the "uuid" box with ID 41e5dcf9e80a41ceadfe7f0c58082c19
+in FLIR MP4 videos.
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    ReflectedApparentTemperature         no
+      2    AtmosphericTemperature               no
+      3    Emissivity                           no
+      4    ObjectDistance                       no
+      5    RelativeHumidity                     no
+      6    EstimatedAtmosphericTrans            no
+      7    IRWindowTemperature                  no
+      8    IRWindowTransmission                 no
+
+=head3 FLIR UnknownUUID Tags
+
+Tags extracted from the "uuid" box with ID 574520502cbb44adae5415e9b839d903
+in FLIR MP4 videos.
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 FLIR GPS_UUID Tags
+
+Tags extracted from the "uuid" box with ID 7f2e21008b464918afb1de709a74f6f5
+in FLIR MP4 videos.
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    GPSLatitude                          no
+      2    GPSLongitude                         no
+      3    GPSAltitude                          no
+
+=head3 FLIR MoreInfo Tags
+
+Tags extracted from the "uuid" box with ID 2b452fdc74354094baee22a6b23a7cf8
+in FLIR MP4 videos.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      5    LensModel                            no
+     11    UnknownTemperature1?                 no
+     15    UnknownTemperature2?                 no
+
+=head3 FLIR AFF Tags
+
+Tags extracted from FLIR "AFF" SEQ images.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  '_header'    AFFHeader                        FLIR Header
+  0x0001       AFF1                             FLIR AFF1
+  0x0005       AFF5                             FLIR AFF5
+
+=head3 FLIR AFF1 Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    SensorWidth                          no
+      2    SensorHeight                         no
+
+=head3 FLIR AFF5 Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+     19    SensorWidth                          no
+     20    SensorHeight                         no
+
+=head3 FLIR FPF Tags
+
+Tags extracted from FLIR Public image Format (FPF) files.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     32    FPFVersion                           no
+     36    ImageDataOffset                      no
+     40    ImageType                            no
+     42    ImagePixelFormat                     no
+     44    ImageWidth                           no
+     46    ImageHeight                          no
+     48    ExternalTriggerCount                 no
+     52    SequenceFrameNumber                  no
+    120    CameraModel                          no
+    152    CameraPartNumber                     no
+    184    CameraSerialNumber                   no
+    216    CameraTemperatureRangeMin            no
+    220    CameraTemperatureRangeMax            no
+    224    LensModel                            no
+    256    LensPartNumber                       no
+    288    LensSerialNumber                     no
+    320    FilterModel                          no
+    336    FilterPartNumber                     no
+    384    FilterSerialNumber                   no
+    480    Emissivity                           no
+    484    ObjectDistance                       no
+    488    ReflectedApparentTemperature         no
+    492    AtmosphericTemperature               no
+    496    RelativeHumidity                     no
+    500    ComputedAtmosphericTrans             no
+    504    EstimatedAtmosphericTrans            no
+    508    ReferenceTemperature                 no
+    512    IRWindowTemperature                  no
+    516    IRWindowTransmission                 no
+    584    DateTimeOriginal                     no
+    676    CameraScaleMin                       no
+    680    CameraScaleMax                       no
+    684    CalculatedScaleMin                   no
+    688    CalculatedScaleMax                   no
+    692    ActualScaleMin                       no
+    696    ActualScaleMax                       no
 
 =head2 FujiFilm Tags
@@ -5474,16 +9905,35 @@
   0x100a   WhiteBalanceFineTune                 int32s[2]
   0x100b   NoiseReduction                       int16u
-  0x100e   HighISONoiseReduction                int16u
+  0x100e   NoiseReduction                       int16u
   0x1010   FujiFlashMode                        int16u
   0x1011   FlashExposureComp                    rational64s
   0x1020   Macro                                int16u
   0x1021   FocusMode                            int16u
+  0x1022   AFMode                               int16u
   0x1023   FocusPixel                           int16u[2]
+  0x102b   PrioritySettings                     FujiFilm PrioritySettings
+  0x102d   FocusSettings                        FujiFilm FocusSettings
+  0x102e   AFCSettings                          FujiFilm AFCSettings
   0x1030   SlowSync                             int16u
   0x1031   PictureMode                          int16u
+  0x1032   ExposureCount                        int16u
   0x1033   EXRAuto                              int16u
   0x1034   EXRMode                              int16u
+  0x1040   ShadowTone                           int32s
+  0x1041   HighlightTone                        int32s
+  0x1044   DigitalZoom                          int32u
+  0x1045   LensModulationOptimizer              int32u
+  0x1047   GrainEffect                          int32s
+  0x1048   ColorChromeEffect                    int32s
+  0x1049   BWAdjustment                         int8s
+  0x104d   CropMode                             int16u
+  0x104e   ColorChromeFXBlue                    int32s
+  0x1050   ShutterType                          int16u
   0x1100   AutoBracketing                       int16u
   0x1101   SequenceNumber                       int16u
+  0x1103   DriveSettings                        FujiFilm DriveSettings
+  0x1153   PanoramaAngle                        int16u
+  0x1154   PanoramaDirection                    int16u
+  0x1201   AdvancedFilter                       int32u
   0x1210   ColorMode                            int16u
   0x1300   BlurWarning                          int16u
@@ -5500,6 +9950,26 @@
   0x1407   MaxApertureAtMaxFocal                rational64s
   0x140b   AutoDynamicRange                     int16u
+  0x1422   ImageStabilization                   int16u[3]
+  0x1425   SceneRecognition                     int16u
+  0x1431   Rating                               int32u
+  0x1436   ImageGeneration                      int16u
+  0x1438   ImageCount                           int16u
+  0x1443   DRangePriority                       int16u
+  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
+  0x4201   FaceElementTypes                     int8u[n]
+  0x4203   FaceElementPositions                 int16u[n]
   0x4282   FaceRecInfo                          FujiFilm FaceRecInfo
   0x8000   FileSource                           string
@@ -5508,4 +9978,36 @@
   0xb211   Parallax                             rational64s
 
+=head3 FujiFilm PrioritySettings Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    AF-SPriority                         int16u & 0x0f
+    0.2    AF-CPriority                         int16u & 0xf0
+
+=head3 FujiFilm FocusSettings Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    FocusMode2                           int32u & 0xff
+    0.2    AFAreaMode                           int32u & 0xf00
+    0.3    AFAreaPointSize                      int32u & 0xf000
+    0.4    AFAreaZoneSize                       int32u & 0xf0000
+
+=head3 FujiFilm AFCSettings Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    AF-CSetting                          int32u
+    0.1    AF-CTrackingSensitivity              int32u & 0x0f
+    0.2    AF-CSpeedTrackingSensitivity         int32u & 0xf0
+    0.3    AF-CZoneAreaSwitching                int32u & 0xf00
+
+=head3 FujiFilm DriveSettings Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    DriveMode                            int32u & 0xff
+    0.2    DriveSpeed                           int32u & 0xff000000
+
 =head3 FujiFilm FaceRecInfo Tags
 
@@ -5514,28 +10016,28 @@
   Tag Name                                      Writable
   --------                                      --------
-  Face1Birthday                                 N
-  Face1Category                                 N
-  Face1Name                                     N
-  Face2Birthday                                 N
-  Face2Category                                 N
-  Face2Name                                     N
-  Face3Birthday                                 N
-  Face3Category                                 N
-  Face3Name                                     N
-  Face4Birthday                                 N
-  Face4Category                                 N
-  Face4Name                                     N
-  Face5Birthday                                 N
-  Face5Category                                 N
-  Face5Name                                     N
-  Face6Birthday                                 N
-  Face6Category                                 N
-  Face6Name                                     N
-  Face7Birthday                                 N
-  Face7Category                                 N
-  Face7Name                                     N
-  Face8Birthday                                 N
-  Face8Category                                 N
-  Face8Name                                     N
+  Face1Birthday                                 no
+  Face1Category                                 no
+  Face1Name                                     no
+  Face2Birthday                                 no
+  Face2Category                                 no
+  Face2Name                                     no
+  Face3Birthday                                 no
+  Face3Category                                 no
+  Face3Name                                     no
+  Face4Birthday                                 no
+  Face4Category                                 no
+  Face4Name                                     no
+  Face5Birthday                                 no
+  Face5Category                                 no
+  Face5Name                                     no
+  Face6Birthday                                 no
+  Face6Category                                 no
+  Face6Name                                     no
+  Face7Birthday                                 no
+  Face7Category                                 no
+  Face7Name                                     no
+  Face8Birthday                                 no
+  Face8Category                                 no
+  Face8Name                                     no
 
 =head3 FujiFilm RAF Tags
@@ -5546,10 +10048,57 @@
 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
+  0x2000  WB_GRGBLevelsAuto                     no
+  0x2100  WB_GRGBLevelsDaylight                 no
+  0x2200  WB_GRGBLevelsCloudy                   no
+  0x2300  WB_GRGBLevelsDaylightFluor            no
+  0x2301  WB_GRGBLevelsDayWhiteFluor            no
+  0x2302  WB_GRGBLevelsWhiteFluorescent         no
+  0x2310  WB_GRGBLevelsWarmWhiteFluor           no
+  0x2311  WB_GRGBLevelsLivingRoomWarmWhiteFluor no
+  0x2400  WB_GRGBLevelsTungsten                 no
+  0x2ff0  WB_GRGBLevels                         no
+  0x9200  RelativeExposure                      no
+  0x9650  RawExposureBias                       no
+  0xc000  RAFData                               FujiFilm RAFData
+
+=head3 FujiFilm RAFData Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    RawImageWidth                        no
+      4    RawImageWidth                        no
+           RawImageHeight                       no
+      8    RawImageWidth                        no
+           RawImageHeight                       no
+     12    RawImageHeight                       no
+
+=head3 FujiFilm IFD Tags
+
+Tags found in the FujiIFD information of RAF images from some models.
+
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0100   RawImageFullSize                     N
-  0x0121   RawImageSize                         N
-  0x0130   FujiLayout                           N
-  0x2ff0   WB_GRGBLevels                        N
+  0xf000   FujiIFD                              FujiFilm IFD
+  0xf001   RawImageFullWidth                    no
+  0xf002   RawImageFullHeight                   no
+  0xf003   BitsPerSample                        no
+  0xf007   StripOffsets                         no
+  0xf008   StripByteCounts                      no
+  0xf00a   BlackLevel                           no
+  0xf00b   GeometricDistortionParams            no
+  0xf00c   WB_GRBLevelsStandard                 no
+  0xf00d   WB_GRBLevelsAuto                     no
+  0xf00e   WB_GRBLevels                         no
+  0xf00f   ChromaticAberrationParams            no
+  0xf010   VignettingParams                     no
 
 =head3 FujiFilm FFMV Tags
@@ -5557,7 +10106,19 @@
 Information found in the FFMV atom of MOV videos.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MovieStreamName                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    MovieStreamName                      no
+
+=head3 FujiFilm MOV Tags
+
+This information is found in MOV videos from some FujiFilm cameras.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    Model                                no
+     46    ExposureTime                         no
+     50    FNumber                              no
+     58    ExposureCompensation                 no
 
 =head2 GE Tags
@@ -5590,7 +10151,7 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Lens Shading'       LensShading              N
-  'PreviewImage'       PreviewImage             N
-  'Serial Number'      SerialNumber             N
+  'Lens Shading'       LensShading              no
+  'PreviewImage'       PreviewImage             no
+  'Serial Number'      SerialNumber             no
 
 =head3 HP Type4 Tags
@@ -5598,11 +10159,11 @@
 These tags are used by the PhotoSmart M627.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     12    MaxAperture                          N
-     16    ExposureTime                         N
-     20    CameraDateTime                       N
-     52    ISO                                  N
-     92    SerialNumber                         N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    MaxAperture                          no
+     16    ExposureTime                         no
+     20    CameraDateTime                       no
+     52    ISO                                  no
+     92    SerialNumber                         no
 
 =head3 HP Type6 Tags
@@ -5610,11 +10171,11 @@
 These tags are used by the PhotoSmart M425, M525 and M527.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     12    FNumber                              N
-     16    ExposureTime                         N
-     20    CameraDateTime                       N
-     52    ISO                                  N
-     88    SerialNumber                         N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    FNumber                              no
+     16    ExposureTime                         no
+     20    CameraDateTime                       no
+     52    ISO                                  no
+     88    SerialNumber                         no
 
 =head3 HP TDHD Tags
@@ -5626,6 +10187,6 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'CMSN'   SerialNumber                         N
-  'FWRV'   FirmwareVersion                      N
+  'CMSN'   SerialNumber                         no
+  'FWRV'   FirmwareVersion                      no
   'LSLV'   LSLV                                 HP TDHD
   'TDHD'   TDHD                                 HP TDHD
@@ -5637,6 +10198,6 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0002   CPUVersions                          N
-  0x0003   Quality                              N
+  0x0002   CPUVersions                          no
+  0x0003   Quality                              no
 
 =head3 JVC Text Tags
@@ -5646,6 +10207,6 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'QTY'    Quality                              N
-  'VER'    MakerNoteVersion                     N
+  'QTY'    Quality                              no
+  'VER'    MakerNoteVersion                     no
 
 =head2 Kodak Tags
@@ -5663,6 +10224,6 @@
 Z7590.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    KodakModel                           string[8]
       9    Quality                              int8u
@@ -5700,4 +10261,847 @@
     107    Sharpness                            int8s
 
+=head3 Kodak IFD Tags
+
+These tags are found in a separate IFD of JPEG, TIFF, DCR and KDC images
+from some older Kodak models such as the DC50, DC120, DCS760C, DCS Pro 14N,
+14nx, SLR/n, Pro Back and Canon EOS D2000.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   KodakVersion                         int8u[4]
+  0x0001   UnknownEV?                           rational64u
+  0x0003   ExposureValue                        rational64u
+  0x03e9   OriginalFileName                     string
+  0x03ea   KodakTag                             int32u
+  0x03eb   SensorLeftBorder                     int16u
+  0x03ec   SensorTopBorder                      int16u
+  0x03ed   SensorImageWidth                     int16u
+  0x03ee   SensorImageHeight                    int16u
+  0x03ef   BlackLevelTop                        int16u
+  0x03f0   BlackLevelBottom                     int16u
+  0x03f1   TextualInfo                          Kodak TextualInfo
+  0x03f2   FlashMode?                           int16u
+  0x03f3   FlashCompensation                    rational64s
+  0x03f4   WindMode?                            int16u
+  0x03f5   FocusMode?                           int16u
+  0x03f8   MinAperture                          rational64u
+  0x03f9   MaxAperture                          rational64u
+  0x03fa   WhiteBalanceMode?                    int16u
+  0x03fb   WhiteBalanceDetected?                int16u
+  0x03fc   WhiteBalance                         int16u
+  0x03fd   Processing                           Kodak Processing
+           ProcessingParameters                 no
+  0x03fe   ImageAbsoluteX                       int16s
+  0x03ff   ImageAbsoluteY                       int16s
+  0x0400   ApplicationKeyString                 string
+  0x0401   Time                                 string
+  0x0402   GPSString                            string
+  0x0403   EventLogCapture?                     no
+  0x0404   ComponentTable?                      no
+  0x0405   CustomIlluminant?                    int16u
+  0x0406   CameraTemperature                    rational64s
+           CameraTemperature                    no
+  0x0407   AdapterVoltage                       rational64u
+  0x0408   BatteryVoltage                       rational64u
+  0x0409   DacVoltages                          no
+  0x040a   IlluminantDetectorData?              no
+  0x040b   PixelClockFrequency                  int32u
+  0x040c   CenterPixel                          int16u[3]
+  0x040d   BurstCount                           int16u
+  0x040e   BlackLevelRough                      int16u
+  0x040f   OffsetMapHorizontal?                 no
+  0x0410   OffsetMapVertical?                   no
+  0x0411   Histogram?                           no
+  0x0412   VerticalClockOverlaps                int16u[2]
+  0x0413   SensorTemperature                    no
+  0x0414   XilinxVersion                        string
+  0x0415   FirmwareVersion                      int32u
+  0x0416   BlackLevelRoughAfter                 int16u
+  0x0417   BrightRowsTop                        no
+  0x0418   EventLogProcess                      no
+  0x0419   DacVoltagesFlush                     no
+  0x041a   FlashUsed                            no
+  0x041b   FlashType                            no
+  0x041c   SelfTimer                            no
+  0x041d   AFMode                               no
+  0x041e   LensType                             no
+  0x041f   ImageCropX                           int16s
+  0x0420   ImageCropY                           int16s
+  0x0421   AdjustedTbnImageWidth                no
+  0x0422   AdjustedTbnImageHeight               no
+  0x0423   IntegrationTime                      int32u
+  0x0424   BracketingMode                       no
+  0x0425   BracketingStep                       no
+  0x0426   BracketingCounter                    no
+  0x042e   HuffmanTableLength                   no
+  0x042f   HuffmanTableValue                    no
+  0x0438   MainBoardVersion                     int32u
+  0x0439   ImagerBoardVersion                   int32u
+  0x044c   FocusEdgeMap                         no
+  0x05e6   IdleTiming                           no
+  0x05e7   FlushTiming                          no
+  0x05e8   IntegrateTiming                      no
+  0x05e9   RegisterReadTiming                   no
+  0x05ea   FirstLineTransferTiming              no
+  0x05eb   ShiftTiming                          no
+  0x05ec   NormalLineTransferTiming             no
+  0x05ed   TestTransferTiming                   no
+  0x05fa   MinimumFlushRows                     no
+  0x05fd   ImagerPowerOnDelayMsec               int32u
+  0x05fe   ImagerInitialTimingCode              no
+  0x05ff   ImagerLogicProgram                   no
+  0x0600   ImagerBiasSettlingDelayMsec          int32u
+  0x0604   IdleSequence                         no
+  0x0605   FirstFlushSequence                   no
+  0x0606   FinalFlushSequence                   no
+  0x0607   SampleBlackSequence                  no
+  0x0608   TransferSequence                     no
+  0x060e   DacCountsPerVolt                     no
+  0x060f   BlackDacChannel                      no
+  0x0610   BlackAdCountsPerDacVolt              no
+  0x0611   BlackTarget                          no
+  0x0612   BlackDacSettlingMsec                 no
+  0x07d0   StandardMatrixDaylight               rational64s[9]
+  0x07d1   StandardMatrixTungsten               rational64s[9]
+  0x07d2   StandardMatrixFluorescent            rational64s[9]
+  0x07d3   StandardMatrixFlash                  rational64s[9]
+  0x07d4   StandardMatrixCustom                 rational64s[9]
+  0x07da   DeviantMatrixDaylight                rational64s[9]
+  0x07db   DeviantMatrixTungsten                rational64s[9]
+  0x07dc   DeviantMatrixFluorescent             rational64s[9]
+  0x07dd   DeviantMatrixFlash                   rational64s[9]
+  0x07de   DeviantMatrixCustom                  rational64s[9]
+  0x07e4   UniqueMatrixDaylight                 rational64s[9]
+  0x07e5   UniqueMatrixTungsten                 rational64s[9]
+  0x07e6   UniqueMatrixFluorescent              rational64s[9]
+  0x07e7   UniqueMatrixFlash                    rational64s[9]
+  0x07e8   UniqueMatrixCustom                   rational64s[9]
+  0x07e9   UniqueMatrixAuto                     rational64s[9]
+  0x0834   StandardWhiteDaylight                rational64s[3]
+  0x0835   StandardWhiteTungsten                rational64s[3]
+  0x0836   StandardWhiteFluorescent             rational64s[3]
+  0x0837   StandardWhiteFlash                   rational64s[3]
+  0x0838   StandardWhiteCustom                  rational64s[3]
+  0x083e   DeviantWhiteDaylight                 rational64s[3]
+  0x083f   DeviantWhiteTungsten                 rational64s[3]
+  0x0840   DeviantWhiteFluorescent              rational64s[3]
+  0x0841   DeviantWhiteFlash                    rational64s[3]
+  0x0842   DeviantWhiteCustom                   rational64s[3]
+  0x0846   ColorTemperature                     int16u
+  0x0847   WB_RGBLevelsAsShot                   no
+  0x0848   WB_RGBLevelsDaylight                 no
+  0x0849   WB_RGBLevelsTungsten                 no
+  0x084a   WB_RGBLevelsFluorescent              no
+  0x084b   WB_RGBLevelsFlash                    no
+  0x084c   WB_RGBLevelsCustom                   no
+  0x084d   WB_RGBLevelsAuto                     no
+  0x0852   WB_RGBMulDaylight                    rational64u[3]
+  0x0853   WB_RGBMulTungsten                    rational64u[3]
+  0x0854   WB_RGBMulFluorescent                 rational64u[3]
+  0x0855   WB_RGBMulFlash                       rational64u[3]
+  0x085c   WB_RGBCoeffsDaylight                 no
+  0x085d   WB_RGBCoeffsTungsten                 no
+  0x085e   WB_RGBCoeffsFluorescent              no
+  0x085f   WB_RGBCoeffsFlash                    no
+  0x0898   ExposureGainDaylight                 rational64s
+  0x0899   ExposureGainTungsten                 rational64s
+  0x089a   ExposureGainFluorescent              rational64s
+  0x089b   ExposureGainFlash                    rational64s
+  0x089c   ExposureGainCustom                   rational64s
+  0x089d   AnalogISOTable                       rational64u[3]
+  0x089e   AnalogCaptureISO                     int32u
+  0x089f   ISOCalibrationGain                   rational64u
+  0x08a0   ISOCalibrationGainTable              no
+  0x08a1   ExposureHeadroomFactor               no
+  0x08ab   LinearitySplineTags                  no
+  0x08fc   MonitorMatrix                        rational64s[9]
+  0x08fd   TonScaleTable                        no
+  0x08fe   Gamma                                rational64u
+  0x08ff   LogLinTable                          no
+  0x0900   LinLogTable                          no
+  0x0901   GammaTable                           no
+  0x0902   LogScale                             rational64u
+  0x0903   BaseISO                              rational64u
+  0x0904   LinLogCoring                         int16u
+  0x0905   PatternGainConversionTable           no
+  0x0906   DefectCount                          no
+  0x0907   DefectList                           no
+  0x0908   DefectListPacked                     no
+  0x0909   ImageSpace                           int16u
+  0x090a   ThumbnailCompressionTable            no
+  0x090b   ThumbnailExpansionTable              no
+  0x090c   ImageCompressionTable                no
+  0x090d   ImageExpansionTable                  no
+  0x090e   EighteenPercentPoint                 no
+  0x090f   DefectIsoCode                        int16u
+  0x0910   BaseISODaylight                      rational64u
+  0x0911   BaseISOTungsten                      rational64u
+  0x0912   BaseISOFluorescent                   rational64u
+  0x0913   BaseISOFlash                         rational64u
+  0x091a   MatrixSelectThreshold                int16s
+  0x091b   MatrixSelectK                        rational64u
+  0x091c   IlluminantDetectTable                no
+  0x091d   RGTable                              no
+  0x091e   MatrixSelectThreshold1               int16s
+  0x091f   MatrixSelectThreshold2               int16s
+  0x0924   PortraitMatrix                       no
+  0x0925   PortraitToneScaleTable               no
+  0x092e   EnableSharpening                     int16u
+  0x092f   SharpeningKernel                     int16s[25]
+  0x0930   EdgeMapSlope                         int16u
+  0x0931   EdgeMapX1                            int16u
+  0x0932   EdgeMapX2                            int16u
+  0x0933   KernelDenominators                   int16u[3]
+  0x0934   EdgeMapX3                            int16u
+  0x0935   EdgeMapX4                            int16u
+  0x0936   SharpenForThumbnail                  no
+  0x0937   EdgeSpline                           no
+  0x0938   DownSampleBy2Hor                     no
+  0x0939   DownSampleBy2Ver                     no
+  0x093a   DownSampleBy4Hor                     no
+  0x093b   DownSampleBy4Ver                     no
+  0x093c   DownSampleBy3Hor                     no
+  0x093d   DownSampleBy3Ver                     no
+  0x093e   DownSampleBy6Hor                     no
+  0x093f   DownSampleBy6Ver                     no
+  0x0940   DownSampleBy2Hor3MPdcr               no
+  0x0941   DownSampleBy2Ver3MPdcr               no
+  0x0942   ThumbnailResizeRatio                 no
+  0x0943   AtCaptureUserCrop                    int32u[4]
+  0x0944   ImageResolution                      int32u
+  0x0945   ImageResolutionJpg                   int32u
+  0x094c   USMParametersLow                     no
+  0x094d   USMParametersMed                     no
+  0x094e   USMParametersHigh                    no
+  0x094f   USMParametersHost                    no
+  0x0950   EdgeSplineLow                        no
+  0x0951   EdgeSplineMed                        no
+  0x0952   EdgeSplineHigh                       no
+  0x0953   USMParametersHost6MP                 no
+  0x0954   USMParametersHost3MP                 no
+  0x0960   PatternImagerWidth                   int16u
+  0x0961   PatternImagerHeight                  int16u
+  0x0962   PatternAreaWidth                     int16u
+  0x0963   PatternAreaHeight                    int16u
+  0x0964   PatternCorrectionGains               no
+  0x0965   PatternCorrectionOffsets             no
+  0x0966   PatternX                             int16u
+  0x0967   PatternY                             int16u
+  0x0968   PatternCorrectionFactors             no
+  0x0969   PatternCorrectionFactorScale         int16u
+  0x096a   PatternCropRows1                     int16u
+  0x096b   PatternCropRows2                     int16u
+  0x096c   PatternCropCols1                     int16u
+  0x096d   PatternCropCols2                     int16u
+  0x096e   PixelCorrectionGains                 no
+  0x096f   StitchRows                           no
+  0x0970   StitchColumns                        no
+  0x0971   PixelCorrectionScale                 int16u
+  0x0972   PixelCorrectionOffset                int16u
+  0x0988   LensTableIndex                       no
+  0x0992   DiffTileGains602832                  no
+  0x0993   DiffTileGains24t852822               no
+  0x099c   TileGainDeterminationTable           no
+  0x099d   NemoBlurKernel                       no
+  0x099e   NemoTileSize                         no
+  0x099f   NemoGainFactors                      no
+  0x09a0   NemoDarkLimit                        no
+  0x09a1   NemoHighlight12Limit                 no
+  0x09c4   ImagerFileProductionLevel            int16u
+  0x09c5   ImagerFileDateCreated                int32u
+  0x09c6   CalibrationVersion                   string
+  0x09c7   ImagerFileTagsVersionStandard        int16u
+  0x09c8   IFCameraModel                        string
+  0x09c9   CalibrationHistory                   string
+  0x09ca   CalibrationLog                       no
+  0x09ce   SensorSerialNumber                   string
+  0x09f6   DefectConcealArtCorrectThres         no
+  0x09f7   SglColDCACThres1                     no
+  0x09f8   SglColDCACThres2                     no
+  0x09f9   SglColDCACTHres3                     no
+  0x0a01   DblColDCACThres1                     no
+  0x0a02   DblColDCACThres2                     no
+  0x0a0a   DefectConcealThresTable              no
+  0x0a28   MonoUniqueMatrix                     no
+  0x0a29   MonoMonitorMatrix                    no
+  0x0a2a   MonoToneScaleTable                   no
+  0x0a5a   OmenInitialScaling                   no
+  0x0a5b   OmenInitialRows                      no
+  0x0a5c   OmenInitialColumns                   no
+  0x0a5d   OmenInitialIPFStrength               int32s[4]
+  0x0a5e   OmenEarlyStrength                    int32s[4]
+  0x0a5f   OmenAutoStrength                     int32s[4]
+  0x0a60   OmenAtCaptureStrength                int32s[4]
+  0x0a61   OmenAtCaptureMode                    no
+  0x0a62   OmenFocalLengthLimit                 int16s
+  0x0a64   OmenSurfaceIndex                     int16s
+  0x0a65   OmenPercentToRationalLimitsRed       no
+  0x0a66   OmenPercentToRationalLimitsGoR       no
+  0x0a67   OmenPercentToRationalLimitsBlue      no
+  0x0a68   OmenPercentToRationalLimitsGoB       no
+  0x0a6e   OmenEarlyGoBSurface                  no
+  0x0a6f   OmenEarlyGoBRows                     no
+  0x0a70   OmenEarlyGoBColumns                  no
+  0x0a73   OmenSmoothingKernel                  no
+  0x0a74   OmenGradientOffset                   no
+  0x0a75   OmenGradientKernel                   no
+  0x0a76   OmenGradientKernelTaps               no
+  0x0a77   OmenRatioClipFactors                 no
+  0x0a78   OmenRatioExclusionFactors            no
+  0x0a79   OmenGradientExclusionLimits          no
+  0x0a7a   OmenROICoordinates                   no
+  0x0a7b   OmenROICoefficients                  no
+  0x0a7c   OmenRangeWeighting                   no
+  0x0a7d   OmenMeanToStrength                   no
+  0x0bb8   FactoryWhiteGainsDaylight            no
+  0x0bb9   FactoryWhiteOffsetsDaylight          no
+  0x0bba   DacGainsCoarse                       no
+  0x0bbb   DacGainsFine                         no
+  0x0bbc   DigitalExposureGains                 no
+  0x0bbd   DigitalExposureBiases                no
+  0x0bbe   BlackClamp                           no
+  0x0bbf   ChannelCoarseGainAdjust              no
+  0x0bc0   BlackClampOffset                     no
+  0x0bf4   DMPixelThresholdFactor               no
+  0x0bf5   DMWindowThresholdFactor              no
+  0x0bf6   DMTrimFraction                       no
+  0x0bf7   DMSmoothRejThresh                    no
+  0x0bf8   DMFillRejThresh                      no
+  0x0bf9   VMWsize                              no
+  0x0bfa   DMErodeRadius                        no
+  0x0bfb   DMNumPatches                         no
+  0x0bfc   DMNoiseScale                         no
+  0x0bfe   BrightDefectThreshold                no
+  0x0bff   BrightDefectIntegrationMS            no
+  0x0c00   BrightDefectIsoCode                  no
+  0x0c03   TopDarkRow1                          no
+  0x0c04   TopDarkRow2                          no
+  0x0c05   BottomDarkRow1                       no
+  0x0c06   BottomDarkRow2                       no
+  0x0c07   LeftDarkCol1                         no
+  0x0c08   LeftDarkCol2                         no
+  0x0c09   RightDarkCol1                        no
+  0x0c0a   RightDarkCol2                        no
+  0x0c0b   HMPixThresh                          no
+  0x0c0c   HMColThresh                          no
+  0x0c0d   HMWsize                              no
+  0x0c0e   HMColRejThresh                       no
+  0x0c0f   VMPixThresh                          no
+  0x0c10   VMColThresh                          no
+  0x0c11   VMNbands                             no
+  0x0c12   VMColDropThresh                      no
+  0x0c13   VMPatchResLimit                      no
+  0x0c14   MapScale                             no
+  0x0c1c   Klut                                 no
+  0x0c1d   RimNonlinearity                      no
+  0x0c1e   InverseRimNonlinearity               no
+  0x0c1f   RembrandtToneScale                   no
+  0x0c20   RimToNifColorTransform               no
+  0x0c21   RimToNifScaleFactor                  no
+  0x0c22   NifNonlinearity                      no
+  0x0c23   SBALogTransform                      no
+  0x0c24   InverseSBALogTransform               no
+  0x0c25   SBABlack                             int16u
+  0x0c26   SBAGray                              int16u
+  0x0c27   SBAWhite                             int16u
+  0x0c28   GaussianWeights                      no
+  0x0c29   SfsBoundary                          no
+  0x0c2a   CoringTableBest                      no
+  0x0c2b   CoringTableBetter                    no
+  0x0c2c   CoringTableGood                      no
+  0x0c2d   ExposureReferenceGain                no
+  0x0c2e   ExposureReferenceOffset              no
+  0x0c2f   SBARedBalanceLut                     no
+  0x0c30   SBAGreenBalanceLut                   no
+  0x0c31   SBABlueBalanceLut                    no
+  0x0c32   SBANeutralBAL                        int32s
+  0x0c33   SBAGreenMagentaBAL                   int32s
+  0x0c34   SBAIlluminantBAL                     int32s
+  0x0c35   SBAAnalysisComplete                  int8u
+  0x0c36   JPEGQTableBest                       no
+  0x0c37   JPEGQTableBetter                     no
+  0x0c38   JPEGQTableGood                       no
+  0x0c39   RembrandtPortraitToneScale           no
+  0x0c3a   RembrandtConsumerToneScale           no
+  0x0c3b   CFAGreenThreshold1                   no
+  0x0c3c   CFAGreenThreshold2                   no
+  0x0c3d   QTableLarge50Pct                     no
+  0x0c3e   QTableLarge67Pct                     no
+  0x0c3f   QTableLarge100Pct                    no
+  0x0c40   QTableMedium50Pct                    no
+  0x0c41   QTableMedium67Pct                    no
+  0x0c42   QTableMedium100Pct                   no
+  0x0c43   QTableSmall50Pct                     no
+  0x0c44   QTableSmall67Pct                     no
+  0x0c45   QTableSmall100Pct                    no
+  0x0c46   SBAHighGray                          int16u
+  0x0c47   SBALowGray                           int16u
+  0x0c48   CaptureLook                          int16u
+  0x0c49   SBAIllOffset                         int16s
+  0x0c4a   SBAGmOffset                          int16s
+  0x0c4b   NifNonlinearity12Bit                 no
+  0x0c4c   SharpeningOn                         no
+  0x0c4d   NifNonlinearity16Bit                 no
+  0x0c4e   RawHistogram                         no
+  0x0c4f   RawCFAComponentAverages              no
+  0x0c50   DisableFlagsPresent                  no
+  0x0c51   DelayCols                            no
+  0x0c52   DummyColsLeft                        no
+  0x0c53   TrashColsRight                       no
+  0x0c54   BlackColsRight                       no
+  0x0c55   DummyColsRight                       no
+  0x0c56   OverClockColsRight                   no
+  0x0c57   UnusedBlackRowsTopOut                no
+  0x0c58   TrashRowsBottom                      no
+  0x0c59   BlackRowsBottom                      no
+  0x0c5a   OverClockRowsBottom                  no
+  0x0c5b   BlackColsLeft                        no
+  0x0c5c   BlackRowsTop                         no
+  0x0c5d   PartialActiveColsLeft                no
+  0x0c5e   PartialActiveColsRight               no
+  0x0c5f   PartialActiveRowsTop                 no
+  0x0c60   PartialActiveRowsBottom              no
+  0x0c61   ProcessBorderColsLeft                int16u
+  0x0c62   ProcessBorderColsRight               int16u
+  0x0c63   ProcessBorderRowsTop                 int16u
+  0x0c64   ProcessBorderRowsBottom              int16u
+  0x0c65   ActiveCols                           no
+  0x0c66   ActiveRows                           no
+  0x0c67   FirstLines                           no
+  0x0c68   UnusedBlackRowsTopIn                 no
+  0x0c69   UnusedBlackRowsBottomIn              no
+  0x0c6a   UnusedBlackRowsBottomOut             no
+  0x0c6b   UnusedBlackColsLeftOut               no
+  0x0c6c   UnusedBlackColsLeftIn                no
+  0x0c6d   UnusedBlackColsRightIn               no
+  0x0c6e   UnusedBlackColsRightOut              no
+  0x0c6f   CFAOffsetRows                        int32u
+  0x0c70   ShiftCols                            int16s
+  0x0c71   CFAOffsetCols                        int32u
+  0x0c76   DarkMapScale                         no
+  0x0c77   HMapHandling                         no
+  0x0c78   VMapHandling                         no
+  0x0c79   DarkThreshold                        no
+  0x0c7a   DMDitherMatrix                       int16u
+  0x0c7b   DMDitherMatrixWidth                  int16u
+  0x0c7c   DMDitherMatrixHeight                 int16u
+  0x0c7d   MaxPixelValueThreshold               int16u
+  0x0c7e   HoleFillDeltaThreshold               int16u
+  0x0c7f   DarkPedestal                         int16u
+  0x0c80   ImageProcessingFileTagsVersionNumber int16u
+  0x0c81   ImageProcessingFileDateCreated       string
+  0x0c82   DoublingMicrovolts                   int32s
+  0x0c83   DarkFrameShortExposure               int32u
+  0x0c84   DarkFrameLongExposure                int32u
+  0x0c85   DarkFrameCountFactor                 rational64u
+  0x0c88   HoleFillDarkDeltaThreshold           int16u
+  0x0c89   FarkleWhiteThreshold                 no
+  0x0c8a   ColumnResetOffsets                   no
+  0x0c8b   ColumnGainFactors                    no
+  0x0c8c   Channel0LagKernel                    no
+  0x0c8d   Channel1LagKernel                    no
+  0x0c8e   Channel2LagKernel                    no
+  0x0c8f   Channel3LagKernel                    no
+  0x0c90   BluegrassTable                       no
+  0x0c91   BluegrassScale1                      no
+  0x0c92   BluegrassScale2                      no
+  0x0ce4   FinishedFileProcessingRequest        no
+  0x0ce5   FirmwareVersion                      string
+  0x0ce6   HostSoftwareExportVersion            no
+  0x0ce7   HostSoftwareRendering                int32u
+  0x0dac   DCS3XXProcessingInfoIFD              no
+  0x0dad   DCS3XXProcessingInfo                 no
+  0x0dae   IPAVersion                           int32u
+  0x0db6   FinishIPAVersion                     no
+  0x0db7   FinishIPFVersion                     no
+  0x0db8   FinishFileType                       int32u
+  0x0db9   FinishResolution                     int32u
+  0x0dba   FinishNoise                          int32u
+  0x0dbb   FinishSharpening                     int32u
+  0x0dbc   FinishLook                           int32u
+  0x0dbd   FinishExposure                       int32u
+  0x0e0b   SigmaScalingFactorLowRes             rational64u
+  0x0e0c   SigmaScalingFactorCamera             rational64u
+  0x0e0d   SigmaImpulseParameters               int16u[n]
+  0x0e0e   SigmaNoiseThreshTableV2              no
+  0x0e0f   SigmaSizeTable                       int16u[n]
+  0x0e10   DacGainsCoarseAdjPreIF41             no
+  0x0e11   SigmaNoiseFilterCalTableV1           no
+  0x0e12   SigmaNoiseFilterTableV1              no
+  0x0e13   Lin12ToKlut8                         no
+  0x0e14   SigmaNoiseFilterTableV1Version       no
+  0x0e15   Lin12ToKlut12                        no
+  0x0e16   Klut12ToLin12                        no
+  0x0e17   NifNonlinearity12To16                no
+  0x0e18   SBALog12Transform                    no
+  0x0e19   InverseSBALog12Transform             no
+  0x0e1a   ToneScale0                           no
+  0x0e1b   ToneScale1                           no
+  0x0e1c   ToneScale2                           no
+  0x0e1d   ToneScale3                           no
+  0x0e1e   ToneScale4                           no
+  0x0e1f   ToneScale5                           no
+  0x0e20   ToneScale6                           no
+  0x0e21   ToneScale7                           no
+  0x0e22   ToneScale8                           no
+  0x0e23   ToneScale9                           no
+  0x0e24   DayMat0                              no
+  0x0e25   DayMat1                              no
+  0x0e26   DayMat2                              no
+  0x0e27   DayMat3                              no
+  0x0e28   DayMat4                              no
+  0x0e29   DayMat5                              no
+  0x0e2a   DayMat6                              no
+  0x0e2b   DayMat7                              no
+  0x0e2c   DayMat8                              no
+  0x0e2d   DayMat9                              no
+  0x0e2e   TungMat0                             no
+  0x0e2f   TungMat1                             no
+  0x0e30   TungMat2                             no
+  0x0e31   TungMat3                             no
+  0x0e32   TungMat4                             no
+  0x0e33   TungMat5                             no
+  0x0e34   TungMat6                             no
+  0x0e35   TungMat7                             no
+  0x0e36   TungMat8                             no
+  0x0e37   TungMat9                             no
+  0x0e38   FluorMat0                            no
+  0x0e39   FluorMat1                            no
+  0x0e3a   FluorMat2                            no
+  0x0e3b   FluorMat3                            no
+  0x0e3c   FluorMat4                            no
+  0x0e3d   FluorMat5                            no
+  0x0e3e   FluorMat6                            no
+  0x0e3f   FluorMat7                            no
+  0x0e40   FluorMat8                            no
+  0x0e41   FluorMat9                            no
+  0x0e42   FlashMat0                            no
+  0x0e43   FlashMat1                            no
+  0x0e44   FlashMat2                            no
+  0x0e45   FlashMat3                            no
+  0x0e46   FlashMat4                            no
+  0x0e47   FlashMat5                            no
+  0x0e48   FlashMat6                            no
+  0x0e49   FlashMat7                            no
+  0x0e4a   FlashMat8                            no
+  0x0e4b   FlashMat9                            no
+  0x0e4c   KodakLook                            string
+  0x0e4d   IPFCameraModel                       string
+  0x0e4e   AH2GreenInterpolationThreshold       int16u
+  0x0e4f   ResamplingKernelDenominators067      int16u[3]
+  0x0e50   ResamplingKernelDenominators050      int16u[3]
+  0x0e51   ResamplingKernelDenominators100      int16u[3]
+  0x0e56   LookMat0                             no
+  0x0e57   LookMat1                             no
+  0x0e58   LookMat2                             no
+  0x0e59   LookMat3                             no
+  0x0e5a   LookMat4                             no
+  0x0e5b   LookMat5                             no
+  0x0e5c   LookMat6                             no
+  0x0e5d   LookMat7                             no
+  0x0e5e   LookMat8                             no
+  0x0e5f   LookMat9                             no
+  0x0e60   CFAInterpolationAlgorithm            int16u
+  0x0e61   CFAInterpolationMetric               int16u
+  0x0e62   CFAZipperFixThreshold                int16u
+  0x0e63   NoiseReductionParametersKhufuRGB     int16u[9]
+  0x0e64   NoiseReductionParametersKhufu6MP     int16u[9]
+  0x0e65   NoiseReductionParametersKhufu3MP     int16u[9]
+  0x0e6a   ChromaNoiseHighFThresh               int32u[2]
+  0x0e6b   ChromaNoiseLowFThresh                int32u[2]
+  0x0e6c   ChromaNoiseEdgeMapThresh             int32u
+  0x0e6d   ChromaNoiseColorSpace                int32u
+  0x0e6e   EnableChromaNoiseReduction           int16u
+  0x0e6f   NoiseReductionParametersHostRGB      int16u[9]
+  0x0e70   NoiseReductionParametersHost6MP      int16u[9]
+  0x0e71   NoiseReductionParametersHost3MP      int16u[9]
+  0x0e72   NoiseReductionParametersCamera       int16u[6]
+  0x0e73   NoiseReductionParametersAtCapture    int16u[6]
+  0x0e74   LCDMatrix                            rational64s[9]
+  0x0e75   LCDMatrixChickFix                    rational64s[9]
+  0x0e76   LCDMatrixMarvin                      rational64s[9]
+  0x0e7c   LCDGammaTableChickFix                no
+  0x0e7d   LCDGammaTableMarvin                  no
+  0x0e7e   LCDGammaTable                        no
+  0x0e7f   LCDSharpeningF1                      no
+  0x0e80   LCDSharpeningF2                      no
+  0x0e81   LCDSharpeningF3                      no
+  0x0e82   LCDSharpeningF4                      no
+  0x0e83   LCDEdgeMapX1                         no
+  0x0e84   LCDEdgeMapX2                         no
+  0x0e85   LCDEdgeMapX3                         no
+  0x0e86   LCDEdgeMapX4                         no
+  0x0e87   LCDEdgeMapSlope                      no
+  0x0e88   YCrCbMatrix                          no
+  0x0e89   LCDEdgeSpline                        no
+  0x0e92   Fac18Per                             int16u
+  0x0e93   Fac170Per                            int16u
+  0x0e94   Fac100Per                            int16u
+  0x0e9b   ExtraTickLocations                   no
+  0x0e9c   RGBtoeV0                             no
+  0x0e9d   RGBtoeV1                             no
+  0x0e9e   RGBtoeV2                             no
+  0x0e9f   RGBtoeV3                             no
+  0x0ea0   RGBtoeV4                             no
+  0x0ea1   RGBtoeV5                             no
+  0x0ea2   RGBtoeV6                             no
+  0x0ea3   RGBtoeV7                             no
+  0x0ea4   RGBtoeV8                             no
+  0x0ea5   RGBtoeV9                             no
+  0x0ea6   LCDHistLUT0                          no
+  0x0ea7   LCDHistLUT1                          no
+  0x0ea8   LCDHistLUT2                          no
+  0x0ea9   LCDHistLUT3                          no
+  0x0eaa   LCDHistLUT4                          no
+  0x0eab   LCDHistLUT5                          no
+  0x0eac   LCDHistLUT6                          no
+  0x0ead   LCDHistLUT7                          no
+  0x0eae   LCDHistLUT8                          no
+  0x0eaf   LCDHistLUT9                          no
+  0x0eb0   LCDLinearClipValue                   no
+  0x0ece   LCDStepYvalues                       no
+  0x0ecf   LCDStepYvaluesChickFix               no
+  0x0ed0   LCDStepYvaluesMarvin                 no
+  0x0ed8   InterpolationCoefficients            no
+  0x0ed9   InterpolationCoefficients6MP         no
+  0x0eda   InterpolationCoefficients3MP         no
+  0x0f00   NoiseReductionParametersHostNormal   no
+  0x0f01   NoiseReductionParametersHostStrong   no
+  0x0f02   NoiseReductionParametersHostLow      no
+  0x0f0a   MariahTextureThreshold               int16u
+  0x0f0b   MariahMapLoThreshold                 int16u
+  0x0f0c   MariahMapHiThreshold                 int16u
+  0x0f0d   MariahChromaBlurSize                 int16u
+  0x0f0e   MariahSigmaThreshold                 int16u
+  0x0f0f   MariahThresholds                     no
+  0x0f10   MariahThresholdsNormal               no
+  0x0f11   MariahThresholdsStrong               no
+  0x0f12   MariahThresholdsLow                  no
+  0x0f14   KhufuLinearRedMixingCoefficient      no
+  0x0f15   KhufuLinearGreenMixingCoefficient    no
+  0x0f16   KhufuLinearBlueMixingCoefficient     no
+  0x0f17   KhufuUSpaceC2MixingCoefficient       no
+  0x0f18   KhufuSigmaGaussianWeights            no
+  0x0f19   KhufuSigmaScalingFactors6MP          no
+  0x0f1a   KhufuSigmaScalingFactors3MP          no
+  0x0f1b   KhufuSigmaScalingFactors14MP         no
+  0x0f32   KhufuI0Thresholds                    no
+  0x0f33   KhufuI1Thresholds                    no
+  0x0f34   KhufuI2Thresholds                    no
+  0x0f35   KhufuI3Thresholds                    no
+  0x0f36   KhufuI4Thresholds                    no
+  0x0f37   KhufuI5Thresholds                    no
+  0x0f3c   CondadoDayBVThresh                   int16u
+  0x0f3d   CondadoNeuRange                      int16u
+  0x0f3e   CondadoBVFactor                      int16s
+  0x0f3f   CondadoIllFactor                     int16s
+  0x0f40   CondadoTunThresh                     int16s
+  0x0f41   CondadoFluThresh                     int16s
+  0x0f42   CondadoDayOffsets                    int16s[2]
+  0x0f43   CondadoTunOffsets                    int16s[2]
+  0x0f44   CondadoFluOffsets                    int16s[2]
+  0x0f5a   ERIMMToCRGB0Spline                   no
+  0x0f5b   ERIMMToCRGB1Spline                   no
+  0x0f5c   ERIMMToCRGB2Spline                   no
+  0x0f5d   ERIMMToCRGB3Spline                   no
+  0x0f5e   ERIMMToCRGB4Spline                   no
+  0x0f5f   ERIMMToCRGB5Spline                   no
+  0x0f60   ERIMMToCRGB6Spline                   no
+  0x0f61   ERIMMToCRGB7Spline                   no
+  0x0f62   ERIMMToCRGB8Spline                   no
+  0x0f63   ERIMMToCRGB9Spline                   no
+  0x0f64   CRGBToERIMM0Spline                   no
+  0x0f65   CRGBToERIMM1Spline                   no
+  0x0f66   CRGBToERIMM2Spline                   no
+  0x0f67   CRGBToERIMM3Spline                   no
+  0x0f68   CRGBToERIMM4Spline                   no
+  0x0f69   CRGBToERIMM5Spline                   no
+  0x0f6a   CRGBToERIMM6Spline                   no
+  0x0f6b   CRGBToERIMM7Spline                   no
+  0x0f6c   CRGBToERIMM8Spline                   no
+  0x0f6d   CRGBToERIMM9Spline                   no
+  0x0f6e   ERIMMNonLinearitySpline              no
+  0x0f6f   Delta12To8Spline                     no
+  0x0f70   Delta8To12Spline                     no
+  0x0f71   InverseMonitorMatrix                 no
+  0x0f72   NifNonlinearityExt                   no
+  0x0f73   InvNifNonLinearity                   no
+  0x0f74   RIMM13ToERIMM12Spline                no
+  0x0f78   ToneScale0Spline                     no
+  0x0f79   ToneScale1Spline                     no
+  0x0f7a   ToneScale2Spline                     no
+  0x0f7b   ToneScale3Spline                     no
+  0x0f7c   ToneScale4Spline                     no
+  0x0f7d   ToneScale5Spline                     no
+  0x0f7e   ToneScale6Spline                     no
+  0x0f7f   ToneScale7Spline                     no
+  0x0f80   ToneScale8Spline                     no
+  0x0f81   ToneScale9Spline                     no
+  0x0f82   ERIMMToneScale0Spline                no
+  0x0f83   ERIMMToneScale1Spline                no
+  0x0f84   ERIMMToneScale2Spline                no
+  0x0f85   ERIMMToneScale3Spline                no
+  0x0f86   ERIMMToneScale4Spline                no
+  0x0f87   ERIMMToneScale5Spline                no
+  0x0f88   ERIMMToneScale6Spline                no
+  0x0f89   ERIMMToneScale7Spline                no
+  0x0f8a   ERIMMToneScale8Spline                no
+  0x0f8b   ERIMMToneScale9Spline                no
+  0x0f8c   RIMMToCRGB0Spline                    no
+  0x0f8d   RIMMToCRGB1Spline                    no
+  0x0f8e   RIMMToCRGB2Spline                    no
+  0x0f8f   RIMMToCRGB3Spline                    no
+  0x0f90   RIMMToCRGB4Spline                    no
+  0x0f91   RIMMToCRGB5Spline                    no
+  0x0f92   RIMMToCRGB6Spline                    no
+  0x0f93   RIMMToCRGB7Spline                    no
+  0x0f94   RIMMToCRGB8Spline                    no
+  0x0f95   RIMMToCRGB9Spline                    no
+  0x0fa0   QTableLarge25Pct                     no
+  0x0fa1   QTableMedium25Pct                    no
+  0x0fa2   QTableSmall25Pct                     no
+  0x1130   NoiseReductionKernel                 no
+  0x1388   UserMetaData                         no
+  0x1389   InputProfile                         undef
+  0x138a   KodakLookProfile                     undef
+  0x138b   OutputProfile                        undef
+  0x1390   SourceProfilePrefix                  string
+  0x1391   ToneCurveProfileName                 string
+  0x1392   InputProfile                         ICC_Profile
+  0x1393   ProcessParametersV2                  no
+  0x1394   ReservedBlob2                        no
+  0x1395   ReservedBlob3                        no
+  0x1396   ReservedBlob4                        no
+  0x1397   ReservedBlob5                        no
+  0x1398   ReservedBlob6                        no
+  0x1399   ReservedBlob7                        no
+  0x139a   ReservedBlob8                        no
+  0x139b   ReservedBlob9                        no
+  0x1770   ScriptVersion                        int32u
+  0x177a   ImagerTimingData                     no
+  0x1784   ISO                                  int32u
+  0x17a2   Scav11Cols                           no
+  0x17a3   Scav12Cols                           no
+  0x17a4   Scav21Cols                           no
+  0x17a5   Scav22Cols                           no
+  0x17a6   ActiveCTEMonitor1Cols                no
+  0x17a7   ActiveCTEMonitor2Cols                no
+  0x17a8   ActiveCTEMonitorRows                 no
+  0x17a9   ActiveBuf1Cols                       no
+  0x17aa   ActiveBuf2Cols                       no
+  0x17ab   ActiveBuf1Rows                       no
+  0x17ac   ActiveBuf2Rows                       no
+  0x17c0   HRNoiseLines                         no
+  0x17c1   RNoiseLines                          no
+  0x17c2   ANoiseLines                          no
+  0x17d4   ImagerCols                           int16u
+  0x17de   ImagerRows                           int16u
+  0x17e8   PartialActiveCols1                   int32u
+  0x17f2   PartialActiveCols2                   int32u
+  0x17fc   PartialActiveRows1                   int32u
+  0x1806   PartialActiveRows2                   int32u
+  0x1810   ElectricalBlackColumns               int32u
+  0x181a   ResetBlackSegRows                    int32u
+  0x1838   CaptureWidthNormal                   int32u
+  0x1839   CaptureHeightNormal                  int32u
+  0x183a   CaptureWidthResetBlackSegNormal      no
+  0x183b   CaptureHeightResetBlackSegNormal     no
+  0x183c   DarkRefOffsetNormal                  no
+  0x1842   CaptureWidthTest                     int32u
+  0x1843   CaptureHeightTest                    no
+  0x1844   CaptureWidthResetBlackSegTest        no
+  0x1845   CaptureHeightResetBlackSegTest       no
+  0x1846   DarkRefOffsetTest                    no
+  0x184c   ImageSegmentStartLine                int32u
+  0x184d   ImageSegmentLines                    int32u
+  0x184e   SkipLineTime                         int32u
+  0x1860   FastResetLineTime                    int32u
+  0x186a   NormalLineTime                       int32u
+  0x1874   MinIntegrationRows                   int32u
+  0x187e   PreReadFastResetCount                int32u
+  0x1888   TransferTimeNormal                   int32u
+  0x1889   TransferTimeTest                     int32u
+  0x188a   QuietTime                            int32u
+  0x189c   OverClockCols                        int16u
+  0x18a6   H2ResetBlackPixels                   int32u
+  0x18b0   H3ResetBlackPixels                   int32u
+  0x18ba   BlackAcquireRows                     int32u
+  0x18c4   OverClockRows                        int16u
+  0x18ce   H3ResetBlackColumns                  int32u
+  0x18d8   DarkBlackSegRows                     int32u
+  0x1900   CrossbarEnable                       no
+  0x1901   FifoenOnePixelDelay                  int32u
+  0x1902   ReadoutTypeRequested                 int32u
+  0x1903   ReadoutTypeActual                    int32u
+  0x190a   OffsetDacValue                       int32u
+  0x1914   TempAmpGainX100                      int32u
+  0x191e   VarrayDacNominalValues               int32u[3]
+  0x1928   VddimDacNominalValues                no
+  0x1964   C14Configuration                     int32u
+  0x196e   TDA1Offset                           int32u[3]
+  0x196f   TDA1Bandwidth                        int32u
+  0x1970   TDA1Gain                             int32u[3]
+  0x1971   TDA1EdgePolarity                     int32u
+  0x1978   TDA2Offset                           int32u[3]
+  0x1979   TDA2Bandwidth                        int32u
+  0x197a   TDA2Gain                             int32u[3]
+  0x197b   TDA2EdgePolarity                     int32u
+  0x1982   TDA3Offset                           int32u[3]
+  0x1983   TDA3Bandwidth                        int32u
+  0x1984   TDA3Gain                             int32u[3]
+  0x1985   TDA3EdgePolarity                     int32u
+  0x198c   TDA4Offset                           int32u[3]
+  0x198d   TDA4Bandwidth                        int32u
+  0x198e   TDA4Gain                             int32u[3]
+  0x198f   TDA4EdgePolarity                     int32u
+  0xfde8   ComLenBlkSize                        int16u
+
+=head3 Kodak TextualInfo Tags
+
+Below is a list of tags which have been observed in the Kodak TextualInfo
+data, however ExifTool will extract information from any tags found here.
+
+  Tag ID                Tag Name                Writable
+  ------                --------                --------
+  'AF Function'         AFMode                  no
+  'Actual Compensation' ActualCompensation      no
+  'Aperture'            Aperture                no
+  'Auto Bracket'        AutoBracket             no
+  'Brightness Value'    BrightnessValue         no
+  'Camera'              CameraModel             no
+  'Camera body'         CameraBody              no
+  'Compensation'        ExposureCompensation    no
+  'Date'                Date                    no
+  'Exposure Bias'       ExposureBias            no
+  'Exposure Mode'       ExposureMode            no
+  'Firmware Version'    FirmwareVersion         no
+  'Flash Compensation'  FlashExposureComp       no
+  'Flash Fired'         FlashFired              no
+  'Flash Sync Mode'     FlashSyncMode           no
+  'Focal Length'        FocalLength             no
+  'Height'              KodakImageHeight        no
+  '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
+  'Popup Flash'         PopupFlash              no
+  'Serial Number'       SerialNumber            no
+  'Shooting Mode'       ShootingMode            no
+  'Shutter'             ShutterSpeed            no
+  'Temperature'         Temperature             no
+  'Time'                Time                    no
+  'White balance'       WhiteBalance            no
+  'Width'               KodakImageWidth         no
+  '_other_info'         OtherInfo               no
+
+=head3 Kodak Processing Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+     20    WB_RGBLevels                         no
+
 =head3 Kodak Type2 Tags
 
@@ -5706,6 +11110,6 @@
 and Minolta EX1500Z.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       8    KodakMaker                           string[32]
      40    KodakModel                           string[32]
@@ -5717,6 +11121,6 @@
 These tags are used by the DC240, DC280, DC3400 and DC5000.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
      12    YearCreated                          int16u
      14    MonthDayCreated                      int8u[2]
@@ -5732,6 +11136,6 @@
 These tags are used by the DC200 and DC215.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
      32    OriginalFileName                     string[12]
 
@@ -5741,6 +11145,6 @@
 and CX6230.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
      20    ExposureTime                         int32u
      26    WhiteBalance                         int8u
@@ -5757,6 +11161,6 @@
 These tags are used by the DX3215 and DX3700.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
      16    ExposureTime                         int32u
      20    ISOSetting?                          int32u
@@ -5776,6 +11180,6 @@
 by 8 digits.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    SerialNumber                         string[16]
 
@@ -5831,6 +11235,6 @@
   0xfa54   ThumbnailWidth                       int16u
   0xfa55   ThumbnailHeight                      int16u
-  0xfa57   PreviewWidth                         int16u
-  0xfa58   PreviewHeight                        int16u
+  0xfa57   PreviewImageWidth                    int16u
+  0xfa58   PreviewImageHeight                   int16u
 
 =head3 Kodak SubIFD1 Tags
@@ -5904,6 +11308,6 @@
 M550, as well as various cameras marketed by other manufacturers.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
      12    FNumber                              int16u
      16    ExposureTime                         int32u
@@ -5911,5 +11315,6 @@
      52    ISO                                  int16u
      87    FirmwareVersion                      string[16]
-    168    SerialNumber                         string[12]
+    168    UnknownNumber                        no
+    196    UnknownNumber                        no
 
 =head3 Kodak Type10 Tags
@@ -5926,88 +11331,31 @@
   0x001d   FocalLength                          int32u
 
+=head3 Kodak Type11 Tags
+
+These tags are found in models such as the PixPro S-1.  They are not
+writable because the inconsistency of Kodak maker notes is beginning to get
+on my nerves.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0104   FirmwareVersion                      no
+  0x0203   PictureEffect                        no
+  0x0207   KodakModel                           no
+  0x0300   KodakMake                            no
+  0x0308   LensSerialNumber                     no
+  0x0309   LensModel                            no
+  0x030d   LevelMeter?                          no
+  0x0311   Pitch                                no
+  0x0312   Yaw                                  no
+  0x0313   Roll                                 no
+  0x0314   CX?                                  no
+  0x0315   CY?                                  no
+  0x0316   Rads?                                no
+
 =head3 Kodak Unknown Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
-
-=head3 Kodak IFD Tags
-
-These tags are found in a separate IFD of JPEG, TIFF, DCR and KDC images
-from some older Kodak models such as the DC50, DC120, DCS760C, DCS Pro 14N,
-14nx, SLR/n, Pro Back and Canon EOS D2000.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  0x0001   UnknownEV?                           rational64u
-  0x0003   ExposureValue                        rational64u
-  0x03e9   OriginalFileName                     string
-  0x03eb   SensorLeftBorder                     N
-  0x03ec   SensorTopBorder                      N
-  0x03ed   SensorImageWidth                     N
-  0x03ee   SensorImageHeight                    N
-  0x03f1   TextualInfo                          Kodak TextualInfo
-  0x03fc   WhiteBalance                         int16u
-  0x03fd   Processing                           Kodak Processing
-  0x0401   Time                                 string
-  0x0414   NCDFileInfo                          string
-  0x0846   ColorTemperature                     int16u
-  0x0852   WB_RGBMul0                           N
-  0x0853   WB_RGBMul1                           N
-  0x0854   WB_RGBMul2                           N
-  0x0855   WB_RGBMul3                           N
-  0x085c   WB_RGBCoeffs0                        N
-  0x085d   WB_RGBCoeffs1                        N
-  0x085e   WB_RGBCoeffs2                        N
-  0x085f   WB_RGBCoeffs3                        N
-  0x0ce5   FirmwareVersion                      string
-  0x1391   ToneCurveFileName                    string
-  0x1784   ISO                                  int32u
-
-=head3 Kodak TextualInfo Tags
-
-Below is a list of tags which have been observed in the Kodak TextualInfo
-data, however ExifTool will extract information from any tags found here.
-
-  Tag ID                Tag Name                Writable
-  ------                --------                --------
-  'AF Function'         AFMode                  N
-  'Actual Compensation' ActualCompensation      N
-  'Aperture'            Aperture                N
-  'Auto Bracket'        AutoBracket             N
-  'Brightness Value'    BrightnessValue         N
-  'Camera'              CameraModel             N
-  'Camera body'         CameraBody              N
-  'Compensation'        ExposureCompensation    N
-  'Date'                Date                    N
-  'Exposure Bias'       ExposureBias            N
-  'Exposure Mode'       ExposureMode            N
-  'Firmware Version'    FirmwareVersion         N
-  'Flash Compensation'  FlashExposureComp       N
-  'Flash Fired'         FlashFired              N
-  'Flash Sync Mode'     FlashSyncMode           N
-  'Focal Length'        FocalLength             N
-  'Height'              KodakImageHeight        N
-  'ISO'                 ISO                     N
-  'ISO Speed'           ISO                     N
-  'Image Number'        ImageNumber             N
-  'Max Aperture'        MaxAperture             N
-  'Meter Mode'          MeterMode               N
-  'Min Aperture'        MinAperture             N
-  'Popup Flash'         PopupFlash              N
-  'Serial Number'       SerialNumber            N
-  'Shooting Mode'       ShootingMode            N
-  'Shutter'             ShutterSpeed            N
-  'Temperature'         Temperature             N
-  'Time'                Time                    N
-  'White balance'       WhiteBalance            N
-  'Width'               KodakImageWidth         N
-  '_other_info'         OtherInfo               N
-
-=head3 Kodak Processing Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     20    WB_RGBLevels                         N
 
 =head3 Kodak Meta Tags
@@ -6020,38 +11368,38 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0xc350   FilmProductCode                      N
-  0xc351   ImageSourceEK                        N
-  0xc352   CaptureConditionsPAR                 N
+  0xc350   FilmProductCode                      no
+  0xc351   ImageSourceEK                        no
+  0xc352   CaptureConditionsPAR                 no
   0xc353   CameraOwner                          undef
   0xc354   SerialNumber                         undef
-  0xc355   UserSelectGroupTitle                 N
-  0xc356   DealerIDNumber                       N
-  0xc357   CaptureDeviceFID                     N
-  0xc358   EnvelopeNumber                       N
-  0xc359   FrameNumber                          N
-  0xc35a   FilmCategory                         N
-  0xc35b   FilmGencode                          N
-  0xc35c   ModelAndVersion                      N
-  0xc35d   FilmSize                             N
-  0xc35e   SBA_RGBShifts                        N
-  0xc35f   SBAInputImageColorspace              N
-  0xc360   SBAInputImageBitDepth                N
-  0xc361   SBAExposureRecord                    N
-  0xc362   UserAdjSBA_RGBShifts                 N
-  0xc363   ImageRotationStatus                  N
-  0xc364   RollGuidElements                     N
-  0xc365   MetadataNumber                       N
-  0xc366   EditTagArray                         N
-  0xc367   Magnification                        N
-  0xc36c   NativeXResolution                    N
-  0xc36d   NativeYResolution                    N
+  0xc355   UserSelectGroupTitle                 no
+  0xc356   DealerIDNumber                       no
+  0xc357   CaptureDeviceFID                     no
+  0xc358   EnvelopeNumber                       no
+  0xc359   FrameNumber                          no
+  0xc35a   FilmCategory                         no
+  0xc35b   FilmGencode                          no
+  0xc35c   ModelAndVersion                      no
+  0xc35d   FilmSize                             no
+  0xc35e   SBA_RGBShifts                        no
+  0xc35f   SBAInputImageColorspace              no
+  0xc360   SBAInputImageBitDepth                no
+  0xc361   SBAExposureRecord                    no
+  0xc362   UserAdjSBA_RGBShifts                 no
+  0xc363   ImageRotationStatus                  no
+  0xc364   RollGuidElements                     no
+  0xc365   MetadataNumber                       no
+  0xc366   EditTagArray                         no
+  0xc367   Magnification                        no
+  0xc36c   NativeXResolution                    no
+  0xc36d   NativeYResolution                    no
   0xc36e   KodakEffectsIFD                      Kodak SpecialEffects
   0xc36f   KodakBordersIFD                      Kodak Borders
-  0xc37a   NativeResolutionUnit                 N
-  0xc418   SourceImageDirectory                 N
-  0xc419   SourceImageFileName                  N
-  0xc41a   SourceImageVolumeName                N
-  0xc46c   PrintQuality                         N
-  0xc46e   ImagePrintStatus                     N
+  0xc37a   NativeResolutionUnit                 no
+  0xc418   SourceImageDirectory                 no
+  0xc419   SourceImageFileName                  no
+  0xc41a   SourceImageVolumeName                no
+  0xc46c   PrintQuality                         no
+  0xc46e   ImagePrintStatus                     no
 
 =head3 Kodak SpecialEffects Tags
@@ -6062,7 +11410,7 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   DigitalEffectsVersion                N
-  0x0001   DigitalEffectsName                   N
-  0x0002   DigitalEffectsType                   N
+  0x0000   DigitalEffectsVersion                no
+  0x0001   DigitalEffectsName                   no
+  0x0002   DigitalEffectsType                   no
 
 =head3 Kodak Borders Tags
@@ -6070,10 +11418,10 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   BordersVersion                       N
-  0x0001   BorderName                           N
-  0x0002   BorderID                             N
-  0x0003   BorderLocation                       N
-  0x0004   BorderType                           N
-  0x0008   WatermarkType                        N
+  0x0000   BordersVersion                       no
+  0x0001   BorderName                           no
+  0x0002   BorderID                             no
+  0x0003   BorderLocation                       no
+  0x0004   BorderType                           no
+  0x0008   WatermarkType                        no
 
 =head3 Kodak KDC_IFD Tags
@@ -6086,23 +11434,97 @@
   0xfa00   SerialNumber                         string
   0xfa0d   WhiteBalance                         int8u
-  0xfa25   WB_RGBLevelsAuto                     N
-  0xfa27   WB_RGBLevelsTungsten                 N
-  0xfa28   WB_RGBLevelsFluorescent              N
-  0xfa29   WB_RGBLevelsDaylight                 N
-  0xfa2a   WB_RGBLevelsShade                    N
+  0xfa25   WB_RGBLevelsAuto                     no
+  0xfa27   WB_RGBLevelsTungsten                 no
+  0xfa28   WB_RGBLevelsFluorescent              no
+  0xfa29   WB_RGBLevelsDaylight                 no
+  0xfa2a   WB_RGBLevelsShade                    no
+
+=head3 Kodak frea Tags
+
+Information stored in the "frea" atom of Kodak PixPro SP360 MP4 videos.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'scra'   PreviewImage                         no
+  'thma'   ThumbnailImage                       no
+  'tima'   Duration                             no
+  'ver '   KodakVersion                         no
+
+=head3 Kodak Free Tags
+
+Information stored in the "free" atom of Kodak MP4 videos. (VERY bad form
+for Kodak to store useful information in an atom intended for unused space!)
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'AprV'   ApertureValue                        no
+  'BrtV'   BrightnessValue                      no
+  'Expc'   ExposureCompensation                 no
+  'Expo'   ExposureTime                         no
+  'FL35'   FocalLengthIn35mmFormat              no
+  'FNum'   FNumber                              no
+  'FoLn'   FocalLength                          no
+  'ISOS'   ISO                                  no
+  'SVer'   FirmwareVersion                      no
+  'Scrn'   PreviewInfo                          Kodak Scrn
+  'Seri'   SerialNumber                         no
+  'StSV'   ShutterSpeedValue                    no
+
+=head3 Kodak Scrn Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    PreviewImageWidth                    no
+      1    PreviewImageHeight                   no
+      2    PreviewImageLength                   no
+      4    PreviewImage                         no
+
+=head3 Kodak DcMD Tags
+
+Metadata directory found in MOV and MP4 videos from some Kodak cameras.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'CMbo'   CameraByteOrder                      no
+  'Cmbo'   CameraByteOrder                      no
+  'DcEM'   DcEM                                 Kodak DcEM
+  'DcME'   DcME                                 Kodak DcME
+
+=head3 Kodak DcEM Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 Kodak DcME Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
 
 =head3 Kodak MOV Tags
 
-This information is found in Kodak MOV videos from models such as the P880.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     22    Model                                N
-     64    ModelType                            N
-     78    ExposureTime                         N
-     82    FNumber                              N
-     90    ExposureCompensation                 N
-    112    FocalLength                          N
+This information is found in the TAGS atom of MOV videos from Kodak models
+such as the P880.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     22    Model                                no
+     64    ModelType                            no
+     78    ExposureTime                         no
+     82    FNumber                              no
+     90    ExposureCompensation                 no
+    112    FocalLength                          no
+
+=head3 Kodak pose Tags
+
+Streamed orientation information from the PixPro 4KVR360, extracted as
+sub-documents when the Duplicates option is used.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Accelerometer'      Accelerometer            no
+  'AngularVelocity'    AngularVelocity          no
 
 =head2 Leaf Tags
@@ -6116,15 +11538,15 @@
   Tag ID                          Tag Name      Writable
   ------                          --------      --------
-  'JPEG_preview_data'             PreviewImage  undef
-  'JPEG_preview_info'             PreviewInfo   N
-  'PDA_histogram_data'            PDAHistogram  N
-  'back_serial_number'            BackSerial    N
+  'JPEG_preview_data'             PreviewImage  no
+  'JPEG_preview_info'             PreviewInfo   no
+  'PDA_histogram_data'            PDAHistogram  no
+  'back_serial_number'            BackSerial    no
   'camera_profile'                CameraProfile Leaf CameraProfile
   'icc_camera_profile'            ICC_Profile   ICC_Profile
-  'icc_camera_to_tone_matrix'     ToneMatrix    N
-  'icc_camera_to_tone_space_flow' ToneSpaceFlow N
+  'icc_camera_to_tone_matrix'     ToneMatrix    no
+  'icc_camera_to_tone_space_flow' ToneSpaceFlow no
   'icc_rgb_ws_profile'            RGB_Profile   ICC_Profile
-  'image_offset'                  ImageOffset   N
-  'pattern_ratation_angle'        PatternAngle  N
+  'image_offset'                  ImageOffset   no
+  'pattern_ratation_angle'        PatternAngle  no
 
 =head3 Leaf CameraProfile Tags
@@ -6135,10 +11557,10 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'back_type'          CameraBackType           N
+  'back_type'          CameraBackType           no
   'capture_profile'    CaptureProfile           Leaf CaptureProfile
   'image_profile'      ImageProfile             Leaf ImageProfile
-  'name'               CameraName               N
-  'type'               CameraType               N
-  'version'            CameraProfileVersion     N
+  'name'               CameraName               no
+  'type'               CameraType               no
+  'version'            CameraProfileVersion     no
 
 =head3 Leaf CaptureProfile Tags
@@ -6149,27 +11571,27 @@
   Tag ID                 Tag Name               Writable
   ------                 --------               --------
-  'CCD_rect'             CCDRect                N
-  'CCD_valid_rect'       CCDValidRect           N
-  'CCD_video_rect'       CCDVideoRect           N
-  'back_type'            CaptProfBackType       N
-  'center_dark_rect'     CenterDarkRect         N
-  'color_averages'       ColorAverages          N
-  'color_matrix'         ColorMatrix            N
-  'dark_correction_type' DarkCorrectionType     N
-  'image_bounds'         ImageBounds            N
-  'image_fields'         ImageFields            N
-  'image_offset'         ImageOffset            N
-  'left_dark_rect'       LeftDarkRect           N
-  'luminance_consts'     LuminanceConsts        N
-  'mosaic_pattern'       MosaicPattern          N
-  'name'                 CaptProfName           N
-  'number_of_planes'     NumberOfPlanes         N
-  'raw_data_rotation'    RawDataRotation        N
-  'reconstruction_type'  ReconstructionType     N
-  'right_dark_rect'      RightDarkRect          N
-  'serial_number'        CaptureSerial          N
-  'type'                 CaptProfType           N
-  'version'              CaptProfVersion        N
-  'xy_offset_info'       XYOffsetInfo           N
+  'CCD_rect'             CCDRect                no
+  'CCD_valid_rect'       CCDValidRect           no
+  'CCD_video_rect'       CCDVideoRect           no
+  'back_type'            CaptProfBackType       no
+  'center_dark_rect'     CenterDarkRect         no
+  'color_averages'       ColorAverages          no
+  'color_matrix'         ColorMatrix            no
+  'dark_correction_type' DarkCorrectionType     no
+  'image_bounds'         ImageBounds            no
+  'image_fields'         ImageFields            no
+  'image_offset'         ImageOffset            no
+  'left_dark_rect'       LeftDarkRect           no
+  'luminance_consts'     LuminanceConsts        no
+  'mosaic_pattern'       MosaicPattern          no
+  'name'                 CaptProfName           no
+  'number_of_planes'     NumberOfPlanes         no
+  'raw_data_rotation'    RawDataRotation        no
+  'reconstruction_type'  ReconstructionType     no
+  'right_dark_rect'      RightDarkRect          no
+  'serial_number'        CaptureSerial          no
+  'type'                 CaptProfType           no
+  'version'              CaptProfVersion        no
+  'xy_offset_info'       XYOffsetInfo           no
 
 =head3 Leaf ImageProfile Tags
@@ -6180,11 +11602,11 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'back_type'          ImgProfBackType          N
-  'image_status'       ImageStatus              N
-  'name'               ImgProfName              N
-  'rotation_angle'     RotationAngle            N
+  'back_type'          ImgProfBackType          no
+  'image_status'       ImageStatus              no
+  'name'               ImgProfName              no
+  'rotation_angle'     RotationAngle            no
   'shoot_setup'        ShootSetup               Leaf ShootSetup
-  'type'               ImgProfType              N
-  'version'            ImgProfVersion           N
+  'type'               ImgProfType              no
+  'version'            ImgProfVersion           no
 
 =head3 Leaf ShootSetup Tags
@@ -6195,13 +11617,13 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'back_type'          ShootObjBackType         N
+  'back_type'          ShootObjBackType         no
   'camera_setup'       CameraSetup              Leaf CameraSetup
   'capture_setup'      CaptureSetup             Leaf CaptureSetup
   'color_setup'        ColorSetup               Leaf ColorSetup
   'look_header'        LookHeader               Leaf LookHeader
-  'name'               ShootObjName             N
+  'name'               ShootObjName             no
   'save_setup'         SaveSetup                Leaf SaveSetup
-  'type'               ShootObjType             N
-  'version'            ShootObjVersion          N
+  'type'               ShootObjType             no
+  'version'            ShootObjVersion          no
 
 =head3 Leaf CameraSetup Tags
@@ -6212,13 +11634,13 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'ISO_speed'          ISOSpeed                 N
-  'back_type'          CameraObjBackType        N
-  'camera_type'        CameraType               N
-  'lens_ID'            LensID                   N
-  'lens_type'          LensType                 N
-  'name'               CameraObjName            N
-  'strobe'             Strobe                   N
-  'type'               CameraObjType            N
-  'version'            CameraObjVersion         N
+  'ISO_speed'          ISOSpeed                 no
+  'back_type'          CameraObjBackType        no
+  'camera_type'        CameraType               no
+  'lens_ID'            LensID                   no
+  'lens_type'          LensType                 no
+  'name'               CameraObjName            no
+  'strobe'             Strobe                   no
+  'type'               CameraObjType            no
+  'version'            CameraObjVersion         no
 
 =head3 Leaf CaptureSetup Tags
@@ -6229,14 +11651,14 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Multi_quality'      MultiQuality             N
-  'back_type'          CaptureObjBackType       N
-  'name'               CaptureObjName           N
+  'Multi_quality'      MultiQuality             no
+  'back_type'          CaptureObjBackType       no
+  'name'               CaptureObjName           no
   'neutals'            Neutals                  Leaf Neutrals
   'selection'          Selection                Leaf Selection
   'sharpness'          Sharpness                Leaf Sharpness
-  'single_quality'     SingleQuality            N
+  'single_quality'     SingleQuality            no
   'tone_curve'         ToneCurve                Leaf ToneCurve
-  'type'               CaptureObjType           N
-  'version'            CaptureObjVersion        N
+  'type'               CaptureObjType           no
+  'version'            CaptureObjVersion        no
 
 =head3 Leaf Neutrals Tags
@@ -6247,12 +11669,12 @@
   Tag ID                 Tag Name               Writable
   ------                 --------               --------
-  'back_type'            NeutObjBackType        N
-  'color_casts'          ColorCasts             N
-  'highlight_end_points' HighlightEndPoints     N
-  'name'                 NeutObjName            N
-  'neutrals'             Neutrals               N
-  'shadow_end_points'    ShadowEndPoints        N
-  'type'                 NeutObjType            N
-  'version'              NeutObjVersion         N
+  'back_type'            NeutObjBackType        no
+  'color_casts'          ColorCasts             no
+  'highlight_end_points' HighlightEndPoints     no
+  'name'                 NeutObjName            no
+  'neutrals'             Neutrals               no
+  'shadow_end_points'    ShadowEndPoints        no
+  'type'                 NeutObjType            no
+  'version'              NeutObjVersion         no
 
 =head3 Leaf Selection Tags
@@ -6263,13 +11685,13 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'back_type'          SelObjBackType           N
-  'locks'              Locks                    N
-  'name'               SelObjName               N
-  'orientation'        Orientation              N
-  'rect'               Rect                     N
-  'resolution'         Resolution               N
-  'scale'              Scale                    N
-  'type'               SelObjType               N
-  'version'            SelObjVersion            N
+  'back_type'          SelObjBackType           no
+  'locks'              Locks                    no
+  'name'               SelObjName               no
+  'orientation'        Orientation              no
+  'rect'               Rect                     no
+  'resolution'         Resolution               no
+  'scale'              Scale                    no
+  'type'               SelObjType               no
+  'version'            SelObjVersion            no
 
 =head3 Leaf Sharpness Tags
@@ -6280,11 +11702,11 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'back_type'          SharpObjBackType         N
-  'data_len'           DataLen                  N
-  'name'               SharpObjName             N
-  'sharp_info'         SharpInfo                N
-  'sharp_method'       SharpMethod              N
-  'type'               SharpObjType             N
-  'version'            SharpObjVersion          N
+  'back_type'          SharpObjBackType         no
+  'data_len'           DataLen                  no
+  'name'               SharpObjName             no
+  'sharp_info'         SharpInfo                no
+  'sharp_method'       SharpMethod              no
+  'type'               SharpObjType             no
+  'version'            SharpObjVersion          no
 
 =head3 Leaf ToneCurve Tags
@@ -6295,11 +11717,11 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'back_type'          ToneObjBackType          N
-  'gamma'              Gamma                    N
-  'name'               ToneObjName              N
-  'npts'               Npts                     N
-  'tones'              Tones                    N
-  'type'               ToneObjType              N
-  'version'            ToneObjVersion           N
+  'back_type'          ToneObjBackType          no
+  'gamma'              Gamma                    no
+  'name'               ToneObjName              no
+  'npts'               Npts                     no
+  'tones'              Tones                    no
+  'type'               ToneObjType              no
+  'version'            ToneObjVersion           no
 
 =head3 Leaf ColorSetup Tags
@@ -6310,13 +11732,13 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'back_type'          ColorObjBackType         N
-  'color_mode'         ColorMode                N
-  'color_type'         ColorType                N
-  'has_ICC'            HasICC                   N
-  'input_profile'      InputProfile             N
-  'name'               ColorObjName             N
-  'output_profile'     OutputProfile            N
-  'type'               ColorObjType             N
-  'version'            ColorObjVersion          N
+  'back_type'          ColorObjBackType         no
+  'color_mode'         ColorMode                no
+  'color_type'         ColorType                no
+  'has_ICC'            HasICC                   no
+  'input_profile'      InputProfile             no
+  'name'               ColorObjName             no
+  'output_profile'     OutputProfile            no
+  'type'               ColorObjType             no
+  'version'            ColorObjVersion          no
 
 =head3 Leaf LookHeader Tags
@@ -6327,8 +11749,8 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'back_type'          LookHeadBackType         N
-  'name'               LookHeadName             N
-  'type'               LookHeadType             N
-  'version'            LookHeadVersion          N
+  'back_type'          LookHeadBackType         no
+  'name'               LookHeadName             no
+  'type'               LookHeadType             no
+  'version'            LookHeadVersion          no
 
 =head3 Leaf SaveSetup Tags
@@ -6339,32 +11761,33 @@
   Tag ID                  Tag Name              Writable
   ------                  --------              --------
-  'back_type'             SaveObjBackType       N
-  'leaf_auto_active'      LeafAutoActive        N
-  'leaf_auto_base_name'   LeafAutoBaseName      N
-  'leaf_hot_folder'       LeafHotFolder         N
-  'leaf_open_proc_HDR'    LeafOpenProcHDR       N
-  'leaf_output_file_type' LeafOutputFileType    N
-  'leaf_save_selection'   LeafSaveSelection     N
-  'name'                  SaveObjName           N
-  'std_auto_active'       StdAutoActive         N
-  'std_base_name'         StdBaseName           N
-  'std_hot_folder'        StdHotFolder          N
-  'std_open_in_photoshop' StdOpenInPhotoshop    N
-  'std_output_bit_depth'  StdOutputBitDepth     N
-  'std_output_color_mode' StdOutputColorMode    N
-  'std_output_file_type'  StdOutputFileType     N
-  'std_oxygen'            StdOxygen             N
-  'std_save_selection'    StdSaveSelection      N
-  'std_scaled_output'     StdScaledOutput       N
-  'std_sharpen_output'    StdSharpenOutput      N
-  'type'                  SaveObjType           N
-  'version'               SaveObjVersion        N
+  'back_type'             SaveObjBackType       no
+  'leaf_auto_active'      LeafAutoActive        no
+  'leaf_auto_base_name'   LeafAutoBaseName      no
+  'leaf_hot_folder'       LeafHotFolder         no
+  'leaf_open_proc_HDR'    LeafOpenProcHDR       no
+  'leaf_output_file_type' LeafOutputFileType    no
+  'leaf_save_selection'   LeafSaveSelection     no
+  'name'                  SaveObjName           no
+  'std_auto_active'       StdAutoActive         no
+  'std_base_name'         StdBaseName           no
+  'std_hot_folder'        StdHotFolder          no
+  'std_open_in_photoshop' StdOpenInPhotoshop    no
+  'std_output_bit_depth'  StdOutputBitDepth     no
+  'std_output_color_mode' StdOutputColorMode    no
+  'std_output_file_type'  StdOutputFileType     no
+  'std_oxygen'            StdOxygen             no
+  'std_save_selection'    StdSaveSelection      no
+  'std_scaled_output'     StdScaledOutput       no
+  'std_sharpen_output'    StdSharpenOutput      no
+  'type'                  SaveObjType           no
+  'version'               SaveObjVersion        no
 
 =head3 Leaf SubIFD Tags
 
 Leaf writes a TIFF-format sub-IFD inside IFD0 of a MOS image.  No tags in
-this sub-IFD are currently known, except for tag 0x8606 which really
-shouldn't be here anyway (so it doesn't appear in the table below) because
-it duplicates a reference to the same data of tag 0x8606 in IFD0.
+this sub-IFD are currently known, except for tags 0x8602 and 0x8606 which
+really shouldn't be here anyway (so they don't appear in the table below)
+because they duplicate references to the same data from tags with the same
+ID in IFD0.
 
   Tag ID   Tag Name                             Writable
@@ -6386,5 +11809,7 @@
   0x0003   MinoltaCameraSettings                Minolta CameraSettings
   0x0004   MinoltaCameraSettings7D              Minolta CameraSettings7D
-  0x0018   ImageStabilization                   N
+  0x0010   CameraInfoA100                       Minolta CameraInfoA100
+  0x0018   ISInfoA100                           Minolta ISInfoA100
+           ImageStabilization                   no
   0x0020   WBInfoA100                           Minolta WBInfoA100
   0x0040   CompressedImageSize                  int32u
@@ -6411,5 +11836,5 @@
   0x0115   WhiteBalance                         int32u
   0x0e00   PrintIM                              PrintIM
-  0x0f00   MinoltaCameraSettings2               N
+  0x0f00   MinoltaCameraSettings2               no
 
 =head3 Minolta CameraSettings Tags
@@ -6419,9 +11844,9 @@
 information may not be as reliable as it should be.  Because of this, tags
 in the following tables are set to lower priority to prevent them from
-superceding the values of same-named tags in other locations when duplicate
+superseding the values of same-named tags in other locations when duplicate
 tags are disabled.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       1    ExposureMode                         int32u
       2    FlashMode                            int32u
@@ -6477,6 +11902,6 @@
 =head3 Minolta CameraSettings7D Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    ExposureMode                         int16u
       2    MinoltaImageSize                     int16u
@@ -6506,28 +11931,111 @@
     117    ZoneMatchingOn                       int16u
 
+=head3 Minolta CameraInfoA100 Tags
+
+Camera information for the Sony DSLR-A100.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    AFSensorActive                       int8u
+      2    AFStatusActiveSensor                 int16s
+      4    AFStatusTop-right                    int16s
+      6    AFStatusBottom-right                 int16s
+      8    AFStatusBottom                       int16s
+     10    AFStatusMiddleHorizontal             int16s
+     12    AFStatusCenterVertical               int16s
+     14    AFStatusTop                          int16s
+     16    AFStatusTop-left                     int16s
+     18    AFStatusBottom-left                  int16s
+     20    FocusLocked                          int8u
+     21    AFPoint                              int8u
+     22    AFMode                               int8u
+     45    AFStatusLeft                         int16s
+     47    AFStatusCenterHorizontal             int16s
+     49    AFStatusRight                        int16s
+     51    AFAreaMode                           int8u
+
+=head3 Minolta ISInfoA100 Tags
+
+Image stabilization information for the Sony DSLR-A100.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageStabilization                   int16u
+
 =head3 Minolta WBInfoA100 Tags
 
 White balance information for the Sony DSLR-A100.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     14    DriveMode                            int8u
+     16    Rotation                             int8u
+     20    ImageStabilizationSetting            int8u
+     21    DynamicRangeOptimizerMode            int8u
+     42    ExposureCompensationMode             int8u
+     43    WBBracketShotNumber                  int8u
+     44    WhiteBalanceBracketing               int8u
+     45    ExposureBracketShotNumber            int8u
+     49    FlashFunction                        int16u
+     52    ExposureMode                         int16u
+     54    ColorMode                            int16u
+     56    AverageLV                            int16u
+     60    FrameNumber                          int8u
     150    WB_RGBLevels                         int16u[3]
     174    WB_GBRGLevels                        int16u[4]
-    772    WB_RBPresetFlash                     int16u[2]
-    776    WB_RBPresetCoolWhiteF                int16u[2]
-   1000    WB_RBPresetTungsten                  int16u[2]
-   1004    WB_RBPresetDaylight                  int16u[2]
-   1008    WB_RBPresetCloudy                    int16u[2]
-   1012    WB_RBPresetFlash                     int16u[2]
-   1020    WB_RedPresetsFluorescent             int16u[7]
-   1034    WB_BluePresetsFluorescent            int16u[7]
-   1048    WB_RBPresetShade                     int16u[2]
-   1060    WB_RBPresetCustom                    int16u[2]
+    192    WB_RedLevelsTungsten                 int16u[7]
+    206    WB_BlueLevelsTungsten                int16u[7]
+    220    WB_RedLevelsDaylight                 int16u[7]
+    234    WB_BlueLevelsDaylight                int16u[7]
+    248    WB_RedLevelsCloudy                   int16u[7]
+    262    WB_BlueLevelsCloudy                  int16u[7]
+    276    WB_RedLevelsFlash                    int16u[7]
+    290    WB_BlueLevelsFlash                   int16u[7]
+    332    WB_RedLevelsFluorescent              int16u[7]
+    346    WB_BlueLevelsFluorescent             int16u[7]
+    360    WB_RedLevelsShade                    int16u[7]
+    374    WB_BlueLevelsShade                   int16u[7]
+    392    WB_RedLevel6500K                     int16u
+    394    WB_BlueLevel6500K                    int16u
+    396    WB_RedLevelCustom                    int16u
+    398    WB_BlueLevelCustom                   int16u
+    408    WB_RedLevel3500K                     int16u
+    410    WB_BlueLevel3500K                    int16u
+    446    WB_RedLevelsKelvin                   int16u[75]
+    596    WB_BlueLevelsKelvin                  int16u[75]
+    772    WB_RBLevelsFlash                     int16u[2]
+    776    WB_RBLevelsCoolWhiteF                int16u[2]
+   1000    WB_RBLevelsTungsten                  int16u[2]
+   1004    WB_RBLevelsDaylight                  int16u[2]
+   1008    WB_RBLevelsCloudy                    int16u[2]
+   1012    WB_RBLevelsFlash                     int16u[2]
+   1020    WB_RedLevelsFluorescent              int16u[7]
+   1034    WB_BlueLevelsFluorescent             int16u[7]
+   1048    WB_RBLevelsShade                     int16u[2]
+   1056    WB_RBLevels6500K                     int16u[2]
+   1060    WB_RBLevelsCustom                    int16u[2]
+   1072    WB_RBLevels3500K                     int16u[2]
+   1320    WB_RBLevelsDaylight                  int16u[2]
+   1350    WB_RGBLevels                         int16u[3]
+   1576    AEMeteringSegments                   int8u[40]
+   1680    MeasuredLV                           int8u
+   1681    BrightnessValue                      int8u
+   4172    TiffMeteringImage                    no
+  18872    ExposureTime                         int8u
+  18874    ISO                                  int8u
+  18875    FocusDistance                        int8u
+  18877    LensType                             int16uRev
+  18880    ExposureCompensation                 int8s
+  18881    FlashExposureComp                    int8s
+  18882    ImageStabilization                   int8u
+  18883    BrightnessValue                      int8u
+  18885    MaxAperture                          int8u
+  18887    FNumber                              int8u
   18908    InternalSerialNumber                 string[12]
 
 =head3 Minolta CameraSettings5D Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
      10    ExposureMode                         int16u
      12    MinoltaImageSize                     int16u
@@ -6561,11 +12069,11 @@
 Camera settings information for the Sony DSLR-A100.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    ExposureMode                         int16u
       1    ExposureCompensationSetting          int16u
       5    HighSpeedSync                        int16u
-      6    ManualExposureTime                   int16u
-      7    ManualFNumber                        int16u
+      6    ShutterSpeedSetting                  int16u
+      7    ApertureSetting                      int16u
       8    ExposureTime                         int16u
       9    FNumber                              int16u
@@ -6573,8 +12081,8 @@
      11    WhiteBalance                         int16u
      12    FocusMode                            int16u
-     13    LocalAFAreaPoint                     int16u
+     13    AFPointSelected                      int16u
      14    AFAreaMode                           int16u
      15    FlashMode                            int16u
-     16    FlashExposureCompSetting             int16u
+     16    FlashExposureCompSet                 int16u
      18    MeteringMode                         int16u
      19    ISOSetting                           int16u
@@ -6640,5 +12148,5 @@
      94    ColorTemperature                     int16u
      95    ColorCompensationFilter              int16s
-     96    BatteryLevel                         int16u
+     96    BatteryState                         int16u
 
 =head3 Minolta MMA Tags
@@ -6647,8 +12155,8 @@
 DiMAGE A2, S414 and 7Hi.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     20    SoftwareVersion                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     20    SoftwareVersion                      no
 
 =head3 Minolta MOV1 Tags
@@ -6657,12 +12165,12 @@
 as the DiMage Z10 and X50.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     32    ModelType                            N
-     46    ExposureTime                         N
-     50    FNumber                              N
-     58    ExposureCompensation                 N
-     80    FocalLength                          N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     32    ModelType                            no
+     46    ExposureTime                         no
+     50    FNumber                              no
+     58    ExposureCompensation                 no
+     80    FocalLength                          no
 
 =head3 Minolta MOV2 Tags
@@ -6671,12 +12179,21 @@
 DiMAGE X and Xt.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     24    ModelType                            N
-     38    ExposureTime                         N
-     42    FNumber                              N
-     50    ExposureCompensation                 N
-     72    FocalLength                          N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    ModelType                            no
+     38    ExposureTime                         no
+     42    FNumber                              no
+     50    ExposureCompensation                 no
+     72    FocalLength                          no
+
+=head2 Motorola Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x5500   BuildNumber                          string
+  0x5501   SerialNumber                         string
+  0x665e   Sensor                               string
+  0x6705   ManufactureDate                      string
 
 =head2 Nikon Tags
@@ -6698,10 +12215,11 @@
   0x000e   ExposureDifference                   undef[4]
   0x000f   ISOSelection                         string
-  0x0010   DataDump                             N
+  0x0010   DataDump                             no
   0x0011   PreviewIFD                           Nikon PreviewIFD
   0x0012   FlashExposureComp                    undef[4]
   0x0013   ISOSetting                           int16u[2]
   0x0014   ColorBalanceA                        Nikon ColorBalanceA
-           NRWData?                             Y
+           NRWData                              Nikon ColorBalanceB
+                                                Nikon ColorBalanceC
   0x0016   ImageBoundary                        int16u[4]
   0x0017   ExternalFlashExposureComp            undef[4]
@@ -6709,5 +12227,5 @@
   0x0019   ExposureBracketValue                 rational64s
   0x001a   ImageProcessing                      string
-  0x001b   CropHiSpeed                          int16u[7]~
+  0x001b   CropHiSpeed                          int16u[7]
   0x001c   ExposureTuning                       undef[3]
   0x001d   SerialNumber                         string!
@@ -6718,4 +12236,7 @@
   0x0022   ActiveD-Lighting                     int16u
   0x0023   PictureControlData                   Nikon PictureControl
+                                                Nikon PictureControl2
+                                                Nikon PictureControl3
+                                                Nikon PictureControlUnknown
   0x0024   WorldTime                            Nikon WorldTime
   0x0025   ISOInfo                              Nikon ISOInfo
@@ -6724,4 +12245,13 @@
   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]
+  0x003e   ImageSizeRAW                         yes
+  0x0045   CropArea                             int16u[4]
+  0x004e   NikonSettings                        NikonSettings
+  0x004f   ColorTemperatureAuto                 int16u
   0x0080   ImageAdjustment                      string
   0x0081   ToneComp                             string
@@ -6736,5 +12266,5 @@
   0x0089   ShootingMode                         int16u~
   0x008b   LensFStops                           undef[4]
-  0x008c   ContrastCurve                        N
+  0x008c   ContrastCurve                        undef!
   0x008d   ColorHue                             string
   0x008f   SceneMode                            string
@@ -6751,13 +12281,25 @@
            ShotInfoD300S                        Nikon ShotInfoD300S
            ShotInfoD700                         Nikon ShotInfoD700
+           ShotInfoD800                         Nikon ShotInfoD800
+           ShotInfoD810                         Nikon ShotInfoD810
+           ShotInfoD850                         Nikon ShotInfoD850
            ShotInfoD5000                        Nikon ShotInfoD5000
+           ShotInfoD5100                        Nikon ShotInfoD5100
+           ShotInfoD5200                        Nikon ShotInfoD5200
            ShotInfoD7000                        Nikon ShotInfoD7000
+           ShotInfoD4                           Nikon ShotInfoD4
+           ShotInfoD4S                          Nikon ShotInfoD4S
+           ShotInfoD5                           Nikon ShotInfoD500
+           ShotInfoD500                         Nikon ShotInfoD500
+           ShotInfoD6                           Nikon ShotInfoD6
+           ShotInfoD610                         Nikon ShotInfoD610
+           ShotInfoZ7_2                         Nikon ShotInfoZ7_2
            ShotInfo02xx                         Nikon ShotInfo
            ShotInfoUnknown                      Nikon ShotInfo
   0x0092   HueAdjustment                        int16s
   0x0093   NEFCompression                       int16u
-  0x0094   Saturation                           int16s
+  0x0094   SaturationAdj                        int16s
   0x0095   NoiseReduction                       string
-  0x0096   LinearizationTable                   N
+  0x0096   NEFLinearizationTable                undef!
   0x0097   ColorBalance0100                     Nikon ColorBalance1
            ColorBalance0102                     Nikon ColorBalance2
@@ -6766,13 +12308,23 @@
            ColorBalance0209                     Nikon ColorBalance4
            ColorBalance02                       Nikon ColorBalance2
-           ColorBalanceUnknown                  N
+           ColorBalance0211                     Nikon ColorBalance4
+           ColorBalance0213                     Nikon ColorBalance2
+           ColorBalance0215                     Nikon ColorBalance4
+           ColorBalanceUnknown02                Nikon ColorBalanceUnknown
+           ColorBalanceUnknown04                Nikon ColorBalanceUnknown
+           ColorBalanceUnknown                  Nikon ColorBalanceUnknown
   0x0098   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
   0x0099   RawImageCenter                       int16u[2]
   0x009a   SensorPixelSize                      rational64u[2]
   0x009c   SceneAssist                          string
+  0x009d   DateStampMode                        int16u
   0x009e   RetouchHistory                       int16u[10]
   0x00a0   SerialNumber                         string
@@ -6784,5 +12336,7 @@
            FlashInfo0102                        Nikon FlashInfo0102
            FlashInfo0103                        Nikon FlashInfo0103
-           FlashInfo0104                        Nikon FlashInfo0103
+           FlashInfo0106                        Nikon FlashInfo0106
+           FlashInfo0107                        Nikon FlashInfo0107
+           FlashInfo0300                        Nikon FlashInfo0300
            FlashInfoUnknown                     Nikon FlashInfoUnknown
   0x00a9   ImageOptimization                    string
@@ -6792,4 +12346,5 @@
   0x00ad   AFResponse                           string
   0x00b0   MultiExposure                        Nikon MultiExposure
+                                                Nikon MultiExposure
   0x00b1   HighISONoiseReduction                int16u
   0x00b3   ToningEffect                         string
@@ -6797,13 +12352,16 @@
   0x00b7   AFInfo2                              Nikon AFInfo2
   0x00b8   FileInfo                             Nikon FileInfo
+                                                Nikon FileInfo
   0x00b9   AFTune                               Nikon AFTune
+  0x00bb   RetouchInfo                          Nikon RetouchInfo
   0x00bd   PictureControlData                   Nikon PictureControl
+  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
@@ -6814,31 +12372,74 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x00fe   SubfileType                          N
-  0x0103   Compression                          N
-  0x011a   XResolution                          N
-  0x011b   YResolution                          N
-  0x0128   ResolutionUnit                       N
+  0x00fe   SubfileType                          no
+  0x0103   Compression                          no
+  0x011a   XResolution                          no
+  0x011b   YResolution                          no
+  0x0128   ResolutionUnit                       no
   0x0201   PreviewImageStart                    int32u*
   0x0202   PreviewImageLength                   int32u*
-  0x0213   YCbCrPositioning                     N
+  0x0213   YCbCrPositioning                     no
 
 =head3 Nikon ColorBalanceA Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-    624    RedBalance                           int16u!
-    625    BlueBalance                          int16u!
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+    624    WB_RBLevels                          int16u[2]!
+    626    WB_RBLevelsAuto                      int16u[2]!
+    628    WB_RBLevelsDaylight                  int16u[14]!
+    642    WB_RBLevelsIncandescent              int16u[14]!
+    656    WB_RBLevelsFluorescent               int16u[6]!
+    662    WB_RBLevelsCloudy                    int16u[14]!
+    676    WB_RBLevelsFlash                     int16u[14]!
+    690    WB_RBLevelsShade                     int16u[14]!
+
+=head3 Nikon ColorBalanceB Tags
+
+Color balance tags used by the P6000.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    ColorBalanceVersion                  undef[4]
+   5096    WB_RGGBLevels                        int32u[4]!
+   5112    WB_RGGBLevelsDaylight                int32u[4]!
+   5128    WB_RGGBLevelsCloudy                  int32u[4]!
+   5160    WB_RGGBLevelsTungsten                int32u[4]!
+   5176    WB_RGGBLevelsFluorescentW            int32u[4]!
+   5192    WB_RGGBLevelsFlash                   int32u[4]!
+   5224    WB_RGGBLevelsCustom                  int32u[4]!
+   5240    WB_RGGBLevelsAuto                    int32u[4]!
+
+=head3 Nikon ColorBalanceC Tags
+
+Color balance tags used by the P1000, P7000, P7100 and B700.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    ColorBalanceVersion                  undef[4]
+     32    BlackLevel                           int16u
+     56    WB_RGGBLevels                        int32u[4]!
+     76    WB_RGGBLevelsDaylight                int32u[4]!
+     96    WB_RGGBLevelsCloudy                  int32u[4]!
+    116    WB_RGGBLevelsShade                   int32u[4]!
+    136    WB_RGGBLevelsTungsten                int32u[4]!
+    156    WB_RGGBLevelsFluorescentW            int32u[4]!
+    176    WB_RGGBLevelsFluorescentN            int32u[4]!
+    196    WB_RGGBLevelsFluorescentD            int32u[4]!
+    216    WB_RGGBLevelsHTMercury               int32u[4]!
+    256    WB_RGGBLevelsCustom                  int32u[4]!
+    276    WB_RGGBLevelsAuto                    int32u[4]!
 
 =head3 Nikon VRInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    VRInfoVersion                        N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    VRInfoVersion                        no
       4    VibrationReduction                   int8u
+      6    VRMode                               int8u
 
 =head3 Nikon FaceDetect Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    FaceDetectFrameSize                  int16u[2]
       3    FacesDetected                        int16u
@@ -6858,7 +12459,7 @@
 =head3 Nikon PictureControl Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    PictureControlVersion                N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PictureControlVersion                no
       4    PictureControlName                   string[20]
      24    PictureControlBase                   string[20]
@@ -6874,9 +12475,54 @@
      57    ToningSaturation                     int8u
 
+=head3 Nikon PictureControl2 Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PictureControlVersion                no
+      4    PictureControlName                   string[20]
+     24    PictureControlBase                   string[20]
+     48    PictureControlAdjust                 int8u
+     49    PictureControlQuickAdjust            int8u
+     51    Sharpness                            int8u
+     53    Clarity                              int8u
+     55    Contrast                             int8u
+     57    Brightness                           int8u
+     59    Saturation                           int8u
+     61    Hue                                  int8u
+     63    FilterEffect                         int8u
+     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
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Timezone                             int16s
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    TimeZone                             int16s
       2    DaylightSavings                      int8u
       3    DateDisplayFormat                    int8u
@@ -6884,6 +12530,6 @@
 =head3 Nikon ISOInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    ISO                                  int8u
       4    ISOExpansion                         int16u
@@ -6893,25 +12539,47 @@
 =head3 Nikon DistortInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    DistortionVersion?                   N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    DistortionVersion?                   no
       4    AutoDistortionControl                int8u
 
 =head3 Nikon UnknownInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    UnknownInfoVersion?                  N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    UnknownInfoVersion?                  no
 
 =head3 Nikon UnknownInfo2 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    UnknownInfo2Version?                 N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    UnknownInfo2Version?                 no
+
+=head3 Nikon HDRInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    HDRInfoVersion                       string[4]
+      4    HDR                                  int8u
+      5    HDRLevel                             int8u
+      6    HDRSmoothing                         int8u
+      7    HDRLevel2                            int8u
+
+=head3 Nikon LocationInfo Tags
+
+Tags written by some Nikon GPS-equipped cameras like the AW100.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LocationInfoVersion                  undef[4]
+      4    TextEncoding                         int8u
+      5    CountryCode                          undef[3]
+      8    POILevel                             int8u
+      9    Location                             undef[70]
 
 =head3 Nikon AFInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    AFAreaMode                           int8u
       1    AFPoint                              int8u
@@ -6924,5 +12592,5 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
+      0    ShotInfoVersion                      no
     582    ShutterCount                         int32u
   586.1    VibrationReduction                   int8u & 0x08
@@ -6935,5 +12603,5 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
+      0    ShotInfoVersion                      no
     586    ShutterCount                         int32u
   590.1    Rotation                             int8u & 0x07
@@ -6951,6 +12619,6 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
     693    ISO2                                 int8u
     725    ShutterCount                         int32u
@@ -6964,5 +12632,5 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
+      0    ShotInfoVersion                      no
     598    ISO2                                 int8u
     630    ShutterCount                         int32u
@@ -6978,6 +12646,6 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
      16    ImageArea                            int8u
     605    ISO2                                 int8u
@@ -6996,6 +12664,6 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
     605    ISO2                                 int8u
     640    ShutterCount                         int32u
@@ -7009,6 +12677,6 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
      16    ImageArea                            int8u
     545    ISO2                                 int8u
@@ -7023,5 +12691,5 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
+      0    ShotInfoVersion                      no
     604    ISO2                                 int8u
     633    ShutterCount                         int32u
@@ -7036,6 +12704,6 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
     613    ISO2                                 int8u
     644    ShutterCount                         int32u
@@ -7050,6 +12718,6 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
     613    ISO2                                 int8u
     646    ShutterCount                         int32u
@@ -7063,10 +12731,65 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
     613    ISO2                                 int8u
     647    ShutterCount                         int32u
     804    CustomSettingsD700                   NikonCustom SettingsD700
 
+=head3 Nikon ShotInfoD800 Tags
+
+These tags are extracted from encrypted data in images from the D800.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+   1216    RepeatingFlashOutputExternal         int8u
+   1218    RepeatingFlashRateExternal           int8u
+   1219    RepeatingFlashCountExternal          int8u
+   1234    FlashExposureComp2                   int8s
+   1242    RepeatingFlashRateBuilt-in           int8u
+   1243    RepeatingFlashCountBuilt-in          int8u
+   1308    SequenceNumber                       int8u
+   1531    ShutterCount                         int32u
+   1772    CustomSettingsD800                   NikonCustom SettingsD800
+
+=head3 Nikon ShotInfoD810 Tags
+
+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
+    464    SecondarySlotFunction                int8u & 0x03
+   5974    AEBracketingSteps                    int8u & 0xff
+   5975    WBBracketingSteps                    int8u & 0xff
+   5982    NikonMeteringMode                    int8u & 0x03
+   6236    ISOAutoShutterTime                   int8u & 0x3f
+   6237    ISOAutoHiLimit                       int8u & 0xff
+   6315    CustomSettingsD810                   NikonCustom SettingsD810
+  14068    RollAngle                            fixed32u
+  14072    PitchAngle                           fixed32u
+  14076    YawAngle                             fixed32u
+
+=head3 Nikon ShotInfoD850 Tags
+
+These tags are extracted from encrypted data in images from the D850.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+   1937    PhotoShootingMenuBankImageArea       int8u & 0x07
+   4029    PhotoShootingMenuBank                int8u & 0x03
+   4031    PrimarySlot                          int8u & 0x80
+   4152    CustomSettingsD850                   NikonCustom SettingsD850
+  12027    RollAngle                            fixed32u
+  12031    PitchAngle                           fixed32u
+  12035    YawAngle                             fixed32u
+
 =head3 Nikon ShotInfoD5000 Tags
 
@@ -7076,10 +12799,28 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
     693    ISO2                                 int8u
     726    ShutterCount                         int32u
     888    CustomSettingsD5000                  NikonCustom SettingsD5000
 
+=head3 Nikon ShotInfoD5100 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+    801    ShutterCount                         int32u
+   1031    CustomSettingsD5100                  NikonCustom SettingsD5100
+
+=head3 Nikon ShotInfoD5200 Tags
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+   3032    ShutterCount                         int32u
+   3285    CustomSettingsD5200                  NikonCustom SettingsD5200
+
 =head3 Nikon ShotInfoD7000 Tags
 
@@ -7089,9 +12830,102 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
     800    ShutterCount                         int32u
    1028    CustomSettingsD7000                  NikonCustom SettingsD7000
 
+=head3 Nikon ShotInfoD4 Tags
+
+These tags are extracted from encrypted data in images from the D4.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+   1873    CustomSettingsD4                     NikonCustom SettingsD4
+
+=head3 Nikon ShotInfoD4S Tags
+
+These tags are extracted from encrypted data in images from the D4S.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+    464    SecondarySlotFunction                int8u & 0x03
+   5964    AEBracketingSteps                    int8u & 0xff
+   5965    WBBracketingSteps                    int8u & 0xff
+   6221    ReleaseMode                          int8u & 0xff
+   6301    CustomSettingsD4S                    NikonCustom SettingsD4
+   6338    MultiSelectorLiveViewMode            int8u & 0xc0
+   6378    ISOAutoShutterTime                   int8u & 0x3f
+   6379    ISOAutoHiLimit                       int8u & 0xff
+   6461    CustomSettingsD4S                    NikonCustom SettingsD4
+  13579    RollAngle                            fixed32u
+  13583    PitchAngle                           fixed32u
+  13587    YawAngle                             fixed32u
+  13971    Rotation                             int8u & 0x30
+
+=head3 Nikon ShotInfoD500 Tags
+
+These tags are extracted from encrypted data in images from the D5 and D500.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+    202    Rotation                             int8u & 0x03
+   1506    FlickerReductionIndicator            int8u & 0x01
+   2004    JPGCompression                       int8u & 0x01
+   2171    AEBracketingSteps                    int8u & 0xff
+   2172    WBBracketingSteps                    int8u & 0xff
+   2179    ADLBracketingStep                    int8u & 0xf0
+   2180    ADLBracketingType                    int8u & 0x0f
+   3709    PhotoShootingMenuBank                int8u & 0x03
+   3711    PrimarySlot                          int8u & 0x80
+   3713    ISOAutoShutterTime                   int8u & 0x3f
+   3714    ISOAutoHiLimit                       int8u & 0xff
+   3716    FlickerReduction                     int8u & 0x20
+  3716.1   PhotoShootingMenuBankImageArea       int8u & 0x07
+   3819    CustomSettingsD5                     NikonCustom SettingsD5
+           CustomSettingsD500                   NikonCustom SettingsD500
+  11300    RollAngle                            fixed32u
+  11304    PitchAngle                           fixed32u
+  11308    YawAngle                             fixed32u
+  11940    NikonMeteringMode                    int8u & 0x03
+
+=head3 Nikon ShotInfoD6 Tags
+
+These tags are extracted from encrypted data in images from the D6.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+  49690    RollAngle                            fixed32u
+  49694    PitchAngle                           fixed32u
+  49698    YawAngle                             fixed32u
+
+=head3 Nikon ShotInfoD610 Tags
+
+These tags are extracted from encrypted data in images from the D610.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+   1999    CustomSettingsD610                   NikonCustom SettingsD610
+
+=head3 Nikon ShotInfoZ7_2 Tags
+
+These tags are extracted from encrypted data in images from the Z7_2.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
+  52786    RollAngle                            fixed32u
+  52790    PitchAngle                           fixed32u
+  52794    YawAngle                             fixed32u
+
 =head3 Nikon ShotInfo Tags
 
@@ -7099,8 +12933,8 @@
 only valid for specific models.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ShotInfoVersion                      N
-      4    FirmwareVersion                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ShotInfoVersion                      no
+      4    FirmwareVersion                      no
      16    DistortionControl                    int8u
     102    VR_0x66?                             int8u
@@ -7115,6 +12949,6 @@
 =head3 Nikon ColorBalance1 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    WB_RBGGLevels                        int16u[4]!
 
@@ -7123,27 +12957,33 @@
 This information is encrypted for most camera models.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    WB_RGGBLevels                        int16u[4]!
 
 =head3 Nikon ColorBalance3 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    WB_RGBGLevels                        int16u[4]!
 
 =head3 Nikon ColorBalance4 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    WB_GRBGLevels                        int16u[4]!
 
+=head3 Nikon ColorBalanceUnknown Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ColorBalanceVersion                  undef[4]
+
 =head3 Nikon LensData00 Tags
 
 This structure is used by the D100, and D1X with firmware version 1.1.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    LensDataVersion                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensDataVersion                      no
       6    LensIDNumber                         int8u
       7    LensFStops                           int8u
@@ -7160,7 +13000,7 @@
 extracted.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    LensDataVersion                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensDataVersion                      no
       4    ExitPupilPosition                    int8u
       5    AFAperture                           int8u
@@ -7183,7 +13023,7 @@
 extracted.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    LensDataVersion                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensDataVersion                      no
       4    ExitPupilPosition                    int8u
       5    AFAperture                           int8u
@@ -7200,9 +13040,62 @@
      19    EffectiveMaxAperture                 int8u
 
+=head3 Nikon LensData0400 Tags
+
+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
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    LensDataVersion                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensDataVersion                      no
 
 =head3 Nikon FlashInfo0100 Tags
@@ -7211,7 +13104,7 @@
 D200.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FlashInfoVersion                     N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FlashInfoVersion                     no
       4    FlashSource                          int8u
       6    ExternalFlashFirmware                int8u[2]
@@ -7237,7 +13130,7 @@
 (firmware 1.00).
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FlashInfoVersion                     N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FlashInfoVersion                     no
       4    FlashSource                          int8u
       6    ExternalFlashFirmware                int8u[2]
@@ -7263,10 +13156,11 @@
 =head3 Nikon FlashInfo0103 Tags
 
-These tags are used by the D3 (firmware 2.x), D3X, D3S, D90, D300 (firmware
-1.10), D300S, D700, D3000 and D5000.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FlashInfoVersion                     N
+These tags are used by the D3 (firmware 2.x), D3X, D3S, D4, D90, D300
+(firmware 1.10), D300S, D600, D700, D800, D3000, D3100, D3200, D5000, D5100,
+D5200, D7000.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FlashInfoVersion                     no
       4    FlashSource                          int8u
       6    ExternalFlashFirmware                int8u[2]
@@ -7290,16 +13184,85 @@
      21    FlashGroupCOutput                    int8u
            FlashGroupCCompensation              int8s
+     27    ExternalFlashCompensation            int8s
+     29    FlashExposureComp3                   int8s
+     39    FlashExposureComp4                   int8s
+
+=head3 Nikon FlashInfo0106 Tags
+
+These tags are used by the Df, D610, D3300, D5300, D7100 and Coolpix A.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FlashInfoVersion                     no
+      4    FlashSource                          int8u
+      6    ExternalFlashFirmware                int8u[2]
+      8    ExternalFlashFlags                   int8u
+    9.1    FlashCommanderMode                   int8u & 0x80
+    9.2    FlashControlMode                     int8u & 0x7f
+     12    FlashFocalLength                     int8u
+     13    RepeatingFlashRate                   int8u
+     14    RepeatingFlashCount                  int8u
+     15    FlashGNDistance                      int8u
+     16    FlashColorFilter                     int8u
+   17.1    FlashGroupAControlMode               int8u & 0x0f
+   18.1    FlashGroupBControlMode               int8u & 0xf0
+   18.2    FlashGroupCControlMode               int8u & 0x0f
+     39    FlashOutput                          int8u
+           FlashCompensation                    int8s
+     40    FlashGroupAOutput                    int8u
+           FlashGroupACompensation              int8s
+     41    FlashGroupBOutput                    int8u
+           FlashGroupBCompensation              int8s
+     42    FlashGroupCOutput                    int8u
+           FlashGroupCCompensation              int8s
+
+=head3 Nikon FlashInfo0107 Tags
+
+These tags are used by the D4S, D750, D810, D5500, D7200 (FlashInfoVersion
+0107) and the D5, D500, D850 and D3400 (FlashInfoVersion 0108).
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FlashInfoVersion                     no
+      4    FlashSource                          int8u
+      6    ExternalFlashFirmware                int8u[2]
+    8.1    ExternalFlashZoomOverride            int8u & 0x80
+    8.2    ExternalFlashStatus                  int8u & 0x01
+    9.1    ExternalFlashReadyState              int8u & 0x07
+     10    FlashCompensation                    int8s
+     12    FlashFocalLength                     int8u
+     13    RepeatingFlashRate                   int8u
+     14    RepeatingFlashCount                  int8u
+     15    FlashGNDistance                      int8u
+   17.1    FlashGroupAControlMode               int8u & 0x0f
+   18.1    FlashGroupBControlMode               int8u & 0xf0
+   18.2    FlashGroupCControlMode               int8u & 0x0f
+     40    FlashGroupAOutput                    int8u
+           FlashGroupACompensation              int8s
+     41    FlashGroupBOutput                    int8u
+           FlashGroupBCompensation              int8s
+     42    FlashGroupCOutput                    int8u
+           FlashGroupCCompensation              int8s
+
+=head3 Nikon FlashInfo0300 Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FlashInfoVersion                     no
+      4    FlashSource                          int8u
+      6    ExternalFlashFirmware                int8u[2]
+     27    FlashCompensation                    int8s
 
 =head3 Nikon FlashInfoUnknown Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FlashInfoVersion                     N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FlashInfoVersion                     no
 
 =head3 Nikon MultiExposure Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MultiExposureVersion                 N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    MultiExposureVersion                 no
       1    MultiExposureMode                    int32u
       2    MultiExposureShots                   int32u
@@ -7310,14 +13273,21 @@
 These tags are written by Nikon DSLR's which have the live view feature.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    AFInfo2Version                       N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    AFInfo2Version                       no
       4    ContrastDetectAF                     int8u
       5    AFAreaMode                           int8u
       6    PhaseDetectAF                        int8u
       7    PrimaryAFPoint                       int8u
-      8    AFPointsUsed                         undef[7]~
+      8    AFPointsUsed                         undef[7]
            AFPointsUsed                         undef[2]
-           AFPointsUsed                         undef[7]~
+           AFPointsUsed                         undef[5]
+           AFPointsUsed                         undef[17]
+           AFPointsUsed                         undef[21]
+           AFPointsUsed                         undef[29]
+           AFPointsUsed                         undef[20]
+           AFPointsUsed                         undef[13]
+           AFPointsUsed                         undef[7]
+     10    AFPointsUsed                         undef[14]
      16    AFImageWidth                         int16u
      18    AFImageHeight                        int16u
@@ -7327,20 +13297,55 @@
      26    AFAreaHeight                         int16u
      28    ContrastDetectAFInFocus              int8u
+           AFPointsSelected                     undef[20]
+     42    AFImageWidth                         int16u
+     44    AFImageHeight                        int16u
+     46    AFAreaXPosition                      int16u
+     47    AFFocusPointXPosition                int8u~
+     48    AFAreaYPosition                      int16u
+           AFPointsInFocus                      undef[20]
+     49    AFFocusPointYPosition                int8u~
+     50    AFAreaWidth                          int16u
+     52    AFAreaHeight                         int16u
+     56    PrimaryAFPoint                       int8u
+     68    PrimaryAFPoint                       int8u
+     70    AFImageWidth                         int16u
+     72    AFImageHeight                        int16u
+     74    AFAreaXPosition                      int16u
+     76    AFAreaYPosition                      int16u
+     78    AFAreaWidth                          int16u
+     80    AFAreaHeight                         int16u
+     82    ContrastDetectAFInFocus              int8u
 
 =head3 Nikon FileInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FileInfoVersion                      N
-      6    DirectoryNumber                      int16u
-      8    FileNumber                           int16u
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    FileInfoVersion                      no
+      2    MemoryCardNumber                     int16u
+      3    DirectoryNumber                      int16u
+      4    FileNumber                           int16u
 
 =head3 Nikon AFTune Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    AFFineTune                           int8u
       1    AFFineTuneIndex                      int8u
       2    AFFineTuneAdj                        int8s
+      3    AFFineTuneAdjTele                    int8s
+
+=head3 Nikon RetouchInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    RetouchInfoVersion                   no
+      5    RetouchNEFProcessing                 int8s
+
+=head3 Nikon BarometerInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    BarometerInfoVersion                 no
+      6    Altitude                             int32s
 
 =head3 Nikon CaptureOffsets Tags
@@ -7348,7 +13353,7 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0001   IFD0_Offset                          N
-  0x0002   PreviewIFD_Offset                    N
-  0x0003   SubIFD_Offset                        N
+  0x0001   IFD0_Offset                          no
+  0x0002   PreviewIFD_Offset                    no
+  0x0003   SubIFD_Offset                        no
 
 =head3 Nikon Scan Tags
@@ -7373,18 +13378,18 @@
 =head3 Nikon ROC Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    DigitalROC                           int32u
 
 =head3 Nikon GEM Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    DigitalGEM                           int32u
 
 =head3 Nikon CaptureOutput Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       2    OutputImageWidth                     int32u
       3    OutputImageHeight                    int32u
@@ -7395,24 +13400,42 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0003   Quality                              Y
-  0x0004   ColorMode                            Y
-  0x0005   ImageAdjustment                      Y
-  0x0006   CCDSensitivity                       Y
-  0x0007   WhiteBalance                         Y
-  0x0008   Focus                                Y
-  0x000a   DigitalZoom                          Y
-  0x000b   Converter                            Y
+  0x0003   Quality                              yes
+  0x0004   ColorMode                            yes
+  0x0005   ImageAdjustment                      yes
+  0x0006   CCDSensitivity                       yes
+  0x0007   WhiteBalance                         yes
+  0x0008   Focus                                yes
+  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 some
-Nikon cameras such as the Coolpix S8000.
+Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from
+various Nikon models.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'NCHD'   MakerNoteVersion                     N
+  'NCDB'   NikonNCDB                            Nikon NCDB
+  'NCHD'   MakerNoteVersion                     no
+  'NCM1'   PreviewImage1                        no
+  'NCM2'   PreviewImage2                        no
   'NCTG'   NikonTags                            Nikon NCTG
-  'NCTH'   ThumbnailImage                       N
-  'NCVW'   PreviewImage                         N
+  'NCTH'   ThumbnailImage                       no
+  'NCVW'   PreviewImage                         no
+
+=head3 Nikon NCDB Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
 
 =head3 Nikon NCTG Tags
@@ -7423,25 +13446,84 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  0x0001       Make                             N
-  0x0002       Model                            N
-  0x0003       Software                         N
-  0x0011       CreateDate                       N
-  0x0012       DateTimeOriginal                 N
-  0x0013       FrameCount                       N
-  0x0016       FrameRate                        N
-  0x0022       FrameWidth                       N
-  0x0023       FrameHeight                      N
-  0x0032       AudioChannels                    N
-  0x0033       AudioBitsPerSample               N
-  0x0034       AudioSampleRate                  N
-  0x2000001    MakerNoteVersion                 N
-  0x2000005    WhiteBalance                     N
-  0x200000b    WhiteBalanceFineTune             N
-  0x200001e    ColorSpace                       N
+  0x0001       Make                             no
+  0x0002       Model                            no
+  0x0003       Software                         no
+  0x0011       CreateDate                       no
+  0x0012       DateTimeOriginal                 no
+  0x0013       FrameCount                       no
+  0x0016       FrameRate                        no
+  0x0019       TimeZone                         no
+  0x0022       FrameWidth                       no
+  0x0023       FrameHeight                      no
+  0x0032       AudioChannels                    no
+  0x0033       AudioBitsPerSample               no
+  0x0034       AudioSampleRate                  no
+  0x1002       NikonDateTime                    no
+  0x1013       ElectronicVR                     no
+  0x110829a    ExposureTime                     no
+  0x110829d    FNumber                          no
+  0x1108822    ExposureProgram                  no
+  0x1109204    ExposureCompensation             no
+  0x1109207    MeteringMode                     no
+  0x110920a    FocalLength                      no
+  0x110a431    SerialNumber                     no
+  0x110a432    LensInfo                         no
+  0x110a433    LensMake                         no
+  0x110a434    LensModel                        no
+  0x110a435    LensSerialNumber                 no
+  0x1200000    GPSVersionID                     no
+  0x1200001    GPSLatitudeRef                   no
+  0x1200002    GPSLatitude                      no
+  0x1200003    GPSLongitudeRef                  no
+  0x1200004    GPSLongitude                     no
+  0x1200005    GPSAltitudeRef                   no
+  0x1200006    GPSAltitude                      no
+  0x1200007    GPSTimeStamp                     no
+  0x1200008    GPSSatellites                    no
+  0x1200010    GPSImgDirectionRef               no
+  0x1200011    GPSImgDirection                  no
+  0x1200012    GPSMapDatum                      no
+  0x120001d    GPSDateStamp                     no
+  0x2000001    MakerNoteVersion                 no
+  0x2000005    WhiteBalance                     no
+  0x2000007    FocusMode                        no
+  0x200000b    WhiteBalanceFineTune             no
+  0x200001b    CropHiSpeed                      no
+  0x200001e    ColorSpace                       no
+  0x200001f    VRInfo                           Nikon VRInfo
+  0x2000022    ActiveD-Lighting                 no
   0x2000023    PictureControlData               Nikon PictureControl
+                                                Nikon PictureControl2
+                                                Nikon PictureControl3
+                                                Nikon PictureControlUnknown
   0x2000024    WorldTime                        Nikon WorldTime
-  0x2000032    UnknownInfo                      Nikon UnknownInfo
-  0x2000083    LensType                         N
-  0x2000084    Lens                             N
+  0x2000025    ISOInfo                          Nikon ISOInfo
+  0x200002a    VignetteControl                  no
+  0x200002c    UnknownInfo                      Nikon UnknownInfo
+  0x2000032    UnknownInfo2                     Nikon UnknownInfo2
+  0x2000039    LocationInfo                     Nikon LocationInfo
+  0x2000083    LensType                         no
+  0x2000084    Lens                             no
+  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
+               FlashInfo0102                    Nikon FlashInfo0102
+               FlashInfo0103                    Nikon FlashInfo0103
+               FlashInfo0106                    Nikon FlashInfo0106
+               FlashInfo0107                    Nikon FlashInfo0107
+               FlashInfoUnknown                 Nikon FlashInfoUnknown
+  0x20000ab    VariProgram                      no
+  0x20000b1    HighISONoiseReduction            no
+  0x20000b7    AFInfo2                          Nikon AFInfo2
+  0x20000c3    BarometerInfo                    Nikon BarometerInfo
 
 =head3 Nikon MOV Tags
@@ -7449,15 +13531,15 @@
 This information is found in MOV and QT videos from some Nikon cameras.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     24    Model                                N
-     38    ExposureTime                         N
-     42    FNumber                              N
-     50    ExposureCompensation                 N
-     68    WhiteBalance                         N
-     72    FocalLength                          N
-    175    Software                             N
-    223    ISO                                  N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    Model                                no
+     38    ExposureTime                         no
+     42    FNumber                              no
+     50    ExposureCompensation                 no
+     68    WhiteBalance                         no
+     72    FocalLength                          no
+    175    Software                             no
+    223    ISO                                  no
 
 =head3 Nikon AVI Tags
@@ -7468,7 +13550,7 @@
   ------   --------                             --------
   'nctg'   NikonTags                            Nikon AVITags
-  'ncth'   ThumbnailImage                       N
+  'ncth'   ThumbnailImage                       no
   'ncvr'   NikonVers                            Nikon AVIVers
-  'ncvw'   PreviewImage                         N
+  'ncvw'   PreviewImage                         no
 
 =head3 Nikon AVITags Tags
@@ -7479,27 +13561,27 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0003   Make                                 N
-  0x0004   Model                                N
-  0x0005   Software                             N
-  0x0006   Equipment                            N
-  0x0007   Orientation                          N
-  0x0008   ExposureTime                         N
-  0x0009   FNumber                              N
-  0x000a   ExposureCompensation                 N
-  0x000b   MaxApertureValue                     N
-  0x000c   MeteringMode                         N
-  0x000f   FocalLength                          N
-  0x0010   XResolution                          N
-  0x0011   YResolution                          N
-  0x0012   ResolutionUnit                       N
-  0x0013   DateTimeOriginal                     N
-  0x0014   CreateDate                           N
-  0x0016   Duration                             N
-  0x0018   FocusMode                            N
-  0x001b   DigitalZoom                          N
-  0x001d   ColorMode                            N
-  0x001e   Sharpness                            N
-  0x001f   WhiteBalance                         N
-  0x0020   NoiseReduction                       N
+  0x0003   Make                                 no
+  0x0004   Model                                no
+  0x0005   Software                             no
+  0x0006   Equipment                            no
+  0x0007   Orientation                          no
+  0x0008   ExposureTime                         no
+  0x0009   FNumber                              no
+  0x000a   ExposureCompensation                 no
+  0x000b   MaxApertureValue                     no
+  0x000c   MeteringMode                         no
+  0x000f   FocalLength                          no
+  0x0010   XResolution                          no
+  0x0011   YResolution                          no
+  0x0012   ResolutionUnit                       no
+  0x0013   DateTimeOriginal                     no
+  0x0014   CreateDate                           no
+  0x0016   Duration                             no
+  0x0018   FocusMode                            no
+  0x001b   DigitalZoom                          no
+  0x001d   ColorMode                            no
+  0x001e   Sharpness                            no
+  0x001f   WhiteBalance                         no
+  0x0020   NoiseReduction                       no
 
 =head3 Nikon AVIVers Tags
@@ -7507,15 +13589,22 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0001   MakerNoteType                        N
-  0x0002   MakerNoteVersion                     N
+  0x0001   MakerNoteType                        no
+  0x0002   MakerNoteVersion                     no
 
 =head2 NikonCustom Tags
 
+Unfortunately, the NikonCustom settings are stored in a binary data block
+which changes from model to model.  This means that significant effort must
+be spent in decoding these for each model, usually requiring hundreds of
+test images from a dedicated Nikon owner.  For this reason, the NikonCustom
+settings have not been decoded for all models.  The tables below list the
+custom settings for the currently supported models.
+
 =head3 NikonCustom SettingsD40 Tags
 
 Custom settings for the Nikon D40.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    Beep                                 int8u & 0x80
     0.2    AFAssist                             int8u & 0x40
@@ -7545,6 +13634,6 @@
 Custom settings for the Nikon D80.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    Beep                                 int8u & 0x80
     0.2    AFAssist                             int8u & 0x40
@@ -7600,6 +13689,6 @@
 Custom settings for the D90.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    LightSwitch                          int8u & 0x08
     2.1    AFAreaModeSetting                    int8u & 0x60
@@ -7661,6 +13750,6 @@
 Custom settings for the D3, D3S, D3X, D300 and D300S.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    CustomSettingsBank                   int8u & 0x03
     0.2    CustomSettingsAllDefault             int8u & 0x80
@@ -7736,10 +13825,17 @@
    20.2    FlashShutterSpeed                    int8u & 0x0f
    21.1    AutoBracketSet                       int8u & 0xc0
+           AutoBracketSet                       int8u & 0xe0
    21.2    AutoBracketModeM                     int8u & 0x30
+           AutoBracketModeM                     int8u & 0x18
    21.3    AutoBracketOrder                     int8u & 0x08
+           AutoBracketOrder                     int8u & 0x04
    21.4    ModelingFlash                        int8u & 0x01
    22.1    NoMemoryCard                         int8u & 0x80
    22.2    MeteringTime                         int8u & 0x0f
    23.1    InternalFlash                        int8u & 0xc0
+   25.1    ImageReviewTime                      int8u & 0xe0
+   25.2    PlaybackMonitorOffTime               int8u & 0x1c
+   26.1    MenuMonitorOffTime                   int8u & 0xe0
+   26.2    ShootingInfoMonitorOffTime           int8u & 0x1c
 
 =head3 NikonCustom SettingsD700 Tags
@@ -7747,6 +13843,6 @@
 Custom settings for the D700.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    CustomSettingsBank                   int8u & 0x03
     0.2    CustomSettingsAllDefault             int8u & 0x80
@@ -7820,10 +13916,227 @@
    33.8    ReleaseButtonToUseDial               int8u & 0x01
 
+=head3 NikonCustom SettingsD800 Tags
+
+Custom settings for the D800 and D800E.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+   12.1    AutoBracketingSet                    int8u & 0xe0
+   12.2    AutoBracketOrder                     int8u & 0x10
+   12.3    AutoBracketingMode                   int8u & 0x0c
+   22.1    FlashSyncSpeed                       int8u & 0xf0
+   22.2    FlashShutterSpeed                    int8u & 0x0f
+   23.1    FlashControlBuilt-in                 int8u & 0xc0
+   23.2    ManualFlashOutput                    int8u & 0x1f
+   24.1    RepeatingFlashOutput                 int8u & 0x70
+   24.2    RepeatingFlashCount                  int8u & 0x0f
+   25.1    RepeatingFlashRate                   int8u & 0xf0
+   25.2    CommanderChannel                     int8u & 0x03
+   27.1    CommanderInternalFlash               int8u & 0xc0
+   27.2    CommanderInternalManualOutput        int8u & 0x1f
+   28.1    CommanderGroupAMode                  int8u & 0xc0
+   28.2    CommanderGroupAManualOutput          int8u & 0x1f
+   29.1    CommanderGroupBMode                  int8u & 0xc0
+   29.2    CommanderGroupBManualOutput          int8u & 0x1f
+   30.1    ModelingFlash                        int8u & 0x20
+   30.2    CommanderInternalTTLComp             int8u & 0x1f
+   31.1    CommanderGroupA_TTL-AAComp           int8u & 0x1f
+   32.1    CommanderGroupB_TTL-AAComp           int8u & 0x1f
+
+=head3 NikonCustom SettingsD810 Tags
+
+Custom settings for the D810.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    LightSwitch                          int8u & 0x08
+    0.2    CustomSettingsBank                   int8u & 0x03
+    1.1    AF-CPrioritySelection                int8u & 0xc0
+    1.2    AF-SPrioritySelection                int8u & 0x20
+    1.3    AFPointSelection                     int8u & 0x10
+    1.4    FocusTrackingLockOn                  int8u & 0x07
+    2.1    AFActivation                         int8u & 0x80
+    2.2    FocusPointWrap                       int8u & 0x08
+    2.3    AFPointBrightness                    int8u & 0x06
+    2.4    AFAssist                             int8u & 0x01
+    3.1    BatteryOrder                         int8u & 0x40
+    3.2    MB-D12BatteryType                    int8u & 0x03
+    4.1    Pitch                                int8u & 0x40
+    4.2    NoMemoryCard                         int8u & 0x20
+    4.3    ISODisplay                           int8u & 0x0c
+    4.4    GridDisplay                          int8u & 0x02
+    5.1    ShootingInfoDisplay                  int8u & 0xc0
+    5.2    LCDIllumination                      int8u & 0x20
+    5.3    ElectronicFront-CurtainShutter       int8u & 0x08
+    5.4    ScreenTips                           int8u & 0x04
+    5.5    Beep                                 int8u & 0x03
+    6.1    ReverseIndicators                    int8u & 0x80
+    6.2    CommandDialsReverseRotation          int8u & 0x18
+    6.3    EasyExposureCompensation             int8u & 0x03
+    7.1    ExposureControlStepSize              int8u & 0xc0
+    7.2    ISOStepSize                          int8u & 0x30
+    7.3    ExposureCompStepSize                 int8u & 0x0c
+    8.1    CenterWeightedAreaSize               int8u & 0xe0
+    8.2    FineTuneOptMatrixMetering            int8u & 0x0f
+    9.1    FineTuneOptCenterWeighted            int8u & 0xf0
+    9.2    FineTuneOptSpotMetering              int8u & 0x0f
+   10.1    MultiSelectorShootMode               int8u & 0xc0
+   10.2    MultiSelectorPlaybackMode            int8u & 0x30
+   10.3    MultiSelector                        int8u & 0x01
+   11.1    ExposureDelayMode                    int8u & 0xc0
+   11.2    CLModeShootingSpeed                  int8u & 0x0f
+   12.1    MaxContinuousRelease                 int8u
+   13.1    AutoBracketSet                       int8u & 0xe0
+   13.2    AutoBracketOrder                     int8u & 0x10
+   13.3    AutoBracketModeM                     int8u & 0x0c
+   14.1    FuncButton                           int8u & 0x1f
+   15.1    PreviewButton                        int8u & 0x1f
+   16.1    AssignBktButton                      int8u & 0x07
+   17.1    AELockButton                         int8u & 0x1f
+   18.1    CommandDialsChangeMainSub            int8u & 0xe0
+   18.2    CommandDialsMenuAndPlayback          int8u & 0x18
+   18.3    CommandDialsApertureSetting          int8u & 0x04
+   18.4    ShutterReleaseButtonAE-L             int8u & 0x02
+   18.5    ReleaseButtonToUseDial               int8u & 0x01
+   19.1    StandbyTimer                         int8u & 0xf0
+   20.1    SelfTimerTime                        int8u & 0xc0
+   20.2    SelfTimerShotInterval                int8u & 0x30
+   20.3    SelfTimerShotCount                   int8u & 0x0f
+   21.1    ImageReviewMonitorOffTime            int8u & 0xe0
+   21.2    LiveViewMonitorOffTime               int8u & 0x1c
+   22.1    MenuMonitorOffTime                   int8u & 0xe0
+   22.2    ShootingInfoMonitorOffTime           int8u & 0x1c
+   23.1    FlashSyncSpeed                       int8u & 0xf0
+   23.2    FlashShutterSpeed                    int8u & 0x0f
+   24.1    FlashControlBuilt-in                 int8u & 0xc0
+   31.1    ModelingFlash                        int8u & 0x20
+   36.1    PlaybackMonitorOffTime               int8u & 0xe0
+   37.1    MultiSelectorLiveView                int8u & 0xc0
+   38.1    ShutterSpeedLock                     int8u & 0x80
+   38.2    ApertureLock                         int8u & 0x40
+   38.3    MovieShutterButton                   int8u & 0x20
+   38.4    FlashExposureCompArea                int8u & 0x04
+   40.1    MovieAELockButtonAssignment          int8u & 0x0f
+   41.1    MovieFunctionButton                  int8u & 0x70
+   41.2    MoviePreviewButton                   int8u & 0x07
+   42.1    FuncButtonPlusDials                  int8u & 0x0f
+   43.1    PreviewButtonPlusDials               int8u & 0x0f
+   44.1    AELockButtonPlusDials                int8u & 0x0f
+   45.1    AssignMovieRecordButton              int8u & 0x0f
+   46.1    FineTuneOptHighlightWeighted         int8u & 0x0f
+   47.1    DynamicAreaAFDisplay                 int8u & 0x80
+   47.2    AFPointIllumination                  int8u & 0x40
+   47.3    StoreByOrientation                   int8u & 0x18
+   47.4    GroupAreaAFIllumination              int8u & 0x04
+   48.1    MatrixMetering                       int8u & 0x80
+   48.2    LiveViewButtonOptions                int8u & 0x30
+   48.3    AFModeRestrictions                   int8u & 0x03
+   49.1    LimitAFAreaModeSelection             int8u & 0x7e
+   50.1    AF-OnForMB-D12                       int8u & 0x07
+   51.1    AssignRemoteFnButton                 int8u & 0x1f
+   52.1    LensFocusFunctionButtons             int8u & 0x3f
+
+=head3 NikonCustom SettingsD850 Tags
+
+Custom settings for the D850.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.2    CustomSettingsBank                   int8u & 0x03
+    1.1    AF-CPrioritySelection                int8u & 0xc0
+    1.2    AF-SPrioritySelection                int8u & 0x20
+    1.3    AFPointSelection                     int8u & 0x10
+    1.4    Three-DTrackingFaceDetection         int8u & 0x08
+    1.5    BlockShotAFResponse                  int8u & 0x07
+    2.1    FocusPointWrap                       int8u & 0x08
+    2.2    AFPointBrightness                    int8u & 0x06
+    4.1    ISODisplay                           int8u & 0x08
+    4.2    GridDisplay                          int8u & 0x02
+    5.1    LCDIllumination                      int8u & 0x20
+    5.2    ElectronicFront-CurtainShutter       int8u & 0x08
+    6.1    ReverseIndicators                    int8u & 0x80
+    6.2    CommandDialsReverseRotation          int8u & 0x18
+    6.3    EasyExposureCompensation             int8u & 0x03
+    7.1    ExposureControlStepSize              int8u & 0xc0
+    7.2    ISOStepSize                          int8u & 0x30
+    7.3    ExposureCompStepSize                 int8u & 0x0c
+    8.1    CenterWeightedAreaSize               int8u & 0xe0
+    8.2    FineTuneOptMatrixMetering            int8u & 0x0f
+    9.1    FineTuneOptCenterWeighted            int8u & 0xf0
+    9.2    FineTuneOptSpotMetering              int8u & 0x0f
+   10.1    MultiSelectorShootMode               int8u & 0xe0
+   10.2    MultiSelectorPlaybackMode            int8u & 0x0c
+   10.3    MultiSelector                        int8u & 0x01
+   11.1    ExposureDelayMode                    int8u & 0xe0
+   11.2    CLModeShootingSpeed                  int8u & 0x0f
+   12.1    MaxContinuousRelease                 int8u
+   13.1    AutoBracketOrder                     int8u & 0x10
+   13.2    AutoBracketModeM                     int8u & 0x0c
+   14.1    Func1Button                          int8u & 0x3f
+   15.1    PreviewButton                        int8u & 0x3f
+   16.1    AssignBktButton                      int8u & 0x07
+   18.1    CommandDialsChangeMainSub            int8u & 0xe0
+   18.2    CommandDialsMenuAndPlayback          int8u & 0x18
+   18.3    CommandDialsApertureSetting          int8u & 0x04
+   18.4    ReleaseButtonToUseDial               int8u & 0x01
+   19.1    StandbyTimer                         int8u & 0xf0
+   20.1    SelfTimerTime                        int8u & 0xc0
+   20.2    SelfTimerShotInterval                int8u & 0x30
+   20.3    SelfTimerShotCount                   int8u & 0x0f
+   21.1    ImageReviewMonitorOffTime            int8u & 0xe0
+   21.2    LiveViewMonitorOffTime               int8u & 0x1c
+   22.1    MenuMonitorOffTime                   int8u & 0xe0
+   22.2    ShootingInfoMonitorOffTime           int8u & 0x1c
+   23.1    FlashSyncSpeed                       int8u & 0xf0
+   23.2    FlashShutterSpeed                    int8u & 0x0f
+   31.1    ModelingFlash                        int8u & 0x20
+   36.1    PlaybackMonitorOffTime               int8u & 0xe0
+   37.1    MultiSelectorLiveView                int8u & 0xc0
+   38.1    ShutterSpeedLock                     int8u & 0x80
+   38.2    ApertureLock                         int8u & 0x40
+   38.3    MovieShutterButton                   int8u & 0x10
+   38.4    FlashExposureCompArea                int8u & 0x04
+   38.5    AutoFlashISOSensitivity              int8u & 0x02
+   41.1    MovieFunc1Button                     int8u & 0xf0
+   41.2    MoviePreviewButton                   int8u & 0x0f
+   42.1    Func1ButtonPlusDials                 int8u & 0x0f
+   43.1    PreviewButtonPlusDials               int8u & 0x0f
+   45.1    AssignMovieRecordButtonPlusDials     int8u & 0x0f
+   46.1    FineTuneOptHighlightWeighted         int8u & 0x0f
+   47.1    DynamicAreaAFDisplay                 int8u & 0x80
+   47.2    AFPointIllumination                  int8u & 0x40
+   47.3    StoreByOrientation                   int8u & 0x18
+   48.1    MatrixMetering                       int8u & 0x80
+   48.2    LiveViewButtonOptions                int8u & 0x30
+   48.3    AFModeRestrictions                   int8u & 0x03
+   49.1    LimitAFAreaModeSelection             int8u & 0x7e
+   52.1    LensFocusFunctionButtons             int8u & 0x3f
+   66.1    VerticalMultiSelector                int8u & 0xff
+   67.1    AssignMB-D18FuncButton               int8u & 0x3f
+   68.1    AssignMB-D18FuncButtonPlusDials      int8u & 0x0f
+   70.1    AF-OnButton                          int8u & 0x3f
+   71.1    SubSelector                          int8u & 0x80
+   72.1    SubSelectorCenter                    int8u & 0x3f
+   73.1    SubSelectorPlusDials                 int8u & 0x0f
+   74.1    AssignMovieSubselector               int8u & 0xf0
+   75.1    AssignMovieFunc1ButtonPlusDials      int8u & 0x10
+   75.2    AssignMoviePreviewButtonPlusDials    int8u & 0x01
+   76.1    AssignMovieSubselectorPlusDials      int8u & 0x10
+   77.1    SyncReleaseMode                      int8u & 0x80
+   77.2    ContinuousModeLiveView               int8u & 0x40
+   78.1    Three-DTrackingWatchArea             int8u & 0x80
+   78.2    SubjectMotion                        int8u & 0x60
+   78.3    AFActivation                         int8u & 0x08
+   78.4    ShutterReleaseButtonAE-L             int8u & 0x03
+   79.1    AssignMB-D18AF-OnButton              int8u & 0x7f
+   80.1    Func2Button                          int8u & 0x3f
+   82.1    AssignMovieFunc2Button               int8u & 0x70
+
 =head3 NikonCustom SettingsD5000 Tags
 
 Custom settings for the D5000.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    AFAreaModeSetting                    int8u & 0x60
     0.2    AFAssist                             int8u & 0x01
@@ -7853,17 +14166,80 @@
    32.1    LiveViewAF                           int8u & 0x60
 
+=head3 NikonCustom SettingsD5100 Tags
+
+Custom settings for the D5100.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    AF-CPrioritySelection                int8u & 0x80
+    1.1    AFAssist                             int8u & 0x01
+    3.1    Beep                                 int8u & 0xc0
+    3.2    NoMemoryCard                         int8u & 0x20
+    3.3    ISODisplay                           int8u & 0x08
+    4.1    FileNumberSequence                   int8u & 0x08
+    5.1    RangeFinder                          int8u & 0x10
+    5.2    ReverseIndicators                    int8u & 0x80
+    6.1    EVStepSize                           int8u & 0x40
+   10.1    ExposureDelayMode                    int8u & 0x40
+   12.1    AutoBracketSet                       int8u & 0xc0
+   13.1    TimerFunctionButton                  int8u & 0x38
+   16.1    AELockButton                         int8u & 0x38
+   17.1    ShutterReleaseButtonAE-L             int8u & 0x02
+   17.2    CommandDialsReverseRotation          int8u & 0x80
+   18.1    MeteringTime                         int8u & 0x70
+   18.2    RemoteOnDuration                     int8u & 0x03
+   19.1    SelfTimerTime                        int8u & 0xc0
+   19.2    SelfTimerShotCount                   int8u & 0x0f
+   20.1    ImageReviewTime                      int8u & 0xe0
+   20.2    LiveViewMonitorOffTime               int8u & 0x1c
+   21.1    PlaybackMenusTime                    int8u & 0xe0
+   23.1    ManualFlashOutput                    int8u & 0x1f
+
+=head3 NikonCustom SettingsD5200 Tags
+
+Custom settings for the D5200.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    AF-CPrioritySelection                int8u & 0x80
+    0.2    NumberOfFocusPoints                  int8u & 0x10
+    1.1    AFAssist                             int8u & 0x01
+    3.1    Beep                                 int8u & 0xc0
+    3.2    NoMemoryCard                         int8u & 0x20
+    3.3    ISODisplay                           int8u & 0x08
+    4.1    FileNumberSequence                   int8u & 0x08
+    5.1    RangeFinder                          int8u & 0x04
+    5.2    ReverseExposureCompDial              int8u & 0x10
+    5.3    ReverseShutterSpeedAperture          int8u & 0x08
+    5.4    ReverseIndicators                    int8u & 0x80
+    6.1    EVStepSize                           int8u & 0x40
+   10.1    ExposureDelayMode                    int8u & 0x40
+   12.1    AutoBracketSet                       int8u & 0xc0
+   13.1    FunctionButton                       int8u & 0x1f
+   16.1    AELockButton                         int8u & 0x0f
+   17.1    ShutterReleaseButtonAE-L             int8u & 0x02
+   18.1    StandbyTimer                         int8u & 0xe0
+   18.2    RemoteOnDuration                     int8u & 0x03
+   19.1    SelfTimerTime                        int8u & 0xc0
+   19.2    SelfTimerShotCount                   int8u & 0x0f
+   20.1    ImageReviewTime                      int8u & 0xe0
+   20.2    LiveViewMonitorOffTime               int8u & 0x1c
+   21.1    PlaybackMenusTime                    int8u & 0xe0
+   23.1    InternalFlash                        int8u & 0xc0
+   23.2    ManualFlashOutput                    int8u & 0x1f
+
 =head3 NikonCustom SettingsD7000 Tags
 
 Custom settings for the D7000.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    AF-CPrioritySelection                int8u & 0x80
     0.2    AF-SPrioritySelection                int8u & 0x20
     0.3    NumberOfFocusPoints                  int8u & 0x10
     0.4    FocusTrackingLockOn                  int8u & 0x07
-    1.2    FocusPointWrap                       int8u & 0x08
-    1.3    AFPointIllumination                  int8u & 0x06
-    1.4    AFAssist                             int8u & 0x01
+    1.1    FocusPointWrap                       int8u & 0x08
+    1.2    AFPointIllumination                  int8u & 0x06
+    1.3    AFAssist                             int8u & 0x01
     2.1    BatteryOrder                         int8u & 0x40
     2.2    AF-OnForMB-D11                       int8u & 0x1c
@@ -7924,4 +14300,324 @@
    35.1    PlaybackMonitorOffTime               int8u & 0xe0
 
+=head3 NikonCustom SettingsD4 Tags
+
+Custom settings for the D4 and D4S.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    CustomSettingsBank                   int8u & 0x03
+    1.1    AF-CPrioritySelection                int8u & 0xc0
+    1.2    AF-SPrioritySelection                int8u & 0x20
+    1.3    AFPointSelection                     int8u & 0x10
+    1.4    FocusTrackingLockOn                  int8u & 0x07
+    2.1    AFActivation                         int8u & 0x80
+    2.2    FocusPointWrap                       int8u & 0x08
+    4.1    Pitch                                int8u & 0x40
+    4.2    NoMemoryCard                         int8u & 0x20
+    4.3    GridDisplay                          int8u & 0x02
+    5.1    ShootingInfoDisplay                  int8u & 0xc0
+    5.2    LCDIllumination                      int8u & 0x20
+    5.3    ScreenTips                           int8u & 0x04
+    5.4    Beep                                 int8u & 0x03
+    6.1    ReverseIndicators                    int8u & 0x80
+    6.2    RearDisplay                          int8u & 0x40
+    6.3    ViewfinderDisplay                    int8u & 0x20
+    6.4    CommandDialsReverseRotation          int8u & 0x18
+    6.5    EasyExposureCompensation             int8u & 0x03
+    7.1    ExposureControlStepSize              int8u & 0xc0
+    7.2    ISOStepSize                          int8u & 0x30
+    7.3    ExposureCompStepSize                 int8u & 0x0c
+    8.1    CenterWeightedAreaSize               int8u & 0xe0
+    8.2    FineTuneOptMatrixMetering            int8u & 0x0f
+    9.1    FineTuneOptCenterWeighted            int8u & 0xf0
+    9.2    FineTuneOptSpotMetering              int8u & 0x0f
+   10.1    MultiSelectorShootMode               int8u & 0xc0
+   10.2    MultiSelectorPlaybackMode            int8u & 0x30
+   10.3    MultiSelector                        int8u & 0x01
+   11.1    ExposureDelayMode                    int8u & 0xc0
+   11.2    CHModeShootingSpeed                  int8u & 0x10
+   11.3    CLModeShootingSpeed                  int8u & 0x0f
+     12    MaxContinuousRelease                 int8u
+   13.1    AutoBracketSet                       int8u & 0xe0
+   13.2    AutoBracketOrder                     int8u & 0x10
+   13.3    AutoBracketModeM                     int8u & 0x0c
+   14.1    FuncButton                           int8u & 0xf8
+   14.2    FuncButtonPlusDials                  int8u & 0x07
+   15.1    PreviewButton                        int8u & 0xf8
+   15.2    PreviewButtonPlusDials               int8u & 0x07
+   16.1    AssignBktButton                      int8u & 0x07
+   18.1    CommandDialsChangeMainSub            int8u & 0xe0
+   18.2    CommandDialsMenuAndPlayback          int8u & 0x18
+   18.3    CommandDialsApertureSetting          int8u & 0x04
+   18.4    ShutterReleaseButtonAE-L             int8u & 0x02
+   18.5    ReleaseButtonToUseDial               int8u & 0x01
+   19.1    StandbyTimer                         int8u & 0xf0
+   20.1    SelfTimerTime                        int8u & 0xc0
+   20.2    SelfTimerShotCount                   int8u & 0x0f
+   20.3    SelfTimerShotInterval                int8u & 0x30
+   21.1    ImageReviewMonitorOffTime            int8u & 0xe0
+   21.2    LiveViewMonitorOffTime               int8u & 0x1c
+   22.1    MenuMonitorOffTime                   int8u & 0xe0
+   22.2    ShootingInfoMonitorOffTime           int8u & 0x1c
+   23.1    FlashSyncSpeed                       int8u & 0xf0
+   23.2    FlashShutterSpeed                    int8u & 0x0f
+   31.1    ModelingFlash                        int8u & 0x20
+   36.1    PlaybackMonitorOffTime               int8u & 0xe0
+   37.1    PlaybackZoom                         int8u & 0x01
+   38.1    ShutterSpeedLock                     int8u & 0x80
+   38.2    ApertureLock                         int8u & 0x40
+   38.3    MovieShutterButton                   int8u & 0x30
+   38.4    FlashExposureCompArea                int8u & 0x04
+   41.1    MovieFunctionButton                  int8u & 0x70
+   41.2    MoviePreviewButton                   int8u & 0x07
+   42.1    VerticalMultiSelector                int8u & 0x60
+   42.2    VerticalFuncButton                   int8u & 0x1f
+   43.1    VerticalFuncButtonPlusDials          int8u & 0xf0
+   43.2    AssignMovieRecordButton              int8u & 0x07
+   46.1    DynamicAreaAFDisplay                 int8u & 0x80
+   46.2    AFPointIllumination                  int8u & 0x60
+   46.3    StoreByOrientation                   int8u & 0x18
+   46.4    GroupAreaAFIllumination              int8u & 0x04
+   46.5    AFPointBrightness                    int8u & 0x03
+   47.1    AFOnButton                           int8u & 0x70
+   47.2    VerticalAFOnButton                   int8u & 0x07
+   48.1    SubSelectorAssignment                int8u & 0x80
+   48.2    MovieSubSelectorAssignment           int8u & 0x07
+   49.1    SubSelector                          int8u & 0xf8
+   49.2    SubSelectorPlusDials                 int8u & 0x07
+   50.1    MatrixMetering                       int8u & 0x80
+   50.2    LiveViewButtonOptions                int8u & 0x30
+   50.3    AFModeRestrictions                   int8u & 0x03
+   51.1    LimitAFAreaModeSelection             int8u & 0x7e
+   52.1    MovieFunctionButtonPlusDials         int8u & 0x10
+   52.2    MoviePreviewButtonPlusDials          int8u & 0x01
+   53.1    MovieSubSelectorAssignmentPlusDials  int8u & 0x10
+   54.1    AssignRemoteFnButton                 int8u & 0x1f
+   55.1    LensFocusFunctionButtons             int8u & 0x3f
+
+=head3 NikonCustom SettingsD5 Tags
+
+Custom settings for the D5.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    CustomSettingsBank                   int8u & 0x03
+    1.1    AF-CPrioritySelection                int8u & 0xc0
+    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
+    4.1    ISODisplay                           int8u & 0x08
+    4.2    GridDisplay                          int8u & 0x02
+    5.1    LCDIllumination                      int8u & 0x20
+    5.2    ElectronicFront-CurtainShutter       int8u & 0x08
+    6.1    ReverseIndicators                    int8u & 0x80
+    6.2    CommandDialsReverseRotation          int8u & 0x18
+    6.3    EasyExposureCompensation             int8u & 0x03
+    7.1    ExposureControlStepSize              int8u & 0xc0
+    7.2    ISOStepSize                          int8u & 0x30
+    7.3    ExposureCompStepSize                 int8u & 0x0c
+    8.1    CenterWeightedAreaSize               int8u & 0xe0
+    8.2    FineTuneOptMatrixMetering            int8u & 0x0f
+    9.1    FineTuneOptCenterWeighted            int8u & 0xf0
+    9.2    FineTuneOptSpotMetering              int8u & 0x0f
+   10.1    MultiSelectorShootMode               int8u & 0xe0
+   10.3    MultiSelector                        int8u & 0x01
+   11.1    ExposureDelayMode                    int8u & 0xc0
+   11.2    CLModeShootingSpeed                  int8u & 0x0f
+   12.1    MaxContinuousRelease                 int8u
+   13.1    AutoBracketOrder                     int8u & 0x10
+   13.2    AutoBracketModeM                     int8u & 0x0c
+   14.1    Func1Button                          int8u & 0x3f
+   15.1    PreviewButton                        int8u & 0x3f
+   16.1    AssignBktButton                      int8u & 0x07
+   18.1    CommandDialsChangeMainSub            int8u & 0xe0
+   18.2    CommandDialsMenuAndPlayback          int8u & 0x18
+   18.3    CommandDialsApertureSetting          int8u & 0x04
+   18.4    ReleaseButtonToUseDial               int8u & 0x01
+   19.1    StandbyTimer                         int8u & 0xf0
+   20.1    SelfTimerTime                        int8u & 0xc0
+   20.2    SelfTimerShotInterval                int8u & 0x30
+   20.3    SelfTimerShotCount                   int8u & 0x0f
+   21.1    ImageReviewMonitorOffTime            int8u & 0xe0
+   21.2    LiveViewMonitorOffTime               int8u & 0x1c
+   22.1    MenuMonitorOffTime                   int8u & 0xe0
+   22.2    ShootingInfoMonitorOffTime           int8u & 0x1c
+   23.1    FlashSyncSpeed                       int8u & 0xf0
+   23.2    FlashShutterSpeed                    int8u & 0x0f
+   31.1    ModelingFlash                        int8u & 0x20
+   36.1    PlaybackMonitorOffTime               int8u & 0xe0
+   37.1    MultiSelectorLiveView                int8u & 0xc0
+   38.1    ShutterSpeedLock                     int8u & 0x80
+   38.2    ApertureLock                         int8u & 0x40
+   38.3    MovieShutterButton                   int8u & 0x10
+   38.4    FlashExposureCompArea                int8u & 0x04
+   38.5    AutoFlashISOSensitivity              int8u & 0x02
+   41.1    MovieFunc1Button                     int8u & 0xf0
+   41.2    MoviePreviewButton                   int8u & 0x0f
+   42.1    Func1ButtonPlusDials                 int8u & 0x0f
+   43.1    PreviewButtonPlusDials               int8u & 0x0f
+   45.1    AssignMovieRecordButtonPlusDials     int8u & 0x0f
+   46.1    FineTuneOptHighlightWeighted         int8u & 0x0f
+   47.1    DynamicAreaAFDisplay                 int8u & 0x80
+   47.2    AFPointIllumination                  int8u & 0x40
+   47.3    StoreByOrientation                   int8u & 0x18
+   48.1    MatrixMetering                       int8u & 0x80
+   48.2    LiveViewButtonOptions                int8u & 0x30
+   48.3    AFModeRestrictions                   int8u & 0x03
+   49.1    LimitAFAreaModeSelection             int8u & 0x7e
+   52.1    LensFocusFunctionButtons             int8u & 0x3f
+   66.1    VerticalMultiSelector                int8u & 0xff
+   67.1    VerticalFuncButton                   int8u & 0x3f
+   68.1    VerticalFuncPlusDials                int8u & 0x0f
+   70.1    AF-OnButton                          int8u & 0x3f
+   71.1    SubSelector                          int8u & 0x80
+   72.1    SubSelectorCenter                    int8u & 0x3f
+   73.1    SubSelectorPlusDials                 int8u & 0x0f
+   74.1    AssignMovieSubselector               int8u & 0xf0
+   75.1    AssignMovieFunc1ButtonPlusDials      int8u & 0x10
+   75.2    AssignMoviePreviewButtonPlusDials    int8u & 0x01
+   76.1    AssignMovieSubselectorPlusDials      int8u & 0x10
+   77.1    SyncReleaseMode                      int8u & 0x80
+   78.1    Three-DTrackingWatchArea             int8u & 0x80
+   78.2    SubjectMotion                        int8u & 0x60
+   78.3    AFActivation                         int8u & 0x08
+   78.4    ShutterReleaseButtonAE-L             int8u & 0x03
+   79.1    VerticalAFOnButton                   int8u & 0x7f
+   80.1    Func2Button                          int8u & 0x3f
+   81.1    Func2ButtonPlusDials                 int8u & 0x0f
+   82.1    AssignMovieFunc2Button               int8u & 0x70
+   83.1    Func3Button                          int8u & 0x03
+
+=head3 NikonCustom SettingsD500 Tags
+
+Custom settings for the D500.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    CustomSettingsBank                   int8u & 0x03
+    1.1    AF-CPrioritySelection                int8u & 0xc0
+    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
+    4.1    ISODisplay                           int8u & 0x08
+    4.2    GridDisplay                          int8u & 0x02
+    5.1    LCDIllumination                      int8u & 0x20
+    5.2    ElectronicFront-CurtainShutter       int8u & 0x08
+    6.1    ReverseIndicators                    int8u & 0x80
+    6.2    CommandDialsReverseRotation          int8u & 0x18
+    6.3    EasyExposureCompensation             int8u & 0x03
+    7.1    ExposureControlStepSize              int8u & 0xc0
+    7.2    ISOStepSize                          int8u & 0x30
+    7.3    ExposureCompStepSize                 int8u & 0x0c
+    8.1    CenterWeightedAreaSize               int8u & 0xe0
+    8.2    FineTuneOptMatrixMetering            int8u & 0x0f
+    9.1    FineTuneOptCenterWeighted            int8u & 0xf0
+    9.2    FineTuneOptSpotMetering              int8u & 0x0f
+   10.1    MultiSelectorShootMode               int8u & 0xe0
+   10.2    MultiSelectorPlaybackMode            int8u & 0x0c
+   10.3    MultiSelector                        int8u & 0x01
+   11.1    ExposureDelayMode                    int8u & 0xc0
+   11.2    CLModeShootingSpeed                  int8u & 0x0f
+   12.1    MaxContinuousRelease                 int8u
+   13.1    AutoBracketOrder                     int8u & 0x10
+   13.2    AutoBracketModeM                     int8u & 0x0c
+   14.1    Func1Button                          int8u & 0x3f
+   15.1    PreviewButton                        int8u & 0x3f
+   16.1    AssignBktButton                      int8u & 0x07
+   18.1    CommandDialsChangeMainSub            int8u & 0xe0
+   18.2    CommandDialsMenuAndPlayback          int8u & 0x18
+   18.3    CommandDialsApertureSetting          int8u & 0x04
+   18.4    ReleaseButtonToUseDial               int8u & 0x01
+   19.1    StandbyTimer                         int8u & 0xf0
+   20.1    SelfTimerTime                        int8u & 0xc0
+   20.2    SelfTimerShotInterval                int8u & 0x30
+   20.3    SelfTimerShotCount                   int8u & 0x0f
+   21.1    ImageReviewMonitorOffTime            int8u & 0xe0
+   21.2    LiveViewMonitorOffTime               int8u & 0x1c
+   22.1    MenuMonitorOffTime                   int8u & 0xe0
+   22.2    ShootingInfoMonitorOffTime           int8u & 0x1c
+   23.1    FlashSyncSpeed                       int8u & 0xf0
+   23.2    FlashShutterSpeed                    int8u & 0x0f
+   31.1    ModelingFlash                        int8u & 0x20
+   36.1    PlaybackMonitorOffTime               int8u & 0xe0
+   37.1    MultiSelectorLiveView                int8u & 0xc0
+   38.1    ShutterSpeedLock                     int8u & 0x80
+   38.2    ApertureLock                         int8u & 0x40
+   38.3    MovieShutterButton                   int8u & 0x10
+   38.4    FlashExposureCompArea                int8u & 0x04
+   38.5    AutoFlashISOSensitivity              int8u & 0x02
+   41.1    MovieFunc1Button                     int8u & 0xf0
+   41.2    MoviePreviewButton                   int8u & 0x0f
+   42.1    Func1ButtonPlusDials                 int8u & 0x0f
+   43.1    PreviewButtonPlusDials               int8u & 0x0f
+   45.1    AssignMovieRecordButtonPlusDials     int8u & 0x0f
+   46.1    FineTuneOptHighlightWeighted         int8u & 0x0f
+   47.1    DynamicAreaAFDisplay                 int8u & 0x80
+   47.2    AFPointIllumination                  int8u & 0x40
+   47.3    StoreByOrientation                   int8u & 0x18
+   47.4    GroupAreaAFIllumination              int8u & 0x04
+   48.1    MatrixMetering                       int8u & 0x80
+   48.2    LiveViewButtonOptions                int8u & 0x30
+   48.3    AFModeRestrictions                   int8u & 0x03
+   49.1    LimitAFAreaModeSelection             int8u & 0x7e
+   52.1    LensFocusFunctionButtons             int8u & 0x3f
+   66.1    VerticalMultiSelector                int8u & 0xff
+   67.1    AssignMB-D17FuncButton               int8u & 0x3f
+   68.1    AssignMB-D17FuncButtonPlusDials      int8u & 0x0f
+   70.1    AF-OnButton                          int8u & 0x3f
+   71.1    SubSelector                          int8u & 0x80
+   72.1    SubSelectorCenter                    int8u & 0x3f
+   73.1    SubSelectorPlusDials                 int8u & 0x0f
+   74.1    AssignMovieSubselector               int8u & 0xf0
+   75.1    AssignMovieFunc1ButtonPlusDials      int8u & 0x10
+   75.2    AssignMoviePreviewButtonPlusDials    int8u & 0x01
+   76.1    AssignMovieSubselectorPlusDials      int8u & 0x10
+   77.1    SyncReleaseMode                      int8u & 0x80
+   78.1    Three-DTrackingWatchArea             int8u & 0x80
+   78.2    SubjectMotion                        int8u & 0x60
+   78.3    AFActivation                         int8u & 0x08
+   78.4    ShutterReleaseButtonAE-L             int8u & 0x03
+   79.1    AssignMB-D17AF-OnButton              int8u & 0x7f
+   80.1    Func2Button                          int8u & 0x3f
+   82.1    AssignMovieFunc2Button               int8u & 0x70
+
+=head3 NikonCustom SettingsD610 Tags
+
+Custom settings for the D610.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    AF-CPrioritySelection                int8u & 0x80
+    0.2    AF-SPrioritySelection                int8u & 0x20
+    0.3    NumberOfFocusPoints                  int8u & 0x10
+    0.4    FocusTrackingLockOn                  int8u & 0x07
+    1.1    FocusPointWrap                       int8u & 0x08
+    1.2    AFPointIllumination                  int8u & 0x06
+    1.3    AFAssist                             int8u & 0x01
+    5.1    EasyExposureCompensation             int8u & 0x03
+    6.1    ExposureControlStep                  int8u & 0x40
+    6.2    ISOSensitivityStep                   int8u & 0x10
+    7.1    CenterWeightedAreaSize               int8u & 0xe0
+    7.2    FineTuneOptMatrixMetering            int8u & 0x0f
+    8.1    FineTuneOptCenterWeighted            int8u & 0xf0
+    8.2    FineTuneOptSpotMetering              int8u & 0x0f
+   17.1    ShutterReleaseButtonAE-L             int8u & 0x02
+   18.1    StandbyTimer                         int8u & 0xf0
+   18.2    RemoteOnDuration                     int8u & 0x03
+   19.1    SelfTimerTime                        int8u & 0xc0
+   19.2    SelfTimerShotInterval                int8u & 0x30
+   19.3    SelfTimerShotCount                   int8u & 0x0f
+   20.1    ImageReviewMonitorOffTime            int8u & 0xe0
+   20.2    LiveViewMonitorOffTime               int8u & 0x1c
+   21.1    MenuMonitorOffTime                   int8u & 0xe0
+   21.2    ShootingInfoMonitorOffTime           int8u & 0x1c
+   35.1    PlaybackMonitorOffTime               int8u & 0xe0
+
 =head2 NikonCapture Tags
 
@@ -7941,4 +14637,5 @@
   0x3cfc73c6   RedEyeData                       NikonCapture RedEyeData
   0x3d136244   EditVersionName                  string
+  0x416391c6   QuickFix                         int8u
   0x56a54260   Exposure                         NikonCapture Exposure
   0x5f0e7d23   ColorBooster                     int8u
@@ -7972,6 +14669,6 @@
 =head3 NikonCapture HighlightData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    ShadowProtection                     int8s
       1    SaturationAdj                        int8s
@@ -7980,6 +14677,6 @@
 =head3 NikonCapture CropData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
      30    CropLeft                             double
      38    CropTop                              double
@@ -7998,6 +14695,6 @@
 =head3 NikonCapture PictureCtrl Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    PictureControlActive                 int8u
      19    PictureControlMode                   string[16]
@@ -8011,14 +14708,14 @@
 =head3 NikonCapture RedEyeData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    RedEyeCorrection                     int8u
 
 =head3 NikonCapture Exposure Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    ExposureAdj                          int16s
-     18    ExposureAdj2                         double~
+     18    ExposureAdj2                         double
      36    ActiveD-Lighting                     int8u
      37    ActiveD-LightingMode                 int8u
@@ -8026,6 +14723,6 @@
 =head3 NikonCapture Brightness Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    BrightnessAdj                        double
       8    EnhanceDarkTones                     int8u
@@ -8033,6 +14730,6 @@
 =head3 NikonCapture DLightingHQ Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    D-LightingHQShadow                   int32u
       1    D-LightingHQHighlight                int32u
@@ -8041,6 +14738,6 @@
 =head3 NikonCapture NoiseReduction Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       4    EdgeNoiseReduction                   int8u
       5    ColorMoireReductionMode              int8u
@@ -8055,6 +14752,6 @@
 =head3 NikonCapture PhotoEffects Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    PhotoEffectsType                     int8u
       4    PhotoEffectsRed                      int16s
@@ -8064,6 +14761,6 @@
 =head3 NikonCapture ColorBoost Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    ColorBoostType                       int8u
       1    ColorBoostLevel                      int32u
@@ -8071,11 +14768,10 @@
 =head3 NikonCapture WBAdjData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    WBAdjRedBalance                      double
       8    WBAdjBlueBalance                     double
      16    WBAdjMode                            int8u
-     20    WBAdjLightingSubtype                 int8u
-     21    WBAdjLighting                        int8u
+     20    WBAdjLighting                        int16u
      24    WBAdjTemperature                     int16u
      37    WBAdjTint                            int32s
@@ -8083,6 +14779,6 @@
 =head3 NikonCapture DLightingHS Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    D-LightingHSAdjustment               int32u
       1    D-LightingHSColorBoost               int32u
@@ -8090,6 +14786,6 @@
 =head3 NikonCapture UnsharpData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    UnsharpCount                         int8u
      19    Unsharp1Color                        int16u
@@ -8110,9 +14806,26 @@
     108    Unsharp4Threshold                    int8u
 
+=head2 Nintendo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x1101   CameraInfo                           Nintendo CameraInfo
+
+=head3 Nintendo CameraInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ModelID                              undef[4]
+      8    TimeStamp                            int32u
+     24    InternalSerialNumber                 undef[4]
+     40    Parallax                             float
+     48    Category                             int16u
+
 =head2 Olympus Tags
 
 Tags 0x0000 through 0x0103 are used by some older Olympus cameras, and are
-the same as Konica/Minolta tags.  The Olympus tags are also used for Epson
-and Agfa cameras.
+the same as Konica/Minolta tags.  These tags are also used for some models
+from other brands such as Acer, BenQ, Epson, Hitachi, HP, Maginon, Minolta,
+Pentax, Ricoh, Samsung, Sanyo, SeaLife, Sony, Supra and Vivitar.
 
   Tag ID   Tag Name                             Writable
@@ -8122,7 +14835,7 @@
   0x0003   MinoltaCameraSettings                Minolta CameraSettings
   0x0040   CompressedImageSize                  int32u
-  0x0081   PreviewImageData                     N
-  0x0088   PreviewImageStart                    N
-  0x0089   PreviewImageLength                   N
+  0x0081   PreviewImageData                     no
+  0x0088   PreviewImageStart                    no
+  0x0089   PreviewImageLength                   no
   0x0100   ThumbnailImage                       undef
   0x0104   BodyFirmwareVersion                  string
@@ -8137,6 +14850,6 @@
   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
@@ -8146,10 +14859,12 @@
   0x0303   WhiteBalanceBracket                  int16u
   0x0304   WhiteBalanceBias                     int16u
+  0x0400   SensorArea                           undef[8]
+  0x0401   BlackLevel                           int32u[4]
   0x0403   SceneMode                            int16u
   0x0404   SerialNumber                         string
   0x0405   Firmware                             string
   0x0e00   PrintIM                              PrintIM
-  0x0f00   DataDump                             N
-  0x0f01   DataDump2                            N
+  0x0f00   DataDump                             no
+  0x0f01   DataDump2                            no
   0x0f04   ZoomedPreviewStart                   int32u*
   0x0f05   ZoomedPreviewLength                  int32u*
@@ -8263,6 +14978,6 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Resolution'         Resolution               N
-  'Type'               CameraType               N
+  'Resolution'         Resolution               no
+  'Type'               CameraType               no
 
 =head3 Olympus Equipment Tags
@@ -8284,5 +14999,5 @@
   0x0207   MinFocalLength                       int16u
   0x0208   MaxFocalLength                       int16u
-  0x020a   MaxApertureAtCurrentFocal            int16u
+  0x020a   MaxAperture                          int16u
   0x020b   LensProperties                       int16u
   0x0301   Extender                             int8u[6]
@@ -8290,4 +15005,5 @@
   0x0303   ExtenderModel                        string
   0x0304   ExtenderFirmwareVersion              int32u
+  0x0403   ConversionLens                       string
   0x1000   FlashType                            int16u
   0x1001   FlashModel                           int16u
@@ -8307,4 +15023,5 @@
   0x0202   MeteringMode                         int16u
   0x0203   ExposureShift                        rational64s
+  0x0204   NDFilter                             yes
   0x0300   MacroMode                            int16u
   0x0301   FocusMode                            int16u[n]
@@ -8312,12 +15029,14 @@
   0x0303   AFSearch                             int16u
   0x0304   AFAreas                              int32u[64]~
-  0x0305   AFPointSelected                      rational64s[5]~
+  0x0305   AFPointSelected                      rational64s[5]
+  0x0306   AFFineTune                           int8u
   0x0307   AFFineTuneAdj                        int16s[3]
+  0x0308   FocusBracketStepSize                 int8u
   0x0400   FlashMode                            int16u
   0x0401   FlashExposureComp                    rational64s
   0x0403   FlashRemoteControl                   int16u
-  0x0404   FlashControlMode                     int16u[3]
-  0x0405   FlashIntensity                       rational64s[3]
-  0x0406   ManualFlashStrength                  rational64s[3]
+  0x0404   FlashControlMode                     int16u[n]
+  0x0405   FlashIntensity                       rational64s[n]
+  0x0406   ManualFlashStrength                  rational64s[n]
   0x0500   WhiteBalance2                        int16u
   0x0501   WhiteBalanceTemperature              int16u
@@ -8344,13 +15063,24 @@
   0x0529   ArtFilter                            int16u[4]
   0x052c   MagicFilter                          int16u[4]
+  0x052d   PictureModeEffect                    int16s[3]
+  0x052e   ToneLevel                            yes
+  0x052f   ArtFilterEffect                      int16u[20]
+  0x0532   ColorCreatorEffect                   int16s[6]
+  0x0537   MonochromeProfileSettings            int16s[6]
+  0x0538   FilmGrainEffect                      int16s
+  0x0539   ColorProfileSettings                 int16s[14]
+  0x053a   MonochromeVignetting                 int16s
+  0x053b   MonochromeColor                      int16s
   0x0600   DriveMode                            int16u[n]~
   0x0601   PanoramaMode                         int16u~
   0x0603   ImageQuality2                        int16u
   0x0604   ImageStabilization                   int32u
+  0x0804   StackedImage                         int32u[2]
   0x0900   ManometerPressure                    int16u
   0x0901   ManometerReading                     int32s[2]
   0x0902   ExtendedWBDetect                     int16u
-  0x0903   LevelGaugeRoll                       int16u
-  0x0904   LevelGaugePitch                      int16u
+  0x0903   RollAngle                            int16s[2]
+  0x0904   PitchAngle                           int16s[2]
+  0x0908   DateTimeUTC                          string
 
 =head3 Olympus RawDevelopment Tags
@@ -8400,4 +15130,5 @@
   0x0119   RawDevAutoGradation                  int16u
   0x0120   RawDevPMNoiseFilter                  int16u
+  0x0121   RawDevArtFilter                      int16u[4]
 
 =head3 Olympus ImageProcessing Tags
@@ -8448,9 +15179,13 @@
   0x0614   CropWidth                            int32u
   0x0615   CropHeight                           int32u
+  0x0635   UnknownBlock1?                       undef
+  0x0636   UnknownBlock2?                       undef
+  0x0805   SensorCalibration                    int16s[2]
   0x1010   NoiseReduction2                      int16u
   0x1011   DistortionCorrection2                int16u
   0x1012   ShadingCompensation2                 int16u
   0x101c   MultipleExposureMode                 int16u[2]
-  0x1103   UnknownBlock?                        undef
+  0x1103   UnknownBlock3?                       undef
+  0x1104   UnknownBlock4?                       undef
   0x1112   AspectRatio                          int8u[2]
   0x1113   AspectFrame                          int16u[4]
@@ -8460,4 +15195,8 @@
   0x1203   FaceDetectFrameSize                  int16u[6]
   0x1207   FaceDetectFrameCrop                  int16s[12]
+  0x1306   CameraTemperature                    no
+  0x1900   KeystoneCompensation                 int8u[2]
+  0x1901   KeystoneDirection                    int8u[2]
+  0x1906   KeystoneValue                        int16s[3]
 
 =head3 Olympus FocusInfo Tags
@@ -8476,4 +15215,5 @@
   0x0305   FocusDistance                        rational64u
   0x0308   AFPoint                              int16u
+  0x0328   AFInfo                               Olympus AFInfo
   0x1201   ExternalFlash                        int16u[2]
   0x1203   ExternalFlashGuideNumber?            rational64s
@@ -8482,7 +15222,14 @@
   0x1208   InternalFlash                        int16u[n]
   0x1209   ManualFlash                          int16u[2]~
+  0x120a   MacroLED                             int16u
   0x1500   SensorTemperature                    int16s
   0x1600   ImageStabilization                   undef~
 
+=head3 Olympus AFInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
 =head3 Olympus FE Tags
 
@@ -8496,5 +15243,5 @@
 =head3 Olympus RawInfo Tags
 
-These tags are found only in ORF images of some models (ie. C8080WZ).
+These tags are found only in ORF images of some models (eg. C8080WZ).
 
   Tag ID   Tag Name                             Writable
@@ -8516,5 +15263,5 @@
   0x0311   CoringValues                         int16u[11]
   0x0600   BlackLevel2                          int16u[4]
-  0x0601   YCbCrCoefficients                    N
+  0x0601   YCbCrCoefficients                    no
   0x0611   ValidPixelDepth                      int16u[2]
   0x0612   CropLeft                             int16u
@@ -8543,4 +15290,17 @@
   [no tags known]
 
+=head3 Olympus DSS Tags
+
+Information extracted from DSS/DS2 files and the ID3 XOLY frame of MP3 files
+written by some Olympus voice recorders.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    Model                                no
+     38    StartTime                            no
+     50    EndTime                              no
+     62    Duration                             no
+    798    Comment                              no
+
 =head3 Olympus MOV1 Tags
 
@@ -8548,12 +15308,12 @@
 D540Z, D595Z, FE100, FE110, FE115, FE170 and FE200.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     24    Model                                N
-     38    ExposureUnknown?                     N
-     42    FNumber                              N
-     50    ExposureCompensation                 N
-     72    FocalLength                          N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    Model                                no
+     38    ExposureUnknown?                     no
+     42    FNumber                              no
+     50    ExposureCompensation                 no
+     72    FocalLength                          no
 
 =head3 Olympus MOV2 Tags
@@ -8562,13 +15322,13 @@
 FE120, FE140 and FE190.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     24    Model                                N
-     54    ExposureTime                         N
-     58    FNumber                              N
-     66    ExposureCompensation                 N
-     88    FocalLength                          N
-    193    ISO                                  N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    Model                                no
+     54    ExposureTime                         no
+     58    FNumber                              no
+     66    ExposureCompensation                 no
+     88    FocalLength                          no
+    193    ISO                                  no
 
 =head3 Olympus MP4 Tags
@@ -8577,10 +15337,105 @@
 u7040 and u9010.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     24    Model                                N
-     40    FNumber                              N
-     48    ExposureCompensation                 N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    Model                                no
+     40    FNumber                              no
+     48    ExposureCompensation                 no
+    104    MovableInfo                          Olympus MovableInfo
+    114    MovableInfo                          Olympus MovableInfo
+
+=head3 Olympus MovableInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    ISO                                  no
+     44    EncoderVersion                       no
+     60    DecoderVersion                       no
+    131    Thumbnail                            Olympus Thumbnail
+
+=head3 Olympus Thumbnail Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    ThumbnailWidth                       no
+      2    ThumbnailHeight                      no
+      3    ThumbnailLength                      no
+      4    ThumbnailOffset                      no
+
+=head3 Olympus MOV3 Tags
+
+QuickTime information found in the TAGS atom of MOV videos from the E-M5.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'OLYM'   OlympusAtom                          Olympus OLYM2
+
+=head3 Olympus OLYM2 Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'prms'   MakerNotes                           Olympus prms
+  'scrn'   PreviewInfo                          Olympus scrn2
+  'thmb'   ThumbInfo                            Olympus thmb2
+
+=head3 Olympus prms Tags
+
+Information extracted from the "prms" atom in MOV videos from Olympus models
+such as the OM E-M5.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     18    Make                                 no
+     44    Model                                no
+    131    DateTime1                            no
+    157    DateTime2                            no
+
+=head3 Olympus scrn2 Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      2    OlympusPreview                       Olympus scrn
+
+=head3 Olympus scrn Tags
+
+Information extracted from the "scrn" atom of Olympus MP4 videos.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PreviewImageLength                   no
+      4    PreviewImage                         no
+
+=head3 Olympus thmb2 Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ThumbnailWidth                       no
+      2    ThumbnailHeight                      no
+      4    ThumbnailLength                      no
+      8    ThumbnailImage                       no
+
+=head3 Olympus thmb Tags
+
+Information extracted from the "thmb" atom of Olympus MP4 videos.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ThumbnailLength                      no
+      4    ThumbnailImage                       no
+
+=head3 Olympus OLYM Tags
+
+Tags found in the OLYM atom of MP4 videos from the TG-810.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     14    Make                                 no
+     40    Model                                no
+     90    FNumber                              no
+    127    DateTimeOriginal                     no
+    153    DateTime2                            no
+    265    ThumbnailWidth                       no
+    267    ThumbnailHeight                      no
 
 =head3 Olympus AVI Tags
@@ -8588,13 +15443,12 @@
 This information is found in Olympus AVI videos.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     18    Make                                 N
-     44    ModelType                            N
-     94    FNumber                              N
-    131    DateTime1                            N
-    157    DateTime2                            N
-    301    ThumbnailLength                      N
-    305    ThumbnailImage                       N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     18    Make                                 no
+     44    Model                                no
+     94    FNumber                              no
+    131    DateTime1                            no
+    157    DateTime2                            no
+    297    ThumbInfo                            Olympus thmb2
 
 =head3 Olympus WAV Tags
@@ -8603,28 +15457,28 @@
 like the LS-5, LS-10, LS-11.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     12    Model                                N
-     28    FileNumber                           N
-     38    DateTimeOriginal                     N
-     50    DateTimeEnd                          N
-     62    RecordingTime                        N
-    512    Duration                             N
-    522    Index01                              N
-    532    Index02                              N
-    542    Index03                              N
-    552    Index04                              N
-    562    Index05                              N
-    572    Index06                              N
-    582    Index07                              N
-    592    Index08                              N
-    602    Index09                              N
-    612    Index10                              N
-    622    Index11                              N
-    632    Index12                              N
-    642    Index13                              N
-    652    Index14                              N
-    662    Index15                              N
-    672    Index16                              N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    Model                                no
+     28    FileNumber                           no
+     38    DateTimeOriginal                     no
+     50    DateTimeEnd                          no
+     62    RecordingTime                        no
+    512    Duration                             no
+    522    Index01                              no
+    532    Index02                              no
+    542    Index03                              no
+    552    Index04                              no
+    562    Index05                              no
+    572    Index06                              no
+    582    Index07                              no
+    592    Index08                              no
+    602    Index09                              no
+    612    Index10                              no
+    622    Index11                              no
+    632    Index12                              no
+    642    Index13                              no
+    652    Index14                              no
+    662    Index15                              no
+    672    Index16                              no
 
 =head2 Panasonic Tags
@@ -8643,9 +15497,10 @@
   0x001f   ShootingMode                         int16u
   0x0020   Audio                                int16u
-  0x0021   DataDump                             N
+  0x0021   DataDump                             no
   0x0023   WhiteBalanceBias                     int16s
   0x0024   FlashBias                            int16s
   0x0025   InternalSerialNumber                 undef[16]
   0x0026   PanasonicExifVersion                 undef
+  0x0027   VideoFrameRate                       int16u
   0x0028   ColorEffect                          int16u
   0x0029   TimeSincePowerOn                     int32u
@@ -8662,9 +15517,10 @@
   0x0035   ConversionLens                       int16u
   0x0036   TravelDay                            int16u
+  0x0038   BatteryLevel                         int16u
   0x0039   Contrast                             int16u
   0x003a   WorldTimeLocation                    int16u
   0x003b   TextStamp                            int16u
   0x003c   ProgramISO                           int16u
-  0x003d   AdvancedSceneMode                    int16u
+  0x003d   AdvancedSceneType                    int16u
   0x003e   TextStamp                            int16u
   0x003f   FacesDetected                        int16u
@@ -8672,6 +15528,11 @@
   0x0041   Sharpness                            int16u
   0x0042   FilmMode                             int16u
-  0x0046   WBAdjustAB                           int16u
-  0x0047   WBAdjustGM                           int16u
+  0x0043   JPEGQuality                          int16u
+  0x0044   ColorTempKelvin                      int16u
+  0x0045   BracketSettings                      int16u
+  0x0046   WBShiftAB                            int16u
+  0x0047   WBShiftGM                            int16u
+  0x0048   FlashCurtain                         int16u
+  0x0049   LongExposureNoiseReduction           int16u
   0x004b   PanasonicImageWidth                  int32u
   0x004c   PanasonicImageHeight                 int32u
@@ -8681,6 +15542,8 @@
   0x0052   LensSerialNumber                     string
   0x0053   AccessoryType                        string
+  0x0054   AccessorySerialNumber                string
   0x0059   Transform                            undef[4]
   0x005d   IntelligentExposure                  int16u
+  0x0060   LensFirmwareVersion                  undef[4]
   0x0061   FaceRecInfo                          Panasonic FaceRecInfo
   0x0062   FlashWarning                         int16u
@@ -8694,12 +15557,57 @@
   0x006f   Landmark                             undef
   0x0070   IntelligentResolution                int8u
+  0x0076   HDRShot                              int16u
+  0x0077   BurstSpeed                           int16u
   0x0079   IntelligentD-Range                   int16u
+  0x007c   ClearRetouch                         int16u
+  0x0080   City2                                undef
+  0x0086   ManometerPressure                    int16u
+  0x0089   PhotoStyle                           int16u
+  0x008a   ShadingCompensation                  int16u
+  0x008b   WBShiftIntelligentAuto               int16u
+  0x008c   AccelerometerZ                       int16u
+  0x008d   AccelerometerX                       int16u
+  0x008e   AccelerometerY                       int16u
+  0x008f   CameraOrientation                    int8u
+  0x0090   RollAngle                            int16u
+  0x0091   PitchAngle                           int16u
+  0x0092   WBShiftCreativeControl               int8u
+  0x0093   SweepPanoramaDirection               int8u
+  0x0094   SweepPanoramaFieldOfView             int16u
+  0x0096   TimerRecording                       int8u
+  0x009d   InternalNDFilter                     rational64u
+  0x009e   HDR                                  int16u
+  0x009f   ShutterType                          int16u
+  0x00a1   FilterEffect                         rational64u[0.5]
+  0x00a3   ClearRetouchValue                    rational64u
+  0x00a7   OutputLUT                            yes
+  0x00ab   TouchAE                              int16u
+  0x00ac   MonochromeFilterEffect               int16u
+  0x00ad   HighlightShadow                      int16u[2]
+  0x00af   TimeStamp                            string
+  0x00b3   VideoBurstResolution                 int16u
+  0x00b4   MultiExposure                        int16u
+  0x00b9   RedEyeRemoval                        int16u
+  0x00bb   VideoBurstMode                       int32u
+  0x00bc   DiffractionCorrection                int16u
+  0x00bd   FocusBracket                         int16u
+  0x00be   LongExposureNRUsed                   int16u
+  0x00bf   PostFocusMerging                     int32u[2]
+  0x00c1   VideoPreburst                        int16u
+  0x00c4   LensTypeMake                         int16u
+  0x00c5   LensTypeModel                        int16u
+  0x00ca   SensorType                           int16u
+  0x00d1   ISO                                  int32u
+  0x00d2   MonochromeGrainEffect                int16u
+  0x00d6   NoiseReductionStrength               rational64s
   0x0e00   PrintIM                              PrintIM
+  0x2003   TimeInfo                             Panasonic TimeInfo
   0x8000   MakerNoteVersion                     undef
   0x8001   SceneMode                            int16u
+  0x8002   HighlightWarning                     int16u
+  0x8003   DarkFocusEnvironment                 int16u
   0x8004   WBRedLevel                           int16u
   0x8005   WBGreenLevel                         int16u
   0x8006   WBBlueLevel                          int16u
-  0x8007   FlashFired                           int16u
   0x8008   TextStamp                            int16u
   0x8009   TextStamp                            int16u
@@ -8711,6 +15619,6 @@
 Face detection position information.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    NumFacePositions                     int16u
       1    Face1Position                        int16u[4]
@@ -8726,6 +15634,6 @@
 user-supplied set of known faces.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    FacesRecognized                      int16u
       4    RecognizedFace1Name                  string[20]
@@ -8739,4 +15647,11 @@
     128    RecognizedFace3Age                   string[20]
 
+=head3 Panasonic TimeInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PanasonicDateTime                    undef[8]
+     16    TimeLapseShotNumber                  int32u
+
 =head3 Panasonic Leica2 Tags
 
@@ -8749,5 +15664,5 @@
   0x0303   SerialNumber                         int32u
   0x0304   WhiteBalance                         int16u
-  0x0310   LensInfo                             Panasonic LensInfo
+  0x0310   LensType                             int32u
   0x0311   ExternalSensorBrightnessValue        rational64s
   0x0312   MeasuredLV                           rational64s
@@ -8765,11 +15680,4 @@
   0x0340   ImageIDNumber                        int32u
 
-=head3 Panasonic LensInfo Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    LensType                             int32u & 0xfffffffc
-    0.1    FrameSelector                        int32u & 0x03
-
 =head3 Panasonic Leica3 Tags
 
@@ -8778,5 +15686,12 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
+  0x000b   SerialInfo                           Panasonic SerialInfo
   0x000d   WB_RGBLevels                         int16u[3]
+
+=head3 Panasonic SerialInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    SerialNumber                         no
 
 =head3 Panasonic Leica4 Tags
@@ -8819,35 +15734,72 @@
 =head3 Panasonic Data1 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     22    LensType                             int32u[0.25]
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     22    LensType                             int32u
 
 =head3 Panasonic Data2 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
 
 =head3 Panasonic Leica5 Tags
 
-This information is written by the X1.
+This information is written by the X1, X2, X VARIO and T.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
+  0x0303   LensType                             string
+  0x0305   SerialNumber                         int32u
   0x0407   OriginalFileName                     string
   0x0408   OriginalDirectory                    string
+  0x040a   FocusInfo                            Panasonic FocusInfo
   0x040d   ExposureMode                         int8u[4]
+  0x0410   ShotInfo                             Panasonic ShotInfo
   0x0412   FilmMode                             string
   0x0413   WB_RGBLevels                         rational64u[3]
+  0x0500   InternalSerialNumber                 undef
+
+=head3 Panasonic FocusInfo Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    FocusDistance                        int16u
+      1    FocalLength                          int16u
+
+=head3 Panasonic ShotInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FileIndex                            int16u
 
 =head3 Panasonic Leica6 Tags
 
-This information is written by the S2 (as a trailer in JPEG images).
+This information is written by the S2 and M (Typ 240), as a trailer in JPEG
+images.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
   0x0300   PreviewImage                         undef
-  0x0301   UnknownBlock?                        N
+  0x0301   UnknownBlock?                        no
   0x0303   LensType                             string
+  0x0304   FocusDistance                        int32u
+  0x0311   ExternalSensorBrightnessValue        rational64s
+  0x0312   MeasuredLV                           rational64s
+  0x0320   FirmwareVersion                      int8u[4]
+  0x0321   LensSerialNumber                     int32u
+
+=head3 Panasonic Leica9 Tags
+
+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
@@ -8857,8 +15809,37 @@
 iPalm.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MakerNoteType                        N
-      3    Gain                                 N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    MakerNoteType                        no
+      3    Gain                                 no
+
+=head3 Panasonic PANA Tags
+
+Tags extracted from the PANA and LEIC user data found in MP4 videos from
+various Panasonic and Leica models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+      4    Model                                no
+     12    Model                                no
+     16    JPEG-likeData                        EXIF
+     22    Model                                no
+     52    Version1                             no
+     62    Version2                             no
+     80    MakerNoteLeica5                      Panasonic Leica5
+     88    ThumbnailWidth                       no
+     90    ThumbnailHeight                      no
+     92    ThumbnailImage                       no
+   1334    ThumbnailWidth                       no
+   1338    ThumbnailHeight                      no
+   1342    ThumbnailLength                      no
+   1350    ThumbnailImage                       no
+   1358    ThumbnailWidth                       no
+   1362    ThumbnailHeight                      no
+   1366    ThumbnailLength                      no
+   1374    ThumbnailImage                       no
+  16488    ExifData                             EXIF
+  16512    ExifData                             EXIF
 
 =head2 Pentax Tags
@@ -8870,5 +15851,5 @@
   0x0000   PentaxVersion                        int8u[4]
   0x0001   PentaxModelType                      int16u
-  0x0002   PreviewImageSize                     int16u[2]~
+  0x0002   PreviewImageSize                     int16u[2]
   0x0003   PreviewImageLength                   int32u*
   0x0004   PreviewImageStart                    int32u*
@@ -8882,5 +15863,6 @@
   0x000d   FocusMode                            int16u
   0x000e   AFPointSelected                      int16u
-  0x000f   AFPointsInFocus                      int16u
+  0x000f   AFPointsInFocus                      int32u
+           AFPointsInFocus                      int16u
   0x0010   FocusPosition                        int16u
   0x0012   ExposureTime                         int32u
@@ -8889,4 +15871,5 @@
   0x0015   LightReading                         int16u
   0x0016   ExposureCompensation                 int16u
+           ExposureCompensation                 int16u[2]
   0x0017   MeteringMode                         int16u
   0x0018   AutoBracketing                       int16u[n]
@@ -8909,4 +15892,5 @@
   0x0029   FrameNumber                          int32u
   0x002d   EffectiveLV                          int16u
+           EffectiveLV                          int32u
   0x0032   ImageEditing                         undef[4]
   0x0033   PictureMode                          int8u[3]
@@ -8916,7 +15900,8 @@
   0x0038   ImageAreaOffset                      int16u[2]
   0x0039   RawImageSize                         int16u[2]~
-  0x003c   AFPointsInFocus                      N
+  0x003c   AFPointsInFocus                      no
+  0x003d   DataScaling                          int16u
   0x003e   PreviewImageBorders                  int8u[4]
-  0x003f   LensType                             int8u[2]
+  0x003f   LensRec                              Pentax LensRec
   0x0040   SensitivityAdjust                    int16u
   0x0041   ImageEditCount                       int16u
@@ -8925,9 +15910,20 @@
   0x0049   NoiseReduction                       int16u
   0x004d   FlashExposureComp                    int32s
+           FlashExposureComp                    int8s[2]
   0x004f   ImageTone                            int16u
   0x0050   ColorTemperature                     int16u
+  0x0053   ColorTempDaylight                    undef[4]
+  0x0054   ColorTempShade                       undef[4]
+  0x0055   ColorTempCloudy                      undef[4]
+  0x0056   ColorTempTungsten                    undef[4]
+  0x0057   ColorTempFluorescentD                undef[4]
+  0x0058   ColorTempFluorescentN                undef[4]
+  0x0059   ColorTempFluorescentW                undef[4]
+  0x005a   ColorTempFlash                       undef[4]
   0x005c   ShakeReductionInfo                   Pentax SRInfo
+                                                Pentax SRInfo2
   0x005d   ShutterCount                         undef[4]
   0x0060   FaceInfo                             Pentax FaceInfo
+  0x0062   RawDevelopmentProcess                int16u
   0x0067   Hue                                  int16u
   0x0068   AWBInfo                              Pentax AWBInfo
@@ -8945,9 +15941,19 @@
   0x0076   FaceDetect                           int8u[2]
   0x0077   FaceDetectFrameSize                  int16u[2]
-  0x0079   ShadowCompensation                   int8u[n]
+  0x0079   ShadowCorrection                     int8u[n]
   0x007a   ISOAutoParameters                    int8u[2]
   0x007b   CrossProcess                         int8u
   0x007d   LensCorr                             Pentax LensCorr
+  0x007e   WhiteLevel                           int32u
   0x007f   BleachBypassToning                   int16u
+  0x0080   AspectRatio                          yes
+  0x0082   BlurControl                          int8u[4]
+  0x0085   HDR                                  int8u[4]
+  0x0087   ShutterType                          int8u
+  0x0088   NeutralDensityFilter                 int8u[n]
+  0x008b   ISO                                  int32u
+  0x0092   IntervalShooting                     int16u[2]
+  0x0095   SkinToneCorrection                   int8s[2]
+  0x0096   ClarityControl                       int8s[2]
   0x0200   BlackPoint                           int16u[4]
   0x0201   WhitePoint                           int16u[4]
@@ -8955,9 +15961,14 @@
   0x0204   ColorMatrixB                         int16s[9]
   0x0205   CameraSettings                       Pentax CameraSettings
+           CameraSettingsUnknown                Pentax CameraSettingsUnknown
   0x0206   AEInfo                               Pentax AEInfo
+           AEInfo2                              Pentax AEInfo2
+           AEInfo3                              Pentax AEInfo3
+           AEInfoUnknown                        Pentax AEInfoUnknown
   0x0207   LensInfo                             Pentax LensInfo
                                                 Pentax LensInfo2
                                                 Pentax LensInfo3
                                                 Pentax LensInfo4
+                                                Pentax LensInfo5
   0x0208   FlashInfo                            Pentax FlashInfo
            FlashInfoUnknown                     Pentax FlashInfoUnknown
@@ -8975,7 +15986,8 @@
   0x0215   CameraInfo                           Pentax CameraInfo
   0x0216   BatteryInfo                          Pentax BatteryInfo
-  0x021b   SaturationInfo?                      N
+  0x021b   SaturationInfo?                      no
   0x021f   AFInfo                               Pentax AFInfo
-  0x0220   HuffmanTable?                        N
+  0x0220   HuffmanTable?                        no
+  0x0221   KelvinWB                             Pentax KelvinWB
   0x0222   ColorInfo                            Pentax ColorInfo
   0x0224   EVStepInfo                           Pentax EVStepInfo
@@ -8985,5 +15997,7 @@
   0x0229   SerialNumber                         string
   0x022a   FilterInfo                           Pentax FilterInfo
+                                                Pentax FilterInfo
   0x022b   LevelInfo                            Pentax LevelInfo
+  0x022d   WBLevels                             Pentax WBLevels
   0x022e   Artist                               string
   0x022f   Copyright                            string
@@ -8991,17 +16005,32 @@
   0x0231   ContrastDetectAFArea                 int16u[4]
   0x0235   CrossProcessParams                   undef[10]
-  0x03fe   DataDump                             N
-  0x03ff   TempInfoK5                           Pentax TempInfoK5
+  0x0239   LensInfoQ                            Pentax LensInfoQ
+  0x023f   Model                                string
+  0x0243   PixelShiftInfo                       Pentax PixelShiftInfo
+  0x0245   AFPointInfo                          Pentax AFPointInfo
+  0x03fe   DataDump                             no
+  0x03ff   TempInfo                             Pentax TempInfo
            UnknownInfo                          Pentax UnknownInfo
-  0x0402   ToneCurve                            Y~
-  0x0403   ToneCurves                           Y~
+  0x0402   ToneCurve                            yes~
+  0x0403   ToneCurves                           yes~
+  0x0405   UnknownBlock?                        undef
   0x0e00   PrintIM                              PrintIM
 
+=head3 Pentax LensRec Tags
+
+This record stores the LensType, plus one or two unknown bytes for some
+models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensType                             int8u[2]
+      3    ExtenderStatus                       int8u
+
 =head3 Pentax SRInfo Tags
 
 Shake reduction information.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    SRResult                             int8u
       1    ShakeReduction                       int8u
@@ -9009,8 +16038,17 @@
       3    SRFocalLength                        int8u
 
+=head3 Pentax SRInfo2 Tags
+
+Shake reduction information for the K-3.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    SRResult?                            int8u
+      1    ShakeReduction                       int8u
+
 =head3 Pentax FaceInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    FacesDetected                        int8u
       2    FacePosition                         int8u[2]
@@ -9018,6 +16056,6 @@
 =head3 Pentax AWBInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    WhiteBalanceAutoAdjustment           int8u
       1    TungstenAWB                          int8u
@@ -9025,6 +16063,6 @@
 =head3 Pentax TimeInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    WorldTimeLocation                    int8u & 0x01
     0.2    HometownDST                          int8u & 0x02
@@ -9035,15 +16073,17 @@
 =head3 Pentax LensCorr Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    DistortionCorrection                 int8u
       1    ChromaticAberrationCorrection        int8u
+      2    PeripheralIlluminationCorr           int8u
+      3    DiffractionCorrection                int8u
 
 =head3 Pentax CameraSettings Tags
 
-Shot information written by Pentax DSLR cameras.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+Camera settings information written by Pentax DSLR cameras.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    PictureMode2                         int8u
     1.1    ProgramLine                          int8u & 0x03
@@ -9078,8 +16118,18 @@
      21    BaseExposureCompensation             int8u
 
+=head3 Pentax CameraSettingsUnknown Tags
+
+This information has not yet been decoded for models such as the K-01.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
 =head3 Pentax AEInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+Auto-exposure information for most Pentax models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    AEExposureTime                       int8u
       1    AEAperture                           int8u
@@ -9089,11 +16139,53 @@
       5    AEMinExposureTime                    int8u
       6    AEProgramMode                        int8u
-      7    AEFlags?                             N
-      8    AEUnknown                            N
+      7    AEFlags                              no
+      8    AEApertureSteps                      int8u
       9    AEMaxAperture                        int8u
      10    AEMaxAperture2                       int8u
      11    AEMinAperture                        int8u
      12    AEMeteringMode                       int8u
+     13    AEWhiteBalance                       int8u & 0xf0
+   13.1    AEMeteringMode2                      int8u & 0x0f
      14    FlashExposureCompSet                 int8s
+     21    LevelIndicator                       int8u
+
+=head3 Pentax AEInfo2 Tags
+
+Auto-exposure information for the K-01.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      2    AEExposureTime                       int8u
+      3    AEAperture                           int8u
+      4    AE_ISO                               int8u
+      5    AEXv                                 int8u
+      6    AEBXv                                int8s
+      8    AEError                              int8s
+     11    AEApertureSteps                      int8u
+     15    SceneMode                            int8u
+     16    AEMaxAperture                        int8u
+     17    AEMaxAperture2                       int8u
+     18    AEMinAperture                        int8u
+     19    AEMinExposureTime                    int8u
+
+=head3 Pentax AEInfo3 Tags
+
+Auto-exposure information for the K-3, K-30, K-50 and K-500.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     16    AEExposureTime                       int8u
+     17    AEAperture                           int8u
+     18    AE_ISO                               int8u
+     28    AEMaxAperture                        int8u
+     29    AEMaxAperture2                       int8u
+     30    AEMinAperture                        int8u
+     31    AEMinExposureTime                    int8u
+
+=head3 Pentax AEInfoUnknown Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
 
 =head3 Pentax LensInfo Tags
@@ -9101,6 +16193,6 @@
 Pentax lens information structure for models such as the *istD.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    LensType                             int8u[2]
       3    LensData                             Pentax LensData
@@ -9110,7 +16202,7 @@
 Pentax lens information structure for models such as the K10D and K20D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    LensType                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensType                             int8u[4]
       4    LensData                             Pentax LensData
 
@@ -9120,6 +16212,6 @@
 gymnastics to decode them into useful values.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    AutoAperture                         int8u & 0x01
     0.2    MinAperture                          int8u & 0x06
@@ -9127,5 +16219,6 @@
       1    LensKind?                            int8u
       2    LC1?                                 int8u
-      3    LC2?                                 int8u
+      3    MinFocusDistance                     int8u & 0xf8
+    3.1    FocusRangeIndex                      int8u & 0x07
       4    LC3?                                 int8u
       5    LC4?                                 int8u
@@ -9133,5 +16226,6 @@
       7    LC6?                                 int8u
       8    LC7?                                 int8u
-      9    FocalLength                          int8u
+      9    LensFocalLength                      int8u
+           LC8?                                 int8u
      10    NominalMaxAperture                   int8u & 0xf0
    10.1    NominalMinAperture                   int8u & 0x0f
@@ -9147,7 +16241,7 @@
 Pentax lens information structure for 645D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    LensType                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    LensType                             int8u[4]
      13    LensData                             Pentax LensData
 
@@ -9156,15 +16250,24 @@
 Pentax lens information structure for models such as the K-5 and K-r.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    LensType                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    LensType                             int8u[4]
      12    LensData                             Pentax LensData
 
+=head3 Pentax LensInfo5 Tags
+
+Pentax lens information structure for the K-01 and newer models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    LensType                             int8u[5]
+     15    LensData                             Pentax LensData
+
 =head3 Pentax FlashInfo Tags
 
 Flash information tags for the K10D, K20D and K200D.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    FlashStatus                          int8u
       1    InternalFlashMode                    int8u
@@ -9181,12 +16284,12 @@
 =head3 Pentax FlashInfoUnknown Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
 
 =head3 Pentax CameraInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    PentaxModelID                        int32u
       1    ManufactureDate                      int32u
@@ -9196,6 +16299,6 @@
 =head3 Pentax BatteryInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
     0.1    PowerSource                          int8u & 0x0f
     1.1    BodyBatteryState                     int8u & 0xf0
@@ -9213,6 +16316,6 @@
 =head3 Pentax AFInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    AFPointsUnknown1?                    int16u
       2    AFPointsUnknown2?                    int16u
@@ -9221,16 +16324,41 @@
       7    AFIntegrationTime                    int8u
      11    AFPointsInFocus                      int8u
+    509    AFHold                               int8u
+
+=head3 Pentax KelvinWB Tags
+
+White balance Blue/Red gains as a function of color temperature.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    KelvinWB_Daylight                    int16u[4]
+      5    KelvinWB_01                          int16u[4]
+      9    KelvinWB_02                          int16u[4]
+     13    KelvinWB_03                          int16u[4]
+     17    KelvinWB_04                          int16u[4]
+     21    KelvinWB_05                          int16u[4]
+     25    KelvinWB_06                          int16u[4]
+     29    KelvinWB_07                          int16u[4]
+     33    KelvinWB_08                          int16u[4]
+     37    KelvinWB_09                          int16u[4]
+     41    KelvinWB_10                          int16u[4]
+     45    KelvinWB_11                          int16u[4]
+     49    KelvinWB_12                          int16u[4]
+     53    KelvinWB_13                          int16u[4]
+     57    KelvinWB_14                          int16u[4]
+     61    KelvinWB_15                          int16u[4]
+     65    KelvinWB_16                          int16u[4]
 
 =head3 Pentax ColorInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
      16    WBShiftAB                            int8s
-     17    WBShiftMG                            int8s
+     17    WBShiftGM                            int8s
 
 =head3 Pentax EVStepInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    EVSteps                              int8u
       1    SensitivitySteps                     int8u
@@ -9238,12 +16366,12 @@
 =head3 Pentax ShotInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       1    CameraOrientation                    int8u
 
 =head3 Pentax FacePos Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    Face1Position                        int16u[2]
       2    Face2Position                        int16u[2]
@@ -9281,6 +16409,6 @@
 =head3 Pentax FaceSize Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       0    Face1Size                            int16u[2]
       2    Face2Size                            int16u[2]
@@ -9323,6 +16451,6 @@
 used.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    SourceDirectoryIndex                 int16u
       2    SourceFileIndex                      int16u
@@ -9350,8 +16478,9 @@
 =head3 Pentax LevelInfo Tags
 
-Tags decoded from the electronic level information.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+Tags decoded from the electronic level information for the K-5.  May not be
+valid for other models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    LevelOrientation                     int8s & 0x0f
     0.1    CompositionAdjust                    int8s & 0xf0
@@ -9362,14 +16491,59 @@
       7    CompositionAdjustRotation            int8s
 
-=head3 Pentax TempInfoK5 Tags
+=head3 Pentax WBLevels Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      2    WB_RGGBLevelsDaylight                int16u[4]
+     11    WB_RGGBLevelsShade                   int16u[4]
+     20    WB_RGGBLevelsCloudy                  int16u[4]
+     29    WB_RGGBLevelsTungsten                int16u[4]
+     38    WB_RGGBLevelsFluorescentD            int16u[4]
+     47    WB_RGGBLevelsFluorescentN            int16u[4]
+     56    WB_RGGBLevelsFluorescentW            int16u[4]
+     65    WB_RGGBLevelsFlash                   int16u[4]
+     74    WB_RGGBLevelsFluorescentL            int16u[4]
+     83    WB_RGGBLevelsUnknown?                int16u[4]
+     92    WB_RGGBLevelsUserSelected            int16u[4]
+
+=head3 Pentax LensInfoQ Tags
+
+More lens information stored by the Pentax Q.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    LensModel                            string[30]
+     42    LensInfo                             string[20]
+
+=head3 Pentax PixelShiftInfo Tags
+
+Pixel shift information stored by the K-3 II.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PixelShiftResolution                 int8u
+
+=head3 Pentax AFPointInfo Tags
+
+AF point information written by the K-1.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      2    NumAFPoints                          int16u
+      4    AFPointsInFocus                      int8u[9]~
+    4.1    AFPointsSelected                     int8u[9]~
+    4.2    AFPointsSpecial                      int8u[9]~
+
+=head3 Pentax TempInfo Tags
 
 A number of additional temperature readings are extracted from this 256-byte
-binary-data block in images from the K-5.  It is not currently known where
-the corresponding temperature sensors are located in the camera.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     12    CameraTemperature2                   int16s
-     14    CameraTemperature3                   int16s
+binary-data block in images from models such as the K-01, K-3, K-5, K-50 and
+K-500.  It is currently not known where the corresponding temperature
+sensors are located in the camera.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    SensorTemperature                    int16s
+     14    SensorTemperature2                   int16s
      20    CameraTemperature4                   int16s
      22    CameraTemperature5                   int16s
@@ -9377,6 +16551,6 @@
 =head3 Pentax UnknownInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
 
@@ -9411,19 +16585,67 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'F/W Version'        FirmwareVersion          N
+  'F/W Version'        FirmwareVersion          no
+
+=head3 Pentax S1 Tags
+
+Tags extracted from the maker notes of AVI videos from the Optio S1.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   MakerNoteVersion                     no
+
+=head3 Pentax PENT Tags
+
+Tags found in the PENT atom of MOV videos from the Optio WG-2 GPS.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     26    Model                                no
+     56    ExposureTime                         no
+     60    FNumber                              no
+     68    ExposureCompensation                 no
+     84    FocalLength                          no
+    113    DateTime1                            no
+    139    DateTime2                            no
+    167    ISO                                  no
+    199    GPSVersionID                         no
+    207    GPSLatitudeRef                       no
+    209    GPSLatitude                          no
+    233    GPSLongitudeRef                      no
+    235    GPSLongitude                         no
+    259    GPSAltitudeRef                       no
+    260    GPSAltitude                          no
+    284    GPSTimeStamp                         no
+    308    GPSSatellites                        no
+    311    GPSStatus                            no
+    313    GPSMeasureMode                       no
+    315    GPSMapDatum                          no
+    322    GPSDateStamp                         no
+    371    AudioCodecID                         no
+   2003    PreviewImage                         no
+
+=head3 Pentax PXTH Tags
+
+Tags found in the PXTH atom of MOV videos from the K-01.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PreviewImageLength                   no
+      4    PreviewImage                         no
 
 =head3 Pentax MOV Tags
 
-This information is found in Pentax MOV videos.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     38    ExposureTime                         N
-     42    FNumber                              N
-     50    ExposureCompensation                 N
-     68    WhiteBalance                         N
-     72    FocalLength                          N
-    175    ISO                                  N
+This information is found in MOV videos from cameras such as the Optio WP.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     38    ExposureTime                         no
+     42    FNumber                              no
+     50    ExposureCompensation                 no
+     68    WhiteBalance                         no
+     72    FocalLength                          no
+    175    ISO                                  no
 
 =head3 Pentax Junk Tags
@@ -9431,7 +16653,23 @@
 Tags found in the JUNK chunk of AVI videos from the RS1000.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     12    Model                                N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    Model                                no
+
+=head3 Pentax Junk2 Tags
+
+This information is found in AVI videos from the Optio RZ18.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     18    Make                                 no
+     44    Model                                no
+     94    FNumber                              no
+    131    DateTime1                            no
+    157    DateTime2                            no
+    299    ThumbnailWidth                       no
+    301    ThumbnailHeight                      no
+    303    ThumbnailLength                      no
+    307    ThumbnailImage                       no
 
 =head3 Pentax AVI Tags
@@ -9442,4 +16680,62 @@
   ------   --------                             --------
   'hymn'   MakerNotes                           Pentax
+  'mknt'   MakerNotes                           Pentax
+
+=head2 PhaseOne Tags
+
+These tags are extracted from the maker notes of Phase One images.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0100   CameraOrientation                    no
+  0x0102   SerialNumber                         string
+  0x0105   ISO                                  int32s
+  0x0106   ColorMatrix1                         float[9]
+  0x0107   WB_RGBLevels                         float[3]
+  0x0108   SensorWidth                          int32s
+  0x0109   SensorHeight                         int32s
+  0x010a   SensorLeftMargin                     int32s
+  0x010b   SensorTopMargin                      int32s
+  0x010c   ImageWidth                           int32s
+  0x010d   ImageHeight                          int32s
+  0x010e   RawFormat                            int32s
+  0x010f   RawData                              no
+  0x0110   SensorCalibration                    PhaseOne SensorCalibration
+  0x0112   DateTimeOriginal                     no
+  0x0113   ImageNumber                          int32s
+  0x0203   Software                             string
+  0x0204   System                               string
+  0x0210   SensorTemperature                    float
+  0x0211   SensorTemperature2                   float
+  0x0212   UnknownDate?                         int32u
+  0x021c   StripOffsets                         no
+  0x021d   BlackLevel                           int32s
+  0x0222   SplitColumn                          int32s
+  0x0223   BlackLevelData                       int16u[n]
+  0x0226   ColorMatrix2                         float[9]
+  0x0267   AFAdjustment                         float
+  0x0301   FirmwareVersions                     string
+  0x0400   ShutterSpeedValue                    float
+  0x0401   ApertureValue                        float
+  0x0402   ExposureCompensation                 float
+  0x0403   FocalLength                          float
+  0x0410   CameraModel                          string
+  0x0412   LensModel                            string
+  0x0414   MaxApertureValue                     float
+  0x0415   MinApertureValue                     float
+  0x0455   Viewfinder                           string
+
+=head3 PhaseOne SensorCalibration Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0400   SensorDefects                        no
+  0x0401   AllColorFlatField1?                  no
+  0x0407   SerialNumber                         string
+  0x040b   RedBlueFlatField?                    no
+  0x0410   AllColorFlatField2?                  no
+  0x0416   AllColorFlatField3?                  no
+  0x0419   LinearizationCoefficients1           no
+  0x041a   LinearizationCoefficients2           no
 
 =head2 Reconyx Tags
@@ -9448,8 +16744,8 @@
 cameras such as the HC500, HC600 and PC900.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MakerNoteVersion                     N
-      1    FirmwareVersion                      N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    MakerNoteVersion                     no
+      1    FirmwareVersion                      no
       4    FirmwareDate                         int16u[2]
       6    TriggerMode                          string[2]
@@ -9458,6 +16754,6 @@
      11    DateTimeOriginal                     int16u[6]
      18    MoonPhase                            int16u
-     19    AmbientTemperatureFahrenheit         int16u
-     20    AmbientTemperature                   int16u
+     19    AmbientTemperatureFahrenheit         int16s
+     20    AmbientTemperature                   int16s
      21    SerialNumber                         undef[30]
      36    Contrast                             int16u
@@ -9470,193 +16766,58 @@
      43    UserLabel                            string[22]
 
-=head2 Ricoh Tags
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  0x0001   MakerNoteType                        string
-  0x0002   FirmwareVersion                      string
-  0x0005   SerialNumber                         undef[16]
-           InternalSerialNumber                 undef[16]
-  0x0e00   PrintIM                              PrintIM
-  0x1001   ImageInfo                            Ricoh ImageInfo
-  0x1003   Sharpness                            int32u
-  0x2001   RicohSubdir                          Ricoh Subdir
-           RicohRR1Subdir                       Ricoh Subdir
-
-=head3 Ricoh ImageInfo Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    RicohImageWidth                      int16u
-      2    RicohImageHeight                     int16u
-      6    RicohDate                            int8u[7]
-     28    PreviewImageStart                    int16u*
-     30    PreviewImageLength                   int16u*
-     32    FlashMode                            int8u
-     33    Macro                                int8u
-     34    Sharpness                            int8u
-     38    WhiteBalance                         int8u
-     39    ISOSetting                           int8u
-     40    Saturation                           int8u
-
-=head3 Ricoh Subdir Tags
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  0x0004   ManufactureDate1                     string[20]
-  0x0005   ManufactureDate2                     string[20]
-  0x001a   FaceInfo                             Ricoh FaceInfo
-  0x0029   FirmwareInfo                         Ricoh FirmwareInfo
-  0x002a   NoiseReduction                       int32u
-  0x002c   SerialInfo                           Ricoh SerialInfo
-
-=head3 Ricoh FaceInfo Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-    181    FacesDetected                        int8u
-    182    FaceDetectFrameSize                  int16u[2]
-    188    Face1Position                        int16u[4]
-    200    Face2Position                        int16u[4]
-    212    Face3Position                        int16u[4]
-    224    Face4Position                        int16u[4]
-    236    Face5Position                        int16u[4]
-    248    Face6Position                        int16u[4]
-    260    Face7Position                        int16u[4]
-    272    Face8Position                        int16u[4]
-
-=head3 Ricoh FirmwareInfo Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FirmwareRevision                     string[12]
-     12    FirmwareRevision2                    string[12]
-
-=head3 Ricoh SerialInfo Tags
-
-This information is found in images from the GXR.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    BodyFirmware                         string[16]
-     16    BodySerialNumber                     string[16]
-     32    LensFirmware                         string[16]
-     48    LensSerialNumber                     string[16]
-
-=head3 Ricoh Text Tags
-
-Some Ricoh DC and RDC models use a text-based format for their maker notes
-instead of the IFD format used by the Caplio models.  Below is a list of known
-tags in this information.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  'Bg'     BlueGain                             N
-  'Gg'     GreenGain                            N
-  'Rev'    FirmwareVersion                      N
-  'Rg'     RedGain                              N
-  'Rv'     FirmwareVersion                      N
-
-=head3 Ricoh RMETA Tags
-
-The Ricoh Caplio Pro G3 has the ability to add custom fields to the APP5
-"RMETA" segment of JPEG images.  While only a few observed tags have been
-defined below, ExifTool will extract any information found here.
-
-  Tag ID               Tag Name                 Writable
-  ------               --------                 --------
-  'Azimuth'            Azimuth                  N
-  'Condition'          Condition                N
-  'Lit'                Lit                      N
-  'Location'           Location                 N
-  'Sign type'          SignType                 N
-
-=head3 Ricoh AVI Tags
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  'mnrt'   MakerNoteRicoh                       Ricoh
-  'rdc2'   RicohRDC2?                           N
-  'thum'   ThumbnailImage                       N
-  'ucmt'   Comment                              N
-
-=head2 Samsung Tags
-
-=head3 Samsung Type1 Tags
-
-Tags found in the binary "STMN" format maker notes written by a number of
-Samsung models.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MakerNoteVersion                     undef[8]
-      2    PreviewImageStart                    int32u*
-      3    PreviewImageLength                   int32u*
-
-=head3 Samsung Type2 Tags
-
-Tags found in the EXIF-format maker notes of newer Samsung models.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  0x0001   MakerNoteVersion                     undef[4]
-  0x0021   PictureWizard                        int16u[5]
-  0x0030   LocalLocationName                    string
-  0x0031   LocationName                         string
-  0x0035   PreviewIFD                           Nikon PreviewIFD
-  0x0043   CameraTemperature                    rational64s
-  0xa001   FirmwareName                         string
-  0xa003   LensType                             int16u
-  0xa004   LensFirmware                         string
-  0xa010   SensorAreas                          int32u[8]
-  0xa011   ColorSpace                           int16u
-  0xa012   SmartRange                           int16u
-  0xa013   ExposureCompensation                 rational64s
-  0xa014   ISO                                  int32u
-  0xa018   ExposureTime                         rational64u
-  0xa019   FNumber                              rational64u
-  0xa01a   FocalLengthIn35mmFormat              int32u
-  0xa020   EncryptionKey                        int32u[11]!
-  0xa021   WB_RGGBLevelsUncorrected             int32u[4]
-  0xa022   WB_RGGBLevelsAuto                    int32u[4]
-  0xa023   WB_RGGBLevelsIlluminator1            int32u[4]
-  0xa024   WB_RGGBLevelsIlluminator2            int32u[4]
-  0xa028   WB_RGGBLevelsBlack                   int32s[4]
-  0xa030   ColorMatrix                          int32s[9]
-  0xa031   ColorMatrixSRGB                      int32s[9]
-  0xa032   ColorMatrixAdobeRGB                  int32s[9]
-  0xa040   ToneCurve1                           int32u[23]
-  0xa041   ToneCurve2                           int32u[23]
-  0xa042   ToneCurve3                           int32u[23]
-  0xa043   ToneCurve4                           int32u[23]
-
-=head3 Samsung INFO Tags
-
-This information is found in MP4 videos from Samsung models such as the
-SMX-C20N.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  'EFCT'   Effect                               N
-  'QLTY'   Quality                              N
-
-=head3 Samsung MP4 Tags
-
-This information is found in Samsung MP4 videos from models such as the
-WP10.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     24    Model                                N
-     46    ExposureTime                         N
-     50    FNumber                              N
-     58    ExposureCompensation                 N
-    106    ISO                                  N
-    125    Software                             N
-    248    ThumbnailWidth                       N
-    252    ThumbnailHeight                      N
-    256    ThumbnailLength                      N
-    260    ThumbnailOffset                      N
+=head3 Reconyx Type2 Tags
+
+Tags extracted from models such as the UltraFire.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     24    FirmwareVersion                      undef[7]
+     31    Micro1Version                        undef[7]
+     38    BootLoaderVersion                    undef[7]
+     45    Micro2Version                        undef[7]
+     52    TriggerMode                          undef[1]
+     53    Sequence                             int8u[2]
+     55    EventNumber                          int32u
+     59    DateTimeOriginal                     int8u[7]
+     66    DayOfWeek                            int8u
+     67    MoonPhase                            int8u
+     68    AmbientTemperatureFahrenheit         int16s
+     70    AmbientTemperature                   int16s
+     72    Illumination                         int8u
+     73    BatteryVoltage                       int16u
+     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
@@ -9670,7 +16831,7 @@
   0x0202   Macro                                int16u
   0x0204   DigitalZoom                          rational64u
-  0x0207   SoftwareVersion                      Y
-  0x0208   PictInfo                             Y
-  0x0209   CameraID                             Y
+  0x0207   SoftwareVersion                      yes
+  0x0208   PictInfo                             yes
+  0x0209   CameraID                             yes
   0x020e   SequentialShot                       int16u
   0x020f   WideRange                            int16u
@@ -9691,10 +16852,10 @@
   0x0225   FlashMode                            int16u
   0x0e00   PrintIM                              PrintIM
-  0x0f00   DataDump                             N
+  0x0f00   DataDump                             no
 
 =head3 Sanyo FaceInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    FacesDetected                        int32u
       4    FacePosition                         int32u[4]
@@ -9704,13 +16865,13 @@
 This information is found in Sanyo MOV videos.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     24    Model                                N
-     38    ExposureTime                         N
-     42    FNumber                              N
-     50    ExposureCompensation                 N
-     68    WhiteBalance                         N
-     72    FocalLength                          N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    Model                                no
+     38    ExposureTime                         no
+     42    FNumber                              no
+     50    ExposureCompensation                 no
+     68    WhiteBalance                         no
+     72    FocalLength                          no
 
 =head3 Sanyo MP4 Tags
@@ -9718,21 +16879,446 @@
 This information is found in Sanyo MP4 videos.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
-     24    Model                                N
-     50    FNumber                              N
-     58    ExposureCompensation                 N
-    106    ISO                                  N
-    209    Software                             N
-    210    Software                             N
-    253    ThumbnailLength                      N
-    254    ThumbnailLength                      N
-    257    ThumbnailOffset                      N
-    258    ThumbnailOffset                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    Model                                no
+     50    FNumber                              no
+     58    ExposureCompensation                 no
+    106    ISO                                  no
+    209    Software                             no
+    210    Software                             no
+    241    Thumbnail                            Sanyo Thumbnail
+    242    Thumbnail                            Sanyo Thumbnail
+
+=head3 Sanyo Thumbnail Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    ThumbnailWidth                       no
+      2    ThumbnailHeight                      no
+      3    ThumbnailLength                      no
+      4    ThumbnailOffset                      no
+
+=head2 Samsung Tags
+
+Tags found in the binary "STMN" format maker notes written by a number of
+Samsung models.
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    MakerNoteVersion                     undef[8]
+      2    PreviewImageStart                    int32u*
+      3    PreviewImageLength                   int32u*
+     11    SamsungIFD                           Samsung IFD
+
+=head3 Samsung IFD Tags
+
+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
+information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 Samsung Type2 Tags
+
+Tags found in the EXIF-format maker notes of newer Samsung models.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   MakerNoteVersion                     undef[4]
+  0x0002   DeviceType                           int32u
+  0x0003   SamsungModelID                       int32u
+  0x0011   OrientationInfo                      Samsung OrientationInfo
+  0x0020   SmartAlbumColor                      int16u[2]
+  0x0021   PictureWizard                        Samsung PictureWizard
+  0x0030   LocalLocationName                    string
+  0x0031   LocationName                         string
+  0x0035   PreviewIFD                           Nikon PreviewIFD
+                                                Nikon PreviewIFD
+  0x0040   RawDataByteOrder                     yes
+  0x0041   WhiteBalanceSetup                    int32u
+  0x0043   CameraTemperature                    rational64s
+  0x0050   RawDataCFAPattern                    yes
+  0x0100   FaceDetect                           int16u
+  0x0120   FaceRecognition                      int32u
+  0x0123   FaceName                             string
+  0xa001   FirmwareName                         string
+  0xa002   SerialNumber                         string
+  0xa003   LensType                             int16u[n]
+  0xa004   LensFirmware                         string
+  0xa005   InternalLensSerialNumber             string
+  0xa010   SensorAreas                          int32u[8]
+  0xa011   ColorSpace                           int16u
+  0xa012   SmartRange                           int16u
+  0xa013   ExposureCompensation                 rational64s
+  0xa014   ISO                                  int32u
+  0xa018   ExposureTime                         rational64u
+  0xa019   FNumber                              rational64u
+  0xa01a   FocalLengthIn35mmFormat              int32u
+  0xa020   EncryptionKey                        int32u[11]!
+  0xa021   WB_RGGBLevelsUncorrected             int32u[4]
+  0xa022   WB_RGGBLevelsAuto                    int32u[4]
+  0xa023   WB_RGGBLevelsIlluminator1            int32u[4]
+  0xa024   WB_RGGBLevelsIlluminator2            int32u[4]
+  0xa025   HighlightLinearityLimit              int32u
+  0xa028   WB_RGGBLevelsBlack                   int32s[4]
+  0xa030   ColorMatrix                          int32s[9]
+  0xa031   ColorMatrixSRGB                      int32s[9]
+  0xa032   ColorMatrixAdobeRGB                  int32s[9]
+  0xa033   CbCrMatrixDefault                    int32s[4]
+  0xa034   CbCrMatrix                           int32s[4]
+  0xa035   CbCrGainDefault                      int32u[2]
+  0xa036   CbCrGain                             int32u[2]
+  0xa040   ToneCurveSRGBDefault                 int32u[23]
+  0xa041   ToneCurveAdobeRGBDefault             int32u[23]
+  0xa042   ToneCurveSRGB                        int32u[23]
+  0xa043   ToneCurveAdobeRGB                    int32u[23]
+  0xa048   RawData?                             int32s[12]
+  0xa050   Distortion?                          int32s[8]
+  0xa051   ChromaticAberration?                 int16u[22]
+  0xa052   Vignetting?                          int16u[15]
+  0xa053   VignettingCorrection?                int16u[15]
+  0xa054   VignettingSetting?                   int16u[15]
+
+=head3 Samsung OrientationInfo Tags
+
+Camera orientation information written by the Gear 360 (SM-C200).
+
+  Index8   Tag Name                             Writable
+  ------   --------                             --------
+      0    YawAngle?                            rational64s
+      1    PitchAngle                           rational64s
+      2    RollAngle                            rational64s
+
+=head3 Samsung PictureWizard Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    PictureWizardMode                    int16u
+      1    PictureWizardColor                   int16u
+      2    PictureWizardSaturation              int16u
+      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
+features (such as "Sound & Shot" or "Shot & More") from Samsung models such
+as the Galaxy S4 and Tab S.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  DepthMapData                                  no
+  DepthMapName                                  no
+  DualCameraImage                               no
+  DualCameraImageName                           no
+  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 DualShotExtra Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+     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
+
+This information is found in the @sec atom of Samsung MP4 videos from models
+such as the WB30F.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     32    Model                                no
+    512    ThumbnailWidth                       no
+    516    ThumbnailHeight                      no
+    520    ThumbnailLength                      no
+    524    ThumbnailImage                       no
+
+=head3 Samsung INFO Tags
+
+This information is found in MP4 videos from Samsung models such as the
+SMX-C20N.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'EFCT'   Effect                               no
+  'QLTY'   Quality                              no
+
+=head3 Samsung MP4 Tags
+
+This information is found in Samsung MP4 videos from models such as the
+WP10.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
+     24    Model                                no
+     46    ExposureTime                         no
+     50    FNumber                              no
+     58    ExposureCompensation                 no
+    106    ISO                                  no
+    125    Software                             no
+    244    Thumbnail                            Samsung Thumbnail
+
+=head3 Samsung Thumbnail Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    ThumbnailWidth                       no
+      2    ThumbnailHeight                      no
+      3    ThumbnailLength                      no
+      4    ThumbnailOffset                      no
+
+=head3 Samsung smta Tags
+
+This information is found in the smta atom of Samsung MP4 videos from models
+such as the Galaxy S4.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'svss'   SamsungSvss                          Samsung svss
+
+=head3 Samsung svss Tags
+
+This information is found in the svss atom of Samsung MP4 videos from models
+such as the Galaxy S4.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head2 Ricoh Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   MakerNoteType                        string
+  0x0002   FirmwareVersion                      string
+  0x0005   SerialNumber                         undef[16]
+           InternalSerialNumber                 undef[16]
+  0x0e00   PrintIM                              PrintIM
+  0x1000   RecordingFormat                      int16u
+  0x1001   ImageInfo                            Ricoh ImageInfo
+           ExposureProgram                      int16u
+  0x1002   DriveMode                            int16u
+  0x1003   Sharpness                            int32u
+           WhiteBalance                         int16u
+  0x1004   WhiteBalanceFineTune                 int16u
+  0x1006   FocusMode                            int16u
+  0x1007   AutoBracketing                       int16u
+  0x1009   MacroMode                            int16u
+  0x100a   FlashMode                            int16u
+  0x100b   FlashExposureComp                    rational64s
+  0x100c   ManualFlashOutput                    rational64s
+  0x100d   FullPressSnap                        int16u
+  0x100e   DynamicRangeExpansion                int16u
+  0x100f   NoiseReduction                       int16u
+  0x1010   ImageEffects                         int16u
+  0x1011   Vignetting                           int16u
+  0x1012   Contrast                             int32u
+  0x1013   Saturation                           int32u
+  0x1014   Sharpness                            int32u
+  0x1015   ToningEffect                         int16u
+  0x1016   HueAdjust                            int16u
+  0x1017   WideAdapter                          int16u
+  0x1018   CropMode                             int16u
+  0x1019   NDFilter                             int16u
+  0x101a   WBBracketShotNumber                  int16u
+  0x1200   AFStatus                             int16u
+  0x1201   AFAreaXPosition1                     int32u
+  0x1202   AFAreaYPosition1                     int32u
+  0x1203   AFAreaXPosition                      int32u
+  0x1204   AFAreaYPosition                      int32u
+  0x1205   AFAreaMode                           int16u
+  0x1307   ColorTempKelvin                      int32u
+  0x1308   ColorTemperature                     int32u
+  0x1500   FocalLength                          rational64u
+  0x1601   SensorWidth                          int32u
+  0x1602   SensorHeight                         int32u
+  0x1603   CroppedImageWidth                    int32u
+  0x1604   CroppedImageHeight                   int32u
+  0x2001   RicohSubdir                          Ricoh Subdir
+           RicohSubdirIFD                       Ricoh Subdir
+           RicohRR1Subdir                       Ricoh Subdir
+  0x4001   ThetaSubdir                          Ricoh ThetaSubdir
+
+=head3 Ricoh ImageInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    RicohImageWidth                      int16u
+      2    RicohImageHeight                     int16u
+      6    RicohDate                            int8u[7]
+     28    PreviewImageStart                    int16u*
+     30    PreviewImageLength                   int16u*
+     32    FlashMode                            int8u
+     33    Macro                                int8u
+     34    Sharpness                            int8u
+     38    WhiteBalance                         int8u
+     39    ISOSetting                           int8u
+     40    Saturation                           int8u
+
+=head3 Ricoh Subdir Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0004   ManufactureDate1                     string[20]
+  0x0005   ManufactureDate2                     string[20]
+  0x001a   FaceInfo                             Ricoh FaceInfo
+  0x0029   FirmwareInfo                         Ricoh FirmwareInfo
+  0x002a   NoiseReduction                       int32u
+  0x002c   SerialInfo                           Ricoh SerialInfo
+
+=head3 Ricoh FaceInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    181    FacesDetected                        int8u
+    182    FaceDetectFrameSize                  int16u[2]
+    188    Face1Position                        int16u[4]
+    200    Face2Position                        int16u[4]
+    212    Face3Position                        int16u[4]
+    224    Face4Position                        int16u[4]
+    236    Face5Position                        int16u[4]
+    248    Face6Position                        int16u[4]
+    260    Face7Position                        int16u[4]
+    272    Face8Position                        int16u[4]
+
+=head3 Ricoh FirmwareInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FirmwareRevision                     string[12]
+     12    FirmwareRevision2                    string[12]
+
+=head3 Ricoh SerialInfo Tags
+
+This information is found in images from the GXR.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    BodyFirmware                         string[16]
+     16    BodySerialNumber                     string[16]
+     32    LensFirmware                         string[16]
+     48    LensSerialNumber                     string[16]
+
+=head3 Ricoh ThetaSubdir Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0003   Accelerometer                        rational64s[2]
+  0x0004   Compass                              rational64u
+  0x000a   TimeZone                             string
+
+=head3 Ricoh Type2 Tags
+
+Tags written by models such as the Ricoh HZ15 and the Pentax XG-1.  These
+are not writable due to numerous formatting errors as written by these
+cameras.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0207   RicohModel                           no
+  0x0300   RicohMake                            no
+
+=head3 Ricoh Text Tags
+
+Some Ricoh DC and RDC models use a text-based format for their maker notes
+instead of the IFD format used by the Caplio models.  Below is a list of known
+tags in this information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Bg'     BlueGain                             no
+  'Gg'     GreenGain                            no
+  'Rev'    FirmwareVersion                      no
+  'Rg'     RedGain                              no
+  'Rv'     FirmwareVersion                      no
+
+=head3 Ricoh RMETA Tags
+
+The Ricoh Caplio Pro G3 has the ability to add custom fields to the APP5
+"RMETA" segment of JPEG images.  While only a few observed tags have been
+defined below, ExifTool will extract any information found here.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Azimuth'            Azimuth                  no
+  'Condition'          Condition                no
+  'Lit'                Lit                      no
+  'Location'           Location                 no
+  'Sign type'          SignType                 no
+  '_audio'             SoundFile                no
+  '_barcode'           Barcodes                 no+
+
+=head3 Ricoh AVI Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'mnrt'   MakerNoteRicoh                       Ricoh
+  'rdc2'   RicohRDC2?                           no
+  'thum'   ThumbnailImage                       no
+  'ucmt'   Comment                              no
 
 =head2 Sigma Tags
 
-These tags are used in Sigma/Foveon cameras.
+These tags are written by Sigma/Foveon cameras.  In the early days Sigma was
+a class leader by releasing their maker note specification to the public,
+but since then they have deviated from this standard and newer camera models
+are less than consistent about their metadata formats.
 
   Tag ID   Tag Name                             Writable
@@ -9774,10 +17360,21 @@
            LuminanceNoiseReduction              string
   0x001c   PreviewImageSize                     int16u[2]
+           PreviewImageStart                    int32u*
   0x001d   MakerNoteVersion                     undef
+           PreviewImageLength                   int32u*
+  0x001e   PreviewImageSize                     int16u[2]
   0x001f   AFPoint                              string
+           MakerNoteVersion                     undef
   0x0022   FileFormat                           string
   0x0024   Calibration                          string
+  0x0026   FileFormat                           string
+  0x0027   LensType                             string
+           LensType                             -
+                                                Sigma LensType
+  0x002a   LensFocalRange                       rational64u[2]
+  0x002b   LensMaxApertureRange                 rational64u[2]
   0x002c   ColorMode                            int32u
   0x0030   LensApertureRange                    string
+           Calibration                          string
   0x0031   FNumber                              rational64u
   0x0032   ExposureTime                         rational64u
@@ -9790,15 +17387,67 @@
   0x003c   WhiteBalance                         string
   0x003d   PictureMode                          string
+  0x0048   LensApertureRange                    string
+  0x0049   FNumber                              rational64u
+  0x004a   ExposureTime                         rational64u
+  0x004b   ExposureTime2                        string
+  0x004d   ExposureCompensation                 rational64s
+  0x0055   SensorTemperature                    string
+  0x0056   FlashExposureComp                    rational64s
+  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
 
-The maker notes in images from most recent Sony camera models contain a
-wealth of information, but for some models very little has been decoded. 
-Use the ExifTool Unknown (-u) or Verbose (-v) options to see information
-about the unknown tags.  Also see the Minolta tags which are used by some
-Sony models.
+The following information has been decoded from the MakerNotes of Sony
+cameras.  Some of these tags have been inherited from the Minolta
+MakerNotes.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
+  0x0010   CameraInfo                           Sony CameraInfo
+           CameraInfo2                          Sony CameraInfo2
+           CameraInfo3                          Sony CameraInfo3
+           CameraInfoUnknown                    Sony CameraInfoUnknown
+  0x0020   FocusInfo                            Sony FocusInfo
+           MoreInfo                             Sony MoreInfo
   0x0102   Quality                              int32u
   0x0104   FlashExposureComp                    rational64s
@@ -9807,6 +17456,10 @@
   0x0114   CameraSettings                       Sony CameraSettings
            CameraSettings2                      Sony CameraSettings2
+           CameraSettings3                      Sony CameraSettings3
            CameraSettingsUnknown                Sony CameraSettingsUnknown
   0x0115   WhiteBalance                         int32u
+  0x0116   ExtraInfo                            Sony ExtraInfo
+           ExtraInfo2                           Sony ExtraInfo2
+           ExtraInfo3                           Sony ExtraInfo3
   0x0e00   PrintIM                              PrintIM
   0x1000   MultiBurstMode                       undef
@@ -9815,4 +17468,5 @@
   0x1003   Panorama                             Sony Panorama
   0x2001   PreviewImage                         undef
+  0x2002   Rating                               int32u
   0x2004   Contrast                             int32s
   0x2005   Saturation                           int32s
@@ -9823,8 +17477,66 @@
   0x200a   HDR                                  int32u
   0x200b   MultiFrameNoiseReduction             int32u
+  0x200e   PictureEffect                        int16u
+  0x200f   SoftSkinEffect                       int32u
+  0x2010   Tag2010a                             Sony Tag2010a
+           Tag2010b                             Sony Tag2010b
+           Tag2010c                             Sony Tag2010c
+           Tag2010d                             Sony Tag2010d
+           Tag2010e                             Sony Tag2010e
+           Tag2010f                             Sony Tag2010f
+           Tag2010g                             Sony Tag2010g
+           Tag2010h                             Sony Tag2010h
+           Tag2010i                             Sony Tag2010i
+  0x2011   VignettingCorrection                 int32u
+  0x2012   LateralChromaticAberration           int32u
+  0x2013   DistortionCorrectionSetting          int32u
+  0x2014   WBShiftAB_GM                         int32s[2]
+  0x2016   AutoPortraitFramed                   int16u
+  0x2017   FlashAction                          int32u
+  0x201a   ElectronicFrontCurtainShutter        int32u
+  0x201b   FocusMode                            int8u
+  0x201c   AFAreaModeSetting                    int8u
+  0x201d   FlexibleSpotPosition                 int16u[2]
+  0x201e   AFPointSelected                      int8u
+  0x2020   AFPointsUsed                         no
+  0x2021   AFTracking                           int8u
+  0x2022   FocalPlaneAFPointsUsed               no
+  0x2023   MultiFrameNREffect                   int32u
+  0x2026   WBShiftAB_GM_Precise                 int32s[2]~
+  0x2027   FocusLocation                        int16u[4]
+  0x2028   VariableLowPassFilter                int16u[2]
+  0x2029   RAWFileType                          int16u
+  0x202a   Tag202a                              Sony Tag202a
+  0x202b   PrioritySetInAWB                     int8u
+  0x202c   MeteringMode2                        int16u
+  0x202d   ExposureStandardAdjustment           rational64s
+  0x202e   Quality                              int16u[2]
+  0x202f   PixelShiftInfo                       undef
+  0x2031   SerialNumber                         string
   0x3000   ShotInfo                             Sony ShotInfo
+  0x900b   Tag900b                              Sony Tag900b
+  0x9050   Tag9050a                             Sony Tag9050a
+           Tag9050b                             Sony Tag9050b
+           Tag9050c                             Sony Tag9050c
+  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
+           Tag9404b                             Sony Tag9404b
+           Tag9404c                             Sony Tag9404c
+  0x9405   Tag9405a                             Sony Tag9405a
+           Tag9405b                             Sony Tag9405b
+  0x9406   Tag9406                              Sony Tag9406
+  0x940a   Tag940a                              Sony Tag940a
+  0x940c   Tag940c                              Sony Tag940c
+  0x940e   AFInfo                               Sony AFInfo
+           Tag940e                              Sony Tag940e
+  0x9416   Sony_0x9416                          Sony Tag9416
   0xb000   FileFormat                           int8u[4]
   0xb001   SonyModelID                          int16u
-  0xb020   ColorReproduction                    string
+  0xb020   CreativeStyle                        string
   0xb021   ColorTemperature                     int32u
   0xb022   ColorCompensationFilter              int32u
@@ -9836,4 +17548,5 @@
   0xb028   MinoltaMakerNote                     Minolta
   0xb029   ColorMode                            int32u
+  0xb02a   LensSpec                             int8u[8]
   0xb02b   FullImageSize                        int32u[2]
   0xb02c   PreviewImageSize                     int32u[2]
@@ -9841,28 +17554,317 @@
   0xb041   ExposureMode                         int16u
   0xb042   FocusMode                            int16u
-  0xb043   AFMode                               int16u
+  0xb043   AFAreaMode                           int16u
   0xb044   AFIlluminator                        int16u
-  0xb047   Quality                              int16u
+  0xb047   JPEGQuality                          int16u
   0xb048   FlashLevel                           int16s
   0xb049   ReleaseMode                          int16u
   0xb04a   SequenceNumber                       int16u
   0xb04b   Anti-Blur                            int16u
-  0xb04e   LongExposureNoiseReduction           int16u
+  0xb04e   FocusMode                            int16u
   0xb04f   DynamicRangeOptimizer                int16u
+  0xb050   HighISONoiseReduction2               int16u
   0xb052   IntelligentAuto                      int16u
   0xb054   WhiteBalance                         int16u
 
+=head3 Sony CameraInfo Tags
+
+Camera information for the A700, A850 and A900.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensSpec                             undef[8]
+     20    FocusModeSetting                     int8u
+     21    AFPointSelected                      int8u
+     25    AFPoint                              int8u
+     30    AFStatusActiveSensor                 int16s
+     32    AFStatusUpper-left                   int16s
+     34    AFStatusLeft                         int16s
+     36    AFStatusLower-left                   int16s
+     38    AFStatusFarLeft                      int16s
+     40    AFStatusBottomAssist-left            int16s
+     42    AFStatusBottom                       int16s
+     44    AFStatusBottomAssist-right           int16s
+     46    AFStatusCenter-7                     int16s
+     48    AFStatusCenter-horizontal            int16s
+     50    AFStatusCenter-9                     int16s
+     52    AFStatusCenter-10                    int16s
+     54    AFStatusCenter-11                    int16s
+     56    AFStatusCenter-12                    int16s
+     58    AFStatusCenter-vertical              int16s
+     60    AFStatusCenter-14                    int16s
+     62    AFStatusTopAssist-left               int16s
+     64    AFStatusTop                          int16s
+     66    AFStatusTopAssist-right              int16s
+     68    AFStatusFarRight                     int16s
+     70    AFStatusUpper-right                  int16s
+     72    AFStatusRight                        int16s
+     74    AFStatusLower-right                  int16s
+     76    AFStatusCenterF2-8                   int16s
+    304    AFMicroAdjValue                      int8u
+    305    AFMicroAdjMode                       int8u & 0x80
+  305.1    AFMicroAdjRegisteredLenses           int8u & 0x7f
+
+=head3 Sony CameraInfo2 Tags
+
+Camera information for the DSLR-A200, A230, A290, A300, A330, A350, A380 and
+A390.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensSpec                             undef[8]
+     20    AFPointSelected                      int8u
+     21    FocusModeSetting                     int8u
+     24    AFPoint                              int8u
+     27    AFStatusActiveSensor                 int16s
+     29    AFStatusTop-right                    int16s
+     31    AFStatusBottom-right                 int16s
+     33    AFStatusBottom                       int16s
+     35    AFStatusMiddleHorizontal             int16s
+     37    AFStatusCenterVertical               int16s
+     39    AFStatusTop                          int16s
+     41    AFStatusTop-left                     int16s
+     43    AFStatusBottom-left                  int16s
+     45    AFStatusLeft                         int16s
+     47    AFStatusCenterHorizontal             int16s
+     49    AFStatusRight                        int16s
+
+=head3 Sony CameraInfo3 Tags
+
+Camera information stored by the A33, A35, A55, A450, A500, A550, A560,
+A580, NEX-3/5/5C/C3 and VG10E.  Some tags are valid only for some of these
+models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    LensSpec                             undef[8]
+     14    FocalLength                          int16u
+     16    FocalLengthTeleZoom                  int16u
+     20    AFPointSelected                      int8u
+     21    FocusMode                            int8u
+     24    AFPoint                              int8u
+     25    FocusStatus                          int8u
+     27    AFStatusActiveSensor                 int16s
+     28    AFPointSelected                      int8u
+     29    FocusMode                            int8u
+           AFStatusTop-right                    int16s
+     31    AFStatusBottom-right                 int16s
+     32    AFPoint                              int8u
+     33    AFStatusActiveSensor                 int16s
+           AFStatusBottom                       int16s
+     35    AFStatus15                           Sony AFStatus15
+           AFStatusMiddleHorizontal             int16s
+     37    AFStatusCenterVertical               int16s
+     39    AFStatusTop                          int16s
+     41    AFStatusTop-left                     int16s
+     43    AFStatusBottom-left                  int16s
+     45    AFStatusLeft                         int16s
+     47    AFStatusCenterHorizontal             int16s
+     49    AFStatusRight                        int16s
+
+=head3 Sony AFStatus15 Tags
+
+AF Status information for models with 15-point AF.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    AFStatusUpper-left                   int16s
+      2    AFStatusLeft                         int16s
+      4    AFStatusLower-left                   int16s
+      6    AFStatusFarLeft                      int16s
+      8    AFStatusTopHorizontal                int16s
+     10    AFStatusNearRight                    int16s
+     12    AFStatusCenterHorizontal             int16s
+     14    AFStatusNearLeft                     int16s
+     16    AFStatusBottomHorizontal             int16s
+     18    AFStatusTopVertical                  int16s
+     20    AFStatusCenterVertical               int16s
+     22    AFStatusBottomVertical               int16s
+     24    AFStatusFarRight                     int16s
+     26    AFStatusUpper-right                  int16s
+     28    AFStatusRight                        int16s
+     30    AFStatusLower-right                  int16s
+     32    AFStatusUpper-middle                 int16s
+     34    AFStatusLower-middle                 int16s
+
+=head3 Sony CameraInfoUnknown Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=head3 Sony FocusInfo Tags
+
+More camera settings and focus information decoded for models such as the
+A200, A230, A290, A300, A330, A350, A380, A390, A700, A850 and A900.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     14    DriveMode2                           int8u
+     16    Rotation                             int8u
+     20    ImageStabilizationSetting            int8u
+     21    DynamicRangeOptimizerMode            int8u
+     43    BracketShotNumber                    int8u
+     44    WhiteBalanceBracketing               int8u
+     45    BracketShotNumber2                   int8u
+     46    DynamicRangeOptimizerBracket         int8u
+     47    ExposureBracketShotNumber            int8u
+     63    ExposureProgram                      int8u
+     65    CreativeStyle                        int8u
+    109    ISOSetting                           int8u
+    111    ISO                                  int8u
+    119    DynamicRangeOptimizerMode            int8u
+    121    DynamicRangeOptimizerLevel           int8u
+   2118    ShutterCount                         int32u
+   2491    FocusPosition                        int8u
+   4368    TiffMeteringImage                    no
+
+=head3 Sony MoreInfo Tags
+
+More camera settings information decoded for the A450, A500, A550, A560,
+A580, A33, A35, A55, NEX-3/5/C3 and VG10E.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   MoreSettings                         Sony MoreSettings
+  0x0002   FaceInfo                             Sony FaceInfo
+           FaceInfoA                            Sony FaceInfoA
+  0x0107   TiffMeteringImage                    no
+  0x0201   MoreInfo0201                         Sony MoreInfo0201
+  0x0401   MoreInfo0401                         Sony MoreInfo0401
+
+=head3 Sony MoreSettings Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    DriveMode2                           int8u
+      2    ExposureProgram                      int8u
+      3    MeteringMode                         int8u
+      4    DynamicRangeOptimizerSetting         int8u
+      5    DynamicRangeOptimizerLevel           int8u
+      6    ColorSpace                           int8u
+      7    CreativeStyleSetting                 int8u
+      8    ContrastSetting                      int8s
+      9    SaturationSetting                    int8s
+     10    SharpnessSetting                     int8s
+     13    WhiteBalanceSetting                  int8u
+     14    ColorTemperatureSetting              int8u
+     15    ColorCompensationFilterSet           int8s
+     16    FlashMode                            int8u
+     17    LongExposureNoiseReduction           int8u
+     18    HighISONoiseReduction                int8u
+     19    FocusMode                            int8u
+     21    MultiFrameNoiseReduction             int8u
+     22    HDRSetting                           int8u
+     23    HDRLevel                             int8u
+     24    ViewingMode                          int8u
+     25    FaceDetection                        int8u
+     26    CustomWB_RBLevels                    int16uRev[2]
+     30    BrightnessValue                      int8u
+           ExposureCompensationSet              int8u
+     31    ISO                                  int8u
+           FlashExposureCompSet                 int8u
+     32    FNumber                              int8u
+           LiveViewAFMethod                     int8u
+     33    ExposureTime                         int8u
+           ISO                                  int8u
+     34    FNumber                              int8u
+     35    FocalLength2                         int8u
+           ExposureTime                         int8u
+     36    ExposureCompensation2                int16s
+     37    FocalLength2                         int8u
+           ISO                                  int8u
+     38    FlashExposureCompSet2                int16s
+           ExposureCompensation2                int16s
+           FNumber                              int8u
+     39    ExposureTime                         int8u
+     40    Orientation2                         int8u
+     41    FocusPosition2                       int8u
+           FocalLength2                         int8u
+     42    FlashAction                          int8u
+           ExposureCompensation2                int16s
+     43    FocusPosition2                       int8u
+     44    FocusMode2                           int8u
+           FlashAction                          int8u
+           FlashExposureCompSet2                int16s
+     46    FocusMode2                           int8u
+           Orientation2                         int8u
+     47    FocusPosition2                       int8u
+     48    FlashAction                          int8u
+     50    FocusMode2                           int8u
+    119    FlashAction2                         int8u
+    120    FlashActionExternal                  int8u
+    124    FlashActionExternal                  int8u
+    130    FlashStatus                          int8u
+    134    FlashStatus                          int8u
+
+=head3 Sony FaceInfo Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    FacesDetected                        int16s
+      1    Face1Position                        int16u[4]
+      6    Face2Position                        int16u[4]
+     11    Face3Position                        int16u[4]
+     16    Face4Position                        int16u[4]
+     21    Face5Position                        int16u[4]
+     26    Face6Position                        int16u[4]
+     31    Face7Position                        int16u[4]
+     36    Face8Position                        int16u[4]
+
+=head3 Sony FaceInfoA Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      3    FacesDetected                        no
+     11    PotentialFace1Position               int16u[4]
+     21    PotentialFace2Position               int16u[4]
+     31    PotentialFace3Position               int16u[4]
+     41    PotentialFace4Position               int16u[4]
+     51    PotentialFace5Position               int16u[4]
+     61    PotentialFace6Position               int16u[4]
+     71    PotentialFace7Position               int16u[4]
+     81    PotentialFace8Position               int16u[4]
+     91    Face1Position                        int16u[4]
+    101    Face2Position                        int16u[4]
+    111    Face3Position                        int16u[4]
+    121    Face4Position                        int16u[4]
+
+=head3 Sony MoreInfo0201 Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    283    ImageCount                           int32u
+    293    ShutterCount                         int32u
+    330    ShutterCount                         int32u
+
+=head3 Sony MoreInfo0401 Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+   1102    ShotNumberSincePowerUp               int32u
+
 =head3 Sony CameraSettings Tags
 
-Camera settings for the A200, A230, A300, A350, A700, A850 and A900.  Some
-tags are only valid for certain models.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      4    DriveMode                            int16u
-      6    WhiteBalanceFineTune                 int16s
-     16    FocusMode                            int16u
+Camera settings for the A200, A300, A350, A700, A850 and A900.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    ExposureTime                         int16u
+      1    FNumber                              int16u
+      2    HighSpeedSync                        int16u
+      3    ExposureCompensationSet              int16u
+      4    DriveMode                            int16u & 0xff
+      5    WhiteBalanceSetting                  int16u
+      6    WhiteBalanceFineTune                 int16u
+      7    ColorTemperatureSet                  int16u
+      8    ColorCompensationFilterSet           int16u
+     12    ColorTemperatureCustom               int16u
+     13    ColorCompensationFilterCustom        int16u
+     15    WhiteBalance                         int16u
+     16    FocusModeSetting                     int16u
      17    AFAreaMode                           int16u
-     18    LocalAFAreaPoint                     int16u
+     18    AFPointSetting                       int16u
+     19    FlashMode                            int16u
+     20    FlashExposureCompSet                 int16u
      21    MeteringMode                         int16u
      22    ISOSetting                           int16u
@@ -9870,4 +17872,5 @@
      25    DynamicRangeOptimizerLevel           int16u
      26    CreativeStyle                        int16u
+     27    ColorSpace                           int16u
      28    Sharpness                            int16u
      29    Contrast                             int16u
@@ -9875,5 +17878,5 @@
      31    ZoneMatchingValue                    int16u
      34    Brightness                           int16u
-     35    FlashMode                            int16u
+     35    FlashControl                         int16u
      40    PrioritySetupShutterRelease          int16u
      41    AFIlluminator                        int16u
@@ -9882,21 +17885,47 @@
      44    HighISONoiseReduction                int16u
      45    ImageStyle                           int16u
+     46    FocusModeSwitch                      int16u
+     47    ShutterSpeedSetting                  int16u
+     48    ApertureSetting                      int16u
      60    ExposureProgram                      int16u
-     61    ImageStabilization                   int16u
+     61    ImageStabilizationSetting            int16u
+     62    FlashAction                          int16u
      63    Rotation                             int16u
+     64    AELock                               int16u
+     76    FlashAction2                         int16u
+     77    FocusMode                            int16u
+     80    BatteryState                         int16u
+     81    BatteryLevel                         int16u
+     83    FocusStatus                          int16u
      84    SonyImageSize                        int16u
      85    AspectRatio                          int16u
      86    Quality                              int16u
      88    ExposureLevelIncrements              int16u
+    106    RedEyeReduction                      int16u
+    154    FolderNumber                         int16u & 0x3ff
+    155    ImageNumber                          int16u & 0x3fff
 
 =head3 Sony CameraSettings2 Tags
 
-Camera settings for the A330 and A380.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     16    FocusMode                            int16u
-     17    AFAreaMode                           int16u
-     18    LocalAFAreaPoint                     int16u
+Camera settings for the A230, A290, A330, A380 and A390.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    ExposureTime                         int16u
+      1    FNumber                              int16u
+      2    HighSpeedSync                        int16u
+      3    ExposureCompensationSet              int16u
+      4    WhiteBalanceSetting                  int16u
+      5    WhiteBalanceFineTune                 int16u
+      6    ColorTemperatureSet                  int16u
+      7    ColorCompensationFilterSet           int16u
+      8    CustomWB_RGBLevels                   int16u[3]
+     11    ColorTemperatureCustom               int16u
+     12    ColorCompensationFilterCustom        int16u
+     14    WhiteBalance                         int16u
+     15    FocusModeSetting                     int16u
+     16    AFAreaMode                           int16u
+     17    AFPointSetting                       int16u
+     18    FlashExposureCompSet                 int16u
      19    MeteringMode                         int16u
      20    ISOSetting                           int16u
@@ -9907,23 +17936,158 @@
      26    Contrast                             int16u
      27    Saturation                           int16u
-     35    FlashMode                            int16u
+     31    FlashControl                         int16u
+     37    LongExposureNoiseReduction           int16u
+     38    HighISONoiseReduction                int16u
+     39    ImageStyle                           int16u
+     40    ShutterSpeedSetting                  int16u
+     41    ApertureSetting                      int16u
      60    ExposureProgram                      int16u
+     61    ImageStabilizationSetting            int16u
+     62    FlashAction                          int16u
      63    Rotation                             int16u
+     64    AELock                               int16u
+     76    FlashAction2                         int16u
+     77    FocusMode                            int16u
+     83    FocusStatus                          int16u
      84    SonyImageSize                        int16u
+     85    AspectRatio                          int16u
+     86    Quality                              int16u
+     88    ExposureLevelIncrements              int16u
+    126    DriveMode                            int16u & 0xff
+    127    FlashMode                            int16u
+    131    ColorSpace                           int16u
+
+=head3 Sony CameraSettings3 Tags
+
+Camera settings for models such as the A33, A35, A55, A450, A500, A550,
+A560, A580, NEX-3, NEX-5, NEX-C3 and NEX-VG10E.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ShutterSpeedSetting                  int8u
+      1    ApertureSetting                      int8u
+      2    ISOSetting                           int8u
+      3    ExposureCompensationSet              int8u
+      4    DriveModeSetting                     int8u
+      5    ExposureProgram                      int8u
+      6    FocusModeSetting                     int8u
+      7    MeteringMode                         int8u
+      9    SonyImageSize                        int8u
+     10    AspectRatio                          int8u
+     11    Quality                              int8u
+     12    DynamicRangeOptimizerSetting         int8u
+     13    DynamicRangeOptimizerLevel           int8u
+     14    ColorSpace                           int8u
+     15    CreativeStyleSetting                 int8u
+     16    ContrastSetting                      int8s
+     17    SaturationSetting                    int8s
+     18    SharpnessSetting                     int8s
+     22    WhiteBalanceSetting                  int8u
+     23    ColorTemperatureSetting              int8u
+     24    ColorCompensationFilterSet           int8s
+     25    CustomWB_RGBLevels                   int16uRev[3]
+     32    FlashMode                            int8u
+     33    FlashControl                         int8u
+     35    FlashExposureCompSet                 int8u
+     36    AFAreaMode                           int8u
+     37    LongExposureNoiseReduction           int8u
+     38    HighISONoiseReduction                int8u
+     39    SmileShutterMode                     int8u
+     40    RedEyeReduction                      int8u
+     45    HDRSetting                           int8u
+     46    HDRLevel                             int8u
+     47    ViewingMode                          int8u
+     48    FaceDetection                        int8u
+     49    SmileShutter                         int8u
+     50    SweepPanoramaSize                    int8u
+     51    SweepPanoramaDirection               int8u
+     52    DriveMode                            int8u
+     53    MultiFrameNoiseReduction             int8u
+     54    LiveViewAFSetting                    int8u
+     56    PanoramaSize3D                       int8u
+    131    AFButtonPressed                      int8u
+    132    LiveViewMetering                     int8u
+    133    ViewingMode2                         int8u
+    134    AELock                               int8u
+    135    FlashStatusBuilt-in                  int8u
+    136    FlashStatusExternal                  int8u
+    139    LiveViewFocusMode                    int8u
+    153    LensMount                            int8u
+    268    SequenceNumber                       int8u
+    276    FolderNumber                         int32u & 0xffc000
+  276.1    ImageNumber                          int32u & 0x3fff
+    512    ShotNumberSincePowerUp2              int32u
+    643    AFButtonPressed                      int8u
+    644    LiveViewMetering                     int8u
+    645    ViewingMode2                         int8u
+    646    AELock                               int8u
+    647    FlashStatusBuilt-in                  int8u
+    648    FlashStatusExternal                  int8u
+    651    LiveViewFocusMode                    int8u
+    780    SequenceNumber                       int8u
+    788    ImageNumber                          int16u & 0x3fff
+    790    FolderNumber                         int16u & 0x3ff
+   1008    LensE-mountVersion                   int16u
+   1011    LensFirmwareVersion                  int16u~
+   1015    LensType2                            int16u
+   1024    ImageNumber                          int16u & 0x3fff
+   1026    FolderNumber                         int16u & 0x3ff
 
 =head3 Sony CameraSettingsUnknown Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
 
+=head3 Sony ExtraInfo Tags
+
+Extra hardware information for the A850 and A900.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    BatteryTemperature                   int8u
+      2    BatteryUnknown?                      no
+      8    BatteryVoltage?                      no
+     10    ImageStabilization2?                 int8u
+     12    BatteryLevel                         int8u
+     26    ExtraInfoVersion                     int8u[4]
+
+=head3 Sony ExtraInfo2 Tags
+
+Extra hardware information for the A230/290/330/380/390.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    BatteryLevel                         int8u
+     18    ImageStabilization                   int8u
+
+=head3 Sony ExtraInfo3 Tags
+
+Extra hardware information for the A33, A35, A55, A450, A500, A550, A560,
+A580 and NEX-3/5/C3/VG10.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    BatteryUnknown?                      int16u
+      2    BatteryTemperature                   int8u
+      4    BatteryLevel                         int8u
+      6    BatteryVoltage1                      int16u
+      8    BatteryVoltage2                      int16u
+     17    ImageStabilization                   int8u
+     20    BatteryState                         int8u
+           ExposureProgram                      int8u
+           ModeDialPosition                     int8u
+     22    MemoryCardConfiguration              int8u & 0xc0
+           CameraOrientation                    int8u
+     24    CameraOrientation                    int8u & 0x30
+
 =head3 Sony Panorama Tags
 
-Tags found only in panorama images from Sony cameras such as the HX1, HX5
-and TX7.  The width/height values of these tags are not affected by camera
+Tags found in panorama images from various Sony DSC, NEX, SLT and DSLR
+cameras.  The width/height values of these tags are not affected by camera
 rotation -- the width is always the longer dimension.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       1    PanoramaFullWidth                    int32u
       2    PanoramaFullHeight                   int32u
@@ -9938,12 +18102,390 @@
      11    PanoramaSourceHeight                 int32u
 
+=head3 Sony Tag2010a Tags
+
+Valid for NEX-5N.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+   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
+
+Information possibly related to metering.  Extracted only if the Unknown
+option is used.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    MeterInfo1Row1                       int32u[27]
+    108    MeterInfo1Row2                       int32u[27]
+    216    MeterInfo1Row3                       int32u[27]
+    324    MeterInfo1Row4                       int32u[27]
+    432    MeterInfo1Row5                       int32u[27]
+    540    MeterInfo1Row6                       int32u[27]
+    648    MeterInfo1Row7                       int32u[27]
+    756    MeterInfo2Row1                       int32u[33]
+    888    MeterInfo2Row2                       int32u[33]
+   1020    MeterInfo2Row3                       int32u[33]
+   1152    MeterInfo2Row4                       int32u[33]
+   1284    MeterInfo2Row5                       int32u[33]
+   1416    MeterInfo2Row6                       int32u[33]
+   1548    MeterInfo2Row7                       int32u[33]
+   1680    MeterInfo2Row8                       int32u[33]
+   1812    MeterInfo2Row9                       int32u[33]
+
+=head3 Sony Tag2010b Tags
+
+Valid for SLT-A65/A77, NEX-7/VG20E.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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.
+
+  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.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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-HX80/HX90V/RX0/RX1RM2/RX10M2/RX10M3/RX100M4/RX100M5/WX500,
+ILCE-6300/6500/7RM2/7SM2, ILCA-99M2.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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-6100/6400/6600/7C/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
+
+Information possibly related to metering.  Extracted only if the Unknown
+option is used.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    MeterInfo1Row1                       no
+     90    MeterInfo1Row2                       no
+    180    MeterInfo1Row3                       no
+    270    MeterInfo1Row4                       no
+    360    MeterInfo1Row5                       no
+    450    MeterInfo1Row6                       no
+    540    MeterInfo1Row7                       no
+    630    MeterInfo2Row1                       no
+    740    MeterInfo2Row2                       no
+    850    MeterInfo2Row3                       no
+    960    MeterInfo2Row4                       no
+   1070    MeterInfo2Row5                       no
+   1180    MeterInfo2Row6                       no
+   1290    MeterInfo2Row7                       no
+   1400    MeterInfo2Row8                       no
+   1510    MeterInfo2Row9                       no
+
+=head3 Sony Tag202a Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    FocalPlaneAFPointsUsed               int8u
+      2    FocalPlaneAFPointArea                int16u[2]
+      6    FocalPlaneAFPointLocation1           int16u[2]
+     10    FocalPlaneAFPointLocation2           int16u[2]
+     14    FocalPlaneAFPointLocation3           int16u[2]
+     18    FocalPlaneAFPointLocation4           int16u[2]
+     22    FocalPlaneAFPointLocation5           int16u[2]
+     26    FocalPlaneAFPointLocation6           int16u[2]
+     30    FocalPlaneAFPointLocation7           int16u[2]
+     34    FocalPlaneAFPointLocation8           int16u[2]
+     38    FocalPlaneAFPointLocation9           int16u[2]
+     42    FocalPlaneAFPointLocation10          int16u[2]
+     46    FocalPlaneAFPointLocation11          int16u[2]
+     50    FocalPlaneAFPointLocation12          int16u[2]
+     54    FocalPlaneAFPointLocation13          int16u[2]
+     58    FocalPlaneAFPointLocation14          int16u[2]
+     62    FocalPlaneAFPointLocation15          int16u[2]
+
 =head3 Sony ShotInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    FaceInfoOffset                       N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      2    FaceInfoOffset                       no
       6    SonyDateTime                         string[20]
+     26    SonyImageHeight                      int16u
+     28    SonyImageWidth                       int16u
      48    FacesDetected                        int16u
-     50    FaceInfoLength                       N
+     50    FaceInfoLength                       no
+     52    MetaVersion                          string[16]
      72    FaceInfo1                            Sony FaceInfo1
      94    FaceInfo2                            Sony FaceInfo2
@@ -9951,6 +18493,6 @@
 =head3 Sony FaceInfo1 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    Face1Position                        int16u[4]
      32    Face2Position                        int16u[4]
@@ -9964,6 +18506,6 @@
 =head3 Sony FaceInfo2 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    Face1Position                        int16u[4]
      37    Face2Position                        int16u[4]
@@ -9975,4 +18517,538 @@
     259    Face8Position                        int16u[4]
 
+=head3 Sony Tag900b Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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-6100/6300/6400/6500/6600/7C/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 Tag9050c Tags
+
+Valid from July 2020 for ILCE-1/7SM3.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     38    Shutter                              int16u[3]
+     57    FlashStatus                          int8u
+     58    ShutterCount                         int32u~
+     70    SonyExposureTime                     int16u
+     72    SonyFNumber                          int16u
+     75    ReleaseMode2                         int8u
+     80    ShutterCount2                        int32u
+    102    SonyExposureTime                     int16u
+    104    SonyFNumber                          int16u
+    107    ReleaseMode2                         int8u
+    136    InternalSerialNumber                 int8u[6]~
+
+=head3 Sony Tag9400a Tags
+
+Valid for many DSC, NEX and SLT models
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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/HX80/HX90V/HX99/HX350/HX400V/QX30/RX0/RX1RM2/RX10/
+RX10M2/RX10M3/RX10M4/RX100M3/RX100M4/RX100M5/RX100M5A/RX100M6/RX100M7/WX220/
+WX350/WX500, ILCE-1/7/7C/7R/7S/7M2/7M3/7RM2/7RM3/7RM4/7SM2/7SM3/9/9M2/5000/
+5100/6000/6100/6300/6400/6500/6600/QX1, ILCA-68/77M2/99M2.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      9    ReleaseMode2                         int8u
+     10    ShotNumberSincePowerUp               int32u
+     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
+   1185    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
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    AmbientTemperature                   int8s
+     22    FocusMode                            int8u & 0x7f
+     23    AFAreaMode                           int8u
+     45    FocusPosition2                       int8u
+
+=head3 Sony Tag9403 Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      5    CameraTemperature                    int8s
+
+=head3 Sony Tag9404a Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     11    ExposureProgram                      int8u
+     13    IntelligentAuto                      int8u
+     25    LensZoomPosition                     int16u
+
+=head3 Sony Tag9404b Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    ExposureProgram                      int8u
+     14    IntelligentAuto                      int8u
+     30    LensZoomPosition                     int16u
+     32    FocusPosition2                       int8u
+
+=head3 Sony Tag9404c Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     11    ExposureProgram                      int8u
+     13    IntelligentAuto                      int8u
+
+=head3 Sony Tag9405a Tags
+
+Valid for SLT, NEX, ILCE-3000/3500 and several DSC models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+   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/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
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    AFPointsSelected                     int32u
+
+=head3 Sony Tag940c Tags
+
+NEX and ILCE models only.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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
+     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
+
+AF Status information for models with 19-point AF.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    AFStatusUpperFarLeft                 int16s
+      2    AFStatusUpper-leftHorizontal         int16s
+      4    AFStatusFarLeftHorizontal            int16s
+      6    AFStatusLeftHorizontal               int16s
+      8    AFStatusLowerFarLeft                 int16s
+     10    AFStatusLower-leftHorizontal         int16s
+     12    AFStatusUpper-leftVertical           int16s
+     14    AFStatusLeftVertical                 int16s
+     16    AFStatusLower-leftVertical           int16s
+     18    AFStatusFarLeftVertical              int16s
+     20    AFStatusTopHorizontal                int16s
+     22    AFStatusNearRight                    int16s
+     24    AFStatusCenterHorizontal             int16s
+     26    AFStatusNearLeft                     int16s
+     28    AFStatusBottomHorizontal             int16s
+     30    AFStatusTopVertical                  int16s
+     32    AFStatusUpper-middle                 int16s
+     34    AFStatusCenterVertical               int16s
+     36    AFStatusLower-middle                 int16s
+     38    AFStatusBottomVertical               int16s
+     40    AFStatusUpperFarRight                int16s
+     42    AFStatusUpper-rightHorizontal        int16s
+     44    AFStatusFarRightHorizontal           int16s
+     46    AFStatusRightHorizontal              int16s
+     48    AFStatusLowerFarRight                int16s
+     50    AFStatusLower-rightHorizontal        int16s
+     52    AFStatusFarRightVertical             int16s
+     54    AFStatusUpper-rightVertical          int16s
+     56    AFStatusRightVertical                int16s
+     58    AFStatusLower-rightVertical          int16s
+
+=head3 Sony AFStatus79 Tags
+
+AF Status information for models with 79-point AF.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    AFStatus_00_B4                       int16s
+      2    AFStatus_01_C4                       int16s
+      4    AFStatus_02_D4                       int16s
+      6    AFStatus_03_E4                       int16s
+      8    AFStatus_04_F4                       int16s
+     10    AFStatus_05_G4                       int16s
+     12    AFStatus_06_H4                       int16s
+     14    AFStatus_07_B3                       int16s
+     16    AFStatus_08_C3                       int16s
+     18    AFStatus_09_D3                       int16s
+     20    AFStatus_10_E3                       int16s
+     22    AFStatus_11_F3                       int16s
+     24    AFStatus_12_G3                       int16s
+     26    AFStatus_13_H3                       int16s
+     28    AFStatus_14_B2                       int16s
+     30    AFStatus_15_C2                       int16s
+     32    AFStatus_16_D2                       int16s
+     34    AFStatus_17_E2                       int16s
+     36    AFStatus_18_F2                       int16s
+     38    AFStatus_19_G2                       int16s
+     40    AFStatus_20_H2                       int16s
+     42    AFStatus_21_C1                       int16s
+     44    AFStatus_22_D1                       int16s
+     46    AFStatus_23_E1                       int16s
+     48    AFStatus_24_F1                       int16s
+     50    AFStatus_25_G1                       int16s
+     52    AFStatus_26_A7_Vertical              int16s
+     54    AFStatus_27_A6_Vertical              int16s
+     56    AFStatus_28_A5_Vertical              int16s
+     58    AFStatus_29_C7_Vertical              int16s
+     60    AFStatus_30_C6_Vertical              int16s
+     62    AFStatus_31_C5_Vertical              int16s
+     64    AFStatus_32_E7_Vertical              int16s
+     66    AFStatus_33_E6_Center_Vertical       int16s
+     68    AFStatus_34_E5_Vertical              int16s
+     70    AFStatus_35_G7_Vertical              int16s
+     72    AFStatus_36_G6_Vertical              int16s
+     74    AFStatus_37_G5_Vertical              int16s
+     76    AFStatus_38_I7_Vertical              int16s
+     78    AFStatus_39_I6_Vertical              int16s
+     80    AFStatus_40_I5_Vertical              int16s
+     82    AFStatus_41_A7                       int16s
+     84    AFStatus_42_B7                       int16s
+     86    AFStatus_43_C7                       int16s
+     88    AFStatus_44_D7                       int16s
+     90    AFStatus_45_E7                       int16s
+     92    AFStatus_46_F7                       int16s
+     94    AFStatus_47_G7                       int16s
+     96    AFStatus_48_H7                       int16s
+     98    AFStatus_49_I7                       int16s
+    100    AFStatus_50_A6                       int16s
+    102    AFStatus_51_B6                       int16s
+    104    AFStatus_52_C6                       int16s
+    106    AFStatus_53_D6                       int16s
+    108    AFStatus_54_E6_Center                int16s
+    110    AFStatus_55_F6                       int16s
+    112    AFStatus_56_G6                       int16s
+    114    AFStatus_57_H6                       int16s
+    116    AFStatus_58_I6                       int16s
+    118    AFStatus_59_A5                       int16s
+    120    AFStatus_60_B5                       int16s
+    122    AFStatus_61_C5                       int16s
+    124    AFStatus_62_D5                       int16s
+    126    AFStatus_63_E5                       int16s
+    128    AFStatus_64_F5                       int16s
+    130    AFStatus_65_G5                       int16s
+    132    AFStatus_66_H5                       int16s
+    134    AFStatus_67_I5                       int16s
+    136    AFStatus_68_C11                      int16s
+    138    AFStatus_69_D11                      int16s
+    140    AFStatus_70_E11                      int16s
+    142    AFStatus_71_F11                      int16s
+    144    AFStatus_72_G11                      int16s
+    146    AFStatus_73_B10                      int16s
+    148    AFStatus_74_C10                      int16s
+    150    AFStatus_75_D10                      int16s
+    152    AFStatus_76_E10                      int16s
+    154    AFStatus_77_F10                      int16s
+    156    AFStatus_78_G10                      int16s
+    158    AFStatus_79_H10                      int16s
+    160    AFStatus_80_B9                       int16s
+    162    AFStatus_81_C9                       int16s
+    164    AFStatus_82_D9                       int16s
+    166    AFStatus_83_E9                       int16s
+    168    AFStatus_84_F9                       int16s
+    170    AFStatus_85_G9                       int16s
+    172    AFStatus_86_H9                       int16s
+    174    AFStatus_87_B8                       int16s
+    176    AFStatus_88_C8                       int16s
+    178    AFStatus_89_D8                       int16s
+    180    AFStatus_90_E8                       int16s
+    182    AFStatus_91_F8                       int16s
+    184    AFStatus_92_G8                       int16s
+    186    AFStatus_93_H8                       int16s
+    188    AFStatus_94_E6_Center_F2-8           int16s
+
+=head3 Sony Tag940e Tags
+
+E-mount models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+   6662    TiffMeteringImageWidth               no
+   6663    TiffMeteringImageHeight              no
+   6664    TiffMeteringImage                    no
+
+=head3 Sony Tag9416 Tags
+
+Valid for the ILCE-1/7SM3.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Tag9416_0000                         no
+      4    SonyISO                              no
+      6    StopsAboveBaseISO                    no
+     10    SonyExposureTime2                    no
+     12    ExposureTime                         no
+     16    SonyFNumber2                         no
+     18    SonyMaxApertureValue                 no
+     29    SequenceImageNumber                  no
+     53    ExposureProgram                      no
+     72    LensMount                            no
+     73    LensFormat                           no
+     74    LensMount                            no
+     75    LensType2                            no
+     77    LensType                             no
+     79    DistortionCorrParams                 no
+    112    PictureProfile                       no
+    113    FocalLength                          no
+    115    MinFocalLength                       no
+    117    MaxFocalLength                       no
+   2191    VignettingCorrParams                 no
+   2324    ChromaticAberrationCorrParams        no
+
+=head3 Sony PIC Tags
+
+The TextInfo data is extracted as a block to preserve the formatting, and
+some of the more interesting information is extracted as separate tags.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'BC:'                Barcode                  no
+  'BarCode:'           Barcode                  no
+  'Capt:'              SensorTemperature        no
+  'FWVer:'             FirmwareVersion          no
+  'IFD'                PIC_IFD                  Sony
+  'Temp:'              CameraTemperature        no
+  'Temp:Clbt:'         BoardTemperature         no
+  'TextInfo1'          TextInfo1                no
+  'TextInfo2'          TextInfo2                no
+  'VR Enable C:'       VibrationReduction       no
+  'barcode:'           Barcode                  no
+
 =head3 Sony Ericsson Tags
 
@@ -9996,6 +19072,6 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   SRF2Key                              N
-  0x0001   DataKey                              N
+  0x0000   SRF2Key                              no
+  0x0001   DataKey                              no
 
 =head3 Sony SRF2 Tags
@@ -10005,8 +19081,30 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0002   SRF6Offset                           N
-  0x0003   SRFDataOffset?                       N
-  0x0004   RawDataOffset                        N
-  0x0005   RawDataLength                        N
+  0x0002   SRF6Offset                           no
+  0x0003   SRFDataOffset?                       no
+  0x0004   RawDataOffset                        no
+  0x0005   RawDataLength                        no
+  0x0043   MaxApertureAtMaxFocal                no
+  0x0044   MaxApertureAtMinFocal                no
+  0x0045   MinFocalLength                       no
+  0x0046   MaxFocalLength                       no
+  0x00c0   WBRedDaylight                        no
+  0x00c1   WBGreenDaylight                      no
+  0x00c2   WBBlueDaylight                       no
+  0x00c3   WBRedCloudy                          no
+  0x00c4   WBGreenCloudy                        no
+  0x00c5   WBBlueCloudy                         no
+  0x00c6   WBRedFluorescent                     no
+  0x00c7   WBGreenFluorescent                   no
+  0x00c8   WBBlueFluorescent                    no
+  0x00c9   WBRedTungsten                        no
+  0x00ca   WBGreenTungsten                      no
+  0x00cb   WBBlueTungsten                       no
+  0x00cc   WBRedFlash                           no
+  0x00cd   WBGreenFlash                         no
+  0x00ce   WBBlueFlash                          no
+  0x00d0   WBRedAsShot                          no
+  0x00d1   WBGreenAsShot                        no
+  0x00d2   WBBlueAsShot                         no
 
 =head3 Sony SR2Private Tags
@@ -10018,7 +19116,7 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x7200   SR2SubIFDOffset                      N
-  0x7201   SR2SubIFDLength                      N
-  0x7221   SR2SubIFDKey                         N
+  0x7200   SR2SubIFDOffset                      no
+  0x7201   SR2SubIFDLength                      no
+  0x7221   SR2SubIFDKey                         no
   0x7240   IDC_IFD                              SonyIDC
   0x7241   IDC2_IFD                             SonyIDC
@@ -10031,15 +19129,40 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x7303   WB_GRBGLevels                        N
-  0x7313   WB_RGGBLevels                        N
-  0x74a0   MaxApertureAtMaxFocal                N
-  0x74a1   MaxApertureAtMinFocal                N
+  0x7300   BlackLevel                           no
+  0x7302   WB_GRBGLevelsAuto                    no
+  0x7303   WB_GRBGLevels                        no
+  0x7310   BlackLevel                           no
+  0x7312   WB_RGGBLevelsAuto                    no
+  0x7313   WB_RGGBLevels                        no
+  0x7480   WB_RGBLevelsDaylight                 no
+  0x7481   WB_RGBLevelsCloudy                   no
+  0x7482   WB_RGBLevelsTungsten                 no
+  0x7483   WB_RGBLevelsFlash                    no
+  0x7484   WB_RGBLevels4500K                    no
+  0x7486   WB_RGBLevelsFluorescent              no
+  0x74a0   MaxApertureAtMaxFocal                no
+  0x74a1   MaxApertureAtMinFocal                no
+  0x74a2   MaxFocalLength                       no
+  0x74a3   MinFocalLength                       no
   0x74c0   SR2DataIFD                           Sony SR2DataIFD
-  0x7820   WB_RGBLevelsDaylight                 N
-  0x7821   WB_RGBLevelsCloudy                   N
-  0x7822   WB_RGBLevelsTungsten                 N
-  0x7825   WB_RGBLevelsShade                    N
-  0x7826   WB_RGBLevelsFluorescent              N
-  0x7828   WB_RGBLevelsFlash                    N
+  0x7800   ColorMatrix                          no
+  0x7820   WB_RGBLevelsDaylight                 no
+  0x7821   WB_RGBLevelsCloudy                   no
+  0x7822   WB_RGBLevelsTungsten                 no
+  0x7823   WB_RGBLevelsFlash                    no
+  0x7824   WB_RGBLevels4500K                    no
+  0x7825   WB_RGBLevelsShade                    no
+  0x7826   WB_RGBLevelsFluorescent              no
+  0x7827   WB_RGBLevelsFluorescentP1            no
+  0x7828   WB_RGBLevelsFluorescentP2            no
+  0x7829   WB_RGBLevelsFluorescentM1            no
+  0x782a   WB_RGBLevels8500K                    no
+  0x782b   WB_RGBLevels6000K                    no
+  0x782c   WB_RGBLevels3200K                    no
+  0x782d   WB_RGBLevels2500K                    no
+  0x787f   WhiteLevel                           no
+  0x797d   VignettingCorrParams                 no
+  0x7980   ChromaticAberrationCorrParams        no
+  0x7982   DistortionCorrParams                 no
 
 =head3 Sony SR2DataIFD Tags
@@ -10047,5 +19170,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x7770   ColorMode                            N
+  0x7770   ColorMode                            no
 
 =head3 Sony PMP Tags
@@ -10054,20 +19177,39 @@
 the DSC-F1.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      8    JpgFromRawStart                      N
-     12    JpgFromRawLength                     N
-     22    SonyImageWidth                       N
-     24    SonyImageHeight                      N
-     27    Orientation                          N
-     29    ImageQuality                         N
-     52    Comment                              N
-     76    DateTimeOriginal                     N
-     84    ModifyDate                           N
-    102    ExposureTime                         N
-    106    FNumber                              N
-    108    ExposureCompensation                 N
-    112    FocalLength                          N
-    118    Flash                                N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    JpgFromRawStart                      no
+     12    JpgFromRawLength                     no
+     22    SonyImageWidth                       no
+     24    SonyImageHeight                      no
+     27    Orientation                          no
+     29    ImageQuality                         no
+     52    Comment                              no
+     76    DateTimeOriginal                     no
+     84    ModifyDate                           no
+    102    ExposureTime                         no
+    106    FNumber                              no
+    108    ExposureCompensation                 no
+    112    FocalLength                          no
+    118    Flash                                no
+
+=head3 Sony rtmd Tags
+
+These tags are extracted from the 'rtmd' timed metadata of MP4 videos from
+some models when the ExtractEmbedded option is used.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x8500   GPSVersionID                         no
+  0x8501   GPSLatitudeRef                       no
+  0x8502   GPSLatitude                          no
+  0x8503   GPSLongitudeRef                      no
+  0x8504   GPSLongitude                         no
+  0x8507   GPSTimeStamp                         no
+  0x8509   GPSStatus                            no
+  0x850a   GPSMeasureMode                       no
+  0x8512   GPSMapDatum                          no
+  0x851d   GPSDateStamp                         no
+  0xe304   DateTime                             no
 
 =head2 SonyIDC Tags
@@ -10106,4 +19248,5 @@
   0x8031   PeripheralIllumCentralValue          int32s
   0x8032   PeripheralIllumPeriphValue           int32s
+  0x8040   DistortionCompensation               int32s
   0x9000   ToneCurveBrightnessX                 int16u[n]
   0x9001   ToneCurveRedX                        int16u[n]
@@ -10114,4 +19257,16 @@
   0x9006   ToneCurveGreenY                      int16u[n]
   0x9007   ToneCurveBlueY                       int16u[n]
+  0x900d   ChromaticAberrationCorrection        int32s
+  0x900e   InclinationCorrection                int32u
+  0x900f   InclinationAngle                     int32s
+  0x9010   Cropping                             int32u
+  0x9011   CropArea                             int32u[4]
+  0x9012   PreviewImageSize                     int32u[2]
+  0x9013   PxShiftPeriphEdgeNR                  int32s
+  0x9014   PxShiftPeriphEdgeNRValue             int32s
+  0x9017   WhitesAdj                            int32s
+  0x9018   BlacksAdj                            int32s
+  0x9019   HighlightsAdj                        int32s
+  0x901a   ShadowsAdj                           int32s
   0xd000   CurrentVersion                       int32u
   0xd001   VersionIFD                           SonyIDC
@@ -10156,10 +19311,15 @@
   'Leaf'   AdobeLeaf                            Leaf SubIFD
   'MRW '   AdobeMRW                             MinoltaRaw
-  'MakN'   MakerNoteCanon                       Canon
+  'MakN'   MakerNoteApple                       Apple
+           MakerNoteNikon                       Nikon
+           MakerNoteCanon                       Canon
            MakerNoteCasio                       Casio
            MakerNoteCasio2                      Casio Type2
+           MakerNoteDJI                         DJI
+           MakerNoteFLIR                        FLIR
            MakerNoteFujiFilm                    FujiFilm
            MakerNoteGE                          GE
            MakerNoteGE2                         FujiFilm
+           MakerNoteHasselblad                  Unknown
            MakerNoteHP                          HP
            MakerNoteHP2                         HP Type2
@@ -10180,6 +19340,9 @@
            MakerNoteKodak8a                     Kodak Type8
            MakerNoteKodak8b                     Kodak Type8
+           MakerNoteKodak8c                     Kodak Type8
            MakerNoteKodak9                      Kodak Type9
            MakerNoteKodak10                     Kodak Type10
+           MakerNoteKodak11                     Kodak Type11
+           MakerNoteKodak12                     Kodak Type11
            MakerNoteKodakUnknown                Kodak Unknown
            MakerNoteKyocera                     Unknown
@@ -10187,7 +19350,8 @@
            MakerNoteMinolta2                    Olympus
            MakerNoteMinolta3                    undef
-           MakerNoteNikon                       Nikon
+           MakerNoteMotorola                    Motorola
            MakerNoteNikon2                      Nikon Type2
            MakerNoteNikon3                      Nikon
+           MakerNoteNintendo                    Nintendo
            MakerNoteOlympus                     Olympus
            MakerNoteOlympus2                    Olympus
@@ -10198,6 +19362,11 @@
            MakerNoteLeica5                      Panasonic Leica5
            MakerNoteLeica6                      Panasonic Leica6
+           MakerNoteLeica7                      Panasonic Leica6
+           MakerNoteLeica8                      Panasonic Leica5
+           MakerNoteLeica9                      Panasonic Leica9
+           MakerNoteLeica10                     Panasonic
            MakerNotePanasonic                   Panasonic
            MakerNotePanasonic2                  Panasonic Type2
+           MakerNotePanasonic3                  Panasonic
            MakerNotePentax                      Pentax
            MakerNotePentax2                     Pentax Type2
@@ -10205,10 +19374,15 @@
            MakerNotePentax4                     Pentax Type4
            MakerNotePentax5                     Pentax
-           MakerNotePhaseOne                    undef
+           MakerNotePentax6                     Pentax S1
+           MakerNotePhaseOne                    PhaseOne
            MakerNoteReconyx                     Reconyx
+           MakerNoteReconyx2                    Reconyx Type2
+           MakerNoteReconyx3                    Reconyx Type3
+           MakerNoteRicohPentax                 Pentax
            MakerNoteRicoh                       Ricoh
+           MakerNoteRicoh2                      Ricoh Type2
            MakerNoteRicohText                   Ricoh Text
            MakerNoteSamsung1a                   undef
-           MakerNoteSamsung1b                   Samsung Type1
+           MakerNoteSamsung1b                   Samsung
            MakerNoteSamsung2                    Samsung Type2
            MakerNoteSanyo                       Sanyo
@@ -10219,8 +19393,10 @@
            MakerNoteSony2                       Olympus
            MakerNoteSony3                       Olympus
-           MakerNoteSony4                       Sony
+           MakerNoteSony4                       Sony PIC
+           MakerNoteSony5                       Sony
            MakerNoteSonyEricsson                Sony Ericsson
            MakerNoteSonySRF                     Sony SRF
            MakerNoteUnknownText                 undef
+           MakerNoteUnknownBinary               undef
            MakerNoteUnknown                     Unknown
   'Pano'   AdobePano                            PanasonicRaw
@@ -10235,12 +19411,12 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   OriginalRawImage                     N
-  0x0001   OriginalRawResource                  N
-  0x0002   OriginalRawFileType                  N
-  0x0003   OriginalRawCreator                   N
-  0x0004   OriginalTHMImage                     N
-  0x0005   OriginalTHMResource                  N
-  0x0006   OriginalTHMFileType                  N
-  0x0007   OriginalTHMCreator                   N
+  0x0000   OriginalRawImage                     no
+  0x0001   OriginalRawResource                  no
+  0x0002   OriginalRawFileType                  no
+  0x0003   OriginalRawCreator                   no
+  0x0004   OriginalTHMImage                     no
+  0x0005   OriginalTHMResource                  no
+  0x0006   OriginalTHMFileType                  no
+  0x0007   OriginalTHMCreator                   no
 
 =head2 CanonRaw Tags
@@ -10250,5 +19426,7 @@
 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
@@ -10260,5 +19438,5 @@
   0x0000   NullRecord                           undef
   0x0001   FreeBytes                            undef
-  0x0032   CanonColorInfo1                      N
+  0x0032   CanonColorInfo1                      no
   0x0805   CanonFileDescription                 string[32]
            UserComment                          string[256]
@@ -10279,5 +19457,5 @@
   0x1029   CanonFocalLength                     Canon FocalLength
   0x102a   CanonShotInfo                        Canon ShotInfo
-  0x102c   CanonColorInfo2                      N
+  0x102c   CanonColorInfo2                      no
   0x102d   CanonCameraSettings                  Canon CameraSettings
   0x1030   WhiteSample                          CanonRaw WhiteSample
@@ -10298,5 +19476,5 @@
   0x1807   TargetDistanceSetting                float
   0x180b   SerialNumber                         int32u
-           UnknownNumber?                       Y
+           UnknownNumber?                       yes
   0x180e   TimeStamp                            CanonRaw TimeStamp
   0x1810   ImageInfo                            CanonRaw ImageInfo
@@ -10308,7 +19486,7 @@
   0x1835   DecoderTable                         CanonRaw DecoderTable
   0x183b   SerialNumberFormat                   int32u
-  0x2005   RawData                              N
-  0x2007   JpgFromRaw                           resize
-  0x2008   ThumbnailImage                       resize
+  0x2005   RawData                              no
+  0x2007   JpgFromRaw                           resize^
+  0x2008   ThumbnailImage                       resize^
   0x2804   ImageDescription                     CanonRaw
   0x2807   CameraObject                         CanonRaw
@@ -10321,6 +19499,6 @@
 =head3 CanonRaw MakeModel Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    Make                                 string[6]
       6    Model                                string
@@ -10328,16 +19506,16 @@
 =head3 CanonRaw WhiteSample Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    WhiteSampleWidth                     N
-      2    WhiteSampleHeight                    N
-      3    WhiteSampleLeftBorder                N
-      4    WhiteSampleTopBorder                 N
-      5    WhiteSampleBits                      N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      1    WhiteSampleWidth                     no
+      2    WhiteSampleHeight                    no
+      3    WhiteSampleLeftBorder                no
+      4    WhiteSampleTopBorder                 no
+      5    WhiteSampleBits                      no
 
 =head3 CanonRaw RawJpgInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
       1    RawJpgQuality                        int16u
       2    RawJpgSize                           int16u
@@ -10347,6 +19525,6 @@
 =head3 CanonRaw ImageFormat Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    FileFormat                           int32u
       1    TargetCompressionRatio               float
@@ -10354,6 +19532,6 @@
 =head3 CanonRaw TimeStamp Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    DateTimeOriginal                     int32u
       1    TimeZoneCode                         int32s
@@ -10362,18 +19540,18 @@
 =head3 CanonRaw ImageInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageWidth                           N
-      1    ImageHeight                          N
-      2    PixelAspectRatio                     N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageWidth                           no
+      1    ImageHeight                          no
+      2    PixelAspectRatio                     no
       3    Rotation                             int32s
-      4    ComponentBitDepth                    N
-      5    ColorBitDepth                        N
-      6    ColorBW                              N
+      4    ComponentBitDepth                    no
+      5    ColorBitDepth                        no
+      6    ColorBW                              no
 
 =head3 CanonRaw FlashInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    FlashGuideNumber                     float
       1    FlashThreshold                       float
@@ -10381,6 +19559,6 @@
 =head3 CanonRaw ExposureInfo Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    ExposureCompensation                 float
       1    ShutterSpeedValue                    float
@@ -10389,9 +19567,9 @@
 =head3 CanonRaw DecoderTable Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    DecoderTableNumber                   N
-      2    CompressedDataOffset                 N
-      3    CompressedDataLength                 N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    DecoderTableNumber                   no
+      2    CompressedDataOffset                 no
+      3    CompressedDataLength                 no
 
 =head2 KyoceraRaw Tags
@@ -10399,17 +19577,17 @@
 Tags for Kyocera Contax N Digital RAW images.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    FirmwareVersion                      N
-     12    Model                                N
-     25    Make                                 N
-     33    DateTimeOriginal                     N
-     52    ISO                                  N
-     56    ExposureTime                         N
-     60    WB_RGGBLevels                        N
-     88    FNumber                              N
-    104    MaxAperture                          N
-    112    FocalLength                          N
-    124    Lens                                 N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    FirmwareVersion                      no
+     12    Model                                no
+     25    Make                                 no
+     33    DateTimeOriginal                     no
+     52    ISO                                  no
+     56    ExposureTime                         no
+     60    WB_RGGBLevels                        no
+     88    FNumber                              no
+    104    MaxAperture                          no
+    112    FocalLength                          no
+    124    Lens                                 no
 
 =head2 MinoltaRaw Tags
@@ -10426,6 +19604,6 @@
 =head3 MinoltaRaw PRD Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    FirmwareID                           string[8]
       8    SensorHeight                         int16u
@@ -10440,6 +19618,6 @@
 =head3 MinoltaRaw RIF Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       1    Saturation                           int8s
       2    Contrast                             int8s
@@ -10454,5 +19632,5 @@
      20    WB_RBLevelsCoolWhiteF                int16u[2]
      24    WB_RBLevelsFlash                     int16u[2]
-     28    WB_RBLevelsUnknown?                  int16u[2]
+     28    WB_RBLevelsCustom                    int16u[2]
      32    WB_RBLevelsShade                     int16u[2]
      36    WB_RBLevelsDaylightF                 int16u[2]
@@ -10469,9 +19647,10 @@
      78    ColorTemperature                     int8u
      79    ColorFilter                          int8u
+     80    RawDataLength                        no
 
 =head3 MinoltaRaw WBG Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
       0    WBScale                              int8u[4]
       4    WB_GBRGLevels                        int16u[4]
@@ -10485,24 +19664,49 @@
   ------   --------                             --------
   0x0001   PanasonicRawVersion                  undef
-  0x0002   SensorWidth                          N
-  0x0003   SensorHeight                         N
-  0x0004   SensorTopBorder                      N
-  0x0005   SensorLeftBorder                     N
-  0x0006   ImageHeight                          N
-  0x0007   ImageWidth                           N
+  0x0002   SensorWidth                          no
+  0x0003   SensorHeight                         no
+  0x0004   SensorTopBorder                      no
+  0x0005   SensorLeftBorder                     no
+  0x0006   SensorBottomBorder                   no
+  0x0007   SensorRightBorder                    no
+  0x0008   SamplesPerPixel                      int16u!
+  0x0009   CFAPattern                           int16u!
+  0x000a   BitsPerSample                        int16u!
+  0x000b   Compression                          int16u!
+  0x000e   LinearityLimitRed                    int16u
+  0x000f   LinearityLimitGreen                  int16u
+  0x0010   LinearityLimitBlue                   int16u
   0x0011   RedBalance                           int16u
   0x0012   BlueBalance                          int16u
+  0x0013   WBInfo                               PanasonicRaw WBInfo
   0x0017   ISO                                  int16u
+  0x0018   HighISOMultiplierRed                 int16u
+  0x0019   HighISOMultiplierGreen               int16u
+  0x001a   HighISOMultiplierBlue                int16u
+  0x001b   NoiseReductionParams                 undef[n]!
+  0x001c   BlackLevelRed                        int16u
+  0x001d   BlackLevelGreen                      int16u
+  0x001e   BlackLevelBlue                       int16u
   0x0024   WBRedLevel                           int16u
   0x0025   WBGreenLevel                         int16u
   0x0026   WBBlueLevel                          int16u
+  0x0027   WBInfo2                              PanasonicRaw WBInfo2
+  0x002d   RawFormat                            int16u!
   0x002e   JpgFromRaw                           JPEG
+  0x002f   CropTop                              int16u
+  0x0030   CropLeft                             int16u
+  0x0031   CropBottom                           int16u
+  0x0032   CropRight                            int16u
   0x010f   Make                                 string
   0x0110   Model                                string
-  0x0111   StripOffsets                         N
+  0x0111   StripOffsets                         no
   0x0112   Orientation                          int16u
-  0x0116   RowsPerStrip                         N
-  0x0117   StripByteCounts                      N
-  0x0118   RawDataOffset                        N
+  0x0116   RowsPerStrip                         no
+  0x0117   StripByteCounts                      no
+  0x0118   RawDataOffset                        no
+  0x0119   DistortionInfo                       PanasonicRaw DistortionInfo
+  0x011c   Gamma                                int16u
+  0x0120   CameraIFD                            PanasonicRaw CameraIFD
+  0x0121   Multishot                            int32u
   0x02bc   ApplicationNotes                     XMP
   0x83bb   IPTC-NAA                             IPTC
@@ -10510,4 +19714,87 @@
   0x8825   GPSInfo                              GPS
 
+=head3 PanasonicRaw WBInfo Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    NumWBEntries                         int16u
+      1    WBType1                              int16u
+      2    WB_RBLevels1                         int16u[2]
+      4    WBType2                              int16u
+      5    WB_RBLevels2                         int16u[2]
+      7    WBType3                              int16u
+      8    WB_RBLevels3                         int16u[2]
+     10    WBType4                              int16u
+     11    WB_RBLevels4                         int16u[2]
+     13    WBType5                              int16u
+     14    WB_RBLevels5                         int16u[2]
+     16    WBType6                              int16u
+     17    WB_RBLevels6                         int16u[2]
+     19    WBType7                              int16u
+     20    WB_RBLevels7                         int16u[2]
+
+=head3 PanasonicRaw WBInfo2 Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    NumWBEntries                         int16u
+      1    WBType1                              int16u
+      2    WB_RGBLevels1                        int16u[3]
+      5    WBType2                              int16u
+      6    WB_RGBLevels2                        int16u[3]
+      9    WBType3                              int16u
+     10    WB_RGBLevels3                        int16u[3]
+     13    WBType4                              int16u
+     14    WB_RGBLevels4                        int16u[3]
+     17    WBType5                              int16u
+     18    WB_RGBLevels5                        int16u[3]
+     21    WBType6                              int16u
+     22    WB_RGBLevels6                        int16u[3]
+     25    WBType7                              int16u
+     26    WB_RGBLevels7                        int16u[3]
+
+=head3 PanasonicRaw DistortionInfo Tags
+
+Lens distortion correction information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0002   DistortionParam02                    int16s
+  0x0004   DistortionParam04                    int16s
+  0x0005   DistortionScale                      int16s
+    7.1    DistortionCorrection                 int16s & 0x0f
+  0x0008   DistortionParam08                    int16s
+  0x0009   DistortionParam09                    int16s
+  0x000b   DistortionParam11                    int16s
+  0x000c   DistortionN?                         int16s
+
+=head3 PanasonicRaw CameraIFD Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  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
+  0x1301   ApertureValue                        no
+  0x1302   ShutterSpeedValue                    no
+  0x1303   SensitivityValue                     no
+  0x1305   HighISOMode                          no
+  0x1412   FacesDetected                        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
 
@@ -10519,22 +19806,36 @@
   ------               --------                 --------
   'Header'             Header                   SigmaRaw Header
+  'Header4'            Header4                  SigmaRaw Header4
   'HeaderExt'          HeaderExt                SigmaRaw HeaderExt
-  'IMA2'               PreviewImage             N
-                       JpgFromRaw               N
-  'IMAG'               PreviewImage             N
+  'IMA2'               PreviewImage             no
+                       JpgFromRaw               no
+  'IMAG'               PreviewImage             no
   'PROP'               Properties               SigmaRaw Properties
 
 =head3 SigmaRaw Header Tags
 
+Information extracted from the header of an X3F file.
+
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0001   FileVersion                          N
-  0x0002   ImageUniqueID                        N
-  0x0006   MarkBits                             N
-  0x0007   ImageWidth                           N
-  0x0008   ImageHeight                          N
-  0x0009   Rotation                             N
-  0x000a   WhiteBalance                         N
-  0x0012   SceneCaptureType                     N
+  0x0001   FileVersion                          no
+  0x0002   ImageUniqueID                        no
+  0x0006   MarkBits                             no
+  0x0007   ImageWidth                           no
+  0x0008   ImageHeight                          no
+  0x0009   Rotation                             no
+  0x000a   WhiteBalance                         no
+  0x0012   SceneCaptureType                     no
+
+=head3 SigmaRaw Header4 Tags
+
+Header information for version 4.0 or greater X3F.
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    FileVersion                          no
+     10    ImageWidth                           no
+     11    ImageHeight                          no
+     12    Rotation                             no
 
 =head3 SigmaRaw HeaderExt Tags
@@ -10544,15 +19845,15 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   Unused                               N
-  0x0001   ExposureAdjust                       N
-  0x0002   Contrast                             N
-  0x0003   Shadow                               N
-  0x0004   Highlight                            N
-  0x0005   Saturation                           N
-  0x0006   Sharpness                            N
-  0x0007   RedAdjust                            N
-  0x0008   GreenAdjust                          N
-  0x0009   BlueAdjust                           N
-  0x000a   X3FillLight                          N
+  0x0000   Unused                               no
+  0x0001   ExposureAdjust                       no
+  0x0002   Contrast                             no
+  0x0003   Shadow                               no
+  0x0004   Highlight                            no
+  0x0005   Saturation                           no
+  0x0006   Sharpness                            no
+  0x0007   RedAdjust                            no
+  0x0008   GreenAdjust                          no
+  0x0009   BlueAdjust                           no
+  0x000a   X3FillLight                          no
 
 =head3 SigmaRaw Properties Tags
@@ -10560,65 +19861,107 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'AEMODE'             MeteringMode             N
-  'AFAREA'             AFArea                   N
-  'AFINFOCUS'          AFInFocus                N
-  'AFMODE'             FocusMode                N
-  'APERTURE'           FNumber                  N
-  'AP_DESC'            ApertureDisplayed        N
-  'BRACKET'            BracketShot              N
-  'BURST'              BurstShot                N
-  'CAMMANUF'           Make                     N
-  'CAMMODEL'           Model                    N
-  'CAMNAME'            CameraName               N
-  'CAMSERIAL'          SerialNumber             N
-  'CM_DESC'            SceneCaptureType         N
-  'COLORSPACE'         ColorSpace               N
-  'DRIVE'              DriveMode                N
-  'EVAL_STATE'         EvalState                N
-  'EXPCOMP'            ExposureCompensation     N
-  'EXPNET'             NetExposureCompensation  N
-  'EXPTIME'            IntegrationTime          N
-  'FIRMVERS'           FirmwareVersion          N
-  'FLASH'              FlashMode                N
-  'FLASHEXPCOMP'       FlashExpComp             N
-  'FLASHPOWER'         FlashPower               N
-  'FLASHTTLMODE'       FlashTTLMode             N
-  'FLASHTYPE'          FlashType                N
-  'FLENGTH'            FocalLength              N
-  'FLEQ35MM'           FocalLengthIn35mmFormat  N
-  'FOCUS'              Focus                    N
-  'IMAGEBOARDID'       ImageBoardID             N
-  'IMAGERBOARDID'      ImagerBoardID            N
-  'IMAGERTEMP'         SensorTemperature        N
-  'ISO'                ISO                      N
-  'LENSARANGE'         LensApertureRange        N
-  'LENSFRANGE'         LensFocalRange           N
-  'LENSMODEL'          LensType                 N
-  'PMODE'              ExposureProgram          N
-  'RESOLUTION'         Quality                  N
-  'SENSORID'           SensorID                 N
-  'SHUTTER'            ExposureTime             N
-  'SH_DESC'            ShutterSpeedDisplayed    N
-  'TIME'               DateTimeOriginal         N
-  'VERSION_BF'         VersionBF                N
-  'WB_DESC'            WhiteBalance             N
+  'AEMODE'             MeteringMode             no
+  'AFAREA'             AFArea                   no
+  'AFINFOCUS'          AFInFocus                no
+  'AFMODE'             FocusMode                no
+  'APERTURE'           FNumber                  no
+  'AP_DESC'            ApertureDisplayed        no
+  'BRACKET'            BracketShot              no
+  'BURST'              BurstShot                no
+  'CAMMANUF'           Make                     no
+  'CAMMODEL'           Model                    no
+  'CAMNAME'            CameraName               no
+  'CAMSERIAL'          SerialNumber             no
+  'CM_DESC'            SceneCaptureType         no
+  'COLORSPACE'         ColorSpace               no
+  'DRIVE'              DriveMode                no
+  'EVAL_STATE'         EvalState                no
+  'EXPCOMP'            ExposureCompensation     no
+  'EXPNET'             NetExposureCompensation  no
+  'EXPTIME'            IntegrationTime          no
+  'FIRMVERS'           FirmwareVersion          no
+  'FLASH'              FlashMode                no
+  'FLASHEXPCOMP'       FlashExpComp             no
+  'FLASHPOWER'         FlashPower               no
+  'FLASHTTLMODE'       FlashTTLMode             no
+  'FLASHTYPE'          FlashType                no
+  'FLENGTH'            FocalLength              no
+  'FLEQ35MM'           FocalLengthIn35mmFormat  no
+  'FOCUS'              Focus                    no
+  'IMAGEBOARDID'       ImageBoardID             no
+  'IMAGERBOARDID'      ImagerBoardID            no
+  'IMAGERTEMP'         SensorTemperature        no
+  'ISO'                ISO                      no
+  'LENSARANGE'         LensApertureRange        no
+  'LENSFRANGE'         LensFocalRange           no
+  'LENSMODEL'          LensType                 no
+  'PMODE'              ExposureProgram          no
+  'RESOLUTION'         Quality                  no
+  'SENSORID'           SensorID                 no
+  'SHUTTER'            ExposureTime             no
+  'SH_DESC'            ShutterSpeedDisplayed    no
+  'TIME'               DateTimeOriginal         no
+  'VERSION_BF'         VersionBF                no
+  'WB_DESC'            WhiteBalance             no
+
+=head2 Lytro Tags
+
+Tag definitions for Lytro Light Field Picture (LFP) files.  ExifTool
+extracts the full JSON metadata blocks, as well as breaking them down into
+individual tags.  All available tags are extracted from the JSON metadata,
+even if they don't appear in the table below.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AccelerometerTime                             no
+  AccelerometerX                                no
+  AccelerometerY                                no
+  AccelerometerZ                                no
+  CameraType                                    no
+  DateTimeOriginal                              no
+  EmbeddedImage                                 no
+  ExposureTime                                  no
+  FNumber                                       no
+  FirmwareVersion                               no
+  FocalLength                                   no
+  FocalPlaneXResolution                         no
+  FrameExposureTime                             no
+  ISO                                           no
+  ImageLimitExposureBias                        no
+  ImageModulationExposureBias                   no
+  JSONMetadata                                  no+
+  LensTemperature                               no
+  Make                                          no
+  Model                                         no
+  Orientation                                   no
+  SensorSerialNumber                            no
+  SerialNumber                                  no
+  SocTemperature                                no
 
 =head2 JFIF Tags
 
 The following information is extracted from the JPEG JFIF header.  See
-L<http://www.jpeg.org/public/jfif.pdf> for the JFIF 1.02 specification.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    JFIFVersion                          N
-      2    ResolutionUnit                       int8u
-      3    XResolution                          int16u
-      5    YResolution                          int16u
+L<https://www.w3.org/Graphics/JPEG/jfif3.pdf> for the JFIF 1.02
+specification.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    JFIFVersion                          no:
+      2    ResolutionUnit                       int8u:
+      3    XResolution                          int16u:
+      5    YResolution                          int16u:
+      7    ThumbnailWidth                       no
+      8    ThumbnailHeight                      no
+      9    ThumbnailTIFF                        no
 
 =head3 JFIF Extension Tags
 
+Thumbnail images extracted from the JFXX segment.
+
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0010   ThumbnailImage                       N
+  0x0010   ThumbnailImage                       no
+  0x0011   ThumbnailTIFF                        no
+  0x0013   ThumbnailTIFF                        no
 
 =head2 FlashPix Tags
@@ -10630,5 +19973,6 @@
 popular.  However, some of the structures used in FlashPix streams are part
 of the EXIF specification, and are still being used in the APP2 FPXR segment
-of JPEG images by some Kodak and Hewlett-Packard digital cameras.
+of JPEG images by some digital cameras from manufacturers such as FujiFilm,
+Hewlett-Packard, Kodak and Sanyo.
 
 ExifTool extracts FlashPix information from both FPX images and the APP2
@@ -10637,5 +19981,6 @@
 (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.
@@ -10652,19 +19997,22 @@
   "\x05Image Info"                 ImageInfo    FlashPix ImageInfo
   "\x05Operation"                  Operation    FlashPix Operation
-  "\x05Screen Nail"                ScreenNail   N
+  "\x05Screen Nail"                ScreenNail   no
   "\x05SummaryInformation"         SummaryInfo  FlashPix SummaryInfo
   "\x05Transform"                  Transform    FlashPix Transform
-  'Audio Stream'                   AudioStream  N
+  'Audio Stream'                   AudioStream  no
   'Contents'                       Contents     XMP
-  'Current User'                   CurrentUser  N
+  'Current User'                   CurrentUser  no
   'ICC Profile 0001'               ICC_Profile  ICC_Profile
+  'Preview'                        PreviewImage no
+  'Property'                       PreviewInfo  FlashPix PreviewInfo
   'Subimage 0000 Header'           SubimageHdr  FlashPix SubimageHdr
+  'WordDocument'                   WordDocument FlashPix WordDocument
 
 =head3 FlashPix CompObj Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    CompObjUserTypeLen                   N
-      1    CompObjUserType                      N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    CompObjUserTypeLen                   no
+      1    CompObjUserType                      no
 
 =head3 FlashPix AudioInfo Tags
@@ -10678,17 +20026,17 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  0x10000      DataObjectID                     N
-  0x10002      LockedPropertyList               N
-  0x10003      DataObjectTitle                  N
-  0x10004      LastModifier                     N
-  0x10005      RevisionNumber                   N
-  0x10006      DataCreateDate                   N
-  0x10007      DataModifyDate                   N
-  0x10008      CreatingApplication              N
-  0x10100      DataObjectStatus                 N
-  0x10101      CreatingTransform                N
-  0x10102      UsingTransforms                  N
-  0x10000000   CachedImageHeight                N
-  0x10000001   CachedImageWidth                 N
+  0x10000      DataObjectID                     no
+  0x10002      LockedPropertyList               no
+  0x10003      DataObjectTitle                  no
+  0x10004      LastModifier                     no
+  0x10005      RevisionNumber                   no
+  0x10006      DataCreateDate                   no
+  0x10007      DataModifyDate                   no
+  0x10008      CreatingApplication              no
+  0x10100      DataObjectStatus                 no
+  0x10101      CreatingTransform                no
+  0x10102      UsingTransforms                  no
+  0x10000000   CachedImageHeight                no
+  0x10000001   CachedImageWidth                 no
 
 =head3 FlashPix DocumentInfo Tags
@@ -10701,25 +20049,25 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  0x0002               Category                 N
-  0x0003               PresentationTarget       N
-  0x0004               Bytes                    N
-  0x0005               Lines                    N
-  0x0006               Paragraphs               N
-  0x0007               Slides                   N
-  0x0008               Notes                    N
-  0x0009               HiddenSlides             N
-  0x000a               MMClips                  N
-  0x000b               ScaleCrop                N
-  0x000c               HeadingPairs             N
-  0x000d               TitleOfParts             N
-  0x000e               Manager                  N
-  0x000f               Company                  N
-  0x0010               LinksUpToDate            N
-  0x0011               CharCountWithSpaces      N
-  0x0013               SharedDoc                N
-  0x0016               HyperlinksChanged        N
-  0x0017               AppVersion               N
-  '_PID_HLINKS'        Hyperlinks               N
-  '_PID_LINKBASE'      HyperlinkBase            N
+  0x0002               Category                 no
+  0x0003               PresentationTarget       no
+  0x0004               Bytes                    no
+  0x0005               Lines                    no
+  0x0006               Paragraphs               no
+  0x0007               Slides                   no
+  0x0008               Notes                    no
+  0x0009               HiddenSlides             no
+  0x000a               MMClips                  no
+  0x000b               ScaleCrop                no
+  0x000c               HeadingPairs             no
+  0x000d               TitleOfParts             no
+  0x000e               Manager                  no
+  0x000f               Company                  no
+  0x0010               LinksUpToDate            no
+  0x0011               CharCountWithSpaces      no
+  0x0013               SharedDoc                no
+  0x0016               HyperlinksChanged        no
+  0x0017               AppVersion               no
+  '_PID_HLINKS'        Hyperlinks               no
+  '_PID_LINKBASE'      HyperlinkBase            no
 
 =head3 FlashPix Extensions Tags
@@ -10727,19 +20075,19 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  0x0001       ExtensionName                    N
-  0x0002       ExtensionClassID                 N
-  0x0003       ExtensionPersistence             N
-  0x0004       ExtensionCreateDate              N
-  0x0005       ExtensionModifyDate              N
-  0x0006       CreatingApplication              N
-  0x0007       ExtensionDescription             N
-  0x1000       Storage-StreamPathname           N
-  0x2000       FlashPixStreamPathname           N
-  0x2001       FlashPixStreamFieldOffset        N
-  0x3000       PropertySetPathname              N
-  0x3001       PropertySetIDCodes               N
-  0x3002       PropertyVectorElements           N
-  0x4000       SubimageResolutions              N
-  0x10000000   UsedExtensionNumbers             N
+  0x0001       ExtensionName                    no
+  0x0002       ExtensionClassID                 no
+  0x0003       ExtensionPersistence             no
+  0x0004       ExtensionCreateDate              no
+  0x0005       ExtensionModifyDate              no
+  0x0006       CreatingApplication              no
+  0x0007       ExtensionDescription             no
+  0x1000       Storage-StreamPathname           no
+  0x2000       FlashPixStreamPathname           no
+  0x2001       FlashPixStreamFieldOffset        no
+  0x3000       PropertySetPathname              no
+  0x3001       PropertySetIDCodes               no
+  0x3002       PropertyVectorElements           no
+  0x4000       SubimageResolutions              no
+  0x10000000   UsedExtensionNumbers             no
 
 =head3 FlashPix GlobalInfo Tags
@@ -10747,11 +20095,11 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x10002  LockedPropertyList                   N
-  0x10003  TransformedImageTitle                N
-  0x10004  LastModifier                         N
-  0x10100  VisibleOutputs                       N
-  0x10101  MaximumImageIndex                    N
-  0x10102  MaximumTransformIndex                N
-  0x10103  MaximumOperationIndex                N
+  0x10002  LockedPropertyList                   no
+  0x10003  TransformedImageTitle                no
+  0x10004  LastModifier                         no
+  0x10100  VisibleOutputs                       no
+  0x10101  MaximumImageIndex                    no
+  0x10102  MaximumTransformIndex                no
+  0x10103  MaximumOperationIndex                no
 
 =head3 FlashPix Image Tags
@@ -10759,19 +20107,19 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  0x1000000    NumberOfResolutions              N
-  0x1000002    ImageWidth                       N
-  0x1000003    ImageHeight                      N
-  0x1000004    DefaultDisplayHeight             N
-  0x1000005    DefaultDisplayWidth              N
-  0x1000006    DisplayUnits                     N
-  0x2000000    SubimageWidth                    N
-  0x2000001    SubimageHeight                   N
-  0x2000002    SubimageColor                    N
-  0x2000003    SubimageNumericalFormat          N
-  0x2000004    DecimationMethod                 N
-  0x2000005    DecimationPrefilterWidth         N
-  0x2000007    SubimageICC_Profile              N
-  0x3000001    JPEGTables                       N
-  0x3000002    MaxJPEGTableIndex                N
+  0x1000000    NumberOfResolutions              no
+  0x1000002    ImageWidth                       no
+  0x1000003    ImageHeight                      no
+  0x1000004    DefaultDisplayHeight             no
+  0x1000005    DefaultDisplayWidth              no
+  0x1000006    DisplayUnits                     no
+  0x2000000    SubimageWidth                    no
+  0x2000001    SubimageHeight                   no
+  0x2000002    SubimageColor                    no
+  0x2000003    SubimageNumericalFormat          no
+  0x2000004    DecimationMethod                 no
+  0x2000005    DecimationPrefilterWidth         no
+  0x2000007    SubimageICC_Profile              no
+  0x3000001    JPEGTables                       no
+  0x3000002    MaxJPEGTableIndex                no
 
 =head3 FlashPix ImageInfo Tags
@@ -10779,73 +20127,73 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  0x21000000   FileSource                       N
-  0x21000001   SceneType                        N
-  0x21000002   CreationPathVector               N
-  0x21000003   SoftwareRelease                  N
-  0x21000004   UserDefinedID                    N
-  0x21000005   SharpnessApproximation           N
-  0x22000000   Copyright                        N
-  0x22000001   OriginalImageBroker              N
-  0x22000002   DigitalImageBroker               N
-  0x22000003   Authorship                       N
-  0x22000004   IntellectualPropertyNotes        N
-  0x23000000   TestTarget                       N
-  0x23000002   GroupCaption                     N
-  0x23000003   CaptionText                      N
-  0x23000004   People                           N
-  0x23000007   Things                           N
-  0x2300000a   DateTimeOriginal                 N
-  0x2300000b   Events                           N
-  0x2300000c   Places                           N
-  0x2300000f   ContentDescriptionNotes          N
-  0x24000000   Make                             N
-  0x24000001   Model                            N
-  0x24000002   SerialNumber                     N
-  0x25000000   CreateDate                       N
-  0x25000001   ExposureTime                     N
-  0x25000002   FNumber                          N
-  0x25000003   ExposureProgram                  N
-  0x25000004   BrightnessValue                  N
-  0x25000005   ExposureCompensation             N
-  0x25000006   SubjectDistance                  N
-  0x25000007   MeteringMode                     N
-  0x25000008   LightSource                      N
-  0x25000009   FocalLength                      N
-  0x2500000a   MaxApertureValue                 N
-  0x2500000b   Flash                            N
-  0x2500000c   FlashEnergy                      N
-  0x2500000d   FlashReturn                      N
-  0x2500000e   BackLight                        N
-  0x2500000f   SubjectLocation                  N
-  0x25000010   ExposureIndex                    N
-  0x25000011   SpecialEffectsOpticalFilter      N
-  0x25000012   PerPictureNotes                  N
-  0x26000000   SensingMethod                    N
-  0x26000001   FocalPlaneXResolution            N
-  0x26000002   FocalPlaneYResolution            N
-  0x26000003   FocalPlaneResolutionUnit         N
-  0x26000004   SpatialFrequencyResponse         N
-  0x26000005   CFAPattern                       N
-  0x26000007   ISO                              N
-  0x26000008   Opto-ElectricConvFactor          N
-  0x27000000   FilmBrand                        N
-  0x27000001   FilmCategory                     N
-  0x27000002   FilmSize                         N
-  0x27000003   FilmRollNumber                   N
-  0x27000004   FilmFrameNumber                  N
-  0x28000000   ScannerMake                      N
-  0x28000001   ScannerModel                     N
-  0x28000002   ScannerSerialNumber              N
-  0x28000003   ScanSoftware                     N
-  0x28000004   ScanSoftwareRevisionDate         N
-  0x28000005   ServiceOrganizationName          N
-  0x28000006   ScanOperatorID                   N
-  0x28000008   ScanDate                         N
-  0x28000009   ModifyDate                       N
-  0x2800000a   ScannerPixelSize                 N
-  0x29000000   OriginalScannedImageSize         N
-  0x29000001   OriginalDocumentSize             N
-  0x29000002   OriginalMedium                   N
-  0x29000003   TypeOfOriginal                   N
+  0x21000000   FileSource                       no
+  0x21000001   SceneType                        no
+  0x21000002   CreationPathVector               no
+  0x21000003   SoftwareRelease                  no
+  0x21000004   UserDefinedID                    no
+  0x21000005   SharpnessApproximation           no
+  0x22000000   Copyright                        no
+  0x22000001   OriginalImageBroker              no
+  0x22000002   DigitalImageBroker               no
+  0x22000003   Authorship                       no
+  0x22000004   IntellectualPropertyNotes        no
+  0x23000000   TestTarget                       no
+  0x23000002   GroupCaption                     no
+  0x23000003   CaptionText                      no
+  0x23000004   People                           no
+  0x23000007   Things                           no
+  0x2300000a   DateTimeOriginal                 no
+  0x2300000b   Events                           no
+  0x2300000c   Places                           no
+  0x2300000f   ContentDescriptionNotes          no
+  0x24000000   Make                             no
+  0x24000001   Model                            no
+  0x24000002   SerialNumber                     no
+  0x25000000   CreateDate                       no
+  0x25000001   ExposureTime                     no
+  0x25000002   FNumber                          no
+  0x25000003   ExposureProgram                  no
+  0x25000004   BrightnessValue                  no
+  0x25000005   ExposureCompensation             no
+  0x25000006   SubjectDistance                  no
+  0x25000007   MeteringMode                     no
+  0x25000008   LightSource                      no
+  0x25000009   FocalLength                      no
+  0x2500000a   MaxApertureValue                 no
+  0x2500000b   Flash                            no
+  0x2500000c   FlashEnergy                      no
+  0x2500000d   FlashReturn                      no
+  0x2500000e   BackLight                        no
+  0x2500000f   SubjectLocation                  no
+  0x25000010   ExposureIndex                    no
+  0x25000011   SpecialEffectsOpticalFilter      no
+  0x25000012   PerPictureNotes                  no
+  0x26000000   SensingMethod                    no
+  0x26000001   FocalPlaneXResolution            no
+  0x26000002   FocalPlaneYResolution            no
+  0x26000003   FocalPlaneResolutionUnit         no
+  0x26000004   SpatialFrequencyResponse         no
+  0x26000005   CFAPattern                       no
+  0x26000007   ISO                              no
+  0x26000008   Opto-ElectricConvFactor          no
+  0x27000000   FilmBrand                        no
+  0x27000001   FilmCategory                     no
+  0x27000002   FilmSize                         no
+  0x27000003   FilmRollNumber                   no
+  0x27000004   FilmFrameNumber                  no
+  0x28000000   ScannerMake                      no
+  0x28000001   ScannerModel                     no
+  0x28000002   ScannerSerialNumber              no
+  0x28000003   ScanSoftware                     no
+  0x28000004   ScanSoftwareRevisionDate         no
+  0x28000005   ServiceOrganizationName          no
+  0x28000006   ScanOperatorID                   no
+  0x28000008   ScanDate                         no
+  0x28000009   ModifyDate                       no
+  0x2800000a   ScannerPixelSize                 no
+  0x29000000   OriginalScannedImageSize         no
+  0x29000001   OriginalDocumentSize             no
+  0x29000002   OriginalMedium                   no
+  0x29000003   TypeOfOriginal                   no
 
 =head3 FlashPix Operation Tags
@@ -10853,5 +20201,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x10000  OperationID                          N
+  0x10000  OperationID                          no
 
 =head3 FlashPix SummaryInfo Tags
@@ -10862,25 +20210,27 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  0x0000       Dictionary                       N
-  0x0001       CodePage                         N
-  0x0002       Title                            N
-  0x0003       Subject                          N
-  0x0004       Author                           N
-  0x0005       Keywords                         N
-  0x0006       Comments                         N
-  0x0007       Template                         N
-  0x0008       LastModifiedBy                   N
-  0x0009       RevisionNumber                   N
-  0x000a       TotalEditTime                    N
-  0x000b       LastPrinted                      N
-  0x000c       CreateDate                       N
-  0x000d       ModifyDate                       N
-  0x000e       Pages                            N
-  0x000f       Words                            N
-  0x0010       Characters                       N
-  0x0011       ThumbnailClip                    N
-  0x0012       Software                         N
-  0x0013       Security                         N
-  0x80000000   LocaleIndicator                  N
+  0x0000       Dictionary                       no
+  0x0001       CodePage                         no
+  0x0002       Title                            no
+  0x0003       Subject                          no
+  0x0004       Author                           no
+  0x0005       Keywords                         no
+  0x0006       Comments                         no
+  0x0007       Template                         no
+  0x0008       LastModifiedBy                   no
+  0x0009       RevisionNumber                   no
+  0x000a       TotalEditTime                    no
+  0x000b       LastPrinted                      no
+  0x000c       CreateDate                       no
+  0x000d       ModifyDate                       no
+  0x000e       Pages                            no
+  0x000f       Words                            no
+  0x0010       Characters                       no
+  0x0011       ThumbnailClip                    no
+  0x0012       Software                         no
+  0x0013       Security                         no
+  0x0022       CreatedBy                        no
+  0x0023       DocumentID                       no
+  0x80000000   LocaleIndicator                  no
 
 =head3 FlashPix Transform Tags
@@ -10888,62 +20238,114 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  0x10000      TransformNodeID                  N
-  0x10001      OperationClassID                 N
-  0x10002      LockedPropertyList               N
-  0x10003      TransformTitle                   N
-  0x10004      LastModifier                     N
-  0x10005      RevisionNumber                   N
-  0x10006      TransformCreateDate              N
-  0x10007      TransformModifyDate              N
-  0x10008      CreatingApplication              N
-  0x10100      InputDataObjectList              N
-  0x10101      OutputDataObjectList             N
-  0x10102      OperationNumber                  N
-  0x10000000   ResultAspectRatio                N
-  0x10000001   RectangleOfInterest              N
-  0x10000002   Filtering                        N
-  0x10000003   SpatialOrientation               N
-  0x10000004   ColorTwistMatrix                 N
-  0x10000005   ContrastAdjustment               N
+  0x10000      TransformNodeID                  no
+  0x10001      OperationClassID                 no
+  0x10002      LockedPropertyList               no
+  0x10003      TransformTitle                   no
+  0x10004      LastModifier                     no
+  0x10005      RevisionNumber                   no
+  0x10006      TransformCreateDate              no
+  0x10007      TransformModifyDate              no
+  0x10008      CreatingApplication              no
+  0x10100      InputDataObjectList              no
+  0x10101      OutputDataObjectList             no
+  0x10102      OperationNumber                  no
+  0x10000000   ResultAspectRatio                no
+  0x10000001   RectangleOfInterest              no
+  0x10000002   Filtering                        no
+  0x10000003   SpatialOrientation               no
+  0x10000004   ColorTwistMatrix                 no
+  0x10000005   ContrastAdjustment               no
+
+=head3 FlashPix PreviewInfo Tags
+
+Preview information written by some FujiFilm models.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     13    PreviewImageWidth                    no
+     23    PreviewImageHeight                   no
 
 =head3 FlashPix SubimageHdr Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    SubimageWidth                        N
-      2    SubimageHeight                       N
-      3    SubimageTileCount                    N
-      4    SubimageTileWidth                    N
-      5    SubimageTileHeight                   N
-      6    NumChannels                          N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    SubimageWidth                        no
+      2    SubimageHeight                       no
+      3    SubimageTileCount                    no
+      4    SubimageTileWidth                    no
+      5    SubimageTileHeight                   no
+      6    NumChannels                          no
+
+=head3 FlashPix WordDocument Tags
+
+Tags extracted from the Microsoft Word document stream.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   Identification                       no
+  0x0003   LanguageCode                         no
+  0x0005   DocFlags                             no
+    9.1    System                               no
+    9.2    Word97                               no
+
+=head3 FlashPix DocTable Tags
+
+Tags extracted from the Microsoft Word document table.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CommentBy                                     no
+  DOP                                           FlashPix DOP
+  LastSavedBy                                   no
+  ModifyDate                                    no
+
+=head3 FlashPix DOP Tags
+
+Microsoft office document properties.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     20    CreateDate                           no
+     24    ModifyDate                           no
+     28    LastPrinted                          no
+     32    RevisionNumber                       no
+     34    TotalEditTime                        no
+     38    Words                                no
+     42    Characters                           no
+     46    Pages                                no
+     48    Paragraphs                           no
+     56    Lines                                no
 
 =head2 MPF Tags
 
 These tags are part of the CIPA Multi-Picture Format specification, and are
-found in the APP2 "MPF" segment of JPEG images.  See
-L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-007_E.pdf> for the
-official specification.
+found in the APP2 "MPF" segment of JPEG images.  MPImage data referenced
+from this segment is stored as a JPEG trailer.  The MPF tags are not
+writable, however the MPF segment may be deleted as a group (with "MPF:All")
+but then the JPEG trailer should also be deleted (with "Trailer:All").  See
+L<https://web.archive.org/web/20190713230858/http://www.cipa.jp/std/documents/e/DC-007_E.pdf>
+for the official specification.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0xb000   MPFVersion                           N
-  0xb001   NumberOfImages                       N
+  0xb000   MPFVersion                           no
+  0xb001   NumberOfImages                       no
   0xb002   MPImageList                          MPF MPImage
-  0xb003   ImageUIDList                         N
-  0xb004   TotalFrames                          N
-  0xb101   MPIndividualNum                      N
-  0xb201   PanOrientation                       N
-  0xb202   PanOverlapH                          N
-  0xb203   PanOverlapV                          N
-  0xb204   BaseViewpointNum                     N
-  0xb205   ConvergenceAngle                     N
-  0xb206   BaselineLength                       N
-  0xb207   VerticalDivergence                   N
-  0xb208   AxisDistanceX                        N
-  0xb209   AxisDistanceY                        N
-  0xb20a   AxisDistanceZ                        N
-  0xb20b   YawAngle                             N
-  0xb20c   PitchAngle                           N
-  0xb20d   RollAngle                            N
+  0xb003   ImageUIDList                         no
+  0xb004   TotalFrames                          no
+  0xb101   MPIndividualNum                      no
+  0xb201   PanOrientation                       no
+  0xb202   PanOverlapH                          no
+  0xb203   PanOverlapV                          no
+  0xb204   BaseViewpointNum                     no
+  0xb205   ConvergenceAngle                     no
+  0xb206   BaselineLength                       no
+  0xb207   VerticalDivergence                   no
+  0xb208   AxisDistanceX                        no
+  0xb209   AxisDistanceY                        no
+  0xb20a   AxisDistanceZ                        no
+  0xb20b   YawAngle                             no
+  0xb20c   PitchAngle                           no
+  0xb20d   RollAngle                            no
 
 =head3 MPF MPImage Tags
@@ -10954,63 +20356,1413 @@
 embedded images.
 
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+    0.1    MPImageFlags                         no
+    0.2    MPImageFormat                        no
+    0.3    MPImageType                          no
+      4    MPImageLength                        no
+      8    MPImageStart                         no
+     12    DependentImage1EntryNumber           no
+     14    DependentImage2EntryNumber           no
+
+=head2 Stim Tags
+
+These tags are part of the CIPA Stereo Still Image specification, and are
+found in the APP3 "Stim" segment of JPEG images.  See
+L<https://web.archive.org/web/20190718152459/http://www.cipa.jp/std/documents/e/DC-006_E.pdf>
+for the official specification.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   StimVersion                          no
+  0x0001   ApplicationData                      no
+  0x0002   ImageArrangement                     no
+  0x0003   ImageRotation                        no
+  0x0004   ScalingFactor                        no
+  0x0005   CropXSize                            no
+  0x0006   CropYSize                            no
+  0x0007   CropX                                Stim CropX
+  0x0008   CropY                                Stim CropY
+  0x0009   ViewType                             no
+  0x000a   RepresentativeImage                  no
+  0x000b   ConvergenceBaseImage                 no
+  0x000c   AssumedDisplaySize                   no
+  0x000d   AssumedDistanceView                  no
+  0x000e   RepresentativeDisparityNear          no
+  0x000f   RepresentativeDisparityFar           no
+  0x0010   InitialDisplayEffect                 no
+  0x0011   ConvergenceDistance                  no
+  0x0012   CameraArrangementInterval            no
+  0x0013   ShootingCount                        no
+
+=head3 Stim CropX Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    CropXCommonOffset                    no
+      2    CropXViewpointNumber                 no
+      3    CropXOffset                          no
+      7    CropXViewpointNumber2                no
+      8    CropXOffset2                         no
+
+=head3 Stim CropY Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    CropYCommonOffset                    no
+      2    CropYViewpointNumber                 no
+      3    CropYOffset                          no
+      7    CropYViewpointNumber2                no
+      8    CropYOffset2                         no
+
+=head2 Scalado Tags
+
+Tags extracted from the JPEG APP4 "SCALADO" segment found in images from
+HTC, LG and Samsung phones.  (Presumably written by Scalado mobile software,
+L<http://www.scalado.com/>.)
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'HGHT'   PreviewImageHeight                   no
+  'QUAL'   PreviewQuality                       no
+  'SPMO'   DataLength?                          no
+  'WDTH'   PreviewImageWidth                    no
+
+=head2 GoPro Tags
+
+=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 (-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
+  ------   --------                             --------
+  'ACCL'   Accelerometer                        no
+  'ALLD'   AutoLowLightDuration                 no
+  'ATTD'   Attitude                             no
+  'ATTR'   AttitudeTarget                       no
+  'AUDO'   AudioSetting                         no
+  'BPOS'   Controller?                          no
+  'CASN'   CameraSerialNumber                   no
+  'CSEN'   CoyoteSense                          no
+  'CYTS'   CoyoteStatus                         no
+  'DEVC'   DeviceContainer                      GoPro GPMF
+  'DVID'   DeviceID?                            no
+  'DVNM'   DeviceName                           no
+  'DZOM'   DigitalZoom                          no
+  'EISA'   ElectronicImageStabilization         no
+  'EMPT'   Empty?                               no
+  'ESCS'   EscapeStatus?                        no
+  'FACE'   FaceDetected                         no
+  'FCNM'   FaceNumbers                          no
+  'FMWR'   FirmwareVersion                      no
+  'FWVS'   OtherFirmware                        no
+  'GLPI'   GPSPos                               GoPro GLPI
+  'GPRI'   GPSRaw?                              GoPro GPRI
+  'GPS5'   GPSInfo                              GoPro GPS5
+  'GPSF'   GPSMeasureMode                       no
+  'GPSP'   GPSHPositioningError                 no
+  'GPSU'   GPSDateTime                          no
+  'GYRO'   Gyroscope                            no
+  'ISOE'   ISOSpeeds                            no
+  'ISOG'   ImageSensorGain                      no
+  'KBAT'   BatteryStatus                        GoPro KBAT
+  'LNED'   LocalPositionNED                     no
+  'MAGN'   Magnetometer                         no
+  'MINF'   Model                                no
+  'OREN'   AutoRotation                         no
+  'PHDR'   HDRSetting                           no
+  'PIMN'   AutoISOMin                           no
+  'PIMX'   AutoISOMax                           no
+  'PRES'   PhotoResolution                      no
+  'PRTN'   ProTune                              no
+  'PTCL'   ColorMode                            no
+  'PTEV'   ExposureCompensation                 no
+  'PTSH'   Sharpness                            no
+  'PTWB'   WhiteBalance                         no
+  'RATE'   Rate                                 no
+  'RMRK'   Comments                             no
+  'SCAL'   ScaleFactor?                         no
+  'SCPR'   ScaledPressure                       no
+  'SHUT'   ExposureTimes                        no
+  'SIMU'   ScaledIMU                            no
+  'SIUN'   SIUnits?                             no
+  'STMP'   TimeStamp                            no
+  'STNM'   StreamName?                          no
+  'STRM'   NestedSignalStream                   GoPro GPMF
+  'SYST'   SystemTime                           no
+  'TMPC'   CameraTemperature                    no
+  'TSMP'   TotalSamples?                        no
+  'TYPE'   StructureType?                       no
+  'UNIT'   Units?                               no
+  'VERS'   MetadataVersion                      no
+  'VFOV'   FieldOfView                          no
+  'VFRH'   VisualFlightRulesHUD                 no
+  'WBAL'   ColorTemperatures                    no
+  'WRGB'   WhiteBalanceRGB                      no
+
+=head3 GoPro GLPI Tags
+
    Index   Tag Name                             Writable
    -----   --------                             --------
-    0.1    MPImageFlags                         N
-    0.2    MPImageFormat                        N
-    0.3    MPImageType                          N
-      4    MPImageLength                        N
-      8    MPImageStart                         N
-     12    DependentImage1EntryNumber           N
-     14    DependentImage2EntryNumber           N
-
-=head2 Stim Tags
-
-These tags are part of the CIPA Stereo Still Image specification, and are
-found in the APP3 "Stim" segment of JPEG images.  See
-L<http://www.cipa.jp/english/hyoujunka/kikaku/pdf/DC-006_E.pdf> for the
-official specification.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  0x0000   StimVersion                          N
-  0x0001   ApplicationData                      N
-  0x0002   ImageArrangement                     N
-  0x0003   ImageRotation                        N
-  0x0004   ScalingFactor                        N
-  0x0005   CropXSize                            N
-  0x0006   CropYSize                            N
-  0x0007   CropX                                Stim CropX
-  0x0008   CropY                                Stim CropY
-  0x0009   ViewType                             N
-  0x000a   RepresentativeImage                  N
-  0x000b   ConvergenceBaseImage                 N
-  0x000c   AssumedDisplaySize                   N
-  0x000d   AssumedDistanceView                  N
-  0x000e   RepresentativeDisparityNear          N
-  0x000f   RepresentativeDisparityFar           N
-  0x0010   InitialDisplayEffect                 N
-  0x0011   ConvergenceDistance                  N
-  0x0012   CameraArrangementInterval            N
-  0x0013   ShootingCount                        N
-
-=head3 Stim CropX Tags
+      0    GPSDateTime                          no
+      1    GPSLatitude                          no
+      2    GPSLongitude                         no
+      3    GPSAltitude                          no
+      5    GPSSpeedX                            no
+      6    GPSSpeedY                            no
+      7    GPSSpeedZ                            no
+      8    GPSTrack                             no
+
+=head3 GoPro GPRI Tags
 
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    CropXCommonOffset                    N
-      2    CropXViewpointNumber                 N
-      3    CropXOffset                          N
-      7    CropXViewpointNumber2                N
-      8    CropXOffset2                         N
-
-=head3 Stim CropY Tags
+      0    GPSDateTimeRaw                       no
+      1    GPSLatitudeRaw                       no
+      2    GPSLongitudeRaw                      no
+      3    GPSAltitudeRaw                       no
+      6    GPSSpeedRaw                          no
+      7    GPSTrackRaw                          no
+
+=head3 GoPro GPS5 Tags
 
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    CropYCommonOffset                    N
-      2    CropYViewpointNumber                 N
-      3    CropYOffset                          N
-      7    CropYViewpointNumber2                N
-      8    CropYOffset2                         N
+      0    GPSLatitude                          no
+      1    GPSLongitude                         no
+      2    GPSAltitude                          no
+      3    GPSSpeed                             no
+      4    GPSSpeed3D                           no
+
+=head3 GoPro KBAT Tags
+
+Battery status information found in GoPro Karma videos.
+
+   Index   Tag Name                             Writable
+   -----   --------                             --------
+      0    BatteryCurrent                       no
+      1    BatteryCapacity                      no
+      3    BatteryTemperature                   no
+      4    BatteryVoltage1                      no
+      5    BatteryVoltage2                      no
+      6    BatteryVoltage3                      no
+      7    BatteryVoltage4                      no
+      8    BatteryTime                          no
+     14    BatteryLevel                         no
+
+=head3 GoPro fdsc Tags
+
+Tags extracted from the MP4 "fdsc" timed metadata when the ExtractEmbedded
+(-ee) option is used.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    FirmwareVersion                      no
+     23    SerialNumber                         no
+     87    OtherSerialNumber                    no
+    102    Model                                no
+
+=head2 Qualcomm Tags
+
+The tags below have been observed in the JPEG APP7 "Qualcomm Camera
+Attributes" segment written by some cameras such as the HP iPAQ Voice
+Messenger.  ExifTool will extract any information found from this segment,
+even if it is not listed in this table.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AECAggressiveness                             no
+  AECCurrentExpIndex                            no
+  AECCurrentSensorLuma                          no
+  AECEnable                                     no
+  AECExposureIndexAdjStep                       no
+  AECHighLumaRegionCount                        no
+  AECHighLumaRegionThreshold                    no
+  AECIndoorIdx                                  no
+  AECLumaTarget                                 no
+  AECLumaTolerance                              no
+  AECMode                                       no
+  AECOdoorIdx                                   no
+  AECOutdoorBrightDiscarded                     no
+  AECOutdoorBrightEnable                        no
+  AECOutdoorBrightReduction                     no
+  AECOutdoorBrightThresholdHI                   no
+  AECOutdoorBrightThresholdLO                   no
+  AECOutdoorGammaIndex                          no
+  AECSnapshotDigitalGain                        no
+  AECSnapshotExposureTimeMs                     no
+  AECSnapshotLineCount                          no
+  AECSnapshotSensorGain                         no
+  AECVfeLuma                                    no
+  AFBoundary                                    no
+  AFCollectEndStat                              no
+  AFEnable                                      no
+  AFFarEnd                                      no
+  AFFineSrchPoints                              no
+  AFFineStep                                    no
+  AFFocusTime                                   no
+  AFGrossStep                                   no
+  AFMode                                        no
+  AFNearEnd                                     no
+  AFPosDefMacro                                 no
+  AFPosDefNorm                                  no
+  AFPosition                                    no
+  AFProcess                                     no
+  AFREnable                                     no
+  AFRFaster0ExpMod                              no
+  AFRFaster0Trigger                             no
+  AFRFaster1ExpMod                              no
+  AFRFaster1Trigger                             no
+  AFRFaster2ExpMod                              no
+  AFRFaster2Trigger                             no
+  AFRFaster3ExpMod                              no
+  AFRFaster3Trigger                             no
+  AFRFaster4ExpMod                              no
+  AFRFaster4Trigger                             no
+  AFRPossibleFrameCnt                           no
+  AFRSlower0ExpMod                              no
+  AFRSlower0Trigger                             no
+  AFRSlower1ExpMod                              no
+  AFRSlower1Trigger                             no
+  AFRSlower2ExpMod                              no
+  AFRSlower2Trigger                             no
+  AFRSlower3ExpMod                              no
+  AFRSlower3Trigger                             no
+  AFRSlower4ExpMod                              no
+  AFRSlower4Trigger                             no
+  AFResetLensAfterSnap                          no
+  AFStepsNearFar                                no
+  AFStepsNearInfinity                           no
+  AFTestMode                                    no
+  AFTracePositions00                            no
+  AFTracePositions01                            no
+  AFTracePositions02                            no
+  AFTracePositions03                            no
+  AFTracePositions04                            no
+  AFTracePositions05                            no
+  AFTracePositions06                            no
+  AFTracePositions07                            no
+  AFTracePositions08                            no
+  AFTracePositions09                            no
+  AFTracePositions10                            no
+  AFTracePositions11                            no
+  AFTracePositions12                            no
+  AFTracePositions13                            no
+  AFTracePositions14                            no
+  AFTracePositions15                            no
+  AFTracePositions16                            no
+  AFTracePositions17                            no
+  AFTracePositions18                            no
+  AFTracePositions19                            no
+  AFTracePositions20                            no
+  AFTracePositions21                            no
+  AFTracePositions22                            no
+  AFTracePositions23                            no
+  AFTracePositions24                            no
+  AFTracePositions25                            no
+  AFTracePositions26                            no
+  AFTracePositions27                            no
+  AFTracePositions28                            no
+  AFTracePositions29                            no
+  AFTracePositions30                            no
+  AFTracePositions31                            no
+  AFTracePositions32                            no
+  AFTracePositions33                            no
+  AFTracePositions34                            no
+  AFTracePositions35                            no
+  AFTracePositions36                            no
+  AFTracePositions37                            no
+  AFTracePositions38                            no
+  AFTracePositions39                            no
+  AFTracePositions40                            no
+  AFTracePositions41                            no
+  AFTracePositions42                            no
+  AFTracePositions43                            no
+  AFTracePositions44                            no
+  AFTracePositions45                            no
+  AFTracePositions46                            no
+  AFTracePositions47                            no
+  AFTracePositions48                            no
+  AFTracePositions49                            no
+  AFTraceStats00                                no
+  AFTraceStats01                                no
+  AFTraceStats02                                no
+  AFTraceStats03                                no
+  AFTraceStats04                                no
+  AFTraceStats05                                no
+  AFTraceStats06                                no
+  AFTraceStats07                                no
+  AFTraceStats08                                no
+  AFTraceStats09                                no
+  AFTraceStats10                                no
+  AFTraceStats11                                no
+  AFTraceStats12                                no
+  AFTraceStats13                                no
+  AFTraceStats14                                no
+  AFTraceStats15                                no
+  AFTraceStats16                                no
+  AFTraceStats17                                no
+  AFTraceStats18                                no
+  AFTraceStats19                                no
+  AFTraceStats20                                no
+  AFTraceStats21                                no
+  AFTraceStats22                                no
+  AFTraceStats23                                no
+  AFTraceStats24                                no
+  AFTraceStats25                                no
+  AFTraceStats26                                no
+  AFTraceStats27                                no
+  AFTraceStats28                                no
+  AFTraceStats29                                no
+  AFTraceStats30                                no
+  AFTraceStats31                                no
+  AFTraceStats32                                no
+  AFTraceStats33                                no
+  AFTraceStats34                                no
+  AFTraceStats35                                no
+  AFTraceStats36                                no
+  AFTraceStats37                                no
+  AFTraceStats38                                no
+  AFTraceStats39                                no
+  AFTraceStats40                                no
+  AFTraceStats41                                no
+  AFTraceStats42                                no
+  AFTraceStats43                                no
+  AFTraceStats44                                no
+  AFTraceStats45                                no
+  AFTraceStats46                                no
+  AFTraceStats47                                no
+  AFTraceStats48                                no
+  AFTraceStats49                                no
+  AFUndershootProtect                           no
+  AFVfeHorzOffset                               no
+  AFVfeHorzWidth                                no
+  AFVfeMetricMax                                no
+  AFVfeVertHeight                               no
+  AFVfeVertOffset                               no
+  ASF3EdgeDetect                                no
+  ASF3EdgeFilterA11                             no
+  ASF3EdgeFilterA12                             no
+  ASF3EdgeFilterA13                             no
+  ASF3EdgeFilterA21                             no
+  ASF3EdgeFilterA22                             no
+  ASF3EdgeFilterA23                             no
+  ASF3EdgeFilterA31                             no
+  ASF3EdgeFilterA32                             no
+  ASF3EdgeFilterA33                             no
+  ASF3Enable                                    no
+  ASF3LowerThreshold                            no
+  ASF3NoiseFilterA11                            no
+  ASF3NoiseFilterA12                            no
+  ASF3NoiseFilterA13                            no
+  ASF3NoiseFilterA21                            no
+  ASF3NoiseFilterA22                            no
+  ASF3NoiseFilterA23                            no
+  ASF3NoiseFilterA31                            no
+  ASF3NoiseFilterA32                            no
+  ASF3NoiseFilterA33                            no
+  ASF3UpperThreshold                            no
+  ASF5BrtLoThres                                no
+  ASF5BrtShrpDegF1                              no
+  ASF5BrtShrpDegF2                              no
+  ASF5BrtSmthPercent                            no
+  ASF5BrtUpThres                                no
+  ASF5Enable                                    no
+  ASF5ExposureIndex1                            no
+  ASF5ExposureIndex2                            no
+  ASF5Filter1A11                                no
+  ASF5Filter1A12                                no
+  ASF5Filter1A13                                no
+  ASF5Filter1A14                                no
+  ASF5Filter1A15                                no
+  ASF5Filter1A21                                no
+  ASF5Filter1A22                                no
+  ASF5Filter1A23                                no
+  ASF5Filter1A24                                no
+  ASF5Filter1A25                                no
+  ASF5Filter1A31                                no
+  ASF5Filter1A32                                no
+  ASF5Filter1A33                                no
+  ASF5Filter1A34                                no
+  ASF5Filter1A35                                no
+  ASF5Filter1A41                                no
+  ASF5Filter1A42                                no
+  ASF5Filter1A43                                no
+  ASF5Filter1A44                                no
+  ASF5Filter1A45                                no
+  ASF5Filter1A51                                no
+  ASF5Filter1A52                                no
+  ASF5Filter1A53                                no
+  ASF5Filter1A54                                no
+  ASF5Filter1A55                                no
+  ASF5Filter2A11                                no
+  ASF5Filter2A12                                no
+  ASF5Filter2A13                                no
+  ASF5Filter2A14                                no
+  ASF5Filter2A15                                no
+  ASF5Filter2A21                                no
+  ASF5Filter2A22                                no
+  ASF5Filter2A23                                no
+  ASF5Filter2A24                                no
+  ASF5Filter2A25                                no
+  ASF5Filter2A31                                no
+  ASF5Filter2A32                                no
+  ASF5Filter2A33                                no
+  ASF5Filter2A34                                no
+  ASF5Filter2A35                                no
+  ASF5Filter2A41                                no
+  ASF5Filter2A42                                no
+  ASF5Filter2A43                                no
+  ASF5Filter2A44                                no
+  ASF5Filter2A45                                no
+  ASF5Filter2A51                                no
+  ASF5Filter2A52                                no
+  ASF5Filter2A53                                no
+  ASF5Filter2A54                                no
+  ASF5Filter2A55                                no
+  ASF5FilterMode                                no
+  ASF5LowLoThres                                no
+  ASF5LowShrpDegF1                              no
+  ASF5LowShrpDegF2                              no
+  ASF5LowSmthPrcnt                              no
+  ASF5LowUpThres                                no
+  ASF5LumaFilter00                              no
+  ASF5LumaFilter01                              no
+  ASF5LumaFilter02                              no
+  ASF5LumaFilter03                              no
+  ASF5LumaFilter04                              no
+  ASF5LumaFilter05                              no
+  ASF5LumaFilter06                              no
+  ASF5LumaFilter07                              no
+  ASF5LumaFilter08                              no
+  ASF5MaxExposureIndex                          no
+  ASF5NrmLoThres                                no
+  ASF5NrmShrpDegF1                              no
+  ASF5NrmShrpDegF2                              no
+  ASF5NrmSmthPrcnt                              no
+  ASF5NrmUpThres                                no
+  ASF5NrmizeFactor1                             no
+  ASF5NrmizeFactor2                             no
+  AWBAggressiveness                             no
+  AWBAgwGridDist2Thresh                         no
+  AWBAlgorithm                                  no
+  AWBAveBgRatio                                 no
+  AWBAveRgRatio                                 no
+  AWBBlueGainAdjRef1                            no
+  AWBBlueGainAdjRef2                            no
+  AWBBlueGainAdjRef3                            no
+  AWBBlueGainAdjRef4                            no
+  AWBBlueGainAdjRef5                            no
+  AWBBlueGainAdjRef6                            no
+  AWBBlueGainAdjRef7                            no
+  AWBBlueGainAdjRef8                            no
+  AWBBlueGainRef1                               no
+  AWBBlueGainRef2                               no
+  AWBBlueGainRef3                               no
+  AWBBlueGainRef4                               no
+  AWBBlueGainRef5                               no
+  AWBBlueGainRef6                               no
+  AWBBlueGainRef7                               no
+  AWBBlueGainRef8                               no
+  AWBCcBias                                     no
+  AWBCompactClusterR2                           no
+  AWBEnable                                     no
+  AWBGreenOffsetBg                              no
+  AWBGreenOffsetRg                              no
+  AWBIndoorSampleInfluence                      no
+  AWBLoVfeC1                                    no
+  AWBLoVfeC2                                    no
+  AWBLoVfeC3                                    no
+  AWBLoVfeC4                                    no
+  AWBLoVfeM1                                    no
+  AWBLoVfeM2                                    no
+  AWBLoVfeM3                                    no
+  AWBLoVfeM4                                    no
+  AWBLoVfeMaxY                                  no
+  AWBLoVfeMinY                                  no
+  AWBLowLigColCorEna                            no
+  AWBMaxBGain                                   no
+  AWBMaxGGain                                   no
+  AWBMaxRGain                                   no
+  AWBMinBGain                                   no
+  AWBMinGGain                                   no
+  AWBMinRGain                                   no
+  AWBNormVfeC1                                  no
+  AWBNormVfeC2                                  no
+  AWBNormVfeC3                                  no
+  AWBNormVfeC4                                  no
+  AWBNormVfeM1                                  no
+  AWBNormVfeM2                                  no
+  AWBNormVfeM3                                  no
+  AWBNormVfeM4                                  no
+  AWBNormVfeMaxY                                no
+  AWBNormVfeMinY                                no
+  AWBOudorVfeC1                                 no
+  AWBOudorVfeC2                                 no
+  AWBOudorVfeC3                                 no
+  AWBOudorVfeC4                                 no
+  AWBOudorVfeM1                                 no
+  AWBOudorVfeM2                                 no
+  AWBOudorVfeM3                                 no
+  AWBOudorVfeM4                                 no
+  AWBOudorVfeMaxY                               no
+  AWBOudorVfeMinY                               no
+  AWBOutdoorSampleInfluence                     no
+  AWBPrevWbBgain                                no
+  AWBPrevWbGgain                                no
+  AWBPrevWbRgain                                no
+  AWBRedGainAdjRef1                             no
+  AWBRedGainAdjRef2                             no
+  AWBRedGainAdjRef3                             no
+  AWBRedGainAdjRef4                             no
+  AWBRedGainAdjRef5                             no
+  AWBRedGainAdjRef6                             no
+  AWBRedGainAdjRef7                             no
+  AWBRedGainAdjRef8                             no
+  AWBRedGainRef1                                no
+  AWBRedGainRef2                                no
+  AWBRedGainRef3                                no
+  AWBRedGainRef4                                no
+  AWBRedGainRef5                                no
+  AWBRedGainRef6                                no
+  AWBRedGainRef7                                no
+  AWBRedGainRef8                                no
+  AWBSampleDecision                             no
+  AWBSnapshotBGain                              no
+  AWBSnapshotRGain                              no
+  AntiBadingPixelClk                            no
+  AntiBadingPixelClkPerLine                     no
+  AntibandingEnable                             no
+  BlckLvlEvenCols                               no
+  BlckLvlOddCols                                no
+  CamMclkHz                                     no
+  ChroSupChroThres1                             no
+  ChroSupChroThres2                             no
+  ChroSupLumaThres1                             no
+  ChroSupLumaThres2                             no
+  ChroSupLumaThres3                             no
+  ChroSupLumaThres4                             no
+  ChromSupress                                  no
+  ClipToAfRato                                  no
+  CurrResol                                     no
+  DayltConvChrmA_M                              no
+  DayltConvChrmA_P                              no
+  DayltConvChrmB_M                              no
+  DayltConvChrmB_P                              no
+  DayltConvChrmC_M                              no
+  DayltConvChrmC_P                              no
+  DayltConvChrmD_M                              no
+  DayltConvChrmD_P                              no
+  DayltConvChrmKCb                              no
+  DayltConvChrmKCr                              no
+  DayltConvLumaK                                no
+  DayltConvLumaV0                               no
+  DayltConvLumaV1                               no
+  DayltConvLumaV2                               no
+  DefConvChrmA_M                                no
+  DefConvChrmA_P                                no
+  DefConvChrmB_M                                no
+  DefConvChrmB_P                                no
+  DefConvChrmC_M                                no
+  DefConvChrmC_P                                no
+  DefConvChrmD_M                                no
+  DefConvChrmD_P                                no
+  DefConvChrmKCb                                no
+  DefConvChrmKCr                                no
+  DefConvLumaK                                  no
+  DefConvLumaV0                                 no
+  DefConvLumaV1                                 no
+  DefConvLumaV2                                 no
+  DefCorC0                                      no
+  DefCorC1                                      no
+  DefCorC2                                      no
+  DefCorC3                                      no
+  DefCorC4                                      no
+  DefCorC5                                      no
+  DefCorC6                                      no
+  DefCorC7                                      no
+  DefCorC8                                      no
+  DefCorK0                                      no
+  DefCorK1                                      no
+  DefCorK2                                      no
+  DefLumaGammaMode                              no
+  DefRgbGammaMode                               no
+  DefectPixCorEnable                            no
+  DefectPixMaxThresh                            no
+  DefectPixMinThresh                            no
+  DiscardFrstFrm                                no
+  FrmSkipPttrn                                  no
+  GammaEnable                                   no
+  HJREnable                                     no
+  HJRMaxNumFrames                               no
+  HJROneToTwoOffset                             no
+  HJRTextureThreshold                           no
+  HJR_NReductionFlat                            no
+  HJR_NReductionTexture                         no
+  IncandConvChrmA_M                             no
+  IncandConvChrmA_P                             no
+  IncandConvChrmB_M                             no
+  IncandConvChrmB_P                             no
+  IncandConvChrmC_M                             no
+  IncandConvChrmC_P                             no
+  IncandConvChrmD_M                             no
+  IncandConvChrmD_P                             no
+  IncandConvChrmKCb                             no
+  IncandConvChrmKCr                             no
+  IncandConvLumaK                               no
+  IncandConvLumaV0                              no
+  IncandConvLumaV1                              no
+  IncandConvLumaV2                              no
+  LADetect                                      no
+  LAEnable                                      no
+  MaxPrviewFps                                  no
+  MaxVideoFps                                   no
+  NghtshtFps                                    no
+  NightshotMode                                 no
+  OutlierDistance                               no
+  PclkInvert                                    no
+  PrviewFps                                     no
+  PrviewResol                                   no
+  R2ABlueCtbl00                                 no
+  R2ABlueCtbl01                                 no
+  R2ABlueCtbl02                                 no
+  R2ABlueCtbl03                                 no
+  R2ABlueCtbl04                                 no
+  R2ABlueCtbl05                                 no
+  R2ABlueCtbl06                                 no
+  R2ABlueCtbl07                                 no
+  R2ABlueCtbl08                                 no
+  R2ABlueCtbl09                                 no
+  R2ABlueCtbl10                                 no
+  R2ABlueCtbl11                                 no
+  R2ABlueCtbl12                                 no
+  R2ABlueCtbl13                                 no
+  R2ABlueCtbl14                                 no
+  R2ABlueCtbl15                                 no
+  R2ABlueCtbl16                                 no
+  R2ABlueCtbl17                                 no
+  R2ABlueCtbl18                                 no
+  R2ABlueCtbl19                                 no
+  R2ABlueCtbl20                                 no
+  R2ABlueCtbl21                                 no
+  R2ABlueCtbl22                                 no
+  R2ABlueCtbl23                                 no
+  R2ABlueCtbl24                                 no
+  R2ABlueCtbl25                                 no
+  R2ABlueCtbl26                                 no
+  R2ABlueCtbl27                                 no
+  R2ABlueCtbl28                                 no
+  R2ABlueCtbl29                                 no
+  R2ABlueCtbl30                                 no
+  R2ABlueCtbl31                                 no
+  R2ABlueStbl00                                 no
+  R2ABlueStbl01                                 no
+  R2ABlueStbl02                                 no
+  R2ABlueStbl03                                 no
+  R2ABlueStbl04                                 no
+  R2ABlueStbl05                                 no
+  R2ABlueStbl06                                 no
+  R2ABlueStbl07                                 no
+  R2ABlueStbl08                                 no
+  R2ABlueStbl09                                 no
+  R2ABlueStbl10                                 no
+  R2ABlueStbl11                                 no
+  R2ABlueStbl12                                 no
+  R2ABlueStbl13                                 no
+  R2ABlueStbl14                                 no
+  R2ABlueStbl15                                 no
+  R2ABlueStbl16                                 no
+  R2ABlueStbl17                                 no
+  R2ABlueStbl18                                 no
+  R2ABlueStbl19                                 no
+  R2ABlueStbl20                                 no
+  R2ABlueStbl21                                 no
+  R2ABlueStbl22                                 no
+  R2ABlueStbl23                                 no
+  R2ABlueStbl24                                 no
+  R2ABlueStbl25                                 no
+  R2ABlueStbl26                                 no
+  R2ABlueStbl27                                 no
+  R2ABlueStbl28                                 no
+  R2ABlueStbl29                                 no
+  R2ABlueStbl30                                 no
+  R2ABlueStbl31                                 no
+  R2ACx                                         no
+  R2ACy                                         no
+  R2AGreenCtbl00                                no
+  R2AGreenCtbl01                                no
+  R2AGreenCtbl02                                no
+  R2AGreenCtbl03                                no
+  R2AGreenCtbl04                                no
+  R2AGreenCtbl05                                no
+  R2AGreenCtbl06                                no
+  R2AGreenCtbl07                                no
+  R2AGreenCtbl08                                no
+  R2AGreenCtbl09                                no
+  R2AGreenCtbl10                                no
+  R2AGreenCtbl11                                no
+  R2AGreenCtbl12                                no
+  R2AGreenCtbl13                                no
+  R2AGreenCtbl14                                no
+  R2AGreenCtbl15                                no
+  R2AGreenCtbl16                                no
+  R2AGreenCtbl17                                no
+  R2AGreenCtbl18                                no
+  R2AGreenCtbl19                                no
+  R2AGreenCtbl20                                no
+  R2AGreenCtbl21                                no
+  R2AGreenCtbl22                                no
+  R2AGreenCtbl23                                no
+  R2AGreenCtbl24                                no
+  R2AGreenCtbl25                                no
+  R2AGreenCtbl26                                no
+  R2AGreenCtbl27                                no
+  R2AGreenCtbl28                                no
+  R2AGreenCtbl29                                no
+  R2AGreenCtbl30                                no
+  R2AGreenCtbl31                                no
+  R2AGreenStbl00                                no
+  R2AGreenStbl01                                no
+  R2AGreenStbl02                                no
+  R2AGreenStbl03                                no
+  R2AGreenStbl04                                no
+  R2AGreenStbl05                                no
+  R2AGreenStbl06                                no
+  R2AGreenStbl07                                no
+  R2AGreenStbl08                                no
+  R2AGreenStbl09                                no
+  R2AGreenStbl10                                no
+  R2AGreenStbl11                                no
+  R2AGreenStbl12                                no
+  R2AGreenStbl13                                no
+  R2AGreenStbl14                                no
+  R2AGreenStbl15                                no
+  R2AGreenStbl16                                no
+  R2AGreenStbl17                                no
+  R2AGreenStbl18                                no
+  R2AGreenStbl19                                no
+  R2AGreenStbl20                                no
+  R2AGreenStbl21                                no
+  R2AGreenStbl22                                no
+  R2AGreenStbl23                                no
+  R2AGreenStbl24                                no
+  R2AGreenStbl25                                no
+  R2AGreenStbl26                                no
+  R2AGreenStbl27                                no
+  R2AGreenStbl28                                no
+  R2AGreenStbl29                                no
+  R2AGreenStbl30                                no
+  R2AGreenStbl31                                no
+  R2AHeight                                     no
+  R2AIntervals                                  no
+  R2ARedCtbl00                                  no
+  R2ARedCtbl01                                  no
+  R2ARedCtbl02                                  no
+  R2ARedCtbl03                                  no
+  R2ARedCtbl04                                  no
+  R2ARedCtbl05                                  no
+  R2ARedCtbl06                                  no
+  R2ARedCtbl07                                  no
+  R2ARedCtbl08                                  no
+  R2ARedCtbl09                                  no
+  R2ARedCtbl10                                  no
+  R2ARedCtbl11                                  no
+  R2ARedCtbl12                                  no
+  R2ARedCtbl13                                  no
+  R2ARedCtbl14                                  no
+  R2ARedCtbl15                                  no
+  R2ARedCtbl16                                  no
+  R2ARedCtbl17                                  no
+  R2ARedCtbl18                                  no
+  R2ARedCtbl19                                  no
+  R2ARedCtbl20                                  no
+  R2ARedCtbl21                                  no
+  R2ARedCtbl22                                  no
+  R2ARedCtbl23                                  no
+  R2ARedCtbl24                                  no
+  R2ARedCtbl25                                  no
+  R2ARedCtbl26                                  no
+  R2ARedCtbl27                                  no
+  R2ARedCtbl28                                  no
+  R2ARedCtbl29                                  no
+  R2ARedCtbl30                                  no
+  R2ARedCtbl31                                  no
+  R2ARedStbl00                                  no
+  R2ARedStbl01                                  no
+  R2ARedStbl02                                  no
+  R2ARedStbl03                                  no
+  R2ARedStbl04                                  no
+  R2ARedStbl05                                  no
+  R2ARedStbl06                                  no
+  R2ARedStbl07                                  no
+  R2ARedStbl08                                  no
+  R2ARedStbl09                                  no
+  R2ARedStbl10                                  no
+  R2ARedStbl11                                  no
+  R2ARedStbl12                                  no
+  R2ARedStbl13                                  no
+  R2ARedStbl14                                  no
+  R2ARedStbl15                                  no
+  R2ARedStbl16                                  no
+  R2ARedStbl17                                  no
+  R2ARedStbl18                                  no
+  R2ARedStbl19                                  no
+  R2ARedStbl20                                  no
+  R2ARedStbl21                                  no
+  R2ARedStbl22                                  no
+  R2ARedStbl23                                  no
+  R2ARedStbl24                                  no
+  R2ARedStbl25                                  no
+  R2ARedStbl26                                  no
+  R2ARedStbl27                                  no
+  R2ARedStbl28                                  no
+  R2ARedStbl29                                  no
+  R2ARedStbl30                                  no
+  R2ARedStbl31                                  no
+  R2ATbl00                                      no
+  R2ATbl01                                      no
+  R2ATbl02                                      no
+  R2ATbl03                                      no
+  R2ATbl04                                      no
+  R2ATbl05                                      no
+  R2ATbl06                                      no
+  R2ATbl07                                      no
+  R2ATbl08                                      no
+  R2ATbl09                                      no
+  R2ATbl10                                      no
+  R2ATbl11                                      no
+  R2ATbl12                                      no
+  R2ATbl13                                      no
+  R2ATbl14                                      no
+  R2ATbl15                                      no
+  R2ATbl16                                      no
+  R2ATbl17                                      no
+  R2ATbl18                                      no
+  R2ATbl19                                      no
+  R2ATbl20                                      no
+  R2ATbl21                                      no
+  R2ATbl22                                      no
+  R2ATbl23                                      no
+  R2ATbl24                                      no
+  R2ATbl25                                      no
+  R2ATbl26                                      no
+  R2ATbl27                                      no
+  R2ATbl28                                      no
+  R2ATbl29                                      no
+  R2ATbl30                                      no
+  R2ATbl31                                      no
+  R2AWidth                                      no
+  R2D65BlueCtbl00                               no
+  R2D65BlueCtbl01                               no
+  R2D65BlueCtbl02                               no
+  R2D65BlueCtbl03                               no
+  R2D65BlueCtbl04                               no
+  R2D65BlueCtbl05                               no
+  R2D65BlueCtbl06                               no
+  R2D65BlueCtbl07                               no
+  R2D65BlueCtbl08                               no
+  R2D65BlueCtbl09                               no
+  R2D65BlueCtbl10                               no
+  R2D65BlueCtbl11                               no
+  R2D65BlueCtbl12                               no
+  R2D65BlueCtbl13                               no
+  R2D65BlueCtbl14                               no
+  R2D65BlueCtbl15                               no
+  R2D65BlueCtbl16                               no
+  R2D65BlueCtbl17                               no
+  R2D65BlueCtbl18                               no
+  R2D65BlueCtbl19                               no
+  R2D65BlueCtbl20                               no
+  R2D65BlueCtbl21                               no
+  R2D65BlueCtbl22                               no
+  R2D65BlueCtbl23                               no
+  R2D65BlueCtbl24                               no
+  R2D65BlueCtbl25                               no
+  R2D65BlueCtbl26                               no
+  R2D65BlueCtbl27                               no
+  R2D65BlueCtbl28                               no
+  R2D65BlueCtbl29                               no
+  R2D65BlueCtbl30                               no
+  R2D65BlueCtbl31                               no
+  R2D65BlueStbl00                               no
+  R2D65BlueStbl01                               no
+  R2D65BlueStbl02                               no
+  R2D65BlueStbl03                               no
+  R2D65BlueStbl04                               no
+  R2D65BlueStbl05                               no
+  R2D65BlueStbl06                               no
+  R2D65BlueStbl07                               no
+  R2D65BlueStbl08                               no
+  R2D65BlueStbl09                               no
+  R2D65BlueStbl10                               no
+  R2D65BlueStbl11                               no
+  R2D65BlueStbl12                               no
+  R2D65BlueStbl13                               no
+  R2D65BlueStbl14                               no
+  R2D65BlueStbl15                               no
+  R2D65BlueStbl16                               no
+  R2D65BlueStbl17                               no
+  R2D65BlueStbl18                               no
+  R2D65BlueStbl19                               no
+  R2D65BlueStbl20                               no
+  R2D65BlueStbl21                               no
+  R2D65BlueStbl22                               no
+  R2D65BlueStbl23                               no
+  R2D65BlueStbl24                               no
+  R2D65BlueStbl25                               no
+  R2D65BlueStbl26                               no
+  R2D65BlueStbl27                               no
+  R2D65BlueStbl28                               no
+  R2D65BlueStbl29                               no
+  R2D65BlueStbl30                               no
+  R2D65BlueStbl31                               no
+  R2D65Cx                                       no
+  R2D65Cy                                       no
+  R2D65GreenCtbl00                              no
+  R2D65GreenCtbl01                              no
+  R2D65GreenCtbl02                              no
+  R2D65GreenCtbl03                              no
+  R2D65GreenCtbl04                              no
+  R2D65GreenCtbl05                              no
+  R2D65GreenCtbl06                              no
+  R2D65GreenCtbl07                              no
+  R2D65GreenCtbl08                              no
+  R2D65GreenCtbl09                              no
+  R2D65GreenCtbl10                              no
+  R2D65GreenCtbl11                              no
+  R2D65GreenCtbl12                              no
+  R2D65GreenCtbl13                              no
+  R2D65GreenCtbl14                              no
+  R2D65GreenCtbl15                              no
+  R2D65GreenCtbl16                              no
+  R2D65GreenCtbl17                              no
+  R2D65GreenCtbl18                              no
+  R2D65GreenCtbl19                              no
+  R2D65GreenCtbl20                              no
+  R2D65GreenCtbl21                              no
+  R2D65GreenCtbl22                              no
+  R2D65GreenCtbl23                              no
+  R2D65GreenCtbl24                              no
+  R2D65GreenCtbl25                              no
+  R2D65GreenCtbl26                              no
+  R2D65GreenCtbl27                              no
+  R2D65GreenCtbl28                              no
+  R2D65GreenCtbl29                              no
+  R2D65GreenCtbl30                              no
+  R2D65GreenCtbl31                              no
+  R2D65GreenStbl00                              no
+  R2D65GreenStbl01                              no
+  R2D65GreenStbl02                              no
+  R2D65GreenStbl03                              no
+  R2D65GreenStbl04                              no
+  R2D65GreenStbl05                              no
+  R2D65GreenStbl06                              no
+  R2D65GreenStbl07                              no
+  R2D65GreenStbl08                              no
+  R2D65GreenStbl09                              no
+  R2D65GreenStbl10                              no
+  R2D65GreenStbl11                              no
+  R2D65GreenStbl12                              no
+  R2D65GreenStbl13                              no
+  R2D65GreenStbl14                              no
+  R2D65GreenStbl15                              no
+  R2D65GreenStbl16                              no
+  R2D65GreenStbl17                              no
+  R2D65GreenStbl18                              no
+  R2D65GreenStbl19                              no
+  R2D65GreenStbl20                              no
+  R2D65GreenStbl21                              no
+  R2D65GreenStbl22                              no
+  R2D65GreenStbl23                              no
+  R2D65GreenStbl24                              no
+  R2D65GreenStbl25                              no
+  R2D65GreenStbl26                              no
+  R2D65GreenStbl27                              no
+  R2D65GreenStbl28                              no
+  R2D65GreenStbl29                              no
+  R2D65GreenStbl30                              no
+  R2D65GreenStbl31                              no
+  R2D65Height                                   no
+  R2D65Intervals                                no
+  R2D65RedCtbl00                                no
+  R2D65RedCtbl01                                no
+  R2D65RedCtbl02                                no
+  R2D65RedCtbl03                                no
+  R2D65RedCtbl04                                no
+  R2D65RedCtbl05                                no
+  R2D65RedCtbl06                                no
+  R2D65RedCtbl07                                no
+  R2D65RedCtbl08                                no
+  R2D65RedCtbl09                                no
+  R2D65RedCtbl10                                no
+  R2D65RedCtbl11                                no
+  R2D65RedCtbl12                                no
+  R2D65RedCtbl13                                no
+  R2D65RedCtbl14                                no
+  R2D65RedCtbl15                                no
+  R2D65RedCtbl16                                no
+  R2D65RedCtbl17                                no
+  R2D65RedCtbl18                                no
+  R2D65RedCtbl19                                no
+  R2D65RedCtbl20                                no
+  R2D65RedCtbl21                                no
+  R2D65RedCtbl22                                no
+  R2D65RedCtbl23                                no
+  R2D65RedCtbl24                                no
+  R2D65RedCtbl25                                no
+  R2D65RedCtbl26                                no
+  R2D65RedCtbl27                                no
+  R2D65RedCtbl28                                no
+  R2D65RedCtbl29                                no
+  R2D65RedCtbl30                                no
+  R2D65RedCtbl31                                no
+  R2D65RedStbl00                                no
+  R2D65RedStbl01                                no
+  R2D65RedStbl02                                no
+  R2D65RedStbl03                                no
+  R2D65RedStbl04                                no
+  R2D65RedStbl05                                no
+  R2D65RedStbl06                                no
+  R2D65RedStbl07                                no
+  R2D65RedStbl08                                no
+  R2D65RedStbl09                                no
+  R2D65RedStbl10                                no
+  R2D65RedStbl11                                no
+  R2D65RedStbl12                                no
+  R2D65RedStbl13                                no
+  R2D65RedStbl14                                no
+  R2D65RedStbl15                                no
+  R2D65RedStbl16                                no
+  R2D65RedStbl17                                no
+  R2D65RedStbl18                                no
+  R2D65RedStbl19                                no
+  R2D65RedStbl20                                no
+  R2D65RedStbl21                                no
+  R2D65RedStbl22                                no
+  R2D65RedStbl23                                no
+  R2D65RedStbl24                                no
+  R2D65RedStbl25                                no
+  R2D65RedStbl26                                no
+  R2D65RedStbl27                                no
+  R2D65RedStbl28                                no
+  R2D65RedStbl29                                no
+  R2D65RedStbl30                                no
+  R2D65RedStbl31                                no
+  R2D65Tbl00                                    no
+  R2D65Tbl01                                    no
+  R2D65Tbl02                                    no
+  R2D65Tbl03                                    no
+  R2D65Tbl04                                    no
+  R2D65Tbl05                                    no
+  R2D65Tbl06                                    no
+  R2D65Tbl07                                    no
+  R2D65Tbl08                                    no
+  R2D65Tbl09                                    no
+  R2D65Tbl10                                    no
+  R2D65Tbl11                                    no
+  R2D65Tbl12                                    no
+  R2D65Tbl13                                    no
+  R2D65Tbl14                                    no
+  R2D65Tbl15                                    no
+  R2D65Tbl16                                    no
+  R2D65Tbl17                                    no
+  R2D65Tbl18                                    no
+  R2D65Tbl19                                    no
+  R2D65Tbl20                                    no
+  R2D65Tbl21                                    no
+  R2D65Tbl22                                    no
+  R2D65Tbl23                                    no
+  R2D65Tbl24                                    no
+  R2D65Tbl25                                    no
+  R2D65Tbl26                                    no
+  R2D65Tbl27                                    no
+  R2D65Tbl28                                    no
+  R2D65Tbl29                                    no
+  R2D65Tbl30                                    no
+  R2D65Tbl31                                    no
+  R2D65Width                                    no
+  R2TL84BlueCtbl00                              no
+  R2TL84BlueCtbl01                              no
+  R2TL84BlueCtbl02                              no
+  R2TL84BlueCtbl03                              no
+  R2TL84BlueCtbl04                              no
+  R2TL84BlueCtbl05                              no
+  R2TL84BlueCtbl06                              no
+  R2TL84BlueCtbl07                              no
+  R2TL84BlueCtbl08                              no
+  R2TL84BlueCtbl09                              no
+  R2TL84BlueCtbl10                              no
+  R2TL84BlueCtbl11                              no
+  R2TL84BlueCtbl12                              no
+  R2TL84BlueCtbl13                              no
+  R2TL84BlueCtbl14                              no
+  R2TL84BlueCtbl15                              no
+  R2TL84BlueCtbl16                              no
+  R2TL84BlueCtbl17                              no
+  R2TL84BlueCtbl18                              no
+  R2TL84BlueCtbl19                              no
+  R2TL84BlueCtbl20                              no
+  R2TL84BlueCtbl21                              no
+  R2TL84BlueCtbl22                              no
+  R2TL84BlueCtbl23                              no
+  R2TL84BlueCtbl24                              no
+  R2TL84BlueCtbl25                              no
+  R2TL84BlueCtbl26                              no
+  R2TL84BlueCtbl27                              no
+  R2TL84BlueCtbl28                              no
+  R2TL84BlueCtbl29                              no
+  R2TL84BlueCtbl30                              no
+  R2TL84BlueCtbl31                              no
+  R2TL84BlueStbl00                              no
+  R2TL84BlueStbl01                              no
+  R2TL84BlueStbl02                              no
+  R2TL84BlueStbl03                              no
+  R2TL84BlueStbl04                              no
+  R2TL84BlueStbl05                              no
+  R2TL84BlueStbl06                              no
+  R2TL84BlueStbl07                              no
+  R2TL84BlueStbl08                              no
+  R2TL84BlueStbl09                              no
+  R2TL84BlueStbl10                              no
+  R2TL84BlueStbl11                              no
+  R2TL84BlueStbl12                              no
+  R2TL84BlueStbl13                              no
+  R2TL84BlueStbl14                              no
+  R2TL84BlueStbl15                              no
+  R2TL84BlueStbl16                              no
+  R2TL84BlueStbl17                              no
+  R2TL84BlueStbl18                              no
+  R2TL84BlueStbl19                              no
+  R2TL84BlueStbl20                              no
+  R2TL84BlueStbl21                              no
+  R2TL84BlueStbl22                              no
+  R2TL84BlueStbl23                              no
+  R2TL84BlueStbl24                              no
+  R2TL84BlueStbl25                              no
+  R2TL84BlueStbl26                              no
+  R2TL84BlueStbl27                              no
+  R2TL84BlueStbl28                              no
+  R2TL84BlueStbl29                              no
+  R2TL84BlueStbl30                              no
+  R2TL84BlueStbl31                              no
+  R2TL84Cx                                      no
+  R2TL84Cy                                      no
+  R2TL84GreenCtbl00                             no
+  R2TL84GreenCtbl01                             no
+  R2TL84GreenCtbl02                             no
+  R2TL84GreenCtbl03                             no
+  R2TL84GreenCtbl04                             no
+  R2TL84GreenCtbl05                             no
+  R2TL84GreenCtbl06                             no
+  R2TL84GreenCtbl07                             no
+  R2TL84GreenCtbl08                             no
+  R2TL84GreenCtbl09                             no
+  R2TL84GreenCtbl10                             no
+  R2TL84GreenCtbl11                             no
+  R2TL84GreenCtbl12                             no
+  R2TL84GreenCtbl13                             no
+  R2TL84GreenCtbl14                             no
+  R2TL84GreenCtbl15                             no
+  R2TL84GreenCtbl16                             no
+  R2TL84GreenCtbl17                             no
+  R2TL84GreenCtbl18                             no
+  R2TL84GreenCtbl19                             no
+  R2TL84GreenCtbl20                             no
+  R2TL84GreenCtbl21                             no
+  R2TL84GreenCtbl22                             no
+  R2TL84GreenCtbl23                             no
+  R2TL84GreenCtbl24                             no
+  R2TL84GreenCtbl25                             no
+  R2TL84GreenCtbl26                             no
+  R2TL84GreenCtbl27                             no
+  R2TL84GreenCtbl28                             no
+  R2TL84GreenCtbl29                             no
+  R2TL84GreenCtbl30                             no
+  R2TL84GreenCtbl31                             no
+  R2TL84GreenStbl00                             no
+  R2TL84GreenStbl01                             no
+  R2TL84GreenStbl02                             no
+  R2TL84GreenStbl03                             no
+  R2TL84GreenStbl04                             no
+  R2TL84GreenStbl05                             no
+  R2TL84GreenStbl06                             no
+  R2TL84GreenStbl07                             no
+  R2TL84GreenStbl08                             no
+  R2TL84GreenStbl09                             no
+  R2TL84GreenStbl10                             no
+  R2TL84GreenStbl11                             no
+  R2TL84GreenStbl12                             no
+  R2TL84GreenStbl13                             no
+  R2TL84GreenStbl14                             no
+  R2TL84GreenStbl15                             no
+  R2TL84GreenStbl16                             no
+  R2TL84GreenStbl17                             no
+  R2TL84GreenStbl18                             no
+  R2TL84GreenStbl19                             no
+  R2TL84GreenStbl20                             no
+  R2TL84GreenStbl21                             no
+  R2TL84GreenStbl22                             no
+  R2TL84GreenStbl23                             no
+  R2TL84GreenStbl24                             no
+  R2TL84GreenStbl25                             no
+  R2TL84GreenStbl26                             no
+  R2TL84GreenStbl27                             no
+  R2TL84GreenStbl28                             no
+  R2TL84GreenStbl29                             no
+  R2TL84GreenStbl30                             no
+  R2TL84GreenStbl31                             no
+  R2TL84Height                                  no
+  R2TL84Intervals                               no
+  R2TL84RedCtbl00                               no
+  R2TL84RedCtbl01                               no
+  R2TL84RedCtbl02                               no
+  R2TL84RedCtbl03                               no
+  R2TL84RedCtbl04                               no
+  R2TL84RedCtbl05                               no
+  R2TL84RedCtbl06                               no
+  R2TL84RedCtbl07                               no
+  R2TL84RedCtbl08                               no
+  R2TL84RedCtbl09                               no
+  R2TL84RedCtbl10                               no
+  R2TL84RedCtbl11                               no
+  R2TL84RedCtbl12                               no
+  R2TL84RedCtbl13                               no
+  R2TL84RedCtbl14                               no
+  R2TL84RedCtbl15                               no
+  R2TL84RedCtbl16                               no
+  R2TL84RedCtbl17                               no
+  R2TL84RedCtbl18                               no
+  R2TL84RedCtbl19                               no
+  R2TL84RedCtbl20                               no
+  R2TL84RedCtbl21                               no
+  R2TL84RedCtbl22                               no
+  R2TL84RedCtbl23                               no
+  R2TL84RedCtbl24                               no
+  R2TL84RedCtbl25                               no
+  R2TL84RedCtbl26                               no
+  R2TL84RedCtbl27                               no
+  R2TL84RedCtbl28                               no
+  R2TL84RedCtbl29                               no
+  R2TL84RedCtbl30                               no
+  R2TL84RedCtbl31                               no
+  R2TL84RedStbl00                               no
+  R2TL84RedStbl01                               no
+  R2TL84RedStbl02                               no
+  R2TL84RedStbl03                               no
+  R2TL84RedStbl04                               no
+  R2TL84RedStbl05                               no
+  R2TL84RedStbl06                               no
+  R2TL84RedStbl07                               no
+  R2TL84RedStbl08                               no
+  R2TL84RedStbl09                               no
+  R2TL84RedStbl10                               no
+  R2TL84RedStbl11                               no
+  R2TL84RedStbl12                               no
+  R2TL84RedStbl13                               no
+  R2TL84RedStbl14                               no
+  R2TL84RedStbl15                               no
+  R2TL84RedStbl16                               no
+  R2TL84RedStbl17                               no
+  R2TL84RedStbl18                               no
+  R2TL84RedStbl19                               no
+  R2TL84RedStbl20                               no
+  R2TL84RedStbl21                               no
+  R2TL84RedStbl22                               no
+  R2TL84RedStbl23                               no
+  R2TL84RedStbl24                               no
+  R2TL84RedStbl25                               no
+  R2TL84RedStbl26                               no
+  R2TL84RedStbl27                               no
+  R2TL84RedStbl28                               no
+  R2TL84RedStbl29                               no
+  R2TL84RedStbl30                               no
+  R2TL84RedStbl31                               no
+  R2TL84Tbl00                                   no
+  R2TL84Tbl01                                   no
+  R2TL84Tbl02                                   no
+  R2TL84Tbl03                                   no
+  R2TL84Tbl04                                   no
+  R2TL84Tbl05                                   no
+  R2TL84Tbl06                                   no
+  R2TL84Tbl07                                   no
+  R2TL84Tbl08                                   no
+  R2TL84Tbl09                                   no
+  R2TL84Tbl10                                   no
+  R2TL84Tbl11                                   no
+  R2TL84Tbl12                                   no
+  R2TL84Tbl13                                   no
+  R2TL84Tbl14                                   no
+  R2TL84Tbl15                                   no
+  R2TL84Tbl16                                   no
+  R2TL84Tbl17                                   no
+  R2TL84Tbl18                                   no
+  R2TL84Tbl19                                   no
+  R2TL84Tbl20                                   no
+  R2TL84Tbl21                                   no
+  R2TL84Tbl22                                   no
+  R2TL84Tbl23                                   no
+  R2TL84Tbl24                                   no
+  R2TL84Tbl25                                   no
+  R2TL84Tbl26                                   no
+  R2TL84Tbl27                                   no
+  R2TL84Tbl28                                   no
+  R2TL84Tbl29                                   no
+  R2TL84Tbl30                                   no
+  R2TL84Tbl31                                   no
+  R2TL84Width                                   no
+  RolloffEnable                                 no
+  SensorFmt                                     no
+  SensorType                                    no
+  SensrFulHght                                  no
+  SensrFulWdth                                  no
+  SensrQtrHght                                  no
+  SensrQtrWdth                                  no
+  SnapshotResol                                 no
+  TL84ConvChrmA_M                               no
+  TL84ConvChrmA_P                               no
+  TL84ConvChrmB_M                               no
+  TL84ConvChrmB_P                               no
+  TL84ConvChrmC_M                               no
+  TL84ConvChrmC_P                               no
+  TL84ConvChrmD_M                               no
+  TL84ConvChrmD_P                               no
+  TL84ConvChrmKCb                               no
+  TL84ConvChrmKCr                               no
+  TL84ConvLumaK                                 no
+  TL84ConvLumaV0                                no
+  TL84ConvLumaV1                                no
+  TL84ConvLumaV2                                no
+  VideoFps                                      no
+  YhiYloConvChrmA_M                             no
+  YhiYloConvChrmA_P                             no
+  YhiYloConvChrmB_M                             no
+  YhiYloConvChrmB_P                             no
+  YhiYloConvChrmC_M                             no
+  YhiYloConvChrmC_P                             no
+  YhiYloConvChrmD_M                             no
+  YhiYloConvChrmD_P                             no
+  YhiYloConvChrmKCb                             no
+  YhiYloConvChrmKCr                             no
+  YhiYloConvLumaK                               no
+  YhiYloConvLumaV0                              no
+  YhiYloConvLumaV1                              no
+  YhiYloConvLumaV2                              no
+  YhiYloCorC0                                   no
+  YhiYloCorC1                                   no
+  YhiYloCorC2                                   no
+  YhiYloCorC3                                   no
+  YhiYloCorC4                                   no
+  YhiYloCorC5                                   no
+  YhiYloCorC6                                   no
+  YhiYloCorC7                                   no
+  YhiYloCorC8                                   no
+  YhiYloCorK0                                   no
+  YhiYloCorK1                                   no
+  YhiYloCorK2                                   no
 
 =head2 APP12 Tags
@@ -11025,31 +21777,31 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Aperture'           Aperture                 N
-  'ColorMode'          ColorMode                N
-  'ConTake'            ConTake                  N
-  'ExpBias'            ExposureCompensation     N
-  'FNumber'            FNumber                  N
-  'FWare'              FirmwareVersion          N
-  'Flash'              Flash                    N
-  'FocusMode'          FocusMode                N
-  'FocusPos'           FocusPos                 N
-  'ID'                 ID                       N
-  'ImageSize'          ImageSize                N
-  'LightS'             LightS                   N
-  'Macro'              Macro                    N
-  'Protect'            Protect                  N
-  'Quality'            Quality                  N
-  'Resolution'         Resolution               N
-  'Serial#'            SerialNumber             N
-  'Shutter'            ExposureTime             N
-  'StrobeTime'         StrobeTime               N
-  'TimeDate'           DateTimeOriginal         N
-  'Type'               CameraType               N
-  'Version'            Version                  N
-  'Ytarget'            YTarget                  N
-  'Zoom'               Zoom                     N
-  'ZoomPos'            ZoomPos                  N
-  'shtr'               ExposureTime             N
-  'ylevel'             YLevel                   N
+  'Aperture'           Aperture                 no
+  'ColorMode'          ColorMode                no
+  'ConTake'            ConTake                  no
+  'ExpBias'            ExposureCompensation     no
+  'FNumber'            FNumber                  no
+  'FWare'              FirmwareVersion          no
+  'Flash'              Flash                    no
+  'FocusMode'          FocusMode                no
+  'FocusPos'           FocusPos                 no
+  'ID'                 ID                       no
+  'ImageSize'          ImageSize                no
+  'LightS'             LightS                   no
+  'Macro'              Macro                    no
+  'Protect'            Protect                  no
+  'Quality'            Quality                  no
+  'Resolution'         Resolution               no
+  'Serial#'            SerialNumber             no
+  'Shutter'            ExposureTime             no
+  'StrobeTime'         StrobeTime               no
+  'TimeDate'           DateTimeOriginal         no
+  'Type'               CameraType               no
+  'Version'            Version                  no
+  'Ytarget'            YTarget                  no
+  'Zoom'               Zoom                     no
+  'ZoomPos'            ZoomPos                  no
+  'shtr'               ExposureTime             no
+  'ylevel'             YLevel                   no
 
 =head3 APP12 Ducky Tags
@@ -11074,10 +21826,504 @@
 and TIFF images.
 
+See
+L<http://web.archive.org/web/20080828211305/http://www.tocarte.com/media/axs_afcp_spec.pdf>
+for the AFCP specification.
+
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
   'IPTC'   IPTC                                 IPTC
-  'Nail'   ThumbnailImage                       N
-  'PrVw'   PreviewImage                         N
-  'TEXT'   Text                                 N
+  'Nail'   ThumbnailImage                       no
+  'PrVw'   PreviewImage                         no
+  'TEXT'   Text                                 no
+
+=head2 DarwinCore Tags
+
+Tags defined in the Darwin Core (dwc) XMP namespace.  See
+L<http://rs.tdwg.org/dwc/index.htm> for the official specification.
+
+These tags belong to the ExifTool XMP-dwc family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  DCTermsLocation                               DarwinCore DCTermsLocation Struct
+  DCContinent                                   string_
+  DCCoordinatePrecision                         string_
+  DCCoordinateUncertaintyInMeters               string_
+  DCCountry                                     string_
+  DCCountryCode                                 string_
+  DCCounty                                      string_
+  DCDecimalLatitude                             string_
+  DCDecimalLongitude                            string_
+  DCFootprintSpatialFit                         string_
+  DCFootprintSRS                                string_
+  DCFootprintWKT                                string_
+  DCGeodeticDatum                               string_
+  DCGeoreferencedBy                             string_
+  DCGeoreferencedDate                           string_
+  DCGeoreferenceProtocol                        string_
+  DCGeoreferenceRemarks                         string_
+  DCGeoreferenceSources                         string_
+  DCGeoreferenceVerificationStatus              string_
+  DCHigherGeography                             string_
+  DCHigherGeographyID                           string_
+  DCIsland                                      string_
+  DCIslandGroup                                 string_
+  DCLocality                                    string_
+  DCLocationAccordingTo                         string_
+  DCLocationID                                  string_
+  DCLocationRemarks                             string_
+  DCMaximumDepthInMeters                        string_
+  DCMaximumDistanceAboveSurfaceInMeters         string_
+  DCMaximumElevationInMeters                    string_
+  DCMinimumDepthInMeters                        string_
+  DCMinimumDistanceAboveSurfaceInMeters         string_
+  DCMinimumElevationInMeters                    string_
+  DCMunicipality                                string_
+  DCPointRadiusSpatialFit                       string_
+  DCStateProvince                               string_
+  DCVerbatimCoordinates                         string_
+  DCVerbatimCoordinateSystem                    string_
+  DCVerbatimDepth                               string_
+  DCVerbatimElevation                           string_
+  DCVerbatimLatitude                            string_
+  DCVerbatimLocality                            string_
+  DCVerbatimLongitude                           string_
+  DCVerbatimSRS                                 string_
+  DCWaterBody                                   string_
+  DCEvent                                       DarwinCore Event Struct
+  EventDay                                      integer_
+  EventEarliestDate                             date_
+  EventEndDayOfYear                             integer_
+  EventDate                                     date_
+  EventID                                       string_
+  EventRemarks                                  lang-alt_
+  EventTime                                     string_
+  EventFieldNotes                               string_
+  EventFieldNumber                              string_
+  EventHabitat                                  string_
+  EventLatestDate                               date_
+  EventMonth                                    integer_
+  EventParentEventID                            string_
+  EventSampleSizeUnit                           string_
+  EventSampleSizeValue                          string_
+  EventSamplingEffort                           string_
+  EventSamplingProtocol                         string_
+  EventStartDayOfYear                           integer_
+  EventVerbatimEventDate                        string_
+  EventYear                                     integer_
+  FossilSpecimen                                DarwinCore MaterialSample Struct
+  FossilSpecimenMaterialSampleID                string_
+  GeologicalContext                            DarwinCore GeologicalContext Struct
+  GeologicalContextBed                          string_
+  EarliestAgeOrLowestStage                      string_
+  EarliestEonOrLowestEonothem                   string_
+  EarliestEpochOrLowestSeries                   string_
+  EarliestEraOrLowestErathem                    string_
+  EarliestPeriodOrLowestSystem                  string_
+  GeologicalContextFormation                    string_
+  GeologicalContextID                           string_
+  GeologicalContextGroup                        string_
+  HighestBiostratigraphicZone                   string_
+  LatestAgeOrHighestStage                       string_
+  LatestEonOrHighestEonothem                    string_
+  LatestEpochOrHighestSeries                    string_
+  LatestEraOrHighestErathem                     string_
+  LatestPeriodOrHighestSystem                   string_
+  LithostratigraphicTerms                       string_
+  LowestBiostratigraphicZone                    string_
+  GeologicalContextMember                       string_
+  HumanObservation                              DarwinCore Event Struct
+  HumanObservationDay                           integer_
+  HumanObservationEarliestDate                  date_
+  HumanObservationEndDayOfYear                  integer_
+  HumanObservationEventDate                     date_
+  HumanObservationEventID                       string_
+  HumanObservationEventRemarks                  lang-alt_
+  HumanObservationEventTime                     string_
+  HumanObservationFieldNotes                    string_
+  HumanObservationFieldNumber                   string_
+  HumanObservationHabitat                       string_
+  HumanObservationLatestDate                    date_
+  HumanObservationMonth                         integer_
+  HumanObservationParentEventID                 string_
+  HumanObservationSampleSizeUnit                string_
+  HumanObservationSampleSizeValue               string_
+  HumanObservationSamplingEffort                string_
+  HumanObservationSamplingProtocol              string_
+  HumanObservationStartDayOfYear                integer_
+  HumanObservationVerbatimEventDate             string_
+  HumanObservationYear                          integer_
+  Identification                                DarwinCore Identification Struct
+  DateIdentified                                date_
+  IdentificationID                              string_
+  IdentificationQualifier                       string_
+  IdentificationReferences                      string_
+  IdentificationRemarks                         string_
+  IdentificationVerificationStatus              string_
+  IdentifiedBy                                  string_
+  TypeStatus                                    string_
+  LivingSpecimen                                DarwinCore MaterialSample Struct
+  LivingSpecimenMaterialSampleID                string_
+  MachineObservation                            DarwinCore Event Struct
+  MachineObservationDay                         integer_
+  MachineObservationEarliestDate                date_
+  MachineObservationEndDayOfYear                integer_
+  MachineObservationEventDate                   date_
+  MachineObservationEventID                     string_
+  MachineObservationEventRemarks                lang-alt_
+  MachineObservationEventTime                   string_
+  MachineObservationFieldNotes                  string_
+  MachineObservationFieldNumber                 string_
+  MachineObservationHabitat                     string_
+  MachineObservationLatestDate                  date_
+  MachineObservationMonth                       integer_
+  MachineObservationParentEventID               string_
+  MachineObservationSampleSizeUnit              string_
+  MachineObservationSampleSizeValue             string_
+  MachineObservationSamplingEffort              string_
+  MachineObservationSamplingProtocol            string_
+  MachineObservationStartDayOfYear              integer_
+  MachineObservationVerbatimEventDate           string_
+  MachineObservationYear                        integer_
+  MaterialSample                                DarwinCore MaterialSample Struct
+  MaterialSampleID                              string_
+  MeasurementOrFact                            DarwinCore MeasurementOrFact Struct
+  MeasurementAccuracy                           string_
+  MeasurementDeterminedBy                       string_
+  MeasurementDeterminedDate                     date_
+  MeasurementID                                 string_
+  MeasurementMethod                             string_
+  MeasurementRemarks                            string_
+  MeasurementType                               string_
+  MeasurementUnit                               string_
+  MeasurementValue                              string_
+  Occurrence                                    DarwinCore Occurrence Struct
+  OccurrenceAssociatedMedia                     string_
+  OccurrenceAssociatedOccurrences               string_
+  OccurrenceAssociatedReferences                string_
+  OccurrenceAssociatedSequences                 string_
+  OccurrenceAssociatedTaxa                      string_
+  OccurrenceBehavior                            string_
+  OccurrenceCatalogNumber                       string_
+  OccurrenceDisposition                         string_
+  OccurrenceEstablishmentMeans                  string_
+  OccurrenceIndividualCount                     string_
+  OccurrenceIndividualID                        string_
+  OccurrenceLifeStage                           string_
+  OccurrenceDetails                             string_
+  OccurrenceID                                  string_
+  OccurrenceRemarks                             string_
+  OccurrenceStatus                              string_
+  OccurrenceOrganismQuantity                    string_
+  OccurrenceOrganismQuantityType                string_
+  OccurrenceOtherCatalogNumbers                 string_
+  OccurrencePreparations                        string_
+  OccurrencePreviousIdentifications             string_
+  OccurrenceRecordedBy                          string_
+  OccurrenceRecordNumber                        string_
+  OccurrenceReproductiveCondition               string_
+  OccurrenceSex                                 string_
+  Organism                                      DarwinCore Organism Struct
+  OrganismAssociatedOccurrences                 string_
+  OrganismAssociatedOrganisms                   string_
+  OrganismID                                    string_
+  OrganismName                                  string_
+  OrganismRemarks                               string_
+  OrganismScope                                 string_
+  OrganismPreviousIdentifications               string_
+  PreservedSpecimen                             DarwinCore MaterialSample Struct
+  PreservedSpecimenMaterialSampleID             string_
+  Record                                        DarwinCore Record Struct
+  RecordBasisOfRecord                           string_
+  RecordCollectionCode                          string_
+  RecordCollectionID                            string_
+  RecordDataGeneralizations                     string_
+  RecordDatasetID                               string_
+  RecordDatasetName                             string_
+  RecordDynamicProperties                       string_
+  RecordInformationWithheld                     string_
+  RecordInstitutionCode                         string_
+  RecordInstitutionID                           string_
+  RecordOwnerInstitutionCode                    string_
+  ResourceRelationship                      DarwinCore ResourceRelationship Struct
+  RelatedResourceID                             string_
+  RelationshipAccordingTo                       string_
+  RelationshipEstablishedDate                   date_
+  RelationshipOfResource                        string_
+  RelationshipRemarks                           string_
+  ResourceID                                    string_
+  ResourceRelationshipID                        string_
+  Taxon                                         DarwinCore Taxon Struct
+  TaxonAcceptedNameUsage                        string_
+  TaxonAcceptedNameUsageID                      string_
+  TaxonClass                                    string_
+  TaxonFamily                                   string_
+  TaxonGenus                                    string_
+  TaxonHigherClassification                     string_
+  TaxonInfraspecificEpithet                     string_
+  TaxonKingdom                                  string_
+  TaxonNameAccordingTo                          string_
+  TaxonNameAccordingToID                        string_
+  TaxonNamePublishedIn                          string_
+  TaxonNamePublishedInID                        string_
+  TaxonNamePublishedInYear                      string_
+  TaxonNomenclaturalCode                        string_
+  TaxonNomenclaturalStatus                      string_
+  TaxonOrder                                    string_
+  TaxonOriginalNameUsage                        string_
+  TaxonOriginalNameUsageID                      string_
+  TaxonParentNameUsage                          string_
+  TaxonParentNameUsageID                        string_
+  TaxonPhylum                                   string_
+  TaxonScientificName                           string_
+  TaxonScientificNameAuthorship                 string_
+  TaxonScientificNameID                         string_
+  TaxonSpecificEpithet                          string_
+  TaxonSubgenus                                 string_
+  TaxonConceptID                                string_
+  TaxonID                                       string_
+  TaxonTaxonomicStatus                          string_
+  TaxonRank                                     string_
+  TaxonRemarks                                  string_
+  TaxonVerbatimTaxonRank                        string_
+  TaxonVernacularName                           lang-alt_
+
+=head3 DarwinCore DCTermsLocation Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Continent                                     string
+  CoordinatePrecision                           string
+  CoordinateUncertaintyInMeters                 string
+  Country                                       string
+  CountryCode                                   string
+  County                                        string
+  DecimalLatitude                               string
+  DecimalLongitude                              string
+  FootprintSRS                                  string
+  FootprintSpatialFit                           string
+  FootprintWKT                                  string
+  GeodeticDatum                                 string
+  GeoreferenceProtocol                          string
+  GeoreferenceRemarks                           string
+  GeoreferenceSources                           string
+  GeoreferenceVerificationStatus                string
+  GeoreferencedBy                               string
+  GeoreferencedDate                             string
+  HigherGeography                               string
+  HigherGeographyID                             string
+  Island                                        string
+  IslandGroup                                   string
+  Locality                                      string
+  LocationAccordingTo                           string
+  LocationID                                    string
+  LocationRemarks                               string
+  MaximumDepthInMeters                          string
+  MaximumDistanceAboveSurfaceInMeters           string
+  MaximumElevationInMeters                      string
+  MinimumDepthInMeters                          string
+  MinimumDistanceAboveSurfaceInMeters           string
+  MinimumElevationInMeters                      string
+  Municipality                                  string
+  PointRadiusSpatialFit                         string
+  StateProvince                                 string
+  VerbatimCoordinateSystem                      string
+  VerbatimCoordinates                           string
+  VerbatimDepth                                 string
+  VerbatimElevation                             string
+  VerbatimLatitude                              string
+  VerbatimLocality                              string
+  VerbatimLongitude                             string
+  VerbatimSRS                                   string
+  WaterBody                                     string
+
+=head3 DarwinCore Event Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Day                                           integer
+  EarliestDate                                  date
+  EndDayOfYear                                  integer
+  EventDate                                     date
+  EventID                                       string
+  EventRemarks                                  lang-alt
+  EventTime                                     string
+  FieldNotes                                    string
+  FieldNumber                                   string
+  Habitat                                       string
+  LatestDate                                    date
+  Month                                         integer
+  ParentEventID                                 string
+  SampleSizeUnit                                string
+  SampleSizeValue                               string
+  SamplingEffort                                string
+  SamplingProtocol                              string
+  StartDayOfYear                                integer
+  VerbatimEventDate                             string
+  Year                                          integer
+
+=head3 DarwinCore MaterialSample Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  MaterialSampleID                              string
+
+=head3 DarwinCore GeologicalContext Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Bed                                           string
+  EarliestAgeOrLowestStage                      string
+  EarliestEonOrLowestEonothem                   string
+  EarliestEpochOrLowestSeries                   string
+  EarliestEraOrLowestErathem                    string
+  EarliestPeriodOrLowestSystem                  string
+  Formation                                     string
+  GeologicalContextID                           string
+  Group                                         string
+  HighestBiostratigraphicZone                   string
+  LatestAgeOrHighestStage                       string
+  LatestEonOrHighestEonothem                    string
+  LatestEpochOrHighestSeries                    string
+  LatestEraOrHighestErathem                     string
+  LatestPeriodOrHighestSystem                   string
+  LithostratigraphicTerms                       string
+  LowestBiostratigraphicZone                    string
+  Member                                        string
+
+=head3 DarwinCore Identification Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  DateIdentified                                date
+  IdentificationID                              string
+  IdentificationQualifier                       string
+  IdentificationReferences                      string
+  IdentificationRemarks                         string
+  IdentificationVerificationStatus              string
+  IdentifiedBy                                  string
+  TypeStatus                                    string
+
+=head3 DarwinCore MeasurementOrFact Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  MeasurementAccuracy                           string
+  MeasurementDeterminedBy                       string
+  MeasurementDeterminedDate                     date
+  MeasurementID                                 string
+  MeasurementMethod                             string
+  MeasurementRemarks                            string
+  MeasurementType                               string
+  MeasurementUnit                               string
+  MeasurementValue                              string
+
+=head3 DarwinCore Occurrence Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  AssociatedMedia                               string
+  AssociatedOccurrences                         string
+  AssociatedReferences                          string
+  AssociatedSequences                           string
+  AssociatedTaxa                                string
+  Behavior                                      string
+  CatalogNumber                                 string
+  Disposition                                   string
+  EstablishmentMeans                            string
+  IndividualCount                               string
+  IndividualID                                  string
+  LifeStage                                     string
+  OccurrenceDetails                             string
+  OccurrenceID                                  string
+  OccurrenceRemarks                             string
+  OccurrenceStatus                              string
+  OrganismQuantity                              string
+  OrganismQuantityType                          string
+  OtherCatalogNumbers                           string
+  Preparations                                  string
+  PreviousIdentifications                       string
+  RecordNumber                                  string
+  RecordedBy                                    string
+  ReproductiveCondition                         string
+  Sex                                           string
+
+=head3 DarwinCore Organism Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  AssociatedOccurrences                         string
+  AssociatedOrganisms                           string
+  OrganismID                                    string
+  OrganismName                                  string
+  OrganismRemarks                               string
+  OrganismScope                                 string
+  PreviousIdentifications                       string
+
+=head3 DarwinCore Record Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  BasisOfRecord                                 string
+  CollectionCode                                string
+  CollectionID                                  string
+  DataGeneralizations                           string
+  DatasetID                                     string
+  DatasetName                                   string
+  DynamicProperties                             string
+  InformationWithheld                           string
+  InstitutionCode                               string
+  InstitutionID                                 string
+  OwnerInstitutionCode                          string
+
+=head3 DarwinCore ResourceRelationship Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  RelatedResourceID                             string
+  RelationshipAccordingTo                       string
+  RelationshipEstablishedDate                   date
+  RelationshipOfResource                        string
+  RelationshipRemarks                           string
+  ResourceID                                    string
+  ResourceRelationshipID                        string
+
+=head3 DarwinCore Taxon Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  AcceptedNameUsage                             string
+  AcceptedNameUsageID                           string
+  Class                                         string
+  Family                                        string
+  Genus                                         string
+  HigherClassification                          string
+  InfraspecificEpithet                          string
+  Kingdom                                       string
+  NameAccordingTo                               string
+  NameAccordingToID                             string
+  NamePublishedIn                               string
+  NamePublishedInID                             string
+  NamePublishedInYear                           string
+  NomenclaturalCode                             string
+  NomenclaturalStatus                           string
+  Order                                         string
+  OriginalNameUsage                             string
+  OriginalNameUsageID                           string
+  ParentNameUsage                               string
+  ParentNameUsageID                             string
+  Phylum                                        string
+  ScientificName                                string
+  ScientificNameAuthorship                      string
+  ScientificNameID                              string
+  SpecificEpithet                               string
+  Subgenus                                      string
+  TaxonConceptID                                string
+  TaxonID                                       string
+  TaxonRank                                     string
+  TaxonRemarks                                  string
+  TaxonomicStatus                               string
+  VerbatimTaxonRank                             string
+  VernacularName                                lang-alt
 
 =head2 FotoStation Tags
@@ -11090,11 +22336,11 @@
   0x0001   IPTC                                 IPTC
   0x0002   SoftEdit                             FotoStation SoftEdit
-  0x0003   ThumbnailImage                       Y
-  0x0004   PreviewImage                         Y
+  0x0003   ThumbnailImage                       yes
+  0x0004   PreviewImage                         yes
 
 =head3 FotoStation SoftEdit Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    OriginalImageWidth                   int32s
       1    OriginalImageHeight                  int32s
@@ -11145,11 +22391,16 @@
 Below is a list of the observed PhotoMechanic XMP tags.  The actual
 namespace prefix is "photomechanic" but ExifTool shortens this in
-the "XMP-photomech" family 1 group name.
+the family 1 group name.
+
+These tags belong to the ExifTool XMP-photomech family 1 group.
 
   Tag Name                                      Writable
   --------                                      --------
+  ColorClass                                    integer
   CountryCode                                   string/
   EditStatus                                    string
+  PMVersion                                     string
   Prefs                                         string
+  Tagged                                        boolean
   TimeCreated                                   string/
 
@@ -11160,17 +22411,22 @@
 Microsoft Photo 1.0 schema XMP tags.  This is likely not a complete list,
 but represents tags which have been observed in sample images.  The actual
-namespace prefix is "MicrosoftPhoto", but ExifTool shortens this to
-"XMP-microsoft" in the family 1 group name.
+namespace prefix is "MicrosoftPhoto", but ExifTool shortens this in the
+family 1 group name.
+
+These tags belong to the ExifTool XMP-microsoft family 1 group.
 
   Tag Name                                      Writable
   --------                                      --------
   CameraSerialNumber                            string
+  CreatorAppID                                  string
+  CreatorOpenWithUIOptions                      string
   DateAcquired                                  date
   FlashManufacturer                             string
   FlashModel                                    string
+  ItemSubType                                   string
   LastKeywordIPTC                               string+
   LastKeywordXMP                                string+
   LensManufacturer                              string
-  LensModel                                     string
+  LensModel                                     string/
   RatingPercent                                 string
 
@@ -11178,7 +22434,13 @@
 
 Microsoft Photo 1.1 schema XMP tags which have been observed.
+
+These tags belong to the ExifTool XMP-MP1 family 1 group.
 
   Tag Name                                      Writable
   --------                                      --------
+  Brightness                                    string/
+  CameraModelID                                 string/
+  Contrast                                      string/
+  ExposureCompensation                          string/
   PanoramicStitchCameraMotion                   string
   PanoramicStitchMapType                        string
@@ -11187,15 +22449,47 @@
   PanoramicStitchTheta0                         real
   PanoramicStitchTheta1                         real
+  PipelineVersion                               string
+  StreamType                                    string
+  WhiteBalance0                                 real
+  WhiteBalance1                                 real
+  WhiteBalance2                                 real
 
 =head3 Microsoft MP Tags
 
 Microsoft Photo 1.2 schema XMP tags which have been observed.
+
+These tags belong to the ExifTool XMP-MP family 1 group.
 
   Tag Name                                      Writable
   --------                                      --------
-  RegionInfoMP                                  RegionInfoMP Struct
-  RegionInfoMPRegions                           Regions Struct_+
+  RegionInfoDateRegionsValid                    date_
+  RegionInfoMP                                  Microsoft RegionInfo Struct
+  RegionInfoRegions                             Microsoft Regions Struct_+
   RegionPersonDisplayName                       string_+
+  RegionPersonEmailDigest                       string_+
+  RegionPersonLiveIdCID                         string_+
+  RegionPersonSourceID                          string_+
   RegionRectangle                               string_+
+
+=head3 Microsoft RegionInfo Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  DateRegionsValid                              date
+  Regions                                       Microsoft Regions Struct+
+
+=head3 Microsoft Regions Struct
+
+Note that PersonLiveIdCID element is called PersonLiveCID according to the
+Microsoft specification, but in practice their software actually writes
+PersonLiveIdCID, so ExifTool uses this too.
+
+  Field Name                                    Writable
+  ----------                                    --------
+  PersonDisplayName                             string
+  PersonEmailDigest                             string
+  PersonLiveIdCID                               string
+  PersonSourceID                                string
+  Rectangle                                     string
 
 =head3 Microsoft Stitch Tags
@@ -11204,6 +22498,6 @@
 Windows Live Photo Gallery.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
       0    PanoramicStitchVersion               int32u
       1    PanoramicStitchCameraMotion          int32u
@@ -11214,4 +22508,461 @@
       6    PanoramicStitchPhi1                  float
 
+=head3 Microsoft Xtra Tags
+
+Tags extracted from the Microsoft "Xtra" atom of QuickTime videos.  Tag ID's
+are not shown because some are unruly GUID's.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Abstract                                      no
+  AccountName                                   no
+  AcquisitionTime                               no
+  AcquisitionTimeDay                            no
+  AcquisitionTimeMonth                          no
+  AcquisitionTimeYear                           no
+  AcquisitionTimeYearMonth                      no
+  AcquisitionTimeYearMonthDay                   no
+  AlbumArtist                                   no
+  AlbumArtist                                   no
+  AlbumArtistSortOrder                          no
+  AlbumCoverURL                                 no
+  AlbumID                                       no
+  AlbumIDAlbumArtist                            no
+  AlbumTitle                                    no
+  AlbumTitle                                    no
+  AlbumTitleSortOrder                           no
+  AlternateSourceURL                            no
+  Anniversary                                   no
+  Artist                                        no
+  AssistantsName                                no
+  AssistantsPhone                               no
+  Attachments                                   no
+  Attributes                                    no
+  AudioBitrate                                  no
+  AudioFormat                                   no
+  AudioSampleRate                               no
+  AudioSampleSize                               no
+  Author                                        no
+  Author                                        no
+  AuthorSortOrder                               no
+  AutoSummary                                   no
+  AverageLevel                                  no
+  BccAddresses                                  no
+  BccNames                                      no
+  Beats-per-minute                              no
+  BeatsPerMinute                                no
+  BillingInformation                            no
+  Birthday                                      no
+  BitDepth                                      no
+  Bitrate                                       no
+  Bitrate                                       no
+  BroadcastDate                                 no
+  BusinessAddress                               no
+  BusinessCity                                  no
+  BusinessCountry-Region                        no
+  BusinessFax                                   no
+  BusinessHomePage                              no
+  BusinessPOBox                                 no
+  BusinessPhone                                 no
+  BusinessPostalCode                            no
+  BusinessStateOrProvince                       no
+  BusinessStreet                                no
+  BuyNow                                        no
+  BuyTickets                                    no
+  CDTrackEnabled                                no
+  CallLetters                                   no
+  CallbackNumber                                no
+  CameraMaker                                   no
+  CameraManufacturer                            no
+  CameraModel                                   no
+  CameraModel                                   no
+  CarPhone                                      no
+  Category                                      no
+  Category                                      no
+  CcAddresses                                   no
+  CcNames                                       no
+  CellPhone                                     no
+  ChannelNumber                                 no
+  Channels                                      no
+  Channels                                      no
+  ChapterNum                                    no
+  Children                                      no
+  City                                          no
+  ClientID                                      no
+  ClosedCaptioning                              no
+  Color                                         no
+  Comment                                       no
+  Comments                                      no
+  Company                                       no
+  CompanyMainPhone                              no
+  Complete                                      no
+  Composer                                      no
+  Composers                                     no
+  Computer                                      no
+  Conductor                                     no
+  Conductors                                    no
+  ContactNames                                  no
+  ContentDistributor                            no
+  ContentDistributorDuration                    no
+  ContentDistributorType                        no
+  ContentGroupDescription                       no
+  ContentType                                   no
+  Contributors                                  no
+  ConversationID                                no
+  Copyright                                     no
+  Copyright                                     no
+  Count                                         no
+  Country-Region                                no
+  Creator                                       no
+  CurrentBitrate                                no
+  DLNAServerUDN                                 no
+  DLNASourceURI                                 no
+  DRMIndividualizedVersion                      no
+  DRMKeyID                                      no
+  DTCPIPHost                                    no
+  DTCPIPPort                                    no
+  DVDID                                         no
+  DataRate                                      no
+  Date                                          no
+  DateAccessed                                  no
+  DateAcquired                                  no
+  DateArchived                                  no
+  DateCompleted                                 no
+  DateCreated                                   no
+  DateImported                                  no
+  DateLastSaved                                 no
+  DateModified                                  no
+  DatePictureTaken                              no
+  DateReceived                                  no
+  DateReleased                                  no
+  DateSent                                      no
+  DateVisited                                   no
+  Department                                    no
+  Description                                   no
+  Description                                   no
+  Description                                   no
+  Dimensions                                    no
+  Director                                      no
+  Directors                                     no
+  DisplayArtist                                 no
+  Division                                      no
+  DocumentID                                    no
+  DueDate                                       no
+  Duration                                      no
+  Duration                                      no
+  Duration                                      no
+  E-mail2                                       no
+  E-mail3                                       no
+  E-mailAddress                                 no
+  E-mailDisplayName                             no
+  E-mailList                                    no
+  EncodedBy                                     no
+  EncodingTime                                  no
+  EndDate                                       no
+  EntryType                                     no
+  EpisodeName                                   no
+  Event                                         no
+  Event                                         no
+  ExifVersion                                   no
+  ExposureBias                                  no
+  ExposureProgram                               no
+  ExposureTime                                  no
+  F-stop                                        no
+  FileAs                                        no
+  FileCount                                     no
+  FileSize                                      no
+  FileType                                      no
+  FileVersion                                   no
+  FirstName                                     no
+  FlagColor                                     no
+  FlagStatus                                    no
+  FlashMode                                     no
+  FocalLength                                   no
+  FocalLength35mm                               no
+  Folder                                        no
+  FolderName                                    no
+  FolderPath                                    no
+  FormatTag                                     no
+  FourCC                                        no
+  FrameHeight                                   no
+  FrameRate                                     no
+  FrameRate                                     no
+  FrameWidth                                    no
+  Free-busyStatus                               no
+  Frequency                                     no
+  FromAddresses                                 no
+  FromNames                                     no
+  FullName                                      no
+  Gender                                        no
+  Genre                                         no
+  Genre                                         no
+  GenreID                                       no
+  GivenName                                     no
+  HasAttachments                                no
+  HasFlag                                       no
+  Hobbies                                       no
+  HomeAddress                                   no
+  HomeCity                                      no
+  HomeCountry-Region                            no
+  HomeFax                                       no
+  HomePOBox                                     no
+  HomePhone                                     no
+  HomePostalCode                                no
+  HomeStateOrProvince                           no
+  HomeStreet                                    no
+  HorizontalResolution                          no
+  IMAddresses                                   no
+  ISOSpeed                                      no
+  Importance                                    no
+  Incomplete                                    no
+  InitialKey                                    no
+  InitialKey                                    no
+  Initials                                      no
+  IsAttachment                                  no
+  IsCompleted                                   no
+  IsDeleted                                     no
+  IsNetworkFeed                                 no
+  IsOnline                                      no
+  IsProtected                                   no
+  IsRecurring                                   no
+  IsVBR                                         no
+  JobTitle                                      no
+  Keywords                                      no
+  Kinds                                         no
+  Label                                         no
+  Language                                      no
+  Language                                      no
+  LastName                                      no
+  LastPrinted                                   no
+  LeadPerformer                                 no
+  LegalTrademarks                               no
+  LensMaker                                     no
+  LensModel                                     no
+  LibraryID                                     no
+  LibraryName                                   no
+  LightSource                                   no
+  LinkStatus                                    no
+  LinkTarget                                    no
+  Location                                      no
+  Location                                      no
+  Lyrics                                        no
+  MCDI                                          no
+  MailingAddress                                no
+  MaxAperture                                   no
+  MediaClassPrimaryID                           no
+  MediaClassSecondaryID                         no
+  MediaContentTypes                             no
+  MediaCreated                                  no
+  MediaOriginalBroadcastDateTime                no
+  MediaOriginalChannel                          no
+  MediaStationName                              no
+  MediaType                                     no
+  MeteringMode                                  no
+  MiddleName                                    no
+  Mileage                                       no
+  ModifiedBy                                    no
+  Mood                                          no
+  Mood                                          no
+  MoreInfo                                      no
+  Name                                          no
+  Nickname                                      no
+  OfficeLocation                                no
+  OfflineAvailability                           no
+  OfflineStatus                                 no
+  OptionalAttendeeAddresses                     no
+  OptionalAttendees                             no
+  OrganizerAddress                              no
+  OrganizerName                                 no
+  Orientation                                   no
+  OriginalAlbumTitle                            no
+  OriginalArtist                                no
+  OriginalLyricist                              no
+  OtherAddress                                  no
+  OtherCity                                     no
+  OtherCountry-Region                           no
+  OtherPOBox                                    no
+  OtherPostalCode                               no
+  OtherStateOrProvince                          no
+  OtherStreet                                   no
+  Owner                                         no
+  POBox                                         no
+  Pager                                         no
+  Pages                                         no
+  ParentalRating                                no
+  ParentalRating                                no
+  ParentalRatingReason                          no
+  PartOfSet                                     no
+  PartOfSet                                     no
+  PartOfSet                                     no
+  Participants                                  no
+  Path                                          no
+  PeakValue                                     no
+  PerceivedType                                 no
+  Period                                        no
+  Period                                        no
+  PersonalTitle                                 no
+  PixelAspectRatioX                             no
+  PixelAspectRatioY                             no
+  PlaylistIndex                                 no
+  PostalCode                                    no
+  PrimaryE-mail                                 no
+  PrimaryPhone                                  no
+  Priority                                      no
+  Producer                                      no
+  Producers                                     no
+  ProductName                                   no
+  ProductVersion                                no
+  Profession                                    no
+  ProgramDescription                            no
+  ProgramMode                                   no
+  ProgramName                                   no
+  Project                                       no
+  Protected                                     no
+  ProtectionType                                no
+  Provider                                      no
+  Provider                                      no
+  ProviderLogoURL                               no
+  ProviderRating                                no
+  ProviderStyle                                 no
+  ProviderURL                                   no
+  Publisher                                     no
+  Publisher                                     no
+  RadioBand                                     no
+  RadioFormat                                   no
+  Rating                                        no
+  RatingOrg                                     no
+  ReadStatus                                    no
+  RecordingTime                                 no
+  RecordingTime                                 no
+  RecordingTimeDay                              no
+  RecordingTimeMonth                            no
+  RecordingTimeYear                             no
+  RecordingTimeYearMonth                        no
+  RecordingTimeYearMonthDay                     no
+  ReleaseDate                                   no
+  ReleaseDateDay                                no
+  ReleaseDateMonth                              no
+  ReleaseDateYear                               no
+  ReleaseDateYearMonth                          no
+  ReleaseDateYearMonthDay                       no
+  ReminderTime                                  no
+  RequestState                                  no
+  RequiredAttendeeAddresses                     no
+  RequiredAttendees                             no
+  Rerun                                         no
+  Resources                                     no
+  SAP                                           no
+  Saturation                                    no
+  SearchRanking                                 no
+  SenderAddress                                 no
+  SenderName                                    no
+  Sensitivity                                   no
+  ShadowFilePath                                no
+  Shared                                        no
+  SharedUserRating                              no
+  SharedWith                                    no
+  Size                                          no
+  Slides                                        no
+  Source                                        no
+  SourceURL                                     no
+  SpaceFree                                     no
+  SpaceUsed                                     no
+  Spouse                                        no
+  StartDate                                     no
+  StateOrProvince                               no
+  StationCallSign                               no
+  StationName                                   no
+  Status                                        no
+  Status                                        no
+  Store                                         no
+  Street                                        no
+  Subject                                       no
+  Subject                                       no
+  SubjectDistance                               no
+  SubscriptionContentID                         no
+  Subtitle                                      no
+  Subtitle                                      no
+  SubtitleDescription                           no
+  Suffix                                        no
+  Summary                                       no
+  Sync01                                        no
+  Sync02                                        no
+  Sync03                                        no
+  Sync04                                        no
+  Sync05                                        no
+  Sync06                                        no
+  Sync07                                        no
+  Sync08                                        no
+  Sync09                                        no
+  Sync10                                        no
+  Sync11                                        no
+  Sync12                                        no
+  Sync13                                        no
+  Sync14                                        no
+  Sync15                                        no
+  Sync16                                        no
+  SyncOnly                                      no
+  SyncState                                     no
+  TTY-TTDPhone                                  no
+  TaskOwner                                     no
+  Telex                                         no
+  Temporary                                     no
+  Title                                         no
+  Title                                         no
+  TitleNum                                      no
+  TitleSortOrder                                no
+  ToAddresses                                   no
+  ToDoTitle                                     no
+  ToNames                                       no
+  TotalBitrate                                  no
+  TotalDuration                                 no
+  TotalEditingTime                              no
+  TotalFileSize                                 no
+  TotalSize                                     no
+  TrackNumber                                   no
+  TrackNumber                                   no
+  TrackingID                                    no
+  Type                                          no
+  Type                                          no
+  URL                                           no
+  UniqueFileIdentifier                          no
+  Untitled0                                     no
+  Untitled1                                     no
+  Untitled2                                     no
+  UserCustom1                                   no
+  UserCustom2                                   no
+  UserEffectiveRating                           no
+  UserLastPlayedTime                            no
+  UserPlayCount                                 no
+  UserPlaycountAfternoon                        no
+  UserPlaycountEvening                          no
+  UserPlaycountMorning                          no
+  UserPlaycountNight                            no
+  UserPlaycountWeekday                          no
+  UserPlaycountWeekend                          no
+  UserRating                                    no
+  UserServiceRating                             no
+  UserWebURL                                    no
+  VerticalResolution                            no
+  VideoBitrate                                  no
+  VideoCompression                              no
+  VideoFormat                                   no
+  VideoFrameRate                                no
+  VideoHeight                                   no
+  VideoWidth                                    no
+  WMCollectionGroupID                           no
+  WMCollectionID                                no
+  WMContentID                                   no
+  WMShadowFileSourceDRMType                     no
+  WMShadowFileSourceFileType                    no
+  Webpage                                       no
+  WhiteBalance                                  no
+  WindowsFileName                               no
+  WordCount                                     no
+  Writer                                        no
+  Writers                                       no
+  Year                                          no
+  Year                                          no
+
 =head2 GIMP Tags
 
@@ -11222,35 +22973,38 @@
   ------   --------                             --------
   'header' Header                               GIMP Header
-  0x0011   Compression                          N
+  0x0011   Compression                          no
   0x0013   Resolution                           GIMP Resolution
+  0x0014   Tattoo                               no
   0x0015   Parasites                            GIMP Parasite
+  0x0016   Units                                no
 
 =head3 GIMP Header Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      9    XCFVersion                           N
-     14    ImageWidth                           N
-     18    ImageHeight                          N
-     22    ColorMode                            N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      9    XCFVersion                           no
+     14    ImageWidth                           no
+     18    ImageHeight                          no
+     22    ColorMode                            no
 
 =head3 GIMP Resolution Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    XResolution                          N
-      1    YResolution                          N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    XResolution                          no
+      1    YResolution                          no
 
 =head3 GIMP Parasite Tags
 
-  Tag ID               Tag Name                 Writable
-  ------               --------                 --------
-  'exif-data'          ExifData                 EXIF
-  'gimp-comment'       Comment                  N
-  'gimp-metadata'      XMP                      XMP
-  'icc-profile'        ICC_Profile              ICC_Profile
-  'icc-profile-name'   ICCProfileName           N
-  'iptc-data'          IPTCData                 IPTC
-  'jpeg-exif-data'     JPEGExifData             EXIF
+  Tag ID                Tag Name                Writable
+  ------                --------                --------
+  'exif-data'           ExifData                EXIF
+  'gimp-comment'        Comment                 no
+  'gimp-image-metadata' XML                     XMP XML
+  'gimp-metadata'       XMP                     XMP
+  'icc-profile'         ICC_Profile             ICC_Profile
+  'icc-profile-name'    ICCProfileName          no
+  'iptc-data'           IPTCData                IPTC
+  'jpeg-exif-data'      JPEGExifData            EXIF
 
 =head2 MIE Tags
@@ -11273,5 +23027,5 @@
 C<TAG-xx_YY>, where C<TAG> is the tag name, C<xx> is a 2-character lower
 case ISO 639-1 language code, and C<YY> is a 2-character upper case ISO
-3166-1 alpha 2 country code (ie. C<Title-en_US>).  But as usual, the user
+3166-1 alpha 2 country code (eg. C<Title-en_US>).  But as usual, the user
 interface is case-insensitive, and ExifTool will write the correct case to
 the file.
@@ -11279,6 +23033,12 @@
 3) Some numerical MIE tags allow units of measurement to be specified.  For
 these tags, units may be added in brackets immediately following the value
-(ie. C<55(mi/h)>).  If no units are specified, the default units are
+(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)
+option is used and Compress::Zlib is available.
+
+See L<https://exiftool.org/MIE1.1-20070121.pdf> for the official MIE
+specification.
 
   Tag ID               Tag Name                 Writable
@@ -11430,5 +23190,5 @@
   'Copyright'          Copyright                string
   'CreateDate'         CreateDate               string
-  'EMail'              EMail                    string
+  'EMail'              Email                    string
   'Keywords'           Keywords                 string+
   'ModifyDate'         ModifyDate               string
@@ -11561,90 +23321,103 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'asoc'   Association                          N
-  'bfil'   BinaryFilter                         N
-  'bpcc'   BitsPerComponent                     N
-  'cdef'   ComponentDefinition                  N
-  'cgrp'   ColorGroup                           N
-  'chck'   DigitalSignature                     N
-  'cmap'   ComponentMapping                     N
-  'colr'   ICC_Profile                          ICC_Profile
-           Colorspace                           N
-           ColorSpecification                   N
-  'comp'   Composition                          N
-  'copt'   CompositionOptions                   N
-  'cref'   Cross-Reference                      N
-  'creg'   CodestreamRegistration               N
-  'drep'   DesiredReproductions                 N
-  'dtbl'   DataReference                        N
-  'flst'   FragmentList                         N
-  'free'   Free                                 N
-  'ftbl'   FragmentTable                        N
+  'asoc'   Association                          Jpeg2000
+  'bfil'   BinaryFilter                         no
+  'bpcc'   BitsPerComponent                     no
+  'cdef'   ComponentDefinition                  no
+  'cgrp'   ColorGroup                           no
+  'chck'   DigitalSignature                     no
+  'cmap'   ComponentMapping                     no
+  'colr'   ColorSpecification                   Jpeg2000 ColorSpec
+  'comp'   Composition                          no
+  'copt'   CompositionOptions                   no
+  'cref'   Cross-Reference                      no
+  'creg'   CodestreamRegistration               no
+  'drep'   DesiredReproductions                 no
+  'dtbl'   DataReference                        no
+  'flst'   FragmentList                         no
+  'free'   Free                                 no
+  'ftbl'   FragmentTable                        no
   'ftyp'   FileType                             Jpeg2000 FileType
-  'gtso'   GraphicsTechnologyStandardOutput     N
+  'gtso'   GraphicsTechnologyStandardOutput     no
   'ihdr'   ImageHeader                          Jpeg2000 ImageHeader
-  'inst'   InstructionSet                       N
-  'jP  '   JP2Signature                         N
-  'jp2c'   ContiguousCodestream                 N
+  'inst'   InstructionSet                       no
+  'jP  '   JP2Signature                         no
+  'jp2c'   ContiguousCodestream                 no
   'jp2h'   JP2Header                            Jpeg2000
   'jp2i'   IntellectualProperty                 XMP
   'jpch'   CodestreamHeader                     Jpeg2000
   'jplh'   CompositingLayerHeader               Jpeg2000
-  'lbl '   Label                                N
-  'mdat'   MediaData                            N
-  'mp7b'   MPEG7Binary                          N
-  'nlst'   NumberList                           N
-  'opct'   Opacity                              N
-  'pclr'   Palette                              N
-  'prfl'   Profile                              N
+  'lbl '   Label                                no
+  'mdat'   MediaData                            no
+  'mp7b'   MPEG7Binary                          no
+  'nlst'   NumberList                           no
+  'opct'   Opacity                              no
+  'pclr'   Palette                              no
+  'prfl'   Profile                              no
   'res '   Resolution                           Jpeg2000
   'resc'   CaptureResolution                    Jpeg2000 CaptureResolution
   'resd'   DisplayResolution                    Jpeg2000 DisplayResolution
-  'roid'   ROIDescription                       N
-  'rreq'   ReaderRequirements                   N
+  'roid'   ROIDescription                       no
+  'rreq'   ReaderRequirements                   no
   'uinf'   UUIDInfo                             Jpeg2000
-  'ulst'   UUIDList                             N
-  'url '   URL                                  N
+  'ulst'   UUIDList                             no
+  'url '   URL                                  no
   'uuid'   UUID-EXIF                            EXIF
+           UUID-EXIF2                           EXIF
+           UUID-EXIF_bad                        EXIF
            UUID-IPTC                            IPTC
+           UUID-IPTC2                           IPTC
            UUID-XMP                             XMP
            UUID-GeoJP2                          EXIF
-           UUID-Unknown                         N
-  'xml '   XML                                  XMP
+           UUID-Photoshop                       Photoshop
+           UUID-Unknown                         no
+  'xml '   XML                                  XMP XML
+
+=head3 Jpeg2000 ColorSpec Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ColorSpecMethod                      no
+      1    ColorSpecPrecedence                  no
+      2    ColorSpecApproximation               no
+      3    ICC_Profile                          ICC_Profile
+           ColorSpace                           no
+           ColorSpecData                        no
 
 =head3 Jpeg2000 FileType Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MajorBrand                           N
-      1    MinorVersion                         N
-      2    CompatibleBrands                     N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    MajorBrand                           no
+      1    MinorVersion                         no
+      2    CompatibleBrands                     no
 
 =head3 Jpeg2000 ImageHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageHeight                          N
-      4    ImageWidth                           N
-      8    NumberOfComponents                   N
-     10    BitsPerComponent                     N
-     11    Compression                          N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageHeight                          no
+      4    ImageWidth                           no
+      8    NumberOfComponents                   no
+     10    BitsPerComponent                     no
+     11    Compression                          no
 
 =head3 Jpeg2000 CaptureResolution Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    CaptureYResolution                   N
-      4    CaptureXResolution                   N
-      8    CaptureYResolutionUnit               N
-      9    CaptureXResolutionUnit               N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    CaptureYResolution                   no
+      4    CaptureXResolution                   no
+      8    CaptureYResolutionUnit               no
+      9    CaptureXResolutionUnit               no
 
 =head3 Jpeg2000 DisplayResolution Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    DisplayYResolution                   N
-      4    DisplayXResolution                   N
-      8    DisplayYResolutionUnit               N
-      9    DisplayXResolutionUnit               N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    DisplayYResolution                   no
+      4    DisplayXResolution                   no
+      8    DisplayYResolutionUnit               no
+      9    DisplayXResolutionUnit               no
 
 =head2 GIF Tags
@@ -11656,20 +23429,44 @@
   Tag Name                                      Writable
   --------                                      --------
-  AnimationExtension                            GIF Animate
-  Comment                                       Y
-  Duration                                      N
-  FrameCount                                    N
-  GIFVersion                                    N
+  Comment                                       yes
+  Duration                                      no
+  Extensions                                    GIF Extensions
+  FrameCount                                    no
+  GIFVersion                                    no
   ScreenDescriptor                              GIF Screen
-  Text                                          N
-  XMPExtension                                  XMP
-
-=head3 GIF Animate Tags
+  Text                                          no
+
+=head3 GIF Extensions Tags
+
+Tags extracted from GIF89a application extensions.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'ICCRGBG1/012'       ICC_Profile              ICC_Profile
+  'MIDICTRL/Jon'       MIDIControl              GIF MIDIControl
+  'MIDISONG/Dm7'       MIDISong                 no
+  'NETSCAPE/2.0'       Animation                GIF Animation
+  'XMP Data/XMP'       XMP                      XMP
+
+=head3 GIF MIDIControl Tags
+
+Information extracted from the MIDI control block extension.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    MIDIControlVersion                   no
+      1    SequenceNumber                       no
+      2    MelodicPolyphony                     no
+      3    PercussivePolyphony                  no
+      4    ChannelUsage                         no
+      6    DelayTime                            no
+
+=head3 GIF Animation Tags
 
 Information extracted from the "NETSCAPE2.0" animation extension.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    AnimationIterations                  N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    AnimationIterations                  no
 
 =head3 GIF Screen Tags
@@ -11677,12 +23474,13 @@
 Information extracted from the GIF logical screen descriptor.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageWidth                           N
-      2    ImageHeight                          N
-    4.1    HasColorMap                          N
-    4.2    ColorResolutionDepth                 N
-    4.3    BitsPerPixel                         N
-      5    BackgroundColor                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageWidth                           no
+      2    ImageHeight                          no
+    4.1    HasColorMap                          no
+    4.2    ColorResolutionDepth                 no
+    4.3    BitsPerPixel                         no
+      5    BackgroundColor                      no
+      6    PixelAspectRatio                     no
 
 =head2 BMP Tags
@@ -11691,16 +23489,31 @@
 of image related information.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      4    ImageWidth                           N
-      8    ImageHeight                          N
-     12    Planes                               N
-     14    BitDepth                             N
-     16    Compression                          N
-     20    ImageLength                          N
-     24    PixelsPerMeterX                      N
-     28    PixelsPerMeterY                      N
-     32    NumColors                            N
-     36    NumImportantColors                   N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    BMPVersion                           no
+      4    ImageWidth                           no
+      8    ImageHeight                          no
+     12    Planes                               no
+     14    BitDepth                             no
+     16    Compression                          no
+     20    ImageLength                          no
+     24    PixelsPerMeterX                      no
+     28    PixelsPerMeterY                      no
+     32    NumColors                            no
+     36    NumImportantColors                   no
+     40    RedMask                              no
+     44    GreenMask                            no
+     48    BlueMask                             no
+     52    AlphaMask                            no
+     56    ColorSpace                           no
+     60    RedEndpoint                          no
+     72    GreenEndpoint                        no
+     84    BlueEndpoint                         no
+     96    GammaRed                             no
+    100    GammaGreen                           no
+    104    GammaBlue                            no
+    108    RenderingIntent                      no
+    112    ProfileDataOffset                    no
+    116    ProfileSize                          no
 
 =head3 BMP OS2 Tags
@@ -11708,10 +23521,48 @@
 Information extracted from OS/2-format BMP images.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      4    ImageWidth                           N
-      6    ImageHeight                          N
-      8    Planes                               N
-     10    BitDepth                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    BMPVersion                           no
+      4    ImageWidth                           no
+      6    ImageHeight                          no
+      8    Planes                               no
+     10    BitDepth                             no
+
+=head3 BMP Extra Tags
+
+Extra information extracted from some BMP images.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  EmbeddedJPG                                   no
+  EmbeddedPNG                                   no
+  ICC_Profile                                   ICC_Profile
+  LinkedProfileName                             no
+
+=head2 BPG Tags
+
+The information listed below is extracted from BPG (Better Portable
+Graphics) images.  See L<http://bellard.org/bpg/> for the specification.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    PixelFormat                          no
+    4.1    Alpha                                no
+    4.2    BitDepth                             no
+    4.3    ColorSpace                           no
+    4.4    Flags                                no
+      6    ImageWidth                           no
+      7    ImageHeight                          no
+      8    ImageLength                          no
+
+=head3 BPG Extensions Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   EXIF                                 EXIF
+  0x0002   ICC_Profile                          ICC_Profile
+  0x0003   XMP                                  XMP
+  0x0004   ThumbnailBPG                         no
+  0x0005   AnimationControl?                    no
 
 =head2 PICT Tags
@@ -11725,150 +23576,150 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   Nop                                  N
-  0x0001   ClipRgn                              N
-  0x0002   BkPat                                N
-  0x0003   TxFont                               N
-  0x0004   TxFace                               N
-  0x0005   TxMode                               N
-  0x0006   SpExtra                              N
-  0x0007   PnSize                               N
-  0x0008   PnMode                               N
-  0x0009   PnPat                                N
-  0x000a   FillPat                              N
-  0x000b   OvSize                               N
-  0x000c   Origin                               N
-  0x000d   TxSize                               N
-  0x000e   FgColor                              N
-  0x000f   BkColor                              N
-  0x0010   TxRatio                              N
-  0x0011   VersionOp                            N
-  0x0012   BkPixPat                             N
-  0x0013   PnPixPat                             N
-  0x0014   FillPixPat                           N
-  0x0015   PnLocHFrac                           N
-  0x0016   ChExtra                              N
-  0x0017   Reserved                             N
-  0x001a   RGBFgCol                             N
-  0x001b   RGBBkCol                             N
-  0x001c   HiliteMode                           N
-  0x001d   HiliteColor                          N
-  0x001e   DefHilite                            N
-  0x001f   OpColor                              N
-  0x0020   Line                                 N
-  0x0021   LineFrom                             N
-  0x0022   ShortLine                            N
-  0x0023   ShortLineFrom                        N
-  0x0024   Reserved                             N
-  0x0028   LongText                             N
-  0x0029   DHText                               N
-  0x002a   DVText                               N
-  0x002b   DHDVText                             N
-  0x002c   FontName                             N
-  0x002d   LineJustify                          N
-  0x002e   GlyphState                           N
-  0x002f   Reserved                             N
-  0x0030   FrameRect                            N
-  0x0031   PaintRect                            N
-  0x0032   EraseRect                            N
-  0x0033   InvertRect                           N
-  0x0034   FillRect                             N
-  0x0035   Reserved                             N
-  0x0038   FrameSameRect                        N
-  0x0039   PaintSameRect                        N
-  0x003a   EraseSameRect                        N
-  0x003b   InvertSameRect                       N
-  0x003c   FillSameRect                         N
-  0x003d   Reserved                             N
-  0x0040   FrameRRect                           N
-  0x0041   PaintRRect                           N
-  0x0042   EraseRRect                           N
-  0x0043   InvertRRect                          N
-  0x0044   FillRRect                            N
-  0x0045   Reserved                             N
-  0x0048   FrameSameRRect                       N
-  0x0049   PaintSameRRect                       N
-  0x004a   EraseSameRRect                       N
-  0x004b   InvertSameRRect                      N
-  0x004c   FillSameRRect                        N
-  0x004d   Reserved                             N
-  0x0050   FrameOval                            N
-  0x0051   PaintOval                            N
-  0x0052   EraseOval                            N
-  0x0053   InvertOval                           N
-  0x0054   FillOval                             N
-  0x0055   Reserved                             N
-  0x0058   FrameSameOval                        N
-  0x0059   PaintSameOval                        N
-  0x005a   EraseSameOval                        N
-  0x005b   InvertSameOval                       N
-  0x005c   FillSameOval                         N
-  0x005d   Reserved                             N
-  0x0060   FrameArc                             N
-  0x0061   PaintArc                             N
-  0x0062   EraseArc                             N
-  0x0063   InvertArc                            N
-  0x0064   FillArc                              N
-  0x0065   Reserved                             N
-  0x0068   FrameSameArc                         N
-  0x0069   PaintSameArc                         N
-  0x006a   EraseSameArc                         N
-  0x006b   InvertSameArc                        N
-  0x006c   FillSameArc                          N
-  0x006d   Reserved                             N
-  0x0070   FramePoly                            N
-  0x0071   PaintPoly                            N
-  0x0072   ErasePoly                            N
-  0x0073   InvertPoly                           N
-  0x0074   FillPoly                             N
-  0x0075   Reserved                             N
-  0x0078   FrameSamePoly                        N
-  0x0079   PaintSamePoly                        N
-  0x007a   EraseSamePoly                        N
-  0x007b   InvertSamePoly                       N
-  0x007c   FillSamePoly                         N
-  0x007d   Reserved                             N
-  0x0080   FrameRgn                             N
-  0x0081   PaintRgn                             N
-  0x0082   EraseRgn                             N
-  0x0083   InvertRgn                            N
-  0x0084   FillRgn                              N
-  0x0085   Reserved                             N
-  0x0088   FrameSameRgn                         N
-  0x0089   PaintSameRgn                         N
-  0x008a   EraseSameRgn                         N
-  0x008b   InvertSameRgn                        N
-  0x008c   FillSameRgn                          N
-  0x008d   Reserved                             N
-  0x0090   BitsRect                             N
-  0x0091   BitsRgn                              N
-  0x0092   Reserved                             N
-  0x0098   PackBitsRect                         N
-  0x0099   PackBitsRgn                          N
-  0x009a   DirectBitsRect                       N
-  0x009b   DirectBitsRgn                        N
-  0x009c   Reserved                             N
-  0x009d   Reserved                             N
-  0x009e   Reserved                             N
-  0x009f   Reserved                             N
-  0x00a0   ShortComment                         N
+  0x0000   Nop                                  no
+  0x0001   ClipRgn                              no
+  0x0002   BkPat                                no
+  0x0003   TxFont                               no
+  0x0004   TxFace                               no
+  0x0005   TxMode                               no
+  0x0006   SpExtra                              no
+  0x0007   PnSize                               no
+  0x0008   PnMode                               no
+  0x0009   PnPat                                no
+  0x000a   FillPat                              no
+  0x000b   OvSize                               no
+  0x000c   Origin                               no
+  0x000d   TxSize                               no
+  0x000e   FgColor                              no
+  0x000f   BkColor                              no
+  0x0010   TxRatio                              no
+  0x0011   VersionOp                            no
+  0x0012   BkPixPat                             no
+  0x0013   PnPixPat                             no
+  0x0014   FillPixPat                           no
+  0x0015   PnLocHFrac                           no
+  0x0016   ChExtra                              no
+  0x0017   Reserved                             no
+  0x001a   RGBFgCol                             no
+  0x001b   RGBBkCol                             no
+  0x001c   HiliteMode                           no
+  0x001d   HiliteColor                          no
+  0x001e   DefHilite                            no
+  0x001f   OpColor                              no
+  0x0020   Line                                 no
+  0x0021   LineFrom                             no
+  0x0022   ShortLine                            no
+  0x0023   ShortLineFrom                        no
+  0x0024   Reserved                             no
+  0x0028   LongText                             no
+  0x0029   DHText                               no
+  0x002a   DVText                               no
+  0x002b   DHDVText                             no
+  0x002c   FontName                             no
+  0x002d   LineJustify                          no
+  0x002e   GlyphState                           no
+  0x002f   Reserved                             no
+  0x0030   FrameRect                            no
+  0x0031   PaintRect                            no
+  0x0032   EraseRect                            no
+  0x0033   InvertRect                           no
+  0x0034   FillRect                             no
+  0x0035   Reserved                             no
+  0x0038   FrameSameRect                        no
+  0x0039   PaintSameRect                        no
+  0x003a   EraseSameRect                        no
+  0x003b   InvertSameRect                       no
+  0x003c   FillSameRect                         no
+  0x003d   Reserved                             no
+  0x0040   FrameRRect                           no
+  0x0041   PaintRRect                           no
+  0x0042   EraseRRect                           no
+  0x0043   InvertRRect                          no
+  0x0044   FillRRect                            no
+  0x0045   Reserved                             no
+  0x0048   FrameSameRRect                       no
+  0x0049   PaintSameRRect                       no
+  0x004a   EraseSameRRect                       no
+  0x004b   InvertSameRRect                      no
+  0x004c   FillSameRRect                        no
+  0x004d   Reserved                             no
+  0x0050   FrameOval                            no
+  0x0051   PaintOval                            no
+  0x0052   EraseOval                            no
+  0x0053   InvertOval                           no
+  0x0054   FillOval                             no
+  0x0055   Reserved                             no
+  0x0058   FrameSameOval                        no
+  0x0059   PaintSameOval                        no
+  0x005a   EraseSameOval                        no
+  0x005b   InvertSameOval                       no
+  0x005c   FillSameOval                         no
+  0x005d   Reserved                             no
+  0x0060   FrameArc                             no
+  0x0061   PaintArc                             no
+  0x0062   EraseArc                             no
+  0x0063   InvertArc                            no
+  0x0064   FillArc                              no
+  0x0065   Reserved                             no
+  0x0068   FrameSameArc                         no
+  0x0069   PaintSameArc                         no
+  0x006a   EraseSameArc                         no
+  0x006b   InvertSameArc                        no
+  0x006c   FillSameArc                          no
+  0x006d   Reserved                             no
+  0x0070   FramePoly                            no
+  0x0071   PaintPoly                            no
+  0x0072   ErasePoly                            no
+  0x0073   InvertPoly                           no
+  0x0074   FillPoly                             no
+  0x0075   Reserved                             no
+  0x0078   FrameSamePoly                        no
+  0x0079   PaintSamePoly                        no
+  0x007a   EraseSamePoly                        no
+  0x007b   InvertSamePoly                       no
+  0x007c   FillSamePoly                         no
+  0x007d   Reserved                             no
+  0x0080   FrameRgn                             no
+  0x0081   PaintRgn                             no
+  0x0082   EraseRgn                             no
+  0x0083   InvertRgn                            no
+  0x0084   FillRgn                              no
+  0x0085   Reserved                             no
+  0x0088   FrameSameRgn                         no
+  0x0089   PaintSameRgn                         no
+  0x008a   EraseSameRgn                         no
+  0x008b   InvertSameRgn                        no
+  0x008c   FillSameRgn                          no
+  0x008d   Reserved                             no
+  0x0090   BitsRect                             no
+  0x0091   BitsRgn                              no
+  0x0092   Reserved                             no
+  0x0098   PackBitsRect                         no
+  0x0099   PackBitsRgn                          no
+  0x009a   DirectBitsRect                       no
+  0x009b   DirectBitsRgn                        no
+  0x009c   Reserved                             no
+  0x009d   Reserved                             no
+  0x009e   Reserved                             no
+  0x009f   Reserved                             no
+  0x00a0   ShortComment                         no
   0x00a1   LongComment                          Photoshop
                                                 ICC_Profile
-  0x00a2   Reserved                             N
-  0x00b0   Reserved                             N
-  0x00d0   Reserved                             N
-  0x00ff   OpEndPic                             N
-  0x0100   Reserved                             N
-  0x0200   Reserved                             N
-  0x02ff   Version                              N
-  0x0300   Reserved                             N
-  0x0bff   Reserved                             N
-  0x0c00   HeaderOp                             N
-  0x0c01   Reserved                             N
-  0x7f00   Reserved                             N
-  0x8000   Reserved                             N
-  0x8100   Reserved                             N
-  0x8200   CompressedQuickTime                  N
-  0x8201   UncompressedQuickTime                N
-  0xffff   Reserved                             N
+  0x00a2   Reserved                             no
+  0x00b0   Reserved                             no
+  0x00d0   Reserved                             no
+  0x00ff   OpEndPic                             no
+  0x0100   Reserved                             no
+  0x0200   Reserved                             no
+  0x02ff   Version                              no
+  0x0300   Reserved                             no
+  0x0bff   Reserved                             no
+  0x0c00   HeaderOp                             no
+  0x0c01   Reserved                             no
+  0x7f00   Reserved                             no
+  0x8000   Reserved                             no
+  0x8100   Reserved                             no
+  0x8200   CompressedQuickTime                  no
+  0x8201   UncompressedQuickTime                no
+  0xffff   Reserved                             no
 
 =head2 PNG Tags
@@ -11878,58 +23729,92 @@
 specification.
 
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  'IHDR'   ImageHeader                          PNG ImageHeader
-  'PLTE'   Palette                              N
-  'bKGD'   BackgroundColor                      N
-  'cHRM'   PrimaryChromaticities                PNG PrimaryChromaticities
-  'dSIG'   DigitalSignature                     N
-  'fRAc'   FractalParameters                    N
-  'gAMA'   Gamma                                N
-  'gIFg'   GIFGraphicControlExtension           N
-  'gIFt'   GIFPlainTextExtension                N
-  'gIFx'   GIFApplicationExtension              N
-  'hIST'   PaletteHistogram                     N
-  'iCCP'   ICC_Profile                          ICC_Profile
-  'iTXt'   InternationalText                    PNG TextualData
-  'oFFs'   ImageOffset                          N
-  'pCAL'   PixelCalibration                     N
-  'pHYs'   PhysicalPixel                        PNG PhysicalPixel
-  'sBIT'   SignificantBits                      N
-  'sCAL'   SubjectScale                         PNG SubjectScale
-  'sPLT'   SuggestedPalette                     N
-  'sRGB'   SRGBRendering                        N
-  'sTER'   StereoImage                          PNG StereoImage
-  'tEXt'   TextualData                          PNG TextualData
-  'tIME'   ModifyDate                           Y
-  'tRNS'   Transparency                         N
-  'tXMP'   XMP                                  XMP
-  'vpAg'   VirtualPage                          PNG VirtualPage
-  'zTXt'   CompressedText                       PNG TextualData
+According to the specification, a PNG file should end at the IEND chunk,
+however ExifTool will preserve any data found after this when writing unless
+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
+  'PLTE'             Palette                    no
+  'acTL'             AnimationControl           PNG AnimationControl
+  'bKGD'             BackgroundColor            no
+  'cHRM'             PrimaryChromaticities      PNG PrimaryChromaticities
+  'dSIG'             DigitalSignature           no
+  'eXIf'             eXIf                       EXIF
+  'fRAc'             FractalParameters          no
+  'gAMA'             Gamma                      no
+  'gIFg'             GIFGraphicControlExtension no
+  'gIFt'             GIFPlainTextExtension      no
+  'gIFx'             GIFApplicationExtension    no
+  'hIST'             PaletteHistogram           no
+  'iCCP'             ICC_Profile                ICC_Profile
+  'iCCP-name'        ProfileName                no
+  'iDOT'             AppleDataOffsets           no
+  'iTXt'             InternationalText          PNG TextualData
+  'oFFs'             ImageOffset                no
+  'pCAL'             PixelCalibration           no
+  'pHYs'             PhysicalPixel              PNG PhysicalPixel
+  'sBIT'             SignificantBits            no
+  'sCAL'             SubjectScale               PNG SubjectScale
+  'sPLT'             SuggestedPalette           no
+  'sRGB'             SRGBRendering              no
+  'sTER'             StereoImage                PNG StereoImage
+  'tEXt'             TextualData                PNG TextualData
+  'tIME'             ModifyDate                 yes
+  'tRNS'             Transparency               no
+  'tXMP'             XMP                        XMP
+  'vpAg'             VirtualPage                PNG VirtualPage
+  'zTXt'             CompressedText             PNG TextualData
+  'zxIf'             zxIf                       EXIF
 
 =head3 PNG ImageHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageWidth                           N
-      4    ImageHeight                          N
-      8    BitDepth                             N
-      9    ColorType                            N
-     10    Compression                          N
-     11    Filter                               N
-     12    Interlace                            N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageWidth                           no
+      4    ImageHeight                          no
+      8    BitDepth                             no
+      9    ColorType                            no
+     10    Compression                          no
+     11    Filter                               no
+     12    Interlace                            no
+
+=head3 PNG AnimationControl Tags
+
+Tags found in the Animation Control chunk.  See
+L<https://wiki.mozilla.org/APNG_Specification> for details.
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    AnimationFrames                      no
+      1    AnimationPlays                       no
 
 =head3 PNG PrimaryChromaticities Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    WhitePointX                          N
-      1    WhitePointY                          N
-      2    RedX                                 N
-      3    RedY                                 N
-      4    GreenX                               N
-      5    GreenY                               N
-      6    BlueX                                N
-      7    BlueY                                N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    WhitePointX                          no
+      1    WhitePointY                          no
+      2    RedX                                 no
+      3    RedY                                 no
+      4    GreenX                               no
+      5    GreenY                               no
+      6    BlueX                                no
+      7    BlueY                                no
 
 =head3 PNG TextualData Tags
@@ -11938,5 +23823,6 @@
 listed below are the only ones that can be written (unless new user-defined
 tags are added via the configuration file), however ExifTool will extract
-any other TextualData tags that are found.
+any other TextualData tags that are found.  All TextualData tags (including
+tags not listed below) are removed when deleting all PNG tags.
 
 These tags may be stored as tEXt, zTXt or iTXt chunks in the PNG image.  By
@@ -11950,5 +23836,5 @@
 
 Alternate languages are accessed by suffixing the tag name with a '-',
-followed by an RFC 3066 language code (ie. "PNG:Comment-fr", or
+followed by an RFC 3066 language code (eg. "PNG:Comment-fr", or
 "Title-en-US").  See L<http://www.ietf.org/rfc/rfc3066.txt> for the RFC 3066
 specification.
@@ -11962,4 +23848,5 @@
   'Artist'                Artist                string
   'Author'                Author                string
+  'Collection'            Collection            string
   'Comment'               Comment               string
   'Copyright'             Copyright             string
@@ -11971,4 +23858,5 @@
   'Make'                  Make                  string
   'Model'                 Model                 string
+  'Raw profile type 8bim' Photoshop_Profile     Photoshop
   'Raw profile type APP1' APP1_Profile          EXIF
                                                 XMP
@@ -11990,31 +23878,35 @@
 =head3 PNG PhysicalPixel Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    PixelsPerUnitX                       N
-      4    PixelsPerUnitY                       N
-      8    PixelUnits                           N
+These tags are found in the PNG pHYs chunk and belong to the PNG-pHYs family
+1 group.  They are all created together with default values if necessary
+when any of these tags is written, and may only be deleted as a group.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PixelsPerUnitX                       int32u
+      4    PixelsPerUnitY                       int32u
+      8    PixelUnits                           int8u
 
 =head3 PNG SubjectScale Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    SubjectUnits                         N
-      1    SubjectPixelWidth                    N
-      2    SubjectPixelHeight                   N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    SubjectUnits                         no
+      1    SubjectPixelWidth                    no
+      2    SubjectPixelHeight                   no
 
 =head3 PNG StereoImage Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    StereoMode                           N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    StereoMode                           no
 
 =head3 PNG VirtualPage Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    VirtualImageWidth                    N
-      1    VirtualImageHeight                   N
-      2    VirtualPageUnits                     N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    VirtualImageWidth                    no
+      1    VirtualImageHeight                   no
+      2    VirtualPageUnits                     no
 
 =head2 MNG Tags
@@ -12031,10 +23923,10 @@
   'CLIP'   ClipObjects                          MNG ClipObjects
   'CLON'   CloneObject                          MNG CloneObject
-  'DBYK'   DropByKeyword                        N
+  'DBYK'   DropByKeyword                        no
   'DEFI'   DefineObject                         MNG DefineObject
   'DHDR'   DeltaPNGHeader                       MNG DeltaPNGHeader
-  'DISC'   DiscardObjects                       N
-  'DROP'   DropChunks                           N
-  'FRAM'   Frame                                N
+  'DISC'   DiscardObjects                       no
+  'DROP'   DropChunks                           no
+  'FRAM'   Frame                                no
   'JHDR'   JNGHeader                            MNG JNGHeader
   'LOOP'   Loop                                 MNG Loop
@@ -12042,202 +23934,220 @@
   'MHDR'   MNGHeader                            MNG MNGHeader
   'MOVE'   MoveObjects                          MNG MoveObjects
-  'ORDR'   OrderingRestrictions                 N
+  'ORDR'   OrderingRestrictions                 no
   'PAST'   PasteImage                           MNG PasteImage
-  'PPLT'   PartialPalette                       N
+  'PPLT'   PartialPalette                       no
   'PROM'   PromoteParent                        MNG PromoteParent
-  'SAVE'   SaveObjects                          N
-  'SEEK'   SeekPoint                            N
+  'SAVE'   SaveObjects                          no
+  'SEEK'   SeekPoint                            no
   'SHOW'   ShowObjects                          MNG ShowObjects
   'TERM'   TerminationAction                    MNG TerminationAction
   'eXPi'   ExportImage                          MNG ExportImage
   'fPRI'   FramePriority                        MNG FramePriority
-  'nEED'   ResourcesNeeded                      N
+  'nEED'   ResourcesNeeded                      no
   'pHYg'   GlobalPixelSize                      PNG PhysicalPixel
 
 =head3 MNG Background Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    BackgroundColor                      N
-      6    MandatoryBackground                  N
-      7    BackgroundImageID                    N
-      9    BackgroundTiling                     N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    BackgroundColor                      no
+      6    MandatoryBackground                  no
+      7    BackgroundImageID                    no
+      9    BackgroundTiling                     no
 
 =head3 MNG BasisObject Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageWidth                           N
-      4    ImageHeight                          N
-      8    BitDepth                             N
-      9    ColorType                            N
-     10    Compression                          N
-     11    Filter                               N
-     12    Interlace                            N
-     13    RedSample                            N
-     17    GreenSample                          N
-     21    BlueSample                           N
-     25    AlphaSample                          N
-     26    Viewable                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageWidth                           no
+      4    ImageHeight                          no
+      8    BitDepth                             no
+      9    ColorType                            no
+     10    Compression                          no
+     11    Filter                               no
+     12    Interlace                            no
+     13    RedSample                            no
+     17    GreenSample                          no
+     21    BlueSample                           no
+     25    AlphaSample                          no
+     26    Viewable                             no
 
 =head3 MNG ClipObjects Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FirstObject                          N
-      2    LastObject                           N
-      4    DeltaType                            N
-      5    ClipBoundary                         N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FirstObject                          no
+      2    LastObject                           no
+      4    DeltaType                            no
+      5    ClipBoundary                         no
 
 =head3 MNG CloneObject Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    SourceID                             N
-      2    CloneID                              N
-      4    CloneType                            N
-      5    DoNotShow                            N
-      6    ConcreteFlag                         N
-      7    LocalDeltaType                       N
-      8    DeltaXY                              N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    SourceID                             no
+      2    CloneID                              no
+      4    CloneType                            no
+      5    DoNotShow                            no
+      6    ConcreteFlag                         no
+      7    LocalDeltaType                       no
+      8    DeltaXY                              no
 
 =head3 MNG DefineObject Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ObjectID                             N
-      2    DoNotShow                            N
-      3    ConcreteFlag                         N
-      4    XYLocation                           N
-     12    ClippingBoundary                     N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ObjectID                             no
+      2    DoNotShow                            no
+      3    ConcreteFlag                         no
+      4    XYLocation                           no
+     12    ClippingBoundary                     no
 
 =head3 MNG DeltaPNGHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ObjectID                             N
-      2    ImageType                            N
-      3    DeltaType                            N
-      4    BlockSize                            N
-     12    BlockLocation                        N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ObjectID                             no
+      2    ImageType                            no
+      3    DeltaType                            no
+      4    BlockSize                            no
+     12    BlockLocation                        no
 
 =head3 MNG JNGHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageWidth                           N
-      4    ImageHeight                          N
-      8    ColorType                            N
-      9    BitDepth                             N
-     10    Compression                          N
-     11    Interlace                            N
-     12    AlphaBitDepth                        N
-     13    AlphaCompression                     N
-     14    AlphaFilter                          N
-     15    AlphaInterlace                       N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageWidth                           no
+      4    ImageHeight                          no
+      8    ColorType                            no
+      9    BitDepth                             no
+     10    Compression                          no
+     11    Interlace                            no
+     12    AlphaBitDepth                        no
+     13    AlphaCompression                     no
+     14    AlphaFilter                          no
+     15    AlphaInterlace                       no
 
 =head3 MNG Loop Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    NestLevel                            N
-      1    IterationCount                       N
-      5    TerminationCondition                 N
-      6    IterationMinMax                      N
-     14    SignalNumber                         N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    NestLevel                            no
+      1    IterationCount                       no
+      5    TerminationCondition                 no
+      6    IterationMinMax                      no
+     14    SignalNumber                         no
 
 =head3 MNG MagnifyObject Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FirstObjectID                        N
-      2    LastObjectID                         N
-      4    XMethod                              N
-      5    XMag                                 N
-      7    YMag                                 N
-      9    LeftMag                              N
-     11    RightMag                             N
-     13    TopMag                               N
-     15    BottomMag                            N
-     17    YMethod                              N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FirstObjectID                        no
+      2    LastObjectID                         no
+      4    XMethod                              no
+      5    XMag                                 no
+      7    YMag                                 no
+      9    LeftMag                              no
+     11    RightMag                             no
+     13    TopMag                               no
+     15    BottomMag                            no
+     17    YMethod                              no
 
 =head3 MNG MNGHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageWidth                           N
-      1    ImageHeight                          N
-      2    TicksPerSecond                       N
-      3    NominalLayerCount                    N
-      4    NominalFrameCount                    N
-      5    NominalPlayTime                      N
-      6    SimplicityProfile                    N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageWidth                           no
+      1    ImageHeight                          no
+      2    TicksPerSecond                       no
+      3    NominalLayerCount                    no
+      4    NominalFrameCount                    no
+      5    NominalPlayTime                      no
+      6    SimplicityProfile                    no
 
 =head3 MNG MoveObjects Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FirstObject                          N
-      2    LastObject                           N
-      4    DeltaType                            N
-      5    DeltaXY                              N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FirstObject                          no
+      2    LastObject                           no
+      4    DeltaType                            no
+      5    DeltaXY                              no
 
 =head3 MNG PasteImage Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    DestinationID                        N
-      2    TargetDeltaType                      N
-      3    TargetXY                             N
-     11    SourceID                             N
-     13    CompositionMode                      N
-     14    Orientation                          N
-     15    OffsetOrigin                         N
-     16    OffsetXY                             N
-     24    BoundaryOrigin                       N
-     25    PastClippingBoundary                 N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    DestinationID                        no
+      2    TargetDeltaType                      no
+      3    TargetXY                             no
+     11    SourceID                             no
+     13    CompositionMode                      no
+     14    Orientation                          no
+     15    OffsetOrigin                         no
+     16    OffsetXY                             no
+     24    BoundaryOrigin                       no
+     25    PastClippingBoundary                 no
 
 =head3 MNG PromoteParent Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    NewColorType                         N
-      1    NewBitDepth                          N
-      2    FillMethod                           N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    NewColorType                         no
+      1    NewBitDepth                          no
+      2    FillMethod                           no
 
 =head3 MNG ShowObjects Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FirstObject                          N
-      2    LastObject                           N
-      4    ShowMode                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FirstObject                          no
+      2    LastObject                           no
+      4    ShowMode                             no
 
 =head3 MNG TerminationAction Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    TerminationAction                    N
-      1    IterationEndAction                   N
-      2    Delay                                N
-      6    IterationMax                         N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    TerminationAction                    no
+      1    IterationEndAction                   no
+      2    Delay                                no
+      6    IterationMax                         no
 
 =head3 MNG ExportImage Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    SnapshotID                           N
-      2    SnapshotName                         N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    SnapshotID                           no
+      2    SnapshotName                         no
 
 =head3 MNG FramePriority Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    DeltaType                            N
-      2    Priority                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    DeltaType                            no
+      2    Priority                             no
+
+=head2 FLIF Tags
+
+Information extracted from Free Lossless Image Format files.  See
+L<http://flif.info/> for more information.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageType                            no
+      1    BitDepth                             no
+      2    ImageWidth                           no
+      3    ImageHeight                          no
+      4    AnimationFrames                      no
+      5    Encoding                             no
+  'eXif'   EXIF                                 EXIF
+  'eXmp'   XMP                                  XMP
+  'iCCP'   ICC_Profile                          ICC_Profile
 
 =head2 DjVu Tags
 
-Information is extracted from the following chunks in DjVu images.
+Information is extracted from the following chunks in DjVu images. See
+L<http://www.djvu.org/> for the DjVu specification.
 
   Tag ID   Tag Name                             Writable
@@ -12246,5 +24156,5 @@
   'ANTz'   CompressedAnnotation                 DjVu Ant
   'FORM'   FORM                                 DjVu Form
-  'INCL'   IncludedFileID                       N
+  'INCL'   IncludedFileID                       no
   'INFO'   INFO                                 DjVu Info
 
@@ -12264,78 +24174,162 @@
 documentation endorses tags borrowed from two standards: 1) BibTeX
 bibliography system tags (all lowercase Tag ID's in the table below), and 2)
-PDF DocInfo tags (uppercase Tag ID's).
+PDF DocInfo tags (capitalized Tag ID's).
 
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Author'             Author                   N
-  'CreationDate'       CreateDate               N
-  'Creator'            Creator                  N
-  'Keywords'           Keywords                 N
-  'ModDate'            ModifyDate               N
-  'Producer'           Producer                 N
-  'Subject'            Subject                  N
-  'Title'              Title                    N
-  'Trapped'            Trapped                  N
-  'address'            Address                  N
-  'annote'             Annotation               N
-  'author'             Author                   N
-  'booktitle'          BookTitle                N
-  'chapter'            Chapter                  N
-  'crossref'           CrossRef                 N
-  'edition'            Edition                  N
-  'eprint'             EPrint                   N
-  'howpublished'       HowPublished             N
-  'institution'        Institution              N
-  'journal'            Journal                  N
-  'key'                Key                      N
-  'month'              Month                    N
-  'note'               Note                     N
-  'number'             Number                   N
-  'organization'       Organization             N
-  'pages'              Pages                    N
-  'publisher'          Publisher                N
-  'school'             School                   N
-  'series'             Series                   N
-  'title'              Title                    N
-  'type'               Type                     N
-  'url'                URL                      N
-  'volume'             Volume                   N
-  'year'               Year                     N
+  'Author'             Author                   no
+  'CreationDate'       CreateDate               no
+  'Creator'            Creator                  no
+  'Keywords'           Keywords                 no
+  'ModDate'            ModifyDate               no
+  'Producer'           Producer                 no
+  'Subject'            Subject                  no
+  'Title'              Title                    no
+  'Trapped'            Trapped                  no
+  'address'            Address                  no
+  'annote'             Annotation               no
+  'author'             Author                   no
+  'booktitle'          BookTitle                no
+  'chapter'            Chapter                  no
+  'crossref'           CrossRef                 no
+  'edition'            Edition                  no
+  'eprint'             EPrint                   no
+  'howpublished'       HowPublished             no
+  'institution'        Institution              no
+  'journal'            Journal                  no
+  'key'                Key                      no
+  'month'              Month                    no
+  'note'               Note                     no
+  'number'             Number                   no
+  'organization'       Organization             no
+  'pages'              Pages                    no
+  'publisher'          Publisher                no
+  'school'             School                   no
+  'series'             Series                   no
+  'title'              Title                    no
+  'type'               Type                     no
+  'url'                URL                      no
+  'volume'             Volume                   no
+  'year'               Year                     no
 
 =head3 DjVu Form Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    SubfileType                          N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    SubfileType                          no
 
 =head3 DjVu Info Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageWidth                           N
-      2    ImageHeight                          N
-      4    DjVuVersion                          N
-      6    SpatialResolution                    N
-      8    Gamma                                N
-      9    Orientation                          N
-
-=head2 PGF Tags
-
-The following table lists information extracted from the header of
-Progressive Graphics File (PGF) images.  As well, information is extracted
-from the embedded PNG metadata image if it exists.  See
-L<http://www.libpgf.org/> for the PGF specification.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      3    PGFVersion                           N
-      8    ImageWidth                           N
-     12    ImageHeight                          N
-     16    PyramidLevels                        N
-     17    Quality                              N
-     18    BitsPerPixel                         N
-     19    ColorComponents                      N
-     20    ColorMode                            N
-     21    BackgroundColor                      N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageWidth                           no
+      2    ImageHeight                          no
+      4    DjVuVersion                          no
+      6    SpatialResolution                    no
+      8    Gamma                                no
+      9    Orientation                          no
+
+=head2 DPX Tags
+
+Tags extracted from DPX (Digital Picture Exchange) images.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ByteOrder                            no
+      8    HeaderVersion                        no
+     16    DPXFileSize                          no
+     20    DittoKey                             no
+     36    ImageFileName                        no
+    136    CreateDate                           no
+    160    Creator                              no
+    260    Project                              no
+    460    Copyright                            no
+    660    EncryptionKey                        no
+    768    Orientation                          no
+    770    ImageElements                        no
+    772    ImageWidth                           no
+    776    ImageHeight                          no
+    780    DataSign                             no
+    800    ComponentsConfiguration              no
+    801    TransferCharacteristic               no
+    802    ColorimetricSpecification            no
+    803    BitDepth                             no
+    820    ImageDescription                     no
+    892    Image2Description                    no
+    964    Image3Description                    no
+   1036    Image4Description                    no
+   1108    Image5Description                    no
+   1180    Image6Description                    no
+   1252    Image7Description                    no
+   1324    Image8Description                    no
+   1432    SourceFileName                       no
+   1532    SourceCreateDate                     no
+   1556    InputDeviceName                      no
+   1588    InputDeviceSerialNumber              no
+   1724    OriginalFrameRate                    no
+   1728    ShutterAngle                         no
+   1732    FrameID                              no
+   1764    SlateInformation                     no
+   1920    TimeCode                             no
+   1940    FrameRate                            no
+   1972    Reserved5?                           no
+   2048    UserID                               no
+
+=head2 OpenEXR Tags
+
+Information extracted from EXR images.  See L<http://www.openexr.com/> for
+the official specification.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  '_lay'               Layout                   no
+  '_ver'               EXRVersion               no
+  'adoptedNeutral'     AdoptedNeutral           no
+  'altitude'           GPSAltitude              no
+  'aperture'           Aperture                 no
+  'capDate'            DateTimeOriginal         no
+  'channels'           Channels                 no
+  'chromaticities'     Chromaticities           no
+  'comments'           Comments                 no
+  'compression'        Compression              no
+  'dataWindow'         DataWindow               no
+  'displayWindow'      DisplayWindow            no
+  'envmap'             EnvironmentMap           no
+  'expTime'            ExposureTime             no
+  'focus'              FocusDistance            no
+  'framesPerSecond'    FramesPerSecond          no
+  'isoSpeed'           ISO                      no
+  'keyCode'            KeyCode                  no
+  'latitude'           GPSLatitude              no
+  'lineOrder'          LineOrder                no
+  'longitude'          GPSLongitude             no
+  'lookModTransform'   LookModTransform         no
+  'multiView'          MultiView                no
+  'owner'              Owner                    no
+  'pixelAspectRatio'   PixelAspectRatio         no
+  'preview'            Preview                  no
+  'renderingTransform' RenderingTransform       no
+  'screenWindowCenter' ScreenWindowCenter       no
+  'screenWindowWidth'  ScreenWindowWidth        no
+  'tiles'              Tiles                    no
+  'timeCode'           TimeCode                 no
+  'utcOffset'          TimeZone                 no
+  'whiteLuminance'     WhiteLuminance           no
+  'worldToCamera'      WorldToCamera            no
+  'worldToNDC'         WorldToNDC               no
+  'wrapmodes'          WrapModes                no
+  'xDensity'           XResolution              no
+
+=head2 ZISRAW Tags
+
+As well as the header information listed below, ExifTool also extracts the
+top-level XML-based metadata from Zeiss Integrated Software RAW (ZISRAW) CZI
+files.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     32    ZISRAWVersion                        no
+     48    PrimaryFileGUID                      no
+     64    FileGUID                             no
 
 =head2 MIFF Tags
@@ -12347,25 +24341,25 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'background-color'   BackgroundColor          N
-  'blue-primary'       BluePrimary              N
-  'border-color'       BorderColor              N
-  'class'              Class                    N
-  'colors'             Colors                   N
-  'colorspace'         Colorspace               N
-  'columns'            ImageWidth               N
-  'compression'        Compression              N
-  'delay'              Delay                    N
-  'depth'              Depth                    N
-  'dispose'            Dispose                  N
-  'gamma'              Gamma                    N
-  'green-primary'      GreenPrimary             N
-  'id'                 ID                       N
-  'iterations'         Iterations               N
-  'label'              Label                    N
-  'matt-color'         MattColor                N
-  'matte'              Matte                    N
-  'montage'            Montage                  N
-  'packets'            Packets                  N
-  'page'               Page                     N
+  'background-color'   BackgroundColor          no
+  'blue-primary'       BluePrimary              no
+  'border-color'       BorderColor              no
+  'class'              Class                    no
+  'colors'             Colors                   no
+  'colorspace'         ColorSpace               no
+  'columns'            ImageWidth               no
+  'compression'        Compression              no
+  'delay'              Delay                    no
+  'depth'              Depth                    no
+  'dispose'            Dispose                  no
+  'gamma'              Gamma                    no
+  'green-primary'      GreenPrimary             no
+  'id'                 ID                       no
+  'iterations'         Iterations               no
+  'label'              Label                    no
+  'matt-color'         MattColor                no
+  'matte'              Matte                    no
+  'montage'            Montage                  no
+  'packets'            Packets                  no
+  'page'               Page                     no
   'profile-APP1'       APP1_Profile             EXIF
                                                 XMP
@@ -12374,12 +24368,53 @@
   'profile-iptc'       IPTC_Profile             Photoshop
   'profile-xmp'        XMP_Profile              XMP
-  'red-primary'        RedPrimary               N
-  'rendering-intent'   RenderingIntent          N
-  'resolution'         Resolution               N
-  'rows'               ImageHeight              N
-  'scene'              Scene                    N
-  'signature'          Signature                N
-  'units'              Units                    N
-  'white-point'        WhitePoint               N
+  'red-primary'        RedPrimary               no
+  'rendering-intent'   RenderingIntent          no
+  'resolution'         Resolution               no
+  'rows'               ImageHeight              no
+  'scene'              Scene                    no
+  'signature'          Signature                no
+  '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
+Progressive Graphics File (PGF) images.  As well, information is extracted
+from the embedded PNG metadata image if it exists.  See
+L<http://www.libpgf.org/> for the PGF specification.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    PGFVersion                           no
+      8    ImageWidth                           no
+     12    ImageHeight                          no
+     16    PyramidLevels                        no
+     17    Quality                              no
+     18    BitsPerPixel                         no
+     19    ColorComponents                      no
+     20    ColorMode                            no
+     21    BackgroundColor                      no
 
 =head2 PSP Tags
@@ -12390,5 +24425,5 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'FileVersion'        FileVersion              N
+  'FileVersion'        FileVersion              no
   0x0000               ImageInfo                PSP Image
                                                 PSP Image
@@ -12398,14 +24433,14 @@
 =head3 PSP Image Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ImageWidth                           N
-      4    ImageHeight                          N
-      8    ImageResolution                      N
-     16    ResolutionUnit                       N
-     17    Compression                          N
-     19    BitsPerSample                        N
-     21    Planes                               N
-     23    NumColors                            N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ImageWidth                           no
+      4    ImageHeight                          no
+      8    ImageResolution                      no
+     16    ResolutionUnit                       no
+     17    Compression                          no
+     19    BitsPerSample                        no
+     21    Planes                               no
+     23    NumColors                            no
 
 =head3 PSP Creator Tags
@@ -12413,12 +24448,12 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   Title                                N
-  0x0001   CreateDate                           N
-  0x0002   ModifyDate                           N
-  0x0003   Artist                               N
-  0x0004   Copyright                            N
-  0x0005   Description                          N
-  0x0006   CreatorAppID                         N
-  0x0007   CreatorAppVersion                    N
+  0x0000   Title                                no
+  0x0001   CreateDate                           no
+  0x0002   ModifyDate                           no
+  0x0003   Artist                               no
+  0x0004   Copyright                            no
+  0x0005   Description                          no
+  0x0006   CreatorAppID                         no
+  0x0007   CreatorAppVersion                    no
 
 =head3 PSP Ext Tags
@@ -12427,4 +24462,60 @@
   ------   --------                             --------
   0x0003   EXIFInfo                             EXIF
+
+=head2 PhotoCD Tags
+
+Tags extracted from Kodak Photo CD Image Pac (PCD) files.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      7    SpecificationVersion                 no
+      9    AuthoringSoftwareRelease             no
+     11    ImageMagnificationDescriptor         no
+     13    CreateDate                           no
+     17    ModifyDate                           no
+     21    ImageMedium                          no
+     22    ProductType                          no
+     42    ScannerVendorID                      no
+     62    ScannerProductID                     no
+     78    ScannerFirmwareVersion               no
+     82    ScannerFirmwareDate                  no
+     90    ScannerSerialNumber                  no
+    110    ScannerPixelSize                     no
+    112    ImageWorkstationMake                 no
+    132    CharacterSet                         no
+    133    CharacterEscapeSequence?             no
+    165    PhotoFinisherName                    no
+    228    SceneBalanceAlgorithmRevision        no
+    230    SceneBalanceAlgorithmCommand         no
+    325    SceneBalanceAlgorithmFilmID          no
+    331    CopyrightStatus                      no
+    332    CopyrightFileName                    no
+   1538    Orientation                          no
+  1538.1   ImageWidth                           no
+  1538.2   ImageHeight                          no
+  1538.3   CompressionClass                     no
+
+=head2 Radiance Tags
+
+Information extracted from Radiance RGBE HDR images.  Tag ID's are all
+uppercase as stored in the file, but converted to lowercase by when
+extracting to avoid conflicts with internal ExifTool variables.  See
+L<http://radsite.lbl.gov/radiance/refer/filefmts.pdf> and
+L<http://www.graphics.cornell.edu/online/formats/rgbe/> for the
+specification.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  '_command'           Command                  no
+  '_comment'           Comment                  no
+  '_orient'            Orientation              no
+  'colorcorr'          ColorCorrection          no
+  'exposure'           Exposure                 no
+  'format'             Format                   no
+  'gamma'              Gamma                    no
+  'pixaspect'          PixelAspectRatio         no
+  'primaries'          ColorPrimaries           no
+  'software'           Software                 no
+  'view'               View                     no
 
 =head2 PDF Tags
@@ -12441,8 +24532,9 @@
 password-protected PDF files.
 
-When writing PDF files, ExifTool uses an incremental update.  This has the
-advantages of being fast and reversible.  The original PDF can be easily
-recovered by deleting the C<PDF-update> pseudo-group (with
-C<-PDF-update:all=> on the command line).  But there are two main
+ExifTool may be used to write native PDF and XMP metadata to PDF files. It
+uses an incremental update technique that has the advantages of being both
+fast and reversible.  If ExifTool was used to modify a PDF file, the
+original may be recovered by deleting the C<PDF-update> pseudo-group (with
+C<-PDF-update:all=> on the command line).  However, there are two main
 disadvantages to this technique:
 
@@ -12452,5 +24544,7 @@
 2) All metadata edits are reversible.  While this would normally be
 considered an advantage, it is a potential security problem because old
-information is never actually deleted from the file.
+information is never actually deleted from the file.  (However, after
+running ExifTool the old information may be removed permanently using the
+"qpdf" utility with this command: "qpdf --linearize in.pdf out.pdf".)
 
   Tag ID               Tag Name                 Writable
@@ -12459,5 +24553,5 @@
   'Info'               Info                     PDF Info
   'Root'               Root                     PDF Root
-  '_linearized'        Linearized               N
+  '_linearized'        Linearized               no
 
 =head3 PDF Encrypt Tags
@@ -12467,6 +24561,6 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'Filter' Encryption                           N
-  'P'      UserAccess                           N
+  'Filter' Encryption                           no
+  'P'      UserAccess                           no
 
 =head3 PDF Info Tags
@@ -12499,12 +24593,19 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Lang'               Language                 N
+  'AcroForm'           AcroForm                 PDF AcroForm
+  'Lang'               Language                 no
   'MarkInfo'           MarkInfo                 PDF MarkInfo
   'Metadata'           Metadata                 PDF Metadata
-  'PageLayout'         PageLayout               N
-  'PageMode'           PageMode                 N
+  'PageLayout'         PageLayout               no
+  'PageMode'           PageMode                 no
   'Pages'              Pages                    PDF Pages
   'Perms'              Perms                    PDF Perms
-  'Version'            PDFVersion               N
+  'Version'            PDFVersion               no
+
+=head3 PDF AcroForm Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  '_has_xfa'   HasXFA                           no
 
 =head3 PDF MarkInfo Tags
@@ -12512,5 +24613,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'Marked' TaggedPDF                            N
+  'Marked' TaggedPDF                            no
 
 =head3 PDF Metadata Tags
@@ -12524,5 +24625,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'Count'  PageCount                            N
+  'Count'  PageCount                            no
   'Kids'   Kids                                 PDF Kids
 
@@ -12531,4 +24632,5 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
+  'Kids'               Kids                     PDF Kids
   'Metadata'           Metadata                 PDF Metadata
   'PieceInfo'          PieceInfo                PDF PieceInfo
@@ -12571,8 +24673,9 @@
   ------               --------                 --------
   'AIMetaData'         AIMetaData               PDF AIMetaData
+  'AIPDFPrivateData'   AIPDFPrivateData         PostScript
   'AIPrivateData'      AIPrivateData            PostScript
-  'ContainerVersion'   ContainerVersion         N
-  'CreatorVersion'     CreatorVersion           N
-  'RoundTripVersion'   RoundTripVersion         N
+  'ContainerVersion'   ContainerVersion         no
+  'CreatorVersion'     CreatorVersion           no
+  'RoundTripVersion'   RoundTripVersion         no
 
 =head3 PDF AIMetaData Tags
@@ -12587,4 +24690,6 @@
   ------               --------                 --------
   'ColorSpace'         ColorSpace               PDF ColorSpace
+  'Properties'         Properties               PDF Properties
+  'XObject'            XObject                  PDF XObject
 
 =head3 PDF ColorSpace Tags
@@ -12592,5 +24697,13 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
+  'Cs1'                Cs1                      PDF Cs1
+  'DefaultCMYK'        DefaultCMYK              PDF DefaultRGB
   'DefaultRGB'         DefaultRGB               PDF DefaultRGB
+
+=head3 PDF Cs1 Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  '_stream'    _stream                          ICC_Profile
 
 =head3 PDF DefaultRGB Tags
@@ -12605,4 +24718,36 @@
   ------       --------                         --------
   '_stream'    _stream                          ICC_Profile
+
+=head3 PDF Properties Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'MC'     MC                                   PDF MC
+
+=head3 PDF MC Tags
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'Metadata'   Metadata                         PDF Metadata
+
+=head3 PDF XObject Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'Im'     Im                                   PDF Im
+
+=head3 PDF Im Tags
+
+Information extracted from embedded images with the ExtractEmbedded option.
+The EmbeddedImage and its metadata are extracted only for JPEG and Jpeg2000
+image formats.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'ColorSpace'         EmbeddedImageColorSpace  no+
+  'Filter'             EmbeddedImageFilter      no+
+  'Height'             EmbeddedImageHeight      no
+  'Image_stream'       EmbeddedImage            no
+  'Width'              EmbeddedImageWidth       no
 
 =head3 PDF Perms Tags
@@ -12620,11 +24765,11 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'ContactInfo'        SignerContactInfo        N
-  'Location'           SigningLocation          N
-  'M'                  SigningDate              N
-  'Name'               SigningAuthority         N
-  'Prop_AuthTime'      AuthenticationTime       N
-  'Prop_AuthType'      AuthenticationType       N
-  'Reason'             SigningReason            N
+  'ContactInfo'        SignerContactInfo        no
+  'Location'           SigningLocation          no
+  'M'                  SigningDate              no
+  'Name'               SigningAuthority         no
+  'Prop_AuthTime'      AuthenticationTime       no
+  'Prop_AuthType'      AuthenticationType       no
+  'Reason'             SigningReason            no
   'Reference'          Reference                PDF Reference
 
@@ -12639,50 +24784,57 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Action'             FieldPermissions         N
-  'Annots'             AnnotationUsageRights    N+
-  'Document'           DocumentUsageRights      N+
-  'EF'                 EmbeddedFileUsageRights  N+
-  'Fields'             FormFields               N+
-  'Form'               FormUsageRights          N+
-  'Msg'                UsageRightsMessage       N
-  'P'                  ModificationPermissions  N
-  'Signature'          SignatureUsageRights     N+
+  'Action'             FieldPermissions         no
+  'Annots'             AnnotationUsageRights    no+
+  'Document'           DocumentUsageRights      no+
+  'EF'                 EmbeddedFileUsageRights  no+
+  'Fields'             FormFields               no+
+  'Form'               FormUsageRights          no+
+  'FormEX'             FormExtraUsageRights     no+
+  'Msg'                UsageRightsMessage       no
+  'P'                  ModificationPermissions  no
+  'Signature'          SignatureUsageRights     no+
 
 =head2 PostScript Tags
 
-  Tag ID               Tag Name                 Writable
-  ------               --------                 --------
-  'Author'             Author                   string
-  'BeginDocument'      EmbeddedFile             PostScript
-  'BeginICCProfile'    ICC_Profile              ICC_Profile
-  'BeginPhotoshop'     PhotoshopData            Photoshop
-  'BoundingBox'        BoundingBox              N
-  'Copyright'          Copyright                string
-  'CreationDate'       CreateDate               string~
-  'Creator'            Creator                  string
-  'EmbeddedFileName'   EmbeddedFileName         N
-  'For'                For                      string
-  'ImageData'          ImageData                N
-  'Keywords'           Keywords                 string
-  'ModDate'            ModifyDate               string~
-  'Pages'              Pages                    N
-  'Routing'            Routing                  string
-  'Subject'            Subject                  string
-  'TIFFPreview'        TIFFPreview              N
-  'Title'              Title                    string
-  'Version'            Version                  string
-  'begin_xml_packet'   XMP                      XMP
+  Tag ID                 Tag Name               Writable
+  ------                 --------               --------
+  'AI12_BuildNumber'     AIBuildNumber          no
+  'AI3_ColorUsage'       AIColorUsage           no
+  'AI5_FileFormat'       AIFileFormat           no
+  'AI5_NumLayers'        AINumLayers            no
+  'AI5_RulerUnits'       AIRulerUnits           no
+  'AI5_TargetResolution' AITargetResolution     no
+  'AI8_CreatorVersion'   AICreatorVersion       no
+  'AI9_ColorModel'       AIColorModel           no
+  'Author'               Author                 string
+  'BeginDocument'        EmbeddedFile           PostScript
+  'BeginICCProfile'      ICC_Profile            ICC_Profile
+  'BeginPhotoshop'       PhotoshopData          Photoshop
+  'BoundingBox'          BoundingBox            no
+  'Copyright'            Copyright              string
+  'CreationDate'         CreateDate             string
+  'Creator'              Creator                string
+  'EmbeddedFileName'     EmbeddedFileName       no
+  'For'                  For                    string
+  'ImageData'            ImageData              no
+  'Keywords'             Keywords               string
+  'ModDate'              ModifyDate             string
+  'Pages'                Pages                  no
+  'Routing'              Routing                string
+  'Subject'              Subject                string
+  'TIFFPreview'          TIFFPreview            no
+  'Title'                Title                  string
+  'Version'              Version                string
+  'begin_xml_packet'     XMP                    XMP
 
 =head2 ID3 Tags
 
-ExifTool extracts ID3 information from MP3, MPEG, AIFF, OGG, FLAC, APE and
-RealAudio files.  ID3v2 tags which support multiple languages (ie. Comment
-and Lyrics) are extracted by specifying the tag name, followed by a dash
-('-'), then a 3-character
-ISO 639-2
-language code (ie. "Comment-spa"). See L<http://www.id3.org/> for the
-official ID3 specification and
-L<http://www.loc.gov/standards/iso639-2/php/code_list.php> for a list of ISO
-639-2 language codes.
+ExifTool extracts ID3 and Lyrics3 information from MP3, MPEG, AIFF, OGG,
+FLAC, APE, MPC and RealAudio files.  ID3v2 tags which support multiple
+languages (eg. Comment and Lyrics) are extracted by specifying the tag name,
+followed by a dash ('-'), then a 3-character ISO 639-2 language code (eg.
+"Comment-spa"). See L<http://www.id3.org/> for the official ID3
+specification and L<http://www.loc.gov/standards/iso639-2/php/code_list.php>
+for a list of ISO 639-2 language codes.
 
   Tag Name                                      Writable
@@ -12696,13 +24848,13 @@
 =head3 ID3 v1 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      3    Title                                N
-     33    Artist                               N
-     63    Album                                N
-     93    Year                                 N
-     97    Comment                              N
-    125    Track                                N
-    127    Genre                                N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      3    Title                                no
+     33    Artist                               no
+     63    Album                                no
+     93    Year                                 no
+     97    Comment                              no
+    125    Track                                no
+    127    Genre                                no
 
 =head3 ID3 v1_Enh Tags
@@ -12710,13 +24862,13 @@
 ID3 version 1 "Enhanced TAG" information (not part of the official spec).
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      4    Title2                               N
-     64    Artist2                              N
-    124    Album2                               N
-    184    Speed                                N
-    185    Genre                                N
-    215    StartTime                            N
-    221    EndTime                              N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    Title2                               no
+     64    Artist2                              no
+    124    Album2                               no
+    184    Speed                                no
+    185    Genre                                no
+    215    StartTime                            no
+    221    EndTime                              no
 
 =head3 ID3 v2_2 Tags
@@ -12730,241 +24882,383 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'CNT'    PlayCounter                          N
-  'COM'    Comment                              N
-  'IPL'    InvolvedPeople                       N
-  'PIC'    Picture                              N
-  'PIC-1'  PictureFormat                        N
-  'PIC-2'  PictureType                          N
-  'PIC-3'  PictureDescription                   N
-  'SLT'    SynchronizedLyricText                N
-  'TAL'    Album                                N
-  'TBP'    BeatsPerMinute                       N
-  'TCM'    Composer                             N
-  'TCO'    Genre                                N
-  'TCP'    Compilation                          N
-  'TCR'    Copyright                            N
-  'TDA'    Date                                 N
-  'TDY'    PlaylistDelay                        N
-  'TEN'    EncodedBy                            N
-  'TFT'    FileType                             N
-  'TIM'    Time                                 N
-  'TKE'    InitialKey                           N
-  'TLA'    Language                             N
-  'TLE'    Length                               N
-  'TMT'    Media                                N
-  'TOA'    OriginalArtist                       N
-  'TOF'    OriginalFilename                     N
-  'TOL'    OriginalLyricist                     N
-  'TOR'    OriginalReleaseYear                  N
-  'TOT'    OriginalAlbum                        N
-  'TP1'    Artist                               N
-  'TP2'    Band                                 N
-  'TP3'    Conductor                            N
-  'TP4'    InterpretedBy                        N
-  'TPA'    PartOfSet                            N
-  'TPB'    Publisher                            N
-  'TRC'    ISRC                                 N
-  'TRD'    RecordingDates                       N
-  'TRK'    Track                                N
-  'TSI'    Size                                 N
-  'TSS'    EncoderSettings                      N
-  'TT1'    Grouping                             N
-  'TT2'    Title                                N
-  'TT3'    Subtitle                             N
-  'TXT'    Lyricist                             N
-  'TXX'    UserDefinedText                      N
-  'TYE'    Year                                 N
-  'ULT'    Lyrics                               N
-  'WAF'    FileURL                              N
-  'WAR'    ArtistURL                            N
-  'WAS'    SourceURL                            N
-  'WCM'    CommercialURL                        N
-  'WCP'    CopyrightURL                         N
-  'WPB'    PublisherURL                         N
-  'WXX'    UserDefinedURL                       N
+  'CNT'    PlayCounter                          no
+  'COM'    Comment                              no
+  'IPL'    InvolvedPeople                       no
+  'ITU'    iTunesU?                             no
+  'PCS'    Podcast?                             no
+  'PIC'    Picture                              no
+  'PIC-1'  PictureFormat                        no
+  'PIC-2'  PictureType                          no
+  'PIC-3'  PictureDescription                   no
+  'POP'    Popularimeter                        no
+  'RVA'    RelativeVolumeAdjustment             no
+  'SLT'    SynLyrics                            ID3 SynLyrics
+  'TAL'    Album                                no
+  'TBP'    BeatsPerMinute                       no
+  'TCM'    Composer                             no
+  'TCO'    Genre                                no
+  'TCP'    Compilation                          no
+  'TCR'    Copyright                            no
+  'TDA'    Date                                 no
+  'TDY'    PlaylistDelay                        no
+  'TEN'    EncodedBy                            no
+  'TFT'    FileType                             no
+  'TIM'    Time                                 no
+  'TKE'    InitialKey                           no
+  'TLA'    Language                             no
+  'TLE'    Length                               no
+  'TMT'    Media                                no
+  'TOA'    OriginalArtist                       no
+  'TOF'    OriginalFileName                     no
+  'TOL'    OriginalLyricist                     no
+  'TOR'    OriginalReleaseYear                  no
+  'TOT'    OriginalAlbum                        no
+  'TP1'    Artist                               no
+  'TP2'    Band                                 no
+  'TP3'    Conductor                            no
+  'TP4'    InterpretedBy                        no
+  'TPA'    PartOfSet                            no
+  'TPB'    Publisher                            no
+  'TRC'    ISRC                                 no
+  'TRD'    RecordingDates                       no
+  'TRK'    Track                                no
+  'TS2'    AlbumArtistSortOrder                 no
+  'TSA'    AlbumSortOrder                       no
+  'TSC'    ComposerSortOrder                    no
+  'TSI'    Size                                 no
+  'TSP'    PerformerSortOrder                   no
+  'TSS'    EncoderSettings                      no
+  'TST'    TitleSortOrder                       no
+  'TT1'    Grouping                             no
+  'TT2'    Title                                no
+  'TT3'    Subtitle                             no
+  'TXT'    Lyricist                             no
+  'TXX'    UserDefinedText                      no
+  'TYE'    Year                                 no
+  'ULT'    Lyrics                               no
+  'WAF'    FileURL                              no
+  'WAR'    ArtistURL                            no
+  'WAS'    SourceURL                            no
+  'WCM'    CommercialURL                        no
+  'WCP'    CopyrightURL                         no
+  'WPB'    PublisherURL                         no
+  'WXX'    UserDefinedURL                       no
+
+=head3 ID3 SynLyrics Tags
+
+The following tags are extracted from synchronized lyrics/text frames.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  SynchronizedLyricsDescription                 no
+  SynchronizedLyricsText                        no+
+  SynchronizedLyricsType                        no
 
 =head3 ID3 v2_3 Tags
 
-ID3 version 2.3 tags
+ID3 version 2.3 tags.  Includes some non-standard tags written by other
+software.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'APIC'   Picture                              N
-  'APIC-1' PictureMimeType                      N
-  'APIC-2' PictureType                          N
-  'APIC-3' PictureDescription                   N
-  'COMM'   Comment                              N
-  'IPLS'   InvolvedPeople                       N
-  'MCDI'   MusicCDIdentifier                    N
-  'PCNT'   PlayCounter                          N
+  'APIC'   Picture                              no
+  'APIC-1' PictureMIMEType                      no
+  'APIC-2' PictureType                          no
+  'APIC-3' PictureDescription                   no
+  'COMM'   Comment                              no
+  'GRP1'   Grouping                             no
+  'IPLS'   InvolvedPeople                       no
+  'ITNU'   iTunesU?                             no
+  'MCDI'   MusicCDIdentifier                    no
+  'MVIN'   MovementNumber                       no
+  'MVNM'   MovementName                         no
+  'OWNE'   Ownership                            no
+  'PCNT'   PlayCounter                          no
+  'PCST'   Podcast?                             no
+  'POPM'   Popularimeter                        no
   'PRIV'   Private                              ID3 Private
-  'SYLT'   SynchronizedLyricText                N
-  'TALB'   Album                                N
-  'TBPM'   BeatsPerMinute                       N
-  'TCMP'   Compilation                          N
-  'TCOM'   Composer                             N
-  'TCON'   Genre                                N
-  'TCOP'   Copyright                            N
-  'TDAT'   Date                                 N
-  'TDLY'   PlaylistDelay                        N
-  'TENC'   EncodedBy                            N
-  'TEXT'   Lyricist                             N
-  'TFLT'   FileType                             N
-  'TIME'   Time                                 N
-  'TIT1'   Grouping                             N
-  'TIT2'   Title                                N
-  'TIT3'   Subtitle                             N
-  'TKEY'   InitialKey                           N
-  'TLAN'   Language                             N
-  'TLEN'   Length                               N
-  'TMED'   Media                                N
-  'TOAL'   OriginalAlbum                        N
-  'TOFN'   OriginalFilename                     N
-  'TOLY'   OriginalLyricist                     N
-  'TOPE'   OriginalArtist                       N
-  'TORY'   OriginalReleaseYear                  N
-  'TOWN'   FileOwner                            N
-  'TPE1'   Artist                               N
-  'TPE2'   Band                                 N
-  'TPE3'   Conductor                            N
-  'TPE4'   InterpretedBy                        N
-  'TPOS'   PartOfSet                            N
-  'TPUB'   Publisher                            N
-  'TRCK'   Track                                N
-  'TRDA'   RecordingDates                       N
-  'TRSN'   InternetRadioStationName             N
-  'TRSO'   InternetRadioStationOwner            N
-  'TSIZ'   Size                                 N
-  'TSRC'   ISRC                                 N
-  'TSSE'   EncoderSettings                      N
-  'TXXX'   UserDefinedText                      N
-  'TYER'   Year                                 N
-  'USER'   TermsOfUse                           N
-  'USLT'   Lyrics                               N
-  'WCOM'   CommercialURL                        N
-  'WCOP'   CopyrightURL                         N
-  'WOAF'   FileURL                              N
-  'WOAR'   ArtistURL                            N
-  'WOAS'   SourceURL                            N
-  'WORS'   InternetRadioStationURL              N
-  'WPAY'   PaymentURL                           N
-  'WPUB'   PublisherURL                         N
-  'WXXX'   UserDefinedURL                       N
+  'SYLT'   SynLyrics                            ID3 SynLyrics
+  'TALB'   Album                                no
+  'TBPM'   BeatsPerMinute                       no
+  'TCAT'   PodcastCategory                      no
+  'TCMP'   Compilation                          no
+  'TCOM'   Composer                             no
+  'TCON'   Genre                                no
+  'TCOP'   Copyright                            no
+  'TDAT'   Date                                 no
+  'TDES'   PodcastDescription                   no
+  'TDLY'   PlaylistDelay                        no
+  'TENC'   EncodedBy                            no
+  'TEXT'   Lyricist                             no
+  'TFLT'   FileType                             no
+  'TGID'   PodcastID                            no
+  'TIME'   Time                                 no
+  'TIT1'   Grouping                             no
+  'TIT2'   Title                                no
+  'TIT3'   Subtitle                             no
+  'TKEY'   InitialKey                           no
+  'TKWD'   PodcastKeywords                      no
+  'TLAN'   Language                             no
+  'TLEN'   Length                               no
+  'TMED'   Media                                no
+  'TOAL'   OriginalAlbum                        no
+  'TOFN'   OriginalFileName                     no
+  'TOLY'   OriginalLyricist                     no
+  'TOPE'   OriginalArtist                       no
+  'TORY'   OriginalReleaseYear                  no
+  'TOWN'   FileOwner                            no
+  'TPE1'   Artist                               no
+  'TPE2'   Band                                 no
+  'TPE3'   Conductor                            no
+  'TPE4'   InterpretedBy                        no
+  'TPOS'   PartOfSet                            no
+  'TPUB'   Publisher                            no
+  'TRCK'   Track                                no
+  'TRDA'   RecordingDates                       no
+  'TRSN'   InternetRadioStationName             no
+  'TRSO'   InternetRadioStationOwner            no
+  'TSIZ'   Size                                 no
+  'TSO2'   AlbumArtistSortOrder                 no
+  'TSOC'   ComposerSortOrder                    no
+  'TSRC'   ISRC                                 no
+  'TSSE'   EncoderSettings                      no
+  'TXXX'   UserDefinedText                      no
+  'TYER'   Year                                 no
+  'USER'   TermsOfUse                           no
+  'USLT'   Lyrics                               no
+  'WCOM'   CommercialURL                        no
+  'WCOP'   CopyrightURL                         no
+  'WFED'   PodcastURL                           no
+  'WOAF'   FileURL                              no
+  'WOAR'   ArtistURL                            no
+  'WOAS'   SourceURL                            no
+  'WORS'   InternetRadioStationURL              no
+  'WPAY'   PaymentURL                           no
+  'WPUB'   PublisherURL                         no
+  'WXXX'   UserDefinedURL                       no
+  'XDOR'   OriginalReleaseTime                  no
+  'XOLY'   OlympusDSS                           Olympus DSS
+  'XSOA'   AlbumSortOrder                       no
+  'XSOP'   PerformerSortOrder                   no
+  'XSOT'   TitleSortOrder                       no
 
 =head3 ID3 Private Tags
 
-ID3 private (PRIV) tags.
+ID3 private (PRIV) tags.  ExifTool will decode any private tags found, even
+if they do not appear in this table.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  AverageLevel                                  no
+  PeakValue                                     no
+  WM_CollectionGroupID                          no
+  WM_CollectionID                               no
+  WM_ContentID                                  no
+  WM_MediaClassPrimaryID                        no
+  WM_MediaClassSecondaryID                      no
+  WM_Provider                                   no
+  XMP                                           XMP
+
+=head3 ID3 v2_4 Tags
+
+ID3 version 2.4 tags.  Includes some non-standard tags written by other
+software.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'APIC'   Picture                              no
+  'APIC-1' PictureMIMEType                      no
+  'APIC-2' PictureType                          no
+  'APIC-3' PictureDescription                   no
+  'COMM'   Comment                              no
+  'GRP1'   Grouping                             no
+  'ITNU'   iTunesU?                             no
+  'MCDI'   MusicCDIdentifier                    no
+  'MVIN'   MovementNumber                       no
+  'MVNM'   MovementName                         no
+  'OWNE'   Ownership                            no
+  'PCNT'   PlayCounter                          no
+  'PCST'   Podcast?                             no
+  'POPM'   Popularimeter                        no
+  'PRIV'   Private                              ID3 Private
+  'RVA2'   RelativeVolumeAdjustment             no
+  'SYLT'   SynLyrics                            ID3 SynLyrics
+  'TALB'   Album                                no
+  'TBPM'   BeatsPerMinute                       no
+  'TCAT'   PodcastCategory                      no
+  'TCMP'   Compilation                          no
+  'TCOM'   Composer                             no
+  'TCON'   Genre                                no
+  'TCOP'   Copyright                            no
+  'TDEN'   EncodingTime                         no
+  'TDES'   PodcastDescription                   no
+  'TDLY'   PlaylistDelay                        no
+  'TDOR'   OriginalReleaseTime                  no
+  'TDRC'   RecordingTime                        no
+  'TDRL'   ReleaseTime                          no
+  'TDTG'   TaggingTime                          no
+  'TENC'   EncodedBy                            no
+  'TEXT'   Lyricist                             no
+  'TFLT'   FileType                             no
+  'TGID'   PodcastID                            no
+  'TIPL'   InvolvedPeople                       no
+  'TIT1'   Grouping                             no
+  'TIT2'   Title                                no
+  'TIT3'   Subtitle                             no
+  'TKEY'   InitialKey                           no
+  'TKWD'   PodcastKeywords                      no
+  'TLAN'   Language                             no
+  'TLEN'   Length                               no
+  'TMCL'   MusicianCredits                      no
+  'TMED'   Media                                no
+  'TMOO'   Mood                                 no
+  'TOAL'   OriginalAlbum                        no
+  'TOFN'   OriginalFileName                     no
+  'TOLY'   OriginalLyricist                     no
+  'TOPE'   OriginalArtist                       no
+  'TOWN'   FileOwner                            no
+  'TPE1'   Artist                               no
+  'TPE2'   Band                                 no
+  'TPE3'   Conductor                            no
+  'TPE4'   InterpretedBy                        no
+  'TPOS'   PartOfSet                            no
+  'TPRO'   ProducedNotice                       no
+  'TPUB'   Publisher                            no
+  'TRCK'   Track                                no
+  'TRSN'   InternetRadioStationName             no
+  'TRSO'   InternetRadioStationOwner            no
+  'TSO2'   AlbumArtistSortOrder                 no
+  'TSOA'   AlbumSortOrder                       no
+  'TSOC'   ComposerSortOrder                    no
+  'TSOP'   PerformerSortOrder                   no
+  'TSOT'   TitleSortOrder                       no
+  'TSRC'   ISRC                                 no
+  'TSSE'   EncoderSettings                      no
+  'TSST'   SetSubtitle                          no
+  'TXXX'   UserDefinedText                      no
+  'USER'   TermsOfUse                           no
+  'USLT'   Lyrics                               no
+  'WCOM'   CommercialURL                        no
+  'WCOP'   CopyrightURL                         no
+  'WFED'   PodcastURL                           no
+  'WOAF'   FileURL                              no
+  'WOAR'   ArtistURL                            no
+  'WOAS'   SourceURL                            no
+  'WORS'   InternetRadioStationURL              no
+  'WPAY'   PaymentURL                           no
+  'WPUB'   PublisherURL                         no
+  'WXXX'   UserDefinedURL                       no
+  'XDOR'   OriginalReleaseTime                  no
+  'XOLY'   OlympusDSS                           Olympus DSS
+  'XSOA'   AlbumSortOrder                       no
+  'XSOP'   PerformerSortOrder                   no
+  'XSOT'   TitleSortOrder                       no
+
+=head3 ID3 Lyrics3 Tags
+
+ExifTool extracts Lyrics3 version 1.00 and 2.00 tags from any file that
+supports ID3.  See L<https://id3.org/Lyrics3> for the specification.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'AUT'    Author                               no
+  'CRC'    CRC                                  no
+  'EAL'    ExtendedAlbumName                    no
+  'EAR'    ExtendedArtistName                   no
+  'ETT'    ExtendedTrackTitle                   no
+  'IMG'    AssociatedImageFile                  no
+  'IND'    Indications                          no
+  'INF'    AdditionalInfo                       no
+  'LYR'    Lyrics                               no
+
+=head2 ITC Tags
+
+This information is found in iTunes Cover Flow data files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'data'   ImageData                            no
+  'itch'   Itch                                 ITC Header
+  'item'   Item                                 ITC Item
+
+=head3 ITC Header Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     16    DataType                             no
+
+=head3 ITC Item Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    LibraryID                            no
+      2    TrackID                              no
+      4    DataLocation                         no
+      5    ImageType                            no
+      7    ImageWidth                           no
+      8    ImageHeight                          no
+
+=head2 FLAC Tags
+
+Free Lossless Audio Codec (FLAC) meta information.  ExifTool also extracts
+ID3 information from these files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   StreamInfo                           FLAC StreamInfo
+  0x0001   Padding?                             no
+  0x0002   Application?                         no
+  0x0003   SeekTable?                           no
+  0x0004   VorbisComment                        Vorbis Comments
+  0x0005   CueSheet?                            no
+  0x0006   Picture                              FLAC Picture
+
+=head3 FLAC StreamInfo Tags
+
+FLAC is big-endian, so bit 0 is the high-order bit in this table.
 
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'AverageLevel'       AverageLevel             N
-  'PeakValue'          PeakValue                N
-  'XMP'                XMP                      XMP
-
-=head3 ID3 v2_4 Tags
-
-ID3 version 2.4 tags
+  'Bit000-015'         BlockSizeMin             no
+  'Bit016-031'         BlockSizeMax             no
+  'Bit032-055'         FrameSizeMin             no
+  'Bit056-079'         FrameSizeMax             no
+  'Bit080-099'         SampleRate               no
+  'Bit100-102'         Channels                 no
+  'Bit103-107'         BitsPerSample            no
+  'Bit108-143'         TotalSamples             no
+  'Bit144-271'         MD5Signature             no
+
+=head3 FLAC Picture Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    PictureType                          no
+      1    PictureMIMEType                      no
+      2    PictureDescription                   no
+      3    PictureWidth                         no
+      4    PictureHeight                        no
+      5    PictureBitsPerPixel                  no
+      6    PictureIndexedColors                 no
+      7    PictureLength                        no
+      8    Picture                              no
+
+=head2 Ogg Tags
+
+ExifTool extracts the following types of information from Ogg files.  See
+L<http://www.xiph.org/vorbis/doc/> for the Ogg specification.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'APIC'   Picture                              N
-  'APIC-1' PictureMimeType                      N
-  'APIC-2' PictureType                          N
-  'APIC-3' PictureDescription                   N
-  'COMM'   Comment                              N
-  'MCDI'   MusicCDIdentifier                    N
-  'PCNT'   PlayCounter                          N
-  'PRIV'   Private                              ID3 Private
-  'SYLT'   SynchronizedLyricText                N
-  'TALB'   Album                                N
-  'TBPM'   BeatsPerMinute                       N
-  'TCMP'   Compilation                          N
-  'TCOM'   Composer                             N
-  'TCON'   Genre                                N
-  'TCOP'   Copyright                            N
-  'TDEN'   EncodingTime                         N
-  'TDLY'   PlaylistDelay                        N
-  'TDOR'   OriginalReleaseTime                  N
-  'TDRC'   RecordingTime                        N
-  'TDRL'   ReleaseTime                          N
-  'TDTG'   TaggingTime                          N
-  'TENC'   EncodedBy                            N
-  'TEXT'   Lyricist                             N
-  'TFLT'   FileType                             N
-  'TIPL'   InvolvedPeople                       N
-  'TIT1'   Grouping                             N
-  'TIT2'   Title                                N
-  'TIT3'   Subtitle                             N
-  'TKEY'   InitialKey                           N
-  'TLAN'   Language                             N
-  'TLEN'   Length                               N
-  'TMCL'   MusicianCredits                      N
-  'TMED'   Media                                N
-  'TMOO'   Mood                                 N
-  'TOAL'   OriginalAlbum                        N
-  'TOFN'   OriginalFilename                     N
-  'TOLY'   OriginalLyricist                     N
-  'TOPE'   OriginalArtist                       N
-  'TOWN'   FileOwner                            N
-  'TPE1'   Artist                               N
-  'TPE2'   Band                                 N
-  'TPE3'   Conductor                            N
-  'TPE4'   InterpretedBy                        N
-  'TPOS'   PartOfSet                            N
-  'TPRO'   ProducedNotice                       N
-  'TPUB'   Publisher                            N
-  'TRCK'   Track                                N
-  'TRSN'   InternetRadioStationName             N
-  'TRSO'   InternetRadioStationOwner            N
-  'TSOA'   AlbumSortOrder                       N
-  'TSOP'   PerformerSortOrder                   N
-  'TSOT'   TitleSortOrder                       N
-  'TSRC'   ISRC                                 N
-  'TSSE'   EncoderSettings                      N
-  'TSST'   SetSubtitle                          N
-  'TXXX'   UserDefinedText                      N
-  'USER'   TermsOfUse                           N
-  'USLT'   Lyrics                               N
-  'WCOM'   CommercialURL                        N
-  'WCOP'   CopyrightURL                         N
-  'WOAF'   FileURL                              N
-  'WOAR'   ArtistURL                            N
-  'WOAS'   SourceURL                            N
-  'WORS'   InternetRadioStationURL              N
-  'WPAY'   PaymentURL                           N
-  'WPUB'   PublisherURL                         N
-  'WXXX'   UserDefinedURL                       N
-
-=head2 ITC Tags
-
-This information is found in iTunes Cover Flow data files.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  'data'   ImageData                            N
-  'itch'   Itch                                 ITC Header
-  'item'   Item                                 ITC Item
-
-=head3 ITC Header Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     16    DataType                             N
-
-=head3 ITC Item Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    LibraryID                            N
-      2    TrackID                              N
-      4    DataLocation                         N
-      5    ImageType                            N
-      7    ImageWidth                           N
-      8    ImageHeight                          N
+  'FLAC'   FLAC                                 FLAC
+  'ID3'    ID3                                  ID3
+  'Opus'   Opus                                 Opus
+  'theora' Theora                               Theora
+  'vorbis' Vorbis                               Vorbis
 
 =head2 Vorbis Tags
 
-ExifTool extracts the following Vorbis information from Ogg files.  As well
-as this, ExifTool also extracts FLAC and ID3 information from Ogg files.
+Information extracted from Ogg Vorbis files.  See
+L<http://www.xiph.org/vorbis/doc/> for the Vorbis specification.
 
   Tag ID   Tag Name                             Writable
@@ -12972,15 +25266,4 @@
   0x0001   Identification                       Vorbis Identification
   0x0003   Comments                             Vorbis Comments
-
-=head3 Vorbis Identification Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    VorbisVersion                        N
-      4    AudioChannels                        N
-      5    SampleRate                           N
-      9    MaximumBitrate                       N
-     13    NominalBitrate                       N
-     17    MinimumBitrate                       N
 
 =head3 Vorbis Comments Tags
@@ -12990,115 +25273,200 @@
 any tag found, even if not listed here.
 
-  Tag ID                  Tag Name              Writable
-  ------                  --------              --------
-  'ALBUM'                 Album                 N
-  'ARTIST'                Artist                N+
-  'COMMENT'               Comment               N
-  'CONTACT'               Contact               N+
-  'COPYRIGHT'             Copyright             N
-  'COVERART'              CoverArt              N
-  'COVERARTMIME'          CoverArtMIMEType      N
-  'DATE'                  Date                  N
-  'DESCRIPTION'           Description           N
-  'ENCODED_BY'            EncodedBy             N
-  'ENCODED_USING'         EncodedUsing          N
-  'GENRE'                 Genre                 N
-  'ISRC'                  ISRCNumber            N
-  'LICENSE'               License               N
-  'LOCATION'              Location              N
-  'ORGANIZATION'          Organization          N
-  'PERFORMER'             Performer             N+
-  'REPLAYGAIN_ALBUM_GAIN' ReplayGainAlbumGain   N
-  'REPLAYGAIN_ALBUM_PEAK' ReplayGainAlbumPeak   N
-  'REPLAYGAIN_TRACK_GAIN' ReplayGainTrackGain   N
-  'REPLAYGAIN_TRACK_PEAK' ReplayGainTrackPeak   N
-  'TITLE'                 Title                 N
-  'TRACKNUMBER'           TrackNumber           N
-  'VERSION'               Version               N
-  'vendor'                Vendor                N
-
-=head2 FLAC Tags
-
-Free Lossless Audio Codec (FLAC) meta information.  ExifTool also extracts
-ID3 information from these files.
+  Tag ID                   Tag Name             Writable
+  ------                   --------             --------
+  'ACTOR'                  Actor                no
+  'ALBUM'                  Album                no
+  'ARTIST'                 Artist               no+
+  'COMMENT'                Comment              no
+  'COMPOSER'               Composer             no
+  'CONTACT'                Contact              no+
+  'COPYRIGHT'              Copyright            no
+  'COVERART'               CoverArt             no
+  'COVERARTMIME'           CoverArtMIMEType     no
+  'DATE'                   Date                 no
+  'DESCRIPTION'            Description          no
+  'DIRECTOR'               Director             no
+  'ENCODED_BY'             EncodedBy            no
+  'ENCODED_USING'          EncodedUsing         no
+  'ENCODER'                Encoder              no
+  'ENCODER_OPTIONS'        EncoderOptions       no
+  'GENRE'                  Genre                no
+  'ISRC'                   ISRCNumber           no
+  'LICENSE'                License              no
+  'LOCATION'               Location             no
+  'METADATA_BLOCK_PICTURE' Picture              FLAC Picture
+  'ORGANIZATION'           Organization         no
+  'PERFORMER'              Performer            no+
+  'PRODUCER'               Producer             no
+  'REPLAYGAIN_ALBUM_GAIN'  ReplayGainAlbumGain  no
+  'REPLAYGAIN_ALBUM_PEAK'  ReplayGainAlbumPeak  no
+  'REPLAYGAIN_TRACK_GAIN'  ReplayGainTrackGain  no
+  'REPLAYGAIN_TRACK_PEAK'  ReplayGainTrackPeak  no
+  'TITLE'                  Title                no
+  'TRACKNUMBER'            TrackNumber          no
+  'VERSION'                Version              no
+  'vendor'                 Vendor               no
+
+=head3 Vorbis Identification Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    VorbisVersion                        no
+      4    AudioChannels                        no
+      5    SampleRate                           no
+      9    MaximumBitrate                       no
+     13    NominalBitrate                       no
+     17    MinimumBitrate                       no
+
+=head2 Opus Tags
+
+Information extracted from Ogg Opus files.  See
+L<https://www.opus-codec.org/docs/> for the specification.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'OpusHead'   Header                           Opus Header
+  'OpusTags'   Comments                         Vorbis Comments
+
+=head3 Opus Header Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    OpusVersion                          no
+      1    AudioChannels                        no
+      4    SampleRate                           no
+      8    OutputGain                           no
+
+=head2 Theora Tags
+
+Information extracted from Ogg Theora video files.  See
+L<http://www.theora.org/doc/Theora.pdf> for the Theora specification.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   StreamInfo                           FLAC StreamInfo
-  0x0004   VorbisComment                        Vorbis Comments
-  0x0006   Picture                              FLAC Picture
-
-=head3 FLAC StreamInfo Tags
-
-FLAC is big-endian, so bit 0 is the high-order bit in this table.
+  0x0080   Identification                       Theora Identification
+  0x0081   Comments                             Vorbis Comments
+
+=head3 Theora Identification Tags
+
+Tags extracted from the Theora identification header.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    TheoraVersion                        no
+      7    ImageWidth                           no
+     10    ImageHeight                          no
+     13    XOffset                              no
+     14    YOffset                              no
+     15    FrameRate                            no
+     23    PixelAspectRatio                     no
+     29    ColorSpace                           no
+     30    NominalVideoBitrate                  no
+     33    Quality                              no
+     34    PixelFormat                          no
+
+=head2 APE Tags
+
+Tags found in Monkey's Audio (APE) information.  Only a few common tags are
+listed below, but ExifTool will extract any tag found.  ExifTool supports
+APEv1 and APEv2 tags, as well as ID3 information in APE files, and will also
+read APE metadata from MP3 and MPC files.
 
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Bit000-015'         BlockSizeMin             N
-  'Bit016-031'         BlockSizeMax             N
-  'Bit032-055'         FrameSizeMin             N
-  'Bit056-079'         FrameSizeMax             N
-  'Bit080-099'         SampleRate               N
-  'Bit100-102'         Channels                 N
-  'Bit103-107'         BitsPerSample            N
-  'Bit108-143'         TotalSamples             N
-
-=head3 FLAC Picture Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    PictureType                          N
-      1    PictureMIMEType                      N
-      2    PictureDescription                   N
-      3    PictureWidth                         N
-      4    PictureHeight                        N
-      5    PictureBitsPerPixel                  N
-      6    PictureIndexedColors                 N
-      7    PictureLength                        N
-      8    Picture                              N
-
-=head2 APE Tags
-
-Tags found in Monkey's Audio (APE) information.  Only a few common tags are
-listed below, but ExifTool will extract any tag found.  ExifTool supports
-APEv1 and APEv2 tags, as well as ID3 information in APE files.
+  'Album'              Album                    no
+  'Artist'             Artist                   no
+  'DURATION'           Duration                 no
+  'Genre'              Genre                    no
+  'Title'              Title                    no
+  'Tool Name'          ToolName                 no
+  'Tool Version'       ToolVersion              no
+  'Track'              Track                    no
+  'Year'               Year                     no
+
+=head3 APE NewHeader Tags
+
+APE MAC audio header for version 3.98 or later.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    CompressionLevel                     no
+      2    BlocksPerFrame                       no
+      4    FinalFrameBlocks                     no
+      6    TotalFrames                          no
+      8    BitsPerSample                        no
+      9    Channels                             no
+     10    SampleRate                           no
+
+=head3 APE OldHeader Tags
+
+APE MAC audio header for version 3.97 or earlier.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    APEVersion                           no
+      1    CompressionLevel                     no
+      3    Channels                             no
+      4    SampleRate                           no
+     10    TotalFrames                          no
+     12    FinalFrameBlocks                     no
+
+=head2 Audible Tags
+
+ExifTool will extract any information found in the metadata dictionary of
+Audible .AA files, even if not listed in the table below.
 
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Album'              Album                    N
-  'Artist'             Artist                   N
-  'Genre'              Genre                    N
-  'Title'              Title                    N
-  'Tool Name'          ToolName                 N
-  'Tool Version'       ToolVersion              N
-  'Track'              Track                    N
-  'Year'               Year                     N
-
-=head3 APE NewHeader Tags
-
-APE MAC audio header for version 3.98 or later.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    CompressionLevel                     N
-      2    BlocksPerFrame                       N
-      4    FinalFrameBlocks                     N
-      6    TotalFrames                          N
-      8    BitsPerSample                        N
-      9    Channels                             N
-     10    SampleRate                           N
-
-=head3 APE OldHeader Tags
-
-APE MAC audio header for version 3.97 or earlier.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    APEVersion                           N
-      1    CompressionLevel                     N
-      3    Channels                             N
-      4    SampleRate                           N
-     10    TotalFrames                          N
-     12    FinalFrameBlocks                     N
+  '_chapter_count'     ChapterCount             no
+  '_cover_art'         CoverArt                 no
+  'author'             Author                   no
+  'copyright'          Copyright                no
+  'pub_date_start'     PublishDateStart         no
+  'pubdate'            PublishDate              no
+
+=head3 Audible tags Tags
+
+Information found in "tags" atom of Audible M4B audio books.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'cvrx'   Audible_cvrx                         Audible cvrx
+  'meta'   Audible_meta                         Audible meta
+  'tseg'   Audible_tseg                         Audible tseg
+
+=head3 Audible cvrx Tags
+
+Audible cover art information in M4B audio books.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  CoverArt                                      no
+  CoverArtType                                  no
+
+=head3 Audible meta Tags
+
+Information found in Audible M4B "meta" atom.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'ALBUMARTIST'        AlbumArtist              no
+  'Album'              Album                    no
+  'Artist'             Artist                   no
+  'Comment'            Comment                  no
+  'Genre'              Genre                    no
+  'SUBTITLE'           Subtitle                 no
+  'TOOL'               CreatorTool              no
+  'Title'              Title                    no
+  'Year'               Year                     no
+  'itunesmediatype'    iTunesMediaType          no
+  'track'              ChapterName              no
+
+=head3 Audible tseg Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'meta'   Audible_meta2                        Audible meta
+  'tshd'   ChapterNumber                        no
 
 =head2 MPC Tags
@@ -13109,15 +25477,15 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Bit032-063'         TotalFrames              N
-  'Bit080-081'         SampleRate               N
-  'Bit084-087'         Quality                  N
-  'Bit088-093'         MaxBand                  N
-  'Bit096-111'         ReplayGainTrackPeak      N
-  'Bit112-127'         ReplayGainTrackGain      N
-  'Bit128-143'         ReplayGainAlbumPeak      N
-  'Bit144-159'         ReplayGainAlbumGain      N
-  'Bit179'             FastSeek                 N
-  'Bit191'             Gapless                  N
-  'Bit216-223'         EncoderVersion           N
+  'Bit032-063'         TotalFrames              no
+  'Bit080-081'         SampleRate               no
+  'Bit084-087'         Quality                  no
+  'Bit088-093'         MaxBand                  no
+  'Bit096-111'         ReplayGainTrackPeak      no
+  'Bit112-127'         ReplayGainTrackGain      no
+  'Bit128-143'         ReplayGainAlbumPeak      no
+  'Bit144-159'         ReplayGainAlbumGain      no
+  'Bit179'             FastSeek                 no
+  'Bit191'             Gapless                  no
+  'Bit216-223'         EncoderVersion           no
 
 =head2 MPEG Tags
@@ -13131,15 +25499,15 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  'Bit11-12'   MPEGAudioVersion                 N
-  'Bit13-14'   AudioLayer                       N
-  'Bit16-19'   AudioBitrate                     N
-  'Bit20-21'   SampleRate                       N
-  'Bit24-25'   ChannelMode                      N
-  'Bit26'      MSStereo                         N
-  'Bit26-27'   ModeExtension                    N
-  'Bit27'      IntensityStereo                  N
-  'Bit28'      CopyrightFlag                    N
-  'Bit29'      OriginalMedia                    N
-  'Bit30-31'   Emphasis                         N
+  'Bit11-12'   MPEGAudioVersion                 no
+  'Bit13-14'   AudioLayer                       no
+  'Bit16-19'   AudioBitrate                     no
+  'Bit20-21'   SampleRate                       no
+  'Bit24-25'   ChannelMode                      no
+  'Bit26'      MSStereo                         no
+  'Bit26-27'   ModeExtension                    no
+  'Bit27'      IntensityStereo                  no
+  'Bit28'      CopyrightFlag                    no
+  'Bit29'      OriginalMedia                    no
+  'Bit30-31'   Emphasis                         no
 
 =head3 MPEG Video Tags
@@ -13147,9 +25515,9 @@
   Tag ID       Tag Name                         Writable
   ------       --------                         --------
-  'Bit00-11'   ImageWidth                       N
-  'Bit12-23'   ImageHeight                      N
-  'Bit24-27'   AspectRatio                      N
-  'Bit28-31'   FrameRate                        N
-  'Bit32-49'   VideoBitrate                     N
+  'Bit00-11'   ImageWidth                       no
+  'Bit12-23'   ImageHeight                      no
+  'Bit24-27'   AspectRatio                      no
+  'Bit28-31'   FrameRate                        no
+  'Bit32-49'   VideoBitrate                     no
 
 =head3 MPEG Xing Tags
@@ -13159,11 +25527,11 @@
   Tag Name                                      Writable
   --------                                      --------
-  VBRFrames                                     N
-  VBRBytes                                      N
-  VBRScale                                      N
-  Encoder                                       N
-  LameVBRQuality                                N
-  LameQuality                                   N
+  Encoder                                       no
   LameHeader                                    MPEG Lame
+  LameQuality                                   no
+  LameVBRQuality                                no
+  VBRBytes                                      no
+  VBRFrames                                     no
+  VBRScale                                      no
 
 =head3 MPEG Lame Tags
@@ -13171,10 +25539,10 @@
 Tags extracted from Lame 3.90 or later header.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      9    LameMethod                           N
-     10    LameLowPassFilter                    N
-     20    LameBitrate                          N
-     24    LameStereoMode                       N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      9    LameMethod                           no
+     10    LameLowPassFilter                    no
+     20    LameBitrate                          no
+     24    LameStereoMode                       no
 
 =head2 M2TS Tags
@@ -13186,7 +25554,7 @@
   Tag Name                                      Writable
   --------                                      --------
-  AudioStreamType                               N
-  Duration                                      N
-  VideoStreamType                               N
+  AudioStreamType                               no
+  Duration                                      no
+  VideoStreamType                               no
   _AC3                                          M2TS AC3
   _H264                                         H264
@@ -13198,8 +25566,8 @@
   Tag Name                                      Writable
   --------                                      --------
-  AudioBitrate                                  N
-  AudioChannels                                 N
-  AudioSampleRate                               N
-  SurroundMode                                  N
+  AudioBitrate                                  no
+  AudioChannels                                 no
+  AudioSampleRate                               no
+  SurroundMode                                  no
 
 =head2 H264 Tags
@@ -13210,6 +25578,6 @@
   Tag Name                                      Writable
   --------                                      --------
-  ImageHeight                                   N
-  ImageWidth                                    N
+  ImageHeight                                   no
+  ImageWidth                                    no
   MDPM                                          H264 MDPM
 
@@ -13227,69 +25595,71 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0018   DateTimeOriginal                     N
+  0x0013   TimeCode                             no
+  0x0018   DateTimeOriginal                     no
   0x0070   Camera1                              H264 Camera1
   0x0071   Camera2                              H264 Camera2
   0x007f   Shutter                              H264 Shutter
-  0x00a0   ExposureTime                         N
-  0x00a1   FNumber                              N
-  0x00a2   ExposureProgram                      N
-  0x00a3   BrightnessValue                      N
-  0x00a4   ExposureCompensation                 N
-  0x00a5   MaxApertureValue                     N
-  0x00a6   Flash                                N
-  0x00a7   CustomRendered                       N
-  0x00a8   WhiteBalance                         N
-  0x00a9   FocalLengthIn35mmFormat              N
-  0x00aa   SceneCaptureType                     N
-  0x00b0   GPSVersionID                         N
-  0x00b1   GPSLatitudeRef                       N
-  0x00b2   GPSLatitude                          N
-  0x00b5   GPSLongitudeRef                      N
-  0x00b6   GPSLongitude                         N
-  0x00b9   GPSAltitudeRef                       N
-  0x00ba   GPSAltitude                          N
-  0x00bb   GPSTimeStamp                         N
-  0x00be   GPSStatus                            N
-  0x00bf   GPSMeasureMode                       N
-  0x00c0   GPSDOP                               N
-  0x00c1   GPSSpeedRef                          N
-  0x00c2   GPSSpeed                             N
-  0x00c3   GPSTrackRef                          N
-  0x00c4   GPSTrack                             N
-  0x00c5   GPSImgDirectionRef                   N
-  0x00c6   GPSImgDirection                      N
-  0x00c7   GPSMapDatum                          N
+  0x00a0   ExposureTime                         no
+  0x00a1   FNumber                              no
+  0x00a2   ExposureProgram                      no
+  0x00a3   BrightnessValue                      no
+  0x00a4   ExposureCompensation                 no
+  0x00a5   MaxApertureValue                     no
+  0x00a6   Flash                                no
+  0x00a7   CustomRendered                       no
+  0x00a8   WhiteBalance                         no
+  0x00a9   FocalLengthIn35mmFormat              no
+  0x00aa   SceneCaptureType                     no
+  0x00b0   GPSVersionID                         no
+  0x00b1   GPSLatitudeRef                       no
+  0x00b2   GPSLatitude                          no
+  0x00b5   GPSLongitudeRef                      no
+  0x00b6   GPSLongitude                         no
+  0x00b9   GPSAltitudeRef                       no
+  0x00ba   GPSAltitude                          no
+  0x00bb   GPSTimeStamp                         no
+  0x00be   GPSStatus                            no
+  0x00bf   GPSMeasureMode                       no
+  0x00c0   GPSDOP                               no
+  0x00c1   GPSSpeedRef                          no
+  0x00c2   GPSSpeed                             no
+  0x00c3   GPSTrackRef                          no
+  0x00c4   GPSTrack                             no
+  0x00c5   GPSImgDirectionRef                   no
+  0x00c6   GPSImgDirection                      no
+  0x00c7   GPSMapDatum                          no
+  0x00ca   GPSDateStamp                         no
   0x00e0   MakeModel                            H264 MakeModel
   0x00e1   RecInfo                              H264 RecInfo
-  0x00e4   Model                                N
+  0x00e4   Model                                no
   0x00ee   FrameInfo                            H264 FrameInfo
 
 =head3 H264 Camera1 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    ApertureSetting                      N
-      1    Gain                                 N
-    1.1    ExposureProgram                      N
-    2.1    WhiteBalance                         N
-      3    Focus                                N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    ApertureSetting                      no
+      1    Gain                                 no
+    1.1    ExposureProgram                      no
+    2.1    WhiteBalance                         no
+      3    Focus                                no
 
 =head3 H264 Camera2 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    ImageStabilization                   N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    ImageStabilization                   no
 
 =head3 H264 Shutter Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-    1.1    ExposureTime                         N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+    1.1    ExposureTime                         no
 
 =head3 H264 MakeModel Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Make                                 N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    Make                                 no
 
 =head3 H264 RecInfo Tags
@@ -13297,7 +25667,7 @@
 Recording information stored by some Canon video cameras.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    RecordingMode                        N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    RecordingMode                        no
 
 =head3 H264 FrameInfo Tags
@@ -13305,42 +25675,744 @@
 Frame rate information stored by some Canon video cameras.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    CaptureFrameRate                     N
-      1    VideoFrameRate                       N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    CaptureFrameRate                     no
+      1    VideoFrameRate                       no
 
 =head2 QuickTime Tags
 
 The QuickTime format is used for many different types of audio, video and
-image files.  Exiftool extracts meta information from the UserData atom
-(including some proprietary manufacturer-specific information), as well as
-extracting various audio, video and image parameters.  Tags with a question
-mark after their name are not extracted unless the Unknown option is set.
+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 Unknown 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<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).  Note that some tags with the same name but different ID's may
+exist in the same location, but the family 7 group names may be used to
+differentiate these.  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, the default language is written and 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.
+
+When writing string-based date/time tags, the system time zone is added if
+the PrintConv option is enabled and no time zone is specified.  This is
+because Apple software may display crazy values if the time zone is missing
+for some tags.
+
+See
+L<https://developer.apple.com/library/archive/documentation/QuickTime/QTFF/>
+for the official specification.
 
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'PICT'               PreviewPICT              N
-  'free'               Free?                    N
+  'GPS '               GPSDataList2?            no
+  '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
-  'junk'               Junk?                    N
-  'mdat'               MovieData?               N
-  'mdat-size'          MovieDataSize            N
+  'gps0'               GPSTrack                 QuickTime Stream
+  'gsen'               GSensor                  QuickTime Stream
+  'junk'               Junk?                    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
-  'pict'               PreviewPICT              N
+  'pict'               PreviewPICT              no
   'pnot'               Preview                  QuickTime Preview
-  'skip'               Skip?                    N
-  'uuid'               UUID-XMP                 XMP
+  'prrt'               ARDroneTelemetry         no
+  'skip'               CanonSkip                Canon Skip
+                       PreviewImage             no
+                       Skip?                    no
+  'thm '               ThumbnailImage           no
+  'thum'               ThumbnailImage           no
+  'udat'               GPSLog                   no
+  'udta'               UserData                 FLIR UserData
+  'uuid'               XMP                      XMP
                        UUID-PROF                QuickTime Profile
                        UUID-Flip                QuickTime Flip
-                       UUID-Unknown?            N
-  'wide'               Wide?                    N
+                       UUID-Canon2              Canon uuid2
+                       SensorData               QuickTime Tags360Fly
+                       SensorData               no
+                       PreviewImage             no
+                       UUID-Unknown?            no
+  'wide'               Wide?                    no
+
+=head3 QuickTime HTCInfo Tags
+
+Tags written by some HTC camera phones.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  '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 49 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
+  SampleDateTime                                no
+  SampleDuration                                no
+  SampleTime                                    no
+  Text                                          no
+  TimeCode                                      no
+  Unknown00?                                    no
+  Unknown01?                                    no
+  Unknown02?                                    no
+  Unknown03?                                    no
+  UserLabel                                     no
+  VerticalSpeed                                 no
+  VideoTimeStamp                                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                                    GoPro GPMF
+  gpmd_Rove                                     QuickTime Stream
+  marl                                          QuickTime marl
+  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 marl Tags
+
+Tags extracted from the marl ctbx timed metadata of GM cars.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  [no tags known]
+
+=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, and
+subtitle text in some other videos.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  'Alt'        GPSAltitude                      no
+  'DateTime'   DateTime                         no
+  'GimPitch'   GimbalPitch                      no
+  'GimRoll'    GimbalRoll                       no
+  'GimYaw'     GimbalYaw                        no
+  'Lat'        GPSLatitude                      no
+  'Lon'        GPSLongitude                     no
+  'Pitch'      Pitch                            no
+  'Roll'       Roll                             no
+  'Text'       Text                             no
+  'Yaw'        Yaw                              no
 
 =head3 QuickTime FileType Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MajorBrand                           N
-      1    MinorVersion                         N
-      2    CompatibleBrands                     N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    MajorBrand                           no
+      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'   DataInfo                             QuickTime DataInfo
+  'free'   Free?                                no
+  'hdlr'   Handler                              QuickTime Handler
+  'idat'   MetaImageSize                        no
+  'iinf'   ItemInformation                      QuickTime ItemInfo
+                                                QuickTime ItemInfo
+  'iloc'   ItemLocation                         no
+  'ilst'   ItemList                             QuickTime ItemList
+  'ipmc'   IPMPControl?                         no
+  'ipro'   ItemProtection?                      no
+  'iprp'   ItemProperties                       QuickTime ItemProp
+  'iref'   ItemReference                        QuickTime ItemRef
+  'keys'   Keys                                 QuickTime Keys
+  'pitm'   PrimaryItemReference                 no
+  'uuid'   MetaVersion                          no
+           UUID-Unknown?                        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
+  ------   --------                             --------
+      4    HandlerClass                         no
+      8    HandlerType                          no
+     12    HandlerVendorID                      no
+     24    HandlerDescription                   no
+
+=head3 QuickTime ItemInfo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'infe'   ItemInfoEntry                        no
+
+=head3 QuickTime ItemList Tags
+
+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 adds an 'mdir' (Metadata) Handler
+box because Apple software may ignore ItemList tags otherwise, but the API
+QuickTimeHandler option may be set to 0 to avoid this.
+
+  Tag ID       Tag Name                         Writable
+  ------       --------                         --------
+  '----'       iTunesInfo                       QuickTime iTunesInfo
+  '@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            int8s
+  'albm'       Album                            string/
+  'apID'       AppleStoreAccount                string
+  'atID'       AlbumTitleID                     int32s
+  'auth'       Author                           string
+  'catg'       Category                         string
+  'cnID'       AppleStoreCatalogID              int32s
+  'covr'       CoverArt                         string
+  'cpil'       Compilation                      int8s
+  'cprt'       Copyright                        string
+  'desc'       Description                      string/
+  'disk'       DiskNumber                       undef
+  'dscp'       Description                      string/
+  'egid'       EpisodeGlobalUniqueID            string
+  'geID'       GenreID                          int32s
+  'gnre'       Genre                            undef/
+  'grup'       Grouping                         string/
+  'gshh'       GoogleHostHeader                 string
+  'gspm'       GooglePingMessage                string
+  'gspu'       GooglePingURL                    string
+  'gssd'       GoogleSourceData                 string
+  'gsst'       GoogleStartTime                  string
+  'gstd'       GoogleTrackDuration              string
+  'hdvd'       HDVideo                          int8s
+  'itnu'       iTunesU                          int8s
+  'keyw'       Keyword                          string
+  'ldes'       LongDescription                  string
+  'pcst'       Podcast                          int8s
+  'perf'       Performer                        string
+  'pgap'       PlayGap                          int8s
+  'plID'       PlayListID                       int32s[0.25]
+  'prID'       ProductID                        string
+  'purd'       PurchaseDate                     string
+  'purl'       PodcastURL                       string
+  'rate'       RatingPercent                    string
+  'rldt'       ReleaseDate                      string
+  'rtng'       Rating                           int8s
+  'sdes'       StoreDescription                 string
+  'sfID'       AppleStoreCountry                int32s
+  'shwm'       ShowMovement                     int8s
+  'soaa'       SortAlbumArtist                  string
+  'soal'       SortAlbum                        string
+  'soar'       SortArtist                       string
+  'soco'       SortComposer                     string
+  'sonm'       SortName                         string
+  'sosn'       SortShow                         string
+  'stik'       MediaType                        int8s
+  'titl'       Title                            string/
+  'tmpo'       BeatsPerMinute                   int16s
+  'trkn'       TrackNumber                      undef
+  'tven'       TVEpisodeID                      string
+  'tves'       TVEpisode                        int32s
+  'tvnn'       TVNetworkName                    string
+  'tvsh'       TVShow                           string
+  'tvsn'       TVSeason                         int32u
+  'yrrc'       Year                             string
+  "\xa9ART"    Artist                           string
+  "\xa9alb"    Album                            string
+  "\xa9ard"    ArtDirector                      string
+  "\xa9arg"    Arranger                         string
+  "\xa9aut"    Author                           string/
+  "\xa9cmt"    Comment                          string
+  "\xa9com"    Composer                         string/
+  "\xa9con"    Conductor                        string
+  "\xa9cpy"    Copyright                        string/
+  "\xa9day"    ContentCreateDate                string
+  "\xa9des"    Description                      string
+  "\xa9dir"    Director                         string
+  "\xa9enc"    EncodedBy                        string
+  "\xa9gen"    Genre                            string
+  "\xa9grp"    Grouping                         string
+  "\xa9lyr"    Lyrics                           string
+  "\xa9mvc"    MovementCount                    int16s
+  "\xa9mvi"    MovementNumber                   int16s
+  "\xa9mvn"    MovementName                     string
+  "\xa9nam"    Title                            string
+  "\xa9nrt"    Narrator                         string
+  "\xa9ope"    OriginalArtist                   string
+  "\xa9prd"    Producer                         string
+  "\xa9pub"    Publisher                        string
+  "\xa9sne"    SoundEngineer                    string
+  "\xa9sol"    Soloist                          string
+  "\xa9st3"    Subtitle                         string
+  "\xa9too"    Encoder                          string
+  "\xa9trk"    Track                            string
+  "\xa9wrk"    Work                             string
+  "\xa9wrt"    Composer                         string
+  "\xa9xpd"    ExecutiveProducer                string
+  "\xa9xyz"    GPSCoordinates                   string
+
+=head3 QuickTime iTunesInfo Tags
+
+ExifTool will extract any iTunesInfo tags that exist, even if they are not
+defined in this table.
+
+  Tag ID                    Tag Name            Writable
+  ------                    --------            --------
+  'DISCNUMBER'              DiscNumber          no
+  'Encoding Params'         EncodingParams      QuickTime EncodingParams
+  'TRACKNUMBER'             TrackNumber         no
+  'iTunEXTC'                ContentRating       no
+  'iTunMOVI'                iTunMOVI            PLIST
+  'iTunNORM'                VolumeNormalization no
+  'iTunSMPB'                iTunSMPB            no
+  'iTunes_CDDB_1'           CDDB1Info           no
+  'iTunes_CDDB_TrackNumber' CDDBTrackNumber     no
+  'popularimeter'           Popularimeter       no
+  'tool'                    iTunTool            no
+
+=head3 QuickTime EncodingParams Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'abrt'   AudioAvailableBitRateRange           no
+  'acbf'   AudioBitRateControlMode              no
+  'acef'   AudioExtendFrequencies               no
+  'brat'   AudioCurrentTargetBitRate            no
+  'cdcv'   AudioComponentVersion                no
+  'cmnc'   AudioAvailableNumberChannels         no
+  'init'   AudioIsInitialized                   no
+  'lmrc'   AudioDoesSampleRateConversion        no
+  'mdel'   AudioMinimumDelayMode                no
+  'mnip'   AudioMinimumNumberInputPackets       no
+  'mnop'   AudioMinimumNumberOutputPackets      no
+  'oppr'   AudioOutputPrecedence                no
+  'pad0'   AudioZeroFramesPadded                no
+  'pakb'   AudioMaximumPacketByteSize           no
+  'pakd'   AudioRequiresPacketDescription       no
+  'pakf'   AudioPacketFrameSize                 no
+  'prmm'   AudioCodecPrimeMethod                no
+  'srcq'   AudioQualitySetting                  no
+  'tbuf'   AudioInputBufferSize                 no
+  'ubuf'   AudioUsedInputBufferSize             no
+  'ursr'   AudioUseRecommendedSampleRate        no
+  'vbrq'   AudioVBRQuality                      no
+  'vers'   AudioEncodingParamsVersion           no
+  'vpk?'   AudioHasVariablePacketByteSizes      no
+
+=head3 QuickTime ItemProp Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'ipco'   ItemPropertyContainer                QuickTime ItemPropCont
+  'ipma'   ItemPropertyAssociation              no
+
+=head3 QuickTime ItemPropCont Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'auxC'   AuxiliaryImageType                   no
+  'av1C'   AV1Configuration                     QuickTime AV1Config
+  'clap'   CleanAperture                        no
+  'colr'   ICC_Profile                          ICC_Profile
+           ColorRepresentation                  no
+  'hvcC'   HEVCConfiguration                    QuickTime HEVCConfig
+  'irot'   Rotation                             int8u!
+  'ispe'   ImageSpatialExtent                   no
+  'pasp'   PixelAspectRatio                     int32u!
+  'pixi'   ImagePixelDepth                      no
+  'rloc'   RelativeLocation                     no
+
+=head3 QuickTime AV1Config Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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 HEVCConfig Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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 ItemRef Tags
+
+The Item reference entries listed in the table below contain information about
+the associations between items in the file.  This information is used by
+ExifTool, but these entries are not extracted as tags.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'auxl'   AuxiliaryImageRef                    no
+  'cdsc'   ContentDescribes                     no
+  'dimg'   DerivedImageRef                      no
+  'thmb'   ThumbnailRef                         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
+  ------   --------                             --------
+  'meta'   Meta                                 QuickTime Meta
 
 =head3 QuickTime Movie Tags
@@ -13348,5 +26420,9 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'iods'   InitialObjectDescriptor?             N
+  'cmov'   CompressedMovie                      QuickTime CMovie
+  'gps '   GPSDataList?                         no
+  'htka'   HTCTrack                             QuickTime Track
+  'iods'   InitialObjectDescriptor?             no
+  'meco'   OtherMeta                            QuickTime OtherMeta
   'meta'   Meta                                 QuickTime Meta
   'mvhd'   MovieHeader                          QuickTime MovieHeader
@@ -13354,188 +26430,27 @@
   'udta'   UserData                             QuickTime UserData
   'uuid'   UUID-USMT                            QuickTime UserMedia
-           UUID-Unknown?                        N
-
-=head3 QuickTime Meta Tags
+           UUID-Canon                           Canon uuid
+           UUID-Unknown?                        no
+
+=head3 QuickTime CMovie Tags
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'bxml'   BinaryXML?                           N
-  'dinf'   DataInformation?                     N
-  'free'   Free?                                N
-  'hdlr'   Handler                              QuickTime Handler
-  'iinf'   ItemInformation?                     N
-  'iloc'   ItemLocation?                        N
-  'ilst'   ItemList                             QuickTime ItemList
-  'ipmc'   IPMPControl?                         N
-  'ipro'   ItemProtection?                      N
-  'keys'   Keys                                 QuickTime Keys
-  'pitm'   PrimaryItemReference?                N
-  'xml '   XML                                  XMP
-
-=head3 QuickTime Handler Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      4    HandlerClass                         N
-      8    HandlerType                          N
-     12    HandlerVendorID                      N
-     24    HandlerDescription                   N
-
-=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.
-
-  Tag ID       Tag Name                         Writable
-  ------       --------                         --------
-  '----'       iTunesInfo                       QuickTime iTunesInfo
-  'aART'       AlbumArtist                      N
-  'akID'       AppleStoreAccountType            N
-  'albm'       Album                            N
-  'apID'       AppleStoreAccount                N
-  'atID'       AlbumTitleID                     N
-  'auth'       Author                           N
-  'catg'       Category                         N
-  'cnID'       AppleStoreCatalogID              N
-  'covr'       CoverArt                         N
-  'cpil'       Compilation                      N
-  'cprt'       Copyright                        N
-  'desc'       Description                      N
-  'disk'       DiskNumber                       N
-  'dscp'       Description                      N
-  'egid'       EpisodeGlobalUniqueID            N
-  'geID'       GenreID                          N
-  'gnre'       Genre                            N
-  'grup'       Grouping                         N
-  'hdvd'       HDVideo                          N
-  'keyw'       Keyword                          N
-  'ldes'       LongDescription                  N
-  'pcst'       Podcast                          N
-  'perf'       Performer                        N
-  'pgap'       PlayGap                          N
-  'plID'       PlayListID                       N
-  'purd'       PurchaseDate                     N
-  'purl'       PodcastURL                       N
-  'rtng'       Rating                           N
-  'sfID'       AppleStoreCountry                N
-  'soaa'       SortAlbumArtist                  N
-  'soal'       SortAlbum                        N
-  'soar'       SortArtist                       N
-  'soco'       SortComposer                     N
-  'sonm'       SortName                         N
-  'sosn'       SortShow                         N
-  'stik'       MediaType                        N
-  'titl'       Title                            N
-  'tmpo'       BeatsPerMinute                   N
-  'trkn'       TrackNumber                      N
-  'tven'       TVEpisodeID                      N
-  'tves'       TVEpisode                        N
-  'tvnn'       TVNetworkName                    N
-  'tvsh'       TVShow                           N
-  'tvsn'       TVSeason                         N
-  'yrrc'       Year                             N
-  "\xa9ART"    Artist                           N
-  "\xa9alb"    Album                            N
-  "\xa9cmt"    Comment                          N
-  "\xa9com"    Composer                         N
-  "\xa9day"    Year                             N
-  "\xa9des"    Description                      N
-  "\xa9enc"    EncodedBy                        N
-  "\xa9gen"    Genre                            N
-  "\xa9grp"    Grouping                         N
-  "\xa9lyr"    Lyrics                           N
-  "\xa9nam"    Title                            N
-  "\xa9too"    Encoder                          N
-  "\xa9trk"    Track                            N
-  "\xa9wrt"    Composer                         N
-
-=head3 QuickTime iTunesInfo Tags
+  'dcom'   Compression                          no
+
+=head3 QuickTime Track Tags
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'data'   Data?                                N
-  'mean'   Mean?                                N
-  'name'   Name?                                N
-
-=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
-  ------                       --------         --------
-  'album'                      Album            N
-  'artist'                     Artist           N
-  'artwork'                    Artwork          N
-  'author'                     Author           N
-  'camera.framereadouttimeinmicroseconds'
-                               FrameReadoutTime N
-  'camera.identifier'          CameraIdentifier N
-  'comment'                    Comment          N
-  'copyright'                  Copyright        N
-  'creationdate'               CreationDate     N
-  'description'                Description      N
-  'direction.facing'           CameraDirection  N
-  'direction.motion'           CameraMotion     N
-  'director'                   Director         N
-  'genre'                      Genre            N
-  'information'                Information      N
-  'keywords'                   Keywords         N
-  'location.ISO6709'           GPSCoordinates   N
-  'location.body'              LocationBody     N
-  'location.date'              LocationDate     N
-  'location.name'              LocationName     N
-  'location.note'              LocationNote     N
-  'location.role'              LocationRole     N
-  'make'                       Make             N
-  'model'                      Model            N
-  'player.movie.audio.balance' Balance          N
-  'player.movie.audio.bass'    Bass             N
-  'player.movie.audio.gain'    AudioGain        N
-  'player.movie.audio.mute'    Mute             N
-  'player.movie.audio.pitchshift' PitchShift    N
-  'player.movie.audio.treble'  Trebel           N
-  'player.movie.visual.brightness' Brightness   N
-  'player.movie.visual.color'  Color            N
-  'player.movie.visual.contrast' Contrast       N
-  'player.movie.visual.tint'   Tint             N
-  'player.version'             PlayerVersion    N
-  'publisher'                  Publisher        N
-  'software'                   Software         N
-  'version'                    Version          N
-  'year'                       Year             N
-
-=head3 QuickTime MovieHeader Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MovieHeaderVersion                   N
-      1    CreateDate                           N
-      2    ModifyDate                           N
-      3    TimeScale                            N
-      4    Duration                             N
-      5    PreferredRate                        N
-      6    PreferredVolume                      N
-      9    MatrixStructure                      N
-     18    PreviewTime                          N
-     19    PreviewDuration                      N
-     20    PosterTime                           N
-     21    SelectionTime                        N
-     22    SelectionDuration                    N
-     23    CurrentTime                          N
-     24    NextTrackID                          N
-
-=head3 QuickTime Track Tags
-
-  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
   'tref'   TrackRef                             QuickTime TrackRef
   'udta'   UserData                             QuickTime UserData
   'uuid'   UUID-USMT                            QuickTime UserMedia
-           UUID-Unknown?                        N
+           SphericalVideoXML                    XMP
+           UUID-Unknown?                        no
 
 =head3 QuickTime Media Tags
@@ -13551,12 +26466,12 @@
 =head3 QuickTime MediaHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MediaHeaderVersion                   N
-      1    MediaCreateDate                      N
-      2    MediaModifyDate                      N
-      3    MediaTimeScale                       N
-      4    MediaDuration                        N
-      5    MediaLanguageCode                    N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    MediaHeaderVersion                   no
+      1    MediaCreateDate                      int32u
+      2    MediaModifyDate                      int32u
+      3    MediaTimeScale                       no
+      4    MediaDuration                        no
+      5    MediaLanguageCode                    no
 
 =head3 QuickTime MediaInfo Tags
@@ -13570,115 +26485,287 @@
   'hdlr'   Handler                              QuickTime Handler
   'hmhd'   HintHeader                           QuickTime HintHeader
-  'nmhd'   NullMediaHeader?                     N
+  'nmhd'   NullMediaHeader?                     no
   'smhd'   AudioHeader                          QuickTime AudioHeader
   'stbl'   SampleTable                          QuickTime SampleTable
   'vmhd'   VideoHeader                          QuickTime VideoHeader
 
-=head3 QuickTime DataInfo Tags
-
-MP4 data information box.
+=head3 QuickTime GenMediaHeader Tags
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'dref'   DataRef                              QuickTime DataRef
-
-=head3 QuickTime DataRef Tags
-
-MP4 data reference box.
+  'gmin'   GenMediaInfo                         QuickTime GenMediaInfo
+  'text'   Text?                                no
+  'tmcd'   TimeCode                             QuickTime TimeCode
+
+=head3 QuickTime GenMediaInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    GenMediaVersion                      no
+      1    GenFlags                             no
+      4    GenGraphicsMode                      no
+      6    GenOpColor                           no
+     12    GenBalance                           no
+
+=head3 QuickTime TimeCode Tags
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'url '   URL                                  N
-  'urn '   URN                                  N
-
-=head3 QuickTime GenMediaHeader Tags
+  'tcmi'   TCMediaInfo                          QuickTime TCMediaInfo
+
+=head3 QuickTime TCMediaInfo Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    TextFont                             no
+      6    TextFace                             no
+      8    TextSize                             no
+     12    TextColor                            no
+     18    BackgroundColor                      no
+     24    FontName                             no
+
+=head3 QuickTime HintHeader Tags
+
+MP4 hint media header.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      2    MaxPDUSize                           no
+      3    AvgPDUSize                           no
+      4    MaxBitrate                           no
+      6    AvgBitrate                           no
+
+=head3 QuickTime AudioHeader Tags
+
+MP4 audio media header.
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      2    Balance                              no
+
+=head3 QuickTime SampleTable Tags
+
+MP4 sample table box.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'gmin'   GenMediaInfo                         QuickTime GenMediaInfo
-  'text'   Text?                                N
-
-=head3 QuickTime GenMediaInfo Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    GenMediaVersion                      N
-      1    GenFlags                             N
-      4    GenGraphicsMode                      N
-      6    GenOpColor                           N
-     12    GenBalance                           N
-
-=head3 QuickTime HintHeader Tags
-
-MP4 hint media header.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    MaxPDUSize                           N
-      3    AvgPDUSize                           N
-      4    MaxBitrate                           N
-      6    AvgBitrate                           N
-
-=head3 QuickTime AudioHeader Tags
-
-MP4 audio media header.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    Balance                              N
-
-=head3 QuickTime SampleTable Tags
-
-MP4 sample table box.
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  'co64'   ChunkOffset64?                       N
-  'cslg'   CompositionToDecodeTimelineMapping?  N
-  'ctts'   CompositionTimeToSample?             N
-  'padb'   SamplePaddingBits?                   N
-  'sbgp'   SampleToGroup?                       N
-  'sdtp'   IdependentAndDisposableSamples?      N
-  'sgpd'   SampleGroupDescription?              N
-  'stco'   ChunkOffset?                         N
-  'stdp'   SampleDegradationPriority?           N
-  'stsc'   SampleToChunk?                       N
+  'co64'   ChunkOffset64?                       no
+  'cslg'   CompositionToDecodeTimelineMapping?  no
+  'ctts'   CompositionTimeToSample?             no
+  'padb'   SamplePaddingBits?                   no
+  'sbgp'   SampleToGroup?                       no
+  'sdtp'   IdependentAndDisposableSamples?      no
+  'sgpd'   SampleGroupDescription?              no
+  'stco'   ChunkOffset?                         no
+  'stdp'   SampleDegradationPriority?           no
+  'stps'   PartialSyncSamples                   no
+  'stsc'   SampleToChunk?                       no
   'stsd'   AudioSampleDesc                      QuickTime AudioSampleDesc
            VideoSampleDesc                      QuickTime ImageDesc
            HintSampleDesc                       QuickTime HintSampleDesc
+           MetaSampleDesc                       QuickTime MetaSampleDesc
            OtherSampleDesc                      QuickTime OtherSampleDesc
-  'stsh'   ShadowSyncSampleTable?               N
-  'stss'   SyncSampleTable?                     N
-  'stsz'   SampleSizes?                         N
-  'stts'   VideoFrameRate                       N
-           TimeToSampleTable?                   N
-  'stz2'   CompactSampleSizes?                  N
-  'subs'   Sub-sampleInformation?               N
+  'stsh'   ShadowSyncSampleTable?               no
+  'stss'   SyncSampleTable?                     no
+  'stsz'   SampleSizes?                         no
+  'stts'   VideoFrameRate                       no
+           TimeToSampleTable?                   no
+  'stz2'   CompactSampleSizes?                  no
+  'subs'   Sub-sampleInformation?               no
 
 =head3 QuickTime AudioSampleDesc Tags
 
-MP4 audio sample description.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    AudioFormat                          N
-     10    AudioVendorID                        N
-     12    AudioChannels                        N
-     13    AudioBitsPerSample                   N
-     16    AudioSampleRate                      N
-     28    AudioFormat                          N
+MP4 audio sample description.  This hybrid atom contains both data and child
+atoms.
+
+  ID/Index Tag Name                             Writable
+  -------- --------                             --------
+      4    AudioFormat                          no
+     20    AudioVendorID                        no
+     24    AudioChannels                        no
+     26    AudioBitsPerSample                   no
+     32    AudioSampleRate                      no
+  'chan'   AudioChannelLayout                   QuickTime ChannelLayout
+  'damr'   DecodeConfig                         QuickTime DecodeConfig
+  'pinf'   PurchaseInfo                         QuickTime ProtectionInfo
+  'sinf'   ProtectionInfo                       QuickTime ProtectionInfo
+  'wave'   Wave                                 QuickTime Wave
+
+=head3 QuickTime ChannelLayout Tags
+
+Audio channel layout.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    LayoutFlags                          no
+      6    AudioChannels                        no
+      8    AudioChannelTypes                    no
+     12    NumChannelDescriptions               no
+     16    Channel1Label                        no
+     20    Channel1Flags                        no
+     24    Channel1Coordinates                  no
+     36    Channel2Label                        no
+     40    Channel2Flags                        no
+     44    Channel2Coordinates                  no
+     56    Channel3Label                        no
+     60    Channel3Flags                        no
+     64    Channel3Coordinates                  no
+     76    Channel4Label                        no
+     80    Channel4Flags                        no
+     84    Channel4Coordinates                  no
+     96    Channel5Label                        no
+    100    Channel5Flags                        no
+    104    Channel5Coordinates                  no
+    116    Channel6Label                        no
+    120    Channel6Flags                        no
+    124    Channel6Coordinates                  no
+    136    Channel7Label                        no
+    140    Channel7Flags                        no
+    144    Channel7Coordinates                  no
+    156    Channel8Label                        no
+    160    Channel8Flags                        no
+    164    Channel8Coordinates                  no
+
+=head3 QuickTime DecodeConfig Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    EncoderVendor                        no
+      4    EncoderVersion                       no
+
+=head3 QuickTime ProtectionInfo Tags
+
+Child atoms found in "sinf" and/or "pinf" atoms.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'enda'   Endianness                           no
+  'frma'   OriginalFormat                       no
+  'schi'   SchemeInfo                           QuickTime SchemeInfo
+  'schm'   SchemeType                           QuickTime SchemeType
+
+=head3 QuickTime SchemeInfo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'cert'   Certificate                          no
+  'iviv'   InitializationVector                 no
+  'key '   KeyID                                no
+  'name'   UserName                             no
+  'righ'   Rights                               QuickTime Rights
+  'user'   UserID                               no
+
+=head3 QuickTime Rights Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'aver'   VersionRestrictions                  no
+  'medi'   MediaFlags                           no
+  'mode'   ModeFlags                            no
+  'plat'   Platform                             no
+  'song'   ItemID                               no
+  'tool'   ItemTool                             no
+  'tran'   TransactionID                        no
+  'veID'   ItemVendorID                         no
+
+=head3 QuickTime SchemeType Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    SchemeType                           no
+      8    SchemeVersion                        no
+     10    SchemeURL                            no
+
+=head3 QuickTime Wave Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'enda'   Endianness                           no
+  'frma'   PurchaseFileFormat                   no
 
 =head3 QuickTime ImageDesc Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    CompressorID                         N
-     10    VendorID                             N
-     16    SourceImageWidth                     N
-     17    SourceImageHeight                    N
-     18    XResolution                          N
-     20    YResolution                          N
-     25    CompressorName                       N
-     41    BitDepth                             N
+  ID/Index Tag Name                             Writable
+  -------- --------                             --------
+      2    CompressorID                         no
+     10    VendorID                             no
+     16    SourceImageWidth                     no
+     17    SourceImageHeight                    no
+     18    XResolution                          no
+     20    YResolution                          no
+     25    CompressorName                       no
+     41    BitDepth                             no
+  'CDI1'   CDI1                                 Canon CDI1
+  'CMP1'   CMP1                                 Canon CMP1
+  'JPEG'   JPEGInfo?                            no
+  'avcC'   AVCConfiguration?                    no
+  'btrt'   BitrateInfo                          QuickTime Bitrate
+  'clap'   CleanAperture                        QuickTime CleanAperture
+  'colr'   ColorRepresentation                  no
+  'fiel'   VideoFieldOrder                      no
+  'gama'   Gamma                                no
+  'pasp'   PixelAspectRatio                     no
+  'st3d'   Stereoscopic3D                       no
+  'sv3d'   SphericalVideo                       QuickTime sv3d
+
+=head3 QuickTime Bitrate Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    BufferSize                           no
+      1    MaxBitrate                           no
+      2    AverageBitrate                       no
+
+=head3 QuickTime CleanAperture Tags
+
+  Index8   Tag Name                             Writable
+  ------   --------                             --------
+      0    CleanApertureWidth                   no
+      1    CleanApertureHeight                  no
+      2    CleanApertureOffsetX                 no
+      3    CleanApertureOffsetY                 no
+
+=head3 QuickTime sv3d Tags
+
+Tags defined by the Spherical Video V2 specification.  See
+L<https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md>
+for the specification.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'proj'   Projection                           QuickTime proj
+  'svhd'   MetadataSource                       no
+
+=head3 QuickTime proj Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'cbmp'   CubemapProj                          QuickTime cbmp
+  'equi'   EquirectangularProj                  QuickTime equi
+  'prhd'   ProjectionHeader                     QuickTime prhd
+
+=head3 QuickTime cbmp Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    Layout                               no
+      2    Padding                              no
+
+=head3 QuickTime equi Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    ProjectionBoundsTop                  no
+      2    ProjectionBoundsBottom               no
+      3    ProjectionBoundsLeft                 no
+      4    ProjectionBoundsRight                no
+
+=head3 QuickTime prhd Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    PoseYawDegrees                       no
+      2    PosePitchDegrees                     no
+      3    PoseRollDegrees                      no
 
 =head3 QuickTime HintSampleDesc Tags
@@ -13686,13 +26773,30 @@
 MP4 hint sample description.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    HintFormat                           N
+  ID/Index Tag Name                             Writable
+  -------- --------                             --------
+      4    HintFormat                           no
+     16    HintTrackVersion                     no
+     20    MaxPacketSize                        no
+  'snro'   SequenceNumberRandomOffset           no
+  'tims'   RTPTimeScale                         no
+  'tsro'   TimestampRandomOffset                no
+
+=head3 QuickTime MetaSampleDesc Tags
+
+MP4 metadata sample description.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0004   MetaFormat                           no
+  'btrt'   BitrateInfo                          QuickTime Bitrate
+  'keys'   Keys                                 QuickTime Keys
 
 =head3 QuickTime OtherSampleDesc Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    OtherFormat                          N
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0004   OtherFormat                          no
+  'ftab'   FontTable                            no
+  'name'   OtherName                            no
 
 =head3 QuickTime VideoHeader Tags
@@ -13700,23 +26804,31 @@
 MP4 video media header.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    GraphicsMode                         N
-      3    OpColor                              N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      2    GraphicsMode                         no
+      3    OpColor                              no
+
+=head3 QuickTime TrackAperture Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'clef'   CleanApertureDimensions              no
+  'enof'   EncodedPixelsDimensions              no
+  'prof'   ProductionApertureDimensions         no
 
 =head3 QuickTime TrackHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    TrackHeaderVersion                   N
-      1    TrackCreateDate                      N
-      2    TrackModifyDate                      N
-      3    TrackID                              N
-      5    TrackDuration                        N
-      8    TrackLayer                           N
-      9    TrackVolume                          N
-     10    MatrixStructure                      N
-     19    ImageWidth                           N
-     20    ImageHeight                          N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    TrackHeaderVersion                   no
+      1    TrackCreateDate                      int32u
+      2    TrackModifyDate                      int32u
+      3    TrackID                              no
+      5    TrackDuration                        no
+      8    TrackLayer                           no
+      9    TrackVolume                          no
+     10    MatrixStructure                      fixed32s[9]!
+     19    ImageWidth                           no
+     20    ImageHeight                          no
 
 =head3 QuickTime TrackRef Tags
@@ -13724,32 +26836,66 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'chap'   ChapterList                          N
+  'cdsc'   ContentDescribes                     no
+  'chap'   ChapterListTrackID                   no
+  'mpod'   ElementaryStreamTrack                no
+  'tmcd'   TimeCode                             no
 
 =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
   ------       --------                         --------
-  'AllF'       PlayAllFrames                    N
-  'CNCV'       CompressorVersion                N
-  'CNFV'       FirmwareVersion                  N
-  'CNMN'       Model                            N
+  '@day'       ContentCreateDate                string/
+  '@mak'       Make                             string/
+  '@mod'       Model                            string/
+  '@sec'       SamsungSec                       Samsung sec
+  '@swr'       SoftwareVersion                  string/
+  '@xyz'       GPSCoordinates                   string/
+  'AllF'       PlayAllFrames                    int8u
+  'CAME'       SerialNumberHash                 string
+  'CNCV'       CompressorVersion                string
+  'CNFV'       FirmwareVersion                  string
+  'CNMN'       Model                            string/
+  'CNOP'       CanonCNOP                        Canon CNOP
   'CNTH'       CanonCNTH                        Canon CNTH
-  'DcMD'       DcMD                             QuickTime DcMD
+  'DcMD'       KodakDcMD                        Kodak DcMD
   'FFMV'       FujiFilmFFMV                     FujiFilm FFMV
+  'FIRM'       FirmwareVersion                  string/
+  "FOV\0"      FieldOfView                      string
+  'GPMF'       GoProGPMF                        GoPro GPMF
+  'GoPr'       GoProType                        string
   'INFO'       SamsungINFO                      Samsung INFO
-  'LOOP'       LoopStyle                        N
+  'LEIC'       LeicaLEIC                        Panasonic PANA
+  'LENS'       LensSerialNumber                 string
+  'LOOP'       LoopStyle                        int32u
+  'Lvlm'       LevelMeter?                      rational64s
   'MMA0'       MinoltaMMA0                      Minolta MMA
   'MMA1'       MinoltaMMA1                      Minolta MMA
   'MVTG'       FujiFilmMVTG                     EXIF
   'NCDT'       NikonNCDT                        Nikon NCDT
+  'PANA'       PanasonicPANA                    Panasonic PANA
+  'PENT'       PentaxPENT                       Pentax PENT
+  'PXMN'       MakerNotePentax5b                Pentax
+               MakerNotePentax5c                Pentax
+               MakerNotePentaxUnknown           string
+  'PXTH'       PentaxPreview                    Pentax PXTH
   'QVMI'       CasioQVMI                        EXIF
-  'SDLN'       PlayMode                         N
-  'SelO'       PlaySelection                    N
-  'TAGS'       KodakTags                        Kodak MOV
+  'RMKN'       RicohRMKN                        EXIF
+  'RTHU'       PreviewImage                     no
+  'SDLN'       PlayMode                         string
+  'SNum'       SerialNumber                     string/
+  'SelO'       PlaySelection                    int8u
+  'TAGS'       FujiFilmTags                     FujiFilm MOV
+               KodakTags                        Kodak MOV
                KonicaMinoltaTags                Minolta MOV1
                MinoltaTags                      Minolta MOV2
@@ -13758,143 +26904,242 @@
                OlympusTags2                     Olympus MOV2
                OlympusTags3                     Olympus MP4
+               OlympusTags4                     Olympus MOV3
                PentaxTags                       Pentax MOV
                SamsungTags                      Samsung MP4
                SanyoMOV                         Sanyo MOV
                SanyoMP4                         Sanyo MP4
-               UnknownTags?                     N
-  'WLOC'       WindowLocation                   N
+               UnknownTags?                     string
+  'TTMD'       TomTomMetaData                   QuickTime TomTom
+  'WLOC'       WindowLocation                   int16u
   'XMP_'       XMP                              XMP
+  'Xtra'       MicrosoftXtra                    Microsoft Xtra
+  '_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                     string
+  'clid'       ClipID                           string
+  'clsf'       Classification                   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                      string
   'hnti'       HintInfo                         QuickTime HintInfo
+  'htcb'       HTCBinary                        QuickTime HTCBinary
+  'icnu'       IconURI                          string
+  'infu'       InfoURL                          string
+  'kgtt'       TrackType                        string
+  'kywd'       Keywords                         no
+  'loci'       LocationInformation              no
+  'lrcu'       LyricsURI                        string
+  'lvlm'       LevelMeter?                      rational64s
+  'manu'       Make                             no
   'meta'       Meta                             QuickTime Meta
-  'name'       Name                             N
+  'modl'       Model                            no
+  'name'       Name                             string
+  'perf'       Performer                        string/
+  'pmcc'       GarminSettings                   string
+  'pose'       pose                             Kodak pose
+  'ptch'       Pitch                            rational64s/
   'ptv '       PrintToVideo                     QuickTime Video
-  'vndr'       Vendor                           N
-  "\xa9ART"    Artist                           N
-  "\xa9alb"    Album                            N
-  "\xa9arg"    Arranger                         N
-  "\xa9ark"    ArrangerKeywords                 N
-  "\xa9cmt"    Comment                          N
-  "\xa9cok"    ComposerKeywords                 N
-  "\xa9com"    Composer                         N
-  "\xa9cpy"    Copyright                        N
-  "\xa9day"    CreateDate                       N
-  "\xa9dir"    Director                         N
-  "\xa9ed1"    Edit1                            N
-  "\xa9ed2"    Edit2                            N
-  "\xa9ed3"    Edit3                            N
-  "\xa9ed4"    Edit4                            N
-  "\xa9ed5"    Edit5                            N
-  "\xa9ed6"    Edit6                            N
-  "\xa9ed7"    Edit7                            N
-  "\xa9ed8"    Edit8                            N
-  "\xa9ed9"    Edit9                            N
-  "\xa9fmt"    Format                           N
-  "\xa9gen"    Genre                            N
-  "\xa9grp"    Grouping                         N
-  "\xa9inf"    Information                      N
-  "\xa9isr"    ISRCCode                         N
-  "\xa9lab"    RecordLabelName                  N
-  "\xa9lal"    RecordLabelURL                   N
-  "\xa9lyr"    Lyrics                           N
-  "\xa9mak"    Make                             N
-  "\xa9mal"    MakerURL                         N
-  "\xa9mod"    Model                            N
-  "\xa9nam"    Title                            N
-  "\xa9pdk"    ProducerKeywords                 N
-  "\xa9phg"    RecordingCopyright               N
-  "\xa9prd"    Producer                         N
-  "\xa9prf"    Performers                       N
-  "\xa9prk"    PerformerKeywords                N
-  "\xa9prl"    PerformerURL                     N
-  "\xa9req"    Requirements                     N
-  "\xa9snk"    SubtitleKeywords                 N
-  "\xa9snm"    Subtitle                         N
-  "\xa9src"    SourceCredits                    N
-  "\xa9swf"    SongWriter                       N
-  "\xa9swk"    SongWriterKeywords               N
-  "\xa9swr"    SoftwareVersion                  N
-  "\xa9too"    Encoder                          N
-  "\xa9trk"    Track                            N
-  "\xa9wrt"    Composer                         N
-  "\xa9xyz"    GPSCoordinates                   N
-
-=head3 QuickTime DcMD Tags
-
-Metadata directory found in MOV videos from some Kodak cameras.
+  'rads'       Rads?                            rational64s
+  'reel'       ReelName                         string
+  'roll'       Roll                             rational64s/
+  'rtng'       Rating                           no
+  'scen'       Scene                            string
+  'scrn'       OlympusPreview                   Olympus scrn
+  'shot'       ShotName                         string
+  'slno'       SerialNumber                     string
+  'smta'       SamsungSmta                      Samsung smta
+  'tags'       Audible_tags                     Audible tags
+  'thmb'       MakerNotePentax5a                Pentax
+               OlympusThumbnail                 Olympus thmb
+               ThumbnailImage                   string
+               ThumbnailPNG                     string
+               UnknownThumbnail                 string
+  'titl'       Title                            string/
+  'urat'       UserRating                       no
+  'uuid'       GarminSoftware                   string
+               UUID-Unknown?                    no
+  'vndr'       Vendor                           string
+  'vrot'       AccelerometerData                no
+  'yrrc'       Year                             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
   ------   --------                             --------
-  'Cmbo'   CameraByteOrder                      N
-  'DcME'   DcME                                 QuickTime DcME
-
-=head3 QuickTime DcME Tags
+  'TTAD'   TomTomAD                             QuickTime Stream
+  'TTHL'   TomTomHL?                            no
+  'TTID'   TomTomID                             no
+  'TTVD'   TomTomVD                             no
+  'TTVI'   TomTomVI?                            no
+
+=head3 QuickTime HintTrackInfo Tags
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
+  'dimm'   ImmediateDataBytes                   no
+  'dmax'   LargestPacketDuration                no
+  'dmed'   MediaTrackBytes                      no
+  'drep'   RepeatedDataBytes                    no
+  'maxr'   MaxDataRate                          no
+  'npck'   NumPackets                           no
+  'nump'   NumPackets                           no
+  'payt'   PayloadType                          no
+  'pmax'   LargestPacketSize                    no
+  'tmax'   MaxTransmissionTime                  no
+  'tmin'   MinTransmissionTime                  no
+  'totl'   TotalBytes                           no
+  'tpaY'   TotalBytesNoRTPHeaders               no
+  'tpay'   TotalBytesNoRTPHeaders               no
+  'tpyl'   TotalBytesNoRTPHeaders               no
+  'trpY'   TotalBytes                           no
+  'trpy'   TotalBytes                           no
+
+=head3 QuickTime HintInfo Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'rtp '   RealtimeStreamingProtocol            no
+  'sdp '   StreamingDataProtocol                no
+
+=head3 QuickTime HTCBinary Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
 
-=head3 QuickTime HintTrackInfo Tags
+=head3 QuickTime Video Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    DisplaySize                          no
+      6    SlideShow                            no
+
+=head3 QuickTime UserMedia Tags
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'dimm'   ImmediateDataBytes                   N
-  'dmax'   LargestPacketDuration                N
-  'dmed'   MediaTrackBytes                      N
-  'drep'   RepeatedDataBytes                    N
-  'maxr'   MaxDataRate                          N
-  'npck'   NumPackets                           N
-  'nump'   NumPackets                           N
-  'payt'   PayloadType                          N
-  'pmax'   LargestPacketSize                    N
-  'tmax'   MaxTransmissionTime                  N
-  'tmin'   MinTransmissionTime                  N
-  'totl'   TotalBytes                           N
-  'tpaY'   TotalBytesNoRTPHeaders               N
-  'tpay'   TotalBytesNoRTPHeaders               N
-  'tpyl'   TotalBytesNoRTPHeaders               N
-  'trpY'   TotalBytes                           N
-  'trpy'   TotalBytes                           N
-
-=head3 QuickTime HintInfo Tags
+  'MTDT'   MetaData                             QuickTime MetaData
+
+=head3 QuickTime MetaData Tags
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'rtp '   RealtimeStreamingProtocol            N
-  'sdp '   StreamingDataProtocol                N
-
-=head3 QuickTime Video Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    DisplaySize                          N
-      6    SlideShow                            N
-
-=head3 QuickTime UserMedia Tags
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  'MTDT'   MetaData                             QuickTime MetaData
-
-=head3 QuickTime MetaData Tags
-
-  Tag ID   Tag Name                             Writable
-  ------   --------                             --------
-  0x0001   Title                                N
-  0x0003   ProductionDate                       N
-  0x0004   Software                             N
-  0x0005   Product                              N
-  0x000a   TrackProperty                        N
-  0x000b   TimeZone                             N
-  0x000c   ModifyDate                           N
+  0x0001   Title                                no
+  0x0003   ProductionDate                       no
+  0x0004   Software                             no
+  0x0005   Product                              no
+  0x000a   TrackProperty                        no
+  0x000b   TimeZone                             no
+  0x000c   ModifyDate                           no
+
+=head3 QuickTime MovieHeader Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    MovieHeaderVersion                   no
+      1    CreateDate                           int32u
+      2    ModifyDate                           int32u
+      3    TimeScale                            no
+      4    Duration                             no
+      5    PreferredRate                        no
+      6    PreferredVolume                      no
+      9    MatrixStructure                      no
+     18    PreviewTime                          no
+     19    PreviewDuration                      no
+     20    PosterTime                           no
+     21    SelectionTime                        no
+     22    SelectionDuration                    no
+     23    CurrentTime                          no
+     24    NextTrackID                          no
 
 =head3 QuickTime Preview Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    PreviewDate                          N
-      2    PreviewVersion                       N
-      3    PreviewAtomType                      N
-      5    PreviewAtomIndex                     N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    PreviewDate                          int32u
+      2    PreviewVersion                       no
+      3    PreviewAtomType                      no
+      5    PreviewAtomIndex                     no
 
 =head3 QuickTime Profile Tags
@@ -13904,42 +27149,43 @@
   'APRF'   AudioProfile                         QuickTime AudioProf
   'FPRF'   FileGlobalProfile                    QuickTime FileProf
+  'OLYM'   OlympusOLYM                          Olympus OLYM
   'VPRF'   VideoProfile                         QuickTime VideoProf
 
 =head3 QuickTime AudioProf Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    AudioProfileVersion?                 N
-      1    AudioTrackID                         N
-      2    AudioCodec                           N
-      3    AudioCodecInfo?                      N
-      4    AudioAttributes                      N
-      5    AudioAvgBitrate                      N
-      6    AudioMaxBitrate                      N
-      7    AudioSampleRate                      N
-      8    AudioChannels                        N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    AudioProfileVersion?                 no
+      1    AudioTrackID                         no
+      2    AudioCodec                           no
+      3    AudioCodecInfo?                      no
+      4    AudioAttributes                      no
+      5    AudioAvgBitrate                      no
+      6    AudioMaxBitrate                      no
+      7    AudioSampleRate                      no
+      8    AudioChannels                        no
 
 =head3 QuickTime FileProf Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FileProfileVersion?                  N
-      1    FileFunctionFlags                    N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    FileProfileVersion?                  no
+      1    FileFunctionFlags                    no
 
 =head3 QuickTime VideoProf Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    VideoProfileVersion?                 N
-      1    VideoTrackID                         N
-      2    VideoCodec                           N
-      3    VideoCodecInfo?                      N
-      4    VideoAttributes                      N
-      5    VideoAvgBitrate                      N
-      6    VideoMaxBitrate                      N
-      7    VideoAvgFrameRate                    N
-      8    VideoMaxFrameRate                    N
-      9    VideoSize                            N
-     10    PixelAspectRatio                     N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    VideoProfileVersion?                 no
+      1    VideoTrackID                         no
+      2    VideoCodec                           no
+      3    VideoCodecInfo?                      no
+      4    VideoAttributes                      no
+      5    VideoAvgBitrate                      no
+      6    VideoMaxBitrate                      no
+      7    VideoAvgFrameRate                    no
+      8    VideoMaxFrameRate                    no
+      9    VideoSize                            no
+     10    PixelAspectRatio                     no
 
 =head3 QuickTime Flip Tags
@@ -13947,11 +27193,77 @@
 Found in MP4 files from Flip Video cameras.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      1    PreviewImageWidth                    N
-      2    PreviewImageHeight                   N
-     13    PreviewImageLength                   N
-     14    SerialNumber                         N
-     28    PreviewImage                         N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    PreviewImageWidth                    no
+      2    PreviewImageHeight                   no
+     13    PreviewImageLength                   no
+     14    SerialNumber                         no
+     28    PreviewImage                         no
+
+=head3 QuickTime Tags360Fly Tags
+
+Timed metadata found in MP4 videos from the 360Fly.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   Accel360Fly                          QuickTime Accel360Fly
+  0x0002   Gyro360Fly                           QuickTime Gyro360Fly
+  0x0003   Mag360Fly                            QuickTime Mag360Fly
+  0x0005   GPS360Fly                            QuickTime GPS360Fly
+  0x0006   Rot360Fly                            QuickTime Rot360Fly
+  0x00fa   Fusion360Fly                         QuickTime Fusion360Fly
+
+=head3 QuickTime Accel360Fly Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    AccelMode?                           no
+      2    SampleTime                           no
+     10    AccelYPR                             no
+
+=head3 QuickTime Gyro360Fly Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    GyroMode?                            no
+      2    SampleTime                           no
+     10    GyroYPR                              no
+
+=head3 QuickTime Mag360Fly Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    MagMode?                             no
+      2    SampleTime                           no
+     10    MagnetometerXYZ                      no
+
+=head3 QuickTime GPS360Fly Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    GPSMode?                             no
+      2    SampleTime                           no
+     10    GPSLatitude                          no
+     14    GPSLongitude                         no
+     18    GPSAltitude                          no
+     22    GPSSpeed                             no
+     24    GPSTrack                             no
+     26    Acceleration                         no
+
+=head3 QuickTime Rot360Fly Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    RotMode?                             no
+      2    SampleTime                           no
+     10    RotationXYZ                          no
+
+=head3 QuickTime Fusion360Fly Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    FusionMode?                          no
+      2    SampleTime                           no
+     10    FusionYPR                            no
 
 =head3 QuickTime ImageFile Tags
@@ -13961,7 +27273,176 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'idat'   ImageData                            N
+  'idat'   ImageData                            no
   'idsc'   ImageDescription                     QuickTime ImageDesc
   'iicc'   ICC_Profile                          ICC_Profile
+
+=head2 Parrot Tags
+
+=head3 Parrot mett Tags
+
+Streaming metadata found in Parrot drone videos. See
+L<https://developer.parrot.com/docs/pdraw/metadata.html> for the
+specification.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  '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 Parrot V1 Tags
+
+Parrot version 1 streaming metadata.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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
+
+=head3 Parrot V2 Tags
+
+Parrot version 2 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    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    TimeStamp                            no
+
+=head3 Parrot FollowMe Tags
+
+Parrot streaming metadata follow-me extension.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    GPSTargetLatitude                    no
+      8    GPSTargetLongitude                   no
+     12    GPSTargetAltitude                    no
+     16    Follow-meMode                        no
+     17    Follow-meAnimation                   no
+
+=head3 Parrot Automation Tags
+
+Parrot streaming metadata automation extension.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      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
+
+Apple Property List tags.  ExifTool reads both XML and binary-format PLIST
+files, and will extract any existing tags even if they aren't listed below.
+These tags belong to the family 0 "PLIST" group, but family 1 group may be
+either "XML" or "PLIST" depending on whether the format is XML or binary.
+
+  Tag ID                       Tag Name         Writable
+  ------                       --------         --------
+  'MetaDataList//DateTimeOriginal'
+                               DateTimeOriginal no
+  'MetaDataList//Duration'     Duration         no
+  'MetaDataList//Geolocation/Latitude'
+                               GPSLatitude      no
+  'MetaDataList//Geolocation/Longitude'
+                               GPSLongitude     no
+  'MetaDataList//Geolocation/MapDatum'
+                               GPSMapDatum      no
+  'XMLFileType'                XMLFileType      no
+  'cast//name'                 Cast             no+
+  'codirectors//name'          Codirectors      no+
+  'directors//name'            Directors        no+
+  'producers//name'            Producers        no+
+  'screenwriters//name'        Screenwriters    no+
+  'studio//name'               Studio           no+
 
 =head2 Matroska Tags
@@ -13977,195 +27458,196 @@
   ------       --------                         --------
   0x0000       ChapterDisplay                   Matroska
-  0x0003       TrackType                        N
-  0x0005       ChapterString                    N
-  0x0006       VideoCodecID                     N
-               AudioCodecID                     N
-               CodecID                          N
-  0x0008       TrackDefault                     N
-  0x0009       ChapterTrackNumber?              N
+  0x0003       TrackType                        no
+  0x0005       ChapterString                    no
+  0x0006       VideoCodecID                     no
+               AudioCodecID                     no
+               CodecID                          no
+  0x0008       TrackDefault                     no
+  0x0009       ChapterTrackNumber?              no
   0x000e       Slices                           Matroska
   0x000f       ChapterTrack                     Matroska
-  0x0011       ChapterTimeStart                 N
-  0x0012       ChapterTimeEnd                   N
-  0x0016       CueRefTime?                      N
-  0x0017       CueRefCluster?                   N
-  0x0018       ChapterFlagHidden?               N
-  0x001a       VideoScanType                    N
-  0x001b       BlockDuration?                   N
-  0x001c       TrackLacing?                     N
-  0x001f       AudioChannels                    N
+  0x0011       ChapterTimeStart                 no
+  0x0012       ChapterTimeEnd                   no
+  0x0016       CueRefTime?                      no
+  0x0017       CueRefCluster?                   no
+  0x0018       ChapterFlagHidden?               no
+  0x001a       VideoScanType                    no
+  0x001b       BlockDuration?                   no
+  0x001c       TrackLacing?                     no
+  0x001f       AudioChannels                    no
   0x0020       BlockGroup                       Matroska
-  0x0021       Block?                           N
-  0x0022       BlockVirtual?                    N
-  0x0023       SimpleBlock?                     N
-  0x0024       CodecState?                      N
-  0x0025       BlockAdditional?                 N
+  0x0021       Block?                           no
+  0x0022       BlockVirtual?                    no
+  0x0023       SimpleBlock?                     no
+  0x0024       CodecState?                      no
+  0x0025       BlockAdditional?                 no
   0x0026       BlockMore                        Matroska
-  0x0027       Position                         N
-  0x002a       CodecDecodeAll                   N
-  0x002b       PrevSize                         N
+  0x0027       Position                         no
+  0x002a       CodecDecodeAll                   no
+  0x002b       PrevSize                         no
   0x002e       TrackEntry                       Matroska
-  0x002f       EncryptedBlock?                  N
-  0x0030       ImageWidth                       N
-  0x0033       CueTime?                         N
-  0x0035       AudioSampleRate                  N
+  0x002f       EncryptedBlock?                  no
+  0x0030       ImageWidth                       no
+  0x0033       CueTime?                         no
+  0x0035       AudioSampleRate                  no
   0x0036       ChapterAtom                      Matroska
   0x0037       CueTrackPositions                Matroska
-  0x0039       TrackUsed                        N
-  0x003a       ImageHeight                      N
+  0x0039       TrackUsed                        no
+  0x003a       ImageHeight                      no
   0x003b       CuePoint                         Matroska
-  0x003f       CRC-32?                          N
-  0x004b       BlockAdditionalID?               N
-  0x004c       LaceNumber?                      N
-  0x004d       FrameNumber?                     N
-  0x004e       Delay?                           N
-  0x004f       ClusterDuration?                 N
-  0x0057       TrackNumber                      N
+  0x003f       CRC-32?                          no
+  0x004b       BlockAdditionalID?               no
+  0x004c       LaceNumber?                      no
+  0x004d       FrameNumber?                     no
+  0x004e       Delay?                           no
+  0x004f       ClusterDuration?                 no
+  0x0057       TrackNumber                      no
   0x005b       CueReference                     Matroska
   0x0060       Video                            Matroska
   0x0061       Audio                            Matroska
-  0x0067       Timecode?                        N
+  0x0067       TimeCode?                        no
   0x0068       TimeSlice                        Matroska
-  0x006a       CueCodecState?                   N
-  0x006b       CueRefCodecState?                N
-  0x006c       Void?                            N
-  0x006e       BlockAddID?                      N
-  0x0071       CueClusterPosition?              N
-  0x0077       CueTrack?                        N
-  0x007a       ReferencePriority?               N
-  0x007b       ReferenceBlock?                  N
-  0x007d       ReferenceVirtual?                N
-  0x0254       ContentCompressionAlgorithm      N
-  0x0255       ContentCompressionSettings?      N
-  0x0282       DocType                          N
-  0x0285       DocTypeReadVersion               N
-  0x0286       EBMLVersion                      N
-  0x0287       DocTypeVersion                   N
-  0x02f2       EBMLMaxIDLength?                 N
-  0x02f3       EBMLMaxSizeLength?               N
-  0x02f7       EBMLReadVersion                  N
-  0x037c       ChapterLanguage                  N
-  0x037e       ChapterCountry                   N
-  0x0444       SegmentFamily?                   N
-  0x0461       DateTimeOriginal                 N
-  0x047a       TagLanguage                      N
-  0x0484       TagDefault                       N
-  0x0485       TagBinary                        N
-  0x0487       TagString                        N
-  0x0489       Duration                         N
-  0x050d       ChapterProcessPrivate?           N
-  0x0598       ChapterFlagEnabled?              N
-  0x05a3       TagName                          N
+  0x006a       CueCodecState?                   no
+  0x006b       CueRefCodecState?                no
+  0x006c       Void?                            no
+  0x006e       BlockAddID?                      no
+  0x0071       CueClusterPosition?              no
+  0x0077       CueTrack?                        no
+  0x007a       ReferencePriority?               no
+  0x007b       ReferenceBlock?                  no
+  0x007d       ReferenceVirtual?                no
+  0x0254       ContentCompressionAlgorithm      no
+  0x0255       ContentCompressionSettings?      no
+  0x0282       DocType                          no
+  0x0285       DocTypeReadVersion               no
+  0x0286       EBMLVersion                      no
+  0x0287       DocTypeVersion                   no
+  0x02f2       EBMLMaxIDLength?                 no
+  0x02f3       EBMLMaxSizeLength?               no
+  0x02f7       EBMLReadVersion                  no
+  0x037c       ChapterLanguage                  no
+  0x037e       ChapterCountry                   no
+  0x0444       SegmentFamily?                   no
+  0x0461       DateTimeOriginal                 no
+  0x047a       TagLanguage                      no
+  0x0484       TagDefault                       no
+  0x0485       TagBinary                        no
+  0x0487       TagString                        no
+  0x0489       Duration                         no
+  0x050d       ChapterProcessPrivate?           no
+  0x0598       ChapterFlagEnabled?              no
+  0x05a3       TagName                          no
   0x05b9       EditionEntry                     Matroska
-  0x05bc       EditionUID?                      N
-  0x05bd       EditionFlagHidden?               N
-  0x05db       EditionFlagDefault?              N
-  0x05dd       EditionFlagOrdered?              N
-  0x065c       AttachedFileData                 N
-  0x0660       AttachedFileMIMEType             N
-  0x066e       AttachedFileName                 N
-  0x0675       AttachedFileReferral?            N
-  0x067e       AttachedFileDescription          N
-  0x06ae       AttachedFileUID                  N
-  0x07e1       ContentEncryptionAlgorithm       N
-  0x07e2       ContentEncryptionKeyID?          N
-  0x07e3       ContentSignature?                N
-  0x07e4       ContentSignatureKeyID?           N
-  0x07e5       ContentSignatureAlgorithm        N
-  0x07e6       ContentSignatureHashAlgorithm    N
-  0x0d80       MuxingApp                        N
+  0x05bc       EditionUID?                      no
+  0x05bd       EditionFlagHidden?               no
+  0x05db       EditionFlagDefault?              no
+  0x05dd       EditionFlagOrdered?              no
+  0x065c       AttachedFileData                 no
+  0x0660       AttachedFileMIMEType             no
+  0x066e       AttachedFileName                 no
+  0x0675       AttachedFileReferral?            no
+  0x067e       AttachedFileDescription          no
+  0x06ae       AttachedFileUID                  no
+  0x07e1       ContentEncryptionAlgorithm       no
+  0x07e2       ContentEncryptionKeyID?          no
+  0x07e3       ContentSignature?                no
+  0x07e4       ContentSignatureKeyID?           no
+  0x07e5       ContentSignatureAlgorithm        no
+  0x07e6       ContentSignatureHashAlgorithm    no
+  0x0d80       MuxingApp                        no
   0x0dbb       Seek                             Matroska
-  0x1031       ContentEncodingOrder?            N
-  0x1032       ContentEncodingScope?            N
-  0x1033       ContentEncodingType              N
+  0x1031       ContentEncodingOrder?            no
+  0x1032       ContentEncodingScope?            no
+  0x1033       ContentEncodingType              no
   0x1034       ContentCompression               Matroska
   0x1035       ContentEncryption                Matroska
-  0x135f       CueRefNumber?                    N
-  0x136e       TrackName                        N
-  0x1378       CueBlockNumber?                  N
-  0x137f       TrackOffset?                     N
-  0x13ab       SeekID?                          N
-  0x13ac       SeekPosition?                    N
-  0x13b8       Stereo3DMode                     N
-  0x14aa       CropBottom                       N
-  0x14b0       DisplayWidth                     N
-  0x14b2       DisplayUnit                      N
-  0x14b3       AspectRatioType                  N
-  0x14ba       DisplayHeight                    N
-  0x14bb       CropTop                          N
-  0x14cc       CropLeft                         N
-  0x14dd       CropRight                        N
-  0x15aa       TrackForced                      N
-  0x15ee       MaxBlockAdditionID?              N
-  0x1741       WritingApp                       N
+  0x135f       CueRefNumber?                    no
+  0x136e       TrackName                        no
+  0x1378       CueBlockNumber?                  no
+  0x137f       TrackOffset?                     no
+  0x13ab       SeekID?                          no
+  0x13ac       SeekPosition?                    no
+  0x13b8       Stereo3DMode                     no
+  0x14aa       CropBottom                       no
+  0x14b0       DisplayWidth                     no
+  0x14b2       DisplayUnit                      no
+  0x14b3       AspectRatioType                  no
+  0x14ba       DisplayHeight                    no
+  0x14bb       CropTop                          no
+  0x14cc       CropLeft                         no
+  0x14dd       CropRight                        no
+  0x15aa       TrackForced                      no
+  0x15ee       MaxBlockAdditionID?              no
+  0x1741       WritingApp                       no
   0x1854       SilentTracks                     Matroska
-  0x18d7       SilentTrackNumber                N
+  0x18d7       SilentTrackNumber                no
   0x21a7       AttachedFile                     Matroska
   0x2240       ContentEncoding                  Matroska
-  0x2264       AudioBitsPerSample               N
-  0x23a2       CodecPrivate?                    N
+  0x2264       AudioBitsPerSample               no
+  0x23a2       CodecPrivate?                    no
   0x23c0       Targets                          Matroska
-  0x23c3       ChapterPhysicalEquivalent        N
-  0x23c4       TagChapterUID?                   N
-  0x23c5       TagTrackUID?                     N
-  0x23c6       TagAttachmentUID?                N
-  0x23c9       TagEditionUID?                   N
-  0x23ca       TargetType                       N
-  0x2532       SignedElement?                   N
+  0x23c3       ChapterPhysicalEquivalent        no
+  0x23c4       TagChapterUID?                   no
+  0x23c5       TagTrackUID?                     no
+  0x23c6       TagAttachmentUID?                no
+  0x23c9       TagEditionUID?                   no
+  0x23ca       TargetType                       no
+  0x2532       SignedElement?                   no
   0x2624       TrackTranslate                   Matroska
-  0x26a5       TrackTranslateTrackID?           N
-  0x26bf       TrackTranslateCodec              N
-  0x26fc       TrackTranslateEditionUID?        N
+  0x26a5       TrackTranslateTrackID?           no
+  0x26bf       TrackTranslateCodec              no
+  0x26fc       TrackTranslateEditionUID?        no
   0x27c8       SimpleTag                        Matroska
-  0x28ca       TargetTypeValue                  N
+  0x28ca       TargetTypeValue                  no
   0x2911       ChapterProcessCommand            Matroska
-  0x2922       ChapterProcessTime?              N
+  0x2922       ChapterProcessTime?              no
   0x2924       ChapterTranslate                 Matroska
-  0x2933       ChapterProcessData?              N
+  0x2933       ChapterProcessData?              no
   0x2944       ChapterProcess                   Matroska
-  0x2955       ChapterProcessCodecID?           N
-  0x29a5       ChapterTranslateID?              N
-  0x29bf       ChapterTranslateCodec            N
-  0x29fc       ChapterTranslateEditionUID?      N
+  0x2955       ChapterProcessCodecID?           no
+  0x29a5       ChapterTranslateID?              no
+  0x29bf       ChapterTranslateCodec            no
+  0x29fc       ChapterTranslateEditionUID?      no
   0x2d80       ContentEncodings                 Matroska
-  0x2de7       MinCache?                        N
-  0x2df8       MaxCache?                        N
-  0x2e67       ChapterSegmentUID?               N
-  0x2ebc       ChapterSegmentEditionUID?        N
-  0x2fab       TrackOverlay?                    N
+  0x2de7       MinCache?                        no
+  0x2df8       MaxCache?                        no
+  0x2e67       ChapterSegmentUID?               no
+  0x2ebc       ChapterSegmentEditionUID?        no
+  0x2fab       TrackOverlay?                    no
   0x3373       Tag                              Matroska
-  0x3384       SegmentFileName                  N
-  0x33a4       SegmentUID?                      N
-  0x33c4       ChapterUID?                      N
-  0x33c5       TrackUID?                        N
-  0x3446       TrackAttachmentUID               N
+  0x3384       SegmentFileName                  no
+  0x33a4       SegmentUID?                      no
+  0x33c4       ChapterUID?                      no
+  0x33c5       TrackUID?                        no
+  0x3446       TrackAttachmentUID               no
   0x35a1       BlockAdditions                   Matroska
-  0x38b5       OutputAudioSampleRate            N
-  0x3ba9       Title                            N
-  0x3d7b       ChannelPositions?                N
+  0x38b5       OutputAudioSampleRate            no
+  0x3ba9       Title                            no
+  0x3d7b       ChannelPositions?                no
   0x3e5b       SignatureElements                Matroska
   0x3e7b       SignatureElementList             Matroska
-  0x3e8a       SignatureAlgo                    N
-  0x3e9a       SignatureHash                    N
-  0x3ea5       SignaturePublicKey?              N
-  0x3eb5       Signature?                       N
-  0x2b59c      TrackLanguage                    N
-  0x3314f      TrackTimecodeScale               N
-  0x383e3      FrameRate                        N
-  0x3e383      VideoFrameRate                   N
-               DefaultDuration                  N
-  0x58688      VideoCodecName                   N
-               AudioCodecName                   N
-               CodecName                        N
-  0x6b240      CodecDownloadURL                 N
-  0xad7b1      TimecodeScale                    N
-  0xeb524      ColorSpace?                      N
-  0xfb523      Gamma                            N
-  0x1a9697     CodecSettings                    N
-  0x1b4040     CodecInfoURL                     N
-  0x1c83ab     PrevFileName                     N
-  0x1cb923     PrevUID?                         N
-  0x1e83bb     NextFileName                     N
-  0x1eb923     NextUID?                         N
+  0x3e8a       SignatureAlgo                    no
+  0x3e9a       SignatureHash                    no
+  0x3ea5       SignaturePublicKey?              no
+  0x3eb5       Signature?                       no
+  0x7670       Projection                       Matroska Projection
+  0x2b59c      TrackLanguage                    no
+  0x3314f      TrackTimecodeScale               no
+  0x383e3      FrameRate                        no
+  0x3e383      VideoFrameRate                   no
+               DefaultDuration                  no
+  0x58688      VideoCodecName                   no
+               AudioCodecName                   no
+               CodecName                        no
+  0x6b240      CodecDownloadURL                 no
+  0xad7b1      TimecodeScale                    no
+  0xeb524      ColorSpace?                      no
+  0xfb523      Gamma                            no
+  0x1a9697     CodecSettings                    no
+  0x1b4040     CodecInfoURL                     no
+  0x1c83ab     PrevFileName                     no
+  0x1cb923     PrevUID?                         no
+  0x1e83bb     NextFileName                     no
+  0x1eb923     NextUID?                         no
   0x43a770     Chapters                         Matroska
   0x14d9b74    SeekHead                         Matroska
@@ -14180,4 +27662,34 @@
   0xf43b675    Cluster                          Matroska
 
+=head3 Matroska Projection Tags
+
+Projection tags defined by the Spherical Video V2 specification.  See
+L<https://github.com/google/spatial-media/blob/master/docs/spherical-video-v2-rfc.md>
+for the specification.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x7671   ProjectionType                       no
+  0x7672   EquirectangularProj                  QuickTime equi
+           CubemapProj                          QuickTime cbmp
+  0x7673   ProjectionPosYaw                     no
+  0x7674   ProjectionPosPitch                   no
+  0x7675   ProjectionPosRoll                    no
+
+=head2 MOI Tags
+
+MOI files store information about associated MOD or TOD files, and are
+written by some JVC, Canon and Panasonic camcorders.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    MOIVersion                           no
+      6    DateTimeOriginal                     no
+     14    Duration                             no
+    128    AspectRatio                          no
+    132    AudioCodec                           no
+    134    AudioBitrate                         no
+    218    VideoBitrate                         no
+
 =head2 MXF Tags
 
@@ -14187,1664 +27699,1664 @@
   Tag Name                                      Writable
   --------                                      --------
-  OrganizationID                                N
-  UPID?                                         N
-  UPN?                                          N
-  IBTN?                                         N
-  ISAN?                                         N
-  ISBN?                                         N
-  ISSN?                                         N
-  ISWC?                                         N
-  ISMN?                                         N
-  ISCI?                                         N
-  ISRC?                                         N
-  ISRN?                                         N
-  ISBD?                                         N
-  ISTC?                                         N
-  SICI?                                         N
-  BICI?                                         N
-  AICI?                                         N
-  PII?                                          N
-  DOI?                                          N
-  InstanceUID?                                  N
-  PackageID?                                    N
-  DeviceDesignation                             N
-  DeviceModel                                   N
-  DeviceSerialNumber                            N
-  URL                                           N
-  URL                                           N
-  PURL                                          N
-  URN                                           N
-  TransmissionID                                N
-  ArchiveID                                     N
-  ItemID                                        N
-  AccountingReferenceNumber                     N
-  TrafficID                                     N
-  ReelOrRollNumber                              N
-  LocalTapeNumber                               N
-  LUID                                          N
-  PackageName                                   N
-  LocalFilePath                                 N
-  EdgeCode                                      N
-  FrameCode                                     N
-  KeyCode?                                      N
-  InkNumber                                     N
-  KeyText                                       N
-  KeyFrame                                      N
-  KeySound                                      N
-  KeyDataOrProgram                              N
-  TitleKind                                     N
-  MainTitle                                     N
-  SecondaryTitle                                N
-  SeriesNumber                                  N
-  EpisodeNumber                                 N
-  SceneNumber                                   N
-  TakeNumber                                    N
-  CISACLegalEntityID?                           N
-  AGICOAID?                                     N
-  SourceOrganization                            N
-  SupplyContractNumber                          N
-  OriginalProducerName                          N
-  TotalEpisodeCount                             N
-  CopyrightStatus                               N
-  CopyrightOwnerName                            N
-  IntellectualPropertyDescription               N
-  IntellectualPropertyRights                    N
-  Rightsholder                                  N
-  RightsManagementAuthority                     N
-  InterestedPartyName                           N
-  MaximumUseCount                               N
-  LicenseOptionsDescription                     N
-  CurrencyCode                                  N
-  RoyaltyPaymentInformation                     N
-  RoyaltyIncomeInformation                      N
-  RestrictionsonUse                             N
-  ExCCIData?                                    N
-  Username                                      N
-  Username                                      N
-  Password                                      N
-  Password                                      N
-  ScramblingKeyKind                             N
-  ScramblingKeyValue                            N
-  BroadcastOrganizationName                     N
-  BroadcastChannel                              N
-  BroadcastMediumKind                           N
-  BroadcastRegion                               N
-  FirstBroadcastFlag                            N
-  CurrentRepeatNumber                           N
-  PreviousRepeatNumber                          N
-  AudienceRating                                N
-  AudienceReach                                 N
-  NatureOfPersonality                           N
-  ContributionStatus                            N
-  SupportOrAdministrationStatus                 N
-  OrganizationKind                              N
-  ProductionOrganizationRole                    N
-  SupportOrganizationRole                       N
-  JobFunctionName                               N
-  RoleName                                      N
-  ContactKind                                   N
-  ContactDepartmentName                         N
-  FamilyName                                    N
-  FirstGivenName                                N
-  SecondGivenName                               N
-  ThirdGivenName                                N
-  MainName                                      N
-  SupplementaryName                             N
-  OrganizationMainName                          N
-  SupplementaryOrganizationName                 N
-  ISO3166CountryCode                            N
-  ISO639-1LanguageCode                          N
-  OperatingSystemInterpretations                N
-  ByteOrder                                     N
-  EssenceIsIdentified                           N
-  LengthSystemName                              N
-  LengthUnitKind                                N
-  AngularUnitKind                               N
-  TimeSystemOffset                              N
-  TimeUnitKind                                  N
-  ContentCodingSystem                           N
-  ProgramKind                                   N
-  Genre                                         N
-  TargetAudience                                N
-  CatalogDataStatus                             N
-  ThesaurusName                                 N
-  Theme                                         N
-  ContentClassification                         N
-  Keywords                                      N
-  KeyFrames                                     N
-  KeySounds                                     N
-  KeyData                                       N
-  Abstract                                      N
-  Purpose                                       N
-  Description                                   N
-  ColorDescriptor                               N
-  FormatDescriptor                              N
-  StratumKind                                   N
-  IndividualAwardName                           N
-  ProgramAwardName                              N
-  AssetValue                                    N
-  ContentValue                                  N
-  CulturalValue                                 N
-  AestheticValue                                N
-  HistoricalValue                               N
-  TechnicalValue                                N
-  OtherValues                                   N
-  CatalogDataStatus                             N
-  CatalogingSystemName                          N
-  ComputedKeywords                              N
-  ComputedKeyFrames                             N
-  ComputedKeySounds                             N
-  ComputedKeyData                               N
-  ComputedStratumKind                           N
-  PresentationAspectRatio                       N
-  CaptureAspectRatio                            N
-  CaptureGammaEquation                          N
-  CaptureGammaEquation                          N
-  LumaEquation                                  N
-  ColorimetryCode                               N
-  SignalFormCode                                N
-  ColorFieldCode                                N
-  FieldRate                                     N
-  FrameRate                                     N
-  FrameLayout                                   N
-  SamplingStructureCode                         N
-  TotalLinesperFrame                            N
-  ActiveLinesperFrame                           N
-  LeadingLines                                  N
-  TrailingLines                                 N
-  AnalogVideoSystemName                         N
-  LuminanceSampleRate                           N
-  ActiveSamplesperLine                          N
-  TotalSamplesperLine                           N
-  SamplingHierarchyCode                         N
-  HorizontalSubsampling                         N
-  ColorSiting                                   N
-  SampledHeight                                 N
-  SampledWidth                                  N
-  SampledXOffset                                N
-  SampledYOffset                                N
-  DisplayHeight                                 N
-  DisplayWidth                                  N
-  DisplayXOffset                                N
-  DisplayYOffset                                N
-  FilteringCode                                 N
-  ImageHeight                                   N
-  ImageWidth                                    N
-  BitsperPixel                                  N
-  RoundingMethodCode                            N
-  BlackReferenceLevel                           N
-  WhiteReferenceLevel                           N
-  FieldFrameTypeCode                            N
-  PulldownSequence?                             N
-  PulldownFieldDominance                        N
-  VideoAndFilmFrameRelationship                 N
-  CaptureFilmFrameRate                          N
-  TransferFilmFrameRate                         N
-  VideoTestParameter                            N
-  VideoTestResult                               N
-  VideoTestResult                               N
-  FilmTestParameter                             N
-  FilmTestResult                                N
-  FilmTestResult?                               N
-  ElectrospatialFormulation                     N
-  FilteringApplied                              N
-  AudioReferenceLevel                           N
-  AudioMonoChannelCount                         N
-  AudioStereoChannelCount                       N
-  AnalogSystem                                  N
-  AudioSampleRate                               N
-  BitsPerSample                                 N
-  RoundingLaw                                   N
-  Dither                                        N
-  OpticalTrack                                  N
-  MagneticTrack                                 N
-  Signal-to-NoiseRatio                          N
-  Weighting                                     N
-  AnalogDataCodingKind                          N
-  TimecodeKind                                  N
-  TimecodeTimebase                              N
-  TimecodeUserBitsFlag                          N
-  IncludeSync                                   N
-  DropFrame                                     N
-  TimecodeSourceKind                            N
-  AnalogMetadataCarrier                         N
-  DigitalMetadataCarrier                        N
-  AnalogMonitoringAndControlCodingKind          N
-  SampleRate                                    N
-  EssenceLength                                 N
-  FilmColorProcess                              N
-  EdgeCodeFormat?                               N
-  FilmFormatName                                N
-  FilmStockKind                                 N
-  FilmStockManufacturerName                     N
-  PhysicalMediaLength?                          N
-  FilmCaptureAperture                           N
-  ImageCategory                                 N
-  ImageSourceDeviceKind                         N
-  OpticalTestParameterName                      N
-  OpticalTestResult                             N
-  OpticalTestResult                             N
-  SensorType                                    N
-  PolarCharacteristic                           N
-  IntegrationIndication                         N
-  EventIndication                               N
-  QualityFlag                                   N
-  PhysicalInstanceKind                          N
-  DigitalOrAnalogOrigination                    N
-  MicrophonePlacementTechniques                 N
-  SimpleFlaggingCount                           N
-  CopyCount                                     N
-  CloneCount                                    N
-  Work-in-ProgressFlag                          N
-  VideoOrImageCompressionAlgorithm              N
-  SplicingMetadata?                             N
-  AudioCompressionAlgorithm                     N
-  VideoNoiseReductionAlgorithm                  N
-  AudioNoiseReductionAlgorithm                  N
-  EnhancementOrModificationDescription          N
-  VideoDeviceKind                               N
-  VideoDeviceParameterName                      N
-  VideoDeviceParameterSetting                   N
-  AudioEnhancementOrModificationDescription     N
-  AudioFirstMix-DownProcess                     N
-  AudioDeviceKind                               N
-  AudioDeviceParameter                          N
-  AudioDeviceParameterSetting                   N
-  DataEnhancementOrModificationDescription      N
-  DataDeviceKind                                N
-  DataDeviceParameterName                       N
-  DataDeviceParameterSetting                    N
-  DefaultFadeType?                              N
-  ActiveState                                   N
-  Fade-InType?                                  N
-  Fade-OutType?                                 N
-  SpeedChangeEffectFlag                         N
-  InputSegmentCount                             N
-  Bypass                                        N
-  VideoCompressionAlgorithm                     N
-  MPEGVideoRecodingDataset?                     N
-  UpstreamAudioCompressionAlgorithm             N
-  MPEGAudioRecodingDataset?                     N
-  ProgramSupportMaterialReference               N
-  AdvertisingMaterialReference                  N
-  ProgramCommercialMaterialReference            N
-  ContiguousDataFlag                            N
-  PositionInSequence                            N
-  RelativePositionInSequenceOffset              N
-  RelativePositionInSequenceName                N
-  ImageCoordinateSystem                         N
-  MapDatumUsed                                  N
-  LocalDatumAbsolutePositionAccuracy            N
-  DeviceAbsolutePositionalAccuracy              N
-  DeviceAltitude                                N
-  DeviceAltitude                                N
-  DeviceLatitude                                N
-  DeviceLatitude                                N
-  DeviceLongitude                               N
-  DeviceLongitude                               N
-  DeviceXDimension                              N
-  DeviceYDimension                              N
-  FramePositionalAccuracy                       N
-  FrameCenterLatitude                           N
-  FrameCenterLatitude                           N
-  FrameCenterLongitude                          N
-  FrameCenterLongitude                          N
-  FrameCenterLatitudeLongitude                  N
-  LocalDatumRelativePositionAccuracy            N
-  DeviceRelativePositionalAccuracy              N
-  DeviceRelativePositionX                       N
-  DeviceRelativePositionY                       N
-  DeviceRelativePositionZ                       N
-  SubjectRelativePositionalAccuracy             N
-  PositionWithinViewportImageXCoordinate        N
-  PositionWithinViewportImageYCoordinate        N
-  SourceImageCenterXCoordinate                  N
-  SourceImageCenterYCoordinate                  N
-  ViewportImageCenterCCoordinate                N
-  ViewportImageCenterYCoordinate                N
-  DeviceAbsoluteSpeed                           N
-  DeviceAbsoluteHeading                         N
-  SubjectAbsoluteSpeed                          N
-  SubjectAbsoluteHeading                        N
-  DeviceRelativeSpeed                           N
-  DeviceRelativeHeading                         N
-  SubjectRelativeSpeed                          N
-  SubjectRelativeHeading                        N
-  SlantRange                                    N
-  TargetWidth                                   N
-  ViewportHeight                                N
-  ViewportWidth                                 N
-  SensorRollAngle                               N
-  AngleToNorth                                  N
-  ObliquityAngle                                N
-  PlaceKeyword                                  N
-  ObjectCountryCode                             N
-  ShootingCountryCode                           N
-  SettingCountryCode                            N
-  CopyrightLicenseCountryCode                   N
-  IntellectualPropertyLicenseCountryCode        N
-  ObjectRegionCode                              N
-  ShootingRegionCode                            N
-  SettingRegionCode                             N
-  CopyrightLicenseRegionCode                    N
-  IntellectualPropertyLicenseRegionCode         N
-  RoomNumber                                    N
-  StreetNumber                                  N
-  StreetName                                    N
-  PostalTown                                    N
-  CityName                                      N
-  StateOrProvinceOrCountyName                   N
-  PostalCode                                    N
-  CountryName                                   N
-  SettingRoomNumber                             N
-  SettingStreetNumberOrBuildingName             N
-  SettingStreetName                             N
-  SettingTownName                               N
-  SettingCityName                               N
-  SettingStateOrProvinceOrCountyName            N
-  SettingPostalCode                             N
-  SettingCountryName                            N
-  TelephoneNumber                               N
-  FaxNumber                                     N
-  E-MailAddress                                 N
-  SettingDescription                            N
-  UTCUserDateTime                               N
-  LocalUserDateTime                             N
-  SMPTE309MUserDateTime?                        N
-  SMPTE12MUserDateTime?                         N
-  UTCStartDateTime                              N
-  LocalStartDateTime                            N
-  TimecodeStartDateTime?                        N
-  UTCEndDateTime                                N
-  LocalEndDateTime                              N
-  TimecodeEndDateTime?                          N
-  UTCLastModifyDate                             N
-  LocalLastModifyDate                           N
-  TimecodeLastModifyDate?                       N
-  UTCEventStartDateTime                         N
-  LocalEventStartDateTime                       N
-  TimecodeEventStartDateTime?                   N
-  UTCEventEndDateTime                           N
-  LocalEventEndDateTime                         N
-  TimecodeEventEndDateTime?                     N
-  StartTimeRelativeToReference                  N
-  StartTimecodeRelativeToReference?             N
-  MaterialEndTimeOffset                         N
-  MaterialEndTimecodeOffset?                    N
-  EventStartTimeOffset                          N
-  EventStartTimecodeOffset?                     N
-  EventEndTimeOffset                            N
-  EventEndTimecodeOffset?                       N
-  FrameCountOffset                              N
-  TimePeriodName                                N
-  LocalCreationDateTime                         N
-  TimecodeCreationDateTime?                     N
-  LocalModifyDate                               N
-  TimecodeModifyDate?                           N
-  FrameCount                                    N
-  MaterialAbsoluteDuration                      N
-  MaterialAbsoluteDuration?                     N
-  TextlessBlackDuration                         N
-  EventAbsoluteDurationFrameCount               N
-  EventAbsoluteDuration                         N
-  EventAbsoluteDuration?                        N
-  BufferDelay?                                  N
-  ProgramIdentifier                             N
-  ProgramIdentifierString                       N
-  ShimName                                      N
-  SignalStandard                                N
-  IntendedAFD                                   N
-  SlateTitle                                    N
-  NOLACode                                      N
-  Rating                                        N
-  NielsenStreamIdentifier                       N
-  IsRecording                                   N
-  IsLiveProduction                              N
-  IsLiveTransmission                            N
-  IsDubbed                                      N
-  IsVoiceover                                   N
-  HasAudioWatermark                             N
-  AudioWatermarkKind                            N
-  HasVideoWatermark                             N
-  VideoWatermarkKind                            N
-  SubtitlesPresent                              N
-  CaptionTitles                                 N
-  CaptionsViaTeletext                           N
-  TextlessMaterial                              N
-  AudioReferenceLevel                           N
-  StorageDeviceKind                             N
-  StorageMediaKind                              N
-  StorageMediaID                                N
-  BroadcastDate                                 N
-  BroadcastTime                                 N
-  IsRepeat                                      N
-  FirstTransmissionInfo                         N
-  TeletextSubtitlesAvailable                    N
-  SeasonEpisodeNumber                           N
-  SeasonEpisodeTitle                            N
-  EPGProgramSynopsis                            N
-  ContentClassification                         N
-  DVBParentalRating                             N
-  ContentMaturityRating                         N
-  ContentMaturityDescription                    N
-  ContentMaturityGraphic                        N
-  ContractEntity                                N
-  ContractTypeLink                              N
-  ConsumerRightsToCopy                          N
-  BroadcasterRightsToCopy                       N
-  DirectorName                                  N
-  ProducerName                                  N
-  FemaleLeadActressName                         N
-  MaleLeadActorName                             N
-  PresenterName                                 N
-  MainSponsorName                               N
-  VoiceTalentName                               N
-  PostboxNumber                                 N
-  PostCodeForPostbox                            N
-  ProgramNumber                                 N
-  DefinitionObjectID?                           N
-  IEEEDeviceID                                  N
-  ProjectNumber                                 N
-  EdgeCodeHeader?                               N
-  ChannelHandle                                 N
-  PhysicalMediaLocation                         N
-  MediaLocation                                 N
-  TrackNumber                                   N
-  EdgeCodeStart                                 N
-  VersionTitle                                  N
-  TrackID                                       N
-  TrackName                                     N
-  TrackName                                     N
-  DefinitionObjectName                          N
-  DefinitionObjectName                          N
-  ContentPackageMetadataLink                    N
-  DefinedName                                   N
-  DefinedName                                   N
-  DeviceManufacturerName                        N
-  DeviceManufacturerName                        N
-  ManufacturerID?                               N
-  IEEEManufacturerID                            N
-  AAFManufacturerID?                            N
-  SupplyingDepartmentName                       N
-  AudienceShare                                 N
-  AudienceAppreciation                          N
-  Salutation                                    N
-  HonorsAndQualifications                       N
-  ObjectModelVersion                            N
-  SDKVersion                                    N
-  IsOptional                                    N
-  IsSearchable                                  N
-  UseDefaultValue                               N
-  DefaultDataValue?                             N
-  Size                                          N
-  IsSigned                                      N
-  ElementCount                                  N
-  ElementNameList                               N
-  TypeDefinitionElementValueList                N
-  MemberNameList                                N
-  ExtendibleElementNameList                     N
-  TypeDefinitionExtendibleElementValues?        N
-  TargetSet?                                    N
-  FillerData?                                   N
-  KLVDataValue?                                 N
-  PackageKLVData?                               N
-  ComponentKLVData?                             N
-  AssignedCategoryName                          N
-  AssignedCategoryName                          N
-  AssignedCategoryValue                         N
-  AssignedCategoryValue                         N
-  ShotList                                      N
-  PackageUserComments?                          N
-  Cue-InWords                                   N
-  Cue-OutWords                                  N
-  ObjectKind                                    N
-  ObjectKind                                    N
-  ObjectDescription                             N
-  ObjectDescription                             N
-  ObjectName                                    N
-  MetadataItemName                              N
-  ShotCommentKind                               N
-  ShotComment                                   N
-  ComputedObjectKind                            N
-  ComputedObjectKind                            N
-  VersionNumberString                           N
-  VersionNumberString                           N
-  VersionNumber                                 N
-  WAVESummary?                                  N
-  AIFCSummary?                                  N
-  TIFFSummary?                                  N
-  ViewportAspectRatio                           N
-  CaptureGammaEquation?                         N
-  ColorimetryCode?                              N
-  PresentationGammaEquation                     N
-  PresentationGammaEquation?                    N
-  FieldDominance                                N
-  VideoLineMap                                  N
-  AnalogVideoSystemName?                        N
-  VerticalSub-sampling                          N
-  BitsperPixel                                  N
-  ColorRangeLevels                              N
-  PixelLayout?                                  N
-  AlphaSampleDepth                              N
-  Palette?                                      N
-  PaletteLayout?                                N
-  ComponentDepth                                N
-  VideoCodingSchemeID?                          N
-  RoundedCaptureFilmFrameRate                   N
-  AudioAverageBitrate                           N
-  AudioFixedBitrateFlag                         N
-  CodingLawKind                                 N
-  AudioCodingSchemeID?                          N
-  LayerNumber                                   N
-  TimecodeTimebase                              N
-  RoundedTimecodeTimebase                       N
-  ComponentDataDefinition                       N
-  StreamData?                                   N
-  TimecodeStreamData?                           N
-  RecordedFormat                                N
-  TapeShellKind                                 N
-  TapeShellKind                                 N
-  TapeFormulation                               N
-  TapeFormulation                               N
-  TapeCapacity                                  N
-  TapeManufacturer                              N
-  TapeManufacturer                              N
-  TapeStock                                     N
-  TapeStock                                     N
-  TapeBatchNumber                               N
-  TapeBatchNumber                               N
-  PerforationsPerFrame                          N
-  PerforationsPerFrame                          N
-  FilmFormatName                                N
-  FilmFormatName?                               N
-  FilmStockKind                                 N
-  FilmStockManufacturerName                     N
-  FilmBatchNumber                               N
-  FilmBatchNumber                               N
-  FilmGauge?                                    N
-  EdgeCodeFilmGauge?                            N
-  ExposedAspectRatio                            N
-  ImageAlignmentOffset                          N
-  ImageStartOffset                              N
-  ImageEndOffset                                N
-  PaddingBits                                   N
-  FocalLength                                   N
-  SensorSize                                    N
-  FNumber                                       N
-  SensorTypeCode                                N
-  FieldOfViewHorizontal                         N
-  AnamorphicLensCharacteristic                  N
-  UniformDataFlag                               N
-  JPEGTableID?                                  N
-  AlphaTransparency                             N
-  GenerationID?                                 N
-  ApplicationSupplierName                       N
-  ApplicationSupplierName                       N
-  ApplicationName                               N
-  ApplicationName                               N
-  ApplicationVersionNumber                      N
-  ApplicationVersionString                      N
-  ApplicationVersionString                      N
-  ApplicationPlatform                           N
-  ApplicationPlatform                           N
-  ApplicationProductID?                         N
-  LinkedGenerationID?                           N
-  ContainerVersion                              N
-  ToolkitVersion                                N
-  Plug-InCategoryID?                            N
-  Plug-InPlatformID?                            N
-  MinimumSupportedPlatformVersion               N
-  MaximumSupportedPlatformVersion               N
-  Plug-InEngineID?                              N
-  MinimumSupportedEngineVersion                 N
-  MaximumSupportedEngineVersion                 N
-  Plug-InAPIID?                                 N
-  MinimumAPIVersion                             N
-  MaximumAPIVersion                             N
-  Software-OnlySupportFlag                      N
-  HardwareAcceleratorFlag                       N
-  Plug-InLocatorSet?                            N
-  AuthenticationFlag                            N
-  AssociatedMetadataDefinition?                 N
-  EventTrackEditRate                            N
-  DefaultFadeEditRate                           N
-  EditingEventComment                           N
-  EditingEventComment                           N
-  EditRate                                      N
-  OperationDefinitionID?                        N
-  Value?                                        N
-  EditHint?                                     N
-  OperationDataDefinition?                      N
-  OperationCategory?                            N
-  DisplayUnits                                  N
-  DisplayUnits                                  N
-  BypassOverride                                N
-  TimepointValue?                               N
-  BeginAnchor                                   N
-  BeginAnchor                                   N
-  EndAnchor                                     N
-  EndAnchor                                     N
-  FilmToVideoTransferDirection?                 N
-  FilmToVideoTransferKind?                      N
-  FilmToVideoTransferPhase?                     N
-  TeletextSubtitlesFlag                         N
-  SubtitleDatafileFlag                          N
-  ClosedCaptionSubtitlesFlag                    N
-  SampleIndex?                                  N
-  SourcePackageID?                              N
-  SourceTrackID                                 N
-  RelativeScope                                 N
-  RelativeTrack                                 N
-  ObjectClass?                                  N
-  EssenceContainerFormat?                       N
-  CodecDefinition?                              N
-  ParameterDefinition?                          N
-  Interpolation?                                N
-  ParameterDataType?                            N
-  CodecEssenceDescriptor?                       N
-  ContentStorage?                               N
-  Dictionary?                                   N
-  EssenceDescription?                           N
-  Sequence?                                     N
-  TransitionEffect?                             N
-  EffectRendering?                              N
-  InputSegment?                                 N
-  StillFrame?                                   N
-  Selected?                                     N
-  Annotation?                                   N
-  ManufacturerInformationObject?                N
-  CodecEssenceKinds?                            N
-  OperationParameters?                          N
-  DegradedEffects?                              N
-  Packages?                                     N
-  EssenceData?                                  N
-  OperationDefinitions?                         N
-  ParameterDefinitions?                         N
-  DataDefinitions?                              N
-  Plug-InDefinitions?                           N
-  CodecDefinitions?                             N
-  ContainerDefinitions?                         N
-  InterpolationDefinitions?                     N
-  AvailableRepresentations?                     N
-  InputSegments?                                N
-  EssenceLocators?                              N
-  IdentificationList?                           N
-  Tracks?                                       N
-  ControlPointList?                             N
-  PackageTracks?                                N
-  Alternates?                                   N
-  ComponentsInSequence?                         N
-  Parameters?                                   N
-  LinkedPackageID?                              N
-  ParentClass?                                  N
-  Properties?                                   N
-  IsConcrete                                    N
-  PropertyType?                                 N
-  LocalID                                       N
-  IsUniqueIdentifier                            N
-  ClassDefinitions?                             N
-  TypeDefinitions?                              N
-  TargetClassOfStrongReference?                 N
-  TargetClassOfWeakReference?                   N
-  EnumerationUnderlyingIntegerType?             N
-  FixedArrayElementType?                        N
-  VariableArrayElementType?                     N
-  SetElementType?                               N
-  StringElementType?                            N
-  StreamElementType?                            N
-  MemberTypes?                                  N
-  RenamedType?                                  N
-  DictionaryIdentifier?                         N
-  DictionaryDescription                         N
-  DictionaryDescription                         N
-  BlockContinuityCount                          N
-  StreamPositionIndicator                       N
-  Origin                                        N
-  StartTimeRelativeToReference                  N
-  StartTimecode                                 N
-  CutPoint                                      N
-  EventStart                                    N
-  ControlPointTime                              N
-  CreateDate                                    N
-  ModifyDate                                    N
-  ContainerLastModifyDate                       N
-  PackageLastModifyDate                         N
-  Duration                                      N
-  DefaultFadeDuration                           N
-  Fade-InDuration                               N
-  Fade-OutDuration                              N
-  TapeFormat?                                   N
-  OrganizationID                                N
-  GlobalNumber                                  N
-  DeviceIDKind                                  N
-  DeviceKind                                    N
-  DeviceKindCode                                N
-  PlatformDesignation                           N
-  PlatformModel                                 N
-  PlatformSerialNumber                          N
-  LocalTargetID                                 N
-  MagneticDiskNumber                            N
-  OpticalDiscNumber                             N
-  StreamID                                      N
-  TransportStreamID                             N
-  OrganizationalProgramNumber                   N
-  OrganizationalProgramNumber                   N
-  ItemDesignatorID?                             N
-  LocalFilePath                                 N
-  TitleKind                                     N
-  MainTitle                                     N
-  SecondaryTitle                                N
-  SeriesNumber                                  N
-  EpisodeNumber                                 N
-  SceneNumber                                   N
-  VersionTitle                                  N
-  MissionID                                     N
-  MissionID                                     N
-  RecordingLabelName                            N
-  RecordingLabelName                            N
-  CollectionName                                N
-  CollectionName                                N
-  OriginCode                                    N
-  MainCatalogNumber                             N
-  CatalogPrefixNumber                           N
-  SideNumber                                    N
-  RecordedTrackNumber                           N
-  SeriesinaSeriesGroupCount                     N
-  ProgrammingGroupKind                          N
-  PurchasingOrganizationName                    N
-  SalesContractNumber                           N
-  PurchasingDepartment                          N
-  ContractType                                  N
-  ContractTypeCode                              N
-  ContractClauseDescription                     N
-  ContractLineCode                              N
-  ContractLineName                              N
-  ContractTermsOfBusiness                       N
-  ContractInstallmentPercentage                 N
-  Jurisdiction                                  N
-  CopyrightStatus                               N
-  CopyrightOwnerName                            N
-  IntellectualPropertyDescription               N
-  IntellectualPropertyRights                    N
-  Rightsholder                                  N
-  RightsManagementAuthority                     N
-  RightsConditionDescription                    N
-  RightsConditionDescription                    N
-  CurrencyName                                  N
-  TotalPayment                                  N
-  PayeeAccountName                              N
-  PayeeAccountNumber                            N
-  PayeeAccountSortCode                          N
-  TotalIncome                                   N
-  PayerAccountName                              N
-  PayerAccountNumber                            N
-  PayerAccountSortCode                          N
-  SecurityClassification                        N
-  SecurityClassificationCaveats                 N
-  ClassifiedBy                                  N
-  ClassificationReason                          N
-  DeclassificationDate                          N
-  DerivedFrom                                   N
-  ClassificationComment                         N
-  ClassificationAndMarkingSystem                N
-  BroadcastOrganizationName                     N
-  BroadcastServiceName                          N
-  BroadcastMediumCode                           N
-  BroadcastRegion                               N
-  NatureOfPersonality                           N
-  ContributionStatus                            N
-  SupportorAdministrationStatus                 N
-  OrganizationKind                              N
-  ProductionOrganizationRole                    N
-  SupportOrganizationRole                       N
-  JobFunctionName                               N
-  JobFunctionCode                               N
-  RoleName                                      N
-  JobTitle                                      N
-  JobTitle                                      N
-  ContactKind                                   N
-  ContactDepartmentName                         N
-  FamilyName                                    N
-  FirstGivenName                                N
-  SecondGivenName                               N
-  ThirdGivenName                                N
-  PersonDescription                             N
-  PersonDescription                             N
-  MainName                                      N
-  SupplementaryName                             N
-  OrganizationMainName                          N
-  SupplementaryOrganizationName                 N
-  RegionCode                                    N
-  CountryName                                   N
-  CountryName                                   N
-  RegionName                                    N
-  RegionName                                    N
-  LanguageName                                  N
-  LanguageName                                  N
-  TerminatingFillerData                         N
-  TimingBiasCorrection                          N
-  TimingBiasCorrectionDescription               N
-  Genre                                         N
-  TargetAudience                                N
-  ProgramMaterialClassificationCode             N
-  Theme                                         N
-  SubjectName                                   N
-  SubjectName                                   N
-  Keywords                                      N
-  KeyFrameSampleCount                           N
-  Abstract                                      N
-  Purpose                                       N
-  Description                                   N
-  ColorDescriptor                               N
-  FormatDescriptor                              N
-  IntentDescriptor                              N
-  IntentDescriptor                              N
-  TextualDescriptionKind                        N
-  TextualDescriptionKind                        N
-  FestivalName                                  N
-  ObjectDescriptionCode                         N
-  DescriptionKind                               N
-  DescriptionKind                               N
-  DescriptiveComment                            N
-  DescriptiveComment                            N
-  ContextDescription                            N
-  ComputedKeywords                              N
-  ObjectIdentificationConfidence                N
-  ObjectHorizontalAverageDimension              N
-  ObjectVerticalAverageDimension                N
-  ObjectAreaDimension                           N
-  HorizontalActionSafePercentage                N
-  VerticalActionSafePercentage                  N
-  HorizontalGraphicsSafePercentage              N
-  VerticalGraphicsSafePercentage                N
-  PerceivedDisplayFormatName                    N
-  PerceivedDisplayFormatCode                    N
-  VideoColorKind                                N
-  PictureDisplayRate                            N
-  VideoAverageBitrate                           N
-  VideoFixedBitrate                             N
-  DigitalVideoFileFormat                        N
-  CodingLawName                                 N
-  AudioCodingSchemeCode                         N
-  AudioCodingSchemeName                         N
-  DigitalEncodingBitrate                        N
-  DataEssenceCodingID?                          N
-  StorageKind                                   N
-  StorageKind                                   N
-  StorageKindCode                               N
-  TapePartitionCapacity                         N
-  DiscPartitionCapacity                         N
-  FocalLength                                   N
-  FieldOfViewHorizontal                         N
-  FieldOfViewVertical                           N
-  SystemNameOrNumber                            N
-  LogoFlag                                      N
-  GraphicKind                                   N
-  GraphicUsageKind                              N
-  SignatureTuneFlag                             N
-  BackgroundMusicFlag                           N
-  ProductionScriptReference                     N
-  ProductionScriptReference                     N
-  TranscriptReference                           N
-  TranscriptReference                           N
-  HorizontalDatum                               N
-  VerticalDatum                                 N
-  DeviceLatitude                                N
-  DeviceLongitude                               N
-  FrameCenterLatitude                           N
-  FrameCenterLongitude                          N
-  CornerLatitudePoint1                          N
-  CornerLatitudePoint1                          N
-  CornerLatitudePoint2                          N
-  CornerLatitudePoint2                          N
-  CornerLatitudePoint3                          N
-  CornerLatitudePoint3                          N
-  CornerLatitudePoint4                          N
-  CornerLatitudePoint4                          N
-  CornerLongitudePoint1                         N
-  CornerLongitudePoint1                         N
-  CornerLongitudePoint2                         N
-  CornerLongitudePoint2                         N
-  CornerLongitudePoint3                         N
-  CornerLongitudePoint3                         N
-  CornerLongitudePoint4                         N
-  CornerLongitudePoint4                         N
-  SubjectDistance                               N
-  PlaceKeyword                                  N
-  ObjectCountryCode                             N
-  ObjectCountryCodeMethod                       N
-  CountryCodeMethod                             N
-  Non-USClassifyingCountryCode                  N
-  ReleasableCountryCode                         N
-  ObjectRegionName                              N
-  ShootingRegionName                            N
-  SettingRegionName                             N
-  CopyrightLicenseRegionName                    N
-  IntellectualPropertyLicenseRegionName         N
-  RoomNumber                                    N
-  StreetNumber                                  N
-  StreetName                                    N
-  PostalTown                                    N
-  CityName                                      N
-  StateOrProvinceOrCountyName                   N
-  PostalCode                                    N
-  CountryName                                   N
-  SettingRoomNumber                             N
-  SettingStreetNumberOrBuildingName             N
-  SettingStreetName                             N
-  SettingTownName                               N
-  SettingCityName                               N
-  SettingStateOrProvinceOrCountyName            N
-  SettingPostalCode                             N
-  SettingCountryName                            N
-  TelephoneNumber                               N
-  FaxNumber                                     N
-  E-MailAddress                                 N
-  SettingDescription                            N
-  POSIXMicroseconds                             N
-  EventElapsedTimeToStart                       N
-  EventElapsedTimeToEnd                         N
-  OrganizationIDKind                            N
-  OrganizationIDKind                            N
-  SMPTEUL?                                      N
-  EssenceContainerArray?                        N
-  EssenceStreamID                               N
-  IndexStreamID                                 N
-  WorkingTitle                                  N
-  WorkingTitle                                  N
-  OriginalTitle                                 N
-  OriginalTitle                                 N
-  ClipNumber                                    N
-  ClipNumber                                    N
-  DescriptiveMetadataTrackIDs                   N
-  IdentifierKind                                N
-  IdentifierValue                               N
-  OrganizationCode                              N
-  OrganizationCode                              N
-  SupplierIdentificationKind                    N
-  SupplierIdentificationValue                   N
-  SupplierAccountNumber                         N
-  SupplierAccountName                           N
-  SupplierAccountName                           N
-  EpisodeStartNumber                            N
-  EpisodeEndNumber                              N
-  PurchaserIdentificationKind                   N
-  PurchaserIdentificationValue                  N
-  PurchaserAccountNumber                        N
-  PurchaserAccountName                          N
-  PurchaserAccountName                          N
-  ContractType                                  N
-  ContractClauseDescription                     N
-  ContractLineName                              N
-  ContractTermsOfBusiness                       N
-  Jurisdiction                                  N
-  TotalCurrencyAmount                           N
-  InstallmentNumber                             N
-  IdentifierIssuingAuthority                    N
-  PublishingOrganizationName                    N
-  PublishingOrganizationName                    N
-  PublishingServiceName                         N
-  PublishingServiceName                         N
-  PublishingMediumName                          N
-  PublishingMediumName                          N
-  PublishingRegionName                          N
-  PublishingRegionName                          N
-  Salutation                                    N
-  HonorsAndQualifications                       N
-  OtherGivenNames                               N
-  OtherGivenNames                               N
-  AlternateName                                 N
-  AlternateName                                 N
-  ISO639TextLanguageCode                        N
-  ISO639CaptionsLanguageCode                    N
-  PrimarySpokenLanguageCode                     N
-  SecondarySpokenLanguageCode                   N
-  PrimaryOriginalLanguageCode                   N
-  SecondaryOriginalLanguageCode                 N
-  MajorVersion                                  N
-  MinorVersion                                  N
-  SectorSize                                    N
-  ElementLength                                 N
-  ThesaurusName                                 N
-  Cue-InWords                                   N
-  Cue-OutWords                                  N
-  KeypointKind                                  N
-  KeypointKind                                  N
-  KeypointValue                                 N
-  KeypointValue                                 N
-  FestivalName                                  N
-  AwardName                                     N
-  AwardName                                     N
-  AwardCategory                                 N
-  AwardCategory                                 N
-  SlateInformation                              N
-  LockedIndicator                               N
-  BitsPerAudioSample                            N
-  CaptionKind                                   N
-  CaptionKind                                   N
-  SliceCount                                    N
-  SliceNumber                                   N
-  ElementDelta                                  N
-  PositionTableIndexing                         N
-  SliceOffsetList?                              N
-  PosTableArray?                                N
-  StreamOffset                                  N
-  EditUnitFlags                                 N
-  TemporalOffset                                N
-  AnchorOffset                                  N
-  EditUnitLength                                N
-  HeaderByteCount                               N
-  IndexByteCount                                N
-  PackLength                                    N
-  IntegrationIndication                         N
-  EventIndication                               N
-  GraphicUsageKind                              N
-  PrimaryPackage?                               N
-  DescriptiveMetadataSets?                      N
-  DescriptiveMetadataSetReferences?             N
-  FileDescriptors?                              N
-  StreamPositionIndicator                       N
-  StreamPositionIndicator                       N
-  StreamPositionIndicator                       N
-  OffsetToMetadata                              N
-  OffsetToMetadata                              N
-  OffsetToIndexTable                            N
-  OffsetToIndexTable                            N
-  ByteOffset                                    N
-  ReversePlay                                   N
-  FirstNumberInSequence                         N
-  FirstNumberInSequence                         N
-  PreviousNumberInSequence                      N
-  PreviousNumberInSequence                      N
-  CurrentNumberInSequence                       N
-  CurrentNumberInSequence                       N
-  NextNumberInSequence                          N
-  NextNumberInSequence                          N
-  LastNumberInSequence                          N
-  LastNumberInSequence                          N
-  CentralTelephoneNumber                        N
-  MobileTelephoneNumber                         N
-  URL                                           N
-  LocationDescription                           N
-  LocationDescription                           N
-  LocationKind                                  N
-  LocationKind                                  N
-  UTCEventStartDateTime                         N
-  LocalEventStartDateTime                       N
-  UTCEventEndDateTime                           N
-  LocalEventEndDateTime                         N
-  KeyTimePoint                                  N
-  TimePeriodName                                N
-  SettingDateTime                               N
-  ContractDateTime                              N
-  RightsStartDateTime                           N
-  RightsStopDateTime                            N
-  PaymentDueDateTime                            N
-  ClipID                                        N
-  DeviceKind                                    N
-  DeviceAssetNumber                             N
-  IdentificationUL?                             N
-  OperationalPatternUL?                         N
-  EssenceContainers?                            N
-  DescriptiveMetadataSchemes?                   N
-  ProjectName                                   N
-  ProjectName                                   N
-  LocalTagValue                                 N
-  LocalTagUniqueID?                             N
-  BrandMainTitle                                N
-  BrandMainTitle                                N
-  BrandOriginalTitle                            N
-  BrandOriginalTitle                            N
-  FrameworkTitle                                N
-  FrameworkTitle                                N
-  SourceTrackIDs                                N
-  ShotTrackIDs                                  N
-  ProgrammingGroupKind                          N
-  ProgrammingGroupTitle                         N
-  ProgrammingGroupTitle                         N
-  IdentifierIssuingAuthority                    N
-  LinkingName                                   N
-  LinkingName                                   N
-  NameSuffix                                    N
-  NameSuffix                                    N
-  FormerFamilyName                              N
-  FormerFamilyName                              N
-  Nationality                                   N
-  Nationality                                   N
-  Citizenship                                   N
-  Citizenship                                   N
-  FrameworkTextLanguageCode                     N
-  KAGSize                                       N
-  ReversedByteOrder                             N
-  ItemName                                      N
-  ItemName                                      N
-  ItemValue                                     N
-  ItemValue                                     N
-  XMLDocumentText?                              N
-  XMLDocumentText                               N
-  XMLDocumentText                               N
-  XMLDocumentText?                              N
-  FrameworkThesaurusName                        N
-  FrameworkThesaurusName                        N
-  GroupSynopsis                                 N
-  GroupSynopsis                                 N
-  AnnotationSynopsis                            N
-  AnnotationSynopsis                            N
-  AnnotationDescription                         N
-  AnnotationDescription                         N
-  ScriptingKind                                 N
-  ScriptingKind                                 N
-  ScriptingText                                 N
-  ScriptingText                                 N
-  ShotDescription                               N
-  ShotDescription                               N
-  AnnotationKind                                N
-  AnnotationKind                                N
-  RelatedMaterialDescription                    N
-  RelatedMaterialDescription                    N
-  ClipKind                                      N
-  DeviceUsageDescription                        N
-  DeviceUsageDescription                        N
-  DisplayF2Offset                               N
-  StoredF2Offset                                N
-  ActiveFormatDescriptor                        N
-  LineNumber                                    N
-  ScanningDirection                             N
-  ComponentMaximumRef                           N
-  ComponentMinimumRef                           N
-  AlphaMaximumRef                               N
-  AlphaMinimumRef                               N
-  VideoPayloadIdentifier                        N
-  VideoPayloadIdentifier2002                    N
-  SingleSequenceFlag                            N
-  ConstantBPictureFlag                          N
-  CodedContentScanningKind                      N
-  LowDelayIndicator                             N
-  ClosedGOPIndicator                            N
-  IdenticalGOPIndicator                         N
-  MaximumGOPSize                                N
-  MaximumBPictureCount                          N
-  ProfileAndLevel                               N
-  Bitrate                                       N
-  ChannelCount                                  N
-  AudioSampleRate                               N
-  PeakEnvelope                                  N
-  PeakEnvelopeData?                             N
-  BlockAlign                                    N
-  SequenceOffset                                N
-  BlockStartOffset                              N
-  FileSecurityReport                            N
-  FileSecurityWave                              N
-  AverageBytesPerSecond                         N
-  AuxiliaryBitsMode                             N
-  ChannelStatusMode                             N
-  FixedChannelStatusData?                       N
-  UserDataMode?                                 N
-  FixedUserData?                                N
-  Emphasis                                      N
-  BextCodingHistory                             N
-  BextCodingHistory                             N
-  QltyBasicData                                 N
-  QltyBasicData                                 N
-  QltyStartOfModulation                         N
-  QltyStartOfModulation                         N
-  QltyQualityEvent                              N
-  QltyQualityEvent                              N
-  QltyEndOfModulation                           N
-  QltyEndOfModulation                           N
-  QltyQualityParameter                          N
-  QltyQualityParameter                          N
-  QltyOperatorComment                           N
-  QltyOperatorComment                           N
-  QltyCueSheet                                  N
-  QltyCueSheet                                  N
-  DialNorm                                      N
-  DataEssenceCoding                             N
-  DateTimeRate                                  N
-  DateTimeDropFrameFlag                         N
-  DateTimeEmbeddedFlag                          N
-  DateTimeKind?                                 N
-  DeltaEntryArray?                              N
-  PositionTableCount                            N
-  PositionTable?                                N
-  IndexEntryArray?                              N
-  SignalStandard                                N
-  DataDefinition?                               N
-  RecordedFormat                                N
-  GenerationCopyNumber                          N
-  GenerationCloneNumber                         N
-  ThemeMusicFlag                                N
-  InsertMusicFlag                               N
-  IndexEditRate                                 N
-  LinkedTrackID                                 N
-  EssenceContainerFormat?                       N
-  CodecDefinition?                              N
-  DescriptiveMetadataFramework?                 N
-  GroupSet?                                     N
-  BankDetailsSet?                               N
-  ImageFormatSet?                               N
-  ProcessingSet?                                N
-  ProjectSet?                                   N
-  ContactsListSet?                              N
-  AnnotationCueWordsSet?                        N
-  ShotCueWordsSet?                              N
-  AwardParticipantSets?                         N
-  ContractParticipantSets?                      N
-  PersonSets?                                   N
-  ParticipantOrganizationSets?                  N
-  PersonOrganizationSets?                       N
-  LocationSets?                                 N
-  TitlesSets?                                   N
-  GroupSets?                                    N
-  IdentificationSets?                           N
-  EpisodicItemSets?                             N
-  BrandingSets?                                 N
-  EventSets?                                    N
-  PublicationSets?                              N
-  AwardSets?                                    N
-  CaptionDescriptionSets?                       N
-  AnnotationSets?                               N
-  ProductionSettingPeriodSets?                  N
-  SceneSettingPeriodSets?                       N
-  ScriptingSets?                                N
-  ClassificationSets?                           N
-  SceneShotSets?                                N
-  ClipShotSets?                                 N
-  KeyPointSets?                                 N
-  ShotParticipantRoleSets?                      N
-  ShotPersonSets?                               N
-  OrganizationSets?                             N
-  ShotLocationSets?                             N
-  AddressSets?                                  N
-  CommunicationSets?                            N
-  ContractSets?                                 N
-  RightsSets?                                   N
-  PaymentsSets?                                 N
-  DeviceParametersSets?                         N
-  ClassificationNameValueSets?                  N
-  ContactNameValueSets?                         N
-  DeviceParameterNameValueSets?                 N
-  MetadataServerLocators?                       N
-  RelatedMaterialLocators?                      N
-  LocalTagEntries?                              N
-  TotalNumberInSequence                         N
-  RoomOrSuiteName                               N
-  RoomOrSuiteName                               N
-  BuildingName                                  N
-  BuildingName                                  N
-  URL                                           N
-  LocalFestivalDateTime                         N
-  ShotStartPosition                             N
-  IndexingStartPosition                         N
-  EventOrigin                                   N
-  SettingPeriodDescription                      N
-  SettingPeriodDescription                      N
-  IndexDuration                                 N
-  ShotDuration                                  N
-  ExtendedClipID                                N
-  ClipIDArray?                                  N
-  ExtendedClipIDArray?                          N
-  TrackNumberBatch                              N
-  ExtendedTextLanguageCode                      N
-  ExtendedCaptionsLanguageCode                  N
-  FrameworkExtendedTextLanguageCode             N
-  PrimaryExtendedSpokenLanguageCode             N
-  SecondaryExtendedSpokenLanguageCode           N
-  OriginalExtendedSpokenPrimaryLanguageCode     N
-  SecondaryOriginalExtendedSpokenLanguageCode   N
-  KLVMetadataSequence?                          N
-  PackageAttributes?                            N
-  ComponentAttributes?                          N
-  MPEG7BiMDecoderInitFrame1?                    N
-  MPEG7BiMDecoderInitFrame2?                    N
-  MPEG7BiMDecoderInitFrame3?                    N
-  MPEG7BiMDecoderInitFrame4?                    N
-  MPEG7BiMDecoderInitFrame5?                    N
-  MPEG7BiMDecoderInitFrame6?                    N
-  MPEG7BiMDecoderInitFrame7?                    N
-  MPEG7BiMDecoderInitFrame8?                    N
-  MPEG7BiMAccessUnitFrame1?                     N
-  MPEG7BiMAccessUnitFrame2?                     N
-  MPEG7BiMAccessUnitFrame3?                     N
-  MPEG7BiMAccessUnitFrame4?                     N
-  MPEG7BiMAccessUnitFrame5?                     N
-  MPEG7BiMAccessUnitFrame6?                     N
-  MPEG7BiMAccessUnitFrame7?                     N
-  MPEG7BiMAccessUnitFrame8?                     N
-  ComponentUserComments?                        N
-  ShotCommentKind                               N
-  ShotComment                                   N
-  SensorMode                                    N
-  ChannelAssignment?                            N
-  ContentPackageIndexArray?                     N
-  VideoIndexArray?                              N
-  ApproximateImageContainerSize                 N
-  MetadataEncodingSchemeCode                    N
-  MIMEMediaType                                 N
-  MIMEMediaType                                 N
-  FieldOfViewVerticalFP                         N
-  PackageUsageKind?                             N
-  ChannelID                                     N
-  ChannelIDs                                    N
-  KLVDataType?                                  N
-  KLVDataParentProperties?                      N
-  TaggedValueParentProperties?                  N
-  AnnotationParticipantSets?                    N
-  KLVDataDefinitions?                           N
-  TaggedValueDefinitions?                       N
-  AddressNameValueSets?                         N
-  NMEADocumentText                              N
-  PlatformRollAngle                             N
-  PlatformPitchAngle                            N
-  PlatformHeadingAngle                          N
-  AddressLine                                   N
-  AddressLine                                   N
-  PlaceName                                     N
-  PlaceName                                     N
-  GeographicalCoordinates?                      N
-  AstronomicalBodyName                          N
-  AstronomicalBodyName                          N
-  TimecodeArray?                                N
-  MarkIn                                        N
-  UserPosition                                  N
-  MarkOut                                       N
-  ClipCreationDateTime                          N
-  VideoClipDuration                             N
-  ParticipantID?                                N
-  ContactID?                                    N
-  DefaultNamespaceURI                           N
-  DefaultNamespaceURI                           N
-  NamespaceURI                                  N
-  NamespaceURI                                  N
-  NamespaceURIs                                 N
-  NamespaceURIs                                 N
-  HTMLDOCTYPE                                   N
-  HTMLDOCTYPE                                   N
-  NamespacePrefix                               N
-  NamespacePrefix                               N
-  NamespacePrefixes                             N
-  NamespacePrefixes                             N
-  RightsComment                                 N
-  RightsComment                                 N
-  NominationCategory                            N
-  NominationCategory                            N
-  PeakEnvelopeVersion                           N
-  PeakEnvelopeFormat                            N
-  PointsPerPeakValue                            N
-  PeakEnvelopeBlockSize                         N
-  PeakChannelCount                              N
-  PeakFrameCount                                N
-  PeakOfPeaksPosition                           N
-  PeakEnvelopeTimestamp                         N
-  PeakEnvelopeData?                             N
-  RIFFChunkID                                   N
-  RIFFChunkLength                               N
-  RIFFChunkData?                                N
-  MIMECharSet                                   N
-  MIMECharSet                                   N
-  MIMEEncoding                                  N
-  MIMEEncoding                                  N
-  MonoSourceTrackIDs                            N
-  CompositionRendering?                         N
-  CaptionsDescriptionParticipantSets?           N
-  EventAnnotationSets?                          N
-  ScriptingLocators?                            N
-  UnknownBWFChunks?                             N
-  CryptographicContextID?                       N
-  PlatformDesignation                           N
-  LocalTargetID                                 N
-  NITFLayerTargetID                             N
-  NITFLayerTargetID                             N
-  PackageName                                   N
-  RP217DataStreamPID                            N
-  RP217VideoStreamPID                           N
-  SourceOrganization                            N
-  OriginalProducerName                          N
-  SecurityClassification                        N
-  SecurityClassificationCaveats                 N
-  ClassificationComment                         N
-  CipherAlgorithm?                              N
-  CryptographicKeyID?                           N
-  EncryptedSourceValue?                         N
-  MICAlgorithm?                                 N
-  MIC?                                          N
-  ISO639-1LanguageCode                          N
-  JFIFMarkerDescription                         N
-  JFIFMarkerDescription                         N
-  HTMLMetaDescription                           N
-  HTMLMetaDescription                           N
-  MetadataItemName                              N
-  ColorPrimaries                                N
-  ColorPrimaries?                               N
-  ProductFormat                                 N
-  ProductFormat                                 N
-  SourceLength                                  N
-  ImageSourceDeviceKind                         N
-  SourceContainerFormat?                        N
-  SourceKey?                                    N
-  DynamicSourcePackageID?                       N
-  DynamicSourceTrackIDs                         N
-  SourceIndex?                                  N
-  SourceSpecies?                                N
-  SourceValue?                                  N
-  CryptographicContextObject?                   N
-  Sub-descriptors?                              N
-  EncryptedTrackFileID?                         N
-  CryptographicContextLink?                     N
-  PlaintextOffset                               N
-  TripletSequenceNumber                         N
-  BoundingRectangle?                            N
-  GeographicLocation?                           N
-  GeographicPolygonCoordinates?                 N
-  GeographicAreaNorthwest?                      N
-  GeographicAreaSoutheast?                      N
-  GeographicAreaSourceDatum                     N
-  GeographicPolygonSourceDatum                  N
-  CountryCodeMethod                             N
-  ClassifyingCountryCode                        N
-  ReleasableCountryCode                         N
-  UTCStartDateTime                              N
-  UTCInstantDateTime                            N
-  UTCInstantDateTime                            N
-  UTCLastModifyDate                             N
-  ToleranceMode?                                N
-  ToleranceWindow?                              N
-  ToleranceInterpolationMethod?                 N
-  VBILineCount                                  N
-  StoredVBILineNumber                           N
-  VBIWrappingType                               N
-  VBIPayloadSampleCount                         N
-  VBIPayloadByteArray                           N
-  ANCPacketCount                                N
-  StoredANCLineNumber                           N
-  ANCWrappingType                               N
-  ANCPayloadSampleCount                         N
-  ANCPayloadByteArray                           N
-  VBIPayloadSampleCoding                        N
-  ANCPayloadSampleCoding                        N
-  Rsiz                                          N
-  Xsiz                                          N
-  Ysiz                                          N
-  XOsiz                                         N
-  YOsiz                                         N
-  XTsiz                                         N
-  YTsiz                                         N
-  XTOsiz                                        N
-  YTOsiz                                        N
-  Csiz                                          N
-  PictureComponentSizing?                       N
-  CodingStyleDefault?                           N
-  QuantizationDefault?                          N
-  MPEGAudioBitrate                              N
-  CBEStartOffset                                N
-  VBEEndOffset                                  N
-  SubDescriptor?                                N
-  SubDescriptors?                               N
-  RootMetaDictionary?                           N
-  RootPreface?                                  N
-  RootObjectDirectory?                          N
-  RootFormatVersion                             N
-  FrameCenterElevation                          N
-  PackageMarkInPosition                         N
-  PackageMarkOutPosition                        N
-  Ad-ID?                                        N
-  ResourceID?                                   N
-  AncillaryResourceID?                          N
-  ApplicationSchemeBatch?                       N
-  RegisterKind?                                 N
-  RegisterVersion                               N
-  RegisterEditorName                            N
-  RegisterStatusKind?                           N
-  RegisterItemName                              N
-  RegisterItemDefinition                        N
-  RegisterItemSymbol?                           N
-  RegisterItemDefiningDocumentName              N
-  RegisterItemUL?                               N
-  RegisterItemNotes                             N
-  RegisterItemIntroductionVersion               N
-  RegisterItemHierarchyLevel                    N
-  RegisterEntryStatus?                          N
-  RegisterAction                                N
-  RegisterApproverName                          N
-  RegisterCreationTime                          N
-  RegistrantName                                N
-  RegisterItemOriginatorName                    N
-  RegisterUserName                              N
-  RegisterUserTime                              N
-  RegisterAdministrationNotes                   N
-  AFDAndBarData?                                N
-  PanScanInformation?                           N
-  VC-1InitializationMetadata?                   N
-  VC-1SingleSequence                            N
-  VC-1CodedContentType                          N
-  VC-1IdenticalGOP                              N
-  VC-1MaximumGOP                                N
-  VC-1BPictureCount                             N
-  VC-1AverageBitrate                            N
-  VC-1MaximumBitrate                            N
-  VC-1Profile                                   N
-  VC-1Level                                     N
-  LinkedTimecodeTrackID?                        N
-  SMPTE337MDataStreamNumber                     N
-  ApplicationScheme?                            N
-  DescriptiveMetadataScheme?                    N
-  UCSEncoding                                   N
-  LinkedApplicationPlug-InInstanceID?           N
-  LinkedDescriptiveFrameworkPlug-InID?          N
-  ApplicationPlug-InInstanceID?                 N
-  DescriptiveMetadataPlug-InID?                 N
-  ApplicationEnvironmentID                      N
-  DescriptiveMetadataApplicationEnvironmentID   N
-  LinkedDescriptiveObjectPlug-InID?             N
-  TimebaseReferenceTrackID                      N
-  ObjectClassDefinition?                        N
-  ApplicationPlug-InBatch?                      N
-  PackageMarker?                                N
-  PackageTimelineMarkerRef?                     N
-  RegisterAdministrationObject?                 N
-  RegisterEntryAdministrationObject?            N
-  GenericPayloads?                              N
-  RegisterEntryArray?                           N
-  RegisterAdministrationArray?                  N
-  ApplicationInformationArray?                  N
-  RegisterChildEntryArray?                      N
-  RegisterReleaseDateTime                       N
-  RegisterItemStatusChangeDateTime              N
+  AAFManufacturerID?                            no
+  AES3PCMDescriptor                             MXF
+  AFDAndBarData?                                no
+  AGICOAID?                                     no
+  AICI?                                         no
+  AIFCSummary?                                  no
+  ANCPacketCount                                no
+  ANCPayloadByteArray                           no
+  ANCPayloadSampleCoding                        no
+  ANCPayloadSampleCount                         no
+  ANCWrappingType                               no
+  Abstract                                      no
+  Abstract                                      no
+  AccountingReferenceNumber                     no
+  ActiveFormatDescriptor                        no
+  ActiveLinesperFrame                           no
+  ActiveSamplesperLine                          no
+  ActiveState                                   no
+  Ad-ID?                                        no
+  Address                                       MXF
+  AddressLine                                   no
+  AddressLine                                   no
+  AddressNameValueSets?                         no
+  AddressSets?                                  no
+  AdvertisingMaterialReference                  no
+  AestheticValue                                no
+  AlphaMaximumRef                               no
+  AlphaMinimumRef                               no
+  AlphaSampleDepth                              no
+  AlphaTransparency                             no
+  AlternateName                                 no
+  AlternateName                                 no
+  Alternates?                                   no
+  AnalogDataCodingKind                          no
+  AnalogMetadataCarrier                         no
+  AnalogMonitoringAndControlCodingKind          no
+  AnalogSystem                                  no
+  AnalogVideoSystemName                         no
+  AnalogVideoSystemName?                        no
+  AnamorphicLensCharacteristic                  no
+  AnchorOffset                                  no
+  AncillaryResourceID?                          no
+  AngleToNorth                                  no
+  AngularUnitKind                               no
+  Annotation?                                   no
+  Annotation                                    MXF
+  AnnotationCueWordsSet?                        no
+  AnnotationDescription                         no
+  AnnotationDescription                         no
+  AnnotationKind                                no
+  AnnotationKind                                no
+  AnnotationParticipantSets?                    no
+  AnnotationSets?                               no
+  AnnotationSynopsis                            no
+  AnnotationSynopsis                            no
+  ApplicationEnvironmentID                      no
+  ApplicationInformationArray?                  no
+  ApplicationName                               no
+  ApplicationName                               no
+  ApplicationPlatform                           no
+  ApplicationPlatform                           no
+  ApplicationPlug-InBatch?                      no
+  ApplicationPlug-InInstanceID?                 no
+  ApplicationProductID?                         no
+  ApplicationScheme?                            no
+  ApplicationSchemeBatch?                       no
+  ApplicationSupplierName                       no
+  ApplicationSupplierName                       no
+  ApplicationVersionNumber                      no
+  ApplicationVersionString                      no
+  ApplicationVersionString                      no
+  ApproximateImageContainerSize                 no
+  ArchiveID                                     no
+  AssetValue                                    no
+  AssignedCategoryName                          no
+  AssignedCategoryName                          no
+  AssignedCategoryValue                         no
+  AssignedCategoryValue                         no
+  AssociatedMetadataDefinition?                 no
+  AstronomicalBodyName                          no
+  AstronomicalBodyName                          no
+  AudienceAppreciation                          no
+  AudienceRating                                no
+  AudienceReach                                 no
+  AudienceShare                                 no
+  AudioAverageBitrate                           no
+  AudioCodingSchemeCode                         no
+  AudioCodingSchemeID?                          no
+  AudioCodingSchemeName                         no
+  AudioCompressionAlgorithm                     no
+  AudioDeviceKind                               no
+  AudioDeviceParameter                          no
+  AudioDeviceParameterSetting                   no
+  AudioEnhancementOrModificationDescription     no
+  AudioFirstMix-DownProcess                     no
+  AudioFixedBitrateFlag                         no
+  AudioMonoChannelCount                         no
+  AudioNoiseReductionAlgorithm                  no
+  AudioReferenceLevel                           no
+  AudioReferenceLevel                           no
+  AudioSampleRate                               no
+  AudioSampleRate                               no
+  AudioStereoChannelCount                       no
+  AudioWatermarkKind                            no
+  AuthenticationFlag                            no
+  AuxiliaryBitsMode                             no
+  AvailableRepresentations?                     no
+  AverageBytesPerSecond                         no
+  Award                                         MXF
+  AwardCategory                                 no
+  AwardCategory                                 no
+  AwardName                                     no
+  AwardName                                     no
+  AwardParticipantSets?                         no
+  AwardSets?                                    no
+  BICI?                                         no
+  BackgroundMusicFlag                           no
+  BankDetailsSet?                               no
+  BeginAnchor                                   no
+  BeginAnchor                                   no
+  BextCodingHistory                             no
+  BextCodingHistory                             no
+  Bitrate                                       no
+  BitsPerAudioSample                            no
+  BitsPerPixel                                  no
+  BitsPerPixel                                  no
+  BitsPerSample                                 no
+  BlackReferenceLevel                           no
+  BlockAlign                                    no
+  BlockContinuityCount                          no
+  BlockStartOffset                              no
+  BoundingRectangle?                            no
+  BrandMainTitle                                no
+  BrandMainTitle                                no
+  BrandOriginalTitle                            no
+  BrandOriginalTitle                            no
+  Branding                                      MXF
+  BrandingSets?                                 no
+  BroadcastChannel                              no
+  BroadcastDate                                 no
+  BroadcastMediumCode                           no
+  BroadcastMediumKind                           no
+  BroadcastOrganizationName                     no
+  BroadcastOrganizationName                     no
+  BroadcastRegion                               no
+  BroadcastRegion                               no
+  BroadcastServiceName                          no
+  BroadcastTime                                 no
+  BroadcasterRightsToCopy                       no
+  BufferDelay?                                  no
+  BuildingName                                  no
+  BuildingName                                  no
+  Bypass                                        no
+  BypassOverride                                no
+  ByteOffset                                    no
+  ByteOrder                                     no
+  CBEStartOffset                                no
+  CDCIEssenceDescriptor                         MXF
+  CISACLegalEntityID?                           no
+  CaptionDescription                            MXF
+  CaptionDescriptionSets?                       no
+  CaptionKind                                   no
+  CaptionKind                                   no
+  CaptionTitles                                 no
+  CaptionsDescriptionParticipantSets?           no
+  CaptionsViaTeletext                           no
+  CaptureAspectRatio                            no
+  CaptureFilmFrameRate                          no
+  CaptureGammaEquation                          no
+  CaptureGammaEquation                          no
+  CaptureGammaEquation?                         no
+  CatalogDataStatus                             no
+  CatalogDataStatus                             no
+  CatalogPrefixNumber                           no
+  CatalogingSystemName                          no
+  CentralTelephoneNumber                        no
+  ChannelAssignment?                            no
+  ChannelCount                                  no
+  ChannelHandle                                 no
+  ChannelID                                     no
+  ChannelIDs                                    no
+  ChannelStatusMode                             no
+  CipherAlgorithm?                              no
+  CipherAlgorithmAES128CBC?                     no
+  Citizenship                                   no
+  Citizenship                                   no
+  CityName                                      no
+  CityName                                      no
+  ClassDefinitions?                             no
+  Classification                                MXF
+  ClassificationAndMarkingSystem                no
+  ClassificationComment                         no
+  ClassificationComment                         no
+  ClassificationNameValueSets?                  no
+  ClassificationReason                          no
+  ClassificationSets?                           no
+  ClassifiedBy                                  no
+  ClassifyingCountryCode                        no
+  ClipCreationDateTime                          no
+  ClipFramework                                 MXF
+  ClipID                                        no
+  ClipIDArray?                                  no
+  ClipKind                                      no
+  ClipNumber                                    no
+  ClipNumber                                    no
+  ClipShotSets?                                 no
+  CloneCount                                    no
+  ClosedBodyPartition?                          no
+  ClosedCaptionSubtitlesFlag                    no
+  ClosedCompleteBodyPartition?                  no
+  ClosedCompleteHeader                          MXF Header
+  ClosedGOPIndicator                            no
+  ClosedHeader                                  MXF Header
+  CodecDefinition?                              no
+  CodecDefinition?                              no
+  CodecDefinitions?                             no
+  CodecEssenceDescriptor?                       no
+  CodecEssenceKinds?                            no
+  CodedContentScanningKind                      no
+  CodingLawKind                                 no
+  CodingLawName                                 no
+  CodingStyleDefault?                           no
+  CollectionName                                no
+  CollectionName                                no
+  ColorDescriptor                               no
+  ColorDescriptor                               no
+  ColorFieldCode                                no
+  ColorPrimaries                                no
+  ColorPrimaries?                               no
+  ColorRangeLevels                              no
+  ColorSiting                                   no
+  ColorimetryCode                               no
+  ColorimetryCode?                              no
+  CommunicationSets?                            no
+  Communications                                MXF
+  CompleteFooter?                               no
+  ComponentAttributes?                          no
+  ComponentDataDefinition                       no
+  ComponentDepth                                no
+  ComponentKLVData?                             no
+  ComponentMaximumRef                           no
+  ComponentMinimumRef                           no
+  ComponentUserComments?                        no
+  ComponentsInSequence?                         no
+  CompositionRendering?                         no
+  ComputedKeyData                               no
+  ComputedKeyFrames                             no
+  ComputedKeySounds                             no
+  ComputedKeywords                              no
+  ComputedKeywords                              no
+  ComputedObjectKind                            no
+  ComputedObjectKind                            no
+  ComputedStratumKind                           no
+  ConstantBPictureFlag                          no
+  ConsumerRightsToCopy                          no
+  ContactDepartmentName                         no
+  ContactDepartmentName                         no
+  ContactID?                                    no
+  ContactKind                                   no
+  ContactKind                                   no
+  ContactNameValueSets?                         no
+  ContactsList                                  MXF
+  ContactsListSet?                              no
+  ContainerDefinitions?                         no
+  ContainerLastModifyDate                       no
+  ContainerVersion                              no
+  ContentClassification                         no
+  ContentClassification                         no
+  ContentCodingSystem                           no
+  ContentMaturityDescription                    no
+  ContentMaturityGraphic                        no
+  ContentMaturityRating                         no
+  ContentPackageIndexArray?                     no
+  ContentPackageMetadataLink                    no
+  ContentStorage?                               no
+  ContentStorageSet                             MXF
+  ContentValue                                  no
+  ContextDescription                            no
+  ContiguousDataFlag                            no
+  Contract                                      MXF
+  ContractClauseDescription                     no
+  ContractClauseDescription                     no
+  ContractDateTime                              no
+  ContractEntity                                no
+  ContractInstallmentPercentage                 no
+  ContractLineCode                              no
+  ContractLineName                              no
+  ContractLineName                              no
+  ContractParticipantSets?                      no
+  ContractSets?                                 no
+  ContractTermsOfBusiness                       no
+  ContractTermsOfBusiness                       no
+  ContractType                                  no
+  ContractType                                  no
+  ContractTypeCode                              no
+  ContractTypeLink                              no
+  ContributionStatus                            no
+  ContributionStatus                            no
+  ControlPointList?                             no
+  ControlPointTime                              no
+  CopyCount                                     no
+  CopyrightLicenseCountryCode                   no
+  CopyrightLicenseRegionCode                    no
+  CopyrightLicenseRegionName                    no
+  CopyrightOwnerName                            no
+  CopyrightOwnerName                            no
+  CopyrightStatus                               no
+  CopyrightStatus                               no
+  CornerLatitudePoint1                          no
+  CornerLatitudePoint1                          no
+  CornerLatitudePoint2                          no
+  CornerLatitudePoint2                          no
+  CornerLatitudePoint3                          no
+  CornerLatitudePoint3                          no
+  CornerLatitudePoint4                          no
+  CornerLatitudePoint4                          no
+  CornerLongitudePoint1                         no
+  CornerLongitudePoint1                         no
+  CornerLongitudePoint2                         no
+  CornerLongitudePoint2                         no
+  CornerLongitudePoint3                         no
+  CornerLongitudePoint3                         no
+  CornerLongitudePoint4                         no
+  CornerLongitudePoint4                         no
+  CountryCodeMethod                             no
+  CountryCodeMethod                             no
+  CountryName                                   no
+  CountryName                                   no
+  CountryName                                   no
+  CountryName                                   no
+  CreateDate                                    no
+  CryptographicContext                          MXF
+  CryptographicContextID?                       no
+  CryptographicContextLink?                     no
+  CryptographicContextObject?                   no
+  CryptographicFramework                        MXF
+  CryptographicFrameworkLabel?                  no
+  CryptographicKeyID?                           no
+  Csiz                                          no
+  Cue-InWords                                   no
+  Cue-InWords                                   no
+  Cue-OutWords                                  no
+  Cue-OutWords                                  no
+  CueWords                                      MXF
+  CulturalValue                                 no
+  CurrencyCode                                  no
+  CurrencyName                                  no
+  CurrentNumberInSequence                       no
+  CurrentNumberInSequence                       no
+  CurrentRepeatNumber                           no
+  CutPoint                                      no
+  DMFramework                                   MXF
+  DMSegment                                     MXF
+  DMSet                                         MXF
+  DMSourceClip                                  MXF
+  DOI?                                          no
+  DVBParentalRating                             no
+  DataDefinition?                               no
+  DataDefinitions?                              no
+  DataDeviceKind                                no
+  DataDeviceParameterName                       no
+  DataDeviceParameterSetting                    no
+  DataEnhancementOrModificationDescription      no
+  DataEssenceCoding                             no
+  DataEssenceCodingID?                          no
+  DateTimeDropFrameFlag                         no
+  DateTimeEmbeddedFlag                          no
+  DateTimeKind?                                 no
+  DateTimeRate                                  no
+  DeclassificationDate                          no
+  DefaultDataValue?                             no
+  DefaultFadeDuration                           no
+  DefaultFadeEditRate                           no
+  DefaultFadeType?                              no
+  DefaultNamespaceURI                           no
+  DefaultNamespaceURI                           no
+  DefaultObject?                                no
+  DefinedName                                   no
+  DefinedName                                   no
+  DefinitionObjectID?                           no
+  DefinitionObjectName                          no
+  DefinitionObjectName                          no
+  DegradedEffects?                              no
+  DeltaEntryArray?                              no
+  DerivedFrom                                   no
+  Description                                   no
+  Description                                   no
+  DescriptionKind                               no
+  DescriptionKind                               no
+  DescriptiveComment                            no
+  DescriptiveComment                            no
+  DescriptiveMetadataApplicationEnvironmentID   no
+  DescriptiveMetadataFramework?                 no
+  DescriptiveMetadataPlug-InID?                 no
+  DescriptiveMetadataScheme?                    no
+  DescriptiveMetadataSchemes?                   no
+  DescriptiveMetadataSetReferences?             no
+  DescriptiveMetadataSets?                      no
+  DescriptiveMetadataTrackIDs                   no
+  DeviceAbsoluteHeading                         no
+  DeviceAbsolutePositionalAccuracy              no
+  DeviceAbsoluteSpeed                           no
+  DeviceAltitude                                no
+  DeviceAltitude                                no
+  DeviceAssetNumber                             no
+  DeviceDesignation                             no
+  DeviceIDKind                                  no
+  DeviceKind                                    no
+  DeviceKind                                    no
+  DeviceKindCode                                no
+  DeviceLatitude                                no
+  DeviceLatitude                                no
+  DeviceLatitude                                no
+  DeviceLongitude                               no
+  DeviceLongitude                               no
+  DeviceLongitude                               no
+  DeviceManufacturerName                        no
+  DeviceManufacturerName                        no
+  DeviceModel                                   no
+  DeviceParameterNameValueSets?                 no
+  DeviceParameters                              MXF
+  DeviceParametersSets?                         no
+  DeviceRelativeHeading                         no
+  DeviceRelativePositionX                       no
+  DeviceRelativePositionY                       no
+  DeviceRelativePositionZ                       no
+  DeviceRelativePositionalAccuracy              no
+  DeviceRelativeSpeed                           no
+  DeviceSerialNumber                            no
+  DeviceUsageDescription                        no
+  DeviceUsageDescription                        no
+  DeviceXDimension                              no
+  DeviceYDimension                              no
+  DialNorm                                      no
+  Dictionary?                                   no
+  DictionaryDescription                         no
+  DictionaryDescription                         no
+  DictionaryIdentifier?                         no
+  DigitalEncodingBitrate                        no
+  DigitalMetadataCarrier                        no
+  DigitalOrAnalogOrigination                    no
+  DigitalVideoFileFormat                        no
+  DirectorName                                  no
+  DiscPartitionCapacity                         no
+  DisplayF2Offset                               no
+  DisplayHeight                                 no
+  DisplayUnits                                  no
+  DisplayUnits                                  no
+  DisplayWidth                                  no
+  DisplayXOffset                                no
+  DisplayYOffset                                no
+  Dither                                        no
+  DropFrame                                     no
+  Duration                                      no
+  DynamicSourcePackageID?                       no
+  DynamicSourceTrackIDs                         no
+  E-mailAddress                                 no
+  E-mailAddress                                 no
+  EPGProgramSynopsis                            no
+  EdgeCode                                      no
+  EdgeCodeFilmGauge?                            no
+  EdgeCodeFormat?                               no
+  EdgeCodeHeader?                               no
+  EdgeCodeStart                                 no
+  EditHint?                                     no
+  EditRate                                      no
+  EditUnitFlags                                 no
+  EditUnitLength                                no
+  EditingEventComment                           no
+  EditingEventComment                           no
+  EffectRendering?                              no
+  ElectrospatialFormulation                     no
+  ElementCount                                  no
+  ElementDelta                                  no
+  ElementLength                                 no
+  ElementNameList                               no
+  Emphasis                                      no
+  EncryptedContainerLabel?                      no
+  EncryptedSourceValue?                         no
+  EncryptedTrackFileID?                         no
+  EndAnchor                                     no
+  EndAnchor                                     no
+  EnhancementOrModificationDescription          no
+  EnumerationUnderlyingIntegerType?             no
+  EpisodeEndNumber                              no
+  EpisodeNumber                                 no
+  EpisodeNumber                                 no
+  EpisodeStartNumber                            no
+  EpisodicItemSets?                             no
+  EssenceContainerArray?                        no
+  EssenceContainerDataSet                       MXF
+  EssenceContainerFormat?                       no
+  EssenceContainerFormat?                       no
+  EssenceContainers?                            no
+  EssenceData?                                  no
+  EssenceDescription?                           no
+  EssenceIsIdentified                           no
+  EssenceLength                                 no
+  EssenceLocators?                              no
+  EssenceStreamID                               no
+  Event                                         MXF
+  EventAbsoluteDuration                         no
+  EventAbsoluteDuration?                        no
+  EventAbsoluteDurationFrameCount               no
+  EventAnnotationSets?                          no
+  EventElapsedTimeToEnd                         no
+  EventElapsedTimeToStart                       no
+  EventEndTimeOffset                            no
+  EventEndTimecodeOffset?                       no
+  EventIndication                               no
+  EventIndication                               no
+  EventOrigin                                   no
+  EventSets?                                    no
+  EventStart                                    no
+  EventStartTimeOffset                          no
+  EventStartTimecodeOffset?                     no
+  EventTrack                                    MXF
+  EventTrackEditRate                            no
+  ExCCIData?                                    no
+  ExposedAspectRatio                            no
+  ExtendedCaptionsLanguageCode                  no
+  ExtendedClipID                                no
+  ExtendedClipIDArray?                          no
+  ExtendedTextLanguageCode                      no
+  ExtendibleElementNameList                     no
+  FNumber                                       no
+  Fade-InDuration                               no
+  Fade-InType?                                  no
+  Fade-OutDuration                              no
+  Fade-OutType?                                 no
+  FamilyName                                    no
+  FamilyName                                    no
+  FaxNumber                                     no
+  FaxNumber                                     no
+  FemaleLeadActressName                         no
+  FestivalName                                  no
+  FestivalName                                  no
+  FieldDominance                                no
+  FieldFrameTypeCode                            no
+  FieldOfViewHorizontal                         no
+  FieldOfViewHorizontal                         no
+  FieldOfViewVertical                           no
+  FieldOfViewVerticalFP                         no
+  FieldRate                                     no
+  FileDescriptor                                MXF
+  FileDescriptors?                              no
+  FileSecurityReport                            no
+  FileSecurityWave                              no
+  FillerData?                                   no
+  FilmBatchNumber                               no
+  FilmBatchNumber                               no
+  FilmCaptureAperture                           no
+  FilmColorProcess                              no
+  FilmFormatName                                no
+  FilmFormatName                                no
+  FilmFormatName?                               no
+  FilmGauge?                                    no
+  FilmStockKind                                 no
+  FilmStockKind                                 no
+  FilmStockManufacturerName                     no
+  FilmStockManufacturerName                     no
+  FilmTestParameter                             no
+  FilmTestResult                                no
+  FilmTestResult?                               no
+  FilmToVideoTransferDirection?                 no
+  FilmToVideoTransferKind?                      no
+  FilmToVideoTransferPhase?                     no
+  FilteringApplied                              no
+  FilteringCode                                 no
+  FirstBroadcastFlag                            no
+  FirstGivenName                                no
+  FirstGivenName                                no
+  FirstNumberInSequence                         no
+  FirstNumberInSequence                         no
+  FirstTransmissionInfo                         no
+  FixedArrayElementType?                        no
+  FixedChannelStatusData?                       no
+  FixedUserData?                                no
+  FocalLength                                   no
+  FocalLength                                   no
+  Footer?                                       no
+  FormatDescriptor                              no
+  FormatDescriptor                              no
+  FormerFamilyName                              no
+  FormerFamilyName                              no
+  FrameCenterElevation                          no
+  FrameCenterLatitude                           no
+  FrameCenterLatitude                           no
+  FrameCenterLatitude                           no
+  FrameCenterLatitudeLongitude                  no
+  FrameCenterLongitude                          no
+  FrameCenterLongitude                          no
+  FrameCenterLongitude                          no
+  FrameCode                                     no
+  FrameCount                                    no
+  FrameCountOffset                              no
+  FrameLayout                                   no
+  FramePositionalAccuracy                       no
+  FrameRate                                     no
+  FrameworkExtendedTextLanguageCode             no
+  FrameworkTextLanguageCode                     no
+  FrameworkThesaurusName                        no
+  FrameworkThesaurusName                        no
+  FrameworkTitle                                no
+  FrameworkTitle                                no
+  GenerationCloneNumber                         no
+  GenerationCopyNumber                          no
+  GenerationID?                                 no
+  GenericDataEssenceDescriptor                  MXF
+  GenericPackage                                MXF
+  GenericPayloads?                              no
+  GenericPictureEssenceDescriptor               MXF
+  GenericSoundEssenceDescriptor                 MXF
+  GenericTrack                                  MXF
+  Genre                                         no
+  Genre                                         no
+  GeographicAreaNorthwest?                      no
+  GeographicAreaSourceDatum                     no
+  GeographicAreaSoutheast?                      no
+  GeographicLocation?                           no
+  GeographicPolygonCoordinates?                 no
+  GeographicPolygonSourceDatum                  no
+  GeographicalCoordinates?                      no
+  GlobalNumber                                  no
+  GraphicKind                                   no
+  GraphicUsageKind                              no
+  GraphicUsageKind                              no
+  GroupRelationship                             MXF
+  GroupSet?                                     no
+  GroupSets?                                    no
+  GroupSynopsis                                 no
+  GroupSynopsis                                 no
+  HMACAlgorithmSHA1128?                         no
+  HTMLDOCTYPE                                   no
+  HTMLDOCTYPE                                   no
+  HTMLMetaDescription                           no
+  HTMLMetaDescription                           no
+  HardwareAcceleratorFlag                       no
+  HasAudioWatermark                             no
+  HasVideoWatermark                             no
+  HeaderByteCount                               no
+  HistoricalValue                               no
+  HonorsAndQualifications                       no
+  HonorsAndQualifications                       no
+  HorizontalActionSafePercentage                no
+  HorizontalDatum                               no
+  HorizontalGraphicsSafePercentage              no
+  HorizontalSubsampling                         no
+  IBTN?                                         no
+  IEEEDeviceID                                  no
+  IEEEManufacturerID                            no
+  ISAN?                                         no
+  ISBD?                                         no
+  ISBN?                                         no
+  ISCI?                                         no
+  ISMN?                                         no
+  ISO3166CountryCode                            no
+  ISO639-1LanguageCode                          no
+  ISO639-1LanguageCode                          no
+  ISO639CaptionsLanguageCode                    no
+  ISO639TextLanguageCode                        no
+  ISRC?                                         no
+  ISRN?                                         no
+  ISSN?                                         no
+  ISTC?                                         no
+  ISWC?                                         no
+  IdenticalGOPIndicator                         no
+  Identification                                MXF
+  Identification                                MXF
+  IdentificationList?                           no
+  IdentificationSets?                           no
+  IdentificationUL?                             no
+  IdentifierIssuingAuthority                    no
+  IdentifierIssuingAuthority                    no
+  IdentifierKind                                no
+  IdentifierValue                               no
+  ImageAlignmentOffset                          no
+  ImageCategory                                 no
+  ImageCoordinateSystem                         no
+  ImageEndOffset                                no
+  ImageFormatSet?                               no
+  ImageHeight                                   no
+  ImageSourceDeviceKind                         no
+  ImageSourceDeviceKind                         no
+  ImageStartOffset                              no
+  ImageWidth                                    no
+  IncludeSync                                   no
+  IndexByteCount                                no
+  IndexDuration                                 no
+  IndexEditRate                                 no
+  IndexEntryArray?                              no
+  IndexStreamID                                 no
+  IndexTableSegment?                            no
+  IndexingStartPosition                         no
+  IndividualAwardName                           no
+  InkNumber                                     no
+  InputSegment?                                 no
+  InputSegmentCount                             no
+  InputSegments?                                no
+  InsertMusicFlag                               no
+  InstallmentNumber                             no
+  InstanceUID?                                  no
+  IntegrationIndication                         no
+  IntegrationIndication                         no
+  IntellectualPropertyDescription               no
+  IntellectualPropertyDescription               no
+  IntellectualPropertyLicenseCountryCode        no
+  IntellectualPropertyLicenseRegionCode         no
+  IntellectualPropertyLicenseRegionName         no
+  IntellectualPropertyRights                    no
+  IntellectualPropertyRights                    no
+  IntendedAFD                                   no
+  IntentDescriptor                              no
+  IntentDescriptor                              no
+  InterestedPartyName                           no
+  Interpolation?                                no
+  InterpolationDefinitions?                     no
+  IsConcrete                                    no
+  IsDubbed                                      no
+  IsLiveProduction                              no
+  IsLiveTransmission                            no
+  IsOptional                                    no
+  IsRecording                                   no
+  IsRepeat                                      no
+  IsSearchable                                  no
+  IsSigned                                      no
+  IsUniqueIdentifier                            no
+  IsVoiceover                                   no
+  ItemDesignatorID?                             no
+  ItemID                                        no
+  ItemName                                      no
+  ItemName                                      no
+  ItemValue                                     no
+  ItemValue                                     no
+  JFIFMarkerDescription                         no
+  JFIFMarkerDescription                         no
+  JPEG2000PictureSubDescriptor                  MXF
+  JPEGTableID?                                  no
+  JobFunctionCode                               no
+  JobFunctionName                               no
+  JobFunctionName                               no
+  JobTitle                                      no
+  JobTitle                                      no
+  Jurisdiction                                  no
+  Jurisdiction                                  no
+  KAGSize                                       no
+  KLVDataDefinitions?                           no
+  KLVDataParentProperties?                      no
+  KLVDataType?                                  no
+  KLVDataValue?                                 no
+  KLVMetadataSequence?                          no
+  KeyCode?                                      no
+  KeyData                                       no
+  KeyDataOrProgram                              no
+  KeyFrame                                      no
+  KeyFrameSampleCount                           no
+  KeyFrames                                     no
+  KeyPoint                                      MXF
+  KeyPointSets?                                 no
+  KeySound                                      no
+  KeySounds                                     no
+  KeyText                                       no
+  KeyTimePoint                                  no
+  KeypointKind                                  no
+  KeypointKind                                  no
+  KeypointValue                                 no
+  KeypointValue                                 no
+  Keywords                                      no
+  Keywords                                      no
+  LUID                                          no
+  LanguageName                                  no
+  LanguageName                                  no
+  LastNumberInSequence                          no
+  LastNumberInSequence                          no
+  LayerNumber                                   no
+  LeadingLines                                  no
+  LengthSystemName                              no
+  LengthUnitKind                                no
+  LicenseOptionsDescription                     no
+  LineNumber                                    no
+  LinkedApplicationPlug-InInstanceID?           no
+  LinkedDescriptiveFrameworkPlug-InID?          no
+  LinkedDescriptiveObjectPlug-InID?             no
+  LinkedGenerationID?                           no
+  LinkedPackageID?                              no
+  LinkedTimecodeTrackID?                        no
+  LinkedTrackID                                 no
+  LinkingName                                   no
+  LinkingName                                   no
+  LocalCreationDateTime                         no
+  LocalDatumAbsolutePositionAccuracy            no
+  LocalDatumRelativePositionAccuracy            no
+  LocalEndDateTime                              no
+  LocalEventEndDateTime                         no
+  LocalEventEndDateTime                         no
+  LocalEventStartDateTime                       no
+  LocalEventStartDateTime                       no
+  LocalFestivalDateTime                         no
+  LocalFilePath                                 no
+  LocalFilePath                                 no
+  LocalID                                       no
+  LocalLastModifyDate                           no
+  LocalModifyDate                               no
+  LocalStartDateTime                            no
+  LocalTagEntries?                              no
+  LocalTagUniqueID?                             no
+  LocalTagValue                                 no
+  LocalTapeNumber                               no
+  LocalTargetID                                 no
+  LocalTargetID                                 no
+  LocalUserDateTime                             no
+  Location                                      MXF
+  LocationDescription                           no
+  LocationDescription                           no
+  LocationKind                                  no
+  LocationKind                                  no
+  LocationSets?                                 no
+  LockedIndicator                               no
+  LogoFlag                                      no
+  LowDelayIndicator                             no
+  LumaEquation                                  no
+  LuminanceSampleRate                           no
+  MIC?                                          no
+  MICAlgorithm?                                 no
+  MIMECharSet                                   no
+  MIMECharSet                                   no
+  MIMEEncoding                                  no
+  MIMEEncoding                                  no
+  MIMEMediaType                                 no
+  MIMEMediaType                                 no
+  MPEG2VideoDescriptor                          MXF
+  MPEG7BiMAccessUnitFrame1?                     no
+  MPEG7BiMAccessUnitFrame2?                     no
+  MPEG7BiMAccessUnitFrame3?                     no
+  MPEG7BiMAccessUnitFrame4?                     no
+  MPEG7BiMAccessUnitFrame5?                     no
+  MPEG7BiMAccessUnitFrame6?                     no
+  MPEG7BiMAccessUnitFrame7?                     no
+  MPEG7BiMAccessUnitFrame8?                     no
+  MPEG7BiMDecoderInitFrame1?                    no
+  MPEG7BiMDecoderInitFrame2?                    no
+  MPEG7BiMDecoderInitFrame3?                    no
+  MPEG7BiMDecoderInitFrame4?                    no
+  MPEG7BiMDecoderInitFrame5?                    no
+  MPEG7BiMDecoderInitFrame6?                    no
+  MPEG7BiMDecoderInitFrame7?                    no
+  MPEG7BiMDecoderInitFrame8?                    no
+  MPEGAudioBitrate                              no
+  MPEGAudioRecodingDataset?                     no
+  MPEGVideoRecodingDataset?                     no
+  MagneticDiskNumber                            no
+  MagneticTrack                                 no
+  MainCatalogNumber                             no
+  MainName                                      no
+  MainName                                      no
+  MainSponsorName                               no
+  MainTitle                                     no
+  MainTitle                                     no
+  MajorVersion                                  no
+  MaleLeadActorName                             no
+  ManufacturerID?                               no
+  ManufacturerInformationObject?                no
+  MapDatumUsed                                  no
+  MarkIn                                        no
+  MarkOut                                       no
+  MaterialAbsoluteDuration                      no
+  MaterialAbsoluteDuration?                     no
+  MaterialEndTimeOffset                         no
+  MaterialEndTimecodeOffset?                    no
+  MaterialPackage                               MXF
+  MaximumAPIVersion                             no
+  MaximumBPictureCount                          no
+  MaximumGOPSize                                no
+  MaximumSupportedEngineVersion                 no
+  MaximumSupportedPlatformVersion               no
+  MaximumUseCount                               no
+  MediaLocation                                 no
+  MemberNameList                                no
+  MemberTypes?                                  no
+  MetadataEncodingSchemeCode                    no
+  MetadataItemName                              no
+  MetadataItemName                              no
+  MetadataServerLocators?                       no
+  MicrophonePlacementTechniques                 no
+  MinimumAPIVersion                             no
+  MinimumSupportedEngineVersion                 no
+  MinimumSupportedPlatformVersion               no
+  MinorVersion                                  no
+  MissionID                                     no
+  MissionID                                     no
+  MobileTelephoneNumber                         no
+  ModifyDate                                    no
+  MonoSourceTrackIDs                            no
+  MultipleDescriptor                            MXF
+  NITFLayerTargetID                             no
+  NITFLayerTargetID                             no
+  NMEADocumentText                              no
+  NOLACode                                      no
+  NameSuffix                                    no
+  NameSuffix                                    no
+  NameValue                                     MXF
+  NamespacePrefix                               no
+  NamespacePrefix                               no
+  NamespacePrefixes                             no
+  NamespacePrefixes                             no
+  NamespaceURI                                  no
+  NamespaceURI                                  no
+  NamespaceURIs                                 no
+  NamespaceURIs                                 no
+  Nationality                                   no
+  Nationality                                   no
+  NatureOfPersonality                           no
+  NatureOfPersonality                           no
+  NetworkLocator                                MXF
+  NextNumberInSequence                          no
+  NextNumberInSequence                          no
+  NielsenStreamIdentifier                       no
+  NominationCategory                            no
+  NominationCategory                            no
+  Non-USClassifyingCountryCode                  no
+  ObjectAreaDimension                           no
+  ObjectClass?                                  no
+  ObjectClassDefinition?                        no
+  ObjectCountryCode                             no
+  ObjectCountryCode                             no
+  ObjectCountryCodeMethod                       no
+  ObjectDescription                             no
+  ObjectDescription                             no
+  ObjectDescriptionCode                         no
+  ObjectHorizontalAverageDimension              no
+  ObjectIdentificationConfidence                no
+  ObjectKind                                    no
+  ObjectKind                                    no
+  ObjectModelVersion                            no
+  ObjectName                                    no
+  ObjectRegionCode                              no
+  ObjectRegionName                              no
+  ObjectVerticalAverageDimension                no
+  ObliquityAngle                                no
+  OffsetToIndexTable                            no
+  OffsetToIndexTable                            no
+  OffsetToMetadata                              no
+  OffsetToMetadata                              no
+  OpenBodyPartition?                            no
+  OpenCompleteBodyPartition?                    no
+  OpenCompleteHeader                            MXF Header
   OpenHeader                                    MXF Header
-  ClosedHeader                                  MXF Header
-  OpenCompleteHeader                            MXF Header
-  ClosedCompleteHeader                          MXF Header
-  OpenBodyPartition?                            N
-  ClosedBodyPartition?                          N
-  OpenCompleteBodyPartition?                    N
-  ClosedCompleteBodyPartition?                  N
-  Footer?                                       N
-  CompleteFooter?                               N
+  OperatingSystemInterpretations                no
+  OperationCategory?                            no
+  OperationDataDefinition?                      no
+  OperationDefinitionID?                        no
+  OperationDefinitions?                         no
+  OperationParameters?                          no
+  OperationalPatternUL?                         no
+  OpticalDiscNumber                             no
+  OpticalTestParameterName                      no
+  OpticalTestResult                             no
+  OpticalTestResult                             no
+  OpticalTrack                                  no
+  Organisation                                  MXF
+  OrganizationCode                              no
+  OrganizationCode                              no
+  OrganizationID                                no
+  OrganizationID                                no
+  OrganizationIDKind                            no
+  OrganizationIDKind                            no
+  OrganizationKind                              no
+  OrganizationKind                              no
+  OrganizationMainName                          no
+  OrganizationMainName                          no
+  OrganizationSets?                             no
+  OrganizationalProgramNumber                   no
+  OrganizationalProgramNumber                   no
+  Origin                                        no
+  OriginCode                                    no
+  OriginalExtendedSpokenPrimaryLanguageCode     no
+  OriginalProducerName                          no
+  OriginalProducerName                          no
+  OriginalTitle                                 no
+  OriginalTitle                                 no
+  OtherGivenNames                               no
+  OtherGivenNames                               no
+  OtherValues                                   no
+  PII?                                          no
+  POSIXMicroseconds                             no
+  PURL                                          no
+  PackLength                                    no
+  PackageAttributes?                            no
+  PackageID?                                    no
+  PackageKLVData?                               no
+  PackageLastModifyDate                         no
+  PackageMarkInPosition                         no
+  PackageMarkOutPosition                        no
+  PackageMarker?                                no
+  PackageName                                   no
+  PackageName                                   no
+  PackageTimelineMarkerRef?                     no
+  PackageTracks?                                no
+  PackageUsageKind?                             no
+  PackageUserComments?                          no
+  Packages?                                     no
+  PaddingBits                                   no
+  Palette?                                      no
+  PaletteLayout?                                no
+  PanScanInformation?                           no
+  ParameterDataType?                            no
+  ParameterDefinition?                          no
+  ParameterDefinitions?                         no
+  Parameters?                                   no
+  ParentClass?                                  no
+  Participant                                   MXF
+  ParticipantID?                                no
+  ParticipantOrganizationSets?                  no
+  PartitionMetadata?                            no
+  Password                                      no
+  Password                                      no
+  PayeeAccountName                              no
+  PayeeAccountNumber                            no
+  PayeeAccountSortCode                          no
+  PayerAccountName                              no
+  PayerAccountNumber                            no
+  PayerAccountSortCode                          no
+  PaymentDueDateTime                            no
+  PaymentsSets?                                 no
+  PeakChannelCount                              no
+  PeakEnvelope                                  no
+  PeakEnvelopeBlockSize                         no
+  PeakEnvelopeData?                             no
+  PeakEnvelopeData?                             no
+  PeakEnvelopeFormat                            no
+  PeakEnvelopeTimestamp                         no
+  PeakEnvelopeVersion                           no
+  PeakFrameCount                                no
+  PeakOfPeaksPosition                           no
+  PerceivedDisplayFormatCode                    no
+  PerceivedDisplayFormatName                    no
+  PerforationsPerFrame                          no
+  PerforationsPerFrame                          no
+  Person                                        MXF
+  PersonDescription                             no
+  PersonDescription                             no
+  PersonOrganizationSets?                       no
+  PersonSets?                                   no
+  PhysicalInstanceKind                          no
+  PhysicalMediaLength?                          no
+  PhysicalMediaLocation                         no
+  PictureComponentSizing?                       no
+  PictureDisplayRate                            no
+  PictureFormat                                 MXF
+  PixelLayout?                                  no
+  PlaceKeyword                                  no
+  PlaceKeyword                                  no
+  PlaceName                                     no
+  PlaceName                                     no
+  PlaintextOffset                               no
+  PlatformDesignation                           no
+  PlatformDesignation                           no
+  PlatformHeadingAngle                          no
+  PlatformModel                                 no
+  PlatformPitchAngle                            no
+  PlatformRollAngle                             no
+  PlatformSerialNumber                          no
+  Plug-InAPIID?                                 no
+  Plug-InCategoryID?                            no
+  Plug-InDefinitions?                           no
+  Plug-InEngineID?                              no
+  Plug-InLocatorSet?                            no
+  Plug-InPlatformID?                            no
+  PointsPerPeakValue                            no
+  PolarCharacteristic                           no
+  PosTableArray?                                no
+  PositionInSequence                            no
+  PositionTable?                                no
+  PositionTableCount                            no
+  PositionTableIndexing                         no
+  PositionWithinViewportImageXCoordinate        no
+  PositionWithinViewportImageYCoordinate        no
+  PostCodeForPostbox                            no
+  PostalCode                                    no
+  PostalCode                                    no
+  PostalTown                                    no
+  PostalTown                                    no
+  PostboxNumber                                 no
+  Preface                                       MXF
+  PresentationAspectRatio                       no
+  PresentationGammaEquation                     no
+  PresentationGammaEquation?                    no
+  PresenterName                                 no
+  PreviousNumberInSequence                      no
+  PreviousNumberInSequence                      no
+  PreviousRepeatNumber                          no
+  PrimaryExtendedSpokenLanguageCode             no
+  PrimaryOriginalLanguageCode                   no
+  PrimaryPackage?                               no
+  PrimarySpokenLanguageCode                     no
   Primer                                        MXF
-  RandomIndexMetadataV10?                       N
-  RandomIndexMetadata?                          N
-  PartitionMetadata?                            N
+  Processing                                    MXF
+  ProcessingSet?                                no
+  ProducerName                                  no
+  ProductFormat                                 no
+  ProductFormat                                 no
+  ProductionFramework                           MXF
+  ProductionOrganizationRole                    no
+  ProductionOrganizationRole                    no
+  ProductionScriptReference                     no
+  ProductionScriptReference                     no
+  ProductionSettingPeriodSets?                  no
+  ProfileAndLevel                               no
+  ProgramAwardName                              no
+  ProgramCommercialMaterialReference            no
+  ProgramIdentifier                             no
+  ProgramIdentifierString                       no
+  ProgramKind                                   no
+  ProgramMaterialClassificationCode             no
+  ProgramNumber                                 no
+  ProgramSupportMaterialReference               no
+  ProgrammingGroupKind                          no
+  ProgrammingGroupKind                          no
+  ProgrammingGroupTitle                         no
+  ProgrammingGroupTitle                         no
+  ProjectName                                   no
+  ProjectName                                   no
+  ProjectNumber                                 no
+  ProjectSet?                                   no
+  Projects                                      MXF
+  Properties?                                   no
+  PropertyType?                                 no
+  Publication                                   MXF
+  PublicationSets?                              no
+  PublishingMediumName                          no
+  PublishingMediumName                          no
+  PublishingOrganizationName                    no
+  PublishingOrganizationName                    no
+  PublishingRegionName                          no
+  PublishingRegionName                          no
+  PublishingServiceName                         no
+  PublishingServiceName                         no
+  PulldownFieldDominance                        no
+  PulldownSequence?                             no
+  PurchaserAccountName                          no
+  PurchaserAccountName                          no
+  PurchaserAccountNumber                        no
+  PurchaserIdentificationKind                   no
+  PurchaserIdentificationValue                  no
+  PurchasingDepartment                          no
+  PurchasingOrganizationName                    no
+  Purpose                                       no
+  Purpose                                       no
+  QltyBasicData                                 no
+  QltyBasicData                                 no
+  QltyCueSheet                                  no
+  QltyCueSheet                                  no
+  QltyEndOfModulation                           no
+  QltyEndOfModulation                           no
+  QltyOperatorComment                           no
+  QltyOperatorComment                           no
+  QltyQualityEvent                              no
+  QltyQualityEvent                              no
+  QltyQualityParameter                          no
+  QltyQualityParameter                          no
+  QltyStartOfModulation                         no
+  QltyStartOfModulation                         no
+  QualityFlag                                   no
+  QuantizationDefault?                          no
+  RGBAEssenceDescriptor                         MXF
+  RIFFChunkData?                                no
+  RIFFChunkID                                   no
+  RIFFChunkLength                               no
+  RP217DataStreamPID                            no
+  RP217VideoStreamPID                           no
+  RandomIndexMetadata?                          no
+  RandomIndexMetadataV10?                       no
+  Rating                                        no
+  RecordedFormat                                no
+  RecordedFormat                                no
+  RecordedTrackNumber                           no
+  RecordingLabelName                            no
+  RecordingLabelName                            no
+  ReelOrRollNumber                              no
+  RegionCode                                    no
+  RegionName                                    no
+  RegionName                                    no
+  RegisterAction                                no
+  RegisterAdministrationArray?                  no
+  RegisterAdministrationNotes                   no
+  RegisterAdministrationObject?                 no
+  RegisterApproverName                          no
+  RegisterChildEntryArray?                      no
+  RegisterCreationTime                          no
+  RegisterEditorName                            no
+  RegisterEntryAdministrationObject?            no
+  RegisterEntryArray?                           no
+  RegisterEntryStatus?                          no
+  RegisterItemDefiningDocumentName              no
+  RegisterItemDefinition                        no
+  RegisterItemHierarchyLevel                    no
+  RegisterItemIntroductionVersion               no
+  RegisterItemName                              no
+  RegisterItemNotes                             no
+  RegisterItemOriginatorName                    no
+  RegisterItemStatusChangeDateTime              no
+  RegisterItemSymbol?                           no
+  RegisterItemUL?                               no
+  RegisterKind?                                 no
+  RegisterReleaseDateTime                       no
+  RegisterStatusKind?                           no
+  RegisterUserName                              no
+  RegisterUserTime                              no
+  RegisterVersion                               no
+  RegistrantName                                no
+  RelatedMaterialDescription                    no
+  RelatedMaterialDescription                    no
+  RelatedMaterialLocators?                      no
+  RelativePositionInSequenceName                no
+  RelativePositionInSequenceOffset              no
+  RelativeScope                                 no
+  RelativeTrack                                 no
+  ReleasableCountryCode                         no
+  ReleasableCountryCode                         no
+  RenamedType?                                  no
+  ResourceID?                                   no
+  RestrictionsonUse                             no
+  ReversePlay                                   no
+  ReversedByteOrder                             no
+  Rights                                        MXF
+  RightsComment                                 no
+  RightsComment                                 no
+  RightsConditionDescription                    no
+  RightsConditionDescription                    no
+  RightsManagementAuthority                     no
+  RightsManagementAuthority                     no
+  RightsSets?                                   no
+  RightsStartDateTime                           no
+  RightsStopDateTime                            no
+  Rightsholder                                  no
+  Rightsholder                                  no
+  RoleName                                      no
+  RoleName                                      no
+  RoomNumber                                    no
+  RoomNumber                                    no
+  RoomOrSuiteName                               no
+  RoomOrSuiteName                               no
+  RootFormatVersion                             no
+  RootMetaDictionary?                           no
+  RootObjectDirectory?                          no
+  RootPreface?                                  no
+  RoundedCaptureFilmFrameRate                   no
+  RoundedTimecodeTimebase                       no
+  RoundingLaw                                   no
+  RoundingMethodCode                            no
+  RoyaltyIncomeInformation                      no
+  RoyaltyPaymentInformation                     no
+  Rsiz                                          no
+  SDKVersion                                    no
+  SICI?                                         no
+  SMPTE12MUserDateTime?                         no
+  SMPTE309MUserDateTime?                        no
+  SMPTE337MDataStreamNumber                     no
+  SMPTEUL?                                      no
+  SalesContractNumber                           no
+  Salutation                                    no
+  Salutation                                    no
+  SampleIndex?                                  no
+  SampleRate                                    no
+  SampledHeight                                 no
+  SampledWidth                                  no
+  SampledXOffset                                no
+  SampledYOffset                                no
+  SamplingHierarchyCode                         no
+  SamplingStructureCode                         no
+  ScanningDirection                             no
+  SceneFramework                                MXF
+  SceneNumber                                   no
+  SceneNumber                                   no
+  SceneSettingPeriodSets?                       no
+  SceneShotSets?                                no
+  ScramblingKeyKind                             no
+  ScramblingKeyValue                            no
+  Scripting                                     MXF
+  ScriptingKind                                 no
+  ScriptingKind                                 no
+  ScriptingLocators?                            no
+  ScriptingSets?                                no
+  ScriptingText                                 no
+  ScriptingText                                 no
+  SeasonEpisodeNumber                           no
+  SeasonEpisodeTitle                            no
+  SecondGivenName                               no
+  SecondGivenName                               no
+  SecondaryExtendedSpokenLanguageCode           no
+  SecondaryOriginalExtendedSpokenLanguageCode   no
+  SecondaryOriginalLanguageCode                 no
+  SecondarySpokenLanguageCode                   no
+  SecondaryTitle                                no
+  SecondaryTitle                                no
+  SectorSize                                    no
+  SecurityClassification                        no
+  SecurityClassification                        no
+  SecurityClassificationCaveats                 no
+  SecurityClassificationCaveats                 no
+  Selected?                                     no
+  SensorMode                                    no
+  SensorRollAngle                               no
+  SensorSize                                    no
+  SensorType                                    no
+  SensorTypeCode                                no
+  Sequence?                                     no
+  SequenceOffset                                no
+  SequenceSet                                   MXF
+  SeriesNumber                                  no
+  SeriesNumber                                  no
+  SeriesinaSeriesGroupCount                     no
+  SetElementType?                               no
+  SettingCityName                               no
+  SettingCityName                               no
+  SettingCountryCode                            no
+  SettingCountryName                            no
+  SettingCountryName                            no
+  SettingDateTime                               no
+  SettingDescription                            no
+  SettingDescription                            no
+  SettingPeriod                                 MXF
+  SettingPeriodDescription                      no
+  SettingPeriodDescription                      no
+  SettingPostalCode                             no
+  SettingPostalCode                             no
+  SettingRegionCode                             no
+  SettingRegionName                             no
+  SettingRoomNumber                             no
+  SettingRoomNumber                             no
+  SettingStateOrProvinceOrCountyName            no
+  SettingStateOrProvinceOrCountyName            no
+  SettingStreetName                             no
+  SettingStreetName                             no
+  SettingStreetNumberOrBuildingName             no
+  SettingStreetNumberOrBuildingName             no
+  SettingTownName                               no
+  SettingTownName                               no
+  ShimName                                      no
+  ShootingCountryCode                           no
+  ShootingRegionCode                            no
+  ShootingRegionName                            no
+  Shot                                          MXF
+  ShotComment                                   no
+  ShotComment                                   no
+  ShotCommentKind                               no
+  ShotCommentKind                               no
+  ShotCueWordsSet?                              no
+  ShotDescription                               no
+  ShotDescription                               no
+  ShotDuration                                  no
+  ShotList                                      no
+  ShotLocationSets?                             no
+  ShotParticipantRoleSets?                      no
+  ShotPersonSets?                               no
+  ShotStartPosition                             no
+  ShotTrackIDs                                  no
+  SideNumber                                    no
+  Signal-to-NoiseRatio                          no
+  SignalFormCode                                no
+  SignalStandard                                no
+  SignalStandard                                no
+  SignatureTuneFlag                             no
+  SimpleFlaggingCount                           no
+  SingleSequenceFlag                            no
+  Size                                          no
+  SlantRange                                    no
+  SlateInformation                              no
+  SlateTitle                                    no
+  SliceCount                                    no
+  SliceNumber                                   no
+  SliceOffsetList?                              no
+  Software-OnlySupportFlag                      no
+  SourceClip?                                   no
+  SourceContainerFormat?                        no
+  SourceImageCenterXCoordinate                  no
+  SourceImageCenterYCoordinate                  no
+  SourceIndex?                                  no
+  SourceKey?                                    no
+  SourceLength                                  no
+  SourceOrganization                            no
+  SourceOrganization                            no
+  SourcePackage                                 MXF
+  SourcePackageID?                              no
+  SourceSpecies?                                no
+  SourceTrackID                                 no
+  SourceTrackIDs                                no
+  SourceValue?                                  no
+  SpeedChangeEffectFlag                         no
+  SplicingMetadata?                             no
+  StartTimeRelativeToReference                  no
+  StartTimeRelativeToReference                  no
+  StartTimecode                                 no
+  StartTimecodeRelativeToReference?             no
+  StateOrProvinceOrCountyName                   no
+  StateOrProvinceOrCountyName                   no
+  StaticTrack                                   MXF
+  StillFrame?                                   no
+  StorageDeviceKind                             no
+  StorageKind                                   no
+  StorageKind                                   no
+  StorageKindCode                               no
+  StorageMediaID                                no
+  StorageMediaKind                              no
+  StoredANCLineNumber                           no
+  StoredF2Offset                                no
+  StoredVBILineNumber                           no
+  StratumKind                                   no
+  StreamData?                                   no
+  StreamElementType?                            no
+  StreamID                                      no
+  StreamOffset                                  no
+  StreamPositionIndicator                       no
+  StreamPositionIndicator                       no
+  StreamPositionIndicator                       no
+  StreamPositionIndicator                       no
+  StreetName                                    no
+  StreetName                                    no
+  StreetNumber                                  no
+  StreetNumber                                  no
+  StringElementType?                            no
   StructuralComponent                           MXF
-  SequenceSet                                   MXF
-  SourceClip?                                   N
+  Sub-descriptors?                              no
+  SubDescriptor?                                no
+  SubDescriptors?                               no
+  SubjectAbsoluteHeading                        no
+  SubjectAbsoluteSpeed                          no
+  SubjectDistance                               no
+  SubjectName                                   no
+  SubjectName                                   no
+  SubjectRelativeHeading                        no
+  SubjectRelativePositionalAccuracy             no
+  SubjectRelativeSpeed                          no
+  SubtitleDatafileFlag                          no
+  SubtitlesPresent                              no
+  SupplementaryName                             no
+  SupplementaryName                             no
+  SupplementaryOrganizationName                 no
+  SupplementaryOrganizationName                 no
+  SupplierAccountName                           no
+  SupplierAccountName                           no
+  SupplierAccountNumber                         no
+  SupplierIdentificationKind                    no
+  SupplierIdentificationValue                   no
+  SupplyContractNumber                          no
+  SupplyingDepartmentName                       no
+  SupportOrAdministrationStatus                 no
+  SupportOrAdministrationStatus                 no
+  SupportOrganizationRole                       no
+  SupportOrganizationRole                       no
+  SystemNameOrNumber                            no
+  TIFFSummary?                                  no
+  TaggedValueDefinitions?                       no
+  TaggedValueParentProperties?                  no
+  TakeNumber                                    no
+  TapeBatchNumber                               no
+  TapeBatchNumber                               no
+  TapeCapacity                                  no
+  TapeFormat?                                   no
+  TapeFormulation                               no
+  TapeFormulation                               no
+  TapeManufacturer                              no
+  TapeManufacturer                              no
+  TapePartitionCapacity                         no
+  TapeShellKind                                 no
+  TapeShellKind                                 no
+  TapeStock                                     no
+  TapeStock                                     no
+  TargetAudience                                no
+  TargetAudience                                no
+  TargetClassOfStrongReference?                 no
+  TargetClassOfWeakReference?                   no
+  TargetSet?                                    no
+  TargetWidth                                   no
+  TechnicalValue                                no
+  TelephoneNumber                               no
+  TelephoneNumber                               no
+  TeletextSubtitlesAvailable                    no
+  TeletextSubtitlesFlag                         no
+  TemporalOffset                                no
+  TerminatingFillerData                         no
+  TextLocator                                   MXF
+  TextlessBlackDuration                         no
+  TextlessMaterial                              no
+  TextualDescriptionKind                        no
+  TextualDescriptionKind                        no
+  Theme                                         no
+  Theme                                         no
+  ThemeMusicFlag                                no
+  ThesaurusName                                 no
+  ThesaurusName                                 no
+  ThirdGivenName                                no
+  ThirdGivenName                                no
+  TimePeriodName                                no
+  TimePeriodName                                no
+  TimeSystemOffset                              no
+  TimeUnitKind                                  no
+  TimebaseReferenceTrackID                      no
+  TimecodeArray?                                no
   TimecodeComponent                             MXF
-  ContentStorageSet                             MXF
-  EssenceContainerDataSet                       MXF
-  FileDescriptor                                MXF
-  GenericPictureEssenceDescriptor               MXF
-  CDCIEssenceDescriptor                         MXF
-  RGBAEssenceDescriptor                         MXF
-  Preface                                       MXF
-  Identification                                MXF
-  NetworkLocator                                MXF
-  TextLocator                                   MXF
-  GenericPackage                                MXF
-  MaterialPackage                               MXF
-  SourcePackage                                 MXF
-  GenericTrack                                  MXF
-  EventTrack                                    MXF
-  StaticTrack                                   MXF
+  TimecodeCreationDateTime?                     no
+  TimecodeEndDateTime?                          no
+  TimecodeEventEndDateTime?                     no
+  TimecodeEventStartDateTime?                   no
+  TimecodeKind                                  no
+  TimecodeLastModifyDate?                       no
+  TimecodeModifyDate?                           no
+  TimecodeSourceKind                            no
+  TimecodeStartDateTime?                        no
+  TimecodeStreamData?                           no
+  TimecodeTimebase                              no
+  TimecodeTimebase                              no
+  TimecodeUserBitsFlag                          no
+  TimepointValue?                               no
+  TimingBiasCorrection                          no
+  TimingBiasCorrectionDescription               no
+  TitleKind                                     no
+  TitleKind                                     no
+  Titles                                        MXF
+  TitlesSets?                                   no
+  ToleranceInterpolationMethod?                 no
+  ToleranceMode?                                no
+  ToleranceWindow?                              no
+  ToolkitVersion                                no
+  TotalCurrencyAmount                           no
+  TotalEpisodeCount                             no
+  TotalIncome                                   no
+  TotalLinesperFrame                            no
+  TotalNumberInSequence                         no
+  TotalPayment                                  no
+  TotalSamplesperLine                           no
   Track                                         MXF
-  DMSegment                                     MXF
-  GenericSoundEssenceDescriptor                 MXF
-  GenericDataEssenceDescriptor                  MXF
-  MultipleDescriptor                            MXF
-  DMSourceClip                                  MXF
-  AES3PCMDescriptor                             MXF
+  TrackID                                       no
+  TrackName                                     no
+  TrackName                                     no
+  TrackNumber                                   no
+  TrackNumberBatch                              no
+  Tracks?                                       no
+  TrafficID                                     no
+  TrailingLines                                 no
+  TranscriptReference                           no
+  TranscriptReference                           no
+  TransferFilmFrameRate                         no
+  TransitionEffect?                             no
+  TransmissionID                                no
+  TransportStreamID                             no
+  TripletSequenceNumber                         no
+  TypeDefinitionElementValueList                no
+  TypeDefinitionExtendibleElementValues?        no
+  TypeDefinitions?                              no
+  UCSEncoding                                   no
+  UPID?                                         no
+  UPN?                                          no
+  URL                                           no
+  URL                                           no
+  URL                                           no
+  URL                                           no
+  URN                                           no
+  UTCEndDateTime                                no
+  UTCEventEndDateTime                           no
+  UTCEventEndDateTime                           no
+  UTCEventStartDateTime                         no
+  UTCEventStartDateTime                         no
+  UTCInstantDateTime                            no
+  UTCInstantDateTime                            no
+  UTCLastModifyDate                             no
+  UTCLastModifyDate                             no
+  UTCStartDateTime                              no
+  UTCStartDateTime                              no
+  UTCUserDateTime                               no
+  UniformDataFlag                               no
+  UnknownBWFChunks?                             no
+  UpstreamAudioCompressionAlgorithm             no
+  UseDefaultValue                               no
+  UserDataMode?                                 no
+  UserName                                      no
+  UserName                                      no
+  UserPosition                                  no
+  V10IndexTableSegment?                         no
+  VBEEndOffset                                  no
+  VBIDataDescriptor                             MXF
+  VBILineCount                                  no
+  VBIPayloadByteArray                           no
+  VBIPayloadSampleCoding                        no
+  VBIPayloadSampleCount                         no
+  VBIWrappingType                               no
+  VC-1AverageBitrate                            no
+  VC-1BPictureCount                             no
+  VC-1CodedContentType                          no
+  VC-1IdenticalGOP                              no
+  VC-1InitializationMetadata?                   no
+  VC-1Level                                     no
+  VC-1MaximumBitrate                            no
+  VC-1MaximumGOP                                no
+  VC-1Profile                                   no
+  VC-1SingleSequence                            no
+  Value?                                        no
+  VariableArrayElementType?                     no
+  VersionNumber                                 no
+  VersionNumberString                           no
+  VersionNumberString                           no
+  VersionTitle                                  no
+  VersionTitle                                  no
+  VerticalActionSafePercentage                  no
+  VerticalDatum                                 no
+  VerticalGraphicsSafePercentage                no
+  VerticalSub-sampling                          no
+  VideoAndFilmFrameRelationship                 no
+  VideoAverageBitrate                           no
+  VideoClipDuration                             no
+  VideoCodingSchemeID?                          no
+  VideoColorKind                                no
+  VideoCompressionAlgorithm                     no
+  VideoDeviceKind                               no
+  VideoDeviceParameterName                      no
+  VideoDeviceParameterSetting                   no
+  VideoFixedBitrate                             no
+  VideoIndexArray?                              no
+  VideoLineMap                                  no
+  VideoNoiseReductionAlgorithm                  no
+  VideoOrImageCompressionAlgorithm              no
+  VideoPayloadIdentifier                        no
+  VideoPayloadIdentifier2002                    no
+  VideoTestParameter                            no
+  VideoTestResult                               no
+  VideoTestResult                               no
+  VideoWatermarkKind                            no
+  ViewportAspectRatio                           no
+  ViewportHeight                                no
+  ViewportImageCenterCCoordinate                no
+  ViewportImageCenterYCoordinate                no
+  ViewportWidth                                 no
+  VoiceTalentName                               no
+  WAVESummary?                                  no
   WaveAudioDescriptor                           MXF
-  MPEG2VideoDescriptor                          MXF
-  JPEG2000PictureSubDescriptor                  MXF
-  VBIDataDescriptor                             MXF
-  V10IndexTableSegment?                         N
-  IndexTableSegment?                            N
-  DMSet                                         MXF
-  DMFramework                                   MXF
-  ProductionFramework                           MXF
-  ClipFramework                                 MXF
-  SceneFramework                                MXF
-  Titles                                        MXF
-  Identification                                MXF
-  GroupRelationship                             MXF
-  Branding                                      MXF
-  Event                                         MXF
-  Publication                                   MXF
-  Award                                         MXF
-  CaptionDescription                            MXF
-  Annotation                                    MXF
-  SettingPeriod                                 MXF
-  Scripting                                     MXF
-  Classification                                MXF
-  Shot                                          MXF
-  KeyPoint                                      MXF
-  CueWords                                      MXF
-  Participant                                   MXF
-  ContactsList                                  MXF
-  Person                                        MXF
-  Organisation                                  MXF
-  Location                                      MXF
-  Address                                       MXF
-  Communications                                MXF
-  Contract                                      MXF
-  Rights                                        MXF
-  PictureFormat                                 MXF
-  DeviceParameters                              MXF
-  NameValue                                     MXF
-  Processing                                    MXF
-  Projects                                      MXF
-  CryptographicFramework                        MXF
-  CryptographicContext                          MXF
-  DefaultObject?                                N
-  CipherAlgorithmAES128CBC?                     N
-  HMACAlgorithmSHA1128?                         N
-  EncryptedContainerLabel?                      N
-  CryptographicFrameworkLabel?                  N
+  Weighting                                     no
+  WhiteReferenceLevel                           no
+  Work-in-ProgressFlag                          no
+  WorkingTitle                                  no
+  WorkingTitle                                  no
+  XMLDocumentText?                              no
+  XMLDocumentText                               no
+  XMLDocumentText                               no
+  XMLDocumentText?                              no
+  XOsiz                                         no
+  XTOsiz                                        no
+  XTsiz                                         no
+  Xsiz                                          no
+  YOsiz                                         no
+  YTOsiz                                        no
+  YTsiz                                         no
+  Ysiz                                          no
 
 =head3 MXF Header Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MXFVersion                           N
-     24    FooterPosition                       N
-     32    HeaderSize                           N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    MXFVersion                           no
+     24    FooterPosition                       no
+     32    HeaderSize                           no
 
 =head2 DV Tags
@@ -15854,17 +29366,17 @@
   Tag Name                                      Writable
   --------                                      --------
-  AspectRatio                                   N
-  AudioBitsPerSample                            N
-  AudioChannels                                 N
-  AudioSampleRate                               N
-  Colorimetry                                   N
-  DateTimeOriginal                              N
-  Duration                                      N
-  FrameRate                                     N
-  ImageHeight                                   N
-  ImageWidth                                    N
-  TotalBitrate                                  N
-  VideoFormat                                   N
-  VideoScanType                                 N
+  AspectRatio                                   no
+  AudioBitsPerSample                            no
+  AudioChannels                                 no
+  AudioSampleRate                               no
+  Colorimetry                                   no
+  DateTimeOriginal                              no
+  Duration                                      no
+  FrameRate                                     no
+  ImageHeight                                   no
+  ImageWidth                                    no
+  TotalBitrate                                  no
+  VideoFormat                                   no
+  VideoScanType                                 no
 
 =head2 Flash Tags
@@ -15875,12 +29387,12 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Compressed'         Compressed               N
-  'Duration'           Duration                 N
-  'FlashVersion'       FlashVersion             N
-  'FrameCount'         FrameCount               N
-  'FrameRate'          FrameRate                N
-  'ImageHeight'        ImageHeight              N
-  'ImageWidth'         ImageWidth               N
-  0x0045               FileAttributes           N
+  'Compressed'         Compressed               no
+  'Duration'           Duration                 no
+  'FlashVersion'       FlashVersion             no
+  'FrameCount'         FrameCount               no
+  'FrameRate'          FrameRate                no
+  'ImageHeight'        ImageHeight              no
+  'ImageWidth'         ImageWidth               no
+  0x0045               FlashAttributes          no
   0x004d               XMP                      XMP
 
@@ -15902,8 +29414,8 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'Bit0-3' AudioEncoding                        N
-  'Bit4-5' AudioSampleRate                      N
-  'Bit6'   AudioBitsPerSample                   N
-  'Bit7'   AudioChannels                        N
+  'Bit0-3' AudioEncoding                        no
+  'Bit4-5' AudioSampleRate                      no
+  'Bit6'   AudioBitsPerSample                   no
+  'Bit7'   AudioChannels                        no
 
 =head3 Flash Video Tags
@@ -15913,5 +29425,5 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'Bit4-7' VideoEncoding                        N
+  'Bit4-7' VideoEncoding                        no
 
 =head3 Flash Meta Tags
@@ -15922,45 +29434,45 @@
   Tag ID                   Tag Name             Writable
   ------                   --------             --------
-  'audiocodecid'           AudioCodecID         N
-  'audiodatarate'          AudioBitrate         N
-  'audiodelay'             AudioDelay           N
-  'audiosamplerate'        AudioSampleRate      N
-  'audiosamplesize'        AudioSampleSize      N
-  'audiosize'              AudioSize            N
-  'bytelength'             ByteLength           N
-  'canSeekToEnd'           CanSeekToEnd         N
-  'canseekontime'          CanSeekOnTime        N
-  'createdby'              CreatedBy            N
-  'creationdate'           CreateDate           N
+  'audiocodecid'           AudioCodecID         no
+  'audiodatarate'          AudioBitrate         no
+  'audiodelay'             AudioDelay           no
+  'audiosamplerate'        AudioSampleRate      no
+  'audiosamplesize'        AudioSampleSize      no
+  'audiosize'              AudioSize            no
+  'bytelength'             ByteLength           no
+  'canSeekToEnd'           CanSeekToEnd         no
+  'canseekontime'          CanSeekOnTime        no
+  'createdby'              CreatedBy            no
+  'creationdate'           CreateDate           no
   'cuePoints'              CuePoint             Flash CuePoint
-  'datasize'               DataSize             N
-  'duration'               Duration             N
-  'filesize'               FileSizeBytes        N
-  'framerate'              FrameRate            N
-  'hasAudio'               HasAudio             N
-  'hasCuePoints'           HasCuePoints         N
-  'hasKeyframes'           HasKeyFrames         N
-  'hasMetadata'            HasMetadata          N
-  'hasVideo'               HasVideo             N
-  'height'                 ImageHeight          N
-  'httphostheader'         HTTPHostHeader       N
-  'keyframesFilepositions' KeyFramePositions    N
-  'keyframesTimes'         KeyFramesTimes       N
-  'lastkeyframetimestamp'  LastKeyFrameTime     N
-  'lasttimestamp'          LastTimeStamp        N
+  'datasize'               DataSize             no
+  'duration'               Duration             no
+  'filesize'               FileSizeBytes        no
+  'framerate'              FrameRate            no
+  'hasAudio'               HasAudio             no
+  'hasCuePoints'           HasCuePoints         no
+  'hasKeyframes'           HasKeyFrames         no
+  'hasMetadata'            HasMetadata          no
+  'hasVideo'               HasVideo             no
+  'height'                 ImageHeight          no
+  'httphostheader'         HTTPHostHeader       no
+  'keyframesFilepositions' KeyFramePositions    no
+  'keyframesTimes'         KeyFramesTimes       no
+  'lastkeyframetimestamp'  LastKeyFrameTime     no
+  'lasttimestamp'          LastTimeStamp        no
   'liveXML'                XMP                  XMP
-  'metadatacreator'        MetadataCreator      N
-  'metadatadate'           MetadataDate         N
-  'pmsg'                   Message              N
-  'purl'                   URL                  N
-  'sourcedata'             SourceData           N
-  'starttime'              StartTime            N
-  'stereo'                 Stereo               N
-  'totaldatarate'          TotalDataRate        N
-  'totalduration'          TotalDuration        N
-  'videocodecid'           VideoCodecID         N
-  'videodatarate'          VideoBitrate         N
-  'videosize'              VideoSize            N
-  'width'                  ImageWidth           N
+  'metadatacreator'        MetadataCreator      no
+  'metadatadate'           MetadataDate         no
+  'pmsg'                   Message              no
+  'purl'                   URL                  no
+  'sourcedata'             SourceData           no
+  'starttime'              StartTime            no
+  'stereo'                 Stereo               no
+  'totaldatarate'          TotalDataRate        no
+  'totalduration'          TotalDuration        no
+  'videocodecid'           VideoCodecID         no
+  'videodatarate'          VideoBitrate         no
+  'videosize'              VideoSize            no
+  'width'                  ImageWidth           no
 
 =head3 Flash CuePoint Tags
@@ -15971,8 +29483,8 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'name'               Name                     N
+  'name'               Name                     no
   'parameters'         Parameter                Flash Parameter
-  'time'               Time                     N
-  'type'               Type                     N
+  'time'               Time                     no
+  'type'               Type                     no
 
 =head3 Flash Parameter Tags
@@ -16007,12 +29519,12 @@
   Sequence Tag Name                             Writable
   -------- --------                             --------
-      0    TitleLen?                            N
-      1    Title                                N
-      2    AuthorLen?                           N
-      3    Author                               N
-      4    CopyrightLen?                        N
-      5    Copyright                            N
-      6    CommentLen?                          N
-      7    Comment                              N
+      0    TitleLen?                            no
+      1    Title                                no
+      2    AuthorLen?                           no
+      3    Author                               no
+      4    CopyrightLen?                        no
+      5    Copyright                            no
+      6    CommentLen?                          no
+      7    Comment                              no
 
 =head3 Real MediaProps Tags
@@ -16020,25 +29532,25 @@
   Sequence Tag Name                             Writable
   -------- --------                             --------
-      0    StreamNumber                         N
-      1    StreamMaxBitrate                     N
-      2    StreamAvgBitrate                     N
-      3    StreamMaxPacketSize                  N
-      4    StreamAvgPacketSize                  N
-      5    StreamStartTime                      N
-      6    StreamPreroll                        N
-      7    StreamDuration                       N
-      8    StreamNameLen?                       N
-      9    StreamName                           N
-     10    StreamMimeLen?                       N
-     11    StreamMimeType                       N
-     12    FileInfoLen?                         N
-     13    FileInfoLen2?                        N
-     14    FileInfoVersion                      N
-     15    PhysicalStreams?                     N
-     16    PhysicalStreamNumbers?               N
-     17    DataOffsets?                         N
-     18    NumRules?                            N
-     19    PhysicalStreamNumberMap?             N
-     20    NumProperties?                       N
+      0    StreamNumber                         no
+      1    StreamMaxBitrate                     no
+      2    StreamAvgBitrate                     no
+      3    StreamMaxPacketSize                  no
+      4    StreamAvgPacketSize                  no
+      5    StreamStartTime                      no
+      6    StreamPreroll                        no
+      7    StreamDuration                       no
+      8    StreamNameLen?                       no
+      9    StreamName                           no
+     10    StreamMimeLen?                       no
+     11    StreamMimeType                       no
+     12    FileInfoLen?                         no
+     13    FileInfoLen2?                        no
+     14    FileInfoVersion                      no
+     15    PhysicalStreams?                     no
+     16    PhysicalStreamNumbers?               no
+     17    DataOffsets?                         no
+     18    NumRules?                            no
+     19    PhysicalStreamNumberMap?             no
+     20    NumProperties?                       no
      21    FileInfoProperties                   Real FileInfo
 
@@ -16050,18 +29562,18 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Audiences'          Audiences                N
-  'Audio Format'       AudioFormat              N
-  'Content Rating'     ContentRating            N
-  'Creation Date'      CreateDate               N
-  'Description'        Description              N
-  'File ID'            FileID                   N
-  'Generated By'       Software                 N
-  'Indexable'          Indexable                N
-  'Keywords'           Keywords                 N
-  'Modification Date'  ModifyDate               N
-  'Target Audiences'   TargetAudiences          N
-  'Video Quality'      VideoQuality             N
-  'audioMode'          AudioMode                N
-  'videoMode'          VideoMode                N
+  'Audiences'          Audiences                no
+  'Audio Format'       AudioFormat              no
+  'Content Rating'     ContentRating            no
+  'Creation Date'      CreateDate               no
+  'Description'        Description              no
+  'File ID'            FileID                   no
+  'Generated By'       Software                 no
+  'Indexable'          Indexable                no
+  'Keywords'           Keywords                 no
+  'Modification Date'  ModifyDate               no
+  'Target Audiences'   TargetAudiences          no
+  'Video Quality'      VideoQuality             no
+  'audioMode'          AudioMode                no
+  'videoMode'          VideoMode                no
 
 =head3 Real Properties Tags
@@ -16069,15 +29581,15 @@
   Sequence Tag Name                             Writable
   -------- --------                             --------
-      0    MaxBitrate                           N
-      1    AvgBitrate                           N
-      2    MaxPacketSize                        N
-      3    AvgPacketSize                        N
-      4    NumPackets                           N
-      5    Duration                             N
-      6    Preroll                              N
-      7    IndexOffset?                         N
-      8    DataOffset?                          N
-      9    NumStreams                           N
-     10    Flags                                N
+      0    MaxBitrate                           no
+      1    AvgBitrate                           no
+      2    MaxPacketSize                        no
+      3    AvgPacketSize                        no
+      4    NumPackets                           no
+      5    Duration                             no
+      6    Preroll                              no
+      7    IndexOffset?                         no
+      8    DataOffset?                          no
+      9    NumStreams                           no
+     10    Flags                                no
 
 =head3 Real Metadata Tags
@@ -16093,8 +29605,8 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Album/Name'         AlbumName                N
-  'Track/Category'     TrackCategory            N
-  'Track/Comments'     TrackComments            N
-  'Track/Lyrics'       TrackLyrics              N
+  'Album/Name'         AlbumName                no
+  'Track/Category'     TrackCategory            no
+  'Track/Comments'     TrackComments            no
+  'Track/Lyrics'       TrackLyrics              no
 
 =head3 Real Audio Tags
@@ -16113,16 +29625,16 @@
   Sequence Tag Name                             Writable
   -------- --------                             --------
-      0    Channels                             N
-      1    Unknown?                             N
-      2    BytesPerMinute                       N
-      3    AudioBytes                           N
-      4    TitleLen?                            N
-      5    Title                                N
-      6    ArtistLen?                           N
-      7    Artist                               N
-      8    CopyrightLen?                        N
-      9    Copyright                            N
-     10    CommentLen?                          N
-     11    Comment                              N
+      0    Channels                             no
+      1    Unknown?                             no
+      2    BytesPerMinute                       no
+      3    AudioBytes                           no
+      4    TitleLen?                            no
+      5    Title                                no
+      6    ArtistLen?                           no
+      7    Artist                               no
+      8    CopyrightLen?                        no
+      9    Copyright                            no
+     10    CommentLen?                          no
+     11    Comment                              no
 
 =head3 Real AudioV4 Tags
@@ -16130,35 +29642,35 @@
   Sequence Tag Name                             Writable
   -------- --------                             --------
-      0    FourCC1?                             N
-      1    AudioFileSize?                       N
-      2    Version2?                            N
-      3    HeaderSize?                          N
-      4    CodecFlavorID?                       N
-      5    CodedFrameSize?                      N
-      6    AudioBytes                           N
-      7    BytesPerMinute                       N
-      8    Unknown?                             N
-      9    SubPacketH?                          N
-     10    AudioFrameSize                       N
-     11    SubPacketSize?                       N
-     12    Unknown?                             N
-     13    SampleRate                           N
-     14    Unknown?                             N
-     15    BitsPerSample                        N
-     16    Channels                             N
-     17    FourCC2Len?                          N
-     18    FourCC2?                             N
-     19    FourCC3Len?                          N
-     20    FourCC3?                             N
-     21    Unknown?                             N
-     22    Unknown?                             N
-     23    TitleLen?                            N
-     24    Title                                N
-     25    ArtistLen?                           N
-     26    Artist                               N
-     27    CopyrightLen?                        N
-     28    Copyright                            N
-     29    CommentLen?                          N
-     30    Comment                              N
+      0    FourCC1?                             no
+      1    AudioFileSize?                       no
+      2    Version2?                            no
+      3    HeaderSize?                          no
+      4    CodecFlavorID?                       no
+      5    CodedFrameSize?                      no
+      6    AudioBytes                           no
+      7    BytesPerMinute                       no
+      8    Unknown?                             no
+      9    SubPacketH?                          no
+     10    AudioFrameSize                       no
+     11    SubPacketSize?                       no
+     12    Unknown?                             no
+     13    SampleRate                           no
+     14    Unknown?                             no
+     15    BitsPerSample                        no
+     16    Channels                             no
+     17    FourCC2Len?                          no
+     18    FourCC2?                             no
+     19    FourCC3Len?                          no
+     20    FourCC3?                             no
+     21    Unknown?                             no
+     22    Unknown?                             no
+     23    TitleLen?                            no
+     24    Title                                no
+     25    ArtistLen?                           no
+     26    Artist                               no
+     27    CopyrightLen?                        no
+     28    Copyright                            no
+     29    CommentLen?                          no
+     30    Comment                              no
 
 =head3 Real AudioV5 Tags
@@ -16166,22 +29678,22 @@
   Sequence Tag Name                             Writable
   -------- --------                             --------
-      0    FourCC1?                             N
-      1    AudioFileSize?                       N
-      2    Version2?                            N
-      3    HeaderSize?                          N
-      4    CodecFlavorID?                       N
-      5    CodedFrameSize?                      N
-      6    AudioBytes                           N
-      7    BytesPerMinute                       N
-      8    Unknown?                             N
-      9    SubPacketH?                          N
-     10    FrameSize?                           N
-     11    SubPacketSize?                       N
-     12    SampleRate                           N
-     13    SampleRate2?                         N
-     14    BitsPerSample                        N
-     15    Channels                             N
-     16    Genr?                                N
-     17    FourCC3?                             N
+      0    FourCC1?                             no
+      1    AudioFileSize?                       no
+      2    Version2?                            no
+      3    HeaderSize?                          no
+      4    CodecFlavorID?                       no
+      5    CodedFrameSize?                      no
+      6    AudioBytes                           no
+      7    BytesPerMinute                       no
+      8    Unknown?                             no
+      9    SubPacketH?                          no
+     10    FrameSize?                           no
+     11    SubPacketSize?                       no
+     12    SampleRate                           no
+     13    SampleRate2?                         no
+     14    BitsPerSample                        no
+     15    Channels                             no
+     16    Genr?                                no
+     17    FourCC3?                             no
 
 =head3 Real Metafile Tags
@@ -16192,24 +29704,110 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'txt'    Text                                 N
-  'url'    URL                                  N
+  'txt'    Text                                 no
+  'url'    URL                                  no
+
+=head2 Red Tags
+
+Tags extracted from Redcode R3D video files.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'RED1'   Red1Header                           Red RED1
+  'RED2'   Red2Header                           Red RED2
+  0x1000   StartEdgeCode                        no
+  0x1001   StartTimecode                        no
+  0x1002   OtherDate1                           no
+  0x1003   OtherDate2                           no
+  0x1004   OtherDate3                           no
+  0x1005   DateTimeOriginal                     no
+  0x1006   SerialNumber                         no
+  0x1019   CameraType                           no
+  0x101a   ReelNumber                           no
+  0x101b   Take                                 no
+  0x1023   DateCreated                          no
+  0x1024   TimeCreated                          no
+  0x1025   FirmwareVersion                      no
+  0x1029   ReelTimecode                         no
+  0x102a   StorageType                          no
+  0x1030   StorageFormatDate                    no
+  0x1031   StorageFormatTime                    no
+  0x1032   StorageSerialNumber                  no
+  0x1033   StorageModel                         no
+  0x1036   AspectRatio                          no
+  0x1042   Revision                             no
+  0x1056   OriginalFileName                     no
+  0x106e   LensMake                             no
+  0x106f   LensNumber                           no
+  0x1070   LensModel                            no
+  0x1071   Model                                no
+  0x107c   CameraOperator                       no
+  0x1086   VideoFormat                          no
+  0x1096   Filter                               no
+  0x10a0   Brain                                no
+  0x10a1   Sensor                               no
+  0x200d   ColorTemperature                     no
+  0x204b   RGBCurves                            no
+  0x2066   OriginalFrameRate                    no
+  0x4037   CropArea                             no
+  0x403b   ISO                                  no
+  0x406a   FNumber                              no
+  0x406b   FocalLength                          no
+  0x606c   FocusDistance                        no
+
+=head3 Red RED1 Tags
+
+Redcode version 1 header.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      7    RedcodeVersion                       no
+     54    ImageWidth                           no
+     58    ImageHeight                          no
+     62    FrameRate                            no
+     67    OriginalFileName                     no
+
+=head3 Red RED2 Tags
+
+Redcode version 2 header.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      7    RedcodeVersion                       no
+     76    ImageWidth                           no
+     80    ImageHeight                          no
+     86    FrameRate                            no
 
 =head2 RIFF Tags
 
-The RIFF container format is used various types of fines including WAV, AVI
-and WEBP.  According to the EXIF specification, Meta information is embedded
-in two types of RIFF C<LIST> chunks: C<INFO> and C<exif>, and information
-about the audio content is stored in the C<fmt > chunk.  As well as this
-information, some video information and proprietary manufacturer-specific
-information is also extracted.
+The RIFF container format is used various types of fines including AVI, WAV,
+WEBP, LA, OFR, PAC and WV.  According to the EXIF specification, Meta
+information is embedded in two types of RIFF C<LIST> chunks: C<INFO> and
+C<exif>, and information about the audio content is stored in the C<fmt >
+chunk.  As well as this information, some video information and proprietary
+manufacturer-specific information is also extracted.
+
+Large AVI videos may be a concatenation of two or more RIFF chunks.  For
+these files, information is extracted from subsequent RIFF chunks as
+sub-documents, but the Duration is calculated for the full video.
 
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
+  'ALPH'               ALPH                     RIFF ALPH
+  'ANIM'               ANIM                     RIFF ANIM
+  'ANMF'               ANMF                     RIFF ANMF
+  'CSET'               CharacterSet             RIFF CSET
+  'EXIF'               EXIF                     EXIF
+                       UnknownEXIF              no
+  'ICCP'               ICC_Profile              ICC_Profile
+  'IDIT'               DateTimeOriginal         no
   'JUNK'               OlympusJunk              Olympus AVI
                        CasioJunk                EXIF
                        RicohJunk                Ricoh AVI
                        PentaxJunk               Pentax Junk
-                       TextJunk                 N
-  'JUNQ'               OldXMP                   N
+                       PentaxJunk2              Pentax Junk2
+                       LucasJunk                QuickTime Stream
+                       TextJunk                 no
+  'JUNQ'               OldXMP                   no
+  'LIST_INF0'          Info                     RIFF Info
   'LIST_INFO'          Info                     RIFF Info
   'LIST_Tdat'          Tdat                     RIFF Tdat
@@ -16218,12 +29816,67 @@
   'LIST_hydt'          PentaxData               Pentax AVI
   'LIST_ncdt'          NikonData                Nikon AVI
+  'LIST_pntx'          PentaxData2              Pentax AVI
+  'SGLT'               BikeBroAccel             QuickTime Stream
+  'SLLT'               BikeBroGPS               QuickTime Stream
+  'VP8 '               VP8Bitstream             RIFF VP8
+  'VP8L'               VP8L                     RIFF VP8L
+  '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
+  'tx_USER'            UserText                 RIFF UserText
+  'tx_Unknown'         Text                     no
+
+=head3 RIFF ALPH Tags
+
+WebP alpha chunk.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    AlphaPreprocessing                   no
+    0.1    AlphaFiltering                       no
+    0.2    AlphaCompression                     no
+
+=head3 RIFF ANIM Tags
+
+WebP animation chunk.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    BackgroundColor                      no
+      4    AnimationLoopCount                   no
+
+=head3 RIFF ANMF Tags
+
+WebP animation frame chunk.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     12    Duration                             no
+
+=head3 RIFF CSET Tags
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    CodePage                             no
+      1    CountryCode                          no
+      2    LanguageCode                         no
+      3    Dialect                              no
 
 =head3 RIFF Info Tags
 
-RIFF INFO tags found in WAV audio and AVI video files.  Tags which are part
+RIFF INFO tags found in AVI video and WAV audio files.  Tags which are part
 of the EXIF 2.3 specification have an underlined Tag Name in the HTML
 version of this documentation.  Other tags are found in AVI files generated
@@ -16232,88 +29885,90 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'AGES'   Rated                                N
-  'CMNT'   Comment                              N
-  'CODE'   EncodedBy                            N
-  'COMM'   Comments                             N
-  'DIRC'   Directory                            N
-  'DISP'   SoundSchemeTitle                     N
-  'DTIM'   DateTimeOriginal                     N
-  'GENR'   Genre                                N
-  'IARL'   ArchivalLocation                     N
-  'IART'   Artist                               N
-  'IAS1'   FirstLanguage                        N
-  'IAS2'   SecondLanguage                       N
-  'IAS3'   ThirdLanguage                        N
-  'IAS4'   FourthLanguage                       N
-  'IAS5'   FifthLanguage                        N
-  'IAS6'   SixthLanguage                        N
-  'IAS7'   SeventhLanguage                      N
-  'IAS8'   EighthLanguage                       N
-  'IAS9'   NinthLanguage                        N
-  'IBSU'   BaseURL                              N
-  'ICAS'   DefaultAudioStream                   N
-  'ICDS'   CostumeDesigner                      N
-  'ICMS'   Commissioned                         N
-  'ICMT'   Comment                              N
-  'ICNM'   Cinematographer                      N
-  'ICNT'   Country                              N
-  'ICOP'   Copyright                            N
-  'ICRD'   DateCreated                          N
-  'ICRP'   Cropped                              N
-  'IDIM'   Dimensions                           N
-  'IDPI'   DotsPerInch                          N
-  'IDST'   DistributedBy                        N
-  'IEDT'   EditedBy                             N
-  'IENC'   EncodedBy                            N
-  'IENG'   Engineer                             N
-  'IGNR'   Genre                                N
-  'IKEY'   Keywords                             N
-  'ILGT'   Lightness                            N
-  'ILGU'   LogoURL                              N
-  'ILIU'   LogoIconURL                          N
-  'ILNG'   Language                             N
-  'IMBI'   MoreInfoBannerImage                  N
-  'IMBU'   MoreInfoBannerURL                    N
-  'IMED'   Medium                               N
-  'IMIT'   MoreInfoText                         N
-  'IMIU'   MoreInfoURL                          N
-  'IMUS'   MusicBy                              N
-  'INAM'   Title                                N
-  'IPDS'   ProductionDesigner                   N
-  'IPLT'   NumColors                            N
-  'IPRD'   Product                              N
-  'IPRO'   ProducedBy                           N
-  'IRIP'   RippedBy                             N
-  'IRTD'   Rating                               N
-  'ISBJ'   Subject                              N
-  'ISFT'   Software                             N
-  'ISGN'   SecondaryGenre                       N
-  'ISHP'   Sharpness                            N
-  'ISRC'   Source                               N
-  'ISRF'   SourceForm                           N
-  'ISTD'   ProductionStudio                     N
-  'ISTR'   Starring                             N
-  'ITCH'   Technician                           N
-  'IWMU'   WatermarkURL                         N
-  'IWRI'   WrittenBy                            N
-  'LANG'   Language                             N
-  'LOCA'   Location                             N
-  'PRT1'   Part                                 N
-  'PRT2'   NumberOfParts                        N
-  'RATE'   Rate                                 N
-  'STAR'   Starring                             N
-  'STAT'   Statistics                           N
-  'TAPE'   TapeName                             N
-  'TCDO'   EndTimecode                          N
-  'TCOD'   StartTimecode                        N
-  'TITL'   Title                                N
-  'TLEN'   Length                               N
-  'TORG'   Organization                         N
-  'TRCK'   TrackNumber                          N
-  'TURL'   URL                                  N
-  'TVER'   Version                              N
-  'VMAJ'   VegasVersionMajor                    N
-  'VMIN'   VegasVersionMinor                    N
-  'YEAR'   Year                                 N
+  'AGES'   Rated                                no
+  'CMNT'   Comment                              no
+  'CODE'   EncodedBy                            no
+  'COMM'   Comments                             no
+  'DIRC'   Directory                            no
+  'DISP'   SoundSchemeTitle                     no
+  'DTIM'   DateTimeOriginal                     no
+  'GENR'   Genre                                no
+  'IARL'   ArchivalLocation                     no
+  'IART'   Artist                               no
+  'IAS1'   FirstLanguage                        no
+  'IAS2'   SecondLanguage                       no
+  'IAS3'   ThirdLanguage                        no
+  'IAS4'   FourthLanguage                       no
+  'IAS5'   FifthLanguage                        no
+  'IAS6'   SixthLanguage                        no
+  'IAS7'   SeventhLanguage                      no
+  'IAS8'   EighthLanguage                       no
+  'IAS9'   NinthLanguage                        no
+  'IBSU'   BaseURL                              no
+  'ICAS'   DefaultAudioStream                   no
+  'ICDS'   CostumeDesigner                      no
+  'ICMS'   Commissioned                         no
+  'ICMT'   Comment                              no
+  'ICNM'   Cinematographer                      no
+  'ICNT'   Country                              no
+  'ICOP'   Copyright                            no
+  'ICRD'   DateCreated                          no
+  'ICRP'   Cropped                              no
+  'IDIM'   Dimensions                           no
+  'IDIT'   DateTimeOriginal                     no
+  'IDPI'   DotsPerInch                          no
+  'IDST'   DistributedBy                        no
+  'IEDT'   EditedBy                             no
+  'IENC'   EncodedBy                            no
+  'IENG'   Engineer                             no
+  'IGNR'   Genre                                no
+  'IKEY'   Keywords                             no
+  'ILGT'   Lightness                            no
+  'ILGU'   LogoURL                              no
+  'ILIU'   LogoIconURL                          no
+  'ILNG'   Language                             no
+  'IMBI'   MoreInfoBannerImage                  no
+  'IMBU'   MoreInfoBannerURL                    no
+  'IMED'   Medium                               no
+  'IMIT'   MoreInfoText                         no
+  'IMIU'   MoreInfoURL                          no
+  'IMUS'   MusicBy                              no
+  'INAM'   Title                                no
+  'IPDS'   ProductionDesigner                   no
+  'IPLT'   NumColors                            no
+  'IPRD'   Product                              no
+  'IPRO'   ProducedBy                           no
+  'IRIP'   RippedBy                             no
+  'IRTD'   Rating                               no
+  'ISBJ'   Subject                              no
+  'ISFT'   Software                             no
+  'ISGN'   SecondaryGenre                       no
+  'ISHP'   Sharpness                            no
+  'ISMP'   TimeCode                             no
+  'ISRC'   Source                               no
+  'ISRF'   SourceForm                           no
+  'ISTD'   ProductionStudio                     no
+  'ISTR'   Starring                             no
+  'ITCH'   Technician                           no
+  'IWMU'   WatermarkURL                         no
+  'IWRI'   WrittenBy                            no
+  'LANG'   Language                             no
+  'LOCA'   Location                             no
+  'PRT1'   Part                                 no
+  'PRT2'   NumberOfParts                        no
+  'RATE'   Rate                                 no
+  'STAR'   Starring                             no
+  'STAT'   Statistics                           no
+  'TAPE'   TapeName                             no
+  'TCDO'   EndTimecode                          no
+  'TCOD'   StartTimecode                        no
+  'TITL'   Title                                no
+  'TLEN'   Length                               no
+  'TORG'   Organization                         no
+  'TRCK'   TrackNumber                          no
+  'TURL'   URL                                  no
+  'TVER'   Version                              no
+  'VMAJ'   VegasVersionMajor                    no
+  'VMIN'   VegasVersionMinor                    no
+  'YEAR'   Year                                 no
 
 =head3 RIFF Tdat Tags
@@ -16329,11 +29984,11 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  'ecor'   Make                                 N
-  'emdl'   Model                                N
-  'emnt'   MakerNotes                           N
-  'erel'   RelatedImageFile                     N
-  'etim'   TimeCreated                          N
-  'eucm'   UserComment                          N
-  'ever'   ExifVersion                          N
+  'ecor'   Make                                 no
+  'emdl'   Model                                no
+  'emnt'   MakerNotes                           no
+  'erel'   RelatedImageFile                     no
+  'etim'   TimeCreated                          no
+  'eucm'   UserComment                          no
+  'ever'   ExifVersion                          no
 
 =head3 RIFF Hdrl Tags
@@ -16341,6 +29996,6 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'IDIT'               DateTimeOriginal         N
-  'ISMP'               Timecode                 N
+  'IDIT'               DateTimeOriginal         no
+  'ISMP'               TimeCode                 no
   'LIST_odml'          OpenDML                  RIFF OpenDML
   'LIST_strl'          Stream                   RIFF Stream
@@ -16355,7 +30010,7 @@
 =head3 RIFF ExtAVIHdr Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    TotalFrameCount                      N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    TotalFrameCount                      no
 
 =head3 RIFF Stream Tags
@@ -16367,5 +30022,5 @@
            VideoFormat                          BMP
   'strh'   StreamHeader                         RIFF StreamHeader
-  'strn'   StreamName                           N
+  'strn'   StreamName                           no
 
 =head3 RIFF StreamData Tags
@@ -16378,44 +30033,76 @@
   'AVIF'       AVIF                             EXIF
   'CASI'       CasioData                        Casio AVI
-  'Zora'       VendorName                       N
-  'unknown'    UnknownData                      N
+  'Zora'       VendorName                       no
+  'unknown'    UnknownData                      no
 
 =head3 RIFF AudioFormat Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Encoding                             N
-      1    NumChannels                          N
-      2    SampleRate                           N
-      4    AvgBytesPerSec                       N
-      7    BitsPerSample                        N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    Encoding                             no
+      1    NumChannels                          no
+      2    SampleRate                           no
+      4    AvgBytesPerSec                       no
+      7    BitsPerSample                        no
 
 =head3 RIFF StreamHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    StreamType                           N
-      1    AudioCodec                           N
-           VideoCodec                           N
-           Codec                                N
-      5    AudioSampleRate                      N
-           VideoFrameRate                       N
-           StreamSampleRate                     N
-      8    AudioSampleCount                     N
-           VideoFrameCount                      N
-           StreamSampleCount                    N
-     10    Quality                              N
-     11    SampleSize                           N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    StreamType                           no
+      1    AudioCodec                           no
+           VideoCodec                           no
+           Codec                                no
+      5    AudioSampleRate                      no
+           VideoFrameRate                       no
+           StreamSampleRate                     no
+      8    AudioSampleCount                     no
+           VideoFrameCount                      no
+           StreamSampleCount                    no
+     10    Quality                              no
+     11    SampleSize                           no
 
 =head3 RIFF AVIHeader Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FrameRate                            N
-      1    MaxDataRate                          N
-      4    FrameCount                           N
-      6    StreamCount                          N
-      8    ImageWidth                           N
-      9    ImageHeight                          N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    FrameRate                            no
+      1    MaxDataRate                          no
+      4    FrameCount                           no
+      6    StreamCount                          no
+      8    ImageWidth                           no
+      9    ImageHeight                          no
+
+=head3 RIFF VP8 Tags
+
+This chunk is found in simple-format (lossy) WebP files. See
+L<https://developers.google.com/speed/webp/docs/riff_container> for the WebP
+container specification.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    VP8Version                           no
+      6    ImageWidth                           no
+    6.1    HorizontalScale                      no
+      8    ImageHeight                          no
+    8.1    VerticalScale                        no
+
+=head3 RIFF VP8L Tags
+
+This chunk is found in lossless WebP files.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      1    ImageWidth                           no
+      2    ImageHeight                          no
+
+=head3 RIFF VP8X Tags
+
+This chunk is found in extended WebP files.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    ImageWidth                           no
+      6    ImageHeight                          no
 
 =head3 RIFF BroadcastExt Tags
@@ -16424,38 +30111,75 @@
 L<http://tech.ebu.ch/docs/tech/tech3285.pdf>).
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    Description                          N
-    256    Originator                           N
-    288    OriginatorReference                  N
-    320    DateTimeOriginal                     N
-    338    TimeReference                        N
-    346    BWFVersion                           N
-    602    CodingHistory                        N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    Description                          no
+    256    Originator                           no
+    288    OriginatorReference                  no
+    320    DateTimeOriginal                     no
+    338    TimeReference                        no
+    346    BWFVersion                           no
+    348    BWF_UMID                             no
+    602    CodingHistory                        no
+
+=head3 RIFF DS64 Tags
+
+64-bit data sizes for MBWF/RF64 files.  See
+L<https://tech.ebu.ch/docs/tech/tech3306-2009.pdf> for the specification.
+
+  Index8   Tag Name                             Writable
+  ------   --------                             --------
+      0    RIFFSize64                           no
+      1    DataSize64                           no
+      2    NumberOfSamples64                    no
+
+=head3 RIFF Label Tags
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    LabelID                              no
+      1    LabelText                            no
+
+=head3 RIFF UserText Tags
+
+Tags decoded from the USER-format txts stream written by Momento M6 dashcam.
+Extracted only if the ExtractEmbedded option is used.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     28    GPSAltitude                          no
+     40    Accelerometer                        no
+     56    GPSSpeed                             no
+     60    GPSLatitude                          no
+     64    GPSLongitude                         no
+     68    GPSDateTime                          no
 
 =head2 AIFF Tags
 
-Only the tags decoded by ExifTool are listed in this table.
+Tags extracted from Audio Interchange File Format (AIFF) files.  See
+L<http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/AIFF/AIFF.html> for
+the AIFF specification.
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  '(c) '   Copyright                            N
-  'ANNO'   Annotation                           N
-  'AUTH'   Author                               N
+  '(c) '   Copyright                            no
+  'ANNO'   Annotation                           no
+  'APPL'   ApplicationData                      no
+  'AUTH'   Author                               no
   'COMM'   Common                               AIFF Common
   'COMT'   Comment                              AIFF Comment
   'FVER'   FormatVersion                        AIFF FormatVers
   'ID3 '   ID3                                  ID3
-  'NAME'   Name                                 N
+  'NAME'   Name                                 no
 
 =head3 AIFF Common Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    NumChannels                          N
-      1    NumSampleFrames                      N
-      3    SampleSize                           N
-      4    SampleRate                           N
-      9    CompressionType                      N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    NumChannels                          no
+      1    NumSampleFrames                      no
+      3    SampleSize                           no
+      4    SampleRate                           no
+      9    CompressionType                      no
+     11    CompressorName                       no
 
 =head3 AIFF Comment Tags
@@ -16463,13 +30187,13 @@
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   CommentTime                          N
-  0x0001   MarkerID                             N
-  0x0002   Comment                              N
+  0x0000   CommentTime                          no
+  0x0001   MarkerID                             no
+  0x0002   Comment                              no
 
 =head3 AIFF FormatVers Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FormatVersionTime                    N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    FormatVersionTime                    no
 
 =head2 ASF Tags
@@ -16481,11 +30205,11 @@
   Tag Name                                      Writable
   --------                                      --------
-  SimpleIndex                                   N
-  TimecodeIndex                                 N
+  SimpleIndex                                   no
+  TimecodeIndex                                 no
   Header                                        ASF Header
-  Data                                          N
+  Data                                          no
   XMP                                           XMP
-  Index                                         N
-  MediaIndex                                    N
+  Index                                         no
+  MediaIndex                                    no
 
 =head3 ASF Header Tags
@@ -16493,20 +30217,20 @@
   Tag Name                                      Writable
   --------                                      --------
-  Padding                                       N
-  ScriptCommand                                 N
+  Padding                                       no
+  ScriptCommand                                 no
   ContentBranding                               ASF ContentBranding
-  ContentEncryption                             N
-  DigitalSignature                              N
-  ExtendedContentEncryption                     N
+  ContentEncryption                             no
+  DigitalSignature                              no
+  ExtendedContentEncryption                     no
   HeaderExtension                               ASF HeaderExtension
   ContentDescription                            ASF ContentDescr
-  ErrorCorrection                               N
-  StreamBitrateProps                            N
+  ErrorCorrection                               no
+  StreamBitrateProps                            no
   CodecList                                     ASF CodecList
   FileProperties                                ASF FileProperties
   StreamProperties                              ASF StreamProperties
   ExtendedContentDescr                          ASF ExtendedDescr
-  BitrateMutualExclusion                        N
-  Marker                                        N
+  BitrateMutualExclusion                        no
+  Marker                                        no
 
 =head3 ASF ContentBranding Tags
@@ -16514,8 +30238,8 @@
   Tag Name                                      Writable
   --------                                      --------
-  BannerImageType                               N
-  BannerImage                                   N
-  BannerImageURL                                N
-  CopyrightURL                                  N
+  BannerImageType                               no
+  BannerImage                                   no
+  BannerImageURL                                no
+  CopyrightURL                                  no
 
 =head3 ASF HeaderExtension Tags
@@ -16523,246 +30247,328 @@
   Tag Name                                      Writable
   --------                                      --------
-  ExtendedStreamProps                           N
-  AdvancedContentEncryption                     N
-  MetadataLibrary                               ASF Metadata
-  TimecodeIndexParms                            N
-  Compatibility                                 N
-  LanguageList                                  N
-  AdvancedMutualExcl                            N
-  BandwidthSharing                              N
-  Reserved1                                     N
-  Metadata                                      ASF Metadata
-  GroupMutualExclusion                          N
-  StreamPrioritization                          N
-  IndexParameters                               N
-
-=head3 ASF Metadata Tags
+  ExtendedStreamProps                           no
+  AdvancedContentEncryption                     no
+  MetadataLibrary                               ASF ExtendedDescr
+  TimecodeIndexParms                            no
+  Compatibility                                 no
+  LanguageList                                  no
+  AdvancedMutualExcl                            no
+  BandwidthSharing                              no
+  Reserved1                                     no
+  Metadata                                      ASF ExtendedDescr
+  GroupMutualExclusion                          no
+  StreamPrioritization                          no
+  IndexParameters                               no
+
+=head3 ASF ExtendedDescr Tags
 
   Tag Name                                      Writable
   --------                                      --------
-  [no tags known]
-
-=head3 ASF ContentDescr Tags
+  ASFLeakyBucketPairs                           no
+  ASFPacketCount                                no
+  ASFSecurityObjectsSize                        no
+  AlbumArtist                                   no
+  AlbumCoverURL                                 no
+  AlbumTitle                                    no
+  AspectRatioX                                  no
+  AspectRatioY                                  no
+  AudioFileURL                                  no
+  AudioSourceURL                                no
+  Author                                        no
+  AuthorURL                                     no
+  AverageLevel                                  no
+  BannerImageData                               no
+  BannerImageType                               no
+  BannerImageURL                                no
+  BeatsPerMinute                                no
+  Bitrate                                       no
+  Broadcast                                     no
+  BufferAverage                                 no
+  Can_Skip_Backward                             no
+  Can_Skip_Forward                              no
+  Category                                      no
+  Codec                                         no
+  Composer                                      no
+  Conductor                                     no
+  ContainerFormat                               no
+  ContentDistributor                            no
+  ContentGroupDescription                       no
+  Copyright                                     no
+  CopyrightURL                                  no
+  CurrentBitrate                                no
+  DRM                                           no
+  DRM_ContentID                                 no
+  DRM_DRMHeader                                 no
+  DRM_DRMHeader_ContentDistributor              no
+  DRM_DRMHeader_ContentID                       no
+  DRM_DRMHeader_IndividualizedVersion           no
+  DRM_DRMHeader_KeyID                           no
+  DRM_DRMHeader_LicenseAcqURL                   no
+  DRM_DRMHeader_SubscriptionContentID           no
+  DRM_IndividualizedVersion                     no
+  DRM_KeyID                                     no
+  DRM_LASignatureCert                           no
+  DRM_LASignatureLicSrvCert                     no
+  DRM_LASignaturePrivKey                        no
+  DRM_LASignatureRootCert                       no
+  DRM_LicenseAcqURL                             no
+  DRM_V1LicenseAcqURL                           no
+  DVDID                                         no
+  Description                                   no
+  Director                                      no
+  Duration                                      no
+  EncodedBy                                     no
+  EncodingSettings                              no
+  EncodingTime                                  no
+  FileSize                                      no
+  Genre                                         no
+  GenreID                                       no
+  HasArbitraryDataStream                        no
+  HasAttachedImages                             no
+  HasAudio                                      no
+  HasFileTransferStream                         no
+  HasImage                                      no
+  HasScript                                     no
+  HasVideo                                      no
+  ISRC                                          no
+  InitialKey                                    no
+  IsVBR                                         no
+  Is_Protected                                  no
+  Is_Trusted                                    no
+  Language                                      no
+  Lyrics                                        no
+  Lyrics_Synchronised                           no
+  MCDI                                          no
+  MediaClassPrimaryID                           no
+  MediaClassSecondaryID                         no
+  MediaCredits                                  no
+  MediaIsDelay                                  no
+  MediaIsFinale                                 no
+  MediaIsLive                                   no
+  MediaIsPremiere                               no
+  MediaIsRepeat                                 no
+  MediaIsSAP                                    no
+  MediaIsStereo                                 no
+  MediaIsSubtitled                              no
+  MediaIsTape                                   no
+  MediaNetworkAffiliation                       no
+  MediaOriginalBroadcastDateTime                no
+  MediaOriginalChannel                          no
+  MediaStationCallSign                          no
+  MediaStationName                              no
+  ModifiedBy                                    no
+  Mood                                          no
+  NSC_Address                                   no
+  NSC_Description                               no
+  NSC_Email                                     no
+  NSC_Name                                      no
+  NSC_Phone                                     no
+  NumberOfFrames                                no
+  OptimalBitrate                                no
+  OriginalAlbumTitle                            no
+  OriginalArtist                                no
+  OriginalFileName                              no
+  OriginalLyricist                              no
+  OriginalReleaseTime                           no
+  OriginalReleaseYear                           no
+  ParentalRating                                no
+  ParentalRatingReason                          no
+  PartOfSet                                     no
+  PeakBitrate                                   no
+  PeakValue                                     no
+  Period                                        no
+  Picture                                       ASF Picture
+  PlaylistDelay                                 no
+  Producer                                      no
+  PromotionURL                                  no
+  ProtectionType                                no
+  Provider                                      no
+  ProviderCopyright                             no
+  ProviderRating                                no
+  ProviderStyle                                 no
+  Publisher                                     no
+  RadioStationName                              no
+  RadioStationOwner                             no
+  Rating                                        no
+  Seekable                                      no
+  SharedUserRating                              no
+  Signature_Name                                no
+  StreamTypeInfo                                no
+  Stridable                                     no
+  Subtitle                                      no
+  SubtitleDescription                           no
+  SubscriptionContentID                         no
+  Text                                          no
+  Title                                         no
+  ToolName                                      no
+  ToolVersion                                   no
+  Track                                         no
+  TrackNumber                                   no
+  UniqueFileIdentifier                          no
+  UserWebURL                                    no
+  VBRPeak                                       no
+  VideoClosedCaptioning                         no
+  VideoFrameRate                                no
+  VideoHeight                                   no
+  VideoWidth                                    no
+  WMADRCAverageReference                        no
+  WMADRCAverageTarget                           no
+  WMADRCPeakReference                           no
+  WMADRCPeakTarget                              no
+  WMCollectionGroupID                           no
+  WMCollectionID                                no
+  WMContentID                                   no
+  Writer                                        no
+  Year                                          no
+
+=head3 ASF Picture Tags
 
   Tag Name                                      Writable
   --------                                      --------
-  Title                                         N
-  Author                                        N
-  Copyright                                     N
-  Description                                   N
-  Rating                                        N
-
-=head3 ASF CodecList Tags
+  PictureType                                   no
+  PictureMIMEType                               no
+  PictureDescription                            no
+  Picture                                       no
+
+=head3 ASF ContentDescr Tags
 
   Tag Name                                      Writable
   --------                                      --------
-  AudioCodecDescription                         N
-  AudioCodecName                                N
-  OtherCodecDescription                         N
-  OtherCodecName                                N
-  VideoCodecDescription                         N
-  VideoCodecName                                N
-
-=head3 ASF FileProperties Tags
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    FileID                               N
-     16    FileLength                           N
-     24    CreationDate                         N
-     32    DataPackets                          N
-     40    PlayDuration                         N
-     48    SendDuration                         N
-     56    Preroll                              N
-     64    Flags                                N
-     68    MinPacketSize                        N
-     72    MaxPacketSize                        N
-     76    MaxBitrate                           N
-
-=head3 ASF StreamProperties Tags
-
-Tags with index 54 and greater are conditional based on the StreamType.
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    StreamType                           N
-     16    ErrorCorrectionType                  N
-     32    TimeOffset                           N
-     48    StreamNumber                         N
-     54    AudioCodecID                         N
-           ImageWidth                           N
-     56    AudioChannels                        N
-     58    AudioSampleRate                      N
-           ImageHeight                          N
-
-=head3 ASF ExtendedDescr Tags
+  Title                                         no
+  Author                                        no
+  Copyright                                     no
+  Description                                   no
+  Rating                                        no
+
+=head3 ASF CodecList Tags
 
   Tag Name                                      Writable
   --------                                      --------
-  ASFLeakyBucketPairs                           N
-  ASFPacketCount                                N
-  ASFSecurityObjectsSize                        N
-  AlbumArtist                                   N
-  AlbumCoverURL                                 N
-  AlbumTitle                                    N
-  AspectRatioX                                  N
-  AspectRatioY                                  N
-  AudioFileURL                                  N
-  AudioSourceURL                                N
-  Author                                        N
-  AuthorURL                                     N
-  AverageLevel                                  N
-  BannerImageData                               N
-  BannerImageType                               N
-  BannerImageURL                                N
-  BeatsPerMinute                                N
-  Bitrate                                       N
-  Broadcast                                     N
-  BufferAverage                                 N
-  Can_Skip_Backward                             N
-  Can_Skip_Forward                              N
-  Category                                      N
-  Codec                                         N
-  Composer                                      N
-  Conductor                                     N
-  ContainerFormat                               N
-  ContentDistributor                            N
-  ContentGroupDescription                       N
-  Copyright                                     N
-  CopyrightURL                                  N
-  CurrentBitrate                                N
-  DRM                                           N
-  DRM_ContentID                                 N
-  DRM_DRMHeader                                 N
-  DRM_DRMHeader_ContentDistributor              N
-  DRM_DRMHeader_ContentID                       N
-  DRM_DRMHeader_IndividualizedVersion           N
-  DRM_DRMHeader_KeyID                           N
-  DRM_DRMHeader_LicenseAcqURL                   N
-  DRM_DRMHeader_SubscriptionContentID           N
-  DRM_IndividualizedVersion                     N
-  DRM_KeyID                                     N
-  DRM_LASignatureCert                           N
-  DRM_LASignatureLicSrvCert                     N
-  DRM_LASignaturePrivKey                        N
-  DRM_LASignatureRootCert                       N
-  DRM_LicenseAcqURL                             N
-  DRM_V1LicenseAcqURL                           N
-  DVDID                                         N
-  Description                                   N
-  Director                                      N
-  Duration                                      N
-  EncodedBy                                     N
-  EncodingSettings                              N
-  EncodingTime                                  N
-  FileSize                                      N
-  Genre                                         N
-  GenreID                                       N
-  HasArbitraryDataStream                        N
-  HasAttachedImages                             N
-  HasAudio                                      N
-  HasFileTransferStream                         N
-  HasImage                                      N
-  HasScript                                     N
-  HasVideo                                      N
-  ISRC                                          N
-  InitialKey                                    N
-  IsVBR                                         N
-  Is_Protected                                  N
-  Is_Trusted                                    N
-  Language                                      N
-  Lyrics                                        N
-  Lyrics_Synchronised                           N
-  MCDI                                          N
-  MediaClassPrimaryID                           N
-  MediaClassSecondaryID                         N
-  MediaCredits                                  N
-  MediaIsDelay                                  N
-  MediaIsFinale                                 N
-  MediaIsLive                                   N
-  MediaIsPremiere                               N
-  MediaIsRepeat                                 N
-  MediaIsSAP                                    N
-  MediaIsStereo                                 N
-  MediaIsSubtitled                              N
-  MediaIsTape                                   N
-  MediaNetworkAffiliation                       N
-  MediaOriginalBroadcastDateTime                N
-  MediaOriginalChannel                          N
-  MediaStationCallSign                          N
-  MediaStationName                              N
-  ModifiedBy                                    N
-  Mood                                          N
-  NSC_Address                                   N
-  NSC_Description                               N
-  NSC_Email                                     N
-  NSC_Name                                      N
-  NSC_Phone                                     N
-  NumberOfFrames                                N
-  OptimalBitrate                                N
-  OriginalAlbumTitle                            N
-  OriginalArtist                                N
-  OriginalFilename                              N
-  OriginalLyricist                              N
-  OriginalReleaseTime                           N
-  OriginalReleaseYear                           N
-  ParentalRating                                N
-  ParentalRatingReason                          N
-  PartOfSet                                     N
-  PeakBitrate                                   N
-  PeakValue                                     N
-  Period                                        N
-  Picture                                       ASF Picture
-  PlaylistDelay                                 N
-  Producer                                      N
-  PromotionURL                                  N
-  ProtectionType                                N
-  Provider                                      N
-  ProviderCopyright                             N
-  ProviderRating                                N
-  ProviderStyle                                 N
-  Publisher                                     N
-  RadioStationName                              N
-  RadioStationOwner                             N
-  Rating                                        N
-  Seekable                                      N
-  SharedUserRating                              N
-  Signature_Name                                N
-  StreamTypeInfo                                N
-  Stridable                                     N
-  SubTitle                                      N
-  SubTitleDescription                           N
-  SubscriptionContentID                         N
-  Text                                          N
-  Title                                         N
-  ToolName                                      N
-  ToolVersion                                   N
-  Track                                         N
-  TrackNumber                                   N
-  UniqueFileIdentifier                          N
-  UserWebURL                                    N
-  VBRPeak                                       N
-  VideoClosedCaptioning                         N
-  VideoFrameRate                                N
-  VideoHeight                                   N
-  VideoWidth                                    N
-  WMADRCAverageReference                        N
-  WMADRCAverageTarget                           N
-  WMADRCPeakReference                           N
-  WMADRCPeakTarget                              N
-  WMCollectionGroupID                           N
-  WMCollectionID                                N
-  WMContentID                                   N
-  Writer                                        N
-  Year                                          N
-
-=head3 ASF Picture Tags
+  AudioCodecDescription                         no
+  AudioCodecName                                no
+  OtherCodecDescription                         no
+  OtherCodecName                                no
+  VideoCodecDescription                         no
+  VideoCodecName                                no
+
+=head3 ASF FileProperties Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    FileID                               no
+     16    FileLength                           no
+     24    CreationDate                         no
+     32    DataPackets                          no
+     40    Duration                             no
+     48    SendDuration                         no
+     56    Preroll                              no
+     64    Flags                                no
+     68    MinPacketSize                        no
+     72    MaxPacketSize                        no
+     76    MaxBitrate                           no
+
+=head3 ASF StreamProperties Tags
+
+Tags with index 54 and greater are conditional based on the StreamType.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    StreamType                           no
+     16    ErrorCorrectionType                  no
+     32    TimeOffset                           no
+     48    StreamNumber                         no
+     54    AudioCodecID                         no
+           ImageWidth                           no
+     56    AudioChannels                        no
+     58    AudioSampleRate                      no
+           ImageHeight                          no
+
+=head2 WTV Tags
+
+Tags found in Windows recorded TV (WTV) videos.
+
+  Tag ID                          Tag Name      Writable
+  ------                          --------      --------
+  'table.0.entries.legacy_attrib' Metdata       WTV Metadata
+
+=head3 WTV Metadata Tags
+
+ExifTool will extract any tag found, even if not in this table.
 
   Tag Name                                      Writable
   --------                                      --------
-  PictureType                                   N
-  PictureMimeType                               N
-  PictureDescription                            N
-  Picture                                       N
+  ATSCContent                                   no
+  ActualSoftPostPadding                         no
+  ActualSoftPrePadding                          no
+  Bitrate?                                      no
+  BrandingImageID                               no
+  BrandingName                                  no
+  ContentProtected                              no
+  ContentProtectedPercent                       no
+  DTVContent                                    no
+  Duration                                      no
+  EncodeTime                                    no
+  EndTime                                       no
+  ExpirationDate?                               no
+  ExpirationSpan?                               no
+  Genre                                         no
+  HDContent                                     no
+  HardPostPadding                               no
+  HardPrePadding                                no
+  InBandRatingAttributes                        no
+  InBandRatingLevel                             no
+  InBandRatingSystem                            no
+  KeepUntil                                     no
+  Language                                      no
+  MediaClassPrimaryID                           no
+  MediaClassSecondaryID                         no
+  MediaCredits                                  no
+  MediaIsDelay                                  no
+  MediaIsFinale                                 no
+  MediaIsLive                                   no
+  MediaIsMovie                                  no
+  MediaIsPremiere                               no
+  MediaIsRepeat                                 no
+  MediaIsSAP                                    no
+  MediaIsSport                                  no
+  MediaIsStereo                                 no
+  MediaIsSubtitled                              no
+  MediaIsTape                                   no
+  MediaNetworkAffiliation                       no
+  MediaOriginalBroadcastDateTime                no
+  MediaOriginalChannel                          no
+  MediaOriginalChannelSubNumber                 no
+  MediaOriginalRunTime                          no
+  MediaStationCallSign                          no
+  MediaStationName                              no
+  MediaThumbAspectRatioX                        no
+  MediaThumbAspectRatioY                        no
+  MediaThumbHeight                              no
+  MediaThumbRatingAttributes                    no
+  MediaThumbRatingLevel                         no
+  MediaThumbRatingSystem                        no
+  MediaThumbRet                                 no
+  MediaThumbStride                              no
+  MediaThumbTimeStamp?                          no
+  MediaThumbWidth                               no
+  OriginalReleaseTime                           no
+  OriginalSoftPostPadding                       no
+  OriginalSoftPrePadding                        no
+  ParentalRating                                no
+  ParentalRatingReason                          no
+  ProgramID                                     no
+  Provider                                      no
+  ProviderCopyright                             no
+  ProviderRating                                no
+  Quality                                       no
+  RequestID                                     no
+  ScheduleItemID                                no
+  SeriesUID                                     no
+  ServiceID                                     no
+  Subtitle                                      no
+  SubtitleDescription                           no
+  Title                                         no
+  VideoClosedCaptioning                         no
+  Watched                                       no
 
 =head2 DICOM Tags
@@ -16775,3152 +30581,3195 @@
 2009 and earlier specifications plus some vendor-specific private tags.
 
+Note that DICOM information may be saved in other file formats using the
+L<XMP DICOM Tags|Image::ExifTool::TagNames/XMP DICOM Tags>.
+
   Tag ID     Tag Name                           Writable
   ------     --------                           --------
-  0002,0000  FileMetaInfoGroupLength            N
-  0002,0001  FileMetaInfoVersion                N
-  0002,0002  MediaStorageSOPClassUID            N
-  0002,0003  MediaStorageSOPInstanceUID         N
-  0002,0010  TransferSyntaxUID                  N
-  0002,0012  ImplementationClassUID             N
-  0002,0013  ImplementationVersionName          N
-  0002,0016  SourceApplicationEntityTitle       N
-  0002,0100  PrivateInformationCreatorUID       N
-  0002,0102  PrivateInformation                 N
-  0004,1130  FileSetID                          N
-  0004,1141  FileSetDescriptorFileID            N
-  0004,1142  SpecificCharacterSetOfFile         N
-  0004,1200  FirstDirectoryRecordOffset         N
-  0004,1202  LastDirectoryRecordOffset          N
-  0004,1212  FileSetConsistencyFlag             N
-  0004,1220  DirectoryRecordSequence            N
-  0004,1400  OffsetOfNextDirectoryRecord        N
-  0004,1410  RecordInUseFlag                    N
-  0004,1420  LowerLevelDirectoryEntityOffset    N
-  0004,1430  DirectoryRecordType                N
-  0004,1432  PrivateRecordUID                   N
-  0004,1500  ReferencedFileID                   N
-  0004,1504  MRDRDirectoryRecordOffset          N
-  0004,1510  ReferencedSOPClassUIDInFile        N
-  0004,1511  ReferencedSOPInstanceUIDInFile     N
-  0004,1512  ReferencedTransferSyntaxUIDInFile  N
-  0004,151A  ReferencedRelatedSOPClassUIDInFile N
-  0004,1600  NumberOfReferences                 N
-  0008,0000  IdentifyingGroupLength             N
-  0008,0001  LengthToEnd                        N
-  0008,0005  SpecificCharacterSet               N
-  0008,0006  LanguageCodeSequence               N
-  0008,0008  ImageType                          N
-  0008,0010  RecognitionCode                    N
-  0008,0012  InstanceCreationDate               N
-  0008,0013  InstanceCreationTime               N
-  0008,0014  InstanceCreatorUID                 N
-  0008,0016  SOPClassUID                        N
-  0008,0018  SOPInstanceUID                     N
-  0008,001A  RelatedGeneralSOPClassUID          N
-  0008,001B  OriginalSpecializedSOPClassUID     N
-  0008,0020  StudyDate                          N
-  0008,0021  SeriesDate                         N
-  0008,0022  AcquisitionDate                    N
-  0008,0023  ContentDate                        N
-  0008,0024  OverlayDate                        N
-  0008,0025  CurveDate                          N
-  0008,002A  AcquisitionDateTime                N
-  0008,0030  StudyTime                          N
-  0008,0031  SeriesTime                         N
-  0008,0032  AcquisitionTime                    N
-  0008,0033  ContentTime                        N
-  0008,0034  OverlayTime                        N
-  0008,0035  CurveTime                          N
-  0008,0040  DataSetType                        N
-  0008,0041  DataSetSubtype                     N
-  0008,0042  NuclearMedicineSeriesType          N
-  0008,0050  AccessionNumber                    N
-  0008,0052  QueryRetrieveLevel                 N
-  0008,0054  RetrieveAETitle                    N
-  0008,0056  InstanceAvailability               N
-  0008,0058  FailedSOPInstanceUIDList           N
-  0008,0060  Modality                           N
-  0008,0061  ModalitiesInStudy                  N
-  0008,0062  SOPClassesInStudy                  N
-  0008,0064  ConversionType                     N
-  0008,0068  PresentationIntentType             N
-  0008,0070  Manufacturer                       N
-  0008,0080  InstitutionName                    N
-  0008,0081  InstitutionAddress                 N
-  0008,0082  InstitutionCodeSequence            N
-  0008,0090  ReferringPhysicianName             N
-  0008,0092  ReferringPhysicianAddress          N
-  0008,0094  ReferringPhysicianTelephoneNumber  N
-  0008,0096  ReferringPhysicianIDSequence       N
-  0008,0100  CodeValue                          N
-  0008,0102  CodingSchemeDesignator             N
-  0008,0103  CodingSchemeVersion                N
-  0008,0104  CodeMeaning                        N
-  0008,0105  MappingResource                    N
-  0008,0106  ContextGroupVersion                N
-  0008,0107  ContextGroupLocalVersion           N
-  0008,010B  ContextGroupExtensionFlag          N
-  0008,010C  CodingSchemeUID                    N
-  0008,010D  ContextGroupExtensionCreatorUID    N
-  0008,010F  ContextIdentifier                  N
-  0008,0110  CodingSchemeIDSequence             N
-  0008,0112  CodingSchemeRegistry               N
-  0008,0114  CodingSchemeExternalID             N
-  0008,0115  CodingSchemeName                   N
-  0008,0116  ResponsibleOrganization            N
-  0008,0117  ContextUID                         N
-  0008,0201  TimezoneOffsetFromUTC              N
-  0008,1000  NetworkID                          N
-  0008,1010  StationName                        N
-  0008,1030  StudyDescription                   N
-  0008,1032  ProcedureCodeSequence              N
-  0008,103E  SeriesDescription                  N
-  0008,1040  InstitutionalDepartmentName        N
-  0008,1048  PhysiciansOfRecord                 N
-  0008,1049  PhysiciansOfRecordIDSequence       N
-  0008,1050  PerformingPhysicianName            N
-  0008,1052  PerformingPhysicianIDSequence      N
-  0008,1060  NameOfPhysicianReadingStudy        N
-  0008,1062  PhysicianReadingStudyIDSequence    N
-  0008,1070  OperatorsName                      N
-  0008,1072  OperatorIDSequence                 N
-  0008,1080  AdmittingDiagnosesDescription      N
-  0008,1084  AdmittingDiagnosesCodeSequence     N
-  0008,1090  ManufacturersModelName             N
-  0008,1100  ReferencedResultsSequence          N
-  0008,1110  ReferencedStudySequence            N
-  0008,1111  ReferencedProcedureStepSequence    N
-  0008,1115  ReferencedSeriesSequence           N
-  0008,1120  ReferencedPatientSequence          N
-  0008,1125  ReferencedVisitSequence            N
-  0008,1130  ReferencedOverlaySequence          N
-  0008,113A  ReferencedWaveformSequence         N
-  0008,1140  ReferencedImageSequence            N
-  0008,1145  ReferencedCurveSequence            N
-  0008,114A  ReferencedInstanceSequence         N
-  0008,1150  ReferencedSOPClassUID              N
-  0008,1155  ReferencedSOPInstanceUID           N
-  0008,115A  SOPClassesSupported                N
-  0008,1160  ReferencedFrameNumber              N
-  0008,1161  SimpleFrameList                    N
-  0008,1162  CalculatedFrameList                N
-  0008,1163  TimeRange                          N
-  0008,1164  FrameExtractionSequence            N
-  0008,1195  TransactionUID                     N
-  0008,1197  FailureReason                      N
-  0008,1198  FailedSOPSequence                  N
-  0008,1199  ReferencedSOPSequence              N
-  0008,1200  OtherReferencedStudiesSequence     N
-  0008,1250  RelatedSeriesSequence              N
-  0008,2110  LossyImageCompression              N
-  0008,2111  DerivationDescription              N
-  0008,2112  SourceImageSequence                N
-  0008,2120  StageName                          N
-  0008,2122  StageNumber                        N
-  0008,2124  NumberOfStages                     N
-  0008,2127  ViewName                           N
-  0008,2128  ViewNumber                         N
-  0008,2129  NumberOfEventTimers                N
-  0008,212A  NumberOfViewsInStage               N
-  0008,2130  EventElapsedTimes                  N
-  0008,2132  EventTimerNames                    N
-  0008,2133  EventTimerSequence                 N
-  0008,2134  EventTimeOffset                    N
-  0008,2135  EventCodeSequence                  N
-  0008,2142  StartTrim                          N
-  0008,2143  StopTrim                           N
-  0008,2144  RecommendedDisplayFrameRate        N
-  0008,2200  TransducerPosition                 N
-  0008,2204  TransducerOrientation              N
-  0008,2208  AnatomicStructure                  N
-  0008,2218  AnatomicRegionSequence             N
-  0008,2220  AnatomicRegionModifierSequence     N
-  0008,2228  PrimaryAnatomicStructureSequence   N
-  0008,2229  AnatomicStructureOrRegionSequence  N
-  0008,2230  AnatomicStructureModifierSequence  N
-  0008,2240  TransducerPositionSequence         N
-  0008,2242  TransducerPositionModifierSequence N
-  0008,2244  TransducerOrientationSequence      N
-  0008,2246  TransducerOrientationModifierSeq   N
-  0008,2253  AnatomicEntrancePortalCodeSeqTrial N
-  0008,2255  AnatomicApproachDirCodeSeqTrial    N
-  0008,2256  AnatomicPerspectiveDescrTrial      N
-  0008,2257  AnatomicPerspectiveCodeSeqTrial    N
-  0008,3001  AlternateRepresentationSequence    N
-  0008,3010  IrradiationEventUID                N
-  0008,4000  IdentifyingComments                N
-  0008,9007  FrameType                          N
-  0008,9092  ReferencedImageEvidenceSequence    N
-  0008,9121  ReferencedRawDataSequence          N
-  0008,9123  CreatorVersionUID                  N
-  0008,9124  DerivationImageSequence            N
-  0008,9154  SourceImageEvidenceSequence        N
-  0008,9205  PixelPresentation                  N
-  0008,9206  VolumetricProperties               N
-  0008,9207  VolumeBasedCalculationTechnique    N
-  0008,9208  ComplexImageComponent              N
-  0008,9209  AcquisitionContrast                N
-  0008,9215  DerivationCodeSequence             N
-  0008,9237  GrayscalePresentationStateSequence N
-  0008,9410  ReferencedOtherPlaneSequence       N
-  0008,9458  FrameDisplaySequence               N
-  0008,9459  RecommendedDisplayFrameRateInFloat N
-  0008,9460  SkipFrameRangeFlag                 N
-  0009,1001  FullFidelity                       N
-  0009,1002  SuiteID                            N
-  0009,1004  ProductID                          N
-  0009,1027  ImageActualDate                    N
-  0009,1030  ServiceID                          N
-  0009,1031  MobileLocationNumber               N
-  0009,10E3  EquipmentUID                       N
-  0009,10E6  GenesisVersionNow                  N
-  0009,10E7  ExamRecordChecksum                 N
-  0009,10E9  ActualSeriesDataTimeStamp          N
-  0010,0000  PatientGroupLength                 N
-  0010,0010  PatientName                        N
-  0010,0020  PatientID                          N
-  0010,0021  IssuerOfPatientID                  N
-  0010,0022  TypeOfPatientID                    N
-  0010,0030  PatientBirthDate                   N
-  0010,0032  PatientBirthTime                   N
-  0010,0040  PatientSex                         N
-  0010,0050  PatientInsurancePlanCodeSequence   N
-  0010,0101  PatientPrimaryLanguageCodeSeq      N
-  0010,0102  PatientPrimaryLanguageCodeModSeq   N
-  0010,1000  OtherPatientIDs                    N
-  0010,1001  OtherPatientNames                  N
-  0010,1002  OtherPatientIDsSequence            N
-  0010,1005  PatientBirthName                   N
-  0010,1010  PatientAge                         N
-  0010,1020  PatientSize                        N
-  0010,1030  PatientWeight                      N
-  0010,1040  PatientAddress                     N
-  0010,1050  InsurancePlanIdentification        N
-  0010,1060  PatientMotherBirthName             N
-  0010,1080  MilitaryRank                       N
-  0010,1081  BranchOfService                    N
-  0010,1090  MedicalRecordLocator               N
-  0010,2000  MedicalAlerts                      N
-  0010,2110  Allergies                          N
-  0010,2150  CountryOfResidence                 N
-  0010,2152  RegionOfResidence                  N
-  0010,2154  PatientTelephoneNumbers            N
-  0010,2160  EthnicGroup                        N
-  0010,2180  Occupation                         N
-  0010,21A0  SmokingStatus                      N
-  0010,21B0  AdditionalPatientHistory           N
-  0010,21C0  PregnancyStatus                    N
-  0010,21D0  LastMenstrualDate                  N
-  0010,21F0  PatientReligiousPreference         N
-  0010,2201  PatientSpeciesDescription          N
-  0010,2202  PatientSpeciesCodeSequence         N
-  0010,2203  PatientSexNeutered                 N
-  0010,2210  AnatomicalOrientationType          N
-  0010,2292  PatientBreedDescription            N
-  0010,2293  PatientBreedCodeSequence           N
-  0010,2294  BreedRegistrationSequence          N
-  0010,2295  BreedRegistrationNumber            N
-  0010,2296  BreedRegistryCodeSequence          N
-  0010,2297  ResponsiblePerson                  N
-  0010,2298  ResponsiblePersonRole              N
-  0010,2299  ResponsibleOrganization            N
-  0010,4000  PatientComments                    N
-  0010,9431  ExaminedBodyThickness              N
-  0011,1010  PatientStatus                      N
-  0012,0010  ClinicalTrialSponsorName           N
-  0012,0020  ClinicalTrialProtocolID            N
-  0012,0021  ClinicalTrialProtocolName          N
-  0012,0030  ClinicalTrialSiteID                N
-  0012,0031  ClinicalTrialSiteName              N
-  0012,0040  ClinicalTrialSubjectID             N
-  0012,0042  ClinicalTrialSubjectReadingID      N
-  0012,0050  ClinicalTrialTimePointID           N
-  0012,0051  ClinicalTrialTimePointDescription  N
-  0012,0060  ClinicalTrialCoordinatingCenter    N
-  0012,0062  PatientIdentityRemoved             N
-  0012,0063  DeidentificationMethod             N
-  0012,0064  DeidentificationMethodCodeSequence N
-  0012,0071  ClinicalTrialSeriesID              N
-  0012,0072  ClinicalTrialSeriesDescription     N
-  0012,0084  DistributionType                   N
-  0012,0085  ConsentForDistributionFlag         N
-  0018,0000  AcquisitionGroupLength             N
-  0018,0010  ContrastBolusAgent                 N
-  0018,0012  ContrastBolusAgentSequence         N
-  0018,0014  ContrastBolusAdministrationRoute   N
-  0018,0015  BodyPartExamined                   N
-  0018,0020  ScanningSequence                   N
-  0018,0021  SequenceVariant                    N
-  0018,0022  ScanOptions                        N
-  0018,0023  MRAcquisitionType                  N
-  0018,0024  SequenceName                       N
-  0018,0025  AngioFlag                          N
-  0018,0026  InterventionDrugInformationSeq     N
-  0018,0027  InterventionDrugStopTime           N
-  0018,0028  InterventionDrugDose               N
-  0018,0029  InterventionDrugSequence           N
-  0018,002A  AdditionalDrugSequence             N
-  0018,0030  Radionuclide                       N
-  0018,0031  Radiopharmaceutical                N
-  0018,0032  EnergyWindowCenterline             N
-  0018,0033  EnergyWindowTotalWidth             N
-  0018,0034  InterventionDrugName               N
-  0018,0035  InterventionDrugStartTime          N
-  0018,0036  InterventionSequence               N
-  0018,0037  TherapyType                        N
-  0018,0038  InterventionStatus                 N
-  0018,0039  TherapyDescription                 N
-  0018,003A  InterventionDescription            N
-  0018,0040  CineRate                           N
-  0018,0042  InitialCineRunState                N
-  0018,0050  SliceThickness                     N
-  0018,0060  KVP                                N
-  0018,0070  CountsAccumulated                  N
-  0018,0071  AcquisitionTerminationCondition    N
-  0018,0072  EffectiveDuration                  N
-  0018,0073  AcquisitionStartCondition          N
-  0018,0074  AcquisitionStartConditionData      N
-  0018,0075  AcquisitionEndConditionData        N
-  0018,0080  RepetitionTime                     N
-  0018,0081  EchoTime                           N
-  0018,0082  InversionTime                      N
-  0018,0083  NumberOfAverages                   N
-  0018,0084  ImagingFrequency                   N
-  0018,0085  ImagedNucleus                      N
-  0018,0086  EchoNumber                         N
-  0018,0087  MagneticFieldStrength              N
-  0018,0088  SpacingBetweenSlices               N
-  0018,0089  NumberOfPhaseEncodingSteps         N
-  0018,0090  DataCollectionDiameter             N
-  0018,0091  EchoTrainLength                    N
-  0018,0093  PercentSampling                    N
-  0018,0094  PercentPhaseFieldOfView            N
-  0018,0095  PixelBandwidth                     N
-  0018,1000  DeviceSerialNumber                 N
-  0018,1002  DeviceUID                          N
-  0018,1003  DeviceID                           N
-  0018,1004  PlateID                            N
-  0018,1005  GeneratorID                        N
-  0018,1006  GridID                             N
-  0018,1007  CassetteID                         N
-  0018,1008  GantryID                           N
-  0018,1010  SecondaryCaptureDeviceID           N
-  0018,1011  HardcopyCreationDeviceID           N
-  0018,1012  DateOfSecondaryCapture             N
-  0018,1014  TimeOfSecondaryCapture             N
-  0018,1016  SecondaryCaptureDeviceManufacturer N
-  0018,1017  HardcopyDeviceManufacturer         N
-  0018,1018  SecondaryCaptureDeviceModelName    N
-  0018,1019  SecondaryCaptureDeviceSoftwareVers N
-  0018,101A  HardcopyDeviceSoftwareVersion      N
-  0018,101B  HardcopyDeviceModelName            N
-  0018,1020  SoftwareVersion                    N
-  0018,1022  VideoImageFormatAcquired           N
-  0018,1023  DigitalImageFormatAcquired         N
-  0018,1030  ProtocolName                       N
-  0018,1040  ContrastBolusRoute                 N
-  0018,1041  ContrastBolusVolume                N
-  0018,1042  ContrastBolusStartTime             N
-  0018,1043  ContrastBolusStopTime              N
-  0018,1044  ContrastBolusTotalDose             N
-  0018,1045  SyringeCounts                      N
-  0018,1046  ContrastFlowRate                   N
-  0018,1047  ContrastFlowDuration               N
-  0018,1048  ContrastBolusIngredient            N
-  0018,1049  ContrastBolusConcentration         N
-  0018,1050  SpatialResolution                  N
-  0018,1060  TriggerTime                        N
-  0018,1061  TriggerSourceOrType                N
-  0018,1062  NominalInterval                    N
-  0018,1063  FrameTime                          N
-  0018,1064  CardiacFramingType                 N
-  0018,1065  FrameTimeVector                    N
-  0018,1066  FrameDelay                         N
-  0018,1067  ImageTriggerDelay                  N
-  0018,1068  MultiplexGroupTimeOffset           N
-  0018,1069  TriggerTimeOffset                  N
-  0018,106A  SynchronizationTrigger             N
-  0018,106C  SynchronizationChannel             N
-  0018,106E  TriggerSamplePosition              N
-  0018,1070  RadiopharmaceuticalRoute           N
-  0018,1071  RadiopharmaceuticalVolume          N
-  0018,1072  RadiopharmaceuticalStartTime       N
-  0018,1073  RadiopharmaceuticalStopTime        N
-  0018,1074  RadionuclideTotalDose              N
-  0018,1075  RadionuclideHalfLife               N
-  0018,1076  RadionuclidePositronFraction       N
-  0018,1077  RadiopharmaceuticalSpecActivity    N
-  0018,1078  RadiopharmaceuticalStartDateTime   N
-  0018,1079  RadiopharmaceuticalStopDateTime    N
-  0018,1080  BeatRejectionFlag                  N
-  0018,1081  LowRRValue                         N
-  0018,1082  HighRRValue                        N
-  0018,1083  IntervalsAcquired                  N
-  0018,1084  IntervalsRejected                  N
-  0018,1085  PVCRejection                       N
-  0018,1086  SkipBeats                          N
-  0018,1088  HeartRate                          N
-  0018,1090  CardiacNumberOfImages              N
-  0018,1094  TriggerWindow                      N
-  0018,1100  ReconstructionDiameter             N
-  0018,1110  DistanceSourceToDetector           N
-  0018,1111  DistanceSourceToPatient            N
-  0018,1114  EstimatedRadiographicMagnification N
-  0018,1120  GantryDetectorTilt                 N
-  0018,1121  GantryDetectorSlew                 N
-  0018,1130  TableHeight                        N
-  0018,1131  TableTraverse                      N
-  0018,1134  TableMotion                        N
-  0018,1135  TableVerticalIncrement             N
-  0018,1136  TableLateralIncrement              N
-  0018,1137  TableLongitudinalIncrement         N
-  0018,1138  TableAngle                         N
-  0018,113A  TableType                          N
-  0018,1140  RotationDirection                  N
-  0018,1141  AngularPosition                    N
-  0018,1142  RadialPosition                     N
-  0018,1143  ScanArc                            N
-  0018,1144  AngularStep                        N
-  0018,1145  CenterOfRotationOffset             N
-  0018,1146  RotationOffset                     N
-  0018,1147  FieldOfViewShape                   N
-  0018,1149  FieldOfViewDimensions              N
-  0018,1150  ExposureTime                       N
-  0018,1151  XRayTubeCurrent                    N
-  0018,1152  Exposure                           N
-  0018,1153  ExposureInMicroAmpSec              N
-  0018,1154  AveragePulseWidth                  N
-  0018,1155  RadiationSetting                   N
-  0018,1156  RectificationType                  N
-  0018,115A  RadiationMode                      N
-  0018,115E  ImageAreaDoseProduct               N
-  0018,1160  FilterType                         N
-  0018,1161  TypeOfFilters                      N
-  0018,1162  IntensifierSize                    N
-  0018,1164  ImagerPixelSpacing                 N
-  0018,1166  Grid                               N
-  0018,1170  GeneratorPower                     N
-  0018,1180  CollimatorGridName                 N
-  0018,1181  CollimatorType                     N
-  0018,1182  FocalDistance                      N
-  0018,1183  XFocusCenter                       N
-  0018,1184  YFocusCenter                       N
-  0018,1190  FocalSpots                         N
-  0018,1191  AnodeTargetMaterial                N
-  0018,11A0  BodyPartThickness                  N
-  0018,11A2  CompressionForce                   N
-  0018,1200  DateOfLastCalibration              N
-  0018,1201  TimeOfLastCalibration              N
-  0018,1210  ConvolutionKernel                  N
-  0018,1240  UpperLowerPixelValues              N
-  0018,1242  ActualFrameDuration                N
-  0018,1243  CountRate                          N
-  0018,1244  PreferredPlaybackSequencing        N
-  0018,1250  ReceiveCoilName                    N
-  0018,1251  TransmitCoilName                   N
-  0018,1260  PlateType                          N
-  0018,1261  PhosphorType                       N
-  0018,1300  ScanVelocity                       N
-  0018,1301  WholeBodyTechnique                 N
-  0018,1302  ScanLength                         N
-  0018,1310  AcquisitionMatrix                  N
-  0018,1312  InPlanePhaseEncodingDirection      N
-  0018,1314  FlipAngle                          N
-  0018,1315  VariableFlipAngleFlag              N
-  0018,1316  SAR                                N
-  0018,1318  DB-Dt                              N
-  0018,1400  AcquisitionDeviceProcessingDescr   N
-  0018,1401  AcquisitionDeviceProcessingCode    N
-  0018,1402  CassetteOrientation                N
-  0018,1403  CassetteSize                       N
-  0018,1404  ExposuresOnPlate                   N
-  0018,1405  RelativeXRayExposure               N
-  0018,1450  ColumnAngulation                   N
-  0018,1460  TomoLayerHeight                    N
-  0018,1470  TomoAngle                          N
-  0018,1480  TomoTime                           N
-  0018,1490  TomoType                           N
-  0018,1491  TomoClass                          N
-  0018,1495  NumberOfTomosynthesisSourceImages  N
-  0018,1500  PositionerMotion                   N
-  0018,1508  PositionerType                     N
-  0018,1510  PositionerPrimaryAngle             N
-  0018,1511  PositionerSecondaryAngle           N
-  0018,1520  PositionerPrimaryAngleIncrement    N
-  0018,1521  PositionerSecondaryAngleIncrement  N
-  0018,1530  DetectorPrimaryAngle               N
-  0018,1531  DetectorSecondaryAngle             N
-  0018,1600  ShutterShape                       N
-  0018,1602  ShutterLeftVerticalEdge            N
-  0018,1604  ShutterRightVerticalEdge           N
-  0018,1606  ShutterUpperHorizontalEdge         N
-  0018,1608  ShutterLowerHorizontalEdge         N
-  0018,1610  CenterOfCircularShutter            N
-  0018,1612  RadiusOfCircularShutter            N
-  0018,1620  VerticesOfPolygonalShutter         N
-  0018,1622  ShutterPresentationValue           N
-  0018,1623  ShutterOverlayGroup                N
-  0018,1624  ShutterPresentationColorCIELabVal  N
-  0018,1700  CollimatorShape                    N
-  0018,1702  CollimatorLeftVerticalEdge         N
-  0018,1704  CollimatorRightVerticalEdge        N
-  0018,1706  CollimatorUpperHorizontalEdge      N
-  0018,1708  CollimatorLowerHorizontalEdge      N
-  0018,1710  CenterOfCircularCollimator         N
-  0018,1712  RadiusOfCircularCollimator         N
-  0018,1720  VerticesOfPolygonalCollimator      N
-  0018,1800  AcquisitionTimeSynchronized        N
-  0018,1801  TimeSource                         N
-  0018,1802  TimeDistributionProtocol           N
-  0018,1803  NTPSourceAddress                   N
-  0018,2001  PageNumberVector                   N
-  0018,2002  FrameLabelVector                   N
-  0018,2003  FramePrimaryAngleVector            N
-  0018,2004  FrameSecondaryAngleVector          N
-  0018,2005  SliceLocationVector                N
-  0018,2006  DisplayWindowLabelVector           N
-  0018,2010  NominalScannedPixelSpacing         N
-  0018,2020  DigitizingDeviceTransportDirection N
-  0018,2030  RotationOfScannedFilm              N
-  0018,3100  IVUSAcquisition                    N
-  0018,3101  IVUSPullbackRate                   N
-  0018,3102  IVUSGatedRate                      N
-  0018,3103  IVUSPullbackStartFrameNumber       N
-  0018,3104  IVUSPullbackStopFrameNumber        N
-  0018,3105  LesionNumber                       N
-  0018,4000  AcquisitionComments                N
-  0018,5000  OutputPower                        N
-  0018,5010  TransducerData                     N
-  0018,5012  FocusDepth                         N
-  0018,5020  ProcessingFunction                 N
-  0018,5021  PostprocessingFunction             N
-  0018,5022  MechanicalIndex                    N
-  0018,5024  BoneThermalIndex                   N
-  0018,5026  CranialThermalIndex                N
-  0018,5027  SoftTissueThermalIndex             N
-  0018,5028  SoftTissueFocusThermalIndex        N
-  0018,5029  SoftTissueSurfaceThermalIndex      N
-  0018,5030  DynamicRange                       N
-  0018,5040  TotalGain                          N
-  0018,5050  DepthOfScanField                   N
-  0018,5100  PatientPosition                    N
-  0018,5101  ViewPosition                       N
-  0018,5104  ProjectionEponymousNameCodeSeq     N
-  0018,5210  ImageTransformationMatrix          N
-  0018,5212  ImageTranslationVector             N
-  0018,6000  Sensitivity                        N
-  0018,6011  SequenceOfUltrasoundRegions        N
-  0018,6012  RegionSpatialFormat                N
-  0018,6014  RegionDataType                     N
-  0018,6016  RegionFlags                        N
-  0018,6018  RegionLocationMinX0                N
-  0018,601A  RegionLocationMinY0                N
-  0018,601C  RegionLocationMaxX1                N
-  0018,601E  RegionLocationMaxY1                N
-  0018,6020  ReferencePixelX0                   N
-  0018,6022  ReferencePixelY0                   N
-  0018,6024  PhysicalUnitsXDirection            N
-  0018,6026  PhysicalUnitsYDirection            N
-  0018,6028  ReferencePixelPhysicalValueX       N
-  0018,602A  ReferencePixelPhysicalValueY       N
-  0018,602C  PhysicalDeltaX                     N
-  0018,602E  PhysicalDeltaY                     N
-  0018,6030  TransducerFrequency                N
-  0018,6031  TransducerType                     N
-  0018,6032  PulseRepetitionFrequency           N
-  0018,6034  DopplerCorrectionAngle             N
-  0018,6036  SteeringAngle                      N
-  0018,6038  DopplerSampleVolumeXPosRetired     N
-  0018,6039  DopplerSampleVolumeXPosition       N
-  0018,603A  DopplerSampleVolumeYPosRetired     N
-  0018,603B  DopplerSampleVolumeYPosition       N
-  0018,603C  TMLinePositionX0Retired            N
-  0018,603D  TMLinePositionX0                   N
-  0018,603E  TMLinePositionY0Retired            N
-  0018,603F  TMLinePositionY0                   N
-  0018,6040  TMLinePositionX1Retired            N
-  0018,6041  TMLinePositionX1                   N
-  0018,6042  TMLinePositionY1Retired            N
-  0018,6043  TMLinePositionY1                   N
-  0018,6044  PixelComponentOrganization         N
-  0018,6046  PixelComponentMask                 N
-  0018,6048  PixelComponentRangeStart           N
-  0018,604A  PixelComponentRangeStop            N
-  0018,604C  PixelComponentPhysicalUnits        N
-  0018,604E  PixelComponentDataType             N
-  0018,6050  NumberOfTableBreakPoints           N
-  0018,6052  TableOfXBreakPoints                N
-  0018,6054  TableOfYBreakPoints                N
-  0018,6056  NumberOfTableEntries               N
-  0018,6058  TableOfPixelValues                 N
-  0018,605A  TableOfParameterValues             N
-  0018,6060  RWaveTimeVector                    N
-  0018,7000  DetectorConditionsNominalFlag      N
-  0018,7001  DetectorTemperature                N
-  0018,7004  DetectorType                       N
-  0018,7005  DetectorConfiguration              N
-  0018,7006  DetectorDescription                N
-  0018,7008  DetectorMode                       N
-  0018,700A  DetectorID                         N
-  0018,700C  DateOfLastDetectorCalibration      N
-  0018,700E  TimeOfLastDetectorCalibration      N
-  0018,7010  DetectorExposuresSinceCalibration  N
-  0018,7011  DetectorExposuresSinceManufactured N
-  0018,7012  DetectorTimeSinceLastExposure      N
-  0018,7014  DetectorActiveTime                 N
-  0018,7016  DetectorActiveOffsetFromExposure   N
-  0018,701A  DetectorBinning                    N
-  0018,7020  DetectorElementPhysicalSize        N
-  0018,7022  DetectorElementSpacing             N
-  0018,7024  DetectorActiveShape                N
-  0018,7026  DetectorActiveDimensions           N
-  0018,7028  DetectorActiveOrigin               N
-  0018,702A  DetectorManufacturerName           N
-  0018,702B  DetectorManufacturersModelName     N
-  0018,7030  FieldOfViewOrigin                  N
-  0018,7032  FieldOfViewRotation                N
-  0018,7034  FieldOfViewHorizontalFlip          N
-  0018,7040  GridAbsorbingMaterial              N
-  0018,7041  GridSpacingMaterial                N
-  0018,7042  GridThickness                      N
-  0018,7044  GridPitch                          N
-  0018,7046  GridAspectRatio                    N
-  0018,7048  GridPeriod                         N
-  0018,704C  GridFocalDistance                  N
-  0018,7050  FilterMaterial                     N
-  0018,7052  FilterThicknessMinimum             N
-  0018,7054  FilterThicknessMaximum             N
-  0018,7060  ExposureControlMode                N
-  0018,7062  ExposureControlModeDescription     N
-  0018,7064  ExposureStatus                     N
-  0018,7065  PhototimerSetting                  N
-  0018,8150  ExposureTimeInMicroSec             N
-  0018,8151  XRayTubeCurrentInMicroAmps         N
-  0018,9004  ContentQualification               N
-  0018,9005  PulseSequenceName                  N
-  0018,9006  MRImagingModifierSequence          N
-  0018,9008  EchoPulseSequence                  N
-  0018,9009  InversionRecovery                  N
-  0018,9010  FlowCompensation                   N
-  0018,9011  MultipleSpinEcho                   N
-  0018,9012  MultiPlanarExcitation              N
-  0018,9014  PhaseContrast                      N
-  0018,9015  TimeOfFlightContrast               N
-  0018,9016  Spoiling                           N
-  0018,9017  SteadyStatePulseSequence           N
-  0018,9018  EchoPlanarPulseSequence            N
-  0018,9019  TagAngleFirstAxis                  N
-  0018,9020  MagnetizationTransfer              N
-  0018,9021  T2Preparation                      N
-  0018,9022  BloodSignalNulling                 N
-  0018,9024  SaturationRecovery                 N
-  0018,9025  SpectrallySelectedSuppression      N
-  0018,9026  SpectrallySelectedExcitation       N
-  0018,9027  SpatialPresaturation               N
-  0018,9028  Tagging                            N
-  0018,9029  OversamplingPhase                  N
-  0018,9030  TagSpacingFirstDimension           N
-  0018,9032  GeometryOfKSpaceTraversal          N
-  0018,9033  SegmentedKSpaceTraversal           N
-  0018,9034  RectilinearPhaseEncodeReordering   N
-  0018,9035  TagThickness                       N
-  0018,9036  PartialFourierDirection            N
-  0018,9037  CardiacSynchronizationTechnique    N
-  0018,9041  ReceiveCoilManufacturerName        N
-  0018,9042  MRReceiveCoilSequence              N
-  0018,9043  ReceiveCoilType                    N
-  0018,9044  QuadratureReceiveCoil              N
-  0018,9045  MultiCoilDefinitionSequence        N
-  0018,9046  MultiCoilConfiguration             N
-  0018,9047  MultiCoilElementName               N
-  0018,9048  MultiCoilElementUsed               N
-  0018,9049  MRTransmitCoilSequence             N
-  0018,9050  TransmitCoilManufacturerName       N
-  0018,9051  TransmitCoilType                   N
-  0018,9052  SpectralWidth                      N
-  0018,9053  ChemicalShiftReference             N
-  0018,9054  VolumeLocalizationTechnique        N
-  0018,9058  MRAcquisitionFrequencyEncodeSteps  N
-  0018,9059  Decoupling                         N
-  0018,9060  DecoupledNucleus                   N
-  0018,9061  DecouplingFrequency                N
-  0018,9062  DecouplingMethod                   N
-  0018,9063  DecouplingChemicalShiftReference   N
-  0018,9064  KSpaceFiltering                    N
-  0018,9065  TimeDomainFiltering                N
-  0018,9066  NumberOfZeroFills                  N
-  0018,9067  BaselineCorrection                 N
-  0018,9069  ParallelReductionFactorInPlane     N
-  0018,9070  CardiacRRIntervalSpecified         N
-  0018,9073  AcquisitionDuration                N
-  0018,9074  FrameAcquisitionDateTime           N
-  0018,9075  DiffusionDirectionality            N
-  0018,9076  DiffusionGradientDirectionSequence N
-  0018,9077  ParallelAcquisition                N
-  0018,9078  ParallelAcquisitionTechnique       N
-  0018,9079  InversionTimes                     N
-  0018,9080  MetaboliteMapDescription           N
-  0018,9081  PartialFourier                     N
-  0018,9082  EffectiveEchoTime                  N
-  0018,9083  MetaboliteMapCodeSequence          N
-  0018,9084  ChemicalShiftSequence              N
-  0018,9085  CardiacSignalSource                N
-  0018,9087  DiffusionBValue                    N
-  0018,9089  DiffusionGradientOrientation       N
-  0018,9090  VelocityEncodingDirection          N
-  0018,9091  VelocityEncodingMinimumValue       N
-  0018,9093  NumberOfKSpaceTrajectories         N
-  0018,9094  CoverageOfKSpace                   N
-  0018,9095  SpectroscopyAcquisitionPhaseRows   N
-  0018,9096  ParallelReductFactorInPlaneRetired N
-  0018,9098  TransmitterFrequency               N
-  0018,9100  ResonantNucleus                    N
-  0018,9101  FrequencyCorrection                N
-  0018,9103  MRSpectroscopyFOV-GeometrySequence N
-  0018,9104  SlabThickness                      N
-  0018,9105  SlabOrientation                    N
-  0018,9106  MidSlabPosition                    N
-  0018,9107  MRSpatialSaturationSequence        N
-  0018,9112  MRTimingAndRelatedParametersSeq    N
-  0018,9114  MREchoSequence                     N
-  0018,9115  MRModifierSequence                 N
-  0018,9117  MRDiffusionSequence                N
-  0018,9118  CardiacTriggerSequence             N
-  0018,9119  MRAveragesSequence                 N
-  0018,9125  MRFOV-GeometrySequence             N
-  0018,9126  VolumeLocalizationSequence         N
-  0018,9127  SpectroscopyAcquisitionDataColumns N
-  0018,9147  DiffusionAnisotropyType            N
-  0018,9151  FrameReferenceDateTime             N
-  0018,9152  MRMetaboliteMapSequence            N
-  0018,9155  ParallelReductionFactorOutOfPlane  N
-  0018,9159  SpectroscopyOutOfPlanePhaseSteps   N
-  0018,9166  BulkMotionStatus                   N
-  0018,9168  ParallelReductionFactSecondInPlane N
-  0018,9169  CardiacBeatRejectionTechnique      N
-  0018,9170  RespiratoryMotionCompTechnique     N
-  0018,9171  RespiratorySignalSource            N
-  0018,9172  BulkMotionCompensationTechnique    N
-  0018,9173  BulkMotionSignalSource             N
-  0018,9174  ApplicableSafetyStandardAgency     N
-  0018,9175  ApplicableSafetyStandardDescr      N
-  0018,9176  OperatingModeSequence              N
-  0018,9177  OperatingModeType                  N
-  0018,9178  OperatingMode                      N
-  0018,9179  SpecificAbsorptionRateDefinition   N
-  0018,9180  GradientOutputType                 N
-  0018,9181  SpecificAbsorptionRateValue        N
-  0018,9182  GradientOutput                     N
-  0018,9183  FlowCompensationDirection          N
-  0018,9184  TaggingDelay                       N
-  0018,9185  RespiratoryMotionCompTechDescr     N
-  0018,9186  RespiratorySignalSourceID          N
-  0018,9195  ChemicalShiftsMinIntegrateLimitHz  N
-  0018,9196  ChemicalShiftsMaxIntegrateLimitHz  N
-  0018,9197  MRVelocityEncodingSequence         N
-  0018,9198  FirstOrderPhaseCorrection          N
-  0018,9199  WaterReferencedPhaseCorrection     N
-  0018,9200  MRSpectroscopyAcquisitionType      N
-  0018,9214  RespiratoryCyclePosition           N
-  0018,9217  VelocityEncodingMaximumValue       N
-  0018,9218  TagSpacingSecondDimension          N
-  0018,9219  TagAngleSecondAxis                 N
-  0018,9220  FrameAcquisitionDuration           N
-  0018,9226  MRImageFrameTypeSequence           N
-  0018,9227  MRSpectroscopyFrameTypeSequence    N
-  0018,9231  MRAcqPhaseEncodingStepsInPlane     N
-  0018,9232  MRAcqPhaseEncodingStepsOutOfPlane  N
-  0018,9234  SpectroscopyAcqPhaseColumns        N
-  0018,9236  CardiacCyclePosition               N
-  0018,9239  SpecificAbsorptionRateSequence     N
-  0018,9240  RFEchoTrainLength                  N
-  0018,9241  GradientEchoTrainLength            N
-  0018,9295  ChemicalShiftsMinIntegrateLimitPPM N
-  0018,9296  ChemicalShiftsMaxIntegrateLimitPPM N
-  0018,9301  CTAcquisitionTypeSequence          N
-  0018,9302  AcquisitionType                    N
-  0018,9303  TubeAngle                          N
-  0018,9304  CTAcquisitionDetailsSequence       N
-  0018,9305  RevolutionTime                     N
-  0018,9306  SingleCollimationWidth             N
-  0018,9307  TotalCollimationWidth              N
-  0018,9308  CTTableDynamicsSequence            N
-  0018,9309  TableSpeed                         N
-  0018,9310  TableFeedPerRotation               N
-  0018,9311  SpiralPitchFactor                  N
-  0018,9312  CTGeometrySequence                 N
-  0018,9313  DataCollectionCenterPatient        N
-  0018,9314  CTReconstructionSequence           N
-  0018,9315  ReconstructionAlgorithm            N
-  0018,9316  ConvolutionKernelGroup             N
-  0018,9317  ReconstructionFieldOfView          N
-  0018,9318  ReconstructionTargetCenterPatient  N
-  0018,9319  ReconstructionAngle                N
-  0018,9320  ImageFilter                        N
-  0018,9321  CTExposureSequence                 N
-  0018,9322  ReconstructionPixelSpacing         N
-  0018,9323  ExposureModulationType             N
-  0018,9324  EstimatedDoseSaving                N
-  0018,9325  CTXRayDetailsSequence              N
-  0018,9326  CTPositionSequence                 N
-  0018,9327  TablePosition                      N
-  0018,9328  ExposureTimeInMilliSec             N
-  0018,9329  CTImageFrameTypeSequence           N
-  0018,9330  XRayTubeCurrentInMilliAmps         N
-  0018,9332  ExposureInMilliAmpSec              N
-  0018,9333  ConstantVolumeFlag                 N
-  0018,9334  FluoroscopyFlag                    N
-  0018,9335  SourceToDataCollectionCenterDist   N
-  0018,9337  ContrastBolusAgentNumber           N
-  0018,9338  ContrastBolusIngredientCodeSeq     N
-  0018,9340  ContrastAdministrationProfileSeq   N
-  0018,9341  ContrastBolusUsageSequence         N
-  0018,9342  ContrastBolusAgentAdministered     N
-  0018,9343  ContrastBolusAgentDetected         N
-  0018,9344  ContrastBolusAgentPhase            N
-  0018,9345  CTDIvol                            N
-  0018,9346  CTDIPhantomTypeCodeSequence        N
-  0018,9351  CalciumScoringMassFactorPatient    N
-  0018,9352  CalciumScoringMassFactorDevice     N
-  0018,9353  EnergyWeightingFactor              N
-  0018,9360  CTAdditionalXRaySourceSequence     N
-  0018,9401  ProjectionPixelCalibrationSequence N
-  0018,9402  DistanceSourceToIsocenter          N
-  0018,9403  DistanceObjectToTableTop           N
-  0018,9404  ObjectPixelSpacingInCenterOfBeam   N
-  0018,9405  PositionerPositionSequence         N
-  0018,9406  TablePositionSequence              N
-  0018,9407  CollimatorShapeSequence            N
-  0018,9412  XA-XRFFrameCharacteristicsSequence N
-  0018,9417  FrameAcquisitionSequence           N
-  0018,9420  XRayReceptorType                   N
-  0018,9423  AcquisitionProtocolName            N
-  0018,9424  AcquisitionProtocolDescription     N
-  0018,9425  ContrastBolusIngredientOpaque      N
-  0018,9426  DistanceReceptorPlaneToDetHousing  N
-  0018,9427  IntensifierActiveShape             N
-  0018,9428  IntensifierActiveDimensions        N
-  0018,9429  PhysicalDetectorSize               N
-  0018,9430  PositionOfIsocenterProjection      N
-  0018,9432  FieldOfViewSequence                N
-  0018,9433  FieldOfViewDescription             N
-  0018,9434  ExposureControlSensingRegionsSeq   N
-  0018,9435  ExposureControlSensingRegionShape  N
-  0018,9436  ExposureControlSensRegionLeftEdge  N
-  0018,9437  ExposureControlSensRegionRightEdge N
-  0018,9440  CenterOfCircExposControlSensRegion N
-  0018,9441  RadiusOfCircExposControlSensRegion N
-  0018,9447  ColumnAngulationPatient            N
-  0018,9449  BeamAngle                          N
-  0018,9451  FrameDetectorParametersSequence    N
-  0018,9452  CalculatedAnatomyThickness         N
-  0018,9455  CalibrationSequence                N
-  0018,9456  ObjectThicknessSequence            N
-  0018,9457  PlaneIdentification                N
-  0018,9461  FieldOfViewDimensionsInFloat       N
-  0018,9462  IsocenterReferenceSystemSequence   N
-  0018,9463  PositionerIsocenterPrimaryAngle    N
-  0018,9464  PositionerIsocenterSecondaryAngle  N
-  0018,9465  PositionerIsocenterDetRotAngle     N
-  0018,9466  TableXPositionToIsocenter          N
-  0018,9467  TableYPositionToIsocenter          N
-  0018,9468  TableZPositionToIsocenter          N
-  0018,9469  TableHorizontalRotationAngle       N
-  0018,9470  TableHeadTiltAngle                 N
-  0018,9471  TableCradleTiltAngle               N
-  0018,9472  FrameDisplayShutterSequence        N
-  0018,9473  AcquiredImageAreaDoseProduct       N
-  0018,9474  CArmPositionerTabletopRelationship N
-  0018,9476  XRayGeometrySequence               N
-  0018,9477  IrradiationEventIDSequence         N
-  0018,9504  XRay3DFrameTypeSequence            N
-  0018,9506  ContributingSourcesSequence        N
-  0018,9507  XRay3DAcquisitionSequence          N
-  0018,9508  PrimaryPositionerScanArc           N
-  0018,9509  SecondaryPositionerScanArc         N
-  0018,9510  PrimaryPositionerScanStartAngle    N
-  0018,9511  SecondaryPositionerScanStartAngle  N
-  0018,9514  PrimaryPositionerIncrement         N
-  0018,9515  SecondaryPositionerIncrement       N
-  0018,9516  StartAcquisitionDateTime           N
-  0018,9517  EndAcquisitionDateTime             N
-  0018,9524  ApplicationName                    N
-  0018,9525  ApplicationVersion                 N
-  0018,9526  ApplicationManufacturer            N
-  0018,9527  AlgorithmType                      N
-  0018,9528  AlgorithmDescription               N
-  0018,9530  XRay3DReconstructionSequence       N
-  0018,9531  ReconstructionDescription          N
-  0018,9538  PerProjectionAcquisitionSequence   N
-  0018,9601  DiffusionBMatrixSequence           N
-  0018,9602  DiffusionBValueXX                  N
-  0018,9603  DiffusionBValueXY                  N
-  0018,9604  DiffusionBValueXZ                  N
-  0018,9605  DiffusionBValueYY                  N
-  0018,9606  DiffusionBValueYZ                  N
-  0018,9607  DiffusionBValueZZ                  N
-  0018,9701  DecayCorrectionDateTime            N
-  0018,9715  StartDensityThreshold              N
-  0018,9722  TerminationTimeThreshold           N
-  0018,9725  DetectorGeometry                   N
-  0018,9727  AxialDetectorDimension             N
-  0018,9735  PETPositionSequence                N
-  0018,9739  NumberOfIterations                 N
-  0018,9740  NumberOfSubsets                    N
-  0018,9751  PETFrameTypeSequence               N
-  0018,9756  ReconstructionType                 N
-  0018,9758  DecayCorrected                     N
-  0018,9759  AttenuationCorrected               N
-  0018,9760  ScatterCorrected                   N
-  0018,9761  DeadTimeCorrected                  N
-  0018,9762  GantryMotionCorrected              N
-  0018,9763  PatientMotionCorrected             N
-  0018,9765  RandomsCorrected                   N
-  0018,9767  SensitivityCalibrated              N
-  0018,9801  DepthsOfFocus                      N
-  0018,9804  ExclusionStartDatetime             N
-  0018,9805  ExclusionDuration                  N
-  0018,9807  ImageDataTypeSequence              N
-  0018,9808  DataType                           N
-  0018,980B  AliasedDataType                    N
-  0018,A001  ContributingEquipmentSequence      N
-  0018,A002  ContributionDateTime               N
-  0018,A003  ContributionDescription            N
-  0019,1002  NumberOfCellsIInDetector           N
-  0019,1003  CellNumberAtTheta                  N
-  0019,1004  CellSpacing                        N
-  0019,100F  HorizFrameOfRef                    N
-  0019,1011  SeriesContrast                     N
-  0019,1012  LastPseq                           N
-  0019,1013  StartNumberForBaseline             N
-  0019,1014  EndNumberForBaseline               N
-  0019,1015  StartNumberForEnhancedScans        N
-  0019,1016  EndNumberForEnhancedScans          N
-  0019,1017  SeriesPlane                        N
-  0019,1018  FirstScanRas                       N
-  0019,1019  FirstScanLocation                  N
-  0019,101A  LastScanRas                        N
-  0019,101B  LastScanLoc                        N
-  0019,101E  DisplayFieldOfView                 N
-  0019,1023  TableSpeed                         N
-  0019,1024  MidScanTime                        N
-  0019,1025  MidScanFlag                        N
-  0019,1026  DegreesOfAzimuth                   N
-  0019,1027  GantryPeriod                       N
-  0019,102A  XRayOnPosition                     N
-  0019,102B  XRayOffPosition                    N
-  0019,102C  NumberOfTriggers                   N
-  0019,102E  AngleOfFirstView                   N
-  0019,102F  TriggerFrequency                   N
-  0019,1039  ScanFOVType                        N
-  0019,1040  StatReconFlag                      N
-  0019,1041  ComputeType                        N
-  0019,1042  SegmentNumber                      N
-  0019,1043  TotalSegmentsRequested             N
-  0019,1044  InterscanDelay                     N
-  0019,1047  ViewCompressionFactor              N
-  0019,104A  TotalNoOfRefChannels               N
-  0019,104B  DataSizeForScanData                N
-  0019,1052  ReconPostProcflag                  N
-  0019,1057  CTWaterNumber                      N
-  0019,1058  CTBoneNumber                       N
-  0019,105A  AcquisitionDuration                N
-  0019,105E  NumberOfChannels                   N
-  0019,105F  IncrementBetweenChannels           N
-  0019,1060  StartingView                       N
-  0019,1061  NumberOfViews                      N
-  0019,1062  IncrementBetweenViews              N
-  0019,106A  DependantOnNoViewsProcessed        N
-  0019,106B  FieldOfViewInDetectorCells         N
-  0019,1070  ValueOfBackProjectionButton        N
-  0019,1071  SetIfFatqEstimatesWereUsed         N
-  0019,1072  ZChanAvgOverViews                  N
-  0019,1073  AvgOfLeftRefChansOverViews         N
-  0019,1074  MaxLeftChanOverViews               N
-  0019,1075  AvgOfRightRefChansOverViews        N
-  0019,1076  MaxRightChanOverViews              N
-  0019,107D  SecondEcho                         N
-  0019,107E  NumberOfEchoes                     N
-  0019,107F  TableDelta                         N
-  0019,1081  Contiguous                         N
-  0019,1084  PeakSAR                            N
-  0019,1085  MonitorSAR                         N
-  0019,1087  CardiacRepetitionTime              N
-  0019,1088  ImagesPerCardiacCycle              N
-  0019,108A  ActualReceiveGainAnalog            N
-  0019,108B  ActualReceiveGainDigital           N
-  0019,108D  DelayAfterTrigger                  N
-  0019,108F  Swappf                             N
-  0019,1090  PauseInterval                      N
-  0019,1091  PulseTime                          N
-  0019,1092  SliceOffsetOnFreqAxis              N
-  0019,1093  CenterFrequency                    N
-  0019,1094  TransmitGain                       N
-  0019,1095  AnalogReceiverGain                 N
-  0019,1096  DigitalReceiverGain                N
-  0019,1097  BitmapDefiningCVs                  N
-  0019,1098  CenterFreqMethod                   N
-  0019,109B  PulseSeqMode                       N
-  0019,109C  PulseSeqName                       N
-  0019,109D  PulseSeqDate                       N
-  0019,109E  InternalPulseSeqName               N
-  0019,109F  TransmittingCoil                   N
-  0019,10A0  SurfaceCoilType                    N
-  0019,10A1  ExtremityCoilFlag                  N
-  0019,10A2  RawDataRunNumber                   N
-  0019,10A3  CalibratedFieldStrength            N
-  0019,10A4  SATFatWaterBone                    N
-  0019,10A5  ReceiveBandwidth                   N
-  0019,10A7  UserData01                         N
-  0019,10A8  UserData02                         N
-  0019,10A9  UserData03                         N
-  0019,10AA  UserData04                         N
-  0019,10AB  UserData05                         N
-  0019,10AC  UserData06                         N
-  0019,10AD  UserData07                         N
-  0019,10AE  UserData08                         N
-  0019,10AF  UserData09                         N
-  0019,10B0  UserData10                         N
-  0019,10B1  UserData11                         N
-  0019,10B2  UserData12                         N
-  0019,10B3  UserData13                         N
-  0019,10B4  UserData14                         N
-  0019,10B5  UserData15                         N
-  0019,10B6  UserData16                         N
-  0019,10B7  UserData17                         N
-  0019,10B8  UserData18                         N
-  0019,10B9  UserData19                         N
-  0019,10BA  UserData20                         N
-  0019,10BB  UserData21                         N
-  0019,10BC  UserData22                         N
-  0019,10BD  UserData23                         N
-  0019,10BE  ProjectionAngle                    N
-  0019,10C0  SaturationPlanes                   N
-  0019,10C1  SurfaceCoilIntensity               N
-  0019,10C2  SATLocationR                       N
-  0019,10C3  SATLocationL                       N
-  0019,10C4  SATLocationA                       N
-  0019,10C5  SATLocationP                       N
-  0019,10C6  SATLocationH                       N
-  0019,10C7  SATLocationF                       N
-  0019,10C8  SATThicknessR-L                    N
-  0019,10C9  SATThicknessA-P                    N
-  0019,10CA  SATThicknessH-F                    N
-  0019,10CB  PrescribedFlowAxis                 N
-  0019,10CC  VelocityEncoding                   N
-  0019,10CD  ThicknessDisclaimer                N
-  0019,10CE  PrescanType                        N
-  0019,10CF  PrescanStatus                      N
-  0019,10D0  RawDataType                        N
-  0019,10D2  ProjectionAlgorithm                N
-  0019,10D3  ProjectionAlgorithm                N
-  0019,10D5  FractionalEcho                     N
-  0019,10D6  PrepPulse                          N
-  0019,10D7  CardiacPhases                      N
-  0019,10D8  VariableEchoflag                   N
-  0019,10D9  ConcatenatedSAT                    N
-  0019,10DA  ReferenceChannelUsed               N
-  0019,10DB  BackProjectorCoefficient           N
-  0019,10DC  PrimarySpeedCorrectionUsed         N
-  0019,10DD  OverrangeCorrectionUsed            N
-  0019,10DE  DynamicZAlphaValue                 N
-  0019,10DF  UserData                           N
-  0019,10E0  UserData                           N
-  0019,10E2  VelocityEncodeScale                N
-  0019,10F2  FastPhases                         N
-  0019,10F9  TransmissionGain                   N
-  0020,0000  RelationshipGroupLength            N
-  0020,000D  StudyInstanceUID                   N
-  0020,000E  SeriesInstanceUID                  N
-  0020,0010  StudyID                            N
-  0020,0011  SeriesNumber                       N
-  0020,0012  AcquisitionNumber                  N
-  0020,0013  InstanceNumber                     N
-  0020,0014  IsotopeNumber                      N
-  0020,0015  PhaseNumber                        N
-  0020,0016  IntervalNumber                     N
-  0020,0017  TimeSlotNumber                     N
-  0020,0018  AngleNumber                        N
-  0020,0019  ItemNumber                         N
-  0020,0020  PatientOrientation                 N
-  0020,0022  OverlayNumber                      N
-  0020,0024  CurveNumber                        N
-  0020,0026  LookupTableNumber                  N
-  0020,0030  ImagePosition                      N
-  0020,0032  ImagePositionPatient               N
-  0020,0035  ImageOrientation                   N
-  0020,0037  ImageOrientationPatient            N
-  0020,0050  Location                           N
-  0020,0052  FrameOfReferenceUID                N
-  0020,0060  Laterality                         N
-  0020,0062  ImageLaterality                    N
-  0020,0070  ImageGeometryType                  N
-  0020,0080  MaskingImage                       N
-  0020,0100  TemporalPositionIdentifier         N
-  0020,0105  NumberOfTemporalPositions          N
-  0020,0110  TemporalResolution                 N
-  0020,0200  SynchronizationFrameOfReferenceUID N
-  0020,1000  SeriesInStudy                      N
-  0020,1001  AcquisitionsInSeries               N
-  0020,1002  ImagesInAcquisition                N
-  0020,1003  ImagesInSeries                     N
-  0020,1004  AcquisitionsInStudy                N
-  0020,1005  ImagesInStudy                      N
-  0020,1020  Reference                          N
-  0020,1040  PositionReferenceIndicator         N
-  0020,1041  SliceLocation                      N
-  0020,1070  OtherStudyNumbers                  N
-  0020,1200  NumberOfPatientRelatedStudies      N
-  0020,1202  NumberOfPatientRelatedSeries       N
-  0020,1204  NumberOfPatientRelatedInstances    N
-  0020,1206  NumberOfStudyRelatedSeries         N
-  0020,1208  NumberOfStudyRelatedInstances      N
-  0020,1209  NumberOfSeriesRelatedInstances     N
-  0020,31xx  SourceImageIDs                     N
-  0020,3401  ModifyingDeviceID                  N
-  0020,3402  ModifiedImageID                    N
-  0020,3403  ModifiedImageDate                  N
-  0020,3404  ModifyingDeviceManufacturer        N
-  0020,3405  ModifiedImageTime                  N
-  0020,3406  ModifiedImageDescription           N
-  0020,4000  ImageComments                      N
-  0020,5000  OriginalImageIdentification        N
-  0020,5002  OriginalImageIdentNomenclature     N
-  0020,9056  StackID                            N
-  0020,9057  InStackPositionNumber              N
-  0020,9071  FrameAnatomySequence               N
-  0020,9072  FrameLaterality                    N
-  0020,9111  FrameContentSequence               N
-  0020,9113  PlanePositionSequence              N
-  0020,9116  PlaneOrientationSequence           N
-  0020,9128  TemporalPositionIndex              N
-  0020,9153  TriggerDelayTime                   N
-  0020,9156  FrameAcquisitionNumber             N
-  0020,9157  DimensionIndexValues               N
-  0020,9158  FrameComments                      N
-  0020,9161  ConcatenationUID                   N
-  0020,9162  InConcatenationNumber              N
-  0020,9163  InConcatenationTotalNumber         N
-  0020,9164  DimensionOrganizationUID           N
-  0020,9165  DimensionIndexPointer              N
-  0020,9167  FunctionalGroupPointer             N
-  0020,9213  DimensionIndexPrivateCreator       N
-  0020,9221  DimensionOrganizationSequence      N
-  0020,9222  DimensionIndexSequence             N
-  0020,9228  ConcatenationFrameOffsetNumber     N
-  0020,9238  FunctionalGroupPrivateCreator      N
-  0020,9241  NominalPercentageOfCardiacPhase    N
-  0020,9245  NominalPercentOfRespiratoryPhase   N
-  0020,9246  StartingRespiratoryAmplitude       N
-  0020,9247  StartingRespiratoryPhase           N
-  0020,9248  EndingRespiratoryAmplitude         N
-  0020,9249  EndingRespiratoryPhase             N
-  0020,9250  RespiratoryTriggerType             N
-  0020,9251  RRIntervalTimeNominal              N
-  0020,9252  ActualCardiacTriggerDelayTime      N
-  0020,9253  RespiratorySynchronizationSequence N
-  0020,9254  RespiratoryIntervalTime            N
-  0020,9255  NominalRespiratoryTriggerDelayTime N
-  0020,9256  RespiratoryTriggerDelayThreshold   N
-  0020,9257  ActualRespiratoryTriggerDelayTime  N
-  0020,9301  ImagePositionVolume                N
-  0020,9302  ImageOrientationVolume             N
-  0020,9308  ApexPosition                       N
-  0020,9421  DimensionDescriptionLabel          N
-  0020,9450  PatientOrientationInFrameSequence  N
-  0020,9453  FrameLabel                         N
-  0020,9518  AcquisitionIndex                   N
-  0020,9529  ContributingSOPInstancesRefSeq     N
-  0020,9536  ReconstructionIndex                N
-  0021,1003  SeriesFromWhichPrescribed          N
-  0021,1005  GenesisVersionNow                  N
-  0021,1007  SeriesRecordChecksum               N
-  0021,1018  GenesisVersionNow                  N
-  0021,1019  AcqreconRecordChecksum             N
-  0021,1020  TableStartLocation                 N
-  0021,1035  SeriesFromWhichPrescribed          N
-  0021,1036  ImageFromWhichPrescribed           N
-  0021,1037  ScreenFormat                       N
-  0021,104A  AnatomicalReferenceForScout        N
-  0021,104F  LocationsInAcquisition             N
-  0021,1050  GraphicallyPrescribed              N
-  0021,1051  RotationFromSourceXRot             N
-  0021,1052  RotationFromSourceYRot             N
-  0021,1053  RotationFromSourceZRot             N
-  0021,1054  ImagePosition                      N
-  0021,1055  ImageOrientation                   N
-  0021,1056  IntegerSlop                        N
-  0021,1057  IntegerSlop                        N
-  0021,1058  IntegerSlop                        N
-  0021,1059  IntegerSlop                        N
-  0021,105A  IntegerSlop                        N
-  0021,105B  FloatSlop                          N
-  0021,105C  FloatSlop                          N
-  0021,105D  FloatSlop                          N
-  0021,105E  FloatSlop                          N
-  0021,105F  FloatSlop                          N
-  0021,1081  AutoWindowLevelAlpha               N
-  0021,1082  AutoWindowLevelBeta                N
-  0021,1083  AutoWindowLevelWindow              N
-  0021,1084  ToWindowLevelLevel                 N
-  0021,1090  TubeFocalSpotPosition              N
-  0021,1091  BiopsyPosition                     N
-  0021,1092  BiopsyTLocation                    N
-  0021,1093  BiopsyRefLocation                  N
-  0022,0001  LightPathFilterPassThroughWavelen  N
-  0022,0002  LightPathFilterPassBand            N
-  0022,0003  ImagePathFilterPassThroughWavelen  N
-  0022,0004  ImagePathFilterPassBand            N
-  0022,0005  PatientEyeMovementCommanded        N
-  0022,0006  PatientEyeMovementCommandCodeSeq   N
-  0022,0007  SphericalLensPower                 N
-  0022,0008  CylinderLensPower                  N
-  0022,0009  CylinderAxis                       N
-  0022,000A  EmmetropicMagnification            N
-  0022,000B  IntraOcularPressure                N
-  0022,000C  HorizontalFieldOfView              N
-  0022,000D  PupilDilated                       N
-  0022,000E  DegreeOfDilation                   N
-  0022,0010  StereoBaselineAngle                N
-  0022,0011  StereoBaselineDisplacement         N
-  0022,0012  StereoHorizontalPixelOffset        N
-  0022,0013  StereoVerticalPixelOffset          N
-  0022,0014  StereoRotation                     N
-  0022,0015  AcquisitionDeviceTypeCodeSequence  N
-  0022,0016  IlluminationTypeCodeSequence       N
-  0022,0017  LightPathFilterTypeStackCodeSeq    N
-  0022,0018  ImagePathFilterTypeStackCodeSeq    N
-  0022,0019  LensesCodeSequence                 N
-  0022,001A  ChannelDescriptionCodeSequence     N
-  0022,001B  RefractiveStateSequence            N
-  0022,001C  MydriaticAgentCodeSequence         N
-  0022,001D  RelativeImagePositionCodeSequence  N
-  0022,0020  StereoPairsSequence                N
-  0022,0021  LeftImageSequence                  N
-  0022,0022  RightImageSequence                 N
-  0022,0030  AxialLengthOfTheEye                N
-  0022,0031  OphthalmicFrameLocationSequence    N
-  0022,0032  ReferenceCoordinates               N
-  0022,0035  DepthSpatialResolution             N
-  0022,0036  MaximumDepthDistortion             N
-  0022,0037  AlongScanSpatialResolution         N
-  0022,0038  MaximumAlongScanDistortion         N
-  0022,0039  OphthalmicImageOrientation         N
-  0022,0041  DepthOfTransverseImage             N
-  0022,0042  MydriaticAgentConcUnitsSeq         N
-  0022,0048  AcrossScanSpatialResolution        N
-  0022,0049  MaximumAcrossScanDistortion        N
-  0022,004E  MydriaticAgentConcentration        N
-  0022,0055  IlluminationWaveLength             N
-  0022,0056  IlluminationPower                  N
-  0022,0057  IlluminationBandwidth              N
-  0022,0058  MydriaticAgentSequence             N
-  0023,1001  NumberOfSeriesInStudy              N
-  0023,1002  NumberOfUnarchivedSeries           N
-  0023,1010  ReferenceImageField                N
-  0023,1050  SummaryImage                       N
-  0023,1070  StartTimeSecsInFirstAxial          N
-  0023,1074  NoofUpdatesToHeader                N
-  0023,107D  IndicatesIfTheStudyHasCompleteInfo N
-  0025,1006  LastPulseSequenceUsed              N
-  0025,1007  ImagesInSeries                     N
-  0025,1010  LandmarkCounter                    N
-  0025,1011  NumberOfAcquisitions               N
-  0025,1014  IndicatesNoofUpdatesToHeader       N
-  0025,1017  SeriesCompleteFlag                 N
-  0025,1018  NumberOfImagesArchived             N
-  0025,1019  LastImageNumberUsed                N
-  0025,101A  PrimaryReceiverSuiteAndHost        N
-  0027,1006  ImageArchiveFlag                   N
-  0027,1010  ScoutType                          N
-  0027,101C  VmaMamp                            N
-  0027,101D  VmaPhase                           N
-  0027,101E  VmaMod                             N
-  0027,101F  VmaClip                            N
-  0027,1020  SmartScanOnOffFlag                 N
-  0027,1030  ForeignImageRevision               N
-  0027,1031  ImagingMode                        N
-  0027,1032  PulseSequence                      N
-  0027,1033  ImagingOptions                     N
-  0027,1035  PlaneType                          N
-  0027,1036  ObliquePlane                       N
-  0027,1040  RASLetterOfImageLocation           N
-  0027,1041  ImageLocation                      N
-  0027,1042  CenterRCoordOfPlaneImage           N
-  0027,1043  CenterACoordOfPlaneImage           N
-  0027,1044  CenterSCoordOfPlaneImage           N
-  0027,1045  NormalRCoord                       N
-  0027,1046  NormalACoord                       N
-  0027,1047  NormalSCoord                       N
-  0027,1048  RCoordOfTopRightCorner             N
-  0027,1049  ACoordOfTopRightCorner             N
-  0027,104A  SCoordOfTopRightCorner             N
-  0027,104B  RCoordOfBottomRightCorner          N
-  0027,104C  ACoordOfBottomRightCorner          N
-  0027,104D  SCoordOfBottomRightCorner          N
-  0027,1050  TableStartLocation                 N
-  0027,1051  TableEndLocation                   N
-  0027,1052  RASLetterForSideOfImage            N
-  0027,1053  RASLetterForAnteriorPosterior      N
-  0027,1054  RASLetterForScoutStartLoc          N
-  0027,1055  RASLetterForScoutEndLoc            N
-  0027,1060  ImageDimensionX                    N
-  0027,1061  ImageDimensionY                    N
-  0027,1062  NumberOfExcitations                N
-  0028,0000  ImagePresentationGroupLength       N
-  0028,0002  SamplesPerPixel                    N
-  0028,0003  SamplesPerPixelUsed                N
-  0028,0004  PhotometricInterpretation          N
-  0028,0005  ImageDimensions                    N
-  0028,0006  PlanarConfiguration                N
-  0028,0008  NumberOfFrames                     N
-  0028,0009  FrameIncrementPointer              N
-  0028,000A  FrameDimensionPointer              N
-  0028,0010  Rows                               N
-  0028,0011  Columns                            N
-  0028,0012  Planes                             N
-  0028,0014  UltrasoundColorDataPresent         N
-  0028,0030  PixelSpacing                       N
-  0028,0031  ZoomFactor                         N
-  0028,0032  ZoomCenter                         N
-  0028,0034  PixelAspectRatio                   N
-  0028,0040  ImageFormat                        N
-  0028,0050  ManipulatedImage                   N
-  0028,0051  CorrectedImage                     N
-  0028,005F  CompressionRecognitionCode         N
-  0028,0060  CompressionCode                    N
-  0028,0061  CompressionOriginator              N
-  0028,0062  CompressionLabel                   N
-  0028,0063  CompressionDescription             N
-  0028,0065  CompressionSequence                N
-  0028,0066  CompressionStepPointers            N
-  0028,0068  RepeatInterval                     N
-  0028,0069  BitsGrouped                        N
-  0028,0070  PerimeterTable                     N
-  0028,0071  PerimeterValue                     N
-  0028,0080  PredictorRows                      N
-  0028,0081  PredictorColumns                   N
-  0028,0082  PredictorConstants                 N
-  0028,0090  BlockedPixels                      N
-  0028,0091  BlockRows                          N
-  0028,0092  BlockColumns                       N
-  0028,0093  RowOverlap                         N
-  0028,0094  ColumnOverlap                      N
-  0028,0100  BitsAllocated                      N
-  0028,0101  BitsStored                         N
-  0028,0102  HighBit                            N
-  0028,0103  PixelRepresentation                N
-  0028,0104  SmallestValidPixelValue            N
-  0028,0105  LargestValidPixelValue             N
-  0028,0106  SmallestImagePixelValue            N
-  0028,0107  LargestImagePixelValue             N
-  0028,0108  SmallestPixelValueInSeries         N
-  0028,0109  LargestPixelValueInSeries          N
-  0028,0110  SmallestImagePixelValueInPlane     N
-  0028,0111  LargestImagePixelValueInPlane      N
-  0028,0120  PixelPaddingValue                  N
-  0028,0121  PixelPaddingRangeLimit             N
-  0028,0200  ImageLocation                      N
-  0028,0300  QualityControlImage                N
-  0028,0301  BurnedInAnnotation                 N
-  0028,0400  TransformLabel                     N
-  0028,0401  TransformVersionNumber             N
-  0028,0402  NumberOfTransformSteps             N
-  0028,0403  SequenceOfCompressedData           N
-  0028,0404  DetailsOfCoefficients              N
-  0028,04x2  CoefficientCoding                  N
-  0028,04x3  CoefficientCodingPointers          N
-  0028,0700  DCTLabel                           N
-  0028,0701  DataBlockDescription               N
-  0028,0702  DataBlock                          N
-  0028,0710  NormalizationFactorFormat          N
-  0028,0720  ZonalMapNumberFormat               N
-  0028,0721  ZonalMapLocation                   N
-  0028,0722  ZonalMapFormat                     N
-  0028,0730  AdaptiveMapFormat                  N
-  0028,0740  CodeNumberFormat                   N
-  0028,08x0  CodeLabel                          N
-  0028,08x2  NumberOfTables                     N
-  0028,08x3  CodeTableLocation                  N
-  0028,08x4  BitsForCodeWord                    N
-  0028,08x8  ImageDataLocation                  N
-  0028,0A02  PixelSpacingCalibrationType        N
-  0028,0A04  PixelSpacingCalibrationDescription N
-  0028,1040  PixelIntensityRelationship         N
-  0028,1041  PixelIntensityRelationshipSign     N
-  0028,1050  WindowCenter                       N
-  0028,1051  WindowWidth                        N
-  0028,1052  RescaleIntercept                   N
-  0028,1053  RescaleSlope                       N
-  0028,1054  RescaleType                        N
-  0028,1055  WindowCenterAndWidthExplanation    N
-  0028,1056  VOI_LUTFunction                    N
-  0028,1080  GrayScale                          N
-  0028,1090  RecommendedViewingMode             N
-  0028,1100  GrayLookupTableDescriptor          N
-  0028,1101  RedPaletteColorTableDescriptor     N
-  0028,1102  GreenPaletteColorTableDescriptor   N
-  0028,1103  BluePaletteColorTableDescriptor    N
-  0028,1111  LargeRedPaletteColorTableDescr     N
-  0028,1112  LargeGreenPaletteColorTableDescr   N
-  0028,1113  LargeBluePaletteColorTableDescr    N
-  0028,1199  PaletteColorTableUID               N
-  0028,1200  GrayLookupTableData                N
-  0028,1201  RedPaletteColorTableData           N
-  0028,1202  GreenPaletteColorTableData         N
-  0028,1203  BluePaletteColorTableData          N
-  0028,1211  LargeRedPaletteColorTableData      N
-  0028,1212  LargeGreenPaletteColorTableData    N
-  0028,1213  LargeBluePaletteColorTableData     N
-  0028,1214  LargePaletteColorLookupTableUID    N
-  0028,1221  SegmentedRedColorTableData         N
-  0028,1222  SegmentedGreenColorTableData       N
-  0028,1223  SegmentedBlueColorTableData        N
-  0028,1300  BreastImplantPresent               N
-  0028,1350  PartialView                        N
-  0028,1351  PartialViewDescription             N
-  0028,1352  PartialViewCodeSequence            N
-  0028,135A  SpatialLocationsPreserved          N
-  0028,1402  DataPathAssignment                 N
-  0028,1404  BlendingLUT1Sequence               N
-  0028,1406  BlendingWeightConstant             N
-  0028,1408  BlendingLookupTableData            N
-  0028,140C  BlendingLUT2Sequence               N
-  0028,140E  DataPathID                         N
-  0028,140F  RGBLUTTransferFunction             N
-  0028,1410  AlphaLUTTransferFunction           N
-  0028,2000  ICCProfile                         N
-  0028,2110  LossyImageCompression              N
-  0028,2112  LossyImageCompressionRatio         N
-  0028,2114  LossyImageCompressionMethod        N
-  0028,3000  ModalityLUTSequence                N
-  0028,3002  LUTDescriptor                      N
-  0028,3003  LUTExplanation                     N
-  0028,3004  ModalityLUTType                    N
-  0028,3006  LUTData                            N
-  0028,3010  VOILUTSequence                     N
-  0028,3110  SoftcopyVOILUTSequence             N
-  0028,4000  ImagePresentationComments          N
-  0028,5000  BiPlaneAcquisitionSequence         N
-  0028,6010  RepresentativeFrameNumber          N
-  0028,6020  FrameNumbersOfInterest             N
-  0028,6022  FrameOfInterestDescription         N
-  0028,6023  FrameOfInterestType                N
-  0028,6030  MaskPointers                       N
-  0028,6040  RWavePointer                       N
-  0028,6100  MaskSubtractionSequence            N
-  0028,6101  MaskOperation                      N
-  0028,6102  ApplicableFrameRange               N
-  0028,6110  MaskFrameNumbers                   N
-  0028,6112  ContrastFrameAveraging             N
-  0028,6114  MaskSubPixelShift                  N
-  0028,6120  TIDOffset                          N
-  0028,6190  MaskOperationExplanation           N
-  0028,7FE0  PixelDataProviderURL               N
-  0028,9001  DataPointRows                      N
-  0028,9002  DataPointColumns                   N
-  0028,9003  SignalDomainColumns                N
-  0028,9099  LargestMonochromePixelValue        N
-  0028,9108  DataRepresentation                 N
-  0028,9110  PixelMeasuresSequence              N
-  0028,9132  FrameVOILUTSequence                N
-  0028,9145  PixelValueTransformationSequence   N
-  0028,9235  SignalDomainRows                   N
-  0028,9411  DisplayFilterPercentage            N
-  0028,9415  FramePixelShiftSequence            N
-  0028,9416  SubtractionItemID                  N
-  0028,9422  PixelIntensityRelationshipLUTSeq   N
-  0028,9443  FramePixelDataPropertiesSequence   N
-  0028,9444  GeometricalProperties              N
-  0028,9445  GeometricMaximumDistortion         N
-  0028,9446  ImageProcessingApplied             N
-  0028,9454  MaskSelectionMode                  N
-  0028,9474  LUTFunction                        N
-  0028,9478  MaskVisibilityPercentage           N
-  0028,9501  PixelShiftSequence                 N
-  0028,9502  RegionPixelShiftSequence           N
-  0028,9503  VerticesOfTheRegion                N
-  0028,9506  PixelShiftFrameRange               N
-  0028,9507  LUTFrameRange                      N
-  0028,9520  ImageToEquipmentMappingMatrix      N
-  0028,9537  EquipmentCoordinateSystemID        N
-  0029,1004  LowerRangeOfPixels1a               N
-  0029,1005  LowerRangeOfPixels1b               N
-  0029,1006  LowerRangeOfPixels1c               N
-  0029,1007  LowerRangeOfPixels1d               N
-  0029,1008  LowerRangeOfPixels1e               N
-  0029,1009  LowerRangeOfPixels1f               N
-  0029,100A  LowerRangeOfPixels1g               N
-  0029,1015  LowerRangeOfPixels1h               N
-  0029,1016  LowerRangeOfPixels1i               N
-  0029,1017  LowerRangeOfPixels2                N
-  0029,1018  UpperRangeOfPixels2                N
-  0029,101A  LenOfTotHdrInBytes                 N
-  0029,1026  VersionOfTheHdrStruct              N
-  0029,1034  AdvantageCompOverflow              N
-  0029,1035  AdvantageCompUnderflow             N
-  0032,0000  StudyGroupLength                   N
-  0032,000A  StudyStatusID                      N
-  0032,000C  StudyPriorityID                    N
-  0032,0012  StudyIDIssuer                      N
-  0032,0032  StudyVerifiedDate                  N
-  0032,0033  StudyVerifiedTime                  N
-  0032,0034  StudyReadDate                      N
-  0032,0035  StudyReadTime                      N
-  0032,1000  ScheduledStudyStartDate            N
-  0032,1001  ScheduledStudyStartTime            N
-  0032,1010  ScheduledStudyStopDate             N
-  0032,1011  ScheduledStudyStopTime             N
-  0032,1020  ScheduledStudyLocation             N
-  0032,1021  ScheduledStudyLocationAETitle      N
-  0032,1030  ReasonForStudy                     N
-  0032,1031  RequestingPhysicianIDSequence      N
-  0032,1032  RequestingPhysician                N
-  0032,1033  RequestingService                  N
-  0032,1040  StudyArrivalDate                   N
-  0032,1041  StudyArrivalTime                   N
-  0032,1050  StudyCompletionDate                N
-  0032,1051  StudyCompletionTime                N
-  0032,1055  StudyComponentStatusID             N
-  0032,1060  RequestedProcedureDescription      N
-  0032,1064  RequestedProcedureCodeSequence     N
-  0032,1070  RequestedContrastAgent             N
-  0032,4000  StudyComments                      N
-  0038,0004  ReferencedPatientAliasSequence     N
-  0038,0008  VisitStatusID                      N
-  0038,0010  AdmissionID                        N
-  0038,0011  IssuerOfAdmissionID                N
-  0038,0016  RouteOfAdmissions                  N
-  0038,001A  ScheduledAdmissionDate             N
-  0038,001B  ScheduledAdmissionTime             N
-  0038,001C  ScheduledDischargeDate             N
-  0038,001D  ScheduledDischargeTime             N
-  0038,001E  ScheduledPatientInstitResidence    N
-  0038,0020  AdmittingDate                      N
-  0038,0021  AdmittingTime                      N
-  0038,0030  DischargeDate                      N
-  0038,0032  DischargeTime                      N
-  0038,0040  DischargeDiagnosisDescription      N
-  0038,0044  DischargeDiagnosisCodeSequence     N
-  0038,0050  SpecialNeeds                       N
-  0038,0060  ServiceEpisodeID                   N
-  0038,0061  IssuerOfServiceEpisodeID           N
-  0038,0062  ServiceEpisodeDescription          N
-  0038,0100  PertinentDocumentsSequence         N
-  0038,0300  CurrentPatientLocation             N
-  0038,0400  PatientInstitutionResidence        N
-  0038,0500  PatientState                       N
-  0038,0502  PatientClinicalTrialParticipSeq    N
-  0038,4000  VisitComments                      N
-  003A,0004  WaveformOriginality                N
-  003A,0005  NumberOfWaveformChannels           N
-  003A,0010  NumberOfWaveformSamples            N
-  003A,001A  SamplingFrequency                  N
-  003A,0020  MultiplexGroupLabel                N
-  003A,0200  ChannelDefinitionSequence          N
-  003A,0202  WaveformChannelNumber              N
-  003A,0203  ChannelLabel                       N
-  003A,0205  ChannelStatus                      N
-  003A,0208  ChannelSourceSequence              N
-  003A,0209  ChannelSourceModifiersSequence     N
-  003A,020A  SourceWaveformSequence             N
-  003A,020C  ChannelDerivationDescription       N
-  003A,0210  ChannelSensitivity                 N
-  003A,0211  ChannelSensitivityUnitsSequence    N
-  003A,0212  ChannelSensitivityCorrectionFactor N
-  003A,0213  ChannelBaseline                    N
-  003A,0214  ChannelTimeSkew                    N
-  003A,0215  ChannelSampleSkew                  N
-  003A,0218  ChannelOffset                      N
-  003A,021A  WaveformBitsStored                 N
-  003A,0220  FilterLowFrequency                 N
-  003A,0221  FilterHighFrequency                N
-  003A,0222  NotchFilterFrequency               N
-  003A,0223  NotchFilterBandwidth               N
-  003A,0230  WaveformDataDisplayScale           N
-  003A,0231  WaveformDisplayBkgCIELabValue      N
-  003A,0240  WaveformPresentationGroupSequence  N
-  003A,0241  PresentationGroupNumber            N
-  003A,0242  ChannelDisplaySequence             N
-  003A,0244  ChannelRecommendDisplayCIELabValue N
-  003A,0245  ChannelPosition                    N
-  003A,0246  DisplayShadingFlag                 N
-  003A,0247  FractionalChannelDisplayScale      N
-  003A,0248  AbsoluteChannelDisplayScale        N
-  003A,0300  MultiplexAudioChannelsDescrCodeSeq N
-  003A,0301  ChannelIdentificationCode          N
-  003A,0302  ChannelMode                        N
-  0040,0001  ScheduledStationAETitle            N
-  0040,0002  ScheduledProcedureStepStartDate    N
-  0040,0003  ScheduledProcedureStepStartTime    N
-  0040,0004  ScheduledProcedureStepEndDate      N
-  0040,0005  ScheduledProcedureStepEndTime      N
-  0040,0006  ScheduledPerformingPhysiciansName  N
-  0040,0007  ScheduledProcedureStepDescription  N
-  0040,0008  ScheduledProtocolCodeSequence      N
-  0040,0009  ScheduledProcedureStepID           N
-  0040,000A  StageCodeSequence                  N
-  0040,000B  ScheduledPerformingPhysicianIDSeq  N
-  0040,0010  ScheduledStationName               N
-  0040,0011  ScheduledProcedureStepLocation     N
-  0040,0012  PreMedication                      N
-  0040,0020  ScheduledProcedureStepStatus       N
-  0040,0031  LocalNamespaceEntityID             N
-  0040,0032  UniversalEntityID                  N
-  0040,0033  UniversalEntityIDType              N
-  0040,0035  IdentifierTypeCode                 N
-  0040,0036  AssigningFacilitySequence          N
-  0040,0100  ScheduledProcedureStepSequence     N
-  0040,0220  ReferencedNonImageCompositeSOPSeq  N
-  0040,0241  PerformedStationAETitle            N
-  0040,0242  PerformedStationName               N
-  0040,0243  PerformedLocation                  N
-  0040,0244  PerformedProcedureStepStartDate    N
-  0040,0245  PerformedProcedureStepStartTime    N
-  0040,0250  PerformedProcedureStepEndDate      N
-  0040,0251  PerformedProcedureStepEndTime      N
-  0040,0252  PerformedProcedureStepStatus       N
-  0040,0253  PerformedProcedureStepID           N
-  0040,0254  PerformedProcedureStepDescription  N
-  0040,0255  PerformedProcedureTypeDescription  N
-  0040,0260  PerformedProtocolCodeSequence      N
-  0040,0261  PerformedProtocolType              N
-  0040,0270  ScheduledStepAttributesSequence    N
-  0040,0275  RequestAttributesSequence          N
-  0040,0280  CommentsOnPerformedProcedureStep   N
-  0040,0281  ProcStepDiscontinueReasonCodeSeq   N
-  0040,0293  QuantitySequence                   N
-  0040,0294  Quantity                           N
-  0040,0295  MeasuringUnitsSequence             N
-  0040,0296  BillingItemSequence                N
-  0040,0300  TotalTimeOfFluoroscopy             N
-  0040,0301  TotalNumberOfExposures             N
-  0040,0302  EntranceDose                       N
-  0040,0303  ExposedArea                        N
-  0040,0306  DistanceSourceToEntrance           N
-  0040,0307  DistanceSourceToSupport            N
-  0040,030E  ExposureDoseSequence               N
-  0040,0310  CommentsOnRadiationDose            N
-  0040,0312  XRayOutput                         N
-  0040,0314  HalfValueLayer                     N
-  0040,0316  OrganDose                          N
-  0040,0318  OrganExposed                       N
-  0040,0320  BillingProcedureStepSequence       N
-  0040,0321  FilmConsumptionSequence            N
-  0040,0324  BillingSuppliesAndDevicesSequence  N
-  0040,0330  ReferencedProcedureStepSequence    N
-  0040,0340  PerformedSeriesSequence            N
-  0040,0400  CommentsOnScheduledProcedureStep   N
-  0040,0440  ProtocolContextSequence            N
-  0040,0441  ContentItemModifierSequence        N
-  0040,050A  SpecimenAccessionNumber            N
-  0040,0512  ContainerIdentifier                N
-  0040,051A  ContainerDescription               N
-  0040,0550  SpecimenSequence                   N
-  0040,0551  SpecimenIdentifier                 N
-  0040,0552  SpecimenDescriptionSequenceTrial   N
-  0040,0553  SpecimenDescriptionTrial           N
-  0040,0554  SpecimenUID                        N
-  0040,0555  AcquisitionContextSequence         N
-  0040,0556  AcquisitionContextDescription      N
-  0040,059A  SpecimenTypeCodeSequence           N
-  0040,0600  SpecimenShortDescription           N
-  0040,06FA  SlideIdentifier                    N
-  0040,071A  ImageCenterPointCoordinatesSeq     N
-  0040,072A  XOffsetInSlideCoordinateSystem     N
-  0040,073A  YOffsetInSlideCoordinateSystem     N
-  0040,074A  ZOffsetInSlideCoordinateSystem     N
-  0040,08D8  PixelSpacingSequence               N
-  0040,08DA  CoordinateSystemAxisCodeSequence   N
-  0040,08EA  MeasurementUnitsCodeSequence       N
-  0040,09F8  VitalStainCodeSequenceTrial        N
-  0040,1001  RequestedProcedureID               N
-  0040,1002  ReasonForRequestedProcedure        N
-  0040,1003  RequestedProcedurePriority         N
-  0040,1004  PatientTransportArrangements       N
-  0040,1005  RequestedProcedureLocation         N
-  0040,1006  PlacerOrderNumber-Procedure        N
-  0040,1007  FillerOrderNumber-Procedure        N
-  0040,1008  ConfidentialityCode                N
-  0040,1009  ReportingPriority                  N
-  0040,100A  ReasonForRequestedProcedureCodeSeq N
-  0040,1010  NamesOfIntendedRecipientsOfResults N
-  0040,1011  IntendedRecipientsOfResultsIDSeq   N
-  0040,1101  PersonIdentificationCodeSequence   N
-  0040,1102  PersonAddress                      N
-  0040,1103  PersonTelephoneNumbers             N
-  0040,1400  RequestedProcedureComments         N
-  0040,2001  ReasonForImagingServiceRequest     N
-  0040,2004  IssueDateOfImagingServiceRequest   N
-  0040,2005  IssueTimeOfImagingServiceRequest   N
-  0040,2006  PlacerOrderNum-ImagingServiceReq   N
-  0040,2007  FillerOrderNum-ImagingServiceReq   N
-  0040,2008  OrderEnteredBy                     N
-  0040,2009  OrderEntererLocation               N
-  0040,2010  OrderCallbackPhoneNumber           N
-  0040,2016  PlacerOrderNum-ImagingServiceReq   N
-  0040,2017  FillerOrderNum-ImagingServiceReq   N
-  0040,2400  ImagingServiceRequestComments      N
-  0040,3001  ConfidentialityOnPatientDataDescr  N
-  0040,4001  GenPurposeScheduledProcStepStatus  N
-  0040,4002  GenPurposePerformedProcStepStatus  N
-  0040,4003  GenPurposeSchedProcStepPriority    N
-  0040,4004  SchedProcessingApplicationsCodeSeq N
-  0040,4005  SchedProcedureStepStartDateAndTime N
-  0040,4006  MultipleCopiesFlag                 N
-  0040,4007  PerformedProcessingAppsCodeSeq     N
-  0040,4009  HumanPerformerCodeSequence         N
-  0040,4010  SchedProcStepModificationDateTime  N
-  0040,4011  ExpectedCompletionDateAndTime      N
-  0040,4015  ResultingGenPurposePerfProcStepSeq N
-  0040,4016  RefGenPurposeSchedProcStepSeq      N
-  0040,4018  ScheduledWorkitemCodeSequence      N
-  0040,4019  PerformedWorkitemCodeSequence      N
-  0040,4020  InputAvailabilityFlag              N
-  0040,4021  InputInformationSequence           N
-  0040,4022  RelevantInformationSequence        N
-  0040,4023  RefGenPurSchedProcStepTransUID     N
-  0040,4025  ScheduledStationNameCodeSequence   N
-  0040,4026  ScheduledStationClassCodeSequence  N
-  0040,4027  SchedStationGeographicLocCodeSeq   N
-  0040,4028  PerformedStationNameCodeSequence   N
-  0040,4029  PerformedStationClassCodeSequence  N
-  0040,4030  PerformedStationGeogLocCodeSeq     N
-  0040,4031  RequestedSubsequentWorkItemCodeSeq N
-  0040,4032  NonDICOMOutputCodeSequence         N
-  0040,4033  OutputInformationSequence          N
-  0040,4034  ScheduledHumanPerformersSequence   N
-  0040,4035  ActualHumanPerformersSequence      N
-  0040,4036  HumanPerformersOrganization        N
-  0040,4037  HumanPerformerName                 N
-  0040,4040  RawDataHandling                    N
-  0040,8302  EntranceDoseInMilliGy              N
-  0040,9094  RefImageRealWorldValueMappingSeq   N
-  0040,9096  RealWorldValueMappingSequence      N
-  0040,9098  PixelValueMappingCodeSequence      N
-  0040,9210  LUTLabel                           N
-  0040,9211  RealWorldValueLastValueMapped      N
-  0040,9212  RealWorldValueLUTData              N
-  0040,9216  RealWorldValueFirstValueMapped     N
-  0040,9224  RealWorldValueIntercept            N
-  0040,9225  RealWorldValueSlope                N
-  0040,A010  RelationshipType                   N
-  0040,A027  VerifyingOrganization              N
-  0040,A030  VerificationDateTime               N
-  0040,A032  ObservationDateTime                N
-  0040,A040  ValueType                          N
-  0040,A043  ConceptNameCodeSequence            N
-  0040,A050  ContinuityOfContent                N
-  0040,A073  VerifyingObserverSequence          N
-  0040,A075  VerifyingObserverName              N
-  0040,A078  AuthorObserverSequence             N
-  0040,A07A  ParticipantSequence                N
-  0040,A07C  CustodialOrganizationSequence      N
-  0040,A080  ParticipationType                  N
-  0040,A082  ParticipationDateTime              N
-  0040,A084  ObserverType                       N
-  0040,A088  VerifyingObserverIdentCodeSequence N
-  0040,A090  EquivalentCDADocumentSequence      N
-  0040,A0B0  ReferencedWaveformChannels         N
-  0040,A120  DateTime                           N
-  0040,A121  Date                               N
-  0040,A122  Time                               N
-  0040,A123  PersonName                         N
-  0040,A124  UID                                N
-  0040,A130  TemporalRangeType                  N
-  0040,A132  ReferencedSamplePositions          N
-  0040,A136  ReferencedFrameNumbers             N
-  0040,A138  ReferencedTimeOffsets              N
-  0040,A13A  ReferencedDateTime                 N
-  0040,A160  TextValue                          N
-  0040,A168  ConceptCodeSequence                N
-  0040,A170  PurposeOfReferenceCodeSequence     N
-  0040,A180  AnnotationGroupNumber              N
-  0040,A195  ModifierCodeSequence               N
-  0040,A300  MeasuredValueSequence              N
-  0040,A301  NumericValueQualifierCodeSequence  N
-  0040,A30A  NumericValue                       N
-  0040,A353  AddressTrial                       N
-  0040,A354  TelephoneNumberTrial               N
-  0040,A360  PredecessorDocumentsSequence       N
-  0040,A370  ReferencedRequestSequence          N
-  0040,A372  PerformedProcedureCodeSequence     N
-  0040,A375  CurrentRequestedProcEvidenceSeq    N
-  0040,A385  PertinentOtherEvidenceSequence     N
-  0040,A390  HL7StructuredDocumentRefSeq        N
-  0040,A491  CompletionFlag                     N
-  0040,A492  CompletionFlagDescription          N
-  0040,A493  VerificationFlag                   N
-  0040,A494  ArchiveRequested                   N
-  0040,A496  PreliminaryFlag                    N
-  0040,A504  ContentTemplateSequence            N
-  0040,A525  IdenticalDocumentsSequence         N
-  0040,A730  ContentSequence                    N
-  0040,B020  AnnotationSequence                 N
-  0040,DB00  TemplateIdentifier                 N
-  0040,DB06  TemplateVersion                    N
-  0040,DB07  TemplateLocalVersion               N
-  0040,DB0B  TemplateExtensionFlag              N
-  0040,DB0C  TemplateExtensionOrganizationUID   N
-  0040,DB0D  TemplateExtensionCreatorUID        N
-  0040,DB73  ReferencedContentItemIdentifier    N
-  0040,E001  HL7InstanceIdentifier              N
-  0040,E004  HL7DocumentEffectiveTime           N
-  0040,E006  HL7DocumentTypeCodeSequence        N
-  0040,E010  RetrieveURI                        N
-  0040,E011  RetrieveLocationUID                N
-  0042,0010  DocumentTitle                      N
-  0042,0011  EncapsulatedDocument               N
-  0042,0012  MIMETypeOfEncapsulatedDocument     N
-  0042,0013  SourceInstanceSequence             N
-  0042,0014  ListOfMIMETypes                    N
-  0043,1001  BitmapOfPrescanOptions             N
-  0043,1002  GradientOffsetInX                  N
-  0043,1003  GradientOffsetInY                  N
-  0043,1004  GradientOffsetInZ                  N
-  0043,1005  ImgIsOriginalOrUnoriginal          N
-  0043,1006  NumberOfEPIShots                   N
-  0043,1007  ViewsPerSegment                    N
-  0043,1008  RespiratoryRateBpm                 N
-  0043,1009  RespiratoryTriggerPoint            N
-  0043,100A  TypeOfReceiverUsed                 N
-  0043,100B  PeakRateOfChangeOfGradientField    N
-  0043,100C  LimitsInUnitsOfPercent             N
-  0043,100D  PSDEstimatedLimit                  N
-  0043,100E  PSDEstimatedLimitInTeslaPerSecond  N
-  0043,100F  Saravghead                         N
-  0043,1010  WindowValue                        N
-  0043,1011  TotalInputViews                    N
-  0043,1012  X-RayChain                         N
-  0043,1013  DeconKernelParameters              N
-  0043,1014  CalibrationParameters              N
-  0043,1015  TotalOutputViews                   N
-  0043,1016  NumberOfOverranges                 N
-  0043,1017  IBHImageScaleFactors               N
-  0043,1018  BBHCoefficients                    N
-  0043,1019  NumberOfBBHChainsToBlend           N
-  0043,101A  StartingChannelNumber              N
-  0043,101B  PpscanParameters                   N
-  0043,101C  GEImageIntegrity                   N
-  0043,101D  LevelValue                         N
-  0043,101E  DeltaStartTime                     N
-  0043,101F  MaxOverrangesInAView               N
-  0043,1020  AvgOverrangesAllViews              N
-  0043,1021  CorrectedAfterGlowTerms            N
-  0043,1025  ReferenceChannels                  N
-  0043,1026  NoViewsRefChansBlocked             N
-  0043,1027  ScanPitchRatio                     N
-  0043,1028  UniqueImageIden                    N
-  0043,1029  HistogramTables                    N
-  0043,102A  UserDefinedData                    N
-  0043,102B  PrivateScanOptions                 N
-  0043,102C  EffectiveEchoSpacing               N
-  0043,102D  StringSlopField1                   N
-  0043,102E  StringSlopField2                   N
-  0043,102F  RawDataType                        N
-  0043,1030  RawDataType                        N
-  0043,1031  RACordOfTargetReconCenter          N
-  0043,1032  RawDataType                        N
-  0043,1033  NegScanspacing                     N
-  0043,1034  OffsetFrequency                    N
-  0043,1035  UserUsageTag                       N
-  0043,1036  UserFillMapMSW                     N
-  0043,1037  UserFillMapLSW                     N
-  0043,1038  User25-48                          N
-  0043,1039  SlopInt6-9                         N
-  0043,1040  TriggerOnPosition                  N
-  0043,1041  DegreeOfRotation                   N
-  0043,1042  DASTriggerSource                   N
-  0043,1043  DASFpaGain                         N
-  0043,1044  DASOutputSource                    N
-  0043,1045  DASAdInput                         N
-  0043,1046  DASCalMode                         N
-  0043,1047  DASCalFrequency                    N
-  0043,1048  DASRegXm                           N
-  0043,1049  DASAutoZero                        N
-  0043,104A  StartingChannelOfView              N
-  0043,104B  DASXmPattern                       N
-  0043,104C  TGGCTriggerMode                    N
-  0043,104D  StartScanToXrayOnDelay             N
-  0043,104E  DurationOfXrayOn                   N
-  0043,1060  SlopInt10-17                       N
-  0043,1061  ScannerStudyEntityUID              N
-  0043,1062  ScannerStudyID                     N
-  0043,106f  ScannerTableEntry                  N
-  0044,0001  ProductPackageIdentifier           N
-  0044,0002  SubstanceAdministrationApproval    N
-  0044,0003  ApprovalStatusFurtherDescription   N
-  0044,0004  ApprovalStatusDateTime             N
-  0044,0007  ProductTypeCodeSequence            N
-  0044,0008  ProductName                        N
-  0044,0009  ProductDescription                 N
-  0044,000A  ProductLotIdentifier               N
-  0044,000B  ProductExpirationDateTime          N
-  0044,0010  SubstanceAdministrationDateTime    N
-  0044,0011  SubstanceAdministrationNotes       N
-  0044,0012  SubstanceAdministrationDeviceID    N
-  0044,0013  ProductParameterSequence           N
-  0044,0019  SubstanceAdminParameterSeq         N
-  0045,1001  NumberOfMacroRowsInDetector        N
-  0045,1002  MacroWidthAtISOCenter              N
-  0045,1003  DASType                            N
-  0045,1004  DASGain                            N
-  0045,1005  DASTemperature                     N
-  0045,1006  TableDirectionInOrOut              N
-  0045,1007  ZSmoothingFactor                   N
-  0045,1008  ViewWeightingMode                  N
-  0045,1009  SigmaRowNumberWhichRowsWereUsed    N
-  0045,100A  MinimumDasValueFoundInTheScanData  N
-  0045,100B  MaximumOffsetShiftValueUsed        N
-  0045,100C  NumberOfViewsShifted               N
-  0045,100D  ZTrackingFlag                      N
-  0045,100E  MeanZError                         N
-  0045,100F  ZTrackingMaximumError              N
-  0045,1010  StartingViewForRow2a               N
-  0045,1011  NumberOfViewsInRow2a               N
-  0045,1012  StartingViewForRow1a               N
-  0045,1013  SigmaMode                          N
-  0045,1014  NumberOfViewsInRow1a               N
-  0045,1015  StartingViewForRow2b               N
-  0045,1016  NumberOfViewsInRow2b               N
-  0045,1017  StartingViewForRow1b               N
-  0045,1018  NumberOfViewsInRow1b               N
-  0045,1019  AirFilterCalibrationDate           N
-  0045,101A  AirFilterCalibrationTime           N
-  0045,101B  PhantomCalibrationDate             N
-  0045,101C  PhantomCalibrationTime             N
-  0045,101D  ZSlopeCalibrationDate              N
-  0045,101E  ZSlopeCalibrationTime              N
-  0045,101F  CrosstalkCalibrationDate           N
-  0045,1020  CrosstalkCalibrationTime           N
-  0045,1021  IterboneOptionFlag                 N
-  0045,1022  PeristalticFlagOption              N
-  0046,0012  LensDescription                    N
-  0046,0014  RightLensSequence                  N
-  0046,0015  LeftLensSequence                   N
-  0046,0018  CylinderSequence                   N
-  0046,0028  PrismSequence                      N
-  0046,0030  HorizontalPrismPower               N
-  0046,0032  HorizontalPrismBase                N
-  0046,0034  VerticalPrismPower                 N
-  0046,0036  VerticalPrismBase                  N
-  0046,0038  LensSegmentType                    N
-  0046,0040  OpticalTransmittance               N
-  0046,0042  ChannelWidth                       N
-  0046,0044  PupilSize                          N
-  0046,0046  CornealSize                        N
-  0046,0060  DistancePupillaryDistance          N
-  0046,0062  NearPupillaryDistance              N
-  0046,0064  OtherPupillaryDistance             N
-  0046,0075  RadiusOfCurvature                  N
-  0046,0076  KeratometricPower                  N
-  0046,0077  KeratometricAxis                   N
-  0046,0092  BackgroundColor                    N
-  0046,0094  Optotype                           N
-  0046,0095  OptotypePresentation               N
-  0046,0100  AddNearSequence                    N
-  0046,0101  AddIntermediateSequence            N
-  0046,0102  AddOtherSequence                   N
-  0046,0104  AddPower                           N
-  0046,0106  ViewingDistance                    N
-  0046,0125  ViewingDistanceType                N
-  0046,0135  VisualAcuityModifiers              N
-  0046,0137  DecimalVisualAcuity                N
-  0046,0139  OptotypeDetailedDefinition         N
-  0046,0146  SpherePower                        N
-  0046,0147  CylinderPower                      N
-  0050,0004  CalibrationImage                   N
-  0050,0010  DeviceSequence                     N
-  0050,0014  DeviceLength                       N
-  0050,0015  ContainerComponentWidth            N
-  0050,0016  DeviceDiameter                     N
-  0050,0017  DeviceDiameterUnits                N
-  0050,0018  DeviceVolume                       N
-  0050,0019  InterMarkerDistance                N
-  0050,001B  ContainerComponentID               N
-  0050,0020  DeviceDescription                  N
-  0054,0010  EnergyWindowVector                 N
-  0054,0011  NumberOfEnergyWindows              N
-  0054,0012  EnergyWindowInformationSequence    N
-  0054,0013  EnergyWindowRangeSequence          N
-  0054,0014  EnergyWindowLowerLimit             N
-  0054,0015  EnergyWindowUpperLimit             N
-  0054,0016  RadiopharmaceuticalInformationSeq  N
-  0054,0017  ResidualSyringeCounts              N
-  0054,0018  EnergyWindowName                   N
-  0054,0020  DetectorVector                     N
-  0054,0021  NumberOfDetectors                  N
-  0054,0022  DetectorInformationSequence        N
-  0054,0030  PhaseVector                        N
-  0054,0031  NumberOfPhases                     N
-  0054,0032  PhaseInformationSequence           N
-  0054,0033  NumberOfFramesInPhase              N
-  0054,0036  PhaseDelay                         N
-  0054,0038  PauseBetweenFrames                 N
-  0054,0039  PhaseDescription                   N
-  0054,0050  RotationVector                     N
-  0054,0051  NumberOfRotations                  N
-  0054,0052  RotationInformationSequence        N
-  0054,0053  NumberOfFramesInRotation           N
-  0054,0060  RRIntervalVector                   N
-  0054,0061  NumberOfRRIntervals                N
-  0054,0062  GatedInformationSequence           N
-  0054,0063  DataInformationSequence            N
-  0054,0070  TimeSlotVector                     N
-  0054,0071  NumberOfTimeSlots                  N
-  0054,0072  TimeSlotInformationSequence        N
-  0054,0073  TimeSlotTime                       N
-  0054,0080  SliceVector                        N
-  0054,0081  NumberOfSlices                     N
-  0054,0090  AngularViewVector                  N
-  0054,0100  TimeSliceVector                    N
-  0054,0101  NumberOfTimeSlices                 N
-  0054,0200  StartAngle                         N
-  0054,0202  TypeOfDetectorMotion               N
-  0054,0210  TriggerVector                      N
-  0054,0211  NumberOfTriggersInPhase            N
-  0054,0220  ViewCodeSequence                   N
-  0054,0222  ViewModifierCodeSequence           N
-  0054,0300  RadionuclideCodeSequence           N
-  0054,0302  AdministrationRouteCodeSequence    N
-  0054,0304  RadiopharmaceuticalCodeSequence    N
-  0054,0306  CalibrationDataSequence            N
-  0054,0308  EnergyWindowNumber                 N
-  0054,0400  ImageID                            N
-  0054,0410  PatientOrientationCodeSequence     N
-  0054,0412  PatientOrientationModifierCodeSeq  N
-  0054,0414  PatientGantryRelationshipCodeSeq   N
-  0054,0500  SliceProgressionDirection          N
-  0054,1000  SeriesType                         N
-  0054,1001  Units                              N
-  0054,1002  CountsSource                       N
-  0054,1004  ReprojectionMethod                 N
-  0054,1100  RandomsCorrectionMethod            N
-  0054,1101  AttenuationCorrectionMethod        N
-  0054,1102  DecayCorrection                    N
-  0054,1103  ReconstructionMethod               N
-  0054,1104  DetectorLinesOfResponseUsed        N
-  0054,1105  ScatterCorrectionMethod            N
-  0054,1200  AxialAcceptance                    N
-  0054,1201  AxialMash                          N
-  0054,1202  TransverseMash                     N
-  0054,1203  DetectorElementSize                N
-  0054,1210  CoincidenceWindowWidth             N
-  0054,1220  SecondaryCountsType                N
-  0054,1300  FrameReferenceTime                 N
-  0054,1310  PrimaryCountsAccumulated           N
-  0054,1311  SecondaryCountsAccumulated         N
-  0054,1320  SliceSensitivityFactor             N
-  0054,1321  DecayFactor                        N
-  0054,1322  DoseCalibrationFactor              N
-  0054,1323  ScatterFractionFactor              N
-  0054,1324  DeadTimeFactor                     N
-  0054,1330  ImageIndex                         N
-  0054,1400  CountsIncluded                     N
-  0054,1401  DeadTimeCorrectionFlag             N
-  0060,3000  HistogramSequence                  N
-  0060,3002  HistogramNumberOfBins              N
-  0060,3004  HistogramFirstBinValue             N
-  0060,3006  HistogramLastBinValue              N
-  0060,3008  HistogramBinWidth                  N
-  0060,3010  HistogramExplanation               N
-  0060,3020  HistogramData                      N
-  0062,0001  SegmentationType                   N
-  0062,0002  SegmentSequence                    N
-  0062,0003  SegmentedPropertyCategoryCodeSeq   N
-  0062,0004  SegmentNumber                      N
-  0062,0005  SegmentLabel                       N
-  0062,0006  SegmentDescription                 N
-  0062,0008  SegmentAlgorithmType               N
-  0062,0009  SegmentAlgorithmName               N
-  0062,000A  SegmentIdentificationSequence      N
-  0062,000B  ReferencedSegmentNumber            N
-  0062,000C  RecommendedDisplayGrayscaleValue   N
-  0062,000D  RecommendedDisplayCIELabValue      N
-  0062,000E  MaximumFractionalValue             N
-  0062,000F  SegmentedPropertyTypeCodeSequence  N
-  0062,0010  SegmentationFractionalType         N
-  0064,0002  DeformableRegistrationSequence     N
-  0064,0003  SourceFrameOfReferenceUID          N
-  0064,0005  DeformableRegistrationGridSequence N
-  0064,0007  GridDimensions                     N
-  0064,0008  GridResolution                     N
-  0064,0009  VectorGridData                     N
-  0064,000F  PreDeformationMatrixRegistSeq      N
-  0064,0010  PostDeformationMatrixRegistSeq     N
-  0066,0001  NumberOfSurfaces                   N
-  0066,0002  SurfaceSequence                    N
-  0066,0003  SurfaceNumber                      N
-  0066,0004  SurfaceComments                    N
-  0066,0009  SurfaceProcessing                  N
-  0066,000A  SurfaceProcessingRatio             N
-  0066,000E  FiniteVolume                       N
-  0066,0010  Manifold                           N
-  0066,0011  SurfacePointsSequence              N
-  0066,0015  NumberOfSurfacePoints              N
-  0066,0016  PointCoordinatesData               N
-  0066,0017  PointPositionAccuracy              N
-  0066,0018  MeanPointDistance                  N
-  0066,0019  MaximumPointDistance               N
-  0066,001B  AxisOfRotation                     N
-  0066,001C  CenterOfRotation                   N
-  0066,001E  NumberOfVectors                    N
-  0066,001F  VectorDimensionality               N
-  0066,0020  VectorAccuracy                     N
-  0066,0021  VectorCoordinateData               N
-  0066,0023  TrianglePointIndexList             N
-  0066,0024  EdgePointIndexList                 N
-  0066,0025  VertexPointIndexList               N
-  0066,0026  TriangleStripSequence              N
-  0066,0027  TriangleFanSequence                N
-  0066,0028  LineSequence                       N
-  0066,0029  PrimitivePointIndexList            N
-  0066,002A  SurfaceCount                       N
-  0066,002F  AlgorithmFamilyCodeSequ            N
-  0066,0031  AlgorithmVersion                   N
-  0066,0032  AlgorithmParameters                N
-  0066,0034  FacetSequence                      N
-  0066,0036  AlgorithmName                      N
-  0070,0001  GraphicAnnotationSequence          N
-  0070,0002  GraphicLayer                       N
-  0070,0003  BoundingBoxAnnotationUnits         N
-  0070,0004  AnchorPointAnnotationUnits         N
-  0070,0005  GraphicAnnotationUnits             N
-  0070,0006  UnformattedTextValue               N
-  0070,0008  TextObjectSequence                 N
-  0070,0009  GraphicObjectSequence              N
-  0070,0010  BoundingBoxTopLeftHandCorner       N
-  0070,0011  BoundingBoxBottomRightHandCorner   N
-  0070,0012  BoundingBoxTextHorizJustification  N
-  0070,0014  AnchorPoint                        N
-  0070,0015  AnchorPointVisibility              N
-  0070,0020  GraphicDimensions                  N
-  0070,0021  NumberOfGraphicPoints              N
-  0070,0022  GraphicData                        N
-  0070,0023  GraphicType                        N
-  0070,0024  GraphicFilled                      N
-  0070,0040  ImageRotationRetired               N
-  0070,0041  ImageHorizontalFlip                N
-  0070,0042  ImageRotation                      N
-  0070,0050  DisplayedAreaTopLeftTrial          N
-  0070,0051  DisplayedAreaBottomRightTrial      N
-  0070,0052  DisplayedAreaTopLeft               N
-  0070,0053  DisplayedAreaBottomRight           N
-  0070,005A  DisplayedAreaSelectionSequence     N
-  0070,0060  GraphicLayerSequence               N
-  0070,0062  GraphicLayerOrder                  N
-  0070,0066  GraphicLayerRecDisplayGraysclValue N
-  0070,0067  GraphicLayerRecDisplayRGBValue     N
-  0070,0068  GraphicLayerDescription            N
-  0070,0080  ContentLabel                       N
-  0070,0081  ContentDescription                 N
-  0070,0082  PresentationCreationDate           N
-  0070,0083  PresentationCreationTime           N
-  0070,0084  ContentCreatorName                 N
-  0070,0086  ContentCreatorIDCodeSequence       N
-  0070,0100  PresentationSizeMode               N
-  0070,0101  PresentationPixelSpacing           N
-  0070,0102  PresentationPixelAspectRatio       N
-  0070,0103  PresentationPixelMagRatio          N
-  0070,0306  ShapeType                          N
-  0070,0308  RegistrationSequence               N
-  0070,0309  MatrixRegistrationSequence         N
-  0070,030A  MatrixSequence                     N
-  0070,030C  FrameOfRefTransformationMatrixType N
-  0070,030D  RegistrationTypeCodeSequence       N
-  0070,030F  FiducialDescription                N
-  0070,0310  FiducialIdentifier                 N
-  0070,0311  FiducialIdentifierCodeSequence     N
-  0070,0312  ContourUncertaintyRadius           N
-  0070,0314  UsedFiducialsSequence              N
-  0070,0318  GraphicCoordinatesDataSequence     N
-  0070,031A  FiducialUID                        N
-  0070,031C  FiducialSetSequence                N
-  0070,031E  FiducialSequence                   N
-  0070,0401  GraphicLayerRecomDisplayCIELabVal  N
-  0070,0402  BlendingSequence                   N
-  0070,0403  RelativeOpacity                    N
-  0070,0404  ReferencedSpatialRegistrationSeq   N
-  0070,0405  BlendingPosition                   N
-  0072,0002  HangingProtocolName                N
-  0072,0004  HangingProtocolDescription         N
-  0072,0006  HangingProtocolLevel               N
-  0072,0008  HangingProtocolCreator             N
-  0072,000A  HangingProtocolCreationDateTime    N
-  0072,000C  HangingProtocolDefinitionSequence  N
-  0072,000E  HangingProtocolUserIDCodeSequence  N
-  0072,0010  HangingProtocolUserGroupName       N
-  0072,0012  SourceHangingProtocolSequence      N
-  0072,0014  NumberOfPriorsReferenced           N
-  0072,0020  ImageSetsSequence                  N
-  0072,0022  ImageSetSelectorSequence           N
-  0072,0024  ImageSetSelectorUsageFlag          N
-  0072,0026  SelectorAttribute                  N
-  0072,0028  SelectorValueNumber                N
-  0072,0030  TimeBasedImageSetsSequence         N
-  0072,0032  ImageSetNumber                     N
-  0072,0034  ImageSetSelectorCategory           N
-  0072,0038  RelativeTime                       N
-  0072,003A  RelativeTimeUnits                  N
-  0072,003C  AbstractPriorValue                 N
-  0072,003E  AbstractPriorCodeSequence          N
-  0072,0040  ImageSetLabel                      N
-  0072,0050  SelectorAttributeVR                N
-  0072,0052  SelectorSequencePointer            N
-  0072,0054  SelectorSeqPointerPrivateCreator   N
-  0072,0056  SelectorAttributePrivateCreator    N
-  0072,0060  SelectorATValue                    N
-  0072,0062  SelectorCSValue                    N
-  0072,0064  SelectorISValue                    N
-  0072,0066  SelectorLOValue                    N
-  0072,0068  SelectorLTValue                    N
-  0072,006A  SelectorPNValue                    N
-  0072,006C  SelectorSHValue                    N
-  0072,006E  SelectorSTValue                    N
-  0072,0070  SelectorUTValue                    N
-  0072,0072  SelectorDSValue                    N
-  0072,0074  SelectorFDValue                    N
-  0072,0076  SelectorFLValue                    N
-  0072,0078  SelectorULValue                    N
-  0072,007A  SelectorUSValue                    N
-  0072,007C  SelectorSLValue                    N
-  0072,007E  SelectorSSValue                    N
-  0072,0080  SelectorCodeSequenceValue          N
-  0072,0100  NumberOfScreens                    N
-  0072,0102  NominalScreenDefinitionSequence    N
-  0072,0104  NumberOfVerticalPixels             N
-  0072,0106  NumberOfHorizontalPixels           N
-  0072,0108  DisplayEnvironmentSpatialPosition  N
-  0072,010A  ScreenMinimumGrayscaleBitDepth     N
-  0072,010C  ScreenMinimumColorBitDepth         N
-  0072,010E  ApplicationMaximumRepaintTime      N
-  0072,0200  DisplaySetsSequence                N
-  0072,0202  DisplaySetNumber                   N
-  0072,0203  DisplaySetLabel                    N
-  0072,0204  DisplaySetPresentationGroup        N
-  0072,0206  DisplaySetPresentationGroupDescr   N
-  0072,0208  PartialDataDisplayHandling         N
-  0072,0210  SynchronizedScrollingSequence      N
-  0072,0212  DisplaySetScrollingGroup           N
-  0072,0214  NavigationIndicatorSequence        N
-  0072,0216  NavigationDisplaySet               N
-  0072,0218  ReferenceDisplaySets               N
-  0072,0300  ImageBoxesSequence                 N
-  0072,0302  ImageBoxNumber                     N
-  0072,0304  ImageBoxLayoutType                 N
-  0072,0306  ImageBoxTileHorizontalDimension    N
-  0072,0308  ImageBoxTileVerticalDimension      N
-  0072,0310  ImageBoxScrollDirection            N
-  0072,0312  ImageBoxSmallScrollType            N
-  0072,0314  ImageBoxSmallScrollAmount          N
-  0072,0316  ImageBoxLargeScrollType            N
-  0072,0318  ImageBoxLargeScrollAmount          N
-  0072,0320  ImageBoxOverlapPriority            N
-  0072,0330  CineRelativeToRealTime             N
-  0072,0400  FilterOperationsSequence           N
-  0072,0402  FilterByCategory                   N
-  0072,0404  FilterByAttributePresence          N
-  0072,0406  FilterByOperator                   N
-  0072,0432  SynchronizedImageBoxList           N
-  0072,0434  TypeOfSynchronization              N
-  0072,0500  BlendingOperationType              N
-  0072,0510  ReformattingOperationType          N
-  0072,0512  ReformattingThickness              N
-  0072,0514  ReformattingInterval               N
-  0072,0516  ReformattingOpInitialViewDir       N
-  0072,0520  3DRenderingType                    N
-  0072,0600  SortingOperationsSequence          N
-  0072,0602  SortByCategory                     N
-  0072,0604  SortingDirection                   N
-  0072,0700  DisplaySetPatientOrientation       N
-  0072,0702  VOIType                            N
-  0072,0704  PseudoColorType                    N
-  0072,0706  ShowGrayscaleInverted              N
-  0072,0710  ShowImageTrueSizeFlag              N
-  0072,0712  ShowGraphicAnnotationFlag          N
-  0072,0714  ShowPatientDemographicsFlag        N
-  0072,0716  ShowAcquisitionTechniquesFlag      N
-  0072,0717  DisplaySetHorizontalJustification  N
-  0072,0718  DisplaySetVerticalJustification    N
-  0074,1000  UnifiedProcedureStepState          N
-  0074,1002  UPSProgressInformationSequence     N
-  0074,1004  UnifiedProcedureStepProgress       N
-  0074,1006  UnifiedProcedureStepProgressDescr  N
-  0074,1008  UnifiedProcedureStepComURISeq      N
-  0074,100a  ContactURI                         N
-  0074,100c  ContactDisplayName                 N
-  0074,1020  BeamTaskSequence                   N
-  0074,1022  BeamTaskType                       N
-  0074,1024  BeamOrderIndex                     N
-  0074,1030  DeliveryVerificationImageSequence  N
-  0074,1032  VerificationImageTiming            N
-  0074,1034  DoubleExposureFlag                 N
-  0074,1036  DoubleExposureOrdering             N
-  0074,1038  DoubleExposureMeterset             N
-  0074,103A  DoubleExposureFieldDelta           N
-  0074,1040  RelatedReferenceRTImageSequence    N
-  0074,1042  GeneralMachineVerificationSequence N
-  0074,1044  ConventionalMachineVerificationSeq N
-  0074,1046  IonMachineVerificationSequence     N
-  0074,1048  FailedAttributesSequence           N
-  0074,104A  OverriddenAttributesSequence       N
-  0074,104C  ConventionalControlPointVerifySeq  N
-  0074,104E  IonControlPointVerificationSeq     N
-  0074,1050  AttributeOccurrenceSequence        N
-  0074,1052  AttributeOccurrencePointer         N
-  0074,1054  AttributeItemSelector              N
-  0074,1056  AttributeOccurrencePrivateCreator  N
-  0074,1200  ScheduledProcedureStepPriority     N
-  0074,1202  WorklistLabel                      N
-  0074,1204  ProcedureStepLabel                 N
-  0074,1210  ScheduledProcessingParametersSeq   N
-  0074,1212  PerformedProcessingParametersSeq   N
-  0074,1216  UPSPerformedProcedureSequence      N
-  0074,1220  RelatedProcedureStepSequence       N
-  0074,1222  ProcedureStepRelationshipType      N
-  0074,1230  DeletionLock                       N
-  0074,1234  ReceivingAE                        N
-  0074,1236  RequestingAE                       N
-  0074,1238  ReasonForCancellation              N
-  0074,1242  SCPStatus                          N
-  0074,1244  SubscriptionListStatus             N
-  0074,1246  UPSListStatus                      N
-  0088,0130  StorageMediaFileSetID              N
-  0088,0140  StorageMediaFileSetUID             N
-  0088,0200  IconImageSequence                  N
-  0088,0904  TopicTitle                         N
-  0088,0906  TopicSubject                       N
-  0088,0910  TopicAuthor                        N
-  0088,0912  TopicKeywords                      N
-  0100,0410  SOPInstanceStatus                  N
-  0100,0420  SOPAuthorizationDateAndTime        N
-  0100,0424  SOPAuthorizationComment            N
-  0100,0426  AuthorizationEquipmentCertNumber   N
-  0400,0005  MACIDNumber                        N
-  0400,0010  MACCalculationTransferSyntaxUID    N
-  0400,0015  MACAlgorithm                       N
-  0400,0020  DataElementsSigned                 N
-  0400,0100  DigitalSignatureUID                N
-  0400,0105  DigitalSignatureDateTime           N
-  0400,0110  CertificateType                    N
-  0400,0115  CertificateOfSigner                N
-  0400,0120  Signature                          N
-  0400,0305  CertifiedTimestampType             N
-  0400,0310  CertifiedTimestamp                 N
-  0400,0401  DigitalSignaturePurposeCodeSeq     N
-  0400,0402  ReferencedDigitalSignatureSeq      N
-  0400,0403  ReferencedSOPInstanceMACSeq        N
-  0400,0404  MAC                                N
-  0400,0500  EncryptedAttributesSequence        N
-  0400,0510  EncryptedContentTransferSyntaxUID  N
-  0400,0520  EncryptedContent                   N
-  0400,0550  ModifiedAttributesSequence         N
-  0400,0561  OriginalAttributesSequence         N
-  0400,0562  AttributeModificationDateTime      N
-  0400,0563  ModifyingSystem                    N
-  0400,0564  SourceOfPreviousValues             N
-  0400,0565  ReasonForTheAttributeModification  N
-  1000,xxx0  EscapeTriplet                      N
-  1000,xxx1  RunLengthTriplet                   N
-  1000,xxx2  HuffmanTableSize                   N
-  1000,xxx3  HuffmanTableTriplet                N
-  1000,xxx4  ShiftTableSize                     N
-  1000,xxx5  ShiftTableTriplet                  N
-  1010,xxxx  ZonalMap                           N
-  2000,0010  NumberOfCopies                     N
-  2000,001E  PrinterConfigurationSequence       N
-  2000,0020  PrintPriority                      N
-  2000,0030  MediumType                         N
-  2000,0040  FilmDestination                    N
-  2000,0050  FilmSessionLabel                   N
-  2000,0060  MemoryAllocation                   N
-  2000,0061  MaximumMemoryAllocation            N
-  2000,0062  ColorImagePrintingFlag             N
-  2000,0063  CollationFlag                      N
-  2000,0065  AnnotationFlag                     N
-  2000,0067  ImageOverlayFlag                   N
-  2000,0069  PresentationLUTFlag                N
-  2000,006A  ImageBoxPresentationLUTFlag        N
-  2000,00A0  MemoryBitDepth                     N
-  2000,00A1  PrintingBitDepth                   N
-  2000,00A2  MediaInstalledSequence             N
-  2000,00A4  OtherMediaAvailableSequence        N
-  2000,00A8  SupportedImageDisplayFormatSeq     N
-  2000,0500  ReferencedFilmBoxSequence          N
-  2000,0510  ReferencedStoredPrintSequence      N
-  2010,0010  ImageDisplayFormat                 N
-  2010,0030  AnnotationDisplayFormatID          N
-  2010,0040  FilmOrientation                    N
-  2010,0050  FilmSizeID                         N
-  2010,0052  PrinterResolutionID                N
-  2010,0054  DefaultPrinterResolutionID         N
-  2010,0060  MagnificationType                  N
-  2010,0080  SmoothingType                      N
-  2010,00A6  DefaultMagnificationType           N
-  2010,00A7  OtherMagnificationTypesAvailable   N
-  2010,00A8  DefaultSmoothingType               N
-  2010,00A9  OtherSmoothingTypesAvailable       N
-  2010,0100  BorderDensity                      N
-  2010,0110  EmptyImageDensity                  N
-  2010,0120  MinDensity                         N
-  2010,0130  MaxDensity                         N
-  2010,0140  Trim                               N
-  2010,0150  ConfigurationInformation           N
-  2010,0152  ConfigurationInformationDescr      N
-  2010,0154  MaximumCollatedFilms               N
-  2010,015E  Illumination                       N
-  2010,0160  ReflectedAmbientLight              N
-  2010,0376  PrinterPixelSpacing                N
-  2010,0500  ReferencedFilmSessionSequence      N
-  2010,0510  ReferencedImageBoxSequence         N
-  2010,0520  ReferencedBasicAnnotationBoxSeq    N
-  2020,0010  ImageBoxPosition                   N
-  2020,0020  Polarity                           N
-  2020,0030  RequestedImageSize                 N
-  2020,0040  RequestedDecimate-CropBehavior     N
-  2020,0050  RequestedResolutionID              N
-  2020,00A0  RequestedImageSizeFlag             N
-  2020,00A2  DecimateCropResult                 N
-  2020,0110  BasicGrayscaleImageSequence        N
-  2020,0111  BasicColorImageSequence            N
-  2020,0130  ReferencedImageOverlayBoxSequence  N
-  2020,0140  ReferencedVOILUTBoxSequence        N
-  2030,0010  AnnotationPosition                 N
-  2030,0020  TextString                         N
-  2040,0010  ReferencedOverlayPlaneSequence     N
-  2040,0011  ReferencedOverlayPlaneGroups       N
-  2040,0020  OverlayPixelDataSequence           N
-  2040,0060  OverlayMagnificationType           N
-  2040,0070  OverlaySmoothingType               N
-  2040,0072  OverlayOrImageMagnification        N
-  2040,0074  MagnifyToNumberOfColumns           N
-  2040,0080  OverlayForegroundDensity           N
-  2040,0082  OverlayBackgroundDensity           N
-  2040,0090  OverlayMode                        N
-  2040,0100  ThresholdDensity                   N
-  2040,0500  ReferencedImageBoxSequence         N
-  2050,0010  PresentationLUTSequence            N
-  2050,0020  PresentationLUTShape               N
-  2050,0500  ReferencedPresentationLUTSequence  N
-  2100,0010  PrintJobID                         N
-  2100,0020  ExecutionStatus                    N
-  2100,0030  ExecutionStatusInfo                N
-  2100,0040  CreationDate                       N
-  2100,0050  CreationTime                       N
-  2100,0070  Originator                         N
-  2100,0140  DestinationAE                      N
-  2100,0160  OwnerID                            N
-  2100,0170  NumberOfFilms                      N
-  2100,0500  ReferencedPrintJobSequence         N
-  2110,0010  PrinterStatus                      N
-  2110,0020  PrinterStatusInfo                  N
-  2110,0030  PrinterName                        N
-  2110,0099  PrintQueueID                       N
-  2120,0010  QueueStatus                        N
-  2120,0050  PrintJobDescriptionSequence        N
-  2120,0070  ReferencedPrintJobSequence         N
-  2130,0010  PrintManagementCapabilitiesSeq     N
-  2130,0015  PrinterCharacteristicsSequence     N
-  2130,0030  FilmBoxContentSequence             N
-  2130,0040  ImageBoxContentSequence            N
-  2130,0050  AnnotationContentSequence          N
-  2130,0060  ImageOverlayBoxContentSequence     N
-  2130,0080  PresentationLUTContentSequence     N
-  2130,00A0  ProposedStudySequence              N
-  2130,00C0  OriginalImageSequence              N
-  2200,0001  LabelFromInfoExtractedFromInstance N
-  2200,0002  LabelText                          N
-  2200,0003  LabelStyleSelection                N
-  2200,0004  MediaDisposition                   N
-  2200,0005  BarcodeValue                       N
-  2200,0006  BarcodeSymbology                   N
-  2200,0007  AllowMediaSplitting                N
-  2200,0008  IncludeNonDICOMObjects             N
-  2200,0009  IncludeDisplayApplication          N
-  2200,000A  SaveCompInstancesAfterMediaCreate  N
-  2200,000B  TotalNumberMediaPiecesCreated      N
-  2200,000C  RequestedMediaApplicationProfile   N
-  2200,000D  ReferencedStorageMediaSequence     N
-  2200,000E  FailureAttributes                  N
-  2200,000F  AllowLossyCompression              N
-  2200,0020  RequestPriority                    N
-  3002,0002  RTImageLabel                       N
-  3002,0003  RTImageName                        N
-  3002,0004  RTImageDescription                 N
-  3002,000A  ReportedValuesOrigin               N
-  3002,000C  RTImagePlane                       N
-  3002,000D  XRayImageReceptorTranslation       N
-  3002,000E  XRayImageReceptorAngle             N
-  3002,0010  RTImageOrientation                 N
-  3002,0011  ImagePlanePixelSpacing             N
-  3002,0012  RTImagePosition                    N
-  3002,0020  RadiationMachineName               N
-  3002,0022  RadiationMachineSAD                N
-  3002,0024  RadiationMachineSSD                N
-  3002,0026  RTImageSID                         N
-  3002,0028  SourceToReferenceObjectDistance    N
-  3002,0029  FractionNumber                     N
-  3002,0030  ExposureSequence                   N
-  3002,0032  MetersetExposure                   N
-  3002,0034  DiaphragmPosition                  N
-  3002,0040  FluenceMapSequence                 N
-  3002,0041  FluenceDataSource                  N
-  3002,0042  FluenceDataScale                   N
-  3002,0051  FluenceMode                        N
-  3002,0052  FluenceModeID                      N
-  3004,0001  DVHType                            N
-  3004,0002  DoseUnits                          N
-  3004,0004  DoseType                           N
-  3004,0006  DoseComment                        N
-  3004,0008  NormalizationPoint                 N
-  3004,000A  DoseSummationType                  N
-  3004,000C  GridFrameOffsetVector              N
-  3004,000E  DoseGridScaling                    N
-  3004,0010  RTDoseROISequence                  N
-  3004,0012  DoseValue                          N
-  3004,0014  TissueHeterogeneityCorrection      N
-  3004,0040  DVHNormalizationPoint              N
-  3004,0042  DVHNormalizationDoseValue          N
-  3004,0050  DVHSequence                        N
-  3004,0052  DVHDoseScaling                     N
-  3004,0054  DVHVolumeUnits                     N
-  3004,0056  DVHNumberOfBins                    N
-  3004,0058  DVHData                            N
-  3004,0060  DVHReferencedROISequence           N
-  3004,0062  DVHROIContributionType             N
-  3004,0070  DVHMinimumDose                     N
-  3004,0072  DVHMaximumDose                     N
-  3004,0074  DVHMeanDose                        N
-  3006,0002  StructureSetLabel                  N
-  3006,0004  StructureSetName                   N
-  3006,0006  StructureSetDescription            N
-  3006,0008  StructureSetDate                   N
-  3006,0009  StructureSetTime                   N
-  3006,0010  ReferencedFrameOfReferenceSequence N
-  3006,0012  RTReferencedStudySequence          N
-  3006,0014  RTReferencedSeriesSequence         N
-  3006,0016  ContourImageSequence               N
-  3006,0020  StructureSetROISequence            N
-  3006,0022  ROINumber                          N
-  3006,0024  ReferencedFrameOfReferenceUID      N
-  3006,0026  ROIName                            N
-  3006,0028  ROIDescription                     N
-  3006,002A  ROIDisplayColor                    N
-  3006,002C  ROIVolume                          N
-  3006,0030  RTRelatedROISequence               N
-  3006,0033  RTROIRelationship                  N
-  3006,0036  ROIGenerationAlgorithm             N
-  3006,0038  ROIGenerationDescription           N
-  3006,0039  ROIContourSequence                 N
-  3006,0040  ContourSequence                    N
-  3006,0042  ContourGeometricType               N
-  3006,0044  ContourSlabThickness               N
-  3006,0045  ContourOffsetVector                N
-  3006,0046  NumberOfContourPoints              N
-  3006,0048  ContourNumber                      N
-  3006,0049  AttachedContours                   N
-  3006,0050  ContourData                        N
-  3006,0080  RTROIObservationsSequence          N
-  3006,0082  ObservationNumber                  N
-  3006,0084  ReferencedROINumber                N
-  3006,0085  ROIObservationLabel                N
-  3006,0086  RTROIIdentificationCodeSequence    N
-  3006,0088  ROIObservationDescription          N
-  3006,00A0  RelatedRTROIObservationsSequence   N
-  3006,00A4  RTROIInterpretedType               N
-  3006,00A6  ROIInterpreter                     N
-  3006,00B0  ROIPhysicalPropertiesSequence      N
-  3006,00B2  ROIPhysicalProperty                N
-  3006,00B4  ROIPhysicalPropertyValue           N
-  3006,00B6  ROIElementalCompositionSequence    N
-  3006,00B7  ROIElementalCompAtomicNumber       N
-  3006,00B8  ROIElementalCompAtomicMassFraction N
-  3006,00C0  FrameOfReferenceRelationshipSeq    N
-  3006,00C2  RelatedFrameOfReferenceUID         N
-  3006,00C4  FrameOfReferenceTransformType      N
-  3006,00C6  FrameOfReferenceTransformMatrix    N
-  3006,00C8  FrameOfReferenceTransformComment   N
-  3008,0010  MeasuredDoseReferenceSequence      N
-  3008,0012  MeasuredDoseDescription            N
-  3008,0014  MeasuredDoseType                   N
-  3008,0016  MeasuredDoseValue                  N
-  3008,0020  TreatmentSessionBeamSequence       N
-  3008,0021  TreatmentSessionIonBeamSequence    N
-  3008,0022  CurrentFractionNumber              N
-  3008,0024  TreatmentControlPointDate          N
-  3008,0025  TreatmentControlPointTime          N
-  3008,002A  TreatmentTerminationStatus         N
-  3008,002B  TreatmentTerminationCode           N
-  3008,002C  TreatmentVerificationStatus        N
-  3008,0030  ReferencedTreatmentRecordSequence  N
-  3008,0032  SpecifiedPrimaryMeterset           N
-  3008,0033  SpecifiedSecondaryMeterset         N
-  3008,0036  DeliveredPrimaryMeterset           N
-  3008,0037  DeliveredSecondaryMeterset         N
-  3008,003A  SpecifiedTreatmentTime             N
-  3008,003B  DeliveredTreatmentTime             N
-  3008,0040  ControlPointDeliverySequence       N
-  3008,0041  IonControlPointDeliverySequence    N
-  3008,0042  SpecifiedMeterset                  N
-  3008,0044  DeliveredMeterset                  N
-  3008,0045  MetersetRateSet                    N
-  3008,0046  MetersetRateDelivered              N
-  3008,0047  ScanSpotMetersetsDelivered         N
-  3008,0048  DoseRateDelivered                  N
-  3008,0050  TreatmentSummaryCalcDoseRefSeq     N
-  3008,0052  CumulativeDoseToDoseReference      N
-  3008,0054  FirstTreatmentDate                 N
-  3008,0056  MostRecentTreatmentDate            N
-  3008,005A  NumberOfFractionsDelivered         N
-  3008,0060  OverrideSequence                   N
-  3008,0061  ParameterSequencePointer           N
-  3008,0062  OverrideParameterPointer           N
-  3008,0063  ParameterItemIndex                 N
-  3008,0064  MeasuredDoseReferenceNumber        N
-  3008,0065  ParameterPointer                   N
-  3008,0066  OverrideReason                     N
-  3008,0068  CorrectedParameterSequence         N
-  3008,006A  CorrectionValue                    N
-  3008,0070  CalculatedDoseReferenceSequence    N
-  3008,0072  CalculatedDoseReferenceNumber      N
-  3008,0074  CalculatedDoseReferenceDescription N
-  3008,0076  CalculatedDoseReferenceDoseValue   N
-  3008,0078  StartMeterset                      N
-  3008,007A  EndMeterset                        N
-  3008,0080  ReferencedMeasuredDoseReferenceSeq N
-  3008,0082  ReferencedMeasuredDoseReferenceNum N
-  3008,0090  ReferencedCalculatedDoseRefSeq     N
-  3008,0092  ReferencedCalculatedDoseRefNumber  N
-  3008,00A0  BeamLimitingDeviceLeafPairsSeq     N
-  3008,00B0  RecordedWedgeSequence              N
-  3008,00C0  RecordedCompensatorSequence        N
-  3008,00D0  RecordedBlockSequence              N
-  3008,00E0  TreatmentSummaryMeasuredDoseRefSeq N
-  3008,00F0  RecordedSnoutSequence              N
-  3008,00F2  RecordedRangeShifterSequence       N
-  3008,00F4  RecordedLateralSpreadingDeviceSeq  N
-  3008,00F6  RecordedRangeModulatorSequence     N
-  3008,0100  RecordedSourceSequence             N
-  3008,0105  SourceSerialNumber                 N
-  3008,0110  TreatmentSessionAppSetupSeq        N
-  3008,0116  ApplicationSetupCheck              N
-  3008,0120  RecordedBrachyAccessoryDeviceSeq   N
-  3008,0122  ReferencedBrachyAccessoryDeviceNum N
-  3008,0130  RecordedChannelSequence            N
-  3008,0132  SpecifiedChannelTotalTime          N
-  3008,0134  DeliveredChannelTotalTime          N
-  3008,0136  SpecifiedNumberOfPulses            N
-  3008,0138  DeliveredNumberOfPulses            N
-  3008,013A  SpecifiedPulseRepetitionInterval   N
-  3008,013C  DeliveredPulseRepetitionInterval   N
-  3008,0140  RecordedSourceApplicatorSequence   N
-  3008,0142  ReferencedSourceApplicatorNumber   N
-  3008,0150  RecordedChannelShieldSequence      N
-  3008,0152  ReferencedChannelShieldNumber      N
-  3008,0160  BrachyControlPointDeliveredSeq     N
-  3008,0162  SafePositionExitDate               N
-  3008,0164  SafePositionExitTime               N
-  3008,0166  SafePositionReturnDate             N
-  3008,0168  SafePositionReturnTime             N
-  3008,0200  CurrentTreatmentStatus             N
-  3008,0202  TreatmentStatusComment             N
-  3008,0220  FractionGroupSummarySequence       N
-  3008,0223  ReferencedFractionNumber           N
-  3008,0224  FractionGroupType                  N
-  3008,0230  BeamStopperPosition                N
-  3008,0240  FractionStatusSummarySequence      N
-  3008,0250  TreatmentDate                      N
-  3008,0251  TreatmentTime                      N
-  300A,0002  RTPlanLabel                        N
-  300A,0003  RTPlanName                         N
-  300A,0004  RTPlanDescription                  N
-  300A,0006  RTPlanDate                         N
-  300A,0007  RTPlanTime                         N
-  300A,0009  TreatmentProtocols                 N
-  300A,000A  PlanIntent                         N
-  300A,000B  TreatmentSites                     N
-  300A,000C  RTPlanGeometry                     N
-  300A,000E  PrescriptionDescription            N
-  300A,0010  DoseReferenceSequence              N
-  300A,0012  DoseReferenceNumber                N
-  300A,0013  DoseReferenceUID                   N
-  300A,0014  DoseReferenceStructureType         N
-  300A,0015  NominalBeamEnergyUnit              N
-  300A,0016  DoseReferenceDescription           N
-  300A,0018  DoseReferencePointCoordinates      N
-  300A,001A  NominalPriorDose                   N
-  300A,0020  DoseReferenceType                  N
-  300A,0021  ConstraintWeight                   N
-  300A,0022  DeliveryWarningDose                N
-  300A,0023  DeliveryMaximumDose                N
-  300A,0025  TargetMinimumDose                  N
-  300A,0026  TargetPrescriptionDose             N
-  300A,0027  TargetMaximumDose                  N
-  300A,0028  TargetUnderdoseVolumeFraction      N
-  300A,002A  OrganAtRiskFullVolumeDose          N
-  300A,002B  OrganAtRiskLimitDose               N
-  300A,002C  OrganAtRiskMaximumDose             N
-  300A,002D  OrganAtRiskOverdoseVolumeFraction  N
-  300A,0040  ToleranceTableSequence             N
-  300A,0042  ToleranceTableNumber               N
-  300A,0043  ToleranceTableLabel                N
-  300A,0044  GantryAngleTolerance               N
-  300A,0046  BeamLimitingDeviceAngleTolerance   N
-  300A,0048  BeamLimitingDeviceToleranceSeq     N
-  300A,004A  BeamLimitingDevicePositionTol      N
-  300A,004B  SnoutPositionTolerance             N
-  300A,004C  PatientSupportAngleTolerance       N
-  300A,004E  TableTopEccentricAngleTolerance    N
-  300A,004F  TableTopPitchAngleTolerance        N
-  300A,0050  TableTopRollAngleTolerance         N
-  300A,0051  TableTopVerticalPositionTolerance  N
-  300A,0052  TableTopLongitudinalPositionTol    N
-  300A,0053  TableTopLateralPositionTolerance   N
-  300A,0055  RTPlanRelationship                 N
-  300A,0070  FractionGroupSequence              N
-  300A,0071  FractionGroupNumber                N
-  300A,0072  FractionGroupDescription           N
-  300A,0078  NumberOfFractionsPlanned           N
-  300A,0079  NumberFractionPatternDigitsPerDay  N
-  300A,007A  RepeatFractionCycleLength          N
-  300A,007B  FractionPattern                    N
-  300A,0080  NumberOfBeams                      N
-  300A,0082  BeamDoseSpecificationPoint         N
-  300A,0084  BeamDose                           N
-  300A,0086  BeamMeterset                       N
-  300A,0088  BeamDosePointDepth                 N
-  300A,0089  BeamDosePointEquivalentDepth       N
-  300A,008A  BeamDosePointSSD                   N
-  300A,00A0  NumberOfBrachyApplicationSetups    N
-  300A,00A2  BrachyAppSetupDoseSpecPoint        N
-  300A,00A4  BrachyApplicationSetupDose         N
-  300A,00B0  BeamSequence                       N
-  300A,00B2  TreatmentMachineName               N
-  300A,00B3  PrimaryDosimeterUnit               N
-  300A,00B4  SourceAxisDistance                 N
-  300A,00B6  BeamLimitingDeviceSequence         N
-  300A,00B8  RTBeamLimitingDeviceType           N
-  300A,00BA  SourceToBeamLimitingDeviceDistance N
-  300A,00BB  IsocenterToBeamLimitingDeviceDist  N
-  300A,00BC  NumberOfLeafJawPairs               N
-  300A,00BE  LeafPositionBoundaries             N
-  300A,00C0  BeamNumber                         N
-  300A,00C2  BeamName                           N
-  300A,00C3  BeamDescription                    N
-  300A,00C4  BeamType                           N
-  300A,00C6  RadiationType                      N
-  300A,00C7  HighDoseTechniqueType              N
-  300A,00C8  ReferenceImageNumber               N
-  300A,00CA  PlannedVerificationImageSequence   N
-  300A,00CC  ImagingDeviceSpecificAcqParams     N
-  300A,00CE  TreatmentDeliveryType              N
-  300A,00D0  NumberOfWedges                     N
-  300A,00D1  WedgeSequence                      N
-  300A,00D2  WedgeNumber                        N
-  300A,00D3  WedgeType                          N
-  300A,00D4  WedgeID                            N
-  300A,00D5  WedgeAngle                         N
-  300A,00D6  WedgeFactor                        N
-  300A,00D7  TotalWedgeTrayWaterEquivThickness  N
-  300A,00D8  WedgeOrientation                   N
-  300A,00D9  IsocenterToWedgeTrayDistance       N
-  300A,00DA  SourceToWedgeTrayDistance          N
-  300A,00DB  WedgeThinEdgePosition              N
-  300A,00DC  BolusID                            N
-  300A,00DD  BolusDescription                   N
-  300A,00E0  NumberOfCompensators               N
-  300A,00E1  MaterialID                         N
-  300A,00E2  TotalCompensatorTrayFactor         N
-  300A,00E3  CompensatorSequence                N
-  300A,00E4  CompensatorNumber                  N
-  300A,00E5  CompensatorID                      N
-  300A,00E6  SourceToCompensatorTrayDistance    N
-  300A,00E7  CompensatorRows                    N
-  300A,00E8  CompensatorColumns                 N
-  300A,00E9  CompensatorPixelSpacing            N
-  300A,00EA  CompensatorPosition                N
-  300A,00EB  CompensatorTransmissionData        N
-  300A,00EC  CompensatorThicknessData           N
-  300A,00ED  NumberOfBoli                       N
-  300A,00EE  CompensatorType                    N
-  300A,00F0  NumberOfBlocks                     N
-  300A,00F2  TotalBlockTrayFactor               N
-  300A,00F3  TotalBlockTrayWaterEquivThickness  N
-  300A,00F4  BlockSequence                      N
-  300A,00F5  BlockTrayID                        N
-  300A,00F6  SourceToBlockTrayDistance          N
-  300A,00F7  IsocenterToBlockTrayDistance       N
-  300A,00F8  BlockType                          N
-  300A,00F9  AccessoryCode                      N
-  300A,00FA  BlockDivergence                    N
-  300A,00FB  BlockMountingPosition              N
-  300A,00FC  BlockNumber                        N
-  300A,00FE  BlockName                          N
-  300A,0100  BlockThickness                     N
-  300A,0102  BlockTransmission                  N
-  300A,0104  BlockNumberOfPoints                N
-  300A,0106  BlockData                          N
-  300A,0107  ApplicatorSequence                 N
-  300A,0108  ApplicatorID                       N
-  300A,0109  ApplicatorType                     N
-  300A,010A  ApplicatorDescription              N
-  300A,010C  CumulativeDoseReferenceCoefficient N
-  300A,010E  FinalCumulativeMetersetWeight      N
-  300A,0110  NumberOfControlPoints              N
-  300A,0111  ControlPointSequence               N
-  300A,0112  ControlPointIndex                  N
-  300A,0114  NominalBeamEnergy                  N
-  300A,0115  DoseRateSet                        N
-  300A,0116  WedgePositionSequence              N
-  300A,0118  WedgePosition                      N
-  300A,011A  BeamLimitingDevicePositionSequence N
-  300A,011C  LeafJawPositions                   N
-  300A,011E  GantryAngle                        N
-  300A,011F  GantryRotationDirection            N
-  300A,0120  BeamLimitingDeviceAngle            N
-  300A,0121  BeamLimitingDeviceRotateDirection  N
-  300A,0122  PatientSupportAngle                N
-  300A,0123  PatientSupportRotationDirection    N
-  300A,0124  TableTopEccentricAxisDistance      N
-  300A,0125  TableTopEccentricAngle             N
-  300A,0126  TableTopEccentricRotateDirection   N
-  300A,0128  TableTopVerticalPosition           N
-  300A,0129  TableTopLongitudinalPosition       N
-  300A,012A  TableTopLateralPosition            N
-  300A,012C  IsocenterPosition                  N
-  300A,012E  SurfaceEntryPoint                  N
-  300A,0130  SourceToSurfaceDistance            N
-  300A,0134  CumulativeMetersetWeight           N
-  300A,0140  TableTopPitchAngle                 N
-  300A,0142  TableTopPitchRotationDirection     N
-  300A,0144  TableTopRollAngle                  N
-  300A,0146  TableTopRollRotationDirection      N
-  300A,0148  HeadFixationAngle                  N
-  300A,014A  GantryPitchAngle                   N
-  300A,014C  GantryPitchRotationDirection       N
-  300A,014E  GantryPitchAngleTolerance          N
-  300A,0180  PatientSetupSequence               N
-  300A,0182  PatientSetupNumber                 N
-  300A,0183  PatientSetupLabel                  N
-  300A,0184  PatientAdditionalPosition          N
-  300A,0190  FixationDeviceSequence             N
-  300A,0192  FixationDeviceType                 N
-  300A,0194  FixationDeviceLabel                N
-  300A,0196  FixationDeviceDescription          N
-  300A,0198  FixationDevicePosition             N
-  300A,0199  FixationDevicePitchAngle           N
-  300A,019A  FixationDeviceRollAngle            N
-  300A,01A0  ShieldingDeviceSequence            N
-  300A,01A2  ShieldingDeviceType                N
-  300A,01A4  ShieldingDeviceLabel               N
-  300A,01A6  ShieldingDeviceDescription         N
-  300A,01A8  ShieldingDevicePosition            N
-  300A,01B0  SetupTechnique                     N
-  300A,01B2  SetupTechniqueDescription          N
-  300A,01B4  SetupDeviceSequence                N
-  300A,01B6  SetupDeviceType                    N
-  300A,01B8  SetupDeviceLabel                   N
-  300A,01BA  SetupDeviceDescription             N
-  300A,01BC  SetupDeviceParameter               N
-  300A,01D0  SetupReferenceDescription          N
-  300A,01D2  TableTopVerticalSetupDisplacement  N
-  300A,01D4  TableTopLongitudinalSetupDisplace  N
-  300A,01D6  TableTopLateralSetupDisplacement   N
-  300A,0200  BrachyTreatmentTechnique           N
-  300A,0202  BrachyTreatmentType                N
-  300A,0206  TreatmentMachineSequence           N
-  300A,0210  SourceSequence                     N
-  300A,0212  SourceNumber                       N
-  300A,0214  SourceType                         N
-  300A,0216  SourceManufacturer                 N
-  300A,0218  ActiveSourceDiameter               N
-  300A,021A  ActiveSourceLength                 N
-  300A,0222  SourceEncapsulationNomThickness    N
-  300A,0224  SourceEncapsulationNomTransmission N
-  300A,0226  SourceIsotopeName                  N
-  300A,0228  SourceIsotopeHalfLife              N
-  300A,0229  SourceStrengthUnits                N
-  300A,022A  ReferenceAirKermaRate              N
-  300A,022B  SourceStrength                     N
-  300A,022C  SourceStrengthReferenceDate        N
-  300A,022E  SourceStrengthReferenceTime        N
-  300A,0230  ApplicationSetupSequence           N
-  300A,0232  ApplicationSetupType               N
-  300A,0234  ApplicationSetupNumber             N
-  300A,0236  ApplicationSetupName               N
-  300A,0238  ApplicationSetupManufacturer       N
-  300A,0240  TemplateNumber                     N
-  300A,0242  TemplateType                       N
-  300A,0244  TemplateName                       N
-  300A,0250  TotalReferenceAirKerma             N
-  300A,0260  BrachyAccessoryDeviceSequence      N
-  300A,0262  BrachyAccessoryDeviceNumber        N
-  300A,0263  BrachyAccessoryDeviceID            N
-  300A,0264  BrachyAccessoryDeviceType          N
-  300A,0266  BrachyAccessoryDeviceName          N
-  300A,026A  BrachyAccessoryDeviceNomThickness  N
-  300A,026C  BrachyAccessoryDevNomTransmission  N
-  300A,0280  ChannelSequence                    N
-  300A,0282  ChannelNumber                      N
-  300A,0284  ChannelLength                      N
-  300A,0286  ChannelTotalTime                   N
-  300A,0288  SourceMovementType                 N
-  300A,028A  NumberOfPulses                     N
-  300A,028C  PulseRepetitionInterval            N
-  300A,0290  SourceApplicatorNumber             N
-  300A,0291  SourceApplicatorID                 N
-  300A,0292  SourceApplicatorType               N
-  300A,0294  SourceApplicatorName               N
-  300A,0296  SourceApplicatorLength             N
-  300A,0298  SourceApplicatorManufacturer       N
-  300A,029C  SourceApplicatorWallNomThickness   N
-  300A,029E  SourceApplicatorWallNomTrans       N
-  300A,02A0  SourceApplicatorStepSize           N
-  300A,02A2  TransferTubeNumber                 N
-  300A,02A4  TransferTubeLength                 N
-  300A,02B0  ChannelShieldSequence              N
-  300A,02B2  ChannelShieldNumber                N
-  300A,02B3  ChannelShieldID                    N
-  300A,02B4  ChannelShieldName                  N
-  300A,02B8  ChannelShieldNominalThickness      N
-  300A,02BA  ChannelShieldNominalTransmission   N
-  300A,02C8  FinalCumulativeTimeWeight          N
-  300A,02D0  BrachyControlPointSequence         N
-  300A,02D2  ControlPointRelativePosition       N
-  300A,02D4  ControlPoint3DPosition             N
-  300A,02D6  CumulativeTimeWeight               N
-  300A,02E0  CompensatorDivergence              N
-  300A,02E1  CompensatorMountingPosition        N
-  300A,02E2  SourceToCompensatorDistance        N
-  300A,02E3  TotalCompTrayWaterEquivThickness   N
-  300A,02E4  IsocenterToCompensatorTrayDistance N
-  300A,02E5  CompensatorColumnOffset            N
-  300A,02E6  IsocenterToCompensatorDistances    N
-  300A,02E7  CompensatorRelStoppingPowerRatio   N
-  300A,02E8  CompensatorMillingToolDiameter     N
-  300A,02EA  IonRangeCompensatorSequence        N
-  300A,02EB  CompensatorDescription             N
-  300A,0302  RadiationMassNumber                N
-  300A,0304  RadiationAtomicNumber              N
-  300A,0306  RadiationChargeState               N
-  300A,0308  ScanMode                           N
-  300A,030A  VirtualSourceAxisDistances         N
-  300A,030C  SnoutSequence                      N
-  300A,030D  SnoutPosition                      N
-  300A,030F  SnoutID                            N
-  300A,0312  NumberOfRangeShifters              N
-  300A,0314  RangeShifterSequence               N
-  300A,0316  RangeShifterNumber                 N
-  300A,0318  RangeShifterID                     N
-  300A,0320  RangeShifterType                   N
-  300A,0322  RangeShifterDescription            N
-  300A,0330  NumberOfLateralSpreadingDevices    N
-  300A,0332  LateralSpreadingDeviceSequence     N
-  300A,0334  LateralSpreadingDeviceNumber       N
-  300A,0336  LateralSpreadingDeviceID           N
-  300A,0338  LateralSpreadingDeviceType         N
-  300A,033A  LateralSpreadingDeviceDescription  N
-  300A,033C  LateralSpreadingDevWaterEquivThick N
-  300A,0340  NumberOfRangeModulators            N
-  300A,0342  RangeModulatorSequence             N
-  300A,0344  RangeModulatorNumber               N
-  300A,0346  RangeModulatorID                   N
-  300A,0348  RangeModulatorType                 N
-  300A,034A  RangeModulatorDescription          N
-  300A,034C  BeamCurrentModulationID            N
-  300A,0350  PatientSupportType                 N
-  300A,0352  PatientSupportID                   N
-  300A,0354  PatientSupportAccessoryCode        N
-  300A,0356  FixationLightAzimuthalAngle        N
-  300A,0358  FixationLightPolarAngle            N
-  300A,035A  MetersetRate                       N
-  300A,0360  RangeShifterSettingsSequence       N
-  300A,0362  RangeShifterSetting                N
-  300A,0364  IsocenterToRangeShifterDistance    N
-  300A,0366  RangeShifterWaterEquivThickness    N
-  300A,0370  LateralSpreadingDeviceSettingsSeq  N
-  300A,0372  LateralSpreadingDeviceSetting      N
-  300A,0374  IsocenterToLateralSpreadingDevDist N
-  300A,0380  RangeModulatorSettingsSequence     N
-  300A,0382  RangeModulatorGatingStartValue     N
-  300A,0384  RangeModulatorGatingStopValue      N
-  300A,038A  IsocenterToRangeModulatorDistance  N
-  300A,0390  ScanSpotTuneID                     N
-  300A,0392  NumberOfScanSpotPositions          N
-  300A,0394  ScanSpotPositionMap                N
-  300A,0396  ScanSpotMetersetWeights            N
-  300A,0398  ScanningSpotSize                   N
-  300A,039A  NumberOfPaintings                  N
-  300A,03A0  IonToleranceTableSequence          N
-  300A,03A2  IonBeamSequence                    N
-  300A,03A4  IonBeamLimitingDeviceSequence      N
-  300A,03A6  IonBlockSequence                   N
-  300A,03A8  IonControlPointSequence            N
-  300A,03AA  IonWedgeSequence                   N
-  300A,03AC  IonWedgePositionSequence           N
-  300A,0401  ReferencedSetupImageSequence       N
-  300A,0402  SetupImageComment                  N
-  300A,0410  MotionSynchronizationSequence      N
-  300A,0412  ControlPointOrientation            N
-  300A,0420  GeneralAccessorySequence           N
-  300A,0421  GeneralAccessoryID                 N
-  300A,0422  GeneralAccessoryDescription        N
-  300A,0423  GeneralAccessoryType               N
-  300A,0424  GeneralAccessoryNumber             N
-  300C,0002  ReferencedRTPlanSequence           N
-  300C,0004  ReferencedBeamSequence             N
-  300C,0006  ReferencedBeamNumber               N
-  300C,0007  ReferencedReferenceImageNumber     N
-  300C,0008  StartCumulativeMetersetWeight      N
-  300C,0009  EndCumulativeMetersetWeight        N
-  300C,000A  ReferencedBrachyAppSetupSeq        N
-  300C,000C  ReferencedBrachyAppSetupNumber     N
-  300C,000E  ReferencedSourceNumber             N
-  300C,0020  ReferencedFractionGroupSequence    N
-  300C,0022  ReferencedFractionGroupNumber      N
-  300C,0040  ReferencedVerificationImageSeq     N
-  300C,0042  ReferencedReferenceImageSequence   N
-  300C,0050  ReferencedDoseReferenceSequence    N
-  300C,0051  ReferencedDoseReferenceNumber      N
-  300C,0055  BrachyReferencedDoseReferenceSeq   N
-  300C,0060  ReferencedStructureSetSequence     N
-  300C,006A  ReferencedPatientSetupNumber       N
-  300C,0080  ReferencedDoseSequence             N
-  300C,00A0  ReferencedToleranceTableNumber     N
-  300C,00B0  ReferencedBolusSequence            N
-  300C,00C0  ReferencedWedgeNumber              N
-  300C,00D0  ReferencedCompensatorNumber        N
-  300C,00E0  ReferencedBlockNumber              N
-  300C,00F0  ReferencedControlPointIndex        N
-  300C,00F2  ReferencedControlPointSequence     N
-  300C,00F4  ReferencedStartControlPointIndex   N
-  300C,00F6  ReferencedStopControlPointIndex    N
-  300C,0100  ReferencedRangeShifterNumber       N
-  300C,0102  ReferencedLateralSpreadingDevNum   N
-  300C,0104  ReferencedRangeModulatorNumber     N
-  300E,0002  ApprovalStatus                     N
-  300E,0004  ReviewDate                         N
-  300E,0005  ReviewTime                         N
-  300E,0008  ReviewerName                       N
-  4000,0000  TextGroupLength                    N
-  4000,0010  Arbitrary                          N
-  4000,4000  TextComments                       N
-  4008,0040  ResultsID                          N
-  4008,0042  ResultsIDIssuer                    N
-  4008,0050  ReferencedInterpretationSequence   N
-  4008,0100  InterpretationRecordedDate         N
-  4008,0101  InterpretationRecordedTime         N
-  4008,0102  InterpretationRecorder             N
-  4008,0103  ReferenceToRecordedSound           N
-  4008,0108  InterpretationTranscriptionDate    N
-  4008,0109  InterpretationTranscriptionTime    N
-  4008,010A  InterpretationTranscriber          N
-  4008,010B  InterpretationText                 N
-  4008,010C  InterpretationAuthor               N
-  4008,0111  InterpretationApproverSequence     N
-  4008,0112  InterpretationApprovalDate         N
-  4008,0113  InterpretationApprovalTime         N
-  4008,0114  PhysicianApprovingInterpretation   N
-  4008,0115  InterpretationDiagnosisDescription N
-  4008,0117  InterpretationDiagnosisCodeSeq     N
-  4008,0118  ResultsDistributionListSequence    N
-  4008,0119  DistributionName                   N
-  4008,011A  DistributionAddress                N
-  4008,0200  InterpretationID                   N
-  4008,0202  InterpretationIDIssuer             N
-  4008,0210  InterpretationTypeID               N
-  4008,0212  InterpretationStatusID             N
-  4008,0300  Impressions                        N
-  4008,4000  ResultsComments                    N
-  4FFE,0001  MACParametersSequence              N
-  50xx,0005  CurveDimensions                    N
-  50xx,0010  NumberOfPoints                     N
-  50xx,0020  TypeOfData                         N
-  50xx,0022  CurveDescription                   N
-  50xx,0030  AxisUnits                          N
-  50xx,0040  AxisLabels                         N
-  50xx,0103  DataValueRepresentation            N
-  50xx,0104  MinimumCoordinateValue             N
-  50xx,0105  MaximumCoordinateValue             N
-  50xx,0106  CurveRange                         N
-  50xx,0110  CurveDataDescriptor                N
-  50xx,0112  CoordinateStartValue               N
-  50xx,0114  CoordinateStepValue                N
-  50xx,1001  CurveActivationLayer               N
-  50xx,2000  AudioType                          N
-  50xx,2002  AudioSampleFormat                  N
-  50xx,2004  NumberOfChannels                   N
-  50xx,2006  NumberOfSamples                    N
-  50xx,2008  SampleRate                         N
-  50xx,200A  TotalTime                          N
-  50xx,200C  AudioSampleData                    N
-  50xx,200E  AudioComments                      N
-  50xx,2500  CurveLabel                         N
-  50xx,2600  ReferencedOverlaySequence          N
-  50xx,2610  ReferencedOverlayGroup             N
-  50xx,3000  CurveData                          N
-  5200,9229  SharedFunctionalGroupsSequence     N
-  5200,9230  PerFrameFunctionalGroupsSequence   N
-  5400,0100  WaveformSequence                   N
-  5400,0110  ChannelMinimumValue                N
-  5400,0112  ChannelMaximumValue                N
-  5400,1004  WaveformBitsAllocated              N
-  5400,1006  WaveformSampleInterpretation       N
-  5400,100A  WaveformPaddingValue               N
-  5400,1010  WaveformData                       N
-  5600,0010  FirstOrderPhaseCorrectionAngle     N
-  5600,0020  SpectroscopyData                   N
-  6000,0000  OverlayGroupLength                 N
-  60xx,0010  OverlayRows                        N
-  60xx,0011  OverlayColumns                     N
-  60xx,0012  OverlayPlanes                      N
-  60xx,0015  NumberOfFramesInOverlay            N
-  60xx,0022  OverlayDescription                 N
-  60xx,0040  OverlayType                        N
-  60xx,0045  OverlaySubtype                     N
-  60xx,0050  OverlayOrigin                      N
-  60xx,0051  ImageFrameOrigin                   N
-  60xx,0052  OverlayPlaneOrigin                 N
-  60xx,0060  OverlayCompressionCode             N
-  60xx,0061  OverlayCompressionOriginator       N
-  60xx,0062  OverlayCompressionLabel            N
-  60xx,0063  OverlayCompressionDescription      N
-  60xx,0066  OverlayCompressionStepPointers     N
-  60xx,0068  OverlayRepeatInterval              N
-  60xx,0069  OverlayBitsGrouped                 N
-  60xx,0100  OverlayBitsAllocated               N
-  60xx,0102  OverlayBitPosition                 N
-  60xx,0110  OverlayFormat                      N
-  60xx,0200  OverlayLocation                    N
-  60xx,0800  OverlayCodeLabel                   N
-  60xx,0802  OverlayNumberOfTables              N
-  60xx,0803  OverlayCodeTableLocation           N
-  60xx,0804  OverlayBitsForCodeWord             N
-  60xx,1001  OverlayActivationLayer             N
-  60xx,1100  OverlayDescriptorGray              N
-  60xx,1101  OverlayDescriptorRed               N
-  60xx,1102  OverlayDescriptorGreen             N
-  60xx,1103  OverlayDescriptorBlue              N
-  60xx,1200  OverlaysGray                       N
-  60xx,1201  OverlaysRed                        N
-  60xx,1202  OverlaysGreen                      N
-  60xx,1203  OverlaysBlue                       N
-  60xx,1301  ROIArea                            N
-  60xx,1302  ROIMean                            N
-  60xx,1303  ROIStandardDeviation               N
-  60xx,1500  OverlayLabel                       N
-  60xx,3000  OverlayData                        N
-  60xx,4000  OverlayComments                    N
-  7Fxx,0000  PixelDataGroupLength               N
-  7Fxx,0010  PixelData                          N
-  7Fxx,0011  VariableNextDataGroup              N
-  7Fxx,0020  VariableCoefficientsSDVN           N
-  7Fxx,0030  VariableCoefficientsSDHN           N
-  7Fxx,0040  VariableCoefficientsSDDN           N
-  FFFA,FFFA  DigitalSignaturesSequence          N
-  FFFC,FFFC  DataSetTrailingPadding             N
-  FFFE,E000  StartOfItem                        N
-  FFFE,E00D  EndOfItems                         N
-  FFFE,E0DD  EndOfSequence                      N
+  0002,0000  FileMetaInfoGroupLength            no
+  0002,0001  FileMetaInfoVersion                no
+  0002,0002  MediaStorageSOPClassUID            no
+  0002,0003  MediaStorageSOPInstanceUID         no
+  0002,0010  TransferSyntaxUID                  no
+  0002,0012  ImplementationClassUID             no
+  0002,0013  ImplementationVersionName          no
+  0002,0016  SourceApplicationEntityTitle       no
+  0002,0100  PrivateInformationCreatorUID       no
+  0002,0102  PrivateInformation                 no
+  0004,1130  FileSetID                          no
+  0004,1141  FileSetDescriptorFileID            no
+  0004,1142  SpecificCharacterSetOfFile         no
+  0004,1200  FirstDirectoryRecordOffset         no
+  0004,1202  LastDirectoryRecordOffset          no
+  0004,1212  FileSetConsistencyFlag             no
+  0004,1220  DirectoryRecordSequence            no
+  0004,1400  OffsetOfNextDirectoryRecord        no
+  0004,1410  RecordInUseFlag                    no
+  0004,1420  LowerLevelDirectoryEntityOffset    no
+  0004,1430  DirectoryRecordType                no
+  0004,1432  PrivateRecordUID                   no
+  0004,1500  ReferencedFileID                   no
+  0004,1504  MRDRDirectoryRecordOffset          no
+  0004,1510  ReferencedSOPClassUIDInFile        no
+  0004,1511  ReferencedSOPInstanceUIDInFile     no
+  0004,1512  ReferencedTransferSyntaxUIDInFile  no
+  0004,151A  ReferencedRelatedSOPClassUIDInFile no
+  0004,1600  NumberOfReferences                 no
+  0008,0000  IdentifyingGroupLength             no
+  0008,0001  LengthToEnd                        no
+  0008,0005  SpecificCharacterSet               no
+  0008,0006  LanguageCodeSequence               no
+  0008,0008  ImageType                          no
+  0008,0010  RecognitionCode                    no
+  0008,0012  InstanceCreationDate               no
+  0008,0013  InstanceCreationTime               no
+  0008,0014  InstanceCreatorUID                 no
+  0008,0016  SOPClassUID                        no
+  0008,0018  SOPInstanceUID                     no
+  0008,001A  RelatedGeneralSOPClassUID          no
+  0008,001B  OriginalSpecializedSOPClassUID     no
+  0008,0020  StudyDate                          no
+  0008,0021  SeriesDate                         no
+  0008,0022  AcquisitionDate                    no
+  0008,0023  ContentDate                        no
+  0008,0024  OverlayDate                        no
+  0008,0025  CurveDate                          no
+  0008,002A  AcquisitionDateTime                no
+  0008,0030  StudyTime                          no
+  0008,0031  SeriesTime                         no
+  0008,0032  AcquisitionTime                    no
+  0008,0033  ContentTime                        no
+  0008,0034  OverlayTime                        no
+  0008,0035  CurveTime                          no
+  0008,0040  DataSetType                        no
+  0008,0041  DataSetSubtype                     no
+  0008,0042  NuclearMedicineSeriesType          no
+  0008,0050  AccessionNumber                    no
+  0008,0052  QueryRetrieveLevel                 no
+  0008,0054  RetrieveAETitle                    no
+  0008,0056  InstanceAvailability               no
+  0008,0058  FailedSOPInstanceUIDList           no
+  0008,0060  Modality                           no
+  0008,0061  ModalitiesInStudy                  no
+  0008,0062  SOPClassesInStudy                  no
+  0008,0064  ConversionType                     no
+  0008,0068  PresentationIntentType             no
+  0008,0070  Manufacturer                       no
+  0008,0080  InstitutionName                    no
+  0008,0081  InstitutionAddress                 no
+  0008,0082  InstitutionCodeSequence            no
+  0008,0090  ReferringPhysicianName             no
+  0008,0092  ReferringPhysicianAddress          no
+  0008,0094  ReferringPhysicianTelephoneNumber  no
+  0008,0096  ReferringPhysicianIDSequence       no
+  0008,0100  CodeValue                          no
+  0008,0102  CodingSchemeDesignator             no
+  0008,0103  CodingSchemeVersion                no
+  0008,0104  CodeMeaning                        no
+  0008,0105  MappingResource                    no
+  0008,0106  ContextGroupVersion                no
+  0008,0107  ContextGroupLocalVersion           no
+  0008,010B  ContextGroupExtensionFlag          no
+  0008,010C  CodingSchemeUID                    no
+  0008,010D  ContextGroupExtensionCreatorUID    no
+  0008,010F  ContextIdentifier                  no
+  0008,0110  CodingSchemeIDSequence             no
+  0008,0112  CodingSchemeRegistry               no
+  0008,0114  CodingSchemeExternalID             no
+  0008,0115  CodingSchemeName                   no
+  0008,0116  ResponsibleOrganization            no
+  0008,0117  ContextUID                         no
+  0008,0201  TimezoneOffsetFromUTC              no
+  0008,1000  NetworkID                          no
+  0008,1010  StationName                        no
+  0008,1030  StudyDescription                   no
+  0008,1032  ProcedureCodeSequence              no
+  0008,103E  SeriesDescription                  no
+  0008,1040  InstitutionalDepartmentName        no
+  0008,1048  PhysiciansOfRecord                 no
+  0008,1049  PhysiciansOfRecordIDSequence       no
+  0008,1050  PerformingPhysicianName            no
+  0008,1052  PerformingPhysicianIDSequence      no
+  0008,1060  NameOfPhysicianReadingStudy        no
+  0008,1062  PhysicianReadingStudyIDSequence    no
+  0008,1070  OperatorsName                      no
+  0008,1072  OperatorIDSequence                 no
+  0008,1080  AdmittingDiagnosesDescription      no
+  0008,1084  AdmittingDiagnosesCodeSequence     no
+  0008,1090  ManufacturersModelName             no
+  0008,1100  ReferencedResultsSequence          no
+  0008,1110  ReferencedStudySequence            no
+  0008,1111  ReferencedProcedureStepSequence    no
+  0008,1115  ReferencedSeriesSequence           no
+  0008,1120  ReferencedPatientSequence          no
+  0008,1125  ReferencedVisitSequence            no
+  0008,1130  ReferencedOverlaySequence          no
+  0008,113A  ReferencedWaveformSequence         no
+  0008,1140  ReferencedImageSequence            no
+  0008,1145  ReferencedCurveSequence            no
+  0008,114A  ReferencedInstanceSequence         no
+  0008,1150  ReferencedSOPClassUID              no
+  0008,1155  ReferencedSOPInstanceUID           no
+  0008,115A  SOPClassesSupported                no
+  0008,1160  ReferencedFrameNumber              no
+  0008,1161  SimpleFrameList                    no
+  0008,1162  CalculatedFrameList                no
+  0008,1163  TimeRange                          no
+  0008,1164  FrameExtractionSequence            no
+  0008,1195  TransactionUID                     no
+  0008,1197  FailureReason                      no
+  0008,1198  FailedSOPSequence                  no
+  0008,1199  ReferencedSOPSequence              no
+  0008,1200  OtherReferencedStudiesSequence     no
+  0008,1250  RelatedSeriesSequence              no
+  0008,2110  LossyImageCompression              no
+  0008,2111  DerivationDescription              no
+  0008,2112  SourceImageSequence                no
+  0008,2120  StageName                          no
+  0008,2122  StageNumber                        no
+  0008,2124  NumberOfStages                     no
+  0008,2127  ViewName                           no
+  0008,2128  ViewNumber                         no
+  0008,2129  NumberOfEventTimers                no
+  0008,212A  NumberOfViewsInStage               no
+  0008,2130  EventElapsedTimes                  no
+  0008,2132  EventTimerNames                    no
+  0008,2133  EventTimerSequence                 no
+  0008,2134  EventTimeOffset                    no
+  0008,2135  EventCodeSequence                  no
+  0008,2142  StartTrim                          no
+  0008,2143  StopTrim                           no
+  0008,2144  RecommendedDisplayFrameRate        no
+  0008,2200  TransducerPosition                 no
+  0008,2204  TransducerOrientation              no
+  0008,2208  AnatomicStructure                  no
+  0008,2218  AnatomicRegionSequence             no
+  0008,2220  AnatomicRegionModifierSequence     no
+  0008,2228  PrimaryAnatomicStructureSequence   no
+  0008,2229  AnatomicStructureOrRegionSequence  no
+  0008,2230  AnatomicStructureModifierSequence  no
+  0008,2240  TransducerPositionSequence         no
+  0008,2242  TransducerPositionModifierSequence no
+  0008,2244  TransducerOrientationSequence      no
+  0008,2246  TransducerOrientationModifierSeq   no
+  0008,2253  AnatomicEntrancePortalCodeSeqTrial no
+  0008,2255  AnatomicApproachDirCodeSeqTrial    no
+  0008,2256  AnatomicPerspectiveDescrTrial      no
+  0008,2257  AnatomicPerspectiveCodeSeqTrial    no
+  0008,3001  AlternateRepresentationSequence    no
+  0008,3010  IrradiationEventUID                no
+  0008,4000  IdentifyingComments                no
+  0008,9007  FrameType                          no
+  0008,9092  ReferencedImageEvidenceSequence    no
+  0008,9121  ReferencedRawDataSequence          no
+  0008,9123  CreatorVersionUID                  no
+  0008,9124  DerivationImageSequence            no
+  0008,9154  SourceImageEvidenceSequence        no
+  0008,9205  PixelPresentation                  no
+  0008,9206  VolumetricProperties               no
+  0008,9207  VolumeBasedCalculationTechnique    no
+  0008,9208  ComplexImageComponent              no
+  0008,9209  AcquisitionContrast                no
+  0008,9215  DerivationCodeSequence             no
+  0008,9237  GrayscalePresentationStateSequence no
+  0008,9410  ReferencedOtherPlaneSequence       no
+  0008,9458  FrameDisplaySequence               no
+  0008,9459  RecommendedDisplayFrameRateInFloat no
+  0008,9460  SkipFrameRangeFlag                 no
+  0009,1001  FullFidelity                       no
+  0009,1002  SuiteID                            no
+  0009,1004  ProductID                          no
+  0009,1027  ImageActualDate                    no
+  0009,1030  ServiceID                          no
+  0009,1031  MobileLocationNumber               no
+  0009,10E3  EquipmentUID                       no
+  0009,10E6  GenesisVersionNow                  no
+  0009,10E7  ExamRecordChecksum                 no
+  0009,10E9  ActualSeriesDataTimeStamp          no
+  0010,0000  PatientGroupLength                 no
+  0010,0010  PatientName                        no
+  0010,0020  PatientID                          no
+  0010,0021  IssuerOfPatientID                  no
+  0010,0022  TypeOfPatientID                    no
+  0010,0030  PatientBirthDate                   no
+  0010,0032  PatientBirthTime                   no
+  0010,0040  PatientSex                         no
+  0010,0050  PatientInsurancePlanCodeSequence   no
+  0010,0101  PatientPrimaryLanguageCodeSeq      no
+  0010,0102  PatientPrimaryLanguageCodeModSeq   no
+  0010,1000  OtherPatientIDs                    no
+  0010,1001  OtherPatientNames                  no
+  0010,1002  OtherPatientIDsSequence            no
+  0010,1005  PatientBirthName                   no
+  0010,1010  PatientAge                         no
+  0010,1020  PatientSize                        no
+  0010,1030  PatientWeight                      no
+  0010,1040  PatientAddress                     no
+  0010,1050  InsurancePlanIdentification        no
+  0010,1060  PatientMotherBirthName             no
+  0010,1080  MilitaryRank                       no
+  0010,1081  BranchOfService                    no
+  0010,1090  MedicalRecordLocator               no
+  0010,2000  MedicalAlerts                      no
+  0010,2110  Allergies                          no
+  0010,2150  CountryOfResidence                 no
+  0010,2152  RegionOfResidence                  no
+  0010,2154  PatientTelephoneNumbers            no
+  0010,2160  EthnicGroup                        no
+  0010,2180  Occupation                         no
+  0010,21A0  SmokingStatus                      no
+  0010,21B0  AdditionalPatientHistory           no
+  0010,21C0  PregnancyStatus                    no
+  0010,21D0  LastMenstrualDate                  no
+  0010,21F0  PatientReligiousPreference         no
+  0010,2201  PatientSpeciesDescription          no
+  0010,2202  PatientSpeciesCodeSequence         no
+  0010,2203  PatientSexNeutered                 no
+  0010,2210  AnatomicalOrientationType          no
+  0010,2292  PatientBreedDescription            no
+  0010,2293  PatientBreedCodeSequence           no
+  0010,2294  BreedRegistrationSequence          no
+  0010,2295  BreedRegistrationNumber            no
+  0010,2296  BreedRegistryCodeSequence          no
+  0010,2297  ResponsiblePerson                  no
+  0010,2298  ResponsiblePersonRole              no
+  0010,2299  ResponsibleOrganization            no
+  0010,4000  PatientComments                    no
+  0010,9431  ExaminedBodyThickness              no
+  0011,1010  PatientStatus                      no
+  0012,0010  ClinicalTrialSponsorName           no
+  0012,0020  ClinicalTrialProtocolID            no
+  0012,0021  ClinicalTrialProtocolName          no
+  0012,0030  ClinicalTrialSiteID                no
+  0012,0031  ClinicalTrialSiteName              no
+  0012,0040  ClinicalTrialSubjectID             no
+  0012,0042  ClinicalTrialSubjectReadingID      no
+  0012,0050  ClinicalTrialTimePointID           no
+  0012,0051  ClinicalTrialTimePointDescription  no
+  0012,0060  ClinicalTrialCoordinatingCenter    no
+  0012,0062  PatientIdentityRemoved             no
+  0012,0063  DeidentificationMethod             no
+  0012,0064  DeidentificationMethodCodeSequence no
+  0012,0071  ClinicalTrialSeriesID              no
+  0012,0072  ClinicalTrialSeriesDescription     no
+  0012,0084  DistributionType                   no
+  0012,0085  ConsentForDistributionFlag         no
+  0018,0000  AcquisitionGroupLength             no
+  0018,0010  ContrastBolusAgent                 no
+  0018,0012  ContrastBolusAgentSequence         no
+  0018,0014  ContrastBolusAdministrationRoute   no
+  0018,0015  BodyPartExamined                   no
+  0018,0020  ScanningSequence                   no
+  0018,0021  SequenceVariant                    no
+  0018,0022  ScanOptions                        no
+  0018,0023  MRAcquisitionType                  no
+  0018,0024  SequenceName                       no
+  0018,0025  AngioFlag                          no
+  0018,0026  InterventionDrugInformationSeq     no
+  0018,0027  InterventionDrugStopTime           no
+  0018,0028  InterventionDrugDose               no
+  0018,0029  InterventionDrugSequence           no
+  0018,002A  AdditionalDrugSequence             no
+  0018,0030  Radionuclide                       no
+  0018,0031  Radiopharmaceutical                no
+  0018,0032  EnergyWindowCenterline             no
+  0018,0033  EnergyWindowTotalWidth             no
+  0018,0034  InterventionDrugName               no
+  0018,0035  InterventionDrugStartTime          no
+  0018,0036  InterventionSequence               no
+  0018,0037  TherapyType                        no
+  0018,0038  InterventionStatus                 no
+  0018,0039  TherapyDescription                 no
+  0018,003A  InterventionDescription            no
+  0018,0040  CineRate                           no
+  0018,0042  InitialCineRunState                no
+  0018,0050  SliceThickness                     no
+  0018,0060  KVP                                no
+  0018,0070  CountsAccumulated                  no
+  0018,0071  AcquisitionTerminationCondition    no
+  0018,0072  EffectiveDuration                  no
+  0018,0073  AcquisitionStartCondition          no
+  0018,0074  AcquisitionStartConditionData      no
+  0018,0075  AcquisitionEndConditionData        no
+  0018,0080  RepetitionTime                     no
+  0018,0081  EchoTime                           no
+  0018,0082  InversionTime                      no
+  0018,0083  NumberOfAverages                   no
+  0018,0084  ImagingFrequency                   no
+  0018,0085  ImagedNucleus                      no
+  0018,0086  EchoNumber                         no
+  0018,0087  MagneticFieldStrength              no
+  0018,0088  SpacingBetweenSlices               no
+  0018,0089  NumberOfPhaseEncodingSteps         no
+  0018,0090  DataCollectionDiameter             no
+  0018,0091  EchoTrainLength                    no
+  0018,0093  PercentSampling                    no
+  0018,0094  PercentPhaseFieldOfView            no
+  0018,0095  PixelBandwidth                     no
+  0018,1000  DeviceSerialNumber                 no
+  0018,1002  DeviceUID                          no
+  0018,1003  DeviceID                           no
+  0018,1004  PlateID                            no
+  0018,1005  GeneratorID                        no
+  0018,1006  GridID                             no
+  0018,1007  CassetteID                         no
+  0018,1008  GantryID                           no
+  0018,1010  SecondaryCaptureDeviceID           no
+  0018,1011  HardcopyCreationDeviceID           no
+  0018,1012  DateOfSecondaryCapture             no
+  0018,1014  TimeOfSecondaryCapture             no
+  0018,1016  SecondaryCaptureDeviceManufacturer no
+  0018,1017  HardcopyDeviceManufacturer         no
+  0018,1018  SecondaryCaptureDeviceModelName    no
+  0018,1019  SecondaryCaptureDeviceSoftwareVers no
+  0018,101A  HardcopyDeviceSoftwareVersion      no
+  0018,101B  HardcopyDeviceModelName            no
+  0018,1020  SoftwareVersion                    no
+  0018,1022  VideoImageFormatAcquired           no
+  0018,1023  DigitalImageFormatAcquired         no
+  0018,1030  ProtocolName                       no
+  0018,1040  ContrastBolusRoute                 no
+  0018,1041  ContrastBolusVolume                no
+  0018,1042  ContrastBolusStartTime             no
+  0018,1043  ContrastBolusStopTime              no
+  0018,1044  ContrastBolusTotalDose             no
+  0018,1045  SyringeCounts                      no
+  0018,1046  ContrastFlowRate                   no
+  0018,1047  ContrastFlowDuration               no
+  0018,1048  ContrastBolusIngredient            no
+  0018,1049  ContrastBolusConcentration         no
+  0018,1050  SpatialResolution                  no
+  0018,1060  TriggerTime                        no
+  0018,1061  TriggerSourceOrType                no
+  0018,1062  NominalInterval                    no
+  0018,1063  FrameTime                          no
+  0018,1064  CardiacFramingType                 no
+  0018,1065  FrameTimeVector                    no
+  0018,1066  FrameDelay                         no
+  0018,1067  ImageTriggerDelay                  no
+  0018,1068  MultiplexGroupTimeOffset           no
+  0018,1069  TriggerTimeOffset                  no
+  0018,106A  SynchronizationTrigger             no
+  0018,106C  SynchronizationChannel             no
+  0018,106E  TriggerSamplePosition              no
+  0018,1070  RadiopharmaceuticalRoute           no
+  0018,1071  RadiopharmaceuticalVolume          no
+  0018,1072  RadiopharmaceuticalStartTime       no
+  0018,1073  RadiopharmaceuticalStopTime        no
+  0018,1074  RadionuclideTotalDose              no
+  0018,1075  RadionuclideHalfLife               no
+  0018,1076  RadionuclidePositronFraction       no
+  0018,1077  RadiopharmaceuticalSpecActivity    no
+  0018,1078  RadiopharmaceuticalStartDateTime   no
+  0018,1079  RadiopharmaceuticalStopDateTime    no
+  0018,1080  BeatRejectionFlag                  no
+  0018,1081  LowRRValue                         no
+  0018,1082  HighRRValue                        no
+  0018,1083  IntervalsAcquired                  no
+  0018,1084  IntervalsRejected                  no
+  0018,1085  PVCRejection                       no
+  0018,1086  SkipBeats                          no
+  0018,1088  HeartRate                          no
+  0018,1090  CardiacNumberOfImages              no
+  0018,1094  TriggerWindow                      no
+  0018,1100  ReconstructionDiameter             no
+  0018,1110  DistanceSourceToDetector           no
+  0018,1111  DistanceSourceToPatient            no
+  0018,1114  EstimatedRadiographicMagnification no
+  0018,1120  GantryDetectorTilt                 no
+  0018,1121  GantryDetectorSlew                 no
+  0018,1130  TableHeight                        no
+  0018,1131  TableTraverse                      no
+  0018,1134  TableMotion                        no
+  0018,1135  TableVerticalIncrement             no
+  0018,1136  TableLateralIncrement              no
+  0018,1137  TableLongitudinalIncrement         no
+  0018,1138  TableAngle                         no
+  0018,113A  TableType                          no
+  0018,1140  RotationDirection                  no
+  0018,1141  AngularPosition                    no
+  0018,1142  RadialPosition                     no
+  0018,1143  ScanArc                            no
+  0018,1144  AngularStep                        no
+  0018,1145  CenterOfRotationOffset             no
+  0018,1146  RotationOffset                     no
+  0018,1147  FieldOfViewShape                   no
+  0018,1149  FieldOfViewDimensions              no
+  0018,1150  ExposureTime                       no
+  0018,1151  XRayTubeCurrent                    no
+  0018,1152  Exposure                           no
+  0018,1153  ExposureInMicroAmpSec              no
+  0018,1154  AveragePulseWidth                  no
+  0018,1155  RadiationSetting                   no
+  0018,1156  RectificationType                  no
+  0018,115A  RadiationMode                      no
+  0018,115E  ImageAreaDoseProduct               no
+  0018,1160  FilterType                         no
+  0018,1161  TypeOfFilters                      no
+  0018,1162  IntensifierSize                    no
+  0018,1164  ImagerPixelSpacing                 no
+  0018,1166  Grid                               no
+  0018,1170  GeneratorPower                     no
+  0018,1180  CollimatorGridName                 no
+  0018,1181  CollimatorType                     no
+  0018,1182  FocalDistance                      no
+  0018,1183  XFocusCenter                       no
+  0018,1184  YFocusCenter                       no
+  0018,1190  FocalSpots                         no
+  0018,1191  AnodeTargetMaterial                no
+  0018,11A0  BodyPartThickness                  no
+  0018,11A2  CompressionForce                   no
+  0018,1200  DateOfLastCalibration              no
+  0018,1201  TimeOfLastCalibration              no
+  0018,1210  ConvolutionKernel                  no
+  0018,1240  UpperLowerPixelValues              no
+  0018,1242  ActualFrameDuration                no
+  0018,1243  CountRate                          no
+  0018,1244  PreferredPlaybackSequencing        no
+  0018,1250  ReceiveCoilName                    no
+  0018,1251  TransmitCoilName                   no
+  0018,1260  PlateType                          no
+  0018,1261  PhosphorType                       no
+  0018,1300  ScanVelocity                       no
+  0018,1301  WholeBodyTechnique                 no
+  0018,1302  ScanLength                         no
+  0018,1310  AcquisitionMatrix                  no
+  0018,1312  InPlanePhaseEncodingDirection      no
+  0018,1314  FlipAngle                          no
+  0018,1315  VariableFlipAngleFlag              no
+  0018,1316  SAR                                no
+  0018,1318  DB-Dt                              no
+  0018,1400  AcquisitionDeviceProcessingDescr   no
+  0018,1401  AcquisitionDeviceProcessingCode    no
+  0018,1402  CassetteOrientation                no
+  0018,1403  CassetteSize                       no
+  0018,1404  ExposuresOnPlate                   no
+  0018,1405  RelativeXRayExposure               no
+  0018,1450  ColumnAngulation                   no
+  0018,1460  TomoLayerHeight                    no
+  0018,1470  TomoAngle                          no
+  0018,1480  TomoTime                           no
+  0018,1490  TomoType                           no
+  0018,1491  TomoClass                          no
+  0018,1495  NumberOfTomosynthesisSourceImages  no
+  0018,1500  PositionerMotion                   no
+  0018,1508  PositionerType                     no
+  0018,1510  PositionerPrimaryAngle             no
+  0018,1511  PositionerSecondaryAngle           no
+  0018,1520  PositionerPrimaryAngleIncrement    no
+  0018,1521  PositionerSecondaryAngleIncrement  no
+  0018,1530  DetectorPrimaryAngle               no
+  0018,1531  DetectorSecondaryAngle             no
+  0018,1600  ShutterShape                       no
+  0018,1602  ShutterLeftVerticalEdge            no
+  0018,1604  ShutterRightVerticalEdge           no
+  0018,1606  ShutterUpperHorizontalEdge         no
+  0018,1608  ShutterLowerHorizontalEdge         no
+  0018,1610  CenterOfCircularShutter            no
+  0018,1612  RadiusOfCircularShutter            no
+  0018,1620  VerticesOfPolygonalShutter         no
+  0018,1622  ShutterPresentationValue           no
+  0018,1623  ShutterOverlayGroup                no
+  0018,1624  ShutterPresentationColorCIELabVal  no
+  0018,1700  CollimatorShape                    no
+  0018,1702  CollimatorLeftVerticalEdge         no
+  0018,1704  CollimatorRightVerticalEdge        no
+  0018,1706  CollimatorUpperHorizontalEdge      no
+  0018,1708  CollimatorLowerHorizontalEdge      no
+  0018,1710  CenterOfCircularCollimator         no
+  0018,1712  RadiusOfCircularCollimator         no
+  0018,1720  VerticesOfPolygonalCollimator      no
+  0018,1800  AcquisitionTimeSynchronized        no
+  0018,1801  TimeSource                         no
+  0018,1802  TimeDistributionProtocol           no
+  0018,1803  NTPSourceAddress                   no
+  0018,2001  PageNumberVector                   no
+  0018,2002  FrameLabelVector                   no
+  0018,2003  FramePrimaryAngleVector            no
+  0018,2004  FrameSecondaryAngleVector          no
+  0018,2005  SliceLocationVector                no
+  0018,2006  DisplayWindowLabelVector           no
+  0018,2010  NominalScannedPixelSpacing         no
+  0018,2020  DigitizingDeviceTransportDirection no
+  0018,2030  RotationOfScannedFilm              no
+  0018,3100  IVUSAcquisition                    no
+  0018,3101  IVUSPullbackRate                   no
+  0018,3102  IVUSGatedRate                      no
+  0018,3103  IVUSPullbackStartFrameNumber       no
+  0018,3104  IVUSPullbackStopFrameNumber        no
+  0018,3105  LesionNumber                       no
+  0018,4000  AcquisitionComments                no
+  0018,5000  OutputPower                        no
+  0018,5010  TransducerData                     no
+  0018,5012  FocusDepth                         no
+  0018,5020  ProcessingFunction                 no
+  0018,5021  PostprocessingFunction             no
+  0018,5022  MechanicalIndex                    no
+  0018,5024  BoneThermalIndex                   no
+  0018,5026  CranialThermalIndex                no
+  0018,5027  SoftTissueThermalIndex             no
+  0018,5028  SoftTissueFocusThermalIndex        no
+  0018,5029  SoftTissueSurfaceThermalIndex      no
+  0018,5030  DynamicRange                       no
+  0018,5040  TotalGain                          no
+  0018,5050  DepthOfScanField                   no
+  0018,5100  PatientPosition                    no
+  0018,5101  ViewPosition                       no
+  0018,5104  ProjectionEponymousNameCodeSeq     no
+  0018,5210  ImageTransformationMatrix          no
+  0018,5212  ImageTranslationVector             no
+  0018,6000  Sensitivity                        no
+  0018,6011  SequenceOfUltrasoundRegions        no
+  0018,6012  RegionSpatialFormat                no
+  0018,6014  RegionDataType                     no
+  0018,6016  RegionFlags                        no
+  0018,6018  RegionLocationMinX0                no
+  0018,601A  RegionLocationMinY0                no
+  0018,601C  RegionLocationMaxX1                no
+  0018,601E  RegionLocationMaxY1                no
+  0018,6020  ReferencePixelX0                   no
+  0018,6022  ReferencePixelY0                   no
+  0018,6024  PhysicalUnitsXDirection            no
+  0018,6026  PhysicalUnitsYDirection            no
+  0018,6028  ReferencePixelPhysicalValueX       no
+  0018,602A  ReferencePixelPhysicalValueY       no
+  0018,602C  PhysicalDeltaX                     no
+  0018,602E  PhysicalDeltaY                     no
+  0018,6030  TransducerFrequency                no
+  0018,6031  TransducerType                     no
+  0018,6032  PulseRepetitionFrequency           no
+  0018,6034  DopplerCorrectionAngle             no
+  0018,6036  SteeringAngle                      no
+  0018,6038  DopplerSampleVolumeXPosRetired     no
+  0018,6039  DopplerSampleVolumeXPosition       no
+  0018,603A  DopplerSampleVolumeYPosRetired     no
+  0018,603B  DopplerSampleVolumeYPosition       no
+  0018,603C  TMLinePositionX0Retired            no
+  0018,603D  TMLinePositionX0                   no
+  0018,603E  TMLinePositionY0Retired            no
+  0018,603F  TMLinePositionY0                   no
+  0018,6040  TMLinePositionX1Retired            no
+  0018,6041  TMLinePositionX1                   no
+  0018,6042  TMLinePositionY1Retired            no
+  0018,6043  TMLinePositionY1                   no
+  0018,6044  PixelComponentOrganization         no
+  0018,6046  PixelComponentMask                 no
+  0018,6048  PixelComponentRangeStart           no
+  0018,604A  PixelComponentRangeStop            no
+  0018,604C  PixelComponentPhysicalUnits        no
+  0018,604E  PixelComponentDataType             no
+  0018,6050  NumberOfTableBreakPoints           no
+  0018,6052  TableOfXBreakPoints                no
+  0018,6054  TableOfYBreakPoints                no
+  0018,6056  NumberOfTableEntries               no
+  0018,6058  TableOfPixelValues                 no
+  0018,605A  TableOfParameterValues             no
+  0018,6060  RWaveTimeVector                    no
+  0018,7000  DetectorConditionsNominalFlag      no
+  0018,7001  DetectorTemperature                no
+  0018,7004  DetectorType                       no
+  0018,7005  DetectorConfiguration              no
+  0018,7006  DetectorDescription                no
+  0018,7008  DetectorMode                       no
+  0018,700A  DetectorID                         no
+  0018,700C  DateOfLastDetectorCalibration      no
+  0018,700E  TimeOfLastDetectorCalibration      no
+  0018,7010  DetectorExposuresSinceCalibration  no
+  0018,7011  DetectorExposuresSinceManufactured no
+  0018,7012  DetectorTimeSinceLastExposure      no
+  0018,7014  DetectorActiveTime                 no
+  0018,7016  DetectorActiveOffsetFromExposure   no
+  0018,701A  DetectorBinning                    no
+  0018,7020  DetectorElementPhysicalSize        no
+  0018,7022  DetectorElementSpacing             no
+  0018,7024  DetectorActiveShape                no
+  0018,7026  DetectorActiveDimensions           no
+  0018,7028  DetectorActiveOrigin               no
+  0018,702A  DetectorManufacturerName           no
+  0018,702B  DetectorManufacturersModelName     no
+  0018,7030  FieldOfViewOrigin                  no
+  0018,7032  FieldOfViewRotation                no
+  0018,7034  FieldOfViewHorizontalFlip          no
+  0018,7040  GridAbsorbingMaterial              no
+  0018,7041  GridSpacingMaterial                no
+  0018,7042  GridThickness                      no
+  0018,7044  GridPitch                          no
+  0018,7046  GridAspectRatio                    no
+  0018,7048  GridPeriod                         no
+  0018,704C  GridFocalDistance                  no
+  0018,7050  FilterMaterial                     no
+  0018,7052  FilterThicknessMinimum             no
+  0018,7054  FilterThicknessMaximum             no
+  0018,7060  ExposureControlMode                no
+  0018,7062  ExposureControlModeDescription     no
+  0018,7064  ExposureStatus                     no
+  0018,7065  PhototimerSetting                  no
+  0018,8150  ExposureTimeInMicroSec             no
+  0018,8151  XRayTubeCurrentInMicroAmps         no
+  0018,9004  ContentQualification               no
+  0018,9005  PulseSequenceName                  no
+  0018,9006  MRImagingModifierSequence          no
+  0018,9008  EchoPulseSequence                  no
+  0018,9009  InversionRecovery                  no
+  0018,9010  FlowCompensation                   no
+  0018,9011  MultipleSpinEcho                   no
+  0018,9012  MultiPlanarExcitation              no
+  0018,9014  PhaseContrast                      no
+  0018,9015  TimeOfFlightContrast               no
+  0018,9016  Spoiling                           no
+  0018,9017  SteadyStatePulseSequence           no
+  0018,9018  EchoPlanarPulseSequence            no
+  0018,9019  TagAngleFirstAxis                  no
+  0018,9020  MagnetizationTransfer              no
+  0018,9021  T2Preparation                      no
+  0018,9022  BloodSignalNulling                 no
+  0018,9024  SaturationRecovery                 no
+  0018,9025  SpectrallySelectedSuppression      no
+  0018,9026  SpectrallySelectedExcitation       no
+  0018,9027  SpatialPresaturation               no
+  0018,9028  Tagging                            no
+  0018,9029  OversamplingPhase                  no
+  0018,9030  TagSpacingFirstDimension           no
+  0018,9032  GeometryOfKSpaceTraversal          no
+  0018,9033  SegmentedKSpaceTraversal           no
+  0018,9034  RectilinearPhaseEncodeReordering   no
+  0018,9035  TagThickness                       no
+  0018,9036  PartialFourierDirection            no
+  0018,9037  CardiacSynchronizationTechnique    no
+  0018,9041  ReceiveCoilManufacturerName        no
+  0018,9042  MRReceiveCoilSequence              no
+  0018,9043  ReceiveCoilType                    no
+  0018,9044  QuadratureReceiveCoil              no
+  0018,9045  MultiCoilDefinitionSequence        no
+  0018,9046  MultiCoilConfiguration             no
+  0018,9047  MultiCoilElementName               no
+  0018,9048  MultiCoilElementUsed               no
+  0018,9049  MRTransmitCoilSequence             no
+  0018,9050  TransmitCoilManufacturerName       no
+  0018,9051  TransmitCoilType                   no
+  0018,9052  SpectralWidth                      no
+  0018,9053  ChemicalShiftReference             no
+  0018,9054  VolumeLocalizationTechnique        no
+  0018,9058  MRAcquisitionFrequencyEncodeSteps  no
+  0018,9059  Decoupling                         no
+  0018,9060  DecoupledNucleus                   no
+  0018,9061  DecouplingFrequency                no
+  0018,9062  DecouplingMethod                   no
+  0018,9063  DecouplingChemicalShiftReference   no
+  0018,9064  KSpaceFiltering                    no
+  0018,9065  TimeDomainFiltering                no
+  0018,9066  NumberOfZeroFills                  no
+  0018,9067  BaselineCorrection                 no
+  0018,9069  ParallelReductionFactorInPlane     no
+  0018,9070  CardiacRRIntervalSpecified         no
+  0018,9073  AcquisitionDuration                no
+  0018,9074  FrameAcquisitionDateTime           no
+  0018,9075  DiffusionDirectionality            no
+  0018,9076  DiffusionGradientDirectionSequence no
+  0018,9077  ParallelAcquisition                no
+  0018,9078  ParallelAcquisitionTechnique       no
+  0018,9079  InversionTimes                     no
+  0018,9080  MetaboliteMapDescription           no
+  0018,9081  PartialFourier                     no
+  0018,9082  EffectiveEchoTime                  no
+  0018,9083  MetaboliteMapCodeSequence          no
+  0018,9084  ChemicalShiftSequence              no
+  0018,9085  CardiacSignalSource                no
+  0018,9087  DiffusionBValue                    no
+  0018,9089  DiffusionGradientOrientation       no
+  0018,9090  VelocityEncodingDirection          no
+  0018,9091  VelocityEncodingMinimumValue       no
+  0018,9093  NumberOfKSpaceTrajectories         no
+  0018,9094  CoverageOfKSpace                   no
+  0018,9095  SpectroscopyAcquisitionPhaseRows   no
+  0018,9096  ParallelReductFactorInPlaneRetired no
+  0018,9098  TransmitterFrequency               no
+  0018,9100  ResonantNucleus                    no
+  0018,9101  FrequencyCorrection                no
+  0018,9103  MRSpectroscopyFOV-GeometrySequence no
+  0018,9104  SlabThickness                      no
+  0018,9105  SlabOrientation                    no
+  0018,9106  MidSlabPosition                    no
+  0018,9107  MRSpatialSaturationSequence        no
+  0018,9112  MRTimingAndRelatedParametersSeq    no
+  0018,9114  MREchoSequence                     no
+  0018,9115  MRModifierSequence                 no
+  0018,9117  MRDiffusionSequence                no
+  0018,9118  CardiacTriggerSequence             no
+  0018,9119  MRAveragesSequence                 no
+  0018,9125  MRFOV-GeometrySequence             no
+  0018,9126  VolumeLocalizationSequence         no
+  0018,9127  SpectroscopyAcquisitionDataColumns no
+  0018,9147  DiffusionAnisotropyType            no
+  0018,9151  FrameReferenceDateTime             no
+  0018,9152  MRMetaboliteMapSequence            no
+  0018,9155  ParallelReductionFactorOutOfPlane  no
+  0018,9159  SpectroscopyOutOfPlanePhaseSteps   no
+  0018,9166  BulkMotionStatus                   no
+  0018,9168  ParallelReductionFactSecondInPlane no
+  0018,9169  CardiacBeatRejectionTechnique      no
+  0018,9170  RespiratoryMotionCompTechnique     no
+  0018,9171  RespiratorySignalSource            no
+  0018,9172  BulkMotionCompensationTechnique    no
+  0018,9173  BulkMotionSignalSource             no
+  0018,9174  ApplicableSafetyStandardAgency     no
+  0018,9175  ApplicableSafetyStandardDescr      no
+  0018,9176  OperatingModeSequence              no
+  0018,9177  OperatingModeType                  no
+  0018,9178  OperatingMode                      no
+  0018,9179  SpecificAbsorptionRateDefinition   no
+  0018,9180  GradientOutputType                 no
+  0018,9181  SpecificAbsorptionRateValue        no
+  0018,9182  GradientOutput                     no
+  0018,9183  FlowCompensationDirection          no
+  0018,9184  TaggingDelay                       no
+  0018,9185  RespiratoryMotionCompTechDescr     no
+  0018,9186  RespiratorySignalSourceID          no
+  0018,9195  ChemicalShiftsMinIntegrateLimitHz  no
+  0018,9196  ChemicalShiftsMaxIntegrateLimitHz  no
+  0018,9197  MRVelocityEncodingSequence         no
+  0018,9198  FirstOrderPhaseCorrection          no
+  0018,9199  WaterReferencedPhaseCorrection     no
+  0018,9200  MRSpectroscopyAcquisitionType      no
+  0018,9214  RespiratoryCyclePosition           no
+  0018,9217  VelocityEncodingMaximumValue       no
+  0018,9218  TagSpacingSecondDimension          no
+  0018,9219  TagAngleSecondAxis                 no
+  0018,9220  FrameAcquisitionDuration           no
+  0018,9226  MRImageFrameTypeSequence           no
+  0018,9227  MRSpectroscopyFrameTypeSequence    no
+  0018,9231  MRAcqPhaseEncodingStepsInPlane     no
+  0018,9232  MRAcqPhaseEncodingStepsOutOfPlane  no
+  0018,9234  SpectroscopyAcqPhaseColumns        no
+  0018,9236  CardiacCyclePosition               no
+  0018,9239  SpecificAbsorptionRateSequence     no
+  0018,9240  RFEchoTrainLength                  no
+  0018,9241  GradientEchoTrainLength            no
+  0018,9295  ChemicalShiftsMinIntegrateLimitPPM no
+  0018,9296  ChemicalShiftsMaxIntegrateLimitPPM no
+  0018,9301  CTAcquisitionTypeSequence          no
+  0018,9302  AcquisitionType                    no
+  0018,9303  TubeAngle                          no
+  0018,9304  CTAcquisitionDetailsSequence       no
+  0018,9305  RevolutionTime                     no
+  0018,9306  SingleCollimationWidth             no
+  0018,9307  TotalCollimationWidth              no
+  0018,9308  CTTableDynamicsSequence            no
+  0018,9309  TableSpeed                         no
+  0018,9310  TableFeedPerRotation               no
+  0018,9311  SpiralPitchFactor                  no
+  0018,9312  CTGeometrySequence                 no
+  0018,9313  DataCollectionCenterPatient        no
+  0018,9314  CTReconstructionSequence           no
+  0018,9315  ReconstructionAlgorithm            no
+  0018,9316  ConvolutionKernelGroup             no
+  0018,9317  ReconstructionFieldOfView          no
+  0018,9318  ReconstructionTargetCenterPatient  no
+  0018,9319  ReconstructionAngle                no
+  0018,9320  ImageFilter                        no
+  0018,9321  CTExposureSequence                 no
+  0018,9322  ReconstructionPixelSpacing         no
+  0018,9323  ExposureModulationType             no
+  0018,9324  EstimatedDoseSaving                no
+  0018,9325  CTXRayDetailsSequence              no
+  0018,9326  CTPositionSequence                 no
+  0018,9327  TablePosition                      no
+  0018,9328  ExposureTimeInMilliSec             no
+  0018,9329  CTImageFrameTypeSequence           no
+  0018,9330  XRayTubeCurrentInMilliAmps         no
+  0018,9332  ExposureInMilliAmpSec              no
+  0018,9333  ConstantVolumeFlag                 no
+  0018,9334  FluoroscopyFlag                    no
+  0018,9335  SourceToDataCollectionCenterDist   no
+  0018,9337  ContrastBolusAgentNumber           no
+  0018,9338  ContrastBolusIngredientCodeSeq     no
+  0018,9340  ContrastAdministrationProfileSeq   no
+  0018,9341  ContrastBolusUsageSequence         no
+  0018,9342  ContrastBolusAgentAdministered     no
+  0018,9343  ContrastBolusAgentDetected         no
+  0018,9344  ContrastBolusAgentPhase            no
+  0018,9345  CTDIvol                            no
+  0018,9346  CTDIPhantomTypeCodeSequence        no
+  0018,9351  CalciumScoringMassFactorPatient    no
+  0018,9352  CalciumScoringMassFactorDevice     no
+  0018,9353  EnergyWeightingFactor              no
+  0018,9360  CTAdditionalXRaySourceSequence     no
+  0018,9401  ProjectionPixelCalibrationSequence no
+  0018,9402  DistanceSourceToIsocenter          no
+  0018,9403  DistanceObjectToTableTop           no
+  0018,9404  ObjectPixelSpacingInCenterOfBeam   no
+  0018,9405  PositionerPositionSequence         no
+  0018,9406  TablePositionSequence              no
+  0018,9407  CollimatorShapeSequence            no
+  0018,9412  XA-XRFFrameCharacteristicsSequence no
+  0018,9417  FrameAcquisitionSequence           no
+  0018,9420  XRayReceptorType                   no
+  0018,9423  AcquisitionProtocolName            no
+  0018,9424  AcquisitionProtocolDescription     no
+  0018,9425  ContrastBolusIngredientOpaque      no
+  0018,9426  DistanceReceptorPlaneToDetHousing  no
+  0018,9427  IntensifierActiveShape             no
+  0018,9428  IntensifierActiveDimensions        no
+  0018,9429  PhysicalDetectorSize               no
+  0018,9430  PositionOfIsocenterProjection      no
+  0018,9432  FieldOfViewSequence                no
+  0018,9433  FieldOfViewDescription             no
+  0018,9434  ExposureControlSensingRegionsSeq   no
+  0018,9435  ExposureControlSensingRegionShape  no
+  0018,9436  ExposureControlSensRegionLeftEdge  no
+  0018,9437  ExposureControlSensRegionRightEdge no
+  0018,9440  CenterOfCircExposControlSensRegion no
+  0018,9441  RadiusOfCircExposControlSensRegion no
+  0018,9447  ColumnAngulationPatient            no
+  0018,9449  BeamAngle                          no
+  0018,9451  FrameDetectorParametersSequence    no
+  0018,9452  CalculatedAnatomyThickness         no
+  0018,9455  CalibrationSequence                no
+  0018,9456  ObjectThicknessSequence            no
+  0018,9457  PlaneIdentification                no
+  0018,9461  FieldOfViewDimensionsInFloat       no
+  0018,9462  IsocenterReferenceSystemSequence   no
+  0018,9463  PositionerIsocenterPrimaryAngle    no
+  0018,9464  PositionerIsocenterSecondaryAngle  no
+  0018,9465  PositionerIsocenterDetRotAngle     no
+  0018,9466  TableXPositionToIsocenter          no
+  0018,9467  TableYPositionToIsocenter          no
+  0018,9468  TableZPositionToIsocenter          no
+  0018,9469  TableHorizontalRotationAngle       no
+  0018,9470  TableHeadTiltAngle                 no
+  0018,9471  TableCradleTiltAngle               no
+  0018,9472  FrameDisplayShutterSequence        no
+  0018,9473  AcquiredImageAreaDoseProduct       no
+  0018,9474  CArmPositionerTabletopRelationship no
+  0018,9476  XRayGeometrySequence               no
+  0018,9477  IrradiationEventIDSequence         no
+  0018,9504  XRay3DFrameTypeSequence            no
+  0018,9506  ContributingSourcesSequence        no
+  0018,9507  XRay3DAcquisitionSequence          no
+  0018,9508  PrimaryPositionerScanArc           no
+  0018,9509  SecondaryPositionerScanArc         no
+  0018,9510  PrimaryPositionerScanStartAngle    no
+  0018,9511  SecondaryPositionerScanStartAngle  no
+  0018,9514  PrimaryPositionerIncrement         no
+  0018,9515  SecondaryPositionerIncrement       no
+  0018,9516  StartAcquisitionDateTime           no
+  0018,9517  EndAcquisitionDateTime             no
+  0018,9524  ApplicationName                    no
+  0018,9525  ApplicationVersion                 no
+  0018,9526  ApplicationManufacturer            no
+  0018,9527  AlgorithmType                      no
+  0018,9528  AlgorithmDescription               no
+  0018,9530  XRay3DReconstructionSequence       no
+  0018,9531  ReconstructionDescription          no
+  0018,9538  PerProjectionAcquisitionSequence   no
+  0018,9601  DiffusionBMatrixSequence           no
+  0018,9602  DiffusionBValueXX                  no
+  0018,9603  DiffusionBValueXY                  no
+  0018,9604  DiffusionBValueXZ                  no
+  0018,9605  DiffusionBValueYY                  no
+  0018,9606  DiffusionBValueYZ                  no
+  0018,9607  DiffusionBValueZZ                  no
+  0018,9701  DecayCorrectionDateTime            no
+  0018,9715  StartDensityThreshold              no
+  0018,9722  TerminationTimeThreshold           no
+  0018,9725  DetectorGeometry                   no
+  0018,9727  AxialDetectorDimension             no
+  0018,9735  PETPositionSequence                no
+  0018,9739  NumberOfIterations                 no
+  0018,9740  NumberOfSubsets                    no
+  0018,9751  PETFrameTypeSequence               no
+  0018,9756  ReconstructionType                 no
+  0018,9758  DecayCorrected                     no
+  0018,9759  AttenuationCorrected               no
+  0018,9760  ScatterCorrected                   no
+  0018,9761  DeadTimeCorrected                  no
+  0018,9762  GantryMotionCorrected              no
+  0018,9763  PatientMotionCorrected             no
+  0018,9765  RandomsCorrected                   no
+  0018,9767  SensitivityCalibrated              no
+  0018,9801  DepthsOfFocus                      no
+  0018,9804  ExclusionStartDatetime             no
+  0018,9805  ExclusionDuration                  no
+  0018,9807  ImageDataTypeSequence              no
+  0018,9808  DataType                           no
+  0018,980B  AliasedDataType                    no
+  0018,A001  ContributingEquipmentSequence      no
+  0018,A002  ContributionDateTime               no
+  0018,A003  ContributionDescription            no
+  0019,1002  NumberOfCellsIInDetector           no
+  0019,1003  CellNumberAtTheta                  no
+  0019,1004  CellSpacing                        no
+  0019,100F  HorizFrameOfRef                    no
+  0019,1011  SeriesContrast                     no
+  0019,1012  LastPseq                           no
+  0019,1013  StartNumberForBaseline             no
+  0019,1014  EndNumberForBaseline               no
+  0019,1015  StartNumberForEnhancedScans        no
+  0019,1016  EndNumberForEnhancedScans          no
+  0019,1017  SeriesPlane                        no
+  0019,1018  FirstScanRas                       no
+  0019,1019  FirstScanLocation                  no
+  0019,101A  LastScanRas                        no
+  0019,101B  LastScanLoc                        no
+  0019,101E  DisplayFieldOfView                 no
+  0019,1023  TableSpeed                         no
+  0019,1024  MidScanTime                        no
+  0019,1025  MidScanFlag                        no
+  0019,1026  DegreesOfAzimuth                   no
+  0019,1027  GantryPeriod                       no
+  0019,102A  XRayOnPosition                     no
+  0019,102B  XRayOffPosition                    no
+  0019,102C  NumberOfTriggers                   no
+  0019,102E  AngleOfFirstView                   no
+  0019,102F  TriggerFrequency                   no
+  0019,1039  ScanFOVType                        no
+  0019,1040  StatReconFlag                      no
+  0019,1041  ComputeType                        no
+  0019,1042  SegmentNumber                      no
+  0019,1043  TotalSegmentsRequested             no
+  0019,1044  InterscanDelay                     no
+  0019,1047  ViewCompressionFactor              no
+  0019,104A  TotalNoOfRefChannels               no
+  0019,104B  DataSizeForScanData                no
+  0019,1052  ReconPostProcflag                  no
+  0019,1057  CTWaterNumber                      no
+  0019,1058  CTBoneNumber                       no
+  0019,105A  AcquisitionDuration                no
+  0019,105E  NumberOfChannels                   no
+  0019,105F  IncrementBetweenChannels           no
+  0019,1060  StartingView                       no
+  0019,1061  NumberOfViews                      no
+  0019,1062  IncrementBetweenViews              no
+  0019,106A  DependantOnNoViewsProcessed        no
+  0019,106B  FieldOfViewInDetectorCells         no
+  0019,1070  ValueOfBackProjectionButton        no
+  0019,1071  SetIfFatqEstimatesWereUsed         no
+  0019,1072  ZChanAvgOverViews                  no
+  0019,1073  AvgOfLeftRefChansOverViews         no
+  0019,1074  MaxLeftChanOverViews               no
+  0019,1075  AvgOfRightRefChansOverViews        no
+  0019,1076  MaxRightChanOverViews              no
+  0019,107D  SecondEcho                         no
+  0019,107E  NumberOfEchoes                     no
+  0019,107F  TableDelta                         no
+  0019,1081  Contiguous                         no
+  0019,1084  PeakSAR                            no
+  0019,1085  MonitorSAR                         no
+  0019,1087  CardiacRepetitionTime              no
+  0019,1088  ImagesPerCardiacCycle              no
+  0019,108A  ActualReceiveGainAnalog            no
+  0019,108B  ActualReceiveGainDigital           no
+  0019,108D  DelayAfterTrigger                  no
+  0019,108F  Swappf                             no
+  0019,1090  PauseInterval                      no
+  0019,1091  PulseTime                          no
+  0019,1092  SliceOffsetOnFreqAxis              no
+  0019,1093  CenterFrequency                    no
+  0019,1094  TransmitGain                       no
+  0019,1095  AnalogReceiverGain                 no
+  0019,1096  DigitalReceiverGain                no
+  0019,1097  BitmapDefiningCVs                  no
+  0019,1098  CenterFreqMethod                   no
+  0019,109B  PulseSeqMode                       no
+  0019,109C  PulseSeqName                       no
+  0019,109D  PulseSeqDate                       no
+  0019,109E  InternalPulseSeqName               no
+  0019,109F  TransmittingCoil                   no
+  0019,10A0  SurfaceCoilType                    no
+  0019,10A1  ExtremityCoilFlag                  no
+  0019,10A2  RawDataRunNumber                   no
+  0019,10A3  CalibratedFieldStrength            no
+  0019,10A4  SATFatWaterBone                    no
+  0019,10A5  ReceiveBandwidth                   no
+  0019,10A7  UserData01                         no
+  0019,10A8  UserData02                         no
+  0019,10A9  UserData03                         no
+  0019,10AA  UserData04                         no
+  0019,10AB  UserData05                         no
+  0019,10AC  UserData06                         no
+  0019,10AD  UserData07                         no
+  0019,10AE  UserData08                         no
+  0019,10AF  UserData09                         no
+  0019,10B0  UserData10                         no
+  0019,10B1  UserData11                         no
+  0019,10B2  UserData12                         no
+  0019,10B3  UserData13                         no
+  0019,10B4  UserData14                         no
+  0019,10B5  UserData15                         no
+  0019,10B6  UserData16                         no
+  0019,10B7  UserData17                         no
+  0019,10B8  UserData18                         no
+  0019,10B9  UserData19                         no
+  0019,10BA  UserData20                         no
+  0019,10BB  UserData21                         no
+  0019,10BC  UserData22                         no
+  0019,10BD  UserData23                         no
+  0019,10BE  ProjectionAngle                    no
+  0019,10C0  SaturationPlanes                   no
+  0019,10C1  SurfaceCoilIntensity               no
+  0019,10C2  SATLocationR                       no
+  0019,10C3  SATLocationL                       no
+  0019,10C4  SATLocationA                       no
+  0019,10C5  SATLocationP                       no
+  0019,10C6  SATLocationH                       no
+  0019,10C7  SATLocationF                       no
+  0019,10C8  SATThicknessR-L                    no
+  0019,10C9  SATThicknessA-P                    no
+  0019,10CA  SATThicknessH-F                    no
+  0019,10CB  PrescribedFlowAxis                 no
+  0019,10CC  VelocityEncoding                   no
+  0019,10CD  ThicknessDisclaimer                no
+  0019,10CE  PrescanType                        no
+  0019,10CF  PrescanStatus                      no
+  0019,10D0  RawDataType                        no
+  0019,10D2  ProjectionAlgorithm                no
+  0019,10D3  ProjectionAlgorithm                no
+  0019,10D5  FractionalEcho                     no
+  0019,10D6  PrepPulse                          no
+  0019,10D7  CardiacPhases                      no
+  0019,10D8  VariableEchoflag                   no
+  0019,10D9  ConcatenatedSAT                    no
+  0019,10DA  ReferenceChannelUsed               no
+  0019,10DB  BackProjectorCoefficient           no
+  0019,10DC  PrimarySpeedCorrectionUsed         no
+  0019,10DD  OverrangeCorrectionUsed            no
+  0019,10DE  DynamicZAlphaValue                 no
+  0019,10DF  UserData                           no
+  0019,10E0  UserData                           no
+  0019,10E2  VelocityEncodeScale                no
+  0019,10F2  FastPhases                         no
+  0019,10F9  TransmissionGain                   no
+  0020,0000  RelationshipGroupLength            no
+  0020,000D  StudyInstanceUID                   no
+  0020,000E  SeriesInstanceUID                  no
+  0020,0010  StudyID                            no
+  0020,0011  SeriesNumber                       no
+  0020,0012  AcquisitionNumber                  no
+  0020,0013  InstanceNumber                     no
+  0020,0014  IsotopeNumber                      no
+  0020,0015  PhaseNumber                        no
+  0020,0016  IntervalNumber                     no
+  0020,0017  TimeSlotNumber                     no
+  0020,0018  AngleNumber                        no
+  0020,0019  ItemNumber                         no
+  0020,0020  PatientOrientation                 no
+  0020,0022  OverlayNumber                      no
+  0020,0024  CurveNumber                        no
+  0020,0026  LookupTableNumber                  no
+  0020,0030  ImagePosition                      no
+  0020,0032  ImagePositionPatient               no
+  0020,0035  ImageOrientation                   no
+  0020,0037  ImageOrientationPatient            no
+  0020,0050  Location                           no
+  0020,0052  FrameOfReferenceUID                no
+  0020,0060  Laterality                         no
+  0020,0062  ImageLaterality                    no
+  0020,0070  ImageGeometryType                  no
+  0020,0080  MaskingImage                       no
+  0020,0100  TemporalPositionIdentifier         no
+  0020,0105  NumberOfTemporalPositions          no
+  0020,0110  TemporalResolution                 no
+  0020,0200  SynchronizationFrameOfReferenceUID no
+  0020,1000  SeriesInStudy                      no
+  0020,1001  AcquisitionsInSeries               no
+  0020,1002  ImagesInAcquisition                no
+  0020,1003  ImagesInSeries                     no
+  0020,1004  AcquisitionsInStudy                no
+  0020,1005  ImagesInStudy                      no
+  0020,1020  Reference                          no
+  0020,1040  PositionReferenceIndicator         no
+  0020,1041  SliceLocation                      no
+  0020,1070  OtherStudyNumbers                  no
+  0020,1200  NumberOfPatientRelatedStudies      no
+  0020,1202  NumberOfPatientRelatedSeries       no
+  0020,1204  NumberOfPatientRelatedInstances    no
+  0020,1206  NumberOfStudyRelatedSeries         no
+  0020,1208  NumberOfStudyRelatedInstances      no
+  0020,1209  NumberOfSeriesRelatedInstances     no
+  0020,31xx  SourceImageIDs                     no
+  0020,3401  ModifyingDeviceID                  no
+  0020,3402  ModifiedImageID                    no
+  0020,3403  ModifiedImageDate                  no
+  0020,3404  ModifyingDeviceManufacturer        no
+  0020,3405  ModifiedImageTime                  no
+  0020,3406  ModifiedImageDescription           no
+  0020,4000  ImageComments                      no
+  0020,5000  OriginalImageIdentification        no
+  0020,5002  OriginalImageIdentNomenclature     no
+  0020,9056  StackID                            no
+  0020,9057  InStackPositionNumber              no
+  0020,9071  FrameAnatomySequence               no
+  0020,9072  FrameLaterality                    no
+  0020,9111  FrameContentSequence               no
+  0020,9113  PlanePositionSequence              no
+  0020,9116  PlaneOrientationSequence           no
+  0020,9128  TemporalPositionIndex              no
+  0020,9153  TriggerDelayTime                   no
+  0020,9156  FrameAcquisitionNumber             no
+  0020,9157  DimensionIndexValues               no
+  0020,9158  FrameComments                      no
+  0020,9161  ConcatenationUID                   no
+  0020,9162  InConcatenationNumber              no
+  0020,9163  InConcatenationTotalNumber         no
+  0020,9164  DimensionOrganizationUID           no
+  0020,9165  DimensionIndexPointer              no
+  0020,9167  FunctionalGroupPointer             no
+  0020,9213  DimensionIndexPrivateCreator       no
+  0020,9221  DimensionOrganizationSequence      no
+  0020,9222  DimensionIndexSequence             no
+  0020,9228  ConcatenationFrameOffsetNumber     no
+  0020,9238  FunctionalGroupPrivateCreator      no
+  0020,9241  NominalPercentageOfCardiacPhase    no
+  0020,9245  NominalPercentOfRespiratoryPhase   no
+  0020,9246  StartingRespiratoryAmplitude       no
+  0020,9247  StartingRespiratoryPhase           no
+  0020,9248  EndingRespiratoryAmplitude         no
+  0020,9249  EndingRespiratoryPhase             no
+  0020,9250  RespiratoryTriggerType             no
+  0020,9251  RRIntervalTimeNominal              no
+  0020,9252  ActualCardiacTriggerDelayTime      no
+  0020,9253  RespiratorySynchronizationSequence no
+  0020,9254  RespiratoryIntervalTime            no
+  0020,9255  NominalRespiratoryTriggerDelayTime no
+  0020,9256  RespiratoryTriggerDelayThreshold   no
+  0020,9257  ActualRespiratoryTriggerDelayTime  no
+  0020,9301  ImagePositionVolume                no
+  0020,9302  ImageOrientationVolume             no
+  0020,9308  ApexPosition                       no
+  0020,9421  DimensionDescriptionLabel          no
+  0020,9450  PatientOrientationInFrameSequence  no
+  0020,9453  FrameLabel                         no
+  0020,9518  AcquisitionIndex                   no
+  0020,9529  ContributingSOPInstancesRefSeq     no
+  0020,9536  ReconstructionIndex                no
+  0021,1003  SeriesFromWhichPrescribed          no
+  0021,1005  GenesisVersionNow                  no
+  0021,1007  SeriesRecordChecksum               no
+  0021,1018  GenesisVersionNow                  no
+  0021,1019  AcqreconRecordChecksum             no
+  0021,1020  TableStartLocation                 no
+  0021,1035  SeriesFromWhichPrescribed          no
+  0021,1036  ImageFromWhichPrescribed           no
+  0021,1037  ScreenFormat                       no
+  0021,104A  AnatomicalReferenceForScout        no
+  0021,104F  LocationsInAcquisition             no
+  0021,1050  GraphicallyPrescribed              no
+  0021,1051  RotationFromSourceXRot             no
+  0021,1052  RotationFromSourceYRot             no
+  0021,1053  RotationFromSourceZRot             no
+  0021,1054  ImagePosition                      no
+  0021,1055  ImageOrientation                   no
+  0021,1056  IntegerSlop                        no
+  0021,1057  IntegerSlop                        no
+  0021,1058  IntegerSlop                        no
+  0021,1059  IntegerSlop                        no
+  0021,105A  IntegerSlop                        no
+  0021,105B  FloatSlop                          no
+  0021,105C  FloatSlop                          no
+  0021,105D  FloatSlop                          no
+  0021,105E  FloatSlop                          no
+  0021,105F  FloatSlop                          no
+  0021,1081  AutoWindowLevelAlpha               no
+  0021,1082  AutoWindowLevelBeta                no
+  0021,1083  AutoWindowLevelWindow              no
+  0021,1084  ToWindowLevelLevel                 no
+  0021,1090  TubeFocalSpotPosition              no
+  0021,1091  BiopsyPosition                     no
+  0021,1092  BiopsyTLocation                    no
+  0021,1093  BiopsyRefLocation                  no
+  0022,0001  LightPathFilterPassThroughWavelen  no
+  0022,0002  LightPathFilterPassBand            no
+  0022,0003  ImagePathFilterPassThroughWavelen  no
+  0022,0004  ImagePathFilterPassBand            no
+  0022,0005  PatientEyeMovementCommanded        no
+  0022,0006  PatientEyeMovementCommandCodeSeq   no
+  0022,0007  SphericalLensPower                 no
+  0022,0008  CylinderLensPower                  no
+  0022,0009  CylinderAxis                       no
+  0022,000A  EmmetropicMagnification            no
+  0022,000B  IntraOcularPressure                no
+  0022,000C  HorizontalFieldOfView              no
+  0022,000D  PupilDilated                       no
+  0022,000E  DegreeOfDilation                   no
+  0022,0010  StereoBaselineAngle                no
+  0022,0011  StereoBaselineDisplacement         no
+  0022,0012  StereoHorizontalPixelOffset        no
+  0022,0013  StereoVerticalPixelOffset          no
+  0022,0014  StereoRotation                     no
+  0022,0015  AcquisitionDeviceTypeCodeSequence  no
+  0022,0016  IlluminationTypeCodeSequence       no
+  0022,0017  LightPathFilterTypeStackCodeSeq    no
+  0022,0018  ImagePathFilterTypeStackCodeSeq    no
+  0022,0019  LensesCodeSequence                 no
+  0022,001A  ChannelDescriptionCodeSequence     no
+  0022,001B  RefractiveStateSequence            no
+  0022,001C  MydriaticAgentCodeSequence         no
+  0022,001D  RelativeImagePositionCodeSequence  no
+  0022,0020  StereoPairsSequence                no
+  0022,0021  LeftImageSequence                  no
+  0022,0022  RightImageSequence                 no
+  0022,0030  AxialLengthOfTheEye                no
+  0022,0031  OphthalmicFrameLocationSequence    no
+  0022,0032  ReferenceCoordinates               no
+  0022,0035  DepthSpatialResolution             no
+  0022,0036  MaximumDepthDistortion             no
+  0022,0037  AlongScanSpatialResolution         no
+  0022,0038  MaximumAlongScanDistortion         no
+  0022,0039  OphthalmicImageOrientation         no
+  0022,0041  DepthOfTransverseImage             no
+  0022,0042  MydriaticAgentConcUnitsSeq         no
+  0022,0048  AcrossScanSpatialResolution        no
+  0022,0049  MaximumAcrossScanDistortion        no
+  0022,004E  MydriaticAgentConcentration        no
+  0022,0055  IlluminationWaveLength             no
+  0022,0056  IlluminationPower                  no
+  0022,0057  IlluminationBandwidth              no
+  0022,0058  MydriaticAgentSequence             no
+  0023,1001  NumberOfSeriesInStudy              no
+  0023,1002  NumberOfUnarchivedSeries           no
+  0023,1010  ReferenceImageField                no
+  0023,1050  SummaryImage                       no
+  0023,1070  StartTimeSecsInFirstAxial          no
+  0023,1074  NoofUpdatesToHeader                no
+  0023,107D  IndicatesIfTheStudyHasCompleteInfo no
+  0025,1006  LastPulseSequenceUsed              no
+  0025,1007  ImagesInSeries                     no
+  0025,1010  LandmarkCounter                    no
+  0025,1011  NumberOfAcquisitions               no
+  0025,1014  IndicatesNoofUpdatesToHeader       no
+  0025,1017  SeriesCompleteFlag                 no
+  0025,1018  NumberOfImagesArchived             no
+  0025,1019  LastImageNumberUsed                no
+  0025,101A  PrimaryReceiverSuiteAndHost        no
+  0027,1006  ImageArchiveFlag                   no
+  0027,1010  ScoutType                          no
+  0027,101C  VmaMamp                            no
+  0027,101D  VmaPhase                           no
+  0027,101E  VmaMod                             no
+  0027,101F  VmaClip                            no
+  0027,1020  SmartScanOnOffFlag                 no
+  0027,1030  ForeignImageRevision               no
+  0027,1031  ImagingMode                        no
+  0027,1032  PulseSequence                      no
+  0027,1033  ImagingOptions                     no
+  0027,1035  PlaneType                          no
+  0027,1036  ObliquePlane                       no
+  0027,1040  RASLetterOfImageLocation           no
+  0027,1041  ImageLocation                      no
+  0027,1042  CenterRCoordOfPlaneImage           no
+  0027,1043  CenterACoordOfPlaneImage           no
+  0027,1044  CenterSCoordOfPlaneImage           no
+  0027,1045  NormalRCoord                       no
+  0027,1046  NormalACoord                       no
+  0027,1047  NormalSCoord                       no
+  0027,1048  RCoordOfTopRightCorner             no
+  0027,1049  ACoordOfTopRightCorner             no
+  0027,104A  SCoordOfTopRightCorner             no
+  0027,104B  RCoordOfBottomRightCorner          no
+  0027,104C  ACoordOfBottomRightCorner          no
+  0027,104D  SCoordOfBottomRightCorner          no
+  0027,1050  TableStartLocation                 no
+  0027,1051  TableEndLocation                   no
+  0027,1052  RASLetterForSideOfImage            no
+  0027,1053  RASLetterForAnteriorPosterior      no
+  0027,1054  RASLetterForScoutStartLoc          no
+  0027,1055  RASLetterForScoutEndLoc            no
+  0027,1060  ImageDimensionX                    no
+  0027,1061  ImageDimensionY                    no
+  0027,1062  NumberOfExcitations                no
+  0028,0000  ImagePresentationGroupLength       no
+  0028,0002  SamplesPerPixel                    no
+  0028,0003  SamplesPerPixelUsed                no
+  0028,0004  PhotometricInterpretation          no
+  0028,0005  ImageDimensions                    no
+  0028,0006  PlanarConfiguration                no
+  0028,0008  NumberOfFrames                     no
+  0028,0009  FrameIncrementPointer              no
+  0028,000A  FrameDimensionPointer              no
+  0028,0010  Rows                               no
+  0028,0011  Columns                            no
+  0028,0012  Planes                             no
+  0028,0014  UltrasoundColorDataPresent         no
+  0028,0030  PixelSpacing                       no
+  0028,0031  ZoomFactor                         no
+  0028,0032  ZoomCenter                         no
+  0028,0034  PixelAspectRatio                   no
+  0028,0040  ImageFormat                        no
+  0028,0050  ManipulatedImage                   no
+  0028,0051  CorrectedImage                     no
+  0028,005F  CompressionRecognitionCode         no
+  0028,0060  CompressionCode                    no
+  0028,0061  CompressionOriginator              no
+  0028,0062  CompressionLabel                   no
+  0028,0063  CompressionDescription             no
+  0028,0065  CompressionSequence                no
+  0028,0066  CompressionStepPointers            no
+  0028,0068  RepeatInterval                     no
+  0028,0069  BitsGrouped                        no
+  0028,0070  PerimeterTable                     no
+  0028,0071  PerimeterValue                     no
+  0028,0080  PredictorRows                      no
+  0028,0081  PredictorColumns                   no
+  0028,0082  PredictorConstants                 no
+  0028,0090  BlockedPixels                      no
+  0028,0091  BlockRows                          no
+  0028,0092  BlockColumns                       no
+  0028,0093  RowOverlap                         no
+  0028,0094  ColumnOverlap                      no
+  0028,0100  BitsAllocated                      no
+  0028,0101  BitsStored                         no
+  0028,0102  HighBit                            no
+  0028,0103  PixelRepresentation                no
+  0028,0104  SmallestValidPixelValue            no
+  0028,0105  LargestValidPixelValue             no
+  0028,0106  SmallestImagePixelValue            no
+  0028,0107  LargestImagePixelValue             no
+  0028,0108  SmallestPixelValueInSeries         no
+  0028,0109  LargestPixelValueInSeries          no
+  0028,0110  SmallestImagePixelValueInPlane     no
+  0028,0111  LargestImagePixelValueInPlane      no
+  0028,0120  PixelPaddingValue                  no
+  0028,0121  PixelPaddingRangeLimit             no
+  0028,0200  ImageLocation                      no
+  0028,0300  QualityControlImage                no
+  0028,0301  BurnedInAnnotation                 no
+  0028,0400  TransformLabel                     no
+  0028,0401  TransformVersionNumber             no
+  0028,0402  NumberOfTransformSteps             no
+  0028,0403  SequenceOfCompressedData           no
+  0028,0404  DetailsOfCoefficients              no
+  0028,04x2  CoefficientCoding                  no
+  0028,04x3  CoefficientCodingPointers          no
+  0028,0700  DCTLabel                           no
+  0028,0701  DataBlockDescription               no
+  0028,0702  DataBlock                          no
+  0028,0710  NormalizationFactorFormat          no
+  0028,0720  ZonalMapNumberFormat               no
+  0028,0721  ZonalMapLocation                   no
+  0028,0722  ZonalMapFormat                     no
+  0028,0730  AdaptiveMapFormat                  no
+  0028,0740  CodeNumberFormat                   no
+  0028,08x0  CodeLabel                          no
+  0028,08x2  NumberOfTables                     no
+  0028,08x3  CodeTableLocation                  no
+  0028,08x4  BitsForCodeWord                    no
+  0028,08x8  ImageDataLocation                  no
+  0028,0A02  PixelSpacingCalibrationType        no
+  0028,0A04  PixelSpacingCalibrationDescription no
+  0028,1040  PixelIntensityRelationship         no
+  0028,1041  PixelIntensityRelationshipSign     no
+  0028,1050  WindowCenter                       no
+  0028,1051  WindowWidth                        no
+  0028,1052  RescaleIntercept                   no
+  0028,1053  RescaleSlope                       no
+  0028,1054  RescaleType                        no
+  0028,1055  WindowCenterAndWidthExplanation    no
+  0028,1056  VOI_LUTFunction                    no
+  0028,1080  GrayScale                          no
+  0028,1090  RecommendedViewingMode             no
+  0028,1100  GrayLookupTableDescriptor          no
+  0028,1101  RedPaletteColorTableDescriptor     no
+  0028,1102  GreenPaletteColorTableDescriptor   no
+  0028,1103  BluePaletteColorTableDescriptor    no
+  0028,1111  LargeRedPaletteColorTableDescr     no
+  0028,1112  LargeGreenPaletteColorTableDescr   no
+  0028,1113  LargeBluePaletteColorTableDescr    no
+  0028,1199  PaletteColorTableUID               no
+  0028,1200  GrayLookupTableData                no
+  0028,1201  RedPaletteColorTableData           no
+  0028,1202  GreenPaletteColorTableData         no
+  0028,1203  BluePaletteColorTableData          no
+  0028,1211  LargeRedPaletteColorTableData      no
+  0028,1212  LargeGreenPaletteColorTableData    no
+  0028,1213  LargeBluePaletteColorTableData     no
+  0028,1214  LargePaletteColorLookupTableUID    no
+  0028,1221  SegmentedRedColorTableData         no
+  0028,1222  SegmentedGreenColorTableData       no
+  0028,1223  SegmentedBlueColorTableData        no
+  0028,1300  BreastImplantPresent               no
+  0028,1350  PartialView                        no
+  0028,1351  PartialViewDescription             no
+  0028,1352  PartialViewCodeSequence            no
+  0028,135A  SpatialLocationsPreserved          no
+  0028,1402  DataPathAssignment                 no
+  0028,1404  BlendingLUT1Sequence               no
+  0028,1406  BlendingWeightConstant             no
+  0028,1408  BlendingLookupTableData            no
+  0028,140C  BlendingLUT2Sequence               no
+  0028,140E  DataPathID                         no
+  0028,140F  RGBLUTTransferFunction             no
+  0028,1410  AlphaLUTTransferFunction           no
+  0028,2000  ICCProfile                         no
+  0028,2110  LossyImageCompression              no
+  0028,2112  LossyImageCompressionRatio         no
+  0028,2114  LossyImageCompressionMethod        no
+  0028,3000  ModalityLUTSequence                no
+  0028,3002  LUTDescriptor                      no
+  0028,3003  LUTExplanation                     no
+  0028,3004  ModalityLUTType                    no
+  0028,3006  LUTData                            no
+  0028,3010  VOILUTSequence                     no
+  0028,3110  SoftcopyVOILUTSequence             no
+  0028,4000  ImagePresentationComments          no
+  0028,5000  BiPlaneAcquisitionSequence         no
+  0028,6010  RepresentativeFrameNumber          no
+  0028,6020  FrameNumbersOfInterest             no
+  0028,6022  FrameOfInterestDescription         no
+  0028,6023  FrameOfInterestType                no
+  0028,6030  MaskPointers                       no
+  0028,6040  RWavePointer                       no
+  0028,6100  MaskSubtractionSequence            no
+  0028,6101  MaskOperation                      no
+  0028,6102  ApplicableFrameRange               no
+  0028,6110  MaskFrameNumbers                   no
+  0028,6112  ContrastFrameAveraging             no
+  0028,6114  MaskSubPixelShift                  no
+  0028,6120  TIDOffset                          no
+  0028,6190  MaskOperationExplanation           no
+  0028,7FE0  PixelDataProviderURL               no
+  0028,9001  DataPointRows                      no
+  0028,9002  DataPointColumns                   no
+  0028,9003  SignalDomainColumns                no
+  0028,9099  LargestMonochromePixelValue        no
+  0028,9108  DataRepresentation                 no
+  0028,9110  PixelMeasuresSequence              no
+  0028,9132  FrameVOILUTSequence                no
+  0028,9145  PixelValueTransformationSequence   no
+  0028,9235  SignalDomainRows                   no
+  0028,9411  DisplayFilterPercentage            no
+  0028,9415  FramePixelShiftSequence            no
+  0028,9416  SubtractionItemID                  no
+  0028,9422  PixelIntensityRelationshipLUTSeq   no
+  0028,9443  FramePixelDataPropertiesSequence   no
+  0028,9444  GeometricalProperties              no
+  0028,9445  GeometricMaximumDistortion         no
+  0028,9446  ImageProcessingApplied             no
+  0028,9454  MaskSelectionMode                  no
+  0028,9474  LUTFunction                        no
+  0028,9478  MaskVisibilityPercentage           no
+  0028,9501  PixelShiftSequence                 no
+  0028,9502  RegionPixelShiftSequence           no
+  0028,9503  VerticesOfTheRegion                no
+  0028,9506  PixelShiftFrameRange               no
+  0028,9507  LUTFrameRange                      no
+  0028,9520  ImageToEquipmentMappingMatrix      no
+  0028,9537  EquipmentCoordinateSystemID        no
+  0029,1004  LowerRangeOfPixels1a               no
+  0029,1005  LowerRangeOfPixels1b               no
+  0029,1006  LowerRangeOfPixels1c               no
+  0029,1007  LowerRangeOfPixels1d               no
+  0029,1008  LowerRangeOfPixels1e               no
+  0029,1009  LowerRangeOfPixels1f               no
+  0029,100A  LowerRangeOfPixels1g               no
+  0029,1015  LowerRangeOfPixels1h               no
+  0029,1016  LowerRangeOfPixels1i               no
+  0029,1017  LowerRangeOfPixels2                no
+  0029,1018  UpperRangeOfPixels2                no
+  0029,101A  LenOfTotHdrInBytes                 no
+  0029,1026  VersionOfTheHdrStruct              no
+  0029,1034  AdvantageCompOverflow              no
+  0029,1035  AdvantageCompUnderflow             no
+  0032,0000  StudyGroupLength                   no
+  0032,000A  StudyStatusID                      no
+  0032,000C  StudyPriorityID                    no
+  0032,0012  StudyIDIssuer                      no
+  0032,0032  StudyVerifiedDate                  no
+  0032,0033  StudyVerifiedTime                  no
+  0032,0034  StudyReadDate                      no
+  0032,0035  StudyReadTime                      no
+  0032,1000  ScheduledStudyStartDate            no
+  0032,1001  ScheduledStudyStartTime            no
+  0032,1010  ScheduledStudyStopDate             no
+  0032,1011  ScheduledStudyStopTime             no
+  0032,1020  ScheduledStudyLocation             no
+  0032,1021  ScheduledStudyLocationAETitle      no
+  0032,1030  ReasonForStudy                     no
+  0032,1031  RequestingPhysicianIDSequence      no
+  0032,1032  RequestingPhysician                no
+  0032,1033  RequestingService                  no
+  0032,1040  StudyArrivalDate                   no
+  0032,1041  StudyArrivalTime                   no
+  0032,1050  StudyCompletionDate                no
+  0032,1051  StudyCompletionTime                no
+  0032,1055  StudyComponentStatusID             no
+  0032,1060  RequestedProcedureDescription      no
+  0032,1064  RequestedProcedureCodeSequence     no
+  0032,1070  RequestedContrastAgent             no
+  0032,4000  StudyComments                      no
+  0038,0004  ReferencedPatientAliasSequence     no
+  0038,0008  VisitStatusID                      no
+  0038,0010  AdmissionID                        no
+  0038,0011  IssuerOfAdmissionID                no
+  0038,0016  RouteOfAdmissions                  no
+  0038,001A  ScheduledAdmissionDate             no
+  0038,001B  ScheduledAdmissionTime             no
+  0038,001C  ScheduledDischargeDate             no
+  0038,001D  ScheduledDischargeTime             no
+  0038,001E  ScheduledPatientInstitResidence    no
+  0038,0020  AdmittingDate                      no
+  0038,0021  AdmittingTime                      no
+  0038,0030  DischargeDate                      no
+  0038,0032  DischargeTime                      no
+  0038,0040  DischargeDiagnosisDescription      no
+  0038,0044  DischargeDiagnosisCodeSequence     no
+  0038,0050  SpecialNeeds                       no
+  0038,0060  ServiceEpisodeID                   no
+  0038,0061  IssuerOfServiceEpisodeID           no
+  0038,0062  ServiceEpisodeDescription          no
+  0038,0100  PertinentDocumentsSequence         no
+  0038,0300  CurrentPatientLocation             no
+  0038,0400  PatientInstitutionResidence        no
+  0038,0500  PatientState                       no
+  0038,0502  PatientClinicalTrialParticipSeq    no
+  0038,4000  VisitComments                      no
+  003A,0004  WaveformOriginality                no
+  003A,0005  NumberOfWaveformChannels           no
+  003A,0010  NumberOfWaveformSamples            no
+  003A,001A  SamplingFrequency                  no
+  003A,0020  MultiplexGroupLabel                no
+  003A,0200  ChannelDefinitionSequence          no
+  003A,0202  WaveformChannelNumber              no
+  003A,0203  ChannelLabel                       no
+  003A,0205  ChannelStatus                      no
+  003A,0208  ChannelSourceSequence              no
+  003A,0209  ChannelSourceModifiersSequence     no
+  003A,020A  SourceWaveformSequence             no
+  003A,020C  ChannelDerivationDescription       no
+  003A,0210  ChannelSensitivity                 no
+  003A,0211  ChannelSensitivityUnitsSequence    no
+  003A,0212  ChannelSensitivityCorrectionFactor no
+  003A,0213  ChannelBaseline                    no
+  003A,0214  ChannelTimeSkew                    no
+  003A,0215  ChannelSampleSkew                  no
+  003A,0218  ChannelOffset                      no
+  003A,021A  WaveformBitsStored                 no
+  003A,0220  FilterLowFrequency                 no
+  003A,0221  FilterHighFrequency                no
+  003A,0222  NotchFilterFrequency               no
+  003A,0223  NotchFilterBandwidth               no
+  003A,0230  WaveformDataDisplayScale           no
+  003A,0231  WaveformDisplayBkgCIELabValue      no
+  003A,0240  WaveformPresentationGroupSequence  no
+  003A,0241  PresentationGroupNumber            no
+  003A,0242  ChannelDisplaySequence             no
+  003A,0244  ChannelRecommendDisplayCIELabValue no
+  003A,0245  ChannelPosition                    no
+  003A,0246  DisplayShadingFlag                 no
+  003A,0247  FractionalChannelDisplayScale      no
+  003A,0248  AbsoluteChannelDisplayScale        no
+  003A,0300  MultiplexAudioChannelsDescrCodeSeq no
+  003A,0301  ChannelIdentificationCode          no
+  003A,0302  ChannelMode                        no
+  0040,0001  ScheduledStationAETitle            no
+  0040,0002  ScheduledProcedureStepStartDate    no
+  0040,0003  ScheduledProcedureStepStartTime    no
+  0040,0004  ScheduledProcedureStepEndDate      no
+  0040,0005  ScheduledProcedureStepEndTime      no
+  0040,0006  ScheduledPerformingPhysiciansName  no
+  0040,0007  ScheduledProcedureStepDescription  no
+  0040,0008  ScheduledProtocolCodeSequence      no
+  0040,0009  ScheduledProcedureStepID           no
+  0040,000A  StageCodeSequence                  no
+  0040,000B  ScheduledPerformingPhysicianIDSeq  no
+  0040,0010  ScheduledStationName               no
+  0040,0011  ScheduledProcedureStepLocation     no
+  0040,0012  PreMedication                      no
+  0040,0020  ScheduledProcedureStepStatus       no
+  0040,0031  LocalNamespaceEntityID             no
+  0040,0032  UniversalEntityID                  no
+  0040,0033  UniversalEntityIDType              no
+  0040,0035  IdentifierTypeCode                 no
+  0040,0036  AssigningFacilitySequence          no
+  0040,0100  ScheduledProcedureStepSequence     no
+  0040,0220  ReferencedNonImageCompositeSOPSeq  no
+  0040,0241  PerformedStationAETitle            no
+  0040,0242  PerformedStationName               no
+  0040,0243  PerformedLocation                  no
+  0040,0244  PerformedProcedureStepStartDate    no
+  0040,0245  PerformedProcedureStepStartTime    no
+  0040,0250  PerformedProcedureStepEndDate      no
+  0040,0251  PerformedProcedureStepEndTime      no
+  0040,0252  PerformedProcedureStepStatus       no
+  0040,0253  PerformedProcedureStepID           no
+  0040,0254  PerformedProcedureStepDescription  no
+  0040,0255  PerformedProcedureTypeDescription  no
+  0040,0260  PerformedProtocolCodeSequence      no
+  0040,0261  PerformedProtocolType              no
+  0040,0270  ScheduledStepAttributesSequence    no
+  0040,0275  RequestAttributesSequence          no
+  0040,0280  CommentsOnPerformedProcedureStep   no
+  0040,0281  ProcStepDiscontinueReasonCodeSeq   no
+  0040,0293  QuantitySequence                   no
+  0040,0294  Quantity                           no
+  0040,0295  MeasuringUnitsSequence             no
+  0040,0296  BillingItemSequence                no
+  0040,0300  TotalTimeOfFluoroscopy             no
+  0040,0301  TotalNumberOfExposures             no
+  0040,0302  EntranceDose                       no
+  0040,0303  ExposedArea                        no
+  0040,0306  DistanceSourceToEntrance           no
+  0040,0307  DistanceSourceToSupport            no
+  0040,030E  ExposureDoseSequence               no
+  0040,0310  CommentsOnRadiationDose            no
+  0040,0312  XRayOutput                         no
+  0040,0314  HalfValueLayer                     no
+  0040,0316  OrganDose                          no
+  0040,0318  OrganExposed                       no
+  0040,0320  BillingProcedureStepSequence       no
+  0040,0321  FilmConsumptionSequence            no
+  0040,0324  BillingSuppliesAndDevicesSequence  no
+  0040,0330  ReferencedProcedureStepSequence    no
+  0040,0340  PerformedSeriesSequence            no
+  0040,0400  CommentsOnScheduledProcedureStep   no
+  0040,0440  ProtocolContextSequence            no
+  0040,0441  ContentItemModifierSequence        no
+  0040,050A  SpecimenAccessionNumber            no
+  0040,0512  ContainerIdentifier                no
+  0040,051A  ContainerDescription               no
+  0040,0550  SpecimenSequence                   no
+  0040,0551  SpecimenIdentifier                 no
+  0040,0552  SpecimenDescriptionSequenceTrial   no
+  0040,0553  SpecimenDescriptionTrial           no
+  0040,0554  SpecimenUID                        no
+  0040,0555  AcquisitionContextSequence         no
+  0040,0556  AcquisitionContextDescription      no
+  0040,059A  SpecimenTypeCodeSequence           no
+  0040,0600  SpecimenShortDescription           no
+  0040,06FA  SlideIdentifier                    no
+  0040,071A  ImageCenterPointCoordinatesSeq     no
+  0040,072A  XOffsetInSlideCoordinateSystem     no
+  0040,073A  YOffsetInSlideCoordinateSystem     no
+  0040,074A  ZOffsetInSlideCoordinateSystem     no
+  0040,08D8  PixelSpacingSequence               no
+  0040,08DA  CoordinateSystemAxisCodeSequence   no
+  0040,08EA  MeasurementUnitsCodeSequence       no
+  0040,09F8  VitalStainCodeSequenceTrial        no
+  0040,1001  RequestedProcedureID               no
+  0040,1002  ReasonForRequestedProcedure        no
+  0040,1003  RequestedProcedurePriority         no
+  0040,1004  PatientTransportArrangements       no
+  0040,1005  RequestedProcedureLocation         no
+  0040,1006  PlacerOrderNumber-Procedure        no
+  0040,1007  FillerOrderNumber-Procedure        no
+  0040,1008  ConfidentialityCode                no
+  0040,1009  ReportingPriority                  no
+  0040,100A  ReasonForRequestedProcedureCodeSeq no
+  0040,1010  NamesOfIntendedRecipientsOfResults no
+  0040,1011  IntendedRecipientsOfResultsIDSeq   no
+  0040,1101  PersonIdentificationCodeSequence   no
+  0040,1102  PersonAddress                      no
+  0040,1103  PersonTelephoneNumbers             no
+  0040,1400  RequestedProcedureComments         no
+  0040,2001  ReasonForImagingServiceRequest     no
+  0040,2004  IssueDateOfImagingServiceRequest   no
+  0040,2005  IssueTimeOfImagingServiceRequest   no
+  0040,2006  PlacerOrderNum-ImagingServiceReq   no
+  0040,2007  FillerOrderNum-ImagingServiceReq   no
+  0040,2008  OrderEnteredBy                     no
+  0040,2009  OrderEntererLocation               no
+  0040,2010  OrderCallbackPhoneNumber           no
+  0040,2016  PlacerOrderNum-ImagingServiceReq   no
+  0040,2017  FillerOrderNum-ImagingServiceReq   no
+  0040,2400  ImagingServiceRequestComments      no
+  0040,3001  ConfidentialityOnPatientDataDescr  no
+  0040,4001  GenPurposeScheduledProcStepStatus  no
+  0040,4002  GenPurposePerformedProcStepStatus  no
+  0040,4003  GenPurposeSchedProcStepPriority    no
+  0040,4004  SchedProcessingApplicationsCodeSeq no
+  0040,4005  SchedProcedureStepStartDateAndTime no
+  0040,4006  MultipleCopiesFlag                 no
+  0040,4007  PerformedProcessingAppsCodeSeq     no
+  0040,4009  HumanPerformerCodeSequence         no
+  0040,4010  SchedProcStepModificationDateTime  no
+  0040,4011  ExpectedCompletionDateAndTime      no
+  0040,4015  ResultingGenPurposePerfProcStepSeq no
+  0040,4016  RefGenPurposeSchedProcStepSeq      no
+  0040,4018  ScheduledWorkitemCodeSequence      no
+  0040,4019  PerformedWorkitemCodeSequence      no
+  0040,4020  InputAvailabilityFlag              no
+  0040,4021  InputInformationSequence           no
+  0040,4022  RelevantInformationSequence        no
+  0040,4023  RefGenPurSchedProcStepTransUID     no
+  0040,4025  ScheduledStationNameCodeSequence   no
+  0040,4026  ScheduledStationClassCodeSequence  no
+  0040,4027  SchedStationGeographicLocCodeSeq   no
+  0040,4028  PerformedStationNameCodeSequence   no
+  0040,4029  PerformedStationClassCodeSequence  no
+  0040,4030  PerformedStationGeogLocCodeSeq     no
+  0040,4031  RequestedSubsequentWorkItemCodeSeq no
+  0040,4032  NonDICOMOutputCodeSequence         no
+  0040,4033  OutputInformationSequence          no
+  0040,4034  ScheduledHumanPerformersSequence   no
+  0040,4035  ActualHumanPerformersSequence      no
+  0040,4036  HumanPerformersOrganization        no
+  0040,4037  HumanPerformerName                 no
+  0040,4040  RawDataHandling                    no
+  0040,8302  EntranceDoseInMilliGy              no
+  0040,9094  RefImageRealWorldValueMappingSeq   no
+  0040,9096  RealWorldValueMappingSequence      no
+  0040,9098  PixelValueMappingCodeSequence      no
+  0040,9210  LUTLabel                           no
+  0040,9211  RealWorldValueLastValueMapped      no
+  0040,9212  RealWorldValueLUTData              no
+  0040,9216  RealWorldValueFirstValueMapped     no
+  0040,9224  RealWorldValueIntercept            no
+  0040,9225  RealWorldValueSlope                no
+  0040,A010  RelationshipType                   no
+  0040,A027  VerifyingOrganization              no
+  0040,A030  VerificationDateTime               no
+  0040,A032  ObservationDateTime                no
+  0040,A040  ValueType                          no
+  0040,A043  ConceptNameCodeSequence            no
+  0040,A050  ContinuityOfContent                no
+  0040,A073  VerifyingObserverSequence          no
+  0040,A075  VerifyingObserverName              no
+  0040,A078  AuthorObserverSequence             no
+  0040,A07A  ParticipantSequence                no
+  0040,A07C  CustodialOrganizationSequence      no
+  0040,A080  ParticipationType                  no
+  0040,A082  ParticipationDateTime              no
+  0040,A084  ObserverType                       no
+  0040,A088  VerifyingObserverIdentCodeSequence no
+  0040,A090  EquivalentCDADocumentSequence      no
+  0040,A0B0  ReferencedWaveformChannels         no
+  0040,A120  DateTime                           no
+  0040,A121  Date                               no
+  0040,A122  Time                               no
+  0040,A123  PersonName                         no
+  0040,A124  UID                                no
+  0040,A130  TemporalRangeType                  no
+  0040,A132  ReferencedSamplePositions          no
+  0040,A136  ReferencedFrameNumbers             no
+  0040,A138  ReferencedTimeOffsets              no
+  0040,A13A  ReferencedDateTime                 no
+  0040,A160  TextValue                          no
+  0040,A168  ConceptCodeSequence                no
+  0040,A170  PurposeOfReferenceCodeSequence     no
+  0040,A180  AnnotationGroupNumber              no
+  0040,A195  ModifierCodeSequence               no
+  0040,A300  MeasuredValueSequence              no
+  0040,A301  NumericValueQualifierCodeSequence  no
+  0040,A30A  NumericValue                       no
+  0040,A353  AddressTrial                       no
+  0040,A354  TelephoneNumberTrial               no
+  0040,A360  PredecessorDocumentsSequence       no
+  0040,A370  ReferencedRequestSequence          no
+  0040,A372  PerformedProcedureCodeSequence     no
+  0040,A375  CurrentRequestedProcEvidenceSeq    no
+  0040,A385  PertinentOtherEvidenceSequence     no
+  0040,A390  HL7StructuredDocumentRefSeq        no
+  0040,A491  CompletionFlag                     no
+  0040,A492  CompletionFlagDescription          no
+  0040,A493  VerificationFlag                   no
+  0040,A494  ArchiveRequested                   no
+  0040,A496  PreliminaryFlag                    no
+  0040,A504  ContentTemplateSequence            no
+  0040,A525  IdenticalDocumentsSequence         no
+  0040,A730  ContentSequence                    no
+  0040,B020  AnnotationSequence                 no
+  0040,DB00  TemplateIdentifier                 no
+  0040,DB06  TemplateVersion                    no
+  0040,DB07  TemplateLocalVersion               no
+  0040,DB0B  TemplateExtensionFlag              no
+  0040,DB0C  TemplateExtensionOrganizationUID   no
+  0040,DB0D  TemplateExtensionCreatorUID        no
+  0040,DB73  ReferencedContentItemIdentifier    no
+  0040,E001  HL7InstanceIdentifier              no
+  0040,E004  HL7DocumentEffectiveTime           no
+  0040,E006  HL7DocumentTypeCodeSequence        no
+  0040,E010  RetrieveURI                        no
+  0040,E011  RetrieveLocationUID                no
+  0042,0010  DocumentTitle                      no
+  0042,0011  EncapsulatedDocument               no
+  0042,0012  MIMETypeOfEncapsulatedDocument     no
+  0042,0013  SourceInstanceSequence             no
+  0042,0014  ListOfMIMETypes                    no
+  0043,1001  BitmapOfPrescanOptions             no
+  0043,1002  GradientOffsetInX                  no
+  0043,1003  GradientOffsetInY                  no
+  0043,1004  GradientOffsetInZ                  no
+  0043,1005  ImgIsOriginalOrUnoriginal          no
+  0043,1006  NumberOfEPIShots                   no
+  0043,1007  ViewsPerSegment                    no
+  0043,1008  RespiratoryRateBpm                 no
+  0043,1009  RespiratoryTriggerPoint            no
+  0043,100A  TypeOfReceiverUsed                 no
+  0043,100B  PeakRateOfChangeOfGradientField    no
+  0043,100C  LimitsInUnitsOfPercent             no
+  0043,100D  PSDEstimatedLimit                  no
+  0043,100E  PSDEstimatedLimitInTeslaPerSecond  no
+  0043,100F  Saravghead                         no
+  0043,1010  WindowValue                        no
+  0043,1011  TotalInputViews                    no
+  0043,1012  X-RayChain                         no
+  0043,1013  DeconKernelParameters              no
+  0043,1014  CalibrationParameters              no
+  0043,1015  TotalOutputViews                   no
+  0043,1016  NumberOfOverranges                 no
+  0043,1017  IBHImageScaleFactors               no
+  0043,1018  BBHCoefficients                    no
+  0043,1019  NumberOfBBHChainsToBlend           no
+  0043,101A  StartingChannelNumber              no
+  0043,101B  PpscanParameters                   no
+  0043,101C  GEImageIntegrity                   no
+  0043,101D  LevelValue                         no
+  0043,101E  DeltaStartTime                     no
+  0043,101F  MaxOverrangesInAView               no
+  0043,1020  AvgOverrangesAllViews              no
+  0043,1021  CorrectedAfterGlowTerms            no
+  0043,1025  ReferenceChannels                  no
+  0043,1026  NoViewsRefChansBlocked             no
+  0043,1027  ScanPitchRatio                     no
+  0043,1028  UniqueImageIden                    no
+  0043,1029  HistogramTables                    no
+  0043,102A  UserDefinedData                    no
+  0043,102B  PrivateScanOptions                 no
+  0043,102C  EffectiveEchoSpacing               no
+  0043,102D  StringSlopField1                   no
+  0043,102E  StringSlopField2                   no
+  0043,102F  RawDataType                        no
+  0043,1030  RawDataType                        no
+  0043,1031  RACordOfTargetReconCenter          no
+  0043,1032  RawDataType                        no
+  0043,1033  NegScanspacing                     no
+  0043,1034  OffsetFrequency                    no
+  0043,1035  UserUsageTag                       no
+  0043,1036  UserFillMapMSW                     no
+  0043,1037  UserFillMapLSW                     no
+  0043,1038  User25-48                          no
+  0043,1039  SlopInt6-9                         no
+  0043,1040  TriggerOnPosition                  no
+  0043,1041  DegreeOfRotation                   no
+  0043,1042  DASTriggerSource                   no
+  0043,1043  DASFpaGain                         no
+  0043,1044  DASOutputSource                    no
+  0043,1045  DASAdInput                         no
+  0043,1046  DASCalMode                         no
+  0043,1047  DASCalFrequency                    no
+  0043,1048  DASRegXm                           no
+  0043,1049  DASAutoZero                        no
+  0043,104A  StartingChannelOfView              no
+  0043,104B  DASXmPattern                       no
+  0043,104C  TGGCTriggerMode                    no
+  0043,104D  StartScanToXrayOnDelay             no
+  0043,104E  DurationOfXrayOn                   no
+  0043,1060  SlopInt10-17                       no
+  0043,1061  ScannerStudyEntityUID              no
+  0043,1062  ScannerStudyID                     no
+  0043,106f  ScannerTableEntry                  no
+  0044,0001  ProductPackageIdentifier           no
+  0044,0002  SubstanceAdministrationApproval    no
+  0044,0003  ApprovalStatusFurtherDescription   no
+  0044,0004  ApprovalStatusDateTime             no
+  0044,0007  ProductTypeCodeSequence            no
+  0044,0008  ProductName                        no
+  0044,0009  ProductDescription                 no
+  0044,000A  ProductLotIdentifier               no
+  0044,000B  ProductExpirationDateTime          no
+  0044,0010  SubstanceAdministrationDateTime    no
+  0044,0011  SubstanceAdministrationNotes       no
+  0044,0012  SubstanceAdministrationDeviceID    no
+  0044,0013  ProductParameterSequence           no
+  0044,0019  SubstanceAdminParameterSeq         no
+  0045,1001  NumberOfMacroRowsInDetector        no
+  0045,1002  MacroWidthAtISOCenter              no
+  0045,1003  DASType                            no
+  0045,1004  DASGain                            no
+  0045,1005  DASTemperature                     no
+  0045,1006  TableDirectionInOrOut              no
+  0045,1007  ZSmoothingFactor                   no
+  0045,1008  ViewWeightingMode                  no
+  0045,1009  SigmaRowNumberWhichRowsWereUsed    no
+  0045,100A  MinimumDasValueFoundInTheScanData  no
+  0045,100B  MaximumOffsetShiftValueUsed        no
+  0045,100C  NumberOfViewsShifted               no
+  0045,100D  ZTrackingFlag                      no
+  0045,100E  MeanZError                         no
+  0045,100F  ZTrackingMaximumError              no
+  0045,1010  StartingViewForRow2a               no
+  0045,1011  NumberOfViewsInRow2a               no
+  0045,1012  StartingViewForRow1a               no
+  0045,1013  SigmaMode                          no
+  0045,1014  NumberOfViewsInRow1a               no
+  0045,1015  StartingViewForRow2b               no
+  0045,1016  NumberOfViewsInRow2b               no
+  0045,1017  StartingViewForRow1b               no
+  0045,1018  NumberOfViewsInRow1b               no
+  0045,1019  AirFilterCalibrationDate           no
+  0045,101A  AirFilterCalibrationTime           no
+  0045,101B  PhantomCalibrationDate             no
+  0045,101C  PhantomCalibrationTime             no
+  0045,101D  ZSlopeCalibrationDate              no
+  0045,101E  ZSlopeCalibrationTime              no
+  0045,101F  CrosstalkCalibrationDate           no
+  0045,1020  CrosstalkCalibrationTime           no
+  0045,1021  IterboneOptionFlag                 no
+  0045,1022  PeristalticFlagOption              no
+  0046,0012  LensDescription                    no
+  0046,0014  RightLensSequence                  no
+  0046,0015  LeftLensSequence                   no
+  0046,0018  CylinderSequence                   no
+  0046,0028  PrismSequence                      no
+  0046,0030  HorizontalPrismPower               no
+  0046,0032  HorizontalPrismBase                no
+  0046,0034  VerticalPrismPower                 no
+  0046,0036  VerticalPrismBase                  no
+  0046,0038  LensSegmentType                    no
+  0046,0040  OpticalTransmittance               no
+  0046,0042  ChannelWidth                       no
+  0046,0044  PupilSize                          no
+  0046,0046  CornealSize                        no
+  0046,0060  DistancePupillaryDistance          no
+  0046,0062  NearPupillaryDistance              no
+  0046,0064  OtherPupillaryDistance             no
+  0046,0075  RadiusOfCurvature                  no
+  0046,0076  KeratometricPower                  no
+  0046,0077  KeratometricAxis                   no
+  0046,0092  BackgroundColor                    no
+  0046,0094  Optotype                           no
+  0046,0095  OptotypePresentation               no
+  0046,0100  AddNearSequence                    no
+  0046,0101  AddIntermediateSequence            no
+  0046,0102  AddOtherSequence                   no
+  0046,0104  AddPower                           no
+  0046,0106  ViewingDistance                    no
+  0046,0125  ViewingDistanceType                no
+  0046,0135  VisualAcuityModifiers              no
+  0046,0137  DecimalVisualAcuity                no
+  0046,0139  OptotypeDetailedDefinition         no
+  0046,0146  SpherePower                        no
+  0046,0147  CylinderPower                      no
+  0050,0004  CalibrationImage                   no
+  0050,0010  DeviceSequence                     no
+  0050,0014  DeviceLength                       no
+  0050,0015  ContainerComponentWidth            no
+  0050,0016  DeviceDiameter                     no
+  0050,0017  DeviceDiameterUnits                no
+  0050,0018  DeviceVolume                       no
+  0050,0019  InterMarkerDistance                no
+  0050,001B  ContainerComponentID               no
+  0050,0020  DeviceDescription                  no
+  0054,0010  EnergyWindowVector                 no
+  0054,0011  NumberOfEnergyWindows              no
+  0054,0012  EnergyWindowInformationSequence    no
+  0054,0013  EnergyWindowRangeSequence          no
+  0054,0014  EnergyWindowLowerLimit             no
+  0054,0015  EnergyWindowUpperLimit             no
+  0054,0016  RadiopharmaceuticalInformationSeq  no
+  0054,0017  ResidualSyringeCounts              no
+  0054,0018  EnergyWindowName                   no
+  0054,0020  DetectorVector                     no
+  0054,0021  NumberOfDetectors                  no
+  0054,0022  DetectorInformationSequence        no
+  0054,0030  PhaseVector                        no
+  0054,0031  NumberOfPhases                     no
+  0054,0032  PhaseInformationSequence           no
+  0054,0033  NumberOfFramesInPhase              no
+  0054,0036  PhaseDelay                         no
+  0054,0038  PauseBetweenFrames                 no
+  0054,0039  PhaseDescription                   no
+  0054,0050  RotationVector                     no
+  0054,0051  NumberOfRotations                  no
+  0054,0052  RotationInformationSequence        no
+  0054,0053  NumberOfFramesInRotation           no
+  0054,0060  RRIntervalVector                   no
+  0054,0061  NumberOfRRIntervals                no
+  0054,0062  GatedInformationSequence           no
+  0054,0063  DataInformationSequence            no
+  0054,0070  TimeSlotVector                     no
+  0054,0071  NumberOfTimeSlots                  no
+  0054,0072  TimeSlotInformationSequence        no
+  0054,0073  TimeSlotTime                       no
+  0054,0080  SliceVector                        no
+  0054,0081  NumberOfSlices                     no
+  0054,0090  AngularViewVector                  no
+  0054,0100  TimeSliceVector                    no
+  0054,0101  NumberOfTimeSlices                 no
+  0054,0200  StartAngle                         no
+  0054,0202  TypeOfDetectorMotion               no
+  0054,0210  TriggerVector                      no
+  0054,0211  NumberOfTriggersInPhase            no
+  0054,0220  ViewCodeSequence                   no
+  0054,0222  ViewModifierCodeSequence           no
+  0054,0300  RadionuclideCodeSequence           no
+  0054,0302  AdministrationRouteCodeSequence    no
+  0054,0304  RadiopharmaceuticalCodeSequence    no
+  0054,0306  CalibrationDataSequence            no
+  0054,0308  EnergyWindowNumber                 no
+  0054,0400  ImageID                            no
+  0054,0410  PatientOrientationCodeSequence     no
+  0054,0412  PatientOrientationModifierCodeSeq  no
+  0054,0414  PatientGantryRelationshipCodeSeq   no
+  0054,0500  SliceProgressionDirection          no
+  0054,1000  SeriesType                         no
+  0054,1001  Units                              no
+  0054,1002  CountsSource                       no
+  0054,1004  ReprojectionMethod                 no
+  0054,1100  RandomsCorrectionMethod            no
+  0054,1101  AttenuationCorrectionMethod        no
+  0054,1102  DecayCorrection                    no
+  0054,1103  ReconstructionMethod               no
+  0054,1104  DetectorLinesOfResponseUsed        no
+  0054,1105  ScatterCorrectionMethod            no
+  0054,1200  AxialAcceptance                    no
+  0054,1201  AxialMash                          no
+  0054,1202  TransverseMash                     no
+  0054,1203  DetectorElementSize                no
+  0054,1210  CoincidenceWindowWidth             no
+  0054,1220  SecondaryCountsType                no
+  0054,1300  FrameReferenceTime                 no
+  0054,1310  PrimaryCountsAccumulated           no
+  0054,1311  SecondaryCountsAccumulated         no
+  0054,1320  SliceSensitivityFactor             no
+  0054,1321  DecayFactor                        no
+  0054,1322  DoseCalibrationFactor              no
+  0054,1323  ScatterFractionFactor              no
+  0054,1324  DeadTimeFactor                     no
+  0054,1330  ImageIndex                         no
+  0054,1400  CountsIncluded                     no
+  0054,1401  DeadTimeCorrectionFlag             no
+  0060,3000  HistogramSequence                  no
+  0060,3002  HistogramNumberOfBins              no
+  0060,3004  HistogramFirstBinValue             no
+  0060,3006  HistogramLastBinValue              no
+  0060,3008  HistogramBinWidth                  no
+  0060,3010  HistogramExplanation               no
+  0060,3020  HistogramData                      no
+  0062,0001  SegmentationType                   no
+  0062,0002  SegmentSequence                    no
+  0062,0003  SegmentedPropertyCategoryCodeSeq   no
+  0062,0004  SegmentNumber                      no
+  0062,0005  SegmentLabel                       no
+  0062,0006  SegmentDescription                 no
+  0062,0008  SegmentAlgorithmType               no
+  0062,0009  SegmentAlgorithmName               no
+  0062,000A  SegmentIdentificationSequence      no
+  0062,000B  ReferencedSegmentNumber            no
+  0062,000C  RecommendedDisplayGrayscaleValue   no
+  0062,000D  RecommendedDisplayCIELabValue      no
+  0062,000E  MaximumFractionalValue             no
+  0062,000F  SegmentedPropertyTypeCodeSequence  no
+  0062,0010  SegmentationFractionalType         no
+  0064,0002  DeformableRegistrationSequence     no
+  0064,0003  SourceFrameOfReferenceUID          no
+  0064,0005  DeformableRegistrationGridSequence no
+  0064,0007  GridDimensions                     no
+  0064,0008  GridResolution                     no
+  0064,0009  VectorGridData                     no
+  0064,000F  PreDeformationMatrixRegistSeq      no
+  0064,0010  PostDeformationMatrixRegistSeq     no
+  0066,0001  NumberOfSurfaces                   no
+  0066,0002  SurfaceSequence                    no
+  0066,0003  SurfaceNumber                      no
+  0066,0004  SurfaceComments                    no
+  0066,0009  SurfaceProcessing                  no
+  0066,000A  SurfaceProcessingRatio             no
+  0066,000E  FiniteVolume                       no
+  0066,0010  Manifold                           no
+  0066,0011  SurfacePointsSequence              no
+  0066,0015  NumberOfSurfacePoints              no
+  0066,0016  PointCoordinatesData               no
+  0066,0017  PointPositionAccuracy              no
+  0066,0018  MeanPointDistance                  no
+  0066,0019  MaximumPointDistance               no
+  0066,001B  AxisOfRotation                     no
+  0066,001C  CenterOfRotation                   no
+  0066,001E  NumberOfVectors                    no
+  0066,001F  VectorDimensionality               no
+  0066,0020  VectorAccuracy                     no
+  0066,0021  VectorCoordinateData               no
+  0066,0023  TrianglePointIndexList             no
+  0066,0024  EdgePointIndexList                 no
+  0066,0025  VertexPointIndexList               no
+  0066,0026  TriangleStripSequence              no
+  0066,0027  TriangleFanSequence                no
+  0066,0028  LineSequence                       no
+  0066,0029  PrimitivePointIndexList            no
+  0066,002A  SurfaceCount                       no
+  0066,002F  AlgorithmFamilyCodeSequ            no
+  0066,0031  AlgorithmVersion                   no
+  0066,0032  AlgorithmParameters                no
+  0066,0034  FacetSequence                      no
+  0066,0036  AlgorithmName                      no
+  0070,0001  GraphicAnnotationSequence          no
+  0070,0002  GraphicLayer                       no
+  0070,0003  BoundingBoxAnnotationUnits         no
+  0070,0004  AnchorPointAnnotationUnits         no
+  0070,0005  GraphicAnnotationUnits             no
+  0070,0006  UnformattedTextValue               no
+  0070,0008  TextObjectSequence                 no
+  0070,0009  GraphicObjectSequence              no
+  0070,0010  BoundingBoxTopLeftHandCorner       no
+  0070,0011  BoundingBoxBottomRightHandCorner   no
+  0070,0012  BoundingBoxTextHorizJustification  no
+  0070,0014  AnchorPoint                        no
+  0070,0015  AnchorPointVisibility              no
+  0070,0020  GraphicDimensions                  no
+  0070,0021  NumberOfGraphicPoints              no
+  0070,0022  GraphicData                        no
+  0070,0023  GraphicType                        no
+  0070,0024  GraphicFilled                      no
+  0070,0040  ImageRotationRetired               no
+  0070,0041  ImageHorizontalFlip                no
+  0070,0042  ImageRotation                      no
+  0070,0050  DisplayedAreaTopLeftTrial          no
+  0070,0051  DisplayedAreaBottomRightTrial      no
+  0070,0052  DisplayedAreaTopLeft               no
+  0070,0053  DisplayedAreaBottomRight           no
+  0070,005A  DisplayedAreaSelectionSequence     no
+  0070,0060  GraphicLayerSequence               no
+  0070,0062  GraphicLayerOrder                  no
+  0070,0066  GraphicLayerRecDisplayGraysclValue no
+  0070,0067  GraphicLayerRecDisplayRGBValue     no
+  0070,0068  GraphicLayerDescription            no
+  0070,0080  ContentLabel                       no
+  0070,0081  ContentDescription                 no
+  0070,0082  PresentationCreationDate           no
+  0070,0083  PresentationCreationTime           no
+  0070,0084  ContentCreatorName                 no
+  0070,0086  ContentCreatorIDCodeSequence       no
+  0070,0100  PresentationSizeMode               no
+  0070,0101  PresentationPixelSpacing           no
+  0070,0102  PresentationPixelAspectRatio       no
+  0070,0103  PresentationPixelMagRatio          no
+  0070,0306  ShapeType                          no
+  0070,0308  RegistrationSequence               no
+  0070,0309  MatrixRegistrationSequence         no
+  0070,030A  MatrixSequence                     no
+  0070,030C  FrameOfRefTransformationMatrixType no
+  0070,030D  RegistrationTypeCodeSequence       no
+  0070,030F  FiducialDescription                no
+  0070,0310  FiducialIdentifier                 no
+  0070,0311  FiducialIdentifierCodeSequence     no
+  0070,0312  ContourUncertaintyRadius           no
+  0070,0314  UsedFiducialsSequence              no
+  0070,0318  GraphicCoordinatesDataSequence     no
+  0070,031A  FiducialUID                        no
+  0070,031C  FiducialSetSequence                no
+  0070,031E  FiducialSequence                   no
+  0070,0401  GraphicLayerRecomDisplayCIELabVal  no
+  0070,0402  BlendingSequence                   no
+  0070,0403  RelativeOpacity                    no
+  0070,0404  ReferencedSpatialRegistrationSeq   no
+  0070,0405  BlendingPosition                   no
+  0072,0002  HangingProtocolName                no
+  0072,0004  HangingProtocolDescription         no
+  0072,0006  HangingProtocolLevel               no
+  0072,0008  HangingProtocolCreator             no
+  0072,000A  HangingProtocolCreationDateTime    no
+  0072,000C  HangingProtocolDefinitionSequence  no
+  0072,000E  HangingProtocolUserIDCodeSequence  no
+  0072,0010  HangingProtocolUserGroupName       no
+  0072,0012  SourceHangingProtocolSequence      no
+  0072,0014  NumberOfPriorsReferenced           no
+  0072,0020  ImageSetsSequence                  no
+  0072,0022  ImageSetSelectorSequence           no
+  0072,0024  ImageSetSelectorUsageFlag          no
+  0072,0026  SelectorAttribute                  no
+  0072,0028  SelectorValueNumber                no
+  0072,0030  TimeBasedImageSetsSequence         no
+  0072,0032  ImageSetNumber                     no
+  0072,0034  ImageSetSelectorCategory           no
+  0072,0038  RelativeTime                       no
+  0072,003A  RelativeTimeUnits                  no
+  0072,003C  AbstractPriorValue                 no
+  0072,003E  AbstractPriorCodeSequence          no
+  0072,0040  ImageSetLabel                      no
+  0072,0050  SelectorAttributeVR                no
+  0072,0052  SelectorSequencePointer            no
+  0072,0054  SelectorSeqPointerPrivateCreator   no
+  0072,0056  SelectorAttributePrivateCreator    no
+  0072,0060  SelectorATValue                    no
+  0072,0062  SelectorCSValue                    no
+  0072,0064  SelectorISValue                    no
+  0072,0066  SelectorLOValue                    no
+  0072,0068  SelectorLTValue                    no
+  0072,006A  SelectorPNValue                    no
+  0072,006C  SelectorSHValue                    no
+  0072,006E  SelectorSTValue                    no
+  0072,0070  SelectorUTValue                    no
+  0072,0072  SelectorDSValue                    no
+  0072,0074  SelectorFDValue                    no
+  0072,0076  SelectorFLValue                    no
+  0072,0078  SelectorULValue                    no
+  0072,007A  SelectorUSValue                    no
+  0072,007C  SelectorSLValue                    no
+  0072,007E  SelectorSSValue                    no
+  0072,0080  SelectorCodeSequenceValue          no
+  0072,0100  NumberOfScreens                    no
+  0072,0102  NominalScreenDefinitionSequence    no
+  0072,0104  NumberOfVerticalPixels             no
+  0072,0106  NumberOfHorizontalPixels           no
+  0072,0108  DisplayEnvironmentSpatialPosition  no
+  0072,010A  ScreenMinimumGrayscaleBitDepth     no
+  0072,010C  ScreenMinimumColorBitDepth         no
+  0072,010E  ApplicationMaximumRepaintTime      no
+  0072,0200  DisplaySetsSequence                no
+  0072,0202  DisplaySetNumber                   no
+  0072,0203  DisplaySetLabel                    no
+  0072,0204  DisplaySetPresentationGroup        no
+  0072,0206  DisplaySetPresentationGroupDescr   no
+  0072,0208  PartialDataDisplayHandling         no
+  0072,0210  SynchronizedScrollingSequence      no
+  0072,0212  DisplaySetScrollingGroup           no
+  0072,0214  NavigationIndicatorSequence        no
+  0072,0216  NavigationDisplaySet               no
+  0072,0218  ReferenceDisplaySets               no
+  0072,0300  ImageBoxesSequence                 no
+  0072,0302  ImageBoxNumber                     no
+  0072,0304  ImageBoxLayoutType                 no
+  0072,0306  ImageBoxTileHorizontalDimension    no
+  0072,0308  ImageBoxTileVerticalDimension      no
+  0072,0310  ImageBoxScrollDirection            no
+  0072,0312  ImageBoxSmallScrollType            no
+  0072,0314  ImageBoxSmallScrollAmount          no
+  0072,0316  ImageBoxLargeScrollType            no
+  0072,0318  ImageBoxLargeScrollAmount          no
+  0072,0320  ImageBoxOverlapPriority            no
+  0072,0330  CineRelativeToRealTime             no
+  0072,0400  FilterOperationsSequence           no
+  0072,0402  FilterByCategory                   no
+  0072,0404  FilterByAttributePresence          no
+  0072,0406  FilterByOperator                   no
+  0072,0432  SynchronizedImageBoxList           no
+  0072,0434  TypeOfSynchronization              no
+  0072,0500  BlendingOperationType              no
+  0072,0510  ReformattingOperationType          no
+  0072,0512  ReformattingThickness              no
+  0072,0514  ReformattingInterval               no
+  0072,0516  ReformattingOpInitialViewDir       no
+  0072,0520  RenderingType3D                    no
+  0072,0600  SortingOperationsSequence          no
+  0072,0602  SortByCategory                     no
+  0072,0604  SortingDirection                   no
+  0072,0700  DisplaySetPatientOrientation       no
+  0072,0702  VOIType                            no
+  0072,0704  PseudoColorType                    no
+  0072,0706  ShowGrayscaleInverted              no
+  0072,0710  ShowImageTrueSizeFlag              no
+  0072,0712  ShowGraphicAnnotationFlag          no
+  0072,0714  ShowPatientDemographicsFlag        no
+  0072,0716  ShowAcquisitionTechniquesFlag      no
+  0072,0717  DisplaySetHorizontalJustification  no
+  0072,0718  DisplaySetVerticalJustification    no
+  0074,1000  UnifiedProcedureStepState          no
+  0074,1002  UPSProgressInformationSequence     no
+  0074,1004  UnifiedProcedureStepProgress       no
+  0074,1006  UnifiedProcedureStepProgressDescr  no
+  0074,1008  UnifiedProcedureStepComURISeq      no
+  0074,100a  ContactURI                         no
+  0074,100c  ContactDisplayName                 no
+  0074,1020  BeamTaskSequence                   no
+  0074,1022  BeamTaskType                       no
+  0074,1024  BeamOrderIndex                     no
+  0074,1030  DeliveryVerificationImageSequence  no
+  0074,1032  VerificationImageTiming            no
+  0074,1034  DoubleExposureFlag                 no
+  0074,1036  DoubleExposureOrdering             no
+  0074,1038  DoubleExposureMeterset             no
+  0074,103A  DoubleExposureFieldDelta           no
+  0074,1040  RelatedReferenceRTImageSequence    no
+  0074,1042  GeneralMachineVerificationSequence no
+  0074,1044  ConventionalMachineVerificationSeq no
+  0074,1046  IonMachineVerificationSequence     no
+  0074,1048  FailedAttributesSequence           no
+  0074,104A  OverriddenAttributesSequence       no
+  0074,104C  ConventionalControlPointVerifySeq  no
+  0074,104E  IonControlPointVerificationSeq     no
+  0074,1050  AttributeOccurrenceSequence        no
+  0074,1052  AttributeOccurrencePointer         no
+  0074,1054  AttributeItemSelector              no
+  0074,1056  AttributeOccurrencePrivateCreator  no
+  0074,1200  ScheduledProcedureStepPriority     no
+  0074,1202  WorklistLabel                      no
+  0074,1204  ProcedureStepLabel                 no
+  0074,1210  ScheduledProcessingParametersSeq   no
+  0074,1212  PerformedProcessingParametersSeq   no
+  0074,1216  UPSPerformedProcedureSequence      no
+  0074,1220  RelatedProcedureStepSequence       no
+  0074,1222  ProcedureStepRelationshipType      no
+  0074,1230  DeletionLock                       no
+  0074,1234  ReceivingAE                        no
+  0074,1236  RequestingAE                       no
+  0074,1238  ReasonForCancellation              no
+  0074,1242  SCPStatus                          no
+  0074,1244  SubscriptionListStatus             no
+  0074,1246  UPSListStatus                      no
+  0088,0130  StorageMediaFileSetID              no
+  0088,0140  StorageMediaFileSetUID             no
+  0088,0200  IconImageSequence                  no
+  0088,0904  TopicTitle                         no
+  0088,0906  TopicSubject                       no
+  0088,0910  TopicAuthor                        no
+  0088,0912  TopicKeywords                      no
+  0100,0410  SOPInstanceStatus                  no
+  0100,0420  SOPAuthorizationDateAndTime        no
+  0100,0424  SOPAuthorizationComment            no
+  0100,0426  AuthorizationEquipmentCertNumber   no
+  0400,0005  MACIDNumber                        no
+  0400,0010  MACCalculationTransferSyntaxUID    no
+  0400,0015  MACAlgorithm                       no
+  0400,0020  DataElementsSigned                 no
+  0400,0100  DigitalSignatureUID                no
+  0400,0105  DigitalSignatureDateTime           no
+  0400,0110  CertificateType                    no
+  0400,0115  CertificateOfSigner                no
+  0400,0120  Signature                          no
+  0400,0305  CertifiedTimestampType             no
+  0400,0310  CertifiedTimestamp                 no
+  0400,0401  DigitalSignaturePurposeCodeSeq     no
+  0400,0402  ReferencedDigitalSignatureSeq      no
+  0400,0403  ReferencedSOPInstanceMACSeq        no
+  0400,0404  MAC                                no
+  0400,0500  EncryptedAttributesSequence        no
+  0400,0510  EncryptedContentTransferSyntaxUID  no
+  0400,0520  EncryptedContent                   no
+  0400,0550  ModifiedAttributesSequence         no
+  0400,0561  OriginalAttributesSequence         no
+  0400,0562  AttributeModificationDateTime      no
+  0400,0563  ModifyingSystem                    no
+  0400,0564  SourceOfPreviousValues             no
+  0400,0565  ReasonForTheAttributeModification  no
+  1000,xxx0  EscapeTriplet                      no
+  1000,xxx1  RunLengthTriplet                   no
+  1000,xxx2  HuffmanTableSize                   no
+  1000,xxx3  HuffmanTableTriplet                no
+  1000,xxx4  ShiftTableSize                     no
+  1000,xxx5  ShiftTableTriplet                  no
+  1010,xxxx  ZonalMap                           no
+  2000,0010  NumberOfCopies                     no
+  2000,001E  PrinterConfigurationSequence       no
+  2000,0020  PrintPriority                      no
+  2000,0030  MediumType                         no
+  2000,0040  FilmDestination                    no
+  2000,0050  FilmSessionLabel                   no
+  2000,0060  MemoryAllocation                   no
+  2000,0061  MaximumMemoryAllocation            no
+  2000,0062  ColorImagePrintingFlag             no
+  2000,0063  CollationFlag                      no
+  2000,0065  AnnotationFlag                     no
+  2000,0067  ImageOverlayFlag                   no
+  2000,0069  PresentationLUTFlag                no
+  2000,006A  ImageBoxPresentationLUTFlag        no
+  2000,00A0  MemoryBitDepth                     no
+  2000,00A1  PrintingBitDepth                   no
+  2000,00A2  MediaInstalledSequence             no
+  2000,00A4  OtherMediaAvailableSequence        no
+  2000,00A8  SupportedImageDisplayFormatSeq     no
+  2000,0500  ReferencedFilmBoxSequence          no
+  2000,0510  ReferencedStoredPrintSequence      no
+  2010,0010  ImageDisplayFormat                 no
+  2010,0030  AnnotationDisplayFormatID          no
+  2010,0040  FilmOrientation                    no
+  2010,0050  FilmSizeID                         no
+  2010,0052  PrinterResolutionID                no
+  2010,0054  DefaultPrinterResolutionID         no
+  2010,0060  MagnificationType                  no
+  2010,0080  SmoothingType                      no
+  2010,00A6  DefaultMagnificationType           no
+  2010,00A7  OtherMagnificationTypesAvailable   no
+  2010,00A8  DefaultSmoothingType               no
+  2010,00A9  OtherSmoothingTypesAvailable       no
+  2010,0100  BorderDensity                      no
+  2010,0110  EmptyImageDensity                  no
+  2010,0120  MinDensity                         no
+  2010,0130  MaxDensity                         no
+  2010,0140  Trim                               no
+  2010,0150  ConfigurationInformation           no
+  2010,0152  ConfigurationInformationDescr      no
+  2010,0154  MaximumCollatedFilms               no
+  2010,015E  Illumination                       no
+  2010,0160  ReflectedAmbientLight              no
+  2010,0376  PrinterPixelSpacing                no
+  2010,0500  ReferencedFilmSessionSequence      no
+  2010,0510  ReferencedImageBoxSequence         no
+  2010,0520  ReferencedBasicAnnotationBoxSeq    no
+  2020,0010  ImageBoxPosition                   no
+  2020,0020  Polarity                           no
+  2020,0030  RequestedImageSize                 no
+  2020,0040  RequestedDecimate-CropBehavior     no
+  2020,0050  RequestedResolutionID              no
+  2020,00A0  RequestedImageSizeFlag             no
+  2020,00A2  DecimateCropResult                 no
+  2020,0110  BasicGrayscaleImageSequence        no
+  2020,0111  BasicColorImageSequence            no
+  2020,0130  ReferencedImageOverlayBoxSequence  no
+  2020,0140  ReferencedVOILUTBoxSequence        no
+  2030,0010  AnnotationPosition                 no
+  2030,0020  TextString                         no
+  2040,0010  ReferencedOverlayPlaneSequence     no
+  2040,0011  ReferencedOverlayPlaneGroups       no
+  2040,0020  OverlayPixelDataSequence           no
+  2040,0060  OverlayMagnificationType           no
+  2040,0070  OverlaySmoothingType               no
+  2040,0072  OverlayOrImageMagnification        no
+  2040,0074  MagnifyToNumberOfColumns           no
+  2040,0080  OverlayForegroundDensity           no
+  2040,0082  OverlayBackgroundDensity           no
+  2040,0090  OverlayMode                        no
+  2040,0100  ThresholdDensity                   no
+  2040,0500  ReferencedImageBoxSequence         no
+  2050,0010  PresentationLUTSequence            no
+  2050,0020  PresentationLUTShape               no
+  2050,0500  ReferencedPresentationLUTSequence  no
+  2100,0010  PrintJobID                         no
+  2100,0020  ExecutionStatus                    no
+  2100,0030  ExecutionStatusInfo                no
+  2100,0040  CreationDate                       no
+  2100,0050  CreationTime                       no
+  2100,0070  Originator                         no
+  2100,0140  DestinationAE                      no
+  2100,0160  OwnerID                            no
+  2100,0170  NumberOfFilms                      no
+  2100,0500  ReferencedPrintJobSequence         no
+  2110,0010  PrinterStatus                      no
+  2110,0020  PrinterStatusInfo                  no
+  2110,0030  PrinterName                        no
+  2110,0099  PrintQueueID                       no
+  2120,0010  QueueStatus                        no
+  2120,0050  PrintJobDescriptionSequence        no
+  2120,0070  ReferencedPrintJobSequence         no
+  2130,0010  PrintManagementCapabilitiesSeq     no
+  2130,0015  PrinterCharacteristicsSequence     no
+  2130,0030  FilmBoxContentSequence             no
+  2130,0040  ImageBoxContentSequence            no
+  2130,0050  AnnotationContentSequence          no
+  2130,0060  ImageOverlayBoxContentSequence     no
+  2130,0080  PresentationLUTContentSequence     no
+  2130,00A0  ProposedStudySequence              no
+  2130,00C0  OriginalImageSequence              no
+  2200,0001  LabelFromInfoExtractedFromInstance no
+  2200,0002  LabelText                          no
+  2200,0003  LabelStyleSelection                no
+  2200,0004  MediaDisposition                   no
+  2200,0005  BarcodeValue                       no
+  2200,0006  BarcodeSymbology                   no
+  2200,0007  AllowMediaSplitting                no
+  2200,0008  IncludeNonDICOMObjects             no
+  2200,0009  IncludeDisplayApplication          no
+  2200,000A  SaveCompInstancesAfterMediaCreate  no
+  2200,000B  TotalNumberMediaPiecesCreated      no
+  2200,000C  RequestedMediaApplicationProfile   no
+  2200,000D  ReferencedStorageMediaSequence     no
+  2200,000E  FailureAttributes                  no
+  2200,000F  AllowLossyCompression              no
+  2200,0020  RequestPriority                    no
+  3002,0002  RTImageLabel                       no
+  3002,0003  RTImageName                        no
+  3002,0004  RTImageDescription                 no
+  3002,000A  ReportedValuesOrigin               no
+  3002,000C  RTImagePlane                       no
+  3002,000D  XRayImageReceptorTranslation       no
+  3002,000E  XRayImageReceptorAngle             no
+  3002,0010  RTImageOrientation                 no
+  3002,0011  ImagePlanePixelSpacing             no
+  3002,0012  RTImagePosition                    no
+  3002,0020  RadiationMachineName               no
+  3002,0022  RadiationMachineSAD                no
+  3002,0024  RadiationMachineSSD                no
+  3002,0026  RTImageSID                         no
+  3002,0028  SourceToReferenceObjectDistance    no
+  3002,0029  FractionNumber                     no
+  3002,0030  ExposureSequence                   no
+  3002,0032  MetersetExposure                   no
+  3002,0034  DiaphragmPosition                  no
+  3002,0040  FluenceMapSequence                 no
+  3002,0041  FluenceDataSource                  no
+  3002,0042  FluenceDataScale                   no
+  3002,0051  FluenceMode                        no
+  3002,0052  FluenceModeID                      no
+  3004,0001  DVHType                            no
+  3004,0002  DoseUnits                          no
+  3004,0004  DoseType                           no
+  3004,0006  DoseComment                        no
+  3004,0008  NormalizationPoint                 no
+  3004,000A  DoseSummationType                  no
+  3004,000C  GridFrameOffsetVector              no
+  3004,000E  DoseGridScaling                    no
+  3004,0010  RTDoseROISequence                  no
+  3004,0012  DoseValue                          no
+  3004,0014  TissueHeterogeneityCorrection      no
+  3004,0040  DVHNormalizationPoint              no
+  3004,0042  DVHNormalizationDoseValue          no
+  3004,0050  DVHSequence                        no
+  3004,0052  DVHDoseScaling                     no
+  3004,0054  DVHVolumeUnits                     no
+  3004,0056  DVHNumberOfBins                    no
+  3004,0058  DVHData                            no
+  3004,0060  DVHReferencedROISequence           no
+  3004,0062  DVHROIContributionType             no
+  3004,0070  DVHMinimumDose                     no
+  3004,0072  DVHMaximumDose                     no
+  3004,0074  DVHMeanDose                        no
+  3006,0002  StructureSetLabel                  no
+  3006,0004  StructureSetName                   no
+  3006,0006  StructureSetDescription            no
+  3006,0008  StructureSetDate                   no
+  3006,0009  StructureSetTime                   no
+  3006,0010  ReferencedFrameOfReferenceSequence no
+  3006,0012  RTReferencedStudySequence          no
+  3006,0014  RTReferencedSeriesSequence         no
+  3006,0016  ContourImageSequence               no
+  3006,0020  StructureSetROISequence            no
+  3006,0022  ROINumber                          no
+  3006,0024  ReferencedFrameOfReferenceUID      no
+  3006,0026  ROIName                            no
+  3006,0028  ROIDescription                     no
+  3006,002A  ROIDisplayColor                    no
+  3006,002C  ROIVolume                          no
+  3006,0030  RTRelatedROISequence               no
+  3006,0033  RTROIRelationship                  no
+  3006,0036  ROIGenerationAlgorithm             no
+  3006,0038  ROIGenerationDescription           no
+  3006,0039  ROIContourSequence                 no
+  3006,0040  ContourSequence                    no
+  3006,0042  ContourGeometricType               no
+  3006,0044  ContourSlabThickness               no
+  3006,0045  ContourOffsetVector                no
+  3006,0046  NumberOfContourPoints              no
+  3006,0048  ContourNumber                      no
+  3006,0049  AttachedContours                   no
+  3006,0050  ContourData                        no
+  3006,0080  RTROIObservationsSequence          no
+  3006,0082  ObservationNumber                  no
+  3006,0084  ReferencedROINumber                no
+  3006,0085  ROIObservationLabel                no
+  3006,0086  RTROIIdentificationCodeSequence    no
+  3006,0088  ROIObservationDescription          no
+  3006,00A0  RelatedRTROIObservationsSequence   no
+  3006,00A4  RTROIInterpretedType               no
+  3006,00A6  ROIInterpreter                     no
+  3006,00B0  ROIPhysicalPropertiesSequence      no
+  3006,00B2  ROIPhysicalProperty                no
+  3006,00B4  ROIPhysicalPropertyValue           no
+  3006,00B6  ROIElementalCompositionSequence    no
+  3006,00B7  ROIElementalCompAtomicNumber       no
+  3006,00B8  ROIElementalCompAtomicMassFraction no
+  3006,00C0  FrameOfReferenceRelationshipSeq    no
+  3006,00C2  RelatedFrameOfReferenceUID         no
+  3006,00C4  FrameOfReferenceTransformType      no
+  3006,00C6  FrameOfReferenceTransformMatrix    no
+  3006,00C8  FrameOfReferenceTransformComment   no
+  3008,0010  MeasuredDoseReferenceSequence      no
+  3008,0012  MeasuredDoseDescription            no
+  3008,0014  MeasuredDoseType                   no
+  3008,0016  MeasuredDoseValue                  no
+  3008,0020  TreatmentSessionBeamSequence       no
+  3008,0021  TreatmentSessionIonBeamSequence    no
+  3008,0022  CurrentFractionNumber              no
+  3008,0024  TreatmentControlPointDate          no
+  3008,0025  TreatmentControlPointTime          no
+  3008,002A  TreatmentTerminationStatus         no
+  3008,002B  TreatmentTerminationCode           no
+  3008,002C  TreatmentVerificationStatus        no
+  3008,0030  ReferencedTreatmentRecordSequence  no
+  3008,0032  SpecifiedPrimaryMeterset           no
+  3008,0033  SpecifiedSecondaryMeterset         no
+  3008,0036  DeliveredPrimaryMeterset           no
+  3008,0037  DeliveredSecondaryMeterset         no
+  3008,003A  SpecifiedTreatmentTime             no
+  3008,003B  DeliveredTreatmentTime             no
+  3008,0040  ControlPointDeliverySequence       no
+  3008,0041  IonControlPointDeliverySequence    no
+  3008,0042  SpecifiedMeterset                  no
+  3008,0044  DeliveredMeterset                  no
+  3008,0045  MetersetRateSet                    no
+  3008,0046  MetersetRateDelivered              no
+  3008,0047  ScanSpotMetersetsDelivered         no
+  3008,0048  DoseRateDelivered                  no
+  3008,0050  TreatmentSummaryCalcDoseRefSeq     no
+  3008,0052  CumulativeDoseToDoseReference      no
+  3008,0054  FirstTreatmentDate                 no
+  3008,0056  MostRecentTreatmentDate            no
+  3008,005A  NumberOfFractionsDelivered         no
+  3008,0060  OverrideSequence                   no
+  3008,0061  ParameterSequencePointer           no
+  3008,0062  OverrideParameterPointer           no
+  3008,0063  ParameterItemIndex                 no
+  3008,0064  MeasuredDoseReferenceNumber        no
+  3008,0065  ParameterPointer                   no
+  3008,0066  OverrideReason                     no
+  3008,0068  CorrectedParameterSequence         no
+  3008,006A  CorrectionValue                    no
+  3008,0070  CalculatedDoseReferenceSequence    no
+  3008,0072  CalculatedDoseReferenceNumber      no
+  3008,0074  CalculatedDoseReferenceDescription no
+  3008,0076  CalculatedDoseReferenceDoseValue   no
+  3008,0078  StartMeterset                      no
+  3008,007A  EndMeterset                        no
+  3008,0080  ReferencedMeasuredDoseReferenceSeq no
+  3008,0082  ReferencedMeasuredDoseReferenceNum no
+  3008,0090  ReferencedCalculatedDoseRefSeq     no
+  3008,0092  ReferencedCalculatedDoseRefNumber  no
+  3008,00A0  BeamLimitingDeviceLeafPairsSeq     no
+  3008,00B0  RecordedWedgeSequence              no
+  3008,00C0  RecordedCompensatorSequence        no
+  3008,00D0  RecordedBlockSequence              no
+  3008,00E0  TreatmentSummaryMeasuredDoseRefSeq no
+  3008,00F0  RecordedSnoutSequence              no
+  3008,00F2  RecordedRangeShifterSequence       no
+  3008,00F4  RecordedLateralSpreadingDeviceSeq  no
+  3008,00F6  RecordedRangeModulatorSequence     no
+  3008,0100  RecordedSourceSequence             no
+  3008,0105  SourceSerialNumber                 no
+  3008,0110  TreatmentSessionAppSetupSeq        no
+  3008,0116  ApplicationSetupCheck              no
+  3008,0120  RecordedBrachyAccessoryDeviceSeq   no
+  3008,0122  ReferencedBrachyAccessoryDeviceNum no
+  3008,0130  RecordedChannelSequence            no
+  3008,0132  SpecifiedChannelTotalTime          no
+  3008,0134  DeliveredChannelTotalTime          no
+  3008,0136  SpecifiedNumberOfPulses            no
+  3008,0138  DeliveredNumberOfPulses            no
+  3008,013A  SpecifiedPulseRepetitionInterval   no
+  3008,013C  DeliveredPulseRepetitionInterval   no
+  3008,0140  RecordedSourceApplicatorSequence   no
+  3008,0142  ReferencedSourceApplicatorNumber   no
+  3008,0150  RecordedChannelShieldSequence      no
+  3008,0152  ReferencedChannelShieldNumber      no
+  3008,0160  BrachyControlPointDeliveredSeq     no
+  3008,0162  SafePositionExitDate               no
+  3008,0164  SafePositionExitTime               no
+  3008,0166  SafePositionReturnDate             no
+  3008,0168  SafePositionReturnTime             no
+  3008,0200  CurrentTreatmentStatus             no
+  3008,0202  TreatmentStatusComment             no
+  3008,0220  FractionGroupSummarySequence       no
+  3008,0223  ReferencedFractionNumber           no
+  3008,0224  FractionGroupType                  no
+  3008,0230  BeamStopperPosition                no
+  3008,0240  FractionStatusSummarySequence      no
+  3008,0250  TreatmentDate                      no
+  3008,0251  TreatmentTime                      no
+  300A,0002  RTPlanLabel                        no
+  300A,0003  RTPlanName                         no
+  300A,0004  RTPlanDescription                  no
+  300A,0006  RTPlanDate                         no
+  300A,0007  RTPlanTime                         no
+  300A,0009  TreatmentProtocols                 no
+  300A,000A  PlanIntent                         no
+  300A,000B  TreatmentSites                     no
+  300A,000C  RTPlanGeometry                     no
+  300A,000E  PrescriptionDescription            no
+  300A,0010  DoseReferenceSequence              no
+  300A,0012  DoseReferenceNumber                no
+  300A,0013  DoseReferenceUID                   no
+  300A,0014  DoseReferenceStructureType         no
+  300A,0015  NominalBeamEnergyUnit              no
+  300A,0016  DoseReferenceDescription           no
+  300A,0018  DoseReferencePointCoordinates      no
+  300A,001A  NominalPriorDose                   no
+  300A,0020  DoseReferenceType                  no
+  300A,0021  ConstraintWeight                   no
+  300A,0022  DeliveryWarningDose                no
+  300A,0023  DeliveryMaximumDose                no
+  300A,0025  TargetMinimumDose                  no
+  300A,0026  TargetPrescriptionDose             no
+  300A,0027  TargetMaximumDose                  no
+  300A,0028  TargetUnderdoseVolumeFraction      no
+  300A,002A  OrganAtRiskFullVolumeDose          no
+  300A,002B  OrganAtRiskLimitDose               no
+  300A,002C  OrganAtRiskMaximumDose             no
+  300A,002D  OrganAtRiskOverdoseVolumeFraction  no
+  300A,0040  ToleranceTableSequence             no
+  300A,0042  ToleranceTableNumber               no
+  300A,0043  ToleranceTableLabel                no
+  300A,0044  GantryAngleTolerance               no
+  300A,0046  BeamLimitingDeviceAngleTolerance   no
+  300A,0048  BeamLimitingDeviceToleranceSeq     no
+  300A,004A  BeamLimitingDevicePositionTol      no
+  300A,004B  SnoutPositionTolerance             no
+  300A,004C  PatientSupportAngleTolerance       no
+  300A,004E  TableTopEccentricAngleTolerance    no
+  300A,004F  TableTopPitchAngleTolerance        no
+  300A,0050  TableTopRollAngleTolerance         no
+  300A,0051  TableTopVerticalPositionTolerance  no
+  300A,0052  TableTopLongitudinalPositionTol    no
+  300A,0053  TableTopLateralPositionTolerance   no
+  300A,0055  RTPlanRelationship                 no
+  300A,0070  FractionGroupSequence              no
+  300A,0071  FractionGroupNumber                no
+  300A,0072  FractionGroupDescription           no
+  300A,0078  NumberOfFractionsPlanned           no
+  300A,0079  NumberFractionPatternDigitsPerDay  no
+  300A,007A  RepeatFractionCycleLength          no
+  300A,007B  FractionPattern                    no
+  300A,0080  NumberOfBeams                      no
+  300A,0082  BeamDoseSpecificationPoint         no
+  300A,0084  BeamDose                           no
+  300A,0086  BeamMeterset                       no
+  300A,0088  BeamDosePointDepth                 no
+  300A,0089  BeamDosePointEquivalentDepth       no
+  300A,008A  BeamDosePointSSD                   no
+  300A,00A0  NumberOfBrachyApplicationSetups    no
+  300A,00A2  BrachyAppSetupDoseSpecPoint        no
+  300A,00A4  BrachyApplicationSetupDose         no
+  300A,00B0  BeamSequence                       no
+  300A,00B2  TreatmentMachineName               no
+  300A,00B3  PrimaryDosimeterUnit               no
+  300A,00B4  SourceAxisDistance                 no
+  300A,00B6  BeamLimitingDeviceSequence         no
+  300A,00B8  RTBeamLimitingDeviceType           no
+  300A,00BA  SourceToBeamLimitingDeviceDistance no
+  300A,00BB  IsocenterToBeamLimitingDeviceDist  no
+  300A,00BC  NumberOfLeafJawPairs               no
+  300A,00BE  LeafPositionBoundaries             no
+  300A,00C0  BeamNumber                         no
+  300A,00C2  BeamName                           no
+  300A,00C3  BeamDescription                    no
+  300A,00C4  BeamType                           no
+  300A,00C6  RadiationType                      no
+  300A,00C7  HighDoseTechniqueType              no
+  300A,00C8  ReferenceImageNumber               no
+  300A,00CA  PlannedVerificationImageSequence   no
+  300A,00CC  ImagingDeviceSpecificAcqParams     no
+  300A,00CE  TreatmentDeliveryType              no
+  300A,00D0  NumberOfWedges                     no
+  300A,00D1  WedgeSequence                      no
+  300A,00D2  WedgeNumber                        no
+  300A,00D3  WedgeType                          no
+  300A,00D4  WedgeID                            no
+  300A,00D5  WedgeAngle                         no
+  300A,00D6  WedgeFactor                        no
+  300A,00D7  TotalWedgeTrayWaterEquivThickness  no
+  300A,00D8  WedgeOrientation                   no
+  300A,00D9  IsocenterToWedgeTrayDistance       no
+  300A,00DA  SourceToWedgeTrayDistance          no
+  300A,00DB  WedgeThinEdgePosition              no
+  300A,00DC  BolusID                            no
+  300A,00DD  BolusDescription                   no
+  300A,00E0  NumberOfCompensators               no
+  300A,00E1  MaterialID                         no
+  300A,00E2  TotalCompensatorTrayFactor         no
+  300A,00E3  CompensatorSequence                no
+  300A,00E4  CompensatorNumber                  no
+  300A,00E5  CompensatorID                      no
+  300A,00E6  SourceToCompensatorTrayDistance    no
+  300A,00E7  CompensatorRows                    no
+  300A,00E8  CompensatorColumns                 no
+  300A,00E9  CompensatorPixelSpacing            no
+  300A,00EA  CompensatorPosition                no
+  300A,00EB  CompensatorTransmissionData        no
+  300A,00EC  CompensatorThicknessData           no
+  300A,00ED  NumberOfBoli                       no
+  300A,00EE  CompensatorType                    no
+  300A,00F0  NumberOfBlocks                     no
+  300A,00F2  TotalBlockTrayFactor               no
+  300A,00F3  TotalBlockTrayWaterEquivThickness  no
+  300A,00F4  BlockSequence                      no
+  300A,00F5  BlockTrayID                        no
+  300A,00F6  SourceToBlockTrayDistance          no
+  300A,00F7  IsocenterToBlockTrayDistance       no
+  300A,00F8  BlockType                          no
+  300A,00F9  AccessoryCode                      no
+  300A,00FA  BlockDivergence                    no
+  300A,00FB  BlockMountingPosition              no
+  300A,00FC  BlockNumber                        no
+  300A,00FE  BlockName                          no
+  300A,0100  BlockThickness                     no
+  300A,0102  BlockTransmission                  no
+  300A,0104  BlockNumberOfPoints                no
+  300A,0106  BlockData                          no
+  300A,0107  ApplicatorSequence                 no
+  300A,0108  ApplicatorID                       no
+  300A,0109  ApplicatorType                     no
+  300A,010A  ApplicatorDescription              no
+  300A,010C  CumulativeDoseReferenceCoefficient no
+  300A,010E  FinalCumulativeMetersetWeight      no
+  300A,0110  NumberOfControlPoints              no
+  300A,0111  ControlPointSequence               no
+  300A,0112  ControlPointIndex                  no
+  300A,0114  NominalBeamEnergy                  no
+  300A,0115  DoseRateSet                        no
+  300A,0116  WedgePositionSequence              no
+  300A,0118  WedgePosition                      no
+  300A,011A  BeamLimitingDevicePositionSequence no
+  300A,011C  LeafJawPositions                   no
+  300A,011E  GantryAngle                        no
+  300A,011F  GantryRotationDirection            no
+  300A,0120  BeamLimitingDeviceAngle            no
+  300A,0121  BeamLimitingDeviceRotateDirection  no
+  300A,0122  PatientSupportAngle                no
+  300A,0123  PatientSupportRotationDirection    no
+  300A,0124  TableTopEccentricAxisDistance      no
+  300A,0125  TableTopEccentricAngle             no
+  300A,0126  TableTopEccentricRotateDirection   no
+  300A,0128  TableTopVerticalPosition           no
+  300A,0129  TableTopLongitudinalPosition       no
+  300A,012A  TableTopLateralPosition            no
+  300A,012C  IsocenterPosition                  no
+  300A,012E  SurfaceEntryPoint                  no
+  300A,0130  SourceToSurfaceDistance            no
+  300A,0134  CumulativeMetersetWeight           no
+  300A,0140  TableTopPitchAngle                 no
+  300A,0142  TableTopPitchRotationDirection     no
+  300A,0144  TableTopRollAngle                  no
+  300A,0146  TableTopRollRotationDirection      no
+  300A,0148  HeadFixationAngle                  no
+  300A,014A  GantryPitchAngle                   no
+  300A,014C  GantryPitchRotationDirection       no
+  300A,014E  GantryPitchAngleTolerance          no
+  300A,0180  PatientSetupSequence               no
+  300A,0182  PatientSetupNumber                 no
+  300A,0183  PatientSetupLabel                  no
+  300A,0184  PatientAdditionalPosition          no
+  300A,0190  FixationDeviceSequence             no
+  300A,0192  FixationDeviceType                 no
+  300A,0194  FixationDeviceLabel                no
+  300A,0196  FixationDeviceDescription          no
+  300A,0198  FixationDevicePosition             no
+  300A,0199  FixationDevicePitchAngle           no
+  300A,019A  FixationDeviceRollAngle            no
+  300A,01A0  ShieldingDeviceSequence            no
+  300A,01A2  ShieldingDeviceType                no
+  300A,01A4  ShieldingDeviceLabel               no
+  300A,01A6  ShieldingDeviceDescription         no
+  300A,01A8  ShieldingDevicePosition            no
+  300A,01B0  SetupTechnique                     no
+  300A,01B2  SetupTechniqueDescription          no
+  300A,01B4  SetupDeviceSequence                no
+  300A,01B6  SetupDeviceType                    no
+  300A,01B8  SetupDeviceLabel                   no
+  300A,01BA  SetupDeviceDescription             no
+  300A,01BC  SetupDeviceParameter               no
+  300A,01D0  SetupReferenceDescription          no
+  300A,01D2  TableTopVerticalSetupDisplacement  no
+  300A,01D4  TableTopLongitudinalSetupDisplace  no
+  300A,01D6  TableTopLateralSetupDisplacement   no
+  300A,0200  BrachyTreatmentTechnique           no
+  300A,0202  BrachyTreatmentType                no
+  300A,0206  TreatmentMachineSequence           no
+  300A,0210  SourceSequence                     no
+  300A,0212  SourceNumber                       no
+  300A,0214  SourceType                         no
+  300A,0216  SourceManufacturer                 no
+  300A,0218  ActiveSourceDiameter               no
+  300A,021A  ActiveSourceLength                 no
+  300A,0222  SourceEncapsulationNomThickness    no
+  300A,0224  SourceEncapsulationNomTransmission no
+  300A,0226  SourceIsotopeName                  no
+  300A,0228  SourceIsotopeHalfLife              no
+  300A,0229  SourceStrengthUnits                no
+  300A,022A  ReferenceAirKermaRate              no
+  300A,022B  SourceStrength                     no
+  300A,022C  SourceStrengthReferenceDate        no
+  300A,022E  SourceStrengthReferenceTime        no
+  300A,0230  ApplicationSetupSequence           no
+  300A,0232  ApplicationSetupType               no
+  300A,0234  ApplicationSetupNumber             no
+  300A,0236  ApplicationSetupName               no
+  300A,0238  ApplicationSetupManufacturer       no
+  300A,0240  TemplateNumber                     no
+  300A,0242  TemplateType                       no
+  300A,0244  TemplateName                       no
+  300A,0250  TotalReferenceAirKerma             no
+  300A,0260  BrachyAccessoryDeviceSequence      no
+  300A,0262  BrachyAccessoryDeviceNumber        no
+  300A,0263  BrachyAccessoryDeviceID            no
+  300A,0264  BrachyAccessoryDeviceType          no
+  300A,0266  BrachyAccessoryDeviceName          no
+  300A,026A  BrachyAccessoryDeviceNomThickness  no
+  300A,026C  BrachyAccessoryDevNomTransmission  no
+  300A,0280  ChannelSequence                    no
+  300A,0282  ChannelNumber                      no
+  300A,0284  ChannelLength                      no
+  300A,0286  ChannelTotalTime                   no
+  300A,0288  SourceMovementType                 no
+  300A,028A  NumberOfPulses                     no
+  300A,028C  PulseRepetitionInterval            no
+  300A,0290  SourceApplicatorNumber             no
+  300A,0291  SourceApplicatorID                 no
+  300A,0292  SourceApplicatorType               no
+  300A,0294  SourceApplicatorName               no
+  300A,0296  SourceApplicatorLength             no
+  300A,0298  SourceApplicatorManufacturer       no
+  300A,029C  SourceApplicatorWallNomThickness   no
+  300A,029E  SourceApplicatorWallNomTrans       no
+  300A,02A0  SourceApplicatorStepSize           no
+  300A,02A2  TransferTubeNumber                 no
+  300A,02A4  TransferTubeLength                 no
+  300A,02B0  ChannelShieldSequence              no
+  300A,02B2  ChannelShieldNumber                no
+  300A,02B3  ChannelShieldID                    no
+  300A,02B4  ChannelShieldName                  no
+  300A,02B8  ChannelShieldNominalThickness      no
+  300A,02BA  ChannelShieldNominalTransmission   no
+  300A,02C8  FinalCumulativeTimeWeight          no
+  300A,02D0  BrachyControlPointSequence         no
+  300A,02D2  ControlPointRelativePosition       no
+  300A,02D4  ControlPoint3DPosition             no
+  300A,02D6  CumulativeTimeWeight               no
+  300A,02E0  CompensatorDivergence              no
+  300A,02E1  CompensatorMountingPosition        no
+  300A,02E2  SourceToCompensatorDistance        no
+  300A,02E3  TotalCompTrayWaterEquivThickness   no
+  300A,02E4  IsocenterToCompensatorTrayDistance no
+  300A,02E5  CompensatorColumnOffset            no
+  300A,02E6  IsocenterToCompensatorDistances    no
+  300A,02E7  CompensatorRelStoppingPowerRatio   no
+  300A,02E8  CompensatorMillingToolDiameter     no
+  300A,02EA  IonRangeCompensatorSequence        no
+  300A,02EB  CompensatorDescription             no
+  300A,0302  RadiationMassNumber                no
+  300A,0304  RadiationAtomicNumber              no
+  300A,0306  RadiationChargeState               no
+  300A,0308  ScanMode                           no
+  300A,030A  VirtualSourceAxisDistances         no
+  300A,030C  SnoutSequence                      no
+  300A,030D  SnoutPosition                      no
+  300A,030F  SnoutID                            no
+  300A,0312  NumberOfRangeShifters              no
+  300A,0314  RangeShifterSequence               no
+  300A,0316  RangeShifterNumber                 no
+  300A,0318  RangeShifterID                     no
+  300A,0320  RangeShifterType                   no
+  300A,0322  RangeShifterDescription            no
+  300A,0330  NumberOfLateralSpreadingDevices    no
+  300A,0332  LateralSpreadingDeviceSequence     no
+  300A,0334  LateralSpreadingDeviceNumber       no
+  300A,0336  LateralSpreadingDeviceID           no
+  300A,0338  LateralSpreadingDeviceType         no
+  300A,033A  LateralSpreadingDeviceDescription  no
+  300A,033C  LateralSpreadingDevWaterEquivThick no
+  300A,0340  NumberOfRangeModulators            no
+  300A,0342  RangeModulatorSequence             no
+  300A,0344  RangeModulatorNumber               no
+  300A,0346  RangeModulatorID                   no
+  300A,0348  RangeModulatorType                 no
+  300A,034A  RangeModulatorDescription          no
+  300A,034C  BeamCurrentModulationID            no
+  300A,0350  PatientSupportType                 no
+  300A,0352  PatientSupportID                   no
+  300A,0354  PatientSupportAccessoryCode        no
+  300A,0356  FixationLightAzimuthalAngle        no
+  300A,0358  FixationLightPolarAngle            no
+  300A,035A  MetersetRate                       no
+  300A,0360  RangeShifterSettingsSequence       no
+  300A,0362  RangeShifterSetting                no
+  300A,0364  IsocenterToRangeShifterDistance    no
+  300A,0366  RangeShifterWaterEquivThickness    no
+  300A,0370  LateralSpreadingDeviceSettingsSeq  no
+  300A,0372  LateralSpreadingDeviceSetting      no
+  300A,0374  IsocenterToLateralSpreadingDevDist no
+  300A,0380  RangeModulatorSettingsSequence     no
+  300A,0382  RangeModulatorGatingStartValue     no
+  300A,0384  RangeModulatorGatingStopValue      no
+  300A,038A  IsocenterToRangeModulatorDistance  no
+  300A,0390  ScanSpotTuneID                     no
+  300A,0392  NumberOfScanSpotPositions          no
+  300A,0394  ScanSpotPositionMap                no
+  300A,0396  ScanSpotMetersetWeights            no
+  300A,0398  ScanningSpotSize                   no
+  300A,039A  NumberOfPaintings                  no
+  300A,03A0  IonToleranceTableSequence          no
+  300A,03A2  IonBeamSequence                    no
+  300A,03A4  IonBeamLimitingDeviceSequence      no
+  300A,03A6  IonBlockSequence                   no
+  300A,03A8  IonControlPointSequence            no
+  300A,03AA  IonWedgeSequence                   no
+  300A,03AC  IonWedgePositionSequence           no
+  300A,0401  ReferencedSetupImageSequence       no
+  300A,0402  SetupImageComment                  no
+  300A,0410  MotionSynchronizationSequence      no
+  300A,0412  ControlPointOrientation            no
+  300A,0420  GeneralAccessorySequence           no
+  300A,0421  GeneralAccessoryID                 no
+  300A,0422  GeneralAccessoryDescription        no
+  300A,0423  GeneralAccessoryType               no
+  300A,0424  GeneralAccessoryNumber             no
+  300C,0002  ReferencedRTPlanSequence           no
+  300C,0004  ReferencedBeamSequence             no
+  300C,0006  ReferencedBeamNumber               no
+  300C,0007  ReferencedReferenceImageNumber     no
+  300C,0008  StartCumulativeMetersetWeight      no
+  300C,0009  EndCumulativeMetersetWeight        no
+  300C,000A  ReferencedBrachyAppSetupSeq        no
+  300C,000C  ReferencedBrachyAppSetupNumber     no
+  300C,000E  ReferencedSourceNumber             no
+  300C,0020  ReferencedFractionGroupSequence    no
+  300C,0022  ReferencedFractionGroupNumber      no
+  300C,0040  ReferencedVerificationImageSeq     no
+  300C,0042  ReferencedReferenceImageSequence   no
+  300C,0050  ReferencedDoseReferenceSequence    no
+  300C,0051  ReferencedDoseReferenceNumber      no
+  300C,0055  BrachyReferencedDoseReferenceSeq   no
+  300C,0060  ReferencedStructureSetSequence     no
+  300C,006A  ReferencedPatientSetupNumber       no
+  300C,0080  ReferencedDoseSequence             no
+  300C,00A0  ReferencedToleranceTableNumber     no
+  300C,00B0  ReferencedBolusSequence            no
+  300C,00C0  ReferencedWedgeNumber              no
+  300C,00D0  ReferencedCompensatorNumber        no
+  300C,00E0  ReferencedBlockNumber              no
+  300C,00F0  ReferencedControlPointIndex        no
+  300C,00F2  ReferencedControlPointSequence     no
+  300C,00F4  ReferencedStartControlPointIndex   no
+  300C,00F6  ReferencedStopControlPointIndex    no
+  300C,0100  ReferencedRangeShifterNumber       no
+  300C,0102  ReferencedLateralSpreadingDevNum   no
+  300C,0104  ReferencedRangeModulatorNumber     no
+  300E,0002  ApprovalStatus                     no
+  300E,0004  ReviewDate                         no
+  300E,0005  ReviewTime                         no
+  300E,0008  ReviewerName                       no
+  4000,0000  TextGroupLength                    no
+  4000,0010  Arbitrary                          no
+  4000,4000  TextComments                       no
+  4008,0040  ResultsID                          no
+  4008,0042  ResultsIDIssuer                    no
+  4008,0050  ReferencedInterpretationSequence   no
+  4008,0100  InterpretationRecordedDate         no
+  4008,0101  InterpretationRecordedTime         no
+  4008,0102  InterpretationRecorder             no
+  4008,0103  ReferenceToRecordedSound           no
+  4008,0108  InterpretationTranscriptionDate    no
+  4008,0109  InterpretationTranscriptionTime    no
+  4008,010A  InterpretationTranscriber          no
+  4008,010B  InterpretationText                 no
+  4008,010C  InterpretationAuthor               no
+  4008,0111  InterpretationApproverSequence     no
+  4008,0112  InterpretationApprovalDate         no
+  4008,0113  InterpretationApprovalTime         no
+  4008,0114  PhysicianApprovingInterpretation   no
+  4008,0115  InterpretationDiagnosisDescription no
+  4008,0117  InterpretationDiagnosisCodeSeq     no
+  4008,0118  ResultsDistributionListSequence    no
+  4008,0119  DistributionName                   no
+  4008,011A  DistributionAddress                no
+  4008,0200  InterpretationID                   no
+  4008,0202  InterpretationIDIssuer             no
+  4008,0210  InterpretationTypeID               no
+  4008,0212  InterpretationStatusID             no
+  4008,0300  Impressions                        no
+  4008,4000  ResultsComments                    no
+  4FFE,0001  MACParametersSequence              no
+  50xx,0005  CurveDimensions                    no
+  50xx,0010  NumberOfPoints                     no
+  50xx,0020  TypeOfData                         no
+  50xx,0022  CurveDescription                   no
+  50xx,0030  AxisUnits                          no
+  50xx,0040  AxisLabels                         no
+  50xx,0103  DataValueRepresentation            no
+  50xx,0104  MinimumCoordinateValue             no
+  50xx,0105  MaximumCoordinateValue             no
+  50xx,0106  CurveRange                         no
+  50xx,0110  CurveDataDescriptor                no
+  50xx,0112  CoordinateStartValue               no
+  50xx,0114  CoordinateStepValue                no
+  50xx,1001  CurveActivationLayer               no
+  50xx,2000  AudioType                          no
+  50xx,2002  AudioSampleFormat                  no
+  50xx,2004  NumberOfChannels                   no
+  50xx,2006  NumberOfSamples                    no
+  50xx,2008  SampleRate                         no
+  50xx,200A  TotalTime                          no
+  50xx,200C  AudioSampleData                    no
+  50xx,200E  AudioComments                      no
+  50xx,2500  CurveLabel                         no
+  50xx,2600  ReferencedOverlaySequence          no
+  50xx,2610  ReferencedOverlayGroup             no
+  50xx,3000  CurveData                          no
+  5200,9229  SharedFunctionalGroupsSequence     no
+  5200,9230  PerFrameFunctionalGroupsSequence   no
+  5400,0100  WaveformSequence                   no
+  5400,0110  ChannelMinimumValue                no
+  5400,0112  ChannelMaximumValue                no
+  5400,1004  WaveformBitsAllocated              no
+  5400,1006  WaveformSampleInterpretation       no
+  5400,100A  WaveformPaddingValue               no
+  5400,1010  WaveformData                       no
+  5600,0010  FirstOrderPhaseCorrectionAngle     no
+  5600,0020  SpectroscopyData                   no
+  6000,0000  OverlayGroupLength                 no
+  60xx,0010  OverlayRows                        no
+  60xx,0011  OverlayColumns                     no
+  60xx,0012  OverlayPlanes                      no
+  60xx,0015  NumberOfFramesInOverlay            no
+  60xx,0022  OverlayDescription                 no
+  60xx,0040  OverlayType                        no
+  60xx,0045  OverlaySubtype                     no
+  60xx,0050  OverlayOrigin                      no
+  60xx,0051  ImageFrameOrigin                   no
+  60xx,0052  OverlayPlaneOrigin                 no
+  60xx,0060  OverlayCompressionCode             no
+  60xx,0061  OverlayCompressionOriginator       no
+  60xx,0062  OverlayCompressionLabel            no
+  60xx,0063  OverlayCompressionDescription      no
+  60xx,0066  OverlayCompressionStepPointers     no
+  60xx,0068  OverlayRepeatInterval              no
+  60xx,0069  OverlayBitsGrouped                 no
+  60xx,0100  OverlayBitsAllocated               no
+  60xx,0102  OverlayBitPosition                 no
+  60xx,0110  OverlayFormat                      no
+  60xx,0200  OverlayLocation                    no
+  60xx,0800  OverlayCodeLabel                   no
+  60xx,0802  OverlayNumberOfTables              no
+  60xx,0803  OverlayCodeTableLocation           no
+  60xx,0804  OverlayBitsForCodeWord             no
+  60xx,1001  OverlayActivationLayer             no
+  60xx,1100  OverlayDescriptorGray              no
+  60xx,1101  OverlayDescriptorRed               no
+  60xx,1102  OverlayDescriptorGreen             no
+  60xx,1103  OverlayDescriptorBlue              no
+  60xx,1200  OverlaysGray                       no
+  60xx,1201  OverlaysRed                        no
+  60xx,1202  OverlaysGreen                      no
+  60xx,1203  OverlaysBlue                       no
+  60xx,1301  ROIArea                            no
+  60xx,1302  ROIMean                            no
+  60xx,1303  ROIStandardDeviation               no
+  60xx,1500  OverlayLabel                       no
+  60xx,3000  OverlayData                        no
+  60xx,4000  OverlayComments                    no
+  7Fxx,0000  PixelDataGroupLength               no
+  7Fxx,0010  PixelData                          no
+  7Fxx,0011  VariableNextDataGroup              no
+  7Fxx,0020  VariableCoefficientsSDVN           no
+  7Fxx,0030  VariableCoefficientsSDHN           no
+  7Fxx,0040  VariableCoefficientsSDDN           no
+  FFFA,FFFA  DigitalSignaturesSequence          no
+  FFFC,FFFC  DataSetTrailingPadding             no
+  FFFE,E000  StartOfItem                        no
+  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
+  'COMMENT'    Comment                          no
+  'DATE'       CreateDate                       no
+  'DATE-END'   ObservationDateEnd               no
+  'DATE-OBS'   ObservationDate                  no
+  'HISTORY'    History                          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
+
+Other than a few tags in the table below, JSON tags have not been
+pre-defined.  However, ExifTool will read any existing tags from basic
+JSON-formatted files.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  ON1_SettingsData                              PLIST
+  ON1_SettingsMetadataCreated                   no
+  ON1_SettingsMetadataModified                  no
+  ON1_SettingsMetadataName                      no
+  ON1_SettingsMetadataPluginID                  no
+  ON1_SettingsMetadataTimestamp                 no
+  ON1_SettingsMetadataUsage                     no
+  ON1_SettingsMetadataVisibleToUser             no
 
 =head2 HTML Tags
@@ -19932,32 +33781,34 @@
   Tag ID                      Tag Name          Writable
   ------                      --------          --------
-  'abstract'                  Abstract          N
-  'author'                    Author            N
-  'classification'            Classification    N
-  'copyright'                 Copyright         N
+  'abstract'                  Abstract          no
+  'author'                    Author            no
+  'classification'            Classification    no
+  'content-language'          ContentLanguage   no
+  'copyright'                 Copyright         no
   'dc'                        DC                HTML dc
-  'description'               Description       N
-  'distribution'              Distribution      N
-  'doc-class'                 DocClass          N
-  'doc-rights'                DocRights         N
-  'doc-type'                  DocType           N
-  'formatter'                 Formatter         N
-  'generator'                 Generator         N
-  'googlebot'                 GoogleBot         N
+  'description'               Description       no
+  'distribution'              Distribution      no
+  'doc-class'                 DocClass          no
+  'doc-rights'                DocRights         no
+  'doc-type'                  DocType           no
+  'formatter'                 Formatter         no
+  'generator'                 Generator         no
+  'generatorversion'          GeneratorVersion  no
+  'googlebot'                 GoogleBot         no
   'http-equiv'                HTTP-equiv        HTML equiv
-  'keywords'                  Keywords          N+
-  'mssmarttagspreventparsing' NoMSSmartTags     N
+  'keywords'                  Keywords          no+
+  'mssmarttagspreventparsing' NoMSSmartTags     no
   'ncc'                       NCC               HTML ncc
   'o'                         Office            HTML Office
-  'originator'                Originator        N
-  'owner'                     Owner             N
+  'originator'                Originator        no
+  'owner'                     Owner             no
   'prod'                      Prod              HTML prod
-  'progid'                    ProgID            N
-  'rating'                    Rating            N
-  'refresh'                   Refresh           N
-  'resource-type'             ResourceType      N
-  'revisit-after'             RevisitAfter      N
-  'robots'                    Robots            N+
-  'title'                     Title             N
+  'progid'                    ProgID            no
+  'rating'                    Rating            no
+  'refresh'                   Refresh           no
+  'resource-type'             ResourceType      no
+  'revisit-after'             RevisitAfter      no
+  'robots'                    Robots            no+
+  'title'                     Title             no
   'vw96'                      VW96              HTML vw96
 
@@ -19968,19 +33819,19 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'contributor'        Contributor              N+
-  'coverage'           Coverage                 N
-  'creator'            Creator                  N+
-  'date'               Date                     N+
-  'description'        Description              N
-  'format'             Format                   N
-  'identifier'         Identifier               N
-  'language'           Language                 N+
-  'publisher'          Publisher                N+
-  'relation'           Relation                 N+
-  'rights'             Rights                   N
-  'source'             Source                   N
-  'subject'            Subject                  N+
-  'title'              Title                    N
-  'type'               Type                     N+
+  'contributor'        Contributor              no+
+  'coverage'           Coverage                 no
+  'creator'            Creator                  no+
+  'date'               Date                     no+
+  'description'        Description              no
+  'format'             Format                   no
+  'identifier'         Identifier               no
+  'language'           Language                 no+
+  'publisher'          Publisher                no+
+  'relation'           Relation                 no+
+  'rights'             Rights                   no
+  'source'             Source                   no
+  'subject'            Subject                  no+
+  'title'              Title                    no
+  'type'               Type                     no+
 
 =head3 HTML equiv Tags
@@ -19990,26 +33841,26 @@
   Tag ID                Tag Name                Writable
   ------                --------                --------
-  'cache-control'       CacheControl            N
-  'content-disposition' ContentDisposition      N
-  'content-language'    ContentLanguage         N
-  'content-script-type' ContentScriptType       N
-  'content-style-type'  ContentStyleType        N
-  'content-type'        ContentType             N
-  'default-style'       DefaultStyle            N
-  'expires'             Expires                 N
-  'ext-cache'           ExtCache                N
-  'imagetoolbar'        ImageToolbar            N
-  'lotus'               Lotus                   N
-  'page-enter'          PageEnter               N
-  'page-exit'           PageExit                N
-  'pics-label'          PicsLabel               N
-  'pragma'              Pragma                  N
-  'refresh'             Refresh                 N
-  'reply-to'            ReplyTo                 N
-  'set-cookie'          SetCookie               N
-  'site-enter'          SiteEnter               N
-  'site-exit'           SiteExit                N
-  'vary'                Vary                    N
-  'window-target'       WindowTarget            N
+  'cache-control'       CacheControl            no
+  'content-disposition' ContentDisposition      no
+  'content-language'    ContentLanguage         no
+  'content-script-type' ContentScriptType       no
+  'content-style-type'  ContentStyleType        no
+  'content-type'        ContentType             no
+  'default-style'       DefaultStyle            no
+  'expires'             Expires                 no
+  'ext-cache'           ExtCache                no
+  'imagetoolbar'        ImageToolbar            no
+  'lotus'               Lotus                   no
+  'page-enter'          PageEnter               no
+  'page-exit'           PageExit                no
+  'pics-label'          PicsLabel               no
+  'pragma'              Pragma                  no
+  'refresh'             Refresh                 no
+  'reply-to'            ReplyTo                 no
+  'set-cookie'          SetCookie               no
+  'site-enter'          SiteEnter               no
+  'site-exit'           SiteExit                no
+  'vary'                Vary                    no
+  'window-target'       WindowTarget            no
 
 =head3 HTML ncc Tags
@@ -20017,30 +33868,30 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'charset'            CharacterSet             N
-  'depth'              Depth                    N
-  'files'              Files                    N
-  'footnotes'          Footnotes                N
-  'generator'          Generator                N
-  'kbytesize'          KByteSize                N
-  'maxpagenormal'      MaxPageNormal            N
-  'multimediatype'     MultimediaType           N
-  'narrator'           Narrator                 N
-  'pagefront'          PageFront                N
-  'pagenormal'         PageNormal               N
-  'pagespecial'        PageSpecial              N
-  'prodnotes'          ProdNotes                N
-  'produceddate'       ProducedDate             N
-  'producer'           Producer                 N
-  'revision'           Revision                 N
-  'revisiondate'       RevisionDate             N
-  'setinfo'            SetInfo                  N
-  'sidebars'           Sidebars                 N
-  'sourcedate'         SourceDate               N
-  'sourceedition'      SourceEdition            N
-  'sourcepublisher'    SourcePublisher          N
-  'sourcerights'       SourceRights             N
-  'sourcetitle'        SourceTitle              N
-  'tocitems'           TOCItems                 N
-  'totaltime'          Duration                 N
+  'charset'            CharacterSet             no
+  'depth'              Depth                    no
+  'files'              Files                    no
+  'footnotes'          Footnotes                no
+  'generator'          Generator                no
+  'kbytesize'          KByteSize                no
+  'maxpagenormal'      MaxPageNormal            no
+  'multimediatype'     MultimediaType           no
+  'narrator'           Narrator                 no
+  'pagefront'          PageFront                no
+  'pagenormal'         PageNormal               no
+  'pagespecial'        PageSpecial              no
+  'prodnotes'          ProdNotes                no
+  'produceddate'       ProducedDate             no
+  'producer'           Producer                 no
+  'revision'           Revision                 no
+  'revisiondate'       RevisionDate             no
+  'setinfo'            SetInfo                  no
+  'sidebars'           Sidebars                 no
+  'sourcedate'         SourceDate               no
+  'sourceedition'      SourceEdition            no
+  'sourcepublisher'    SourcePublisher          no
+  'sourcerights'       SourceRights             no
+  'sourcetitle'        SourceTitle              no
+  'tocitems'           TOCItems                 no
+  'totaltime'          Duration                 no
 
 =head3 HTML Office Tags
@@ -20050,25 +33901,25 @@
   Tag ID                 Tag Name               Writable
   ------                 --------               --------
-  'Author'               Author                 N
-  'Category'             Category               N
-  'Characters'           Characters             N
-  'CharactersWithSpaces' CharactersWithSpaces   N
-  'Company'              Company                N
-  'Created'              CreateDate             N
-  'Description'          Description            N
-  'Keywords'             Keywords               N
-  'LastAuthor'           LastAuthor             N
-  'LastPrinted'          LastPrinted            N
-  'LastSaved'            ModifyDate             N
-  'Lines'                Lines                  N
-  'Manager'              Manager                N
-  'Pages'                Pages                  N
-  'Paragraphs'           Paragraphs             N
-  'Revision'             RevisionNumber         N
-  'Subject'              Subject                N
-  'Template'             Template               N
-  'TotalTime'            TotalEditTime          N
-  'Version'              RevisionNumber         N
-  'Words'                Words                  N
+  'Author'               Author                 no
+  'Category'             Category               no
+  'Characters'           Characters             no
+  'CharactersWithSpaces' CharactersWithSpaces   no
+  'Company'              Company                no
+  'Created'              CreateDate             no
+  'Description'          Description            no
+  'Keywords'             Keywords               no
+  'LastAuthor'           LastAuthor             no
+  'LastPrinted'          LastPrinted            no
+  'LastSaved'            ModifyDate             no
+  'Lines'                Lines                  no
+  'Manager'              Manager                no
+  'Pages'                Pages                  no
+  'Paragraphs'           Paragraphs             no
+  'Revision'             RevisionNumber         no
+  'Subject'              Subject                no
+  'Template'             Template               no
+  'TotalTime'            TotalEditTime          no
+  'Version'              RevisionNumber         no
+  'Words'                Words                  no
 
 =head3 HTML prod Tags
@@ -20076,6 +33927,6 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'recengineer'        RecEngineer              N
-  'reclocation'        RecLocation              N
+  'recengineer'        RecEngineer              no
+  'reclocation'        RecLocation              no
 
 =head3 HTML vw96 Tags
@@ -20083,5 +33934,141 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'objecttype'         ObjectType               N
+  'objecttype'         ObjectType               no
+
+=head2 Palm Tags
+
+Information extracted from Palm database files (PDB and PRC extensions),
+Mobipocket electronic books (MOBI), and Amazon Kindle KF7 and KF8 books (AZW
+and AZW3).
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    DatabaseName                         no
+      9    CreateDate                           no
+     10    ModifyDate                           no
+     11    LastBackupDate                       no
+     12    ModificationNumber                   no
+     15    PalmFileType                         no
+
+=head3 Palm MOBI Tags
+
+Information extracted from the MOBI header of Mobipocket and Amazon Kindle
+KF7 and KF8 files.
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      0    Compression                          no
+      1    UncompressedTextLength               no
+      3    Encryption                           no
+      6    MobiType                             no
+      7    CodePage                             no
+      9    MobiVersion                          no
+     21    BookName                             no
+     26    MinimumVersion                       no
+
+=head3 Palm EXTH Tags
+
+Information extracted from the MOBI extended header.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0001   DRMServerID                          no
+  0x0002   DRMCommerceID                        no
+  0x0003   DRM_E-BookBaseID                     no
+  0x0064   Author                               no
+  0x0065   Publisher                            no
+  0x0066   Imprint                              no
+  0x0067   Description                          no
+  0x0068   ISBN                                 no
+  0x0069   Subject                              no+
+  0x006a   PublishDate                          no
+  0x006b   Review                               no
+  0x006c   Contributor                          no
+  0x006d   Rights                               no
+  0x006e   SubjectCode                          no
+  0x006f   BookType                             no
+  0x0070   Source                               no
+  0x0071   ASIN                                 no
+  0x0072   BookVersion                          no
+  0x0073   SampleFlag                           no
+  0x0074   StartReading                         no
+  0x0075   Adult                                no
+  0x0076   RetailPrice                          no
+  0x0077   RetailPriceCurrency                  no
+  0x007d   ResourceCount                        no
+  0x0081   KF8CoverURI                          no
+  0x00c8   DictionaryShortName                  no
+  0x00cc   CreatorSoftware                      no
+  0x00cd   CreatorMajorVersion                  no
+  0x00ce   CreatorMinorVersion                  no
+  0x00cf   CreatorBuildNumber                   no
+  0x00d0   Watermark                            no
+  0x00d1   Tamper-proofKeys                     no
+  0x0191   ClippingLimit                        no
+  0x0192   PublisherLimit                       no
+  0x0194   TextToSpeech                         no
+  0x0195   RentalFlag                           no
+  0x0196   RentalExpirationDate                 no
+  0x01f5   CDEType                              no
+  0x01f6   LastUpdateTime                       no
+  0x01f7   UpdatedTitle                         no
+  0x01f8   ASIN2                                no
+  0x020c   Language                             no
+  0x020d   Alignment                            no
+  0x0217   CreatorBuildNumber2                  no
+
+=head2 Torrent Tags
+
+Below are tags commonly found in BitTorrent files.  As well as these tags,
+any other existing tags will be extracted.  For convenience, list items are
+expanded into individual tags with an index in the tag name, but only the
+tags with index "1" are listed in the tables below.  See
+L<https://wiki.theory.org/BitTorrentSpecification> for the BitTorrent
+specification.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'announce'           Announce                 no
+  'announce-list'      AnnounceList1            no
+  'comment'            Comment                  no
+  'created by'         Creator                  no
+  'creation date'      CreateDate               no
+  'encoding'           Encoding                 no
+  'info'               Info                     Torrent Info
+  'url-list'           URLList1                 no
+
+=head3 Torrent Info Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'file-duration'      File1Duration            no
+  'file-media'         File1Media               no
+  'files'              Files                    Torrent Files
+  'length'             Length                   no
+  'md5sum'             MD5Sum                   no
+  'name'               Name                     no
+  'name.utf-8'         NameUTF-8                no
+  'piece length'       PieceLength              no
+  'pieces'             Pieces                   no
+  'private'            Private                  no
+  'profiles'           Profiles                 Torrent Profiles
+
+=head3 Torrent Files Tags
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'length'             File1Length              no
+  'md5sum'             File1MD5Sum              no
+  'path'               File1Path                no
+  'path.utf-8'         File1PathUTF-8           no
+
+=head3 Torrent Profiles Tags
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  'acodec' Profile1AudioCodec                   no
+  'height' Profile1Height                       no
+  'vcodec' Profile1VideoCodec                   no
+  'width'  Profile1Width                        no
 
 =head2 EXE Tags
@@ -20092,18 +34079,19 @@
 DLL libraries.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    MachineType                          N
-      2    TimeStamp                            N
-     10    PEType                               N
-     11    LinkerVersion                        N
-     12    CodeSize                             N
-     14    InitializedDataSize                  N
-     16    UninitializedDataSize                N
-     18    EntryPoint                           N
-     30    OSVersion                            N
-     32    ImageVersion                         N
-     34    SubsystemVersion                     N
-     44    Subsystem                            N
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      0    MachineType                          no
+      2    TimeStamp                            no
+      9    ImageFileCharacteristics             no
+     10    PEType                               no
+     11    LinkerVersion                        no
+     12    CodeSize                             no
+     14    InitializedDataSize                  no
+     16    UninitializedDataSize                no
+     18    EntryPoint                           no
+     30    OSVersion                            no
+     32    ImageVersion                         no
+     34    SubsystemVersion                     no
+     44    Subsystem                            no
 
 =head3 EXE PEVersion Tags
@@ -20112,13 +34100,13 @@
 files.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    FileVersionNumber                    N
-      4    ProductVersionNumber                 N
-      6    FileFlagsMask                        N
-      7    FileFlags                            N
-      8    FileOS                               N
-      9    ObjectFileType                       N
-     10    FileSubtype                          N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      2    FileVersionNumber                    no
+      4    ProductVersionNumber                 no
+      6    FileFlagsMask                        no
+      7    FileFlags                            no
+      8    FileOS                               no
+      9    ObjectFileType                       no
+     10    FileSubtype                          no
 
 =head3 EXE PEString Tags
@@ -20130,21 +34118,21 @@
   Tag Name                                      Writable
   --------                                      --------
-  BuildDate                                     N
-  BuildVersion                                  N
-  CharacterSet                                  N
-  Comments                                      N
-  CompanyName                                   N
-  Copyright                                     N
-  FileDescription                               N
-  FileVersion                                   N
-  InternalName                                  N
-  LanguageCode                                  N
-  LegalCopyright                                N
-  LegalTrademarks                               N
-  OriginalFilename                              N
-  PrivateBuild                                  N
-  ProductName                                   N
-  ProductVersion                                N
-  SpecialBuild                                  N
+  BuildDate                                     no
+  BuildVersion                                  no
+  CharacterSet                                  no
+  Comments                                      no
+  CompanyName                                   no
+  Copyright                                     no
+  FileDescription                               no
+  FileVersion                                   no
+  InternalName                                  no
+  LanguageCode                                  no
+  LegalCopyright                                no
+  LegalTrademarks                               no
+  OriginalFileName                              no
+  PrivateBuild                                  no
+  ProductName                                   no
+  ProductVersion                                no
+  SpecialBuild                                  no
 
 =head3 EXE MachO Tags
@@ -20155,10 +34143,11 @@
    Index   Tag Name                             Writable
    -----   --------                             --------
-      0    CPUArchitecture                      N
-      1    CPUByteOrder                         N
-      2    CPUCount                             N
-      3    CPUType                              N+
-      4    CPUSubtype                           N+
-      5    ObjectFileType                       N
+      0    CPUArchitecture                      no
+      1    CPUByteOrder                         no
+      2    CPUCount                             no
+      3    CPUType                              no+
+      4    CPUSubtype                           no+
+      5    ObjectFileType                       no
+      6    ObjectFlags                          no
 
 =head3 EXE PEF Tags
@@ -20167,9 +34156,9 @@
 libraries.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    CPUArchitecture                      N
-      3    PEFVersion                           N
-      4    TimeStamp                            N
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      2    CPUArchitecture                      no
+      3    PEFVersion                           no
+      4    TimeStamp                            no
 
 =head3 EXE ELF Tags
@@ -20177,10 +34166,27 @@
 Information extracted from ELF (Unix) executable files and SO libraries.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      4    CPUArchitecture                      N
-      5    CPUByteOrder                         N
-     16    ObjectFileType                       N
-     18    CPUType                              N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      4    CPUArchitecture                      no
+      5    CPUByteOrder                         no
+     16    ObjectFileType                       no
+     18    CPUType                              no
+
+=head3 EXE AR Tags
+
+Information extracted from static libraries.
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     16    CreateDate                           no
+
+=head3 EXE CHM Tags
+
+Tags extracted from Microsoft Compiled HTML files.
+
+  Index4   Tag Name                             Writable
+  ------   --------                             --------
+      1    CHMVersion                           no
+      5    LanguageCode                         no
 
 =head2 LNK Tags
@@ -20188,22 +34194,22 @@
 Information extracted from MS Shell Link (Windows shortcut) files.
 
-   Index       Tag Name                         Writable
-   -----       --------                         --------
-         20    Flags                            N
-         24    FileAttributes                   N
-         28    CreateDate                       N
-         36    AccessDate                       N
-         44    ModifyDate                       N
-         52    TargetFileSize                   N
-         56    IconIndex                        N
-         60    RunWindow                        N
-         64    HotKey                           N
-  0x00010000   ItemID                           LNK ItemID
-  0x00020000   LinkInfo                         LNK LinkInfo
-  0x00030004   Description                      N
-  0x00030008   RelativePath                     N
-  0x00030010   WorkingDirectory                 N
-  0x00030020   CommandLineArguments             N
-  0x00030040   IconFileName                     N
+  Index1       Tag Name                         Writable
+  ------       --------                         --------
+  0x0014       Flags                            no
+  0x0018       FileAttributes                   no
+  0x001c       CreateDate                       no
+  0x0024       AccessDate                       no
+  0x002c       ModifyDate                       no
+  0x0034       TargetFileSize                   no
+  0x0038       IconIndex                        no
+  0x003c       RunWindow                        no
+  0x0040       HotKey                           no
+  0x10000      ItemID                           LNK ItemID
+  0x20000      LinkInfo                         LNK LinkInfo
+  0x30004      Description                      no
+  0x30008      RelativePath                     no
+  0x30010      WorkingDirectory                 no
+  0x30020      CommandLineArguments             no
+  0x30040      IconFileName                     no
   0xa0000000   UnknownData                      LNK UnknownData
   0xa0000001   EnvVarData                       LNK UnknownData
@@ -20227,7 +34233,7 @@
 =head3 LNK Item0032 Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     14    TargetFileDOSName                    N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     14    TargetFileDOSName                    no
 
 =head3 LNK LinkInfo Tags
@@ -20235,54 +34241,54 @@
   Tag Name                                      Writable
   --------                                      --------
-  CommonNetworkRelLink                          N
-  CommonPathSuffix                              N
-  DeviceName                                    N
-  DriveSerialNumber                             N
-  DriveType                                     N
-  LocalBasePath                                 N
-  NetName                                       N
-  NetProviderType                               N
-  VolumeID                                      N
-  VolumeLabel                                   N
+  CommonNetworkRelLink                          no
+  CommonPathSuffix                              no
+  DeviceName                                    no
+  DriveSerialNumber                             no
+  DriveType                                     no
+  LocalBasePath                                 no
+  NetName                                       no
+  NetProviderType                               no
+  VolumeID                                      no
+  VolumeLabel                                   no
 
 =head3 LNK UnknownData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
   [no tags known]
 
 =head3 LNK ConsoleData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      8    FillAttributes                       N
-     10    PopupFillAttributes                  N
-     12    ScreenBufferSize                     N
-     16    WindowSize                           N
-     20    WindowOrigin                         N
-     32    FontSize                             N
-     36    FontFamily                           N
-     40    FontWeight                           N
-     44    FontName                             N
-    108    CursorSize                           N
-    112    FullScreen                           N
-    116    QuickEdit                            N
-    120    InsertMode                           N
-    124    WindowOriginAuto                     N
-    128    HistoryBufferSize                    N
-    132    NumHistoryBuffers                    N
-    136    RemoveHistoryDuplicates              N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    FillAttributes                       no
+     10    PopupFillAttributes                  no
+     12    ScreenBufferSize                     no
+     16    WindowSize                           no
+     20    WindowOrigin                         no
+     32    FontSize                             no
+     36    FontFamily                           no
+     40    FontWeight                           no
+     44    FontName                             no
+    108    CursorSize                           no
+    112    FullScreen                           no
+    116    QuickEdit                            no
+    120    InsertMode                           no
+    124    WindowOriginAuto                     no
+    128    HistoryBufferSize                    no
+    132    NumHistoryBuffers                    no
+    136    RemoveHistoryDuplicates              no
 
 =head3 LNK TrackerData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-     16    MachineID                            N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+     16    MachineID                            no
 
 =head3 LNK ConsoleFEData Tags
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      8    CodePage                             N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    CodePage                             no
 
 =head2 Font Tags
@@ -20297,8 +34303,8 @@
   'PFM'        PFMHeader                        Font PFM
   'PSInfo'     PSFontInfo                       Font PSInfo
-  'fontname'   FontName                         N
+  'fontname'   FontName                         no
   'name'       Name                             Font Name
-  'numfonts'   NumFonts                         N
-  'postfont'   PostScriptFontName               N
+  'numfonts'   NumFonts                         no
+  'postfont'   PostScriptFontName               no
 
 =head3 Font AFM Tags
@@ -20308,22 +34314,22 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Ascender'           Ascender                 N
-  'CapHeight'          CapHeight                N
-  'CharacterSet'       CharacterSet             N
-  'Characters'         Characters               N
-  'Creation Date'      CreateDate               N
-  'Descender'          Descender                N
-  'EncodingScheme'     EncodingScheme           N
-  'EscChar'            EscChar                  N
-  'FamilyName'         FontFamily               N
-  'FontName'           FontName                 N
-  'FullName'           FullName                 N
-  'IsBaseFont'         IsBaseFont               N
-  'IsFixedV'           IsFixedV                 N
-  'MappingScheme'      MappingScheme            N
-  'Notice'             Notice                   N
-  'Version'            Version                  N
-  'Weight'             Weight                   N
-  'XHeight'            XHeight                  N
+  'Ascender'           Ascender                 no
+  'CapHeight'          CapHeight                no
+  'CharacterSet'       CharacterSet             no
+  'Characters'         Characters               no
+  'Creation Date'      CreateDate               no
+  'Descender'          Descender                no
+  'EncodingScheme'     EncodingScheme           no
+  'EscChar'            EscChar                  no
+  'FamilyName'         FontFamily               no
+  'FontName'           FontName                 no
+  'FullName'           FullName                 no
+  'IsBaseFont'         IsBaseFont               no
+  'IsFixedV'           IsFixedV                 no
+  'MappingScheme'      MappingScheme            no
+  'Notice'             Notice                   no
+  'Version'            Version                  no
+  'Weight'             Weight                   no
+  'XHeight'            XHeight                  no
 
 =head3 Font PFM Tags
@@ -20331,30 +34337,30 @@
 Tags extracted from the PFM file header.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    PFMVersion                           N
-      6    Copyright                            N
-     66    FontType                             N
-     68    PointSize                            N
-     70    YResolution                          N
-     72    XResolution                          N
-     74    Ascent                               N
-     76    InternalLeading                      N
-     78    ExternalLeading                      N
-     80    Italic                               N
-     81    Underline                            N
-     82    Strikeout                            N
-     83    Weight                               N
-     85    CharacterSet                         N
-     86    PixWidth                             N
-     88    PixHeight                            N
-     90    PitchAndFamily                       N
-     91    AvgWidth                             N
-     93    MaxWidth                             N
-     95    FirstChar                            N
-     96    LastChar                             N
-     97    DefaultChar                          N
-     98    BreakChar                            N
-     99    WidthBytes                           N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    PFMVersion                           no
+      6    Copyright                            no
+     66    FontType                             no
+     68    PointSize                            no
+     70    YResolution                          no
+     72    XResolution                          no
+     74    Ascent                               no
+     76    InternalLeading                      no
+     78    ExternalLeading                      no
+     80    Italic                               no
+     81    Underline                            no
+     82    Strikeout                            no
+     83    Weight                               no
+     85    CharacterSet                         no
+     86    PixWidth                             no
+     88    PixHeight                            no
+     90    PitchAndFamily                       no
+     91    AvgWidth                             no
+     93    MaxWidth                             no
+     95    FirstChar                            no
+     96    LastChar                             no
+     97    DefaultChar                          no
+     98    BreakChar                            no
+     99    WidthBytes                           no
 
 =head3 Font PSInfo Tags
@@ -20364,17 +34370,17 @@
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'Copyright'          Copyright                N
-  'FSType'             FSType                   N
-  'FamilyName'         FontFamily               N
-  'FontName'           FontName                 N
-  'FontType'           FontType                 N
-  'FullName'           FullName                 N
-  'ItalicAngle'        ItalicAngle              N
-  'Notice'             Notice                   N
-  'UnderlinePosition'  UnderlinePosition        N
-  'UnderlineThickness' UnderlineThickness       N
-  'Weight'             Weight                   N
-  'isFixedPitch'       IsFixedPitch             N
-  'version'            Version                  N
+  'Copyright'          Copyright                no
+  'FSType'             FSType                   no
+  'FamilyName'         FontFamily               no
+  'FontName'           FontName                 no
+  'FontType'           FontType                 no
+  'FullName'           FullName                 no
+  'ItalicAngle'        ItalicAngle              no
+  'Notice'             Notice                   no
+  'UnderlinePosition'  UnderlinePosition        no
+  'UnderlineThickness' UnderlineThickness       no
+  'Weight'             Weight                   no
+  'isFixedPitch'       IsFixedPitch             no
+  'version'            Version                  no
 
 =head3 Font Name Tags
@@ -20382,51 +34388,204 @@
 The following tags are extracted from the TrueType font "name" table found
 in OTF, TTF, TTC and DFONT files.  These tags support localized languages by
-adding a hyphen followed by a language code to the end of the tag name (ie.
-"Copyright-fr" or "Licence-en-US").  Tags with no language code use the
+adding a hyphen followed by a language code to the end of the tag name (eg.
+"Copyright-fr" or "License-en-US").  Tags with no language code use the
 default language of "en".
 
   Tag ID   Tag Name                             Writable
   ------   --------                             --------
-  0x0000   Copyright                            N
-  0x0001   FontFamily                           N
-  0x0002   FontSubfamily                        N
-  0x0003   FontSubfamilyID                      N
-  0x0004   FontName                             N
-  0x0005   NameTableVersion                     N
-  0x0006   PostScriptFontName                   N
-  0x0007   Trademark                            N
-  0x0008   Manufacturer                         N
-  0x0009   Designer                             N
-  0x000a   Description                          N
-  0x000b   VendorURL                            N
-  0x000c   DesignerURL                          N
-  0x000d   License                              N
-  0x000e   LicenseInfoURL                       N
-  0x0010   PreferredFamily                      N
-  0x0011   PreferredSubfamily                   N
-  0x0012   CompatibleFontName                   N
-  0x0013   SampleText                           N
-  0x0014   PostScriptFontName                   N
-  0x0015   WWSFamilyName                        N
-  0x0016   WWSSubfamilyName                     N
+  0x0000   Copyright                            no
+  0x0001   FontFamily                           no
+  0x0002   FontSubfamily                        no
+  0x0003   FontSubfamilyID                      no
+  0x0004   FontName                             no
+  0x0005   NameTableVersion                     no
+  0x0006   PostScriptFontName                   no
+  0x0007   Trademark                            no
+  0x0008   Manufacturer                         no
+  0x0009   Designer                             no
+  0x000a   Description                          no
+  0x000b   VendorURL                            no
+  0x000c   DesignerURL                          no
+  0x000d   License                              no
+  0x000e   LicenseInfoURL                       no
+  0x0010   PreferredFamily                      no
+  0x0011   PreferredSubfamily                   no
+  0x0012   CompatibleFontName                   no
+  0x0013   SampleText                           no
+  0x0014   PostScriptFontName                   no
+  0x0015   WWSFamilyName                        no
+  0x0016   WWSSubfamilyName                     no
+
+=head2 VCard Tags
+
+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.
+
+  Tag ID               Tag Name                 Writable
+  ------               --------                 --------
+  'Adr'                Address                  no
+  'Anniversary'        Anniversary              no
+  'Bday'               Birthday                 no
+  'Email'              Email                    no
+  'Fn'                 FormattedName            no
+  'Gender'             Gender                   no
+  'Geo'                Geolocation              no
+  'Impp'               IMPP                     no
+  'Lang'               Language                 no
+  'Logo'               Logo                     no
+  'N'                  Name                     no
+  'Nickname'           Nickname                 no
+  'Note'               Note                     no
+  'Org'                Organization             no
+  'Photo'              Photo                    no
+  'Prodid'             Software                 no
+  'Rev'                Revision                 no
+  'Sound'              Sound                    no
+  'Tel'                Telephone                no
+  'Title'              JobTitle                 no
+  'Tz'                 TimeZone                 no
+  'Uid'                UID                      no
+  'Url'                URL                      no
+  'Version'            VCardVersion             no
+  'X-abdate'           ABDate                   no
+  'X-ablabel'          ABLabel                  no
+  'X-abrelatednames'   ABRelatedNames           no
+  'X-abuid'            AB_UID                   no
+  'X-aim'              AIM                      no
+  'X-icq'              ICQ                      no
+  'X-socialprofile'    SocialProfile            no
+
+=head3 VCard VCalendar Tags
+
+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.
+
+  Tag ID                Tag Name                Writable
+  ------                --------                --------
+  'Acknowledged'        Acknowledged            no
+  'Action'              Action                  no
+  'Attach'              Attachment              no
+  'Attendee'            Attendee                no
+  'Calscale'            CalendarScale           no
+  'Categories'          Categories              no
+  'Class'               Classification          no
+  'Comment'             Comment                 no
+  'Completed'           DateTimeCompleted       no
+  'Contact'             Contact                 no
+  'Created'             DateCreated             no
+  'Description'         Description             no
+  'Dtend'               DateTimeEnd             no
+  'Dtstamp'             DateTimeStamp           no
+  'Dtstart'             DateTimeStart           no
+  'Due'                 DateTimeDue             no
+  'Duration'            Duration                no
+  'Exdate'              ExceptionDateTimes      no
+  'Freebusy'            FreeBusyTime            no
+  'Geo'                 Geolocation             no
+  'Last-modified'       ModifyDate              no
+  'Location'            Location                no
+  'Method'              Method                  no
+  'Organizer'           Organizer               no
+  'Percent-complete'    PercentComplete         no
+  'Priority'            Priority                no
+  'Prodid'              Software                no
+  'Rdate'               RecurrenceDateTimes     no
+  'Recurrence-id'       RecurrenceID            no
+  'Related-to'          RelatedTo               no
+  'Repeat'              Repeat                  no
+  'Request-status'      RequestStatus           no
+  'Resources'           Resources               no
+  'Rrule'               RecurrenceRule          no
+  'Sequence'            SequenceNumber          no
+  'Status'              Status                  no
+  'Summary'             Summary                 no
+  'Transp'              TimeTransparency        no
+  'Trigger'             Trigger                 no
+  'Tzid'                TimezoneID              no
+  'Tzname'              TimezoneName            no
+  'Tzoffsetfrom'        TimezoneOffsetFrom      no
+  'Tzoffsetto'          TimezoneOffsetTo        no
+  'Tzurl'               TimeZoneURL             no
+  'Uid'                 UID                     no
+  'Url'                 URL                     no
+  'Version'             VCalendarVersion        no
+  'X-apple-calendar-color' CalendarColor        no
+  'X-apple-default-alarm' DefaultAlarm          no
+  'X-apple-local-default-alarm'
+                        LocalDefaultAlarm       no
+  'X-microsoft-cdo-alldayevent' AllDayEvent     no
+  'X-microsoft-cdo-appt-sequence'
+                        AppointmentSequence     no
+  'X-microsoft-cdo-busystatus' BusyStatus       no
+  'X-microsoft-cdo-importance' Importance       no
+  'X-microsoft-cdo-insttype' InstanceType       no
+  'X-microsoft-cdo-intendedstatus'
+                        IntendedBusyStatus      no
+  'X-microsoft-cdo-ownerapptid'
+                        OwnerAppointmentID      no
+  'X-microsoft-disallow-counter'
+                        DisallowCounterProposal no
+  'X-microsoft-donotforwardmeeting'
+                        DoNotForwardMeeting     no
+  'X-microsoft-locations' MeetingLocations      no
+  'X-wr-alarmuid'       AlarmUID                no
+  'X-wr-caldesc'        CalendarDescription     no
+  'X-wr-calname'        CalendarName            no
+  '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
-also be extracted from the resource fork of any file in OS X, either by
-adding "/rsrc" to the filename to process the resource fork alone, or by
-using the ExtractEmbedded (-ee) option to process the resource fork as a
-sub-document of the main file.
+Tags extracted from Mac OS resource files, DFONT files and "._" sidecar
+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 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.
 
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
   '8BIM'               PhotoshopInfo            Photoshop
-  'STR _0xbff3'        ApplicationMissingMsg    N
-  'STR _0xbff4'        CreatorApplication       N
-  'STR#_0x0080'        Keywords                 N
-  'TEXT_0x0080'        Description              N
+  'POST_0x01f5'        PostscriptFont           PostScript
+  'STR _0xbff3'        ApplicationMissingMsg    no
+  'STR _0xbff4'        CreatorApplication       no
+  'STR#_0x0080'        Keywords                 no
+  'TEXT_0x0080'        Description              no
   'sfnt'               Font                     Font Name
-  'usro_0x0000'        OpenWithApplication      N
-  'vers_0x0001'        ApplicationVersion       N
+  'usro_0x0000'        OpenWithApplication      no
+  'vers_0x0001'        ApplicationVersion       no
 
 =head2 Rawzor Tags
@@ -20438,9 +34597,9 @@
   Tag Name                                      Writable
   --------                                      --------
-  CompressionFactor                             N
-  OriginalFileSize                              N
-  OriginalFileType                              N
-  RawzorCreatorVersion                          N
-  RawzorRequiredVersion                         N
+  CompressionFactor                             no
+  OriginalFileSize                              no
+  OriginalFileType                              no
+  RawzorCreatorVersion                          no
+  RawzorRequiredVersion                         no
 
 =head2 ZIP Tags
@@ -20448,19 +34607,21 @@
 The following tags are extracted from ZIP archives.  ExifTool also extracts
 additional meta information from compressed documents inside some ZIP-based
-files such Office Open XML (DOCX, PPTX and XLSX), Open Document (ODP, ODS
-and ODT), iWork (KEY, PAGES, NUMBERS), and Capture One Enhanced Image
-Package (EIP).  The ExifTool family 3 groups may be used to organize the
-output by embedded document number (ie. the exiftool C<-g3> option).
-
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    ZipRequiredVersion                   N
-      3    ZipBitFlag                           N
-      4    ZipCompression                       N
-      5    ZipModifyDate                        N
-      7    ZipCRC                               N
-      9    ZipCompressedSize                    N
-     11    ZipUncompressedSize                  N
-     15    ZipFileName                          N
+files such Office Open XML (DOCX, PPTX and XLSX), Open Document (ODB, ODC,
+ODF, ODG, ODI, ODP, ODS and ODT), iWork (KEY, PAGES, NUMBERS), Capture One
+Enhanced Image Package (EIP), Adobe InDesign Markup Language (IDML),
+Electronic Publication (EPUB), and Sketch design files (SKETCH).  The
+ExifTool family 3 groups may be used to organize ZIP tags by embedded
+document number (ie. the exiftool C<-g3> option).
+
+  Index2   Tag Name                             Writable
+  ------   --------                             --------
+      2    ZipRequiredVersion                   no
+      3    ZipBitFlag                           no
+      4    ZipCompression                       no
+      5    ZipModifyDate                        no
+      7    ZipCRC                               no
+      9    ZipCompressedSize                    no
+     11    ZipUncompressedSize                  no
+     15    ZipFileName                          no
 
 =head3 ZIP GZIP Tags
@@ -20469,13 +34630,13 @@
 for the first file in the archive.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      2    Compression                          N
-      3    Flags                                N
-      4    ModifyDate                           N
-      8    ExtraFlags                           N
-      9    OperatingSystem                      N
-     10    ArchivedFileName                     N
-     11    Comment                              N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      2    Compression                          no
+      3    Flags                                no
+      4    ModifyDate                           no
+      8    ExtraFlags                           no
+      9    OperatingSystem                      no
+     10    ArchivedFileName                     no
+     11    Comment                              no
 
 =head3 ZIP RAR Tags
@@ -20483,12 +34644,12 @@
 These tags are extracted from RAR archive files.
 
-   Index   Tag Name                             Writable
-   -----   --------                             --------
-      0    CompressedSize                       N
-      4    UncompressedSize                     N
-      8    OperatingSystem                      N
-     13    ModifyDate                           N
-     18    PackingMethod                        N
-     25    ArchivedFileName                     N
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      0    CompressedSize                       no
+      4    UncompressedSize                     no
+      8    OperatingSystem                      no
+     13    ModifyDate                           no
+     18    PackingMethod                        no
+     25    ArchivedFileName                     no
 
 =head2 RTF Tags
@@ -20497,33 +34658,33 @@
 will also extract any non-standard tags found in this group.  As well,
 ExifTool will extract any custom properties that are found.  See
-L<http://download.microsoft.com/download/2/f/5/2f599e18-07ee-4ec5-a1e7-f4e6a9423592/Word2007RTFSpec9.doc>
-for the specification.
+L<http://www.microsoft.com/en-ca/download/details.aspx?id=10725> for the
+specification.
 
   Tag ID               Tag Name                 Writable
   ------               --------                 --------
-  'author'             Author                   N
-  'buptim'             BackupTime               N
-  'category'           Category                 N
-  'comment'            Comment                  N
-  'company'            Company                  N
-  'copyright'          Copyright                N
-  'creatim'            CreateDate               N
-  'doccomm'            Comments                 N
-  'edmins'             TotalEditTime            N
-  'hlinkbase'          HyperlinkBase            N
-  'id'                 InternalIDNumber         N
-  'keywords'           Keywords                 N
-  'manager'            Manager                  N
-  'nofchars'           Characters               N
-  'nofcharsws'         CharactersWithSpaces     N
-  'nofpages'           Pages                    N
-  'nofwords'           Words                    N
-  'operator'           LastModifiedBy           N
-  'printim'            LastPrinted              N
-  'revtim'             ModifyDate               N
-  'subject'            Subject                  N
-  'title'              Title                    N
-  'vern'               InternalVersionNumber    N
-  'version'            RevisionNumber           N
+  'author'             Author                   no
+  'buptim'             BackupTime               no
+  'category'           Category                 no
+  'comment'            Comment                  no
+  'company'            Company                  no
+  'copyright'          Copyright                no
+  'creatim'            CreateDate               no
+  'doccomm'            Comments                 no
+  'edmins'             TotalEditTime            no
+  'hlinkbase'          HyperlinkBase            no
+  'id'                 InternalIDNumber         no
+  'keywords'           Keywords                 no
+  'manager'            Manager                  no
+  'nofchars'           Characters               no
+  'nofcharsws'         CharactersWithSpaces     no
+  'nofpages'           Pages                    no
+  'nofwords'           Words                    no
+  'operator'           LastModifiedBy           no
+  'printim'            LastPrinted              no
+  'revtim'             ModifyDate               no
+  'subject'            Subject                  no
+  'title'              Title                    no
+  'vern'               InternalVersionNumber    no
+  'version'            RevisionNumber           no
 
 =head2 OOXML Tags
@@ -20546,63 +34707,63 @@
   Tag Name                                      Writable
   --------                                      --------
-  AppVersion                                    N
-  Application                                   N
-  Characters                                    N
-  CharactersWithSpaces                          N
-  CheckedBy                                     N
-  Client                                        N
-  Company                                       N
-  DateCompleted                                 N
-  Department                                    N
-  Destination                                   N
-  Disposition                                   N
-  Division                                      N
-  DocSecurity                                   N
-  DocumentNumber                                N
-  Editor                                        N
-  ForwardTo                                     N
-  Group                                         N
-  HeadingPairs                                  N
-  HiddenSlides                                  N
-  HyperlinkBase                                 N
-  HyperlinksChanged                             N
-  Language                                      N
-  Lines                                         N
-  LinksUpToDate                                 N
-  MMClips                                       N
-  Mailstop                                      N
-  Manager                                       N
-  Matter                                        N
-  Notes                                         N
-  Office                                        N
-  Owner                                         N
-  Pages                                         N
-  Paragraphs                                    N
-  PresentationFormat                            N
-  Project                                       N
-  Publisher                                     N
-  Purpose                                       N
-  ReceivedFrom                                  N
-  RecordedBy                                    N
-  RecordedDate                                  N
-  Reference                                     N
-  ScaleCrop                                     N
-  SharedDoc                                     N
-  Slides                                        N
-  Source                                        N
-  Status                                        N
-  TelephoneNumber                               N
-  Template                                      N
-  TitlesOfParts                                 N
-  TotalEditTime                                 N
-  Typist                                        N
-  Words                                         N
-  Category                                      N
-  CreateDate                                    N
-  Keywords                                      N
-  LastModifiedBy                                N
-  LastPrinted                                   N
-  ModifyDate                                    N
-  RevisionNumber                                N
+  AppVersion                                    no
+  Application                                   no
+  Category                                      no
+  Characters                                    no
+  CharactersWithSpaces                          no
+  CheckedBy                                     no
+  Client                                        no
+  Company                                       no
+  CreateDate                                    no
+  DateCompleted                                 no
+  Department                                    no
+  Destination                                   no
+  Disposition                                   no
+  Division                                      no
+  DocSecurity                                   no
+  DocumentNumber                                no
+  Editor                                        no
+  ForwardTo                                     no
+  Group                                         no
+  HeadingPairs                                  no
+  HiddenSlides                                  no
+  HyperlinkBase                                 no
+  HyperlinksChanged                             no
+  Keywords                                      no
+  Language                                      no
+  LastModifiedBy                                no
+  LastPrinted                                   no
+  Lines                                         no
+  LinksUpToDate                                 no
+  MMClips                                       no
+  Mailstop                                      no
+  Manager                                       no
+  Matter                                        no
+  ModifyDate                                    no
+  Notes                                         no
+  Office                                        no
+  Owner                                         no
+  Pages                                         no
+  Paragraphs                                    no
+  PresentationFormat                            no
+  Project                                       no
+  Publisher                                     no
+  Purpose                                       no
+  ReceivedFrom                                  no
+  RecordedBy                                    no
+  RecordedDate                                  no
+  Reference                                     no
+  RevisionNumber                                no
+  ScaleCrop                                     no
+  SharedDoc                                     no
+  Slides                                        no
+  Source                                        no
+  Status                                        no
+  TelephoneNumber                               no
+  Template                                      no
+  TitlesOfParts                                 no
+  TotalEditTime                                 no
+  Typist                                        no
+  Words                                         no
 
 =head2 iWork Tags
@@ -20614,55 +34775,325 @@
   Tag Name                                      Writable
   --------                                      --------
-  Author                                        N
-  Comment                                       N
-  Copyright                                     N
-  Keywords                                      N
-  Projects                                      N+
-  Title                                         N
-
-=head2 Extra Tags
-
-The extra tags represent extra information extracted or generated by
-ExifTool that is not directly associated with another tag group.  The three
-writable "pseudo" tags (FileName, Directory and FileModifyDate) may be
-written without the need to rewrite the file since their values are not
-contained within the file data.  These "pseudo" tags belong to the family 1
-"System" group.
+  Author                                        no
+  Comment                                       no
+  Copyright                                     no
+  Keywords                                      no
+  Projects                                      no+
+  Title                                         no
+
+=head2 ISO Tags
+
+Tags extracted from ISO 9660 disk images.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0000   BootRecord                           ISO BootRecord
+  0x0001   PrimaryVolume                        ISO PrimaryVolume
+
+=head3 ISO BootRecord Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      7    BootSystem                           no
+     39    BootIdentifier                       no
+
+=head3 ISO PrimaryVolume Tags
+
+  Index1   Tag Name                             Writable
+  ------   --------                             --------
+      8    System                               no
+     40    VolumeName                           no
+     80    VolumeBlockCount                     no
+    120    VolumeSetDiskCount?                  no
+    124    VolumeSetDiskNumber?                 no
+    128    VolumeBlockSize                      no
+    132    PathTableSize?                       no
+    140    PathTableLocation?                   no
+    174    RootDirectoryCreateDate              no
+    190    VolumeSetName                        no
+    318    Publisher                            no
+    446    DataPreparer                         no
+    574    Software                             no
+    702    CopyrightFileName                    no
+    740    AbstractFileName                     no
+    776    BibligraphicFileName                 no
+    813    VolumeCreateDate                     no
+    830    VolumeModifyDate                     no
+    847    VolumeExpirationDate                 no
+    864    VolumeEffectiveDate                  no
+
+=head2 MacOS Tags
+
+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.  (Except when reading
+MacOS "._" files directly, see below.)
+
+The tables below list some of the tags that may be extracted, but ExifTool
+will extract all available information even for tags not listed.
+
+Tags in these tables are referred to as "pseudo" tags because their
+information is not stored in the file itself.  As such, B<Writable> tags in
+these tables may be changed without having to rewrite the file.
+
+Note that on some filesystems, MacOS creates sidecar files with names that
+begin with "._".  ExifTool will read these files if specified, and extract
+the information listed in the following table without the need for extra
+options, but these files are not writable directly.
+
+  Tag ID   Tag Name                             Writable
+  ------   --------                             --------
+  0x0002   RSRC                                 RSRC
+  0x0009   ATTR                                 MacOS XAttr
+
+=head3 MacOS XAttr Tags
+
+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 XAttrTags API option to 1 or the RequestAll API option to 2 or higher.
+And they extracted by default from MacOS "._" files when reading
+these files directly.
 
   Tag Name                                      Writable
   --------                                      --------
-  CanonVRD                                      Y!
-  Comment                                       Y
-  CurrentIPTCDigest                             N
-  Directory                                     Y!
-  EXIF                                          Y!
-  Error                                         N
-  ExifByteOrder                                 Y
-  ExifToolVersion                               N
-  ExifUnicodeByteOrder                          Y
-  FileModifyDate                                Y!
-  FileName                                      Y!
-  FilePermissions                               N
-  FileSize                                      N
-  FileType                                      N
-  Geosync                                       Y
-  Geotag                                        Y
-  Geotime                                       Y
-  ICC_Profile                                   Y!
-  ID3Size                                       N
-  ImageHeight                                   N
-  ImageWidth                                    N
-  JPEGDigest                                    N
-  MIMEType                                      N
-  MaxVal                                        N
-  Now                                           N
-  PreviewImage                                  Y
-  PreviewPNG                                    N
-  RAFVersion                                    N
-  ResourceForkSize                              N
-  Warning                                       N
-  XMP                                           Y!
-  XResolution                                   N
-  YResolution                                   N
+  XAttrAppleMailDateReceived                    no
+  XAttrAppleMailDateSent                        no
+  XAttrAppleMailIsRemoteAttachment              no
+  XAttrFinderInfo                               no
+  XAttrLastUsedDate                             no
+  XAttrMDItemDownloadedDate                     no
+  XAttrMDItemFinderComment                      no
+  XAttrMDItemWhereFroms                         no
+  XAttrMDLabel                                  no
+  XAttrQuarantine                               yes!
+  XAttrResourceFork                             no
+
+=head3 MacOS MDItem Tags
+
+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.  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
+  AppleMailRepliedTo                            no
+  MDItemAccountHandles                          no
+  MDItemAccountIdentifier                       no
+  MDItemAcquisitionMake                         no
+  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
+  MDItemContentTypeTree                         no
+  MDItemContributors                            no
+  MDItemCopyright                               no
+  MDItemCountry                                 no
+  MDItemCreator                                 no
+  MDItemDateAdded                               no
+  MDItemDateAdded_Ranking                       no
+  MDItemDescription                             no
+  MDItemDisplayName                             no
+  MDItemDownloadedDate                          no
+  MDItemDurationSeconds                         no
+  MDItemEXIFGPSVersion                          no
+  MDItemEXIFVersion                             no
+  MDItemEmailConversationID                     no
+  MDItemEncodingApplications                    no
+  MDItemExposureMode                            no
+  MDItemExposureProgram                         no
+  MDItemExposureTimeSeconds                     no
+  MDItemFNumber                                 no
+  MDItemFSContentChangeDate                     no
+  MDItemFSCreationDate                          yes!
+  MDItemFSCreatorCode                           no
+  MDItemFSFinderFlags                           no
+  MDItemFSHasCustomIcon                         no
+  MDItemFSInvisible                             no
+  MDItemFSIsExtensionHidden                     no
+  MDItemFSIsStationery                          no
+  MDItemFSLabel                                 yes!
+  MDItemFSName                                  no
+  MDItemFSNodeCount                             no
+  MDItemFSOwnerGroupID                          no
+  MDItemFSOwnerUserID                           no
+  MDItemFSSize                                  no
+  MDItemFSTypeCode                              no
+  MDItemFinderComment                           yes!
+  MDItemFlashOnOff                              no
+  MDItemFocalLength                             no
+  MDItemGPSDateStamp                            no
+  MDItemGPSStatus                               no
+  MDItemGPSTrack                                no
+  MDItemHasAlphaChannel                         no
+  MDItemISOSpeed                                no
+  MDItemIdentifier                              no
+  MDItemImageDirection                          no
+  MDItemInterestingDateRanking                  no
+  MDItemInterestingDate_Ranking                 no
+  MDItemIsApplicationManaged                    no
+  MDItemIsExistingThread                        no
+  MDItemIsLikelyJunk                            no
+  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
+  MDItemOriginMessageID                         no
+  MDItemOriginSenderDisplayName                 no
+  MDItemOriginSenderHandle                      no
+  MDItemOriginSubject                           no
+  MDItemPageHeight                              no
+  MDItemPageWidth                               no
+  MDItemPhysicalSize                            no
+  MDItemPixelCount                              no
+  MDItemPixelHeight                             no
+  MDItemPixelWidth                              no
+  MDItemPrimaryRecipientEmailAddresses          no
+  MDItemProfileName                             no
+  MDItemRecipients                              no
+  MDItemRedEyeOnOff                             no
+  MDItemResolutionHeightDPI                     no
+  MDItemResolutionWidthDPI                      no
+  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
+
+=head2 Extra Tags
+
+The extra tags provide extra features or extra information extracted or
+generated by ExifTool that is not directly associated with another tag
+group.  The B<Group> column lists the family 1 group name when reading. 
+Tags with a "-" in this column are write-only.
+
+Tags in the family 1 "System" group are referred to as "pseudo" tags because
+they don't represent real metadata in the file.  Instead, this information
+is stored in the directory structure of the filesystem.  The B<Writable>
+System "pseudo" tags in this table may be written without modifying the file
+itself.  The TestName tag is used for dry-run testing before writing
+FileName.
+
+  Tag Name                   Group              Writable
+  --------                   -----              --------
+  Adobe                      Adobe              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
+  ExifUnicodeByteOrder       -                  yes
+  FileAccessDate             System             no
+  FileAttributes             System             no
+  FileBlockCount             System             no
+  FileBlockSize              System             no
+  FileCreateDate             System             yes!
+  FileDeviceID               System             no
+  FileDeviceNumber           System             no
+  FileGroupID                System             yes!
+  FileHardLinks              System             no
+  FileInodeChangeDate        System             no
+  FileInodeNumber            System             no
+  FileModifyDate             System             yes!
+  FileName                   System             yes!
+  FilePath                   System             no
+  FilePermissions            System             yes!
+  FileSequence               ExifTool           no
+  FileSize                   System             no
+  FileType                   File               no
+  FileTypeExtension          File               no
+  FileUserID                 System             yes!
+  ForceWrite                 -                  yes
+  Geosync                    -                  yes
+  Geotag                     -                  yes
+  Geotime                    -                  yes
+  HardLink                   -                  yes!
+  ICC_Profile                ICC_Profile        yes!
+  ID3Size                    File               no
+  IPTC                       IPTC               yes!
+  ImageHeight                File               no
+  ImageWidth                 File               no
+  JPEGDigest                 File               no
+  JPEGImageLength            File               no
+  JPEGQualityEstimate        File               no
+  MIMEType                   File               no
+  MaxVal                     File               no
+  NewGUID                    ExifTool           no
+  Now                        ExifTool           no
+  OtherImage                 File               no
+  PreviewImage               File               yes
+  PreviewPDF                 File               no
+  PreviewPNG                 File               no
+  PreviewTIFF                File               no
+  PreviewWMF                 File               no
+  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
+  XML                        XML                no
+  XMP                        XMP                yes!
+  XResolution                File               no
+  YResolution                File               no
 
 =head2 Composite Tags
@@ -20670,19 +35101,25 @@
 The values of the composite tags are B<Derived From> the values of other
 tags.  These are convenience tags which are calculated after all other
-information is extracted.
+information is extracted.  Only a few of these tags are writable directly,
+the others are changed by writing the corresponding B<Derived From> tags.
+User-defined Composite tags, also useful for custom-formatting of tag
+values, may created via the ExifTool configuration file.
 
   Tag Name             Derived From             Writable
   --------             ------------             --------
-  Aperture             FNumber                  N
+  AdvancedSceneMode    Model                    no
+                       SceneMode
+                       AdvancedSceneType
+  Aperture             FNumber                  no
                        ApertureValue
-  AudioBitrate         MPEG:MPEGAudioVersion    N
+  AudioBitrate         MPEG:MPEGAudioVersion    no
                        MPEG:SampleRate
                        MPEG:VBRBytes
                        MPEG:VBRFrames
-  AutoFocus            Nikon:PhaseDetectAF      N
+  AutoFocus            Nikon:PhaseDetectAF      no
                        Nikon:ContrastDetectAF
-  AvgBitrate           QuickTime::MovieDataSize N
+  AvgBitrate           QuickTime::MediaDataSize no
                        QuickTime::Duration
-  BlueBalance          WB_RGGBLevels            N
+  BlueBalance          WB_RGGBLevels            no
                        WB_RGBGLevels
                        WB_RBGGLevels
@@ -20691,13 +35128,16 @@
                        WB_GBRGLevels
                        WB_RGBLevels
+                       WB_GRBLevels
                        WB_RBLevels
                        WBBlueLevel
                        WBGreenLevel
-  CFAPattern           CFARepeatPatternDim      N
+  CDDBDiscPlayTime     CDDB1Info                no
+  CDDBDiscTracks       CDDB1Info                no
+  CFAPattern           CFARepeatPatternDim      no
                        CFAPattern2
-  CircleOfConfusion    ScaleFactor35efl         N
-  ConditionalFEC       FlashExposureComp        N
+  CircleOfConfusion    ScaleFactor35efl         no
+  ConditionalFEC       FlashExposureComp        no
                        FlashBits
-  DOF                  FocalLength              N
+  DOF                  FocalLength              no
                        Aperture
                        CircleOfConfusion
@@ -20705,25 +35145,37 @@
                        SubjectDistance
                        ObjectDistance
-  DateCreated          Kodak:YearCreated        N
+                       ApproximateFocusDistance
+                       FocusDistanceLower
+                       FocusDistanceUpper
+  DateCreated          Kodak:YearCreated        no
                        Kodak:MonthDayCreated
-  DateTimeCreated      IPTC:DateCreated         N
+  DateTimeCreated      IPTC:DateCreated         no
                        IPTC:TimeCreated
-  DateTimeOriginal     DateTimeCreated          N
+  DateTimeOriginal     DateTimeCreated          no
                        DateCreated
                        TimeCreated
-  DateTimeOriginal     ID3:RecordingTime        N
+  DateTimeOriginal     ID3:RecordingTime        no
                        ID3:Year
                        ID3:Date
                        ID3:Time
-  DigitalCreationDateTime IPTC:DigitalCreationDate N
+  DepthMapTiff         DepthMapData             no
+                       DepthMapWidth
+                       DepthMapHeight
+  DigitalCreationDateTime IPTC:DigitalCreationDate no
                        IPTC:DigitalCreationTime
-  DigitalZoom          Canon:ZoomSourceWidth    N
+  DigitalZoom          Canon:ZoomSourceWidth    no
                        Canon:ZoomTargetWidth
                        Canon:DigitalZoom
-  DriveMode            ContinuousDrive          N
+  DriveMode            ContinuousDrive          no
                        SelfTimer
-  Duration             FLAC:SampleRate          N
+  Duration             AIFF:SampleRate          no
+                       AIFF:NumSampleFrames
+  Duration             APE:SampleRate           no
+                       APE:TotalFrames
+                       APE:BlocksPerFrame
+                       APE:FinalFrameBlocks
+  Duration             FLAC:SampleRate          no
                        FLAC:TotalSamples
-  Duration             FileSize                 N
+  Duration             FileSize                 no
                        ID3Size
                        MPEG:AudioBitrate
@@ -20732,74 +35184,115 @@
                        MPEG:SampleRate
                        MPEG:MPEGAudioVersion
-  Duration             RIFF:FrameRate           N
+  Duration             RIFF:FrameRate           no
                        RIFF:FrameCount
                        VideoFrameRate
                        VideoFrameCount
-  Duration             RIFF:AvgBytesPerSec      N
+  Duration             RIFF:AvgBytesPerSec      no
                        FileSize
                        FrameCount
                        VideoFrameCount
-  ExtenderStatus       Olympus:Extender         N
+  Duration             Vorbis:NominalBitrate    no
+                       FileSize
+  ExtenderStatus       Olympus:Extender         no
                        Olympus:LensType
                        MaxApertureValue
-  FOV                  FocalLength              N
+  FOV                  FocalLength              no
                        ScaleFactor35efl
                        FocusDistance
-  FileNumber           DirectoryIndex           Y
+  FileNumber           DirectoryIndex           yes
                        FileIndex
-  FlashType            FlashBits                N
-  FocalLength35efl     FocalLength              N
+  Flash                XMP:FlashFired           yes
+                       XMP:FlashReturn
+                       XMP:FlashMode
+                       XMP:FlashFunction
+                       XMP:FlashRedEyeMode
+                       XMP:Flash
+  FlashType            FlashBits                no
+  FocalLength35efl     FocalLength              no
                        ScaleFactor35efl
-  GPSAltitude          QuickTime:GPSCoordinates N
-  GPSAltitudeRef       QuickTime:GPSCoordinates N
-  GPSAltitude          GPS:GPSAltitude          N
+  FocusDistance        Sony:FocusPosition       no
+                       FocalLength
+  FocusDistance2       Sony:FocusPosition2      no
+                       FocalLengthIn35mmFormat
+  GPSAltitude          GPS:GPSAltitude          no
                        GPS:GPSAltitudeRef
                        XMP:GPSAltitude
                        XMP:GPSAltitudeRef
-  GPSDateTime          GPS:GPSDateStamp         N
+  GPSAltitude          QuickTime:GPSCoordinates no
+  GPSAltitude          QuickTime:LocationInformation no
+  GPSAltitudeRef       QuickTime:GPSCoordinates no
+  GPSAltitudeRef       QuickTime:LocationInformation no
+  GPSDateTime          GPS:GPSDateStamp         no
                        GPS:GPSTimeStamp
-  GPSLatitude          QuickTime:GPSCoordinates N
-  GPSLatitudeRef       XMP:GPSLatitude          N
-  GPSLatitude          GPS:GPSLatitude          N
+  GPSDateTime          Parrot:GPSLatitude       no
+                       Main:CreateDate
+                       SampleTime
+  GPSDateTime          Sony:GPSDateStamp        no
+                       Sony:GPSTimeStamp
+  GPSDestLatitude      GPS:GPSDestLatitude      no
+                       GPS:GPSDestLatitudeRef
+  GPSDestLatitudeRef   XMP-exif:GPSDestLatitude no
+  GPSDestLongitude     GPS:GPSDestLongitude     no
+                       GPS:GPSDestLongitudeRef
+  GPSDestLongitudeRef  XMP-exif:GPSDestLongitude no
+  GPSLatitude          GPS:GPSLatitude          no
                        GPS:GPSLatitudeRef
-  GPSLongitude         QuickTime:GPSCoordinates N
-  GPSLongitudeRef      XMP:GPSLongitude         N
-  GPSLongitude         GPS:GPSLongitude         N
+  GPSLatitude          QuickTime:GPSCoordinates no
+  GPSLatitude          QuickTime:LocationInformation no
+  GPSLatitudeRef       XMP-exif:GPSLatitude     no
+  GPSLongitude         GPS:GPSLongitude         no
                        GPS:GPSLongitudeRef
-  GPSPosition          GPSLatitude              N
+  GPSLongitude         QuickTime:GPSCoordinates no
+  GPSLongitude         QuickTime:LocationInformation no
+  GPSLongitudeRef      XMP-exif:GPSLongitude    no
+  GPSPosition          GPSLatitude              no
                        GPSLongitude
-  HyperfocalDistance   FocalLength              N
+  HyperfocalDistance   FocalLength              no
                        Aperture
                        CircleOfConfusion
-  IDCPreviewImage      IDCPreviewStart          N
+  IDCPreviewImage      IDCPreviewStart          no
                        IDCPreviewLength
-  ISO                  Canon:CameraISO          N
+  ISO                  Canon:CameraISO          no
                        Canon:BaseISO
                        Canon:AutoISO
-  ImageHeight          Main:PostScript:ImageData N
+  ImageHeight          IFD0:SensorTopBorder     no
+                       IFD0:SensorBottomBorder
+  ImageHeight          Main:PostScript:ImageData no
                        PostScript:BoundingBox
-  ImageSize            ImageWidth               N
+  ImageSize            ImageWidth               no
                        ImageHeight
                        ExifImageWidth
                        ExifImageHeight
-  ImageWidth           Main:PostScript:ImageData N
+                       RawImageCroppedSize
+  ImageWidth           IFD0:SensorLeftBorder    no
+                       IFD0:SensorRightBorder
+  ImageWidth           Main:PostScript:ImageData no
                        PostScript:BoundingBox
-  JpgFromRaw           JpgFromRawStart          Y
+  JpgFromRaw           JpgFromRawStart          yes
                        JpgFromRawLength
-  Lens                 ShortFocal               N
-                       LongFocal
-  Lens35efl            ShortFocal               N
-                       LongFocal
+  Lens                 Canon:MinFocalLength     no
+                       Canon:MaxFocalLength
+  Lens35efl            Canon:MinFocalLength     no
+                       Canon:MaxFocalLength
                        Lens
                        ScaleFactor35efl
-  LensID               LensType                 N
+  LensID               LensType                 no
                        FocalLength
                        MaxAperture
                        MaxApertureValue
-                       ShortFocal
-                       LongFocal
+                       MinFocalLength
+                       MaxFocalLength
                        LensModel
                        LensFocalRange
-  LensID               Nikon:LensIDNumber       N
+                       LensSpec
+                       LensType2
+                       LensType3
+                       LensFocalLength
+                       RFLensType
+  LensID               LensModel                no
+                       Lens
+                       XMP-aux:LensID
+                       Make
+  LensID               Nikon:LensIDNumber       no
                        LensFStops
                        MinFocalLength
@@ -20809,25 +35302,35 @@
                        MCUVersion
                        Nikon:LensType
-  LensID               Ricoh:LensFirmware       N
-  LensSpec             Nikon:Lens               N
+  LensID               Ricoh:LensFirmware       no
+  LensID               XMP-aux:LensID           no
+                       Make
+                       LensInfo
+                       FocalLength
+                       LensModel
+                       MaxApertureValue
+  LensSpec             Nikon:Lens               no
                        Nikon:LensType
-  LightValue           Aperture                 N
+  LensType             LensTypeMake             no
+                       LensTypeModel
+  LightValue           Aperture                 no
                        ShutterSpeed
                        ISO
-  MPImage              MPImageStart             N
+  MPImage              MPImageStart             no
                        MPImageLength
                        MPImageType
-  OriginalDecisionData OriginalDecisionDataOffset Y!
-  OtherImage           OtherImageStart          N
+  Megapixels           ImageSize                no
+  OriginalDecisionData OriginalDecisionDataOffset yes!
+  OtherImage           OtherImageStart          yes
                        OtherImageLength
-  PreviewImage         PreviewImageStart        Y
+  PeakSpectralSensitivity FLIR:PlanckB          no
+  PreviewImage         PreviewImageStart        yes
                        PreviewImageLength
                        PreviewImageValid
                        PreviewImageStart (1)
                        PreviewImageLength (1)
-  PreviewImageSize     PreviewImageWidth        N
+  PreviewImage         ScreenNail               no
+  PreviewImageSize     PreviewImageWidth        no
                        PreviewImageHeight
-  PreviewImage         ScreenNail               N
-  RedBalance           WB_RGGBLevels            N
+  RedBalance           WB_RGGBLevels            no
                        WB_RGBGLevels
                        WB_RBGGLevels
@@ -20836,15 +35339,21 @@
                        WB_GBRGLevels
                        WB_RGBLevels
+                       WB_GRBLevels
                        WB_RBLevels
                        WBRedLevel
                        WBGreenLevel
-  RedEyeReduction      CanonFlashMode           N
+  RedEyeReduction      CanonFlashMode           no
                        FlashBits
-  Rotation             QuickTime:MatrixStructure N
+  RicohPitch           Ricoh:Accelerometer      no
+  RicohRoll            Ricoh:Accelerometer      no
+  Rotation             QuickTime:MatrixStructure yes!
                        QuickTime:HandlerType
-  ScaleFactor35efl     FocalLength              N
+  RunTimeSincePowerUp  Apple:RunTimeValue       no
+                       Apple:RunTimeScale
+  ScaleFactor35efl     FocalLength              no
                        FocalLengthIn35mmFormat
                        Composite:DigitalZoom
                        FocalPlaneDiagonal
+                       SensorSize
                        FocalPlaneXSize
                        FocalPlaneYSize
@@ -20858,21 +35367,41 @@
                        ImageWidth
                        ImageHeight
-  ShootingMode         CanonExposureMode        N
+  ShootingMode         CanonExposureMode        no
                        EasyMode
                        BulbDuration
-  ShutterCurtainHack   FlashBits                N
+  ShutterCurtainHack   FlashBits                no
                        ShutterCurtainSync
-  ShutterSpeed         ExposureTime             N
+  ShutterSpeed         ExposureTime             no
                        ShutterSpeedValue
                        BulbDuration
-  SubSecCreateDate     EXIF:CreateDate          N
+  SingleShotDepthMapTiff SingleShotDepthMap     no
+                       SegWidth
+                       SegHeight
+  SubSecCreateDate     EXIF:CreateDate          yes
                        SubSecTimeDigitized
-  SubSecDateTimeOriginal EXIF:DateTimeOriginal  N
+                       OffsetTimeDigitized
+  SubSecDateTimeOriginal EXIF:DateTimeOriginal  yes
                        SubSecTimeOriginal
-  SubSecModifyDate     EXIF:ModifyDate          N
+                       OffsetTimeOriginal
+  SubSecModifyDate     EXIF:ModifyDate          yes
                        SubSecTime
-  ThumbnailImage       ThumbnailOffset          Y
+                       OffsetTime
+  ThumbnailImage       ThumbnailOffset          yes
                        ThumbnailLength
-  WB_RGBLevels         KDC_IFD:WhiteBalance     N
+  ThumbnailTIFF        SubfileType              no
+                       Compression
+                       ImageWidth
+                       ImageHeight
+                       BitsPerSample
+                       PhotometricInterpretation
+                       StripOffsets
+                       SamplesPerPixel
+                       RowsPerStrip
+                       StripByteCounts
+                       PlanarConfiguration
+                       Orientation
+  VolumeSize           ISO:VolumeBlockCount     no
+                       ISO:VolumeBlockSize
+  WB_RGBLevels         KDC_IFD:WhiteBalance     no
                        WB_RGBLevelsAuto
                        WB_RGBLevelsFluorescent
@@ -20882,5 +35411,5 @@
                        WB_RGBLevels5
                        WB_RGBLevelsShade
-  WB_RGBLevels         KodakIFD:WhiteBalance    N
+  WB_RGBLevels         KodakIFD:WhiteBalance    no
                        WB_RGBMul0
                        WB_RGBMul1
@@ -20893,5 +35422,5 @@
                        KodakIFD:ColorTemperature
                        Kodak:WB_RGBLevels
-  WB_RGGBLevels        Canon:WhiteBalance       N
+  WB_RGGBLevels        Canon:WhiteBalance       no
                        WB_RGGBLevelsAsShot
                        WB_RGGBLevelsAuto
@@ -20904,7 +35433,7 @@
                        WB_RGGBLevelsShade
                        WB_RGGBLevelsKelvin
-  WB_RGGBLevels        WB_RGGBLevelsUncorrected N
+  WB_RGGBLevels        WB_RGGBLevelsUncorrected no
                        WB_RGGBLevelsBlack
-  ZoomedPreviewImage   ZoomedPreviewStart       N
+  ZoomedPreviewImage   ZoomedPreviewStart       no
                        ZoomedPreviewLength
 
@@ -20922,8 +35451,8 @@
   Tag Name             Refers To                Writable
   --------             ---------                --------
-  AllDates             DateTimeOriginal         Y
+  AllDates             DateTimeOriginal         yes
                        CreateDate
                        ModifyDate
-  Canon                FileName                 Y
+  Canon                FileName                 yes
                        Model
                        DateTimeOriginal
@@ -20956,5 +35485,9 @@
                        OwnerName
                        SerialNumber
-  Common               FileName                 Y
+  ColorSpaceTags       ExifIFD:ColorSpace       yes
+                       ExifIFD:Gamma
+                       InteropIFD:InteropIndex
+                       ICC_Profile
+  Common               FileName                 yes
                        FileSize
                        Model
@@ -20968,5 +35501,5 @@
                        WhiteBalance
                        Flash
-  CommonIFD0           IFD0:ImageDescription    Y
+  CommonIFD0           IFD0:ImageDescription    yes
                        IFD0:Make
                        IFD0:Model
@@ -20985,11 +35518,31 @@
                        IFD0:XPKeywords
                        IFD0:XPSubject
-  MakerNotes           MakerNotes               Y
+  LargeTags            CanonVRD                 yes
+                       DLOData
+                       EXIF
+                       ICC_Profile
+                       IDCPreviewImage
+                       ImageData
+                       IPTC
+                       JpgFromRaw
+                       OriginalRawImage
+                       OtherImage
+                       PreviewImage
+                       ThumbnailImage
+                       TIFFPreview
+                       XML
+                       XMP
+                       ZoomedPreviewImage
+  MakerNotes           MakerNotes               yes
+                       MakerNoteApple
                        MakerNoteCanon
                        MakerNoteCasio
                        MakerNoteCasio2
+                       MakerNoteDJI
+                       MakerNoteFLIR
                        MakerNoteFujiFilm
                        MakerNoteGE
                        MakerNoteGE2
+                       MakerNoteHasselblad
                        MakerNoteHP
                        MakerNoteHP2
@@ -21010,6 +35563,9 @@
                        MakerNoteKodak8a
                        MakerNoteKodak8b
+                       MakerNoteKodak8c
                        MakerNoteKodak9
                        MakerNoteKodak10
+                       MakerNoteKodak11
+                       MakerNoteKodak12
                        MakerNoteKodakUnknown
                        MakerNoteKyocera
@@ -21017,7 +35573,9 @@
                        MakerNoteMinolta2
                        MakerNoteMinolta3
+                       MakerNoteMotorola
                        MakerNoteNikon
                        MakerNoteNikon2
                        MakerNoteNikon3
+                       MakerNoteNintendo
                        MakerNoteOlympus
                        MakerNoteOlympus2
@@ -21028,6 +35586,11 @@
                        MakerNoteLeica5
                        MakerNoteLeica6
+                       MakerNoteLeica7
+                       MakerNoteLeica8
+                       MakerNoteLeica9
+                       MakerNoteLeica10
                        MakerNotePanasonic
                        MakerNotePanasonic2
+                       MakerNotePanasonic3
                        MakerNotePentax
                        MakerNotePentax2
@@ -21035,7 +35598,12 @@
                        MakerNotePentax4
                        MakerNotePentax5
+                       MakerNotePentax6
                        MakerNotePhaseOne
                        MakerNoteReconyx
+                       MakerNoteReconyx2
+                       MakerNoteReconyx3
                        MakerNoteRicoh
+                       MakerNoteRicoh2
+                       MakerNoteRicohPentax
                        MakerNoteRicohText
                        MakerNoteSamsung1a
@@ -21050,9 +35618,11 @@
                        MakerNoteSony3
                        MakerNoteSony4
+                       MakerNoteSony5
                        MakerNoteSonyEricsson
                        MakerNoteSonySRF
                        MakerNoteUnknownText
+                       MakerNoteUnknownBinary
                        MakerNoteUnknown
-  Nikon                Model                    Y
+  Nikon                Model                    yes
                        SubSecDateTimeOriginal
                        ShutterCount
@@ -21082,5 +35652,5 @@
                        FlashMode
                        FlashExposureComp
-  Unsafe               IFD0:YCbCrPositioning    Y
+  Unsafe               IFD0:YCbCrPositioning    yes
                        IFD0:YCbCrCoefficients
                        IFD0:TransferFunction
@@ -21091,22 +35661,30 @@
                        InteropIFD:RelatedImageWidth
                        InteropIFD:RelatedImageHeight
+  ls-l                 FilePermissions          yes
+                       FileHardLinks
+                       FileUserID
+                       FileGroupID
+                       FileSize#
+                       FileModifyDate
+                       FileName
 
 =head2 MWG Tags
 
+The Metadata Working Group (MWG) recommends techniques to allow certain
+overlapping EXIF, IPTC and XMP tags to be reconciled when reading, and
+synchronized when writing.  The MWG Composite tags below are designed to aid
+in the implementation of these recommendations.  As well, the MWG defines
+new XMP tags which are listed in the subsequent tables below.  See
+L<https://web.archive.org/web/20181006115950/http://www.metadataworkinggroup.org/specs/>
+for the official MWG specification.
+
 =head3 MWG Composite Tags
-
-The Metadata Working Group (MWG) recommendations provide a set of rules to
-allow certain overlapping EXIF, IPTC and XMP tags to be reconciled when
-reading, and synchronized when writing.  The ExifTool MWG module is designed
-to aid in the implementation of these recommendations.  (See
-L<http://www.metadataworkinggroup.org/> for the complete MWG technical
-specifications.)
 
 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
-when the MWG module is loaded.  The MWG module is loaded automatically by
-the exiftool application if MWG is specified as a group for any tag on the
-command line, or manually with the C<-use MWG> option.  Via the API, the MWG
-module is loaded with "C<use Image::ExifTool::MWG>".
+when explicitly loaded, but this is done automatically by the exiftool
+application if MWG is specified as a group for any tag on the command line,
+or manually with the C<-use MWG> option.  Via the API, the MWG Composite
+tags are loaded by calling "C<Image::ExifTool::MWG::Load()>".
 
 When reading, the value of each MWG tag is B<Derived From> the specified
@@ -21128,5 +35706,11 @@
 EXIF/IPTC/XMP records that exist.
 
-A complication of the specification is that although the MWG:Creator
+Contrary to the EXIF specification, the MWG recommends that EXIF "ASCII"
+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.
+
+A complication of the MWG specification is that although the MWG:Creator
 property may consist of multiple values, the associated EXIF tag
 (EXIF:Artist) is only a simple string.  To resolve this discrepancy the MWG
@@ -21138,19 +35722,21 @@
   Tag Name             Derived From             Writable
   --------             ------------             --------
-  City                 IPTC:City                Y
+  City                 IPTC:City                yes
                        XMP-photoshop:City
+                       XMP-iptcExt:LocationShownCity
                        CurrentIPTCDigest
                        IPTCDigest
-  Copyright            EXIF:Copyright           Y
+  Copyright            EXIF:Copyright           yes
                        IPTC:CopyrightNotice
                        XMP-dc:Rights
                        CurrentIPTCDigest
                        IPTCDigest
-  Country              IPTC:Country-PrimaryLocationName Y
+  Country              IPTC:Country-PrimaryLocationName yes
                        XMP-photoshop:Country
+                       XMP-iptcExt:LocationShownCountryName
                        CurrentIPTCDigest
                        IPTCDigest
-  CreateDate           EXIF:CreateDate          Y
-                       EXIF:SubSecTimeDigitized
+  CreateDate           Composite:SubSecCreateDate yes
+                       EXIF:CreateDate
                        IPTC:DigitalCreationDate
                        IPTC:DigitalCreationTime
@@ -21158,11 +35744,11 @@
                        CurrentIPTCDigest
                        IPTCDigest
-  Creator              EXIF:Artist              Y+
+  Creator              EXIF:Artist              yes+
                        IPTC:By-line
                        XMP-dc:Creator
                        CurrentIPTCDigest
                        IPTCDigest
-  DateTimeOriginal     EXIF:DateTimeOriginal    Y
-                       EXIF:SubSecTimeOriginal
+  DateTimeOriginal     Composite:SubSecDateTimeOriginal yes
+                       EXIF:DateTimeOriginal
                        IPTC:DateCreated
                        IPTC:TimeCreated
@@ -21170,29 +35756,167 @@
                        CurrentIPTCDigest
                        IPTCDigest
-  Description          EXIF:ImageDescription    Y
+  Description          EXIF:ImageDescription    yes
                        IPTC:Caption-Abstract
                        XMP-dc:Description
                        CurrentIPTCDigest
                        IPTCDigest
-  Keywords             IPTC:Keywords            Y+
+  Keywords             IPTC:Keywords            yes+
                        XMP-dc:Subject
                        CurrentIPTCDigest
                        IPTCDigest
-  Location             IPTC:Sub-location        Y
+  Location             IPTC:Sub-location        yes
                        XMP-iptcCore:Location
+                       XMP-iptcExt:LocationShownSublocation
                        CurrentIPTCDigest
                        IPTCDigest
-  ModifyDate           EXIF:ModifyDate          Y
-                       EXIF:SubSecTime
+  ModifyDate           Composite:SubSecModifyDate yes
+                       EXIF:ModifyDate
                        XMP-xmp:ModifyDate
                        CurrentIPTCDigest
                        IPTCDigest
-  Orientation          EXIF:Orientation         Y
-  Rating               XMP-xmp:Rating           Y
-  State                IPTC:Province-State      Y
+  Orientation          EXIF:Orientation         yes
+  Rating               XMP-xmp:Rating           yes
+  State                IPTC:Province-State      yes
                        XMP-photoshop:State
+                       XMP-iptcExt:LocationShownProvinceState
                        CurrentIPTCDigest
                        IPTCDigest
 
+=head3 MWG Regions Tags
+
+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<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.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  RegionInfo                                    MWG RegionInfo Struct
+  RegionAppliedToDimensions                     Dimensions Struct_
+  RegionAppliedToDimensionsH                    real_
+  RegionAppliedToDimensionsUnit                 string_
+  RegionAppliedToDimensionsW                    real_
+  RegionList                                    MWG RegionStruct Struct_+
+  RegionArea                                    Area Struct_+
+  RegionAreaD                                   real_+
+  RegionAreaH                                   real_+
+  RegionAreaUnit                                string_+
+  RegionAreaW                                   real_+
+  RegionAreaX                                   real_+
+  RegionAreaY                                   real_+
+  RegionBarCodeValue                            string_+
+  RegionDescription                             string_+
+  RegionExtensions                              MWG Extensions Struct_+
+  RegionFocusUsage                              string_+
+  RegionName                                    string_+
+  RegionRotation                                real_+
+  RegionSeeAlso                                 string_+
+  RegionType                                    string_+
+
+=head3 MWG RegionInfo Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  AppliedToDimensions                           Dimensions Struct
+  RegionList                                    MWG RegionStruct Struct+
+
+=head3 MWG RegionStruct Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Area                                          Area Struct
+  BarCodeValue                                  string
+  Description                                   string
+  Extensions                                    MWG Extensions Struct
+  FocusUsage                                    string
+  Name                                          string
+  Rotation                                      real
+  Type                                          string
+  SeeAlso                                       string
+
+=head3 MWG Extensions Struct
+
+This structure may contain any top-level XMP tags, but none have been
+pre-defined in ExifTool.  Since no flattened tags have been pre-defined,
+RegionExtensions is writable only as a structure (eg.
+C<{xmp-dc:creator=me,rating=5}>).  Fields for this structure are identified
+using the standard ExifTool tag name (with optional leading group name,
+and/or trailing language code, and/or trailing C<#> symbol to disable print
+conversion).
+
+  Field Name                                    Writable
+  ----------                                    --------
+  [no tags known]
+
+=head3 MWG Keywords Tags
+
+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<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.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  KeywordInfo                                   MWG KeywordInfo Struct
+  HierarchicalKeywords                          MWG KeywordStruct Struct_+
+  HierarchicalKeywords1Applied                  boolean_+
+  HierarchicalKeywords1Children                 MWG KeywordStruct Struct_+
+  HierarchicalKeywords2Applied                  boolean_+
+  HierarchicalKeywords2Children                 MWG KeywordStruct Struct_+
+  HierarchicalKeywords3Applied                  boolean_+
+  HierarchicalKeywords3Children                 MWG KeywordStruct Struct_+
+  HierarchicalKeywords4Applied                  boolean_+
+  HierarchicalKeywords4Children                 MWG KeywordStruct Struct_+
+  HierarchicalKeywords5Applied                  boolean_+
+  HierarchicalKeywords5Children                 MWG KeywordStruct Struct_+
+  HierarchicalKeywords6Applied                  boolean_+
+  HierarchicalKeywords6                         string_+
+  HierarchicalKeywords5                         string_+
+  HierarchicalKeywords4                         string_+
+  HierarchicalKeywords3                         string_+
+  HierarchicalKeywords2                         string_+
+  HierarchicalKeywords1                         string_+
+
+=head3 MWG KeywordInfo Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Hierarchy                                     MWG KeywordStruct Struct+
+
+=head3 MWG KeywordStruct Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  Applied                                       boolean
+  Children                                      MWG KeywordStruct Struct+
+  Keyword                                       string
+
+=head3 MWG Collections Tags
+
+Collections metadata defined by the MWG 2.0 specification.  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-coll family 1 group.
+
+  Tag Name                                      Writable
+  --------                                      --------
+  Collections                                   MWG CollectionInfo Struct+
+  CollectionName                                string_+
+  CollectionURI                                 string_+
+
+=head3 MWG CollectionInfo Struct
+
+  Field Name                                    Writable
+  ----------                                    --------
+  CollectionName                                string
+  CollectionURI                                 string
+
 =head1 NOTES
 
@@ -21202,5 +35926,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Text.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Text.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Text.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Theora.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Theora.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Theora.pm	(revision 34921)
@@ -0,0 +1,145 @@
+#------------------------------------------------------------------------------
+# File:         Theora.pm
+#
+# Description:  Read Theora video meta information
+#
+# Revisions:    2011/07/13 - P. Harvey Created
+#
+# References:   1) http://www.theora.org/doc/Theora.pdf
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Theora;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.00';
+
+# Theora header types
+%Image::ExifTool::Theora::Main = (
+    NOTES => q{
+        Information extracted from Ogg Theora video files.  See
+        L<http://www.theora.org/doc/Theora.pdf> for the Theora specification.
+    },
+    0x80 => {
+        Name => 'Identification',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Theora::Identification',
+            ByteOrder => 'BigEndian',
+        },
+    },
+    0x81 => {
+        Name => 'Comments',
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::Vorbis::Comments',
+        },
+    },
+    # 0x82 - Setup
+);
+
+# tags extracted from Theora Idenfication header
+%Image::ExifTool::Theora::Identification = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 2 => 'Video' },
+    NOTES => 'Tags extracted from the Theora identification header.',
+    0 => {
+        Name => 'TheoraVersion',
+        Format => 'int8u[3]',
+        PrintConv => '$val =~ tr/ /./; $val',
+    },
+    7 => {
+        Name => 'ImageWidth',
+        Format => 'int32u',
+        ValueConv => '$val >> 8',
+    },
+    10 => {
+        Name => 'ImageHeight',
+        Format => 'int32u',
+        ValueConv => '$val >> 8',
+    },
+    13 => 'XOffset',
+    14 => 'YOffset',
+    15 => {
+        Name => 'FrameRate',
+        Format => 'rational64u',
+        PrintConv => 'int($val * 1000 + 0.5) / 1000',
+    },
+    23 => {
+        Name => 'PixelAspectRatio',
+        Format => 'int16u[3]',
+        ValueConv => 'my @a=split(" ",$val); (($a[0]<<8)+($a[1]>>8)) / ((($a[1]&0xff)<<8)+$a[2])',
+        PrintConv => 'int($val * 1000 + 0.5) / 1000',
+    },
+    29 => {
+        Name => 'ColorSpace',
+        PrintConv => {
+            0 => 'Undefined',
+            1 => 'Rec. 470M',
+            2 => 'Rec. 470BG',
+        },
+    },
+    30 => {
+        Name => 'NominalVideoBitrate',
+        Format => 'int32u',
+        ValueConv => '$val >> 8',
+        PrintConv => {
+            0 => 'Unspecified',
+            OTHER => \&Image::ExifTool::ConvertBitrate,
+        },
+    },
+    33 => {
+        Name => 'Quality',
+        ValueConv => '$val >> 2',
+    },
+    34 => {
+        Name => 'PixelFormat',
+        ValueConv => '($val >> 3) & 0x3',
+        PrintConv => {
+            0 => '4:2:0',
+            2 => '4:2:2',
+            3 => '4:4:4',
+        },
+    },
+);
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Theora - Read Theora video 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 Theora video streams.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.theora.org/doc/Theora.pdf>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Theora Tags>,
+L<Image::ExifTool::TagNames/Ogg Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Torrent.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Torrent.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Torrent.pm	(revision 34921)
@@ -0,0 +1,325 @@
+#------------------------------------------------------------------------------
+# File:         Torrent.pm
+#
+# Description:  Read information from BitTorrent file
+#
+# Revisions:    2013/08/27 - P. Harvey Created
+#
+# References:   1) https://wiki.theory.org/BitTorrentSpecification
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::Torrent;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.04';
+
+sub ReadBencode($$);
+sub ExtractTags($$$;$$@);
+
+# tags extracted from BitTorrent files
+%Image::ExifTool::Torrent::Main = (
+    GROUPS => { 2 => 'Document' },
+    NOTES => q{
+        Below are tags commonly found in BitTorrent files.  As well as these tags,
+        any other existing tags will be extracted.  For convenience, list items are
+        expanded into individual tags with an index in the tag name, but only the
+        tags with index "1" are listed in the tables below.  See
+        L<https://wiki.theory.org/BitTorrentSpecification> for the BitTorrent
+        specification.
+    },
+    'announce'      => { },
+    'announce-list' => { Name => 'AnnounceList1' },
+    'comment'       => { },
+    'created by'    => { Name => 'Creator' }, # software used to create the torrent
+    'creation date' => {
+        Name => 'CreateDate',
+        Groups => { 2 => 'Time' },
+        ValueConv => 'ConvertUnixTime($val,1)',
+        PrintConv => '$self->ConvertDateTime($val)',
+    },
+    'encoding'      => { },
+    'info'          => {
+        SubDirectory => { TagTable => 'Image::ExifTool::Torrent::Info' },
+        Notes => 'extracted as a structure with the Struct option',
+    },
+    'url-list'      => { Name => 'URLList1' },
+);
+
+%Image::ExifTool::Torrent::Info = (
+    GROUPS => { 2 => 'Document' },
+    'file-duration' => { Name => 'File1Duration' },
+    'file-media'    => { Name => 'File1Media' },
+    'files'         => { SubDirectory => { TagTable => 'Image::ExifTool::Torrent::Files' } },
+    'length'        => { },
+    'md5sum'        => { Name => 'MD5Sum' },
+    'name'          => { },
+    'name.utf-8'    => { Name => 'NameUTF-8' },
+    'piece length'  => { Name => 'PieceLength' },
+    'pieces'        => {
+        Name => 'Pieces',
+        Notes => 'concatenation of 20-byte SHA-1 digests for each piece',
+    },
+    'private'       => { },
+    'profiles'      => { SubDirectory => { TagTable => 'Image::ExifTool::Torrent::Profiles' } },
+);
+
+%Image::ExifTool::Torrent::Profiles = (
+    GROUPS => { 2 => 'Document' },
+    'width'         => { Name => 'Profile1Width' },
+    'height'        => { Name => 'Profile1Height' },
+    'acodec'        => { Name => 'Profile1AudioCodec' },
+    'vcodec'        => { Name => 'Profile1VideoCodec' },
+);
+
+%Image::ExifTool::Torrent::Files = (
+    GROUPS => { 2 => 'Document' },
+    'length'        => { Name => 'File1Length', PrintConv => 'ConvertFileSize($val)' },
+    'md5sum'        => { Name => 'File1MD5Sum'  },
+    'path'          => { Name => 'File1Path', JoinPath => 1 },
+    'path.utf-8'    => { Name => 'File1PathUTF-8', JoinPath => 1 },
+);
+
+#------------------------------------------------------------------------------
+# Read 64kB more data into buffer
+# Inputs: 0) RAF ref, 1) buffer ref
+# Returns: number of bytes read
+# Notes: Sets BencodeEOF element of RAF on end of file
+sub ReadMore($$)
+{
+    my ($raf, $dataPt) = @_;
+    my $buf2;
+    my $n = $raf->Read($buf2, 65536);
+    $$raf{BencodeEOF} = 1 if $n != 65536;
+    $$dataPt = substr($$dataPt, pos($$dataPt)) . $buf2 if $n;
+    return $n;
+}
+
+#------------------------------------------------------------------------------
+# Read bencoded value
+# Inputs: 0) input file, 1) buffer (pos must be set to current position)
+# Returns: HASH ref, ARRAY ref, SCALAR ref, SCALAR, or undef on error or end of data
+# Notes: Sets BencodeError element of RAF on any error
+sub ReadBencode($$)
+{
+    my ($raf, $dataPt) = @_;
+
+    # read more if necessary (keep a minimum of 64 bytes in the buffer)
+    my $pos = pos($$dataPt);
+    return undef unless defined $pos;
+    my $remaining = length($$dataPt) - $pos;
+    ReadMore($raf, $dataPt) if $remaining < 64 and not $$raf{BencodeEOF};
+
+    # read next token
+    $$dataPt =~ /(.)/sg or return undef;
+
+    my $val;
+    my $tok = $1;
+    if ($tok eq 'i') {      # integer
+        $$dataPt =~ /\G(-?\d+)e/g or return $val;
+        $val = $1;
+    } elsif ($tok eq 'd') { # dictionary
+        $val = { };
+        for (;;) {
+            my $k = ReadBencode($raf, $dataPt);
+            last unless defined $k;
+            # the key must be a byte string
+            if (ref $k) {
+                ref $k ne 'SCALAR' and $$raf{BencodeError} = 'Bad dictionary key', last;
+                $k = $$k;
+            }
+            my $v = ReadBencode($raf, $dataPt);
+            last unless defined $v;
+            $$val{$k} = $v;
+        }
+    } elsif ($tok eq 'l') { # list
+        $val = [ ];
+        for (;;) {
+            my $v = ReadBencode($raf, $dataPt);
+            last unless defined $v;
+            push @$val, $v;
+        }
+    } elsif ($tok eq 'e') { # end of dictionary or list
+        # return undef (no error)
+    } elsif ($tok =~ /^\d$/ and $$dataPt =~ /\G(\d*):/g) { # byte string
+        my $len = $tok . $1;
+        my $more = $len - (length($$dataPt) - pos($$dataPt));
+        my $value;
+        if ($more <= 0) {
+            $value = substr($$dataPt,pos($$dataPt),$len);
+            pos($$dataPt) = pos($$dataPt) + $len;
+        } elsif ($more > 10000000) {
+            # just skip over really long values
+            $val = \ "(Binary data $len bytes)" if $raf->Seek($more, 1);
+        } else {
+            # need to read more from file
+            my $buff;
+            my $n = $raf->Read($buff, $more);
+            if ($n == $more) {
+                $value = substr($$dataPt,pos($$dataPt)) . $buff;
+                $$dataPt = '';
+                pos($$dataPt) = 0;
+            }
+        }
+        if (defined $value) {
+            # return as binary data unless it is a reasonable-length ASCII string
+            if (length($value) > 256 or $value =~ /[^\t\x20-\x7e]/) {
+                $val = \$value;
+            } else {
+                $val = $value;
+            }
+        } elsif (not defined $val) {
+            $$raf{BencodeError} = 'Truncated byte string';
+        }
+    } else {
+        $$raf{BencodeError} = 'Bad format';
+    }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Extract tags from dictionary hash
+# Inputs: 0) ExifTool ref, 1) dictionary hash reference, 2) tag table ref,
+#         3) parent hash ID, 4) parent hash name, 5-N) list indices
+# Returns: number of tags extracted
+sub ExtractTags($$$;$$@)
+{
+    my ($et, $hashPtr, $tagTablePtr, $baseID, $baseName, @index) = @_;
+    my $count = 0;
+    my $tag;
+    foreach $tag (sort keys %$hashPtr) {
+        my $val = $$hashPtr{$tag};
+        my ($i, $j, @more);
+        for (; defined $val; $val = shift @more) {
+            my $id = defined $baseID ? "$baseID/$tag" : $tag;
+            unless ($$tagTablePtr{$id}) {
+                my $name = ucfirst $tag;
+                # capitalize all words in tag name and remove illegal characters
+                $name =~ s/[^-_a-zA-Z0-9]+(.?)/\U$1/g;
+                $name = "Tag$name" if length($name) < 2 or $name !~ /^[A-Z]/;
+                $name = $baseName . $name if defined $baseName; # add base name if necessary
+                AddTagToTable($tagTablePtr, $id, { Name => $name });
+                $et->VPrint(0, "  [adding $id '${name}']\n");
+            }
+            my $tagInfo = $et->GetTagInfo($tagTablePtr, $id) or next;
+            if (ref $val eq 'ARRAY') {
+                if ($$tagInfo{JoinPath}) {
+                    $val = join '/', @$val;
+                } else {
+                    push @more, @$val;
+                    next if ref $more[0] eq 'ARRAY'; # continue expanding nested lists
+                    $val = shift @more;
+                    $i or $i = 0, push(@index, $i);
+                }
+            }
+            $index[-1] = ++$i if defined $i;
+            if (@index) {
+                $id .= join '_', @index;  # add instance number(s) to tag ID
+                unless ($$tagTablePtr{$id}) {
+                    my $name = $$tagInfo{Name};
+                    # embed indices at position of '1' in tag name
+                    my $n = ($name =~ tr/1/#/);
+                    for ($j=0; $j<$n; ++$j) {
+                        my $idx = $index[$j] || '';
+                        $name =~ s/#/$idx/;
+                    }
+                    # put remaining indices at end of tag name
+                    for (; $j<@index; ++$j) {
+                        $name .= '_' if $name =~ /\d$/;
+                        $name .= $index[$j];
+                    }
+                    AddTagToTable($tagTablePtr, $id, { %$tagInfo, Name => $name });
+                }
+                $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}) {
+                    $table = GetTagTable($$tagInfo{SubDirectory}{TagTable});
+                } else {
+                    $table = $tagTablePtr;
+                    # use hash ID and Name as base for contained tags to avoid conflicts
+                    $rootID = $id;
+                    $rootName = $$tagInfo{Name};
+                }
+                $count += ExtractTags($et, $val, $table, $rootID, $rootName, @index);
+            } else {
+                # handle this simple tag value
+                $et->HandleTag($tagTablePtr, $id, $val);
+                ++$count;
+            }
+        }
+        pop @index if defined $i;
+    }
+    return $count;
+}
+
+#------------------------------------------------------------------------------
+# Process BitTorrent file
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference (with RAF set)
+# Returns: 1 on success, 0 if this wasn't a valid BitTorrent file
+sub ProcessTorrent($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $success = 0;
+    my $raf = $$dirInfo{RAF};
+    my $buff = '';
+    pos($buff) = 0;
+    my $dict = ReadBencode($raf, \$buff);
+    my $err = $$raf{BencodeError};
+    $et->Warn("Bencode error: $err") if $err;
+    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;
+    }
+    return $success;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::Torrent - Read information from BitTorrent file
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read
+bencoded information from BitTorrent files.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.theory.org/BitTorrentSpecification>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/Torrent Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Unknown.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Unknown.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Unknown.pm	(revision 34921)
@@ -54,5 +54,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/VCard.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/VCard.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/VCard.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Validate.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Validate.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Validate.pm	(revision 34921)
@@ -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.18';
+
+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
+            # (default is 1) 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 => 'not defined $val or $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-2021, 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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Vorbis.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Vorbis.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Vorbis.pm	(revision 34921)
@@ -2,10 +2,12 @@
 # File:         Vorbis.pm
 #
-# Description:  Read Ogg Vorbis meta information
+# Description:  Read Ogg Vorbis audio meta information
 #
-# Revisions:    11/10/2006 - P. Harvey Created
+# Revisions:    2006/11/10 - P. Harvey Created
+#               2011/07/12 - PH Moved Ogg to a separate module and added Theora
 #
 # References:   1) http://www.xiph.org/vorbis/doc/
 #               2) http://flac.sourceforge.net/ogg_mapping.html
+#               3) http://www.theora.org/doc/Theora.pdf
 #------------------------------------------------------------------------------
 
@@ -16,16 +18,13 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.03';
-
-my $MAX_PACKETS = 2;    # maximum packets to scan from each stream at start of file
+$VERSION = '1.08';
 
 sub ProcessComments($$$);
-sub DecodeCoverArt($);
-
-# Vorbis comment tags
+
+# Vorbis header types
 %Image::ExifTool::Vorbis::Main = (
     NOTES => q{
-        ExifTool extracts the following Vorbis information from Ogg files.  As well
-        as this, ExifTool also extracts FLAC and ID3 information from Ogg files.
+        Information extracted from Ogg Vorbis files.  See
+        L<http://www.xiph.org/vorbis/doc/> for the Vorbis specification.
     },
     1 => {
@@ -98,4 +97,5 @@
     COVERART  => {
         Name => 'CoverArt',
+        Groups => { 2 => 'Preview' },
         Notes => 'base64-encoded image',
         ValueConv => q{
@@ -112,5 +112,42 @@
     ENCODED_BY  => { Name => 'EncodedBy' },
     COMMENT     => { Name => 'Comment' },
-);
+    # in Theora documentation (ref 3)
+    DIRECTOR    => { Name => 'Director' },
+    PRODUCER    => { Name => 'Producer' },
+    COMPOSER    => { Name => 'Composer' },
+    ACTOR       => { Name => 'Actor' },
+    # Opus tags
+    ENCODER     => { Name => 'Encoder' },
+    ENCODER_OPTIONS => { Name => 'EncoderOptions' },
+    METADATA_BLOCK_PICTURE => {
+        Name => 'Picture',
+        Binary => 1,
+        # ref https://wiki.xiph.org/VorbisComment#METADATA_BLOCK_PICTURE
+        RawConv => q{
+            require Image::ExifTool::XMP;
+            Image::ExifTool::XMP::DecodeBase64($val);
+        },
+        SubDirectory => {
+            TagTable => 'Image::ExifTool::FLAC::Picture',
+            ByteOrder => 'BigEndian',
+        },
+    },
+);
+
+# Vorbis composite tags
+%Image::ExifTool::Vorbis::Composite = (
+    Duration => {
+        Require => {
+            0 => 'Vorbis:NominalBitrate',
+            1 => 'FileSize',
+        },
+        RawConv => '$val[0] ? $val[1] * 8 / $val[0] : undef',
+        PrintConv => 'ConvertDuration($val) . " (approx)"', # (only approximate)
+    },
+);
+
+# add our composite tags
+Image::ExifTool::AddCompositeTags('Image::ExifTool::Vorbis');
+
 
 #------------------------------------------------------------------------------
@@ -120,5 +157,5 @@
 sub ProcessComments($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
     my $dataPos = $$dirInfo{DataPos};
@@ -138,10 +175,13 @@
         if (defined $num) {
             $buff =~ /(.*?)=(.*)/s or last;
-            ($tag, $val) = ($1, $2);
+            ($tag, $val) = (uc $1, $2);
+            # Vorbis tag ID's are all capitals, so they may conflict with our internal tags
+            # --> protect against this by adding a trailing underline if necessary
+            $tag .= '_' if $Image::ExifTool::specialTags{$tag};
         } else {
             $tag = 'vendor';
             $val = $buff;
             $num = ($pos + 4 < $end) ? Get32u($dataPt, $pos) : 0;
-            $exifTool->VPrint(0, "  + [Vorbis comments with $num entries]\n");
+            $et->VPrint(0, "  + [Vorbis comments with $num entries]\n");
             $pos += 4;
         }
@@ -152,7 +192,8 @@
             $name =~ s/[^\w-]+(.?)/\U$1/sg;
             $name =~ s/([a-z0-9])_([a-z])/$1\U$2/g;
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => $name });
+            $et->VPrint(0, "  | [adding $tag]\n");
+            AddTagToTable($tagTablePtr, $tag, { Name => $name });
         }
-        $exifTool->HandleTag($tagTablePtr, $tag, $exifTool->Decode($val, 'UTF8'),
+        $et->HandleTag($tagTablePtr, $tag, $et->Decode($val, 'UTF8'),
             Index   => $index,
             DataPt  => $dataPt,
@@ -165,153 +206,8 @@
         $index = (defined $index) ? $index + 1 : 0;
     }
-    $exifTool->Warn('Format error in Vorbis comments');
+    $et->Warn('Format error in Vorbis comments');
     return 0;
 }
 
-#------------------------------------------------------------------------------
-# Process Ogg packet
-# Inputs: 0) ExifTool object ref, 1) data ref, 2) tag table ref
-# Returns: 1 on success
-sub ProcessPacket($$$)
-{
-    my ($exifTool, $dataPt, $tagTablePtr) = @_;
-    if ($$dataPt =~ /^(.)vorbis/s) {
-        my $tag = ord($1);
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tag);
-        return 0 unless $tagInfo and $$tagInfo{SubDirectory};
-        my %dirInfo = (
-            DataPt => $dataPt,
-            DirName => $$tagInfo{Name},
-            DirStart => 7,
-        );
-        my $table = GetTagTable($tagInfo->{SubDirectory}->{TagTable});
-        return $exifTool->ProcessDirectory(\%dirInfo, $table);
-    }
-    return 0;
-}
-
-#------------------------------------------------------------------------------
-# Extract information from an Ogg Vorbis or Ogg FLAC file
-# Inputs: 0) ExifTool object reference, 1) dirInfo reference
-# Returns: 1 on success, 0 if this wasn't a valid Ogg Vorbis file
-sub ProcessOGG($$)
-{
-    my ($exifTool, $dirInfo) = @_;
-
-    # must first check for leading/trailing ID3 information
-    unless ($exifTool->{DoneID3}) {
-        require Image::ExifTool::ID3;
-        Image::ExifTool::ID3::ProcessID3($exifTool, $dirInfo) and return 1;
-    }
-    my $raf = $$dirInfo{RAF};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
-    my ($success, $page, $packets, $streams) = (0,0,0,0);
-    my ($buff, $tagTablePtr, $flag, $stream, %val, $numFlac);
-
-    for (;;) {
-        # must read ahead to next page to see if it is a continuation
-        # (this code would be a lot simpler if the continuation flag
-        #  was on the leading instead of the trailing page!)
-        if ($raf and $raf->Read($buff, 28) == 28) {
-            # validate magic number
-            unless ($buff =~ /^OggS/) {
-                $success and $exifTool->Warn('Lost synchronization');
-                last;
-            }
-            unless ($success) {
-                # set file type and initialize on first page
-                $success = 1;
-                $exifTool->SetFileType();
-                SetByteOrder('II');
-                $tagTablePtr = GetTagTable('Image::ExifTool::Vorbis::Main');
-            }
-            $flag = Get8u(\$buff, 5);       # page flag
-            $stream = Get32u(\$buff, 14);   # stream serial number
-            ++$streams if $flag & 0x02;     # count start-of-stream pages
-            ++$packets unless $flag & 0x01; # keep track of packet count
-        } else {
-            # all done unless we have to process our last packet
-            last unless %val;
-            ($stream) = sort keys %val;     # take a stream
-            $flag = 0;                      # no continuation
-            undef $raf;                     # flag for done reading
-        }
-
-        if (defined $numFlac) {
-            # stop to process FLAC headers if we hit the end of file
-            last unless $raf;
-            --$numFlac; # one less header packet to read
-        } else {
-            # can finally process previous packet from this stream
-            # unless this is a continuation page
-            if (defined $val{$stream} and not $flag & 0x01) {
-                ProcessPacket($exifTool, \$val{$stream}, $tagTablePtr);
-                delete $val{$stream};
-                # only read the first $MAX_PACKETS packets from each stream
-                if ($packets > $MAX_PACKETS * $streams or not defined $raf) {
-                    last unless %val;   # all done (success!)
-                    next;               # process remaining stream(s)
-                }
-            }
-            # stop processing Ogg Vorbis if we have scanned enough packets
-            last if $packets > $MAX_PACKETS * $streams and not %val;
-        }
-
-        # continue processing the current page
-        my $pageNum = Get32u(\$buff, 18);   # page sequence number
-        my $nseg = Get8u(\$buff, 26);       # number of segments
-        # calculate total data length
-        my $dataLen = Get8u(\$buff, 27);
-        if ($nseg) {
-            $raf->Read($buff, $nseg-1) == $nseg-1 or last;
-            my @segs = unpack('C*', $buff);
-            # could check that all these (but the last) are 255...
-            foreach (@segs) { $dataLen += $_ }
-        }
-        if (defined $page) {
-            if ($page == $pageNum) {
-                ++$page;
-            } else {
-                $exifTool->Warn('Missing page(s) in Ogg file');
-                undef $page;
-            }
-        }
-        # read page data
-        $raf->Read($buff, $dataLen) == $dataLen or last;
-        if ($verbose > 1) {
-            printf $out "Page %d, stream 0x%x, flag 0x%x (%d bytes)\n",
-                   $pageNum, $stream, $flag, $dataLen;
-            $exifTool->VerboseDump(\$buff, DataPos => $raf->Tell() - $dataLen);
-        }
-        if (defined $val{$stream}) {
-            $val{$stream} .= $buff;     # add this continuation page
-        } elsif (not $flag & 0x01) {    # ignore remaining pages of a continued packet
-            # ignore the first page of any packet we aren't parsing
-            if ($buff =~ /^(.)vorbis/s and $$tagTablePtr{ord($1)}) {
-                $val{$stream} = $buff;      # save this page
-            } elsif ($buff =~ /^\x7fFLAC..(..)/s) {
-                $numFlac = unpack('n',$1);
-                $val{$stream} = substr($buff, 9);
-            }
-        }
-        if (defined $numFlac) {
-            # stop to process FLAC headers if we have them all
-            last if $numFlac <= 0;
-        } elsif (defined $val{$stream} and $flag & 0x04) {
-            # process Ogg Vorbis packet now if end-of-stream bit is set
-            ProcessPacket($exifTool, \$val{$stream}, $tagTablePtr);
-            delete $val{$stream};
-        }
-    }
-    if (defined $numFlac and defined $val{$stream}) {
-        # process FLAC headers as if it was a complete FLAC file
-        require Image::ExifTool::FLAC;
-        my %dirInfo = ( RAF => new File::RandomAccess(\$val{$stream}) );
-        Image::ExifTool::FLAC::ProcessFLAC($exifTool, \%dirInfo);
-    }
-    return $success;
-}
-
 1;  # end
 
@@ -320,5 +216,5 @@
 =head1 NAME
 
-Image::ExifTool::Vorbis - Read Ogg Vorbis meta information
+Image::ExifTool::Vorbis - Read Ogg Vorbis audio meta information
 
 =head1 SYNOPSIS
@@ -329,9 +225,9 @@
 
 This module contains definitions required by Image::ExifTool to extract meta
-information from Ogg Vorbis and Ogg FLAC audio files.
+information from Ogg Vorbis audio headers.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -346,4 +242,6 @@
 =item L<http://flac.sourceforge.net/ogg_mapping.html>
 
+=item L<http://www.theora.org/doc/Theora.pdf>
+
 =back
 
@@ -351,4 +249,5 @@
 
 L<Image::ExifTool::TagNames/Vorbis Tags>,
+L<Image::ExifTool::TagNames/Ogg Tags>,
 L<Image::ExifTool(3pm)|Image::ExifTool>
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WTV.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WTV.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WTV.pm	(revision 34921)
@@ -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-2021, 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
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteCanonRaw.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteCanonRaw.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteCanonRaw.pl	(revision 34921)
@@ -5,4 +5,5 @@
 #
 # Revisions:    01/25/2005 - P. Harvey Created
+#               09/16/2010 - PH Added ability to write XMP in CRW images
 #------------------------------------------------------------------------------
 package Image::ExifTool::CanonRaw;
@@ -60,6 +61,6 @@
 sub InitMakerNotes($)
 {
-    my $exifTool = shift;
-    $exifTool->{MAKER_NOTE_INFO} = {
+    my $et = shift;
+    $$et{MAKER_NOTE_INFO} = {
         Entries => { },     # directory entries keyed by tagID
         ValBuff => "\0\0\0\0", # value data buffer (start with zero nextIFD pointer)
@@ -76,5 +77,5 @@
 sub BuildMakerNotes($$$$$$)
 {
-    my ($exifTool, $rawTag, $tagInfo, $valuePt, $formName, $count) = @_;
+    my ($et, $rawTag, $tagInfo, $valuePt, $formName, $count) = @_;
 
     my $tagID = $mapRawTag{$rawTag} || return;
@@ -100,5 +101,5 @@
     }
     my $offsetVal;
-    my $makerInfo = $exifTool->{MAKER_NOTE_INFO};
+    my $makerInfo = $$et{MAKER_NOTE_INFO};
     if ($size > 4) {
         my $len = length $makerInfo->{ValBuff};
@@ -122,8 +123,8 @@
 sub SaveMakerNotes($)
 {
-    my $exifTool = shift;
+    my $et = shift;
     # save maker notes
-    my $makerInfo = $exifTool->{MAKER_NOTE_INFO};
-    delete $exifTool->{MAKER_NOTE_INFO};
+    my $makerInfo = $$et{MAKER_NOTE_INFO};
+    delete $$et{MAKER_NOTE_INFO};
     my $dirEntries = $makerInfo->{Entries};
     my $numEntries = scalar(keys %$dirEntries);
@@ -142,13 +143,13 @@
     # save position of maker notes for pointer fixups
     $fixup->{Shift} += length($makerNotes);
-    $exifTool->{MAKER_NOTE_FIXUP} = $fixup;
-    $exifTool->{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
+    $$et{MAKER_NOTE_FIXUP} = $fixup;
+    $$et{MAKER_NOTE_BYTE_ORDER} = GetByteOrder();
     # add value data
     $makerNotes .= $makerInfo->{ValBuff};
     # get MakerNotes tag info
     my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Exif::Main');
-    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 0x927c);
+    my $tagInfo = $et->GetTagInfo($tagTablePtr, 0x927c, \$makerNotes);
     # save the MakerNotes
-    $exifTool->FoundTag($tagInfo, $makerNotes);
+    $et->FoundTag($tagInfo, $makerNotes);
     # save the garbage collection some work later
     delete $makerInfo->{Entries};
@@ -156,8 +157,8 @@
     delete $makerInfo->{FixupTags};
     # also generate Orientation tag since Rotation isn't transferred from RAW info
-    my $rotation = $exifTool->GetValue('Rotation', 'ValueConv');
+    my $rotation = $et->GetValue('Rotation', 'ValueConv');
     if (defined $rotation and defined $mapRotation{$rotation}) {
-        $tagInfo = $exifTool->GetTagInfo($tagTablePtr, 0x112);
-        $exifTool->FoundTag($tagInfo, $mapRotation{$rotation});
+        $tagInfo = $et->GetTagInfo($tagTablePtr, 0x112);
+        $et->FoundTag($tagInfo, $mapRotation{$rotation});
     }
 }
@@ -170,9 +171,9 @@
 sub CheckCanonRaw($$$)
 {
-    my ($exifTool, $tagInfo, $valPtr) = @_;
+    my ($et, $tagInfo, $valPtr) = @_;
     my $tagName = $$tagInfo{Name};
     if ($tagName eq 'JpgFromRaw' or $tagName eq 'ThumbnailImage') {
-        unless ($$valPtr =~ /^\xff\xd8/ or $exifTool->Options('IgnoreMinorErrors')) {
-            return '[minor] Not a valid image';
+        unless ($$valPtr =~ /^\xff\xd8/ or $et->Options('IgnoreMinorErrors')) {
+            return '[Minor] Not a valid image';
         }
     } else {
@@ -195,5 +196,5 @@
 sub WriteCR2($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt} or return 0;
     my $outfile = $$dirInfo{OutFile} or return 0;
@@ -211,13 +212,13 @@
             $msg = 'Unrecognized Canon RAW file';
         }
-        return 0 if $exifTool->Error($msg, $minor);
+        return 0 if $et->Error($msg, $minor);
     }
 
     # CR2 has a 16-byte header
     $$dirInfo{NewDataPos} = 16;
-    my $newData = $exifTool->WriteDirectory($dirInfo, $tagTablePtr);
+    my $newData = $et->WriteDirectory($dirInfo, $tagTablePtr);
     return 0 unless defined $newData;
     unless ($$dirInfo{LastIFD}) {
-        $exifTool->Error("CR2 image IFD may not be deleted");
+        $et->Error("CR2 image IFD may not be deleted");
         return 0;
     }
@@ -235,5 +236,5 @@
         # copy over image data now if necessary
         if (ref $$dirInfo{ImageData}) {
-            $exifTool->CopyImageData($$dirInfo{ImageData}, $outfile) or return 0;
+            $et->CopyImageData($$dirInfo{ImageData}, $outfile) or return 0;
             delete $$dirInfo{ImageData};
         }
@@ -255,6 +256,6 @@
 sub WriteCanonRaw($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
     my $blockStart = $$dirInfo{DirStart};
     my $blockSize = $$dirInfo{DirLen};
@@ -263,6 +264,6 @@
     my $outPos = $$dirInfo{OutPos} or return 0;
     my $outBase = $outPos;
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     my ($buff, $tagInfo);
 
@@ -279,5 +280,5 @@
 
     # get hash of new information keyed by tagID
-    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+    my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
 
     # generate list of tags to add or delete (currently, we only allow JpgFromRaw
@@ -307,5 +308,5 @@
             my $addTag = shift @addTags;
             $tagInfo = $$newTags{$addTag};
-            my $newVal = $exifTool->GetNewValues($tagInfo);
+            my $newVal = $et->GetNewValue($tagInfo);
             if (defined $newVal) {
                 # pad value to an even length (Canon ImageBrowser and ZoomBrowser
@@ -321,5 +322,5 @@
                 $outPos += length($newVal);     # update current position
                 $verbose > 1 and print $out "    + CanonRaw:$$tagInfo{Name}\n";
-                ++$exifTool->{CHANGED};
+                ++$$et{CHANGED};
             }
             # set flag to delete this tag if found later
@@ -332,5 +333,5 @@
         my $valueInDir = ($tag & 0x4000);   # flag for value in directory
 
-        my $tagInfo = $exifTool->GetTagInfo($tagTablePtr,$tagID);
+        my $tagInfo = $et->GetTagInfo($tagTablePtr,$tagID);
         my $format = $crwTagFormat{$tagType};
         my ($count, $subdir);
@@ -363,5 +364,5 @@
                     OutPos   => $outPos,
                 );
-                my $result = $exifTool->WriteDirectory(\%subdirInfo, $tagTablePtr);
+                my $result = $et->WriteDirectory(\%subdirInfo, $tagTablePtr);
                 return 0 unless $result;
                 # set size and pointer for this new directory
@@ -406,7 +407,7 @@
                 #### eval Validate ($dirData, $subdirStart, $size)
                 if (defined $$subdir{Validate} and not eval $$subdir{Validate}) {
-                    $exifTool->Warn("Invalid $name data");
+                    $et->Warn("Invalid $name data");
                 } else {
-                    $subdir = $exifTool->WriteDirectory(\%subdirInfo, $newTagTable);
+                    $subdir = $et->WriteDirectory(\%subdirInfo, $newTagTable);
                     if (defined $subdir and length $subdir) {
                         if ($subdirStart) {
@@ -421,5 +422,5 @@
                 if ($delTag{$tagID}) {
                     $verbose > 1 and print $out "    - CanonRaw:$$tagInfo{Name}\n";
-                    ++$exifTool->{CHANGED};
+                    ++$$et{CHANGED};
                     next;   # next since we already added this tag
                 }
@@ -430,7 +431,7 @@
                     $oldVal = $value;
                 }
-                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-                if (Image::ExifTool::IsOverwriting($nvHash, $oldVal)) {
-                    my $newVal = Image::ExifTool::GetNewValues($nvHash);
+                my $nvHash = $et->GetNewValueHash($tagInfo);
+                if ($et->IsOverwriting($nvHash, $oldVal)) {
+                    my $newVal = $et->GetNewValue($nvHash);
                     my $verboseVal;
                     $verboseVal = $newVal if $verbose > 1;
@@ -441,7 +442,7 @@
                     if (defined $newVal) {
                         $value = $newVal;
-                        ++$exifTool->{CHANGED};
-                        $exifTool->VerboseValue("- CanonRaw:$$tagInfo{Name}", $oldVal);
-                        $exifTool->VerboseValue("+ CanonRaw:$$tagInfo{Name}", $verboseVal);
+                        ++$$et{CHANGED};
+                        $et->VerboseValue("- CanonRaw:$$tagInfo{Name}", $oldVal);
+                        $et->VerboseValue("+ CanonRaw:$$tagInfo{Name}", $verboseVal);
                     }
                 }
@@ -454,5 +455,5 @@
                 $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);
             }
@@ -505,5 +506,5 @@
 sub WriteCRW($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $outfile = $$dirInfo{OutFile};
     my $raf = $$dirInfo{RAF};
@@ -519,16 +520,16 @@
     my $hlen = Get32u(\$buff, 0);   # get header length
 
-    if ($exifTool->{DEL_GROUP}->{MakerNotes}) {
+    if ($$et{DEL_GROUP}{MakerNotes}) {
         if ($type eq 'CCDR') {
-            $exifTool->Error("Can't delete MakerNotes group in CRW file");
+            $et->Error("Can't delete MakerNotes from CRW");
             return 0;
         } else {
-            ++$exifTool->{CHANGED};
+            ++$$et{CHANGED};
             return 1;
         }
     }
     # make XMP the preferred group for CRW files
-    if ($$exifTool{FILE_TYPE} eq 'CRW') {
-        $exifTool->InitWriteDirs(\%crwMap, 'XMP');
+    if ($$et{FILE_TYPE} eq 'CRW') {
+        $et->InitWriteDirs(\%crwMap, 'XMP');
     }
 
@@ -554,5 +555,5 @@
     # process the raw directory
     my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::CanonRaw::Main');
-    my $success = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+    my $success = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
 
     my $trailPt;
@@ -563,5 +564,5 @@
         $buff = '';
         $$trailInfo{OutFile} = \$buff;
-        $success = $exifTool->ProcessTrailers($trailInfo) or last;
+        $success = $et->ProcessTrailers($trailInfo) or last;
         $trailPt = $$trailInfo{OutFile};
         # nothing to write if trailers were deleted
@@ -571,11 +572,11 @@
     if ($success) {
         # add CanonVRD trailer if writing as a block
-        $trailPt = $exifTool->AddNewTrailers($trailPt,'CanonVRD');
-        if (not $trailPt and $$exifTool{ADD_DIRS}{CanonVRD}) {
+        $trailPt = $et->AddNewTrailers($trailPt,'CanonVRD');
+        if (not $trailPt and $$et{ADD_DIRS}{CanonVRD}) {
             # create CanonVRD from scratch if necessary
             my $outbuff = '';
             my $saveOrder = GetByteOrder();
             require Image::ExifTool::CanonVRD;
-            if (Image::ExifTool::CanonVRD::ProcessCanonVRD($exifTool, { OutFile => \$outbuff }) > 0) {
+            if (Image::ExifTool::CanonVRD::ProcessCanonVRD($et, { OutFile => \$outbuff }) > 0) {
                 $trailPt = \$outbuff;
             }
@@ -592,5 +593,5 @@
         $rtnVal = $err ? -1 : 1;
     } else {
-        $exifTool->Error('Error rewriting CRW file');
+        $et->Error('Error rewriting CRW file');
     }
     return $rtnVal;
@@ -617,11 +618,11 @@
 
 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-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -632,5 +633,5 @@
 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
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteExif.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteExif.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteExif.pl	(revision 34921)
@@ -14,6 +14,4 @@
 
 use Image::ExifTool::Fixup;
-
-sub InsertWritableProperties($$;$);
 
 # some information may be stored in different IFD's with the same meaning.
@@ -41,5 +39,5 @@
     },
     ExifIFD => {
-        0x9000 => '0230',   # ExifVersion
+        0x9000 => '0232',   # ExifVersion
         0x9101 => "1 2 3 0",# ComponentsConfiguration
         0xa000 => '0100',   # FlashpixVersion
@@ -56,1032 +54,4 @@
 );
 
-# The main EXIF table is unique because the tags from this table may appear
-# in many different directories.  For this reason, we introduce a
-# "WriteGroup" member to the tagInfo that tells us the preferred location
-# for writing each tag.  Here is the lookup for Writable flag (format)
-# and WriteGroup for all writable tags
-# - WriteGroup is ExifIFD unless otherwise specified
-# - Protected is 1 if the tag shouldn't be copied with SetNewValuesFromFile()
-my %writeTable = (
-    0x0001 => {             # InteropIndex
-        Protected => 1,
-        Writable => 'string',
-        WriteGroup => 'InteropIFD',
-    },
-    0x0002 => {             # InteropVersion
-        Protected => 1,
-        Writable => 'undef',
-        Mandatory => 1,
-        WriteGroup => 'InteropIFD',
-    },
-    0x000b => {             # ProcessingSoftware
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x00fe => {             # SubfileType
-        Protected => 1,
-        Writable => 'int32u',
-        WriteGroup => 'IFD0',
-    },
-    0x00ff => {             # OldSubfileType
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0100 => {             # ImageWidth
-        Protected => 1,
-        Writable => 'int32u',
-        WriteGroup => 'IFD0',
-    },
-    0x0101 => {             # ImageHeight
-        Protected => 1,
-        Writable => 'int32u',
-        WriteGroup => 'IFD0',
-    },
-    0x0102 => {             # BitsPerSample
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Count => -1, # can be 1 or 3: -1 means 'variable'
-    },
-    0x0103 => {             # Compression
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Mandatory => 1,
-    },
-    0x0106 => {             # PhotometricInterpretation
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0107 => {             # Thresholding
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0108 => {             # CellWidth
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0109 => {             # CellLength
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x010a => {             # FillOrder
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x010d => {             # DocumentName
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x010e => {             # ImageDescription
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x010f => {             # Make
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x0110 => {             # Model
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x0112 => {             # Orientation
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0115 => {             # SamplesPerPixel
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0116 => {             # RowsPerStrip
-        Protected => 1,
-        Writable => 'int32u',
-        WriteGroup => 'IFD0',
-    },
-    0x0118 => {             # MinSampleValue
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0119 => {             # MaxSampleValue
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x011a => {             # XResolution
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Mandatory => 1,
-    },
-    0x011b => {             # YResolution
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Mandatory => 1,
-    },
-    0x011c => {             # PlanarConfiguration
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x011d => {             # PageName
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x011e => {             # XPosition
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-    },
-    0x011f => {             # YPosition
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-    },
-    0x0122 => {             # GrayResponseUnit
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0128 => {             # ResolutionUnit
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Mandatory => 1,
-    },
-    0x0129 => {             # PageNumber
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Count => 2,
-    },
-    0x012d => {             # TransferFunction
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Count => 768,
-    },
-    0x0131 => {             # Software
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x0132 => {             # ModifyDate
-        Writable => 'string',
-        Shift => 'Time',
-        WriteGroup => 'IFD0',
-        PrintConvInv => '$self->InverseDateTime($val,0)',
-    },
-    0x013b => {             # Artist
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x013c => {             # HostComputer
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x013d => {             # Predictor
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x013e => {             # WhitePoint
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Count => 2,
-    },
-    0x013f => {             # PrimaryChromaticities
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Count => 6,
-    },
-    0x0141 => {             # HalftoneHints
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Count => 2,
-    },
-    0x0142 => {             # TileWidth
-        Protected => 1,
-        Writable => 'int32u',
-        WriteGroup => 'IFD0',
-    },
-    0x0143 => {             # TileLength
-        Protected => 1,
-        Writable => 'int32u',
-        WriteGroup => 'IFD0',
-    },
-    0x014c => {             # InkSet
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0x0150 => {             # TargetPrinter
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x013c => {             # HostComputer
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x0211 => {             # YCbCrCoefficients
-        Protected => 1,
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Count => 3,
-    },
-    0x0212 => {             # YCbCrSubSampling
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Count => 2,
-    },
-    0x0213 => {             # YCbCrPositioning
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Mandatory => 1,
-    },
-    0x0214 => {             # ReferenceBlackWhite
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Count => 6,
-    },
-    0x1000 => {             # RelatedImageFileFormat
-        Protected => 1,
-        Writable => 'string',
-        WriteGroup => 'InteropIFD',
-    },
-    0x1001 => {             # RelatedImageWidth
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'InteropIFD',
-    },
-    0x1002 => {             # RelatedImageHeight (more commonly RelatedImageLength)
-        Protected => 1,
-        Writable => 'int16u',
-        WriteGroup => 'InteropIFD',
-    },
-    0x4746 => {             # Rating (MicrosoftPhoto)
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Avoid => 1,
-    },
-    0x4749 => {             # RatingPercent (MicrosoftPhoto)
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Avoid => 1,
-    },
-    0x8298 => {             # Copyright
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        RawConvInv => q{
-            if ($val =~ /(.*?)\s*[\n\r]+\s*(.*)/s) {
-                return $1 . "\0" unless length $2;
-                # photographer copyright set to ' ' if it doesn't exist, according to spec.
-                return((length($1) ? $1 : ' ') . "\0" . $2 . "\0");
-            }
-            return $val . "\0";
-        },
-    },
-#
-# Most of the tags below this belong in the ExifIFD...
-#
-    0x829a => {             # ExposureTime
-        Writable => 'rational64u',
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
-    },
-    0x829d => {             # FNumber
-        Writable => 'rational64u',
-        PrintConvInv => '$val',
-    },
-    0x8546 => {             # SEMInfo
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0x8822 => 'int16u',     # ExposureProgram
-    0x8824 => 'string',     # SpectralSensitivity
-    0x8827 => {             # ISO
-        Writable => 'int16u',
-        Count => -1,
-        PrintConvInv => '$val=~tr/,//d; $val',
-    },
-    0x882a => {             # TimeZoneOffset
-        Writable => 'int16s',
-        Count => -1, # can be 1 or 2
-        Notes => q{
-            1 or 2 values: 1. The time zone offset of DateTimeOriginal from GMT in
-            hours, 2. If present, the time zone offset of ModifyDate
-        },
-    },
-    0x882b => 'int16u',     # SelfTimerMode
-    0x8830 => 'int16u',     # SensitivityType
-    0x8831 => 'int32u',     # StandardOutputSensitivity
-    0x8832 => 'int32u',     # RecommendedExposureIndex
-    0x8833 => 'int32u',     # ISOSpeed
-    0x8834 => 'int32u',     # ISOSpeedLatitudeyyy
-    0x8835 => 'int32u',     # ISOSpeedLatitudezzz
-    0x9000 => {             # ExifVersion
-        Writable => 'undef',
-        Mandatory => 1,
-    },
-    0x9003 => {             # DateTimeOriginal
-        Writable => 'string',
-        Shift => 'Time',
-        PrintConvInv => '$self->InverseDateTime($val,0)',
-    },
-    0x9004 => {             # CreateDate
-        Writable => 'string',
-        Shift => 'Time',
-        PrintConvInv => '$self->InverseDateTime($val,0)',
-    },
-    0x9101 => {             # ComponentsConfiguration
-        Protected => 1,
-        Writable => 'undef',
-        Count => 4,
-        Mandatory => 1,
-        ValueConvInv => '$val=~tr/,//d; $val',  # (so we can copy from XMP with -n)
-    },
-    0x9102 => {             # CompressedBitsPerPixel
-        Protected => 1,
-        Writable => 'rational64u',
-    },
-    0x9201 => {             # ShutterSpeedValue
-        Writable => 'rational64s',
-        ValueConvInv => '$val>0 ? -log($val)/log(2) : -100',
-        # do eval to convert things like '1/100'
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
-    },
-    0x9202 => {             # ApertureValue
-        Writable => 'rational64u',
-        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
-        PrintConvInv => '$val',
-    },
-    0x9203 => 'rational64s',# BrightnessValue
-    0x9204 => {             # ExposureCompensation
-        Writable => 'rational64s',
-        # do eval to convert things like '+2/3'
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
-    },
-    0x9205 => {             # MaxApertureValue
-        Writable => 'rational64u',
-        ValueConvInv => '$val>0 ? 2*log($val)/log(2) : 0',
-        PrintConvInv => '$val',
-    },
-    0x9206 => {             # SubjectDistance
-        Writable => 'rational64u',
-        PrintConvInv => '$val=~s/\s*m$//;$val',
-    },
-    0x9207 => 'int16u',     # MeteringMode
-    0x9208 => 'int16u',     # LightSource
-    0x9209 => 'int16u',     # Flash
-    0x920a => {             # FocalLength
-        Writable => 'rational64u',
-        PrintConvInv => '$val=~s/\s*mm$//;$val',
-    },
-    0x9211 => 'int32u',     # ImageNumber
-    0x9212 => 'string',     # SecurityClassification
-    0x9213 => 'string',     # ImageHistory
-    0x9214 => {             # SubjectArea
-        Writable => 'int16u',
-        Count => -1, # 2, 3 or 4 values
-    },
-#    0x927c => 'undef',      # MakerNotes
-    0x9286 => {             # UserComment
-        Writable => 'undef',
-        #  (starts with "ASCII\0\0\0", "UNICODE\0", "JIS\0\0\0\0\0" or "\0\0\0\0\0\0\0\0")
-        RawConvInv => 'Image::ExifTool::Exif::EncodeExifText($self,$val)',
-        # SHOULD ADD SPECIAL LOGIC TO ALLOW CONDITIONAL OVERWRITE OF
-        # "UNKNOWN" VALUES FILLED WITH SPACES
-    },
-    0x9290 => {             # SubSecTime
-        Writable => 'string',
-        # extract fractional seconds from a full date/time value
-        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
-    },
-    0x9291 => {             # SubSecTimeOriginal
-        Writable => 'string',
-        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
-    },
-    0x9292 => {             # SubSecTimeDigitized
-        Writable => 'string',
-        ValueConvInv => '$val=~/^(\d+)\s*$/ ? $1 : ($val=~/\.(\d+)/ ? $1 : undef)',
-    },
-    0x935c => {             # ImageSourceData
-        Writable => 'undef',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-#    0x9928 => 'undef',      # Opto-ElectricConversionFactor
-    0x9c9b => {             # XPTitle
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        Notes => q{
-            tags 0x9c9b-0x9c9f are used by Windows Explorer; special characters
-            in these values are converted to UTF-8 by default, or Windows Latin1
-            with the -L option.  XPTitle is ignored by Windows Explorer if
-            ImageDescription exists
-        },
-        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
-    },
-    0x9c9c => {             # XPComment
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
-    },
-    0x9c9d => {             # XPAuthor
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        Notes => 'ignored by Windows Explorer if Artist exists',
-        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
-    },
-    0x9c9e => {             # XPKeywords
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
-    },
-    0x9c9f => {             # XPSubject
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        ValueConvInv => '$self->Encode($val,"UCS2","II") . "\0\0"',
-    },
-    0xa000 => {             # FlashpixVersion
-        Writable => 'undef',
-        Mandatory => 1,
-    },
-    0xa001 => {             # ColorSpace
-        Writable => 'int16u',
-        Mandatory => 1,
-    },
-    0xa002 => {             # ExifImageWidth (could also be int32u)
-        Writable => 'int16u',
-        Mandatory => 1,
-    },
-    0xa003 => {             # ExifImageHeight (could also be int32u)
-        Writable => 'int16u',
-        Mandatory => 1,
-    },
-    0xa004 => 'string',     # RelatedSoundFile
-    0xa20b => {             # FlashEnergy
-        Writable => 'rational64u',
-        Count => -1, # 1 or 2 (ref 12)
-    },
-#    0xa20c => 'undef',      # SpatialFrequencyResponse
-    0xa20e => 'rational64u',# FocalPlaneXResolution
-    0xa20f => 'rational64u',# FocalPlaneYResolution
-    0xa210 => 'int16u',     # FocalPlaneResolutionUnit
-    0xa214 => {             # SubjectLocation
-        Writable => 'int16u',
-        Count => 2,
-    },
-    0xa215 => 'rational64u',# ExposureIndex
-    0xa217 => 'int16u',     # SensingMethod
-    0xa300 => {             # FileSource
-        Writable => 'undef',
-        ValueConvInv => '($val=~/^\d+$/ and $val < 256) ? chr($val) : $val',
-    },
-    0xa301 => {             # SceneType
-        Writable => 'undef',
-        ValueConvInv => 'chr($val)',
-    },
-    0xa302 => {             # CFAPattern
-        Writable => 'undef',
-        PrintConvInv => 'Image::ExifTool::Exif::GetCFAPattern($val)',
-    },
-    0xa401 => 'int16u',     # CustomRendered
-    0xa402 => 'int16u',     # ExposureMode
-    0xa403 => 'int16u',     # WhiteBalance
-    0xa404 => 'rational64u',# DigitalZoomRatio
-    0xa405 => {             # FocalLengthIn35mmFormat
-        Writable => 'int16u',
-        PrintConvInv => '$val=~s/\s*mm$//;$val',
-    },
-    0xa406 => 'int16u',     # SceneCaptureType
-    0xa407 => 'int16u',     # GainControl
-    0xa408 => {             # Contrast
-        Writable => 'int16u',
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
-    },
-    0xa409 => {             # Saturation
-        Writable => 'int16u',
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
-    },
-    0xa40a => {             # Sharpness
-        Writable => 'int16u',
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertParameter($val)',
-    },
-#    0xa40b => 'undef',      # DeviceSettingDescription
-    0xa40c => 'int16u',     # SubjectDistanceRange
-    0xa420 => 'string',     # ImageUniqueID
-    0xa430 => 'string',     # OwnerName
-    0xa431 => 'string',     # SerialNumber
-    0xa432 => {             # LensInfo
-        Writable => 'rational64u',
-        Count => 4,
-        PrintConvInv => \&ConvertLensInfo,
-    },
-    0xa433 => 'string',     # LensMake
-    0xa434 => 'string',     # LensModel
-    0xa435 => 'string',     # LensSerialNumber
-    0xa500 => 'rational64u',# Gamma
-#
-# DNG stuff (back in IFD0)
-#
-    0xc612 => {             # DNGVersion
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        Count => 4,
-        Protected => 1, # (confuses Apple Preview if written to a TIFF image)
-        PrintConvInv => '$val =~ tr/./ /; $val',
-    },
-    0xc613 => {             # DNGBackwardVersion
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        Count => 4,
-        Protected => 1,
-    },
-    0xc614 => {             # UniqueCameraModel
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0xc615 => {             # LocalizedCameraModel
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        PrintConvInv => '$val',
-    },
-    0xc619 => {             # BlackLevelRepeatDim
-        Writable => 'int16u',
-        WriteGroup => 'SubIFD',
-        Count => 2,
-        Protected => 1,
-    },
-    0xc61a => {             # BlackLevel
-        Writable => 'rational64u',
-        WriteGroup => 'SubIFD',
-        Count => -1,
-        Protected => 1,
-    },
-    0xc61d => {             # WhiteLevel
-        Writable => 'int32u',
-        WriteGroup => 'SubIFD',
-        Count => -1,
-        Protected => 1,
-    },
-    0xc61e => {             # DefaultScale
-        Writable => 'rational64u',
-        WriteGroup => 'SubIFD',
-        Count => 2,
-        Protected => 1,
-    },
-    0xc61f => {             # DefaultCropOrigin
-        Writable => 'int32u',
-        WriteGroup => 'SubIFD',
-        Count => 2,
-        Protected => 1,
-    },
-    0xc620 => {             # DefaultCropSize
-        Writable => 'int32u',
-        WriteGroup => 'SubIFD',
-        Count => 2,
-        Protected => 1,
-    },
-    0xc621 => {             # ColorMatrix1
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc622 => {             # ColorMatrix2
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc623 => {             # CameraCalibration1
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc624 => {             # CameraCalibration2
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc625 => {             # ReductionMatrix1
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc626 => {             # ReductionMatrix2
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc627 => {             # AnalogBalance
-        Writable => 'rational64u',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc628 => {             # AsShotNeutral
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Count => -1,
-        Protected => 1,
-    },
-    0xc629 => {             # AsShotWhiteXY
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Count => 2,
-        Protected => 1,
-    },
-    0xc62a => {             # BaselineExposure
-        Writable => 'rational64s',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc62b => {             # BaselineNoise
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc62c => {             # BaselineSharpness
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc62d => {             # BayerGreenSplit
-        Writable => 'int32u',
-        WriteGroup => 'SubIFD',
-        Protected => 1,
-    },
-    0xc62e => {             # LinearResponseLimit
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc62f => {             # CameraSerialNumber
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-    },
-    0xc630 => {             # DNGLensInfo
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Count => 4,
-        PrintConvInv => \&ConvertLensInfo,
-    },
-    0xc631 => {             # ChromaBlurRadius
-        Writable => 'rational64u',
-        WriteGroup => 'SubIFD',
-        Protected => 1,
-    },
-    0xc632 => {             # AntiAliasStrength
-        Writable => 'rational64u',
-        WriteGroup => 'SubIFD',
-        Protected => 1,
-    },
-    0xc633 => {             # ShadowScale
-        Writable => 'rational64u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc635 => {             # MakerNoteSafety
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-    },
-    0xc65a => {             # CalibrationIlluminant1
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc65b => {             # CalibrationIlluminant2
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc65c => {             # BestQualityScale
-        Writable => 'rational64u',
-        WriteGroup => 'SubIFD',
-        Protected => 1,
-    },
-    0xc65d => {             # RawDataUniqueID
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        Count => 16,
-        ValueConvInv => 'pack("H*", $val)',
-        Protected => 1,
-    },
-    0xc68b => {             # OriginalRawFileName
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc68d => {             # ActiveArea
-        Writable => 'int32u',
-        WriteGroup => 'SubIFD',
-        Count => 4,
-        Protected => 1,
-    },
-    0xc68e => {             # MaskedAreas
-        Writable => 'int32u',
-        WriteGroup => 'SubIFD',
-        Count => 4,
-        Protected => 1,
-    },
-    0xc68f => {             # AsShotICCProfile (writable directory)
-        WriteGroup => 'IFD0',
-        Protected => 1,
-        WriteCheck => q{
-            require Image::ExifTool::ICC_Profile;
-            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
-        },
-    },
-    0xc690 => {             # AsShotPreProfileMatrix
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc691 => {             # CurrentICCProfile (writable directory)
-        Writable => 'undef',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-        WriteCheck => q{
-            require Image::ExifTool::ICC_Profile;
-            return Image::ExifTool::ICC_Profile::ValidateICC(\$val);
-        },
-    },
-    0xc692 => {             # CurrentPreProfileMatrix
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6bf => {             # ColorimetricReference
-        Writable => 'int16u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6d2 => {             # PanasonicTitle (Panasonic DMC-TZ5, not a DNG tag)
-        Writable => 'undef',
-        WriteGroup => 'IFD0',
-        ValueConvInv => '$self->Encode($val,"UTF8")',
-    },
-    0xc6d3 => {             # PanasonicTitle2 (Panasonic DMC-FS7, not a DNG tag)
-        Writable => 'undef',
-        WriteGroup => 'IFD0',
-        ValueConvInv => '$self->Encode($val,"UTF8")',
-    },
-    0xc6f3 => {             # CameraCalibrationSig
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6f4 => {             # ProfileCalibrationSig
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6f6 => {             # AsShotProfileName
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6f7 => {             # NoiseReductionApplied
-        Writable => 'rational64u',
-        WriteGroup => 'SubIFD',
-        Protected => 1,
-    },
-    0xc6f8 => {             # ProfileName
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6f9 => {             # ProfileHueSatMapDims
-        Writable => 'int32u',
-        Count => 3,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6fa => {             # ProfileHueSatMapData1
-        Writable => 'float',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6fb => {             # ProfileHueSatMapData2
-        Writable => 'float',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6fc => {             # ProfileToneCurve
-        Writable => 'float',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6fd => {             # ProfileEmbedPolicy
-        Writable => 'int32u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc6fe => {             # ProfileCopyright
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc714 => {             # ForwardMatrix1
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc715 => {             # ForwardMatrix2
-        Writable => 'rational64s',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc716 => {             # PreviewApplicationName
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc717 => {             # PreviewApplicationVersion
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc718 => {             # PreviewSettingsName
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc719 => {             # PreviewSettingsDigest
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-        ValueConvInv => 'pack("H*", $val)',
-    },
-    0xc71a => {             # PreviewColorSpace
-        Writable => 'int32u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-        PrintConv => {
-            0 => 'Unknown',
-            1 => 'Gray Gamma 2.2',
-            2 => 'sRGB',
-            3 => 'Adobe RGB',
-            4 => 'ProPhoto RGB',
-        },
-    },
-    0xc71b => {             # PreviewDateTime
-        Writable => 'string',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-        ValueConvInv => q{
-            require Image::ExifTool::XMP;
-            return Image::ExifTool::XMP::FormatXMPDate($val);
-        },
-        PrintConvInv => '$self->InverseDateTime($val,1,1)',
-    },
-    0xc71c => {             # RawImageDigest
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-        ValueConvInv => 'pack("H*", $val)',
-    },
-    0xc71d => {             # OriginalRawFileDigest
-        Writable => 'int8u',
-        WriteGroup => 'IFD0',
-        Protected => 1,
-        ValueConvInv => 'pack("H*", $val)',
-    },
-    0xc725 => {             # ProfileLookTableDims
-        Writable => 'int32u',
-        Count => 3,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xc726 => {             # ProfileLookTableData
-        Writable => 'float',
-        Count => -1,
-        WriteGroup => 'IFD0',
-        Protected => 1,
-    },
-    0xea1d => {             # OffsetSchema
-        Writable => 'int32s',
-    },
-    # tags produced by Photoshop Camera RAW
-    # (avoid creating these tags unless there is no other option)
-    0xfde8 => {
-        Name => 'OwnerName',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Owner's Name: $val"},
-        Notes => q{
-            tags 0xfde8-0xfdea and 0xfe4c-0xfe58 are generated by Photoshop Camera RAW.
-            Some names are the same as other EXIF tags, but ExifTool will avoid writing
-            these unless they already exist in the file
-        },
-    },
-    0xfde9 => {
-        Name => 'SerialNumber',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Serial Number: $val"},
-    },
-    0xfdea => {
-        Name => 'Lens',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Lens: $val"},
-    },
-    0xfe4c => {
-        Name => 'RawFile',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Raw File: $val"},
-    },
-    0xfe4d => {
-        Name => 'Converter',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Converter: $val"},
-    },
-    0xfe4e => {
-        Name => 'WhiteBalance',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"White Balance: $val"},
-    },
-    0xfe51 => {
-        Name => 'Exposure',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Exposure: $val"},
-    },
-    0xfe52 => {
-        Name => 'Shadows',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Shadows: $val"},
-    },
-    0xfe53 => {
-        Name => 'Brightness',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Brightness: $val"},
-    },
-    0xfe54 => {
-        Name => 'Contrast',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Contrast: $val"},
-    },
-    0xfe55 => {
-        Name => 'Saturation',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Saturation: $val"},
-    },
-    0xfe56 => {
-        Name => 'Sharpness',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Sharpness: $val"},
-    },
-    0xfe57 => {
-        Name => 'Smoothness',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Smoothness: $val"},
-    },
-    0xfe58 => {
-        Name => 'MoireFilter',
-        Avoid => 1,
-        Writable => 'string',
-        ValueConv => '$val=~s/.*: //;$val',
-        ValueConvInv => q{"Moire Filter: $val"},
-    },
-);
-
-# insert our writable properties into main EXIF tag table
-InsertWritableProperties(\%Image::ExifTool::Exif::Main, \%writeTable, \&CheckExif);
-
 #------------------------------------------------------------------------------
 # Inverse print conversion for LensInfo
@@ -1097,6 +67,6 @@
 #------------------------------------------------------------------------------
 # Get binary CFA Pattern from a text string
-# Inputs: CFA pattern string (ie. '[Blue,Green][Green,Red]')
-# Returns: Binary CFA data or prints warning and returns undef on error
+# Inputs: Print-converted CFA pattern (eg. '[Blue,Green][Green,Red]')
+# Returns: CFA pattern as a string of numbers
 sub GetCFAPattern($)
 {
@@ -1107,5 +77,5 @@
     @cols or warn("Colors not separated by ','\n"), return undef;
     my $ny = @cols;
-    my $rtnVal = Set16u(scalar(@rows)) . Set16u(scalar(@cols));
+    my @a = (scalar(@rows), scalar(@cols));
     my %cfaLookup = (red=>0, green=>1, blue=>2, cyan=>3, magenta=>4, yellow=>5, white=>6);
     my $row;
@@ -1116,9 +86,9 @@
             tr/ \]\[//d;    # remove remaining brackets and any spaces
             my $c = $cfaLookup{lc($_)};
-            defined $c or warn("Unknown color '$_'\n"), return undef;
-            $rtnVal .= Set8u($c);
+            defined $c or warn("Unknown color '${_}'\n"), return undef;
+            push @a, $c;
         }
     }
-    return $rtnVal;
+    return "@a";
 }
 
@@ -1129,8 +99,8 @@
 sub CheckExif($$$)
 {
-    my ($exifTool, $tagInfo, $valPtr) = @_;
-    my $format = $$tagInfo{Format} || $$tagInfo{Writable} || $tagInfo->{Table}{WRITABLE};
+    my ($et, $tagInfo, $valPtr) = @_;
+    my $format = $$tagInfo{Format} || $$tagInfo{Writable} || $$tagInfo{Table}{WRITABLE};
     if (not $format or $format eq '1') {
-        if ($tagInfo->{Groups}{0} eq 'MakerNotes') {
+        if ($$tagInfo{Groups}{0} eq 'MakerNotes') {
             return undef;   # OK to have no format for makernotes
         } else {
@@ -1148,9 +118,9 @@
 sub EncodeExifText($$)
 {
-    my ($exifTool, $val) = @_;
+    my ($et, $val) = @_;
     # does the string contain special characters?
     if ($val =~ /[\x80-\xff]/) {
-        my $order = $exifTool->GetNewValues('ExifUnicodeByteOrder');
-        return "UNICODE\0" . $exifTool->Encode($val,'UCS2',$order);
+        my $order = $et->GetNewValue('ExifUnicodeByteOrder');
+        return "UNICODE\0" . $et->Encode($val,'UTF16',$order);
     } else {
         return "ASCII\0\0\0$val";
@@ -1159,41 +129,11 @@
 
 #------------------------------------------------------------------------------
-# insert writable properties into main tag table
-# Inputs: 0) tag table ref, 1) reference to writable properties
-#         2) [optional] CHECK_PROC reference
-sub InsertWritableProperties($$;$)
-{
-    my ($tagTablePtr, $writeTablePtr, $checkProc) = @_;
-    my $tag;
-    $checkProc and $tagTablePtr->{CHECK_PROC} = $checkProc;
-    foreach $tag (keys %$writeTablePtr) {
-        my $writeInfo = $$writeTablePtr{$tag};
-        my @infoList = GetTagInfoList($tagTablePtr, $tag);
-        if (@infoList) {
-            my $tagInfo;
-            foreach $tagInfo (@infoList) {
-                if (ref $writeInfo) {
-                    my $key;
-                    foreach $key (%$writeInfo) {
-                        $$tagInfo{$key} = $$writeInfo{$key} unless defined $$tagInfo{$key};
-                    }
-                } else {
-                    $$tagInfo{Writable} = $writeInfo unless defined $$tagInfo{Writable};
-                }
-            }
-        } else {
-            Image::ExifTool::AddTagToTable($tagTablePtr, $tag, $writeInfo);
-        }
-    }
-}
-
-#------------------------------------------------------------------------------
 # rebuild maker notes to properly contain all value data
 # (some manufacturers put value data outside maker notes!!)
-# Inputs: 0) ExifTool object ref, 1) tag table ref, 2) dirInfo ref
+# Inputs: 0) ExifTool object ref, 1) dirInfo ref, 2) tag table ref
 # Returns: new maker note data (and creates MAKER_NOTE_FIXUP), or undef on error
 sub RebuildMakerNotes($$$)
 {
-    my ($exifTool, $tagTablePtr, $dirInfo) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dirStart = $$dirInfo{DirStart};
     my $dirLen = $$dirInfo{DirLen};
@@ -1203,5 +143,5 @@
     my %subdirInfo = %$dirInfo;
 
-    delete $exifTool->{MAKER_NOTE_FIXUP};
+    delete $$et{MAKER_NOTE_FIXUP};
 
     # don't need to rebuild text, BinaryData or PreviewImage maker notes
@@ -1217,9 +157,13 @@
     }
     my $saveOrder = GetByteOrder();
-    my $loc = Image::ExifTool::MakerNotes::LocateIFD($exifTool,\%subdirInfo);
+    my $loc = Image::ExifTool::MakerNotes::LocateIFD($et,\%subdirInfo);
     if (defined $loc) {
         my $makerFixup = $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
         # create new exiftool object to rewrite the directory without changing it
         my $newTool = new Image::ExifTool;
+        $newTool->Options(
+            IgnoreMinorErrors => $$et{OPTIONS}{IgnoreMinorErrors},
+            FixBase           => $$et{OPTIONS}{FixBase},
+        );
         $newTool->Init();   # must do this before calling WriteDirectory()!
         # don't copy over preview image
@@ -1227,24 +171,24 @@
         # copy all transient members over in case they are used for writing
         # (Make, Model, etc)
-        foreach (grep /[a-z]/, keys %$exifTool) {
-            $$newTool{$_} = $$exifTool{$_};
+        foreach (grep /[a-z]/, keys %$et) {
+            $$newTool{$_} = $$et{$_};
         }
         # fix base offsets if specified
-        $newTool->Options(FixBase => $exifTool->Options('FixBase'));
+        $newTool->Options(FixBase => $et->Options('FixBase'));
         # set GENERATE_PREVIEW_INFO flag so PREVIEW_INFO will be generated
-        $newTool->{GENERATE_PREVIEW_INFO} = 1;
+        $$newTool{GENERATE_PREVIEW_INFO} = 1;
         # drop any large tags
-        $newTool->{DROP_TAGS} = 1;
+        $$newTool{DropTags} = 1;
         # initialize other necessary data members
-        $newTool->{FILE_TYPE} = $exifTool->{FILE_TYPE};
-        $newTool->{TIFF_TYPE} = $exifTool->{TIFF_TYPE};
+        $$newTool{FILE_TYPE} = $$et{FILE_TYPE};
+        $$newTool{TIFF_TYPE} = $$et{TIFF_TYPE};
         # rewrite maker notes
         $rtnValue = $newTool->WriteDirectory(\%subdirInfo, $tagTablePtr);
         if (defined $rtnValue and length $rtnValue) {
             # add the dummy/empty preview image if necessary
-            if ($newTool->{PREVIEW_INFO}) {
+            if ($$newTool{PREVIEW_INFO}) {
                 $makerFixup->SetMarkerPointers(\$rtnValue, 'PreviewImage', length($rtnValue));
-                $rtnValue .= $newTool->{PREVIEW_INFO}{Data};
-                delete $newTool->{PREVIEW_INFO};
+                $rtnValue .= $$newTool{PREVIEW_INFO}{Data};
+                delete $$newTool{PREVIEW_INFO};
             }
             # add makernote header
@@ -1252,19 +196,26 @@
                 my $hdr = substr($$dataPt, $dirStart, $loc);
                 # special case: convert Pentax/Samsung DNG maker notes to JPEG style
-                # (in JPEG, Pentax makernotes are absolute and start with "AOC\0")
-                if ($hdr =~ s/^(PENTAX |SAMSUNG)\0/AOC\0/) {
-                    # save fixup so we will adjust to absolute offsets when writing
-                    $exifTool->{MAKER_NOTE_FIXUP} = $makerFixup;
+                # (in JPEG, Pentax makernotes are absolute and start with "AOC\0" for some
+                # models, but in DNG images they are stored in tag 0xc634 of IFD0 and
+                # start with either "PENTAX \0" or "SAMSUNG\0")
+                if ($$dirInfo{Parent} eq 'IFD0' and $hdr =~ /^(PENTAX |SAMSUNG)\0/) {
+                    # convert to JPEG-style AOC maker notes if used by this model
+                    # (Note: this expression also appears in Exif.pm)
+                    if ($$et{Model} =~ /\b(K(-[57mrx]|(10|20|100|110|200)D|2000)|GX(10|20))\b/) {
+                        $hdr =~ s/^(PENTAX |SAMSUNG)\0/AOC\0/;
+                        # save fixup because AOC maker notes have absolute offsets
+                        $$et{MAKER_NOTE_FIXUP} = $makerFixup;
+                    }
                 }
                 $rtnValue = $hdr . $rtnValue;
                 # adjust fixup for shift in start position
-                $makerFixup->{Start} += length $hdr;
+                $$makerFixup{Start} += length $hdr;
             }
             # shift offsets according to original position of maker notes,
             # and relative to the makernotes Base
-            $makerFixup->{Shift} += $dataPos + $dirStart +
-                                    $$dirInfo{Base} - $subdirInfo{Base};
+            $$makerFixup{Shift} += $dataPos + $dirStart +
+                                   $$dirInfo{Base} - $subdirInfo{Base};
             # repair incorrect offsets if offsets were fixed
-            $makerFixup->{Shift} += $subdirInfo{FixedBy} || 0;
+            $$makerFixup{Shift} += $subdirInfo{FixedBy} || 0;
             # fix up pointers to the specified offset
             $makerFixup->ApplyFixup(\$rtnValue);
@@ -1272,6 +223,6 @@
             unless ($subdirInfo{Relative}) {
                 # set shift so offsets are all relative to start of maker notes
-                $makerFixup->{Shift} -= $dataPos + $dirStart;
-                $exifTool->{MAKER_NOTE_FIXUP} = $makerFixup;    # save fixup for later
+                $$makerFixup{Shift} -= $dataPos + $dirStart;
+                $$et{MAKER_NOTE_FIXUP} = $makerFixup;    # save fixup for later
             }
         }
@@ -1284,11 +235,11 @@
 #------------------------------------------------------------------------------
 # Sort IFD directory entries
-# Inputs: 0) data reference, 1) directory start, 2) number of entries
-sub SortIFD($$$)
+# Inputs: 0) data reference, 1) directory start, 2) number of entries,
+#         3) flag to treat 0 as a valid tag ID (as opposed to an empty IFD entry)
+sub SortIFD($$$;$)
 {
-    my ($dataPt, $dirStart, $numEntries) = @_;
+    my ($dataPt, $dirStart, $numEntries, $allowZero) = @_;
     my ($index, %entries);
     # split the directory into separate entries
-    my $newDir = '';
     for ($index=0; $index<$numEntries; ++$index) {
         my $entry = $dirStart + 2 + 12 * $index;
@@ -1296,5 +247,5 @@
         my $entryData = substr($$dataPt, $entry, 12);
         # silly software can pad directories with zero entries -- put these at the end
-        $tagID = 0x10000 unless $tagID or $index == 0;
+        $tagID = 0x10000 unless $tagID or $index == 0 or $allowZero;
         # add new entry (allow for duplicate tag ID's, which shouldn't normally happen)
         if ($entries{$tagID}) {
@@ -1306,4 +257,6 @@
     # sort the directory entries
     my @sortedTags = sort { $a <=> $b } keys %entries;
+    # generate the sorted IFD
+    my $newDir = '';
     foreach (@sortedTags) {
         $newDir .= $entries{$_};
@@ -1382,9 +335,73 @@
 sub UpdateTiffEnd($$)
 {
-    my ($exifTool, $end) = @_;
-    if (defined $exifTool->{TIFF_END} and
-        $exifTool->{TIFF_END} < $end)
+    my ($et, $end) = @_;
+    if (defined $$et{TIFF_END} and
+        $$et{TIFF_END} < $end)
     {
-        $exifTool->{TIFF_END} = $end;
+        $$et{TIFF_END} = $end;
+    }
+}
+
+#------------------------------------------------------------------------------
+# Validate image data size
+# Inputs: 0) ExifTool ref, 1) validate info hash ref,
+#         2) flag to issue error (ie. we're writing)
+# - issues warning or error if problems found
+sub ValidateImageData($$$;$)
+{
+    local $_;
+    my ($et, $vInfo, $dirName, $errFlag) = @_;
+
+    # determine the expected size of the image data for an uncompressed image
+    # (0x102 BitsPerSample, 0x103 Compression and 0x115 SamplesPerPixel
+    #  all default to a value of 1 if they don't exist)
+    if ((not defined $$vInfo{0x103} or $$vInfo{0x103} eq '1') and
+        $$vInfo{0x100} and $$vInfo{0x101} and ($$vInfo{0x117} or $$vInfo{0x145}))
+    {
+        my $samplesPerPix = $$vInfo{0x115} || 1;
+        my @bitsPerSample = $$vInfo{0x102} ? split(' ',$$vInfo{0x102}) : (1) x $samplesPerPix;
+        my $byteCountInfo = $$vInfo{0x117} || $$vInfo{0x145};
+        my $byteCounts = $$byteCountInfo[1];
+        my $totalBytes = 0;
+        $totalBytes += $_ foreach split ' ', $byteCounts;
+        my $minor;
+        $minor = 1 if $$et{DOC_NUM} or $$et{FILE_TYPE} ne 'TIFF';
+        unless (@bitsPerSample == $samplesPerPix) {
+            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];
+                $et->WarnOnce("Invalid $dirName BitsPerSample value", $minor) if $_ < 1 or $_ > 32;
+            }
+        }
+        my $bitsPerPixel = 0;
+        $bitsPerPixel += $_ foreach @bitsPerSample;
+        my $expectedBytes = int(($$vInfo{0x100} * $$vInfo{0x101} * $bitsPerPixel + 7) / 8);
+        if ($expectedBytes != $totalBytes and
+            # (this problem seems normal for certain types of RAW files...)
+            $$et{TIFF_TYPE} !~ /^(K25|KDC|MEF|ORF|SRF)$/)
+        {
+            my ($adj, $minor);
+            if ($expectedBytes > $totalBytes) {
+                $adj = 'Under'; # undersized is a bigger problem because we may lose data
+                $minor = 0 unless $errFlag;
+            } else {
+                $adj = 'Over';
+                $minor = 1;
+            }
+            my $msg = "${adj}sized $dirName $$byteCountInfo[0]{Name} ($totalBytes bytes, but expected $expectedBytes)";
+            if (not defined $minor) {
+                # this is a serious error if we are writing the file and there
+                # is a chance that we may not copy all of the image data
+                # (but make it minor to allow the file to be written anyway)
+                $et->Error($msg, 1);
+            } else {
+                $et->Warn($msg, $minor);
+            }
+        }
     }
 }
@@ -1396,12 +413,12 @@
 sub ExifErr($$$)
 {
-    my ($exifTool, $errStr, $tagTablePtr) = @_;
+    my ($et, $errStr, $tagTablePtr) = @_;
     # MakerNote errors are minor by default
-    my $minor = ($tagTablePtr->{GROUPS}{0} eq 'MakerNotes');
-    if ($tagTablePtr->{VARS} and $tagTablePtr->{VARS}{MINOR_ERRORS}) {
-        $exifTool->Warn("$errStr. IFD dropped.") and return '' if $minor;
+    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;
     }
-    return undef if $exifTool->Error($errStr, $minor);
+    return undef if $et->Error($errStr, $minor);
     return '';
 }
@@ -1414,10 +431,10 @@
 sub ProcessTiffIFD($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access
     my $raf = $$dirInfo{RAF};
     my $base = $$dirInfo{Base} || 0;
     my $dirName = $$dirInfo{DirName};
-    my $magic = $dirInfo->{Subdir}{Magic} || 0x002a;
+    my $magic = $$dirInfo{Subdir}{Magic} || 0x002a;
     my $buff;
 
@@ -1427,8 +444,8 @@
         my $msg = "Invalid $dirName header";
         if ($$dirInfo{IsWriting}) {
-            $exifTool->Error($msg);
+            $et->Error($msg);
             return undef;
         } else {
-            $exifTool->Warn($msg);
+            $et->Warn($msg);
             return 0;
         }
@@ -1449,5 +466,5 @@
     if ($$dirInfo{IsWriting}) {
         # rewrite the Camera Profile IFD
-        my $newDir = WriteExif($exifTool, \%dirInfo, $tagTablePtr);
+        my $newDir = WriteExif($et, \%dirInfo, $tagTablePtr);
         # don't add header if error writing directory ($newDir is undef)
         # or if directory is being deleted ($newDir is empty)
@@ -1456,10 +473,10 @@
         return GetByteOrder() . Set16u($magic) . Set32u(8) . $newDir;
     }
-    if ($exifTool->{HTML_DUMP}) {
+    if ($$et{HTML_DUMP}) {
         my $tip = sprintf("Byte order: %s endian\nIdentifier: 0x%.4x\n%s offset: 0x%.4x",
                           (GetByteOrder() eq 'II') ? 'Little' : 'Big', $magic, $dirName, $offset);
-        $exifTool->HDump($base, 8, "$dirName header", $tip, 0);
+        $et->HDump($base, 8, "$dirName header", $tip, 0);
     }
-    return ProcessExif($exifTool, \%dirInfo, $tagTablePtr);
+    return ProcessExif($et, \%dirInfo, $tagTablePtr);
 }
 
@@ -1478,6 +495,6 @@
 sub WriteExif($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;      # allow dummy access to autoload this package
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;      # allow dummy access to autoload this package
     my $origDirInfo = $dirInfo; # save original dirInfo
     my $dataPt = $$dirInfo{DataPt};
@@ -1496,8 +513,8 @@
     my $fixup = $$dirInfo{Fixup} || new Image::ExifTool::Fixup;
     my $imageDataFlag = $$dirInfo{ImageData} || '';
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
     my ($nextIfdPos, %offsetData, $inMakerNotes);
-    my (@offsetInfo, %xDelete);
+    my (@offsetInfo, %validateInfo, %xDelete, $strEnc);
     my $deleteAll = 0;
     my $newData = '';   # initialize buffer to receive new directory data
@@ -1506,12 +523,22 @@
     $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';
+
     # allow multiple IFD's in IFD0-IFD1-IFD2... chain
     $$dirInfo{Multi} = 1 if $dirName =~ /^(IFD0|SubIFD)$/ and not defined $$dirInfo{Multi};
-    $inMakerNotes = 1 if $tagTablePtr->{GROUPS}{0} eq 'MakerNotes';
+    $inMakerNotes = 1 if $$tagTablePtr{GROUPS}{0} eq 'MakerNotes';
     my $ifd;
+
 #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 # loop through each IFD
 #
     for ($ifd=0; ; ++$ifd) {  # loop through multiple IFD's
+
+        # make sure that Compression and SubfileType are defined for this IFD (for Condition's)
+        $$et{Compression} = $$et{SubfileType} = '';
 
         # save pointer to start of this IFD within the newData
@@ -1522,5 +549,5 @@
         if ($dirStart < 0 or $dirStart > $dataLen-2) {
             $mustRead = 1;
-        } elsif ($dirLen > 2) {
+        } elsif ($dirLen >= 2) {
             my $len = 2 + 12 * Get16u($dataPt, $dirStart);
             $mustRead = 1 if $dirStart + $len > $dataLen;
@@ -1533,10 +560,10 @@
                 my ($buff, $buf2);
                 unless ($raf->Seek($offset + $base, 0) and $raf->Read($buff,2) == 2) {
-                    return ExifErr($exifTool, "Bad IFD or truncated file in $name", $tagTablePtr);
+                    return ExifErr($et, "Bad IFD or truncated file in $name", $tagTablePtr);
                 }
                 my $len = 12 * Get16u(\$buff,0);
                 # (also read next IFD pointer if available)
                 unless ($raf->Read($buf2, $len+4) >= $len) {
-                    return ExifErr($exifTool, "Error reading $name", $tagTablePtr);
+                    return ExifErr($et, "Error reading $name", $tagTablePtr);
                 }
                 $buff .= $buf2;
@@ -1552,10 +579,10 @@
                 # 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($exifTool, $offset+$base+2+$len);
-            } elsif ($dirLen) {
+                UpdateTiffEnd($et, $offset+$base+2+$len);
+            } 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 = $exifTool->Options('IgnoreMinorErrors') ? 'Deleted bad' : 'Bad';
-                $exifTool->Error("$str $name directory", 1);
+                my $str = $et->Options('IgnoreMinorErrors') ? 'Deleted bad' : 'Bad';
+                $et->Error("$str $name directory", 1);
             }
         }
@@ -1565,5 +592,8 @@
             $dirEnd = $dirStart + 2 + 12 * $numEntries;
             if ($dirEnd > $dataLen) {
-                return ExifErr($exifTool, "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)
@@ -1573,7 +603,7 @@
                     my $tagID = Get16u($dataPt, $dirStart + 2 + 12 * $index);
                     # check for proper sequence (but ignore null entries at end)
-                    if ($tagID < $lastID and $tagID) {
-                        SortIFD($dataPt, $dirStart, $numEntries);
-                        $exifTool->Warn("Entries in $name were out of sequence. Fixed.",1);
+                    if ($tagID < $lastID and ($tagID or $$tagTablePtr{0})) {
+                        SortIFD($dataPt, $dirStart, $numEntries, $$tagTablePtr{0});
+                        $et->Warn("Entries in $name were out of sequence. Fixed.",1);
                         last;
                     }
@@ -1587,86 +617,26 @@
 
         # loop through new values and accumulate all information for this IFD
-        my (%set, $tagInfo);
+        my (%set, %mayDelete, $tagInfo);
         my $wrongDir = $crossDelete{$dirName};
-        foreach $tagInfo ($exifTool->GetNewTagInfoList($tagTablePtr)) {
+        my @newTagInfo = $et->GetNewTagInfoList($tagTablePtr);
+        foreach $tagInfo (@newTagInfo) {
             my $tagID = $$tagInfo{TagID};
-            # evaluate conditional lists now if necessary
-            if (ref $tagTablePtr->{$tagID} eq 'ARRAY' or $$tagInfo{Condition}) {
-                my $curInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
-                if (defined $curInfo and not $curInfo) {
-                    # need value to evaluate the condition
-                    my ($val) = $exifTool->GetNewValues($tagInfo);
-                    # must convert to binary for evaluating in Condition
-                    if ($$tagInfo{Format} and defined $val) {
-                        $val = WriteValue($val, $$tagInfo{Format}, $$tagInfo{Count});
-                    }
-                    if (defined $val) {
-                        my $fmt = $$tagInfo{Writable} || $$tagInfo{Format} || 'undef';
-                        my $cnt = $$tagInfo{Count} || 1;
-                        # always use old format/count for Condition in maker notes
-                        if ($inMakerNotes) {
-                            for ($index=0; $index<$numEntries; ++$index) {
-                                my $entry = $dirStart + 2 + 12 * $index;
-                                my $id = Get16u($dataPt, $entry);
-                                if ($id eq $tagID) {
-                                    my $f = Get16u($dataPt, $entry + 2);
-                                    if ($formatName[$f]) {
-                                        $fmt = $formatName[$f];
-                                        $cnt = Get32u($dataPt, $entry + 4);
-                                    }
-                                    last;
-                                }
-                            }
-                        }
-                        $curInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID, \$val, $fmt, $cnt);
-                    }
-                }
-                # don't set this tag unless valid for the current condition
-                next unless defined $curInfo and $curInfo eq $tagInfo;
-            }
-            if ($$tagInfo{WriteCondition}) {
-                my $self = $exifTool;   # set $self to be used in eval
-                #### eval WriteCondition ($self)
-                unless (eval $$tagInfo{WriteCondition}) {
-                    $@ and warn $@;
-                    next;
-                }
-            }
-            my $nvHash = $exifTool->GetNewValueHash($tagInfo, $dirName);
-            unless ($nvHash) {
-                next unless $wrongDir;
-                # delete stuff from the wrong directory if setting somewhere else
-                $nvHash = $exifTool->GetNewValueHash($tagInfo, $wrongDir);
-                next unless Image::ExifTool::IsOverwriting($nvHash);
-                # don't cross delete if specifically deleting from the other directory
-                my $val = Image::ExifTool::GetNewValues($nvHash);
-                next if not defined $val and $nvHash->{WantGroup} and
-                        lc($nvHash->{WantGroup}) eq lc($wrongDir);
-                # remove this tag if found in this IFD
-                $xDelete{$tagID} = 1;
-            }
-            if ($set{$tagID}) {
-                # this tag is being set twice, which can happen if two Condition's
-                # were true for this tag.  Hopefully the only case where this can
-                # happen is the MakerNotes tag since it may store two very different
-                # types of information (MakerNotes and PreviewImage), but we want
-                # to store the MakerNotes if both are available
-                if ($tagID == 0x927c and $dirName =~ /^(ExifIFD|IFD0)$/) {
-                    next if $$tagInfo{Name} eq 'PreviewImage';
-                } else {
-                    $exifTool->Warn(sprintf("Multiple new values for $name tag 0x%.4x",$tagID));
-                }
-            }
-            $set{$tagID} = $tagInfo;
-        }
-        
+            # must evaluate Condition later when we have all DataMember's available
+            $set{$tagID} = (ref $$tagTablePtr{$tagID} eq 'ARRAY' or $$tagInfo{Condition}) ? '' : $tagInfo;
+        }
+
         # fix base offsets (some cameras incorrectly write maker notes in IFD0)
         if ($dirName eq 'MakerNotes' and $$dirInfo{Parent} =~ /^(ExifIFD|IFD0)$/ and
-            $$exifTool{TIFF_TYPE} !~ /^(ARW|SR2)$/ and not $$exifTool{LeicaTrailerPos} and
-            Image::ExifTool::MakerNotes::FixBase($exifTool, $dirInfo))
+            $$et{TIFF_TYPE} !~ /^(ARW|SR2)$/ and not $$et{LeicaTrailerPos} and
+            Image::ExifTool::MakerNotes::FixBase($et, $dirInfo))
         {
             # update local variables from fixed values
             $base = $$dirInfo{Base};
             $dataPos = $$dirInfo{DataPos};
+            # changed if ForceWrite tag was was set to "FixBase"
+            ++$$et{CHANGED} if $$et{FORCE_WRITE}{FixBase};
+            if ($$et{TIFF_TYPE} eq 'SRW' and $$et{Make} eq 'SAMSUNG' and $$et{Model} eq 'EK-GN120') {
+                $et->Error("EK-GN120 SRW files are too buggy to write");
+            }
         }
 
@@ -1676,9 +646,9 @@
         if ($mandatory) {
             # use X/Y resolution values from JFIF if available
-            if ($dirName eq 'IFD0' and defined $$exifTool{JFIFYResolution}) {
+            if ($dirName eq 'IFD0' and defined $$et{JFIFYResolution}) {
                 my %ifd0Vals = %$mandatory;
-                $ifd0Vals{0x011a} = $$exifTool{JFIFXResolution};
-                $ifd0Vals{0x011b} = $$exifTool{JFIFYResolution};
-                $ifd0Vals{0x0128} = $$exifTool{JFIFResolutionUnit} + 1;
+                $ifd0Vals{0x011a} = $$et{JFIFXResolution};
+                $ifd0Vals{0x011b} = $$et{JFIFYResolution};
+                $ifd0Vals{0x0128} = $$et{JFIFResolutionUnit} + 1;
                 $mandatory = \%ifd0Vals;
             }
@@ -1687,5 +657,5 @@
             unless ($numEntries) {
                 foreach (keys %$mandatory) {
-                    $set{$_} or $set{$_} = $$tagTablePtr{$_};
+                    defined $set{$_} or $set{$_} = $$tagTablePtr{$_};
                 }
             }
@@ -1701,4 +671,5 @@
             #  logic to add new tags relies on ordered entries)
             foreach (keys %set) {
+                next unless $set{$_};
                 my $perm = $set{$_}{Permanent};
                 push @newTags, $_ if defined $perm and not $perm;
@@ -1707,10 +678,7 @@
         } else {
             # get a hash of directories we will be writing in this one
-            $addDirs = $exifTool->GetAddDirHash($tagTablePtr, $dirName);
+            $addDirs = $et->GetAddDirHash($tagTablePtr, $dirName);
             # make a union of tags & dirs (can set whole dirs, like MakerNotes)
-            my %allTags = %set;
-            foreach (keys %$addDirs) {
-                $allTags{$_} = $$addDirs{$_};
-            }
+            my %allTags = ( %set, %$addDirs );
             # make sorted list of new tags to be added
             @newTags = sort { $a <=> $b } keys(%allTags);
@@ -1731,5 +699,5 @@
 
         # patch for Canon EOS 40D firmware 1.0.4 bug (incorrect directory counts)
-        if ($inMakerNotes and $$exifTool{Model} eq 'Canon EOS 40D') {
+        if ($inMakerNotes and $$et{Model} eq 'Canon EOS 40D') {
             my $fmt = Get16u($dataPt, $dirStart + 2 + 12 * ($numEntries - 1) + 2);
             if ($fmt < 1 or $fmt > 13) {
@@ -1757,11 +725,17 @@
                     undef $oldImageData;
                     if ($oldFormat < 1 or $oldFormat > 13) {
+                        my $msg = "Bad format ($oldFormat) for $name entry $index";
                         # patch to preserve invalid directory entries in SubIFD3 of
                         # various Kodak Z-series cameras (Z812, Z1085IS, Z1275)
-                        if ($dirName eq 'MakerNotes' and $$exifTool{Make}=~/KODAK/i and
-                            $$dirInfo{Name} and $$dirInfo{Name} eq 'SubIFD3')
+                        # and some Sony cameras such as the DSC-P10
+                        if ($dirName eq 'MakerNotes' and (($$et{Make}=~/KODAK/i and
+                            $$dirInfo{Name} and $$dirInfo{Name} eq 'SubIFD3') or
+                            ($numEntries == 12 and $$et{Make} eq 'SONY' and $index >= 8)))
                         {
                             $dirBuff .= substr($$dataPt, $entry, 12);
-                            goto WroteIt;
+                            ++$index;
+                            $newID = $oldID;    # we wrote this
+                            $et->Warn($msg, 1);
+                            next;
                         }
                         # don't write out null directory entry
@@ -1770,10 +744,9 @@
                             # must keep same directory size to avoid messing up our fixed offsets
                             $dirBuff .= ("\0" x 12) if $$dirInfo{FixBase};
-WroteIt:                    ++$index;
+                            ++$index;
                             $newID = $oldID;    # pretend we wrote this
                             next;
                         }
-                        my $msg = "Bad format ($oldFormat) for $name entry $index";
-                        return ExifErr($exifTool, $msg, $tagTablePtr);
+                        return ExifErr($et, $msg, $tagTablePtr);
                     }
                     $readFormName = $oldFormName = $formatName[$oldFormat];
@@ -1787,7 +760,7 @@
                         # must get unknown tags too
                         # (necessary so we don't miss a tag we want to Drop)
-                        my $unk = $exifTool->Options(Unknown => 1);
-                        $oldInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID);
-                        $exifTool->Options(Unknown => $unk);
+                        my $unk = $et->Options(Unknown => 1);
+                        $oldInfo = $et->GetTagInfo($tagTablePtr, $oldID);
+                        $et->Options(Unknown => $unk);
                     }
                     # patch incorrect count in Kodak SubIFD3 tags
@@ -1812,9 +785,9 @@
                             eval $$dirInfo{FixOffsets};
                             unless (defined $valuePtr) {
-                                unless ($$exifTool{DROP_TAGS}) {
-                                    my $tagStr = $oldInfo ? $$oldInfo{Name} : sprintf("tag 0x%x",$oldID);
-                                    return undef if $exifTool->Error("Bad $name offset for $tagStr", $inMakerNotes);
+                                unless ($$et{DropTags}) {
+                                    my $tagStr = $oldInfo ? $$oldInfo{Name} : sprintf("tag 0x%.4x",$oldID);
+                                    return undef if $et->Error("Bad $name offset for $tagStr", $inMakerNotes);
                                 }
-                                goto DropTag;
+                                ++$index;  $oldID = $newID;  next;  # drop this tag
                             }
                         }
@@ -1823,5 +796,5 @@
                         # convert offset to pointer in $$dataPt
                         if ($$dirInfo{EntryBased} or (ref $$tagTablePtr{$oldID} eq 'HASH' and
-                            $tagTablePtr->{$oldID}{EntryBased}))
+                            $$tagTablePtr{$oldID}{EntryBased}))
                         {
                             $valuePtr += $entry;
@@ -1833,16 +806,20 @@
                         # get value by seeking in file if we are allowed
                         if ($valuePtr < 0 or $valuePtr+$oldSize > $dataLen) {
-                            my ($pos, $tagStr, $invalidPreview, $tmpInfo);
+                            my ($pos, $tagStr, $invalidPreview, $tmpInfo, $leicaTrailer);
                             if ($oldInfo) {
                                 $tagStr = $$oldInfo{Name};
+                                $leicaTrailer = $$oldInfo{LeicaTrailer};
                             } elsif (defined $oldInfo) {
-                                $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \ '', $oldFormName, $oldCount);
-                                $tagStr = $$tmpInfo{Name} if $tmpInfo;
-                            }
-                            $tagStr or $tagStr = sprintf("tag 0x%x",$oldID);
+                                $tmpInfo = $et->GetTagInfo($tagTablePtr, $oldID, \ '', $oldFormName, $oldCount);
+                                if ($tmpInfo) {
+                                    $tagStr = $$tmpInfo{Name};
+                                    $leicaTrailer = $$tmpInfo{LeicaTrailer};
+                                }
+                            }
+                            $tagStr or $tagStr = sprintf("tag 0x%.4x",$oldID);
                             # allow PreviewImage to run outside EXIF segment in JPEG images
                             if (not $raf) {
                                 if ($tagStr eq 'PreviewImage') {
-                                    $raf = $exifTool->{RAF};
+                                    $raf = $$et{RAF};
                                     if ($raf) {
                                         $pos = $raf->Tell();
@@ -1856,10 +833,11 @@
                                         $invalidPreview = 1;
                                     }
-                                } elsif ($tagStr eq 'MakerNoteLeica6') {
+                                } elsif ($leicaTrailer) {
                                     # save information about Leica makernote trailer
-                                    $$exifTool{LeicaTrailer} = {
+                                    $$et{LeicaTrailer} = {
                                         TagInfo => $oldInfo || $tmpInfo,
                                         Offset  => $base + $valuePtr + $dataPos,
                                         Size    => $oldSize,
+                                        Fixup   => new Image::ExifTool::Fixup,
                                     },
                                     $invalidPreview = 2;
@@ -1872,10 +850,11 @@
                             }
                             if ($oldSize > BINARY_DATA_LIMIT and $$origDirInfo{ImageData} and
-                                (not defined $oldInfo or ($oldInfo and not $$oldInfo{SubDirectory})))
+                                (not defined $oldInfo or ($oldInfo and
+                                (not $$oldInfo{SubDirectory} or $$oldInfo{ReadFromRAF}))))
                             {
                                 # copy huge data blocks later instead of loading into memory
                                 $oldValue = ''; # dummy empty value
                                 # copy this value later unless writing a new value
-                                unless ($set{$oldID}) {
+                                unless (defined $set{$oldID}) {
                                     my $pad = $oldSize & 0x01 ? 1 : 0;
                                     # save block information to copy later (set directory offset later)
@@ -1895,14 +874,14 @@
                                 }
                                 unless ($success) {
-                                    return undef if $exifTool->Error("Error reading value for $name entry $index", $inMakerNotes);
-                                    goto DropTag;
+                                    return undef if $et->Error("Error reading value for $name entry $index", $inMakerNotes);
+                                    ++$index;  $oldID = $newID;  next;  # drop this tag
                                 }
                             } elsif (not $invalidPreview) {
-                                return undef if $exifTool->Error("Bad $name offset for $tagStr", $inMakerNotes);
-                                goto DropTag;
+                                return undef if $et->Error("Bad $name offset for $tagStr", $inMakerNotes);
+                                ++$index;  $oldID = $newID;  next;  # drop this tag
                             }
                             if ($invalidPreview) {
                                 # set value for invalid preview
-                                if ($exifTool->{FILE_TYPE} eq 'JPEG') {
+                                if ($$et{FILE_TYPE} eq 'JPEG') {
                                     # define dummy value for preview (or Leica MakerNote) to write later
                                     # (value must be larger than 4 bytes to generate PREVIEW_INFO,
@@ -1915,5 +894,5 @@
                                 $valuePtr = 0;
                             } else {
-                                UpdateTiffEnd($exifTool, $base+$valuePtr+$dataPos+$oldSize);
+                                UpdateTiffEnd($et, $base+$valuePtr+$dataPos+$oldSize);
                             }
                             # update pointers for value just read from file
@@ -1928,7 +907,7 @@
                             my $str = "Suspicious $name offset for $tagStr";
                             if ($inMakerNotes) {
-                                $exifTool->Warn($str, 1);
+                                $et->Warn($str, 1);
                             } else {
-                                return undef if $exifTool->Error($str, 1);
+                                return undef if $et->Error($str, 1);
                             }
                         }
@@ -1938,7 +917,22 @@
                     # get tagInfo using value if necessary
                     if (defined $oldInfo and not $oldInfo) {
-                        my $unk = $exifTool->Options(Unknown => 1);
-                        $oldInfo = $exifTool->GetTagInfo($tagTablePtr, $oldID, \$oldValue, $oldFormName, $oldCount);
-                        $exifTool->Options(Unknown => $unk);
+                        my $unk = $et->Options(Unknown => 1);
+                        $oldInfo = $et->GetTagInfo($tagTablePtr, $oldID, \$oldValue, $oldFormName, $oldCount);
+                        $et->Options(Unknown => $unk);
+                        # now that we have the value, we can resolve the Condition to finally
+                        # determine whether we want to delete this tag or not
+                        if ($mayDelete{$oldID} and $oldInfo and (not @newTags or $newTags[0] != $oldID)) {
+                            my $nvHash = $et->GetNewValueHash($oldInfo, $dirName);
+                            if (not $nvHash and $wrongDir) {
+                                # delete from wrong directory if necessary
+                                $nvHash = $et->GetNewValueHash($oldInfo, $wrongDir);
+                                $nvHash and $xDelete{$oldID} = 1;
+                            }
+                            if ($nvHash) {
+                                # we want to delete this tag after all, so insert it into our list
+                                $set{$oldID} = $oldInfo;
+                                unshift @newTags, $oldID;
+                            }
+                        }
                     }
                     # make sure we are handling the 'ifd' format properly
@@ -1947,5 +941,5 @@
                     {
                         my $str = sprintf('%s tag 0x%.4x IFD format not handled', $name, $oldID);
-                        $exifTool->Error($str, $inMakerNotes);
+                        $et->Error($str, $inMakerNotes);
                     }
                     # override format we use to read the value if specified
@@ -1955,12 +949,11 @@
                             not $intFormat{$oldFormName})
                         {
-                            $exifTool->Error("Invalid format ($oldFormName) for $name $$oldInfo{Name}", $inMakerNotes);
-                            goto DropTag;
-                        }
-                        if ($$oldInfo{Drop} and $$exifTool{DROP_TAGS}) {
-                            # don't rewrite this tag
-DropTag:                    ++$index;
-                            $oldID = $newID;
-                            next;
+                            $et->Error("Invalid format ($oldFormName) for $name $$oldInfo{Name}", $inMakerNotes);
+                            ++$index;  $oldID = $newID;  next;  # drop this tag
+                        }
+                        if ($$oldInfo{Drop} and $$et{DropTags} and
+                            ($$oldInfo{Drop} == 1 or $$oldInfo{Drop} < $oldSize))
+                        {
+                            ++$index;  $oldID = $newID;  next;  # drop this tag
                         }
                         if ($$oldInfo{Format}) {
@@ -1972,4 +965,8 @@
                                 $readFormat = $oldFormat;
                             }
+                            if ($$oldInfo{FixedSize}) {
+                                $oldSize = $$oldInfo{FixedSize} if $$oldInfo{FixedSize};
+                                $oldValue = substr($$valueDataPt, $valuePtr, $oldSize);
+                            }
                             # adjust number of items to read if format size changed
                             $readCount = $oldSize / $formatSize[$readFormat];
@@ -1979,7 +976,9 @@
                         my $str = $oldInfo ? "$$oldInfo{Name} tag" : sprintf('tag 0x%x',$oldID);
                         if ($oldID == $lastTagID) {
-                            $exifTool->Warn("Duplicate $str in $name");;
+                            $et->Warn("Duplicate $str in $name");
+                            # put this tag back into the newTags list if necessary
+                            unshift @newTags, $oldID if defined $set{$oldID};
                         } else {
-                            $exifTool->Warn("\u$str out of sequence in $name");
+                            $et->Warn("\u$str out of sequence in $name");
                         }
                     }
@@ -2000,5 +999,5 @@
             } elsif (not defined $newID) {
                 # maker notes will have no new tags defined
-                if ($set{$oldID}) {
+                if (defined $set{$oldID}) {
                     $newID = $oldID;
                     $isNew = 0;
@@ -2021,4 +1020,76 @@
                 # add, edit or delete this tag
                 shift @newTags; # remove from list
+                my $curInfo = $set{$newID};
+                unless ($curInfo or $$addDirs{$newID}) {
+                    # we can finally get the specific tagInfo reference for this tag
+                    # (because we can now evaluate the Condition statement since all
+                    #  DataMember's have been obtained for tags up to this one)
+                    $curInfo = $et->GetTagInfo($tagTablePtr, $newID);
+                    if (defined $curInfo and not $curInfo) {
+                        # need value to evaluate the condition
+                        # (tricky because we need the tagInfo ref to get the value,
+                        #  so we must loop through all new tagInfo's...)
+                        foreach $tagInfo (@newTagInfo) {
+                            next unless $$tagInfo{TagID} == $newID;
+                            my $val = $et->GetNewValue($tagInfo);
+                            defined $val or $mayDelete{$newID} = 1, next;
+                            # must convert to binary for evaluating in Condition
+                            my $fmt = $$tagInfo{Format} || $$tagInfo{Writable};
+                            if ($fmt) {
+                                $val = WriteValue($val, $fmt, $$tagInfo{Count});
+                                defined $val or $mayDelete{$newID} = 1, next;
+                            }
+                            $curInfo = $et->GetTagInfo($tagTablePtr, $newID, \$val, $oldFormName, $oldCount);
+                            if ($curInfo) {
+                                last if $curInfo eq $tagInfo;
+                                undef $curInfo;
+                            }
+                        }
+                        # may want to delete this, but we need to see the old value first
+                        $mayDelete{$newID} = 1 unless $curInfo;
+                    }
+                    # don't set this tag unless valid for the current condition
+                    if ($curInfo and $$et{NEW_VALUE}{$curInfo}) {
+                        $set{$newID} = $curInfo;
+                    } else {
+                        next if $isNew > 0;
+                        $isNew = -1;
+                        undef $curInfo;
+                    }
+                }
+                if ($curInfo) {
+                    if ($$curInfo{WriteCondition}) {
+                        my $self = $et;   # set $self to be used in eval
+                        #### eval WriteCondition ($self)
+                        unless (eval $$curInfo{WriteCondition}) {
+                            $@ and warn $@;
+                            goto NoWrite;   # GOTO !
+                        }
+                    }
+                    my $nvHash;
+                    $nvHash = $et->GetNewValueHash($curInfo, $dirName) if $isNew >= 0;
+                    unless ($nvHash or defined $$mandatory{$newID}) {
+                        goto NoWrite unless $wrongDir;  # GOTO !
+                        # delete stuff from the wrong directory if setting somewhere else
+                        $nvHash = $et->GetNewValueHash($curInfo, $wrongDir);
+                        # don't cross delete if not overwriting
+                        goto NoWrite unless $et->IsOverwriting($nvHash);    # GOTO !
+                        # don't cross delete if specifically deleting from the other directory
+                        # (Note: don't call GetValue() here because it shouldn't be called
+                        #  if IsOverwriting returns < 0 -- eg. when shifting)
+                        if (not defined $$nvHash{Value} and $$nvHash{WantGroup} and
+                                lc($$nvHash{WantGroup}) eq lc($wrongDir))
+                        {
+                            goto NoWrite;   # GOTO !
+                        } else {
+                            # remove this tag if found in this IFD
+                            $xDelete{$newID} = 1;
+                        }
+                    }
+                } elsif (not $$addDirs{$newID}) {
+NoWrite:            next if $isNew > 0;
+                    delete $set{$newID};
+                    $isNew = -1;
+                }
                 if ($set{$newID}) {
 #
@@ -2028,14 +1099,14 @@
                     $newCount = $$newInfo{Count};
                     my ($val, $newVal, $n);
-                    my $nvHash = $exifTool->GetNewValueHash($newInfo, $dirName);
+                    my $nvHash = $et->GetNewValueHash($newInfo, $dirName);
                     if ($isNew > 0) {
                         # don't create new entry unless requested
                         if ($nvHash) {
-                            next unless Image::ExifTool::IsCreating($nvHash);
+                            next unless $$nvHash{IsCreating};
                             if ($$newInfo{IsOverwriting}) {
                                 my $proc = $$newInfo{IsOverwriting};
-                                $isOverwriting = &$proc($exifTool, $nvHash, $val, \$newVal);
+                                $isOverwriting = &$proc($et, $nvHash, $val, \$newVal);
                             } else {
-                                $isOverwriting = Image::ExifTool::IsOverwriting($nvHash);
+                                $isOverwriting = $et->IsOverwriting($nvHash);
                             }
                         } else {
@@ -2059,8 +1130,12 @@
                     } elsif ($nvHash or $xDelete{$newID}) {
                         unless ($nvHash) {
-                            $nvHash = $exifTool->GetNewValueHash($newInfo, $wrongDir);
+                            $nvHash = $et->GetNewValueHash($newInfo, $wrongDir);
                         }
                         # read value
-                        $val = ReadValue(\$oldValue, 0, $readFormName, $readCount, $oldSize);
+                        if (length $oldValue >= $oldSize) {
+                            $val = ReadValue(\$oldValue, 0, $readFormName, $readCount, $oldSize);
+                        } else {
+                            $val = '';
+                        }
                         # determine write format (by default, use 'Writable' format)
                         my $writable = $$newInfo{Writable};
@@ -2088,20 +1163,21 @@
                         if ($$newInfo{IsOverwriting}) {
                             my $proc = $$newInfo{IsOverwriting};
-                            $isOverwriting = &$proc($exifTool, $nvHash, $val, \$newVal);
+                            $isOverwriting = &$proc($et, $nvHash, $val, \$newVal);
                         } else {
-                            $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $val);
+                            $isOverwriting = $et->IsOverwriting($nvHash, $val);
                         }
                     }
                     if ($isOverwriting) {
-                        $newVal = Image::ExifTool::GetNewValues($nvHash) unless defined $newVal;
+                        $newVal = $et->GetNewValue($nvHash) unless defined $newVal;
                         # value undefined if deleting this tag
                         # (also delete tag if cross-deleting and this isn't a date/time shift)
                         if (not defined $newVal or ($xDelete{$newID} and not defined $$nvHash{Shift})) {
-                            if ($$newInfo{RawConvInv} and defined $$nvHash{Value}) {
-                                goto NoOverwrite;   # error in RawConvInv, so rewrite existing tag
+                            if (not defined $newVal and $$newInfo{RawConvInv} and defined $$nvHash{Value}) {
+                                # error in RawConvInv, so rewrite existing tag
+                                goto NoOverwrite; # GOTO!
                             }
                             unless ($isNew) {
-                                ++$exifTool->{CHANGED};
-                                $exifTool->VerboseValue("- $dirName:$$newInfo{Name}", $val);
+                                ++$$et{CHANGED};
+                                $et->VerboseValue("- $dirName:$$newInfo{Name}", $val);
                             }
                             next;
@@ -2115,24 +1191,27 @@
                         $newValue = WriteValue($newVal, $newFormName, $newCount);
                         unless (defined $newValue) {
-                            $exifTool->Warn("Error writing $dirName:$$newInfo{Name}");
-                            goto NoOverwrite;
+                            $et->Warn("Invalid value for $dirName:$$newInfo{Name}");
+                            goto NoOverwrite; # GOTO!
                         }
                         if (length $newValue) {
                             # limit maximum value length in JPEG images
                             # (max segment size is 65533 bytes and the min EXIF size is 96 incl an additional IFD entry)
-                            if ($$exifTool{FILE_TYPE} eq 'JPEG' and length($newValue) > 65436 and
+                            if ($$et{FILE_TYPE} eq 'JPEG' and length($newValue) > 65436 and
                                 $$newInfo{Name} ne 'PreviewImage')
                             {
                                 my $name = $$newInfo{MakerNotes} ? 'MakerNotes' : $$newInfo{Name};
-                                $exifTool->Warn("$name too large to write in JPEG segment");
-                                goto NoOverwrite;
+                                $et->Warn("Writing large value for $name",1);
+                            }
+                            # re-code if necessary
+                            if ($strEnc and $newFormName eq 'string') {
+                                $newValue = $et->Encode($newValue, $strEnc);
                             }
                         } else {
-                            $exifTool->Warn("Can't write zero length $$newInfo{Name} in $tagTablePtr->{GROUPS}{1}");
-                            goto NoOverwrite;
+                            $et->Warn("Can't write zero length $$newInfo{Name} in $$tagTablePtr{GROUPS}{1}");
+                            goto NoOverwrite; # GOTO!
                         }
                         if ($isNew >= 0) {
                             $newCount = length($newValue) / $formatSize[$newFormat];
-                            ++$exifTool->{CHANGED};
+                            ++$$et{CHANGED};
                             if (defined $allMandatory) {
                                 # not all mandatory if we are writing any tag specifically
@@ -2145,7 +1224,11 @@
                             }
                             if ($verbose > 1) {
-                                $exifTool->VerboseValue("- $dirName:$$newInfo{Name}", $val) unless $isNew;
-                                my $str = $nvHash ? '' : ' (mandatory)';
-                                $exifTool->VerboseValue("+ $dirName:$$newInfo{Name}", $newVal, $str);
+                                $et->VerboseValue("- $dirName:$$newInfo{Name}", $val) unless $isNew;
+                                if ($$newInfo{OffsetPair} and $newVal eq '4277010157') { # (0xfeedfeed)
+                                    print { $$et{OPTIONS}{TextOut} } "    + $dirName:$$newInfo{Name} = <tbd>\n";
+                                } else {
+                                    my $str = $nvHash ? '' : ' (mandatory)';
+                                    $et->VerboseValue("+ $dirName:$$newInfo{Name}", $newVal, $str);
+                                }
                             }
                         }
@@ -2165,5 +1248,5 @@
 #
                     # newInfo may not be defined if we try to add a mandatory tag
-                    # to a directory that doesn't support it (ie. IFD1 in RW2 images)
+                    # to a directory that doesn't support it (eg. IFD1 in RW2 images)
                     $newInfo = $$addDirs{$newID} or next;
                     # make sure we don't try to generate a new MakerNotes directory
@@ -2171,6 +1254,6 @@
                     next if $$newInfo{MakerNotes} or $$newInfo{Name} eq 'SubIFD';
                     my $subTable;
-                    if ($newInfo->{SubDirectory}{TagTable}) {
-                        $subTable = Image::ExifTool::GetTagTable($newInfo->{SubDirectory}{TagTable});
+                    if ($$newInfo{SubDirectory}{TagTable}) {
+                        $subTable = Image::ExifTool::GetTagTable($$newInfo{SubDirectory}{TagTable});
                     } else {
                         $subTable = $tagTablePtr;
@@ -2181,6 +1264,6 @@
                         Fixup => new Image::ExifTool::Fixup,
                     );
-                    $sourceDir{DirName} = $newInfo->{Groups}{1} if $$newInfo{SubIFD};
-                    $newValue = $exifTool->WriteDirectory(\%sourceDir, $subTable);
+                    $sourceDir{DirName} = $$newInfo{Groups}{1} if $$newInfo{SubIFD};
+                    $newValue = $et->WriteDirectory(\%sourceDir, $subTable);
                     # only add new directory if it isn't empty
                     next unless defined $newValue and length($newValue);
@@ -2214,4 +1297,8 @@
                     $newFormName = $$newInfo{Writable};
                     $newFormat = $formatNumber{$newFormName};
+                } elsif ($$addDirs{$newID} and $newInfo ne $$addDirs{$newID}) {
+                    # this can happen if we are trying to add a directory that doesn't exist
+                    # in this type of file (eg. try adding a SubIFD tag to an A100 image)
+                    $isNew = -1;
                 }
             }
@@ -2240,6 +1327,6 @@
                         # prefer tag from Composite table if it exists (otherwise
                         # PreviewImage data would be taken from Extra tag)
-                        my $compInfo = $Image::ExifTool::Composite{$dataTag};
-                        $offsetData{$dataTag} = $exifTool->GetNewValues($compInfo || $dataTag);
+                        my $compInfo = Image::ExifTool::GetCompositeTagInfo($dataTag);
+                        $offsetData{$dataTag} = $et->GetNewValue($compInfo || $dataTag);
                         my $err;
                         if (defined $offsetData{$dataTag}) {
@@ -2247,8 +1334,5 @@
                             if ($dataTag eq 'PreviewImage') {
                                 # must set DEL_PREVIEW flag now if preview fit into IFD
-                                $$exifTool{DEL_PREVIEW} = 1 if $len <= 4;
-                            } elsif ($exifTool->{FILE_TYPE} eq 'JPEG' and $len > 60000) {
-                                delete $offsetData{$dataTag};
-                                $err = "$dataTag not written (too large for JPEG segment)";
+                                $$et{DEL_PREVIEW} = 1 if $len <= 4;
                             }
                         } else {
@@ -2256,5 +1340,5 @@
                         }
                         if ($err) {
-                            $exifTool->Warn($err) if $$newInfo{IsOffset};
+                            $et->Warn($err) if $$newInfo{IsOffset};
                             delete $set{$newID};    # remove from list of tags we are setting
                             next;
@@ -2267,23 +1351,27 @@
                 if ($$newInfo{MakerNotes}) {
                     # don't write new makernotes if we are deleting this group
-                    if ($exifTool->{DEL_GROUP}{MakerNotes} and
-                       ($exifTool->{DEL_GROUP}{MakerNotes} != 2 or $isNew <= 0))
+                    if ($$et{DEL_GROUP}{MakerNotes} and
+                       ($$et{DEL_GROUP}{MakerNotes} != 2 or $isNew <= 0))
                     {
-                        if ($isNew <= 0) {
-                            ++$exifTool->{CHANGED};
-                            $verbose and print $out "  Deleting MakerNotes\n";
-                        }
-                        next;
+                        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;
+                        }
                     }
                     my $saveOrder = GetByteOrder();
-                    if ($isNew >= 0 and $set{$newID}) {
+                    if ($isNew >= 0 and defined $set{$newID}) {
                         # we are writing a whole new maker note block
                         # --> add fixup information if necessary
-                        my $nvHash = $exifTool->GetNewValueHash($newInfo, $dirName);
-                        if ($nvHash and $nvHash->{MAKER_NOTE_FIXUP}) {
+                        my $nvHash = $et->GetNewValueHash($newInfo, $dirName);
+                        if ($nvHash and $$nvHash{MAKER_NOTE_FIXUP}) {
                             # must clone fixup because we will be shifting it
-                            my $makerFixup = $nvHash->{MAKER_NOTE_FIXUP}->Clone();
+                            my $makerFixup = $$nvHash{MAKER_NOTE_FIXUP}->Clone();
                             my $valLen = length($valBuff);
-                            $makerFixup->{Start} += $valLen;
+                            $$makerFixup{Start} += $valLen;
                             push @valFixups, $makerFixup;
                         }
@@ -2311,4 +1399,5 @@
                             $subdirInfo{NoFixBase} = 1 if defined $$sub{Base};
                             $subdirInfo{AutoFix} = $$sub{AutoFix};
+                            SetByteOrder($$sub{ByteOrder}) if $$sub{ByteOrder};
                         }
                         # get the proper tag table for these maker notes
@@ -2319,6 +1408,7 @@
                             $notIFD = $$oldInfo{NotIFD};
                         } else {
-                            $exifTool->Warn('Internal problem getting maker notes tag table');
-                        }
+                            $et->Warn('Internal problem getting maker notes tag table');
+                        }
+                        $writeProc or $writeProc = $$subTable{WRITE_PROC} if $subTable;
                         $subTable or $subTable = $tagTablePtr;
                         if ($writeProc and
@@ -2329,5 +1419,5 @@
                         } elsif (not $notIFD) {
                             # look for IFD-style maker notes
-                            $loc = Image::ExifTool::MakerNotes::LocateIFD($exifTool,\%subdirInfo);
+                            $loc = Image::ExifTool::MakerNotes::LocateIFD($et,\%subdirInfo);
                         }
                         if (defined $loc) {
@@ -2335,5 +1425,10 @@
                             $subdirInfo{Fixup} = new Image::ExifTool::Fixup;
                             # rewrite maker notes
-                            $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
+                            my $changed = $$et{CHANGED};
+                            $subdir = $et->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
+                            if ($changed == $$et{CHANGED} and $subdirInfo{Fixup}->IsEmpty()) {
+                                # return original data if nothing changed and no fixups
+                                undef $subdir;
+                            }
                         } elsif ($$subTable{PROCESS_PROC} and
                                  $$subTable{PROCESS_PROC} eq \&Image::ExifTool::ProcessBinaryData)
@@ -2350,15 +1445,20 @@
                             }
                             # rewrite maker notes
-                            $subdir = $exifTool->WriteDirectory(\%subdirInfo, $subTable);
-                        } elsif (not $notIFD) {
+                            $subdir = $et->WriteDirectory(\%subdirInfo, $subTable);
+                        } elsif ($notIFD) {
+                            if ($writeProc) {
+                                $loc = 0;
+                                $subdir = $et->WriteDirectory(\%subdirInfo, $subTable);
+                            }
+                        } else {
                             my $msg = 'Maker notes could not be parsed';
-                            if ($$exifTool{FILE_TYPE} eq 'JPEG') {
-                                $exifTool->Warn($msg, 1);
+                            if ($$et{FILE_TYPE} eq 'JPEG') {
+                                $et->Warn($msg, 1);
                             } else {
-                                $exifTool->Error($msg, 1);
+                                $et->Error($msg, 1);
                             }
                         }
                         if (defined $subdir) {
-                            next unless length $subdir;
+                            length $subdir or SetByteOrder($saveOrder), next;
                             my $valLen = length($valBuff);
                             # restore existing header and substitute the new
@@ -2366,16 +1466,16 @@
                             $newValue = substr($oldValue, 0, $loc) . $subdir;
                             my $makerFixup = $subdirInfo{Fixup};
-                            my $previewInfo = $exifTool->{PREVIEW_INFO};
+                            my $previewInfo = $$et{PREVIEW_INFO};
                             if ($subdirInfo{Relative}) {
                                 # apply a one-time fixup to $loc since offsets are relative
-                                $makerFixup->{Start} += $loc;
+                                $$makerFixup{Start} += $loc;
                                 # shift all offsets to be relative to new base
                                 my $baseShift = $valueDataPos + $valuePtr + $base - $subdirInfo{Base};
-                                $makerFixup->{Shift} += $baseShift;
+                                $$makerFixup{Shift} += $baseShift;
                                 $makerFixup->ApplyFixup(\$newValue);
                                 if ($previewInfo) {
                                     # remove all but PreviewImage fixup (since others shouldn't change)
-                                    foreach (keys %{$makerFixup->{Pointers}}) {
-                                        /_PreviewImage$/ or delete $makerFixup->{Pointers}{$_};
+                                    foreach (keys %{$$makerFixup{Pointers}}) {
+                                        /_PreviewImage$/ or delete $$makerFixup{Pointers}{$_};
                                     }
                                     # zero pointer so we can see how it gets shifted later
@@ -2383,8 +1483,8 @@
                                     # set the pointer to the start of the EXIF information
                                     # add preview image fixup to list of value fixups
-                                    $makerFixup->{Start} += $valLen;
+                                    $$makerFixup{Start} += $valLen;
                                     push @valFixups, $makerFixup;
-                                    $previewInfo->{BaseShift} = $baseShift;
-                                    $previewInfo->{Relative} = 1;
+                                    $$previewInfo{BaseShift} = $baseShift;
+                                    $$previewInfo{Relative} = 1;
                                 }
                             # don't shift anything if relative flag set to zero (Pentax patch)
@@ -2400,20 +1500,20 @@
                                     (not $subdirInfo{MinOffset} or $subdirInfo{MinOffset} + $baseShift < 0))
                                 {
-                                    my $fixBase = $exifTool->Options('FixBase');
+                                    my $fixBase = $et->Options('FixBase');
                                     if (not defined $fixBase) {
-                                        my $str = $exifTool->Options('IgnoreMinorErrors') ? 'ignored' : 'fix or ignore?';
-                                        $exifTool->Error("MakerNotes offsets may be incorrect ($str)", 1);
+                                        my $str = $et->Options('IgnoreMinorErrors') ? 'ignored' : 'fix or ignore?';
+                                        $et->Error("MakerNotes offsets may be incorrect ($str)", 1);
                                     } elsif ($fixBase eq '') {
-                                        $exifTool->Warn('Fixed incorrect MakerNotes offsets');
+                                        $et->Warn('Fixed incorrect MakerNotes offsets');
                                         $baseShift = 0;
                                     }
                                 }
-                                $makerFixup->{Start} += $valLen + $loc;
-                                $makerFixup->{Shift} += $baseShift;
+                                $$makerFixup{Start} += $valLen + $loc;
+                                $$makerFixup{Shift} += $baseShift;
                                 # permanently fix makernote offset errors
-                                $makerFixup->{Shift} += $subdirInfo{FixedBy} || 0;
+                                $$makerFixup{Shift} += $subdirInfo{FixedBy} || 0;
                                 push @valFixups, $makerFixup;
-                                if ($previewInfo and not $previewInfo->{NoBaseShift}) {
-                                    $previewInfo->{BaseShift} = $baseShift;
+                                if ($previewInfo and not $$previewInfo{NoBaseShift}) {
+                                    $$previewInfo{BaseShift} = $baseShift;
                                 }
                             }
@@ -2426,5 +1526,6 @@
                 } elsif ($$newInfo{SubDirectory} and $isNew <= 0 and not $isOverwriting
                     # don't edit directory if Writable is set to 0
-                    and (not defined $$newInfo{Writable} or $$newInfo{Writable}))
+                    and (not defined $$newInfo{Writable} or $$newInfo{Writable}) and
+                    not $$newInfo{ReadFromRAF})
                 {
 
@@ -2439,11 +1540,11 @@
                         }
                         # determine directory name for this IFD
-                        my $subdirName = $newInfo->{Groups}{1} || $$newInfo{Name};
+                        my $subdirName = $$newInfo{Groups}{1} || $$newInfo{Name};
                         # all makernotes directory names must be 'MakerNotes'
-                        $subdirName = 'MakerNotes' if $subTable->{GROUPS}{0} eq 'MakerNotes';
+                        $subdirName = 'MakerNotes' if $$subTable{GROUPS}{0} eq 'MakerNotes';
                         # must handle sub-IFD's specially since the values
                         # are actually offsets to subdirectories
                         unless ($readCount) {   # can't have zero count
-                            return undef if $exifTool->Error("$name entry $index has zero count", 1);
+                            return undef if $et->Error("$name entry $index has zero count", 2);
                             next;
                         }
@@ -2453,8 +1554,20 @@
                         for ($i=0; $i<$readCount; ++$i) {
                             my $off = $i * $formatSize[$readFormat];
-                            my $pt = Image::ExifTool::ReadValue($valueDataPt, $valuePtr + $off,
-                                            $readFormName, 1, $oldSize - $off);
-                            my $subdirStart = $pt - $dataPos;
+                            my $val = ReadValue($valueDataPt, $valuePtr + $off,
+                                                $readFormName, 1, $oldSize - $off);
+                            my $subdirStart = $val - $dataPos;
                             my $subdirBase = $base;
+                            my $hdrLen;
+                            if (defined $$subdir{Start}) {
+                                #### eval Start ($val)
+                                my $newStart = eval $$subdir{Start};
+                                unless (Image::ExifTool::IsInt($newStart)) {
+                                    $et->Error("Bad subdirectory start for $$newInfo{Name}");
+                                    next;
+                                }
+                                $newStart -= $dataPos;
+                                $hdrLen = $newStart - $subdirStart;
+                                $subdirStart = $newStart;
+                            }
                             if ($$subdir{Base}) {
                                 my $start = $subdirStart + $dataPos;
@@ -2496,7 +1609,7 @@
                                 } else {
                                     my @err = ("Can't read $subdirName data", $inMakerNotes);
-                                    if ($$subTable{VARS} and $subTable->{VARS}{MINOR_ERRORS}) {
-                                        $exifTool->Warn($err[0] . '. Ignored.');
-                                    } elsif ($exifTool->Error(@err)) {
+                                    if ($$subTable{VARS} and $$subTable{VARS}{MINOR_ERRORS}) {
+                                        $et->Warn($err[0] . '. Ignored.');
+                                    } elsif ($et->Error(@err)) {
                                         return undef;
                                     }
@@ -2504,9 +1617,14 @@
                                 }
                             }
-                            my $subdirData = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
+                            my $subdirData = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
                             unless (defined $subdirData) {
                                 # WriteDirectory should have issued an error, but check just in case
-                                $exifTool->Error("Error writing $subdirName") unless $$exifTool{VALUE}{Error};
+                                $et->Error("Error writing $subdirName") unless $$et{VALUE}{Error};
                                 return undef;
+                            }
+                            # add back original header if necessary (eg. Ricoh GR)
+                            if ($hdrLen and $hdrLen > 0 and $subdirStart <= $dataLen) {
+                                $subdirData = substr($$dataPt, $subdirStart - $hdrLen, $hdrLen) . $subdirData;
+                                $subdirInfo{Fixup}{Start} += $hdrLen;
                             }
                             unless (length $subdirData) {
@@ -2604,5 +1722,5 @@
                         my $oldOrder = GetByteOrder();
                         SetByteOrder($$subdir{ByteOrder}) if $$subdir{ByteOrder};
-                        $newValue = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
+                        $newValue = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
                         SetByteOrder($oldOrder);
                         if (defined $newValue) {
@@ -2610,11 +1728,9 @@
                             if ($hdrLen) {
                                 $newValue = substr($$valueDataPt, $valuePtr, $hdrLen) . $newValue;
-                                $subFixup->{Start} += $hdrLen;
+                                $$subFixup{Start} += $hdrLen;
                             }
                             $newValuePt = \$newValue;
-                        }
-                        unless (defined $$newValuePt) {
-                            $exifTool->Error("Error writing $dirName:$$newInfo{Name}");
-                            return undef;
+                        } else {
+                            $newValuePt = \$oldValue;
                         }
                         unless (length $$newValuePt) {
@@ -2622,6 +1738,6 @@
                             next if $oldSize or not $inMakerNotes;
                         }
-                        if ($subFixup->{Pointers} and $subdirInfo{Base} == $base) {
-                            $subFixup->{Start} += length $valBuff;
+                        if ($$subFixup{Pointers} and $subdirInfo{Base} == $base) {
+                            $$subFixup{Start} += length $valBuff;
                             push @valFixups, $subFixup;
                         } else {
@@ -2639,9 +1755,9 @@
                         # must decide now if we will write CanonVRD information
                         my $hasVRD;
-                        if ($exifTool->{NEW_VALUE}{$Image::ExifTool::Extra{CanonVRD}}) {
+                        if ($$et{NEW_VALUE}{$Image::ExifTool::Extra{CanonVRD}}) {
                             # adding or deleting as a block
-                            $hasVRD = $exifTool->GetNewValues('CanonVRD') ? 1 : 0;
-                        } elsif ($exifTool->{DEL_GROUP}{CanonVRD} or
-                                 $exifTool->{DEL_GROUP}{Trailer})
+                            $hasVRD = $et->GetNewValue('CanonVRD') ? 1 : 0;
+                        } elsif ($$et{DEL_GROUP}{CanonVRD} or
+                                 $$et{DEL_GROUP}{Trailer})
                         {
                             $hasVRD = 0;    # deleting as a group
@@ -2662,12 +1778,12 @@
                         #   invalidated anyway by our edits
                         my $odd;
-                        my $oddInfo = $Image::ExifTool::Composite{OriginalDecisionData};
-                        if ($oddInfo and $exifTool->{NEW_VALUE}{$oddInfo}) {
-                            $odd = $exifTool->GetNewValues($dataTag);
+                        my $oddInfo = Image::ExifTool::GetCompositeTagInfo('OriginalDecisionData');
+                        if ($oddInfo and $$et{NEW_VALUE}{$oddInfo}) {
+                            $odd = $et->GetNewValue($dataTag);
                             if ($verbose > 1) {
                                 print $out "    - $dirName:$dataTag\n" if $$newValuePt ne "\0\0\0\0";
                                 print $out "    + $dirName:$dataTag\n" if $odd;
                             }
-                            ++$exifTool->{CHANGED};
+                            ++$$et{CHANGED};
                         } elsif ($$newValuePt ne "\0\0\0\0") {
                             if (length($$newValuePt) == 4) {
@@ -2675,9 +1791,9 @@
                                 my $offset = Get32u($newValuePt,0);
                                 # absolute offset in JPEG images only
-                                $offset += $base unless $$exifTool{FILE_TYPE} eq 'JPEG';
-                                $odd = Image::ExifTool::Canon::ReadODD($exifTool, $offset);
+                                $offset += $base unless $$et{FILE_TYPE} eq 'JPEG';
+                                $odd = Image::ExifTool::Canon::ReadODD($et, $offset);
                                 $odd = $$odd if ref $odd;
                             } else {
-                                $exifTool->Error("Invalid $$newInfo{Name}",1);
+                                $et->Error("Invalid $$newInfo{Name}",1);
                             }
                         }
@@ -2685,5 +1801,5 @@
                             my $newOffset = length($valBuff);
                             # (ODD offset is absolute in JPEG, so add base offset!)
-                            $newOffset += $base if $$exifTool{FILE_TYPE} eq 'JPEG';
+                            $newOffset += $base if $$et{FILE_TYPE} eq 'JPEG';
                             $newValue = Set32u($newOffset);
                             $dirFixup->AddFixup(length($dirBuff) + 8, $dataTag);
@@ -2703,4 +1819,5 @@
                             @vals = ReadValue(\$oldValue, 0, $readFormName, $readCount, $oldSize);
                             SetByteOrder($oldOrder);
+                            $validateInfo{$newID} = [$newInfo, join(' ',@vals)] unless $$newInfo{IsOffset};
                         }
                         # only support int32 pointers (for now)
@@ -2716,4 +1833,5 @@
                                 return undef;
                             }
+                            $newValuePt = \$newValue;
                         }
                         $offsetInfo or $offsetInfo = $offsetInfo[$ifd] = { };
@@ -2724,5 +1842,5 @@
                         $newCount or $newCount = 1; # make sure count is set for offsetInfo
                         # save value pointer and value count for each tag
-                        $offsetInfo->{$newID} = [$newInfo, $ptr, $newCount, \@vals, $newFormat];
+                        $$offsetInfo{$newID} = [$newInfo, $ptr, $newCount, \@vals, $newFormat];
                     }
 
@@ -2744,12 +1862,13 @@
                         # let the RawConv store the (possibly converted) data member
                         if (ref $conv eq 'CODE') {
-                            &$conv($val, $exifTool);
+                            &$conv($val, $et);
                         } else {
-                            my ($self, $tag, $taginfo) = ($exifTool, $$newInfo{Name}, $newInfo);
-                            #### eval RawConv ($self, $val, $tag, $tagInfo)
+                            my ($priority, @grps);
+                            my ($self, $tag, $tagInfo) = ($et, $$newInfo{Name}, $newInfo);
+                            #### eval RawConv ($self, $val, $tag, $tagInfo, $priority, @grps)
                             eval $conv;
                         }
                     } else {
-                        $$exifTool{$$newInfo{DataMember}} = $val;
+                        $$et{$$newInfo{DataMember}} = $val;
                     }
                 }
@@ -2761,5 +1880,10 @@
             my $fsize = $formatSize[$newFormat];
             my $offsetVal;
-            $newCount = int(($newSize + $fsize - 1) / $fsize);  # set proper count
+            # set proper count
+            $newCount = int(($newSize + $fsize - 1) / $fsize) unless $oldInfo and $$oldInfo{FixedSize};
+            if ($saveForValidate{$newID} and $tagTablePtr eq \%Image::ExifTool::Exif::Main) {
+                my @vals = ReadValue(\$newValue, 0, $newFormName, $newCount, $newSize);
+                $validateInfo{$newID} = join ' ',@vals;
+            }
             if ($newSize > 4) {
                 # zero-pad to an even number of bytes (required by EXIF standard)
@@ -2779,18 +1903,20 @@
                 ($dataTag, $putFirst) = @$newInfo{'DataTag','PutFirst'} if $newInfo;
                 if ($dataTag) {
-                    if ($dataTag eq 'PreviewImage' and ($exifTool->{FILE_TYPE} eq 'JPEG' or
-                        $$exifTool{GENERATE_PREVIEW_INFO}))
+                    if ($dataTag eq 'PreviewImage' and ($$et{FILE_TYPE} eq 'JPEG' or
+                        $$et{GENERATE_PREVIEW_INFO}))
                     {
                         # hold onto the PreviewImage until we can determine if it fits
-                        $exifTool->{PREVIEW_INFO} or $exifTool->{PREVIEW_INFO} = { };
-                        $exifTool->{PREVIEW_INFO}{Data} = $$newValuePt;
-                        $exifTool->{PREVIEW_INFO}{ChangeBase} = 1 if $$newInfo{ChangeBase};
+                        $$et{PREVIEW_INFO} or $$et{PREVIEW_INFO} = {
+                            Data => $$newValuePt,
+                            Fixup => new Image::ExifTool::Fixup,
+                        };
+                        $$et{PREVIEW_INFO}{ChangeBase} = 1 if $$newInfo{ChangeBase};
                         if ($$newInfo{IsOffset} and $$newInfo{IsOffset} eq '2') {
-                            $exifTool->{PREVIEW_INFO}{NoBaseShift} = 1;
+                            $$et{PREVIEW_INFO}{NoBaseShift} = 1;
                         }
                         # use original preview size if we will attempt to load it later
                         $newCount = $oldCount if $$newValuePt eq 'LOAD_PREVIEW';
                         $$newValuePt = '';
-                    } elsif ($dataTag eq 'LeicaTrailer' and $$exifTool{LeicaTrailer}) {
+                    } elsif ($dataTag eq 'LeicaTrailer' and $$et{LeicaTrailer}) {
                         $$newValuePt = '';
                     }
@@ -2798,5 +1924,5 @@
                 if ($putFirst and $$dirInfo{HeaderPtr}) {
                     my $hdrPtr = $$dirInfo{HeaderPtr};
-                    # place this value immediately after the TIFF header
+                    # place this value immediately after the TIFF header (eg. IIQ maker notes)
                     $offsetVal = Set32u(length $$hdrPtr);
                     $$hdrPtr .= $$newValuePt;
@@ -2834,11 +1960,16 @@
             }
         }
+        if (%validateInfo) {
+            ValidateImageData($et, \%validateInfo, $dirName, 1);
+            undef %validateInfo;
+        }
         if ($ignoreCount) {
             my $y = $ignoreCount > 1 ? 'ies' : 'y';
-            $exifTool->Warn("Removed $ignoreCount invalid entr$y from $name", 1);
+            my $verb = $$dirInfo{FixBase} ? 'Ignored' : 'Removed';
+            $et->Warn("$verb $ignoreCount invalid entr$y from $name", 1);
         }
         if ($fixCount) {
             my $s = $fixCount > 1 ? 's' : '';
-            $exifTool->Warn("Fixed invalid count$s for $fixCount $name tag$s", 1);
+            $et->Warn("Fixed invalid count$s for $fixCount $name tag$s", 1);
         }
 #..............................................................................
@@ -2854,5 +1985,7 @@
         my $isNextIFD = ($$dirInfo{Multi} and ($nextIfdOffset or
                         # account for the case where we will create the next IFD
-                        ($dirName eq 'IFD0' and $exifTool->{ADD_DIRS}{'IFD1'})));
+                        # (IFD1 only, but not in TIFF-format images)
+                        ($dirName eq 'IFD0' and $$et{ADD_DIRS}{'IFD1'} and
+                         $$et{FILE_TYPE} ne 'TIFF')));
         # calculate number of entries in new directory
         my $newEntries = length($dirBuff) / 12;
@@ -2866,5 +1999,5 @@
             ++$deleteAll if defined $deleteAll;
             $verbose > 1 and print $out "    - $allMandatory mandatory tag(s)\n";
-            $exifTool->{CHANGED} -= $addMandatory;    # didn't change these after all
+            $$et{CHANGED} -= $addMandatory;    # didn't change these after all
         }
         if ($ifd and not $newEntries) {
@@ -2874,11 +2007,17 @@
         # apply one-time fixup for entry-based offsets
         if ($entryBasedFixup) {
-            $entryBasedFixup->{Shift} = length($dirBuff) + 4;
+            $$entryBasedFixup{Shift} = length($dirBuff) + 4;
             $entryBasedFixup->ApplyFixup(\$dirBuff);
             undef $entryBasedFixup;
         }
+        # initialize next IFD pointer to zero
+        my $nextIFD = Set32u(0);
+        # some cameras use a different amount of padding after the makernote IFD
+        if ($dirName eq 'MakerNotes' and $$dirInfo{Parent} =~ /^(ExifIFD|IFD0)$/) {
+            my ($rel, $pad) = Image::ExifTool::MakerNotes::GetMakerNoteOffset($et);
+            $nextIFD = "\0" x $pad if defined $pad and ($pad==0 or ($pad>4 and $pad<=32));
+        }
         # add directory entry count to start of IFD and next IFD pointer to end
-        # (temporarily set next IFD pointer to zero)
-        $newData .= Set16u($newEntries) . $dirBuff . Set32u(0);
+        $newData .= Set16u($newEntries) . $dirBuff . $nextIFD;
         # get position of value data in newData
         my $valPos = length($newData);
@@ -2890,5 +2029,5 @@
         }
         # remember position of 'next IFD' pointer so we can set it next time around
-        $nextIfdPos = $valPos - 4;
+        $nextIfdPos = length($nextIFD) ? $valPos - length($nextIFD) : undef;
         # add value data after IFD
         $newData .= $valBuff;
@@ -2930,5 +2069,5 @@
                 # check to be sure we got the right offset
                 unless (Get32u(\$newData, $offset) == 0xfeedf00d) {
-                    $exifTool->Error("Internal error while rewriting $name");
+                    $et->Error("Internal error while rewriting $name");
                     return undef;
                 }
@@ -2941,6 +2080,6 @@
         # (which is at the end of this directory)
         if ($dirFixup) {
-            $dirFixup->{Start} = $newStart + 2;
-            $dirFixup->{Shift} = $valPos - $dirFixup->{Start};
+            $$dirFixup{Start} = $newStart + 2;
+            $$dirFixup{Shift} = $valPos - $$dirFixup{Start};
             $fixup->AddFixup($dirFixup);
         }
@@ -2948,5 +2087,5 @@
         my $valFixup;
         foreach $valFixup (@valFixups) {
-            $valFixup->{Start} += $valPos;
+            $$valFixup{Start} += $valPos;
             $fixup->AddFixup($valFixup);
         }
@@ -2967,30 +2106,32 @@
         my $ifdNum = $dirName =~ s/(\d+)$// ? $1 : 0;
         $dirName .= $ifdNum + 1;
-        $$exifTool{DIR_NAME} = $$exifTool{PATH}[-1] = $dirName;
+        $name =~ s/\d+$//;
+        $name .= $ifdNum + 1;
+        $$et{DIR_NAME} = $$et{PATH}[-1] = $dirName;
         next unless $nextIfdOffset;
 
         # guard against writing the same directory twice
         my $addr = $nextIfdOffset + $base;
-        if ($exifTool->{PROCESSED}{$addr}) {
-            $exifTool->Error("$name pointer references previous $exifTool->{PROCESSED}{$addr} directory", 1);
+        if ($$et{PROCESSED}{$addr}) {
+            $et->Error("$name pointer references previous $$et{PROCESSED}{$addr} directory", 1);
             last;
         }
-        $exifTool->{PROCESSED}{$addr} = $name;
+        $$et{PROCESSED}{$addr} = $name;
 
         if ($dirName eq 'SubIFD1' and not ValidateIFD($dirInfo, $dirStart)) {
-            if ($exifTool->{TIFF_TYPE} eq 'TIFF') {
-                $exifTool->Error('Ignored bad IFD linked from SubIFD', 1);
+            if ($$et{TIFF_TYPE} eq 'TIFF') {
+                $et->Error('Ignored bad IFD linked from SubIFD', 1);
             } elsif ($verbose) {
-                $exifTool->Warn('Ignored bad IFD linked from SubIFD');
+                $et->Warn('Ignored bad IFD linked from SubIFD');
             }
             last;   # don't write bad IFD
         }
-        if ($exifTool->{DEL_GROUP}{$dirName}) {
+        if ($$et{DEL_GROUP}{$dirName}) {
             $verbose and print $out "  Deleting $dirName\n";
-            $raf and $exifTool->Error("Deleting $dirName also deletes subsequent" .
+            $raf and $et->Error("Deleting $dirName also deletes subsequent" .
                                       " IFD's and possibly image data", 1);
-            ++$exifTool->{CHANGED};
-            if ($exifTool->{DEL_GROUP}{$dirName} == 2 and
-                $exifTool->{ADD_DIRS}{$dirName})
+            ++$$et{CHANGED};
+            if ($$et{DEL_GROUP}{$dirName} == 2 and
+                $$et{ADD_DIRS}{$dirName})
             {
                 my $emptyIFD = "\0" x 2;    # start with empty IFD
@@ -3035,5 +2176,5 @@
                     require Image::ExifTool::PanasonicRaw;
                     my $err = Image::ExifTool::PanasonicRaw::PatchRawDataOffset($offsetInfo, $raf, $ifd);
-                    $err and $exifTool->Error($err);
+                    $err and $et->Error($err);
                 }
                 my $tagID;
@@ -3041,8 +2182,8 @@
                 # data before main image data if both exist in the same IFD
                 foreach $tagID (reverse sort keys %$offsetInfo) {
-                    my $tagInfo = $offsetInfo->{$tagID}[0];
+                    my $tagInfo = $$offsetInfo{$tagID}[0];
                     next unless $$tagInfo{IsOffset}; # handle byte counts with offsets
-                    my $sizeInfo = $offsetInfo->{$$tagInfo{OffsetPair}};
-                    $sizeInfo or $exifTool->Error("No size tag for $dirName:$$tagInfo{Name}"), next;
+                    my $sizeInfo = $$offsetInfo{$$tagInfo{OffsetPair}};
+                    $sizeInfo or $et->Error("No size tag for $dirName:$$tagInfo{Name}"), next;
                     my $dataTag = $$tagInfo{DataTag};
                     # write TIFF image data (strips or tiles) later if requested
@@ -3056,7 +2197,7 @@
                         (not defined $dataTag or not defined $offsetData{$dataTag}))
                     {
-                        push @writeLater, [ $offsetInfo->{$tagID}, $sizeInfo ];
+                        push @writeLater, [ $$offsetInfo{$tagID}, $sizeInfo ];
                     } else {
-                        push @offsetList, [ $offsetInfo->{$tagID}, $sizeInfo ];
+                        push @offsetList, [ $$offsetInfo{$tagID}, $sizeInfo ];
                     }
                 }
@@ -3071,5 +2212,5 @@
                 # must be the same number of offset and byte count values
                 unless ($count == $count2) {
-                    $exifTool->Error("Offsets/ByteCounts disagree on count for $$tagInfo{Name}");
+                    $et->Error("Offsets/ByteCounts disagree on count for $$tagInfo{Name}");
                     return undef;
                 }
@@ -3080,5 +2221,5 @@
                 $n > 4 and $byteCounts = Get32u(\$newData, $byteCounts);
                 if ($byteCounts < 0 or $byteCounts + $n > length($newData)) {
-                    $exifTool->Error("Error reading $$tagInfo{Name} byte counts");
+                    $et->Error("Error reading $$tagInfo{Name} byte counts");
                     return undef;
                 }
@@ -3094,5 +2235,5 @@
                 # use different base if necessary for some offsets (Minolta A200)
                 if ($$tagInfo{WrongBase}) {
-                    my $self = $exifTool;
+                    my $self = $et;
                     #### eval WrongBase ($self)
                     $wrongBase = eval $$tagInfo{WrongBase} || 0;
@@ -3113,5 +2254,5 @@
                         $oldEnd = $$oldOffset[$n] + $$oldSize[$n];
                         # update TIFF_END as if we read this data from file
-                        UpdateTiffEnd($exifTool, $oldEnd + $dbase);
+                        UpdateTiffEnd($et, $oldEnd + $dbase);
                     }
                     my $offsetPos = $offsets + $n * 4;
@@ -3128,5 +2269,5 @@
                         $offset -= $dpos;
                     } elsif ($size != 0xfeedfeed) {
-                        $exifTool->Error('Internal error (no offset)');
+                        $et->Error('Internal error (no offset)');
                         return undef;
                     }
@@ -3136,18 +2277,18 @@
                     if ($size == 0xfeedfeed) {
                         unless (defined $dataTag) {
-                            $exifTool->Error("No DataTag defined for $$tagInfo{Name}");
+                            $et->Error("No DataTag defined for $$tagInfo{Name}");
                             return undef;
                         }
                         unless (defined $offsetData{$dataTag}) {
-                            $exifTool->Error("Internal error (no $dataTag)");
+                            $et->Error("Internal error (no $dataTag)");
                             return undef;
                         }
                         if ($count > 1) {
-                            $exifTool->Error("Can't modify $$tagInfo{Name} with count $count");
+                            $et->Error("Can't modify $$tagInfo{Name} with count $count");
                             return undef;
                         }
                         $buff = $offsetData{$dataTag};
                         if ($formatSize[$format] != 4) {
-                            $exifTool->Error("$$cntInfo{Name} is not int32");
+                            $et->Error("$$cntInfo{Name} is not int32");
                             return undef;
                         }
@@ -3158,6 +2299,6 @@
                         # pad if necessary (but don't pad contiguous image blocks)
                         my $pad = 0;
-                        ++$pad if $size & 0x01 and ($n+1 >= $count or not $oldEnd or
-                                  $oldEnd != $$oldOffset[$n+1]);
+                        ++$pad if ($blockSize + $size) & 0x01 and ($n+1 >= $count or
+                                  not $oldEnd or $oldEnd != $$oldOffset[$n+1]);
                         # preserve original image padding if specified
                         if ($$origDirInfo{PreserveImagePadding} and $n+1 < $count and
@@ -3180,5 +2321,5 @@
                         # take data from old dir data buffer
                         $buff = substr($$dataPt, $offset, $size);
-                    } elsif ($$exifTool{TIFF_TYPE} eq 'MRW') {
+                    } elsif ($$et{TIFF_TYPE} eq 'MRW') {
                         # TTW segment must be an even 4 bytes long, so pad now if necessary
                         my $n = length $newData;
@@ -3193,6 +2334,6 @@
                         # (data was read OK)
                         # patch incorrect ThumbnailOffset in Sony A100 1.00 ARW images
-                        if ($$exifTool{TIFF_TYPE} eq 'ARW' and $$tagInfo{Name} eq 'ThumbnailOffset' and
-                            $$exifTool{Model} eq 'DSLR-A100' and $buff !~ /^\xff\xd8\xff/)
+                        if ($$et{TIFF_TYPE} eq 'ARW' and $$tagInfo{Name} eq 'ThumbnailOffset' and
+                            $$et{Model} eq 'DSLR-A100' and $buff !~ /^\xff\xd8\xff/)
                         {
                             my $pos = $offset + $dbase + $dpos;
@@ -3202,7 +2343,7 @@
                             {
                                 $buff = $try;
-                                $exifTool->Warn('Adjusted incorrect A100 ThumbnailOffset', 1);
+                                $et->Warn('Adjusted incorrect A100 ThumbnailOffset', 1);
                             } else {
-                                $exifTool->Error('Invalid ThumbnailImage');
+                                $et->Error('Invalid ThumbnailImage');
                             }
                         }
@@ -3210,5 +2351,5 @@
                         # Grrr.  The Canon 350D writes the thumbnail with an incorrect byte count
                         my $diff = $offset + $size - $dataLen;
-                        $exifTool->Warn("ThumbnailImage runs outside EXIF data by $diff bytes (truncated)",1);
+                        $et->Warn("ThumbnailImage runs outside EXIF data by $diff bytes (truncated)",1);
                         # set the size to the available data
                         $size -= $diff;
@@ -3218,8 +2359,8 @@
                         # get the truncated image
                         $buff = substr($$dataPt, $offset, $size);
-                    } elsif ($$tagInfo{Name} eq 'PreviewImageStart' and $exifTool->{FILE_TYPE} eq 'JPEG') {
+                    } elsif ($$tagInfo{Name} eq 'PreviewImageStart' and $$et{FILE_TYPE} eq 'JPEG') {
                         # try to load the preview image using the specified offset
                         undef $buff;
-                        my $r = $exifTool->{RAF};
+                        my $r = $$et{RAF};
                         if ($r and not $raf) {
                             my $tell = $r->Tell();
@@ -3227,6 +2368,6 @@
                             undef $buff unless $r->Seek($offset+$base+$dataPos,0) and
                                                $r->Read($buff,$size) == $size and
-                                               $buff =~ /^.\xd8\xff[\xc4\xdb\xe0-\xef]/;
-                            $r->Seek($tell, 0) or $exifTool->Error('Seek error'), return undef;
+                                               $buff =~ /^.\xd8\xff[\xc4\xdb\xe0-\xef]/s;
+                            $r->Seek($tell, 0) or $et->Error('Seek error'), return undef;
                         }
                         # set flag if we must load PreviewImage
@@ -3234,21 +2375,27 @@
                     } else {
                         my $dataName = $dataTag || $$tagInfo{Name};
-                        return undef if $exifTool->Error("Error reading $dataName data in $name", $inMakerNotes);
+                        return undef if $et->Error("Error reading $dataName data in $name", $inMakerNotes);
                         $buff = '';
                     }
                     if ($$tagInfo{Name} eq 'PreviewImageStart') {
-                        if ($$exifTool{FILE_TYPE} eq 'JPEG' and not $$tagInfo{MakerPreview}) {
+                        if ($$et{FILE_TYPE} eq 'JPEG' and not $$tagInfo{MakerPreview}) {
                             # hold onto the PreviewImage until we can determine if it fits
-                            $exifTool->{PREVIEW_INFO} or $exifTool->{PREVIEW_INFO} = { };
-                            $exifTool->{PREVIEW_INFO}{Data} = $buff;
+                            $$et{PREVIEW_INFO} or $$et{PREVIEW_INFO} = {
+                                Data => $buff,
+                                Fixup => new Image::ExifTool::Fixup,
+                            };
                             if ($$tagInfo{IsOffset} and $$tagInfo{IsOffset} eq '2') {
-                                $exifTool->{PREVIEW_INFO}{NoBaseShift} = 1;
+                                $$et{PREVIEW_INFO}{NoBaseShift} = 1;
+                            }
+                            if ($offset >= 0 and $offset+$size <= $dataLen) {
+                                # set flag indicating this preview wasn't in a trailer
+                                $$et{PREVIEW_INFO}{WasContained} = 1;
                             }
                             $buff = '';
-                        } elsif ($$exifTool{TIFF_TYPE} eq 'ARW' and $$exifTool{Model}  eq 'DSLR-A100') {
+                        } elsif ($$et{TIFF_TYPE} eq 'ARW' and $$et{Model}  eq 'DSLR-A100') {
                             # the A100 double-references the same preview, so ignore the
                             # second one (the offset and size will be patched later)
-                            next if $$exifTool{A100PreviewLength};
-                            $$exifTool{A100PreviewLength} = length $buff if defined $buff;
+                            next if $$et{A100PreviewLength};
+                            $$et{A100PreviewLength} = length $buff if defined $buff;
                         }
                     }
@@ -3278,5 +2425,5 @@
         # verify that nothing else got written after determining TTW length
         if (defined $ttwLen and $ttwLen != length($newData)) {
-            $exifTool->Error('Internal error writing MRW TTW');
+            $et->Error('Internal error writing MRW TTW');
         }
     }
@@ -3290,5 +2437,5 @@
             my $format = Get16u(\$newData, $entry + 2);
             if ($format < 1 or $format > 13) {
-                $exifTool->Error('Internal error copying huge value');
+                $et->Error('Internal error copying huge value');
                 last;
             } else {
@@ -3302,5 +2449,5 @@
                     $subIfdDataFixup->AddFixup($entry + 8);
                     # save fixup in imageData list
-                    $$blockInfo[4] = $subIfdDataFixup; 
+                    $$blockInfo[4] = $subIfdDataFixup;
                 }
                 # must reset entry pointer so we don't use it again in a parent IFD!
@@ -3313,5 +2460,5 @@
             # but it will actually be at length($newData) + $blockSize.  So adjust
             # accordingly (and subtract an extra Start because this shift is applied later)
-            $subFix->{Shift} += length($newData) - $$subFix{BlockLen} - 2 * $$subFix{Start} + $blockSize;
+            $$subFix{Shift} += length($newData) - $$subFix{BlockLen} - 2 * $$subFix{Start} + $blockSize;
             $subFix->ApplyFixup(\$newData);
         }
@@ -3332,46 +2479,43 @@
         $fixup->SetMarkerPointers(\$newData, 'CanonVRD', length($newData) + $blockSize);
         if ($newDataPos) {
-            $fixup->{Shift} += $newDataPos;
+            $$fixup{Shift} += $newDataPos;
             $fixup->ApplyFixup(\$newData);
         }
         # save fixup for adjusting Leica trailer offset if necessary
-        if ($$exifTool{LeicaTrailer}) {
-            my $trail = $$exifTool{LeicaTrailer};
-            $$trail{Fixup} or $$trail{Fixup} = new Image::ExifTool::Fixup;
-            $$trail{Fixup}->AddFixup($fixup);
-        }
+        $$et{LeicaTrailer}{Fixup}->AddFixup($fixup) if $$et{LeicaTrailer};
         # save fixup for PreviewImage in JPEG file if necessary
-        my $previewInfo = $exifTool->{PREVIEW_INFO};
+        my $previewInfo = $$et{PREVIEW_INFO};
         if ($previewInfo) {
-            my $pt = \$previewInfo->{Data}; # image data or 'LOAD_PREVIEW' flag
+            my $pt = \$$previewInfo{Data}; # image data or 'LOAD_PREVIEW' flag
             # now that we know the size of the EXIF data, first test to see if our new image fits
             # inside the EXIF segment (remember about the TIFF and EXIF headers: 8+6 bytes)
             if (($$pt ne 'LOAD_PREVIEW' and length($$pt) + length($newData) + 14 <= 0xfffd and
-                not $previewInfo->{IsTrailer}) or
-                $previewInfo->{IsShort}) # must fit in this segment if using short pointers
+                not $$previewInfo{IsTrailer}) or
+                $$previewInfo{IsShort}) # must fit in this segment if using short pointers
             {
                 # It fits! (or must exist in EXIF segment), so fixup the
                 # PreviewImage pointers and stuff the preview image in here
                 my $newPos = length($newData) + $newDataPos;
-                $newPos += ($previewInfo->{BaseShift} || 0);
-                if ($previewInfo->{Relative}) {
+                $newPos += ($$previewInfo{BaseShift} || 0);
+                if ($$previewInfo{Relative}) {
                     # calculate our base by looking at how far the pointer got shifted
-                    $newPos -= $fixup->GetMarkerPointers(\$newData, 'PreviewImage');
+                    $newPos -= ($fixup->GetMarkerPointers(\$newData, 'PreviewImage') || 0);
                 }
                 $fixup->SetMarkerPointers(\$newData, 'PreviewImage', $newPos);
                 $newData .= $$pt;
-                delete $exifTool->{PREVIEW_INFO};   # done with our preview data
-                $exifTool->{DEL_PREVIEW} = 1;       # set flag to delete old preview
+                # set flag to delete old preview unless it was contained in the EXIF
+                $$et{DEL_PREVIEW} = 1 unless $$et{PREVIEW_INFO}{WasContained};
+                delete $$et{PREVIEW_INFO};   # done with our preview data
             } else {
                 # Doesn't fit, or we still don't know, so save fixup information
                 # and put the preview at the end of the file
-                $previewInfo->{Fixup} or $previewInfo->{Fixup} = new Image::ExifTool::Fixup;
-                $previewInfo->{Fixup}->AddFixup($fixup);
+                $$previewInfo{Fixup} or $$previewInfo{Fixup} = new Image::ExifTool::Fixup;
+                $$previewInfo{Fixup}->AddFixup($fixup);
             }
         } elsif (defined $newData and $deleteAll) {
             $newData = '';  # delete both IFD0 and IFD1 since only mandatory tags remain
-        } elsif ($$exifTool{A100PreviewLength}) {
+        } elsif ($$et{A100PreviewLength}) {
             # save preview image start for patching A100 quirks later
-            $$exifTool{A100PreviewStart} = $fixup->GetMarkerPointers(\$newData, 'PreviewImage');
+            $$et{A100PreviewStart} = $fixup->GetMarkerPointers(\$newData, 'PreviewImage');
         }
         # save location of last IFD for use in Canon RAW header
@@ -3381,8 +2525,8 @@
         }
         # recrypt SR2 SubIFD data if necessary
-        my $key = $$exifTool{SR2SubIFDKey};
+        my $key = $$et{SR2SubIFDKey};
         if ($key) {
             my $start = $fixup->GetMarkerPointers(\$newData, 'SR2SubIFDOffset');
-            my $len = $$exifTool{SR2SubIFDLength};
+            my $len = $$et{SR2SubIFDLength};
             # (must subtract 8 for size of TIFF header)
             if ($start and $start - 8 + $len <= length $newData) {
@@ -3396,4 +2540,7 @@
     $newData = '' if defined $newData and length($newData) < 12;
 
+    # set changed if ForceWrite tag was set to "EXIF"
+    ++$$et{CHANGED} if defined $newData and length $newData and $$et{FORCE_WRITE}{EXIF};
+
     return $newData;    # return our directory data
 }
@@ -3417,5 +2564,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteIPTC.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteIPTC.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteIPTC.pl	(revision 34921)
@@ -86,5 +86,5 @@
     my $code = $iptcCharsetInv{uc($val)};
     unless ($code) {
-        if (($code = $val) =~ s/ESC /\x1b/g) {  # translate ESC chars
+        if (($code = $val) =~ s/ESC */\x1b/ig) {  # translate ESC chars
             $code =~ s/, \x1b/\x1b/g;   # remove comma separators
             $code =~ tr/ //d;           # remove spaces
@@ -102,9 +102,9 @@
 sub CheckIPTC($$$)
 {
-    my ($exifTool, $tagInfo, $valPtr) = @_;
-    my $format = $$tagInfo{Format} || $tagInfo->{Table}->{FORMAT} || '';
+    my ($et, $tagInfo, $valPtr) = @_;
+    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";
         }
@@ -128,9 +128,13 @@
             }
         }
-        if (defined $minlen) {
+        if (defined $minlen and $fmt ne 'string') { # (must truncate strings later, after recoding)
             $maxlen or $maxlen = $minlen;
-            return "String too short (minlen is $minlen)" if $len < $minlen;
-            if ($len > $maxlen and not $exifTool->Options('IgnoreMinorErrors')) {
-                $$exifTool{CHECK_WARN} = "[minor] IPTC:$$tagInfo{Name} exceeds length limit (truncated)";
+            if ($len < $minlen) {
+                unless ($$et{OPTIONS}{IgnoreMinorErrors}) {
+                    return "[Minor] String too short (minlen is $minlen)";
+                }
+                $$et{CHECK_WARN} = "String too short for IPTC:$$tagInfo{Name} (written anyway)";
+            } elsif ($len > $maxlen and not $$et{OPTIONS}{IgnoreMinorErrors}) {
+                $$et{CHECK_WARN} = "[Minor] IPTC:$$tagInfo{Name} exceeds length limit (truncated)";
                 $$valPtr = substr($$valPtr, 0, $maxlen);
             }
@@ -150,5 +154,5 @@
 sub FormatIPTC($$$$$;$)
 {
-    my ($exifTool, $tagInfo, $valPtr, $xlatPtr, $rec, $read) = @_;
+    my ($et, $tagInfo, $valPtr, $xlatPtr, $rec, $read) = @_;
     my $format = $$tagInfo{Format} || $$tagInfo{Table}{FORMAT};
     return unless $format;
@@ -177,8 +181,28 @@
         if ($rec == 1) {
             if ($$tagInfo{Name} eq 'CodedCharacterSet') {
-                $$xlatPtr = HandleCodedCharset($exifTool, $$valPtr);
+                $$xlatPtr = HandleCodedCharset($et, $$valPtr);
             }
         } elsif ($$xlatPtr and $rec < 7 and $$valPtr =~ /[\x80-\xff]/) {
-            TranslateCodedString($exifTool, $valPtr, $xlatPtr, $read);
+            TranslateCodedString($et, $valPtr, $xlatPtr, $read);
+        }
+        # must check length now (after any string recoding)
+        if (not $read and $format =~ /^string\[(\d+),?(\d*)\]$/) {
+            my ($minlen, $maxlen) = ($1, $2);
+            my $len = length $$valPtr;
+            $maxlen or $maxlen = $minlen;
+            if ($len < $minlen) {
+                if ($et->Warn("String too short for IPTC:$$tagInfo{Name} (padded)", 2)) {
+                    $$valPtr .= ' ' x ($minlen - $len);
+                }
+            } elsif ($len > $maxlen) {
+                if ($et->Warn("IPTC:$$tagInfo{Name} exceeds length limit (truncated)", 2)) {
+                    $$valPtr = substr($$valPtr, 0, $maxlen);
+                    # make sure UTF-8 is still valid
+                    if (($$xlatPtr || $et->Options('Charset')) eq 'UTF8') {
+                        require Image::ExifTool::XMP;
+                        Image::ExifTool::XMP::FixUTF8($valPtr,'.');
+                    }
+                }
+            }
         }
     }
@@ -192,5 +216,5 @@
 {
     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;
@@ -214,10 +238,10 @@
             $tz = '+0000';  # UTC
         } else {
-            # use local system timezone by default 
+            # use local system timezone by default
             my (@tm, $time);
-            if ($date and $date =~ /^(\d{4}):(\d{2}):(\d{2})\s*$/ and eval 'require Time::Local') {
+            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);
@@ -238,4 +262,15 @@
         undef $val;     # time format error
     }
+    return $val;
+}
+
+#------------------------------------------------------------------------------
+# Inverse print conversion for IPTC date or time value
+# Inputs: 0) ExifTool ref, 1) IPTC date or 'now'
+# Returns: IPTC date
+sub InverseDateOrTime($$)
+{
+    my ($et, $val) = @_;
+    return $et->TimeNow() if lc($val) eq 'now';
     return $val;
 }
@@ -292,7 +327,7 @@
 sub DoWriteIPTC($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    my $verbose = $et->Options('Verbose');
+    my $out = $et->Options('TextOut');
 
     # avoid editing IPTC directory unless necessary:
@@ -300,9 +335,9 @@
     # - avoids changing current MD5 digest unnecessarily
     # - avoids adding mandatory tags unless some other IPTC is changed
-    unless (exists $$exifTool{EDIT_DIRS}{$$dirInfo{DirName}} or
-        # standard IPTC tags in other locations should be edited too (ie. AFCP_IPTC)
-        ($tagTablePtr = \%Image::ExifTool::IPTC::Main and exists $$exifTool{EDIT_DIRS}{IPTC}))
+    unless (exists $$et{EDIT_DIRS}{$$dirInfo{DirName}} or
+        # standard IPTC tags in other locations should be edited too (eg. AFCP_IPTC)
+        ($tagTablePtr eq \%Image::ExifTool::IPTC::Main and exists $$et{EDIT_DIRS}{IPTC}))
     {
-        print $out "$$exifTool{INDENT}  [nothing changed]\n" if $verbose;
+        print $out "$$et{INDENT}  [nothing changed]\n" if $verbose;
         return undef;
     }
@@ -317,6 +352,6 @@
 
     # start by assuming default IPTC encoding
-    my $xlat = $exifTool->Options('CharsetIPTC');
-    undef $xlat if $xlat eq $exifTool->Options('Charset');
+    my $xlat = $et->Options('CharsetIPTC');
+    undef $xlat if $xlat eq $et->Options('Charset');
 
     # make sure our dataLen is defined (note: allow zero length directory)
@@ -330,5 +365,5 @@
                          substr($$dataPt, $start + 3, 1) eq "\x1c")
     {
-        $exifTool->Warn('IPTC data was improperly byte-swapped');
+        $et->Warn('IPTC data was improperly byte-swapped');
         my $newData = pack('N*', unpack('V*', substr($$dataPt, $start, $dirLen) . "\0\0\0"));
         $dataPt = \$newData;
@@ -339,7 +374,7 @@
     my %recordNum;
     foreach $tag (Image::ExifTool::TagTableKeys($tagTablePtr)) {
-        $tagInfo = $tagTablePtr->{$tag};
+        $tagInfo = $$tagTablePtr{$tag};
         $$tagInfo{SubDirectory} or next;
-        my $table = $tagInfo->{SubDirectory}->{TagTable} or next;
+        my $table = $$tagInfo{SubDirectory}{TagTable} or next;
         my $subTablePtr = Image::ExifTool::GetTagTable($table);
         $recordNum{$subTablePtr} = $tag;
@@ -348,5 +383,5 @@
     # loop through new values and accumulate all IPTC information
     # into lists based on their IPTC record type
-    foreach $tagInfo ($exifTool->GetNewTagInfoList()) {
+    foreach $tagInfo ($et->GetNewTagInfoList()) {
         my $table = $$tagInfo{Table};
         my $record = $recordNum{$table};
@@ -392,10 +427,10 @@
                 if ($rec < $lastRec) {
                     if ($rec == 0) {
-                        return undef if $exifTool->Warn("IPTC record 0 encountered, subsequent records ignored", 1);
+                        return undef if $et->Warn("IPTC record 0 encountered, subsequent records ignored", 2);
                         undef $rec;
                         $pos = $dirEnd;
                         $len = 0;
                     } else {
-                        return undef if $exifTool->Warn("IPTC doesn't conform to spec: Records out of sequence", 1);
+                        return undef if $et->Warn("IPTC doesn't conform to spec: Records out of sequence", 2);
                     }
                 }
@@ -455,14 +490,14 @@
                                 next if $foundRec{$lastRec}->{$mandTag};
                                 unless ($subTablePtr) {
-                                    $tagInfo = $tagTablePtr->{$lastRec};
+                                    $tagInfo = $$tagTablePtr{$lastRec};
                                     $tagInfo and $$tagInfo{SubDirectory} or warn("WriteIPTC: Internal error 1\n"), next;
-                                    $tagInfo->{SubDirectory}->{TagTable} or next;
-                                    $subTablePtr = Image::ExifTool::GetTagTable($tagInfo->{SubDirectory}->{TagTable});
+                                    $$tagInfo{SubDirectory}{TagTable} or next;
+                                    $subTablePtr = Image::ExifTool::GetTagTable($$tagInfo{SubDirectory}{TagTable});
                                 }
-                                $tagInfo = $subTablePtr->{$mandTag} or warn("WriteIPTC: Internal error 2\n"), next;
-                                my $value = $mandatory->{$mandTag};
-                                $exifTool->VerboseValue("+ IPTC:$$tagInfo{Name}", $value, ' (mandatory)');
+                                $tagInfo = $$subTablePtr{$mandTag} or warn("WriteIPTC: Internal error 2\n"), next;
+                                my $value = $$mandatory{$mandTag};
+                                $et->VerboseValue("+ IPTC:$$tagInfo{Name}", $value, ' (mandatory)');
                                 # apply necessary format conversions
-                                FormatIPTC($exifTool, $tagInfo, \$value, \$xlat, $lastRec);
+                                FormatIPTC($et, $tagInfo, \$value, \$xlat, $lastRec);
                                 $len = length $value;
                                 # generate our new entry
@@ -470,5 +505,5 @@
                                 $newData .= $entry . $value;    # add entry to new IPTC data
                                 # (don't mark as changed if just mandatory tags changed)
-                                # ++$exifTool->{CHANGED};
+                                # ++$$et{CHANGED};
                             }
                         }
@@ -487,5 +522,5 @@
                 }
                 my $newTag = $$tagInfo{TagID};
-                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
+                my $nvHash = $et->GetNewValueHash($tagInfo);
                 # only add new values if...
                 my ($doSet, @values);
@@ -496,23 +531,23 @@
                 } elsif ($$tagInfo{List}) {
                     # ...tag is List and it existed before or we are creating it
-                    $doSet = 1 if $found or Image::ExifTool::IsCreating($nvHash);
+                    $doSet = 1 if $found ? not $$nvHash{CreateOnly} : $$nvHash{IsCreating};
                 } else {
                     # ...tag didn't exist before and we are creating it
-                    $doSet = 1 if not $found and Image::ExifTool::IsCreating($nvHash);
+                    $doSet = 1 if not $found and $$nvHash{IsCreating};
                 }
                 if ($doSet) {
-                    @values = Image::ExifTool::GetNewValues($nvHash);
+                    @values = $et->GetNewValue($nvHash);
                     @values and $foundRec{$newRec}->{$newTag} = $found | 0x04;
                     # write tags for each value in list
                     my $value;
                     foreach $value (@values) {
-                        $exifTool->VerboseValue("+ IPTC:$$tagInfo{Name}", $value);
+                        $et->VerboseValue("+ $$dirInfo{DirName}:$$tagInfo{Name}", $value);
                         # reset allMandatory flag if a non-mandatory tag is written
                         if ($allMandatory) {
                             my $mandatory = $mandatory{$newRec};
-                            $allMandatory = 0 unless $mandatory and $mandatory->{$newTag};
+                            $allMandatory = 0 unless $mandatory and $$mandatory{$newTag};
                         }
                         # apply necessary format conversions
-                        FormatIPTC($exifTool, $tagInfo, \$value, \$xlat, $newRec);
+                        FormatIPTC($et, $tagInfo, \$value, \$xlat, $newRec);
                         # (note: IPTC string values are NOT null terminated)
                         $len = length $value;
@@ -526,5 +561,5 @@
                         }
                         $newData .= $entry . $value;    # add entry to new IPTC data
-                        ++$exifTool->{CHANGED};
+                        ++$$et{CHANGED};
                     }
                 }
@@ -553,13 +588,15 @@
         $tagInfo = $set{$rec}->{$tag};
         if ($tagInfo) {
-            my $nvHash = $exifTool->GetNewValueHash($tagInfo);
+            my $nvHash = $et->GetNewValueHash($tagInfo);
             $len = $pos - $valuePtr;
             my $val = substr($$dataPt, $valuePtr, $len);
+            # remove null terminator if it exists (written by braindead software like Picasa 2.0)
+            $val =~ s/\0+$// if $$tagInfo{Format} and $$tagInfo{Format} =~ /^string/;
             my $oldXlat = $xlat;
-            FormatIPTC($exifTool, $tagInfo, \$val, \$xlat, $rec, 1);
-            if (Image::ExifTool::IsOverwriting($nvHash, $val)) {
+            FormatIPTC($et, $tagInfo, \$val, \$xlat, $rec, 1);
+            if ($et->IsOverwriting($nvHash, $val)) {
                 $xlat = $oldXlat;   # don't change translation (not writing this value)
-                $exifTool->VerboseValue("- IPTC:$$tagInfo{Name}", $val);
-                ++$exifTool->{CHANGED};
+                $et->VerboseValue("- $$dirInfo{DirName}:$$tagInfo{Name}", $val);
+                ++$$et{CHANGED};
                 # set deleted flag to indicate we found and deleted this tag
                 $foundRec{$rec}->{$tag} |= 0x02;
@@ -577,10 +614,10 @@
             # handle CodedCharacterSet tag
             my $val = substr($$dataPt, $valuePtr, $pos - $valuePtr);
-            $xlat = HandleCodedCharset($exifTool, $val);
+            $xlat = HandleCodedCharset($et, $val);
         }
         # reset allMandatory flag if a non-mandatory tag is written
         if ($allMandatory) {
             my $mandatory = $mandatory{$rec};
-            unless ($mandatory and $mandatory->{$tag}) {
+            unless ($mandatory and $$mandatory{$tag}) {
                 $allMandatory = 0;
             }
@@ -591,7 +628,7 @@
     # make sure the rest of the data is zero
     if ($tail < $dirEnd) {
-        my $trailer = substr($$dataPt, $tail, $dirEnd-$tail);
-        if ($trailer =~ /[^\0]/) {
-            return undef if $exifTool->Warn('Unrecognized data in IPTC trailer', 1);
+        my $pad = substr($$dataPt, $tail, $dirEnd-$tail);
+        if ($pad =~ /[^\0]/) {
+            return undef if $et->Warn('Unrecognized data in IPTC padding', 2);
         }
     }
@@ -606,22 +643,22 @@
 sub WriteIPTC($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
-
-    my $newData = DoWriteIPTC($exifTool, $dirInfo, $tagTablePtr);
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
+
+    my $newData = DoWriteIPTC($et, $dirInfo, $tagTablePtr);
 
     # calculate standard IPTC digests only if we are writing or deleting
     # Photoshop:IPTCDigest with a value of 'new' or 'old'
     while ($Image::ExifTool::Photoshop::iptcDigestInfo) {
-        my $nvHash = $exifTool->{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo};
+        my $nvHash = $$et{NEW_VALUE}{$Image::ExifTool::Photoshop::iptcDigestInfo};
         last unless defined $nvHash;
-        last unless IsStandardIPTC($exifTool->MetadataPath());
-        my @values = Image::ExifTool::GetNewValues($nvHash);
+        last unless IsStandardIPTC($et->MetadataPath());
+        my @values = $et->GetNewValue($nvHash);
         push @values, @{$$nvHash{DelValue}} if $$nvHash{DelValue};
         my $new = grep /^new$/, @values;
         my $old = grep /^old$/, @values;
         last unless $new or $old;
-        unless (eval 'require Digest::MD5') {
-            $exifTool->Warn('Digest::MD5 must be installed to calculate IPTC digest');
+        unless (eval { require Digest::MD5 }) {
+            $et->Warn('Digest::MD5 must be installed to calculate IPTC digest');
             last;
         }
@@ -638,9 +675,9 @@
             }
             # set NewIPTCDigest data member unless IPTC is being deleted
-            $$exifTool{NewIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt;
+            $$et{NewIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt;
         }
         if ($old) {
             if ($new and not defined $newData) {
-                $$exifTool{OldIPTCDigest} = $$exifTool{NewIPTCDigest};
+                $$et{OldIPTCDigest} = $$et{NewIPTCDigest};
             } elsif ($$dirInfo{DataPt}) { #(may be undef if creating new IPTC)
                 $dataPt = $$dirInfo{DataPt};
@@ -649,9 +686,11 @@
                     $dataPt = \$buff;
                 }
-                $$exifTool{OldIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt;
+                $$et{OldIPTCDigest} = Digest::MD5::md5($$dataPt) if length $$dataPt;
             }
         }
         last;
     }
+    # set changed if ForceWrite tag was set to "IPTC"
+    ++$$et{CHANGED} if defined $newData and length $newData and $$et{FORCE_WRITE}{IPTC};
     return $newData;
 }
@@ -677,5 +716,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePDF.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePDF.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePDF.pl	(revision 34921)
@@ -32,4 +32,9 @@
 );
 
+# map for directories that we can add
+my %pdfMap = (
+    XMP => 'PDF',
+);
+
 #------------------------------------------------------------------------------
 # Validate raw PDF values for writing (string date integer real boolean name)
@@ -38,13 +43,10 @@
 sub CheckPDF($$$)
 {
-    my ($exifTool, $tagInfo, $valPtr) = @_;
+    my ($et, $tagInfo, $valPtr) = @_;
     my $format = $$tagInfo{Writable} || $tagInfo->{Table}->{WRITABLE};
     if (not $format) {
         return 'No writable format';
     } elsif ($format eq 'string') {
-        # convert to Unicode if necessary
-        if ($$valPtr =~ /[\x80-\xff]/) {
-            $$valPtr = "\xfe\xff" . $exifTool->Encode($$valPtr,'UCS2','MM');
-        }
+        # (encode later because list-type string tags need to be encoded as a unit)
     } elsif ($format eq 'date') {
         # be flexible about this for now
@@ -59,5 +61,5 @@
         return 'Invalid PDF name' if $$valPtr =~ /\0/;
     } else {
-        return "Invalid PDF format '$format'";
+        return "Invalid PDF format '${format}'";
     }
     return undef;   # value is OK
@@ -66,17 +68,19 @@
 #------------------------------------------------------------------------------
 # Format value for writing to PDF file
-# Inputs: 0) value, 1) format string (string,date,integer,real,boolean,name)
+# Inputs: 0) ExifTool ref, 1) value, 2) format string (string,date,integer,real,boolean,name)
 # Returns: formatted value or undef on error
 # Notes: Called at write time, so $pdfVer may be checked
-sub WritePDFValue($$)
+sub WritePDFValue($$$)
 {
-    my ($val, $format) = @_;
+    my ($et, $val, $format) = @_;
     if (not $format) {
         return undef;
     } elsif ($format eq 'string') {
+        # encode as UCS2 if it contains any special characters
+        $val = "\xfe\xff" . $et->Encode($val,'UCS2','MM') if $val =~ /[\x80-\xff]/;
         EncodeString(\$val);
     } elsif ($format eq 'date') {
         # convert date to "D:YYYYmmddHHMMSS+-HH'MM'" format
-        $val =~ s/([-+]\d{2}):(\d{2})/$1'$2'/;  # change timezone delimiters if necessary
+        $val =~ s/([-+]\d{2}):(\d{2})/${1}'${2}'/;  # change timezone delimiters if necessary
         $val =~ tr/ ://d;                       # remove spaces and colons
         $val =  "D:$val";                       # add leading "D:"
@@ -273,5 +277,5 @@
 sub WritePDF($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
@@ -281,6 +285,7 @@
     # make sure this is a PDF file
     my $pos = $raf->Tell();
-    $raf->Read($buff, 10) >= 8 or return 0;
-    $buff =~ /^%PDF-(\d+\.\d+)/ or return 0;
+    $raf->Read($buff, 1024) >= 8 or return 0;
+    $buff =~ /^(\s*)%PDF-(\d+\.\d+)/ or return 0;
+    $$et{PDFBase} = length $1;
     $raf->Seek($pos, 0);
 
@@ -288,5 +293,5 @@
     my $newTool = new Image::ExifTool;
     $newTool->Options(List => 1);
-    $newTool->Options(Password => $exifTool->Options('Password'));
+    $newTool->Options(Password => $et->Options('Password'));
     $$newTool{PDF_CAPTURE} = \%capture;
     my $info = $newTool->ImageInfo($raf, 'XMP', 'PDF:*', 'Error', 'Warning');
@@ -294,17 +299,15 @@
     # (note: can't just check $$info{PDFVersion} due to possibility of XMP-pdf:PDFVersion)
     my $vers = $newTool->GetInfo('PDF:PDFVersion');
-    ($pdfVer) = values %$vers;
-    $pdfVer or $exifTool->Error('Missing PDF:PDFVersion'), return 0;
+    # 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) {
-            $exifTool->Error("Can't yet write PDF version $pdfVer"); # (future major version changes)
-            return 1;
-        }
-        $exifTool->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}) {
-        $exifTool->Error($capture{Error} || $$info{Error});
+        $et->Error($capture{Error} || $$info{Error});
         return 1;
     }
@@ -313,8 +316,9 @@
         next if $capture{$obj};
         # any warning we received may give a clue about why this object is missing
-        $exifTool->Error($$info{Warning}) if $$info{Warning};
-        $exifTool->Error("Can't find $obj object");
+        $et->Error($$info{Warning}) if $$info{Warning};
+        $et->Error("Can't find $obj object");
         return 1;
     }
+    $et->InitWriteDirs(\%pdfMap, 'XMP');
 
     # copy file up to start of previous exiftool update or end of file
@@ -327,18 +331,18 @@
         $prevUpdate = $1;
         # rewrite the file up to the original EOF
-        Image::ExifTool::CopyBlock($raf, $outfile, $prevUpdate) or $rtn = -1;
+        Image::ExifTool::CopyBlock($raf, $outfile, $prevUpdate + $$et{PDFBase}) or $rtn = -1;
         # verify that we are now at the start of an ExifTool update
         unless ($raf->Read($buff, length $beginComment) and $buff eq $beginComment) {
-            $exifTool->Error('Previous ExifTool update is corrupted');
+            $et->Error('Previous ExifTool update is corrupted');
             return $rtn;
         }
-        $raf->Seek($prevUpdate, 0) or $rtn = -1;
-        if ($exifTool->{DEL_GROUP}->{'PDF-update'}) {
-            $exifTool->VPrint(0, "  Reverted previous ExifTool updates\n");
-            ++$$exifTool{CHANGED};
+        $raf->Seek($prevUpdate+$$et{PDFBase}, 0) or $rtn = -1;
+        if ($$et{DEL_GROUP}{'PDF-update'}) {
+            $et->VPrint(0, "  Reverted previous ExifTool updates\n");
+            ++$$et{CHANGED};
             return $rtn;
         }
-    } elsif ($exifTool->{DEL_GROUP}->{'PDF-update'}) {
-        $exifTool->Error('File contains no previous ExifTool update');
+    } elsif ($$et{DEL_GROUP}{'PDF-update'}) {
+        $et->Error('File contains no previous ExifTool update');
         return $rtn;
     } else {
@@ -348,5 +352,5 @@
         }
     }
-    $out = $exifTool->Options('TextOut') if $exifTool->Options('Verbose');
+    $out = $et->Options('TextOut') if $et->Options('Verbose');
 #
 # create our new PDF objects to write
@@ -362,5 +366,5 @@
     if ($prevUpdate) {
         unless ($capture{Prev}) {
-            $exifTool->Error("Can't locate trailer dictionary prior to last edit");
+            $et->Error("Can't locate trailer dictionary prior to last edit");
             return $rtn;
         }
@@ -378,5 +382,5 @@
     # delete entire PDF group if specified
     my $infoChanged = 0;
-    if ($exifTool->{DEL_GROUP}->{PDF} and $capture{Info}) {
+    if ($$et{DEL_GROUP}{PDF} and $capture{Info}) {
         delete $capture{Info};
         $info = { XMP => $$info{XMP} }; # remove extracted PDF tags
@@ -395,14 +399,14 @@
     # must encrypt all values in dictionary if they came from an encrypted stream
     CryptObject($infoDict) if $$infoDict{_needCrypt};
-    
+
     # must set line separator before calling WritePDFValue()
     local $/ = $capture{newline};
 
     # rewrite PDF Info tags
-    my $newTags = $exifTool->GetNewTagInfoHash(\%Image::ExifTool::PDF::Info);
+    my $newTags = $et->GetNewTagInfoHash(\%Image::ExifTool::PDF::Info);
     my $tagID;
     foreach $tagID (sort keys %$newTags) {
         my $tagInfo = $$newTags{$tagID};
-        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
+        my $nvHash = $et->GetNewValueHash($tagInfo);
         my (@vals, $deleted);
         my $tag = $$tagInfo{Name};
@@ -421,7 +425,7 @@
             }
             for (;;) {
-                if (Image::ExifTool::IsOverwriting($nvHash, $val) > 0) {
+                if ($et->IsOverwriting($nvHash, $val) > 0) {
                     $deleted = 1;
-                    $exifTool->VerboseValue("- PDF:$tag", $val);
+                    $et->VerboseValue("- PDF:$tag", $val);
                     ++$infoChanged;
                 } else {
@@ -433,11 +437,13 @@
             # don't write this out if we deleted all values
             delete $$infoDict{$tagID} unless @vals;
+        } elsif ($$nvHash{EditOnly}) {
+            next;
         }
         # decide whether we want to write this tag
-        # (always create native PDF information, so don't check IsCreating())
+        # (native PDF information is always preferred, so don't check IsCreating)
         next unless $deleted or $$tagInfo{List} or not exists $$infoDict{$tagID};
 
         # add new values to existing ones
-        my @newVals = Image::ExifTool::GetNewValues($nvHash);
+        my @newVals = $et->GetNewValue($nvHash);
         if (@newVals) {
             push @vals, @newVals;
@@ -445,5 +451,5 @@
             if ($out) {
                 foreach $val (@newVals) {
-                    $exifTool->VerboseValue("+ PDF:$tag", $val);
+                    $et->VerboseValue("+ PDF:$tag", $val);
                 }
             }
@@ -457,13 +463,13 @@
         my $writable = $$tagInfo{Writable} || $Image::ExifTool::PDF::Info{WRITABLE};
         if (not $$tagInfo{List}) {
-            $val = WritePDFValue(shift @vals, $writable);
+            $val = WritePDFValue($et, shift(@vals), $writable);
         } elsif ($$tagInfo{List} eq 'array') {
             foreach $val (@vals) {
-                $val = WritePDFValue($val, $writable);
+                $val = WritePDFValue($et, $val, $writable);
                 defined $val or undef(@vals), last;
             }
             $val = @vals ? \@vals : undef;
         } else {
-            $val = WritePDFValue(join($exifTool->Options('ListSep'), @vals), $writable);
+            $val = WritePDFValue($et, join($et->Options('ListSep'), @vals), $writable);
         }
         if (defined $val) {
@@ -471,9 +477,9 @@
             ++$infoChanged;
         } else {
-            $exifTool->Warn("Error converting $$tagInfo{Name} value");
+            $et->Warn("Error converting $$tagInfo{Name} value");
         }
     }
     if ($infoChanged) {
-        $$exifTool{CHANGED} += $infoChanged;
+        $$et{CHANGED} += $infoChanged;
     } elsif ($prevUpdate) {
         # must still write Info dictionary if it was previously updated
@@ -503,6 +509,6 @@
     );
     my $xmpTable = Image::ExifTool::GetTagTable('Image::ExifTool::XMP::Main');
-    my $oldChanged = $$exifTool{CHANGED};
-    my $newXMP = $exifTool->WriteDirectory(\%xmpInfo, $xmpTable);
+    my $oldChanged = $$et{CHANGED};
+    my $newXMP = $et->WriteDirectory(\%xmpInfo, $xmpTable);
     $newXMP = $$info{XMP} ? ${$$info{XMP}} : '' unless defined $newXMP;
 
@@ -510,10 +516,10 @@
     # XMP is deleted as a block -- so check for this
     unless ($newXMP or $$info{XMP}) {
-        $$exifTool{CHANGED} = $oldChanged;
-        $exifTool->VPrint(0, "  (XMP not changed -- still empty)\n");
+        $$et{CHANGED} = $oldChanged;
+        $et->VPrint(0, "  (XMP not changed -- still empty)\n");
     }
     my ($metaChanged, $rootChanged);
 
-    if ($$exifTool{CHANGED} != $oldChanged and defined $newXMP) {
+    if ($$et{CHANGED} != $oldChanged and defined $newXMP) {
         $metaChanged = 1;
     } elsif ($prevUpdate and $capture{Root}->{Metadata}) {
@@ -550,5 +556,5 @@
     my $rootRef = $$mainDict{Root};
     unless ($rootRef) {
-        $exifTool->Error("Can't find Root dictionary");
+        $et->Error("Can't find Root dictionary");
         return $rtn;
     }
@@ -562,7 +568,7 @@
 # write incremental update if anything was changed
 #
-    if ($$exifTool{CHANGED}) {
+    if ($$et{CHANGED}) {
         # remember position of original EOF
-        my $oldEOF = Tell($outfile);
+        my $oldEOF = Tell($outfile) - $$et{PDFBase};
         Write($outfile, $beginComment) or $rtn = -1;
 
@@ -578,5 +584,5 @@
             }
             # create new entry for xref table
-            $newXRef{$id} = [ Tell($outfile) + length($/), $gen, 'n' ];
+            $newXRef{$id} = [ Tell($outfile) - $$et{PDFBase} + length($/), $gen, 'n' ];
             $keyExt = "$id $gen obj";  # (must set for stream encryption)
             Write($outfile, $/, $keyExt) or $rtn = -1;
@@ -629,6 +635,9 @@
                 my $byte = unpack('H2',chr((hex($1) + 1) & 0xff));
                 substr($id, 1, 2) = $byte;
-            } elsif ($id =~ /^\((.)/s) {
-                substr($id, 1, 1) = chr((ord($1) + 1) & 0xff);
+            } elsif ($id =~ /^\((.)/s and $1 ne '\\' and $1 ne ')' and $1 ne '(') {
+                my $ch = chr((ord($1) + 1) & 0xff);
+                # avoid generating characters that could cause problems
+                $ch = 'a' if $ch =~ /[()\\\x00-\x08\x0a-\x1f\x7f\xff]/;
+                substr($id, 1, 1) = $ch;
             }
             $mainDict->{ID}->[1] = $id;
@@ -636,5 +645,5 @@
 
         # remember position of xref table in file (we will write this next)
-        my $startxref = Tell($outfile) + length($/);
+        my $startxref = Tell($outfile) - $$et{PDFBase} + length($/);
 
         # must write xref as a stream in xref-stream-only files
@@ -642,5 +651,5 @@
 
             # create entry for the xref stream object itself
-            $newXRef{$nextObject++} = [ Tell($outfile) + length($/), 0, 'n' ];
+            $newXRef{$nextObject++} = [ Tell($outfile) - $$et{PDFBase} + length($/), 0, 'n' ];
             $$mainDict{Size} = $nextObject;
             # create xref stream and Index entry
@@ -655,5 +664,5 @@
                     my ($pos, $gen, $type) = @{$newXRef{$id}};
                     if ($pos > 0xffffffff) {
-                        $exifTool->Error('Huge files not yet supported');
+                        $et->Error('Huge files not yet supported');
                         last;
                     }
@@ -702,8 +711,11 @@
 
         # nothing new changed, so copy over previous incremental update
-        $raf->Seek($prevUpdate, 0) or $rtn = -1;
+        $raf->Seek($prevUpdate+$$et{PDFBase}, 0) or $rtn = -1;
         while ($raf->Read($buff, 65536)) {
             Write($outfile, $buff) or $rtn = -1;
         }
+    }
+    if ($rtn > 0 and $$et{CHANGED} and ($$et{DEL_GROUP}{PDF} or $$et{DEL_GROUP}{XMP})) {
+        $et->Warn('ExifTool PDF edits are reversible. Deleted tags may be recovered!', 1);
     }
     undef $newTool;
@@ -738,5 +750,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePNG.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePNG.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePNG.pl	(revision 34921)
@@ -14,5 +14,5 @@
 #------------------------------------------------------------------------------
 # 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
@@ -61,5 +61,5 @@
 
 #------------------------------------------------------------------------------
-# Write profile to tEXt or zTXt chunk (zTXt if Zlib is available)
+# Write profile chunk (possibly compressed if Zlib is available)
 # Inputs: 0) outfile, 1) Raw profile type, 2) data ref
 #         3) profile header type (undef if not a text profile)
@@ -69,17 +69,27 @@
     my ($outfile, $rawType, $dataPt, $profile) = @_;
     my ($buff, $prefix, $chunk, $deflate);
-    if (eval 'require Compress::Zlib') {
+    if ($rawType ne $stdCase{exif} and eval { require Compress::Zlib }) {
         $deflate = Compress::Zlib::deflateInit();
     }
     if (not defined $profile) {
         # write ICC profile as compressed iCCP chunk if possible
-        return 0 unless $deflate;
-        $buff = $deflate->deflate($$dataPt);
-        return 0 unless defined $buff;
-        $buff .= $deflate->flush();
-        my %rawTypeChunk = ( icm => 'iCCP' );
-        $chunk = $rawTypeChunk{$rawType} or return 0;
-        $prefix = "$rawType\0\0";
-        $dataPt = \$buff;
+        if ($rawType eq 'icm') {
+            return 0 unless $deflate;
+            $chunk = 'iCCP';
+            $prefix = "$rawType\0\0";
+        } else {
+            $chunk = $rawType;
+            if ($rawType eq $stdCase{zxif}) {
+                $prefix = "\0" . pack('N', length $$dataPt); # (proposed compressed EXIF)
+            } else {
+                $prefix = '';   # standard EXIF
+            }
+        }
+        if ($deflate) {
+            $buff = $deflate->deflate($$dataPt);
+            return 0 unless defined $buff;
+            $buff .= $deflate->flush();
+            $dataPt = \$buff;
+        }
     } else {
         # write as ASCII-hex encoded profile in tEXt or zTXt chunk
@@ -107,21 +117,41 @@
 
 #------------------------------------------------------------------------------
-# 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($$)
 {
-    my ($exifTool, $outfile) = @_;
-    if ($exifTool->{ADD_DIRS}->{ICC_Profile}) {
+    my ($et, $outfile) = @_;
+    if ($$et{ADD_DIRS}{ICC_Profile}) {
         # write new ICC data
         my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::ICC_Profile::Main');
         my %dirInfo = ( Parent => 'PNG', DirName => 'ICC_Profile' );
-        my $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+        my $buff = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
         if (defined $buff and length $buff and WriteProfile($outfile, 'icm', \$buff)) {
-            $exifTool->VPrint(0, "Created ICC profile\n");
-            delete $exifTool->{ADD_DIRS}->{ICC_Profile}; # don't add it again
+            $et->VPrint(0, "Created ICC profile\n");
+            delete $$et{ADD_DIRS}{ICC_Profile}; # don't add it again
         }
     }
     return 1;
+}
+
+#------------------------------------------------------------------------------
+# This routine is called after we edit an existing directory
+# Inputs: 0) ExifTool ref, 1) dir name, 2) output data ref
+#         3) flag set if location is non-standard (to update, but not create from scratch)
+# - on return, $$outBuff is set to '' if the directory is to be deleted
+sub DoneDir($$$;$)
+{
+    my ($et, $dir, $outBuff, $nonStandard) = @_;
+    my $saveDir = $dir;
+    $dir = 'EXIF' if $dir eq 'IFD0';
+    # don't add this directory again unless this is in a non-standard location
+    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 = '';
+    }
 }
 
@@ -133,5 +163,5 @@
 sub BuildTextChunk($$$$$)
 {
-    my ($exifTool, $tag, $tagInfo, $val, $lang) = @_;
+    my ($et, $tag, $tagInfo, $val, $lang) = @_;
     my ($xtra, $compVal, $iTXt, $comp);
     if ($$tagInfo{SubDirectory}) {
@@ -144,9 +174,9 @@
     } else {
         # compress if specified
-        $comp = 1 if $exifTool->Options('Compress');
+        $comp = 1 if $et->Options('Compress');
         if ($lang) {
             $iTXt = 1;      # write as iTXt if it has a language code
             $tag =~ s/-$lang$//;    # remove language code from tagID
-        } elsif ($$exifTool{OPTIONS}{Charset} ne 'Latin' and $val =~  /[\x80-\xff]/) {
+        } elsif ($$et{OPTIONS}{Charset} ne 'Latin' and $val =~  /[\x80-\xff]/) {
             $iTXt = 1;      # write as iTXt if it contains non-Latin special characters
         }
@@ -154,5 +184,5 @@
     if ($comp) {
         my $warn;
-        if (eval 'require Compress::Zlib') {
+        if (eval { require Compress::Zlib }) {
             my $deflate = Compress::Zlib::deflateInit();
             $compVal = $deflate->deflate($val) if $deflate;
@@ -172,18 +202,18 @@
         # warn if any user-specified compression fails
         if ($warn and $comp == 1) {
-            $exifTool->Warn("PNG:$$tagInfo{Name} not compressed ($warn)", 1);
+            $et->Warn("PNG:$$tagInfo{Name} not compressed ($warn)", 1);
         }
     }
     # decide whether to write as iTXt, zTXt or tEXt
     if ($iTXt) {
-        $$exifTool{TextChunkType} = 'iTXt';
+        $$et{TextChunkType} = 'iTXt';
         $xtra = (defined $compVal ? "\x01\0" : "\0\0") . ($lang || '') . "\0\0";
         # iTXt is encoded as UTF-8 (but note that XMP is already UTF-8)
-        $val = $exifTool->Encode($val, 'UTF8') if $iTXt == 1;
+        $val = $et->Encode($val, 'UTF8') if $iTXt == 1;
     } elsif (defined $compVal) {
-        $$exifTool{TextChunkType} = 'zTXt';
+        $$et{TextChunkType} = 'zTXt';
         $xtra = "\0";
     } else {
-        $$exifTool{TextChunkType} = 'tEXt';
+        $$et{TextChunkType} = 'tEXt';
         $xtra = '';
     }
@@ -194,25 +224,34 @@
 # 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 except EXIF 'IFD0', including PNG tags)
 # Returns: true on success
-sub AddChunks($$)
-{
-    my ($exifTool, $outfile) = @_;
+sub AddChunks($$;@)
+{
+    my ($et, $outfile, @add) = @_;
+    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
+        # add all directories
+        @add = sort keys %{$$et{ADD_DIRS}};
+    }
     # write any outstanding PNG tags
-    my $addTags = $exifTool->{ADD_PNG};
-    delete $exifTool->{ADD_PNG};
-    my ($tag, $dir, $err, $tagTablePtr);
-
     foreach $tag (sort keys %$addTags) {
         my $tagInfo = $$addTags{$tag};
-        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-        # (always create native PNG information, so don't check IsCreating())
-        next unless Image::ExifTool::IsOverwriting($nvHash) > 0;
-        my $val = Image::ExifTool::GetNewValues($nvHash);
+        my $nvHash = $et->GetNewValueHash($tagInfo);
+        # (native PNG information is always preferred, so don't check IsCreating)
+        next unless $et->IsOverwriting($nvHash);
+        my $val = $et->GetNewValue($nvHash);
         if (defined $val) {
+            next if $$nvHash{EditOnly};
             my $data;
             if ($$tagInfo{Table} eq \%Image::ExifTool::PNG::TextualData) {
-                $data = BuildTextChunk($exifTool, $tag, $tagInfo, $val, $$tagInfo{LangCode});
-                $data = $$exifTool{TextChunkType} . $data;
-                delete $$exifTool{TextChunkType};
+                $data = BuildTextChunk($et, $tag, $tagInfo, $val, $$tagInfo{LangCode});
+                $data = $$et{TextChunkType} . $data;
+                delete $$et{TextChunkType};
             } else {
                 $data = "$tag$val";
@@ -221,11 +260,11 @@
             my $cbuf = pack('N', CalculateCRC(\$data, undef));
             Write($outfile, $hdr, $data, $cbuf) or $err = 1;
-            $exifTool->VerboseValue("+ PNG:$$tagInfo{Name}", $val);
-            ++$exifTool->{CHANGED};
-        }
-    }
-    $addTags = { };     # prevent from adding tags again
+            $et->VerboseValue("+ PNG:$$tagInfo{Name}", $val);
+            ++$$et{CHANGED};
+        }
+    }
     # create any necessary directories
-    foreach $dir (sort keys %{$exifTool->{ADD_DIRS}}) {
+    foreach $dir (@add) {
+        next unless $$et{ADD_DIRS}{$dir}; # make sure we want to add it first
         my $buff;
         my %dirInfo = (
@@ -234,17 +273,26 @@
         );
         if ($dir eq 'IFD0') {
-            $exifTool->VPrint(0, "Creating EXIF profile:\n");
-            $exifTool->{TIFF_TYPE} = 'APP1';
+            next unless $specified;     # wait until specifically asked to write EXIF 'IFD0'
+            my $chunk = $stdCase{exif};
+            # (zxIf was not adopted)
+            #if ($et->Options('Compress')) {
+            #    if (eval { require Compress::Zlib }) {
+            #        $chunk = $stdCase{zxif};
+            #    } else {
+            #        $et->Warn("Creating uncompressed $stdCase{exif} chunk (Compress::Zlib not available)");
+            #    }
+            #}
+            $et->VPrint(0, "Creating $chunk chunk:\n");
+            $$et{TIFF_TYPE} = 'APP1';
             $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Exif::Main');
-            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr, \&Image::ExifTool::WriteTIFF);
+            $buff = $et->WriteDirectory(\%dirInfo, $tagTablePtr, \&Image::ExifTool::WriteTIFF);
             if (defined $buff and length $buff) {
-                $buff = $Image::ExifTool::exifAPP1hdr . $buff;
-                WriteProfile($outfile, 'APP1', \$buff, 'generic') or $err = 1;
+                WriteProfile($outfile, $chunk, \$buff) or $err = 1;
             }
         } elsif ($dir eq 'XMP') {
-            $exifTool->VPrint(0, "Creating XMP iTXt chunk:\n");
+            $et->VPrint(0, "Creating XMP iTXt chunk:\n");
             $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::XMP::Main');
             $dirInfo{ReadOnly} = 1;
-            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            $buff = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
             if (defined $buff and length $buff and
                 # the packet is read-only (because of CRC)
@@ -261,23 +309,39 @@
             }
         } elsif ($dir eq 'IPTC') {
-            $exifTool->VPrint(0, "Creating IPTC profile:\n");
-            # write new IPTC data
+            $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';
             $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::Photoshop::Main');
-            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            $buff = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
             if (defined $buff and length $buff) {
                 WriteProfile($outfile, 'iptc', \$buff, 'IPTC') or $err = 1;
             }
         } elsif ($dir eq 'ICC_Profile') {
-            $exifTool->VPrint(0, "Creating ICC profile:\n");
+            $et->VPrint(0, "Creating ICC profile:\n");
             # write new ICC data (only done if we couldn't create iCCP chunk)
             $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::ICC_Profile::Main');
-            $buff = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+            $buff = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
             if (defined $buff and length $buff) {
                 WriteProfile($outfile, 'icm', \$buff, 'ICC') or $err = 1;
-                $exifTool->Warn('Wrote ICC as a raw profile (no Compress::Zlib)');
-            }
-        }
-    }
-    $exifTool->{ADD_DIRS} = { };    # prevent from adding dirs again
+                $et->Warn('Wrote ICC as a raw profile (no Compress::Zlib)');
+            }
+        } elsif ($dir eq 'PNG-pHYs') {
+            $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;
+            $buff = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
+            if (defined $buff and length $buff) {
+                $buff = 'pHYs' . $buff; # CRC includes chunk name
+                my $hdr = pack('N', length($buff) - 4);
+                my $cbuf = pack('N', CalculateCRC(\$buff, undef));
+                Write($outfile, $hdr, $buff, $cbuf) or $err = 1;
+            }
+        } else {
+            next;
+        }
+        delete $$et{ADD_DIRS}{$dir};  # don't add again
+    }
     return not $err;
 }
@@ -305,5 +369,5 @@
 
 Existing text tags are always rewritten in their original form (compressed
-zTXt, uncompressed tEXt or internation iTXt), so pre-existing compressed
+zTXt, uncompressed tEXt or international iTXt), so pre-existing compressed
 information can only be modified if Compress::Zlib is available.
 
@@ -316,5 +380,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePhotoshop.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePhotoshop.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePhotoshop.pl	(revision 34921)
@@ -45,6 +45,6 @@
 sub WritePhotoshop($$$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
     my $dataPt = $$dirInfo{DataPt};
     unless ($dataPt) {
@@ -58,7 +58,7 @@
 
     # make a hash of new tag info, keyed on tagID
-    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
-
-    my ($addDirs, $editDirs) = $exifTool->GetAddDirHash($tagTablePtr);
+    my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
+
+    my ($addDirs, $editDirs) = $et->GetAddDirHash($tagTablePtr);
 
     SetByteOrder('MM');     # Photoshop is always big-endian
@@ -67,5 +67,5 @@
 # (the Photoshop directory entries aren't in any particular order)
 #
-    # Format: 0) Type, 4 bytes - '8BIM' (or the rare 'PHUT', 'DCSR' or 'AgHg')
+    # Format: 0) Type, 4 bytes - '8BIM' (or the rare 'PHUT', 'DCSR', 'AgHg' or 'MeSa')
     #         1) TagID,2 bytes
     #         2) Name, pascal string padded to even no. bytes
@@ -77,6 +77,6 @@
         ++$pos if ($pos ^ $start) & 0x01;
         my $type = substr($$dataPt, $pos, 4);
-        if ($type !~ /^(8BIM|PHUT|DCSR|AgHg)$/) {
-            $exifTool->Error("Bad Photoshop IRB resource");
+        if ($type !~ /^(8BIM|PHUT|DCSR|AgHg|MeSa)$/) {
+            $et->Error("Bad Photoshop IRB resource");
             undef $newData;
             last;
@@ -87,5 +87,5 @@
         ++$namelen if $namelen & 0x01;
         if ($pos + $namelen + 10 > $dirEnd) {
-            $exifTool->Error("Bad APP13 resource block");
+            $et->Error("Bad APP13 resource block");
             undef $newData;
             last;
@@ -95,5 +95,5 @@
         $pos += $namelen + 10;
         if ($size + $pos > $dirEnd) {
-            $exifTool->Error("Bad APP13 resource data size $size");
+            $et->Error("Bad APP13 resource data size $size");
             undef $newData;
             last;
@@ -102,21 +102,21 @@
             $tagInfo = $$newTags{$tagID};
             delete $$newTags{$tagID};
-            my $nvHash = $exifTool->GetNewValueHash($tagInfo);
+            my $nvHash = $et->GetNewValueHash($tagInfo);
             # check to see if we are overwriting this tag
             $value = substr($$dataPt, $pos, $size);
-            my $isOverwriting = Image::ExifTool::IsOverwriting($nvHash, $value);
+            my $isOverwriting = $et->IsOverwriting($nvHash, $value);
             # handle special 'new' and 'old' values for IPTCDigest
             if (not $isOverwriting and $tagInfo eq $iptcDigestInfo) {
                 if (grep /^new$/, @{$$nvHash{DelValue}}) {
-                    $isOverwriting = 1 if $$exifTool{NewIPTCDigest} and
-                                          $$exifTool{NewIPTCDigest} eq $value;
+                    $isOverwriting = 1 if $$et{NewIPTCDigest} and
+                                          $$et{NewIPTCDigest} eq $value;
                 }
                 if (grep /^old$/, @{$$nvHash{DelValue}}) {
-                    $isOverwriting = 1 if $$exifTool{OldIPTCDigest} and
-                                          $$exifTool{OldIPTCDigest} eq $value;
+                    $isOverwriting = 1 if $$et{OldIPTCDigest} and
+                                          $$et{OldIPTCDigest} eq $value;
                 }
             }
             if ($isOverwriting) {
-                $exifTool->VerboseValue("- Photoshop:$$tagInfo{Name}", $value);
+                $et->VerboseValue("- Photoshop:$$tagInfo{Name}", $value);
                 # handle IPTCDigest specially because we want to write it last
                 # so the new IPTC digest will be known
@@ -125,11 +125,11 @@
                     $value = undef;
                 } else {
-                    $value = Image::ExifTool::GetNewValues($nvHash);
-                }
-                ++$exifTool->{CHANGED};
+                    $value = $et->GetNewValue($nvHash);
+                }
+                ++$$et{CHANGED};
                 next unless defined $value;     # next if tag is being deleted
                 # set resource name if necessary
                 SetResourceName($tagInfo, $name, \$value);
-                $exifTool->VerboseValue("+ Photoshop:$$tagInfo{Name}", $value);
+                $et->VerboseValue("+ Photoshop:$$tagInfo{Name}", $value);
             }
         } else {
@@ -139,5 +139,9 @@
                     # process subdirectory anyway if writable (except EXIF to avoid recursion)
                     # --> this allows IPTC to be processed if found here in TIFF images
-                    my $tmpInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+                    # (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')
@@ -159,5 +163,5 @@
                 my $subTable = Image::ExifTool::GetTagTable($tagInfo->{SubDirectory}->{TagTable});
                 my $writeProc = $tagInfo->{SubDirectory}->{WriteProc};
-                my $newValue = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
+                my $newValue = $et->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
                 if (defined $newValue) {
                     next unless length $newValue;   # remove subdirectory entry
@@ -185,21 +189,21 @@
         if ($$newTags{$tagID}) {
             $tagInfo = $$newTags{$tagID};
-            my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-            $value = Image::ExifTool::GetNewValues($nvHash);
+            my $nvHash = $et->GetNewValueHash($tagInfo);
+            $value = $et->GetNewValue($nvHash);
             # handle new IPTCDigest value specially
             if ($tagInfo eq $iptcDigestInfo and defined $value) {
                 if ($value eq 'new') {
-                    $value = $$exifTool{NewIPTCDigest};
+                    $value = $$et{NewIPTCDigest};
                 } elsif ($value eq 'old') {
-                    $value = $$exifTool{OldIPTCDigest};
+                    $value = $$et{OldIPTCDigest};
                 }
                 # (we already know we want to create this tag)
             } else {
                 # don't add this tag unless specified
-                next unless Image::ExifTool::IsCreating($nvHash);
+                next unless $$nvHash{IsCreating};
             }
             next unless defined $value;     # next if tag is being deleted
-            $exifTool->VerboseValue("+ Photoshop:$$tagInfo{Name}", $value);
-            ++$exifTool->{CHANGED};
+            $et->VerboseValue("+ Photoshop:$$tagInfo{Name}", $value);
+            ++$$et{CHANGED};
         } else {
             $tagInfo = $$addDirs{$tagID};
@@ -210,5 +214,5 @@
             my $subTable = Image::ExifTool::GetTagTable($tagInfo->{SubDirectory}->{TagTable});
             my $writeProc = $tagInfo->{SubDirectory}->{WriteProc};
-            $value = $exifTool->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
+            $value = $et->WriteDirectory(\%subdirInfo, $subTable, $writeProc);
             next unless $value;
         }
@@ -219,5 +223,5 @@
         $newData .= '8BIM' . Set16u($tagID) . $name . Set32u($size) . $value;
         $newData .= "\0" if $size & 0x01;   # must null pad to even numbered byte
-        ++$exifTool->{CHANGED};
+        ++$$et{CHANGED};
     }
     return $newData;
@@ -254,5 +258,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePostScript.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePostScript.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WritePostScript.pl	(revision 34921)
@@ -95,5 +95,5 @@
 sub WritePSDirectory($$$$$)
 {
-    my ($exifTool, $outfile, $dirName, $dataPt, $flags) = @_;
+    my ($et, $outfile, $dirName, $dataPt, $flags) = @_;
     my $success = 2;
     my $len = $dataPt ? length($$dataPt) : 0;
@@ -117,5 +117,5 @@
         pos($$dataPt) = 0;
         unless ($$dataPt =~ /(.*)(<\?xpacket begin=.{7,13}W5M0MpCehiHzreSzNTczkc9d)/sg) {
-            $exifTool->Warn('No XMP packet start');
+            $et->Warn('No XMP packet start');
             return WriteXMPDir($outfile, $flags, $$dataPt);
         }
@@ -124,5 +124,5 @@
         my $p1 = pos($$dataPt);
         unless ($$dataPt =~ m{<\?xpacket end=.(w|r).\?>}sg) {
-            $exifTool->Warn('No XMP packet end');
+            $et->Warn('No XMP packet end');
             return WriteXMPDir($outfile, $flags, $$dataPt);
         }
@@ -143,5 +143,5 @@
     }
     my $tagTablePtr = Image::ExifTool::GetTagTable("Image::ExifTool::${dirName}::Main");
-    my $val = $exifTool->WriteDirectory(\%dirInfo, $tagTablePtr);
+    my $val = $et->WriteDirectory(\%dirInfo, $tagTablePtr);
     if (defined $val) {
         $dataPt = \$val;    # use modified directory
@@ -157,9 +157,9 @@
         # 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 $exifTool->Options('Compact');
+        $val .= ((' ' x 100) . "\n") x 24 unless $$et{OPTIONS}{Compact}{NoPadding};
         $val .= q{<?xpacket end='w'?>};
         $dataPt = \$val;
@@ -239,5 +239,5 @@
         Write($outfile, $endToken, $/) or $success = 0;
     } else {
-        $exifTool->Warn("Can't write PS directory $dirName");
+        $et->Warn("Can't write PS directory $dirName");
     }
     undef $val;
@@ -263,8 +263,9 @@
     }
     my $line = "%%$tag: $val";
-    # postscript line limit is 255 characters
+    # postscript line limit is 255 characters (but it seems that
+    # the limit may be 254 characters if the DOS CR/LF is used)
     # --> split if necessary using continuation comment "%%+"
     my $n;
-    for ($n=255; length($line)>$n; $n+=255+length($/)) {
+    for ($n=254; length($line)>$n; $n+=254+length($/)) {
         substr($line, $n, 0) = "$/%%+";
     }
@@ -278,5 +279,5 @@
 sub WriteNewTags($$$)
 {
-    my ($exifTool, $outfile, $newTags) = @_;
+    my ($et, $outfile, $newTags) = @_;
     my $success = 1;
     my $tag;
@@ -288,10 +289,10 @@
     foreach $tag (sort keys %$newTags) {
         my $tagInfo = $$newTags{$tag};
-        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-        next unless Image::ExifTool::IsCreating($nvHash);
-        my $val = Image::ExifTool::GetNewValues($nvHash);
-        $exifTool->VerboseValue("+ PostScript:$$tagInfo{Name}", $val);
+        my $nvHash = $et->GetNewValueHash($tagInfo);
+        next unless $$nvHash{IsCreating};
+        my $val = $et->GetNewValue($nvHash);
+        $et->VerboseValue("+ PostScript:$$tagInfo{Name}", $val);
         Write($outfile, EncodeTag($tag, $val)) or $success = 0;
-        ++$exifTool->{CHANGED};
+        ++$$et{CHANGED};
     }
     # write XMP hint if necessary
@@ -300,52 +301,4 @@
     %$newTags = ();     # all done with new tags
     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
 }
 
@@ -357,13 +310,13 @@
 sub WritePS($$)
 {
-    my ($exifTool, $dirInfo) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
     my $tagTablePtr = Image::ExifTool::GetTagTable('Image::ExifTool::PostScript::Main');
     my $raf = $$dirInfo{RAF};
     my $outfile = $$dirInfo{OutFile};
-    my $verbose = $exifTool->Options('Verbose');
-    my $out = $exifTool->Options('TextOut');
+    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;
@@ -387,8 +340,8 @@
                 $raf->Read($data, 4) == 4 and $data eq '%!PS')
         {
-            $exifTool->Error('Invalid PS header');
+            $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
@@ -400,5 +353,5 @@
                 NoTiffEnd => 1, # no end-of-TIFF check
             );
-            $buff = $exifTool->WriteTIFF(\%dirInfo);
+            $buff = $et->WriteTIFF(\%dirInfo);
             SetByteOrder('II'); # (WriteTIFF may change this)
             if ($buff) {
@@ -408,8 +361,8 @@
                 my $len = Get32u(\$dos, 24);
                 unless ($raf->Seek($base, 0) and $raf->Read($buff, $len) == $len) {
-                    $exifTool->Error('Error reading embedded TIFF');
+                    $et->Error('Error reading embedded TIFF');
                     return 1;
                 }
-                $exifTool->Warn('Bad embedded TIFF');
+                $et->Warn('Bad embedded TIFF');
             }
             Set32u(0, \$dos, 12);                   # zero metafile pointer
@@ -421,5 +374,5 @@
             my $len = Get32u(\$dos, 16);
             unless ($raf->Seek($base, 0) and $raf->Read($buff, $len) == $len) {
-                $exifTool->Error('Error reading metafile section');
+                $et->Error('Error reading metafile section');
                 return 1;
             }
@@ -438,10 +391,10 @@
     local $/ = GetInputRecordSeparator($raf);
     unless ($/ and $raf->ReadLine($buff)) {
-        $exifTool->Error('Invalid PostScript data');
+        $et->Error('Invalid PostScript data');
         return 1;
     }
     $data .= $buff;
     unless ($data =~ /^%!PS-Adobe-3\.(\d+)\b/ and $1 < 2) {
-        if ($exifTool->Error("Document does not conform to DSC spec. Metadata may be unreadable by other apps", 1)) {
+        if ($et->Error("Document does not conform to DSC spec. Metadata may be unreadable by other apps", 2)) {
             return 1;
         }
@@ -452,45 +405,20 @@
 
     # get hash of new information keyed by tagID and directories to add/edit
-    my $newTags = $exifTool->GetNewTagInfoHash($tagTablePtr);
+    my $newTags = $et->GetNewTagInfoHash($tagTablePtr);
 
     # figure out which directories we need to write (PostScript takes priority)
-    $exifTool->InitWriteDirs(\%psMap, 'PostScript');
-    my $addDirs = $exifTool->{ADD_DIRS};
-    my $editDirs = $exifTool->{EDIT_DIRS};
+    $et->InitWriteDirs(\%psMap, 'PostScript');
+    my $addDirs = $$et{ADD_DIRS};
+    my $editDirs = $$et{EDIT_DIRS};
     my %doneDir;
 
     # set XMP hint flag (1 for adding, 0 for deleting, undef for no change)
     $xmpHint = 1 if $$addDirs{XMP};
-    $xmpHint = 0 if $$exifTool{DEL_GROUP}{XMP};
+    $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
@@ -499,7 +427,7 @@
                 # found end: process this information
                 if ($mode) {
-                    $doneDir{$mode} and $exifTool->Error("Multiple $mode directories", 1);
+                    $doneDir{$mode} and $et->Error("Multiple $mode directories", 1);
                     $doneDir{$mode} = 1;
-                    WritePSDirectory($exifTool, $outfile, $mode, \$buff, \%flags) or $err = 1;
+                    WritePSDirectory($et, $outfile, $mode, \$buff, \%flags) or $err = 1;
                     # write end token if we wrote the begin token
                     Write($outfile, $data) or $err = 1 if $flags{WROTE_BEGIN};
@@ -531,5 +459,5 @@
         } elsif ($data =~ m{^(%{1,2})(Begin)(?!Object:)(.*?)[:\x0d\x0a]}i) {
             # comments section is over... write any new tags now
-            WriteNewTags($exifTool, $outfile, $newTags) or $err = 1 if %$newTags;
+            WriteNewTags($et, $outfile, $newTags) or $err = 1 if %$newTags;
             undef $xmpHint;
             # the beginning of a data block (can only write XMP and Photoshop)
@@ -558,13 +486,8 @@
             #   (because Illustrator doesn't care if the Creator is changed)
             if ($tag eq 'Creator' and $val =~ /^Adobe Illustrator/) {
-                # disable writing XMP to PS-format Adobe Illustrator files and
-                # older Illustrator EPS files becaues it confuses Illustrator
-                # (Illustrator 8 and older write PS-Adobe-3.0, newer write PS-Adobe-3.1)
-                if ($$editDirs{XMP} and $psRev == 0) {
-                    if ($flags{EPS}) {
-                        $exifTool->Warn("Can't write XMP to Illustrator 8 or older EPS files");
-                    } else {
-                        $exifTool->Warn("Can't write XMP to PS-format AI files");
-                    }
+                # disable writing XMP to PostScript-format Adobe Illustrator files
+                # because it confuses Illustrator
+                if ($$editDirs{XMP}) {
+                    $et->Warn("Can't write XMP to PostScript-format Illustrator files");
                     # pretend like we wrote it already so we won't try to add it later
                     $doneDir{XMP} = 1;
@@ -574,5 +497,5 @@
                 # --> find a better way to do this!
                 if ($$newTags{$tag}) {
-                    $exifTool->Warn("Can't change Postscript:Creator of Illustrator files");
+                    $et->Warn("Can't change Postscript:Creator of Illustrator files");
                     delete $$newTags{$tag};
                 }
@@ -584,12 +507,12 @@
                 # decode comment string (reading continuation lines if necessary)
                 $val = DecodeComment($val, $raf, \@lines, \$data);
-                $val = join $exifTool->Options('ListSep'), @$val if ref $val eq 'ARRAY';
-                my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-                if (Image::ExifTool::IsOverwriting($nvHash, $val)) {
-                    $exifTool->VerboseValue("- PostScript:$$tagInfo{Name}", $val);
-                    $val = Image::ExifTool::GetNewValues($nvHash);
-                    ++$exifTool->{CHANGED};
+                $val = join $et->Options('ListSep'), @$val if ref $val eq 'ARRAY';
+                my $nvHash = $et->GetNewValueHash($tagInfo);
+                if ($et->IsOverwriting($nvHash, $val)) {
+                    $et->VerboseValue("- PostScript:$$tagInfo{Name}", $val);
+                    $val = $et->GetNewValue($nvHash);
+                    ++$$et{CHANGED};
                     next unless defined $val;   # next if tag is being deleted
-                    $exifTool->VerboseValue("+ PostScript:$$tagInfo{Name}", $val);
+                    $et->VerboseValue("+ PostScript:$$tagInfo{Name}", $val);
                     $data = EncodeTag($tag, $val);
                 }
@@ -612,5 +535,5 @@
             {
                 # write new tags at end of comments section
-                WriteNewTags($exifTool, $outfile, $newTags) or $err = 1;
+                WriteNewTags($et, $outfile, $newTags) or $err = 1;
                 undef $xmpHint;
             }
@@ -629,10 +552,10 @@
                     if ($plateFile) {
                         # PlateFile comments may contain offsets so we can't edit these files!
-                        $exifTool->Warn("Can only edit PostScript information DCS Plate files");
+                        $et->Warn("Can only edit PostScript information DCS Plate files");
                         last;
                     }
                     next unless $$addDirs{$dir} or $dir eq 'XMP';
                     $flags{WROTE_BEGIN} = 0;
-                    WritePSDirectory($exifTool, $outfile, $dir, undef, \%flags) or $err = 1;
+                    WritePSDirectory($et, $outfile, $dir, undef, \%flags) or $err = 1;
                     $doneDir{$dir} = 1;
                 }
@@ -646,5 +569,5 @@
                         } 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"
@@ -664,5 +587,5 @@
                     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;
                     }
@@ -684,5 +607,5 @@
                     seek($outfile, $pos, 0))
             {
-                $exifTool->Error("Can't write DOS-style PS files in non-seekable stream");
+                $et->Error("Can't write DOS-style PS files in non-seekable stream");
                 $err = 1;
             }
@@ -696,9 +619,9 @@
         foreach $dir (qw{Photoshop ICC_Profile XMP}) {
             push @notDone, $dir if $$editDirs{$dir} and not $doneDir{$dir} and
-                                   not $$exifTool{DEL_GROUP}{$dir};
-        }
-        @notDone and $exifTool->Warn("Couldn't write ".join('/',@notDone).' information');
-    }
-    $endToken and $exifTool->Error("File missing $endToken");
+                                   not $$et{DEL_GROUP}{$dir};
+        }
+        @notDone and $et->Warn("Couldn't write ".join('/',@notDone).' information');
+    }
+    $endToken and $et->Error("File missing $endToken");
     return $err ? -1 : 1;
 }
@@ -764,5 +687,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteQuickTime.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteQuickTime.pl	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteQuickTime.pl	(revision 34921)
@@ -0,0 +1,1891 @@
+#------------------------------------------------------------------------------
+# File:         WriteQuickTime.pl
+#
+# Description:  Write XMP to QuickTime (MOV and MP4) files
+#
+# Revisions:    2013-10-29 - P. Harvey Created
+#------------------------------------------------------------------------------
+package Image::ExifTool::QuickTime;
+
+use strict;
+
+# maps for adding metadata to various QuickTime-based file types
+my %movMap = (
+    # 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 ') -> 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,
+    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;
+}
+
+#------------------------------------------------------------------------------
+# Convert GPS coordinates back to ISO6709 format
+# Inputs: 0) ValueConv value
+# Returns: ISO6709 coordinates
+sub ConvInvISO6709($)
+{
+    local $_;
+    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 "-", and Google Photos
+        # requires at least 3 digits after the decimal point
+        my @fmt = ('%s%02d.%s%s','%s%03d.%s%s','%s%d.%s%s');
+        foreach (@a) {
+            return undef unless Image::ExifTool::IsFloat($_);
+            $_ =~ s/^([-+]?)(\d+)\.?(\d*)/sprintf(shift(@fmt),$1||'+',$2,$3,length($3)<3 ? '0'x(3-length($3)) : '')/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), 3) Writable (or undef)
+# Returns: Flags for QT data type, and reformats value as required
+sub FormatQTValue($$;$$)
+{
+    my ($et, $valPt, $format, $writable) = @_;
+    my $flags;
+    if ($format and $format ne 'string') {
+        $$valPt = WriteValue($$valPt, $format);
+        if ($writable and $qtFormat{$writable}) {
+            $flags = $qtFormat{$writable};
+        } else {
+            $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
+    my $primary = $$et{PrimaryItem};
+    my $curPos = $raf->Tell();
+    my $id;
+    foreach $id (sort { $a <=> $b } keys %$items) {
+        $primary = $id unless defined $primary; # assume primary is lowest-number item if pitm missing
+        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 (not length $buff) {
+                # create EXIF from scratch
+                $hdr = "\0\0\0\x06Exif\0\0";
+            } elsif ($buff =~ /^(MM\0\x2a|II\x2a\0)/) {
+                $et->Warn('Missing Exif header');
+                $hdr = '';
+            } elsif (length($buff) >= 4 and length($buff) >= 4 + unpack('N',$buff)) {
+                $hdr = substr($buff, 0, 4 + unpack('N',$buff));
+            } else {
+                $et->Warn('Invalid Exif header');
+                next;
+            }
+            $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;
+        }
+        unless (defined $$et{PrimaryItem}) {
+            unless (defined $primary) {
+                $et->Warn("Can't create $name. No items to reference");
+                last;
+            }
+            # add new primary item reference box after hdrl box
+            if ($primary < 0x10000) {
+                $add{hdlr} = pack('Na4Nn', 14, 'pitm', 0, $primary);
+            } else {
+                $add{hdlr} = pack('Na4CCCCN', 16, 'pitm', 1, 0, 0, 0, $primary);
+            }
+            $et->Warn("Added missing PrimaryItemReference (for item $primary)", 1);
+        }
+        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 < 0x10000 ? 0 : 1);
+                $$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,
+        # and add new pitm box after hdlr if necessary
+        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};
+            } elsif ($tag ne 'hdlr') {
+                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}};
+                }
+            } elsif ($tag ne 'hdlr') {
+                next;
+            }
+            # add new entries to this box (or add pitm after hdlr)
+            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;
+}
+
+#------------------------------------------------------------------------------
+# Write a series of QuickTime atoms from file or in memory
+# Inputs: 0) ExifTool ref, 1) dirInfo ref, 2) tag table ref
+# 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) = @_;
+    $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 $didTag = $$et{DidTag};
+    my $newTags = { };
+    my $createKeys = 0;
+    my ($rtnVal, $rtnErr) = $dataPt ? (undef, undef) : (1, 0);
+
+    if ($dataPt) {
+        $raf = new File::RandomAccess($dataPt);
+    } else {
+        return 0 unless $raf;
+    }
+    # 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
+                $term = $hdr;
+            } elsif ($n != 0) {
+                $et->Error('File format error');
+            }
+            last;
+        }
+        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 ($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 {
+                # 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 ];
+            }
+            last;
+        } elsif ($size < 0) {
+            $et->Error('Invalid atom size');
+            last;
+        }
+
+        # keep track of 'mdat' atom locations for writing later
+        if ($tag eq 'mdat') {
+            if ($dataPt) {
+                $et->Error("'mdat' not at top level");
+                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 {
+                $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, \$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;
+            }
+        }
+        # 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})) {
+            my $subdir = $$tagInfo{SubDirectory};
+            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;
+                my $dPos = 0;
+                my $hdrLen = $start;
+                if ($$subdir{Base}) {
+                    my $localBase = eval $$subdir{Base};
+                    $dPos -= $localBase;
+                    $base -= $dPos;
+                    # get length of header before base offset
+                    $hdrLen -= $localBase if $localBase <= $hdrLen;
+                }
+                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},
+                    Multi    => $$subdir{Multi},    # necessary?
+                    OutFile  => $outfile,
+                    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)
+                if ($hdrLen and $hdrLen < $size) {
+                    my $header = substr($buff,0,$hdrLen);
+                    $subdirInfo{HeaderPtr} = \$header;
+                }
+                SetByteOrder('II') if $$subdir{ByteOrder} and $$subdir{ByteOrder} =~ /^Little/;
+                my $oldWriteGroup = $$et{CUR_WRITE_GROUP};
+                if ($subName eq 'Track') {
+                    $track or $track = 0;
+                    $$et{CUR_WRITE_GROUP} = 'Track' . (++$track);
+                }
+                my $subTable = GetTagTable($$subdir{TagTable});
+                # demote non-QuickTime errors to warnings
+                $$et{DemoteErrors} = 1 unless $$subTable{GROUPS}{0} eq 'QuickTime';
+                my $oldChanged = $$et{CHANGED};
+                $newData = $et->WriteDirectory(\%subdirInfo, $subTable, $$subdir{WriteProc});
+                if ($$et{DemoteErrors}) {
+                    # just copy existing subdirectory if a non-quicktime error occurred
+                    $$et{CHANGED} = $oldChanged if $$et{DemoteErrors} > 1;
+                    delete $$et{DemoteErrors};
+                }
+                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
+                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, $$tagInfo{Writable});
+                                        next unless defined $newVal;
+                                        my ($ctry, $lang) = (0, 0);
+                                        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
+                                        if ($$tagInfo{Writable} and $qtFormat{$$tagInfo{Writable}}) {
+                                            $flags = $qtFormat{$$tagInfo{Writable}};
+                                        } elsif ($qtFormat{$format}) {
+                                            $flags = $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, $$tagInfo{Writable});
+                                    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;
+                                    my $wLang = $lang eq $undLang ? 0 : $lang;
+                                    $newData .= pack('Na4Nnn', length($newVal)+16, $type, $flags, $ctry, $wLang);
+                                    $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 {
+                        $val = $buff;
+                    }
+                    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');
+                                my $wLang = $lang eq $undLang ? 0 : $lang;
+                                if ($$tagInfo{IText} and $$tagInfo{IText} == 6) {
+                                    $newData = pack('Nn', 0, $wLang) . $newData . "\0";
+                                } else {
+                                    $newData = pack('nn', length($newData), $wLang) . $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 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 {
+            # 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;
+        }
+    }
+    $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), 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} || $$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}, $$tagInfo{Writable});
+                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
+                    $newVal = pack('Na4Nnn',16+length($newVal),'data',$flags,$ctry,$lang).$newVal;
+                } elsif ($tag =~ /^\xa9/ or $$tagInfo{IText}) {
+                    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
+            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, $$subdir{WriteProc});
+            if ($newData and length($newData) <= 0x7ffffff7) {
+                my $prefix = '';
+                # add atom version or ID if necessary
+                if ($$subdir{Start}) {
+                    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;
+                }
+            }
+            # 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};
+        }
+    }
+
+    # 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
+    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 $rtnVal;
+}
+
+#------------------------------------------------------------------------------
+# Write QuickTime-format MOV/MP4 file
+# Inputs: 0) ExifTool ref, 1) dirInfo ref
+# Returns: 1 on success, 0 if this wasn't a valid QuickTime file,
+#          or -1 if a write error occurred
+sub WriteMOV($$)
+{
+    my ($et, $dirInfo) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
+    my $raf = $$dirInfo{RAF} or return 0;
+    my ($buff, $ftype);
+
+    # read the first atom header
+    return 0 unless $raf->Read($buff, 8) == 8;
+    my ($size, $tag) = unpack('Na4', $buff);
+    return 0 if $size < 8 and $size != 1;
+
+    # validate the file format
+    my $tagTablePtr = GetTagTable('Image::ExifTool::QuickTime::Main');
+    return 0 unless $$tagTablePtr{$tag};
+
+    # 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)
+    {
+        if ($buff =~ /^crx /) {
+            $ftype = 'CR3',
+        } elsif ($buff =~ /^(heic|mif1|msf1|heix|hevc|hevx|avif)/) {
+            $ftype = 'HEIC';
+        } else {
+            $ftype = 'MP4';
+        }
+    } else {
+        $ftype = 'MOV';
+    }
+    $et->SetFileType($ftype); # need to set "FileType" tag for a Condition
+    $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;
+}
+
+1; # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::WriteQuickTime.pl - Write XMP to QuickTime (MOV and MP4) files
+
+=head1 SYNOPSIS
+
+These routines are autoloaded by Image::ExifTool::QuickTime.
+
+=head1 DESCRIPTION
+
+This file contains routines used by ExifTool to write XMP metadata to
+QuickTime-based file formats like MOV and MP4.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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::QuickTime(3pm)|Image::ExifTool::QuickTime>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteXMP.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteXMP.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/WriteXMP.pl	(revision 34921)
@@ -9,9 +9,9 @@
 
 use strict;
-use vars qw(%specialStruct %dateTimeInfo $xlatNamespace);
+use vars qw(%specialStruct %dateTimeInfo %stdXlatNS);
 
 use Image::ExifTool qw(:DataAccess :Utils);
 
-sub CheckXMP($$$);
+sub CheckXMP($$$;$);
 sub CaptureXMP($$$;$);
 sub SetPropertyPath($$;$$$$);
@@ -46,4 +46,5 @@
 my $pktCloseW =  "<?xpacket end='w'?>"; # writable by default
 my $pktCloseR =  "<?xpacket end='r'?>";
+my ($sp, $nl);
 
 #------------------------------------------------------------------------------
@@ -53,11 +54,11 @@
 sub XMPOpen($)
 {
-    my $exifTool = shift;
-    my $nv = $exifTool->{NEW_VALUE}->{$Image::ExifTool::XMP::x{xmptk}};
+    my $et = shift;
+    my $nv = $$et{NEW_VALUE}{$Image::ExifTool::XMP::x{xmptk}};
     my $tk;
     if (defined $nv) {
-        $tk = Image::ExifTool::GetNewValues($nv);
-        $exifTool->VerboseValue(($tk ? '+' : '-') . ' XMP-x:XMPToolkit', $tk);
-        ++$exifTool->{CHANGED};
+        $tk = $et->GetNewValue($nv);
+        $et->VerboseValue(($tk ? '+' : '-') . ' XMP-x:XMPToolkit', $tk);
+        ++$$et{CHANGED};
     } else {
         $tk = "Image::ExifTool $Image::ExifTool::VERSION";
@@ -74,4 +75,5 @@
 {
     my ($xmpPt, $mode) = @_;
+    $$xmpPt =~ s/^\s*<!--.*?-->\s*//s; # remove leading comment if it exists
     unless ($$xmpPt =~ /^\0*<\0*\?\0*x\0*p\0*a\0*c\0*k\0*e\0*t/) {
         return '' unless $$xmpPt =~ /^<x(mp)?:x[ma]pmeta/;
@@ -88,6 +90,53 @@
 
 #------------------------------------------------------------------------------
+# Validate XMP property
+# Inputs: 0) ExifTool ref, 1) validate hash ref, 2) attribute hash ref
+# - issues warnings if problems detected
+sub ValidateProperty($$;$)
+{
+    my ($et, $propList, $attr) = @_;
+
+    if ($$et{XmpValidate} and @$propList > 2) {
+        if ($$propList[0] =~ /^x:x[ma]pmeta$/ and
+            $$propList[1] eq 'rdf:RDF' and
+            $$propList[2] =~ /rdf:Description( |$)/)
+        {
+            if (@$propList > 3) {
+                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");
+                    } else {
+                        $$xmpValidate{$path} = 1;
+                    }
+                }
+            }
+        } elsif ($$propList[0] ne 'rdf:RDF' or
+                 $$propList[1] !~ /rdf:Description( |$)/)
+        {
+            $et->Warn('Improperly enclosed XMP property: ' . join('/',@$propList));
+        }
+    }
+}
+
+#------------------------------------------------------------------------------
 # 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($)
@@ -117,10 +166,10 @@
 #------------------------------------------------------------------------------
 # Check XMP values for validity and format accordingly
-# Inputs: 0) ExifTool object ref, 1) tagInfo hash ref, 2) raw value ref
+# Inputs: 0) ExifTool object ref, 1) tagInfo hash ref, 2) raw value ref, 3) conversion type
 # Returns: error string or undef (and may change value) on success
 # Note: copies structured information to avoid conflicts with calling code
-sub CheckXMP($$$)
-{
-    my ($exifTool, $tagInfo, $valPtr) = @_;
+sub CheckXMP($$$;$)
+{
+    my ($et, $tagInfo, $valPtr, $convType) = @_;
 
     if ($$tagInfo{Struct}) {
@@ -130,5 +179,8 @@
             ($$valPtr, $warn) = InflateStruct($valPtr);
             # expect a structure HASH ref or ARRAY of structures
-            ref $$valPtr or return 'Improperly formed structure';
+            unless (ref $$valPtr) {
+                $$valPtr eq '' and $$valPtr = { }, return undef; # allow empty structures
+                return 'Improperly formed structure';
+            }
         }
         if (ref $$valPtr eq 'ARRAY') {
@@ -144,21 +196,21 @@
                     last;
                 }
-                ($item, $err) = CheckStruct($exifTool, $item, $$tagInfo{Struct});
+                ($item, $err) = CheckStruct($et, $item, $$tagInfo{Struct});
                 last if $err;
             }
         } else {
-            ($$valPtr, $err) = CheckStruct($exifTool, $$valPtr, $$tagInfo{Struct});
-        }
-        $warn and $$exifTool{CHECK_WARN} = $warn;
+            ($$valPtr, $err) = CheckStruct($et, $$valPtr, $$tagInfo{Struct});
+        }
+        $warn and $$et{CHECK_WARN} = $warn;
         return $err;
     }
-    my $format = $tagInfo->{Writable};
+    my $format = $$tagInfo{Writable};
     # (if no format specified, value is a simple string)
     if (not $format or $format eq 'string' or $format eq 'lang-alt') {
         # convert value to UTF8 if necessary
-        if ($exifTool->{OPTIONS}->{Charset} ne 'UTF8') {
+        if ($$et{OPTIONS}{Charset} ne 'UTF8') {
             if ($$valPtr =~ /[\x80-\xff]/) {
                 # convert from Charset to UTF-8
-                $$valPtr = $exifTool->Encode($$valPtr,'UTF8');
+                $$valPtr = $et->Encode($$valPtr,'UTF8');
             }
         } else {
@@ -166,7 +218,7 @@
             $$valPtr =~ tr/\0-\x08\x0b\x0c\x0e-\x1f/./;
             # fix any malformed UTF-8 characters
-            if (FixUTF8($valPtr) and not $$exifTool{WarnBadUTF8}) {
-                $exifTool->Warn('Malformed UTF-8 character(s)');
-                $$exifTool{WarnBadUTF8} = 1;
+            if (FixUTF8($valPtr) and not $$et{WarnBadUTF8}) {
+                $et->Warn('Malformed UTF-8 character(s)');
+                $$et{WarnBadUTF8} = 1;
             }
         }
@@ -180,5 +232,5 @@
              $$valPtr eq 'undef' or Image::ExifTool::IsRational($$valPtr))))
         {
-            return 'Not a floating point number' 
+            return 'Not a floating point number';
         }
         if ($format eq 'rational') {
@@ -199,7 +251,10 @@
         $$valPtr = $newDate;
     } elsif ($format eq 'boolean') {
+        # (allow lower-case 'true' and 'false' if not setting PrintConv value)
         if (not $$valPtr or $$valPtr =~ /false/i or $$valPtr =~ /^no$/i) {
-            $$valPtr = 'False';
-        } else {
+            if (not $$valPtr or $$valPtr ne 'false' or not $convType or $convType eq 'PrintConv') {
+                $$valPtr = 'False';
+            }
+        } elsif ($$valPtr ne 'true' or not $convType or $convType eq 'PrintConv') {
             $$valPtr = 'True';
         }
@@ -235,11 +290,23 @@
     my $table = $structPtr || $tagTablePtr;
     my $tagInfo = $$table{$tagID};
-
-    return if ref($tagInfo) ne 'HASH' or $$tagInfo{PropertyPath};
-
-    # don't override existing main table entry if already set by a Struct
+    my $flatInfo;
+
+    return if ref($tagInfo) ne 'HASH'; # (shouldn't happen)
+
     if ($structPtr) {
+        my $flatID = $parentID . ucfirst($tagID);
+        $flatInfo = $$tagTablePtr{$flatID};
+        if ($flatInfo) {
+            return if $$flatInfo{PropertyPath};
+        } else {
+            # flattened tag doesn't exist, so create it now
+            # (could happen if we were just writing a structure)
+            $flatInfo = { Name => ucfirst($flatID), Flat => 1 };
+            AddTagToTable($tagTablePtr, $flatID, $flatInfo);
+        }
         $isType = 1 if $$structPtr{TYPE};
     } else {
+        # don't override existing main table entry if already set by a Struct
+        return if $$tagInfo{PropertyPath};
         # use property path from original tagInfo if this is an alternate-language tag
         my $srcInfo = $$tagInfo{SrcTagInfo};
@@ -251,4 +318,5 @@
             return if $$tagInfo{PropertyPath};
             warn "Internal Error: Didn't set path from root for $tagID\n";
+            warn "(Is the Struct NAMESPACE defined?)\n";
         }
     }
@@ -263,5 +331,5 @@
         # remove language code from property path if it exists
         $propList[-1] =~ s/-$$tagInfo{LangCode}$// if $$tagInfo{LangCode};
-        # handle lists of lang-alt lists (ie. XMP-plus:Custom tags)
+        # handle lists of lang-alt lists (eg. XMP-plus:Custom tags)
         if ($$tagInfo{List} and $$tagInfo{List} ne '1') {
             push @propList, "rdf:$$tagInfo{List}", 'rdf:li 10';
@@ -273,7 +341,10 @@
     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}) {
+    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
+    {
         # make sure the structure namespace has been registered
         # (user-defined namespaces may not have been)
@@ -290,12 +361,5 @@
     # we set PropertyPath in the corresponding flattened tag
     if ($structPtr) {
-        my $flatID = $parentID . ucfirst($tagID);
-        $tagInfo = $$tagTablePtr{$flatID};
-        # create flattened tag now if necessary
-        # (could happen if we were just writing a structure)
-        unless ($tagInfo) {
-            $tagInfo = { Name => ucfirst($flatID), Flat => 1 };
-            Image::ExifTool::AddTagToTable($tagTablePtr, $flatID, $tagInfo);
-        }
+        $tagInfo = $flatInfo;
         # set StructType flag if any containing structure has a TYPE
         $$tagInfo{StructType} = 1 if $isType;
@@ -312,5 +376,5 @@
 sub CaptureXMP($$$;$)
 {
-    my ($exifTool, $propList, $val, $attrs) = @_;
+    my ($et, $propList, $val, $attrs) = @_;
     return unless defined $val and @$propList > 2;
     if ($$propList[0] =~ /^x:x[ma]pmeta$/ and
@@ -322,12 +386,12 @@
         # ignore empty list properties
         if ($$propList[-1] =~ /^rdf:(Bag|Seq|Alt)$/) {
-            $exifTool->Warn("Ignored empty $$propList[-1] list for $$propList[-2]", 1);
+            $et->Warn("Ignored empty $$propList[-1] list for $$propList[-2]", 1);
             return;
         }
         # save information about this property
-        my $capture = $exifTool->{XMP_CAPTURE};
+        my $capture = $$et{XMP_CAPTURE};
         my $path = join('/', @$propList[3..$#$propList]);
         if (defined $$capture{$path}) {
-            $exifTool->{XMP_ERROR} = "Duplicate XMP property: $path";
+            $$et{XMP_ERROR} = "Duplicate XMP property: $path";
         } else {
             $$capture{$path} = [$val, $attrs || { }];
@@ -337,10 +401,10 @@
     {
         # set flag so we don't write x:xmpmeta element
-        $exifTool->{XMP_NO_XMPMETA} = 1;
+        $$et{XMP_NO_XMPMETA} = 1;
         # add missing x:xmpmeta element and try again
         unshift @$propList, 'x:xmpmeta';
-        CaptureXMP($exifTool, $propList, $val, $attrs);
+        CaptureXMP($et, $propList, $val, $attrs);
     } else {
-        $exifTool->{XMP_ERROR} = 'Improperly enclosed XMP property: ' . join('/',@$propList);
+        $$et{XMP_ERROR} = 'Improperly enclosed XMP property: ' . join('/',@$propList);
     }
 }
@@ -374,8 +438,8 @@
             }
         }
-        $blankInfo->{Prop}->{$id}->{Pre}->{$pre} = 1;
+        $$blankInfo{Prop}{$id}{Pre}{$pre} = 1;
         if ((defined $post and length $post) or (defined $val and length $val)) {
             # save the property value and attributes for each unique path suffix
-            $blankInfo->{Prop}->{$id}->{Post}->{$post} = [ $val, $attrs, $propPath ];
+            $$blankInfo{Prop}{$id}{Post}{$post} = [ $val, $attrs, $propPath ];
         }
     }
@@ -388,26 +452,26 @@
 sub ProcessBlankInfo($$$;$)
 {
-    my ($exifTool, $tagTablePtr, $blankInfo, $isWriting) = @_;
-    $exifTool->VPrint(1, "  [Elements with nodeID set:]\n") unless $isWriting;
+    my ($et, $tagTablePtr, $blankInfo, $isWriting) = @_;
+    $et->VPrint(1, "  [Elements with nodeID set:]\n") unless $isWriting;
     my ($id, $pre, $post);
     # handle each nodeID separately
     foreach $id (sort keys %{$$blankInfo{Prop}}) {
-        my $path = $blankInfo->{Prop}->{$id};
+        my $path = $$blankInfo{Prop}{$id};
         # flag all resource names so we can warn later if some are unused
         my %unused;
-        foreach $post (keys %{$path->{Post}}) {
+        foreach $post (keys %{$$path{Post}}) {
             $unused{$post} = 1;
         }
         # combine property paths for all possible paths through this node
-        foreach $pre (sort keys %{$path->{Pre}}) {
+        foreach $pre (sort keys %{$$path{Pre}}) {
             # there will be no description for the object of a blank node
             next unless $pre =~ m{/$rdfDesc/};
-            foreach $post (sort keys %{$path->{Post}}) {
+            foreach $post (sort keys %{$$path{Post}}) {
                 my @propList = split m{/}, "$pre$post";
-                my ($val, $attrs) = @{$path->{Post}->{$post}};
+                my ($val, $attrs) = @{$$path{Post}{$post}};
                 if ($isWriting) {
-                    CaptureXMP($exifTool, \@propList, $val, $attrs);
+                    CaptureXMP($et, \@propList, $val, $attrs);
                 } else {
-                    FoundXMP($exifTool, $tagTablePtr, \@propList, $val);
+                    FoundXMP($et, $tagTablePtr, \@propList, $val);
                 }
                 delete $unused{$post};
@@ -416,12 +480,12 @@
         # save information from unused properties (if RDF is malformed like f-spot output)
         if (%unused) {
-            $exifTool->Options('Verbose') and $exifTool->Warn('An XMP resource is about nothing');
+            $et->Options('Verbose') and $et->Warn('An XMP resource is about nothing');
             foreach $post (sort keys %unused) {
-                my ($val, $attrs, $propPath) = @{$path->{Post}->{$post}};
+                my ($val, $attrs, $propPath) = @{$$path{Post}{$post}};
                 my @propList = split m{/}, $propPath;
                 if ($isWriting) {
-                    CaptureXMP($exifTool, \@propList, $val, $attrs);
+                    CaptureXMP($et, \@propList, $val, $attrs);
                 } else {
-                    FoundXMP($exifTool, $tagTablePtr, \@propList, $val);
+                    FoundXMP($et, $tagTablePtr, \@propList, $val);
                 }
             }
@@ -437,7 +501,7 @@
 sub ConformPathToNamespace($$)
 {
-    my ($exifTool, $path) = @_;
+    my ($et, $path) = @_;
     my @propList = split('/',$path);
-    my $nsUsed = $exifTool->{XMP_NS};
+    my $nsUsed = $$et{XMP_NS};
     my $prop;
     foreach $prop (@propList) {
@@ -446,5 +510,5 @@
         my $uri = $nsURI{$ns};
         unless ($uri) {
-            warn "No URI for namepace prefix $ns!\n";
+            warn "No URI for namespace prefix $ns!\n";
             next;
         }
@@ -467,5 +531,5 @@
 sub AddStructType($$$$;$)
 {
-    my ($exifTool, $tagTablePtr, $capture, $path, $basePath) = @_;
+    my ($et, $tagTablePtr, $capture, $path, $basePath) = @_;
     my @props = split '/', $path;
     my %doneID;
@@ -483,5 +547,5 @@
                 my $pat = $$tagInfo{PropertyPath};
                 $pat or warn("Missing PropertyPath in AddStructType\n"), last;
-                $pat = ConformPathToNamespace($exifTool, $pat);
+                $pat = ConformPathToNamespace($et, $pat);
                 $pat =~  s/ \d+/ \\d\+/g;
                 $path =~ /^($pat)/ or warn("Wrong path in AddStructType\n"), last;
@@ -496,8 +560,38 @@
 
 #------------------------------------------------------------------------------
+# 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
+# Inputs: 0) binary data string, 1) flag to avoid inserting newlines
 # Returns:   base64-encoded string
-sub EncodeBase64($)
+sub EncodeBase64($;$)
 {
     # encode the data in 45-byte chunks
@@ -517,4 +611,5 @@
     my $pad = 3 - ($len % 3);
     substr($str, -$pad-1, $pad) = ('=' x $pad) if $pad < 3;
+    $str =~ tr/\n//d if $_[1];  # remove newlines if specified
     return $str;
 }
@@ -547,5 +642,5 @@
 sub LimitXMPSize($$$$$$)
 {
-    my ($exifTool, $dataPt, $maxLen, $about, $startPt, $extStart) = @_;
+    my ($et, $dataPt, $maxLen, $about, $startPt, $extStart) = @_;
 
     # return straight away if it isn't too big
@@ -556,7 +651,10 @@
     my $guid = '0' x 32;
     # write the required xmpNote:HasExtendedXMP property
-    $newData .= "\n <$rdfDesc rdf:about='$about'\n  xmlns:xmpNote='$nsURI{xmpNote}'>\n" .
-                  "  <xmpNote:HasExtendedXMP>$guid</xmpNote:HasExtendedXMP>\n" .
-                  " </$rdfDesc>\n";
+    $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 .= ">$nl$sp$sp<xmpNote:HasExtendedXMP>$guid</xmpNote:HasExtendedXMP>$nl$sp</$rdfDesc>\n";
+    }
 
     my ($i, %descSize, $start);
@@ -568,5 +666,5 @@
     # write the descriptions from smallest to largest, as many in main XMP as possible
     my @descStart = sort { $descSize{$a} <=> $descSize{$b} } @$startPt;
-    my $extData = XMPOpen($exifTool) . $rdfOpen;
+    my $extData = XMPOpen($et) . $rdfOpen;
     for ($i=0; $i<2; ++$i) {
       foreach $start (@descStart) {
@@ -579,9 +677,9 @@
     $extData .= $rdfClose . $xmpClose;  # close rdf:RDF and x:xmpmeta
     # calculate GUID from MD5 of extended XMP data
-    if (eval 'require Digest::MD5') {
+    if (eval { require Digest::MD5 }) {
         $guid = uc unpack('H*', Digest::MD5::md5($extData));
         $newData =~ s/0{32}/$guid/;     # update GUID in main XMP segment
     }
-    $exifTool->VerboseValue('+ XMP-xmpNote:HasExtendedXMP', $guid);
+    $et->VerboseValue('+ XMP-xmpNote:HasExtendedXMP', $guid);
     $$dataPt = $newData;        # return main XMP block
     return (\$extData, $guid);  # return extended XMP and its GUID
@@ -589,10 +687,63 @@
 
 #------------------------------------------------------------------------------
+# 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 Shorthand is enabled)
+sub CloseProperty($$$$)
+{
+    my ($curPropList, $long, $short, $resFlag) = @_;
+
+    my $prop = pop @$curPropList;
+    $prop =~ s/ .*//;       # remove list index if it exists
+    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] .= ">$nl$pad<$rdfDesc";
+                $$short[-1] .= ">$nl";
+                $$long[-1] .= "$pad</$rdfDesc>$nl";
+            } else {
+                # simply close empty property if all shorthand
+                $$short[-1] .= "/>$nl";
+            }
+        } else {
+            # use "parseType" instead of opening a new Description
+            $$long[-2] .= ' rdf:parseType="Resource"';
+            $$short[-1] = length $$long[-1] ? ">$nl" : "/>$nl";
+        }
+        $$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] . ">$nl" . $$long[-1] . "$pad</$prop>$nl";
+        } else {
+            $$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>$nl";
+        unless (@$curPropList) {
+            # add properties now that this top-level Description is complete
+            $$long[-2] .= ">$nl" . $$long[-1];
+            $$long[-1] = '';
+        }
+    }
+    $#$resFlag = $#$curPropList;    # remove expired resource flags
+}
+
+#------------------------------------------------------------------------------
 # 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
+# Notes: May set dirInfo InPlace flag to rewrite with specified DirLen (=2 to allow larger)
 #        May set dirInfo ReadOnly flag to write as read-only XMP ('r' mode and no padding)
 #        May set dirInfo Compact flag to force compact (drops 2kB of padding)
@@ -601,13 +752,14 @@
 sub WriteXMP($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
-    $exifTool or return 1;    # allow dummy access to autoload this package
+    my ($et, $dirInfo, $tagTablePtr) = @_;
+    $et or return 1;    # allow dummy access to autoload this package
     my $dataPt = $$dirInfo{DataPt};
-    my (%capture, %nsUsed, $xmpErr, $tagInfo, $about);
+    my (%capture, %nsUsed, $xmpErr, $about);
     my $changed = 0;
     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 || ($$exifTool{PreferredGroup} and $$exifTool{PreferredGroup} eq 'XMP');
-    my $verbose = $exifTool->Options('Verbose');
+    my $preferred = $xmpFile || ($$et{PreferredGroup} and $$et{PreferredGroup} eq 'XMP');
+    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;
@@ -621,19 +773,27 @@
     # rdf:RDF/rdf:Description/.  The values are array references with the
     # following entries: 0) value, 1) attribute hash reference.
-    $exifTool->{XMP_CAPTURE} = \%capture;
-    $exifTool->{XMP_NS} = \%nsUsed;
-    delete $exifTool->{XMP_NO_XMPMETA};
-    delete $exifTool->{XMP_NO_XPACKET};
-    delete $exifTool->{XMP_IS_XML};
-    delete $exifTool->{XMP_IS_SVG};
+    $$et{XMP_CAPTURE} = \%capture;
+    $$et{XMP_NS} = \%nsUsed;
+    delete $$et{XMP_NO_XMPMETA};
+    delete $$et{XMP_NO_XPACKET};
+    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}) {
+        $about = $et->GetNewValue($$et{NEW_VALUE}{$tagInfo}) || '';
+    }
 
     if ($xmpFile or $dirLen) {
-        delete $exifTool->{XMP_ERROR};
-        delete $exifTool->{XMP_ABOUT};
+        delete $$et{XMP_ERROR};
         # extract all existing XMP information (to the XMP_CAPTURE hash)
-        my $success = ProcessXMP($exifTool, $dirInfo, $tagTablePtr);
+        my $success = ProcessXMP($et, $dirInfo, $tagTablePtr);
         # don't continue if there is nothing to parse or if we had a parsing error
-        unless ($success and not $exifTool->{XMP_ERROR}) {
-            my $err = $exifTool->{XMP_ERROR} || 'Error parsing XMP';
+        unless ($success and not $$et{XMP_ERROR}) {
+            my $err = $$et{XMP_ERROR} || 'Error parsing XMP';
             # may ignore this error only if we were successful
             if ($xmpFile) {
@@ -642,32 +802,40 @@
                 if ($success or not $raf->Seek(0,2) or $raf->Tell()) {
                     # no error message if not an XMP file
-                    return 0 unless $exifTool->{XMP_ERROR};
-                    if ($exifTool->Error($err, $success)) {
-                        delete $exifTool->{XMP_CAPTURE};
+                    return 0 unless $$et{XMP_ERROR};
+                    if ($et->Error($err, $success)) {
+                        delete $$et{XMP_CAPTURE};
                         return 0;
                     }
                 }
             } else {
-                if ($exifTool->Warn($err, $success)) {
-                    delete $exifTool->{XMP_CAPTURE};
+                $success = 2 if $success and $success eq '1';
+                if ($et->Warn($err, $success)) {
+                    delete $$et{XMP_CAPTURE};
                     return undef;
                 }
             }
         }
-        $tagInfo = $Image::ExifTool::XMP::rdf{about};
-        if (defined $exifTool->{NEW_VALUE}->{$tagInfo}) {
-            $about = Image::ExifTool::GetNewValues($exifTool->{NEW_VALUE}->{$tagInfo}) || '';
+        if (defined $about) {
             if ($verbose > 1) {
-                my $wasAbout = $exifTool->{XMP_ABOUT};
-                $exifTool->VerboseValue('- XMP-rdf:About', UnescapeXML($wasAbout)) if defined $wasAbout;
-                $exifTool->VerboseValue('+ XMP-rdf:About', $about);
+                my $wasAbout = $$et{XmpAbout};
+                $et->VerboseValue('- XMP-rdf:About', UnescapeXML($wasAbout)) if defined $wasAbout;
+                $et->VerboseValue('+ XMP-rdf:About', $about);
             }
             $about = EscapeXML($about); # must escape for XML
             ++$changed;
         } else {
-            $about = $exifTool->{XMP_ABOUT} || '';
-        }
-        delete $exifTool->{XMP_ERROR};
-        delete $exifTool->{XMP_ABOUT};
+            $about = $$et{XmpAbout} || '';
+        }
+        delete $$et{XMP_ERROR};
+
+        # call InitWriteDirs to initialize FORCE_WRITE flags if necessary
+        $et->InitWriteDirs({}, 'XMP') if $xmpFile and $et->GetNewValue('ForceWrite');
+        # set changed if we are ForceWrite tag was set to "XMP"
+        ++$changed if $$et{FORCE_WRITE}{XMP};
+
+    } elsif (defined $about) {
+        $et->VerboseValue('+ XMP-rdf:About', $about);
+        $about = EscapeXML($about); # must escape for XML
+        # (don't increment $changed here because we need another tag to be written)
     } else {
         $about = '';
@@ -678,13 +846,13 @@
     if ($xmpFile) {
         $tagInfo = $Image::ExifTool::Extra{XMP};
-        if ($tagInfo and $exifTool->{NEW_VALUE}->{$tagInfo}) {
+        if ($tagInfo and $$et{NEW_VALUE}{$tagInfo}) {
             my $rtnVal = 1;
-            my $newVal = Image::ExifTool::GetNewValues($exifTool->{NEW_VALUE}->{$tagInfo});
+            my $newVal = $et->GetNewValue($$et{NEW_VALUE}{$tagInfo});
             if (defined $newVal and length $newVal) {
-                $exifTool->VPrint(0, "  Writing XMP as a block\n");
-                ++$exifTool->{CHANGED};
+                $et->VPrint(0, "  Writing XMP as a block\n");
+                ++$$et{CHANGED};
                 Write($$dirInfo{OutFile}, $newVal) or $rtnVal = -1;
             }
-            delete $exifTool->{XMP_CAPTURE};
+            delete $$et{XMP_CAPTURE};
             return $rtnVal;
         }
@@ -693,9 +861,9 @@
 # delete groups in family 1 if requested
 #
-    if (%{$exifTool->{DEL_GROUP}} and (grep /^XMP-.+$/, keys %{$exifTool->{DEL_GROUP}} or
+    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 = $exifTool->{DEL_GROUP};
+        my $del = $$et{DEL_GROUP};
         my $path;
         foreach $path (keys %capture) {
@@ -703,8 +871,8 @@
             my ($tag, $ns) = GetXMPTagID(\@propList);
             # translate namespace if necessary
-            $ns = $$xlatNamespace{$ns} if $$xlatNamespace{$ns};
+            $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]";
@@ -721,5 +889,5 @@
                 next unless $$del{$ucg} or ($$del{'XMP-*'} and not $$del{"-$ucg"});
             }
-            $exifTool->VerboseValue("- $grp:$tag", $capture{$path}->[0]);
+            $et->VerboseValue("- $grp:$tag", $capture{$path}->[0]);
             delete $capture{$path};
             ++$changed;
@@ -729,21 +897,33 @@
     my $hasExtTag = 'xmpNote:HasExtendedXMP';
     if ($capture{$hasExtTag}) {
-        $exifTool->VerboseValue("- XMP-$hasExtTag", $capture{$hasExtTag}->[0]);
+        $et->VerboseValue("- XMP-$hasExtTag", $capture{$hasExtTag}->[0]);
         delete $capture{$hasExtTag};
     }
     # set $xmpOpen now to to handle xmptk tag first
-    my $xmpOpen = $exifTool->{XMP_NO_XMPMETA} ? '' : XMPOpen($exifTool);
+    my $xmpOpen = $$et{XMP_NO_XMPMETA} ? '' : XMPOpen($et);
 #
 # add, delete or change information as specified
 #
     # get hash of all information we want to change
-    # (sorted by tag name so alternate languages come last)
-    my @tagInfoList = sort ByTagName $exifTool->GetNewTagInfoList();
+    # (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, $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 {
+            push @tagInfoList, $tagInfo;
+        }
+    }
     foreach $tagInfo (@tagInfoList) {
-        next unless $exifTool->GetGroup($tagInfo, 0) eq 'XMP';
+        my @delPaths;   # list of deleted paths
         my $tag = $$tagInfo{TagID};
         my $path = GetPropertyPath($tagInfo);
         unless ($path) {
-            $exifTool->Warn("Can't write XMP:$tag (namespace unknown)");
+            $et->Warn("Can't write XMP:$tag (namespace unknown)");
             next;
         }
@@ -756,73 +936,142 @@
         # change our property path namespace prefixes to conform
         # to the ones used in this file
-        $path = ConformPathToNamespace($exifTool, $path);
+        $path = ConformPathToNamespace($et, $path);
         # find existing property
-        my $cap = $capture{$path}; 
+        my $cap = $capture{$path};
         # MicrosoftPhoto screws up the case of some tags, and some other software,
         # including Adobe software, has been known to write the wrong list type or
         # not properly enclose properties in a list, so we check for this
-        # (NOTE: we don't currently do these tests when writing structures!
-        #  --> add this to DeleteStruct() below if it turns out to be a problem)
-        unless ($cap or $isStruct) {
-            my $regex = quotemeta $path;
-            # also allow for missing structure fields in lists of structures
-            $regex =~  s/ \d+/ \\d\+/g;
-            my $ok = $regex; # regular expression to match standard property names
-            # also check for incorrect list types which can cause problems
-            if ($regex =~ s{\\/rdf\\:(Bag|Seq|Alt)\\/}{/rdf:(Bag|Seq|Alt)/}g) {
-                # also look for missing bottom-level list
-                $regex =~ s{/rdf:\(Bag\|Seq\|Alt\)\/rdf\\:li\\ \\d\+$}{(/.*)?};
-            }
-            my @matches = sort grep m{^$regex$}i, keys %capture;
-            if (@matches) {
-                if ($matches[0] =~ /^$ok$/) {
-                    $path = $matches[0];    # use existing property path
-                    $cap = $capture{$path};
+        until ($cap) {
+            # find and fix all incorrect property names if this is a structure or a flattened tag
+            my @fixInfo;
+            if ($isStruct or defined $$tagInfo{Flat}) {
+                # get tagInfo for all containing (possibly nested) structures
+                my @props = split '/', $path;
+                my $tbl = $$tagInfo{Table};
+                while (@props) {
+                    my $info = $$tbl{GetXMPTagID(\@props)};
+                    unshift @fixInfo, $info if ref $info eq 'HASH' and $$info{Struct} and
+                        (not @fixInfo or $fixInfo[0] ne $info);
+                    pop @props;
+                }
+                $et->WarnOnce("Error finding parent structure for $$tagInfo{Name}") unless @fixInfo;
+            }
+            # fix property path for this tag (last in the @fixInfo list)
+            push @fixInfo, $tagInfo unless @fixInfo and $isStruct;
+            # start from outermost containing structure, fixing incorrect list types, etc,
+            # finally fixing the actual tag properties after all containing structures
+            my $err;
+            while (@fixInfo) {
+                my $fixInfo = shift @fixInfo;
+                my $fixPath = ConformPathToNamespace($et, GetPropertyPath($fixInfo));
+                my $regex = quotemeta($fixPath);
+                $regex =~ s/ \d+/ \\d\+/g;  # match any list index
+                my $ok = $regex;
+                my ($ok2, $match, $i, @fixed, %fixed, $fixed);
+                # check for incorrect list types
+                if ($regex =~ s{\\/rdf\\:(Bag|Seq|Alt)\\/}{/rdf:(Bag|Seq|Alt)/}g) {
+                    # also look for missing bottom-level list
+                    if ($regex =~ s{/rdf:\(Bag\|Seq\|Alt\)\/rdf\\:li\\ \\d\+$}{}) {
+                        $regex .= '(/.*)?' unless @fixInfo;
+                    }
+                } elsif (not @fixInfo) {
+                    $ok2 = $regex;
+                    # check for properties in lists that shouldn't be (ref forum4325)
+                    $regex .= '(/rdf:(Bag|Seq|Alt)/rdf:li \d+)?';
+                }
+                if (@fixInfo) {
+                    $regex .= '(/.*)?';
+                    $ok .= '(/.*)?';
+                }
+                my @matches = sort grep m{^$regex$}i, keys %capture;
+                last unless @matches;
+                if ($matches[0] =~ m{^$ok$}) {
+                    unless (@fixInfo) {
+                        $path = $matches[0];
+                        $cap = $capture{$path};
+                    }
+                    next;
+                }
+                # needs fixing...
+                my @fixProps = split '/', $fixPath;
+                foreach $match (@matches) {
+                    my @matchProps = split '/', $match;
+                    # remove superfluous list properties if necessary
+                    $#matchProps = $#fixProps if $ok2 and $#matchProps > $#fixProps;
+                    for ($i=0; $i<@fixProps; ++$i) {
+                        defined $matchProps[$i] or $matchProps[$i] = $fixProps[$i], next;
+                        next if $matchProps[$i] =~ / \d+$/ or $matchProps[$i] eq $fixProps[$i];
+                        $matchProps[$i] = $fixProps[$i];
+                    }
+                    $fixed = join '/', @matchProps;
+                    $err = 1 if $fixed{$fixed} or ($capture{$fixed} and $match ne $fixed);
+                    push @fixed, $fixed;
+                    $fixed{$fixed} = 1;
+                }
+                my $tg = $et->GetGroup($fixInfo, 1) . ':' . $$fixInfo{Name};
+                my $wrn = lc($fixed[0]) eq lc($matches[0]) ? 'tag ID case' : 'list type';
+                if ($err) {
+                    $et->Warn("Incorrect $wrn for existing $tg (not changed)");
                 } else {
-                    # property list was wrong, so issue a warning and fix it
-                    my ($match, @fixed, %fixed, $err);
-                    foreach $match (@matches) {
-                        my $fixed = $path;
-                        # set list indices
-                        while ($match =~ / (\d+)/g) {
-                            my $idx = $1;
-                            # insert leading "X" so we don't replace this one again
-                            $fixed =~ s/ \d+/ X$idx/;
-                        }
-                        $fixed =~ s/ X/ /g if $fixed ne $path;  # remove "X"s
-                        $err = 1 if $capture{$fixed} or $fixed{$fixed};
-                        push @fixed, $fixed;
-                        $fixed{$fixed} = 1;
-                    }
-                    my $tg = $exifTool->GetGroup($tagInfo, 1) . ':' . $$tagInfo{Name};
-                    my $wrn = lc($path) eq lc($matches[0]) ? 'tag ID case' : 'list type';
-                    if ($err) {
-                        $exifTool->Warn("Incorrect $wrn for $tg conflicts with existing tag");
-                    } else {
-                        # fix the incorrect property paths for all values of this tag
-                        foreach $match (@matches) {
-                            my $fixed = shift @fixed;
-                            $capture{$fixed} = $capture{$match};
-                            delete $capture{$match};
-                        }
-                        $cap = $capture{$path} || $capture{$fixed[0]};
-                        $exifTool->Warn("Fixed incorrect $wrn for $tg", 1);
-                    }
-                }
-            }
-        }
-        my $nvHash = $exifTool->GetNewValueHash($tagInfo);
-        my $overwrite = Image::ExifTool::IsOverwriting($nvHash);
+                    # fix the incorrect property paths for all values of this tag
+                    my $didFix;
+                    foreach $fixed (@fixed) {
+                        my $match = shift @matches;
+                        next if $fixed eq $match;
+                        $capture{$fixed} = $capture{$match};
+                        delete $capture{$match};
+                        # remove xml:lang attribute from incorrect lang-alt list if necessary
+                        delete $capture{$fixed}[1]{'xml:lang'} if $ok2 and $match !~ /^$ok2$/;
+                        $didFix = 1;
+                    }
+                    $cap = $capture{$path} || $capture{$fixed[0]} unless @fixInfo;
+                    if ($didFix) {
+                        $et->Warn("Fixed incorrect $wrn for $tg", 1);
+                        ++$changed;
+                    }
+                }
+            }
+            last;
+        }
+        my $nvHash = $et->GetNewValueHash($tagInfo);
+        my $overwrite = $et->IsOverwriting($nvHash);
         my $writable = $$tagInfo{Writable} || '';
-        my (%attrs, $deleted, $added);
+        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) = DeleteStruct($exifTool, \%capture, \$path, $nvHash, \$changed);
+            ($deleted, $added, $existed) = DeleteStruct($et, \%capture, \$path, $nvHash, \$changed);
+            next unless $deleted or $added or $et->IsOverwriting($nvHash);
+            next if $existed and $$nvHash{CreateOnly};
         } elsif ($cap) {
+            next if $$nvHash{CreateOnly};   # (necessary for List-type tags)
             # 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 =~ / /) {
@@ -833,19 +1082,26 @@
                     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 = Image::ExifTool::IsCreating($nvHash) ? 1 : 0;
+                            $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!)
-                            $addLang = Image::ExifTool::IsOverwriting($nvHash, UnescapeXML($val));
+                            $addLang = $et->IsOverwriting($nvHash, UnescapeXML($val));
                             next unless $addLang;
                         }
@@ -861,19 +1117,43 @@
                     } elsif ($overwrite < 0) {
                         # only overwrite specific values
+                        if ($$nvHash{Shift}) {
+                            # values to be shifted are checked (hence re-formatted) late,
+                            # so we must un-format the to-be-shifted value for IsOverwriting()
+                            my $fmt = $$tagInfo{Writable} || '';
+                            if ($fmt eq 'rational') {
+                                ConvertRational($val);
+                            } elsif ($fmt eq 'date') {
+                                $val = ConvertXMPDate($val);
+                            }
+                        }
                         # (note: this won't match if original XML contains CDATA!)
-                        next unless Image::ExifTool::IsOverwriting($nvHash, UnescapeXML($val));
+                        next unless $et->IsOverwriting($nvHash, UnescapeXML($val));
                     }
                     if ($verbose > 1) {
-                        my $grp = $exifTool->GetGroup($tagInfo, 1);
+                        my $grp = $et->GetGroup($tagInfo, 1);
                         my $tagName = $$tagInfo{Name};
                         $tagName =~ s/-$$tagInfo{LangCode}$// if $$tagInfo{LangCode};
                         $tagName .= '-' . $$attrs{'xml:lang'} if $$attrs{'xml:lang'};
-                        $exifTool->VerboseValue("- $grp:$tagName", $val);
+                        $et->VerboseValue("- $grp:$tagName", $val);
                     }
                     # 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
@@ -887,7 +1167,11 @@
                     }
                 }
-                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 {
@@ -895,4 +1179,14 @@
                     # 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;
@@ -900,7 +1194,15 @@
                 }
             } else {
-                # are never overwriting, so we must be adding to a list
+                # 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;
@@ -919,5 +1221,5 @@
                 {
                     my $saveCap = $capture{$path};
-                    for (;;) {
+                    while ($saveCap) {
                         my $p = $path;
                         substr($p, $pos, $len) = length($nxt) . $nxt;
@@ -931,8 +1233,7 @@
                 } 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;
@@ -943,7 +1244,7 @@
         # check to see if we want to create this tag
         # (create non-avoided tags in XMP data files by default)
-        my $isCreating = (Image::ExifTool::IsCreating($nvHash) or $isStruct or
+        my $isCreating = ($$nvHash{IsCreating} or (($isStruct or
                           ($preferred and not $$tagInfo{Avoid} and
-                            not defined $$nvHash{Shift}));
+                            not defined $$nvHash{Shift})) and not $$nvHash{EditOnly}));
 
         # don't add new values unless...
@@ -954,9 +1255,11 @@
 
         # get list of new values (all done if no new values specified)
-        my @newValues = Image::ExifTool::GetNewValues($nvHash) or next;
+        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;
@@ -964,21 +1267,33 @@
             my $newValue = shift @newValues;
             if ($isStruct) {
-                ++$changed if AddNewStruct($exifTool, $tagInfo, \%capture,
+                ++$changed if AddNewStruct($et, $tagInfo, \%capture,
                                            $path, $newValue, $$tagInfo{Struct});
             } else {
                 $newValue = EscapeXML($newValue);
-                if ($$tagInfo{Resource}) {
-                    $capture{$path} = [ '', { %attrs, 'rdf:resource' => $newValue } ];
-                } else {
+                for (;;) { # (a cheap 'goto')
+                    if ($$tagInfo{Resource}) {
+                        # only store as a resource if it doesn't contain any illegal characters
+                        if ($newValue !~ /[^a-z0-9\:\/\?\#\[\]\@\!\$\&\'\(\)\*\+\,\;\=\.\-\_\~]/i) {
+                            $capture{$path} = [ '', { %attrs, 'rdf:resource' => $newValue } ];
+                            last;
+                        }
+                        my $grp = $et->GetGroup($tagInfo, 1);
+                        $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
+                    }
+                    # remove existing value and/or resource attribute if they exist
+                    delete $attrs{'rdf:value'};
+                    delete $attrs{'rdf:resource'};
                     $capture{$path} = [ $newValue, \%attrs ];
+                    last;
                 }
                 if ($verbose > 1) {
-                    my $grp = $exifTool->GetGroup($tagInfo, 1);
-                    $exifTool->VerboseValue("+ $grp:$$tagInfo{Name}", $newValue);
+                    my $grp = $et->GetGroup($tagInfo, 1);
+                    $et->VerboseValue("+ $grp:$$tagInfo{Name}", $newValue);
                 }
                 ++$changed;
                 # add rdf:type if necessary
                 if ($$tagInfo{StructType}) {
-                    AddStructType($exifTool, $$tagInfo{Table}, \%capture, $path);
+                    AddStructType($et, $$tagInfo{Table}, \%capture, $path);
                 }
             }
@@ -987,13 +1302,21 @@
             # 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';
@@ -1001,12 +1324,24 @@
             substr($path, $pos, $len) = $idx . $subIdx;
         }
+        # make sure any empty structures are deleted
+        # (ExifTool shouldn't write these, but other software may)
+        if (defined $$tagInfo{Flat}) {
+            my $p = $path;
+            while ($p =~ s/\/[^\/]+$//) {
+                next unless $capture{$p};
+                # it is an error if this property has a value
+                $et->Error("Improperly structured XMP ($p)",1) if $capture{$p}[0] =~ /\S/;
+                delete $capture{$p};    # delete the (hopefully) empty structure
+            }
+        }
     }
     # remove the ExifTool members we created
-    delete $exifTool->{XMP_CAPTURE};
-    delete $exifTool->{XMP_NS};
+    delete $$et{XMP_CAPTURE};
+    delete $$et{XMP_NS};
 
     my $maxDataLen = $$dirInfo{MaxDataLen};
     # get DataPt again because it may have been set by ProcessXMP
     $dataPt = $$dirInfo{DataPt};
+
     # return now if we didn't change anything
     unless ($changed or ($maxDataLen and $dataPt and defined $$dataPt and
@@ -1021,13 +1356,14 @@
 #
     # start writing the XMP data
-    my $newData = '';
-    if ($$exifTool{XMP_NO_XPACKET}) {
+    my (@long, @short, @resFlag);
+    $long[0] = $long[1] = $short[0] = '';
+    if ($$et{XMP_NO_XPACKET}) {
         # write BOM if flag is set
-        $newData .= "\xef\xbb\xbf" if $$exifTool{XMP_NO_XPACKET} == 2;
+        $long[-2] .= "\xef\xbb\xbf" if $$et{XMP_NO_XPACKET} == 2;
     } else {
-        $newData .= $pktOpen;
-    }
-    $newData .= $xmlOpen if $$exifTool{XMP_IS_XML};
-    $newData .= $xmpOpen . $rdfOpen;
+        $long[-2] .= $pktOpen;
+    }
+    $long[-2] .= $xmlOpen if $$et{XMP_IS_XML};
+    $long[-2] .= $xmpOpen . $rdfOpen;
 
     # initialize current property path list
@@ -1069,6 +1405,5 @@
             @pathList = @writeLast;
             undef @writeLast;
-            $extStart = length $newData;
-            $newDesc = 1;   # start with a new description
+            $newDesc = 2;   # start with a new description for the extended data
         }
         $path = shift @pathList;
@@ -1098,5 +1433,5 @@
             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';
@@ -1117,124 +1452,147 @@
         }
         # close out properties down to the common base path
-        while (@curPropList > $closeTo) {
-            ($prop = pop @curPropList) =~ s/ .*//;
-            $newData .= (' ' x scalar(@curPropList)) . " </$prop>\n";
-        }
+        CloseProperty(\@curPropList, \@long, \@short, \@resFlag) while @curPropList > $closeTo;
+
+        # open new description if necessary
         if ($newDesc) {
+            $extStart = length($long[-2]) if $newDesc == 2; # extended data starts after this
             # save rdf:Description start positions so we can reorder them if necessary
-            push @descStart, length($newData) if $maxDataLen;
+            push @descStart, length($long[-2]) if $maxDataLen;
             # open the new description
             $prop = $rdfDesc;
             %nsCur = %nsNew;            # save current namespaces
-            $newData .= "\n <$prop rdf:about='$about'";
             my @ns = sort keys %nsCur;
+            $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/}) {
-                $newData .= "\n  xmlns:et='http://ns.exiftool.ca/1.0/'" .
+            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'";
             }
-            foreach (@ns) {
-                $newData .= "\n  xmlns:$_='$nsCur{$_}'";
-            }
-            $newData .= ">\n";
+            $long[-2] .= "\n$sp${sp}xmlns:$_='$nsCur{$_}'" foreach @ns;
             push @curPropList, $prop;
-        }
-        # loop over all values for this new property
+            # 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";
-        # open new properties
-        my $attr;
+        # open new properties if necessary
+        my ($attr, $dummy);
         for ($n=@curPropList; $n<$#propList; ++$n) {
             $prop = $propList[$n];
             push @curPropList, $prop;
-            # remove list index if it exists
-            $prop =~ s/ .*//;
-            $attr = '';
+            $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] .= ($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)))
             {
-                # need parseType='Resource' to avoid new 'rdf:Description'
-                $attr = " rdf:parseType='Resource'";
-            }
-            $newData .= (' ' x scalar(@curPropList)) . "<$prop$attr>\n";
+                # check for empty structure
+                if ($propList[$n+1] =~ /:~dummy~$/) {
+                    $long[-1] .= " rdf:parseType='Resource'/>$nl";
+                    pop @curPropList;
+                    $dummy = 1;
+                    last;
+                }
+                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'>$nl";
+                }
+            } else {
+                $long[-1] .= ">$nl"; # (will be no shorthand properties)
+            }
         }
         my $prop2 = pop @propList;  # get new property name
-        $prop2 =~ s/ .*//;          # remove list index if it exists
-        $newData .= (' ' x scalar(@curPropList)) . " <$prop2";
-        # write out attributes
-        foreach $attr (sort keys %$attrs) {
-            my $attrVal = $$attrs{$attr};
-            my $quot = ($attrVal =~ /'/) ? '"' : "'";
-            $newData .= " $attr=$quot$attrVal$quot";
-        }
-        $newData .= length $val ? ">$val</$prop2>\n" : "/>\n";
-    }
-    # close off any open elements
-    while ($prop = pop @curPropList) {
-        $prop =~ s/ .*//;   # remove list index if it exists
-        $newData .= (' ' x scalar(@curPropList)) . " </$prop>\n";
-    }
+        # 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 = $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}'";
+            } else {
+                $long[-1] .= "$pad<$prop2";
+                # write out attributes
+                foreach $attr (sort keys %$attrs) {
+                    my $attrVal = $$attrs{$attr};
+                    my $quot = ($attrVal =~ /'/) ? '"' : "'";
+                    $long[-1] .= " $attr=$quot$attrVal$quot";
+                }
+                $long[-1] .= length $val ? ">$val</$prop2>$nl" : "/>$nl";
+            }
+        }
+    }
+    # close out all open properties
+    CloseProperty(\@curPropList, \@long, \@short, \@resFlag) while @curPropList;
+
     # limit XMP length and re-arrange if necessary to fit inside specified size
-    my $compact = $$dirInfo{Compact} || $exifTool->Options('Compact');
     if ($maxDataLen) {
         # adjust maxDataLen to allow room for closing elements
         $maxDataLen -= length($rdfClose) + length($xmpClose) + length($pktCloseW);
-        $extStart or $extStart = length $newData;
-        my @rtn = LimitXMPSize($exifTool, \$newData, $maxDataLen, $about, \@descStart, $extStart);
+        $extStart or $extStart = length $long[-2];
+        my @rtn = LimitXMPSize($et, \$long[-2], $maxDataLen, $about, \@descStart, $extStart);
         # return extended XMP information in $dirInfo
         $$dirInfo{ExtendedXMP} = $rtn[0];
         $$dirInfo{ExtendedGUID} = $rtn[1];
         # compact if necessary to fit
-        $compact = 1 if length($newData) + 101 * $numPadLines > $maxDataLen;
-    }
+        $compact{NoPadding} = 1 if length($long[-2]) + 101 * $numPadLines > $maxDataLen;
+    }
+    $compact{NoPadding} = 1 if $$dirInfo{Compact};
 #
 # close out the XMP, clean up, and return our data
 #
-    $newData .= $rdfClose;
-    $newData .= $xmpClose unless $exifTool->{XMP_NO_XMPMETA};
+    $long[-2] .= $rdfClose;
+    $long[-2] .= $xmpClose unless $$et{XMP_NO_XMPMETA};
 
     # remove the ExifTool members we created
-    delete $exifTool->{XMP_CAPTURE};
-    delete $exifTool->{XMP_NS};
-    delete $exifTool->{XMP_NO_XMPMETA};
+    delete $$et{XMP_CAPTURE};
+    delete $$et{XMP_NS};
+    delete $$et{XMP_NO_XMPMETA};
 
     # (the XMP standard recommends writing 2k-4k of white space before the
     # packet trailer, with a newline every 100 characters)
-    unless ($$exifTool{XMP_NO_XPACKET}) {
+    unless ($$et{XMP_NO_XPACKET}) {
         my $pad = (' ' x 100) . "\n";
-        if ($$dirInfo{InPlace}) {
+        # get current XMP length without padding
+        my $len = length($long[-2]) + length($pktCloseW);
+        if ($$dirInfo{InPlace} and not ($$dirInfo{InPlace} == 2 and $len > $dirLen)) {
             # pad to specified DirLen
-            my $len = length($newData) + length($pktCloseW);
             if ($len > $dirLen) {
-                $exifTool->Warn('Not enough room to edit XMP in place');
+                my $str = 'Not enough room to edit XMP in place';
+                $str .= '. Try Shorthand feature' unless $compact{Shorthand};
+                $et->Warn($str);
                 return undef;
             }
             my $num = int(($dirLen - $len) / length($pad));
             if ($num) {
-                $newData .= $pad x $num;
+                $long[-2] .= $pad x $num;
                 $len += length($pad) * $num;
             }
-            $len < $dirLen and $newData .= (' ' x ($dirLen - $len - 1)) . "\n";
-        } elsif (not $compact and not $xmpFile and not $$dirInfo{ReadOnly}) {
-            $newData .= $pad x $numPadLines;
-        }
-        $newData .= ($$dirInfo{ReadOnly} ? $pktCloseR : $pktCloseW);
+            $len < $dirLen and $long[-2] .= (' ' x ($dirLen - $len - 1)) . "\n";
+        } elsif (not $compact{NoPadding} and not $xmpFile and not $$dirInfo{ReadOnly}) {
+            $long[-2] .= $pad x $numPadLines;
+        }
+        $long[-2] .= ($$dirInfo{ReadOnly} ? $pktCloseR : $pktCloseW);
     }
     # return empty data if no properties exist and this is allowed
     unless (%capture or $xmpFile or $$dirInfo{InPlace} or $$dirInfo{NoDelete}) {
-        $newData = '';
+        $long[-2] = '';
     }
     if ($xmpErr) {
         if ($xmpFile) {
-            $exifTool->Error($xmpErr);
+            $et->Error($xmpErr);
             return -1;
         }
-        $exifTool->Warn($xmpErr);
+        $et->Warn($xmpErr);
         return undef;
     }
-    $exifTool->{CHANGED} += $changed;
-    $debug > 1 and $newData and print $newData,"\n";
-    return $newData unless $xmpFile;
-    Write($$dirInfo{OutFile}, $newData) or return -1;
+    $$et{CHANGED} += $changed;
+    $debug > 1 and $long[-2] and print $long[-2],"\n";
+    return $long[-2] unless $xmpFile;
+    Write($$dirInfo{OutFile}, $long[-2]) or return -1;
     return 1;
 }
@@ -1259,5 +1617,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Writer.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Writer.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/Writer.pl	(revision 34921)
@@ -6,5 +6,5 @@
 # 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
@@ -20,5 +20,6 @@
 sub AssembleRational($$@);
 sub LastInList($);
-sub CreateDirectory($);
+sub CreateDirectory($$);
+sub NextFreeTagKey($$);
 sub RemoveNewValueHash($$$);
 sub RemoveNewValuesForGroup($$);
@@ -28,4 +29,5 @@
 
 my $loadedAllTables;    # flag indicating we loaded all tables
+my $advFmtSelf;         # ExifTool object during evaluation of advanced formatting expr
 
 # the following is a road map of where we write each directory
@@ -47,4 +49,5 @@
     CanonVRD     => 'MakerNotes', # (so VRDOffset will get updated)
     NikonCapture => 'MakerNotes', # (to allow delete by group)
+    PhaseOne     => 'MakerNotes', # (for editing PhaseOne SensorCalibration tags)
 );
 my %exifMap = (
@@ -69,4 +72,5 @@
     ICC_Profile  => 'APP2',
     FlashPix     => 'APP2',
+    MPF          => 'APP2',
     Meta         => 'APP3',
     MetaIFD      => 'Meta',
@@ -74,4 +78,5 @@
     Ducky        => 'APP12',
     Photoshop    => 'APP13',
+    Adobe        => 'APP14',
     IPTC         => 'Photoshop',
     MakerNotes   => ['ExifIFD', 'CIFF'], # (first parent is the default)
@@ -82,4 +87,5 @@
 my %dirMap = (
     JPEG => \%jpegMap,
+    EXV  => \%jpegMap,
     TIFF => \%tiffMap,
     ORF  => \%tiffMap,
@@ -88,4 +94,39 @@
 );
 
+# module names and write functions for each writable file type
+# (defaults to "$type" and "Process$type" if not defined)
+# - types that are handled specially will not appear in this list
+my %writableType = (
+    CRW => [ 'CanonRaw',    'WriteCRW' ],
+    DR4 =>   'CanonVRD',
+    EPS => [ 'PostScript',  'WritePS'  ],
+    FLIF=> [ undef,         'WriteFLIF'],
+    GIF =>   undef,
+    ICC => [ 'ICC_Profile', 'WriteICC' ],
+    IND =>   'InDesign',
+    JP2 =>   'Jpeg2000',
+    MIE =>   undef,
+    MOV => [ 'QuickTime',   'WriteMOV' ],
+    MRW =>   'MinoltaRaw',
+    PDF => [ undef,         'WritePDF' ],
+    PNG =>   undef,
+    PPM =>   undef,
+    PS  => [ 'PostScript',  'WritePS'  ],
+    PSD =>   'Photoshop',
+    RAF => [ 'FujiFilm',    'WriteRAF' ],
+    VRD =>   'CanonVRD',
+    X3F =>   'SigmaRaw',
+    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:
@@ -93,9 +134,32 @@
 # 2) any dependencies must be added to %excludeGroups
 my @delGroups = qw(
-    AFCP CanonVRD CIFF Ducky EXIF ExifIFD File FlashPix FotoStation GlobParamIFD
-    GPS ICC_Profile IFD0 IFD1 InteropIFD IPTC JFIF MakerNotes Meta MetaIFD MIE
-    NikonCapture PDF PDF-update PhotoMechanic Photoshop PNG 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';
+
+# groups we don't delete when deleting all information
+my $protectedGroups = '(IFD1|SubIFD|InteropIFD|GlobParamIFD|PDF-update|Adobe)';
+
 # other group names of new tag values to remove when deleting an entire group
 my %removeGroups = (
@@ -125,13 +189,21 @@
     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 = (
+    ciff  => 'canonraw',
 );
 # group names to translate for writing
 my %translateWriteGroup = (
-    EXIF => 'ExifIFD',
-    Meta => 'MetaIFD',
-    File => 'Comment',
-    MIE  => 'MIE',
+    EXIF  => 'ExifIFD',
+    Meta  => 'MetaIFD',
+    File  => 'Comment',
+    # any entry in this table causes the write group to be set from the
+    # tag information instead of whatever the user specified...
+    MIE   => 'MIE',
+    APP14 => 'APP14',
 );
-# names of valid EXIF and Meta directories:
+# names of valid EXIF and Meta directories (lower case keys):
 my %exifDirs = (
     gps          => 'GPS',
@@ -140,8 +212,19 @@
     globparamifd => 'GlobParamIFD',
     interopifd   => 'InteropIFD',
-    makernotes   => 'MakerNotes',
     previewifd   => 'PreviewIFD', # (in MakerNotes)
     metaifd      => 'MetaIFD', # Kodak APP3 Meta
+    makernotes   => 'MakerNotes',
 );
+# valid family 0 groups when WriteGroup is set to "All"
+my %allFam0 = (
+    exif         => 1,
+    makernotes   => 1,
+);
+
+my @writableMacOSTags = qw(
+    FileCreateDate MDItemFinderComment MDItemFSCreationDate MDItemFSLabel MDItemUserTags
+    XAttrQuarantine
+);
+
 # min/max values for integer formats
 my %intRange = (
@@ -153,7 +236,9 @@
     'int32u' => [0, 0xffffffff],
     'int32s' => [-0x80000000, 0x7fffffff],
+    'int64u' => [0, 18446744073709551615],
+    'int64s' => [-9223372036854775808, 9223372036854775807],
 );
 # lookup for file types with block-writable EXIF
-my %blockExifTypes = ( JPEG=>1, PNG=>1, JP2=>1, MIE=>1, EXIF=>1 );
+my %blockExifTypes = map { $_ => 1 } qw(JPEG PNG JP2 MIE EXIF FLIF MOV MP4);
 
 my $maxSegmentLen = 0xfffd;     # maximum length of data in a JPEG segment
@@ -164,5 +249,5 @@
 
 # printConv hash keys to ignore when doing reverse lookup
-my %ignorePrintConv = ( OTHER => 1, BITMASK => 1, Notes => 1 );
+my %ignorePrintConv = map { $_ => 1 } qw(OTHER BITMASK Notes);
 
 #------------------------------------------------------------------------------
@@ -175,5 +260,6 @@
 #           Type => PrintConv, ValueConv or Raw - specifies value type
 #           AddValue => true to add to list of existing values instead of overwriting
-#           DelValue => true to delete this existing value value from a list
+#           DelValue => true to delete this existing value value from a list, or
+#                       or doing a conditional delete, or to shift a time value
 #           Group => family 0 or 1 group name (case insensitive)
 #           Replace => 0, 1 or 2 - overwrite previous new values (2=reset)
@@ -182,23 +268,35 @@
 #           EditGroup => true to only edit existing groups (don't create new group)
 #           Shift => undef, 0, +1 or -1 - shift value if possible
+#           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
+#           Sanitized => [internal use] set to avoid double-sanitizing the value
 # Returns: number of tags set (plus error string in list context)
 # Notes: For tag lists (like Keywords), call repeatedly with the same tag name for
 #        each value in the list.  Internally, the new information is stored in
-#        the following members of the $self->{NEW_VALUE}{$tagInfo} hash:
+#        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
-#           IsCreating - must be set for the tag to be added, otherwise just
-#                        changed if it already exists.  Set to 2 to not create group
+#           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 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)
 #           CreateGroups - hash of all family 0 group names where tag may be created
 #           WriteGroup - group name where information is being written (correct case)
 #           WantGroup - group name as specified in call to function (case insensitive)
 #           Next - pointer to next new value hash (if more than one)
-#           Self - ExifTool object reference
+#           NoReplace - set if value was created with Replace=0
+#           AddBefore - number of list items added by a subsequent Replace=0 call
+#           IsNVH - Flag indicating this is a new value hash
 #           Shift - shift value
+#           Save - counter used by SaveNewValues()/RestoreNewValues()
 #           MAKER_NOTE_FIXUP - pointer to fixup if necessary for a maker note value
 sub SetNewValue($;$$%)
@@ -206,17 +304,17 @@
     local $_;
     my ($self, $tag, $value, %options) = @_;
-    my ($err, $tagInfo);
-    my $verbose = $self->{OPTIONS}{Verbose};
-    my $out = $self->{OPTIONS}{TextOut};
+    my ($err, $tagInfo, $family);
+    my $verbose = $$self{OPTIONS}{Verbose};
+    my $out = $$self{OPTIONS}{TextOut};
     my $protected = $options{Protected} || 0;
     my $listOnly = $options{ListOnly};
     my $setTags = $options{SetTags};
+    my $noFlat = $options{NoFlat};
     my $numSet = 0;
 
     unless (defined $tag) {
-        # remove any existing set values
-        delete $self->{NEW_VALUE};
-        $self->{DEL_GROUP} = { };
-        $verbose > 1 and print $out "Cleared new values\n";
+        delete $$self{NEW_VALUE};
+        $$self{SAVE_COUNT} = 0;
+        $$self{DEL_GROUP} = { };
         return 1;
     }
@@ -224,17 +322,26 @@
     if (ref $value) {
         if (ref $value eq 'ARRAY') {
-            # (since value is an ARRAY, it will have more than one entry)
-            # set all list-type tags first
-            my $replace = $options{Replace};
-            foreach (@$value) {
-                my ($n, $e) = SetNewValue($self, $tag, $_, %options, ListOnly => 1);
-                $err = $e if $e;
-                $numSet += $n;
-                delete $options{Replace}; # don't replace earlier values in list
-            }
-            # and now set only non-list tags
-            $value = join $self->{OPTIONS}{ListSep}, @$value;
-            $options{Replace} = $replace;
-            $listOnly = $options{ListOnly} = 0;
+            # value is an ARRAY so it may have more than one entry
+            # - set values both separately and as a combined string if there are more than one
+            if (@$value > 1) {
+                # set all list-type tags first
+                my $replace = $options{Replace};
+                my $noJoin;
+                foreach (@$value) {
+                    $noJoin = 1 if ref $_;
+                    my ($n, $e) = SetNewValue($self, $tag, $_, %options, ListOnly => 1);
+                    $err = $e if $e;
+                    $numSet += $n;
+                    delete $options{Replace}; # don't replace earlier values in list
+                }
+                return $numSet if $noJoin;  # don't join if list contains objects
+                # and now set only non-list tags
+                $value = join $$self{OPTIONS}{ListSep}, @$value;
+                $options{Replace} = $replace;
+                $listOnly = $options{ListOnly} = 0;
+            } else {
+                $value = $$value[0];
+                $value = $$value if ref $value eq 'SCALAR'; # (handle single scalar ref in a list)
+            }
         } elsif (ref $value eq 'SCALAR') {
             $value = $$value;
@@ -243,159 +350,234 @@
     # un-escape as necessary and make sure the Perl UTF-8 flag is OFF for the value
     # if perl is 5.6 or greater (otherwise our byte manipulations get corrupted!!)
-    $self->Sanitize(\$value) if defined $value and not ref $value;
+    $self->Sanitize(\$value) if defined $value and not ref $value and not $options{Sanitized};
 
     # set group name in options if specified
-    if ($tag =~ /(.*):(.+)/) {
-        $options{Group} = $1 if $1 ne '*' and lc($1) ne 'all';
-        $tag = $2;
-    }
+    ($options{Group}, $tag) = ($1, $2) if $tag =~ /(.*):(.+)/;
+
     # allow trailing '#' for ValueConv value
     $options{Type} = 'ValueConv' if $tag =~ s/#$//;
-    # ignore leading family number if 0 or 1 specified
-    if ($options{Group} and $options{Group} =~ /^(\d+)(.*)/ and $1 < 2) {
-        $options{Group} = $2;
+    my $convType = $options{Type} || ($$self{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv');
+
+    # filter value if necessary
+    $self->Filter($$self{OPTIONS}{FilterW}, \$value) or return 0 if $convType eq 'PrintConv';
+
+    my (@wantGroup, $family2);
+    my $wantGroup = $options{Group};
+    if ($wantGroup) {
+        foreach (split /:/, $wantGroup) {
+            next unless length($_) and /^(\d+)?(.*)/; # separate family number and group name
+            my ($f, $g) = ($1, $2);
+            my $lcg = lc $g;
+            # save group/family unless '*' or 'all'
+            push @wantGroup, [ $f, $lcg ] unless $lcg eq '*' or $lcg eq 'all';
+            if ($g =~ s/^ID-//i) {          # family 7 is a tag ID
+                return 0 if defined $f and $f ne 7;
+                $wantGroup[-1] = [ 7, $g ]; # group name with 'ID-' removed and case preserved
+            } elsif (defined $f) {
+                $f > 2 and return 0;        # only allow family 0, 1 or 2
+                $family2 = 1 if $f == 2;    # set flag indicating family 2 was used
+            } else {
+                $family2 = 1 if $family2groups{$lcg};
+            }
+        }
+        undef $wantGroup unless @wantGroup;
+    }
+
+    $tag =~ s/ .*//;    # convert from tag key to tag name if necessary
+    $tag = '*' if lc($tag) eq 'all';    # use '*' instead of 'all'
+#
+# handle group delete
+#
+    while ($tag eq '*' and not defined $value and not $family2 and @wantGroup < 2) {
+        # set groups to delete
+        my (@del, $grp);
+        my $remove = ($options{Replace} and $options{Replace} > 1);
+        if ($wantGroup) {
+            @del = grep /^$wantGroup$/i, @delGroups unless $wantGroup =~ /^XM[LP]-\*$/i;
+            # remove associated groups when excluding from mass delete
+            if (@del and $remove) {
+                # remove associated groups in other family
+                push @del, @{$excludeGroups{$del[0]}} if $excludeGroups{$del[0]};
+                # remove upstream groups according to JPEG map
+                my $dirName = $del[0];
+                my @dirNames;
+                for (;;) {
+                    my $parent = $jpegMap{$dirName};
+                    if (ref $parent) {
+                        push @dirNames, @$parent;
+                        $parent = pop @dirNames;
+                    }
+                    $dirName = $parent || shift @dirNames or last;
+                    push @del, $dirName;    # exclude this too
+                }
+            }
+            # allow MIE groups to be deleted by number,
+            # and allow any XMP family 1 group to be deleted
+            push @del, uc($wantGroup) if $wantGroup =~ /^(MIE\d+|XM[LP]-[-\w]*\w)$/i;
+        } else {
+            # push all groups plus '*', except the protected groups
+            push @del, (grep !/^$protectedGroups$/, @delGroups), '*';
+        }
+        if (@del) {
+            ++$numSet;
+            my @donegrps;
+            my $delGroup = $$self{DEL_GROUP};
+            foreach $grp (@del) {
+                if ($remove) {
+                    my $didExcl;
+                    if ($grp =~ /^(XM[LP])(-.*)?$/) {
+                        my $x = $1;
+                        if ($grp eq $x) {
+                            # exclude all related family 1 groups too
+                            foreach (keys %$delGroup) {
+                                next unless /^(-?)$x-/;
+                                push @donegrps, $_ unless $1;
+                                delete $$delGroup{$_};
+                            }
+                        } elsif ($$delGroup{"$x-*"} and not $$delGroup{"-$grp"}) {
+                            # must also exclude XMP or XML to prevent bulk delete
+                            if ($$delGroup{$x}) {
+                                push @donegrps, $x;
+                                delete $$delGroup{$x};
+                            }
+                            # flag XMP/XML family 1 group for exclusion with leading '-'
+                            $$delGroup{"-$grp"} = 1;
+                            $didExcl = 1;
+                        }
+                    }
+                    if (exists $$delGroup{$grp}) {
+                        delete $$delGroup{$grp};
+                    } else {
+                        next unless $didExcl;
+                    }
+                } else {
+                    $$delGroup{$grp} = 1;
+                    # 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);
+                }
+                push @donegrps, $grp;
+            }
+            if ($verbose > 1 and @donegrps) {
+                @donegrps = sort @donegrps;
+                my $msg = $remove ? 'Excluding from deletion' : 'Deleting tags in';
+                print $out "  $msg: @donegrps\n";
+            }
+        } elsif (grep /^$wantGroup$/i, @delGroup2) {
+            last;   # allow tags to be deleted by group2 name
+        } else {
+            $err = "Not a deletable group: $wantGroup";
+        }
+        # all done
+        return ($numSet, $err) if wantarray;
+        $err and warn "$err\n";
+        return $numSet;
+    }
+
+    # initialize write/create flags
+    my $createOnly;
+    my $editOnly = $options{EditOnly};
+    my $editGroup = $options{EditGroup};
+    my $writeMode = $$self{OPTIONS}{WriteMode};
+    if ($writeMode ne 'wcg') {
+        $createOnly = 1 if $writeMode !~ /w/i;  # don't write existing tags
+        if ($writeMode !~ /c/i) {
+            return 0 if $createOnly;    # nothing to do unless writing existing tags
+            $editOnly = 1;              # don't create new tags
+        } elsif ($writeMode !~ /g/i) {
+            $editGroup = 1;             # don't create new groups
+        }
+    }
+    my ($ifdName, $mieGroup, $movGroup, $fg);
+    # set family 1 group names
+    foreach $fg (@wantGroup) {
+        next if defined $$fg[0] and $$fg[0] != 1;
+        $_ = $$fg[1];
+        # set $ifdName if this group is a valid IFD or SubIFD name
+        my $grpName;
+        if (/^IFD(\d+)$/i) {
+            $grpName = $ifdName = "IFD$1";
+        } elsif (/^SubIFD(\d+)$/i) {
+            $grpName = $ifdName = "SubIFD$1";
+        } elsif (/^Version(\d+)$/i) {
+            $grpName = $ifdName = "Version$1"; # Sony IDC VersionIFD
+        } elsif ($exifDirs{$_}) {
+            $grpName = $exifDirs{$_};
+            $ifdName = $grpName unless $ifdName and $allFam0{$_};
+        } elsif ($allFam0{$_}) {
+            $grpName = $allFam0{$_};
+        } elsif (/^Track(\d+)$/i) {
+            $grpName = $movGroup = "Track$1";  # QuickTime track
+        } elsif (/^MIE(\d*-?)(\w+)$/i) {
+            $grpName = $mieGroup = "MIE$1" . ucfirst(lc($2));
+        } elsif (not $ifdName and /^XMP\b/i) {
+            # must load XMP table to set group1 names
+            my $table = GetTagTable('Image::ExifTool::XMP::Main');
+            my $writeProc = $$table{WRITE_PROC};
+            if ($writeProc) {
+                no strict 'refs';
+                &$writeProc();
+            }
+        }
+        # fix case for known groups
+        $wantGroup =~ s/$grpName/$grpName/i if $grpName and $grpName ne $_;
     }
 #
 # get list of tags we want to set
 #
-    my $wantGroup = $options{Group};
-    $tag =~ s/ .*//;    # convert from tag key to tag name if necessary
+    my $origTag = $tag;
     my @matchingTags = FindTagInfo($tag);
     until (@matchingTags) {
-        if ($tag eq '*' or lc($tag) eq 'all') {
-            # set groups to delete
-            if (defined $value) {
-                $err = "Can't set value for all tags";
-            } else {
-                my (@del, $grp);
-                my $remove = ($options{Replace} and $options{Replace} > 1);
-                if ($wantGroup) {
-                    @del = grep /^$wantGroup$/i, @delGroups unless $wantGroup =~ /^XM[LP]-\*$/i;
-                    # remove associated groups when excluding from mass delete
-                    if (@del and $remove) {
-                        # remove associated groups in other family
-                        push @del, @{$excludeGroups{$del[0]}} if $excludeGroups{$del[0]};
-                        # remove upstream groups according to JPEG map
-                        my $dirName = $del[0];
-                        my @dirNames;
-                        for (;;) {
-                            my $parent = $jpegMap{$dirName};
-                            if (ref $parent) {
-                                push @dirNames, @$parent;
-                                $parent = pop @dirNames;
-                            }
-                            $dirName = $parent || shift @dirNames or last;
-                            push @del, $dirName;    # exclude this too
-                        }
-                    }
-                    # allow MIE groups to be deleted by number,
-                    # and allow any XMP family 1 group to be deleted
-                    push @del, uc($wantGroup) if $wantGroup =~ /^(MIE\d+|XM[LP]-[-\w]+)$/i;
+        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/QuickTime
+        {
+            $tag = $1;
+            # normalize case of language codes
+            $langCode = lc($2);
+            $langCode .= (length($3) == 3 ? uc($3) : lc($3)) if $3;
+            my @newMatches = FindTagInfo($tag);
+            foreach $tagInfo (@newMatches) {
+                # only allow language codes in tables which support them
+                next unless $$tagInfo{Table};
+                my $langInfoProc = $$tagInfo{Table}{LANG_INFO} or next;
+                my $langInfo = &$langInfoProc($tagInfo, $langCode);
+                push @matchingTags, $langInfo if $langInfo;
+            }
+            last if @matchingTags;
+        } elsif (not $options{NoShortcut}) {
+            # look for a shortcut or alias
+            require Image::ExifTool::Shortcuts;
+            my ($match) = grep /^\Q$tag\E$/i, keys %Image::ExifTool::Shortcuts::Main;
+            undef $err;
+            if ($match) {
+                $options{NoShortcut} = $options{Sanitized} = 1;
+                foreach $tag (@{$Image::ExifTool::Shortcuts::Main{$match}}) {
+                    my ($n, $e) = $self->SetNewValue($tag, $value, %options);
+                    $numSet += $n;
+                    $e and $err = $e;
+                }
+                undef $err if $numSet;  # no error if any set successfully
+                return ($numSet, $err) if wantarray;
+                $err and warn "$err\n";
+                return $numSet;
+            }
+        }
+        unless ($listOnly) {
+            if (not TagExists($tag)) {
+                if ($tag =~ /^[-\w*?]+$/) {
+                    my $pre = $wantGroup ? $wantGroup . ':' : '';
+                    $err = "Tag '$pre${origTag}' is not defined";
+                    $err .= ' or has a bad language code' if $origTag =~ /-/;
                 } else {
-                    # push all groups plus '*', except IFD1 and a few others
-                    push @del, (grep !/^(IFD1|SubIFD|InteropIFD|GlobParamIFD|PDF-update)$/, @delGroups), '*';
-                }
-                if (@del) {
-                    ++$numSet;
-                    my @donegrps;
-                    my $delGroup = $self->{DEL_GROUP};
-                    foreach $grp (@del) {
-                        if ($remove) {
-                            my $didExcl;
-                            if ($grp =~ /^(XM[LP])(-.*)?$/) {
-                                my $x = $1;
-                                if ($grp eq $x) {
-                                    # exclude all related family 1 groups too
-                                    foreach (keys %$delGroup) {
-                                        next unless /^-?$x-/;
-                                        push @donegrps, $_ if /^$x/;
-                                        delete $$delGroup{$_};
-                                    }
-                                } elsif ($$delGroup{"$x-*"} and not $$delGroup{"-$grp"}) {
-                                    # must also exclude XMP or XML to prevent bulk delete
-                                    if ($$delGroup{$x}) {
-                                        push @donegrps, $x;
-                                        delete $$delGroup{$x};
-                                    }
-                                    # flag XMP/XML family 1 group for exclusion with leading '-'
-                                    $$delGroup{"-$grp"} = 1;
-                                    $didExcl = 1;
-                                }
-                            }
-                            if (exists $$delGroup{$grp}) {
-                                delete $$delGroup{$grp};
-                            } else {
-                                next unless $didExcl;
-                            }
-                        } 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-*";
-                            }
-                            # remove all of this group from previous new values
-                            $self->RemoveNewValuesForGroup($grp);
-                        }
-                        push @donegrps, $grp;
-                    }
-                    if ($verbose > 1 and @donegrps) {
-                        @donegrps = sort @donegrps;
-                        my $msg = $remove ? 'Excluding from deletion' : 'Deleting tags in';
-                        print $out "  $msg: @donegrps\n";
-                    }
-                } else {
-                    $err = "Not a deletable group: $wantGroup";
-                }
-            }
-        } else {
-            my $origTag = $tag;
-            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 = $1;
-                # normalize case of language codes
-                $langCode = lc($2);
-                $langCode .= (length($3) == 3 ? uc($3) : lc($3)) if $3;
-                my @newMatches = FindTagInfo($tag);
-                foreach $tagInfo (@newMatches) {
-                    # only allow language codes in tables which support them
-                    next unless $$tagInfo{Table};
-                    my $langInfoProc = $tagInfo->{Table}{LANG_INFO} or next;
-                    my $langInfo = &$langInfoProc($tagInfo, $langCode);
-                    push @matchingTags, $langInfo if $langInfo;
-                }
-                last if @matchingTags;
-            } else {
-                # look for a shortcut or alias
-                require Image::ExifTool::Shortcuts;
-                my ($match) = grep /^\Q$tag\E$/i, keys %Image::ExifTool::Shortcuts::Main;
-                undef $err;
-                if ($match and not $options{NoShortcut}) {
-                    if (@{$Image::ExifTool::Shortcuts::Main{$match}} == 1) {
-                        $tag = $Image::ExifTool::Shortcuts::Main{$match}[0];
-                        @matchingTags = FindTagInfo($tag);
-                        last if @matchingTags;
-                    } else {
-                        $options{NoShortcut} = 1;
-                        foreach $tag (@{$Image::ExifTool::Shortcuts::Main{$match}}) {
-                            my ($n, $e) = $self->SetNewValue($tag, $value, %options);
-                            $numSet += $n;
-                            $e and $err = $e;
-                        }
-                        undef $err if $numSet;  # no error if any set successfully
-                        return ($numSet, $err) if wantarray;
-                        $err and warn "$err\n";
-                        return $numSet;
-                    }
-                }
-            }
-            if (not TagExists($tag)) {
-                $err = "Tag '$origTag' does not exist";
-                $err .= ' or has a bad language code' if $origTag =~ /-/;
+                    $err = "Invalid tag name '${tag}'";
+                    $err .= " (remove the leading '\$')" if $tag =~ /^\$/;
+                }
             } elsif ($langCode) {
-                $err = "Tag '$tag' does not support alternate languages";
+                $err = "Tag '${tag}' does not support alternate languages";
             } elsif ($wantGroup) {
                 $err = "Sorry, $wantGroup:$origTag doesn't exist or isn't writable";
@@ -412,69 +594,88 @@
     # get group name that we're looking for
     my $foundMatch = 0;
-    my ($ifdName, $mieGroup);
-    if ($wantGroup) {
-        # set $ifdName if this group is a valid IFD or SubIFD name
-        if ($wantGroup =~ /^IFD(\d+)$/i) {
-            $ifdName = "IFD$1";
-        } elsif ($wantGroup =~ /^SubIFD(\d+)$/i) {
-            $ifdName = "SubIFD$1";
-        } elsif ($wantGroup =~ /^Version(\d+)$/i) {
-            $ifdName = "Version$1"; # Sony IDC VersionIFD
-        } elsif ($wantGroup =~ /^MIE(\d*-?)(\w+)$/i) {
-            $mieGroup = "MIE$1" . ucfirst(lc($2));
-        } else {
-            $ifdName = $exifDirs{lc($wantGroup)};
-            if (not $ifdName and $wantGroup =~ /^XMP\b/i) {
-                # must load XMP table to set group1 names
-                my $table = GetTagTable('Image::ExifTool::XMP::Main');
-                my $writeProc = $table->{WRITE_PROC};
-                $writeProc and &$writeProc();
-            }
-        }
-    }
 #
 # determine the groups for all tags found, and the tag with
 # the highest priority group
 #
-    my (@tagInfoList, @writeAlsoList, %writeGroup, %preferred, %tagPriority, $avoid, $wasProtected);
-    my $highestPriority = -1;
-    foreach $tagInfo (@matchingTags) {
-        $tag = $tagInfo->{Name};    # set tag so warnings will use proper case
-        my ($writeGroup, $priority);
+    my (@tagInfoList, @writeAlsoList, %writeGroup, %preferred, %tagPriority);
+    my (%avoid, $wasProtected, $noCreate, %highestPriority, %highestQT);
+
+TAG: foreach $tagInfo (@matchingTags) {
+        $tag = $$tagInfo{Name};     # get tag name for warnings
+        my $lcTag = lc $tag;        # get lower-case tag name for use in variables
+        # 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) {
-            my $lcWant = lc($wantGroup);
-            # only set tag in specified group
-            $writeGroup = $self->GetGroup($tagInfo, 0);
-            unless (lc($writeGroup) eq $lcWant) {
-                if ($writeGroup eq 'EXIF' or $writeGroup eq 'SonyIDC') {
-                    next unless $ifdName;
-                    # can't yet write PreviewIFD tags
-                    $ifdName eq 'PreviewIFD' and ++$foundMatch, next;
-                    $writeGroup = $ifdName;  # write to the specified IFD
-                } elsif ($writeGroup eq 'MIE') {
-                    next unless $mieGroup;
+            # 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 general write group of "All"
+                        # if something more specific was wanted
+                        $writeGroup = $grp[0] if $wgAll and not $writeGroup;
+                        next;
+                    }
+                    next if $lcWant eq lc $grp[2];
+                } elsif ($fam == 7) {
+                    next if IsSameID($$tagInfo{TagID}, $lcWant);
+                } elsif ($fam != 1 and not $$tagInfo{AllowGroup}) {
+                    next if $lcWant eq lc $grp[$fam];
+                    if ($wgAll and not $fam and $allFam0{$lcWant}) {
+                        $writeGroup or $writeGroup = $allFam0{$lcWant};
+                        next;
+                    }
+                    next TAG;   # wrong group
+                }
+                # handle family 1 groups specially
+                if ($grp[0] eq 'EXIF' or $grp[0] eq 'SonyIDC' or $wgAll) {
+                    unless ($ifdName and $lcWant eq lc $ifdName) {
+                        next TAG unless $wgAll and not $fam and $allFam0{$lcWant};
+                        $writeGroup = $allFam0{$lcWant} unless $writeGroup;
+                        next;
+                    }
+                    next TAG if $wgAll and $allFam0{$lcWant} and $fam;
+                    # 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') {
+                    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
                     # set specific write group with document number if specified
-                    if ($writeGroup =~ /^MIE\d+$/ and $tagInfo->{Table}{WRITE_GROUP}) {
-                        $writeGroup = $tagInfo->{Table}{WRITE_GROUP};
+                    if ($writeGroup =~ /^MIE\d+$/ and $$tagInfo{Table}{WRITE_GROUP}) {
+                        $writeGroup = $$tagInfo{Table}{WRITE_GROUP};
                         $writeGroup =~ s/^MIE/$mieGroup/;
                     }
-                } elsif (not $$tagInfo{AllowGroup} or $wantGroup !~ /^$$tagInfo{AllowGroup}$/i) {
+                } elsif (not $$tagInfo{AllowGroup} or $lcWant !~ /^$$tagInfo{AllowGroup}$/i) {
                     # allow group1 name to be specified
-                    my $grp1 = $self->GetGroup($tagInfo, 1);
-                    unless ($grp1 and lc($grp1) eq $lcWant) {
-                        # must also check group1 name directly in case it is different
-                        $grp1 = $tagInfo->{Groups}{1};
-                        next unless $grp1 and lc($grp1) eq $lcWant;
-                    }
-                }
-            }
-            $priority = 1000;   # highest priority since group was specified
+                    next TAG unless $lcWant eq lc $grp[1];
+                }
+            }
+            $writeGroup or $writeGroup = ($$tagInfo{WriteGroup} || $$tagInfo{Table}{WRITE_GROUP} || $grp[0]);
+            $priority = $hiPri; # highest priority since group was specified
         }
         ++$foundMatch;
         # must do a dummy call to the write proc to autoload write package
         # before checking Writable flag
-        my $table = $tagInfo->{Table};
-        my $writeProc = $table->{WRITE_PROC};
+        my $table = $$tagInfo{Table};
+        my $writeProc = $$table{WRITE_PROC};
         # load source table if this was a user-defined table
         if ($$table{SRC_TABLE}) {
@@ -482,13 +683,18 @@
             $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
+        my $writable = $$tagInfo{Writable};
+        next unless $writable or ($$table{WRITABLE} and
             not defined $writable and not $$tagInfo{SubDirectory});
         # set specific write group (if we didn't already)
-        if (not $writeGroup or $translateWriteGroup{$writeGroup}) {
+        if (not $writeGroup or ($translateWriteGroup{$writeGroup} and
+            (not $$tagInfo{WriteGroup} or $$tagInfo{WriteGroup} ne 'All')))
+        {
             # use default write group
-            $writeGroup = $tagInfo->{WriteGroup} || $tagInfo->{Table}{WRITE_GROUP};
+            $writeGroup = $$tagInfo{WriteGroup} || $$tagInfo{Table}{WRITE_GROUP};
             # use group 0 name if no WriteGroup specified
             my $group0 = $self->GetGroup($tagInfo, 0);
@@ -496,13 +702,17 @@
             # get priority for this group
             unless ($priority) {
-                $priority = $self->{WRITE_PRIORITY}{lc($writeGroup)};
+                $priority = $$self{WRITE_PRIORITY}{lc($writeGroup)};
                 unless ($priority) {
-                    $priority = $self->{WRITE_PRIORITY}{lc($group0)} || 0;
-                }
-            }
+                    $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
-        if ($tagInfo->{Protected}) {
-            my $prot = $tagInfo->{Protected} & ~$protected;
+        my $prot = $$tagInfo{Protected};
+        $prot = 1 if $noFlat and defined $$tagInfo{Flat};
+        if ($prot) {
+            $prot &= ~$protected;
             if ($prot) {
                 my %lkup = ( 1=>'unsafe', 2=>'protected', 3=>'unsafe and protected');
@@ -510,5 +720,5 @@
                 if ($verbose > 1) {
                     my $wgrp1 = $self->GetWriteGroup1($tagInfo, $writeGroup);
-                    print $out "Not writing $wgrp1:$tag ($wasProtected)\n";
+                    print $out "Sorry, $wgrp1:$tag is $wasProtected for writing\n";
                 }
                 next;
@@ -517,13 +727,15 @@
         # set priority for this tag
         $tagPriority{$tagInfo} = $priority;
-        if ($priority > $highestPriority) {
-            $highestPriority = $priority;
-            %preferred = ( $tagInfo => 1 );
-            $avoid = 0;
-            ++$avoid if $$tagInfo{Avoid};
-        } elsif ($priority == $highestPriority) {
+        # 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 };
+            $avoid{$lcTag} = $$tagInfo{Avoid} ? 1 : 0;
+        } elsif ($priority == $highestPriority{$lcTag}) {
             # create all tags with highest priority
-            $preferred{$tagInfo} = 1;
-            ++$avoid if $$tagInfo{Avoid};
+            $preferred{$lcTag}{$tagInfo} = 1;
+            ++$avoid{$lcTag} if $$tagInfo{Avoid};
         }
         if ($$tagInfo{WriteAlso}) {
@@ -533,7 +745,12 @@
             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;
@@ -541,36 +758,46 @@
     unshift @tagInfoList, @writeAlsoList if @writeAlsoList;
 
-    # don't create tags with priority 0 if group priorities are set
-    if ($highestPriority == 0 and %{$self->{WRITE_PRIORITY}}) {
-        undef %preferred;
-    }
-    # avoid creating tags with 'Avoid' flag set if there are other alternatives
-    if ($avoid and %preferred) {
-        if ($avoid < scalar(keys %preferred)) {
-            # just remove the 'Avoid' tags since there are other preferred tags
-            foreach $tagInfo (@tagInfoList) {
-                delete $preferred{$tagInfo} if $$tagInfo{Avoid};
-            }
-        } elsif ($highestPriority < 1000) {
-            # look for another priority tag to create instead
-            my $nextHighest = 0;
-            my @nextBestTags;
-            foreach $tagInfo (@tagInfoList) {
-                my $priority = $tagPriority{$tagInfo} or next;
-                next if $priority == $highestPriority;
-                next if $priority < $nextHighest;
-                next if $$tagInfo{Avoid} or $$tagInfo{Permanent};
-                next if $writeGroup{$tagInfo} eq 'MakerNotes';
-                if ($nextHighest < $priority) {
-                    $nextHighest = $priority;
-                    undef @nextBestTags;
-                }
-                push @nextBestTags, $tagInfo;
-            }
-            if (@nextBestTags) {
-                # change our preferred tags to the next best tags
-                undef %preferred;
-                foreach $tagInfo (@nextBestTags) {
-                    $preferred{$tagInfo} = 1;
+    # check priorities for each set of tags we are writing
+    my $lcTag;
+    foreach $lcTag (keys %preferred) {
+        # don't create tags with priority 0 if group priorities are set
+        if ($preferred{$lcTag} and $highestPriority{$lcTag} == 0 and
+            %{$$self{WRITE_PRIORITY}})
+        {
+            delete $preferred{$lcTag}
+        }
+        # avoid creating tags with 'Avoid' flag set if there are other alternatives
+        if ($avoid{$lcTag} and $preferred{$lcTag}) {
+            if ($avoid{$lcTag} < scalar(keys %{$preferred{$lcTag}})) {
+                # just remove the 'Avoid' tags since there are other preferred tags
+                foreach $tagInfo (@tagInfoList) {
+                    next unless $lcTag eq lc $$tagInfo{Name};
+                    delete $preferred{$lcTag}{$tagInfo} if $$tagInfo{Avoid};
+                }
+            } elsif ($highestPriority{$lcTag} < 1000) {
+                # look for another priority tag to create instead
+                my $nextHighest = 0;
+                my @nextBestTags;
+                foreach $tagInfo (@tagInfoList) {
+                    next unless $lcTag eq lc $$tagInfo{Name};
+                    my $priority = $tagPriority{$tagInfo} or next;
+                    next if $priority == $highestPriority{$lcTag};
+                    next if $priority < $nextHighest;
+                    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;
+                        undef @nextBestTags;
+                    }
+                    push @nextBestTags, $tagInfo;
+                }
+                if (@nextBestTags) {
+                    # change our preferred tags to the next best tags
+                    delete $preferred{$lcTag};
+                    foreach $tagInfo (@nextBestTags) {
+                        $preferred{$lcTag}{$tagInfo} = 1;
+                    }
                 }
             }
@@ -592,15 +819,25 @@
         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 proper case for tag name
+        $tag = $$tagInfo{Name};     # get tag name for warnings
+        my $lcTag = lc $tag;
+        my $pref = $preferred{$lcTag} || { };
         my $shift = $options{Shift};
+        my $addValue = $options{AddValue};
         if (defined $shift) {
-            # (can't currently shift List-type tags)
-            if ($tagInfo->{Shift} and not $tagInfo->{List}) {
+            # (can't currently shift list-type tags)
+            my $shiftable;
+            if ($$tagInfo{List}) {
+                $shiftable = '';    # can add/delete but not shift
+            } else {
+                $shiftable = $$tagInfo{Shift};
                 unless ($shift) {
                     # set shift according to AddValue/DelValue
-                    $shift = 1 if $options{AddValue};
-                    $shift = -1 if $options{DelValue};
+                    $shift = 1 if $addValue;
+                    # can shift a date/time with -=, but this is
+                    # a conditional delete operation for other tags
+                    $shift = -1 if $options{DelValue} and defined $shiftable and $shiftable eq 'Time';
                 }
                 if ($shift and (not defined $value or not length $value)) {
@@ -611,5 +848,10 @@
                     undef $shift;
                 }
-            } elsif ($shift) {
+            }
+                # can't shift List-type tag
+            if ((defined $shiftable and not $shiftable) and
+                # and don't try to conditionally delete if Shift is "0"
+                ($shift or ($shiftable eq '0' and $options{DelValue})))
+            {
                 $err = "$wgrp1:$tag is not shiftable";
                 $verbose > 2 and print $out "$err\n";
@@ -620,17 +862,29 @@
         if (defined $val) {
             # check to make sure this is a List or Shift tag if adding
-            if ($options{AddValue} and not ($shift or $tagInfo->{List})) {
-                $err = "Can't add $wgrp1:$tag (not a List type)";
-                $verbose > 2 and print $out "$err\n";
-                next;
+            if ($addValue and not ($shift or $$tagInfo{List})) {
+                if ($addValue eq '2') {
+                    undef $addValue;    # quietly reset this option
+                } else {
+                    $err = "Can't add $wgrp1:$tag (not a List type)";
+                    $verbose > 2 and print $out "$err\n";
+                    next;
+                }
             }
             if ($shift) {
-                # add '+' or '-' prefix to indicate shift direction
-                $val = ($shift > 0 ? '+' : '-') . $val;
-                # check the shift for validity
-                require 'Image/ExifTool/Shift.pl';
-                my $err2 = CheckShift($tagInfo->{Shift}, $val);
-                if ($err2) {
-                    $err = "$err2 for $wgrp1:$tag";
+                if ($$tagInfo{Shift} and $$tagInfo{Shift} eq 'Time') {
+                    # add '+' or '-' prefix to indicate shift direction
+                    $val = ($shift > 0 ? '+' : '-') . $val;
+                    # check the shift for validity
+                    require 'Image/ExifTool/Shift.pl';
+                    my $err2 = CheckShift($$tagInfo{Shift}, $val);
+                    if ($err2) {
+                        $err = "$err2 for $wgrp1:$tag";
+                        $verbose > 2 and print $out "$err\n";
+                        next;
+                    }
+                } elsif (IsFloat($val)) {
+                    $val *= $shift;
+                } else {
+                    $err = "Shift value for $wgrp1:$tag is not a number";
                     $verbose > 2 and print $out "$err\n";
                     next;
@@ -645,4 +899,5 @@
             }
         } 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}) {
@@ -652,22 +907,35 @@
                 $val = '';
             }
-        } elsif ($options{AddValue} or $options{DelValue}) {
+        } elsif ($addValue or $options{DelValue}) {
             $err = "No value to add or delete in $wgrp1:$tag";
             $verbose > 2 and print $out "$err\n";
             next;
         } else {
-            if ($tagInfo->{DelCheck}) {
+            if ($$tagInfo{DelCheck}) {
                 #### eval DelCheck ($self, $tagInfo, $wantGroup)
-                my $err2 = eval $tagInfo->{DelCheck};
+                my $err2 = eval $$tagInfo{DelCheck};
                 $@ and warn($@), $err2 = 'Error evaluating DelCheck';
-                if ($err2) {
+                if (defined $err2) {
+                    # (allow other tags to be set using DelCheck as a hook)
+                    $err2 or goto WriteAlso; # GOTO!
                     $err2 .= ' for' unless $err2 =~ /delete$/;
                     $err = "$err2 $wgrp1:$tag";
                     $verbose > 2 and print $out "$err\n";
                     next;
-                } elsif (defined $err2) {
-                    ++$numSet;  # (allow other tags to be set using DelCheck as a hook)
-                    goto WriteAlso;
-                }
+                }
+            }
+            # 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
@@ -677,13 +945,11 @@
         unless ($noConv) {
             # set default conversion type used by ConvInv() and CHECK_PROC routines
-            $$self{ConvType} = $options{Type} || ($self->{OPTIONS}{PrintConv} ? 'PrintConv' : 'ValueConv');
+            $$self{ConvType} = $convType;
             my $e;
-            ($val,$e) = $self->ConvInv($val, $tagInfo, $tag, $wgrp1, $$self{ConvType}, $wantGroup);
+            ($val,$e) = $self->ConvInv($val,$tagInfo,$tag,$wgrp1,$$self{ConvType},$wantGroup);
             if (defined $e) {
-                if ($e) {
-                    ($err = $e) =~ s/\$wgrp1/$wgrp1/g;
-                } else {
-                    ++$numSet;  # an empty error string causes error to be ignored
-                }
+                # empty error string causes error to be ignored without setting the value
+                $e or goto WriteAlso; # GOTO!
+                $err = $e;
             }
         }
@@ -694,13 +960,18 @@
             $val = 'xxx never delete xxx';
         }
-        $self->{NEW_VALUE} or $self->{NEW_VALUE} = { };
+        $$self{NEW_VALUE} or $$self{NEW_VALUE} = { };
         if ($options{Replace}) {
             # delete the previous new value
-            $self->GetNewValueHash($tagInfo, $writeGroup, 'delete');
+            $self->GetNewValueHash($tagInfo, $writeGroup, 'delete', $options{ProtectSaved});
             # also delete related tag previous new values
             if ($$tagInfo{WriteAlso}) {
-                my $wtag;
+                my ($wgrp, $wtag);
+                if ($$tagInfo{WriteGroup} and $$tagInfo{WriteGroup} eq 'All' and $writeGroup) {
+                    $wgrp = $writeGroup . ':';
+                } else {
+                    $wgrp = '';
+                }
                 foreach $wtag (keys %{$$tagInfo{WriteAlso}}) {
-                    my ($n,$e) = $self->SetNewValue($wtag, undef, Replace=>2);
+                    my ($n,$e) = $self->SetNewValue($wgrp . $wtag, undef, Replace=>2);
                     $numSet += $n;
                 }
@@ -711,24 +982,33 @@
         if (defined $val) {
             # we are editing this tag, so create a NEW_VALUE hash entry
-            my $nvHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');
-            $nvHash->{WantGroup} = $wantGroup;
+            my $nvHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create',
+                                $options{ProtectSaved}, ($options{DelValue} and not $shift));
+            # ignore new values protected with ProtectSaved
+            $nvHash or ++$numSet, next; # (increment $numSet to avoid warning)
+            $$nvHash{NoReplace} = 1 if $$tagInfo{List} and not $options{Replace};
+            $$nvHash{WantGroup} = $wantGroup;
+            $$nvHash{EditOnly} = 1 if $editOnly;
             # save maker note information if writing maker notes
             if ($$tagInfo{MakerNotes}) {
-                $nvHash->{MAKER_NOTE_FIXUP} = $self->{MAKER_NOTE_FIXUP};
-            }
-            if ($options{DelValue} or $options{AddValue} or $shift) {
+                $$nvHash{MAKER_NOTE_FIXUP} = $$self{MAKER_NOTE_FIXUP};
+            }
+            if ($createOnly) {  # create only (never edit)
+                # empty item in DelValue list to never edit existing value
+                $$nvHash{DelValue} = [ '' ];
+                $$nvHash{CreateOnly} = 1;
+            } elsif ($options{DelValue} or $addValue or $shift) {
                 # flag any AddValue or DelValue by creating the DelValue list
-                $nvHash->{DelValue} or $nvHash->{DelValue} = [ ];
+                $$nvHash{DelValue} or $$nvHash{DelValue} = [ ];
                 if ($shift) {
                     # add shift value to list
-                    $nvHash->{Shift} = $val;
+                    $$nvHash{Shift} = $val;
                 } elsif ($options{DelValue}) {
                     # don't create if we are replacing a specific value
-                    $nvHash->{IsCreating} = 0 unless $val eq '' or $tagInfo->{List};
+                    $$nvHash{IsCreating} = 0 unless $val eq '' or $$tagInfo{List};
                     # add delete value to list
-                    push @{$nvHash->{DelValue}}, ref $val eq 'ARRAY' ? @$val : $val;
+                    push @{$$nvHash{DelValue}}, ref $val eq 'ARRAY' ? @$val : $val;
                     if ($verbose > 1) {
                         my $verb = $permanent ? 'Replacing' : 'Deleting';
-                        my $fromList = $tagInfo->{List} ? ' from list' : '';
+                        my $fromList = $$tagInfo{List} ? ' from list' : '';
                         my @vals = (ref $val eq 'ARRAY' ? @$val : $val);
                         foreach (@vals) {
@@ -737,5 +1017,5 @@
                                 $_ = Image::ExifTool::XMP::SerializeStruct($_);
                             }
-                            print $out "$verb $wgrp1:$tag$fromList if value is '$_'\n";
+                            print $out "$verb $wgrp1:$tag$fromList if value is '${_}'\n";
                         }
                     }
@@ -745,57 +1025,76 @@
             # (will only create the priority tag if it doesn't exist,
             #  others get changed only if they already exist)
-            if ($preferred{$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
-                    $nvHash->{IsCreating} = 0;
-                } elsif (($tagInfo->{List} and not $options{DelValue}) or
-                         not ($nvHash->{DelValue} and @{$nvHash->{DelValue}}) or
+                    $$nvHash{IsCreating} = 0;
+                } elsif (($$tagInfo{List} and not $options{DelValue}) or
+                         not ($$nvHash{DelValue} and @{$$nvHash{DelValue}}) or
                          # also create tag if any DelValue value is empty ('')
-                         grep(/^$/,@{$nvHash->{DelValue}}))
+                         grep(/^$/,@{$$nvHash{DelValue}}))
                 {
-                    $nvHash->{IsCreating} = $options{EditOnly} ? 0 : ($options{EditGroup} ? 2 : 1);
+                    $$nvHash{IsCreating} = $editOnly ? 0 : ($editGroup ? 2 : 1);
                     # add to hash of groups where this tag is being created
                     $createGroups or $createGroups = $options{CreateGroups} || { };
                     $$createGroups{$self->GetGroup($tagInfo, 0)} = 1;
-                    $nvHash->{CreateGroups} = $createGroups;
-                }
-            }
-            if (%{$self->{DEL_GROUP}} and $nvHash->{IsCreating}) {
-                my ($grp, @grps);
-                foreach $grp (keys %{$self->{DEL_GROUP}}) {
-                    next if $self->{DEL_GROUP}{$grp} == 2;
-                    # set flag indicating tags were written after this group was deleted
-                    $self->{DEL_GROUP}{$grp} = 2;
-                    push @grps, $grp;
-                }
-                if ($verbose > 1 and @grps) {
-                    @grps = sort @grps;
-                    print $out "  Writing new tags after deleting groups: @grps\n";
-                }
+                    $$nvHash{CreateGroups} = $createGroups;
+                }
+            }
+            if ($$nvHash{IsCreating}) {
+                if (%{$$self{DEL_GROUP}}) {
+                    my ($grp, @grps);
+                    foreach $grp (keys %{$$self{DEL_GROUP}}) {
+                        next if $$self{DEL_GROUP}{$grp} == 2;
+                        # set flag indicating tags were written after this group was deleted
+                        $$self{DEL_GROUP}{$grp} = 2;
+                        push @grps, $grp;
+                    }
+                    if ($verbose > 1 and @grps) {
+                        @grps = sort @grps;
+                        print $out "  Writing new tags after deleting groups: @grps\n";
+                    }
+                }
+            } elsif ($createOnly) {
+                $noCreate = $permanent ? 'permanent' : ($$tagInfo{Avoid} ? 'avoided' : '');
+                $noCreate or $noCreate = $shift ? 'shifting' : 'not preferred';
+                $verbose > 2 and print $out "Not creating $wgrp1:$tag ($noCreate)\n";
+                next;   # nothing to do (not creating and not editing)
             }
             if ($shift or not $options{DelValue}) {
-                $nvHash->{Value} or $nvHash->{Value} = [ ];
-                if (not $tagInfo->{List}) {
+                $$nvHash{Value} or $$nvHash{Value} = [ ];
+                if (not $$tagInfo{List}) {
                     # not a List tag -- overwrite existing value
-                    $nvHash->{Value}[0] = $val;
+                    $$nvHash{Value}[0] = $val;
+                } elsif (defined $$nvHash{AddBefore} and @{$$nvHash{Value}} >= $$nvHash{AddBefore}) {
+                    # values from a later argument have been added (ie. Replace=0)
+                    # to this list, so the new values should come before these
+                    splice @{$$nvHash{Value}}, -$$nvHash{AddBefore}, 0, ref $val eq 'ARRAY' ? @$val : $val;
                 } else {
-                    # add to existing list
-                    push @{$nvHash->{Value}}, ref $val eq 'ARRAY' ? @$val : $val;
+                    # add at end of existing list
+                    push @{$$nvHash{Value}}, ref $val eq 'ARRAY' ? @$val : $val;
                 }
                 if ($verbose > 1) {
-                    my $ifExists = $nvHash->{IsCreating} ?
-                                  ($nvHash->{IsCreating} == 2 ? " if $writeGroup exists" : '') :
-                                  (($nvHash->{DelValue} and @{$nvHash->{DelValue}}) ?
-                                   ' if tag was deleted' : ' if tag exists');
-                    my $verb = ($shift ? 'Shifting' : ($options{AddValue} ? 'Adding' : 'Writing'));
+                    my $ifExists = $$nvHash{IsCreating} ? ( $createOnly ?
+                                  ($$nvHash{IsCreating} == 2 ?
+                                    " if $writeGroup exists and tag doesn't" :
+                                    " if tag doesn't exist") :
+                                  ($$nvHash{IsCreating} == 2 ? " if $writeGroup exists" : '')) :
+                                  (($$nvHash{DelValue} and @{$$nvHash{DelValue}}) ?
+                                    ' if tag was deleted' : ' if tag exists');
+                    my $verb = ($shift ? 'Shifting' : ($addValue ? 'Adding' : 'Writing'));
                     print $out "$verb $wgrp1:$tag$ifExists\n";
                 }
             }
         } elsif ($permanent) {
-            $err = "Can't delete $wgrp1:$tag";
+            $err = "Can't delete Permanent tag $wgrp1:$tag";
             $verbose > 1 and print $out "$err\n";
             next;
-        } elsif ($options{AddValue} or $options{DelValue}) {
+        } elsif ($addValue or $options{DelValue}) {
             $verbose > 1 and print $out "Adding/Deleting nothing does nothing\n";
             next;
@@ -804,34 +1103,44 @@
             $self->GetNewValueHash($tagInfo, $writeGroup, 'delete');
             my $nvHash = $self->GetNewValueHash($tagInfo, $writeGroup, 'create');
-            $nvHash->{WantGroup} = $wantGroup;
+            $$nvHash{WantGroup} = $wantGroup;
             $verbose > 1 and print $out "Deleting $wgrp1:$tag\n";
         }
+        $$setTags{$tagInfo} = 1 if $setTags;
+        $prioritySet = 1 if $$pref{$tagInfo};
+WriteAlso:
         ++$numSet;
-        $$setTags{$tagInfo} = 1 if $setTags;
-        $prioritySet = 1 if $preferred{$tagInfo};
-WriteAlso:
         # also write related tags
         my $writeAlso = $$tagInfo{WriteAlso};
         if ($writeAlso) {
-            my ($wtag, $n);
+            my ($wgrp, $wtag, $n);
+            if ($$tagInfo{WriteGroup} and $$tagInfo{WriteGroup} eq 'All' and $writeGroup) {
+                $wgrp = $writeGroup . ':';
+            } else {
+                $wgrp = '';
+            }
             local $SIG{'__WARN__'} = \&SetWarning;
             foreach $wtag (keys %$writeAlso) {
                 my %opts = (
                     Type => 'ValueConv',
-                    Protected => $protected | 0x02,
-                    AddValue => $options{AddValue},
-                    DelValue => $options{DelValue},
-                    CreateGroups => $createGroups,
-                    SetTags => \%alsoWrote, # remember tags already written
+                    Protected   => $protected | 0x02,
+                    AddValue    => $addValue,
+                    DelValue    => $options{DelValue},
+                    Shift       => $options{Shift},
+                    Replace     => $options{Replace},   # handle lists properly
+                    CreateGroups=> $createGroups,
+                    SetTags     => \%alsoWrote,         # remember tags already written
                 );
                 undef $evalWarning;
                 #### eval WriteAlso ($val)
-                my $v = eval $writeAlso->{$wtag};
+                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($wtag, $v, %opts);
+                    ($n,$evalWarning) = $self->SetNewValue($wgrp . $wtag, $v, %opts);
                     $numSet += $n;
                     # count this as being set if any related tag is set
-                    $prioritySet = 1 if $n and $preferred{$tagInfo};
+                    $prioritySet = 1 if $n and $$pref{$tagInfo};
                 }
                 if ($evalWarning and (not $err or $verbose > 2)) {
@@ -851,14 +1160,35 @@
         warn "$err\n" if $err and not wantarray;
     } elsif (not $numSet) {
-        my $pre = $wantGroup ? ($ifdName || $wantGroup) . ':' : '';
+        my $pre = $wantGroup ? $wantGroup . ':' : '';
         if ($wasProtected) {
-            $err = "Tag '$pre$tag' is $wasProtected for writing";
-        } elsif ($foundMatch) {
-            $err = "Sorry, $pre$tag is not writable";
-        } else {
-            $err = "Tag '$pre$tag' does not exist";
-        }
-        $verbose > 2 and print $out "$err\n";
-        warn "$err\n" unless wantarray;
+            $verbose = 0;   # we already printed this verbose message
+            unless ($options{Replace} and $options{Replace} == 2) {
+                $err = "Sorry, $pre$tag is $wasProtected for writing";
+            }
+        } elsif (not $listOnly) {
+            if ($origTag =~ /[?*]/) {
+                if ($noCreate) {
+                    $err = "No tags matching 'pre${origTag}' will be created";
+                    $verbose = 0;   # (already printed)
+                } elsif ($foundMatch) {
+                    $err = "Sorry, no writable tags matching '$pre${origTag}'";
+                } else {
+                    $err = "No matching tags for '$pre${origTag}'";
+                }
+            } elsif ($noCreate) {
+                $err = "Not creating $pre$tag";
+                $verbose = 0;   # (already printed)
+            } elsif ($foundMatch) {
+                $err = "Sorry, $pre$tag is not writable";
+            } elsif ($wantGroup and @matchingTags) {
+                $err = "Sorry, $pre$tag doesn't exist or isn't writable";
+            } else {
+                $err = "Tag '$pre${tag}' is not defined";
+            }
+        }
+        if ($err) {
+            $verbose > 2 and print $out "$err\n";
+            warn "$err\n" unless wantarray;
+        }
     } elsif ($$self{CHECK_WARN}) {
         $err = $$self{CHECK_WARN};
@@ -888,5 +1218,5 @@
     local $_;
     my ($self, $srcFile, @setTags) = @_;
-    my $key;
+    my ($key, $tag, @exclude, @reqTags);
 
     # get initial SetNewValuesFromFile options
@@ -895,5 +1225,5 @@
         $_ = shift @setTags;
         foreach $key (keys %$_) {
-            $opts{$key} = $_->{$key};
+            $opts{$key} = $$_{$key};
         }
     }
@@ -901,7 +1231,14 @@
     @setTags and ExpandShortcuts(\@setTags);
     my $srcExifTool = new Image::ExifTool;
-    my $options = $self->{OPTIONS};
+    # set flag to indicate we are being called from inside SetNewValuesFromFile()
+    $$srcExifTool{TAGS_FROM_FILE} = 1;
+    # synchronize and increment the file sequence number
+    $$srcExifTool{FILE_SEQUENCE} = $$self{FILE_SEQUENCE}++;
     # set options for our extraction tool
-    $srcExifTool->{TAGS_FROM_FILE} = 1;
+    my $options = $$self{OPTIONS};
+    # copy both structured and flattened tags by default (but flattened tags are "unsafe")
+    my $structOpt = defined $$options{Struct} ? $$options{Struct} : 2;
+    # copy structures only if no tags specified (since flattened tags are "unsafe")
+    $structOpt = 1 if $structOpt eq '2' and not @setTags;
     # +------------------------------------------+
     # ! DON'T FORGET!!  Must consider each new   !
@@ -909,30 +1246,77 @@
     # +------------------------------------------+
     $srcExifTool->Options(
-        Binary      => 1,
-        Charset     => $$options{Charset},
-        CharsetID3  => $$options{CharsetID3},
-        CharsetIPTC => $$options{CharsetIPTC},
-        CharsetPhotoshop => $$options{CharsetPhotoshop},
-        Composite   => $$options{Composite},
-        CoordFormat => $$options{CoordFormat} || '%d %d %.8f', # copy coordinates at high resolution unless otherwise specified
-        DateFormat  => $$options{DateFormat},
-        Duplicates  => 1,
-        Escape      => $$options{Escape},
+        Binary          => 1,
+        Charset         => $$options{Charset},
+        CharsetEXIF     => $$options{CharsetEXIF},
+        CharsetFileName => $$options{CharsetFileName},
+        CharsetID3      => $$options{CharsetID3},
+        CharsetIPTC     => $$options{CharsetIPTC},
+        CharsetPhotoshop=> $$options{CharsetPhotoshop},
+        Composite       => $$options{Composite},
+        CoordFormat     => $$options{CoordFormat} || '%d %d %.8f', # copy coordinates at high resolution unless otherwise specified
+        DateFormat      => $$options{DateFormat},
+        Duplicates      => 1,
+        Escape          => $$options{Escape},
+      # Exclude (set below)
+        ExtendedXMP     => $$options{ExtendedXMP},
         ExtractEmbedded => $$options{ExtractEmbedded},
-        FastScan    => $$options{FastScan},
-        FixBase     => $$options{FixBase},
-        IgnoreMinorErrors => $$options{IgnoreMinorErrors},
-        Lang        => $$options{Lang},
-        LargeFileSupport => $$options{LargeFileSupport},
-        List        => 1,
-        MakerNotes  => 1,
+        FastScan        => $$options{FastScan},
+        Filter          => $$options{Filter},
+        FixBase         => $$options{FixBase},
+        GlobalTimeShift => $$options{GlobalTimeShift},
+        HexTagIDs       => $$options{HexTagIDs},
+        IgnoreMinorErrors=>$$options{IgnoreMinorErrors},
+        Lang            => $$options{Lang},
+        LargeFileSupport=> $$options{LargeFileSupport},
+        List            => 1,
+        ListItem        => $$options{ListItem},
+        ListSep         => $$options{ListSep},
+        MakerNotes      => $$options{FastScan} && $$options{FastScan} > 1 ? undef : 1,
+        MDItemTags      => $$options{MDItemTags},
         MissingTagValue => $$options{MissingTagValue},
-        Password    => $$options{Password},
-        PrintConv   => $$options{PrintConv},
-        ScanForXMP  => $$options{ScanForXMP},
-        StrictDate  => 1,
-        Struct      => ($$options{Struct} or not defined $$options{Struct}) ? 1 : 0,
-        Unknown     => $$options{Unknown},
+        NoPDFList       => $$options{NoPDFList},
+        Password        => $$options{Password},
+        PrintConv       => $$options{PrintConv},
+        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,
+        SystemTags      => $$options{SystemTags},
+        TimeZone        => $$options{TimeZone},
+        Unknown         => $$options{Unknown},
+        UserParam       => $$options{UserParam},
+        Validate        => $$options{Validate},
+        XAttrTags       => $$options{XAttrTags},
+        XMPAutoConv     => $$options{XMPAutoConv},
     );
+    $$srcExifTool{GLOBAL_TIME_OFFSET} = $$self{GLOBAL_TIME_OFFSET};
+    foreach $tag (@setTags) {
+        next if ref $tag;
+        if ($tag =~ /^-(.*)/) {
+            # avoid extracting tags that are excluded
+            push @exclude, $1;
+            next;
+        }
+        # add specified tags to list of requested tags
+        $_ = $tag;
+        if (/(.+?)\s*(>|<)\s*(.+)/) {
+            if ($2 eq '>') {
+                $_ = $1;
+            } else {
+                $_ = $3;
+                /\$/ and push(@reqTags, /\$\{?(?:[-\w]+:)*([-\w?*]+)/g), next;
+            }
+        }
+        push @reqTags, $2 if /(^|:)([-\w?*]+)#?$/;
+    }
+    if (@exclude) {
+        ExpandShortcuts(\@exclude, 1);
+        $srcExifTool->Options(Exclude => \@exclude);
+    }
+    $srcExifTool->Options(RequestTags => \@reqTags) if @reqTags;
     my $printConv = $$options{PrintConv};
     if ($opts{Type}) {
@@ -948,9 +1332,8 @@
     my $info = $srcExifTool->ImageInfo($srcFile);
     return $info if $$info{Error} and $$info{Error} eq 'Error opening file';
-    delete $srcExifTool->{VALUE}{Error};  # delete so we can check this later
+    delete $$srcExifTool{VALUE}{Error}; # delete so we can check this later
 
     # sort tags in reverse order so we get priority tag last
     my @tags = reverse sort keys %$info;
-    my $tag;
 #
 # simply transfer all tags from source image if no tags specified
@@ -958,10 +1341,10 @@
     unless (@setTags) {
         # transfer maker note information to this object
-        $self->{MAKER_NOTE_FIXUP} = $srcExifTool->{MAKER_NOTE_FIXUP};
-        $self->{MAKER_NOTE_BYTE_ORDER} = $srcExifTool->{MAKER_NOTE_BYTE_ORDER};
+        $$self{MAKER_NOTE_FIXUP} = $$srcExifTool{MAKER_NOTE_FIXUP};
+        $$self{MAKER_NOTE_BYTE_ORDER} = $$srcExifTool{MAKER_NOTE_BYTE_ORDER};
         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});
@@ -969,5 +1352,5 @@
             # 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};
         }
@@ -978,10 +1361,10 @@
 #
     # 1) loop through input list of tags to set, and build @setList
-    my (@setList, $set, %setMatches);
-    foreach (@setTags) {
-        if (ref $_ eq 'HASH') {
+    my (@setList, $set, %setMatches, $t);
+    foreach $t (@setTags) {
+        if (ref $t eq 'HASH') {
             # update current options
-            foreach $key (keys %$_) {
-                $opts{$key} = $_->{$key};
+            foreach $key (keys %$t) {
+                $opts{$key} = $$t{$key};
             }
             next;
@@ -990,6 +1373,6 @@
         # (also use this hash to store expression and wildcard flags, EXPR and WILD)
         my $opts = { %opts };
-        $tag = lc($_);  # change tag/group names to all lower case
-        my ($fam, $grp, $dst, $dstGrp, $dstTag, $isExclude);
+        $tag = lc $t;   # change tag/group names to all lower case
+        my (@fg, $grp, $dst, $dstGrp, $dstTag, $isExclude);
         # handle redirection to another tag
         if ($tag =~ /(.+?)\s*(>|<)\s*(.+)/) {
@@ -998,5 +1381,5 @@
             if ($2 eq '>') {
                 ($tag, $dstTag) = ($1, $3);
-                # flag add and delete (ie. '+<' and '-<') redirections
+                # flag add and delete (eg. '+<' and '-<') redirections
                 $opt = $1 if $tag =~ s/\s*([-+])$// or $dstTag =~ s/^([-+])\s*//;
             } else {
@@ -1005,35 +1388,37 @@
                 # handle expressions
                 if ($tag =~ /\$/) {
-                    $tag = $_;  # restore original case
+                    $tag = $t;  # restore original case
                     # recover leading whitespace (except for initial single space)
                     $tag =~ s/(.+?)\s*(>|<) ?//;
                     $$opts{EXPR} = 1; # flag this expression
-                    $grp = '';
                 } else {
                     $opt = $1 if $tag =~ s/^([-+])\s*//;
                 }
             }
+            # validate tag name(s)
+            $$opts{EXPR} or ValidTagName($tag) or $self->Warn("Invalid tag name '${tag}'"), next;
+            ValidTagName($dstTag) or $self->Warn("Invalid tag name '${dstTag}'"), next;
             # translate '+' and '-' to appropriate SetNewValue option
             if ($opt) {
                 $$opts{{ '+' => 'AddValue', '-' => 'DelValue' }->{$opt}} = 1;
-                $$opts{Shift} = 0;  # shift if this is a date/time tag
+                $$opts{Shift} = 0;  # shift if shiftable
             }
             ($dstGrp, $dstTag) = ($1, $2) if $dstTag =~ /(.*):(.+)/;
             # ValueConv may be specified separately on the destination with '#'
             $$opts{Type} = 'ValueConv' if $dstTag =~ s/#$//;
-            # ignore leading family number
-            $dstGrp = $2 if $dstGrp =~ /^(\d+)(.*)/ and $1 < 2;
-            # replace 'all' with '*' in tag and group names
+            # replace tag name of 'all' with '*'
             $dstTag = '*' if $dstTag eq 'all';
-            $dstGrp = '*' if $dstGrp eq 'all';
         }
         unless ($$opts{EXPR}) {
             $isExclude = ($tag =~ s/^-//);
-            if ($tag =~ /^([-\w]*?|\*):(.+)/) {
+            if ($tag =~ /(.*):(.+)/) {
                 ($grp, $tag) = ($1, $2);
-                # separate leading family number
-                ($fam, $grp) = ($1, $2) if $grp =~ /^(\d+)(.*)/;
-            } else {
-                $grp = '';  # flag for don't care about group
+                foreach (split /:/, $grp) {
+                    # save family/groups in list (ignoring 'all' and '*')
+                    next unless length($_) and /^(\d+)?(.*)/;
+                    my ($f, $g) = ($1, $2);
+                    $f = 7 if $g =~ s/^ID-//i;
+                    push @fg, [ $f, $g ] unless $g eq '*' or $g eq 'all';
+                }
             }
             # allow ValueConv to be specified by a '#' on the tag name
@@ -1044,29 +1429,17 @@
             # replace 'all' with '*' in tag and group names
             $tag = '*' if $tag eq 'all';
-            $grp = '*' if $grp eq 'all';
-            # allow wildcards in tag names
+            # allow wildcards in tag names (handle differently from all tags: '*')
             if ($tag =~ /[?*]/ and $tag ne '*') {
-                $$opts{WILD} = 1;   # set flag indicating wildcards were used
+                $$opts{WILD} = 1;   # set flag indicating wildcards were used in source tag
                 $tag =~ s/\*/[-\\w]*/g;
                 $tag =~ s/\?/[-\\w]/g;
             }
         }
-        # redirect, exclude or set this tag (Note: $grp is '' if we don't care)
+        # redirect, exclude or set this tag (Note: @fg is empty if we don't care about the group)
         if ($dstTag) {
             # redirect this tag
             $isExclude and return { Error => "Can't redirect excluded tag" };
-            if ($dstTag ne '*') {
-                if ($dstTag =~ /[?*]/) {
-                    if ($dstTag eq $tag) {
-                        $dstTag = '*';
-                    } else {
-                        return { Error => "Invalid use of wildcards in destination tag" };
-                    }
-                } elsif ($tag eq '*') {
-                    return { Error => "Can't redirect from all tags to one tag" };
-                }
-            }
             # set destination group the same as source if necessary
-          # (removed in 7.72 so '-xmp:*>*:*' will preserve XMP family 1 groups)
+          # (removed in 7.72 so '-*:*<xmp:*' will preserve XMP family 1 groups)
           # $dstGrp = $grp if $dstGrp eq '*' and $grp;
             # write to specified destination group/tag
@@ -1074,16 +1447,15 @@
         } elsif ($isExclude) {
             # implicitly assume '*' if first entry is an exclusion
-            unshift @setList, [ undef, '*', '*', [ '', '*' ], $opts ] unless @setList;
+            unshift @setList, [ [ ], '*', [ '', '*' ], $opts ] unless @setList;
             # exclude this tag by leaving $dst undefined
         } else {
-            $dst = [ $grp, $$opts{WILD} ? '*' : $tag ]; # copy to same group
-        }
-        $grp or $grp = '*';     # use '*' for any group
+            $dst = [ $grp || '', $$opts{WILD} ? '*' : $tag ]; # use same group name for dest
+        }
         # save in reverse order so we don't set tags before an exclude
-        unshift @setList, [ $fam, $grp, $tag, $dst, $opts ];
+        unshift @setList, [ \@fg, $tag, $dst, $opts ];
     }
     # 2) initialize lists of matching tags for each setTag
     foreach $set (@setList) {
-        $$set[3] and $setMatches{$set} = [ ];
+        $$set[2] and $setMatches{$set} = [ ];
     }
     # 3) loop through all tags in source image and save tags matching each setTag
@@ -1098,12 +1470,12 @@
         my $lcTag = lc(GetTagName($tag));
         my (@grp, %grp);
-        foreach $set (@setList) {
+SET:    foreach $set (@setList) {
             # check first for matching tag
-            unless ($$set[2] eq $lcTag or $$set[2] eq '*') {
+            unless ($$set[1] eq $lcTag or $$set[1] eq '*') {
                 # handle wildcards
-                next unless $$set[4]{WILD} and $lcTag =~ /^$$set[2]$/;
+                next unless $$set[3]{WILD} and $lcTag =~ /^$$set[1]$/;
             }
             # then check for matching group
-            unless ($$set[1] eq '*') {
+            if (@{$$set[0]}) {
                 # get lower case group names if not done already
                 unless (@grp) {
@@ -1111,12 +1483,16 @@
                     $grp{$_} = 1 foreach @grp;
                 }
-                # handle leading family number
-                if (defined $$set[0]) {
-                    next unless $grp[$$set[0]] and $$set[1] eq $grp[$$set[0]];
-                } else {
-                    next unless $grp{$$set[1]};
-                }
-            }
-            last unless $$set[3];   # all done if we hit an exclude
+                foreach (@{$$set[0]}) {
+                    my ($f, $g) = @$_;
+                    if (not defined $f) {
+                        next SET unless $grp{$g};
+                    } elsif ($f == 7) {
+                        next SET unless IsSameID($srcExifTool->GetTagID($tag), $g);
+                    } else {
+                        next SET unless defined $grp[$f] and $g eq $grp[$f];
+                    }
+                }
+            }
+            last unless $$set[2];   # all done if we hit an exclude
             # add to the list of tags matching this setTag
             push @{$setMatches{$set}}, $tag;
@@ -1126,17 +1502,17 @@
     foreach $set (reverse @setList) {
         # get options for SetNewValue
-        my $opts = $$set[4];
+        my $opts = $$set[3];
         # handle expressions
         if ($$opts{EXPR}) {
-            my $val = $srcExifTool->InsertTagValues(\@tags, $$set[2], 'Error');
-            unless (defined $val) {
-                # return warning if one of the tags didn't exist
-                $tag = NextTagKey(\%rtnInfo, 'Warning');
-                $rtnInfo{$tag} = $srcExifTool->GetValue('Error');
-                delete $srcExifTool->{VALUE}{Error};
-                next;
-            }
-            my ($dstGrp, $dstTag) = @{$$set[3]};
-            $$opts{Protected} = 1;
+            my $val = $srcExifTool->InsertTagValues(\@tags, $$set[1], 'Error');
+            if ($$srcExifTool{VALUE}{Error}) {
+                # pass on any error as a warning
+                $tag = NextFreeTagKey(\%rtnInfo, 'Warning');
+                $rtnInfo{$tag} = $$srcExifTool{VALUE}{Error};
+                delete $$srcExifTool{VALUE}{Error};
+                next unless defined $val;
+            }
+            my ($dstGrp, $dstTag) = @{$$set[2]};
+            $$opts{Protected} = 1 unless $dstTag =~ /[?*]/ and $dstTag ne '*';
             $$opts{Group} = $dstGrp if $dstGrp;
             my @rtnVals = $self->SetNewValue($dstTag, $val, %$opts);
@@ -1151,18 +1527,22 @@
                 $val = $$info{$tag};
             }
-            my ($dstGrp, $dstTag) = @{$$set[3]};
+            my ($dstGrp, $dstTag) = @{$$set[2]};
             if ($dstGrp) {
-                if ($dstGrp eq '*') {
-                    $dstGrp = $srcExifTool->GetGroup($tag, 1);
+                my @dstGrp = split /:/, $dstGrp;
+                # destination group of '*' writes to same group as source tag
+                # (family 1 unless otherwise specified)
+                foreach (@dstGrp) {
+                    next unless /^(\d*)(all|\*)$/i;
+                    $_ = $1 . $srcExifTool->GetGroup($tag, length $1 ? $1 : 1);
                     $noWarn = 1;    # don't warn on wildcard destinations
                 }
-                $$opts{Group} = $dstGrp;
+                $$opts{Group} = join ':', @dstGrp;
             } else {
                 delete $$opts{Group};
             }
             # transfer maker note information if setting this tag
-            if ($srcExifTool->{TAG_INFO}{$tag}{MakerNotes}) {
-                $self->{MAKER_NOTE_FIXUP} = $srcExifTool->{MAKER_NOTE_FIXUP};
-                $self->{MAKER_NOTE_BYTE_ORDER} = $srcExifTool->{MAKER_NOTE_BYTE_ORDER};
+            if ($$srcExifTool{TAG_INFO}{$tag}{MakerNotes}) {
+                $$self{MAKER_NOTE_FIXUP} = $$srcExifTool{MAKER_NOTE_FIXUP};
+                $$self{MAKER_NOTE_BYTE_ORDER} = $$srcExifTool{MAKER_NOTE_BYTE_ORDER};
             }
             if ($dstTag eq '*') {
@@ -1170,11 +1550,27 @@
                 $noWarn = 1;
             }
-            # allow protected tags to be copied if specified explicitly
-            $$opts{Protected} = ($$set[2] eq '*' ? undef : 1);
+            if ($$set[1] eq '*' or $$set[3]{WILD}) {
+                # don't copy from protected binary tags when using wildcards
+                next if $$srcExifTool{TAG_INFO}{$tag}{Protected} and
+                        $$srcExifTool{TAG_INFO}{$tag}{Binary};
+                # don't copy to protected tags when using wildcards
+                delete $$opts{Protected};
+                # don't copy flattened tags if copying structures too when copying all
+                $$opts{NoFlat} = $structOpt eq '2' ? 1 : 0;
+            } else {
+                # allow protected tags to be copied if specified explicitly
+                $$opts{Protected} = 1 unless $dstTag =~ /[?*]/;
+                delete $$opts{NoFlat};
+            }
             # set value(s) for this tag
             my ($rtn, $wrn) = $self->SetNewValue($dstTag, $val, %$opts);
+            # this was added in version 9.14, and allowed actions like "-subject<all" to
+            # write values of multiple tags into a list, but it had the side effect of
+            # duplicating items if there were multiple list tags with the same name
+            # (eg. -use mwg "-creator<creator"), so disable this as of ExifTool 9.36:
+            # $$opts{Replace} = 0;    # accumulate values from tags matching a single argument
             if ($wrn and not $noWarn) {
                 # return this warning
-                $rtnInfo{NextTagKey(\%rtnInfo, 'Warning')} = $wrn;
+                $rtnInfo{NextFreeTagKey(\%rtnInfo, 'Warning')} = $wrn;
                 $noWarn = 1;
             }
@@ -1187,20 +1583,22 @@
 #------------------------------------------------------------------------------
 # 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) 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
 # 3) Tag name is case sensitive and may be prefixed by family 0 or 1 group name
-sub GetNewValues($;$$)
+# 4) Value may have been modified by CHECK_PROC routine after ValueConv
+sub GetNewValue($$;$)
 {
     local $_;
+    my $self = shift;
+    my $tag = shift;
     my $nvHash;
-    if (ref $_[0] eq 'HASH') {
-        $nvHash = shift;
+    if ((ref $tag eq 'HASH' and $$tag{IsNVH}) or not defined $tag) {
+        $nvHash = $tag;
     } else {
-        my ($self, $tag, $newValueHashPt) = @_;
-        if ($self->{NEW_VALUE}) {
+        my $newValueHashPt = shift;
+        if ($$self{NEW_VALUE}) {
             my ($group, $tagInfo);
             if (ref $tag) {
@@ -1212,19 +1610,23 @@
             } else {
                 # separate group from tag name
-                $group = $1 if $tag =~ s/(.*)://;
+                my @groups;
+                @groups = split ':', $1 if $tag =~ s/(.*)://;
                 my @tagInfoList = FindTagInfo($tag);
                 # decide which tag we want
 GNV_TagInfo:    foreach $tagInfo (@tagInfoList) {
                     my $nvh = $self->GetNewValueHash($tagInfo) or next;
-                    # select tag in specified group if necessary
-                    while ($group and $group ne $$nvh{WriteGroup}) {
+                    # select tag in specified group(s) if necessary
+                    foreach (@groups) {
+                        next if $_ eq $$nvh{WriteGroup};
                         my @grps = $self->GetGroup($tagInfo);
                         if ($grps[0] eq $$nvh{WriteGroup}) {
                             # check family 1 group only if WriteGroup is not specific
-                            last if $group eq $grps[1];
+                            next if $_ eq $grps[1];
                         } else {
                             # otherwise check family 0 group
-                            last if $group eq $grps[0];
+                            next if $_ eq $grps[0];
                         }
+                        # also check family 7
+                        next if /^ID-(.*)/i and IsSameID($$tagInfo{TagID}, $1);
                         # step to next entry in list
                         $nvh = $$nvh{Next} or next GNV_TagInfo;
@@ -1232,5 +1634,5 @@
                     $nvHash = $nvh;
                     # give priority to the one we are creating
-                    last if defined $nvHash->{IsCreating};
+                    last if defined $$nvHash{IsCreating};
                 }
             }
@@ -1239,52 +1641,57 @@
         $newValueHashPt and $$newValueHashPt = $nvHash;
     }
-    if ($nvHash and $nvHash->{Value}) {
-        my $vals = $nvHash->{Value};
-        # do inverse raw conversion if necessary
-        if ($nvHash->{TagInfo}{RawConvInv}) {
-            my @copyVals = @$vals;  # modify a copy of the values
-            $vals = \@copyVals;
-            my $tagInfo = $$nvHash{TagInfo};
-            my $conv = $$tagInfo{RawConvInv};
-            my $self = $nvHash->{Self};
-            my ($val, $checkProc);
-            my $table = $tagInfo->{Table};
-            $checkProc = $$table{CHECK_PROC} if $table;
-            local $SIG{'__WARN__'} = \&SetWarning;
-            undef $evalWarning;
-            foreach $val (@$vals) {
-                if (ref($conv) eq 'CODE') {
-                    $val = &$conv($val, $self);
-                } else {
-                    #### eval RawConvInv ($self, $val, $taginfo)
-                    $val = eval $conv;
-                    $@ and $evalWarning = $@;
-                }
-                if ($evalWarning) {
-                    # an empty warning ("\n") ignores tag with no error
-                    if ($evalWarning ne "\n") {
-                        my $err = CleanWarning() . " in $$tagInfo{Name} (RawConvInv)";
-                        $self->Warn($err);
-                    }
-                    @$vals = ();
-                    last;
-                }
-                # must check value now
-                next unless $checkProc;
+    unless ($nvHash and $$nvHash{Value}) {
+        return () if wantarray;  # return empty list
+        return undef;
+    }
+    my $vals = $$nvHash{Value};
+    # do inverse raw conversion if necessary
+    # - must also check after doing a Shift
+    if ($$nvHash{TagInfo}{RawConvInv} or $$nvHash{Shift}) {
+        my @copyVals = @$vals;  # modify a copy of the values
+        $vals = \@copyVals;
+        my $tagInfo = $$nvHash{TagInfo};
+        my $conv = $$tagInfo{RawConvInv};
+        my $table = $$tagInfo{Table};
+        my ($val, $checkProc);
+        $checkProc = $$table{CHECK_PROC} if $$nvHash{Shift} and $table;
+        local $SIG{'__WARN__'} = \&SetWarning;
+        undef $evalWarning;
+        foreach $val (@$vals) {
+            # must check value now if it was shifted
+            if ($checkProc) {
                 my $err = &$checkProc($self, $tagInfo, \$val);
                 if ($err or not defined $val) {
                     $err or $err = 'Error generating raw value';
-                    $self->Warn("$err for $$tagInfo{Name}");
+                    $self->WarnOnce("$err for $$tagInfo{Name}");
                     @$vals = ();
                     last;
                 }
-            }
-        }
-        # return our value(s)
-        return @$vals if wantarray;
-        return $$vals[0];
-    }
-    return () if wantarray;  # return empty list
-    return undef;
+                next unless $conv;
+            } else {
+                last unless $conv;
+            }
+            # do inverse raw conversion
+            if (ref($conv) eq 'CODE') {
+                $val = &$conv($val, $self);
+            } else {
+                #### eval RawConvInv ($self, $val, $tagInfo)
+                $val = eval $conv;
+                $@ and $evalWarning = $@;
+            }
+            if ($evalWarning) {
+                # an empty warning ("\n") ignores tag with no error
+                if ($evalWarning ne "\n") {
+                    my $err = CleanWarning() . " in $$tagInfo{Name} (RawConvInv)";
+                    $self->WarnOnce($err);
+                }
+                @$vals = ();
+                last;
+            }
+        }
+    }
+    # return our value(s)
+    return @$vals if wantarray;
+    return $$vals[0];
 }
 
@@ -1292,29 +1699,25 @@
 # Return the total number of new values set
 # Inputs: 0) ExifTool object reference
-# Returns: Scalar context) Number of new values that have been set
-#          List context) Number of new values, number of "pseudo" values
+# Returns: Scalar context) Number of new values that have been set (incl pseudo)
+#          List context) Number of new values (incl pseudo), number of "pseudo" values
 # ("pseudo" values are those which don't require rewriting the file to change)
 sub CountNewValues($)
 {
     my $self = shift;
-    my $newVal = $self->{NEW_VALUE};
-    my $num = 0;
-    my $tag;
+    my $newVal = $$self{NEW_VALUE};
+    my ($num, $pseudo) = (0, 0);
     if ($newVal) {
-        $num += scalar keys %$newVal;
-        # don't count "fake" tags (only in Extra table)
-        foreach $tag (qw{Geotag Geosync}) {
-            --$num if defined $$newVal{$Image::ExifTool::Extra{$tag}};
-        }
-    }
-    $num += scalar keys %{$self->{DEL_GROUP}};
+        $num = scalar keys %$newVal;
+        my $nv;
+        foreach $nv (values %$newVal) {
+            my $tagInfo = $$nv{TagInfo};
+            # don't count tags that don't write anything
+            $$tagInfo{WriteNothing} and --$num, next;
+            # count the number of pseudo tags included
+            $$tagInfo{WritePseudo} and ++$pseudo;
+        }
+    }
+    $num += scalar keys %{$$self{DEL_GROUP}};
     return $num unless wantarray;
-    my $pseudo = 0;
-    if ($newVal) {
-        # (Note: all writable "pseudo" tags must be found in Extra table)
-        foreach $tag (qw{FileName Directory FileModifyDate}) {
-            ++$pseudo if defined $$newVal{$Image::ExifTool::Extra{$tag}};
-        }
-    }
     return ($num, $pseudo);
 }
@@ -1323,25 +1726,26 @@
 # Save new values for subsequent restore
 # Inputs: 0) ExifTool object reference
+# Returns: Number of times new values have been saved
+# Notes: increments SAVE_COUNT flag each time routine is called
 sub SaveNewValues($)
 {
     my $self = shift;
-    my $newValues = $self->{NEW_VALUE};
+    my $newValues = $$self{NEW_VALUE};
+    my $saveCount = ++$$self{SAVE_COUNT};
     my $key;
     foreach $key (keys %$newValues) {
         my $nvHash = $$newValues{$key};
         while ($nvHash) {
-            $nvHash->{Save} = 1;  # set Save flag
-            $nvHash = $nvHash->{Next};
+            # set Save count if not done already
+            $$nvHash{Save} or $$nvHash{Save} = $saveCount;
+            $nvHash = $$nvHash{Next};
         }
     }
     # initialize hash for saving overwritten new values
-    $self->{SAVE_NEW_VALUE} = { };
+    $$self{SAVE_NEW_VALUE} = { };
     # make a copy of the delete group hash
-    if ($self->{DEL_GROUP}) {
-        my %delGrp = %{$self->{DEL_GROUP}};
-        $self->{SAVE_DEL_GROUP} = \%delGrp;
-    } else {
-        delete $self->{SAVE_DEL_GROUP};
-    }
+    my %delGrp = %{$$self{DEL_GROUP}};
+    $$self{SAVE_DEL_GROUP} = \%delGrp;
+    return $saveCount;
 }
 
@@ -1351,10 +1755,12 @@
 # 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. ie) XMP:Identifier, XMP-dc:Identifier
+# 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;
-    my $newValues = $self->{NEW_VALUE};
-    my $savedValues = $self->{SAVE_NEW_VALUE};
+    my $newValues = $$self{NEW_VALUE};
+    my $savedValues = $$self{SAVE_NEW_VALUE};
     my $key;
     # 1) remove any new values which don't have the Save flag set
@@ -1365,17 +1771,17 @@
             my $nvHash = $$newValues{$key};
             while ($nvHash) {
-                if ($nvHash->{Save}) {
+                if ($$nvHash{Save}) {
                     $lastHash = $nvHash;
                 } else {
                     # remove this entry from the list
                     if ($lastHash) {
-                        $lastHash->{Next} = $nvHash->{Next};
-                    } elsif ($nvHash->{Next}) {
-                        $$newValues{$key} = $nvHash->{Next};
+                        $$lastHash{Next} = $$nvHash{Next};
+                    } elsif ($$nvHash{Next}) {
+                        $$newValues{$key} = $$nvHash{Next};
                     } else {
                         delete $$newValues{$key};
                     }
                 }
-                $nvHash = $nvHash->{Next};
+                $nvHash = $$nvHash{Next};
             }
         }
@@ -1383,52 +1789,65 @@
     # 2) restore saved new values
     if ($savedValues) {
-        $newValues or $newValues = $self->{NEW_VALUE} = { };
+        $newValues or $newValues = $$self{NEW_VALUE} = { };
         foreach $key (keys %$savedValues) {
             if ($$newValues{$key}) {
                 # add saved values to end of list
                 my $nvHash = LastInList($$newValues{$key});
-                $nvHash->{Next} = $$savedValues{$key};
+                $$nvHash{Next} = $$savedValues{$key};
             } else {
                 $$newValues{$key} = $$savedValues{$key};
             }
         }
-        $self->{SAVE_NEW_VALUE} = { };  # reset saved new values
+        $$self{SAVE_NEW_VALUE} = { };  # reset saved new values
     }
     # 3) restore delete groups
-    if ($self->{SAVE_DEL_GROUP}) {
-        my %delGrp = %{$self->{SAVE_DEL_GROUP}};
-        $self->{DEL_GROUP} = \%delGrp;
-    } else {
-        delete $self->{DEL_GROUP};
-    }
-}
-
-#------------------------------------------------------------------------------
-# Set file modification time from FileModifyDate tag
+    my %delGrp = %{$$self{SAVE_DEL_GROUP}};
+    $$self{DEL_GROUP} = \%delGrp;
+}
+
+#------------------------------------------------------------------------------
+# Set filesystem time from from FileModifyDate or FileCreateDate tag
 # Inputs: 0) ExifTool object reference, 1) file name or file ref
-#         2) modify time (-M) of original file (needed for time shift)
+#         2) time (-M or -C) of original file (used for shift; obtained from file if not given)
+#         3) tag name to write (undef for 'FileModifyDate')
+#         4) flag set if argument 2 has already been converted to Unix seconds
 # Returns: 1=time changed OK, 0=nothing done, -1=error setting time
-#          (and increments CHANGED flag if time was changed)
-sub SetFileModifyDate($$;$)
-{
-    my ($self, $file, $originalTime) = @_;
+#          (increments CHANGED flag and sets corresponding WRITTEN tag)
+sub SetFileModifyDate($$;$$$)
+{
+    my ($self, $file, $originalTime, $tag, $isUnixTime) = @_;
     my $nvHash;
-    my $val = $self->GetNewValues('FileModifyDate', \$nvHash);
+    $tag = 'FileModifyDate' unless defined $tag;
+    my $val = $self->GetNewValue($tag, \$nvHash);
     return 0 unless defined $val;
-    my $isOverwriting = IsOverwriting($nvHash);
+    my $isOverwriting = $self->IsOverwriting($nvHash);
     return 0 unless $isOverwriting;
+    # can currently only set creation date on Windows systems
+    # (and Mac now too, but that is handled with the MacOS tags)
+    return 0 if $tag eq 'FileCreateDate' and $^O ne 'MSWin32';
     if ($isOverwriting < 0) {  # are we shifting time?
         # use original time of this file if not specified
-        $originalTime = -M $file unless defined $originalTime;
-        return 0 unless defined $originalTime;
-        return 0 unless IsOverwriting($nvHash, $^T - $originalTime*(24*3600));
-        $val = $nvHash->{Value}[0]; # get shifted value
-    }
-    unless (utime($val, $val, $file)) {
-        $self->Warn('Error setting FileModifyDate');
-        return -1;
-    }
-    ++$self->{CHANGED};
-    $self->VerboseValue('+ FileModifyDate', $val);
+        unless (defined $originalTime) {
+            my ($aTime, $mTime, $cTime) = $self->GetFileTime($file);
+            $originalTime = ($tag eq 'FileCreateDate') ? $cTime : $mTime;
+            return 0 unless defined $originalTime;
+            $isUnixTime = 1;
+        }
+        $originalTime = int($^T - $originalTime*(24*3600) + 0.5) unless $isUnixTime;
+        return 0 unless $self->IsOverwriting($nvHash, $originalTime);
+        $val = $$nvHash{Value}[0]; # get shifted value
+    }
+    my ($aTime, $mTime, $cTime);
+    if ($tag eq 'FileCreateDate') {
+        eval { require Win32::API } or $self->WarnOnce("Install Win32::API to set $tag"), return -1;
+        eval { require Win32API::File } or $self->WarnOnce("Install Win32API::File to set $tag"), return -1;
+        $cTime = $val;
+    } else {
+        $aTime = $mTime = $val;
+    }
+    $self->SetFileTime($file, $aTime, $mTime, $cTime, 1) or $self->Warn("Error setting $tag"), return -1;
+    ++$$self{CHANGED};
+    $$self{WRITTEN}{$tag} = $val;   # remember that we wrote this tag
+    $self->VerboseValue("+ $tag", $val);
     return 1;
 }
@@ -1437,51 +1856,142 @@
 # 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)
+#         2) new name (or undef to build from FileName and Directory tags)
+#         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
 #          (and increments CHANGED flag if filename changed)
 # Notes: Will not overwrite existing file.  Creates directories as necessary.
-sub SetFileName($$;$)
-{
-    my ($self, $file, $newName) = @_;
+sub SetFileName($$;$$$)
+{
+    my ($self, $file, $newName, $opt, $usedFlag) = @_;
     my ($nvHash, $doName, $doDir);
+
+    $opt or $opt = '';
     # determine the new file name
     unless (defined $newName) {
-        my $filename = $self->GetNewValues('FileName', \$nvHash);
-        $doName = 1 if defined $filename and IsOverwriting($nvHash, $file);
-        my $dir = $self->GetNewValues('Directory', \$nvHash);
-        $doDir = 1 if defined $dir and IsOverwriting($nvHash, $file);
-        return 0 unless $doName or $doDir;  # nothing to do
-        if ($doName) {
-            $newName = GetNewFileName($file, $filename);
-            $newName = GetNewFileName($newName, $dir) if $doDir;
+        if ($opt) {
+            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');
+            }
+            return 0 unless defined $newName;
         } else {
-            $newName = GetNewFileName($file, $dir);
-        }
-    }
-    if (-e $newName) {
-        # don't replace existing file
-        $self->Warn("File '$newName' already exists");
-        return -1;
+            my $filename = $self->GetNewValue('FileName', \$nvHash);
+            $doName = 1 if defined $filename and $self->IsOverwriting($nvHash, $file);
+            my $dir = $self->GetNewValue('Directory', \$nvHash);
+            $doDir = 1 if defined $dir and $self->IsOverwriting($nvHash, $file);
+            return 0 unless $doName or $doDir;  # nothing to do
+            if ($doName) {
+                $newName = GetNewFileName($file, $filename);
+                $newName = GetNewFileName($newName, $dir) if $doDir;
+            } else {
+                $newName = GetNewFileName($file, $dir);
+            }
+        }
+    }
+    # validate new file name in Windows
+    if ($^O eq 'MSWin32') {
+        if ($newName =~ /[\0-\x1f<>"|*]/) {
+            $self->Warn('New file name not allowed in Windows (contains reserved characters)');
+            return -1;
+        }
+        if ($newName =~ /:/ and $newName !~ /^[A-Z]:[^:]*$/i) {
+            $self->Warn("New file name not allowed in Windows (contains ':')");
+            return -1;
+        }
+        if ($newName =~ /\?/ and $newName !~ m{^[\\/]{2}\?[\\/][^?]*$}) {
+            $self->Warn("New file name not allowed in Windows (contains '?')");
+            return -1;
+        }
+        if ($newName =~ m{(^|[\\/])(CON|PRN|AUX|NUL|COM[1-9]|LPT[1-9])(\.[^.]*)?$}i) {
+            $self->Warn('New file name not allowed in Windows (reserved device name)');
+            return -1;
+        }
+        if ($newName =~ /([. ])$/) {
+            $self->Warn("New file name not recommended for Windows (ends with '${1}')", 2) and return -1;
+        }
+        if (length $newName > 259 and $newName !~ /\?/) {
+            $self->Warn('New file name not recommended for Windows (exceeds 260 chars)', 2) and return -1;
+        }
+    } else {
+        $newName =~ tr/\0//d;   # make sure name doesn't contain nulls
+    }
+    # protect against empty file name
+    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 =~ /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;
+        }
+    }
+    if ($opt eq 'Test') {
+        my $out = $$self{OPTIONS}{TextOut};
+        print $out "'${file}' --> '${newName}'\n";
+        return 1;
     }
     # create directory for new file if necessary
     my $result;
-    if (($result = CreateDirectory($newName)) != 0) {
+    if (($result = $self->CreateDirectory($newName)) != 0) {
         if ($result < 0) {
-            $self->Warn("Error creating directory for '$newName'");
+            $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 'HardLink' or $opt eq 'Link') {
+        unless (link $file, $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 (rename $file, $newName) {
+    unless ($self->Rename($file, $newName)) {
         local (*EXIFTOOL_SFN_IN, *EXIFTOOL_SFN_OUT);
         # renaming didn't work, so copy the file instead
-        unless (open EXIFTOOL_SFN_IN, $file) {
-            $self->Warn("Error opening '$file'");
+        unless ($self->Open(\*EXIFTOOL_SFN_IN, $file)) {
+            $self->Error("Error opening '${file}'");
             return -1;
         }
-        unless (open EXIFTOOL_SFN_OUT, ">$newName") {
+        unless ($self->Open(\*EXIFTOOL_SFN_OUT, $newName, '>')) {
             close EXIFTOOL_SFN_IN;
-            $self->Warn("Error creating '$newName'");
+            $self->Error("Error creating '${newName}'");
             return -1;
         }
@@ -1495,16 +2005,16 @@
         close EXIFTOOL_SFN_IN;
         if ($err) {
-            unlink $newName;    # erase bad output file
-            $self->Warn("Error writing '$newName'");
+            $self->Unlink($newName);    # erase bad output file
+            $self->Error("Error writing '${newName}'");
             return -1;
         }
         # preserve modification time
-        my $modTime = $^T - (-M $file) * (24 * 3600);
-        my $accTime = $^T - (-A $file) * (24 * 3600);
-        utime($accTime, $modTime, $newName);
+        my ($aTime, $mTime, $cTime) = $self->GetFileTime($file);
+        $self->SetFileTime($newName, $aTime, $mTime, $cTime);
         # remove the original file
-        unlink $file or $self->Warn('Error removing old file');
-    }
-    ++$self->{CHANGED};
+        $self->Unlink($file) or $self->Warn('Error removing old file');
+    }
+    $$self{NewName} = $newName; # remember new file name
+    ++$$self{CHANGED};
     $self->VerboseValue('+ FileName', $newName);
     return 1;
@@ -1512,7 +2022,60 @@
 
 #------------------------------------------------------------------------------
+# Set file permissions, group/user id and various MDItem tags from new tag values
+# Inputs: 0) ExifTool ref, 1) file name or glob (must be a name for MDItem tags)
+# 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 SetSystemTags($$)
+{
+    my ($self, $file) = @_;
+    my $result = 0;
+
+    my $perm = $self->GetNewValue('FilePermissions');
+    if (defined $perm) {
+        if (eval { chmod($perm & 07777, $file) }) {
+            $self->VerboseValue('+ FilePermissions', $perm);
+            $result = 1;
+        } else {
+            $self->WarnOnce('Error setting FilePermissions');
+            $result = -1;
+        }
+    }
+    my $uid = $self->GetNewValue('FileUserID');
+    my $gid = $self->GetNewValue('FileGroupID');
+    if (defined $uid or defined $gid) {
+        defined $uid or $uid = -1;
+        defined $gid or $gid = -1;
+        if (eval { chown($uid, $gid, $file) }) {
+            $self->VerboseValue('+ FileUserID', $uid) if $uid >= 0;
+            $self->VerboseValue('+ FileGroupID', $gid) if $gid >= 0;
+            $result = 1;
+        } else {
+            $self->WarnOnce('Error setting FileGroup/UserID');
+            $result = -1 unless $result;
+        }
+    }
+    my $tag;
+    foreach $tag (@writableMacOSTags) {
+        my $nvHash;
+        my $val = $self->GetNewValue($tag, \$nvHash);
+        next unless $nvHash;
+        if ($^O eq 'darwin') {
+            ref $file and $self->Warn('Setting MDItem tags requires a file name'), last;
+            require Image::ExifTool::MacOS;
+            my $res = Image::ExifTool::MacOS::SetMacOSTags($self, $file, \@writableMacOSTags);
+            $result = $res if $res == 1 or not $result;
+            last;
+        } elsif ($tag ne 'FileCreateDate') {
+            $self->WarnOnce('Can only set MDItem tags on OS X');
+            last;
+        }
+    }
+    return $result;
+}
+
+#------------------------------------------------------------------------------
 # Write information back to file
 # Inputs: 0) ExifTool object reference,
-#         1) input filename, file ref, or scalar ref (or '' or undef to create from scratch)
+#         1) input filename, file ref, RAF ref, or scalar ref (or '' or undef to create from scratch)
 #         2) output filename, file ref, or scalar ref (or undef to overwrite)
 #         3) optional output file type (required only if input file is not specified
@@ -1524,19 +2087,30 @@
     my ($self, $infile, $outfile, $outType) = @_;
     my (@fileTypeList, $fileType, $tiffType, $hdr, $seekErr, $type, $tmpfile);
-    my ($inRef, $outRef, $closeIn, $closeOut, $outPos, $outBuff, $eraseIn);
-    my $oldRaf = $self->{RAF};
+    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)
-    my ($nvHash, $originalTime);
-    my $fileModifyDate =  $self->GetNewValues('FileModifyDate', \$nvHash);
-    if (defined $fileModifyDate and IsOverwriting($nvHash) < 0 and
+    my ($nvHash, $nvHash2, $originalTime, $createTime);
+    my $setModDate = defined $self->GetNewValue('FileModifyDate', \$nvHash);
+    my $setCreateDate = defined $self->GetNewValue('FileCreateDate', \$nvHash2);
+    my ($aTime, $mTime, $cTime);
+    if ($setModDate and $self->IsOverwriting($nvHash) < 0 and
         defined $infile and ref $infile ne 'SCALAR')
     {
-        $originalTime = -M $infile;
+        ($aTime, $mTime, $cTime) = $self->GetFileTime($infile);
+        $originalTime = $mTime;
+    }
+    if ($setCreateDate and $self->IsOverwriting($nvHash2) < 0 and
+        defined $infile and ref $infile ne 'SCALAR')
+    {
+        ($aTime, $mTime, $cTime) = $self->GetFileTime($infile) unless defined $cTime;
+        $createTime = $cTime;
     }
 #
@@ -1545,12 +2119,37 @@
     my ($numNew, $numPseudo) = $self->CountNewValues();
     if (not defined $outfile and defined $infile) {
-        my $newFileName =  $self->GetNewValues('FileName', \$nvHash);
+        $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');
+        if (defined $newDir and length $newDir) {
+            $newDir .= '/' unless $newDir =~ m{/$};
+        } else {
+            undef $newDir;
+        }
         if ($numNew == $numPseudo) {
             $rtnVal = 2;
-            if (defined $fileModifyDate and (not ref $infile or UNIVERSAL::isa($infile,'GLOB'))) {
-                $self->SetFileModifyDate($infile) > 0 and $rtnVal = 1;
-            }
-            if (defined $newFileName and not ref $infile) {
-                $self->SetFileName($infile) > 0 and $rtnVal = 1;
+            if ((defined $newFileName or defined $newDir) and not ref $infile) {
+                my $result = $self->SetFileName($infile);
+                if ($result > 0) {
+                    $infile = $$self{NewName};  # file name changed
+                    $rtnVal = 1;
+                } elsif ($result < 0) {
+                    return 0;   # don't try to do anything else
+                }
+            }
+            if (not ref $infile or UNIVERSAL::isa($infile,'GLOB')) {
+                $self->SetFileModifyDate($infile) > 0 and $rtnVal = 1 if $setModDate;
+                $self->SetFileModifyDate($infile, undef, 'FileCreateDate') > 0 and $rtnVal = 1 if $setCreateDate;
+                $self->SetSystemTags($infile) > 0 and $rtnVal = 1;
+            }
+            if (defined $hardLink or defined $symLink or defined $testName) {
+                $hardLink and $self->SetFileName($infile, $hardLink, 'HardLink') and $rtnVal = 1;
+                $symLink and $self->SetFileName($infile, $symLink, 'SymLink') and $rtnVal = 1;
+                $testName and $self->SetFileName($infile, $testName, 'Test') and $rtnVal = 1;
             }
             return $rtnVal;
@@ -1561,7 +2160,15 @@
                 $outfile = $newFileName;
                 # can't delete original
-            } elsif (IsOverwriting($nvHash, $infile)) {
+            } elsif ($self->IsOverwriting($nvHash, $infile)) {
                 $outfile = GetNewFileName($infile, $newFileName);
                 $eraseIn = 1; # delete original
+            }
+        }
+        # set new directory if specified
+        if (defined $newDir) {
+            $outfile = $infile unless defined $outfile or ref $infile;
+            if (defined $outfile) {
+                $outfile = GetNewFileName($outfile, $newDir);
+                $eraseIn = 1 unless ref $infile;
             }
         }
@@ -1574,7 +2181,10 @@
         if (UNIVERSAL::isa($inRef,'GLOB')) {
             seek($inRef, 0, 0); # make sure we are at the start of the file
-        } elsif ($] >= 5.006 and (eval 'require Encode; Encode::is_utf8($$inRef)' or $@)) {
+        } elsif (UNIVERSAL::isa($inRef,'File::RandomAccess')) {
+            $inRef->Seek(0);
+            $raf = $inRef;
+        } elsif ($] >= 5.006 and (eval { require Encode; Encode::is_utf8($$inRef) } or $@)) {
             # convert image data from UTF-8 to character stream if necessary
-            my $buff = $@ ? pack('C*',unpack('U0C*',$$inRef)) : Encode::encode('utf8',$$inRef);
+            my $buff = $@ ? pack('C*',unpack($] < 5.010000 ? 'U0C*' : 'C0C*',$$inRef)) : Encode::encode('utf8',$$inRef);
             if (defined $outfile) {
                 $inRef = \$buff;
@@ -1586,5 +2196,6 @@
         # write to a temporary file if no output file given
         $outfile = $tmpfile = "${infile}_exiftool_tmp" unless defined $outfile;
-        if (open(EXIFTOOL_FILE2, $infile)) {
+        if ($self->Open(\*EXIFTOOL_FILE2, $infile)) {
+            $fileExt = GetFileExtension($infile);
             $fileType = GetFileType($infile);
             @fileTypeList = GetFileType($infile);
@@ -1604,8 +2215,13 @@
         $outType = GetFileExtension($outfile) unless $outType or ref $outfile;
         if (CanCreate($outType)) {
-            $fileType = $tiffType = $outType;   # use output file type if no input file
-            $infile = "$fileType file";         # make bogus file name
-            $self->VPrint(0, "Creating $infile...\n");
-            $inRef = \ '';      # set $inRef to reference to empty data
+            if ($$self{OPTIONS}{WriteMode} =~ /g/i) {
+                $fileType = $tiffType = $outType;   # use output file type if no input file
+                $infile = "$fileType file";         # make bogus file name
+                $self->VPrint(0, "Creating $infile...\n");
+                $inRef = \ '';      # set $inRef to reference to empty data
+            } else {
+                $self->Error("Not creating new $outType file (disallowed by WriteMode)");
+                return 0;
+            }
         } elsif ($outType) {
             $self->Error("Can't create $outType files");
@@ -1640,10 +2256,14 @@
         # editing in place, so write to memory first
         # (only when infile is a file ref or scalar ref)
+        if ($raf) {
+            $self->Error("Can't edit File::RandomAccess object in place");
+            return 0;
+        }
         $outBuff = '';
         $outRef = \$outBuff;
         $outPos = 0;
-    } elsif (-e $outfile) {
+    } elsif ($self->Exists($outfile)) {
         $self->Error("File already exists: $outfile");
-    } elsif (open(EXIFTOOL_OUTFILE, ">$outfile")) {
+    } elsif ($self->Open(\*EXIFTOOL_OUTFILE, $outfile, '>')) {
         $outRef = \*EXIFTOOL_OUTFILE;
         $closeOut = 1;  # we must close $outRef
@@ -1657,7 +2277,7 @@
 # write the file
 #
-    until ($self->{VALUE}{Error}) {
+    until ($$self{VALUE}{Error}) {
         # create random access file object (disable seek test in case of straight copy)
-        my $raf = new File::RandomAccess($inRef, 1);
+        $raf or $raf = new File::RandomAccess($inRef, 1);
         $raf->BinMode();
         if ($numNew == $numPseudo) {
@@ -1671,5 +2291,5 @@
         } elsif (not ref $infile and ($infile eq '-' or $infile =~ /\|$/)) {
             # patch for Windows command shell pipe
-            $raf->{TESTED} = -1;    # force buffering
+            $$raf{TESTED} = -1; # force buffering
         } else {
             $raf->SeekTest();
@@ -1677,5 +2297,5 @@
        # $raf->Debug() and warn "  RAF debugging enabled!\n";
         my $inPos = $raf->Tell();
-        $self->{RAF} = $raf;
+        $$self{RAF} = $raf;
         my %dirInfo = (
             RAF => $raf,
@@ -1694,8 +2314,8 @@
             }
             # save file type in member variable
-            $dirInfo{Parent} = $self->{FILE_TYPE} = $self->{PATH}[0] = $type;
+            $dirInfo{Parent} = $$self{FILE_TYPE} = $$self{PATH}[0] = $type;
             # determine which directories we must write for this file type
             $self->InitWriteDirs($type);
-            if ($type eq 'JPEG') {
+            if ($type eq 'JPEG' or $type eq 'EXV') {
                 $rtnVal = $self->WriteJPEG(\%dirInfo);
             } elsif ($type eq 'TIFF') {
@@ -1705,57 +2325,26 @@
                     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);
                 }
-            } elsif ($type eq 'GIF') {
-                require Image::ExifTool::GIF;
-                $rtnVal = Image::ExifTool::GIF::ProcessGIF($self,\%dirInfo);
-            } elsif ($type eq 'CRW') {
-                require Image::ExifTool::CanonRaw;
-                $rtnVal = Image::ExifTool::CanonRaw::WriteCRW($self, \%dirInfo);
-            } elsif ($type eq 'MRW') {
-                require Image::ExifTool::MinoltaRaw;
-                $rtnVal = Image::ExifTool::MinoltaRaw::ProcessMRW($self, \%dirInfo);
-            } elsif ($type eq 'RAF') {
-                require Image::ExifTool::FujiFilm;
-                $rtnVal = Image::ExifTool::FujiFilm::WriteRAF($self, \%dirInfo);
+            } elsif (exists $writableType{$type}) {
+                my ($module, $func);
+                if (ref $writableType{$type} eq 'ARRAY') {
+                    $module = $writableType{$type}[0] || $type;
+                    $func = $writableType{$type}[1];
+                } else {
+                    $module = $writableType{$type} || $type;
+                }
+                require "Image/ExifTool/$module.pm";
+                $func = "Image::ExifTool::${module}::" . ($func || "Process$type");
+                no strict 'refs';
+                $rtnVal = &$func($self, \%dirInfo);
+                use strict 'refs';
             } elsif ($type eq 'ORF' or $type eq 'RAW') {
                 $rtnVal = $self->ProcessTIFF(\%dirInfo);
-            } elsif ($type eq 'X3F') {
-                require Image::ExifTool::SigmaRaw;
-                $rtnVal = Image::ExifTool::SigmaRaw::ProcessX3F($self, \%dirInfo);
-            } elsif ($type eq 'PNG') {
-                require Image::ExifTool::PNG;
-                $rtnVal = Image::ExifTool::PNG::ProcessPNG($self, \%dirInfo);
-            } elsif ($type eq 'MIE') {
-                require Image::ExifTool::MIE;
-                $rtnVal = Image::ExifTool::MIE::ProcessMIE($self, \%dirInfo);
-            } elsif ($type eq 'XMP') {
-                require Image::ExifTool::XMP;
-                $rtnVal = Image::ExifTool::XMP::WriteXMP($self, \%dirInfo);
-            } elsif ($type eq 'PPM') {
-                require Image::ExifTool::PPM;
-                $rtnVal = Image::ExifTool::PPM::ProcessPPM($self, \%dirInfo);
-            } elsif ($type eq 'PSD') {
-                require Image::ExifTool::Photoshop;
-                $rtnVal = Image::ExifTool::Photoshop::ProcessPSD($self, \%dirInfo);
-            } elsif ($type eq 'EPS' or $type eq 'PS') {
-                require Image::ExifTool::PostScript;
-                $rtnVal = Image::ExifTool::PostScript::WritePS($self, \%dirInfo);
-            } elsif ($type eq 'PDF') {
-                require Image::ExifTool::PDF;
-                $rtnVal = Image::ExifTool::PDF::WritePDF($self, \%dirInfo);
-            } elsif ($type eq 'ICC') {
-                require Image::ExifTool::ICC_Profile;
-                $rtnVal = Image::ExifTool::ICC_Profile::WriteICC($self, \%dirInfo);
-            } elsif ($type eq 'VRD') {
-                require Image::ExifTool::CanonVRD;
-                $rtnVal = Image::ExifTool::CanonVRD::ProcessVRD($self, \%dirInfo);
-            } elsif ($type eq 'JP2') {
-                require Image::ExifTool::Jpeg2000;
-                $rtnVal = Image::ExifTool::Jpeg2000::ProcessJP2($self, \%dirInfo);
-            } elsif ($type eq 'IND') {
-                require Image::ExifTool::InDesign;
-                $rtnVal = Image::ExifTool::InDesign::ProcessIND($self, \%dirInfo);
             } elsif ($type eq 'EXIF') {
                 # go through WriteDirectory so block writes, etc are handled
@@ -1787,5 +2376,5 @@
                 $err = 'Error seeking in file';
             } elsif ($fileType and defined $rtnVal) {
-                if ($self->{VALUE}{Error}) {
+                if ($$self{VALUE}{Error}) {
                     # existing error message will do
                 } elsif ($fileType eq 'RAW') {
@@ -1793,5 +2382,6 @@
                 } else {
                     if ($wrongType) {
-                        $err = "Not a valid $fileType";
+                        my $type = $fileExt || ($fileType eq 'TIFF' ? $tiffType : $fileType);
+                        $err = "Not a valid $type";
                         # do a quick check to see what this file looks like
                         foreach $type (@fileTypes) {
@@ -1820,7 +2410,15 @@
     # don't return success code if any error occurred
     if ($rtnVal > 0) {
-        unless (Tell($outRef) or $self->{VALUE}{Error}) {
+        if ($outType and $type and $outType ne $type) {
+            my @types = GetFileType($outType);
+            unless (grep /^$type$/, @types) {
+                $self->Error("Can't create $outType file from $type");
+                $rtnVal = 0;
+            }
+        }
+        if ($rtnVal > 0 and not Tell($outRef) and not $$self{VALUE}{Error}) {
             # don't write a file with zero length
             if (defined $hdr and length $hdr) {
+                $type = '<unk>' unless defined $type;
                 $self->Error("Can't delete all meta information from $type file");
             } else {
@@ -1828,10 +2426,10 @@
             }
         }
-        $rtnVal = 0 if $self->{VALUE}{Error};
+        $rtnVal = 0 if $$self{VALUE}{Error};
     }
 
     # rewrite original file in place if required
     if (defined $outBuff) {
-        if ($rtnVal <= 0 or not $self->{CHANGED}) {
+        if ($rtnVal <= 0 or not $$self{CHANGED}) {
             # nothing changed, so no need to write $outBuff
         } elsif (UNIVERSAL::isa($inRef,'GLOB')) {
@@ -1844,5 +2442,5 @@
                 print $inRef $outBuff and       # write the new data
                 ($len >= $size or               # if necessary:
-                eval 'truncate($inRef, $len)'); #  shorten output file
+                eval { truncate($inRef, $len) }); #  shorten output file
         } else {
             $$inRef = $outBuff;                 # replace original data
@@ -1856,6 +2454,6 @@
         if ($rtnVal > 0) {
             # copy Mac OS resource fork if it exists
-            if ($^O eq 'darwin' and -s "$infile/rsrc") {
-                if ($$self{DEL_GROUP} and $$self{DEL_GROUP}{RSRC}) {
+            if ($^O eq 'darwin' and -s "$infile/..namedfork/rsrc") {
+                if ($$self{DEL_GROUP}{RSRC}) {
                     $self->VPrint(0,"Deleting Mac OS resource fork\n");
                     ++$$self{CHANGED};
@@ -1864,6 +2462,6 @@
                     my ($buf, $err);
                     local (*SRC, *DST);
-                    if (open SRC, "$infile/rsrc") {
-                        if (open DST, ">$outfile/rsrc") {
+                    if ($self->Open(\*SRC, "$infile/..namedfork/rsrc")) {
+                        if ($self->Open(\*DST, "$outfile/..namedfork/rsrc", '>')) {
                             binmode SRC; # (not necessary for Darwin, but let's be thorough)
                             binmode DST;
@@ -1880,9 +2478,9 @@
                         $err = 'opening';
                     }
-                    $rtnVal = 0 if $err and $self->Error("Error $err Mac OS resource fork", 1);
+                    $rtnVal = 0 if $err and $self->Error("Error $err Mac OS resource fork", 2);
                 }
             }
             # erase input file if renaming while editing information in place
-            unlink $infile or $self->Warn('Error erasing original file') if $eraseIn;
+            $self->Unlink($infile) or $self->Warn('Error erasing original file') if $eraseIn;
         }
     }
@@ -1893,27 +2491,37 @@
         # erase the output file if we weren't successful
         if ($rtnVal <= 0) {
-            unlink $outfile;
+            $self->Unlink($outfile);
         # else rename temporary file if necessary
         } elsif ($tmpfile) {
-            CopyFileAttrs($infile, $tmpfile);   # copy attributes to new file
-            unless (rename($tmpfile, $infile)) {
+            $self->CopyFileAttrs($infile, $tmpfile);    # copy attributes to new file
+            unless ($self->Rename($tmpfile, $infile)) {
                 # some filesystems won't overwrite with 'rename', so try erasing original
-                if (not unlink($infile)) {
-                    unlink $tmpfile;
+                if (not $self->Unlink($infile)) {
+                    $self->Unlink($tmpfile);
                     $self->Error('Error renaming temporary file');
                     $rtnVal = 0;
-                } elsif (not rename($tmpfile, $infile)) {
+                } elsif (not $self->Rename($tmpfile, $infile)) {
                     $self->Error('Error renaming temporary file after deleting original');
                     $rtnVal = 0;
                 }
             }
-        }
-    }
-    # set FileModifyDate if requested (and if possible!)
-    if (defined $fileModifyDate and $rtnVal > 0 and
-        ($closeOut or ($closeIn and defined $outBuff)) and
-        $self->SetFileModifyDate($closeOut ? $outfile : $infile, $originalTime) > 0)
-    {
-        ++$self->{CHANGED}; # we changed something
+            # the output file should now have the name of the original infile
+            $outfile = $infile if $rtnVal > 0;
+        }
+    }
+    # set filesystem attributes if requested (and if possible!)
+    if ($rtnVal > 0 and ($closeOut or (defined $outBuff and ($closeIn or UNIVERSAL::isa($infile,'GLOB'))))) {
+        my $target = $closeOut ? $outfile : $infile;
+        # set file permissions if requested
+        ++$$self{CHANGED} if $self->SetSystemTags($target) > 0;
+        if ($closeIn) { # (no use setting file times unless the input file is closed)
+            ++$$self{CHANGED} if $setModDate and $self->SetFileModifyDate($target, $originalTime, undef, 1) > 0;
+            # 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, 'HardLink');
+            ++$$self{CHANGED} if defined $symLink and $self->SetFileName($target, $symLink, 'SymLink');
+            defined $testName and $self->SetFileName($target, $testName, 'Test');
+        }
     }
     # check for write error and set appropriate error message and return value
@@ -1922,8 +2530,8 @@
         $rtnVal = 0;    # return 0 on failure
     } elsif ($rtnVal > 0) {
-        ++$rtnVal unless $self->{CHANGED};
+        ++$rtnVal unless $$self{CHANGED};
     }
     # set things back to the way they were
-    $self->{RAF} = $oldRaf;
+    $$self{RAF} = $oldRaf;
 
     return $rtnVal;
@@ -1942,5 +2550,5 @@
     @groups = split ':', $group if $group;
 
-    my $exifTool = new Image::ExifTool;
+    my $et = new Image::ExifTool;
     LoadAllTables();    # first load all our tables
     my @tableNames = keys %allTables;
@@ -1949,4 +2557,8 @@
     while (@tableNames) {
         my $table = GetTagTable(pop @tableNames);
+        # generate flattened tag names for structure fields if this is an XMP table
+        if ($$table{GROUPS} and $$table{GROUPS}{0} eq 'XMP') {
+            Image::ExifTool::XMP::AddFlattenedTags($table);
+        }
         my $tagID;
         foreach $tagID (TagTableKeys($table)) {
@@ -1960,5 +2572,5 @@
                 next if $$tagInfo{Hidden};  # ignore hidden tags
                 if (@groups) {
-                    my @tg = $exifTool->GetGroup($tagInfo);
+                    my @tg = $et->GetGroup($tagInfo);
                     foreach $group (@groups) {
                         next GATInfo unless grep /^$group$/i, @tg;
@@ -1975,5 +2587,5 @@
 # Get list of all writable tags
 # Inputs: 0) optional group name (or names separated by colons)
-# Returns: tag list (sorted alphbetically)
+# Returns: tag list (sorted alphabetically)
 sub GetWritableTags(;$)
 {
@@ -1983,5 +2595,5 @@
     @groups = split ':', $group if $group;
 
-    my $exifTool = new Image::ExifTool;
+    my $et = new Image::ExifTool;
     LoadAllTables();
     my @tableNames = keys %allTables;
@@ -1990,11 +2602,15 @@
         my $tableName = pop @tableNames;
         my $table = GetTagTable($tableName);
+        # generate flattened tag names for structure fields if this is an XMP table
+        if ($$table{GROUPS} and $$table{GROUPS}{0} eq 'XMP') {
+            Image::ExifTool::XMP::AddFlattenedTags($table);
+        }
         # attempt to load Write tables if autoloaded
-        my @path = split(/::/,$tableName);
-        if (@path > 3) {
-            my $i = $#path - 1;
-            $path[$i] = "Write$path[$i]";   # add 'Write' before class name
-            my $module = join('::',@path[0..($#path-1)]);
-            eval "require $module"; # (fails silently if nothing loaded)
+        my @parts = split(/::/,$tableName);
+        if (@parts > 3) {
+            my $i = $#parts - 1;
+            $parts[$i] = "Write$parts[$i]";   # add 'Write' before class name
+            my $module = join('::',@parts[0..$i]);
+            eval { require $module }; # (fails silently if nothing loaded)
         }
         my $tagID;
@@ -2006,9 +2622,9 @@
                 $tag or warn("no name for tag!\n"), next;
                 my $writable = $$tagInfo{Writable};
-                next unless $writable or ($table->{WRITABLE} and
+                next unless $writable or ($$table{WRITABLE} and
                     not defined $writable and not $$tagInfo{SubDirectory});
                 next if $$tagInfo{Hidden};  # ignore hidden tags
                 if (@groups) {
-                    my @tg = $exifTool->GetGroup($tagInfo);
+                    my @tg = $et->GetGroup($tagInfo);
                     foreach $group (@groups) {
                         next GWTInfo unless grep /^$group$/i, @tg;
@@ -2024,13 +2640,17 @@
 #------------------------------------------------------------------------------
 # Get list of all group names
-# Inputs: 1) Group family number
+# Inputs: 0) [optional] ExifTool ref, 1) Group family number
 # Returns: List of group names (sorted alphabetically)
-sub GetAllGroups($)
+sub GetAllGroups($;$)
 {
     local $_;
     my $family = shift || 0;
+    my $self;
+    ref $family and $self = $family, $family = shift || 0;
 
     $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
@@ -2046,10 +2666,25 @@
         foreach $tag (TagTableKeys($table)) {
             my @infoArray = GetTagInfoList($table, $tag);
-            foreach $tagInfo (@infoArray) {
-                next unless ($grps = $$tagInfo{Groups}) and ($grp = $$grps{$family});
-                $allGroups{$grp} = 1;
-            }
-        }
-    }
+            if ($family == 7) {
+                foreach $tagInfo (@infoArray) {
+                    my $id = $$tagInfo{TagID};
+                    if (not defined $id) {
+                        $id = '';   # (just to be safe)
+                    } elsif ($id =~ /^\d+$/) {
+                        $id = sprintf('0x%x', $id) if $self and $$self{OPTIONS}{HexTagIDs};
+                    } else {
+                        $id =~ s/([^-_A-Za-z0-9])/sprintf('%.2x',ord $1)/ge;
+                    }
+                    $allGroups{'ID-' . $id} = 1;
+                }
+            } else {
+                foreach $tagInfo (@infoArray) {
+                    next unless ($grps = $$tagInfo{Groups}) and ($grp = $$grps{$family});
+                    $allGroups{$grp} = 1;
+                }
+            }
+        }
+    }
+    delete $allGroups{'*'};     # (not a real group)
     return sort keys %allGroups;
 }
@@ -2062,5 +2697,5 @@
 {
     my $self = shift;
-    return @{$self->{WRITE_GROUPS}};
+    return @{$$self{WRITE_GROUPS}};
 }
 
@@ -2070,9 +2705,40 @@
 sub GetDeleteGroups()
 {
-    return sort @delGroups;
+    return sort @delGroups, @delGroup2;
+}
+
+#------------------------------------------------------------------------------
+# Add user-defined tags at run time
+# Inputs: 0) destination table name, 1) tagID/tagInfo pairs for tags to add
+# Returns: number of tags added
+# Notes: will replace existing tags
+sub AddUserDefinedTags($%)
+{
+    local $_;
+    my ($tableName, %addTags) = @_;
+    my $table = GetTagTable($tableName) or return 0;
+    # add tags to writer lookup
+    Image::ExifTool::TagLookup::AddTags(\%addTags, $tableName);
+    my $tagID;
+    my $num = 0;
+    foreach $tagID (keys %addTags) {
+        next if $specialTags{$tagID};
+        delete $$table{$tagID}; # delete old entry if it existed
+        AddTagToTable($table, $tagID, $addTags{$tagID}, 1);
+        ++$num;
+    }
+    return $num;
 }
 
 #==============================================================================
 # Functions below this are not part of the public API
+
+#------------------------------------------------------------------------------
+# Maintain backward compatibility for old GetNewValues function name
+sub GetNewValues($$;$)
+{
+    my ($self, $tag, $nvHashPt) = @_;
+    return $self->GetNewValue($tag, $nvHashPt);
+}
 
 #------------------------------------------------------------------------------
@@ -2087,7 +2753,8 @@
     # make sure the Perl UTF-8 flag is OFF for the value if perl 5.6 or greater
     # (otherwise our byte manipulations get corrupted!!)
-    if ($] >= 5.006 and (eval 'require Encode; Encode::is_utf8($$valPt)' or $@)) {
+    if ($] >= 5.006 and (eval { require Encode; Encode::is_utf8($$valPt) } or $@)) {
+        local $SIG{'__WARN__'} = \&SetWarning;
         # repack by hand if Encode isn't available
-        $$valPt = $@ ? pack('C*',unpack('U0C*',$$valPt)) : Encode::encode('utf8',$$valPt);
+        $$valPt = $@ ? pack('C*',unpack($] < 5.010000 ? 'U0C*' : 'C0C*',$$valPt)) : Encode::encode('utf8',$$valPt);
     }
     # un-escape value if necessary
@@ -2097,5 +2764,5 @@
             $$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});
         }
     }
@@ -2106,11 +2773,15 @@
 # Inputs: 0) ExifTool ref, 1) value, 2) tagInfo (or Struct item) ref,
 #         3) tag name, 4) group 1 name, 5) conversion type (or undef),
-#         6) [optional] want group
+#         6) [optional] want group ("" for structure field)
 # Returns: 0) converted value, 1) error string (or undef on success)
-# Notes: Uses ExifTool "ConvType" member to specify conversion type
+# Notes:
+# - uses ExifTool "ConvType" member when conversion type is undef
+# - conversion types other than 'ValueConv' and 'PrintConv' are treated as 'Raw'
 sub ConvInv($$$$$;$$)
 {
     my ($self, $val, $tagInfo, $tag, $wgrp1, $convType, $wantGroup) = @_;
     my ($err, $type);
+
+    $convType or $convType = $$self{ConvType} || 'PrintConv';
 
 Conv: for (;;) {
@@ -2118,48 +2789,57 @@
             # split value into list if necessary
             if ($$tagInfo{List}) {
-                my $listSplit = $$tagInfo{AutoSplit} || $self->{OPTIONS}{ListSplit};
-                if (defined $listSplit) {
+                my $listSplit = $$tagInfo{AutoSplit} || $$self{OPTIONS}{ListSplit};
+                if (defined $listSplit and not $$tagInfo{Struct} and
+                    ($wantGroup or not defined $wantGroup))
+                {
                     $listSplit = ',?\s+' if $listSplit eq '1' and $$tagInfo{AutoSplit};
-                    my @splitVal = split /$listSplit/, $val;
-                    $val = \@splitVal if @splitVal > 1;
-                }
-            }
-            $type = $convType || $$self{ConvType} || 'PrintConv';
-        } elsif ($type ne 'ValueConv') {
+                    my @splitVal = split /$listSplit/, $val, -1;
+                    $val = @splitVal > 1 ? \@splitVal : @splitVal ? $splitVal[0] : '';
+                }
+            }
+            $type = $convType;
+        } elsif ($type eq 'PrintConv') {
             $type = 'ValueConv';
-        } else {    
+        } else {
+            # split raw value if necessary
+            if ($$tagInfo{RawJoin} and $$tagInfo{List} and not ref $val) {
+                my @splitVal = split ' ', $val;
+                $val = \@splitVal if @splitVal > 1;
+            }
             # finally, do our value check
             my ($err2, $v);
-            if ($tagInfo->{WriteCheck}) {
+            if ($$tagInfo{WriteCheck}) {
                 #### eval WriteCheck ($self, $tagInfo, $val)
-                $err2 = eval $tagInfo->{WriteCheck};
+                $err2 = eval $$tagInfo{WriteCheck};
                 $@ and warn($@), $err2 = 'Error evaluating WriteCheck';
             }
             unless ($err2) {
-                my $table = $tagInfo->{Table};
-                if ($table and $table->{CHECK_PROC} and not $$tagInfo{RawConvInv}) {
-                    my $checkProc = $table->{CHECK_PROC};
+                my $table = $$tagInfo{Table};
+                if ($table and $$table{CHECK_PROC} and not $$tagInfo{RawConvInv}) {
+                    my $checkProc = $$table{CHECK_PROC};
                     if (ref $val eq 'ARRAY') {
                         # loop through array values
                         foreach $v (@$val) {
-                            $err2 = &$checkProc($self, $tagInfo, \$v);
+                            $err2 = &$checkProc($self, $tagInfo, \$v, $convType);
                             last if $err2;
                         }
                     } else {
-                        $err2 = &$checkProc($self, $tagInfo, \$val);
+                        $err2 = &$checkProc($self, $tagInfo, \$val, $convType);
                     }
                 }
             }
             if (defined $err2) {
-                # skip writing this tag if error string is empty
-                $err2 or goto WriteAlso;
-                $err = "$err2 for $wgrp1:$tag";
-                $self->VPrint(2, "$err\n");
-                undef $val; # value was invalid
+                if ($err2) {
+                    $err = "$err2 for $wgrp1:$tag";
+                    $self->VPrint(2, "$err\n");
+                    undef $val;     # value was invalid
+                } else {
+                    $err = $err2;   # empty error (quietly don't write tag)
+                }
             }
             last;
         }
-        my $conv = $tagInfo->{$type};
-        my $convInv = $tagInfo->{"${type}Inv"};
+        my $conv = $$tagInfo{$type};
+        my $convInv = $$tagInfo{"${type}Inv"};
         # nothing to do at this level if no conversion defined
         next unless defined $conv or defined $convInv;
@@ -2212,9 +2892,9 @@
                 }
             } 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
-                        ref($lc = $self->{CUR_LANG}{$tag}) eq 'HASH' and
+                        ref($lc = $$self{CUR_LANG}{$tag}) eq 'HASH' and
                         ($lc = $$lc{PrintConv}))
                     {
@@ -2234,7 +2914,9 @@
                         $conv = \%newConv;
                     }
+                    undef $evalWarning;
                     if ($$conv{BITMASK}) {
                         my $lookupBits = $$conv{BITMASK};
-                        my ($val2, $err2) = EncodeBits($val, $lookupBits);
+                        my ($wbits, $tbits) = @$tagInfo{'BitsPerWord','BitsTotal'};
+                        my ($val2, $err2) = EncodeBits($val, $lookupBits, $wbits, $tbits);
                         if ($err2) {
                             # ok, try matching a straight value
@@ -2255,9 +2937,11 @@
                         ($val, $multi) = ReverseLookup($val, $conv);
                     }
-                    unless (defined $val) {
-                        $err = "Can't convert $wgrp1:$tag (" .
-                               ($multi ? 'matches more than one' : 'not in') . " $type)";
+                    if (not defined $val) {
+                        my $prob = $evalWarning ? lcfirst CleanWarning() : ($multi ? 'matches more than one ' : 'not in ') . $type;
+                        $err = "Can't convert $wgrp1:$tag ($prob)";
                         $self->VPrint(2, "$err\n");
                         last Conv;
+                    } elsif ($evalWarning) {
+                        $self->VPrint(2, CleanWarning() . " for $wgrp1:$tag\n");
                     }
                 } elsif (not $$tagInfo{WriteAlso}) {
@@ -2285,5 +2969,6 @@
 
 #------------------------------------------------------------------------------
-# convert tag names to values in a string (ie. "${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:
@@ -2291,25 +2976,44 @@
 #              'Error'   - issue minor error on missing tag (and return undef)
 #              'Warn'    - issue minor warning on missing tag (and return undef)
-#               Hash ref - hash for return of tag/value pairs
+#              'Silent'  - just return undef on missing tag (no errors/warnings)
+#               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)
 # Notes:
 # - tag names are not case sensitive and may end with '#' for ValueConv value
 # - uses MissingTagValue option if set
-sub InsertTagValues($$$;$)
-{
-    my ($self, $foundTags, $line, $opt) = @_;
+# - '$GROUP:all' evaluates to 1 if any tag from GROUP exists, or 0 otherwise
+# - advanced feature allows Perl expressions inside braces (eg. '${model;tr/ //d}')
+# - an error/warning in an advanced expression ("${TAG;EXPR}") generates an error
+#   if option set to 'Error', or a warning otherwise
+sub InsertTagValues($$$;$$$)
+{
+    local $_;
+    my ($self, $foundTags, $line, $opt, $docGrp, $cache) = @_;
     my $rtnStr = '';
-    while ($line =~ /(.*?)\$(\{?)([-\w]+|\$|\/)(.*)/s) {
-        my (@tags, $pre, $var, $bra, $val, $tg, @vals, $type);
-        ($pre, $bra, $var, $line) = ($1, $2, $3, $4);
+    my ($docNum, $tag);
+    if ($docGrp) {
+        $docNum = $docGrp =~ /(\d+)$/ ? $1 : 0;
+    } else {
+        undef $cache;   # no cache if no document groups
+    }
+    while ($line =~ s/(.*?)\$(\{\s*)?([-\w]*\w|\$|\/)//s) {
+        my ($pre, $bra, $var) = ($1, $2, $3);
+        my (@tags, $val, $tg, @val, $type, $expr, $didExpr, $level, $asList);
         # "$$" represents a "$" symbol, and "$/" is a newline
         if ($var eq '$' or $var eq '/') {
-            $var = "\n" if $var eq '/';
+            $line =~ s/^\s*\}// if $bra;
+            if ($var eq '/') {
+                $var = "\n";
+            } elsif ($line =~ /^self\b/ and not $rtnStr =~ /\$$/) {
+                $var = '$$';    # ("$$self{var}" in string)
+            }
             $rtnStr .= "$pre$var";
-            $line =~ s/^\}// if $bra;
             next;
         }
         # allow multiple group names
-        while ($line =~ /^:([-\w]+)(.*)/s) {
+        while ($line =~ /^:([-\w]*\w)(.*)/s) {
             my $group = $var;
             ($var, $line) = ($1, $2);
@@ -2318,65 +3022,183 @@
         # allow trailing '#' to indicate ValueConv value
         $type = 'ValueConv' if $line =~ s/^#//;
+        # special advanced formatting '@' feature to evaluate list values separately
+        if ($bra and $line =~ s/^\@(#)?//) {
+            $asList = 1;
+            $type = 'ValueConv' if $1;
+        }
         # remove trailing bracket if there was a leading one
-        $line =~ s/^\}// if $bra;
+        # and extract Perl expression from inside brackets if it exists
+        if ($bra and $line !~ s/^\s*\}// and $line =~ s/^\s*;\s*(.*?)\s*\}//s) {
+            my $part = $1;
+            $expr = '';
+            for ($level=0; ; --$level) {
+                # increase nesting level for each opening brace
+                ++$level while $part =~ /\{/g;
+                $expr .= $part;
+                last unless $level and $line =~ s/^(.*?)\s*\}//s; # get next part
+                $part = $1;
+                $expr .= '}';  # this brace was part of the expression
+            }
+            # use default Windows filename filter if expression is empty
+            $expr = 'tr(/\\\\?*:|"<>\\0)()d' unless length $expr;
+        }
         push @tags, $var;
         ExpandShortcuts(\@tags);
         @tags or $rtnStr .= $pre, next;
+        # save advanced formatting expression to allow access by user-defined ValueConv
+        $$self{FMT_EXPR} = $expr;
 
         for (;;) {
-            my $tag = shift @tags;
-            if ($tag =~ /(.*):(.+)/) {
+            # temporarily reset ListJoin option if evaluating list values separately
+            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)
                 my $group;
-                ($group, $tag) = ($1, $2);
-                # find the specified tag
-                my @matches = grep /^$tag(\s|$)/i, @$foundTags;
-                @matches = $self->GroupMatches($group, \@matches);
-                foreach $tg (@matches) {
-                    if (defined $val and $tg =~ / \((\d+)\)$/) {
-                        # take the most recently extracted tag
-                        my $tagNum = $1;
-                        next if $tag !~ / \((\d+)\)$/ or $1 > $tagNum;
-                    }
-                    $val = $self->GetValue($tg, $type);
-                    $tag = $tg;
-                    last unless $tag =~ / /;    # all done if we got our best match
+                $tag =~ s/^(.*):// and $group = $1;
+                # cache tag keys to speed processing for a large number of sub-documents
+                # (similar to code in BuildCompositeTags(), but this is case-insensitive)
+                my $cacheTag = $$cache{$lcTag};
+                unless ($cacheTag) {
+                    $cacheTag = $$cache{$lcTag} = [ ];
+                    # find all matching keys, organize into groups, and store in cache
+                    my $ex = $$self{TAG_EXTRA};
+                    my @matches = grep /^$tag(\s|$)/i, @$foundTags;
+                    @matches = $self->GroupMatches($group, \@matches) if defined $group;
+                    foreach (@matches) {
+                        my $doc = $$ex{$_} ? $$ex{$_}{G3} || 0 : 0;
+                        if (defined $$cacheTag[$doc]) {
+                            next unless $$cacheTag[$doc] =~ / \((\d+)\)$/;
+                            my $cur = $1;
+                            # keep the most recently extracted tag
+                            next if / \((\d+)\)$/ and $1 < $cur;
+                        }
+                        $$cacheTag[$doc] = $_;
+                    }
+                }
+                my $doc = $lcTag =~ /\b(main|doc(\d+)):/ ? ($2 || 0) : $docNum;
+                if ($$cacheTag[$doc]) {
+                    $tag = $$cacheTag[$doc];
+                    $val = $self->GetValue($tag, $type);
                 }
             } else {
-                # get the tag value
-                $val = $self->GetValue($tag, $type);
-                unless (defined $val) {
-                    # check for tag name with different case
-                    ($tg) = grep /^$tag$/i, @$foundTags;
-                    if (defined $tg) {
-                        $val = $self->GetValue($tg, $type);
-                        $tag = $tg;
-                    }
-                }
-            }
+                # add document number to tag if specified and it doesn't already exist
+                if ($docGrp and $lcTag !~ /\b(main|doc\d+):/) {
+                    $tag = $docGrp . ':' . $tag;
+                    $lcTag = lc $tag;
+                }
+                if ($lcTag eq 'all') {
+                    $val = 1;   # always some tag available
+                } elsif (defined $$self{OPTIONS}{UserParam}{$lcTag}) {
+                    $val = $$self{OPTIONS}{UserParam}{$lcTag};
+                } elsif ($tag =~ /(.*):(.+)/) {
+                    my $group;
+                    ($group, $tag) = ($1, $2);
+                    if (lc $tag eq 'all') {
+                        # see if any tag from the specified group exists
+                        my $match = $self->GroupMatches($group, $foundTags);
+                        $val = $match ? 1 : 0;
+                    } else {
+                        # find the specified tag
+                        my @matches = grep /^$tag(\s|$)/i, @$foundTags;
+                        @matches = $self->GroupMatches($group, \@matches);
+                        foreach $tg (@matches) {
+                            if (defined $val and $tg =~ / \((\d+)\)$/) {
+                                # take the most recently extracted tag
+                                my $tagNum = $1;
+                                next if $tag !~ / \((\d+)\)$/ or $1 > $tagNum;
+                            }
+                            $val = $self->GetValue($tg, $type);
+                            $tag = $tg;
+                            last unless $tag =~ / /;    # all done if we got our best match
+                        }
+                    }
+                } elsif ($tag eq 'self') {
+                    $val = $self; # ("$self{var}" or "$self->{var}" in string)
+                } else {
+                    # get the tag value
+                    $val = $self->GetValue($tag, $type);
+                    unless (defined $val) {
+                        # check for tag name with different case
+                        ($tg) = grep /^$tag$/i, @$foundTags;
+                        if (defined $tg) {
+                            $val = $self->GetValue($tg, $type);
+                            $tag = $tg;
+                        }
+                    }
+                }
+            }
+            $self->Options(ListJoin => $oldListJoin) if $asList;
             if (ref $val eq 'ARRAY') {
-                $val = join($self->{OPTIONS}{ListSep}, @$val);
+                push @val, @$val;
+                undef $val;
+                last unless @tags;
             } elsif (ref $val eq 'SCALAR') {
-                if ($self->{OPTIONS}{Binary} or $$val =~ /^Binary data/) {
+                if ($$self{OPTIONS}{Binary} or $$val =~ /^Binary data/) {
                     $val = $$val;
                 } else {
                     $val = 'Binary data ' . length($$val) . ' bytes';
                 }
+            } elsif (ref $val eq 'HASH') {
+                require 'Image/ExifTool/XMPStruct.pl';
+                $val = Image::ExifTool::XMP::SerializeStruct($val);
             } elsif (not defined $val) {
-                last unless @tags;
-                next;
+                $val = $$self{OPTIONS}{MissingTagValue} if $asList;
             }
             last unless @tags;
-            push @vals, $val;
+            push @val, $val if defined $val;
             undef $val;
         }
-        if (@vals) {
-            push @vals, $val if defined $val;
-            $val = join '', @vals;
+        if (@val) {
+            push @val, $val if defined $val;
+            $val = join $$self{OPTIONS}{ListSep}, @val;
+        } else {
+            push @val, $val if defined $val; # (so the eval has access to @val if required)
+        }
+        # evaluate advanced formatting expression if given (eg. "${TAG;EXPR}")
+        if (defined $expr and defined $val) {
+            local $SIG{'__WARN__'} = \&SetWarning;
+            undef $evalWarning;
+            $advFmtSelf = $self;
+            if ($asList) {
+                foreach (@val) {
+                    #### eval advanced formatting expression ($_, $self, @val, $advFmtSelf)
+                    eval $expr;
+                    $@ and $evalWarning = $@;
+                }
+                # join back together if any values are still defined
+                @val = grep defined, @val;
+                $val = @val ? join $$self{OPTIONS}{ListSep}, @val : undef;
+            } else {
+                $_ = $val;
+                #### eval advanced formatting expression ($_, $self, @val, $advFmtSelf)
+                eval $expr;
+                $@ and $evalWarning = $@;
+                $val = ref $_ eq 'ARRAY' ? join($$self{OPTIONS}{ListSep}, @$_): $_;
+            }
+            if ($evalWarning) {
+                my $g3 = ($docGrp and $var !~ /\b(main|doc\d+):/i) ? $docGrp . ':' : '';
+                my $str = CleanWarning() . " for '$g3${var}'";
+                if ($opt) {
+                    if ($opt eq 'Error') {
+                        $self->Error($str);
+                    } elsif ($opt ne 'Silent') {
+                        $self->Warn($str);
+                    }
+                }
+            }
+            undef $advFmtSelf;
+            $didExpr = 1;   # set flag indicating an expression was evaluated
         }
         unless (defined $val or ref $opt) {
-            $val = $self->{OPTIONS}{MissingTagValue};
+            $val = $$self{OPTIONS}{MissingTagValue};
             unless (defined $val) {
+                my $g3 = ($docGrp and $var !~ /\b(main|doc\d+):/i) ? $docGrp . ':' : '';
+                my $msg = $didExpr ? "Advanced formatting expression returned undef for '$g3${var}'" :
+                                     "Tag '$g3${var}' not defined";
                 no strict 'refs';
-                return undef if $opt and &$opt($self, "Tag '$var' not defined", 1);
+                $opt and ($opt eq 'Silent' or &$opt($self, $msg, 2)) and return $$self{FMT_EXPR} = undef;
                 $val = '';
             }
@@ -2384,5 +3206,11 @@
         if (ref $opt eq 'HASH') {
             $var .= '#' if $type;
-            $rtnStr .= "$pre\$info{'$var'}";
+            if (defined $expr) {
+                # generate unique variable name for this modified tag value
+                my $i = 1;
+                ++$i while exists $$opt{"$var.expr$i"};
+                $var .= '.expr' . $i;
+            }
+            $rtnStr .= "$pre\$info{'${var}'}";
             $$opt{$var} = $val;
         } else {
@@ -2390,5 +3218,34 @@
         }
     }
+    $$self{FMT_EXPR} = undef;
     return $rtnStr . $line;
+}
+
+#------------------------------------------------------------------------------
+# Reformat date/time value in $_ based on specified format string
+# Inputs: 0) date/time format string
+sub DateFmt($)
+{
+    my $et = bless { OPTIONS => { DateFormat => shift, StrictDate => 1 } };
+    my $shift;
+    if ($advFmtSelf and defined($shift = $$advFmtSelf{OPTIONS}{GlobalTimeShift})) {
+        $$et{OPTIONS}{GlobalTimeShift} = $shift;
+        $$et{GLOBAL_TIME_OFFSET} = $$advFmtSelf{GLOBAL_TIME_OFFSET};
+    }
+    $_ = $et->ConvertDateTime($_);
+    defined $_ or warn "Error converting date/time\n";
+    $$advFmtSelf{GLOBAL_TIME_OFFSET} = $$et{GLOBAL_TIME_OFFSET} if $shift;
+}
+
+#------------------------------------------------------------------------------
+# Utility routine to remove duplicate items from default input string
+# Inputs: 0) true to set $_ to undef if not changed
+# Notes: - for use only in advanced formatting expressions
+sub NoDups
+{
+    my %seen;
+    my $sep = $advFmtSelf ? $$advFmtSelf{OPTIONS}{ListSep} : ', ';
+    my $new = join $sep, grep { !$seen{$_}++ } split /\Q$sep\E/, $_;
+    $_ = ($_[0] and $new eq $_) ? undef : $new;
 }
 
@@ -2408,10 +3265,13 @@
     my $tagInfo;
     foreach $tagInfo (@tagInfo) {
-        return 1 if $$tagInfo{Writable} or $tagInfo->{Table}{WRITABLE};
+        return $$tagInfo{Writable} ? 1 : 0 if defined $$tagInfo{Writable};
+        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};
+        my $writeProc = $$tagInfo{Table}{WRITE_PROC};
+        if ($writeProc) {
+            no strict 'refs';
+            &$writeProc();  # dummy call to autoload writer
+            return 1 if $$tagInfo{Writable};
+        }
     }
     return 0;
@@ -2419,22 +3279,81 @@
 
 #------------------------------------------------------------------------------
+# 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) complete file name including path
+# Inputs: 0) ExifTool ref, 1) complete file name including path
 # Returns: 1 = directory created, 0 = nothing done, -1 = error
-sub CreateDirectory($)
+my $k32CreateDir;
+sub CreateDirectory($$)
 {
     local $_;
-    my $file = shift;
+    my ($self, $file) = @_;
     my $rtnVal = 0;
+    my $enc = $$self{OPTIONS}{CharsetFileName};
     my $dir;
     ($dir = $file) =~ s/[^\/]*$//;  # remove filename from path specification
-    if ($dir and not -d $dir) {
+    # recode as UTF-8 if necessary
+    if ($dir and not $self->IsDirectory($dir)) {
         my @parts = split /\//, $dir;
         $dir = '';
         foreach (@parts) {
             $dir .= $_;
-            if (length $dir and not -d $dir) {
+            if (length $dir and not $self->IsDirectory($dir)) {
                 # create directory since it doesn't exist
-                mkdir($dir, 0777) or return -1;
+                my $d2 = $dir; # (must make a copy in case EncodeFileName recodes it)
+                if ($self->EncodeFileName($d2)) {
+                    # handle Windows Unicode directory names
+                    unless (eval { require Win32::API }) {
+                        $self->Warn('Install Win32::API to create directories with Unicode names');
+                        return -1;
+                    }
+                    unless ($k32CreateDir) {
+                        return -1 if defined $k32CreateDir;
+                        $k32CreateDir = new Win32::API('KERNEL32', 'CreateDirectoryW', 'PP', 'I');
+                        unless ($k32CreateDir) {
+                            $self->Warn('Error calling Win32::API::CreateDirectoryW');
+                            $k32CreateDir = 0;
+                            return -1;
+                        }
+                    }
+                    $k32CreateDir->Call($d2, 0) or return -1;
+                } else {
+                    mkdir($d2, 0777) or return -1;
+                }
                 $rtnVal = 1;
             }
@@ -2447,17 +3366,27 @@
 #------------------------------------------------------------------------------
 # Copy file attributes from one file to another
-# Inputs: 0) source file name, 1) destination file name
+# Inputs: 0) ExifTool ref, 1) source file name, 2) destination file name
 # Notes: eventually add support for extended attributes?
-sub CopyFileAttrs($$)
-{
-    my ($src, $dst) = @_;
+sub CopyFileAttrs($$$)
+{
+    my ($self, $src, $dst) = @_;
     my ($mode, $uid, $gid) = (stat($src))[2, 4, 5];
-    eval { chmod($mode & 07777, $dst) } if defined $mode;
-    eval { chown($uid, $gid, $dst) } if defined $uid and defined $gid;
-}
-
-#------------------------------------------------------------------------------
-# Get new file name
-# Inputs: 0) existing name, 1) new name
+    # copy file attributes unless we already set them
+    if (defined $mode and not defined $self->GetNewValue('FilePermissions')) {
+        eval { chmod($mode & 07777, $dst) };
+    }
+    my $newUid = $self->GetNewValue('FileUserID');
+    my $newGid = $self->GetNewValue('FileGroupID');
+    if (defined $uid and defined $gid and (not defined $newUid or not defined $newGid)) {
+        defined $newGid and $gid = $newGid;
+        defined $newUid and $uid = $newUid;
+        eval { chown($uid, $gid, $dst) };
+    }
+}
+
+#------------------------------------------------------------------------------
+# Get new file path name
+# Inputs: 0) existing name (may contain directory),
+#         1) new file name, new directory, or new path (dir+name)
 # Returns: new file path name
 sub GetNewFileName($$)
@@ -2478,5 +3407,5 @@
 # Inputs: 0) hash reference (keys are tag keys), 1) tag name
 # Returns: next available tag key
-sub NextTagKey($$)
+sub NextFreeTagKey($$)
 {
     my ($info, $tag) = @_;
@@ -2501,8 +3430,12 @@
         $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 {
-        my $qval = quotemeta $val;
+        my $qval = $val;
+        $qval =~ s/\s+$//;      # remove trailing whitespace
+        $qval = quotemeta $qval;
         my @patterns = (
             "^$qval\$",         # exact match
@@ -2533,5 +3466,11 @@
         unless ($found) {
             # call OTHER conversion routine if available
-            $val = $$conv{OTHER} ? &{$$conv{OTHER}}($val,1,$conv) : undef;
+            if ($$conv{OTHER}) {
+                local $SIG{'__WARN__'} = \&SetWarning;
+                undef $evalWarning;
+                $val = &{$$conv{OTHER}}($val,1,$conv);
+            } else {
+                $val = undef;
+            }
             $multi = 1 if $matches > 1;
         }
@@ -2543,12 +3482,13 @@
 #------------------------------------------------------------------------------
 # Return true if we are deleting or overwriting the specified tag
-# Inputs: 0) new value hash reference
-#         1) optional tag value (before RawConv) if deleting specific values
+# Inputs: 0) ExifTool object ref, 1) new value hash reference
+#         2) optional tag value (before RawConv) if deleting specific values
 # Returns: >0 - tag should be overwritten
 #          =0 - the tag should be preserved
 #          <0 - not sure, we need the value to know
-sub IsOverwriting($;$)
-{
-    my ($nvHash, $val) = @_;
+# Notes: $$nvHash{Value} is updated with the new value when shifting a value
+sub IsOverwriting($$;$)
+{
+    my ($self, $nvHash, $val) = @_;
     return 0 unless $nvHash;
     # overwrite regardless if no DelValues specified
@@ -2566,9 +3506,9 @@
         undef $evalWarning;
         if (ref $conv eq 'CODE') {
-            $val = &$conv($val, $$nvHash{Self});
+            $val = &$conv($val, $self);
         } else {
-            my $self = $$nvHash{Self};
+            my ($priority, @grps);
             my $tag = $$tagInfo{Name};
-            #### eval RawConv ($self, $val, $tag, $tagInfo)
+            #### eval RawConv ($self, $val, $tag, $tagInfo, $priority, @grps)
             $val = eval $conv;
             $@ and $evalWarning = $@;
@@ -2576,12 +3516,44 @@
         return -1 unless defined $val;
     }
-    # apply time shift if necessary
+    # do not overwrite if only creating
+    return 0 if $$nvHash{CreateOnly};
+    # apply time/number shift if necessary
     if (defined $shift) {
+        my $shiftType = $$tagInfo{Shift};
+        unless ($shiftType and $shiftType eq 'Time') {
+            unless (IsFloat($val)) {
+                # do the ValueConv to try to get a number
+                my $conv = $$tagInfo{ValueConv};
+                if (defined $conv) {
+                    local $SIG{'__WARN__'} = \&SetWarning;
+                    undef $evalWarning;
+                    if (ref $conv eq 'CODE') {
+                        $val = &$conv($val, $self);
+                    } elsif (not ref $conv) {
+                        #### eval ValueConv ($val, $self)
+                        $val = eval $conv;
+                        $@ and $evalWarning = $@;
+                    }
+                    if ($evalWarning) {
+                        $self->Warn("ValueConv $$tagInfo{Name}: " . CleanWarning());
+                        return 0;
+                    }
+                }
+                unless (defined $val and IsFloat($val)) {
+                    $self->Warn("Can't shift $$tagInfo{Name} (not a number)");
+                    return 0;
+                }
+            }
+            $shiftType = 'Number';  # allow any number to be shifted
+        }
         require 'Image/ExifTool/Shift.pl';
-        my $err = ApplyShift($$tagInfo{Shift}, $shift, $val, $nvHash);
+        my $err = $self->ApplyShift($shiftType, $shift, $val, $nvHash);
         if ($err) {
-            $nvHash->{Self}->Warn("$err when shifting $$tagInfo{Name}");
+            $self->Warn("$err when shifting $$tagInfo{Name}");
             return 0;
         }
+        # ensure that the shifted value is valid and reformat if necessary
+        my $checkVal = $self->GetNewValue($nvHash);
+        return 0 unless defined $checkVal;
         # don't bother overwriting if value is the same
         return 0 if $val eq $$nvHash{Value}[0];
@@ -2597,13 +3569,4 @@
 
 #------------------------------------------------------------------------------
-# Return true if we are creating the specified tag even if it didn't exist before
-# Inputs: 0) new value hash reference
-# Returns: true if we should add the tag
-sub IsCreating($)
-{
-    return $_[0]{IsCreating};
-}
-
-#------------------------------------------------------------------------------
 # Get write group for specified tag
 # Inputs: 0) new value hash reference
@@ -2621,5 +3584,5 @@
 {
     my ($self, $tagInfo, $writeGroup) = @_;
-    return $writeGroup unless $writeGroup =~ /^(MakerNotes|XMP|Composite)$/;
+    return $writeGroup unless $writeGroup =~ /^(MakerNotes|XMP|Composite|QuickTime)$/;
     return $self->GetGroup($tagInfo, 1);
 }
@@ -2628,11 +3591,14 @@
 # Get new value hash for specified tagInfo/writeGroup
 # Inputs: 0) ExifTool object reference, 1) reference to tag info hash
-#         2) Write group name, 3) Options: 'delete' or 'create'
+#         2) Write group name, 3) Options: 'delete' or 'create' new value hash
+#         4) optional ProtectSaved value, 5) true if we are deleting a value
 # Returns: new value hash reference for specified write group
 #          (or first new value hash in linked list if write group not specified)
-sub GetNewValueHash($$;$$)
+# Notes: May return undef when 'create' is used with ProtectSaved
+sub GetNewValueHash($$;$$$$)
 {
     my ($self, $tagInfo, $writeGroup, $opts) = @_;
-    my $nvHash = $self->{NEW_VALUE}{$tagInfo};
+    return undef unless $tagInfo;
+    my $nvHash = $$self{NEW_VALUE}{$tagInfo};
 
     my %opts;   # quick lookup for options
@@ -2642,14 +3608,24 @@
     if ($writeGroup) {
         # find the new value in the list with the specified write group
-        while ($nvHash and $nvHash->{WriteGroup} ne $writeGroup) {
-            $nvHash = $nvHash->{Next};
+        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};
         }
     }
     # remove this entry if deleting, or if creating a new entry and
     # this entry is marked with "Save" flag
-    if (defined $nvHash and ($opts{'delete'} or
-        ($opts{'create'} and $nvHash->{Save})))
-    {
-        if ($opts{'delete'}) {
+    if (defined $nvHash and ($opts{'delete'} or ($opts{'create'} and $$nvHash{Save}))) {
+        my $protect = (defined $_[4] and defined $$nvHash{Save} and $$nvHash{Save} > $_[4]);
+        # this is a bit tricky:  we want to add to a protected nvHash only if we
+        # are adding a conditional delete ($_[5] true or DelValue with no Shift)
+        # or accumulating List items (NoReplace true)
+        if ($protect and not ($opts{create} and ($$nvHash{NoReplace} or $_[5] or
+            ($$nvHash{DelValue} and not defined $$nvHash{Shift}))))
+        {
+            return undef;   # honour ProtectSaved value by not writing this tag
+        } elsif ($opts{'delete'}) {
             $self->RemoveNewValueHash($nvHash, $tagInfo);
             undef $nvHash;
@@ -2657,15 +3633,16 @@
             # save a copy of this new value hash
             my %copy = %$nvHash;
+            # make copy of Value and DelValue lists
             my $key;
-            # make copy of Value and DelValue lists
             foreach $key (keys %copy) {
                 next unless ref $copy{$key} eq 'ARRAY';
                 $copy{$key} = [ @{$copy{$key}} ];
             }
-            my $saveHash = $self->{SAVE_NEW_VALUE};
+            my $saveHash = $$self{SAVE_NEW_VALUE};
             # add to linked list of saved new value hashes
-            $copy{Next} = $saveHash->{$tagInfo};
-            $saveHash->{$tagInfo} = \%copy;
-            delete $nvHash->{Save};   # don't save it again
+            $copy{Next} = $$saveHash{$tagInfo};
+            $$saveHash{$tagInfo} = \%copy;
+            delete $$nvHash{Save}; # don't save it again
+            $$nvHash{AddBefore} = scalar @{$$nvHash{Value}} if $protect and $$nvHash{Value};
         }
     }
@@ -2675,13 +3652,13 @@
             TagInfo => $tagInfo,
             WriteGroup => $writeGroup,
-            Self => $self,
+            IsNVH => 1, # set flag so we can recognize a new value hash
         };
         # add entry to our NEW_VALUE hash
-        if ($self->{NEW_VALUE}{$tagInfo}) {
+        if ($$self{NEW_VALUE}{$tagInfo}) {
             # add to end of linked list
-            my $lastHash = LastInList($self->{NEW_VALUE}{$tagInfo});
-            $lastHash->{Next} = $nvHash;
+            my $lastHash = LastInList($$self{NEW_VALUE}{$tagInfo});
+            $$lastHash{Next} = $nvHash;
         } else {
-            $self->{NEW_VALUE}{$tagInfo} = $nvHash;
+            $$self{NEW_VALUE}{$tagInfo} = $nvHash;
         }
     }
@@ -2711,6 +3688,9 @@
         $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();
+        my $writeProc = $$table{WRITE_PROC};
+        if ($writeProc) {
+            no strict 'refs';
+            &$writeProc();
+        }
         # recursively scan through tables in subdirectories
         foreach (TagTableKeys($table)) {
@@ -2736,24 +3716,24 @@
 {
     my ($self, $nvHash, $tagInfo) = @_;
-    my $firstHash = $self->{NEW_VALUE}{$tagInfo};
+    my $firstHash = $$self{NEW_VALUE}{$tagInfo};
     if ($nvHash eq $firstHash) {
         # remove first entry from linked list
-        if ($nvHash->{Next}) {
-            $self->{NEW_VALUE}{$tagInfo} = $nvHash->{Next};
+        if ($$nvHash{Next}) {
+            $$self{NEW_VALUE}{$tagInfo} = $$nvHash{Next};
         } else {
-            delete $self->{NEW_VALUE}{$tagInfo};
+            delete $$self{NEW_VALUE}{$tagInfo};
         }
     } else {
         # find the list element pointing to this hash
-        $firstHash = $firstHash->{Next} while $firstHash->{Next} ne $nvHash;
+        $firstHash = $$firstHash{Next} while $$firstHash{Next} ne $nvHash;
         # remove from linked list
-        $firstHash->{Next} = $nvHash->{Next};
+        $$firstHash{Next} = $$nvHash{Next};
     }
     # save the existing entry if necessary
-    if ($nvHash->{Save}) {
-        my $saveHash = $self->{SAVE_NEW_VALUE};
+    if ($$nvHash{Save}) {
+        my $saveHash = $$self{SAVE_NEW_VALUE};
         # add to linked list of saved new value hashes
-        $nvHash->{Next} = $saveHash->{$tagInfo};
-        $saveHash->{$tagInfo} = $nvHash;
+        $$nvHash{Next} = $$saveHash{$tagInfo};
+        $$saveHash{$tagInfo} = $nvHash;
     }
 }
@@ -2766,5 +3746,5 @@
     my ($self, $group) = @_;
 
-    return unless $self->{NEW_VALUE};
+    return unless $$self{NEW_VALUE};
 
     # make list of all groups we must remove
@@ -2773,16 +3753,16 @@
 
     my ($out, @keys, $hashKey);
-    $out = $self->{OPTIONS}{TextOut} if $self->{OPTIONS}{Verbose} > 1;
+    $out = $$self{OPTIONS}{TextOut} if $$self{OPTIONS}{Verbose} > 1;
 
     # loop though all new values, and remove any in this group
-    @keys = keys %{$self->{NEW_VALUE}};
+    @keys = keys %{$$self{NEW_VALUE}};
     foreach $hashKey (@keys) {
-        my $nvHash = $self->{NEW_VALUE}{$hashKey};
+        my $nvHash = $$self{NEW_VALUE}{$hashKey};
         # loop through each entry in linked list
         for (;;) {
-            my $nextHash = $nvHash->{Next};
-            my $tagInfo = $nvHash->{TagInfo};
+            my $nextHash = $$nvHash{Next};
+            my $tagInfo = $$nvHash{TagInfo};
             my ($grp0,$grp1) = $self->GetGroup($tagInfo);
-            my $wgrp = $nvHash->{WriteGroup};
+            my $wgrp = $$nvHash{WriteGroup};
             # use group1 if write group is not specific
             $wgrp = $grp1 if $wgrp eq $grp0;
@@ -2805,10 +3785,10 @@
     my ($self, $tagTablePtr) = @_;
     my @tagInfoList;
-    my $nv = $self->{NEW_VALUE};
+    my $nv = $$self{NEW_VALUE};
     if ($nv) {
         my $hashKey;
         foreach $hashKey (keys %$nv) {
-            my $tagInfo = $nv->{$hashKey}{TagInfo};
-            next if $tagTablePtr and $tagTablePtr ne $tagInfo->{Table};
+            my $tagInfo = $$nv{$hashKey}{TagInfo};
+            next if $tagTablePtr and $tagTablePtr ne $$tagInfo{Table};
             push @tagInfoList, $tagInfo;
         }
@@ -2821,14 +3801,15 @@
 # Inputs: 0) ExifTool object reference, 1-N) tag table pointers
 # Returns: hash reference
+# Notes: returns only one tagInfo ref for each conditional list
 sub GetNewTagInfoHash($@)
 {
     my $self = shift;
     my (%tagInfoHash, $hashKey);
-    my $nv = $self->{NEW_VALUE};
+    my $nv = $$self{NEW_VALUE};
     while ($nv) {
         my $tagTablePtr = shift || last;
         foreach $hashKey (keys %$nv) {
-            my $tagInfo = $nv->{$hashKey}{TagInfo};
-            next if $tagTablePtr and $tagTablePtr ne $tagInfo->{Table};
+            my $tagInfo = $$nv{$hashKey}{TagInfo};
+            next if $tagTablePtr and $tagTablePtr ne $$tagInfo{Table};
             $tagInfoHash{$$tagInfo{TagID}} = $tagInfo;
         }
@@ -2846,10 +3827,10 @@
 {
     my ($self, $tagTablePtr, $parent) = @_;
-    $parent or $parent = $tagTablePtr->{GROUPS}{0};
+    $parent or $parent = $$tagTablePtr{GROUPS}{0};
     my $tagID;
     my %addDirHash;
     my %editDirHash;
-    my $addDirs = $self->{ADD_DIRS};
-    my $editDirs = $self->{EDIT_DIRS};
+    my $addDirs = $$self{ADD_DIRS};
+    my $editDirs = $$self{EDIT_DIRS};
     foreach $tagID (TagTableKeys($tagTablePtr)) {
         my @infoArray = GetTagInfoList($tagTablePtr,$tagID);
@@ -2860,9 +3841,9 @@
             # (take directory name from SubDirectory DirName if it exists,
             #  otherwise Group0 name of SubDirectory TagTable or tag Group1 name)
-            my $dirName = $tagInfo->{SubDirectory}{DirName};
+            my $dirName = $$tagInfo{SubDirectory}{DirName};
             unless ($dirName) {
                 # use tag name for directory name and save for next time
                 $dirName = $$tagInfo{Name};
-                $tagInfo->{SubDirectory}{DirName} = $dirName;
+                $$tagInfo{SubDirectory}{DirName} = $dirName;
             }
             # save this directory information if we are writing it
@@ -2879,5 +3860,5 @@
 #------------------------------------------------------------------------------
 # Get localized version of tagInfo hash (used by MIE, XMP, PNG and QuickTime)
-# Inputs: 0) tagInfo hash ref, 1) locale code (ie. "en_CA" for MIE)
+# Inputs: 0) tagInfo hash ref, 1) locale code (eg. "en_CA" for MIE)
 # Returns: new tagInfo hash ref, or undef if invalid
 # - sets LangCode member in new tagInfo
@@ -2897,4 +3878,5 @@
                            " ($langCode)",
             LangCode => $langCode,
+            SrcTagInfo => $tagInfo, # save reference to original tagInfo
         };
         AddTagToTable($table, $tagID, $langInfo);
@@ -2905,14 +3887,16 @@
 #------------------------------------------------------------------------------
 # initialize ADD_DIRS and EDIT_DIRS hashes for all directories that need
-# need to be created or will have tags changed in them
+# 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
-# 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)
-sub InitWriteDirs($$;$)
-{
-    my ($self, $fileType, $preferredGroup) = @_;
-    my $editDirs = $self->{EDIT_DIRS} = { };
-    my $addDirs = $self->{ADD_DIRS} = { };
+#         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($$;$$)
+{
+    my ($self, $fileType, $preferredGroup, $altGroup) = @_;
+    my $editDirs = $$self{EDIT_DIRS} = { };
+    my $addDirs = $$self{ADD_DIRS} = { };
     my $fileDirs = $dirMap{$fileType};
     unless ($fileDirs) {
@@ -2930,20 +3914,24 @@
         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);
+            my $isCreating = $$nvHash{IsCreating};
+            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
-            my $dirName = $nvHash->{WriteGroup};
+            my $dirName = $$nvHash{WriteGroup};
             # remove MIE copy number(s) if they exist
             if ($dirName =~ /^MIE\d*(-[a-z]+)?\d*$/i) {
@@ -2951,4 +3939,20 @@
             }
             my @dirNames;
+            # 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 PNG FixBase)) {
+                        next unless $val =~ /\b($_|All)\b/i;
+                        push @dirNames, $_;
+                        push @dirNames, 'EXIF' if $_ eq 'FixBase';
+                        $$self{FORCE_WRITE}{$_} = 1;
+                    }
+                }
+                $dirName = shift @dirNames;
+            } elsif ($dirName eq 'QuickTime') {
+                # write to specific QuickTime group
+                $dirName = $self->GetGroup($tagInfo, 1);
+            }
             while ($dirName) {
                 my $parent = $$fileDirs{$dirName};
@@ -2963,7 +3967,7 @@
         }
     }
-    if (%{$self->{DEL_GROUP}}) {
+    if (%{$$self{DEL_GROUP}}) {
         # add delete groups to list of edited groups
-        foreach (keys %{$self->{DEL_GROUP}}) {
+        foreach (keys %{$$self{DEL_GROUP}}) {
             next if /^-/;   # ignore excluded groups
             my $dirName = $_;
@@ -2990,10 +3994,10 @@
     }
 
-    if ($self->{OPTIONS}{Verbose}) {
-        my $out = $self->{OPTIONS}{TextOut};
+    if ($$self{OPTIONS}{Verbose}) {
+        my $out = $$self{OPTIONS}{TextOut};
         print $out "  Editing tags in: ";
         foreach (sort keys %$editDirs) { print $out "$_ "; }
         print $out "\n";
-        return unless $self->{OPTIONS}{Verbose} > 1;
+        return unless $$self{OPTIONS}{Verbose} > 1;
         print $out "  Creating tags in: ";
         foreach (sort keys %$addDirs) { print $out "$_ "; }
@@ -3006,24 +4010,33 @@
 # Inputs: 0) ExifTool object reference, 1) source directory information reference
 #         2) tag table reference, 3) optional reference to writing procedure
-# Returns: New directory data or undefined on error
+# Returns: New directory data or undefined on error (or empty string to delete directory)
 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};
+    $out = $$self{OPTIONS}{TextOut} if $$self{OPTIONS}{Verbose};
     # set directory name from default group0 name if not done already
     my $dirName = $$dirInfo{DirName};
     my $dataPt = $$dirInfo{DataPt};
-    my $grp0 = $tagTablePtr->{GROUPS}{0};
+    my $grp0 = $$tagTablePtr{GROUPS}{0};
     $dirName or $dirName = $$dirInfo{DirName} = $grp0;
-    if (%{$self->{DEL_GROUP}}) {
-        my $delGroup = $self->{DEL_GROUP};
+    if (%{$$self{DEL_GROUP}}) {
+        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)
@@ -3034,5 +4047,5 @@
                     # allow anything to be deleted from PostScript files
                 } elsif ($grp1 eq 'IFD0') {
-                    my $type = $self->{TIFF_TYPE} || $self->{FILE_TYPE};
+                    my $type = $$self{TIFF_TYPE} || $$self{FILE_TYPE};
                     $$delGroup{IFD0} and $self->Warn("Can't delete IFD0 from $type",1);
                     undef $grp1;
@@ -3043,8 +4056,9 @@
             if ($grp1) {
                 if ($dataPt or $$dirInfo{RAF}) {
-                    ++$self->{CHANGED};
+                    ++$$self{CHANGED};
                     $out and print $out "  Deleting $grp1\n";
+                    $self->Warn('ICC_Profile deleted. Image colors may be affected') if $grp1 eq 'ICC_Profile';
                     # can no longer validate TIFF_END if deleting an entire IFD
-                    delete $self->{TIFF_END} if $dirName =~ /IFD/;
+                    delete $$self{TIFF_END} if $dirName =~ /IFD/;
                 }
                 # don't add back into the wrong location
@@ -3056,21 +4070,26 @@
                     # also check grandparent because some routines create 2 levels in 1
                     my $right2 = $$self{ADD_DIRS}{$right} || '';
-                    if (not $$dirInfo{Parent} or $$dirInfo{Parent} eq $right or
-                        $$dirInfo{Parent} eq $right2)
-                    {
-                        # create new empty directory
+                    my $parent = $$dirInfo{Parent};
+                    if (not $parent or $parent eq $right or $parent eq $right2) {
+                        # prevent duplicate directories from being recreated at the same path
+                        my $path = join '-', @{$$self{PATH}}, $dirName;
+                        $$self{Recreated} or $$self{Recreated} = { };
+                        if ($$self{Recreated}{$path}) {
+                            my $p = $parent ? " in $parent" : '';
+                            $self->Warn("Not recreating duplicate $grp1$p",1);
+                            return '';
+                        }
+                        $$self{Recreated}{$path} = 1;
+                        # empty the directory
                         my $data = '';
-                        my %dirInfo = (
-                            DirName    => $$dirInfo{DirName},
-                            Parent     => $$dirInfo{Parent},
-                            DirStart   => 0,
-                            DirLen     => 0,
-                            DataPt     => \$data,
-                            NewDataPos => $$dirInfo{NewDataPos},
-                            Fixup      => $$dirInfo{Fixup},
-                        );
-                        $dirInfo = \%dirInfo;
+                        $$dirInfo{DataPt}   = \$data;
+                        $$dirInfo{DataLen}  = 0;
+                        $$dirInfo{DirStart} = 0;
+                        $$dirInfo{DirLen}   = 0;
+                        delete $$dirInfo{RAF};
+                        delete $$dirInfo{Base};
+                        delete $$dirInfo{DataPos};
                     } else {
-                        $self->Warn("Not recreating $grp1 in $$dirInfo{Parent} (should be in $right)",1);
+                        $self->Warn("Not recreating $grp1 in $parent (should be in $right)",1);
                         return '';
                     }
@@ -3083,4 +4102,7 @@
     # use default proc from tag table if no proc specified
     $writeProc or $writeProc = $$tagTablePtr{WRITE_PROC} or return undef;
+
+    # are we rewriting a pre-existing directory?
+    my $isRewriting = ($$dirInfo{DirLen} or (defined $dataPt and length $$dataPt) or $$dirInfo{RAF});
 
     # copy or delete new directory as a block if specified
@@ -3088,5 +4110,7 @@
     $blockName = 'EXIF' if $blockName eq 'IFD0';
     my $tagInfo = $Image::ExifTool::Extra{$blockName} || $$dirInfo{TagInfo};
-    while ($tagInfo and ($nvHash = $self->{NEW_VALUE}{$tagInfo}) and IsOverwriting($nvHash)) {
+    while ($tagInfo and ($nvHash = $$self{NEW_VALUE}{$tagInfo}) and
+        $self->IsOverwriting($nvHash) and not ($$nvHash{CreateOnly} and $isRewriting))
+    {
         # protect against writing EXIF to wrong file types, etc
         if ($blockName eq 'EXIF') {
@@ -3095,15 +4119,20 @@
                 last;
             }
-            unless ($writeProc eq \&Image::ExifTool::WriteTIFF) {
-                # this could happen if we called WriteDirectory for an EXIF directory
-                # without going through WriteTIFF as the WriteProc, which would be bad
-                # because the EXIF block could end up with two TIFF headers
-                $self->Warn('Internal error writing EXIF -- please report');
-                last;
-            }
-        }
+            # 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
+            last unless $writeProc eq \&Image::ExifTool::WriteTIFF;
+        }
+        last unless $self->IsOverwriting($nvHash, $dataPt ? $$dataPt : '');
         my $verb = 'Writing';
-        my $newVal = GetNewValues($nvHash);
+        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 = '';
@@ -3111,28 +4140,37 @@
         $$dirInfo{BlockWrite} = 1;  # set flag indicating we did a block write
         $out and print $out "  $verb $blockName as a block\n";
-        ++$self->{CHANGED};
+        ++$$self{CHANGED};
         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')) {
-            if ($self->Error("$dirName pointer references previous $self->{PROCESSED}{$addr} directory", 1)) {
+        if ($$self{PROCESSED}{$addr} and ($dirName ne 'ICC_Profile' or $$self{TIFF_TYPE} ne 'IIQ')) {
+            if (defined $$dirInfo{DirLen} and not $$dirInfo{DirLen} and $dirName ne $$self{PROCESSED}{$addr}) {
+                # it is hypothetically possible to have 2 different directories
+                # with the same address if one has a length of zero
+            } elsif ($self->Error("$dirName pointer references previous $$self{PROCESSED}{$addr} directory", 2)) {
                 return undef;
             } else {
                 $self->Warn("Deleting duplicate $dirName directory");
                 $out and print $out "  Deleting $dirName\n";
-                return '';  # delete the duplicate directory
-            }
-        }
-        $self->{PROCESSED}{$addr} = $dirName;
-    }
-    my $oldDir = $self->{DIR_NAME};
-    my $isRewriting = ($$dirInfo{DirLen} or (defined $dataPt and length $$dataPt) or $$dirInfo{RAF});
+                # delete the duplicate directory (don't recreate it when writing new
+                # tags to prevent propagating a duplicate IFD in cases like when the
+                # same ExifIFD exists in both IFD0 and IFD1)
+                return '';
+            }
+        } else {
+            $$self{PROCESSED}{$addr} = $dirName;
+        }
+    }
+    my $oldDir = $$self{DIR_NAME};
+    my @save = @$self{'Compression','SubfileType'};
     my $name;
     if ($out) {
         $name = ($dirName eq 'MakerNotes' and $$dirInfo{TagInfo}) ?
-                 $dirInfo->{TagInfo}{Name} : $dirName;
+                 $$dirInfo{TagInfo}{Name} : $dirName;
         if (not defined $oldDir or $oldDir ne $name) {
             my $verb = $isRewriting ? 'Rewriting' : 'Creating';
@@ -3141,13 +4179,18 @@
     }
     my $saveOrder = GetByteOrder();
-    my $oldChanged = $self->{CHANGED};
-    $self->{DIR_NAME} = $dirName;
-    push @{$self->{PATH}}, $$dirInfo{DirName};
+    my $oldChanged = $$self{CHANGED};
+    $$self{DIR_NAME} = $dirName;
+    push @{$$self{PATH}}, $dirName;
     $$dirInfo{IsWriting} = 1;
-    my $newData = &$writeProc($self, $dirInfo, $tagTablePtr);
-    pop @{$self->{PATH}};
+    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);
-    $self->{DIR_NAME} = $oldDir;
+    $$self{CHANGED} = $oldChanged unless defined $newData and (length($newData) or $isRewriting);
+    $$self{DIR_NAME} = $oldDir;
+    @$self{'Compression','SubfileType'} = @save;
     SetByteOrder($saveOrder);
     print $out "  Deleting $name\n" if $out and defined $newData and not length $newData;
@@ -3173,4 +4216,11 @@
     my $lo = Get32u($dataPt, $pos + 4 - $pt);
     return $hi * 4294967296 + $lo;
+}
+sub GetFixed64s($$)
+{
+    my ($dataPt, $pos) = @_;
+    my $val = Get64s($dataPt, $pos) / 4294967296;
+    # remove insignificant digits
+    return int($val * 1e10 + ($val>0 ? 0.5 : -0.5)) / 1e10;
 }
 # Decode extended 80-bit float used by Apple SANE and Intel 8087
@@ -3191,6 +4241,7 @@
 # Inputs: 0) data reference, 1) length or undef, 2-N) Options:
 # Options: Start => offset to start of data (default=0)
-#          Addr => address to print for data start (default=DataPos+Start)
-#          DataPos => address of start of data
+#          Addr => address to print for data start (default=DataPos+Base+Start)
+#          DataPos => position of data within block (relative to Base)
+#          Base => base offset for pointers from start of file
 #          Width => width of printout (bytes, default=16)
 #          Prefix => prefix to print at start of line (default='')
@@ -3213,5 +4264,5 @@
     $len = $opts{Len} if defined $opts{Len};
 
-    $addr = $start + ($opts{DataPos} || 0) unless defined $addr;
+    $addr = $start + ($opts{DataPos} || 0) + ($opts{Base} || 0) unless defined $addr;
     $len = $datLen unless defined $len;
     if ($maxLen and $len > $maxLen) {
@@ -3238,5 +4289,5 @@
         print $out "[$dat]\n";
     }
-    $more and printf $out "$prefix    [snip $more bytes]\n";
+    $more and print $out "$prefix    [snip $more bytes]\n";
 }
 
@@ -3250,4 +4301,5 @@
 #        DataPt => reference to value data block
 #        DataPos => location of data block in file
+#        Base => base added to all offsets
 #        Size => length of value data within block
 #        Format => value format string
@@ -3259,6 +4311,6 @@
 {
     my ($self, $tagID, $tagInfo, %parms) = @_;
-    my $verbose = $self->{OPTIONS}{Verbose};
-    my $out = $self->{OPTIONS}{TextOut};
+    my $verbose = $$self{OPTIONS}{Verbose};
+    my $out = $$self{OPTIONS}{TextOut};
     my ($tag, $line, $hexID);
 
@@ -3285,5 +4337,5 @@
     my $size = $parms{Size};
     $size = length $$dataPt unless defined $size or not $dataPt;
-    my $indent = $self->{INDENT};
+    my $indent = $$self{INDENT};
 
     # Level 1: print tag/value information
@@ -3300,6 +4352,8 @@
     } else {
         my $maxLen = 90 - length($line);
-        if (defined $parms{Value}) {
-            $line .= ' = ' . $self->Printable($parms{Value}, $maxLen);
+        my $val = $parms{Value};
+        if (defined $val) {
+            $val = '[' . join(',',@$val) . ']' if ref $val eq 'ARRAY';
+            $line .= ' = ' . $self->Printable($val, $maxLen);
         } elsif ($dataPt) {
             my $start = $parms{Start} || 0;
@@ -3318,5 +4372,5 @@
         } else {
             $tagID =~ s/([\0-\x1f\x7f-\xff])/sprintf('\\x%.2x',ord $1)/ge;
-            $line .= "'$tagID'";
+            $line .= "'${tagID}'";
         }
         $line .= $parms{Extra} if defined $parms{Extra};
@@ -3339,5 +4393,5 @@
 
     # Level 3: do hex dump of value
-    if ($verbose > 2 and $parms{DataPt}) {
+    if ($verbose > 2 and $parms{DataPt} and (not $tagInfo or not $$tagInfo{ReadFromRAF})) {
         $parms{Out} = $out;
         $parms{Prefix} = $indent;
@@ -3359,6 +4413,6 @@
     my $trailer = $$dirInfo{DirName} || 'Unknown';
     my $pos = $$dirInfo{DataPos};
-    my $verbose = $self->{OPTIONS}{Verbose};
-    my $htmlDump = $self->{HTML_DUMP};
+    my $verbose = $$self{OPTIONS}{Verbose};
+    my $htmlDump = $$self{HTML_DUMP};
     my ($buff, $buf2);
     my $size = $$dirInfo{DirLen};
@@ -3380,5 +4434,5 @@
             last;
         }
-        my $out = $self->{OPTIONS}{TextOut};
+        my $out = $$self{OPTIONS}{TextOut};
         printf $out "$trailer trailer (%d bytes at offset 0x%.4x):\n", $size, $pos;
         last unless $verbose > 2;
@@ -3420,6 +4474,6 @@
     my $endPos = $pos + $$dirInfo{DirLen};
     # account for preview/MPF image trailer
-    my $prePos = $self->{VALUE}{PreviewImageStart} || $$self{PreviewImageStart};
-    my $preLen = $self->{VALUE}{PreviewImageLength} || $$self{PreviewImageLength};
+    my $prePos = $$self{VALUE}{PreviewImageStart} || $$self{PreviewImageStart};
+    my $preLen = $$self{VALUE}{PreviewImageLength} || $$self{PreviewImageLength};
     my $tag = 'PreviewImage';
     my $mpImageNum = 0;
@@ -3431,10 +4485,10 @@
         # look for MPF images (in the the proper order)
         ++$mpImageNum;
-        $prePos = $self->{VALUE}{"MPImageStart ($mpImageNum)"};
+        $prePos = $$self{VALUE}{"MPImageStart ($mpImageNum)"};
         if (defined $prePos) {
-            $preLen = $self->{VALUE}{"MPImageLength ($mpImageNum)"};
+            $preLen = $$self{VALUE}{"MPImageLength ($mpImageNum)"};
         } else {
-            $prePos = $self->{VALUE}{'MPImageStart'};
-            $preLen = $self->{VALUE}{'MPImageLength'};
+            $prePos = $$self{VALUE}{'MPImageStart'};
+            $preLen = $$self{VALUE}{'MPImageLength'};
             $lastOne = 1;
         }
@@ -3454,5 +4508,5 @@
         last unless $preLen;
         # dump image if verbose (it is htmlDump'd by ExtractImage)
-        if ($self->{OPTIONS}{Verbose}) {
+        if ($$self{OPTIONS}{Verbose}) {
             $$dirInfo{DirName} = $tag;
             $$dirInfo{DataPos} = $prePos;
@@ -3471,6 +4525,6 @@
 {
     my $element = shift;
-    while ($element->{Next}) {
-        $element = $element->{Next};
+    while ($$element{Next}) {
+        $element = $$element{Next};
     }
     return $element;
@@ -3478,26 +4532,6 @@
 
 #------------------------------------------------------------------------------
-# Print verbose directory information
-# Inputs: 0) ExifTool object reference, 1) directory name or dirInfo ref
-#         2) number of entries in directory (or 0 if unknown)
-#         3) optional size of directory in bytes
-sub VerboseDir($$;$$)
-{
-    my ($self, $name, $entries, $size) = @_;
-    return unless $self->{OPTIONS}{Verbose};
-    if (ref $name eq 'HASH') {
-        $size = $$name{DirLen} unless $size;
-        $name = $$name{Name} || $$name{DirName};
-    }
-    my $indent = substr($self->{INDENT}, 0, -2);
-    my $out = $self->{OPTIONS}{TextOut};
-    my $str = $entries ? " with $entries entries" : '';
-    $str .= ", $size bytes" if $size;
-    print $out "$indent+ [$name directory$str]\n";
-}
-
-#------------------------------------------------------------------------------
 # Print verbose value while writing
-# Inputs: 0) ExifTool object ref, 1) heading "ie. '+ IPTC:Keywords',
+# Inputs: 0) ExifTool object ref, 1) heading "eg. '+ IPTC:Keywords',
 #         2) value, 3) [optional] extra text after value
 sub VerboseValue($$$;$)
@@ -3505,9 +4539,9 @@
     return unless $_[0]{OPTIONS}{Verbose} > 1;
     my ($self, $str, $val, $xtra) = @_;
-    my $out = $self->{OPTIONS}{TextOut};
+    my $out = $$self{OPTIONS}{TextOut};
     $xtra or $xtra = '';
     my $maxLen = 81 - length($str) - length($xtra);
     $val = $self->Printable($val, $maxLen);
-    print $out "    $str = '$val'$xtra\n";
+    print $out "    $str = '${val}'$xtra\n";
 }
 
@@ -3591,4 +4625,96 @@
 
 #------------------------------------------------------------------------------
+# Generate a new, random GUID
+# Inputs: <none>
+# Returns: GUID string
+my $guidCount;
+sub NewGUID()
+{
+    my @tm = localtime time;
+    $guidCount = 0 unless defined $guidCount and ++$guidCount < 0x100;
+    return sprintf('%.4d%.2d%.2d%.2d%.2d%.2d%.2X%.4X%.4X%.4X%.4X',
+                   $tm[5]+1900, $tm[4]+1, $tm[3], $tm[2], $tm[1], $tm[0], $guidCount,
+                   $$ & 0xffff, rand(0x10000), rand(0x10000), rand(0x10000));
+}
+
+#------------------------------------------------------------------------------
+# Make TIFF header for raw data
+# Inputs: 0) width, 1) height, 2) num colour components, 3) bits, 4) resolution
+#         5) color-map data for palette-color image (8 or 16 bit)
+# Returns: TIFF header
+# Notes: Multi-byte data must be little-endian
+sub MakeTiffHeader($$$$;$$)
+{
+    my ($w, $h, $cols, $bits, $res, $cmap) = @_;
+    $res or $res = 72;
+    my $saveOrder = GetByteOrder();
+    SetByteOrder('II');
+    if (not $cmap) {
+        $cmap = '';
+    } elsif (length $cmap == 3 * 2**$bits) {
+        # convert to short
+        $cmap = pack 'v*', map { $_ | ($_<<8) } unpack 'C*', $cmap;
+    } elsif (length $cmap != 6 * 2**$bits) {
+        $cmap = '';
+    }
+    my $cmo = $cmap ? 12 : 0;   # offset due to ColorMap IFD entry
+    my $hdr =
+    "\x49\x49\x2a\0\x08\0\0\0\x0e\0" .                  # 0x00 14 menu entries:
+    "\xfe\x00\x04\0\x01\0\0\0\x00\0\0\0" .              # 0x0a SubfileType = 0
+    "\x00\x01\x04\0\x01\0\0\0" . Set32u($w) .           # 0x16 ImageWidth
+    "\x01\x01\x04\0\x01\0\0\0" . Set32u($h) .           # 0x22 ImageHeight
+    "\x02\x01\x03\0" . Set32u($cols) .                  # 0x2e BitsPerSample
+     Set32u($cols == 1 ? $bits : 0xb6 + $cmo) .
+    "\x03\x01\x03\0\x01\0\0\0\x01\0\0\0" .              # 0x3a Compression = 1
+    "\x06\x01\x03\0\x01\0\0\0" .                        # 0x46 PhotometricInterpretation
+     Set32u($cmap ? 3 : $cols == 1 ? 1 : 2) .
+    "\x11\x01\x04\0\x01\0\0\0" .                        # 0x52 StripOffsets
+     Set32u(0xcc + $cmo + length($cmap)) .
+    "\x15\x01\x03\0\x01\0\0\0" . Set32u($cols) .        # 0x5e SamplesPerPixel
+    "\x16\x01\x04\0\x01\0\0\0" . Set32u($h) .           # 0x6a RowsPerStrip
+    "\x17\x01\x04\0\x01\0\0\0" .                        # 0x76 StripByteCounts
+     Set32u($w * $h * $cols * int(($bits+7)/8)) .
+    "\x1a\x01\x05\0\x01\0\0\0" . Set32u(0xbc + $cmo) .  # 0x82 XResolution
+    "\x1b\x01\x05\0\x01\0\0\0" . Set32u(0xc4 + $cmo) .  # 0x8e YResolution
+    "\x1c\x01\x03\0\x01\0\0\0\x01\0\0\0" .              # 0x9a PlanarConfiguration = 1
+    "\x28\x01\x03\0\x01\0\0\0\x02\0\0\0" .              # 0xa6 ResolutionUnit = 2
+    ($cmap ?                                            # 0xb2 ColorMap [optional]
+    "\x40\x01\x03\0" . Set32u(3 * 2**$bits) . "\xd8\0\0\0" : '') .
+    "\0\0\0\0" .                                        # 0xb2+$cmo (no IFD1)
+    (Set16u($bits) x 3) .                               # 0xb6+$cmo BitsPerSample value
+    Set32u($res) . "\x01\0\0\0" .                       # 0xbc+$cmo XResolution = 72
+    Set32u($res) . "\x01\0\0\0" .                       # 0xc4+$cmo YResolution = 72
+    $cmap;                                              # 0xcc or 0xd8 (cmap and data go here)
+    SetByteOrder($saveOrder);
+    return $hdr;
+}
+
+#------------------------------------------------------------------------------
+# Return current time in EXIF format
+# Inputs: 0) [optional] ExifTool ref, 1) flag to include timezone (0 to disable,
+#            undef or 1 to include)
+# Returns: time string
+# - a consistent value is returned for each processed file
+sub TimeNow(;$$)
+{
+    my ($self, $tzFlag) = @_;
+    my $timeNow;
+    ref $self or $tzFlag = $self, $self = { };
+    if ($$self{Now}) {
+        $timeNow = $$self{Now}[0];
+    } else {
+        my $time = time();
+        my @tm = localtime $time;
+        my $tz = TimeZoneString(\@tm, $time);
+        $timeNow = sprintf("%4d:%.2d:%.2d %.2d:%.2d:%.2d",
+                    $tm[5]+1900, $tm[4]+1, $tm[3],
+                    $tm[2], $tm[1], $tm[0]);
+        $$self{Now} = [ $timeNow, $tz ];
+    }
+    $timeNow .= $$self{Now}[1] if $tzFlag or not defined $tzFlag;
+    return $timeNow;
+}
+
+#------------------------------------------------------------------------------
 # Inverse date/time print conversion (reformat to YYYY:mm:dd HH:MM:SS[.ss][+-HH:MM|Z])
 # Inputs: 0) ExifTool object ref, 1) Date/Time string, 2) timezone flag:
@@ -3599,30 +4725,92 @@
 # Returns: formatted date/time string (or undef and issues warning on error)
 # Notes: currently accepts different separators, but doesn't use DateFormat yet
+my $strptimeLib; # strptime library name if available
 sub InverseDateTime($$;$$)
 {
     my ($self, $val, $tzFlag, $dateOnly) = @_;
     my ($rtnVal, $tz);
+    my $fmt = $$self{OPTIONS}{DateFormat};
     # strip off timezone first if it exists
-    if ($val =~ s/([+-])(\d{1,2}):?(\d{2})$//i) {
+    if (not $fmt and $val =~ s/([+-])(\d{1,2}):?(\d{2})\s*(DST)?$//i) {
         $tz = sprintf("$1%.2d:$3", $2);
-    } elsif ($val =~ s/Z$//i) {
+    } elsif (not $fmt and $val =~ s/Z$//i) {
         $tz = 'Z';
     } else {
         $tz = '';
-    }
-    # strip of sub seconds
-    my $fs = $val =~ /(\.\d+)$/ ? $1 : '';
+        # allow special value of 'now'
+        return $self->TimeNow($tzFlag) if lc($val) eq 'now';
+    }
+    # only convert date if a format was specified and the date is recognizable
+    if ($fmt) {
+        unless (defined $strptimeLib) {
+            if (eval { require POSIX::strptime }) {
+                $strptimeLib = 'POSIX::strptime';
+            } elsif (eval { require Time::Piece }) {
+                $strptimeLib = 'Time::Piece';
+                # (call use_locale() to convert localized date/time,
+                #  only available in Time::Piece 1.32 and later)
+                eval { Time::Piece->use_locale() };
+            } else {
+                $strptimeLib = '';
+            }
+        }
+        my ($lib, $wrn, @a);
+TryLib: for ($lib=$strptimeLib; ; $lib='') {
+            if (not $lib) {
+                last unless $$self{OPTIONS}{StrictDate};
+                warn $wrn || "Install POSIX::strptime or Time::Piece for inverse date/time conversions\n";
+                return undef;
+            } 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);
+                };
+            }
+            if (defined $a[5] and length $a[5]) {
+                $a[5] += 1900; # add 1900 to year
+            } else {
+                $wrn = "Invalid date/time (no year) using $lib\n";
+                next;
+            }
+            ++$a[4] if defined $a[4] and length $a[4];  # add 1 to month
+            my $i;
+            foreach $i (0..4) {
+                if (not defined $a[$i] or not length $a[$i]) {
+                    if ($i < 2 or $dateOnly) { # (allow missing minutes/seconds)
+                        $a[$i] = '  ';
+                    } else {
+                        $wrn = "Incomplete date/time specification using $lib\n";
+                        next TryLib;
+                    }
+                } elsif (length($a[$i]) < 2) {
+                    $$a[$i] = "0$a[$i]";# pad to 2 digits if necessary
+                }
+            }
+            $val = join(':', @a[5,4,3]) . ' ' . join(':', @a[2,1,0]);
+            last;
+        }
+    }
     if ($val =~ /(\d{4})/g) {           # get YYYY
         my $yr = $1;
-        my @a = ($val =~ /\d{2}/g);     # get mm, dd, HH, and maybe MM, SS
+        my @a = ($val =~ /\d{1,2}/g);   # get mm, dd, HH, and maybe MM, SS
+        length($_) < 2 and $_ = "0$_" foreach @a;   # pad to 2 digits if necessary
         if (@a >= 3) {
             my $ss = $a[4];             # get SS
             push @a, '00' while @a < 5; # add MM, SS if not given
+            # get sub-seconds if they exist (must be after SS, and have leading ".")
+            my $fs = (@a > 5 and $val =~ /(\.\d+)\s*$/) ? $1 : '';
             # add/remove timezone if necessary
             if ($tzFlag) {
                 if (not $tz) {
-                    if (eval 'require Time::Local') {
+                    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);
@@ -3634,5 +4822,5 @@
                 $tz = $fs = ''; # remove timezone and sub-seconds
             }
-            if (defined $ss) {
+            if (defined $ss and $ss < 60) {
                 $ss = ":$ss";
             } elsif ($dateOnly) {
@@ -3642,4 +4830,14 @@
             }
             # construct properly formatted date/time string
+            if ($a[0] < 1 or $a[0] > 12) {
+                warn "Month '$a[0]' out of range 1..12\n";
+                return undef;
+            }
+            if ($a[1] < 1 or $a[1] > 31) {
+                warn "Day '$a[1]' out of range 1..31\n";
+                return undef;
+            }
+            $a[2] > 24 and warn("Hour '$a[2]' out of range 0..24\n"), return undef;
+            $a[3] > 59 and warn("Minutes '$a[3]' out of range 0..59\n"), return undef;
             $rtnVal = "$yr:$a[0]:$a[1] $a[2]:$a[3]$ss$fs$tz";
         } elsif ($dateOnly) {
@@ -3653,20 +4851,21 @@
 #------------------------------------------------------------------------------
 # 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($)
-{
-    my $self = shift;
+#  3) default byte order passed to this routine
+#  4) makenote byte order from last file read
+#  5) big endian
+sub SetPreferredByteOrder($;$)
+{
+    my ($self, $default) = @_;
     my $byteOrder = $self->Options('ByteOrder') ||
-                    $self->GetNewValues('ExifByteOrder') ||
-                    $self->{MAKER_NOTE_BYTE_ORDER} || 'MM';
+                    $self->GetNewValue('ExifByteOrder') ||
+                    $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';
+        warn "Invalid byte order '${byteOrder}'\n" if $self->Options('Verbose');
+        $byteOrder = $$self{MAKER_NOTE_BYTE_ORDER} || 'MM';
         SetByteOrder($byteOrder);
     }
@@ -3692,6 +4891,8 @@
 # Notes:
 # - the returned rational will be accurate to at least 8 significant figures if possible
-# - ie. an input of 3.14159265358979 returns a rational of 104348/33215,
+# - eg. an input of 3.14159265358979 returns a rational of 104348/33215,
 #   which equals    3.14159265392142 and is accurate to 10 significant figures
+# - the returned rational will be reduced to the lowest common denominator except when
+#   the input is a fraction in which case the input is returned unchanged
 # - these routines were a bit tricky, but fun to write!
 sub Rationalize($;$)
@@ -3741,4 +4942,14 @@
     return Set32u($val, @_);
 }
+sub Set64u(@)
+{
+    my $val = $_[0];
+    my $hi = int($val / 4294967296);
+    my $lo = Set32u($val - $hi * 4294967296);
+    $hi = Set32u($hi);
+    $val = GetByteOrder() eq 'MM' ? $hi . $lo : $lo . $hi;
+    $_[1] and substr(${$_[1]}, $_[2], length($val)) = $val;
+    return $val;
+}
 sub SetRational64u(@) {
     my ($numer,$denom) = Rationalize($_[0],0xffffffff);
@@ -3802,4 +5013,5 @@
     int32s => \&Set32s,
     int32u => \&Set32u,
+    int64u => \&Set64u,
     rational32s => \&SetRational32s,
     rational32u => \&SetRational32u,
@@ -3835,7 +5047,10 @@
 # write binary data value (with current byte ordering)
 # Inputs: 0) value, 1) format string
-#         2) optional number of values (1 or string length if not specified)
-#         3) optional data reference, 4) value offset
+#         2) number of values:
+#               undef = 1 for numerical types, or data length for string/undef types
+#                  -1 = number of space-delimited values in the input string
+#         3) optional data reference, 4) value offset (may be negative for bytes from end)
 # Returns: packed value (and sets value in data) or undef on error
+# Notes: May modify input value to round for integer formats
 sub WriteValue($$;$$$$)
 {
@@ -3857,5 +5072,10 @@
             # validate numerical formats
             if ($format =~ /^int/) {
-                return undef unless IsInt($val) or IsHex($val);
+                unless (IsInt($val) or IsHex($val)) {
+                    return undef unless IsFloat($val);
+                    # round to nearest integer
+                    $val = int($val + ($val < 0 ? -0.5 : 0.5));
+                    $_[0] = $val;
+                }
             } elsif (not IsFloat($val)) {
                 return undef unless $format =~ /^rational/ and ($val eq 'inf' or
@@ -3920,5 +5140,5 @@
                         # don't return error string unless more than one value
                         return undef unless @vals > 1 and wantarray;
-                        return (undef, "no match for '$val'");
+                        return (undef, "no match for '${val}'");
                     }
                 }
@@ -3938,5 +5158,5 @@
 
 #------------------------------------------------------------------------------
-# get current position in output file
+# get current position in output file (or end of file if a scalar reference)
 # Inputs: 0) file or scalar reference
 # Returns: Current position or -1 on error
@@ -3974,7 +5194,7 @@
 {
     my ($self, $trailInfo, $outfile) = @_;
-    if ($self->{DEL_GROUP}{Trailer}) {
+    if ($$self{DEL_GROUP}{Trailer}) {
         $self->VPrint(0, "  Deleting trailer ($$trailInfo{Offset} bytes)\n");
-        ++$self->{CHANGED};
+        ++$$self{CHANGED};
         return 1;
     }
@@ -3985,6 +5205,6 @@
         if ($pos > 0) {
             # shift offsets to final AFCP location and write it out
-            $trailInfo->{Fixup}{Shift} += $pos;
-            $trailInfo->{Fixup}->ApplyFixup($trailPt);
+            $$trailInfo{Fixup}{Shift} += $pos;
+            $$trailInfo{Fixup}->ApplyFixup($trailPt);
         } else {
             $self->Error("Can't get file position for trailer offset fixup",1);
@@ -4007,10 +5227,18 @@
     $types[0] or shift @types; # (in case undef data ref is passed)
     # add all possible trailers if none specified (currently only CanonVRD)
-    @types or @types = qw(CanonVRD);
-    # add trailers as a block
+    @types or @types = qw(CanonVRD CanonDR4);
+    # add trailers as a block (if not done already)
     my $type;
     foreach $type (@types) {
-        next unless $self->{NEW_VALUE}{$Image::ExifTool::Extra{$type}};
-        my $val = $self->GetNewValues($type) or next;
+        next unless $$self{NEW_VALUE}{$Image::ExifTool::Extra{$type}};
+        next if $$self{"Did$type"};
+        my $val = $self->GetNewValue($type) or next;
+        # DR4 record must be wrapped in VRD trailer package
+        if ($type eq 'CanonDR4') {
+            next if $$self{DidCanonVRD};    # (only allow one VRD trailer)
+            require Image::ExifTool::CanonVRD;
+            $val = Image::ExifTool::CanonVRD::WrapDR4($val);
+            $$self{DidCanonVRD} = 1;
+        }
         my $verb = $trailPt ? 'Writing' : 'Adding';
         $self->VPrint(0, "  $verb $type as a block\n");
@@ -4020,4 +5248,5 @@
             $trailPt = \$val;
         }
+        $$self{"Did$type"} = 1;
         ++$$self{CHANGED};
     }
@@ -4030,4 +5259,5 @@
 #         2) segment header, 3) segment data ref, 4) segment type
 # Returns: number of segments written, or 0 on error
+# Notes: Writes a single empty segment if data is empty
 sub WriteMultiSegment($$$$;$)
 {
@@ -4040,12 +5270,19 @@
     $maxLen -= 2 if $type eq 'ICC'; # leave room for segment counters
     my $num = int(($len + $maxLen - 1) / $maxLen);  # number of segments to write
-    my $n;
+    my $n = 0;
     # write data, splitting into multiple segments if necessary
     # (each segment gets its own header)
-    for ($n=0; $n<$len; $n+=$maxLen) {
+    for (;;) {
         ++$count;
         my $size = $len - $n;
-        $size > $maxLen and $size = $maxLen;
+        if ($size > $maxLen) {
+            $size = $maxLen;
+            # avoid starting an Extended EXIF segment with a valid TIFF header
+            # (because we would interpret that as a separate EXIF segment)
+            --$size if $type eq 'EXIF' and $n+$maxLen <= $len-4 and
+                substr($$dataPt, $n+$maxLen, 4) =~ /^(MM\0\x2a|II\x2a\0)/;
+        }
         my $buff = substr($$dataPt,$n,$size);
+        $n += $size;
         $size += length($header);
         if ($type eq 'ICC') {
@@ -4056,4 +5293,5 @@
         my $segHdr = $hdr . pack('n', $size + 2);
         Write($outfile, $segHdr, $header, $buff) or return 0;
+        last if $n >= $len;
     }
     return $count;
@@ -4081,5 +5319,5 @@
     if (defined $guid) {
         $size = length($$extPt);
-        my $maxLen = $maxXMPLen - 75; # maximum size without 75 byte header
+        my $maxLen = $maxXMPLen - 75; # maximum size without 75-byte header
         my $off;
         for ($off=0; $off<$size; $off+=$maxLen) {
@@ -4106,24 +5344,33 @@
     my $outfile = $$dirInfo{OutFile};
     my $raf = $$dirInfo{RAF};
-    my ($ch,$s,$length);
-    my $verbose = $self->{OPTIONS}{Verbose};
-    my $out = $self->{OPTIONS}{TextOut};
+    my ($ch, $s, $length,$err, %doneDir, $isEXV, $creatingEXV);
+    my $verbose = $$self{OPTIONS}{Verbose};
+    my $out = $$self{OPTIONS}{TextOut};
     my $rtnVal = 0;
-    my ($err, %doneDir);
     my %dumpParms = ( Out => $out );
     my ($writeBuffer, $oldOutfile); # used to buffer writing until PreviewImage position is known
 
-    # check to be sure this is a valid JPG file
-    return 0 unless $raf->Read($s,2) == 2 and $s eq "\xff\xd8";
+    # check to be sure this is a valid JPG or EXV file
+    unless ($raf->Read($s,2) == 2 and $s eq "\xff\xd8") {
+        if (defined $s and length $s) {
+            return 0 unless $s eq "\xff\x01" and $raf->Read($s,5) == 5 and $s eq 'Exiv2';
+        } else {
+            return 0 unless $$self{FILE_TYPE} eq 'EXV';
+            $s = 'Exiv2';
+            $creatingEXV = 1;
+        }
+        Write($outfile,"\xff\x01") or $err = 1;
+        $isEXV = 1;
+    }
     $dumpParms{MaxLen} = 128 unless $verbose > 3;
 
-    delete $self->{PREVIEW_INFO};   # reset preview information
-    delete $self->{DEL_PREVIEW};    # reset flag to delete preview
+    delete $$self{PREVIEW_INFO};   # reset preview information
+    delete $$self{DEL_PREVIEW};    # reset flag to delete preview
 
     Write($outfile, $s) or $err = 1;
     # figure out what segments we need to write for the tags we have set
-    my $addDirs = $self->{ADD_DIRS};
-    my $editDirs = $self->{EDIT_DIRS};
-    my $delGroup = $self->{DEL_GROUP};
+    my $addDirs = $$self{ADD_DIRS};
+    my $editDirs = $$self{EDIT_DIRS};
+    my $delGroup = $$self{DEL_GROUP};
     my $path = $$self{PATH};
     my $pn = scalar @$path;
@@ -4145,11 +5392,12 @@
             last unless $marker == 0xff;
         }
-        # SOS signifies end of meta information
-        if ($marker == 0xda) {
-            push(@dirOrder, 'SOS');
-            $dirCount{SOS} = 1;
+        my $dirName;
+        # stop pre-scan at SOS (end of meta information) or EOI (end of image)
+        if ($marker == 0xda or $marker == 0xd9) {
+            $dirName = $jpegMarker{$marker};
+            push(@dirOrder, $dirName);
+            $dirCount{$dirName} = 1;
             last;
         }
-        my $dirName;
         # handle SOF markers: SOF0-SOF15, except DHT(0xc4), JPGA(0xc8) and DAC(0xcc)
         if (($marker & 0xf0) == 0xc0 and ($marker == 0xc0 or $marker & 0x03)) {
@@ -4167,18 +5415,37 @@
                 $raf->Read($s, $n) == $n or last;
                 $len -= $n;
-                # (Note: only necessary to recognize APP segments that we can create)
+                # Note: only necessary to recognize APP segments that we can create,
+                # or delete as a group (and the names below should match @delGroups)
                 if ($marker == 0xe0) {
                     $s =~ /^JFIF\0/         and $dirName = 'JFIF';
                     $s =~ /^JFXX\0\x10/     and $dirName = 'JFXX';
+                    $s =~ /^(II|MM).{4}HEAPJPGM/s and $dirName = 'CIFF';
                 } elsif ($marker == 0xe1) {
-                    $s =~ /^$exifAPP1hdr/   and $dirName = 'IFD0';
+                    if ($s =~ /^(.{0,4})$exifAPP1hdr(.{1,4})/is) {
+                        $dirName = 'IFD0';
+                        my ($junk, $bytes) = ($1, $2);
+                        # support multi-segment EXIF
+                        if (@dirOrder and $dirOrder[-1] =~ /^(IFD0|ExtendedEXIF)$/ and
+                            not length $junk and $bytes !~ /^(MM\0\x2a|II\x2a\0)/)
+                        {
+                            $dirName = 'ExtendedEXIF';
+                        }
+                    }
                     $s =~ /^$xmpAPP1hdr/    and $dirName = 'XMP';
                     $s =~ /^$xmpExtAPP1hdr/ and $dirName = 'XMP';
                 } elsif ($marker == 0xe2) {
                     $s =~ /^ICC_PROFILE\0/  and $dirName = 'ICC_Profile';
+                    $s =~ /^FPXR\0/         and $dirName = 'FlashPix';
+                    $s =~ /^MPF\0/          and $dirName = 'MPF';
+                } elsif ($marker == 0xe3) {
+                    $s =~ /^(Meta|META|Exif)\0\0/ and $dirName = 'Meta';
+                } elsif ($marker == 0xe5) {
+                    $s =~ /^RMETA\0/        and $dirName = 'RMETA';
                 } elsif ($marker == 0xec) {
                     $s =~ /^Ducky/          and $dirName = 'Ducky';
                 } elsif ($marker == 0xed) {
                     $s =~ /^$psAPP13hdr/    and $dirName = 'Photoshop';
+                } elsif ($marker == 0xee) {
+                    $s =~ /^Adobe/          and $dirName = 'Adobe';
                 }
                 # initialize doneDir as a flag that the directory exists
@@ -4193,6 +5460,6 @@
     }
     unless ($marker and $marker == 0xda) {
-        $self->Error('Corrupted JPEG image');
-        return 1;
+        $isEXV or $self->Error('Corrupted JPEG image'), 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;
@@ -4200,5 +5467,6 @@
 # re-write the image
 #
-    my ($combinedSegData, $segPos, %extendedXMP);
+    my ($combinedSegData, $segPos, $firstSegPos, %extendedXMP);
+    my (@iccChunk, $iccChunkCount, $iccChunksTotal);
     # read through each segment in the JPEG file
     Marker: for (;;) {
@@ -4208,11 +5476,22 @@
         $raf->ReadLine($segJunk) or $segJunk = '';
         # remove the 0xff but write the rest of the junk up to this point
+        # (this will handle the data after the first 7 bytes of SOF segments)
         chomp($segJunk);
         Write($outfile, $segJunk) if length $segJunk;
         # JPEG markers can be padded with unlimited 0xff's
         for (;;) {
-            $raf->Read($ch, 1) or $self->Error('Format error'), return 1;
-            $marker = ord($ch);
-            last unless $marker == 0xff;
+            if ($raf->Read($ch, 1)) {
+                $marker = ord($ch);
+                last unless $marker == 0xff;
+            } elsif ($creatingEXV) {
+                # create EXV from scratch
+                $marker = 0xd9; # EOI
+                push @dirOrder, 'EOI';
+                $dirCount{EOI} = 1;
+                last;
+            } else {
+                $self->Error('Format error');
+                return 1;
+            }
         }
         # read the segment data
@@ -4222,6 +5501,8 @@
             last unless $raf->Read($segData, 7) == 7;
         # read data for all markers except stand-alone
-        # markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, RST0-RST7)
-        } elsif ($marker!=0x00 and $marker!=0x01 and ($marker<0xd0 or $marker>0xd7)) {
+        # markers 0x00, 0x01 and 0xd0-0xd7 (NULL, TEM, EOI, RST0-RST7)
+        } elsif ($marker!=0x00 and $marker!=0x01 and $marker!=0xd9 and
+            ($marker<0xd0 or $marker>0xd7))
+        {
             # read record length word
             last unless $raf->Read($s, 2) == 2;
@@ -4236,5 +5517,4 @@
         my $markerName = JpegMarkerName($marker);
         my $dirName = shift @dirOrder;      # get directory name
-        $$path[$pn] = $markerName;
 #
 # create all segments that must come before this one
@@ -4244,29 +5524,37 @@
             if (exists $$addDirs{JFIF} and not defined $doneDir{JFIF}) {
                 $doneDir{JFIF} = 1;
-                if ($verbose) {
-                    print $out "Creating APP0:\n";
-                    print $out "  Creating JFIF with default values\n";
-                }
-                my $jfif = "\x01\x02\x01\0\x48\0\x48\0\0";
-                SetByteOrder('MM');
-                my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Main');
-                my %dirInfo = (
-                    DataPt   => \$jfif,
-                    DirStart => 0,
-                    DirLen   => length $jfif,
-                );
-                # must temporarily remove JFIF from DEL_GROUP so we can
-                # delete JFIF and add it back again in a single step
-                my $delJFIF = $$delGroup{JFIF};
-                delete $$delGroup{JFIF};
-                my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
-                $$delGroup{JFIF} = $delJFIF if defined $delJFIF;
-                if (defined $newData and length $newData) {
-                    my $app0hdr = "\xff\xe0" . pack('n', length($newData) + 7);
-                    Write($outfile,$app0hdr,"JFIF\0",$newData) or $err = 1;
+                if (defined $doneDir{Adobe}) {
+                    # JFIF overrides Adobe APP14 colour components, so don't allow this
+                    # (ref https://docs.oracle.com/javase/8/docs/api/javax/imageio/metadata/doc-files/jpeg_metadata.html)
+                    $self->Warn('Not creating JFIF in JPEG with Adobe APP14');
+                } else {
+                    if ($verbose) {
+                        print $out "Creating APP0:\n";
+                        print $out "  Creating JFIF with default values\n";
+                    }
+                    my $jfif = "\x01\x02\x01\0\x48\0\x48\0\0";
+                    SetByteOrder('MM');
+                    my $tagTablePtr = GetTagTable('Image::ExifTool::JFIF::Main');
+                    my %dirInfo = (
+                        DataPt   => \$jfif,
+                        DirStart => 0,
+                        DirLen   => length $jfif,
+                        Parent   => 'JFIF',
+                    );
+                    # must temporarily remove JFIF from DEL_GROUP so we can
+                    # delete JFIF and add it back again in a single step
+                    my $delJFIF = $$delGroup{JFIF};
+                    delete $$delGroup{JFIF};
+                    $$path[$pn] = 'JFIF';
+                    my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                    $$delGroup{JFIF} = $delJFIF if defined $delJFIF;
+                    if (defined $newData and length $newData) {
+                        my $app0hdr = "\xff\xe0" . pack('n', length($newData) + 7);
+                        Write($outfile,$app0hdr,"JFIF\0",$newData) or $err = 1;
+                    }
                 }
             }
             # don't create anything before APP0 or APP1 EXIF (containing IFD0)
-            last if $markerName eq 'APP0' or $dirCount{IFD0};
+            last if $markerName eq 'APP0' or $dirCount{IFD0} or $dirCount{ExtendedEXIF};
             # EXIF information must come immediately after APP0
             if (exists $$addDirs{IFD0} and not defined $doneDir{IFD0}) {
@@ -4274,5 +5562,5 @@
                 $verbose and print $out "Creating APP1:\n";
                 # write new EXIF data
-                $self->{TIFF_TYPE} = 'APP1';
+                $$self{TIFF_TYPE} = 'APP1';
                 my $tagTablePtr = GetTagTable('Image::ExifTool::Exif::Main');
                 my %dirInfo = (
@@ -4280,24 +5568,32 @@
                     Parent  => 'APP1',
                 );
+                $$path[$pn] = 'APP1';
                 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr, \&WriteTIFF);
                 if (defined $buff and length $buff) {
-                    my $size = length($buff) + length($exifAPP1hdr);
-                    if ($size <= $maxSegmentLen) {
-                        # switch to buffered output if required
-                        if (($$self{PREVIEW_INFO} or $$self{LeicaTrailer}) and not $oldOutfile) {
-                            $writeBuffer = '';
-                            $oldOutfile = $outfile;
-                            $outfile = \$writeBuffer;
-                            # account for segment, EXIF and TIFF headers
-                            $$self{PREVIEW_INFO}{Fixup}{Start} += 18 if $$self{PREVIEW_INFO};
-                            $$self{LeicaTrailer}{Fixup}{Start} += 18 if $$self{LeicaTrailer};
+                    if (length($buff) + length($exifAPP1hdr) > $maxSegmentLen) {
+                        if ($self->Options('NoMultiExif')) {
+                            $self->Error('EXIF is too large for JPEG segment');
+                        } else {
+                            $self->Warn('Creating multi-segment EXIF',1);
                         }
-                        # write the new segment with appropriate header
-                        my $app1hdr = "\xff\xe1" . pack('n', $size + 2);
-                        Write($outfile,$app1hdr,$exifAPP1hdr,$buff) or $err = 1;
-                    } else {
-                        delete $self->{PREVIEW_INFO};
-                        $self->Warn("EXIF APP1 segment too large! ($size bytes)");
-                    }
+                    }
+                    # switch to buffered output if required
+                    if (($$self{PREVIEW_INFO} or $$self{LeicaTrailer}) and not $oldOutfile) {
+                        $writeBuffer = '';
+                        $oldOutfile = $outfile;
+                        $outfile = \$writeBuffer;
+                        # account for segment, EXIF and TIFF headers
+                        $$self{PREVIEW_INFO}{Fixup}{Start} += 18 if $$self{PREVIEW_INFO};
+                        $$self{LeicaTrailer}{Fixup}{Start} += 18 if $$self{LeicaTrailer};
+                    }
+                    # write as multi-segment
+                    my $n = WriteMultiSegment($outfile, 0xe1, $exifAPP1hdr, \$buff, 'EXIF');
+                    if (not $n) {
+                        $err = 1;
+                    } elsif ($n > 1 and $oldOutfile) {
+                        # (punt on this because updating the pointers would be a real pain)
+                        $self->Error("Can't write multi-segment EXIF with external pointers");
+                    }
+                    ++$$self{CHANGED};
                 }
             }
@@ -4312,8 +5608,9 @@
                     Parent => 'APP13',
                 );
+                $$path[$pn] = 'APP13';
                 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
                 if (defined $buff and length $buff) {
                     WriteMultiSegment($outfile, 0xed, $psAPP13hdr, \$buff) or $err = 1;
-                    ++$self->{CHANGED};
+                    ++$$self{CHANGED};
                 }
             }
@@ -4330,4 +5627,5 @@
                     MaxDataLen  => $maxXMPLen - length($xmpAPP1hdr),
                 );
+                $$path[$pn] = 'APP1';
                 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
                 if (defined $buff and length $buff) {
@@ -4347,8 +5645,9 @@
                     Parent   => 'APP2',
                 );
+                $$path[$pn] = 'APP2';
                 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
                 if (defined $buff and length $buff) {
                     WriteMultiSegment($outfile, 0xe2, "ICC_PROFILE\0", \$buff, 'ICC') or $err = 1;
-                    ++$self->{CHANGED};
+                    ++$$self{CHANGED};
                 }
             }
@@ -4363,4 +5662,5 @@
                     Parent   => 'APP12',
                 );
+                $$path[$pn] = 'APP12';
                 my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
                 if (defined $buff and length $buff) {
@@ -4371,5 +5671,23 @@
                         Write($outfile, $app12hdr, 'Ducky', $buff) or $err = 1;
                     } else {
-                        $self->Warn("Ducky APP12 segment too large! ($size bytes)");
+                        $self->Warn("APP12 Ducky segment too large! ($size bytes)");
+                    }
+                }
+            }
+            # then APP14 Adobe segment
+            last if $dirCount{Adobe};
+            if (exists $$addDirs{Adobe} and not defined $doneDir{Adobe}) {
+                $doneDir{Adobe} = 1;
+                my $buff = $self->GetNewValue('Adobe');
+                if ($buff) {
+                    $verbose and print $out "Creating APP14:\n  Creating Adobe segment\n";
+                    my $size = length($buff);
+                    if ($size <= $maxSegmentLen) {
+                        # write the new segment with appropriate header
+                        my $app14hdr = "\xff\xee" . pack('n', $size + 2);
+                        Write($outfile, $app14hdr, $buff) or $err = 1;
+                        ++$$self{CHANGED};
+                    } else {
+                        $self->Warn("APP14 Adobe segment too large! ($size bytes)");
                     }
                 }
@@ -4380,6 +5698,6 @@
                 $doneDir{COM} = 1;
                 next if $$delGroup{File} and $$delGroup{File} != 2;
-                my $newComment = $self->GetNewValues('Comment');
-                if (defined $newComment and length($newComment)) {
+                my $newComment = $self->GetNewValue('Comment');
+                if (defined $newComment) {
                     if ($verbose) {
                         print $out "Creating COM:\n";
@@ -4387,9 +5705,10 @@
                     }
                     WriteMultiSegment($outfile, 0xfe, '', \$newComment) or $err = 1;
-                    ++$self->{CHANGED};
+                    ++$$self{CHANGED};
                 }
             }
             last;   # didn't want to loop anyway
         }
+        $$path[$pn] = $markerName;
         # decrement counter for this directory since we are about to process it
         --$dirCount{$dirName};
@@ -4409,7 +5728,8 @@
             Write($outfile, $hdr, $s, $segData) or $err = 1;
             my ($buff, $endPos, $trailInfo);
-            my $delPreview = $self->{DEL_PREVIEW};
+            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)) {
@@ -4442,5 +5762,18 @@
             # 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 = '';
@@ -4473,7 +5806,7 @@
                 # use this fixup to set the size too (sneaky)
                 my $trailSize = defined($dat) ? length($dat) - $junk : $$self{LeicaTrailer}{Size};
-                $fixup->{Start} -= 4;  $fixup->{Shift} += 4;
-                $fixup->SetMarkerPointers($outfile, 'LeicaTrailer', $trailSize);
-                $fixup->{Start} += 4;  $fixup->{Shift} -= 4;
+                $$fixup{Start} -= 4;  $$fixup{Shift} += 4;
+                $fixup->SetMarkerPointers($outfile, 'LeicaTrailer', $trailSize) if defined $trailSize;
+                $$fixup{Start} += 4;  $$fixup{Shift} -= 4;
                 # clean up and write the buffered data
                 $outfile = $oldOutfile;
@@ -4487,5 +5820,5 @@
             } else {
                 # locate preview image and fix up preview offsets
-                my $scanLen = $$self{Make} =~ /Sony/i ? 65536 : 1024;
+                my $scanLen = $$self{Make} =~ /^SONY/i ? 65536 : 1024;
                 if (length($buff) < $scanLen) { # make sure we have enough trailer to scan
                     my $buf2;
@@ -4495,14 +5828,31 @@
                 my $newPos = length($$outfile) - 10; # (subtract 10 for segment and EXIF headers)
                 my $junkLen;
-                # adjust position if image isn't at the start (ie. Olympus E-1/E-300)
-                if ($buff =~ m/(\xff\xd8\xff.|.\xd8\xff\xdb)/sg) {
-                    $junkLen = pos($buff) - 4;
+                # adjust position if image isn't at the start (eg. Olympus E-1/E-300)
+                if ($buff =~ /(\xff\xd8\xff.|.\xd8\xff\xdb)(..)/sg) {
+                    my ($jpegHdr, $segLen) = ($1, $2);
+                    $junkLen = pos($buff) - 6;
                     # Sony previewimage trailer has a 32 byte header
-                    $junkLen -= 32 if $$self{Make} =~/SONY/i and $junkLen > 32;
+                    if ($$self{Make} =~ /^SONY/i and $junkLen > 32) {
+                        # with some newer Sony models, the makernotes preview pointer
+                        # points to JPEG at end of EXIF inside MPImage preview (what a pain!)
+                        if ($jpegHdr eq "\xff\xd8\xff\xe1") {   # is the first segment EXIF?
+                            $segLen = unpack('n', $segLen);     # the EXIF segment length
+                            # Sony PreviewImage starts with last 2 bytes of EXIF segment
+                            # (and first byte is usually "\0", not "\xff", so don't check this)
+                            if (length($buff) > $junkLen + $segLen + 6 and
+                                substr($buff, $junkLen + $segLen + 3, 3) eq "\xd8\xff\xdb")
+                            {
+                                $junkLen += $segLen + 2;
+                                # (note: this will not copy the trailer after PreviewImage,
+                                #  which is a 14kB block full of zeros for the A77)
+                            }
+                        }
+                        $junkLen -= 32;
+                    }
                     $newPos += $junkLen;
                 }
                 # fix up the preview offsets to point to the start of the new image
-                my $previewInfo = $self->{PREVIEW_INFO};
-                delete $self->{PREVIEW_INFO};
+                my $previewInfo = $$self{PREVIEW_INFO};
+                delete $$self{PREVIEW_INFO};
                 my $fixup = $$previewInfo{Fixup};
                 $newPos += ($$previewInfo{BaseShift} || 0);
@@ -4511,5 +5861,5 @@
                 if ($$previewInfo{Relative}) {
                     # adjust for our base by looking at how far the pointer got shifted
-                    $newPos -= $fixup->GetMarkerPointers($outfile, 'PreviewImage');
+                    $newPos -= ($fixup->GetMarkerPointers($outfile, 'PreviewImage') || 0);
                 } elsif ($$previewInfo{ChangeBase}) {
                     # Leica S2 uses relative offsets for the preview only (leica sucks)
@@ -4548,5 +5898,5 @@
                     if ($$delGroup{Trailer}) {
                         $verbose and print $out "  Deleting unknown trailer ($extra bytes)\n";
-                        ++$self->{CHANGED};
+                        ++$$self{CHANGED};
                     } else {
                         # copy over unknown trailer
@@ -4564,4 +5914,10 @@
             last;   # all done parsing file
 
+        } elsif ($marker==0xd9 and $isEXV) {
+            # write EXV EOI (any trailer will be lost)
+            Write($outfile, "\xff\xd9") or $err = 1;
+            $rtnVal = 1;
+            last;
+
         } elsif ($marker==0x00 or $marker==0x01 or ($marker>=0xd0 and $marker<=0xd7)) {
             $verbose and $marker and print $out "JPEG $markerName:\n";
@@ -4573,5 +5929,5 @@
         # NOTE: A 'next' statement after this point will cause $$segDataPt
         #       not to be written if there is an output file, so in this case
-        #       the $self->{CHANGED} flags must be updated
+        #       the $$self{CHANGED} flags must be updated
         #
         my $segDataPt = \$segData;
@@ -4583,9 +5939,15 @@
             }
         }
+        # group delete of APP segments
+        if ($$delGroup{$dirName}) {
+            $verbose and print $out "  Deleting $dirName segment\n";
+            $self->Warn('ICC_Profile deleted. Image colors may be affected') if $dirName eq 'ICC_Profile';
+            ++$$self{CHANGED};
+            next Marker;
+        }
         my ($segType, $del);
         # rewrite this segment only if we are changing a tag which is contained in its
         # directory (or deleting '*', in which case we need to identify the segment type)
         while (exists $$editDirs{$markerName} or $$delGroup{'*'}) {
-            my $oldChanged = $self->{CHANGED};
             if ($marker == 0xe0) {              # APP0 (JFIF, CIFF)
                 if ($$segDataPt =~ /^JFIF\0/) {
@@ -4631,9 +5993,33 @@
             } elsif ($marker == 0xe1) {         # APP1 (EXIF, XMP)
                 # check for EXIF data
-                if ($$segDataPt =~ /^$exifAPP1hdr/) {
+                if ($$segDataPt =~ /^(.{0,4})$exifAPP1hdr/is) {
+                    my $hdrLen = length $exifAPP1hdr;
+                    if (length $1) {
+                        $hdrLen += length $1;
+                        $self->Error('Unknown garbage at start of EXIF segment',1);
+                    } elsif ($$segDataPt !~ /^Exif\0/) {
+                        $self->Error('Incorrect EXIF segment identifier',1);
+                    }
                     $segType = 'EXIF';
-                    $doneDir{IFD0} and $self->Warn('Multiple APP1 EXIF segments');
+                    last unless $$editDirs{IFD0};
+                    # add this data to the combined data if it exists
+                    if (defined $combinedSegData) {
+                        $combinedSegData .= substr($$segDataPt,$hdrLen);
+                        $segDataPt = \$combinedSegData;
+                        $segPos = $firstSegPos;
+                        $length = length $combinedSegData;  # update length
+                    }
+                    # peek ahead to see if the next segment is extended EXIF
+                    if ($dirOrder[0] eq 'ExtendedEXIF') {
+                        # initialize combined data if necessary
+                        unless (defined $combinedSegData) {
+                            $combinedSegData = $$segDataPt;
+                            $firstSegPos = $segPos;
+                            $self->Warn('File contains multi-segment EXIF',1);
+                        }
+                        next Marker;    # get the next segment to combine
+                    }
+                    $doneDir{IFD0} and $self->Warn('Multiple APP1 EXIF records');
                     $doneDir{IFD0} = 1;
-                    last unless $$editDirs{IFD0};
                     # check del groups now so we can change byte order in one step
                     if ($$delGroup{IFD0} or $$delGroup{EXIF}) {
@@ -4645,7 +6031,7 @@
                     my %dirInfo = (
                         DataPt   => $segDataPt,
-                        DataPos  => $segPos,
-                        DirStart => 6,
-                        Base     => $segPos + 6,
+                        DataPos  => -$hdrLen, # (remember: relative to Base!)
+                        DirStart => $hdrLen,
+                        Base     => $segPos + $hdrLen,
                         Parent   => $markerName,
                         DirName  => 'IFD0',
@@ -4655,9 +6041,17 @@
                     my $buff = $self->WriteDirectory(\%dirInfo, $tagTablePtr, \&WriteTIFF);
                     if (defined $buff) {
-                        # update segment with new data
-                        $$segDataPt = $exifAPP1hdr . $buff;
+                        undef $$segDataPt;  # free the old buffer
+                        $segDataPt = \$buff;
                     } else {
                         last Marker unless $self->Options('IgnoreMinorErrors');
-                        $self->{CHANGED} = $oldChanged; # nothing changed
+                    }
+                    # delete segment if IFD contains no entries
+                    length $$segDataPt or $del = 1, last;
+                    if (length($$segDataPt) + length($exifAPP1hdr) > $maxSegmentLen) {
+                        if ($self->Options('NoMultiExif')) {
+                            $self->Error('EXIF is too large for JPEG segment');
+                        } else {
+                            $self->Warn('Writing multi-segment EXIF',1);
+                        }
                     }
                     # switch to buffered output if required
@@ -4670,6 +6064,15 @@
                         $$self{LeicaTrailer}{Fixup}{Start} += 18 if $$self{LeicaTrailer};
                     }
-                    # delete segment if IFD contains no entries
-                    $del = 1 unless length($$segDataPt) > length($exifAPP1hdr);
+                    # write as multi-segment
+                    my $n = WriteMultiSegment($outfile, $marker, $exifAPP1hdr, $segDataPt, 'EXIF');
+                    if (not $n) {
+                        $err = 1;
+                    } elsif ($n > 1 and $oldOutfile) {
+                        # (punt on this because updating the pointers would be a real pain)
+                        $self->Error("Can't write multi-segment EXIF with external pointers");
+                    }
+                    undef $combinedSegData;
+                    undef $$segDataPt;
+                    next Marker;
                 # check for XMP data
                 } elsif ($$segDataPt =~ /^($xmpAPP1hdr|$xmpExtAPP1hdr)/) {
@@ -4688,13 +6091,17 @@
                                 my ($size, $off) = unpack('x67N2', $$segDataPt);
                                 $guid = substr($$segDataPt, 35, 32);
-                                # remember extended data for each GUID
-                                $extXMP = $extendedXMP{$guid};
-                                if ($extXMP) {
-                                    $size == $$extXMP{Size} or $extendedXMP{Error} = 'Invalid size';
+                                if ($guid =~ /[^A-Za-z0-9]/) { # (technically, should be uppercase)
+                                    $extendedXMP{Error} = 'Invalid GUID';
                                 } else {
-                                    $extXMP = $extendedXMP{$guid} = { };
+                                    # remember extended data for each GUID
+                                    $extXMP = $extendedXMP{$guid};
+                                    if ($extXMP) {
+                                        $size == $$extXMP{Size} or $extendedXMP{Error} = 'Inconsistent size';
+                                    } else {
+                                        $extXMP = $extendedXMP{$guid} = { };
+                                    }
+                                    $$extXMP{Size} = $size;
+                                    $$extXMP{$off} = substr($$segDataPt, 75);
                                 }
-                                $$extXMP{Size} = $size;
-                                $$extXMP{$off} = substr($$segDataPt, 75);
                             }
                         } else {
@@ -4707,7 +6114,30 @@
                         # reconstruct an XMP super-segment
                         $$segDataPt = $xmpAPP1hdr;
-                        $$segDataPt .= $_ foreach @{$extendedXMP{Main}};
+                        my $goodGuid = '';
+                        foreach (@{$extendedXMP{Main}}) {
+                            # get the HasExtendedXMP GUID if it exists
+                            if (/:HasExtendedXMP\s*(=\s*['"]|>)(\w{32})/) {
+                                # warn of subsequent XMP blocks specifying a different
+                                # HasExtendedXMP (have never seen this)
+                                if ($goodGuid and $goodGuid ne $2) {
+                                    $self->WarnOnce('Multiple XMP segments specifying different extended XMP GUID');
+                                }
+                                $goodGuid = $2; # GUID for the standard extended XMP
+                            }
+                            $$segDataPt .= $_;
+                        }
+                        # GUID of the extended XMP that we want to read
+                        my $readGuid = $$self{OPTIONS}{ExtendedXMP} || 0;
+                        $readGuid = $goodGuid if $readGuid eq '1';
                         foreach $guid (sort keys %extendedXMP) {
-                            next unless length $guid == 32;     # ignore other keys
+                            next unless length $guid == 32;     # ignore other (internal) keys
+                            if ($guid ne $readGuid and $readGuid ne '2') {
+                                my $non = $guid eq $goodGuid ? '' : 'non-';
+                                $self->Warn("Ignored ${non}standard extended XMP (GUID $guid)");
+                                next;
+                            }
+                            if ($guid ne $goodGuid) {
+                                $self->Warn("Reading non-standard extended XMP (GUID $guid)");
+                            }
                             $extXMP = $extendedXMP{$guid};
                             next unless ref $extXMP eq 'HASH';  # (just to be safe)
@@ -4723,5 +6153,5 @@
                                 $$segDataPt .= $$extXMP{$_} foreach @offsets;
                             } else {
-                                $extendedXMP{Error} = 'Missing XMP data';
+                                $self->Error("Incomplete extended XMP (GUID $guid)", 1);
                             }
                         }
@@ -4750,5 +6180,4 @@
                         }
                     } else {
-                        $self->{CHANGED} = $oldChanged;
                         $verbose and print $out "    [XMP rewritten with no changes]\n";
                         if ($doneDir{XMP} > 1) {
@@ -4781,46 +6210,72 @@
                     $self->Warn('Ignored APP1 XMP segment with non-standard header', 1);
                 }
-            } elsif ($marker == 0xe2) {         # APP2 (ICC Profile, FPXR)
-                if ($$segDataPt =~ /^ICC_PROFILE\0/) {
+            } elsif ($marker == 0xe2) {         # APP2 (ICC Profile, FPXR, MPF)
+                if ($$segDataPt =~ /^ICC_PROFILE\0/ and $length >= 14) {
                     $segType = 'ICC_Profile';
                     $$delGroup{ICC_Profile} and $del = 1, last;
                     # must concatenate blocks of profile
-                    my $block_num = ord(substr($$segDataPt, 12, 1));
-                    my $blocks_tot = ord(substr($$segDataPt, 13, 1));
-                    $combinedSegData = '' if $block_num == 1;
-                    unless (defined $combinedSegData) {
-                        $self->Warn('APP2 ICC_Profile segments out of sequence');
+                    my $chunkNum = Get8u($segDataPt, 12);
+                    my $chunksTot = Get8u($segDataPt, 13);
+                    if (defined $iccChunksTotal) {
+                        # abort parsing ICC_Profile if the total chunk count is inconsistent
+                        if ($chunksTot != $iccChunksTotal and defined $iccChunkCount) {
+                            # an error because the accumulated profile data will be lost
+                            $self->Error('Inconsistent ICC_Profile chunk count', 1);
+                            undef $iccChunkCount; # abort ICC_Profile parsing
+                            undef $chunkNum;      # avoid 2nd warning below
+                            ++$$self{CHANGED};    # we are deleting the bad chunks before this one
+                        }
+                    } else {
+                        $iccChunkCount = 0;
+                        $iccChunksTotal = $chunksTot;
+                        $self->Warn('ICC_Profile chunk count is zero') if !$chunksTot;
+                    }
+                    if (defined $iccChunkCount) {
+                        # save this chunk
+                        if (defined $iccChunk[$chunkNum]) {
+                            $self->Warn("Duplicate ICC_Profile chunk number $chunkNum");
+                            $iccChunk[$chunkNum] .= substr($$segDataPt, 14);
+                        } else {
+                            $iccChunk[$chunkNum] = substr($$segDataPt, 14);
+                        }
+                        # continue accumulating chunks unless we have all of them
+                        next Marker unless ++$iccChunkCount >= $iccChunksTotal;
+                        undef $iccChunkCount;   # prevent reprocessing
+                        $doneDir{ICC_Profile} = 1;
+                        # combine the ICC_Profile chunks
+                        my $icc_profile = '';
+                        defined $_ and $icc_profile .= $_ foreach @iccChunk;
+                        undef @iccChunk;   # free memory
+                        $segDataPt = \$icc_profile;
+                        $length = length $icc_profile;
+                        my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
+                        my %dirInfo = (
+                            DataPt   => $segDataPt,
+                            DataPos  => $segPos + 14,
+                            DataLen  => $length,
+                            DirStart => 0,
+                            DirLen   => $length,
+                            Parent   => $markerName,
+                        );
+                        my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
+                        if (defined $newData) {
+                            undef $$segDataPt;  # free the old buffer
+                            $segDataPt = \$newData;
+                        }
+                        length $$segDataPt or $del = 1, last;
+                        # write as ICC multi-segment
+                        WriteMultiSegment($outfile, $marker, "ICC_PROFILE\0", $segDataPt, 'ICC') or $err = 1;
+                        undef $$segDataPt;
                         next Marker;
-                    }
-                    $combinedSegData .= substr($$segDataPt, 14);
-                    # continue accumulating segments unless this is the last
-                    next Marker unless $block_num == $blocks_tot;
-                    $doneDir{ICC_Profile} and $self->Warn('Multiple ICC_Profile records');
-                    $doneDir{ICC_Profile} = 1;
-                    $segDataPt = \$combinedSegData;
-                    $length = length $combinedSegData;
-                    my $tagTablePtr = GetTagTable('Image::ExifTool::ICC_Profile::Main');
-                    my %dirInfo = (
-                        DataPt   => $segDataPt,
-                        DataPos  => $segPos + 14,
-                        DataLen  => $length,
-                        DirStart => 0,
-                        DirLen   => $length,
-                        Parent   => $markerName,
-                    );
-                    my $newData = $self->WriteDirectory(\%dirInfo, $tagTablePtr);
-                    if (defined $newData) {
-                        undef $$segDataPt;  # free the old buffer
-                        $segDataPt = \$newData;
-                    }
-                    length $$segDataPt or $del = 1, last;
-                    # write as ICC multi-segment
-                    WriteMultiSegment($outfile, $marker, "ICC_PROFILE\0", $segDataPt, 'ICC') or $err = 1;
-                    undef $combinedSegData;
-                    undef $$segDataPt;
-                    next Marker;
+                    } elsif (defined $chunkNum) {
+                        $self->WarnOnce('Invalid or extraneous ICC_Profile chunk(s)');
+                        # fall through to preserve this extra profile...
+                    }
                 } elsif ($$segDataPt =~ /^FPXR\0/) {
                     $segType = 'FPXR';
                     $$delGroup{FlashPix} and $del = 1;
+                } elsif ($$segDataPt =~ /^MPF\0/) {
+                    $segType = 'MPF';
+                    $$delGroup{MPF} and $del = 1;
                 }
             } elsif ($marker == 0xe3) {         # APP3 (Kodak Meta)
@@ -4834,5 +6289,5 @@
                     my %dirInfo = (
                         DataPt   => $segDataPt,
-                        DataPos  => $segPos,
+                        DataPos  => -6, # (remember: relative to Base!)
                         DirStart => 6,
                         Base     => $segPos + 6,
@@ -4848,5 +6303,4 @@
                     } else {
                         last Marker unless $self->Options('IgnoreMinorErrors');
-                        $self->{CHANGED} = $oldChanged; # nothing changed
                     }
                     # delete segment if IFD contains no entries
@@ -4880,6 +6334,4 @@
                         $newData = 'Ducky' . $newData if length $newData;
                         $segDataPt = \$newData;
-                    } else {
-                        $self->{CHANGED} = $oldChanged;
                     }
                     $del = 1 unless length $$segDataPt;
@@ -4921,6 +6373,4 @@
                         undef $$segDataPt;  # free the old buffer
                         $segDataPt = \$newData;
-                    } else {
-                        $self->{CHANGED} = $oldChanged;
                     }
                     length $$segDataPt or $del = 1, last;
@@ -4930,4 +6380,13 @@
                     undef $$segDataPt;
                     next Marker;
+                }
+            } elsif ($marker == 0xee) {         # APP14 (Adobe)
+                if ($$segDataPt =~ /^Adobe/) {
+                    $segType = 'Adobe';
+                    # delete it and replace it later if editing
+                    if ($$delGroup{Adobe} or $$editDirs{Adobe}) {
+                        $del = 1;
+                        undef $doneDir{Adobe};  # so we can add it back again above
+                    }
                 }
             } elsif ($marker == 0xfe) {         # COM (JPEG comment)
@@ -4938,6 +6397,8 @@
                         my $tagInfo = $Image::ExifTool::Extra{Comment};
                         my $nvHash = $self->GetNewValueHash($tagInfo);
-                        if (IsOverwriting($nvHash, $segData) or $$delGroup{File}) {
-                            $newComment = GetNewValues($nvHash);
+                        my $val = $segData;
+                        $val =~ s/\0+$//;   # allow for stupid software that adds NULL terminator
+                        if ($self->IsOverwriting($nvHash, $val) or $$delGroup{File}) {
+                            $newComment = $self->GetNewValue($nvHash);
                         } else {
                             delete $$editDirs{COM}; # we aren't editing COM after all
@@ -4947,5 +6408,5 @@
                 }
                 $self->VerboseValue('- Comment', $$segDataPt);
-                if (defined $newComment and length $newComment) {
+                if (defined $newComment) {
                     # write out the comments
                     $self->VerboseValue('+ Comment', $newComment);
@@ -4954,18 +6415,19 @@
                     $verbose and print $out "  Deleting COM segment\n";
                 }
-                ++$self->{CHANGED};     # increment the changed flag
+                ++$$self{CHANGED};      # increment the changed flag
                 undef $segDataPt;       # don't write existing comment
             }
             last;   # didn't want to loop anyway
         }
+
         # delete necessary segments (including unknown segments if deleting all)
         if ($del or ($$delGroup{'*'} and not $segType and $marker>=0xe0 and $marker<=0xef)) {
             $segType = 'unknown' unless $segType;
             $verbose and print $out "  Deleting $markerName $segType segment\n";
-            ++$self->{CHANGED};
+            ++$$self{CHANGED};
             next Marker;
         }
         # write out this segment if $segDataPt is still defined
-        if (defined $segDataPt) {
+        if (defined $segDataPt and defined $$segDataPt) {
             # write the data for this record (the data could have been
             # modified, so recalculate the length word)
@@ -4980,6 +6442,9 @@
             }
             undef $$segDataPt;  # free the buffer
-        }
-    }
+            undef $segDataPt;
+        }
+    }
+    # make sure the ICC_Profile was complete
+    $self->Error('Incomplete ICC_Profile record', 1) if defined $iccChunkCount;
     pop @$path if @$path > $pn;
     # if oldOutfile is still set, there was an error copying the JPEG
@@ -4992,4 +6457,8 @@
     # set return value to -1 if we only had a write error
     $rtnVal = -1 if $rtnVal and $err;
+    if ($creatingEXV and $rtnVal > 0 and not $$self{CHANGED}) {
+        $self->Error('Nothing written');
+        $rtnVal = -1;
+    }
     return $rtnVal;
 }
@@ -5005,5 +6474,5 @@
         $self->Options('IgnoreMinorErrors'))
     {
-        return '[minor] Not a valid image';
+        return '[Minor] Not a valid image';
     }
     return undef;
@@ -5073,5 +6542,5 @@
                     }
                 }
-                return 'Not a floating point number' 
+                return 'Not a floating point number';
             }
             if ($format =~ /^rational\d+u$/ and $val < 0) {
@@ -5111,4 +6580,153 @@
 
 #------------------------------------------------------------------------------
+# Rename a file (with patch for Windows Unicode file names, and other problem)
+# Inputs: 0) ExifTool ref, 1) old name, 2) new name
+# Returns: true on success
+sub Rename($$$)
+{
+    my ($self, $old, $new) = @_;
+    my ($result, $try, $winUni);
+
+    if ($self->EncodeFileName($old)) {
+        $self->EncodeFileName($new, 1);
+        $winUni = 1;
+    } elsif ($self->EncodeFileName($new)) {
+        $old = $_[1];
+        $self->EncodeFileName($old, 1);
+        $winUni = 1;
+    }
+    for (;;) {
+        if ($winUni) {
+            $result = eval { Win32API::File::MoveFileExW($old, $new,
+                Win32API::File::MOVEFILE_REPLACE_EXISTING() |
+                Win32API::File::MOVEFILE_COPY_ALLOWED()) };
+        } else {
+            $result = rename($old, $new);
+        }
+        last if $result or $^O ne 'MSWin32';
+        # keep trying for up to 0.5 seconds
+        # (patch for Windows denial-of-service susceptibility)
+        $try = ($try || 1) + 1;
+        last if $try > 50;
+        select(undef,undef,undef,0.01); # sleep for 0.01 sec
+    }
+    return $result;
+}
+
+#------------------------------------------------------------------------------
+# Delete a file (with patch for Windows Unicode file names)
+# Inputs: 0) ExifTool ref, 1-N) names of files to delete
+# Returns: number of files deleted
+sub Unlink($@)
+{
+    my $self = shift;
+    my $result = 0;
+    while (@_) {
+        my $file = shift;
+        if ($self->EncodeFileName($file)) {
+            ++$result if eval { Win32API::File::DeleteFileW($file) };
+        } else {
+            ++$result if unlink $file;
+        }
+    }
+    return $result;
+}
+
+#------------------------------------------------------------------------------
+# Set file times (Unix seconds since the epoch)
+# Inputs: 0) ExifTool ref, 1) file name or ref, 2) access time, 3) modification time,
+#         4) inode change or creation time (or undef for any time to avoid setting)
+#         5) flag to suppress warning
+# Returns: 1 on success, 0 on error
+my $k32SetFileTime;
+sub SetFileTime($$;$$$$)
+{
+    my ($self, $file, $atime, $mtime, $ctime, $noWarn) = @_;
+    my $saveFile;
+    local *FH;
+
+    # open file by name if necessary
+    unless (ref $file) {
+        # (file will be automatically closed when *FH goes out of scope)
+        unless ($self->Open(\*FH, $file, '+<')) {
+            my $success;
+            if (defined $atime or defined $mtime) {
+                my ($a, $m, $c) = $self->GetFileTime($file);
+                $atime = $a unless defined $atime;
+                $mtime = $m unless defined $mtime;
+                $success = eval { utime($atime, $mtime, $file) } if defined $atime and defined $mtime;
+            }
+            $self->Warn('Error opening file for update') unless $success;
+            return $success;
+        }
+        $saveFile = $file;
+        $file = \*FH;
+    }
+    # on Windows, try to work around incorrect file times when daylight saving time is in effect
+    if ($^O eq 'MSWin32') {
+        if (not eval { require Win32::API }) {
+            $self->WarnOnce('Install Win32::API for proper handling of Windows file times');
+        } elsif (not eval { require Win32API::File }) {
+            $self->WarnOnce('Install Win32API::File for proper handling of Windows file times');
+        } else {
+            # get Win32 handle, needed for SetFileTime
+            my $win32Handle = eval { Win32API::File::GetOsFHandle($file) };
+            unless ($win32Handle) {
+                $self->Warn('Win32API::File::GetOsFHandle returned invalid handle');
+                return 0;
+            }
+            # convert Unix seconds to FILETIME structs
+            my $time;
+            foreach $time ($atime, $mtime, $ctime) {
+                # set to NULL if not defined (i.e. do not change)
+                defined $time or $time = 0, next;
+                # convert to 100 ns intervals since 0:00 UTC Jan 1, 1601
+                # (89 leap years between 1601 and 1970)
+                my $wt = ($time + (((1970-1601)*365+89)*24*3600)) * 1e7;
+                my $hi = int($wt / 4294967296);
+                $time = pack 'LL', int($wt - $hi * 4294967296), $hi; # pack FILETIME struct
+            }
+            unless ($k32SetFileTime) {
+                return 0 if defined $k32SetFileTime;
+                $k32SetFileTime = new Win32::API('KERNEL32', 'SetFileTime', 'NPPP', 'I');
+                unless ($k32SetFileTime) {
+                    $self->Warn('Error calling Win32::API::SetFileTime');
+                    $k32SetFileTime = 0;
+                    return 0;
+                }
+            }
+            unless ($k32SetFileTime->Call($win32Handle, $ctime, $atime, $mtime)) {
+                $self->Warn('Win32::API::SetFileTime returned ' . Win32::GetLastError());
+                return 0;
+            }
+            return 1;
+        }
+    }
+    # other OS (or Windows fallback)
+    if (defined $atime and defined $mtime) {
+        my $success;
+        local $SIG{'__WARN__'} = \&SetWarning; # (this may not be necessary)
+        for (;;) {
+            undef $evalWarning;
+            # (this may fail on the first try if futimes is not implemented)
+            $success = eval { utime($atime, $mtime, $file) };
+            last if $success or not defined $saveFile;
+            close $file;
+            $file = $saveFile;
+            undef $saveFile;
+        }
+        unless ($noWarn) {
+            if ($@ or $evalWarning) {
+                $self->Warn(CleanWarning($@ || $evalWarning));
+            } elsif (not $success) {
+                $self->Warn('Error setting file time');
+            }
+        }
+        return $success;
+    }
+    return 1; # (nothing to do)
+}
+
+#------------------------------------------------------------------------------
 # Copy data block from RAF to output file in max 64kB chunks
 # Inputs: 0) RAF ref, 1) outfile ref, 2) block size
@@ -5129,5 +6747,5 @@
 
 #------------------------------------------------------------------------------
-# 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 ]
@@ -5137,5 +6755,5 @@
 {
     my ($self, $imageDataBlocks, $outfile) = @_;
-    my $raf = $self->{RAF};
+    my $raf = $$self{RAF};
     my ($dataBlock, $err);
     my $num = @$imageDataBlocks;
@@ -5158,5 +6776,5 @@
 
 #------------------------------------------------------------------------------
-# 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
@@ -5191,6 +6809,6 @@
     my $tagInfo;
     $dataPt = \$newData;
-    foreach $tagInfo ($self->GetNewTagInfoList($tagTablePtr)) {
-        my $tagID = $tagInfo->{TagID};
+    foreach $tagInfo (sort { $$a{TagID} <=> $$b{TagID} } $self->GetNewTagInfoList($tagTablePtr)) {
+        my $tagID = $$tagInfo{TagID};
         # evaluate conditional tags now if necessary
         if (ref $$tagTablePtr{$tagID} eq 'ARRAY' or $$tagInfo{Condition}) {
@@ -5199,7 +6817,7 @@
         }
         # add offsets for variable-sized tags if necessary
-        while (@varInfo and $varInfo[0] < $tagID) {
-            shift @varInfo;             # discard index
-            $varSize = shift @varInfo;  # get accumulated variable size
+        while (@varInfo and $varInfo[0][0] < $tagID) {
+            $varSize = $varInfo[0][1];  # get accumulated variable size
+            shift @varInfo;
         }
         my $count = 1;
@@ -5222,17 +6840,21 @@
             $format = $defaultFormat;
         }
+        # read/write using variable format if changed in Hook
+        $format = $varInfo[0][2] if @varInfo and $varInfo[0][0] == $tagID;
         my $val = ReadValue($dataPt, $entry, $format, $count, $dirLen-$entry);
         next unless defined $val;
-        my $nvHash = $self->GetNewValueHash($tagInfo);
-        next unless IsOverwriting($nvHash, $val);
-        my $newVal = GetNewValues($nvHash);
+        my $nvHash = $self->GetNewValueHash($tagInfo, $$self{CUR_WRITE_GROUP});
+        next unless $self->IsOverwriting($nvHash, $val) > 0;
+        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 & $mask) | ($val & ~$mask) if defined $mask;
+        $newVal = (($newVal << $$tagInfo{BitShift}) & $mask) | ($val & ~$mask) if $mask;
         # set the size
         if ($$tagInfo{DataTag} and not $$tagInfo{IsOffset}) {
             warn 'Internal error' unless $newVal == 0xfeedfeed;
-            my $data = $self->GetNewValues($$tagInfo{DataTag});
+            my $data = $self->GetNewValue($$tagInfo{DataTag});
             $newVal = length($data) if defined $data;
             my $format = $$tagInfo{Format} || $$tagTablePtr{FORMAT} || 'int32u';
@@ -5245,5 +6867,5 @@
             $self->VerboseValue("- $dirName:$$tagInfo{Name}", $val);
             $self->VerboseValue("+ $dirName:$$tagInfo{Name}", $newVal);
-            ++$self->{CHANGED};
+            ++$$self{CHANGED};
         }
     }
@@ -5254,9 +6876,9 @@
         my $fixup = $$dirInfo{Fixup};
         my $tagID;
-        foreach $tagID (@{$tagTablePtr->{IS_OFFSET}}) {
+        foreach $tagID (@{$$tagTablePtr{IS_OFFSET}}) {
             $tagInfo = $self->GetTagInfo($tagTablePtr, $tagID) or next;
-            while (@varInfo and $varInfo[0] < $tagID) {
+            while (@varInfo and $varInfo[0][0] < $tagID) {
+                $varSize = $varInfo[0][1];
                 shift @varInfo;
-                $varSize = shift @varInfo;
             }
             my $entry = $tagID * $increment + $varSize; # (no offset to dirStart for new dir data)
@@ -5265,9 +6887,9 @@
             my $format = $$tagInfo{Format} || $$tagTablePtr{FORMAT} || 'int32u';
             my $offset = ReadValue($dataPt, $entry, $format, 1, $dirLen-$entry);
-            # ignore if offset is zero (ie. Ricoh DNG uses this to indicate no preview)
+            # ignore if offset is zero (eg. Ricoh DNG uses this to indicate no preview)
             next unless $offset;
             $fixup->AddFixup($entry, $$tagInfo{DataTag}, $format);
             # handle the preview image now if this is a JPEG file
-            next unless $self->{FILE_TYPE} eq 'JPEG' and $$tagInfo{DataTag} and
+            next unless $$self{FILE_TYPE} eq 'JPEG' and $$tagInfo{DataTag} and
                 $$tagInfo{DataTag} eq 'PreviewImage' and defined $$tagInfo{OffsetPair};
             # NOTE: here we assume there are no var-sized tags between the
@@ -5276,11 +6898,13 @@
             $entry = $$tagInfo{OffsetPair} * $increment + $varSize;
             my $size = ReadValue($dataPt, $entry, $format, 1, $dirLen-$entry);
-            my $previewInfo = $self->{PREVIEW_INFO};
-            $previewInfo or $previewInfo = $self->{PREVIEW_INFO} = { };
+            my $previewInfo = $$self{PREVIEW_INFO};
+            $previewInfo or $previewInfo = $$self{PREVIEW_INFO} = {
+                Fixup => new Image::ExifTool::Fixup,
+            };
             # set flag indicating we are using short pointers
             $$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->GetNewValues($Image::ExifTool::Composite{PreviewImage});
+            $$previewInfo{Data} = $self->GetNewValue(GetCompositeTagInfo('PreviewImage'));
             unless (defined $$previewInfo{Data}) {
                 if ($offset >= 0 and $offset + $size <= $$dirInfo{DataLen}) {
@@ -5300,7 +6924,7 @@
             my $tagInfo = $self->GetTagInfo($tagTablePtr, $tagID);
             next unless defined $tagInfo;
-            while (@varInfo and $varInfo[0] < $tagID) {
+            while (@varInfo and $varInfo[0][0] < $tagID) {
+                $varSize = $varInfo[0][1];
                 shift @varInfo;
-                $varSize = shift @varInfo;
             }
             my $entry = int($tagID) * $increment + $varSize;
@@ -5316,5 +6940,5 @@
             next unless $$tagInfo{SubDirectory}; # (just to be safe)
             my %subdirInfo = ( DataPt => \$newData, DirStart => $entry );
-            my $subTablePtr = GetTagTable($tagInfo->{SubDirectory}{TagTable});
+            my $subTablePtr = GetTagTable($$tagInfo{SubDirectory}{TagTable});
             my $dat = $self->WriteDirectory(\%subdirInfo, $subTablePtr);
             substr($newData, $entry) = $dat if defined $dat and length $dat;
@@ -5331,4 +6955,5 @@
 {
     my ($self, $dirInfo, $tagTablePtr) = @_;
+    $self or return 1;    # allow dummy access
     my $buff = '';
     $$dirInfo{OutFile} = \$buff;
@@ -5356,5 +6981,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMP.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMP.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMP.pm	(revision 34921)
@@ -24,4 +24,8 @@
 #               9) http://www.w3.org/TR/SVG11/
 #               10) http://www.adobe.com/devnet/xmp/pdfs/XMPSpecificationPart2.pdf (Oct 2008)
+#               11) http://www.extensis.com/en/support/kb_article.jsp?articleNumber=6102211
+#               12) http://www.cipa.jp/std/documents/e/DC-010-2012_E.pdf
+#               13) http://www.cipa.jp/std/documents/e/DC-010-2017_E.pdf (changed to
+#                   http://www.cipa.jp/std/documents/e/DC-X010-2017.pdf)
 #
 # Notes:      - Property qualifiers are handled as if they were separate
@@ -40,11 +44,12 @@
 
 use strict;
-use vars qw($VERSION $AUTOLOAD @ISA @EXPORT_OK $xlatNamespace %nsURI %dateTimeInfo
-            %xmpTableDefaults %specialStruct %sDimensions %sArea %sColorant);
+use vars qw($VERSION $AUTOLOAD @ISA @EXPORT_OK %stdXlatNS %nsURI %latConv %longConv
+            %dateTimeInfo %xmpTableDefaults %specialStruct %sDimensions %sArea %sColorant);
 use Image::ExifTool qw(:Utils);
 use Image::ExifTool::Exif;
+use Image::ExifTool::GPS;
 require Exporter;
 
-$VERSION = '2.37';
+$VERSION = '3.38';
 @ISA = qw(Exporter);
 @EXPORT_OK = qw(EscapeXML UnescapeXML);
@@ -52,20 +57,21 @@
 sub ProcessXMP($$;$);
 sub WriteXMP($$;$);
-sub CheckXMP($$$);
-sub ParseXMPElement($$$;$$$);
+sub CheckXMP($$$;$);
+sub ParseXMPElement($$$;$$$$);
 sub DecodeBase64($);
+sub EncodeBase64($;$);
 sub SaveBlankInfo($$$;$);
 sub ProcessBlankInfo($$$;$);
 sub ValidateXMP($;$);
-sub UnescapeChar($$);
-sub AddFlattenedTags($$);
+sub ValidateProperty($$;$);
+sub UnescapeChar($$;$);
+sub AddFlattenedTags($;$$);
 sub FormatXMPDate($);
 sub ConvertRational($);
-
-my %curNS;  # namespaces currently in effect while parsing the file
-
-# lookup for translating to ExifTool namespaces
-# Note: Use $xlatNamespace (only valid during processing) to do the translation
-my %stdXlatNS = (
+sub ConvertRationalList($);
+sub WriteGSpherical($$$);
+
+# lookup for translating to ExifTool namespaces (and family 1 group names)
+%stdXlatNS = (
     # shorten ugly namespace prefixes
     'Iptc4xmpCore' => 'iptcCore',
@@ -74,28 +80,33 @@
     'MicrosoftPhoto' => 'microsoft',
     'prismusagerights' => 'pur',
-);
-
-# translate ExifTool namespaces to standard XMP namespace prefixes
+    'GettyImagesGIFT' => 'getty',
+);
+
+# translate ExifTool XMP family 1 group names back to standard XMP namespace prefixes
 my %xmpNS = (
-    # shorten ugly namespace prefixes
     'iptcCore' => 'Iptc4xmpCore',
     'iptcExt' => 'Iptc4xmpExt',
-    'photomechanic'=> 'photomech',
+    'photomech'=> 'photomechanic',
     'microsoft' => 'MicrosoftPhoto',
+    'getty' => 'GettyImagesGIFT',
     # (prism changed their spec to now use 'pur')
     # 'pur' => 'prismusagerights',
 );
 
-# Lookup to translate our namespace prefixes into URI's.  This list need
-# not be complete, but it must contain an entry for each namespace prefix
-# (NAMESPACE) for writable tags in the XMP tables or in structures
+# Lookup to translate standard XMP namespace prefixes into URI's.  This list
+# need not be complete, but it must contain an entry for each namespace prefix
+# (NAMESPACE) for writable tags in the XMP tables or in structures that doesn't
+# define a URI.  Also, the namespace must be defined here for non-standard
+# namespace prefixes to be recognized.
 %nsURI = (
     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/',
     exif      => 'http://ns.adobe.com/exif/1.0/',
+    exifEX    => 'http://cipa.jp/exif/1.0/',
     iX        => 'http://ns.adobe.com/iX/1.0/',
     pdf       => 'http://ns.adobe.com/pdf/1.3/',
@@ -105,5 +116,4 @@
     rdfs      => 'http://www.w3.org/2000/01/rdf-schema#',
     stDim     => 'http://ns.adobe.com/xap/1.0/sType/Dimensions#',
-    stArea    => 'http://ns.adobe.com/xap/1.0/sType/Area#',
     stEvt     => 'http://ns.adobe.com/xap/1.0/sType/ResourceEvent#',
     stFnt     => 'http://ns.adobe.com/xap/1.0/sType/Font#',
@@ -127,4 +137,5 @@
     dex       => 'http://ns.optimasc.com/dex/1.0/',
     mediapro  => 'http://ns.iview-multimedia.com/mediapro/1.0/',
+    expressionmedia => 'http://ns.microsoft.com/expressionmedia/1.0/',
     Iptc4xmpCore => 'http://iptc.org/std/Iptc4xmpCore/1.0/xmlns/',
     Iptc4xmpExt => 'http://iptc.org/std/Iptc4xmpExt/2008-02-29/',
@@ -136,22 +147,47 @@
     lr        => 'http://ns.adobe.com/lightroom/1.0/',
     DICOM     => 'http://ns.adobe.com/DICOM/',
+   'drone-dji'=> 'http://www.dji.com/drone-dji/1.0/',
     svg       => 'http://www.w3.org/2000/svg',
     et        => 'http://ns.exiftool.ca/1.0/',
-    # namespaces defined in XMP2.pl:
+#
+# namespaces defined in XMP2.pl:
+#
     plus      => 'http://ns.useplus.org/ldf/xmp/1.0/',
-    prism     => 'http://prismstandard.org/namespaces/basic/2.1/',
+    # (prism recommendations from http://www.prismstandard.org/specifications/3.0/Image_Guide_3.0.htm)
+    prism     => 'http://prismstandard.org/namespaces/basic/2.0/',
     prl       => 'http://prismstandard.org/namespaces/prl/2.1/',
     pur       => 'http://prismstandard.org/namespaces/prismusagerights/2.1/',
+    pmi       => 'http://prismstandard.org/namespaces/pmi/2.2/',
+    prm       => 'http://prismstandard.org/namespaces/prm/3.0/',
     acdsee    => 'http://ns.acdsee.com/iptc/1.0/',
     digiKam   => 'http://www.digikam.org/ns/1.0/',
-    swf       => 'http://ns.adobe.com/swf/1.0',
+    swf       => 'http://ns.adobe.com/swf/1.0/',
     cell      => 'http://developer.sonyericsson.com/cell/1.0/',
+    aas       => 'http://ns.apple.com/adjustment-settings/1.0/',
    'mwg-rs'   => 'http://www.metadataworkinggroup.com/schemas/regions/',
    'mwg-kw'   => 'http://www.metadataworkinggroup.com/schemas/keywords/',
    'mwg-coll' => 'http://www.metadataworkinggroup.com/schemas/collections/',
+    stArea    => 'http://ns.adobe.com/xmp/sType/Area#',
+    extensis  => 'http://ns.extensis.com/extensis/1.0/',
+    ics       => 'http://ns.idimager.com/ics/1.0/',
+    fpv       => 'http://ns.fastpictureviewer.com/fpv/1.0/',
+    creatorAtom=>'http://ns.adobe.com/creatorAtom/1.0/',
+   'apple-fi' => 'http://ns.apple.com/faceinfo/1.0/',
+    GAudio    => 'http://ns.google.com/photos/1.0/audio/',
+    GImage    => 'http://ns.google.com/photos/1.0/image/',
+    GPano     => 'http://ns.google.com/photos/1.0/panorama/',
+    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;
@@ -162,28 +198,15 @@
 
 # conversions for GPS coordinates
-sub ToDegrees
-{
-    require Image::ExifTool::GPS;
-    Image::ExifTool::GPS::ToDegrees($_[0], 1);
-}
-my %latConv = (
-    ValueConv    => \&ToDegrees,
-    RawConv => 'require Image::ExifTool::GPS; $val', # to load Composite tags and routines
-    ValueConvInv => q{
-        require Image::ExifTool::GPS;
-        Image::ExifTool::GPS::ToDMS($self, $val, 2, "N");
-    },
+%latConv = (
+    ValueConv    => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
+    ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val, 2, "N")',
     PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "N")',
-    PrintConvInv => \&ToDegrees,
-);
-my %longConv = (
-    ValueConv    => \&ToDegrees,
-    RawConv => 'require Image::ExifTool::GPS; $val',
-    ValueConvInv => q{
-        require Image::ExifTool::GPS;
-        Image::ExifTool::GPS::ToDMS($self, $val, 2, "E");
-    },
+    PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
+);
+%longConv = (
+    ValueConv    => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
+    ValueConvInv => 'Image::ExifTool::GPS::ToDMS($self, $val, 2, "E")',
     PrintConv    => 'Image::ExifTool::GPS::ToDMS($self, $val, 1, "E")',
-    PrintConvInv => \&ToDegrees,
+    PrintConvInv => 'Image::ExifTool::GPS::ToDegrees($val, 1)',
 );
 %dateTimeInfo = (
@@ -191,6 +214,21 @@
     Writable => 'date',
     Shift => 'Time',
+    Validate => 'ValidateXMPDate($val)',
     PrintConv => '$self->ConvertDateTime($val)',
     PrintConvInv => '$self->InverseDateTime($val,undef,1)',
+);
+
+# this conversion allows alternate language support for designated boolean tags
+my %boolConv = (
+    PrintConv => {
+        OTHER => sub { # (inverse conversion is the same)
+            my $val = shift;
+            return 'False' if lc $val eq 'false';
+            return 'True' if lc $val eq 'true';
+            return $val;
+        },
+        True => 'True',
+        False => 'False',
+    },
 );
 
@@ -198,4 +236,7 @@
 # (Note: namespaces with non-standard prefixes aren't currently ignored)
 my %ignoreNamespace = ( 'x'=>1, rdf=>1, xmlns=>1, xml=>1, svg=>1, et=>1, office=>1 );
+
+# XMP properties to ignore (set dynamically via dirInfo IgnoreProp)
+my %ignoreProp;
 
 # these are the attributes that we handle for properties that contain
@@ -211,5 +252,6 @@
     'rdf:nodeID' => 1,
     'et:toolkit' => 1,
-    'rdf:xmlns' => 1, # this is presumably the default namespace, which we currently ignore
+    'rdf:xmlns'  => 1, # this is presumably the default namespace, which we currently ignore
+    'lastUpdate' => [ 'Image::ExifTool::XMP::XML', 'lastUpdate', 'LastUpdate' ], # found in XML from Sony ILCE-7S MP4
 );
 
@@ -222,4 +264,5 @@
     TYPE        => 1, # [optional] rdf:type resource for struct (if used, the StructType flag
                       # will be set automatically for all derived flattened tags when writing)
+    GROUPS      => 1, # [optional] specifies family group 2 name for the structure
 );
 # XMP structures (each structure is similar to a tag table so we can
@@ -252,4 +295,11 @@
     # added May 2010
     originalDocumentID => { }, # (undocumented property written by Adobe InDesign)
+    # added Aug 2016 (INDD again)
+    lastURL         => { },
+    linkForm        => { },
+    linkCategory    => { },
+    placedXResolution    => { },
+    placedYResolution    => { },
+    placedResolutionUnit => { },
 );
 my %sResourceEvent = (
@@ -287,4 +337,6 @@
    'format'     => { },
     image       => {
+        Avoid => 1,
+        Groups => { 2 => 'Preview' },
         ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
         ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
@@ -299,4 +351,5 @@
    'format'     => { },
     image       => {
+        Groups => { 2 => 'Preview' },
         ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
         ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
@@ -339,7 +392,21 @@
     green       => { Writable => 'integer' },
     blue        => { Writable => 'integer' },
+    gray        => { Writable => 'integer' },
     L           => { Writable => 'real' },
     A           => { Writable => 'integer' },
     B           => { Writable => 'integer' },
+    # 'tint' observed in INDD sample - PH
+    tint        => { Writable => 'integer', Notes => 'not part of 2010 XMP specification' },
+);
+my %sSwatchGroup = (
+    STRUCT_NAME => 'SwatchGroup',
+    NAMESPACE   => 'xmpG',
+    groupName   => { },
+    groupType   => { Writable => 'integer' },
+    Colorants => {
+        FlatName => 'SwatchColorant',
+        Struct => \%sColorant,
+        List => 'Seq',
+    },
 );
 my %sFont = (
@@ -356,6 +423,6 @@
 );
 my %sOECF = (
+    STRUCT_NAME => 'OECF',
     NAMESPACE   => 'exif',
-    STRUCT_NAME => 'OECF',
     Columns     => { Writable => 'integer' },
     Rows        => { Writable => 'integer' },
@@ -368,42 +435,105 @@
     STRUCT_NAME => 'CorrectionMask',
     NAMESPACE   => 'crs',
-    What         => { },
-    MaskValue    => { Writable => 'real' },
-    Radius       => { Writable => 'real' },
-    Flow         => { Writable => 'real' },
-    CenterWeight => { Writable => 'real' },
+    # disable List behaviour of flattened Gradient/PaintBasedCorrections
+    # because these are nested in lists and the flattened tags can't
+    # do justice to this complex structure
+    What         => { List => 0 },
+    MaskValue    => { Writable => 'real', List => 0, FlatName => 'Value' },
+    Radius       => { Writable => 'real', List => 0 },
+    Flow         => { Writable => 'real', List => 0 },
+    CenterWeight => { Writable => 'real', List => 0 },
     Dabs         => { List => 'Seq' },
-    ZeroX        => { Writable => 'real' },
-    ZeroY        => { Writable => 'real' },
-    FullX        => { Writable => 'real' },
-    FullY        => { Writable => 'real' },
+    ZeroX        => { Writable => 'real', List => 0 },
+    ZeroY        => { Writable => 'real', List => 0 },
+    FullX        => { Writable => 'real', List => 0 },
+    FullY        => { Writable => 'real', List => 0 },
+    # new elements used in CircularGradientBasedCorrections CorrectionMasks
+    # and RetouchAreas Masks
+    Top          => { Writable => 'real', List => 0 },
+    Left         => { Writable => 'real', List => 0 },
+    Bottom       => { Writable => 'real', List => 0 },
+    Right        => { Writable => 'real', List => 0 },
+    Angle        => { Writable => 'real', List => 0 },
+    Midpoint     => { Writable => 'real', List => 0 },
+    Roundness    => { Writable => 'real', List => 0 },
+    Feather      => { Writable => 'real', List => 0 },
+    Flipped      => { Writable => 'boolean', List => 0 },
+    Version      => { Writable => 'integer', List => 0 },
+    SizeX        => { Writable => 'real', List => 0 },
+    SizeY        => { Writable => 'real', List => 0 },
+    X            => { Writable => 'real', List => 0 },
+    Y            => { Writable => 'real', List => 0 },
+    Alpha        => { Writable => 'real', List => 0 },
+    CenterValue  => { Writable => 'real', List => 0 },
+    PerimeterValue=>{ Writable => 'real', List => 0 },
+);
+my %sCorrectionRangeMask = (
+    STRUCT_NAME => 'CorrectionRangeMask',
+    NAMESPACE   => 'crs',
+    Version     => { },
+    Type        => { },
+    ColorAmount => { Writable => 'real' },
+    LumMin      => { Writable => 'real' },
+    LumMax      => { Writable => 'real' },
+    LumFeather  => { Writable => 'real' },
+    DepthMin    => { Writable => 'real' },
+    DepthMax    => { Writable => 'real' },
+    DepthFeather=> { Writable => 'real' },
 );
 my %sCorrection = (
     STRUCT_NAME => 'Correction',
     NAMESPACE   => 'crs',
-    What => { },
-    CorrectionAmount => { Writable => 'real' },
-    CorrectionActive => { Writable => 'boolean' },
-    LocalExposure    => { Writable => 'real' },
-    LocalSaturation  => { Writable => 'real' },
-    LocalContrast    => { Writable => 'real' },
-    LocalClarity     => { Writable => 'real' },
-    LocalSharpness   => { Writable => 'real' },
-    LocalBrightness  => { Writable => 'real' },
-    LocalToningHue   => { Writable => 'real' },
-    LocalToningSaturation => { Writable => 'real' },
-    CorrectionMasks  => { Struct => \%sCorrectionMask, List => 'Seq' },
-);
-
-# IPTC Extension 1.0 structures
-my %sLocationDetails = (
-    NAMESPACE   => 'Iptc4xmpExt',
-    STRUCT_NAME => 'LocationDetails',
-    City         => { },
-    CountryCode  => { },
-    CountryName  => { },
-    ProvinceState=> { },
-    Sublocation  => { },
-    WorldRegion  => { },
+    What => { List => 0 },
+    CorrectionAmount => { FlatName => 'Amount',     Writable => 'real', List => 0 },
+    CorrectionActive => { FlatName => 'Active',     Writable => 'boolean', List => 0 },
+    LocalExposure    => { FlatName => 'Exposure',   Writable => 'real', List => 0 },
+    LocalSaturation  => { FlatName => 'Saturation', Writable => 'real', List => 0 },
+    LocalContrast    => { FlatName => 'Contrast',   Writable => 'real', List => 0 },
+    LocalClarity     => { FlatName => 'Clarity',    Writable => 'real', List => 0 },
+    LocalSharpness   => { FlatName => 'Sharpness',  Writable => 'real', List => 0 },
+    LocalBrightness  => { FlatName => 'Brightness', Writable => 'real', List => 0 },
+    LocalToningHue   => { FlatName => 'Hue',        Writable => 'real', List => 0 },
+    LocalToningSaturation => { FlatName => 'Saturation',        Writable => 'real', List => 0 },
+    LocalExposure2012     => { FlatName => 'Exposure2012',      Writable => 'real', List => 0 },
+    LocalContrast2012     => { FlatName => 'Contrast2012',      Writable => 'real', List => 0 },
+    LocalHighlights2012   => { FlatName => 'Highlights2012',    Writable => 'real', List => 0 },
+    LocalShadows2012      => { FlatName => 'Shadows2012',       Writable => 'real', List => 0 },
+    LocalClarity2012      => { FlatName => 'Clarity2012',       Writable => 'real', List => 0 },
+    LocalLuminanceNoise   => { FlatName => 'LuminanceNoise',    Writable => 'real', List => 0 },
+    LocalMoire       => { FlatName => 'Moire',      Writable => 'real', List => 0 },
+    LocalDefringe    => { FlatName => 'Defringe',   Writable => 'real', List => 0 },
+    LocalTemperature => { FlatName => 'Temperature',Writable => 'real', List => 0 },
+    LocalTint        => { FlatName => 'Tint',       Writable => 'real', List => 0 },
+    LocalHue         => { FlatName => 'Hue',        Writable => 'real', List => 0 },
+    LocalWhites2012  => { FlatName => 'Whites2012', Writable => 'real', List => 0 },
+    LocalBlacks2012  => { FlatName => 'Blacks2012', Writable => 'real', List => 0 },
+    LocalDehaze      => { FlatName => 'Dehaze', Writable => 'real', List => 0 },
+    LocalTexture     => { FlatName => 'Texture', Writable => 'real', List => 0 },
+    CorrectionRangeMask => {
+        FlatName => 'RangeMask',
+        Struct => \%sCorrectionRangeMask,
+    },
+    CorrectionMasks  => {
+        FlatName => 'Mask',
+        Struct => \%sCorrectionMask,
+        List => 'Seq',
+    },
+);
+my %sRetouchArea = (
+    STRUCT_NAME => 'RetouchArea',
+    NAMESPACE   => 'crs',
+    SpotType        => { List => 0 },
+    SourceState     => { List => 0 },
+    Method          => { List => 0 },
+    SourceX         => { Writable => 'real',    List => 0 },
+    OffsetY         => { Writable => 'real',    List => 0 },
+    Opacity         => { Writable => 'real',    List => 0 },
+    Feather         => { Writable => 'real',    List => 0 },
+    Seed            => { Writable => 'integer', List => 0 },
+    Masks => {
+        FlatName => 'Mask',
+        Struct => \%sCorrectionMask,
+        List => 'Seq',
+    },
 );
 
@@ -457,9 +587,13 @@
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::photoshop' },
     },
+    crd => {
+        Name => 'crd',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::crd' },
+    },
     crs => {
         Name => 'crs',
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::crs' },
     },
-    # crss - it would be difficult to add the ability to write this
+    # crss - it would be tedious to add the ability to write this
     aux => {
         Name => 'aux',
@@ -474,4 +608,8 @@
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::exif' },
     },
+    exifEX => {
+        Name => 'exifEX',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::exifEX' },
+    },
     iptcCore => {
         Name => 'iptcCore',
@@ -491,5 +629,5 @@
     plus => {
         Name => 'plus',
-        SubDirectory => { TagTable => 'Image::ExifTool::XMP::plus' },
+        SubDirectory => { TagTable => 'Image::ExifTool::PLUS::XMP' },
     },
     cc => {
@@ -509,4 +647,8 @@
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::MediaPro' },
     },
+    expressionmedia => {
+        Name => 'expressionmedia',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::ExpressionMedia' },
+    },
     microsoft => {
         Name => 'microsoft',
@@ -545,4 +687,12 @@
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::pur' },
     },
+    pmi => {
+        Name => 'pmi',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::pmi' },
+    },
+    prm => {
+        Name => 'prm',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::prm' },
+    },
     rdf => {
         Name => 'rdf',
@@ -569,20 +719,111 @@
         SubDirectory => { TagTable => 'Image::ExifTool::XMP::cell' },
     },
+    aas => {
+        Name => 'aas',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::aas' },
+    },
    'mwg-rs' => {
         Name => 'mwg-rs',
-        SubDirectory => { TagTable => 'Image::ExifTool::XMP::mwg_rs' },
+        SubDirectory => { TagTable => 'Image::ExifTool::MWG::Regions' },
     },
    'mwg-kw' => {
         Name => 'mwg-kw',
-        SubDirectory => { TagTable => 'Image::ExifTool::XMP::mwg_kw' },
+        SubDirectory => { TagTable => 'Image::ExifTool::MWG::Keywords' },
     },
    'mwg-coll' => {
         Name => 'mwg-coll',
-        SubDirectory => { TagTable => 'Image::ExifTool::XMP::mwg_coll' },
+        SubDirectory => { TagTable => 'Image::ExifTool::MWG::Collections' },
+    },
+    extensis => {
+        Name => 'extensis',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::extensis' },
+    },
+    ics => {
+        Name => 'ics',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::ics' },
+    },
+    fpv => {
+        Name => 'fpv',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::fpv' },
+    },
+    creatorAtom => {
+        Name => 'creatorAtom',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::creatorAtom' },
+    },
+   'apple-fi' => {
+        Name => 'apple-fi',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::apple_fi' },
+    },
+    GAudio => {
+        Name => 'GAudio',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::GAudio' },
+    },
+    GImage => {
+        Name => 'GImage',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::GImage' },
+    },
+    GPano => {
+        Name => 'GPano',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::GPano' },
+    },
+    GSpherical => {
+        Name => 'GSpherical',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::GSpherical' },
+    },
+    GDepth => {
+        Name => 'GDepth',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::GDepth' },
+    },
+    GFocus => {
+        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' },
+    },
+    getty => {
+        Name => 'getty',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::GettyImages' },
+    },
+   'drone-dji' => {
+        Name => 'drone-dji',
+        SubDirectory => { TagTable => 'Image::ExifTool::DJI::XMP' },
+    },
+    LImage => {
+        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)
+%Image::ExifTool::XMP::XML = (
+    GROUPS => { 0 => 'XML', 1 => 'XML', 2 => 'Unknown' },
+    PROCESS_PROC => \&ProcessXMP,
+    dc => {
+        Name => 'dc',
+        SubDirectory => { TagTable => 'Image::ExifTool::XMP::dc' },
+    },
+    lastUpdate => {
+        Groups => { 2 => 'Time' },
+        ValueConv => 'Image::ExifTool::XMP::ConvertXMPDate($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
     },
 );
 
 #
-# Tag tables for all XMP schemas:
+# Tag tables for all XMP namespaces:
 #
 # Writable - only need to define this for writable tags if not plain text
@@ -621,5 +862,5 @@
         The "x" namespace is used for the "xmpmeta" wrapper, and may contain an
         "xmptk" attribute that is extracted as the XMPToolkit tag.  When writing,
-        the XMPToolkit tag is automatically generated by ExifTool unless
+        the XMPToolkit tag is generated automatically by ExifTool unless
         specifically set to another value.
     },
@@ -627,5 +868,5 @@
 );
 
-# Dublin Core schema properties (dc)
+# Dublin Core namespace properties (dc)
 %Image::ExifTool::XMP::dc = (
     %xmpTableDefaults,
@@ -633,5 +874,5 @@
     NAMESPACE   => 'dc',
     TABLE_DESC => 'XMP Dublin Core',
-    NOTES => 'Dublin Core schema tags.',
+    NOTES => 'Dublin Core namespace tags.',
     contributor => { Groups => { 2 => 'Author' }, List => 'Bag' },
     coverage    => { },
@@ -651,5 +892,5 @@
 );
 
-# XMP Basic schema properties (xmp, xap)
+# XMP namespace properties (xmp, xap)
 %Image::ExifTool::XMP::xmp = (
     %xmpTableDefaults,
@@ -657,9 +898,9 @@
     NAMESPACE   => 'xmp',
     NOTES => q{
-        XMP Basic schema tags.  If the older "xap", "xapBJ", "xapMM" or "xapRights"
+        XMP namespace tags.  If the older "xap", "xapBJ", "xapMM" or "xapRights"
         namespace prefixes are found, they are translated to the newer "xmp",
         "xmpBJ", "xmpMM" and "xmpRights" prefixes for use in family 1 group names.
     },
-    Advisory    => { List => 'Bag' }, # (deprecated)
+    Advisory    => { List => 'Bag', Notes => 'deprecated' },
     BaseURL     => { },
     # (date/time tags not as reliable as EXIF)
@@ -672,24 +913,30 @@
     Nickname    => { },
     Rating      => { Writable => 'real', Notes => 'a value from 0 to 5, or -1 for "rejected"' },
-    Thumbnails  => { Struct => \%sThumbnail, List => 'Alt' },
-    ThumbnailsHeight => { Name => 'ThumbnailHeight', Flat => 1 },
-    ThumbnailsWidth  => { Name => 'ThumbnailWidth',  Flat => 1 },
-    ThumbnailsFormat => { Name => 'ThumbnailFormat', Flat => 1 },
-    ThumbnailsImage  => { Name => 'ThumbnailImage',  Flat => 1, Avoid => 1 },
+    RatingPercent=>{ Writable => 'real', Avoid => 1, Notes => 'non-standard' },
+    Thumbnails  => {
+        FlatName => 'Thumbnail',
+        Struct => \%sThumbnail,
+        List => 'Alt',
+    },
     # the following written by Adobe InDesign, not part of XMP spec:
-    PageInfo        => { Struct => \%sPageInfo, List => 'Seq' },
-    PageInfoPageNumber=>{Name => 'PageImagePageNumber', Flat => 1 },
-    PageInfoHeight  => { Name => 'PageImageHeight', Flat => 1 },
-    PageInfoWidth   => { Name => 'PageImageWidth',  Flat => 1 },
-    PageInfoFormat  => { Name => 'PageImageFormat', Flat => 1 },
-    PageInfoImage   => { Name => 'PageImage',       Flat => 1 },
-);
-
-# XMP Rights Management schema properties (xmpRights, xapRights)
+    PageInfo        => {
+        FlatName => 'PageImage',
+        Struct => \%sPageInfo,
+        List => 'Seq',
+    },
+    PageInfoImage => { Name => 'PageImage', Flat => 1 },
+    Title       => { Avoid => 1, Notes => 'non-standard', Writable => 'lang-alt' }, #11
+    Author      => { Avoid => 1, Notes => 'non-standard', Groups => { 2 => 'Author' } }, #11
+    Keywords    => { Avoid => 1, Notes => 'non-standard' }, #11
+    Description => { Avoid => 1, Notes => 'non-standard', Writable => 'lang-alt' }, #11
+    Format      => { Avoid => 1, Notes => 'non-standard' }, #11
+);
+
+# XMP Rights Management namespace properties (xmpRights, xapRights)
 %Image::ExifTool::XMP::xmpRights = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-xmpRights', 2 => 'Author' },
     NAMESPACE   => 'xmpRights',
-    NOTES => 'XMP Rights Management schema tags.',
+    NOTES => 'XMP Rights Management namespace tags.',
     Certificate     => { },
     Marked          => { Writable => 'boolean' },
@@ -699,17 +946,24 @@
 );
 
-# XMP Note schema properties (xmpNote)
+# XMP Note namespace properties (xmpNote)
 %Image::ExifTool::XMP::xmpNote = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-xmpNote' },
     NAMESPACE   => 'xmpNote',
-    NOTES => 'XMP Note schema tags.',
-    HasExtendedXMP => { Writable => 'boolean', Protected => 2 },
+    NOTES => 'XMP Note namespace tags.',
+    HasExtendedXMP => {
+        Notes => q{
+            this tag is protected so it is not writable directly.  Instead, it is set
+            automatically to the GUID of the extended XMP when writing extended XMP to a
+            JPEG image
+        },
+        Protected => 2,
+    },
 );
 
 # XMP xmpMM ManifestItem struct (ref PH, written by Adobe PDF library 8.0)
 my %sManifestItem = (
-    NAMESPACE => 'stMfs',
     STRUCT_NAME => 'ManifestItem',
+    NAMESPACE   => 'stMfs',
     linkForm            => { },
     placedXResolution   => { Namespace => 'xmpMM', Writable => 'real' },
@@ -721,14 +975,14 @@
 # the xmpMM Pantry
 my %sPantryItem = (
-    NAMESPACE => undef, # stores any top-level XMP tags
     STRUCT_NAME => 'PantryItem',
+    NAMESPACE   => undef, # stores any top-level XMP tags
     NOTES => q{
         This structure must have an InstanceID field, but may also contain any other
         XMP properties.
     },
-    InstanceID => { Namespace => 'xmpMM' },
-);
-
-# XMP Media Management schema properties (xmpMM, xapMM)
+    InstanceID => { Namespace => 'xmpMM', List => 0 },
+);
+
+# XMP Media Management namespace properties (xmpMM, xapMM)
 %Image::ExifTool::XMP::xmpMM = (
     %xmpTableDefaults,
@@ -736,5 +990,5 @@
     NAMESPACE   => 'xmpMM',
     TABLE_DESC => 'XMP Media Management',
-    NOTES => 'XMP Media Management schema tags.',
+    NOTES => 'XMP Media Management namespace tags.',
     DerivedFrom     => { Struct => \%sResourceRef },
     DocumentID      => { },
@@ -759,7 +1013,8 @@
     RenditionOf     => { Struct => \%sResourceRef }, # (deprecated)
     SaveID          => { Writable => 'integer' }, # (deprecated)
-);
-
-# XMP Basic Job Ticket schema properties (xmpBJ, xapBJ)
+    subject         => { List => 'Seq', Avoid => 1, Notes => 'undocumented' },
+);
+
+# XMP Basic Job Ticket namespace properties (xmpBJ, xapBJ)
 %Image::ExifTool::XMP::xmpBJ = (
     %xmpTableDefaults,
@@ -767,5 +1022,5 @@
     NAMESPACE   => 'xmpBJ',
     TABLE_DESC => 'XMP Basic Job Ticket',
-    NOTES => 'XMP Basic Job Ticket schema tags.',
+    NOTES => 'XMP Basic Job Ticket namespace tags.',
     # Note: JobRef is a List of structures.  To accomplish this, we set the XMP
     # List=>'Bag', but since SubDirectory is defined, this tag isn't writable
@@ -775,5 +1030,5 @@
 );
 
-# XMP Paged-Text schema properties (xmpTPg)
+# XMP Paged-Text namespace properties (xmpTPg)
 %Image::ExifTool::XMP::xmpTPg = (
     %xmpTableDefaults,
@@ -781,34 +1036,33 @@
     NAMESPACE   => 'xmpTPg',
     TABLE_DESC => 'XMP Paged-Text',
-    NOTES => 'XMP Paged-Text schema tags.',
+    NOTES => 'XMP Paged-Text namespace tags.',
     MaxPageSize         => { Struct => \%sDimensions },
     NPages              => { Writable => 'integer' },
-    Fonts               => { Struct => \%sFont, List => 'Bag' },
-    FontsFontName       => { Flat => 1, Name => 'FontName' },
-    FontsFontFamily     => { Flat => 1, Name => 'FontFamily' },
-    FontsFontFace       => { Flat => 1, Name => 'FontFace' },
-    FontsFontType       => { Flat => 1, Name => 'FontType' },
-    FontsVersionString  => { Flat => 1, Name => 'FontVersion' },
-    FontsComposite      => { Flat => 1, Name => 'FontComposite' },
-    FontsFontFileName   => { Flat => 1, Name => 'FontFileName' },
-    FontsChildFontFiles => { Flat => 1, Name => 'ChildFontFiles' },
-    Colorants           => { Struct => \%sColorant, List => 'Seq' },
-    ColorantsSwatchName => { Flat => 1, Name => 'ColorantSwatchName' },
-    ColorantsMode       => { Flat => 1, Name => 'ColorantMode' },
-    ColorantsType       => { Flat => 1, Name => 'ColorantType' },
-    ColorantsCyan       => { Flat => 1, Name => 'ColorantCyan' },
-    ColorantsMagenta    => { Flat => 1, Name => 'ColorantMagenta' },
-    ColorantsYellow     => { Flat => 1, Name => 'ColorantYellow' },
-    ColorantsBlack      => { Flat => 1, Name => 'ColorantBlack' },
-    ColorantsRed        => { Flat => 1, Name => 'ColorantRed' },
-    ColorantsGreen      => { Flat => 1, Name => 'ColorantGreen' },
-    ColorantsBlue       => { Flat => 1, Name => 'ColorantBlue' },
-    ColorantsL          => { Flat => 1, Name => 'ColorantL' },
-    ColorantsA          => { Flat => 1, Name => 'ColorantA' },
-    ColorantsB          => { Flat => 1, Name => 'ColorantB' },
+    Fonts               => {
+        FlatName => '',
+        Struct => \%sFont,
+        List => 'Bag',
+    },
+    FontsVersionString  => { Name => 'FontVersion',     Flat => 1 },
+    FontsComposite      => { Name => 'FontComposite',   Flat => 1 },
+    Colorants           => {
+        FlatName => 'Colorant',
+        Struct => \%sColorant,
+        List => 'Seq',
+    },
     PlateNames          => { List => 'Seq' },
-);
-
-# PDF schema properties (pdf)
+    # the following found in an AI file:
+    HasVisibleTransparency => { Writable => 'boolean' },
+    HasVisibleOverprint    => { Writable => 'boolean' },
+    SwatchGroups => {
+        Struct => \%sSwatchGroup,
+        List => 'Seq',
+    },
+    SwatchGroupsColorants => { Name => 'SwatchGroupsColorants', Flat => 1 },
+    SwatchGroupsGroupName => { Name => 'SwatchGroupName',       Flat => 1 },
+    SwatchGroupsGroupType => { Name => 'SwatchGroupType',       Flat => 1 },
+);
+
+# PDF namespace properties (pdf)
 %Image::ExifTool::XMP::pdf = (
     %xmpTableDefaults,
@@ -817,5 +1071,5 @@
     TABLE_DESC => 'XMP PDF',
     NOTES => q{
-        Adobe PDF schema tags.  The official XMP specification defines only
+        Adobe PDF namespace tags.  The official XMP specification defines only
         Keywords, PDFVersion, Producer and Trapped.  The other tags are included
         because they have been observed in PDF files, but some are avoided when
@@ -836,10 +1090,10 @@
         PrintConv => { True => 'True', False => 'False', Unknown => 'Unknown' },
     },
-    Keywords    => { },
+    Keywords    => { Priority => -1 }, # (-1 to get below Priority 0 PDF:Keywords)
     PDFVersion  => { },
     Producer    => { Groups => { 2 => 'Author' } },
 );
 
-# PDF extension schema properties (pdfx)
+# PDF extension namespace properties (pdfx)
 %Image::ExifTool::XMP::pdfx = (
     %xmpTableDefaults,
@@ -853,5 +1107,5 @@
 );
 
-# Photoshop schema properties (photoshop)
+# Photoshop namespace properties (photoshop)
 %Image::ExifTool::XMP::photoshop = (
     %xmpTableDefaults,
@@ -859,5 +1113,5 @@
     NAMESPACE   => 'photoshop',
     TABLE_DESC => 'XMP Photoshop',
-    NOTES => 'Adobe Photoshop schema tags.',
+    NOTES => 'Adobe Photoshop namespace tags.',
     AuthorsPosition => { Groups => { 2 => 'Author' } },
     CaptionWriter   => { Groups => { 2 => 'Author' } },
@@ -882,12 +1136,14 @@
     DateCreated     => { Groups => { 2 => 'Time' }, %dateTimeInfo },
     DocumentAncestors => {
-        List => 'bag',
-        Struct => {
-            STRUCT_NAME => 'Ancestor',
-            NAMESPACE   => 'photoshop',
-            AncestorID => { },
-        },
-    },
-    DocumentAncestorsAncestorID => { Name => 'DocumentAncestorID', Flat => 1 },
+        List => 'Bag',
+        # Contrary to their own XMP specification, Adobe writes this as a simple Bag
+        # of strings instead of structures, so comment out the structure definition...
+        # FlatName => 'Document',
+        # Struct => {
+        #     STRUCT_NAME => 'Ancestor',
+        #     NAMESPACE   => 'photoshop',
+        #     AncestorID  => { },
+        # },
+    },
     Headline        => { },
     History         => { }, #PH (CS3)
@@ -904,15 +1160,14 @@
     SupplementalCategories  => { List => 'Bag' },
     TextLayers => {
-        List => 'seq',
+        FlatName => 'Text',
+        List => 'Seq',
         Struct => {
             STRUCT_NAME => 'Layer',
             NAMESPACE   => 'photoshop',
-            LayerName => { },
+            LayerName   => { },
             LayerText => { },
         },
     },
-    TextLayersLayerName => { Flat => 1, Name => 'TextLayerName' },
-    TextLayersLayerText => { Flat => 1, Name => 'TextLayerText' },
-    TransmissionReference   => { },
+    TransmissionReference => { Notes => 'Now used as a job identifier' },
     Urgency         => {
         Writable => 'integer',
@@ -931,13 +1186,17 @@
         },
     },
-);
-
-# Photoshop Camera Raw Schema properties (crs) - (ref 8,PH)
+    EmbeddedXMPDigest => { },   #PH (LR5)
+);
+
+# Photoshop Camera Raw namespace properties (crs) - (ref 8,PH)
 %Image::ExifTool::XMP::crs = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-crs', 2 => 'Image' },
     NAMESPACE   => 'crs',
-    TABLE_DESC => 'Photoshop Camera Raw Schema',
-    NOTES => 'Photoshop Camera Raw Schema tags.',
+    TABLE_DESC => 'Photoshop Camera Raw namespace',
+    NOTES => q{
+        Photoshop Camera Raw namespace tags.  It is a shame that Adobe pollutes the
+        metadata space with these incredibly bulky image editing parameters.
+    },
     AlreadyApplied  => { Writable => 'boolean' }, #PH (written by LightRoom beta 4.1)
     AutoBrightness  => { Writable => 'boolean' },
@@ -984,5 +1243,5 @@
     Sharpness       => { Writable => 'integer', Avoid => 1 },
     Smoothness      => { Writable => 'integer' },
-    Temperature     => { Writable => 'integer', Avoid => 1, Name => 'ColorTemperature' },
+    Temperature     => { Writable => 'integer', Name => 'ColorTemperature' },
     Tint            => { Writable => 'integer' },
     ToneCurve       => { List => 'Seq' },
@@ -1055,9 +1314,9 @@
     SharpenEdgeMasking          => { Writable => 'integer' },
     SharpenRadius               => { Writable => 'real' },
-    SplitToningBalance          => { Writable => 'integer' },
-    SplitToningHighlightHue     => { Writable => 'integer' },
-    SplitToningHighlightSaturation => { Writable => 'integer' },
-    SplitToningShadowHue        => { Writable => 'integer' },
-    SplitToningShadowSaturation => { Writable => 'integer' },
+    SplitToningBalance          => { Writable => 'integer', Notes => 'also used for newer ColorGrade settings' },
+    SplitToningHighlightHue     => { Writable => 'integer', Notes => 'also used for newer ColorGrade settings' },
+    SplitToningHighlightSaturation => { Writable => 'integer', Notes => 'also used for newer ColorGrade settings' },
+    SplitToningShadowHue        => { Writable => 'integer', Notes => 'also used for newer ColorGrade settings' },
+    SplitToningShadowSaturation => { Writable => 'integer', Notes => 'also used for newer ColorGrade settings' },
     Vibrance                    => { Writable => 'integer' },
     # new tags written by LR 1.4 (not sure in what version they first appeared)
@@ -1090,72 +1349,13 @@
     # because these are nested in lists and the flattened tags can't
     # do justice to this complex structure
-    GradientBasedCorrections => { Struct => \%sCorrection, List => 'Seq' },
-    GradientBasedCorrectionsWhat => {
-        Name => 'GradientBasedCorrWhat',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionAmount => {
-        Name => 'GradientBasedCorrAmount',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionActive => {
-        Name => 'GradientBasedCorrActive',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsLocalExposure => {
-        Name => 'GradientBasedCorrExposure',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsLocalSaturation => {
-        Name => 'GradientBasedCorrSaturation',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsLocalContrast => {
-        Name => 'GradientBasedCorrContrast',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsLocalClarity => {
-        Name => 'GradientBasedCorrClarity',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsLocalSharpness => {
-        Name => 'GradientBasedCorrSharpness',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsLocalBrightness => {
-        Name => 'GradientBasedCorrBrightness',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsLocalToningHue => {
-        Name => 'GradientBasedCorrHue',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsLocalToningSaturation => {
-        Name => 'GradientBasedCorrSaturation',
-        Flat => 1, List => 0,
+    GradientBasedCorrections => {
+        FlatName => 'GradientBasedCorr',
+        Struct => \%sCorrection,
+        List => 'Seq',
     },
     GradientBasedCorrectionsCorrectionMasks => {
         Name => 'GradientBasedCorrMasks',
+        FlatName => 'GradientBasedCorrMask',
         Flat => 1
-    },
-    GradientBasedCorrectionsCorrectionMasksWhat => {
-        Name => 'GradientBasedCorrMaskWhat',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionMasksMaskValue => {
-        Name => 'GradientBasedCorrMaskValue',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionMasksRadius => {
-        Name => 'GradientBasedCorrMaskRadius',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionMasksFlow => {
-        Name => 'GradientBasedCorrMaskFlow',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionMasksCenterWeight => {
-        Name => 'GradientBasedCorrMaskCenterWeight',
-        Flat => 1, List => 0,
     },
     GradientBasedCorrectionsCorrectionMasksDabs => {
@@ -1163,88 +1363,13 @@
         Flat => 1, List => 0,
     },
-    GradientBasedCorrectionsCorrectionMasksZeroX => {
-        Name => 'GradientBasedCorrMaskZeroX',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionMasksZeroY => {
-        Name => 'GradientBasedCorrMaskZeroY',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionMasksFullX => {
-        Name => 'GradientBasedCorrMaskFullX',
-        Flat => 1, List => 0,
-    },
-    GradientBasedCorrectionsCorrectionMasksFullY => {
-        Name => 'GradientBasedCorrMaskFullY',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrections => { Struct => \%sCorrection, List => 'Seq' },
-    PaintBasedCorrectionsWhat => {
-        Name => 'PaintCorrectionWhat',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsCorrectionAmount => {
-        Name => 'PaintCorrectionAmount',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsCorrectionActive => {
-        Name => 'PaintCorrectionActive',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsLocalExposure => {
-        Name => 'PaintCorrectionExposure',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsLocalSaturation => {
-        Name => 'PaintCorrectionSaturation',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsLocalContrast => {
-        Name => 'PaintCorrectionContrast',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsLocalClarity => {
-        Name => 'PaintCorrectionClarity',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsLocalSharpness => {
-        Name => 'PaintCorrectionSharpness',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsLocalBrightness => {
-        Name => 'PaintCorrectionBrightness',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsLocalToningHue => {
-        Name => 'PaintCorrectionHue',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsLocalToningSaturation => {
-        Name => 'PaintCorrectionSaturation',
-        Flat => 1, List => 0,
+    PaintBasedCorrections => {
+        FlatName => 'PaintCorrection',
+        Struct => \%sCorrection,
+        List => 'Seq',
     },
     PaintBasedCorrectionsCorrectionMasks => {
         Name => 'PaintBasedCorrectionMasks',
+        FlatName => 'PaintCorrectionMask',
         Flat => 1,
-    },
-    PaintBasedCorrectionsCorrectionMasksWhat => {
-        Name => 'PaintCorrectionMaskWhat',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsCorrectionMasksMaskValue => {
-        Name => 'PaintCorrectionMaskValue',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsCorrectionMasksRadius => {
-        Name => 'PaintCorrectionMaskRadius',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsCorrectionMasksFlow => {
-        Name => 'PaintCorrectionMaskFlow',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsCorrectionMasksCenterWeight => {
-        Name => 'PaintCorrectionMaskCenterWeight',
-        Flat => 1, List => 0,
     },
     PaintBasedCorrectionsCorrectionMasksDabs => {
@@ -1252,45 +1377,202 @@
         Flat => 1, List => 0,
     },
-    PaintBasedCorrectionsCorrectionMasksZeroX => {
-        Name => 'PaintCorrectionMaskZeroX',
+    # new tags written by LR 3 (thanks Wolfgang Guelcker)
+    ProcessVersion                      => { },
+    LensProfileEnable                   => { Writable => 'integer' },
+    LensProfileSetup                    => { },
+    LensProfileName                     => { },
+    LensProfileFilename                 => { },
+    LensProfileDigest                   => { },
+    LensProfileDistortionScale          => { Writable => 'integer' },
+    LensProfileChromaticAberrationScale => { Writable => 'integer' },
+    LensProfileVignettingScale          => { Writable => 'integer' },
+    LensManualDistortionAmount          => { Writable => 'integer' },
+    PerspectiveVertical                 => { Writable => 'integer' },
+    PerspectiveHorizontal               => { Writable => 'integer' },
+    PerspectiveRotate                   => { Writable => 'real'    },
+    PerspectiveScale                    => { Writable => 'integer' },
+    CropConstrainToWarp                 => { Writable => 'integer' },
+    LuminanceNoiseReductionDetail       => { Writable => 'integer' },
+    LuminanceNoiseReductionContrast     => { Writable => 'integer' },
+    ColorNoiseReductionDetail           => { Writable => 'integer' },
+    GrainAmount                         => { Writable => 'integer' },
+    GrainSize                           => { Writable => 'integer' },
+    GrainFrequency                      => { Writable => 'integer' },
+    # new tags written by LR4
+    AutoLateralCA                       => { Writable => 'integer' },
+    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' },
+    Clarity2012                         => { Writable => 'integer' },
+    PostCropVignetteHighlightContrast   => { Writable => 'integer' },
+    ToneCurveName2012                   => { },
+    ToneCurveRed                        => { List => 'Seq' },
+    ToneCurveGreen                      => { List => 'Seq' },
+    ToneCurveBlue                       => { List => 'Seq' },
+    ToneCurvePV2012                     => { List => 'Seq' },
+    ToneCurvePV2012Red                  => { List => 'Seq' },
+    ToneCurvePV2012Green                => { List => 'Seq' },
+    ToneCurvePV2012Blue                 => { List => 'Seq' },
+    DefringePurpleAmount                => { Writable => 'integer' },
+    DefringePurpleHueLo                 => { Writable => 'integer' },
+    DefringePurpleHueHi                 => { Writable => 'integer' },
+    DefringeGreenAmount                 => { Writable => 'integer' },
+    DefringeGreenHueLo                  => { Writable => 'integer' },
+    DefringeGreenHueHi                  => { Writable => 'integer' },
+    # new tags written by LR5
+    AutoWhiteVersion                    => { Writable => 'integer' },
+    CircularGradientBasedCorrections => {
+        FlatName => 'CircGradBasedCorr',
+        Struct => \%sCorrection,
+        List => 'Seq',
+    },
+    CircularGradientBasedCorrectionsCorrectionMasks => {
+        Name => 'CircGradBasedCorrMasks',
+        FlatName => 'CircGradBasedCorrMask',
+        Flat => 1
+    },
+    CircularGradientBasedCorrectionsCorrectionMasksDabs => {
+        Name => 'CircGradBasedCorrMaskDabs',
         Flat => 1, List => 0,
     },
-    PaintBasedCorrectionsCorrectionMasksZeroY => {
-        Name => 'PaintCorrectionMaskZeroY',
+    ColorNoiseReductionSmoothness       => { Writable => 'integer' },
+    PerspectiveAspect                   => { Writable => 'integer' },
+    PerspectiveUpright                  => { Writable => 'integer' },
+    RetouchAreas => {
+        FlatName => 'RetouchArea',
+        Struct => \%sRetouchArea,
+        List => 'Seq',
+    },
+    RetouchAreasMasks => {
+        Name => 'RetouchAreaMasks',
+        FlatName => 'RetouchAreaMask',
+        Flat => 1
+    },
+    RetouchAreasMasksDabs => {
+        Name => 'RetouchAreaMaskDabs',
         Flat => 1, List => 0,
     },
-    PaintBasedCorrectionsCorrectionMasksFullX => {
-        Name => 'PaintCorrectionMaskFullX',
-        Flat => 1, List => 0,
-    },
-    PaintBasedCorrectionsCorrectionMasksFullY => {
-        Name => 'PaintCorrectionMaskFullY',
-        Flat => 1, List => 0,
-    },
-    # new tags written by LR 3 (thanks Wolfgang Guelcker)
-    ProcessVersion                       => { },
-    LensProfileEnable                    => { Writable => 'integer' },
-    LensProfileSetup                     => { },
-    LensProfileName                      => { },
-    LensProfileFilename                  => { },
-    LensProfileDigest                    => { },
-    LensProfileDistortionScale           => { Writable => 'integer' },
-    LensProfileChromaticAberrationScale  => { Writable => 'integer' },
-    LensProfileVignettingScale           => { Writable => 'integer' },
-    LensManualDistortionAmount           => { Writable => 'integer' },
-    PerspectiveVertical                  => { Writable => 'integer' },
-    PerspectiveHorizontal                => { Writable => 'integer' },
-    PerspectiveRotate                    => { Writable => 'real'    },
-    PerspectiveScale                     => { Writable => 'integer' },
-    CropConstrainToWarp                  => { Writable => 'integer' },      
-    LuminanceNoiseReductionDetail        => { Writable => 'integer' },
-    LuminanceNoiseReductionContrast      => { Writable => 'integer' },
-    ColorNoiseReductionDetail            => { Writable => 'integer' },
-    GrainAmount                          => { Writable => 'integer' },
-    GrainSize                            => { Writable => 'integer' },
-    GrainFrequency                       => { Writable => 'integer' },
-);
-
-# Tiff schema properties (tiff)
+    UprightVersion                      => { Writable => 'integer' },
+    UprightCenterMode                   => { Writable => 'integer' },
+    UprightCenterNormX                  => { Writable => 'real' },
+    UprightCenterNormY                  => { Writable => 'real' },
+    UprightFocalMode                    => { Writable => 'integer' },
+    UprightFocalLength35mm              => { Writable => 'real' },
+    UprightPreview                      => { Writable => 'boolean' },
+    UprightTransformCount               => { Writable => 'integer' },
+    UprightDependentDigest              => { },
+    UprightTransform_0                  => { },
+    UprightTransform_1                  => { },
+    UprightTransform_2                  => { },
+    UprightTransform_3                  => { },
+    UprightTransform_4                  => { },
+    UprightTransform_5                  => { },
+    # more stuff seen in lens profile file (unknown source)
+    What => { }, # (with value "LensProfileDefaultSettings")
+    LensProfileMatchKeyExifMake         => { },
+    LensProfileMatchKeyExifModel        => { },
+    LensProfileMatchKeyCameraModelName  => { },
+    LensProfileMatchKeyLensInfo         => { },
+    LensProfileMatchKeyLensID           => { },
+    LensProfileMatchKeyLensName         => { },
+    LensProfileMatchKeyIsRaw            => { Writable => 'boolean' },
+    LensProfileMatchKeySensorFormatFactor=>{ Writable => 'real' },
+    # more stuff (ref forum6993)
+    DefaultAutoTone                     => { Writable => 'boolean' },
+    DefaultAutoGray                     => { Writable => 'boolean' },
+    DefaultsSpecificToSerial            => { Writable => 'boolean' },
+    DefaultsSpecificToISO               => { Writable => 'boolean' },
+    DNGIgnoreSidecars                   => { Writable => 'boolean' },
+    NegativeCachePath                   => { },
+    NegativeCacheMaximumSize            => { Writable => 'real' },
+    NegativeCacheLargePreviewSize       => { Writable => 'integer' },
+    JPEGHandling                        => { },
+    TIFFHandling                        => { },
+    Dehaze                              => { Writable => 'real' },
+    ToneMapStrength                     => { Writable => 'real' },
+    # yet more
+    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        => { },
+            Amount      => { },
+            Cluster     => { },
+            UUID        => { },
+            SupportsMonochrome => { },
+            SupportsAmount     => { },
+            SupportsOutputReferred => { },
+            Copyright   => { },
+            Group       => { Writable => 'lang-alt' },
+            Parameters => {
+                Struct => {
+                    STRUCT_NAME => 'LookParms',
+                    NAMESPACE   => 'crs',
+                    Version         => { },
+                    ProcessVersion  => { },
+                    Clarity2012     => { },
+                    ConvertToGrayscale => { },
+                    CameraProfile   => { },
+                    LookTable       => { },
+                    ToneCurvePV2012 => { List => 'Seq' },
+                },
+            },
+        }
+    },
+    # more again (ref forum11258)
+    GrainSeed => { },
+    ClipboardOrientation => { Writable => 'integer' },
+    ClipboardAspectRatio => { Writable => 'integer' },
+    PresetType  => { },
+    Cluster     => { },
+    UUID        => { Avoid => 1 },
+    SupportsAmount          => { Writable => 'boolean' },
+    SupportsColor           => { Writable => 'boolean' },
+    SupportsMonochrome      => { Writable => 'boolean' },
+    SupportsHighDynamicRange=> { Writable => 'boolean' },
+    SupportsNormalDynamicRange=> { Writable => 'boolean' },
+    SupportsSceneReferred   => { Writable => 'boolean' },
+    SupportsOutputReferred  => { Writable => 'boolean' },
+    CameraModelRestriction  => { },
+    Copyright   => { Avoid => 1 },
+    ContactInfo => { },
+    GrainSeed   => { Writable => 'integer' },
+    Name        => { Writable => 'lang-alt', Avoid => 1 },
+    ShortName   => { Writable => 'lang-alt' },
+    SortName    => { Writable => 'lang-alt' },
+    Group       => { Writable => 'lang-alt', Avoid => 1 },
+    Description => { Writable => 'lang-alt', Avoid => 1 },
+    # new for DNG converter 13.0
+    LookName => { NotFlat => 1 }, # (grr... conflicts with "Name" element of "Look" struct!)
+    # new for Lightroom CC 2021 (ref forum11745)
+    ColorGradeMidtoneHue    => { Writable => 'integer' },
+    ColorGradeMidtoneSat    => { Writable => 'integer' },
+    ColorGradeShadowLum     => { Writable => 'integer' },
+    ColorGradeMidtoneLum    => { Writable => 'integer' },
+    ColorGradeHighlightLum  => { Writable => 'integer' },
+    ColorGradeBlending      => { Writable => 'integer' },
+    ColorGradeGlobalHue     => { Writable => 'integer' },
+    ColorGradeGlobalSat     => { Writable => 'integer' },
+    ColorGradeGlobalLum     => { Writable => 'integer' },
+    # new for Adobe Camera Raw 13 (ref forum11745)
+    LensProfileIsEmbedded   => { Writable => 'boolean'},
+    AutoToneDigest          => { },
+    AutoToneDigestNoSat     => { },
+    ToggleStyleDigest       => { },
+    ToggleStyleAmount       => { Writable => 'integer' },
+);
+
+# Tiff namespace properties (tiff)
 %Image::ExifTool::XMP::tiff = (
     %xmpTableDefaults,
@@ -1299,5 +1581,9 @@
     PRIORITY => 0, # not as reliable as actual TIFF tags
     TABLE_DESC => 'XMP TIFF',
-    NOTES => 'EXIF schema for TIFF tags.',
+    NOTES => q{
+        EXIF namespace for TIFF tags.  See
+        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' },
@@ -1324,5 +1610,16 @@
         },
     },
-    YCbCrSubSampling => { PrintConv => \%Image::ExifTool::JPEG::yCbCrSubSampling },
+    YCbCrSubSampling => {
+        Writable => 'integer',
+        List => 'Seq',
+        # join the raw values before conversion to allow PrintConv to operate on
+        # the combined string as it does for the corresponding EXIF tag
+        RawJoin => 1,
+        Notes => q{
+            while technically this is a list-type tag, for compatibility with its EXIF
+            counterpart it is written and read as a simple string
+        },
+        PrintConv => \%Image::ExifTool::JPEG::yCbCrSubSampling,
+    },
     YCbCrPositioning => {
         Writable => 'integer',
@@ -1343,5 +1640,5 @@
         },
     },
-    TransferFunction      => { Writable => 'integer',  List => 'Seq' },
+    TransferFunction      => { Writable => 'integer',  List => 'Seq', AutoSplit => 1 },
     WhitePoint            => { Writable => 'rational', List => 'Seq', AutoSplit => 1 },
     PrimaryChromaticities => { Writable => 'rational', List => 'Seq', AutoSplit => 1 },
@@ -1354,6 +1651,13 @@
     },
     ImageDescription => { Writable => 'lang-alt' },
-    Make      => { Groups => { 2 => 'Camera' } },
-    Model     => { Groups => { 2 => 'Camera' }, Description => 'Camera Model Name' },
+    Make => {
+        Groups => { 2 => 'Camera' },
+        RawConv => '$$self{Make} ? $val : $$self{Make} = $val',
+    },
+    Model => {
+        Groups => { 2 => 'Camera' },
+        Description => 'Camera Model Name',
+        RawConv => '$$self{Model} ? $val : $$self{Model} = $val',
+    },
     Software  => { },
     Artist    => { Groups => { 2 => 'Author' } },
@@ -1362,5 +1666,5 @@
 );
 
-# Exif schema properties (exif)
+# Exif namespace properties (exif)
 %Image::ExifTool::XMP::exif = (
     %xmpTableDefaults,
@@ -1368,5 +1672,9 @@
     NAMESPACE   => 'exif',
     PRIORITY => 0, # not as reliable as actual EXIF tags
-    NOTES => 'EXIF schema for EXIF tags.',
+    NOTES => q{
+        EXIF namespace for EXIF tags.  See
+        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 => { },
@@ -1383,6 +1691,6 @@
     },
     ComponentsConfiguration => {
+        Writable => 'integer',
         List => 'Seq',
-        Writable => 'integer',
         AutoSplit => 1,
         PrintConvColumns => 2,
@@ -1416,9 +1724,9 @@
         Writable => 'rational',
         PrintConv => 'Image::ExifTool::Exif::PrintExposureTime($val)',
-        PrintConvInv => 'Image::ExifTool::Exif::ConvertFraction($val)',
+        PrintConvInv => '$val',
     },
     FNumber => {
         Writable => 'rational',
-        PrintConv => 'sprintf("%.1f",$val)',
+        PrintConv => 'Image::ExifTool::Exif::PrintFNumber($val)',
         PrintConvInv => '$val',
     },
@@ -1447,11 +1755,8 @@
     OECF => {
         Name => 'Opto-ElectricConvFactor',
+        FlatName => 'OECF',
         Groups => { 2 => 'Camera' },
         Struct => \%sOECF,
     },
-    OECFColumns => { Flat => 1 },
-    OECFRows    => { Flat => 1 },
-    OECFNames   => { Flat => 1 },
-    OECFValues  => { Flat => 1 },
     ShutterSpeedValue => {
         Writable => 'rational',
@@ -1512,5 +1817,5 @@
             STRUCT_NAME => 'Flash',
             NAMESPACE   => 'exif',
-            Fired       => { Writable => 'boolean' },
+            Fired       => { Writable => 'boolean', %boolConv },
             Return => {
                 Writable => 'integer',
@@ -1530,6 +1835,6 @@
                 },
             },
-            Function    => { Writable => 'boolean' },
-            RedEyeMode  => { Writable => 'boolean' },
+            Function    => { Writable => 'boolean', %boolConv },
+            RedEyeMode  => { Writable => 'boolean', %boolConv },
         },
     },
@@ -1713,5 +2018,4 @@
         Groups => { 2 => 'Location' },
         Writable => 'rational',
-        RawConv => 'require Image::ExifTool::GPS; $val', # to load Composite tags and routines
         # extricate unsigned decimal number from string
         ValueConvInv => '$val=~/((?=\d|\.\d)\d*(?:\.\d*)?)/ ? $1 : undef',
@@ -1766,4 +2070,5 @@
     GPSTrack => { Groups => { 2 => 'Location' }, Writable => 'rational' },
     GPSImgDirectionRef => {
+        Groups => { 2 => 'Location' },
         PrintConv => {
             M => 'Magnetic North',
@@ -1805,28 +2110,60 @@
         },
     },
+    GPSHPositioningError => { #12
+        Description => 'GPS Horizontal Positioning Error',
+        Groups => { 2 => 'Location' },
+        Writable => 'rational',
+        PrintConv => '"$val m"',
+        PrintConvInv => '$val=~s/\s*m$//; $val',
+    },
     NativeDigest => { }, #PH
-);
-
-# Auxiliary schema properties (aux) - not fully documented (ref PH)
-%Image::ExifTool::XMP::aux = (
+    # new Exif
+);
+
+# Exif extended properties (exifEX, ref 12)
+%Image::ExifTool::XMP::exifEX = (
     %xmpTableDefaults,
-    GROUPS => { 1 => 'XMP-aux', 2 => 'Camera' },
-    NAMESPACE   => 'aux',
-    NOTES => 'Photoshop Auxiliary schema tags.',
-    Firmware        => { }, #7
-    FlashCompensation => { Writable => 'rational' }, #7
-    ImageNumber     => { }, #7
-    LensInfo        => { #7
-        Notes => '4 rational values giving focal and aperture ranges',
-        # convert to floating point values (or 'inf' or 'undef')
-        ValueConv => sub {
-            my $val = shift;
-            my @vals = split ' ', $val;
-            return $val unless @vals == 4;
-            foreach (@vals) {
-                ConvertRational($_) or return $val;
-            }
-            return join ' ', @vals;
-        },
+    GROUPS => { 1 => 'XMP-exifEX', 2 => 'Image' },
+    NAMESPACE   => 'exifEX',
+    PRIORITY => 0, # not as reliable as actual EXIF tags
+    NOTES => q{
+        EXIF tags added by the EXIF 2.31 for XMP specification (see
+        L<http://www.cipa.jp/std/documents/e/DC-X010-2017.pdf>).
+    },
+    Gamma                       => { Writable => 'rational' },
+    PhotographicSensitivity     => { Writable => 'integer' },
+    SensitivityType => {
+        Writable => 'integer',
+        PrintConv => {
+            0 => 'Unknown',
+            1 => 'Standard Output Sensitivity',
+            2 => 'Recommended Exposure Index',
+            3 => 'ISO Speed',
+            4 => 'Standard Output Sensitivity and Recommended Exposure Index',
+            5 => 'Standard Output Sensitivity and ISO Speed',
+            6 => 'Recommended Exposure Index and ISO Speed',
+            7 => 'Standard Output Sensitivity, Recommended Exposure Index and ISO Speed',
+        },
+    },
+    StandardOutputSensitivity   => { Writable => 'integer' },
+    RecommendedExposureIndex    => { Writable => 'integer' },
+    ISOSpeed                    => { Writable => 'integer' },
+    ISOSpeedLatitudeyyy => {
+        Description => 'ISO Speed Latitude yyy',
+        Writable => 'integer',
+    },
+    ISOSpeedLatitudezzz => {
+        Description => 'ISO Speed Latitude zzz',
+        Writable => 'integer',
+    },
+    CameraOwnerName     => { Name => 'OwnerName' },
+    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,
         ValueConvInv => sub {
             my $val = shift;
@@ -1840,5 +2177,95 @@
                 $_ = join '/', @a;
             }
-            return join ' ', @vals;
+            return \@vals; # return list reference (List-type tag)
+        },
+        PrintConv => \&Image::ExifTool::Exif::PrintLensInfo,
+        PrintConvInv => \&Image::ExifTool::Exif::ConvertLensInfo,
+        Notes => q{
+            unfortunately the EXIF 2.3 for XMP specification defined this new tag
+            instead of using the existing XMP-aux:LensInfo
+        },
+    },
+    LensMake            => { Groups => { 2 => 'Camera' } },
+    LensModel           => { Groups => { 2 => 'Camera' } },
+    LensSerialNumber    => { Groups => { 2 => 'Camera' } },
+    InteroperabilityIndex => {
+        Name => 'InteropIndex',
+        Description => 'Interoperability Index',
+        PrintConv => {
+            R98 => 'R98 - DCF basic file (sRGB)',
+            R03 => 'R03 - DCF option file (Adobe RGB)',
+            THM => 'THM - DCF thumbnail file',
+        },
+    },
+    # new in Exif 2.31
+    Temperature         => { Writable => 'rational', Name => 'AmbientTemperature' },
+    Humidity            => { Writable => 'rational' },
+    Pressure            => { Writable => 'rational' },
+    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)
+%Image::ExifTool::XMP::aux = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-aux', 2 => 'Camera' },
+    NAMESPACE   => 'aux',
+    NOTES => q{
+        Adobe-defined auxiliary EXIF tags.  This namespace existed in the XMP
+        specification until it was dropped in 2012, presumably due to the
+        introduction of the EXIF 2.3 for XMP specification and the exifEX namespace
+        at this time.  For this reason, tags below with equivalents in the
+        L<exifEX namespace|/XMP exifEX Tags> are avoided when writing.
+    },
+    Firmware        => { }, #7
+    FlashCompensation => { Writable => 'rational' }, #7
+    ImageNumber     => { }, #7
+    LensInfo        => { #7
+        Notes => '4 rational values giving focal and aperture ranges',
+        Avoid => 1,
+        # convert to floating point values (or 'inf' or 'undef')
+        ValueConv => \&ConvertRationalList,
+        ValueConvInv => sub {
+            my $val = shift;
+            my @vals = split ' ', $val;
+            return $val unless @vals == 4;
+            foreach (@vals) {
+                $_ eq 'inf' and $_ = '1/0', next;
+                $_ eq 'undef' and $_ = '0/0', next;
+                Image::ExifTool::IsFloat($_) or return $val;
+                my @a = Image::ExifTool::Rationalize($_);
+                $_ = join '/', @a;
+            }
+            return join ' ', @vals; # return string (string tag)
         },
         # convert to the form "12-20mm f/3.8-4.5" or "50mm f/1.4"
@@ -1847,6 +2274,7 @@
     },
     Lens            => { },
-    OwnerName       => { }, #7
-    SerialNumber    => { },
+    OwnerName       => { Avoid => 1 }, #7
+    SerialNumber    => { Avoid => 1 },
+    LensSerialNumber=> { Avoid => 1 },
     LensID          => {
         Priority => 0,
@@ -1858,7 +2286,14 @@
     },
     ApproximateFocusDistance => { Writable => 'rational' }, #PH (LR3)
-);
-
-# IPTC Core schema properties (Iptc4xmpCore) (ref 4)
+    # the following new in LR6 (ref forum6497)
+    IsMergedPanorama         => { Writable => 'boolean' },
+    IsMergedHDR              => { Writable => 'boolean' },
+    DistortionCorrectionAlreadyApplied  => { Writable => 'boolean' },
+    VignetteCorrectionAlreadyApplied    => { Writable => 'boolean' },
+    LateralChromaticAberrationCorrectionAlreadyApplied => { Writable => 'boolean' },
+    LensDistortInfo => { }, # (LR 7.5.1, 4 signed rational values)
+);
+
+# IPTC Core namespace properties (Iptc4xmpCore) (ref 4)
 %Image::ExifTool::XMP::iptcCore = (
     %xmpTableDefaults,
@@ -1867,7 +2302,7 @@
     TABLE_DESC => 'XMP IPTC Core',
     NOTES => q{
-        IPTC Core schema tags.  The actual IPTC Core namespace prefix is
+        IPTC Core namespace tags.  The actual IPTC Core namespace prefix is
         "Iptc4xmpCore", which is the prefix recorded in the file, but ExifTool
-        shortens this for the "XMP-iptcCore" family 1 group name. (see
+        shortens this for the family 1 group name. (see
         L<http://www.iptc.org/IPTC4XMP/>)
     },
@@ -1899,79 +2334,8 @@
     Scene               => { Groups => { 2 => 'Other' }, List => 'Bag' },
     SubjectCode         => { Groups => { 2 => 'Other' }, List => 'Bag' },
-);
-
-# IPTC Extension schema properties (Iptc4xmpExt) (ref 4)
-%Image::ExifTool::XMP::iptcExt = (
-    %xmpTableDefaults,
-    GROUPS => { 1 => 'XMP-iptcExt', 2 => 'Author' },
-    NAMESPACE   => 'Iptc4xmpExt',
-    TABLE_DESC => 'XMP IPTC Extension',
-    NOTES => q{
-        IPTC Extension schema tags.  The actual namespace prefix is "Iptc4xmpExt",
-        but ExifTool shortens this for the "XMP-iptcExt" family 1 group name.
-        (see L<http://www.iptc.org/IPTC4XMP/>)
-    },
-    AddlModelInfo   => { Name => 'AdditionalModelInformation' },
-    ArtworkOrObject => {
-        Struct => {
-            STRUCT_NAME => 'ArtworkOrObjectDetails',
-            NAMESPACE   => 'Iptc4xmpExt',
-            AOCopyrightNotice => { },
-            AOCreator    => { List => 'Seq' },
-            AODateCreated=> { Groups => { 2 => 'Time' }, %dateTimeInfo },
-            AOSource     => { },
-            AOSourceInvNo=> { },
-            AOTitle      => { Writable => 'lang-alt' },
-        },
-        List => 'Bag',
-    },
-    ArtworkOrObjectAOCopyrightNotice=> { Flat => 1, Name => 'ArtworkCopyrightNotice' },
-    ArtworkOrObjectAOCreator        => { Flat => 1, Name => 'ArtworkCreator' },
-    ArtworkOrObjectAODateCreated    => { Flat => 1, Name => 'ArtworkDateCreated' },
-    ArtworkOrObjectAOSource         => { Flat => 1, Name => 'ArtworkSource' },
-    ArtworkOrObjectAOSourceInvNo    => { Flat => 1, Name => 'ArtworkSourceInventoryNo' },
-    ArtworkOrObjectAOTitle          => { Flat => 1, Name => 'ArtworkTitle' },
-    OrganisationInImageCode => { List => 'Bag' },
-    CVterm => {
-        Name => 'ControlledVocabularyTerm',
-        List => 'Bag',
-    },
-    LocationShown => {
-        Struct => \%sLocationDetails,
-        Groups => { 2 => 'Location' },
-        List => 'Bag',
-    },
-    ModelAge                => { List => 'Bag', Writable => 'integer' },
-    OrganisationInImageName => { List => 'Bag' },
-    PersonInImage           => { List => 'Bag' },
-    DigImageGUID            => { Name => 'DigitalImageGUID' },
-    DigitalSourcefileType   => {
-        Name => 'DigitalSourceFileType',
-        Notes => 'now deprecated -- replaced by DigitalSourceType',
-    },
-    DigitalSourceType       => { Name => 'DigitalSourceType' },
-    Event                   => { Writable => 'lang-alt' },
-    RegistryId => {
-        Struct => {
-            STRUCT_NAME => 'RegistryEntryDetails',
-            NAMESPACE   => 'Iptc4xmpExt',
-            RegItemId    => { },
-            RegOrgId     => { },
-        },
-        List => 'Bag',
-    },
-    RegistryIdRegItemId         => { Flat => 1, Name => 'RegistryItemID' },
-    RegistryIdRegOrgId          => { Flat => 1, Name => 'RegistryOrganisationID' },
-    IptcLastEdited          => { Groups => { 2 => 'Time' }, %dateTimeInfo },
-    LocationCreated => {
-        Struct => \%sLocationDetails,
-        Groups => { 2 => 'Location' },
-        List => 'Bag',
-    },
-    MaxAvailHeight  => { Writable => 'integer' },
-    MaxAvailWidth   => { Writable => 'integer' },
-);
-
-# Adobe Lightroom schema properties (lr) (ref PH)
+    # Copyright - have seen this in a sample (Jan 2021), but I think it is non-standard
+);
+
+# Adobe Lightroom namespace properties (lr) (ref PH)
 %Image::ExifTool::XMP::Lightroom = (
     %xmpTableDefaults,
@@ -1979,10 +2343,10 @@
     NAMESPACE   => 'lr',
     TABLE_DESC => 'XMP Adobe Lightroom',
-    NOTES => 'Adobe Lightroom "lr" schema tags.',
+    NOTES => 'Adobe Lightroom "lr" namespace tags.',
     privateRTKInfo => { },
     hierarchicalSubject => { List => 'Bag' },
 );
 
-# Adobe Album schema properties (album) (ref PH)
+# Adobe Album namespace properties (album) (ref PH)
 %Image::ExifTool::XMP::Album = (
     %xmpTableDefaults,
@@ -1990,5 +2354,5 @@
     NAMESPACE   => 'album',
     TABLE_DESC => 'XMP Adobe Album',
-    NOTES => 'Adobe Album schema tags.',
+    NOTES => 'Adobe Album namespace tags.',
     Notes => { },
 );
@@ -2002,28 +2366,99 @@
 # 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])/;
+            $val[0] =~ /^.*([NS])/;
             return $1;
         },
-        PrintConv => {
-            N => 'North',
-            S => 'South',
-        },
+        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])/;
+            $val[0] =~ /^.*([EW])/;
             return $1;
         },
-        PrintConv => {
-            E => 'East',
-            W => 'West',
+        PrintConv => { E => 'East', W => 'West' },
+    },
+    GPSDestLatitudeRef => {
+        Require => 'XMP-exif:GPSDestLatitude',
+        Groups => { 2 => 'Location' },
+        ValueConv => q{
+            IsFloat($val[0]) and return $val[0] < 0 ? "S" : "N";
+            $val[0] =~ /^.*([NS])/;
+            return $1;
+        },
+        PrintConv => { N => 'North', S => 'South' },
+    },
+    GPSDestLongitudeRef => {
+        Require => 'XMP-exif:GPSDestLongitude',
+        Groups => { 2 => 'Location' },
+        ValueConv => q{
+            IsFloat($val[0]) and return $val[0] < 0 ? "W" : "E";
+            $val[0] =~ /^.*([EW])/;
+            return $1;
+        },
+        PrintConv => { E => 'East', W => 'West' },
+    },
+    LensID => {
+        Notes => 'attempt to convert numerical XMP-aux:LensID stored by Adobe applications',
+        Require => {
+            0 => 'XMP-aux:LensID',
+            1 => 'Make',
+        },
+        Desire => {
+            2 => 'LensInfo',
+            3 => 'FocalLength',
+            4 => 'LensModel',
+            5 => 'MaxApertureValue',
+        },
+        Inhibit => {
+            6 => 'Composite:LensID',    # don't override existing Composite:LensID
+        },
+        Groups => { 2 => 'Camera' },
+        ValueConv => '$val',
+        PrintConv => 'Image::ExifTool::XMP::PrintLensID($self, @val)',
+    },
+    Flash => {
+        Notes => 'facilitates copying camera flash information between XMP and EXIF',
+        Desire => {
+            0 => 'XMP:FlashFired',
+            1 => 'XMP:FlashReturn',
+            2 => 'XMP:FlashMode',
+            3 => 'XMP:FlashFunction',
+            4 => 'XMP:FlashRedEyeMode',
+            5 => 'XMP:Flash', # handle structured flash information too
+        },
+        Groups => { 2 => 'Camera' },
+        Writable => 1,
+        PrintHex => 1,
+        SeparateTable => 'EXIF Flash',
+        ValueConv => q{
+            if (ref $val[5] eq 'HASH') {
+                # copy structure fields into value array
+                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) |
+                   (($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));
+        },
+        PrintConv => \%Image::ExifTool::Exif::flash,
+        WriteAlso => {
+            'XMP:FlashFired'      => '$val & 0x01 ? "True" : "False"',
+            'XMP:FlashReturn'     => '($val & 0x06) >> 1',
+            'XMP:FlashMode'       => '($val & 0x18) >> 3',
+            'XMP:FlashFunction'   => '$val & 0x20 ? "True" : "False"',
+            'XMP:FlashRedEyeMode' => '$val & 0x40 ? "True" : "False"',
         },
     },
@@ -2057,11 +2492,12 @@
 # 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;
 }
@@ -2099,10 +2535,11 @@
 #------------------------------------------------------------------------------
 # Convert XML character reference to UTF-8
-# Inputs: 0) XML character reference stripped of the '&' and ';' (ie. 'quot', '#34', '#x22')
+# 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) {
@@ -2116,17 +2553,19 @@
     }
     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
-sub IsUTF8($)
+# (see http://www.fileformat.info/info/unicode/utf8.htm for help understanding this)
+sub IsUTF8($;$)
 {
-    my $strPt = shift;
+    my ($strPt, $trunc) = @_;
     pos($$strPt) = 0; # start at beginning of string
     return 0 unless $$strPt =~ /([\x80-\xff])/g;
@@ -2150,5 +2589,19 @@
             $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
+                         ($ch == 0xed and (ord($1) & 0xe0) == 0xa0) or
+                         ($ch == 0xef and ord($1) == 0xbf and
+                            (ord(substr $1, 1) & 0xfe) == 0xbe);
+        } else {
+            return -1 if ($ch == 0xf0 and (ord($1) & 0xf0) == 0x80) or
+                         ($ch == 0xf4 and ord($1) > 0x8f) or $ch > 0xf4;
+        }
         last unless $$strPt =~ /([\x80-\xff])/g;
     }
@@ -2157,10 +2610,11 @@
 
 #------------------------------------------------------------------------------
-# Fix malformed UTF8 (by replacing bad bytes with '?')
-# Inputs: 0) string reference
+# Fix malformed UTF8 (by replacing bad bytes with specified character)
+# Inputs: 0) string reference, 1) string to replace each bad byte,
+#         may be '' to delete bad bytes, or undef to use '?'
 # Returns: true if string was fixed, and updates string
-sub FixUTF8($)
+sub FixUTF8($;$)
 {
-    my $strPt = shift;
+    my ($strPt, $bad) = @_;
     my $fixed;
     pos($$strPt) = 0; # start at beginning of string
@@ -2172,9 +2626,22 @@
         if ($ch >= 0xc2 and $ch < 0xf8) {
             my $n = $ch < 0xe0 ? 1 : ($ch < 0xf0 ? 2 : 3);
-            next if $$strPt =~ /\G[\x80-\xbf]{$n}/g;
-        }
-        # replace bad character with '?'
-        substr($$strPt, $pos-1, 1) = '?';
-        pos($$strPt) = $fixed = $pos;
+            if ($$strPt =~ /\G([\x80-\xbf]{$n})/g) {
+                next if $n == 1;
+                if ($n == 2) {
+                    next unless ($ch == 0xe0 and (ord($1) & 0xe0) == 0x80) or
+                                ($ch == 0xed and (ord($1) & 0xe0) == 0xa0) or
+                                ($ch == 0xef and ord($1) == 0xbf and
+                                    (ord(substr $1, 1) & 0xfe) == 0xbe);
+                } else {
+                    next unless ($ch == 0xf0 and (ord($1) & 0xf0) == 0x80) or
+                                ($ch == 0xf4 and ord($1) > 0x8f) or $ch > 0xf4;
+                }
+            }
+        }
+        # replace bad character
+        $bad = '?' unless defined $bad;
+        substr($$strPt, $pos-1, 1) = $bad;
+        pos($$strPt) = $pos-1 + length $bad;
+        $fixed = 1;
     }
     return $fixed;
@@ -2218,5 +2685,5 @@
 
 #------------------------------------------------------------------------------
-# Generate a name for this XMP tag
+# Generate a tag ID for this XMP tag
 # Inputs: 0) tag property name list ref, 1) array ref for receiving structure property list
 #         2) array for receiving namespace list
@@ -2230,6 +2697,7 @@
         # (Note: namespace can be '' for property qualifiers)
         my ($ns, $nm) = ($prop =~ /(.*?):(.*)/) ? ($1, $2) : ('', $prop);
-        if ($ignoreNamespace{$ns}) {
+        if ($ignoreNamespace{$ns} or $ignoreProp{$prop}) {
             # special case: don't ignore rdf numbered items
+            # (not technically allowed in XMP, but used in RDF/XML)
             unless ($prop =~ /^rdf:(_\d+)$/) {
                 # save list index if necessary for structures
@@ -2244,11 +2712,11 @@
             # all uppercase is ugly, so convert it
             if ($nm !~ /[a-z]/) {
-                my $xlatNS = $$xlatNamespace{$ns} || $ns;
-                my $info = $Image::ExifTool::XMP::Main{$xlatNS};
+                my $xlat = $stdXlatNS{$ns} || $ns;
+                my $info = $Image::ExifTool::XMP::Main{$xlat};
                 my $table;
-                if (ref $info eq 'HASH' and $info->{SubDirectory}) {
-                    $table = GetTagTable($info->{SubDirectory}{TagTable});
+                if (ref $info eq 'HASH' and $$info{SubDirectory}) {
+                    $table = GetTagTable($$info{SubDirectory}{TagTable});
                 }
-                unless ($table and $table->{$nm}) {
+                unless ($table and $$table{$nm}) {
                     $nm = lc($nm);
                     $nm =~ s/_([a-z])/\u$1/g;
@@ -2278,5 +2746,5 @@
 #------------------------------------------------------------------------------
 # Register namespace for specified user-defined table
-# Inputs: 0) tag or structure table ref
+# Inputs: 0) tag/structure table ref
 # Returns: namespace prefix
 sub RegisterNamespace($)
@@ -2290,4 +2758,5 @@
         $ns = $$nsRef[0];
         $nsURI{$ns} = $$nsRef[1];
+        $uri2ns{$$nsRef[1]} = $ns;
     } else { # must be a hash
         my @ns = sort keys %$nsRef; # allow multiple namespace definitions
@@ -2295,7 +2764,8 @@
             $ns = pop @ns;
             if ($nsURI{$ns} and $nsURI{$ns} ne $$nsRef{$ns}) {
-                warn "User-defined namespace prefix '$ns' conflicts with existing namespace\n";
+                warn "User-defined namespace prefix '${ns}' conflicts with existing namespace\n";
             }
             $nsURI{$ns} = $$nsRef{$ns};
+            $uri2ns{$$nsRef{$ns}} = $ns;
         }
     }
@@ -2305,90 +2775,115 @@
 #------------------------------------------------------------------------------
 # Generate flattened tags and add to table
-# Inputs: 0) tag table ref, 1) tag ID for Struct tag in table
+# Inputs: 0) tag table ref, 1) tag ID for Struct tag (if not defined, whole table is done),
+#         2) flag to not expand sub-structures
 # Returns: number of tags added (not counting those just initialized)
 # Notes: Must have verified that $$tagTablePtr{$tagID}{Struct} exists before calling this routine
 # - makes sure that the tagInfo Struct is a HASH reference
-sub AddFlattenedTags($$)
+sub AddFlattenedTags($;$$)
 {
     local $_;
-    my ($tagTablePtr, $tagID) = @_;
-    my $tagInfo = $$tagTablePtr{$tagID};
-
-    $$tagInfo{Flattened} and return 0;  # only generate flattened tags once
-    $$tagInfo{Flattened} = 1;
-
-    my $strTable = $$tagInfo{Struct};
-    unless (ref $strTable) { # (allow a structure name for backward compatibility only)
-        my $strName = $strTable;
-        $strTable = $Image::ExifTool::UserDefined::xmpStruct{$strTable} or return 0;
-        $$strTable{STRUCT_NAME} or $$strTable{STRUCT_NAME} = $strName;
-        $$tagInfo{Struct} = $strTable;  # replace old-style name with HASH ref
-        delete $$tagInfo{SubDirectory}; # deprecated use of SubDirectory in Struct tags
+    my ($tagTablePtr, $tagID, $noSubStruct) = @_;
+    my $count = 0;
+    my @tagIDs;
+
+    if (defined $tagID) {
+        push @tagIDs, $tagID;
+    } else {
+        foreach $tagID (TagTableKeys($tagTablePtr)) {
+            my $tagInfo = $$tagTablePtr{$tagID};
+            next unless ref $tagInfo eq 'HASH' and $$tagInfo{Struct};
+            push @tagIDs, $tagID;
+        }
     }
-    # do not add flattened tags to variable-namespace structures
-    return 0 if exists $$strTable{NAMESPACE} and not defined $$strTable{NAMESPACE};
-
-    # get family 2 group name for this structure tag
-    my ($tagG2, $field);
-    $tagG2 = $$tagInfo{Groups}{2} if $$tagInfo{Groups};
-    $tagG2 or $tagG2 = $$tagTablePtr{GROUPS}{2};
-
-    my $count = 0;
-    foreach $field (keys %$strTable) {
-        next if $specialStruct{$field};
-        my $fieldInfo = $$strTable{$field};
-        next if $$fieldInfo{LangCode};  # don't flatten lang-alt tags
-        # build a tag ID for the corresponding flattened tag
-        my $fieldName = ucfirst($field);
-        my $flatID = $tagID . $fieldName;
-        my $flatInfo = $$tagTablePtr{$flatID};
-        if ($flatInfo) {
-            ref $flatInfo eq 'HASH' or warn("$flatInfo is not a HASH!\n"), next; # (to be safe)
-            # pre-defined flattened tags should have Flat flag set
-            if (not defined $$flatInfo{Flat} and $Image::ExifTool::debug) {
-                warn "Missing Flat flag for $$flatInfo{Name}\n";
-            }
-            $$flatInfo{Flat} = 0;
-            # copy all missing entries from field information
-            foreach (keys %$fieldInfo) {
-                # must not copy PropertyPath (but can't delete it afterwards
-                # because the flat tag may already have this set)
-                next if $_ eq 'PropertyPath';
-                $$flatInfo{$_} = $$fieldInfo{$_} unless defined $$flatInfo{$_};
-            }
-            # NOTE: Do NOT delete Groups because we need them if GotGroups was done
-            # --> just override group 2 later according to field group
-            # re-generate List flag unless it is set to 0
-            delete $$flatInfo{List} if $$flatInfo{List};
-        } else {
-            # generate new flattened tag information based on structure field
-            $flatInfo = { %$fieldInfo, Name => $$tagInfo{Name} . $fieldName, Flat => 0 };
-            # add new flattened tag to table
-            Image::ExifTool::AddTagToTable($tagTablePtr, $flatID, $flatInfo);
-            ++$count;
-        }
-        # propagate List flag (unless set to 0 in pre-defined flattened tag)
-        unless (defined $$flatInfo{List}) {
-            $$flatInfo{List} = $$fieldInfo{List} || 1 if $$fieldInfo{List} or $$tagInfo{List};
-        }
-        # set group 2 name from the first existing family 2 group in the:
-        # 1) structure field Groups, 2) structure table GROUPS, 3) structure tag Groups
-        if ($$fieldInfo{Groups} and $$fieldInfo{Groups}{2}) {
-            $$flatInfo{Groups}{2} = $$fieldInfo{Groups}{2};
-        } elsif ($$strTable{GROUPS} and $$strTable{GROUPS}{2}) {
-            $$flatInfo{Groups}{2} = $$strTable{GROUPS}{2};
-        } else {
-            $$flatInfo{Groups}{2} = $tagG2;
-        }
-        # save reference to top-level structure
-        $$flatInfo{RootTagInfo} = $$tagInfo{RootTagInfo} || $tagInfo;
-        # recursively generate flattened tags for sub-structures
-        next unless $$flatInfo{Struct};
-        length($flatID) > 150 and warn("Possible deep recursion for tag $flatID\n"), last;
-        # reset flattened tag just in case we flattened hierarchy in the wrong order
-        # because we must start from the outtermost structure to get the List flags right
-        # (this should only happen when building tag tables)
-        delete $$flatInfo{Flattened};
-        $count += AddFlattenedTags($tagTablePtr, $flatID);
+
+    # loop through specified tags
+    foreach $tagID (@tagIDs) {
+
+        my $tagInfo = $$tagTablePtr{$tagID};
+
+        $$tagInfo{Flattened} and next;  # only generate flattened tags once
+        $$tagInfo{Flattened} = 1;
+
+        my $strTable = $$tagInfo{Struct};
+        unless (ref $strTable) { # (allow a structure name for backward compatibility only)
+            my $strName = $strTable;
+            $strTable = $Image::ExifTool::UserDefined::xmpStruct{$strTable} or next;
+            $$strTable{STRUCT_NAME} or $$strTable{STRUCT_NAME} = "XMP $strName";
+            $$tagInfo{Struct} = $strTable;  # replace old-style name with HASH ref
+            delete $$tagInfo{SubDirectory}; # deprecated use of SubDirectory in Struct tags
+        }
+
+        # get prefix for flattened tag names
+        my $flat = (defined $$tagInfo{FlatName} ? $$tagInfo{FlatName} : $$tagInfo{Name});
+
+        # get family 2 group name for this structure tag
+        my ($tagG2, $field);
+        $tagG2 = $$tagInfo{Groups}{2} if $$tagInfo{Groups};
+        $tagG2 or $tagG2 = $$tagTablePtr{GROUPS}{2};
+
+        foreach $field (keys %$strTable) {
+            next if $specialStruct{$field};
+            my $fieldInfo = $$strTable{$field};
+            next if $$fieldInfo{LangCode};  # don't flatten lang-alt tags
+            next if $$fieldInfo{Struct} and $noSubStruct;   # don't expand sub-structures if specified
+            # build a tag ID for the corresponding flattened tag
+            my $fieldName = ucfirst($field);
+            my $flatField = $$fieldInfo{FlatName} || $fieldName;
+            my $flatID = $tagID . $fieldName;
+            my $flatInfo = $$tagTablePtr{$flatID};
+            if ($flatInfo) {
+                ref $flatInfo eq 'HASH' or warn("$flatInfo is not a HASH!\n"), next; # (to be safe)
+                # pre-defined flattened tags should have Flat flag set
+                if (not defined $$flatInfo{Flat}) {
+                    next if $$flatInfo{NotFlat};
+                    warn "Missing Flat flag for $$flatInfo{Name}\n" if $Image::ExifTool::debug;
+                }
+                $$flatInfo{Flat} = 0;
+                # copy all missing entries from field information
+                foreach (keys %$fieldInfo) {
+                    # must not copy PropertyPath (but can't delete it afterwards
+                    # because the flat tag may already have this set)
+                    next if $_ eq 'PropertyPath' or defined $$flatInfo{$_};
+                    # copy the property (making a copy of the Groups hash)
+                    $$flatInfo{$_} = $_ eq 'Groups' ? { %{$$fieldInfo{$_}} } : $$fieldInfo{$_};
+                }
+                # (NOTE: Can NOT delete Groups because we need them if GotGroups was done)
+                # re-generate List flag unless it is set to 0
+                delete $$flatInfo{List} if $$flatInfo{List};
+            } else {
+                # 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
+                AddTagToTable($tagTablePtr, $flatID, $flatInfo);
+                ++$count;
+            }
+            # propagate List flag (unless set to 0 in pre-defined flattened tag)
+            unless (defined $$flatInfo{List}) {
+                $$flatInfo{List} = $$fieldInfo{List} || 1 if $$fieldInfo{List} or $$tagInfo{List};
+            }
+            # set group 2 name from the first existing family 2 group in the:
+            # 1) structure field Groups, 2) structure table GROUPS, 3) structure tag Groups
+            if ($$fieldInfo{Groups} and $$fieldInfo{Groups}{2}) {
+                $$flatInfo{Groups}{2} = $$fieldInfo{Groups}{2};
+            } elsif ($$strTable{GROUPS} and $$strTable{GROUPS}{2}) {
+                $$flatInfo{Groups}{2} = $$strTable{GROUPS}{2};
+            } else {
+                $$flatInfo{Groups}{2} = $tagG2;
+            }
+            # save reference to top-level structure
+            $$flatInfo{RootTagInfo} = $$tagInfo{RootTagInfo} || $tagInfo;
+            # recursively generate flattened tags for sub-structures
+            next unless $$flatInfo{Struct};
+            length($flatID) > 250 and warn("Possible deep recursion for tag $flatID\n"), last;
+            # reset flattened tag just in case we flattened hierarchy in the wrong order
+            # because we must start from the outtermost structure to get the List flags right
+            # (this should only happen when building tag tables)
+            delete $$flatInfo{Flattened};
+            $count += AddFlattenedTags($tagTablePtr, $flatID, $$flatInfo{NoSubStruct});
+        }
     }
     return $count;
@@ -2397,5 +2892,5 @@
 #------------------------------------------------------------------------------
 # Get localized version of tagInfo hash
-# Inputs: 0) tagInfo hash ref, 1) language code (ie. "x-default")
+# Inputs: 0) tagInfo hash ref, 1) language code (eg. "x-default")
 # Returns: new tagInfo hash ref, or undef if invalid
 sub GetLangInfo($$)
@@ -2406,6 +2901,4 @@
     $langCode =~ tr/_/-/;   # RFC 3066 specifies '-' as a separator
     my $langInfo = Image::ExifTool::GetLangInfo($tagInfo, $langCode);
-    # save reference to source tagInfo hash in case we need to set the PropertyPath later
-    $$langInfo{SrcTagInfo} = $tagInfo;
     return $langInfo;
 }
@@ -2430,9 +2923,9 @@
 sub ScanForXMP($$)
 {
-    my ($exifTool, $raf) = @_;
+    my ($et, $raf) = @_;
     my ($buff, $xmp);
     my $lastBuff = '';
 
-    $exifTool->VPrint(0,"Scanning for XMP\n");
+    $et->VPrint(0,"Scanning for XMP\n");
     for (;;) {
         defined $buff or $raf->Read($buff, 65536) or return 0;
@@ -2462,15 +2955,95 @@
         }
     }
-    unless ($exifTool->{VALUE}{FileType}) {
-        $exifTool->{FILE_TYPE} = $exifTool->{FILE_EXT};
-        $exifTool->SetFileType('<unknown file containing XMP>');
+    unless ($$et{VALUE}{FileType}) {
+        $$et{FILE_TYPE} = $$et{FILE_EXT};
+        $et->SetFileType('<unknown file containing XMP>', undef, '');
     }
     my %dirInfo = (
-        DataPt => \$xmp,
-        DirLen => length $xmp,
+        DataPt  => \$xmp,
+        DirLen  => length $xmp,
         DataLen => length $xmp,
     );
-    ProcessXMP($exifTool, \%dirInfo);
+    ProcessXMP($et, \%dirInfo);
     return 1;
+}
+
+#------------------------------------------------------------------------------
+# Print conversion for XMP-aux:LensID
+# Inputs: 0) ExifTool ref, 1) LensID, 2) Make, 3) LensInfo, 4) FocalLength,
+#         5) LensModel, 6) MaxApertureValue
+# (yes, this is ugly -- blame Adobe)
+sub PrintLensID(@)
+{
+    local $_;
+    my ($et, $id, $make, $info, $focalLength, $lensModel, $maxAv) = @_;
+    my ($mk, $printConv);
+    my %alt = ( Pentax => 'Ricoh' );    # Pentax changed its name to Ricoh
+    # missing: Olympus (no XMP:LensID written by Adobe)
+    foreach $mk (qw(Canon Nikon Pentax Sony Sigma Samsung Leica)) {
+        next unless $make =~ /$mk/i or ($alt{$mk} and $make =~ /$alt{$mk}/i);
+        # get name of module containing the lens lookup (default "Make.pm")
+        my $mod = { Sigma => 'SigmaRaw', Leica => 'Panasonic' }->{$mk} || $mk;
+        require "Image/ExifTool/$mod.pm";
+        # get the name of the lens name lookup (default "makeLensTypes")
+        # (canonLensTypes, pentaxLensTypes, nikonLensIDs, etc)
+        my $convName = "Image::ExifTool::${mod}::" .
+            ({ Nikon => 'nikonLensIDs' }->{$mk} || lc($mk) . 'LensTypes');
+        no strict 'refs';
+        %$convName or last;
+        my $printConv = \%$convName;
+        use strict 'refs';
+        # sf = short focal
+        # lf = long focal
+        # sa = max aperture at short focal
+        # la = max aperture at long focal
+        my ($sf, $lf, $sa, $la);
+        if ($info) {
+            my @a = split ' ', $info;
+            $_ eq 'undef' and $_ = undef foreach @a;
+            ($sf, $lf, $sa, $la) = @a;
+            # for Sony and ambiguous LensID, $info data may be incorrect:
+            # use only if it agrees with $focalLength and $maxAv (ref JR)
+            if ($mk eq 'Sony' and
+                (($focalLength and (($sf and $focalLength < $sf - 0.5) or
+                                    ($lf and $focalLength > $lf + 0.5))) or
+                 ($maxAv and (($sa and $maxAv < $sa - 0.15) or
+                              ($la and $maxAv > $la + 0.15)))))
+            {
+                undef $sf;
+                undef $lf;
+                undef $sa;
+                undef $la;
+            } elsif ($maxAv) {
+                # (using the short-focal-length max aperture in place of MaxAperture
+                # is a bad approximation, so don't do this if MaxApertureValue exists)
+                undef $sa;
+            }
+        }
+        if ($mk eq 'Pentax' and $id =~ /^\d+$/) {
+            # for Pentax, CS4 stores an int16u, but we use 2 x int8u
+            $id = join(' ', unpack('C*', pack('n', $id)));
+        }
+        # Nikon is a special case because Adobe doesn't store the full LensID
+        # (Apple Photos does, but we have to convert back to hex)
+        if ($mk eq 'Nikon') {
+            $id = sprintf('%X', $id);
+            $id = "0$id" if length($id) & 0x01;     # pad with leading 0 if necessary
+            $id =~ s/(..)/$1 /g and $id =~ s/ $//;  # put spaces between bytes
+            my (%newConv, %used);
+            my $i = 0;
+            foreach (grep /^$id/, keys %$printConv) {
+                my $lens = $$printConv{$_};
+                next if $used{$lens}; # avoid duplicates
+                $used{$lens} = 1;
+                $newConv{$i ? "$id.$i" : $id} = $lens;
+                ++$i;
+            }
+            $printConv = \%newConv;
+        }
+        my $str = $$printConv{$id} || "Unknown ($id)";
+        return Image::ExifTool::Exif::PrintLensID($et, $str, $printConv,
+                    undef, $id, $focalLength, $sa, $maxAv, $sf, $lf, $lensModel);
+    }
+    return "Unknown ($id)";
 }
 
@@ -2499,5 +3072,5 @@
     my $val = $_[0];
     $val =~ m{^(-?\d+)/(-?\d+)$} or return undef;
-    if ($2) {
+    if ($2 != 0) {
         $_[0] = $1 / $2; # calculate quotient
     } elsif ($1) {
@@ -2507,4 +3080,19 @@
     }
     return 1;
+}
+
+#------------------------------------------------------------------------------
+# Convert a string of floating point values to rationals
+# Inputs: 0) string of floating point numbers separated by spaces
+# Returns: string of rational numbers separated by spaces
+sub ConvertRationalList($)
+{
+    my $val = shift;
+    my @vals = split ' ', $val;
+    return $val unless @vals == 4;
+    foreach (@vals) {
+        ConvertRational($_) or return $val;
+    }
+    return join ' ', @vals;
 }
 
@@ -2518,15 +3106,15 @@
 {
     local $_;
-    my ($exifTool, $tagTablePtr, $props, $val, $attrs) = @_;
-    my ($lang, @structProps);
-    my ($tag, $ns) = GetXMPTagID($props, $exifTool->{OPTIONS}{Struct} ? \@structProps : undef);
+    my ($et, $tagTablePtr, $props, $val, $attrs) = @_;
+    my ($lang, @structProps, $rawVal, $rational);
+    my ($tag, $ns) = GetXMPTagID($props, $$et{OPTIONS}{Struct} ? \@structProps : undef);
     return 0 unless $tag;   # ignore things that aren't valid tags
 
     # translate namespace if necessary
-    $ns = $$xlatNamespace{$ns} if $$xlatNamespace{$ns};
-    my $info = $tagTablePtr->{$ns};
+    $ns = $stdXlatNS{$ns} if $stdXlatNS{$ns};
+    my $info = $$tagTablePtr{$ns};
     my ($table, $added, $xns, $tagID);
     if ($info) {
-        $table = $info->{SubDirectory}{TagTable} or warn "Missing TagTable for $tag!\n";
+        $table = $$info{SubDirectory}{TagTable} or warn "Missing TagTable for $tag!\n";
     } elsif ($$props[0] eq 'svg:svg') {
         if (not $ns) {
@@ -2541,17 +3129,39 @@
     }
 
-    # look up this tag in the appropriate table
-    $table or $table = 'Image::ExifTool::XMP::other';
-    $tagTablePtr = GetTagTable($table);
-    if ($$tagTablePtr{NAMESPACE}) {
+    my $xmlGroups;
+    my $grp0 = $$tagTablePtr{GROUPS}{0};
+    if (not $ns and $grp0 ne 'XMP') {
         $tagID = $tag;
+    } elsif ($grp0 eq 'XML' and not $table) {
+        # this is an XML table (no namespace lookup)
+        $tagID = "$ns:$tag";
     } else {
-        # 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;
+        $xmlGroups = 1 if $grp0 eq 'XML';
+        # look up this tag in the appropriate table
+        $table or $table = 'Image::ExifTool::XMP::other';
+        $tagTablePtr = GetTagTable($table);
+        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
+            $tagID = "$xns:$tag";
+            # add namespace to top-level structure property
+            $structProps[0][0] = "$xns:" . $structProps[0][0] if @structProps;
+        }
     }
-    my $tagInfo = $exifTool->GetTagInfo($tagTablePtr, $tagID);
+    my $tagInfo = $et->GetTagInfo($tagTablePtr, $tagID);
 
     $lang = $$attrs{'xml:lang'} if $attrs;
@@ -2573,12 +3183,4 @@
             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;
@@ -2597,5 +3199,6 @@
                 next unless ref $ti eq 'HASH';
                 my $strTable = $$ti{Struct} or next;
-                $name = $$ti{Name} . ucfirst($t2);
+                my $flat = (defined $$ti{FlatName} ? $$ti{FlatName} : $$ti{Name});
+                $name = $flat . ucfirst($t2);
                 # don't continue if structure is known but field is not
                 last if $$strTable{NAMESPACE} or not exists $$strTable{NAMESPACE};
@@ -2605,5 +3208,5 @@
                 my $n = $nsList[$i+1];  # namespace of structure field
                 # translate to standard ExifTool namespace
-                $n = $$xlatNamespace{$n} if $$xlatNamespace{$n};
+                $n = $stdXlatNS{$n} if $stdXlatNS{$n};
                 my $xn = $xmpNS{$n} || $n;  # standard XMP namespace
                 # no need to continue with variable-namespace logic if
@@ -2620,9 +3223,9 @@
                 last unless ref $tg eq 'HASH' and $$tg{SubDirectory};
                 my $tbl = GetTagTable($$tg{SubDirectory}{TagTable}) or last;
-                my $sti = $exifTool->GetTagInfo($tbl, $t2);
+                my $sti = $et->GetTagInfo($tbl, $t2);
                 if (not $sti or $$sti{Flat}) {
                     # again, we must initialize flattened tags if necessary
                     # (but don't bother to recursively apply full logic to
-                    #  allow nest variable-namespace strucures until someone
+                    #  allow nested variable-namespace strucures until someone
                     #  actually wants to do such a silly thing)
                     my $t3 = '';
@@ -2637,9 +3240,6 @@
                     last unless $sti;
                 }
-                $tagInfo = {
-                    %$sti,
-                    Name     => $$ti{Name} . $$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
@@ -2651,9 +3251,10 @@
             }
         }
-        $tagInfo or $tagInfo = { Name => $name, WasAdded => 1 };
+        # 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 ($curNS{$ns} and $curNS{$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
@@ -2683,6 +3284,7 @@
         #    $$tagInfo{List} = 1;
         }
-        Image::ExifTool::AddTagToTable($tagTablePtr, $tagID, $tagInfo);
-        $added = 1;
+        # save property list for verbose "adding" message unless this tag already exists
+        $added = \@tagList unless $$tagTablePtr{$tagID};
+        AddTagToTable($tagTablePtr, $tagID, $tagInfo);
         last;
     }
@@ -2717,31 +3319,74 @@
     }
     # decode from UTF8
-    $val = $exifTool->Decode($val, 'UTF8');
+    $val = $et->Decode($val, 'UTF8');
     # convert rational and date values to a more sensible format
     my $fmt = $$tagInfo{Writable};
-    my $new = $$tagInfo{WasAdded};
-    if (($fmt or $new)) {
-        unless (($new or $fmt eq 'rational') and ConvertRational($val)) {
+    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)) {
+            $rational = $rawVal;
+        } else {
             $val = ConvertXMPDate($val, $new) if $new or $fmt eq 'date';
         }
+        if ($$et{XmpValidate} and $fmt and $fmt eq 'boolean') {
+            $et->WarnOnce("Boolean value for XMP-$ns:$$tagInfo{Name} should be capitalized",1);
+        }
+        # protect against large binary data in unknown tags
+        $$tagInfo{Binary} = 1 if $new and length($val) > 65536;
     }
     # store the value for this tag
-    my $key = $exifTool->FoundTag($tagInfo, $val);
+    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])) {
-        $exifTool->{TAG_EXTRA}{$key}{Struct} = \@structProps;
-        $exifTool->{IsStruct} = 1;
+    if (@structProps and (@structProps > 1 or defined $structProps[0][1]) and
+        not $$et{NO_STRUCT})
+    {
+        $$et{TAG_EXTRA}{$key}{Struct} = \@structProps;
+        $$et{IsStruct} = 1;
     }
-    if ($ns and not $$tagInfo{StaticGroup1}) {
+    if ($xmlGroups) {
+        $et->SetGroup($key, 'XML', 0);
+        $et->SetGroup($key, "XML-$ns", 1);
+    } elsif ($ns and not $$tagInfo{StaticGroup1}) {
         # set group1 dynamically according to the namespace
-        $exifTool->SetGroup($key, "$tagTablePtr->{GROUPS}{0}-$ns");
+        $et->SetGroup($key, "$$tagTablePtr{GROUPS}{0}-$ns");
     }
-    if ($exifTool->{OPTIONS}{Verbose}) {
+    if ($$et{OPTIONS}{Verbose}) {
         if ($added) {
-            my $g1 = $exifTool->GetGroup($key, 1);
-            $exifTool->VPrint(0, $exifTool->{INDENT}, "[adding $g1:$tag]\n");
+            my $props;
+            if (@$added > 1) {
+                $$tagInfo{Flat} = 0;    # this is a flattened tag
+                my @props = map { $$_[0] } @$added;
+                $props = ' (' . join('/',@props) . ')';
+            } else {
+                $props = '';
+            }
+            my $g1 = $et->GetGroup($key, 1);
+            $et->VPrint(0, $$et{INDENT}, "[adding $g1:$tag]$props\n");
         }
         my $tagID = join('/',@$props);
-        $exifTool->VerboseInfo($tagID, $tagInfo, Value=>$val);
+        $et->VerboseInfo($tagID, $tagInfo, Value => $rawVal || $val);
     }
     return 1;
@@ -2750,28 +3395,30 @@
 #------------------------------------------------------------------------------
 # Recursively parse nested XMP data element
-# Inputs: 0) ExifTool object reference
-#         1) Pointer to tag table
-#         2) reference to XMP data
-#         3) start of xmp element
-#         4) reference to array of enclosing XMP property names (undef if none)
-#         5) reference to blank node information hash
+# Inputs: 0) ExifTool ref, 1) tag table ref, 2) XMP data ref
+#         3) offset to start of XMP element, 4) offset to end of XMP element
+#         5) reference to array of enclosing XMP property names (undef if none)
+#         6) reference to blank node information hash
 # Returns: Number of contained XMP elements
-sub ParseXMPElement($$$;$$$)
+sub ParseXMPElement($$$;$$$$)
 {
-    my ($exifTool, $tagTablePtr, $dataPt, $start, $propListPt, $blankInfo) = @_;
+    local $_;
+    my ($et, $tagTablePtr, $dataPt, $start, $end, $propList, $blankInfo) = @_;
     my ($count, $nItems) = (0, 0);
-    my $isWriting = $exifTool->{XMP_CAPTURE};
-    my $isSVG = $$exifTool{XMP_IS_SVG};
+    my $isWriting = $$et{XMP_CAPTURE};
+    my $isSVG = $$et{XMP_IS_SVG};
+    my $saveNS;     # save xlatNS lookup if changed for the scope of this element
+    my (%definedNS, %usedNS);  # namespaces defined and used in this scope
 
     # get our parse procs
     my ($attrProc, $foundProc);
-    if ($$exifTool{XMPParseOpts}) {
-        $attrProc = $$exifTool{XMPParseOpts}{AttrProc};
-        $foundProc = $$exifTool{XMPParseOpts}{FoundProc} || \&FoundXMP;
+    if ($$et{XMPParseOpts}) {
+        $attrProc = $$et{XMPParseOpts}{AttrProc};
+        $foundProc = $$et{XMPParseOpts}{FoundProc} || \&FoundXMP;
     } else {
         $foundProc = \&FoundXMP;
     }
     $start or $start = 0;
-    $propListPt or $propListPt = [ ];
+    $end or $end = length $$dataPt;
+    $propList or $propList = [ ];
 
     my $processBlankInfo;
@@ -2780,38 +3427,162 @@
     # keep track of current nodeID at this nesting level
     my $oldNodeID = $$blankInfo{NodeID};
-
     pos($$dataPt) = $start;
+
+    # lookup for translating namespace prefixes
+    my $xlatNS = $$et{xlatNS};
+
     Element: for (;;) {
+        # all done if there isn't enough data for another element
+        # (the smallest possible element is 4 bytes, eg. "<a/>")
+        last if pos($$dataPt) > $end - 4;
         # reset nodeID before processing each element
         my $nodeID = $$blankInfo{NodeID} = $oldNodeID;
         # get next element
-        last unless $$dataPt =~ m/<([-\w:.\x80-\xff]+)(.*?)>/sg;
-        my ($prop, $attrs) = ($1, $2);
-        my $val = '';
+        last if $$dataPt !~ m{<([?/]?)([-\w:.\x80-\xff]+|!--)([^>]*)>}sg or pos($$dataPt) > $end;
+        # (the only reason we match '<[?/]' is to keep from scanning past the
+        #  "<?xpacket end..." terminator or other closing token, so
+        next if $1;
+        my ($prop, $attrs) = ($2, $3);
+        # skip comments
+        if ($prop eq '!--') {
+            next if $attrs =~ /--$/ or $$dataPt =~ /-->/sg;
+            last;
+        }
+        my $valStart = pos($$dataPt);
+        my $valEnd;
         # only look for closing token if this is not an empty element
-        # (empty elements end with '/', ie. <a:b/>)
+        # (empty elements end with '/', eg. <a:b/>)
         if ($attrs !~ s/\/$//) {
             my $nesting = 1;
             for (;;) {
 # this match fails with perl 5.6.2 (perl bug!), but it works without
-# the '(.*?)', so do it the hard way instead...
+# the '(.*?)', so we must do it differently...
 #                $$dataPt =~ m/(.*?)<\/$prop>/sg or last Element;
 #                my $val2 = $1;
-                my $pos = pos($$dataPt);
-                unless ($$dataPt =~ m/<\/$prop>/sg) {
-                    $exifTool->Warn("XMP format error (no closing tag for $prop)");
+                # find next matching closing token, or the next opening token
+                # of a nested same-named element
+                if ($$dataPt !~ m{<(/?)$prop([-\w:.\x80-\xff]*)(.*?(/?))>}sg or
+                    pos($$dataPt) > $end)
+                {
+                    $et->Warn("XMP format error (no closing tag for $prop)");
                     last Element;
                 }
-                my $len = pos($$dataPt) - $pos - length($prop) - 3;
-                my $val2 = substr($$dataPt, $pos, $len);
-                # increment nesting level for each contained similar opening token
-                ++$nesting while $val2 =~ m/<$prop\b.*?(\/?)>/sg and $1 ne '/';
-                $val .= $val2;
-                --$nesting or last;
-                $val .= "</$prop>";
-            }
-        }
-        my $parseResource;
+                next if $2; # ignore opening properties with different names
+                if ($1) {
+                    next if --$nesting;
+                    $valEnd = pos($$dataPt) - length($prop) - length($3) - 3;
+                    last;   # this element is complete
+                }
+                # this is a nested opening token (or empty element)
+                ++$nesting unless $4;
+            }
+        } else {
+            $valEnd = $valStart;
+        }
+        $start = pos($$dataPt);         # start from here the next time around
+
+        # extract property attributes
+        my ($parseResource, %attrs, @attrs);
+        while ($attrs =~ m/(\S+?)\s*=\s*(['"])(.*?)\2/sg) {
+            my ($attr, $val) = ($1, $3);
+            # handle namespace prefixes (defined by xmlns:PREFIX, or used with PREFIX:tag)
+            if ($attr =~ /(.*?):/) {
+                if ($1 eq 'xmlns') {
+                    my $ns = substr($attr, 6);
+                    my $stdNS = $uri2ns{$val};
+                    # keep track of namespace prefixes defined in this scope (for Validate)
+                    $$et{definedNS}{$ns} = $definedNS{$ns} = 1 unless $$et{definedNS}{$ns};
+                    unless ($stdNS) {
+                        my $try = $val;
+                        # patch for Nikon NX2 URI bug for Microsoft PhotoInfo namespace
+                        $try =~ s{/$}{} or $try .= '/';
+                        $stdNS = $uri2ns{$try};
+                        if ($stdNS) {
+                            $val = $try;
+                            $et->WarnOnce("Fixed incorrect URI for xmlns:$ns", 1);
+                        } else {
+                            # look for same namespace with different version number
+                            $try = quotemeta $val; # (note: escapes slashes too)
+                            $try =~ s{\\/\d+\\\.\d+(\\/|$)}{\\/\\d+\\\.\\d+$1};
+                            my ($good) = grep /^$try$/, keys %uri2ns;
+                            if ($good) {
+                                $stdNS = $uri2ns{$good};
+                                $et->VPrint(0, $$et{INDENT}, "[different $stdNS version: $val]\n");
+                            }
+                        }
+                    }
+                    # tame wild namespace prefixes (patches Microsoft stupidity)
+                    my $newNS;
+                    if ($stdNS) {
+                        # use standard namespace prefix if pre-defined
+                        if ($stdNS ne $ns) {
+                            $newNS = $stdNS;
+                        } elsif ($$xlatNS{$ns}) {
+                            # this prefix is re-defined to the standard prefix in this scope
+                            $newNS = '';
+                        }
+                    } elsif ($$et{curNS}{$val}) {
+                        # use a consistent prefix over the entire XMP for a given namespace URI
+                        $newNS = $$et{curNS}{$val} if $$et{curNS}{$val} ne $ns;
+                    } else {
+                        my $curURI = $$et{curURI};
+                        my $curNS = $$et{curNS};
+                        my $usedNS = $ns;
+                        # use unique prefixes for all namespaces across the entire XMP
+                        if ($$curURI{$ns} or $nsURI{$ns}) {
+                            # generate a temporary namespace prefix to resolve any conflict
+                            my $i = 0;
+                            ++$i while $$curURI{"tmp$i"};
+                            $newNS = $usedNS = "tmp$i";
+                        }
+                        # keep track of the namespace prefixes and URI's used in this XMP
+                        $$curNS{$val} = $usedNS;
+                        $$curURI{$usedNS} = $val;
+                    }
+                    if (defined $newNS) {
+                        # save translation used in containing scope if necessary
+                        # create new namespace translation for the scope of this element
+                        $saveNS or $saveNS = $xlatNS, $xlatNS = $$et{xlatNS} = { %$xlatNS };
+                        if (length $newNS) {
+                            # use the new namespace prefix
+                            $$xlatNS{$ns} = $newNS;
+                            $attr = 'xmlns:' . $newNS;
+                            # must go through previous attributes and change prefixes if necessary
+                            foreach (@attrs) {
+                                next unless /(.*?):/ and $1 eq $ns and $1 ne $newNS;
+                                my $newAttr = $newNS . substr($_, length($ns));
+                                $attrs{$newAttr} = $attrs{$_};
+                                delete $attrs{$_};
+                                $_ = $newAttr;
+                            }
+                        } else {
+                            delete $$xlatNS{$ns};
+                        }
+                    }
+                } else {
+                    $attr = $$xlatNS{$1} . substr($attr, length($1)) if $$xlatNS{$1};
+                    $usedNS{$1} = 1;
+                }
+            }
+            push @attrs, $attr;    # preserve order
+            $attrs{$attr} = $val;
+        }
+        if ($prop =~ /(.*?):/) {
+            $usedNS{$1} = 1;
+            # tame wild namespace prefixes (patch for Microsoft stupidity)
+            $prop = $$xlatNS{$1} . substr($prop, length($1)) if $$xlatNS{$1};
+        }
+
         if ($prop eq 'rdf:li') {
+            # impose a reasonable maximum on the number of items in a list
+            if ($nItems == 1000) {
+                my ($tg,$ns) = GetXMPTagID($propList);
+                if ($isWriting) {
+                    $et->Warn("Excessive number of items for $ns:$tg. Processing may be slow", 1);
+                } elsif (not $$et{OPTIONS}{IgnoreMinorErrors}) {
+                    $et->Warn("Extracted only 1000 $ns:$tg items. Ignore minor errors to extract all", 2);
+                    last;
+                }
+            }
             # add index to list items so we can keep them in order
             # (this also enables us to keep structure elements grouped properly
@@ -2823,27 +3594,30 @@
             # 10,11,12-19,210,211-299,3100,3101-3999,41000...9999999999.
             $prop .= ' ' . length($nItems) . $nItems;
+            # reset LIST_TAGS at the start of the outtermost list
+            # (avoids accumulating incorrectly-written elements in a correctly-written list)
+            if (not $nItems and not grep /^rdf:li /, @$propList) {
+                $$et{LIST_TAGS} = { };
+            }
             ++$nItems;
         } elsif ($prop eq 'rdf:Description') {
-            # trim comments and whitespace from rdf:Description properties only
-            $val =~ s/<!--.*?-->//g;
-            $val =~ s/^\s*(.*)\s*$/$1/;
             # remove unnecessary rdf:Description elements since parseType='Resource'
             # is more efficient (also necessary to make property path consistent)
-            $parseResource = 1 if grep /^rdf:Description$/, @$propListPt;
+            $parseResource = 1 if grep /^rdf:Description$/, @$propList;
         } elsif ($prop eq 'xmp:xmpmeta') {
             # patch MicrosoftPhoto unconformity
             $prop = 'x:xmpmeta';
-        }
-
-        # extract property attributes
-        my (%attrs, @attrs);
-        while ($attrs =~ m/(\S+?)\s*=\s*(['"])(.*?)\2/sg) {
-            push @attrs, $1;    # preserve order
-            $attrs{$1} = $3;
+            $et->Warn('Wrong namespace for xmpmeta') if $$et{XmpValidate};
         }
 
         # hook for special parsing of attributes
-        $attrProc and &$attrProc(\@attrs, \%attrs, \$prop, \$val);
-            
+        my $val;
+        if ($attrProc) {
+            $val = substr($$dataPt, $valStart, $valEnd - $valStart);
+            if (&$attrProc(\@attrs, \%attrs, \$prop, \$val)) {
+                # the value was changed, so reset $valStart/$valEnd to use $val instead
+                $valStart = $valEnd;
+            }
+        }
+
         # add nodeID to property path (with leading ' #') if it exists
         if (defined $attrs{'rdf:nodeID'}) {
@@ -2855,11 +3629,11 @@
 
         # push this property name onto our hierarchy list
-        push @$propListPt, $prop unless $parseResource;
+        push @$propList, $prop unless $parseResource;
 
         if ($isSVG) {
             # ignore everything but top level SVG tags and metadata unless Unknown set
-            unless ($exifTool->{OPTIONS}{Unknown} > 1 or $exifTool->{OPTIONS}{Verbose}) {
-                if (@$propListPt > 1 and $$propListPt[1] !~ /\b(metadata|desc|title)$/) {
-                    pop @$propListPt;
+            unless ($$et{OPTIONS}{Unknown} > 1 or $$et{OPTIONS}{Verbose}) {
+                if (@$propList > 1 and $$propList[1] !~ /\b(metadata|desc|title)$/) {
+                    pop @$propList;
                     next;
                 }
@@ -2867,5 +3641,10 @@
             if ($prop eq 'svg' or $prop eq 'metadata') {
                 # add svg namespace prefix if missing to ignore these entries in the tag name
-                $$propListPt[-1] = "svg:$prop";
+                $$propList[-1] = "svg:$prop";
+            }
+        } elsif ($$et{XmpIgnoreProps}) { # ignore specified properties for tag name
+            foreach (@{$$et{XmpIgnoreProps}}) {
+                last unless @$propList;
+                pop @$propList if $_ eq $$propList[0];
             }
         }
@@ -2875,4 +3654,5 @@
         my ($shortName, $shorthand, $ignored);
         foreach $shortName (@attrs) {
+            next unless defined $attrs{$shortName};
             my $propName = $shortName;
             my ($ns, $name);
@@ -2891,18 +3671,17 @@
                 $name = $propName;
             }
-            # keep track of the namespace prefixes used
-            if ($ns eq 'xmlns') {
-                unless ($attrs{$shortName}) {
-                    $exifTool->WarnOnce("Duplicate namespace '$shortName'");
-                    next;
-                }
-                $curNS{$name} = $attrs{$shortName};
-                my $stdNS = $uri2ns{$attrs{$shortName}};
-                # translate namespace if non-standard (except 'x' and 'iX')
-                if ($stdNS and $name ne $stdNS and $stdNS ne 'x' and $stdNS ne 'iX') {
-                    # make a copy of the standard translations so we can modify it
-                    $xlatNamespace = { %stdXlatNS } if $xlatNamespace eq \%stdXlatNS;
-                    # translate this namespace prefix to the standard version
-                    $$xlatNamespace{$name} = $stdXlatNS{$stdNS} || $stdNS;
+            if ($propName eq 'rdf:about') {
+                if (not $$et{XmpAbout}) {
+                    $$et{XmpAbout} = $attrs{$shortName};
+                } elsif ($$et{XmpAbout} ne $attrs{$shortName}) {
+                    if ($isWriting) {
+                        my $str = "Different 'rdf:about' attributes not handled";
+                        unless ($$et{WARNED_ONCE}{$str}) {
+                            $et->Error($str, 1);
+                            $$et{WARNED_ONCE}{$str} = 1;
+                        }
+                    } elsif ($$et{XmpValidate}) {
+                        $et->WarnOnce("Different 'rdf:about' attributes");
+                    }
                 }
             }
@@ -2912,5 +3691,5 @@
                     my $stdNS = $uri2ns{$attrs{$shortName}};
                     unless ($stdNS and ($stdNS eq 'x' or $stdNS eq 'iX')) {
-                        my $nsUsed = $exifTool->{XMP_NS};
+                        my $nsUsed = $$et{XMP_NS};
                         $$nsUsed{$name} = $attrs{$shortName} unless defined $$nsUsed{$name};
                     }
@@ -2918,24 +3697,16 @@
                     next;
                 } elsif ($recognizedAttrs{$propName}) {
-                    # save UUID to use same ID when writing
-                    if ($propName eq 'rdf:about') {
-                        if (not $exifTool->{XMP_ABOUT}) {
-                            $exifTool->{XMP_ABOUT} = $attrs{$shortName};
-                        } elsif ($exifTool->{XMP_ABOUT} ne $attrs{$shortName}) {
-                            $exifTool->Error("Different 'rdf:about' attributes not handled", 1);
-                        }
-                    }
                     next;
                 }
             }
             my $shortVal = $attrs{$shortName};
-            if ($ignoreNamespace{$ns}) {
+            if ($ignoreNamespace{$ns} or $ignoreProp{$prop}) {
                 $ignored = $propName;
                 # handle special attributes (extract as tags only once if not empty)
                 if (ref $recognizedAttrs{$propName} and $shortVal) {
                     my ($tbl, $id, $name) = @{$recognizedAttrs{$propName}};
-                    my $val = UnescapeXML($shortVal);
-                    unless (defined $$exifTool{VALUE}{$name} and $$exifTool{VALUE}{$name} eq $val) {
-                        $exifTool->HandleTag(GetTagTable($tbl), $id, $val);
+                    my $tval = UnescapeXML($shortVal);
+                    unless (defined $$et{VALUE}{$name} and $$et{VALUE}{$name} eq $tval) {
+                        $et->HandleTag(GetTagTable($tbl), $id, $tval);
                     }
                 }
@@ -2943,61 +3714,99 @@
             }
             delete $attrs{$shortName};  # don't re-use this attribute
-            push @$propListPt, $propName;
+            push @$propList, $propName;
             # save this shorthand XMP property
             if (defined $nodeID) {
-                SaveBlankInfo($blankInfo, $propListPt, $shortVal);
+                SaveBlankInfo($blankInfo, $propList, $shortVal);
             } elsif ($isWriting) {
-                CaptureXMP($exifTool, $propListPt, $shortVal);
+                CaptureXMP($et, $propList, $shortVal);
             } else {
-                &$foundProc($exifTool, $tagTablePtr, $propListPt, $shortVal);
-            }
-            pop @$propListPt;
+                ValidateProperty($et, $propList) if $$et{XmpValidate};
+                &$foundProc($et, $tagTablePtr, $propList, $shortVal);
+            }
+            pop @$propList;
             $shorthand = 1;
         }
         if ($isWriting) {
-            if (ParseXMPElement($exifTool, $tagTablePtr, \$val, 0, $propListPt, $blankInfo)) {
-                # undefine value since we found more properties within this one
-                undef $val;
+            if (ParseXMPElement($et, $tagTablePtr, $dataPt, $valStart, $valEnd,
+                                $propList, $blankInfo))
+            {
+                # (no value since we found more properties within this one)
                 # set an error on any ignored attributes here, because they will be lost
-                $exifTool->{XMP_ERROR} = "Can't handle XMP attribute '$ignored'" if $ignored;
-            }
-            if (defined $val and (length $val or not $shorthand)) {
+                $$et{XMP_ERROR} = "Can't handle XMP attribute '${ignored}'" if $ignored;
+            } elsif (not $shorthand or $valEnd != $valStart) {
+                $val = substr($$dataPt, $valStart, $valEnd - $valStart);
+                # remove comments and whitespace from rdf:Description only
+                if ($prop eq 'rdf:Description') {
+                    $val =~ s/<!--.*?-->//g; $val =~ s/^\s+//; $val =~ s/\s+$//;
+                }
                 if (defined $nodeID) {
-                    SaveBlankInfo($blankInfo, $propListPt, $val, \%attrs);
+                    SaveBlankInfo($blankInfo, $propList, $val, \%attrs);
                 } else {
-                    CaptureXMP($exifTool, $propListPt, $val, \%attrs);
+                    CaptureXMP($et, $propList, $val, \%attrs);
                 }
             }
         } else {
-            # if element value is empty, take value from 'resource' attribute
-            # (preferentially) or 'about' attribute (if no 'resource')
-            my $wasEmpty;
-            if ($val eq '' and ($attrs =~ /\bresource=(['"])(.*?)\1/ or
-                                $attrs =~ /\babout=(['"])(.*?)\1/))
+            # look for additional elements contained within this one
+            if ($valStart == $valEnd or
+                !ParseXMPElement($et, $tagTablePtr, $dataPt, $valStart, $valEnd,
+                                 $propList, $blankInfo))
             {
-                $val = $2;
-                $wasEmpty = 1;
-            }
-            # look for additional elements contained within this one
-            if (!ParseXMPElement($exifTool, $tagTablePtr, \$val, 0, $propListPt, $blankInfo)) {
+                my $wasEmpty;
+                unless (defined $val) {
+                    $val = substr($$dataPt, $valStart, $valEnd - $valStart);
+                    # remove comments and whitespace from rdf:Description only
+                    if ($prop eq 'rdf:Description' and $val) {
+                        $val =~ s/<!--.*?-->//g; $val =~ s/^\s+//; $val =~ s/\s+$//;
+                    }
+                    # 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;
+                    }
+                }
                 # there are no contained elements, so this must be a simple property value
                 # (unless we already extracted shorthand values from this element)
                 if (length $val or not $shorthand) {
-                    my $lastProp = $$propListPt[-1];
+                    my $lastProp = $$propList[-1];
                     if (defined $nodeID) {
-                        SaveBlankInfo($blankInfo, $propListPt, $val);
+                        SaveBlankInfo($blankInfo, $propList, $val);
                     } elsif ($lastProp eq 'rdf:type' and $wasEmpty) {
                         # do not extract empty structure types (for now)
                     } elsif ($lastProp =~ /^et:(desc|prt|val)$/ and ($count or $1 eq 'desc')) {
-                        # ignore et:desc, and et:val if preceeded by et:prt
+                        # ignore et:desc, and et:val if preceded by et:prt
                         --$count;
                     } else {
-                        &$foundProc($exifTool, $tagTablePtr, $propListPt, $val, \%attrs);
+                        ValidateProperty($et, $propList, \%attrs) if $$et{XmpValidate};
+                        &$foundProc($et, $tagTablePtr, $propList, $val, \%attrs);
                     }
                 }
             }
         }
-        pop @$propListPt unless $parseResource;
+        pop @$propList unless $parseResource;
         ++$count;
+
+        # validate namespace prefixes used at this level if necessary
+        if ($$et{XmpValidate}) {
+            foreach (sort keys %usedNS) {
+                next if $$et{definedNS}{$_} or $_ eq 'xml';
+                if (defined $$et{definedNS}{$_}) {
+                    $et->Warn("XMP namespace $_ is used out of scope");
+                } else {
+                    $et->Warn("Undefined XMP namespace: $_");
+                }
+                $$et{definedNS}{$_} = -1;  # (don't warn again for this namespace)
+            }
+            # reset namespaces that went out of scope
+            $$et{definedNS}{$_} = 0 foreach keys %definedNS;
+            undef %usedNS;
+            undef %definedNS;
+        }
+
+        last if $start >= $end;
+        pos($$dataPt) = $start;
+        $$dataPt =~ /\G\s+/gc;  # skip white space after closing token
     }
 #
@@ -3005,7 +3814,10 @@
 #
     if ($processBlankInfo and %{$$blankInfo{Prop}}) {
-        ProcessBlankInfo($exifTool, $tagTablePtr, $blankInfo, $isWriting);
+        ProcessBlankInfo($et, $tagTablePtr, $blankInfo, $isWriting);
         %$blankInfo = ();   # free some memory
     }
+    # restore namespace lookup from the containing scope
+    $$et{xlatNS} = $saveNS if $saveNS;
+
     return $count;  # return the number of elements found at this level
 }
@@ -3027,20 +3839,41 @@
 sub ProcessXMP($$;$)
 {
-    my ($exifTool, $dirInfo, $tagTablePtr) = @_;
+    my ($et, $dirInfo, $tagTablePtr) = @_;
     my $dataPt = $$dirInfo{DataPt};
-    my ($dirStart, $dirLen, $dataLen);
+    my ($dirStart, $dirLen, $dataLen, $double);
     my ($buff, $fmt, $hasXMP, $isXML, $isRDF, $isSVG);
     my $rtnVal = 0;
     my $bom = 0;
-    undef %curNS;
+
+    # namespaces and prefixes currently in effect while parsing the file,
+    # and lookup to translate brain-dead-Microsoft-Photo-software prefixes
+    $$et{curURI} = { };
+    $$et{curNS}  = { };
+    $$et{xlatNS} = { };
+    $$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 and not $$exifTool{XMP_CAPTURE} and
-        $$exifTool{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/)
+    if (($Image::ExifTool::MWG::strict or $$et{OPTIONS}{Validate}) and
+        not ($$et{XMP_CAPTURE} or $$et{DOC_NUM}) and
+        (($$dirInfo{DirName} || '') eq 'XMP' or $$et{FILE_TYPE} eq 'XMP'))
     {
-        my $path = $exifTool->MetadataPath();
-        unless ($path =~ /^(JPEG-APP1-XMP|TIFF-IFD0-XMP|PSD-XMP)$/) {
-            $exifTool->Warn("Ignored non-standard XMP at $path");
+        $$et{XmpValidate} = { } if $$et{OPTIONS}{Validate};
+        my $path = $et->MetadataPath();
+        my $nonStd;
+        if ($$et{FILE_TYPE} =~ /^(JPEG|TIFF|PSD)$/ and $path !~ /^(JPEG-APP1-XMP|TIFF-IFD0-XMP|PSD-XMP)$/) {
+            $nonStd = 1;
+        }
+        if ($nonStd and $Image::ExifTool::MWG::strict) {
+            $et->Warn("Ignored non-standard XMP at $path");
             return 1;
+        }
+        if ($nonStd) {
+            $et->Warn("Non-standard XMP at $path", 1);
+        } elsif (not $$dirInfo{IsExtended}) {
+            $et->Warn("Duplicate XMP at $path") if $$et{DIR_COUNT}{XMP};
+            $$et{DIR_COUNT}{XMP} = ($$et{DIR_COUNT}{XMP} || 0) + 1; # count standard XMP
         }
     }
@@ -3049,12 +3882,14 @@
         $dirLen = $$dirInfo{DirLen} || (length($$dataPt) - $dirStart);
         $dataLen = $$dirInfo{DataLen} || length($$dataPt);
+        # check leading BOM (may indicate double-encoded UTF)
+        pos($$dataPt) = $dirStart;
+        $double = $1 if $$dataPt =~ /\G((\0\0)?\xfe\xff|\xff\xfe(\0\0)?|\xef\xbb\xbf)\0*<\0*\?\0*x\0*p\0*a\0*c\0*k\0*e\0*t/g;
     } else {
-        my $type;
+        my ($type, $mime, $buf2, $buf3);
         # read information from XMP file
         my $raf = $$dirInfo{RAF} or return 0;
         $raf->Read($buff, 256) or return 0;
-        my ($buf2, $buf3, $double);
         ($buf2 = $buff) =~ tr/\0//d;    # cheap conversion to UTF-8
-        # remove leading comments if they exist (ie. ImageIngester)
+        # remove leading comments if they exist (eg. ImageIngester)
         while ($buf2 =~ /^\s*<!--/) {
             # remove the comment if it is complete
@@ -3081,5 +3916,5 @@
             } 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) {
@@ -3090,8 +3925,16 @@
             $bom = 1 if $1;
             if ($2 eq '<?xml') {
-                if ($buf2 =~ /<x(mp)?:x[ma]pmeta/) {
+                if (defined $fmt and not $fmt and $buf2 =~ /^[^\n\r]*[\n\r]+<\?aid /s) {
+                    undef $$et{XmpValidate};    # don't validate INX
+                    if ($$et{XMP_CAPTURE}) {
+                        $et->Error("ExifTool does not yet support writing of INX files");
+                        return 0;
+                    }
+                    $type = 'INX';
+                } elsif ($buf2 =~ /<x(mp)?:x[ma]pmeta/) {
                     $hasXMP = 1;
                 } else {
-                    # identify SVG images by DOCTYPE if available
+                    undef $$et{XmpValidate};    # don't validate XML
+                    # identify SVG images and PLIST files by DOCTYPE if available
                     if ($buf2 =~ /<!DOCTYPE\s+(\w+)/) {
                         if ($1 eq 'svg') {
@@ -3099,4 +3942,7 @@
                         } elsif ($1 eq 'plist') {
                             $type = 'PLIST';
+                        } elsif ($1 eq 'REDXIF') {
+                            $type = 'RMD';
+                            $mime = 'application/xml';
                         } else {
                             return 0;
@@ -3106,7 +3952,9 @@
                     } elsif ($buf2 =~ /<rdf:RDF/) {
                         $isRDF = 1;
+                    } elsif ($buf2 =~ /<plist[\s>]/) {
+                        $type = 'PLIST';
                     }
-                    if ($isSVG and $exifTool->{XMP_CAPTURE}) {
-                        $exifTool->Error("ExifTool does not yet support writing of SVG images");
+                    if ($isSVG and $$et{XMP_CAPTURE}) {
+                        $et->Error("ExifTool does not yet support writing of SVG images");
                         return 0;
                     }
@@ -3118,67 +3966,114 @@
             if ($buff =~ /^\0\0/) {
                 $fmt = 'N';     # UTF-32 MM with or without BOM
-            } elsif ($buff =~ /^..\0\0/) {
+            } elsif ($buff =~ /^..\0\0/s) {
                 $fmt = 'V';     # UTF-32 II with or without BOM
             } elsif (not $fmt) {
                 if ($buff =~ /^\0/) {
                     $fmt = 'n'; # UTF-16 MM without BOM
-                } elsif ($buff =~ /^.\0/) {
+                } elsif ($buff =~ /^.\0/s) {
                     $fmt = 'v'; # UTF-16 II without BOM
                 }
             }
         }
-        $raf->Seek(0, 2) or return 0;
-        my $size = $raf->Tell() or return 0;
-        $raf->Seek(0, 0) or return 0;
-        $raf->Read($buff, $size) == $size or return 0;
-        # decode the first layer of double-encoded UTF text
-        if ($double) {
-            $buff = substr($buff, length $double);  # remove leading BOM
-            Image::ExifTool::SetWarning(undef);     # clear old warning
-            local $SIG{'__WARN__'} = \&Image::ExifTool::SetWarning;
-            my $tmp;
-            # assume that character data has been re-encoded in UTF, so re-pack
-            # as characters and look for warnings indicating a false assumption
-            if ($double eq "\xef\xbb\xbf") {
-                require Image::ExifTool::Charset;
-                my $uni = Image::ExifTool::Charset::Decompose(undef,$buff,'UTF8');
-                $tmp = pack('C*', @$uni);
-            } else {
-                my $fmt = ($double eq "\xfe\xff") ? 'n' : 'v';
-                $tmp = pack('C*', unpack("$fmt*",$buff));
-            }
-            if (Image::ExifTool::GetWarning()) {
-                $exifTool->Warn('Superfluous BOM at start of XMP');
-            } else {
-                $exifTool->Warn('XMP is double UTF-encoded');
-                $buff = $tmp;   # use the decoded XMP
-            }
-            $size = length $buff;
-        }
-        $dataPt = \$buff;
-        $dirStart = 0;
-        $dirLen = $dataLen = $size;
-        unless ($type) {
+        my $size;
+        if ($type) {
+            if ($type eq 'PLIST') {
+                my $ext = $$et{FILE_EXT};
+                $type = $ext if $ext and $ext eq 'MODD';
+                $tagTablePtr = GetTagTable('Image::ExifTool::PLIST::Main');
+                $$dirInfo{XMPParseOpts}{FoundProc} = \&Image::ExifTool::PLIST::FoundTag;
+            }
+        } else {
             if ($isSVG) {
                 $type = 'SVG';
             } elsif ($isXML and not $hasXMP and not $isRDF) {
                 $type = 'XML';
-            }
-        }
-        $exifTool->SetFileType($type);
-    }
-
-    # take substring if necessary
-    if ($dataLen != $dirStart + $dirLen) {
-        $buff = substr($$dataPt, $dirStart, $dirLen);
+                my $ext = $$et{FILE_EXT};
+                $type = $ext if $ext and $ext eq 'COS'; # recognize COS by extension
+            }
+        }
+        $et->SetFileType($type, $mime);
+
+        my $fast = $et->Options('FastScan');
+        return 1 if $fast and $fast == 3;
+
+        if ($type and $type eq 'INX') {
+            # brute force search for first XMP packet in INX file
+            # start: '<![CDATA[<?xpacket begin' (24 bytes)
+            # end:   '<?xpacket end="r"?>]]>'   (22 bytes)
+            $raf->Seek(0, 0) or return 0;
+            $raf->Read($buff, 65536) or return 1;
+            for (;;) {
+                last if $buff =~ /<!\[CDATA\[<\?xpacket begin/g;
+                $raf->Read($buf2, 65536) or return 1;
+                $buff = substr($buff, -24) . $buf2;
+            }
+            $buff = substr($buff, pos($buff) - 15); # (discard '<![CDATA[' and before)
+            for (;;) {
+                last if $buff =~ /<\?xpacket end="[rw]"\?>\]\]>/g;
+                my $n = length $buff;
+                $raf->Read($buf2, 65536) or $et->Warn('Missing xpacket end'), return 1;
+                $buff .= $buf2;
+                pos($buff) = $n - 22;   # don't miss end pattern if it was split
+            }
+            $size = pos($buff) - 3;     # (discard ']]>' and after)
+            $buff = substr($buff, 0, $size);
+        } else {
+            # read the entire file
+            $raf->Seek(0, 2) or return 0;
+            $size = $raf->Tell() or return 0;
+            $raf->Seek(0, 0) or return 0;
+            $raf->Read($buff, $size) == $size or return 0;
+        }
         $dataPt = \$buff;
         $dirStart = 0;
+        $dirLen = $dataLen = $size;
     }
-    # extract XMP as a block if specified
-    if (($exifTool->{REQ_TAG_LOOKUP}{xmp} or $exifTool->{OPTIONS}{Binary}) and not $isSVG) {
-        $exifTool->FoundTag('XMP', substr($$dataPt, $dirStart, $dirLen));
+
+    # decode the first layer of double-encoded UTF text (if necessary)
+    if ($double) {
+        my ($buf2, $fmt);
+        $buff = substr($$dataPt, $dirStart + length $double); # remove leading BOM
+        Image::ExifTool::SetWarning(undef); # clear old warning
+        local $SIG{'__WARN__'} = \&Image::ExifTool::SetWarning;
+        # assume that character data has been re-encoded in UTF, so re-pack
+        # as characters and look for warnings indicating a false assumption
+        if ($double eq "\xef\xbb\xbf") {
+            require Image::ExifTool::Charset;
+            my $uni = Image::ExifTool::Charset::Decompose(undef,$buff,'UTF8');
+            $buf2 = pack('C*', @$uni);
+        } else {
+            if (length($double) == 2) {
+                $fmt = ($double eq "\xfe\xff") ? 'n' : 'v';
+            } else {
+                $fmt = ($double eq "\0\0\xfe\xff") ? 'N' : 'V';
+            }
+            $buf2 = pack('C*', unpack("$fmt*",$buff));
+        }
+        if (Image::ExifTool::GetWarning()) {
+            $et->Warn('Superfluous BOM at start of XMP');
+            $dataPt = \$buff;   # use XMP with the BOM removed
+        } else {
+            $et->Warn('XMP is double UTF-encoded');
+            $dataPt = \$buf2;   # use the decoded XMP
+        }
+        $dirStart = 0;
+        $dirLen = $dataLen = length $$dataPt;
     }
-    if ($exifTool->Options('Verbose') and not $exifTool->{XMP_CAPTURE}) {
-        $exifTool->VerboseDir($isSVG ? 'SVG' : 'XMP', 0, $dirLen);
+
+    # extract XMP/XML 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
+        (($$et{FileType} eq 'XMP' and $blockName eq 'XMP') or
+        ($$dirInfo{DirName} and $$dirInfo{DirName} eq $blockName)))
+    {
+        $et->FoundTag($$dirInfo{BlockInfo} || 'XMP', substr($$dataPt, $dirStart, $dirLen));
+    }
+
+    $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
+    if ($et->Options('Verbose') and not $$et{XMP_CAPTURE}) {
+        my $dirType = $isSVG ? 'SVG' : $$tagTablePtr{GROUPS}{1};
+        $et->VerboseDir($dirType, 0, $dirLen);
     }
 #
@@ -3186,22 +4081,25 @@
 #
     my $begin = '<?xpacket begin=';
+    my $dirEnd = $dirStart + $dirLen;
     pos($$dataPt) = $dirStart;
-    delete $$exifTool{XMP_IS_XML};
-    delete $$exifTool{XMP_IS_SVG};
+    delete $$et{XMP_IS_XML};
+    delete $$et{XMP_IS_SVG};
     if ($isXML or $isRDF) {
-        $$exifTool{XMP_IS_XML} = $isXML;
-        $$exifTool{XMP_IS_SVG} = $isSVG;
-        $$exifTool{XMP_NO_XPACKET} = 1 + $bom;
+        $$et{XMP_IS_XML} = $isXML;
+        $$et{XMP_IS_SVG} = $isSVG;
+        $$et{XMP_NO_XPACKET} = 1 + $bom;
     } elsif ($$dataPt =~ /\G\Q$begin\E/gc) {
-        delete $$exifTool{XMP_NO_XPACKET};
-    } elsif ($$dataPt =~ /<x(mp)?:x[ma]pmeta/gc) {
-        $$exifTool{XMP_NO_XPACKET} = 1 + $bom;
+        delete $$et{XMP_NO_XPACKET};
+    } elsif ($$dataPt =~ /<x(mp)?:x[ma]pmeta/gc and
+             pos($$dataPt) > $dirStart and pos($$dataPt) < $dirEnd)
+    {
+        $$et{XMP_NO_XPACKET} = 1 + $bom;
     } else {
-        delete $$exifTool{XMP_NO_XPACKET};
+        delete $$et{XMP_NO_XPACKET};
         # check for UTF-16 encoding (insert one \0 between characters)
         $begin = join "\0", split //, $begin;
         # must reset pos because it was killed by previous unsuccessful //g match
         pos($$dataPt) = $dirStart;
-        if ($$dataPt =~ /\G(\0)?\Q$begin\E\0./g) {
+        if ($$dataPt =~ /\G(\0)?\Q$begin\E\0./sg) {
             # validate byte ordering by checking for U+FEFF character
             if ($1) {
@@ -3215,5 +4113,5 @@
             $begin =~ s/\0/\0\0\0/g;
             pos($$dataPt) = $dirStart;
-            if ($$dataPt !~ /\G(\0\0\0)?\Q$begin\E\0\0\0./g) {
+            if ($$dataPt !~ /\G(\0\0\0)?\Q$begin\E\0\0\0./sg) {
                 $fmt = 0;   # set format to zero as indication we didn't find encoded XMP
             } elsif ($1) {
@@ -3224,9 +4122,9 @@
             }
         }
-        defined $fmt or $exifTool->Warn('XMP character encoding error');
+        defined $fmt or $et->Warn('XMP character encoding error');
     }
     if ($fmt) {
         # trim if necessary to avoid converting non-UTF data
-        if ($dirStart or $dirLen != length($$dataPt) - $dirStart) {
+        if ($dirStart or $dirEnd != length($$dataPt)) {
             $buff = substr($$dataPt, $dirStart, $dirLen);
             $dataPt = \$buff;
@@ -3241,20 +4139,51 @@
         $dirStart = 0;
         $dirLen = length $$dataPt;
+        $dirEnd = $dirStart + $dirLen;
     }
-    # initialize namespace translation
-    $xlatNamespace = \%stdXlatNS;
-
     # avoid scanning for XMP later in case ScanForXMP is set
-    $$exifTool{FoundXMP} = 1;
+    $$et{FoundXMP} = 1 if $tagTablePtr eq \%Image::ExifTool::XMP::Main;
 
     # set XMP parsing options
-    $$exifTool{XMPParseOpts} = $$dirInfo{XMPParseOpts};
+    $$et{XMPParseOpts} = $$dirInfo{XMPParseOpts};
+
+    # ignore any specified properties (XML hack)
+    if ($$dirInfo{IgnoreProp}) {
+        %ignoreProp = %{$$dirInfo{IgnoreProp}};
+    } else {
+        undef %ignoreProp;
+    }
 
     # need to preserve list indices to be able to handle multi-dimensional lists
-    $$exifTool{NO_LIST} = 1 if $exifTool->Options('Struct');
+    my $keepFlat;
+    if ($$et{OPTIONS}{Struct}) {
+        if ($$et{OPTIONS}{Struct} eq '2') {
+            $keepFlat = 1;      # preserve flattened tags
+            # setting NO_LIST to 0 combines list items in a TAG_EXTRA "NoList" element
+            # to allow them to be re-listed later if necessary.  A "NoListDel" element
+            # is also created for tags that wouldn't have existed.
+            $$et{NO_LIST} = 0;
+        } else {
+            $$et{NO_LIST} = 1;
+        }
+    }
+
+    # don't generate structures if this isn't real XMP
+    $$et{NO_STRUCT} = 1 if $$dirInfo{BlockInfo} or $$dirInfo{NoStruct};
 
     # parse the XMP
-    $tagTablePtr or $tagTablePtr = GetTagTable('Image::ExifTool::XMP::Main');
-    $rtnVal = 1 if ParseXMPElement($exifTool, $tagTablePtr, $dataPt, $dirStart);
+    if (ParseXMPElement($et, $tagTablePtr, $dataPt, $dirStart, $dirEnd)) {
+        $rtnVal = 1;
+    } elsif ($$dirInfo{DirName} and $$dirInfo{DirName} eq 'XMP') {
+        # if DirName was 'XMP' we expect well-formed XMP, so set Warning since it wasn't
+        # (but allow empty XMP as written by some PhaseOne cameras)
+        my $xmp = substr($$dataPt, $dirStart, $dirLen);
+        if ($xmp =~ /^ *\0*$/) {
+            $et->Warn('Invalid XMP');
+        } else {
+            $et->Warn('Empty XMP',1);
+            $rtnVal = 1;
+        }
+    }
+    delete $$et{NO_STRUCT};
 
     # return DataPt if successful in case we want it for writing
@@ -3262,13 +4191,17 @@
 
     # restore structures if necessary
-    if ($$exifTool{IsStruct}) {
+    if ($$et{IsStruct}) {
         require 'Image/ExifTool/XMPStruct.pl';
-        RestoreStruct($exifTool);
-        delete $$exifTool{IsStruct};
+        RestoreStruct($et, $keepFlat);
+        delete $$et{IsStruct};
     }
     # reset NO_LIST flag (must do this _after_ RestoreStruct() above)
-    delete $$exifTool{NO_LIST};
-
-    undef %curNS;
+    delete $$et{NO_LIST};
+    delete $$et{XMPParseOpts};
+    delete $$et{curURI};
+    delete $$et{curNS};
+    delete $$et{xlatNS};
+    delete $$et{definedNS};
+
     return $rtnVal;
 }
@@ -3296,5 +4229,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMP2.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMP2.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMP2.pl	(revision 34921)
@@ -2,5 +2,5 @@
 # File:         XMP2.pl
 #
-# Description:  Additional XMP schema definitions
+# Description:  Additional XMP namespace definitions
 #
 # Revisions:    10/12/2008 - P. Harvey Created
@@ -9,8 +9,12 @@
 #               2) PRISM - http://www.prismstandard.org/
 #               3) http://www.portfoliofaq.com/pfaq/v7mappings.htm
+#               4) http://www.iptc.org/IPTC4XMP/
 #               5) http://creativecommons.org/technology/xmp
 #                  --> changed to http://wiki.creativecommons.org/Companion_File_metadata_specification (2007/12/21)
 #               6) http://www.optimasc.com/products/fileid/xmp-extensions.pdf
 #               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
 #------------------------------------------------------------------------------
 
@@ -21,5 +25,9 @@
 use Image::ExifTool::XMP;
 
-# structure definitions
+sub Init_crd($);
+
+#------------------------------------------------------------------------------
+
+# xmpDM structure definitions
 my %sCuePointParam = (
     STRUCT_NAME => 'CuePointParam',
@@ -68,13 +76,84 @@
     },
     timeValue   => { },
-    value       => { Writable => 'integer' },
-);
-
-# XMP Dynamic Media schema properties (xmpDM)
+    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 = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-xmpDM', 2 => 'Image' },
     NAMESPACE => 'xmpDM',
-    NOTES => 'XMP Dynamic Media schema tags.',
+    NOTES => 'XMP Dynamic Media namespace tags.',
     absPeakAudioFilePath=> { },
     album               => { },
@@ -139,4 +218,5 @@
     director        => { },
     directorPhotography => { },
+    discNumber      => { }, #12
     duration        => { Struct => \%sTime },
     engineer        => { },
@@ -156,8 +236,10 @@
     logComment      => { },
     loop            => { Writable => 'boolean' },
+    lyrics          => { }, #12
     numberOfBeats   => { Writable => 'real' },
     markers         => { Struct => \%sMarker, List => 'Seq' },
     metadataModDate => { Groups => { 2 => 'Time' }, %dateTimeInfo },
     outCue          => { Struct => \%sTime },
+    partOfCompilation=>{ Writable => 'boolean' }, #12
     projectName     => { },
     projectRef => {
@@ -213,4 +295,6 @@
     speakerPlacement=> { },
     startTimecode   => { Struct => \%sTimecode },
+    startTimeSampleSize => { Writable => 'integer' }, #PH
+    startTimeScale  => { }, #PH (real?)
     stretchMode     => {
         PrintConv => {
@@ -270,5 +354,5 @@
         },
     },
-    videoCompressor     => { },
+    videoCompressor => { },
     videoFieldOrder => {
         PrintConv => {
@@ -278,7 +362,7 @@
         },
     },
-    videoFrameRate      => { },
-    videoFrameSize      => { Struct => \%sDimensions },
-    videoModDate        => { Groups => { 2 => 'Time' }, %dateTimeInfo },
+    videoFrameRate  => { Writable => 'real' },
+    videoFrameSize  => { Struct => \%sDimensions },
+    videoModDate    => { Groups => { 2 => 'Time' }, %dateTimeInfo },
     videoPixelAspectRatio => { Writable => 'rational' },
     videoPixelDepth => {
@@ -295,321 +379,422 @@
 
 #------------------------------------------------------------------------------
-# 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.0 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',
-    TYPE => 'plus:LicenseeDetail',
-    LicenseeID  => { },
-    LicenseeName=> { },
-);
-my %plusEndUser = (
-    STRUCT_NAME => 'EndUser',
-    NAMESPACE   => 'plus',
-    TYPE => 'plus:EndUserDetail',
-    EndUserID   => { },
-    EndUserName => { },
-);
-my %plusLicensor = (
-    STRUCT_NAME => 'Licensor',
-    NAMESPACE   => 'plus',
-    TYPE => 'plus:LicensorDetail',
-    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',
-    CopyrightOwnerID    => { },
-    CopyrightOwnerName  => { },
-);
-my %plusImageCreator = (
-    STRUCT_NAME => 'ImageCreator',
-    NAMESPACE   => 'plus',
-    TYPE        => 'plus:ImageCreatorDetail',
-    ImageCreatorID      => { },
-    ImageCreatorName    => { },
-);
-my %plusImageSupplier = (
-    STRUCT_NAME => 'ImageSupplier',
-    NAMESPACE   => 'plus',
-    TYPE        => 'plus:ImageSupplierDetail',
-    ImageSupplierID     => { },
-    ImageSupplierName   => { },
-);
-
-# PLUS License Data Format 1.2.0 (plus) (ref 1)
-%Image::ExifTool::XMP::plus = (
-    %xmpTableDefaults,
-    GROUPS => { 0 => 'XMP', 1 => 'XMP-plus', 2 => 'Author' },
-    NAMESPACE => 'plus',
+# IPTC Extensions version 1.3 (+ proposed video extensions)
+
+# IPTC Extension 1.0 structures
+my %sLocationDetails = (
+    STRUCT_NAME => 'LocationDetails',
+    NAMESPACE   => 'Iptc4xmpExt',
+    GROUPS      => { 2 => 'Location' },
+    Identifier  => { List => 'Bag', Namespace => 'xmp' },
+    City        => { },
+    CountryCode => { },
+    CountryName => { },
+    ProvinceState => { },
+    Sublocation => { },
+    WorldRegion => { },
+    LocationId  => { List => 'Bag' },
+    LocationName => { Writable => 'lang-alt' },
+    GPSLatitude  => { Namespace => 'exif', %latConv },
+    GPSLongitude => { Namespace => 'exif', %longConv },
+    GPSAltitude => {
+        Namespace => 'exif',
+        Writable => 'rational',
+        PrintConv => '$val =~ /^(inf|undef)$/ ? $val : "$val m"',
+        PrintConvInv => '$val=~s/\s*m$//;$val',
+    },
+);
+my %sCVTermDetails = (
+    STRUCT_NAME => 'CVTermDetails',
+    NAMESPACE   => 'Iptc4xmpExt',
+    CvTermId    => { },
+    CvTermName  => { Writable => 'lang-alt' },
+    CvId        => { },
+    CvTermRefinedAbout => { },
+);
+
+# IPTC video extensions
+my %sPublicationEvent = (
+    STRUCT_NAME => 'PublicationEvent',
+    NAMESPACE   => 'Iptc4xmpExt',
+    Date        => { Groups => { 2 => 'Time' }, %dateTimeInfo },
+    Name        => { },
+    Identifier  => { },
+);
+my %sEntity = (
+    STRUCT_NAME => 'Entity',
+    NAMESPACE   => 'Iptc4xmpExt',
+    Identifier  => { List => 'Bag', Namespace => 'xmp' },
+    Name        => { Writable => 'lang-alt' },
+);
+my %sEntityWithRole = (
+    STRUCT_NAME => 'EntityWithRole',
+    NAMESPACE   => 'Iptc4xmpExt',
+    Identifier  => { List => 'Bag', Namespace => 'xmp' },
+    Name        => { Writable => 'lang-alt' },
+    Role        => { List => 'Bag' },
+);
+# (no longer used)
+#my %sFrameSize = (
+#    STRUCT_NAME => 'FrameSize',
+#    NAMESPACE   => 'Iptc4xmpExt',
+#    WidthPixels  => { Writable => 'integer' },
+#    HeightPixels => { Writable => 'integer' },
+#);
+my %sRating = (
+    STRUCT_NAME => 'Rating',
+    NAMESPACE   => 'Iptc4xmpExt',
+    RatingValue         => { FlatName => 'Value' },
+    RatingSourceLink    => { FlatName => 'SourceLink' },
+    RatingScaleMinValue => { FlatName => 'ScaleMinValue' },
+    RatingScaleMaxValue => { FlatName => 'ScaleMaxValue' },
+    RatingValueLogoLink => { FlatName => 'ValueLogoLink' },
+    RatingRegion => {
+        FlatName => 'Region',
+        Struct => \%sLocationDetails,
+        List => 'Bag',
+    },
+);
+my %sEpisode = (
+    STRUCT_NAME => 'EpisodeOrSeason',
+    NAMESPACE   => 'Iptc4xmpExt',
+    Name        => { },
+    Number      => { },
+    Identifier  => { },
+);
+my %sSeries = (
+    STRUCT_NAME => 'Series',
+    NAMESPACE   => 'Iptc4xmpExt',
+    Name        => { },
+    Identifier  => { },
+);
+my %sTemporalCoverage = (
+    STRUCT_NAME => 'TemporalCoverage',
+    NAMESPACE   => 'Iptc4xmpExt',
+    tempCoverageFrom => { FlatName => 'From', %dateTimeInfo, Groups => { 2 => 'Time' } },
+    tempCoverageTo   => { FlatName => 'To',   %dateTimeInfo, Groups => { 2 => 'Time' } },
+);
+my %sQualifiedLink = (
+    STRUCT_NAME => 'QualifiedLink',
+    NAMESPACE   => 'Iptc4xmpExt',
+    Link        => { },
+    LinkQualifier => { },
+);
+my %sTextRegion = (
+    STRUCT_NAME => 'TextRegion',
+    NAMESPACE   => 'Iptc4xmpExt',
+    RegionText  => { },
+    Region      => { Struct => \%Image::ExifTool::XMP::sArea },
+);
+my %sLinkedImage = (
+    STRUCT_NAME => 'LinkedImage',
+    NAMESPACE   => 'Iptc4xmpExt',
+    Link        => { },
+    LinkQualifier => { List => 'Bag' },
+    ImageRole   => { },
+   'format'     => { Namespace => 'dc' },
+    WidthPixels => { Writable => 'integer' },
+    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{
-        PLUS License Data Format 1.2.0 schema 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/>)
-    },
-    Version  => { Name => 'PLUSVersion' },
-    Licensee => {
-        Struct => \%plusLicensee,
-        List => 'Seq',
-    },
-    LicenseeLicenseeID   => { Flat => 1, Name => 'LicenseeID' },
-    LicenseeLicenseeName => { Flat => 1, Name => 'LicenseeName' },
-    EndUser => {
-        Struct => \%plusEndUser,
-        List => 'Seq',
-    },
-    EndUserEndUserID    => { Flat => 1, Name => 'EndUserID' },
-    EndUserEndUserName  => { Flat => 1, Name => 'EndUserName' },
-    Licensor => {
-        Struct => \%plusLicensor,
-        List => 'Seq',
-    },
-    LicensorLicensorID              => { Flat => 1, Name => 'LicensorID' },
-    LicensorLicensorName            => { Flat => 1, Name => 'LicensorName' },
-    LicensorLicensorStreetAddress   => { Flat => 1, Name => 'LicensorStreetAddress' },
-    LicensorLicensorExtendedAddress => { Flat => 1, Name => 'LicensorExtendedAddress' },
-    LicensorLicensorCity            => { Flat => 1, Name => 'LicensorCity' },
-    LicensorLicensorRegion          => { Flat => 1, Name => 'LicensorRegion' },
-    LicensorLicensorPostalCode      => { Flat => 1, Name => 'LicensorPostalCode' },
-    LicensorLicensorCountry         => { Flat => 1, Name => 'LicensorCountry' },
-    LicensorLicensorTelephoneType1  => { Flat => 1, Name => 'LicensorTelephoneType1' },
-    LicensorLicensorTelephone1      => { Flat => 1, Name => 'LicensorTelephone1' },
-    LicensorLicensorTelephoneType2  => { Flat => 1, Name => 'LicensorTelephoneType2' },
-    LicensorLicensorTelephone2      => { Flat => 1, Name => 'LicensorTelephone2' },
-    LicensorLicensorEmail           => { Flat => 1, Name => 'LicensorEmail' },
-    LicensorLicensorURL             => { Flat => 1, Name => 'LicensorURL' },
-    LicensorNotes               => { Writable => 'lang-alt' },
-    MediaSummaryCode            => { },
-    LicenseStartDate            => { %dateTimeInfo, Groups => { 2 => 'Time'} },
-    LicenseEndDate              => { %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        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
-    CopyrightOwner              => { Struct => \%plusCopyrightOwner, List => 'Seq' },
-    CopyrightOwnerCopyrightOwnerID   => { Flat => 1, Name => 'CopyrightOwnerID' },
-    CopyrightOwnerCopyrightOwnerName => { Flat => 1, Name => 'CopyrightOwnerName' },
-    CopyrightOwnerImageID            => { },
-    ImageCreator => {
-        Struct => \%plusImageCreator,
-        List => 'Seq',
-    },
-    ImageCreatorImageCreatorID   => { Flat => 1, Name => 'ImageCreatorID' },
-    ImageCreatorImageCreatorName => { Flat => 1, Name => 'ImageCreatorName' },
-    ImageCreatorImageID          => { },
-    ImageSupplier => {
-        Struct => \%plusImageSupplier,
-        List => 'Seq',
-    },
-    ImageSupplierImageSupplierID   => { Flat => 1, Name => 'ImageSupplierID' },
-    ImageSupplierImageSupplierName => { Flat => 1, Name => 'ImageSupplierName' },
-    ImageSupplierImageID    => { },
-    LicenseeImageID         => { },
-    LicenseeImageNotes      => { Writable => 'lang-alt' },
-    OtherImageInfo          => { Writable => 'lang-alt' },
-    LicenseID               => { },
-    LicensorTransactionID   => { List => 'Bag' },
-    LicenseeTransactionID   => { List => 'Bag' },
-    LicenseeProjectReference=> { List => 'Bag' },
-    LicenseTransactionDate  => { %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' },
+        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 = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-iptcExt', 2 => 'Author' },
+    NAMESPACE   => 'Iptc4xmpExt',
+    TABLE_DESC => 'XMP IPTC Extension',
+    NOTES => q{
+        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,
+        List => 'Bag',
+    },
+    AboutCvTermCvId                 => { Flat => 1, Name => 'AboutCvTermCvId' },
+    AboutCvTermCvTermId             => { Flat => 1, Name => 'AboutCvTermId' },
+    AboutCvTermCvTermName           => { Flat => 1, Name => 'AboutCvTermName' },
+    AboutCvTermCvTermRefinedAbout   => { Flat => 1, Name => 'AboutCvTermRefinedAbout' },
+    AddlModelInfo   => { Name => 'AdditionalModelInformation' },
+    ArtworkOrObject => {
+        Struct => {
+            STRUCT_NAME => 'ArtworkOrObjectDetails',
+            NAMESPACE   => 'Iptc4xmpExt',
+            AOCopyrightNotice => { },
+            AOCreator    => { List => 'Seq' },
+            AODateCreated=> { Groups => { 2 => 'Time' }, %dateTimeInfo },
+            AOSource     => { },
+            AOSourceInvNo=> { },
+            AOTitle      => { Writable => 'lang-alt' },
+            AOCurrentCopyrightOwnerName => { },
+            AOCurrentCopyrightOwnerId   => { },
+            AOCurrentLicensorName       => { },
+            AOCurrentLicensorId         => { },
+            AOCreatorId                 => { List => 'Seq' },
+            AOCircaDateCreated          => { Groups => { 2 => 'Time' }, Protected => 1 },
+            AOStylePeriod               => { List => 'Bag' },
+            AOSourceInvURL              => { },
+            AOContentDescription        => { Writable => 'lang-alt' },
+            AOContributionDescription   => { Writable => 'lang-alt' },
+            AOPhysicalDescription       => { Writable => 'lang-alt' },
+        },
+        List => 'Bag',
+    },
+    ArtworkOrObjectAOCopyrightNotice           => { Flat => 1, Name => 'ArtworkCopyrightNotice' },
+    ArtworkOrObjectAOCreator                   => { Flat => 1, Name => 'ArtworkCreator' },
+    ArtworkOrObjectAODateCreated               => { Flat => 1, Name => 'ArtworkDateCreated' },
+    ArtworkOrObjectAOSource                    => { Flat => 1, Name => 'ArtworkSource' },
+    ArtworkOrObjectAOSourceInvNo               => { Flat => 1, Name => 'ArtworkSourceInventoryNo' },
+    ArtworkOrObjectAOTitle                     => { Flat => 1, Name => 'ArtworkTitle' },
+    ArtworkOrObjectAOCurrentCopyrightOwnerName => { Flat => 1, Name => 'ArtworkCopyrightOwnerName' },
+    ArtworkOrObjectAOCurrentCopyrightOwnerId   => { Flat => 1, Name => 'ArtworkCopyrightOwnerID' },
+    ArtworkOrObjectAOCurrentLicensorName       => { Flat => 1, Name => 'ArtworkLicensorName' },
+    ArtworkOrObjectAOCurrentLicensorId         => { Flat => 1, Name => 'ArtworkLicensorID' },
+    ArtworkOrObjectAOCreatorId                 => { Flat => 1, Name => 'ArtworkCreatorID' },
+    ArtworkOrObjectAOCircaDateCreated          => { Flat => 1, Name => 'ArtworkCircaDateCreated' },
+    ArtworkOrObjectAOStylePeriod               => { Flat => 1, Name => 'ArtworkStylePeriod' },
+    ArtworkOrObjectAOSourceInvURL              => { Flat => 1, Name => 'ArtworkSourceInvURL' },
+    ArtworkOrObjectAOContentDescription        => { Flat => 1, Name => 'ArtworkContentDescription' },
+    ArtworkOrObjectAOContributionDescription   => { Flat => 1, Name => 'ArtworkContributionDescription' },
+    ArtworkOrObjectAOPhysicalDescription       => { Flat => 1, Name => 'ArtworkPhysicalDescription' },
+    CVterm => {
+        Name => 'ControlledVocabularyTerm',
+        List => 'Bag',
+        Notes => 'deprecated by version 1.2',
+    },
+    DigImageGUID            => { Groups => { 2 => 'Image' }, Name => 'DigitalImageGUID' },
+    DigitalSourcefileType   => {
+        Name => 'DigitalSourceFileType',
+        Notes => 'now deprecated -- replaced by DigitalSourceType',
+        Groups => { 2 => 'Image' },
+    },
+    DigitalSourceType       => { Name => 'DigitalSourceType', Groups => { 2 => 'Image' } },
+    EmbdEncRightsExpr => {
+        Struct => {
+            STRUCT_NAME => 'EEREDetails',
+            NAMESPACE   => 'Iptc4xmpExt',
+            EncRightsExpr       => { },
+            RightsExprEncType   => { },
+            RightsExprLangId    => { },
+        },
+        List => 'Bag',
+    },
+    EmbdEncRightsExprEncRightsExpr      => { Flat => 1, Name => 'EmbeddedEncodedRightsExpr' },
+    EmbdEncRightsExprRightsExprEncType  => { Flat => 1, Name => 'EmbeddedEncodedRightsExprType' },
+    EmbdEncRightsExprRightsExprLangId   => { Flat => 1, Name => 'EmbeddedEncodedRightsExprLangID' },
+    Event       => { Writable => 'lang-alt' },
+    IptcLastEdited => {
+        Name => 'IPTCLastEdited',
+        Groups => { 2 => 'Time' },
+        %dateTimeInfo,
+    },
+    LinkedEncRightsExpr => {
+        Struct => {
+            STRUCT_NAME => 'LEREDetails',
+            NAMESPACE   => 'Iptc4xmpExt',
+            LinkedRightsExpr    => { },
+            RightsExprEncType   => { },
+            RightsExprLangId    => { },
+        },
+        List => 'Bag',
+    },
+    LinkedEncRightsExprLinkedRightsExpr  => { Flat => 1, Name => 'LinkedEncodedRightsExpr' },
+    LinkedEncRightsExprRightsExprEncType => { Flat => 1, Name => 'LinkedEncodedRightsExprType' },
+    LinkedEncRightsExprRightsExprLangId  => { Flat => 1, Name => 'LinkedEncodedRightsExprLangID' },
+    LocationCreated => {
+        Struct => \%sLocationDetails,
+        Groups => { 2 => 'Location' },
+        List => 'Bag',
+    },
+    LocationShown => {
+        Struct => \%sLocationDetails,
+        Groups => { 2 => 'Location' },
+        List => 'Bag',
+    },
+    MaxAvailHeight          => { Groups => { 2 => 'Image' }, Writable => 'integer' },
+    MaxAvailWidth           => { Groups => { 2 => 'Image' }, Writable => 'integer' },
+    ModelAge                => { List => 'Bag', Writable => 'integer' },
+    OrganisationInImageCode => { List => 'Bag' },
+    OrganisationInImageName => { List => 'Bag' },
+    PersonInImage           => { List => 'Bag' },
+    PersonInImageWDetails => {
+        Struct => {
+            STRUCT_NAME => 'PersonDetails',
+            NAMESPACE   => 'Iptc4xmpExt',
+            PersonId    => { List => 'Bag' },
+            PersonName  => { Writable => 'lang-alt' },
+            PersonCharacteristic => {
+                Struct  => \%sCVTermDetails,
+                List    => 'Bag',
+            },
+            PersonDescription => { Writable => 'lang-alt' },
+        },
+        List => 'Bag',
+    },
+    PersonInImageWDetailsPersonId                               => { Flat => 1, Name => 'PersonInImageId' },
+    PersonInImageWDetailsPersonName                             => { Flat => 1, Name => 'PersonInImageName' },
+    PersonInImageWDetailsPersonCharacteristic                   => { Flat => 1, Name => 'PersonInImageCharacteristic' },
+    PersonInImageWDetailsPersonCharacteristicCvId               => { Flat => 1, Name => 'PersonInImageCvTermCvId' },
+    PersonInImageWDetailsPersonCharacteristicCvTermId           => { Flat => 1, Name => 'PersonInImageCvTermId' },
+    PersonInImageWDetailsPersonCharacteristicCvTermName         => { Flat => 1, Name => 'PersonInImageCvTermName' },
+    PersonInImageWDetailsPersonCharacteristicCvTermRefinedAbout => { Flat => 1, Name => 'PersonInImageCvTermRefinedAbout' },
+    PersonInImageWDetailsPersonDescription                      => { Flat => 1, Name => 'PersonInImageDescription' },
+    ProductInImage => {
+        Struct => {
+            STRUCT_NAME => 'ProductDetails',
+            NAMESPACE   => 'Iptc4xmpExt',
+            ProductName => { Writable => 'lang-alt' },
+            ProductGTIN => { },
+            ProductDescription => { Writable => 'lang-alt' },
+        },
+        List => 'Bag',
+    },
+    ProductInImageProductName        => { Flat => 1, Name => 'ProductInImageName' },
+    ProductInImageProductGTIN        => { Flat => 1, Name => 'ProductInImageGTIN' },
+    ProductInImageProductDescription => { Flat => 1, Name => 'ProductInImageDescription' },
+    RegistryId => {
+        Name => 'RegistryID',
+        Struct => {
+            STRUCT_NAME => 'RegistryEntryDetails',
+            NAMESPACE   => 'Iptc4xmpExt',
+            RegItemId   => { },
+            RegOrgId    => { },
+            RegEntryRole=> { }, # (new in 1.3)
+        },
+        List => 'Bag',
+    },
+    RegistryIdRegItemId => { Flat => 1, Name => 'RegistryItemID' },
+    RegistryIdRegOrgId  => { Flat => 1, Name => 'RegistryOrganisationID' },
+    RegistryIdRegEntryRole => { Flat => 1, Name => 'RegistryEntryRole' },
+
+    # new Extension 1.3 properties
+    Genre           => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sCVTermDetails },
+
+    # new video properties (Oct 2016, ref Michael Steidl)
+    # (see http://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.0.html)
+    CircaDateCreated=> { Groups => { 2 => 'Time' } },
+    Episode         => { Groups => { 2 => 'Video' }, Struct => \%sEpisode },
+    ExternalMetadataLink => { Groups => { 2 => 'Other' }, List => 'Bag' },
+    FeedIdentifier  => { Groups => { 2 => 'Video' } },
+    PublicationEvent=> { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sPublicationEvent },
+    Rating          => {
+        Groups => { 2 => 'Other' },
+        Struct  => \%sRating,
+        List    => 'Bag',
+    },
+    ReleaseReady    => { Groups => { 2 => 'Other' }, Writable => 'boolean' },
+    Season          => { Groups => { 2 => 'Video' }, Struct => \%sEpisode },
+    Series          => { Groups => { 2 => 'Video' }, Struct => \%sSeries },
+    StorylineIdentifier => { Groups => { 2 => 'Video' }, List => 'Bag' },
+    StylePeriod     => { Groups => { 2 => 'Video' } },
+    TemporalCoverage=> { Groups => { 2 => 'Video' }, Struct => \%sTemporalCoverage },
+    WorkflowTag     => { Groups => { 2 => 'Video' }, Struct => \%sCVTermDetails },
+    DataOnScreen    => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sTextRegion },
+    Dopesheet       => { Groups => { 2 => 'Video' }, Writable => 'lang-alt' },
+    DopesheetLink   => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sQualifiedLink },
+    Headline        => { Groups => { 2 => 'Video' }, Writable => 'lang-alt', Avoid => 1 },
+    PersonHeard     => { Groups => { 2 => 'Audio' }, List => 'Bag', Struct => \%sEntity },
+    VideoShotType   => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sEntity },
+    EventExt        => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sEntity, Name => 'ShownEvent' },
+    Transcript      => { Groups => { 2 => 'Video' }, Writable => 'lang-alt' },
+    TranscriptLink  => { Groups => { 2 => 'Video' }, List => 'Bag', Struct => \%sQualifiedLink },
+    VisualColour    => {
+        Name => 'VisualColor',
+        Groups => { 2 => 'Video' },
+        PrintConv => {
+            'bw-monochrome' => 'Monochrome',
+            'colour'        => 'Color',
+        },
+    },
+    Contributor     => { List => 'Bag', Struct => \%sEntityWithRole },
+    CopyrightYear   => { Groups => { 2 => 'Time' },  Writable => 'integer' },
+    Creator         => { List => 'Bag', Struct => \%sEntityWithRole },
+    SupplyChainSource => { Groups => { 2 => 'Other' }, List => 'Bag', Struct => \%sEntity },
+    audioBitRate    => { Groups => { 2 => 'Audio' }, Writable => 'integer', Name => 'AudioBitrate' },
+    audioBitRateMode=> {
+        Name => 'AudioBitrateMode',
+        Groups => { 2 => 'Audio' },
+        PrintConv => {
+            fixed => 'Fixed',
+            variable => 'Variable',
+        },
+    },
+    audioChannelCount       => { Groups => { 2 => 'Audio' }, Writable => 'integer' },
+    videoDisplayAspectRatio => { Groups => { 2 => 'Audio' }, Writable => 'rational' },
+    ContainerFormat         => { Groups => { 2 => 'Video' }, Struct => \%sEntity },
+    StreamReady => {
+        Groups => { 2 => 'Video' },
+        PrintConv => {
+            true => 'True',
+            false => 'False',
+            unknown => 'Unknown',
+        },
+    },
+    videoBitRate     => { Groups => { 2 => 'Video' }, Writable => 'integer', Name => 'VideoBitrate' },
+    videoBitRateMode => {
+        Name => 'VideoBitrateMode',
+        Groups => { 2 => 'Video' },
+        PrintConv => {
+            fixed => 'Fixed',
+            variable => 'Variable',
+        },
+    },
+    videoEncodingProfile => { Groups => { 2 => 'Video' } },
+    videoStreamsCount    => { Groups => { 2 => 'Video' }, Writable => 'integer' },
+    # new IPTC video metadata 1.1 properties
+    # (ref https://www.iptc.org/std/videometadatahub/recommendation/IPTC-VideoMetadataHub-props-Rec_1.1.html)
+    SnapshotLink => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sLinkedImage, Name => 'Snapshot' },
+    # 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',
+            Manufacturer        => { },
+            ModelName           => { },
+            SerialNumber        => { },
+            AttLensDescription  => { },
+            OwnersDeviceId      => { },
+        },
+    },
+    PlanningRef         => { List => 'Bag', Struct => \%sEntityWithRole },
+    audioBitsPerSample  => { Groups => { 2 => 'Audio' }, Writable => 'integer' },
+    # new IPTC Extension schema 1.5 property
+    ImageRegion => { Groups => { 2 => 'Image' }, List => 'Bag', Struct => \%sImageRegion },
 );
 
@@ -617,5 +802,5 @@
 # PRISM
 #
-# NOTE: The "Avoid" flag is set for all PRISM tags
+# NOTE: The "Avoid" flag is set for all PRISM tags (via tag table AVOID flag)
 
 # my %obsolete = (
@@ -631,19 +816,56 @@
 # );
 
-# Publishing Requirements for Industry Standard Metadata 2.1 (prism) (ref 2)
+# PRISM structure definitions
+my %prismPublicationDate = (
+    STRUCT_NAME => 'prismPublicationDate',
+    NAMESPACE   => 'prism',
+    date        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
+    'a-platform'=> { },
+);
+
+# Publishing Requirements for Industry Standard Metadata (prism) (ref 2)
 %Image::ExifTool::XMP::prism = (
     %xmpTableDefaults,
     GROUPS => { 0 => 'XMP', 1 => 'XMP-prism', 2 => 'Document' },
     NAMESPACE => 'prism',
+    AVOID => 1,
     NOTES => q{
-        Publishing Requirements for Industry Standard Metadata 2.1 schema tags. (see
-        L<http://www.prismstandard.org/>)
-    },
+        Publishing Requirements for Industry Standard Metadata 3.0 namespace
+        tags.  (see L<http://www.prismstandard.org/>)
+    },
+    academicField   => { }, # (3.0)
+    aggregateIssueNumber => { Writable => 'integer' }, # (3.0)
     aggregationType => { List => 'Bag' },
-    alternateTitle  => { List => 'Bag' },
+    alternateTitle  => {
+        List => 'Bag',
+        Struct => { # (becomes a structure in 3.0)
+            STRUCT_NAME => 'prismAlternateTitle',
+            NAMESPACE   => 'prism',
+            text        => { },
+            'a-platform'=> { },
+            'a-lang'    => { },
+        },
+    },
+    blogTitle       => { }, # (3.0)
+    blogURL         => { }, # (3.0)
+    bookEdition     => { }, # (3.0)
     byteCount       => { Writable => 'integer' },
-    channel         => { List => 'Bag' },
+    channel         => {
+        List => 'Bag',
+        Struct => { # (becomes a structure in 3.0)
+            STRUCT_NAME => 'prismChannel',
+            NAMESPACE   => 'prism',
+            channel     => { },
+            subchannel1 => { },
+            subchannel2 => { },
+            subchannel3 => { },
+            subchannel4 => { },
+            'a-lang'    => { },
+        },
+    },
     complianceProfile=>{ PrintConv => { three => 'Three' } },
-    copyright       => { Groups => { 2 => 'Author' } },
+    contentType     => { }, # (3.0)
+    copyrightYear   => { }, # (3.0)
+    # copyright       => { Groups => { 2 => 'Author' } }, # (deprecated in 3.0)
     corporateEntity => { List => 'Bag' },
     coverDate       => { %dateTimeInfo, Groups => { 2 => 'Time'} },
@@ -651,30 +873,79 @@
     creationDate    => { %dateTimeInfo, Groups => { 2 => 'Time'} },
     dateRecieved    => { %dateTimeInfo, Groups => { 2 => 'Time'} },
+    device          => { }, # (3.0)
     distributor     => { },
     doi             => { Name => 'DOI', Description => 'Digital Object Identifier' },
     edition         => { },
     eIssn           => { },
-    embargoDate     => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
+    #embargoDate     => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, # (deprecated in 3.0)
     endingPage      => { },
     event           => { List => 'Bag' },
-    expirationDate  => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
+    #expirationDate  => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} }, # (deprecated in 3.0)
     genre           => { List => 'Bag' },
     hasAlternative  => { List => 'Bag' },
-    hasCorrection   => { },
-    hasPreviousVersion => { },
+    hasCorrection   => {
+        Struct => { # (becomes a structure in 3.0)
+            STRUCT_NAME => 'prismHasCorrection',
+            NAMESPACE   => 'prism',
+            text        => { },
+            'a-platform'=> { },
+            'a-lang'    => { },
+        },
+    },
+    # hasPreviousVersion => { }, # (not in 3.0)
     hasTranslation  => { List => 'Bag' },
     industry        => { List => 'Bag' },
+    isAlternativeOf => { List => 'Bag' }, # (3.0)
+    isbn            => { Name => 'ISBN', List => 'Bag' }, # 2.1 (becomes a list in 3.0)
     isCorrectionOf  => { List => 'Bag' },
     issn            => { Name => 'ISSN' },
     issueIdentifier => { },
     issueName       => { },
+    issueTeaser     => { }, # (3.0)
+    issueType       => { }, # (3.0)
     isTranslationOf => { },
     keyword         => { List => 'Bag' },
-    killDate        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
+    killDate        => {
+        Struct => { # (becomes a structure in 3.0)
+            STRUCT_NAME => 'prismKillDate',
+            NAMESPACE   => 'prism',
+            date        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
+            'a-platform'=> { }, #PH (missed in spec?)
+        },
+    },
+   'link'           => { List => 'Bag' }, # (3.0)
     location        => { List => 'Bag' },
     # metadataContainer => { }, (not valid for PRISM XMP)
     modificationDate=> { %dateTimeInfo, Groups => { 2 => 'Time'} },
+    nationalCatalogNumber => { }, # (3.0)
     number          => { },
     object          => { List => 'Bag' },
+    onSaleDate => { # (3.0)
+        List => 'Bag',
+        Struct => {
+            STRUCT_NAME => 'prismOnSaleDate',
+            NAMESPACE   => 'prism',
+            date        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
+            'a-platform'=> { },
+        },
+    },
+    onSaleDay => { # (3.0)
+        List => 'Bag',
+        Struct => {
+            STRUCT_NAME => 'prismOnSaleDay',
+            NAMESPACE   => 'prism',
+            day         => { }, #PH (not named in spec)
+            'a-platform'=> { },
+        },
+    },
+    offSaleDate => { # (3.0)
+        List => 'Bag',
+        Struct => {
+            STRUCT_NAME => 'prismOffSaleDate',
+            NAMESPACE   => 'prism',
+            date        => { %dateTimeInfo, Groups => { 2 => 'Time'} },
+            'a-platform'=> { },
+        },
+    },
     organization    => { List => 'Bag' },
     originPlatform  => {
@@ -690,10 +961,31 @@
         },
     },
+    pageCount       => { Writable => 'integer' }, # (3.0)
+    pageProgressionDirection => { # (3.0)
+        PrintConv => { LTR => 'Left to Right', RTL => 'Right to Left' },
+    },
     pageRange       => { List => 'Bag' },
     person          => { },
-    publicationDate => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
+    platform        => { }, # (3.0)
+    productCode     => { }, # (3.0)
+    profession      => { }, # (3.0)
+    publicationDate => {
+        List => 'Bag',
+        Struct => \%prismPublicationDate, # (becomes a structure in 3.0)
+    },
+    publicationDisplayDate => { # (3.0)
+        List => 'Bag',
+        Struct => \%prismPublicationDate,
+    },
     publicationName => { },
-    rightsAgent     => { },
+    publishingFrequency => { }, # (3.0)
+    rating          => { },
+    # rightsAgent     => { }, # (deprecated in 3.0)
+    samplePageRange => { }, # (3.0)
     section         => { },
+    sellingAgency   => { }, # (3.0)
+    seriesNumber    => { Writable => 'integer' }, # (3.0)
+    seriesTitle     => { }, # (3.0)
+    sport           => { }, # (3.0)
     startingPage    => { },
     subsection1     => { },
@@ -701,13 +993,25 @@
     subsection3     => { },
     subsection4     => { },
+    subtitle        => { }, # (3.0)
+    supplementDisplayID => { }, # (3.0)
+    supplementStartingPage => { }, # (3.0)
+    supplementTitle => { }, # (3.0)
     teaser          => { List => 'Bag' },
     ticker          => { List => 'Bag' },
     timePeriod      => { },
-    url             => { Name => 'URL', List => 'Bag' },
+    url             => {
+        Name => 'URL',
+        List => 'Bag',
+        Struct => { # (becomes a structure in 3.0)
+            STRUCT_NAME => 'prismUrl',
+            NAMESPACE   => 'prism',
+            url         => { },
+            'a-platform'=> { },
+        },
+    },
+    uspsNumber      => { }, # (3.0)
     versionIdentifier => { },
     volume          => { },
     wordCount       => { Writable => 'integer' },
-    # new in PRISM 2.1
-    isbn            => { Name => 'ISBN' },
 # tags that existed in version 1.3
 #    category        => { %obsolete, List => 'Bag' },
@@ -738,11 +1042,13 @@
 );
 
-# PRISM Rights Language 2.1 schema (prl) (ref 2)
+# PRISM Rights Language namespace (prl) (ref 2)
 %Image::ExifTool::XMP::prl = (
     %xmpTableDefaults,
     GROUPS => { 0 => 'XMP', 1 => 'XMP-prl', 2 => 'Document' },
     NAMESPACE => 'prl',
+    AVOID => 1,
     NOTES => q{
-        PRISM Rights Language 2.1 schema tags.  (see
+        PRISM Rights Language 2.1 namespace tags.  These tags have been deprecated
+        since the release of the PRISM Usage Rights 3.0. (see
         L<http://www.prismstandard.org/>)
     },
@@ -752,15 +1058,22 @@
 );
 
-# PRISM Usage Rights 2.1 schema (prismusagerights) (ref 2)
+# PRISM Usage Rights namespace (prismusagerights) (ref 2)
 %Image::ExifTool::XMP::pur = (
     %xmpTableDefaults,
     GROUPS => { 0 => 'XMP', 1 => 'XMP-pur', 2 => 'Document' },
     NAMESPACE => 'pur',
+    AVOID => 1,
     NOTES => q{
-        Prism Usage Rights 2.1 schema tags.  (see L<http://www.prismstandard.org/>)
+        PRISM Usage Rights 3.0 namespace tags.  (see
+        L<http://www.prismstandard.org/>)
     },
     adultContentWarning => { List => 'Bag' },
     agreement           => { List => 'Bag' },
-    copyright           => { Writable => 'lang-alt', Groups => { 2 => 'Author' } },
+    copyright           => {
+        # (not clear in 3.0 spec, which lists only "bag Text", and called
+        #  "copyrightDate" instead of "copyright" the PRISM basic 3.0 spec)
+        Writable => 'lang-alt',
+        Groups => { 2 => 'Author' },
+    },
     creditLine          => { List => 'Bag' },
     embargoDate         => { List => 'Bag', %dateTimeInfo, Groups => { 2 => 'Time'} },
@@ -774,13 +1087,118 @@
     rightsAgent         => { },
     rightsOwner         => { },
-    usageFee            => { List => 'Bag' },
-);
-
-# DICOM schema properties (DICOM) (ref PH, written by CS3)
+    # usageFee            => { List => 'Bag' }, # (not in 3.0)
+);
+
+# PRISM Metadata for Images namespace (pmi) (ref 2)
+%Image::ExifTool::XMP::pmi = (
+    %xmpTableDefaults,
+    GROUPS => { 0 => 'XMP', 1 => 'XMP-pmi', 2 => 'Image' },
+    NAMESPACE => 'pmi',
+    AVOID => 1,
+    NOTES => q{
+        PRISM Metadata for Images 3.0 namespace tags.  (see
+        L<http://www.prismstandard.org/>)
+    },
+    color => {
+        PrintConv => {
+            bw => 'BW',
+            color => 'Color',
+            sepia => 'Sepia',
+            duotone => 'Duotone',
+            tritone => 'Tritone',
+            quadtone => 'Quadtone',
+        },
+    },
+    contactInfo     => { },
+    displayName     => { },
+    distributorProductID => { },
+    eventAlias      => { },
+    eventEnd        => { },
+    eventStart      => { },
+    eventSubtype    => { },
+    eventType       => { },
+    field           => { },
+    framing         => { },
+    location        => { },
+    make            => { },
+    manufacturer    => { },
+    model           => { },
+    modelYear       => { },
+    objectDescription=>{ },
+    objectSubtype   => { },
+    objectType      => { },
+    orientation => {
+        PrintConv => {
+            horizontal => 'Horizontal',
+            vertical => 'Vertical',
+        }
+    },
+    positionDescriptor => { },
+    productID       => { },
+    productIDType   => { },
+    season => {
+        PrintConv => {
+            spring => 'Spring',
+            summer => 'Summer',
+            fall => 'Fall',
+            winter => 'Winter',
+        },
+    },
+    sequenceName    => { },
+    sequenceNumber  => { },
+    sequenceTotalNumber => { },
+    setting         => { },
+    shootID         => { },
+    slideshowName   => { },
+    slideshowNumber => { Writable => 'integer' },
+    slideshowTotalNumber => { Writable => 'integer' },
+    viewpoint       => { },
+    visualTechnique => { },
+);
+
+# PRISM Recipe Metadata (prm) (ref 2)
+%Image::ExifTool::XMP::prm = (
+    %xmpTableDefaults,
+    GROUPS => { 0 => 'XMP', 1 => 'XMP-prm', 2 => 'Document' },
+    NAMESPACE => 'prm',
+    AVOID => 1,
+    NOTES => q{
+        PRISM Recipe Metadata 3.0 namespace tags.  (see
+        L<http://www.prismstandard.org/>)
+    },
+    cookingEquipment    => { },
+    cookingMethod       => { },
+    course              => { },
+    cuisine             => { },
+    dietaryNeeds        => { },
+    dishType            => { },
+    duration            => { },
+    ingredientExclusion => { },
+    mainIngredient      => { },
+    meal                => { },
+    recipeEndingPage    => { },
+    recipePageRange     => { },
+    recipeSource        => { },
+    recipeStartingPage  => { },
+    recipeTitle         => { },
+    servingSize         => { },
+    skillLevel          => { },
+    specialOccasion     => { },
+    yield               => { },
+);
+
+#------------------------------------------------------------------------------
+
+# DICOM namespace properties (DICOM) (ref PH, written by CS3)
 %Image::ExifTool::XMP::DICOM = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-DICOM', 2 => 'Image' },
     NAMESPACE => 'DICOM',
-    NOTES => 'DICOM schema tags.',
+    NOTES => q{
+        DICOM namespace tags.  These XMP tags allow some DICOM information to be
+        stored in files of other than DICOM format.  See the
+        L<DICOM Tags documentation|Image::ExifTool::TagNames/DICOM Tags> for a list
+        of tags available in DICOM-format files.
+    },
     # change some tag names to correspond with DICOM tags
     PatientName             => { },
@@ -804,42 +1222,121 @@
 );
 
-# PixelLive schema properties (PixelLive) (ref 3)
+# PixelLive namespace properties (PixelLive) (ref 3)
 %Image::ExifTool::XMP::PixelLive = (
     GROUPS => { 1 => 'XMP-PixelLive', 2 => 'Image' },
     NAMESPACE => 'PixelLive',
+    AVOID => 1,
     NOTES => q{
-        PixelLive schema 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.
     },
-    AUTHOR    => { Name => 'Author',   Avoid => 1, Groups => { 2 => 'Author' } },
-    COMMENTS  => { Name => 'Comments', Avoid => 1 },
-    COPYRIGHT => { Name => 'Copyright',Avoid => 1, Groups => { 2 => 'Author' } },
-    DATE      => { Name => 'Date',     Avoid => 1, Groups => { 2 => 'Time' } },
-    GENRE     => { Name => 'Genre',    Avoid => 1 },
-    TITLE     => { Name => 'Title',    Avoid => 1 },
-);
-
-# ACDSee schema (acdsee) (ref PH)
+    AUTHOR    => { Name => 'Author',    Groups => { 2 => 'Author' } },
+    COMMENTS  => { Name => 'Comments' },
+    COPYRIGHT => { Name => 'Copyright', Groups => { 2 => 'Author' } },
+    DATE      => { Name => 'Date',      Groups => { 2 => 'Time' } },
+    GENRE     => { Name => 'Genre' },
+    TITLE     => { Name => 'Title' },
+);
+
+# Extensis Portfolio tags (extensis) (ref 11)
+%Image::ExifTool::XMP::extensis = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-extensis', 2 => 'Image' },
+    NAMESPACE => 'extensis',
+    NOTES => 'Tags used by Extensis Portfolio.',
+    Approved     => { Writable => 'boolean' },
+    ApprovedBy   => { },
+    ClientName   => { },
+    JobName      => { },
+    JobStatus    => { },
+    RoutedTo     => { },
+    RoutingNotes => { },
+    WorkToDo     => { },
+);
+
+# IDimager structures (ref PH)
+my %sTagStruct;
+%sTagStruct = (
+    STRUCT_NAME => 'TagStructure',
+    NAMESPACE => 'ics',
+    LabelName => { },
+    Reference => { },
+    ParentReference => { },
+    SubLabels => { Struct => \%sTagStruct, List => 'Bag' },
+);
+my %sSubVersion = (
+    STRUCT_NAME => 'SubVersion',
+    NAMESPACE => 'ics',
+    VersRef => { },
+    FileName => { },
+);
+
+# IDimager namespace (ics) (ref PH)
+%Image::ExifTool::XMP::ics = (
+    %xmpTableDefaults,
+    GROUPS => { 0 => 'XMP', 1 => 'XMP-ics', 2 => 'Image' },
+    NAMESPACE => 'ics',
+    NOTES => q{
+        Tags used by IDimager.  Nested TagStructure structures are unrolled to an
+        arbitrary depth of 6 to avoid infinite recursion.
+    },
+    ImageRef => { },
+    TagStructure => { Struct => \%sTagStruct, List => 'Bag' },
+    TagStructureLabelName => { Name => 'LabelName1', Flat => 1 },
+    TagStructureReference => { Name => 'Reference1', Flat => 1 },
+    TagStructureSubLabels => { Name => 'SubLabels1', Flat => 1 },
+    TagStructureParentReference => { Name => 'ParentReference1', Flat => 1 },
+    TagStructureSubLabelsLabelName => { Name => 'LabelName2', Flat => 1 },
+    TagStructureSubLabelsReference => { Name => 'Reference2', Flat => 1 },
+    TagStructureSubLabelsSubLabels => { Name => 'SubLabels2', Flat => 1 },
+    TagStructureSubLabelsParentReference => { Name => 'ParentReference2', Flat => 1 },
+    TagStructureSubLabelsSubLabelsLabelName => { Name => 'LabelName3', Flat => 1 },
+    TagStructureSubLabelsSubLabelsReference => { Name => 'Reference3', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabels => { Name => 'SubLabels3', Flat => 1 },
+    TagStructureSubLabelsSubLabelsParentReference => { Name => 'ParentReference3', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName4', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference4', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsSubLabels => { Name => 'SubLabels4', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference4', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName5', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference5', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabels => { Name => 'SubLabels5', Flat => 1, NoSubStruct => 1 }, # break infinite recursion
+    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference5', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsLabelName => { Name => 'LabelName6', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsReference => { Name => 'Reference6', Flat => 1 },
+    TagStructureSubLabelsSubLabelsSubLabelsSubLabelsSubLabelsParentReference => { Name => 'ParentReference6', Flat => 1 },
+    SubVersions => { Struct => \%sSubVersion, List => 'Bag' },
+    SubVersionsVersRef => { Name => 'SubVersionReference', Flat => 1 },
+    SubVersionsFileName => { Name => 'SubVersionFileName', Flat => 1 },
+    TimeStamp  => { Avoid => 1, Groups => { 2 => 'Time' }, %dateTimeInfo },
+    AppVersion => { Avoid => 1 },
+);
+
+# ACDSee namespace (acdsee) (ref PH)
 %Image::ExifTool::XMP::acdsee = (
     %xmpTableDefaults,
     GROUPS => { 0 => 'XMP', 1 => 'XMP-acdsee', 2 => 'Image' },
     NAMESPACE => 'acdsee',
+    AVOID => 1,
     NOTES => q{
-        ACD Systems ACDSee schema tags.
+        ACD Systems ACDSee namespace tags.
 
         (A note to software developers: Re-inventing your own private tags instead
-        of using the equivalent tags in standard XMP schemas defeats one of the most
-        valuable features of metadata: interoperability.  Your applications mumble
-        to themselves instead of speaking out for the rest of the world to hear.)
-    },
-    author     => { Avoid => 1, Groups => { 2 => 'Author' } },
-    caption    => { Avoid => 1 },
-    categories => { Avoid => 1 },
-    datetime   => { Avoid => 1, Groups => { 2 => 'Time' }, %dateTimeInfo },
-    keywords   => { Avoid => 1, List => 'Bag' },
-    notes      => { Avoid => 1 },
-    rating     => { Avoid => 1, Writable => 'real' }, # integer?
-    tagged     => { Avoid => 1, Writable => 'boolean' },
+        of using the equivalent tags in standard XMP namespaces defeats one of the
+        most valuable features of metadata: interoperability.  Your applications
+        mumble to themselves instead of speaking out for the rest of the world to
+        hear.)
+    },
+    author     => { Groups => { 2 => 'Author' } },
+    caption    => { },
+    categories => { },
+    collections=> { },
+    datetime   => { Name => 'DateTime', Groups => { 2 => 'Time' }, %dateTimeInfo },
+    keywords   => { List => 'Bag' },
+    notes      => { },
+    rating     => { Writable => 'real' }, # integer?
+    tagged     => { Writable => 'boolean' },
+    rawrppused => { Writable => 'boolean' },
     rpp => {
         Name => 'RPP',
@@ -848,17 +1345,36 @@
         Binary => 1,
     },
-);
-
-# Picture Licensing Universal System schema properties (xmpPLUS)
+    dpp => {
+        Name => 'DPP',
+        Writable => 'lang-alt',
+        Notes => 'newer version of XML raw processing settings',
+        Binary => 1,
+    },
+    # more tags (ref forum6840)
+    FixtureIdentifier   => { },
+    EditStatus          => { },
+    ReleaseDate         => { },
+    ReleaseTime         => { },
+    OriginatingProgram  => { },
+    ObjectCycle         => { },
+    Snapshots           => { List => 'Bag', Binary => 1 },
+);
+
+# Picture Licensing Universal System namespace properties (xmpPLUS)
 %Image::ExifTool::XMP::xmpPLUS = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-xmpPLUS', 2 => 'Author' },
     NAMESPACE => 'xmpPLUS',
-    NOTES => 'XMP Picture Licensing Universal System (PLUS) schema tags.',
+    AVOID => 1,
+    NOTES => q{
+        XMP Picture Licensing Universal System (PLUS) tags as written by some older
+        Adobe applications.  See L<PLUS XMP Tags|Image::ExifTool::TagNames/PLUS XMP Tags>
+        for the current PLUS tags.
+    },
     CreditLineReq   => { Writable => 'boolean' },
     ReuseAllowed    => { Writable => 'boolean' },
 );
 
-# Creative Commons schema properties (cc) (ref 5)
+# Creative Commons namespace properties (cc) (ref 5)
 %Image::ExifTool::XMP::cc = (
     %xmpTableDefaults,
@@ -866,14 +1382,51 @@
     NAMESPACE => 'cc',
     NOTES => q{
-        Creative Commons schema tags.  (see
-        L<http://creativecommons.org/technology/xmp>)
-    },
-    license => { },
-    morePermissions => { },
+        Creative Commons namespace tags.  Note that the CC specification for XMP is
+        non-existent, so ExifTool must make some assumptions about the format of the
+        specific properties in XMP (see L<http://creativecommons.org/ns>).
+    },
+    # Work properties
+    license         => { Resource => 1 },
     attributionName => { },
-    attributionURL  => { },
-);
-
-# Description Explorer schema properties (dex) (ref 6)
+    attributionURL  => { Resource => 1 },
+    morePermissions => { Resource => 1 },
+    useGuidelines   => { Resource => 1 },
+    # License properties
+    permits => {
+        List => 'Bag',
+        Resource => 1,
+        PrintConv => {
+            'cc:Sharing' => 'Sharing',
+            'cc:DerivativeWorks' => 'Derivative Works',
+            'cc:Reproduction' => 'Reproduction',
+            'cc:Distribution' => 'Distribution',
+        },
+    },
+    requires => {
+        List => 'Bag',
+        Resource => 1,
+        PrintConv => {
+            'cc:Copyleft' => 'Copyleft',
+            'cc:LesserCopyleft' => 'Lesser Copyleft',
+            'cc:SourceCode' => 'Source Code',
+            'cc:ShareAlike' => 'Share Alike',
+            'cc:Notice' => 'Notice',
+            'cc:Attribution' => 'Attribution',
+        },
+    },
+    prohibits => {
+        List => 'Bag',
+        Resource => 1,
+        PrintConv => {
+            'cc:HighIncomeNationUse' => 'High Income Nation Use',
+            'cc:CommercialUse' => 'Commercial Use',
+        },
+    },
+    jurisdiction    => { Resource => 1 },
+    legalcode       => { Name => 'LegalCode', Resource => 1 },
+    deprecatedOn    => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+);
+
+# Description Explorer namespace properties (dex) (ref 6)
 %Image::ExifTool::XMP::dex = (
     %xmpTableDefaults,
@@ -881,5 +1434,5 @@
     NAMESPACE => 'dex',
     NOTES => q{
-        Description Explorer schema tags.  These tags are not very common.  The
+        Description Explorer namespace tags.  These tags are not very common.  The
         Source and Rating tags are avoided when writing due to name conflicts with
         other XMP tags.  (see L<http://www.optimasc.com/products/fileid/>)
@@ -910,11 +1463,14 @@
 );
 
-# iView MediaPro schema properties (mediapro) (ref PH)
+# iView MediaPro namespace properties (mediapro) (ref PH)
 %Image::ExifTool::XMP::MediaPro = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-mediapro', 2 => 'Image' },
     NAMESPACE => 'mediapro',
-    NOTES => 'iView MediaPro schema tags.',
-    Event       => { },
+    NOTES => 'iView MediaPro namespace tags.',
+    Event       => {
+        Avoid => 1,
+        Notes => 'avoided due to conflict with XMP-iptcExt:Event',
+    },
     Location    => {
         Avoid => 1,
@@ -928,21 +1484,43 @@
 );
 
-# DigiKam schema tags (ref PH)
+# Microsoft ExpressionMedia namespace properties (expressionmedia)
+# (ref https://exiftool.org/forum/index.php/topic,4235.0.html)
+%Image::ExifTool::XMP::ExpressionMedia = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-expressionmedia', 2 => 'Image' },
+    NAMESPACE => 'expressionmedia',
+    AVOID => 1,
+    NOTES => q{
+        Microsoft Expression Media namespace tags.  These tags are avoided when
+        writing due to name conflicts with tags in other schemas.
+    },
+    Event       => { },
+    Status      => { },
+    People      => { List => 'Bag' },
+    CatalogSets => { List => 'Bag' },
+);
+
+# DigiKam namespace tags (ref PH)
 %Image::ExifTool::XMP::digiKam = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-digiKam', 2 => 'Image' },
     NAMESPACE => 'digiKam',
-    NOTES => 'DigiKam schema tags.',
+    NOTES => 'DigiKam namespace tags.',
     CaptionsAuthorNames    => { Writable => 'lang-alt' },
-    CaptionsDateTimeStamps => { Writable => 'lang-alt' },
+    CaptionsDateTimeStamps => { Writable => 'lang-alt', Groups => { 2 => 'Time' } },
     TagsList               => { List => 'Seq' },
-);
-
-# SWF schema tags (ref PH)
+    ColorLabel             => { },
+    PickLabel              => { },
+    ImageHistory           => { Avoid => 1, Notes => 'different format from EXIF:ImageHistory' },
+    LensCorrectionSettings => { },
+    ImageUniqueID          => { Avoid => 1 },
+);
+
+# SWF namespace tags (ref PH)
 %Image::ExifTool::XMP::swf = (
     %xmpTableDefaults,
     GROUPS => { 1 => 'XMP-swf', 2 => 'Image' },
     NAMESPACE => 'swf',
-    NOTES => 'Adobe SWF schema tags.',
+    NOTES => 'Adobe SWF namespace tags.',
     type         => { Avoid => 1 },
     bgalpha      => { Name => 'BackgroundAlpha', Writable => 'integer' },
@@ -968,167 +1546,515 @@
 );
 
-my %sExtensions = (
-    STRUCT_NAME => 'Extensions',
-    NAMESPACE   => undef, # variable namespace
+# Apple adjustment settings (ref PH)
+%Image::ExifTool::XMP::aas = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-aas', 2 => 'Image' },
+    NAMESPACE => 'aas',
+    NOTES => 'Apple Adjustment Settings used by iPhone/iPad.',
+    CropX      => { Writable => 'integer', Avoid => 1 },
+    CropY      => { Writable => 'integer', Avoid => 1 },
+    CropW      => { Writable => 'integer', Avoid => 1 },
+    CropH      => { Writable => 'integer', Avoid => 1 },
+    AffineA    => { Writable => 'real' },
+    AffineB    => { Writable => 'real' },
+    AffineC    => { Writable => 'real' },
+    AffineD    => { Writable => 'real' },
+    AffineX    => { Writable => 'real' },
+    AffineY    => { Writable => 'real' },
+    Vibrance   => { Writable => 'real', Avoid => 1 },
+    Curve0x    => { Writable => 'real' },
+    Curve0y    => { Writable => 'real' },
+    Curve1x    => { Writable => 'real' },
+    Curve1y    => { Writable => 'real' },
+    Curve2x    => { Writable => 'real' },
+    Curve2y    => { Writable => 'real' },
+    Curve3x    => { Writable => 'real' },
+    Curve3y    => { Writable => 'real' },
+    Curve4x    => { Writable => 'real' },
+    Curve4y    => { Writable => 'real' },
+    Shadows    => { Writable => 'real', Avoid => 1 },
+    Highlights => { Writable => 'real', Avoid => 1 },
+    # the following from StarGeek
+    FaceBalanceOrigI    => { Writable => 'real' },
+    FaceBalanceOrigQ    => { Writable => 'real' },
+    FaceBalanceStrength => { Writable => 'real' },
+    FaceBalanceWarmth   => { Writable => 'real' },
+);
+
+# Adobe creatorAtom properties (ref PH)
+%Image::ExifTool::XMP::creatorAtom = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-creatorAtom', 2 => 'Image' },
+    NAMESPACE => 'creatorAtom',
+    NOTES => 'Adobe creatorAtom tags, written by After Effects.',
+    macAtom => {
+        Struct => {
+            STRUCT_NAME => 'MacAtom',
+            NAMESPACE   => 'creatorAtom',
+            applicationCode      => { },
+            invocationAppleEvent => { },
+            posixProjectPath     => { },
+        },
+    },
+    windowsAtom => {
+        Struct => {
+            STRUCT_NAME => 'WindowsAtom',
+            NAMESPACE   => 'creatorAtom',
+            extension       => { },
+            invocationFlags => { },
+            uncProjectPath  => { },
+        },
+    },
+    aeProjectLink => { # (After Effects Project Link)
+        Struct => {
+            STRUCT_NAME => 'AEProjectLink',
+            NAMESPACE   => 'creatorAtom',
+            renderTimeStamp         => { Writable => 'integer' },
+            compositionID           => { },
+            renderQueueItemID       => { },
+            renderOutputModuleIndex => { },
+            fullPath                => { },
+        },
+    },
+);
+
+# FastPictureViewer namespace properties (http://www.fastpictureviewer.com/help/#rtfcomments)
+%Image::ExifTool::XMP::fpv = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-fpv', 2 => 'Image' },
+    NAMESPACE => 'fpv',
     NOTES => q{
-        This structure may contain any top-level XMP tags, but none have been
-        pre-defined in ExifTool.  Without pre-defined flattened tag names,
-        RegionExtensions may be written only as a structure (ie.
-        C<{xmp-dc:creator=me,rating=5}>).  Fields for this structure are identified
-        using the standard ExifTool tag name (with optional leading group name,
-        and/or trailing language code, and/or trailing C<#> symbol to disable print
-        conversion).
-    },
-);
-my %sRegionStruct = (
-    STRUCT_NAME => 'RegionStruct',
-    NAMESPACE   => 'mwg-rs',
-    Area => { Struct => \%sArea },
-    Type => {
-        PrintConv => {
-            Face => 'Face',
-            Pet => 'Pet',
-            Focus => 'Focus',
-            BarCode => 'BarCode',
-        },
-    },
-    Name        => { },
-    Description => { },
-    FocusUsage  => {
-        PrintConv => {
-            EvaluatedUsed => 'Evaluated, Used',
-            EvaluatedNotUsed => 'Evaluated, Not Used',
-            NotEvaluatedNotUsed => 'Not Evaluated, Not Used',
-        },
-    },
-    BarCodeValue=> { },
-    Extensions  => { Struct => \%sExtensions },
-    seeAlso => { Namespace => 'rdfs', Resource => 1 },
-);
-my %sKeywordStruct4 = (
-    STRUCT_NAME => 'KeywordStruct4',
-    NAMESPACE   => 'mwg-kw',
-    Keyword   => { },
-    Applied   => { Writable => 'boolean' },
-);
-my %sKeywordStruct3 = (
-    STRUCT_NAME => 'KeywordStruct3',
-    NAMESPACE   => 'mwg-kw',
-    Keyword   => { },
-    Applied   => { Writable => 'boolean' },
-    Children  => { Struct => \%sKeywordStruct4, List => 'Bag' },
-);
-my %sKeywordStruct2 = (
-    STRUCT_NAME => 'KeywordStruct2',
-    NAMESPACE   => 'mwg-kw',
-    Keyword   => { },
-    Applied   => { Writable => 'boolean' },
-    Children  => { Struct => \%sKeywordStruct3, List => 'Bag' },
-);
-my %sKeywordStruct1 = (
-    STRUCT_NAME => 'KeywordStruct1',
-    NAMESPACE   => 'mwg-kw',
-    Keyword   => { },
-    Applied   => { Writable => 'boolean' },
-    Children  => { Struct => \%sKeywordStruct2, List => 'Bag' },
-);
-
-# MWG 2.0 region schema tags
-%Image::ExifTool::XMP::mwg_rs = (
-    %xmpTableDefaults,
-    GROUPS => { 1 => 'XMP-mwg-rs', 2 => 'Image' },
-    NAMESPACE => 'mwg-rs',
+        Fast Picture Viewer tags (see
+        L<http://www.fastpictureviewer.com/help/#rtfcomments>).
+    },
+    RichTextComment => { },
+);
+
+# Apple FaceInfo namespace properties (ref PH)
+%Image::ExifTool::XMP::apple_fi = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-apple-fi', 2 => 'Image' },
+    NAMESPACE => 'apple-fi',
     NOTES => q{
-        Image region metadata defined by the MWG 2.0 specification.  See
-        L<http://www.metadataworkinggroup.org/> for the official specification.
-    },
-    Regions => {
-        Name => 'RegionInfo',
-        Struct => {
-            STRUCT_NAME => 'RegionInfo',
-            NAMESPACE   => 'mwg-rs',
-            RegionList => { Struct => \%sRegionStruct, List => 'Bag' },
-            AppliedToDimensions => { Struct => \%sDimensions },
-        },
-    },
-    RegionsAppliedToDimensions  => { Flat => 1, Name => 'RegionAppliedToDimensions' },
-    RegionsAppliedToDimensionsW => { Flat => 1, Name => 'RegionAppliedToDimensionsW' },
-    RegionsAppliedToDimensionsH => { Flat => 1, Name => 'RegionAppliedToDimensionsH' },
-    RegionsAppliedToDimensionsUnit=>{Flat => 1, Name => 'RegionAppliedToDimensionsUnit' },
-    RegionsRegionList           => { Flat => 1, Name => 'RegionList' },
-    RegionsRegionListArea       => { Flat => 1, Name => 'RegionArea' },
-    RegionsRegionListAreaX      => { Flat => 1, Name => 'RegionAreaX' },
-    RegionsRegionListAreaY      => { Flat => 1, Name => 'RegionAreaY' },
-    RegionsRegionListAreaW      => { Flat => 1, Name => 'RegionAreaW' },
-    RegionsRegionListAreaH      => { Flat => 1, Name => 'RegionAreaH' },
-    RegionsRegionListAreaD      => { Flat => 1, Name => 'RegionAreaD' },
-    RegionsRegionListAreaUnit   => { Flat => 1, Name => 'RegionAreaUnit' },
-    RegionsRegionListType       => { Flat => 1, Name => 'RegionType' },
-    RegionsRegionListName       => { Flat => 1, Name => 'RegionName' },
-    RegionsRegionListDescription=> { Flat => 1, Name => 'RegionDescription' },
-    RegionsRegionListFocusUsage => { Flat => 1, Name => 'RegionFocusUsage' },
-    RegionsRegionListBarCodeValue=>{ Flat => 1, Name => 'RegionBarCodeValue' },
-    RegionsRegionListExtensions => { Flat => 1, Name => 'RegionExtensions' },
-    RegionsRegionListSeeAlso    => { Flat => 1, Name => 'RegionSeeAlso' },
-);
-
-# MWG 2.0 hierarchical keyword schema tags
-%Image::ExifTool::XMP::mwg_kw = (
-    %xmpTableDefaults,
-    GROUPS => { 1 => 'XMP-mwg-kw', 2 => 'Image' },
-    NAMESPACE => 'mwg-kw',
+        Face information tags written by the Apple iPhone 5 inside the mwg-rs
+        RegionExtensions.
+    },
+    Timestamp => {
+        Name => 'TimeStamp',
+        Writable => 'integer',
+        # (don't know how to convert this)
+    },
+    FaceID          => { Writable => 'integer' },
+    AngleInfoRoll   => { Writable => 'integer' },
+    AngleInfoYaw    => { Writable => 'integer' },
+    ConfidenceLevel => { Writable => 'integer' },
+);
+
+# Google audio namespace
+%Image::ExifTool::XMP::GAudio = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-GAudio', 2 => 'Audio' },
+    NAMESPACE => 'GAudio',
+    Data => {
+        Name => 'AudioData',
+        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
+        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
+    },
+    Mime => { Name => 'AudioMimeType' },
+);
+
+# Google image namespace
+%Image::ExifTool::XMP::GImage = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-GImage', 2 => 'Image' },
+    NAMESPACE => 'GImage',
+    Data => {
+        Name => 'ImageData',
+        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
+        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
+    },
+    Mime => { Name => 'ImageMimeType' },
+);
+
+# Google panorama namespace properties
+# (ref https://exiftool.org/forum/index.php/topic,4569.0.html)
+%Image::ExifTool::XMP::GPano = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-GPano', 2 => 'Image' },
+    NAMESPACE => 'GPano',
     NOTES => q{
-        Hierarchical keywords metadata defined by the MWG 2.0 specification. 
-        ExifTool unrolls keyword structures to an arbitrary depth of 4 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.
-    },
-    # arbitrarily define only the first 4 levels of the keyword hierarchy
-    Keywords => {
-        Name => 'KeywordInfo',
-        Struct => {
-            STRUCT_NAME => 'KeywordInfo',
-            NAMESPACE   => 'mwg-kw',
-            Hierarchy => { Struct => \%sKeywordStruct1, List => 'Bag' },
-        },
-    },
-    KeywordsHierarchy => { Name => 'HierarchicalKeywords', Flat => 1 },
-    KeywordsHierarchyKeyword  => { Name => 'HierarchicalKeywords1', Flat => 1 },
-    KeywordsHierarchyApplied  => { Name => 'HierarchicalKeywords1Applied', Flat => 1 },
-    KeywordsHierarchyChildren => { Name => 'HierarchicalKeywords1Children', Flat => 1 },
-    KeywordsHierarchyChildrenKeyword  => { Name => 'HierarchicalKeywords2', Flat => 1 },
-    KeywordsHierarchyChildrenApplied  => { Name => 'HierarchicalKeywords2Applied', Flat => 1 },
-    KeywordsHierarchyChildrenChildren => { Name => 'HierarchicalKeywords2Children', Flat => 1 },
-    KeywordsHierarchyChildrenChildrenKeyword  => { Name => 'HierarchicalKeywords3', Flat => 1 },
-    KeywordsHierarchyChildrenChildrenApplied  => { Name => 'HierarchicalKeywords3Applied', Flat => 1 },
-    KeywordsHierarchyChildrenChildrenChildren => { Name => 'HierarchicalKeywords3Children', Flat => 1 },
-    KeywordsHierarchyChildrenChildrenChildrenKeyword => { Name => 'HierarchicalKeywords4', Flat => 1 },
-    KeywordsHierarchyChildrenChildrenChildrenApplied => { Name => 'HierarchicalKeywords4Applied', Flat => 1 },
-);
-
-# MWG 2.0 collections schema tags
-%Image::ExifTool::XMP::mwg_coll = (
-    %xmpTableDefaults,
-    GROUPS => { 1 => 'XMP-mwg-coll', 2 => 'Image' },
-    NAMESPACE => 'mwg-coll',
+        Panorama tags written by Google Photosphere. See
+        L<https://developers.google.com/panorama/metadata/> for the specification.
+    },
+    UsePanoramaViewer               => { Writable => 'boolean' },
+    CaptureSoftware                 => { },
+    StitchingSoftware               => { },
+    ProjectionType                  => { },
+    PoseHeadingDegrees              => { Writable => 'real' },
+    PosePitchDegrees                => { Writable => 'real' },
+    PoseRollDegrees                 => { Writable => 'real' },
+    InitialViewHeadingDegrees       => { Writable => 'real' },
+    InitialViewPitchDegrees         => { Writable => 'real' },
+    InitialViewRollDegrees          => { Writable => 'real' },
+    InitialHorizontalFOVDegrees     => { Writable => 'real' },
+    InitialVerticalFOVDegrees       => { Writable => 'real' },
+    FirstPhotoDate                  => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+    LastPhotoDate                   => { %dateTimeInfo, Groups => { 2 => 'Time' } },
+    SourcePhotosCount               => { Writable => 'integer' },
+    ExposureLockUsed                => { Writable => 'boolean' },
+    CroppedAreaImageWidthPixels     => { Writable => 'real' },
+    CroppedAreaImageHeightPixels    => { Writable => 'real' },
+    FullPanoWidthPixels             => { Writable => 'real' },
+    FullPanoHeightPixels            => { Writable => 'real' },
+    CroppedAreaLeftPixels           => { Writable => 'real' },
+    CroppedAreaTopPixels            => { Writable => 'real' },
+    InitialCameraDolly              => { Writable => 'real' },
+    # (the following have been observed, but are not in the specification)
+    LargestValidInteriorRectLeft    => { Writable => 'real' },
+    LargestValidInteriorRectTop     => { Writable => 'real' },
+    LargestValidInteriorRectWidth   => { Writable => 'real' },
+    LargestValidInteriorRectHeight  => { Writable => 'real' },
+);
+
+# Google Spherical Images namespace (ref https://github.com/google/spatial-media/blob/master/docs/spherical-video-rfc.md)
+%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{
-        Collections metadata defined by the MWG 2.0 specification.  See
-        L<http://www.metadataworkinggroup.org/> for the official specification.
-    },
-    Collections => {
-        List => 'Bag',
-        Struct => {
-            STRUCT_NAME => 'CollectionInfo',
-            NAMESPACE   => 'mwg-coll',
-            CollectionName => { },
-            CollectionURI  => { },
-        },
-    },
-    CollectionsCollectionName => { Name => 'CollectionName', Flat => 1 },
-    CollectionsCollectionURI  => { Name => 'CollectionURI',  Flat => 1 },
-);
-
-# SVG schema properties (ref 9)
+        Not actually XMP.  These RDF/XML tags are used in Google spherical MP4
+        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.
+    },
+    # (avoid due to conflicts with XMP-GPano tags)
+    Spherical                   => { Writable => 'boolean' },
+    Stitched                    => { Writable => 'boolean' },
+    StitchingSoftware           => { },
+    ProjectionType              => { },
+    StereoMode                  => { },
+    SourceCount                 => { Writable => 'integer' },
+    InitialViewHeadingDegrees   => { Writable => 'real' },
+    InitialViewPitchDegrees     => { Writable => 'real' },
+    InitialViewRollDegrees      => { Writable => 'real' },
+    Timestamp                   => {
+        Name => 'TimeStamp',
+        Groups => { 2 => 'Time' },
+        Writable => 'integer',
+        Shift => 'Time',
+        ValueConv => 'ConvertUnixTime($val)', #(NC)
+        ValueConvInv => 'GetUnixTime($val)',
+        PrintConv => '$self->ConvertDateTime($val)',
+        PrintConvInv => '$self->InverseDateTime($val)',
+    },
+    FullPanoWidthPixels         => { Writable => 'integer' },
+    FullPanoHeightPixels        => { Writable => 'integer' },
+    CroppedAreaImageWidthPixels => { Writable => 'integer' },
+    CroppedAreaImageHeightPixels=> { Writable => 'integer' },
+    CroppedAreaLeftPixels       => { Writable => 'integer' },
+    CroppedAreaTopPixels        => { Writable => 'integer' },
+);
+
+# 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',
+    AVOID       => 1, # (too many potential tag name conflicts)
+    NOTES       => q{
+        Google depthmap information. See
+        L<https://developers.google.com/depthmap-metadata/> for the specification.
+    },
+    WRITABLE    => 'string', # (default to string-type tags)
+    PRIORITY    => 0,
+    Format => {
+        PrintConv => {
+            RangeInverse => 'RangeInverse',
+            RangeLinear  => 'RangeLinear',
+        },
+    },
+    Near        => { Writable => 'real' },
+    Far         => { Writable => 'real' },
+    Mime        => { },
+    Data => {
+        Name => 'DepthImage',
+        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
+        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
+    },
+    Units       => { },
+    MeasureType => {
+        PrintConv => {
+            OpticalAxis => 'OpticalAxis',
+            OpticalRay  => 'OpticalRay',
+        },
+    },
+    ConfidenceMime  => { },
+    Confidence => {
+        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
+        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
+    },
+    Manufacturer=> { },
+    Model       => { },
+    Software    => { },
+    ImageWidth  => { Writable => 'real' },
+    ImageHeight => { Writable => 'real' },
+);
+
+# Google focus namespace
+%Image::ExifTool::XMP::GFocus = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-GFocus', 2 => 'Image' },
+    NAMESPACE => 'GFocus',
+    NOTES => 'Focus information found in Google depthmap images.',
+    BlurAtInfinity  => { Writable => 'real' },
+    FocalDistance   => { Writable => 'real' },
+    FocalPointX     => { Writable => 'real' },
+    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)',
+    },
+    MicroVideo          => { Writable => 'integer' },
+    MicroVideoVersion   => { Writable => 'integer' },
+    MicroVideoOffset    => { Writable => 'integer' },
+    MicroVideoPresentationTimestampUs => { Writable => 'integer' },
+);
+
+# 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,
+    GROUPS => { 1 => 'XMP-getty', 2 => 'Image' },
+    NAMESPACE => 'GettyImagesGIFT',
+    NOTES => q{
+        The actual Getty Images namespace prefix is "GettyImagesGIFT", which is the
+        prefix recorded in the file, but ExifTool shortens this for the family 1
+        group name.
+    },
+    Personality         => { List => 'Bag' },
+    OriginalFilename    => { Name => 'OriginalFileName' },
+    ParentMEID          => { },
+    # the following from StarGeek
+    AssetID             => { },
+    CallForImage        => { },
+    CameraFilename      => { },
+    CameraMakeModel     => { Avoid => 1 },
+    Composition         => { },
+    CameraSerialNumber  => { Avoid => 1 },
+    ExclusiveCoverage   => { },
+    GIFTFtpPriority     => { },
+    ImageRank           => { },
+    MediaEventIdDate    => { },
+    OriginalCreateDateTime => { %dateTimeInfo, Groups => { 2 => 'Time' }, Avoid => 1 },
+    ParentMediaEventID  => { },
+    PrimaryFTP          => { List => 'Bag' },
+    RoutingDestinations => { List => 'Bag' },
+    RoutingExclusions   => { List => 'Bag' },
+    SecondaryFTP        => { List => 'Bag' },
+    TimeShot            => { },
+);
+
+# RED smartphone images (ref PH)
+%Image::ExifTool::XMP::LImage = (
+    %xmpTableDefaults,
+    GROUPS => { 1 => 'XMP-LImage', 2 => 'Image' },
+    NAMESPACE => 'LImage',
+    NOTES => 'Tags written by RED smartphones.',
+    MajorVersion => { },
+    MinorVersion => { },
+    RightAlbedo => {
+        Notes => 'Right stereoscopic image',
+        Groups => { 2 => 'Preview' },
+        ValueConv => 'Image::ExifTool::XMP::DecodeBase64($val)',
+        ValueConvInv => 'Image::ExifTool::XMP::EncodeBase64($val)',
+    },
+);
+
+# SVG namespace properties (ref 9)
 %Image::ExifTool::XMP::SVG = (
     GROUPS => { 0 => 'SVG', 1 => 'SVG', 2 => 'Image' },
@@ -1145,6 +2071,12 @@
     id         => 'ID',
     metadataId => 'MetadataID',
-    width      => 'ImageWidth',
-    height     => 'ImageHeight',
+    width      => {
+        Name => 'ImageWidth',
+        ValueConv => '$val =~ s/px$//; $val',
+    },
+    height     => {
+        Name => 'ImageHeight',
+        ValueConv => '$val =~ s/px$//; $val',
+    },
 );
 
@@ -1156,13 +2088,17 @@
 );
 
-# set "Avoid" flag for all PRISM tags
-my ($table, $key);
-foreach $table (
-    \%Image::ExifTool::XMP::prism,
-    \%Image::ExifTool::XMP::prl,
-    \%Image::ExifTool::XMP::pur)
+#------------------------------------------------------------------------------
+# Generate crd tags
+# Inputs: 0) tag table ref
+sub Init_crd($)
 {
-    foreach $key (TagTableKeys($table)) {
-        $table->{$key}->{Avoid} = 1;
+    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};
     }
 }
@@ -1175,5 +2111,5 @@
 =head1 NAME
 
-Image::ExifTool::XMP2.pl - Additional XMP schema definitions
+Image::ExifTool::XMP2.pl - Additional XMP namespace definitions
 
 =head1 SYNOPSIS
@@ -1183,9 +2119,9 @@
 =head1 DESCRIPTION
 
-This file contains definitions for less common XMP schemas.
+This file contains definitions for less common XMP namespaces.
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
@@ -1202,4 +2138,6 @@
 =item L<http://www.portfoliofaq.com/pfaq/v7mappings.htm>
 
+=item L<http://www.iptc.org/IPTC4XMP/>
+
 =item L<http://creativecommons.org/technology/xmp>
 
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMPStruct.pl
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMPStruct.pl	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/XMPStruct.pl	(revision 34921)
@@ -10,5 +10,5 @@
 
 use strict;
-use vars qw(%specialStruct $xlatNamespace);
+use vars qw(%specialStruct %stdXlatNS);
 
 use Image::ExifTool qw(:Utils);
@@ -26,5 +26,5 @@
 # Inputs: 0) HASH ref, ARRAY ref, or SCALAR, 1) closing bracket (or undef)
 # Returns: serialized structure string
-# ie) "{field=text with {braces|}|, and a comma, field2=val2,field3={field4=[a,b]}}"
+# eg) "{field=text with {braces|}|, and a comma, field2=val2,field3={field4=[a,b]}}"
 sub SerializeStruct($;$)
 {
@@ -84,5 +84,5 @@
                 $part =~ s/[\x0d\x0a].*//s;
                 $part = substr($part,0,27) . '...' if length($part) > 30;
-                $warn = "Invalid structure field at '$part'";
+                $warn = "Invalid structure field at '${part}'";
             } else {
                 $warn = 'Missing closing brace for structure';
@@ -108,5 +108,6 @@
         $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;
@@ -177,7 +178,7 @@
 sub CheckStruct($$$)
 {
-    my ($exifTool, $struct, $strTable) = @_;
-
-    my $strName = $$strTable{STRUCT_NAME} || RegisterNamespace($strTable);
+    my ($et, $struct, $strTable) = @_;
+
+    my $strName = $$strTable{STRUCT_NAME} || ('XMP ' . RegisterNamespace($strTable));
     ref $struct eq 'HASH' or return wantarray ? (undef, "Expecting $strName structure") : undef;
 
@@ -197,5 +198,5 @@
         }
         until (ref $fieldInfo eq 'HASH') {
-            # generate wildcard fields on the fly (ie. mwg-rs:Extensions)
+            # generate wildcard fields on the fly (eg. mwg-rs:Extensions)
             unless ($$strTable{NAMESPACE}) {
                 my ($grp, $tg, $langCode);
@@ -212,5 +213,5 @@
                 # find best matching tag
                 foreach $ti (@matches) {
-                    my @grps = $exifTool->GetGroup($ti);
+                    my @grps = $et->GetGroup($ti);
                     next unless $grps[0] eq 'XMP';
                     next if $grp and $grp ne lc $grps[1];
@@ -224,5 +225,5 @@
                     $g1 = $grps[1];
                 }
-                $tagInfo or $warn =  "'$tag' is not a writable XMP tag", next Key;
+                $tagInfo or $warn =  "'${tag}' is not a writable XMP tag", next Key;
                 GetPropertyPath($tagInfo);  # make sure property path is generated for this tag
                 $tag = $$tagInfo{Name};
@@ -233,5 +234,5 @@
                 $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,
                 };
@@ -242,5 +243,5 @@
                 last; # write this dynamically-generated field
             }
-            # generate lang-alt fields on the fly (ie. Iptc4xmpExt:AOTitle)
+            # generate lang-alt fields on the fly (eg. Iptc4xmpExt:AOTitle)
             my ($tg, $langCode) = GetLangCode($tag);
             if (defined $langCode) {
@@ -265,5 +266,5 @@
                 }
             }
-            $warn = "'$tag' is not a field of $strName";
+            $warn = "'${tag}' is not a field of $strName";
             next Key;
         }
@@ -271,5 +272,5 @@
             $$fieldInfo{Struct} or $warn = "$tag is not a structure in $strName", next Key;
             # recursively check this structure
-            ($val, $err) = CheckStruct($exifTool, $$struct{$key}, $$fieldInfo{Struct});
+            ($val, $err) = CheckStruct($et, $$struct{$key}, $$fieldInfo{Struct});
             $err and $warn = $err, next Key;
             $copy{$tag} = $val;
@@ -282,13 +283,19 @@
                 if (not ref $item) {
                     $item = '' unless defined $item; # use empty string for missing items
-                    $$fieldInfo{Struct} and $warn = "$tag items are not valid structures", next Key;
-                    $exifTool->Sanitize(\$item);
-                    ($copy[$i],$err) = $exifTool->ConvInv($item,$fieldInfo,$tag,$strName,$type);
-                    $err and $warn = $err, next Key;
-                    $err = CheckXMP($exifTool, $fieldInfo, \$copy[$i]);
-                    $err and $warn = "$err in $strName $tag", next Key;
+                    if ($$fieldInfo{Struct}) {
+                        # (allow empty structures)
+                        $item =~ /^\s*$/ or $warn = "$tag items are not valid structures", next Key;
+                        $copy[$i] = { }; # create hash for empty structure
+                    } else {
+                        $et->Sanitize(\$item);
+                        ($copy[$i],$err) = $et->ConvInv($item,$fieldInfo,$tag,$strName,$type,'');
+                        $copy[$i] = '' unless defined $copy[$i];    # avoid undefined item
+                        $err and $warn = $err, next Key;
+                        $err = CheckXMP($et, $fieldInfo, \$copy[$i]);
+                        $err and $warn = "$err in $strName $tag", next Key;
+                    }
                 } elsif (ref $item eq 'HASH') {
                     $$fieldInfo{Struct} or $warn = "$tag is not a structure in $strName", next Key;
-                    ($copy[$i], $err) = CheckStruct($exifTool, $item, $$fieldInfo{Struct});
+                    ($copy[$i], $err) = CheckStruct($et, $item, $$fieldInfo{Struct});
                     $err and $warn = $err, next Key;
                 } else {
@@ -302,8 +309,9 @@
             $warn = "Improperly formed structure in $strName $tag";
         } else {
-            $exifTool->Sanitize(\$$struct{$key});
-            ($val,$err) = $exifTool->ConvInv($$struct{$key},$fieldInfo,$tag,$strName,$type);
+            $et->Sanitize(\$$struct{$key});
+            ($val,$err) = $et->ConvInv($$struct{$key},$fieldInfo,$tag,$strName,$type,'');
             $err and $warn = $err, next Key;
-            $err = CheckXMP($exifTool, $fieldInfo, \$val);
+            next Key unless defined $val;   # check for undefined
+            $err = CheckXMP($et, $fieldInfo, \$val);
             $err and $warn = "$err in $strName $tag", next Key;
             # turn this into a list if necessary
@@ -311,10 +319,10 @@
         }
     }
-    if (%copy) {
+    if (%copy or not $warn) {
         $rtnVal = \%copy;
         undef $err;
-        $$exifTool{CHECK_WARN} = $warn if $warn;
+        $$et{CHECK_WARN} = $warn if $warn;
     } else {
-        $err = $warn || 'Structure has no fields';
+        $err = $warn;
     }
     return wantarray ? ($rtnVal, $err) : $rtnVal;
@@ -326,15 +334,16 @@
 #         3) new value hash ref, 4) reference to change counter
 # Returns: 0) delete flag, 1) list index of deleted structure if adding to list
+#          2) flag set if structure existed
 # Notes: updates path to new base path for structure to be added
 sub DeleteStruct($$$$$)
 {
-    my ($exifTool, $capture, $pathPt, $nvHash, $changed) = @_;
-    my ($deleted, $added, $p, $pp, $val, $delPath);
+    my ($et, $capture, $pathPt, $nvHash, $changed) = @_;
+    my ($deleted, $added, $existed, $p, $pp, $val, $delPath);
     my (@structPaths, @matchingPaths, @delPaths);
 
     # find all existing elements belonging to this structure
     ($pp = $$pathPt) =~ s/ \d+/ \\d\+/g;
-    @structPaths = sort grep(/^$pp\//, keys %$capture);
-
+    @structPaths = sort grep(/^$pp(\/|$)/, keys %$capture);
+    $existed = 1 if @structPaths;
     # delete only structures with matching fields if necessary
     if ($$nvHash{DelValue}) {
@@ -362,5 +371,5 @@
                             next unless $$a2{'xml:lang'} and $$a2{'xml:lang'} eq $$attr{'xml:lang'};
                         }
-                        if ($$capture{$p2}[0] eq $cap{$p}[0]) {
+                        if ($$capture{$p2} and $$capture{$p2}[0] eq $cap{$p}[0]) {
                             # ($1 contains root path for this structure)
                             $match{$1} = ($match{$1} || 0) + 1;
@@ -387,36 +396,44 @@
     }
     if (@delPaths) {
-        my $verbose = $exifTool->Options('Verbose');
+        my $verbose = $et->Options('Verbose');
         @delPaths = sort @delPaths if $verbose > 1;
         foreach $p (@delPaths) {
-            $exifTool->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;
         }
-        $delPath or warn("Internal error 1 in DeleteStruct\n"), return(undef,undef);
+        $delPath or warn("Internal error 1 in DeleteStruct\n"), return(undef,undef,$existed);
         $$pathPt = $delPath;    # return path of first element deleted
-    } else {
-        my $tagInfo = $$nvHash{TagInfo};
-        if ($$tagInfo{List}) {
-            # NOTE: we don't yet properly handle lang-alt elements!!!!
-            if (@structPaths) {
-                $structPaths[-1] =~ /^($pp)/ or warn("Internal error 2 in DeleteStruct\n"), return(undef,undef);
-                my $path = $1;
-                # (match last index to put in same lang-alt list for Bag of lang-alt items)
-                $path =~ m/.* (\d+)/g or warn("Internal error 3 in DeleteStruct\n"), return(undef,undef);
-                $added = $1;
-                # add after last item in list
-                my $len = length $added;
-                my $pos = pos($path) - $len;
-                my $nxt = substr($added, 1) + 1;
-                substr($path, $pos, $len) = length($nxt) . $nxt;
-                $$pathPt = $path;
-            } else {
-                $added = '10';
-            }
-        }
-    }
-    return($deleted, $added);
+    } elsif ($$nvHash{TagInfo}{List}) {
+        # NOTE: we don't yet properly handle lang-alt elements!!!!
+        if (@structPaths) {
+            $structPaths[-1] =~ /^($pp)/ or warn("Internal error 2 in DeleteStruct\n"), return(undef,undef,$existed);
+            my $path = $1;
+            # delete any improperly formatted xmp
+            if ($$capture{$path}) {
+                my $cap = $$capture{$path};
+                # an error unless this was an empty structure
+                $et->Error("Improperly structured XMP ($path)",1) if ref $cap ne 'ARRAY' or $$cap[0];
+                delete $$capture{$path};
+            }
+            # (match last index to put in same lang-alt list for Bag of lang-alt items)
+            $path =~ m/.* (\d+)/g or warn("Internal error 3 in DeleteStruct\n"), return(undef,undef,$existed);
+            $added = $1;
+            # add after last item in list
+            my $len = length $added;
+            my $pos = pos($path) - $len;
+            my $nxt = substr($added, 1) + 1;
+            substr($path, $pos, $len) = length($nxt) . $nxt;
+            $$pathPt = $path;
+        } else {
+            $added = '10';
+        }
+    }
+    return($deleted, $added, $existed);
 }
 
@@ -427,5 +444,5 @@
 sub AddNewTag($$$$$$)
 {
-    my ($exifTool, $tagInfo, $capture, $path, $valPtr, $langIdx) = @_;
+    my ($et, $tagInfo, $capture, $path, $valPtr, $langIdx) = @_;
     my $val = EscapeXML($$valPtr);
     my %attrs;
@@ -449,6 +466,8 @@
     $$capture{$path} = [ $val, \%attrs ];
     # print verbose message
-    if ($exifTool and $exifTool->Options('Verbose') > 1) {
-        $exifTool->VerboseValue("+ XMP-$path", $val);
+    if ($et and $et->Options('Verbose') > 1) {
+        my $p = $path;
+        $p =~ s/^(\w+)/$stdXlatNS{$1} || $1/e;
+        $et->VerboseValue("+ XMP-$p", $val);
     }
 }
@@ -463,6 +482,6 @@
 sub AddNewStruct($$$$$$)
 {
-    my ($exifTool, $tagInfo, $capture, $basePath, $struct, $strTable) = @_;
-    my $verbose = $exifTool ? $exifTool->Options('Verbose') : 0;
+    my ($et, $tagInfo, $capture, $basePath, $struct, $strTable) = @_;
+    my $verbose = $et ? $et->Options('Verbose') : 0;
     my ($tag, %langIdx);
 
@@ -470,6 +489,14 @@
     my $changed = 0;
 
+    # add dummy field to allow empty structures (name starts with '~' so it will come
+    # after all valid structure fields, which is necessary when serializing the XMP later)
+    %$struct or $$struct{'~dummy~'} = '';
+
     foreach $tag (sort keys %$struct) {
-        my $fieldInfo = $$strTable{$tag} or next;
+        my $fieldInfo = $$strTable{$tag};
+        unless ($fieldInfo) {
+            next unless $tag eq '~dummy~'; # check for dummy field
+            $fieldInfo = { }; # create dummy field info for dummy structure
+        }
         my $val = $$struct{$tag};
         my $propPath = $$fieldInfo{PropertyPath};
@@ -484,18 +511,19 @@
             $$fieldInfo{PropertyPath} = $propPath;  # save for next time
         }
-        my $path = $basePath . '/' . ConformPathToNamespace($exifTool, $propPath);
+        my $path = $basePath . '/' . ConformPathToNamespace($et, $propPath);
         my $addedTag;
         if (ref $val eq 'HASH') {
             my $subStruct = $$fieldInfo{Struct} or next;
-            $changed += AddNewStruct($exifTool, $tagInfo, $capture, $path, $val, $subStruct);
+            $changed += AddNewStruct($et, $tagInfo, $capture, $path, $val, $subStruct);
         } elsif (ref $val eq 'ARRAY') {
             next unless $$fieldInfo{List};
             my $i = 0;
             my ($item, $p);
+            my $level = scalar(() = ($propPath =~ / \d+/g));
             # loop through all list items (note: can't yet write multi-dimensional lists)
             foreach $item (@{$val}) {
                 if ($i) {
                     # update first index in field property (may be list of lang-alt lists)
-                    $p = ConformPathToNamespace($exifTool, $propPath);
+                    $p = ConformPathToNamespace($et, $propPath);
                     my $idx = length($i) . $i;
                     $p =~ s/ \d+/ $idx/;
@@ -506,7 +534,8 @@
                 if (ref $item eq 'HASH') {
                     my $subStruct = $$fieldInfo{Struct} or next;
-                    AddNewStruct($exifTool, $tagInfo, $capture, $p, $item, $subStruct) or next;
-                } elsif (length $item) { # don't write empty items in list
-                    AddNewTag($exifTool, $fieldInfo, $capture, $p, \$item, \%langIdx);
+                    AddNewStruct($et, $tagInfo, $capture, $p, $item, $subStruct) or next;
+                # don't write empty items in upper-level list
+                } elsif (length $item or (defined $item and $level == 1)) {
+                    AddNewTag($et, $fieldInfo, $capture, $p, \$item, \%langIdx);
                     $addedTag = 1;
                 }
@@ -515,5 +544,5 @@
             }
         } else {
-            AddNewTag($exifTool, $fieldInfo, $capture, $path, \$val, \%langIdx);
+            AddNewTag($et, $fieldInfo, $capture, $path, \$val, \%langIdx);
             $addedTag = 1;
             ++$changed;
@@ -523,13 +552,17 @@
         # flattened tag inside a variable-namespace structure
         if ($addedTag and $$fieldInfo{StructType} and $$fieldInfo{Table}) {
-            AddStructType($exifTool, $$fieldInfo{Table}, $capture, $propPath, $basePath);
+            AddStructType($et, $$fieldInfo{Table}, $capture, $propPath, $basePath);
         }
     }
     # add 'rdf:type' property if necessary
     if ($$strTable{TYPE} and $changed) {
-        my $path = $basePath . '/' . ConformPathToNamespace($exifTool, "rdf:type");
+        my $path = $basePath . '/' . ConformPathToNamespace($et, "rdf:type");
         unless ($$capture{$path}) {
             $$capture{$path} = [ '', { 'rdf:resource' => $$strTable{TYPE} } ];
-            $exifTool->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});
+            }
         }
     }
@@ -545,5 +578,5 @@
 sub ConvertStruct($$$$;$)
 {
-    my ($exifTool, $tagInfo, $value, $type, $parentID) = @_;
+    my ($et, $tagInfo, $value, $type, $parentID) = @_;
     if (ref $value eq 'HASH') {
         my (%struct, $key);
@@ -563,7 +596,7 @@
             my $v = $$value{$key};
             if (ref $v) {
-                $v = ConvertStruct($exifTool, $flatInfo, $v, $type, $tagID);
+                $v = ConvertStruct($et, $flatInfo, $v, $type, $tagID);
             } else {
-                $v = $exifTool->GetValue($flatInfo, $type, $v);
+                $v = $et->GetValue($flatInfo, $type, $v);
             }
             $struct{$key} = $v if defined $v;  # save the converted value
@@ -571,12 +604,21 @@
         return \%struct;
     } elsif (ref $value eq 'ARRAY') {
-        my (@list, $val);
-        foreach $val (@$value) {    
-            my $v = ConvertStruct($exifTool, $tagInfo, $val, $type, $parentID);
-            push @list, $v if defined $v;
-        }
-        return \@list;
+        if (defined $$et{OPTIONS}{ListItem}) {
+            my $li = $$et{OPTIONS}{ListItem};
+            return undef unless defined $$value[$li];
+            undef $$et{OPTIONS}{ListItem};      # only do top-level list
+            my $val = ConvertStruct($et, $tagInfo, $$value[$li], $type, $parentID);
+            $$et{OPTIONS}{ListItem} = $li;
+            return $val;
+        } else {
+            my (@list, $val);
+            foreach $val (@$value) {
+                my $v = ConvertStruct($et, $tagInfo, $val, $type, $parentID);
+                push @list, $v if defined $v;
+            }
+            return \@list;
+        }
     } else {
-        return $exifTool->GetValue($tagInfo, $type, $value);
+        return $et->GetValue($tagInfo, $type, $value);
     }
 }
@@ -584,17 +626,20 @@
 #------------------------------------------------------------------------------
 # Restore XMP structures in extracted information
-# Inputs: 0) ExifTool object ref
+# Inputs: 0) ExifTool object ref, 1) flag to keep original flattened tags
 # Notes: also restores lists (including multi-dimensional)
-sub RestoreStruct($)
+sub RestoreStruct($;$)
 {
     local $_;
-    my $exifTool = shift;
-    my ($key, %structs, %var, %lists, $si, %listKeys);
-    my $ex = $$exifTool{TAG_EXTRA};
-    foreach $key (keys %{$$exifTool{TAG_INFO}}) {
+    my ($et, $keepFlat) = @_;
+    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;
-        my ($err, $i);
         my $structProps = $$ex{$key}{Struct} or next;
-        my $tagInfo = $$exifTool{TAG_INFO}{$key};   # tagInfo for flattened tag
+        delete $$ex{$key}{Struct}; # (don't re-use)
+        my $tagInfo = $$et{TAG_INFO}{$key};   # tagInfo for flattened tag
         my $table = $$tagInfo{Table};
         my $prop = shift @$structProps;
@@ -608,5 +653,5 @@
                 # (or for something like this -- what should we do here?:
                 # <meta:user-defined meta:name="License">test</meta:user-defined>)
-                $exifTool->Warn("$$strInfo{Name} is not a structure!");
+                $et->Warn("$$strInfo{Name} is not a structure!") unless $$et{NO_STRUCT_WARN};
                 next;
             }
@@ -615,8 +660,10 @@
             my $g1 = $$table{GROUPS}{0} || 'XMP';
             my $name = $tag;
+            # tag keys will have a group 1 prefix when coming from import of XML from -X option
             if ($tag =~ /(.+):(.+)/) {
                 my $ns;
                 ($ns, $name) = ($1, $2);
-                $ns = $$xlatNamespace{$ns} if $$xlatNamespace{$ns};
+                $ns =~ s/^XMP-//; # remove leading "XMP-" if it exists because we add it later
+                $ns = $stdXlatNS{$ns} if $stdXlatNS{$ns};
                 $g1 .= "-$ns";
             }
@@ -629,5 +676,5 @@
             if (@$structProps) {
                 # this is a structure
-                $$strInfo{Struct} = { STRUCT_NAME => 'Unknown' } if @$structProps;
+                $$strInfo{Struct} = { STRUCT_NAME => 'XMP Unknown' } if @$structProps;
             } elsif ($$tagInfo{LangCode}) {
                 # this is lang-alt list
@@ -635,5 +682,5 @@
                 $$strInfo{LangCode} = $$tagInfo{LangCode};
             }
-            Image::ExifTool::AddTagToTable($table, $tag, $strInfo);
+            AddTagToTable($table, $tag, $strInfo);
         }
         # use strInfo ref for base key to avoid collisions
@@ -645,4 +692,5 @@
         # walk through the stored structure property information
         # to rebuild this structure
+        my ($err, $i);
         for (;;) {
             my $index = $$prop[1];
@@ -688,5 +736,5 @@
                 } else {
                     $lists{$struct} = $struct;
-                    $$struct[$index] = $$exifTool{VALUE}{$key};
+                    $$struct[$index] = $$valueHash{$key};
                     last;
                 }
@@ -698,5 +746,5 @@
                     $struct = $$struct{$tag} = { };
                 } else {
-                    $$struct{$tag} = $$exifTool{VALUE}{$key};
+                    $$struct{$tag} = $$valueHash{$key};
                     last;
                 }
@@ -709,5 +757,5 @@
                 # the corresponding group1 name to the tag ID.
                 my ($ns, $name) = ($1, $2);
-                $ns = $$xlatNamespace{$ns} if $$xlatNamespace{$ns};
+                $ns = $stdXlatNS{$ns} if $stdXlatNS{$ns};
                 $tag = "XMP-$ns:" . ucfirst $name;
             } else {
@@ -718,8 +766,11 @@
             # this may happen if we have a structural error in the XMP
             # (like an improperly contained list for example)
-            $exifTool->Warn("Error $err placing $$tagInfo{Name} in structure", 1);
+            unless ($$et{NO_STRUCT_WARN}) {
+                my $ns = $$tagInfo{Namespace} || $$tagInfo{Table}{NAMESPACE} || '';
+                $et->Warn("Error $err placing $ns:$$tagInfo{TagID} in structure or list", 1);
+            }
             delete $structs{$strInfo} unless $oldStruct;
         } elsif ($tagInfo eq $strInfo) {
-            # just a regular list tag
+            # just a regular list tag (or an empty structure)
             if ($oldStruct) {
                 # keep tag with lowest numbered key (well, not exactly, since
@@ -727,14 +778,42 @@
                 # everything else, and this is really what we care about)
                 my $k = $listKeys{$oldStruct};
-                $k lt $key and $exifTool->DeleteTag($key), next;
-                $exifTool->DeleteTag($k);   # remove tag with greater copy number
+                if ($k) {   # ($k will be undef for an empty structure)
+                    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
+                }
             }
             # replace existing value with new list
-            $$exifTool{VALUE}{$key} = $structs{$strInfo};
+            $$valueHash{$key} = $structs{$strInfo};
             $listKeys{$structs{$strInfo}} = $key;   # save key for this list tag
         } else {
             # save strInfo ref and file order
-            $var{$strInfo} = [ $strInfo, $$exifTool{FILE_ORDER}{$key} ];
-            $exifTool->DeleteTag($key);
+            if ($var{$strInfo}) {
+                # set file order to just before the first associated flattened tag
+                if ($var{$strInfo}[1] > $$fileOrder{$key}) {
+                    $var{$strInfo}[1] = $$fileOrder{$key} - 0.5;
+                }
+            } else {
+                $var{$strInfo} = [ $strInfo, $$fileOrder{$key} - 0.5 ];
+            }
+            # preserve original flattened tags if requested
+            if ($keepFlat) {
+                my $extra = $$tagExtra{$key} or next;
+                # restore list behaviour of this flattened tag
+                if ($$extra{NoList}) {
+                    $$valueHash{$key} = $$extra{NoList};
+                    delete $$extra{NoList};
+                } elsif ($$extra{NoListDel}) {
+                    # delete this tag since its value was included another list
+                    $et->DeleteTag($key);
+                }
+            } else {
+                $et->DeleteTag($key); # delete the flattened tag
+            }
         }
     }
@@ -745,10 +824,11 @@
         defined $_ or $_ = '' foreach @{$lists{$si}};
     }
-    # save new structure tags
-    foreach $si (keys %structs) {
-        next unless $var{$si};  # already handled regular lists
-        $key = $exifTool->FoundTag($var{$si}[0], '');
-        $$exifTool{VALUE}{$key} = $structs{$si};
-        $$exifTool{FILE_ORDER}{$key} = $var{$si}[1];
+    # make a list of all new structures we generated
+    $var{$_} and push @siList, $_ foreach keys %structs;
+    # save new structures in the same order they were read from file
+    foreach $si (sort { $var{$a}[1] <=> $var{$b}[1] } @siList) {
+        $key = $et->FoundTag($var{$si}[0], '');
+        $$valueHash{$key} = $structs{$si};
+        $$fileOrder{$key} = $var{$si}[1];
     }
 }
@@ -774,5 +854,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ZIP.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ZIP.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ZIP.pm	(revision 34921)
@@ -10,4 +10,6 @@
 #               3) http://www.gzip.org/zlib/rfc-gzip.html
 #               4) http://DataCompression.info/ArchiveFormats/RAR202.txt
+#               5) https://jira.atlassian.com/browse/CONF-21706
+#               6) http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/indesign/cs55-docs/IDML/idml-specification.pdf
 #------------------------------------------------------------------------------
 
@@ -18,5 +20,5 @@
 use Image::ExifTool qw(:DataAccess :Utils);
 
-$VERSION = '1.07';
+$VERSION = '1.26';
 
 sub WarnProc($) { $warnString = $_[0]; }
@@ -24,7 +26,28 @@
 # file types for recognized Open Document "mimetype" values
 my %openDocType = (
+    'application/vnd.oasis.opendocument.database'     => 'ODB', #5
+    'application/vnd.oasis.opendocument.chart'        => 'ODC', #5
+    'application/vnd.oasis.opendocument.formula'      => 'ODF', #5
+    'application/vnd.oasis.opendocument.graphics'     => 'ODG', #5
+    'application/vnd.oasis.opendocument.image'        => 'ODI', #5
     'application/vnd.oasis.opendocument.presentation' => 'ODP',
     'application/vnd.oasis.opendocument.spreadsheet'  => 'ODS',
     'application/vnd.oasis.opendocument.text'         => 'ODT',
+    'application/vnd.adobe.indesign-idml-package'     => 'IDML', #6 (not open doc)
+    'application/epub+zip' => 'EPUB', #PH (not open doc)
+);
+
+# iWork file types based on names of files found in the zip archive
+my %iWorkFile = (
+    'Index/Slide.iwa' => 'KEY',
+    'Index/Tables/DataList.iwa' => 'NUMBERS',
+);
+
+my %iWorkType = (
+    NUMBERS => 'NUMBERS',
+    PAGES   => 'PAGES',
+    KEY     => 'KEY',
+    KTH     => 'KTH',
+    NMBTEMPLATE => 'NMBTEMPLATE',
 );
 
@@ -37,8 +60,10 @@
         The following tags are extracted from ZIP archives.  ExifTool also extracts
         additional meta information from compressed documents inside some ZIP-based
-        files such Office Open XML (DOCX, PPTX and XLSX), Open Document (ODP, ODS
-        and ODT), iWork (KEY, PAGES, NUMBERS), and Capture One Enhanced Image
-        Package (EIP).  The ExifTool family 3 groups may be used to organize the
-        output by embedded document number (ie. the exiftool C<-g3> option).
+        files such Office Open XML (DOCX, PPTX and XLSX), Open Document (ODB, ODC,
+        ODF, ODG, ODI, ODP, ODS and ODT), iWork (KEY, PAGES, NUMBERS), Capture One
+        Enhanced Image Package (EIP), Adobe InDesign Markup Language (IDML),
+        Electronic Publication (EPUB), and Sketch design files (SKETCH).  The
+        ExifTool family 3 groups may be used to organize ZIP tags by embedded
+        document number (ie. the exiftool C<-g3> option).
     },
     2 => 'ZipRequiredVersion',
@@ -82,5 +107,5 @@
                 ($val >> 11) & 0x1f, # hour
                 ($val >> 5)  & 0x3f, # minute
-                 $val        & 0x1f  # second
+                ($val        & 0x1f) * 2  # second
             );
         },
@@ -200,5 +225,5 @@
                 ($val >> 11) & 0x1f, # hour
                 ($val >> 5)  & 0x3f, # minute
-                 $val        & 0x1f  # second
+                ($val        & 0x1f) * 2  # second
             );
         },
@@ -235,5 +260,5 @@
 sub ProcessRAR($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($flags, $buff);
@@ -241,5 +266,5 @@
     return 0 unless $raf->Read($buff, 7) and $buff eq "Rar!\x1a\x07\0";
 
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('II');
     my $tagTablePtr = GetTagTable('Image::ExifTool::ZIP::RAR');
@@ -258,6 +283,6 @@
         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 $exifTool->Options('LargeFileSupport')) {
-            $exifTool->Warn('Large block encountered. Aborting.');
+        if ($size >= 0x80000000 and not $et->Options('LargeFileSupport')) {
+            $et->Warn('Large block encountered. Aborting.');
             last;
         }
@@ -269,6 +294,6 @@
             # add compressed size to start of data so we can extract it with the other tags
             $buff = pack('V',$size) . $buff;
-            $$exifTool{DOC_NUM} = ++$docNum;
-            $exifTool->ProcessDirectory({ DataPt => \$buff }, $tagTablePtr);
+            $$et{DOC_NUM} = ++$docNum;
+            $et->ProcessDirectory({ DataPt => \$buff }, $tagTablePtr);
             $size -= $n;
         } elsif ($type == 0x75 and $size > 6) { # comment block
@@ -276,5 +301,5 @@
             # save comment, only if "Stored" (this is untested)
             if (Get8u(\$buff, 3) == 0x30) {
-                $exifTool->FoundTag('Comment', substr($buff, 6));
+                $et->FoundTag('Comment', substr($buff, 6));
             }
             next;
@@ -283,5 +308,8 @@
         $raf->Seek($size, 1) or last if $size;
     }
-    $$exifTool{DOC_NUM} = 0;
+    $$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;
@@ -294,5 +322,5 @@
 sub ProcessGZIP($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
     my ($flags, $buff);
@@ -300,13 +328,13 @@
     return 0 unless $raf->Read($buff, 10) and $buff =~ /^\x1f\x8b\x08/;
 
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('II');
 
     my $tagTablePtr = GetTagTable('Image::ExifTool::ZIP::GZIP');
-    $exifTool->HandleTag($tagTablePtr, 2, Get8u(\$buff, 2));
-    $exifTool->HandleTag($tagTablePtr, 3, $flags = Get8u(\$buff, 3));
-    $exifTool->HandleTag($tagTablePtr, 4, Get32u(\$buff, 4));
-    $exifTool->HandleTag($tagTablePtr, 8, Get8u(\$buff, 8));
-    $exifTool->HandleTag($tagTablePtr, 9, Get8u(\$buff, 9));
+    $et->HandleTag($tagTablePtr, 2, Get8u(\$buff, 2));
+    $et->HandleTag($tagTablePtr, 3, $flags = Get8u(\$buff, 3));
+    $et->HandleTag($tagTablePtr, 4, Get32u(\$buff, 4));
+    $et->HandleTag($tagTablePtr, 8, Get8u(\$buff, 8));
+    $et->HandleTag($tagTablePtr, 9, Get8u(\$buff, 9));
 
     # extract file name and comment if they exist
@@ -330,5 +358,5 @@
             # it because I could just as easily screw it up)
             my $str = substr($buff, $pos, $end - $pos);
-            $exifTool->HandleTag($tagTablePtr, $tagID, $str);
+            $et->HandleTag($tagTablePtr, $tagID, $str);
             last if $end >= length $buff;
             $pos = $end + 1;
@@ -343,66 +371,80 @@
 sub HandleMember($$;$)
 {
-    my ($exifTool, $member, $tagTablePtr) = @_;
+    my ($et, $member, $tagTablePtr) = @_;
     $tagTablePtr or  $tagTablePtr = GetTagTable('Image::ExifTool::ZIP::Main');
-    $exifTool->HandleTag($tagTablePtr, 2, $member->versionNeededToExtract());
-    $exifTool->HandleTag($tagTablePtr, 3, $member->bitFlag());
-    $exifTool->HandleTag($tagTablePtr, 4, $member->compressionMethod());
-    $exifTool->HandleTag($tagTablePtr, 5, $member->lastModFileDateTime());
-    $exifTool->HandleTag($tagTablePtr, 7, $member->crc32());
-    $exifTool->HandleTag($tagTablePtr, 9, $member->compressedSize());
-    $exifTool->HandleTag($tagTablePtr, 11, $member->uncompressedSize());
-    $exifTool->HandleTag($tagTablePtr, 15, $member->fileName());
+    $et->HandleTag($tagTablePtr, 2, $member->versionNeededToExtract());
+    $et->HandleTag($tagTablePtr, 3, $member->bitFlag());
+    $et->HandleTag($tagTablePtr, 4, $member->compressionMethod());
+    $et->HandleTag($tagTablePtr, 5, $member->lastModFileDateTime());
+    $et->HandleTag($tagTablePtr, 7, $member->crc32());
+    $et->HandleTag($tagTablePtr, 9, $member->compressedSize());
+    $et->HandleTag($tagTablePtr, 11, $member->uncompressedSize());
+    $et->HandleTag($tagTablePtr, 15, $member->fileName());
 }
 
 #------------------------------------------------------------------------------
-# Extract information from an ZIP file
+# Extract information from a ZIP file
 # Inputs: 0) ExifTool object reference, 1) dirInfo reference
 # Returns: 1 on success, 0 if this wasn't a valid ZIP file
 sub ProcessZIP($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $raf = $$dirInfo{RAF};
-    my ($buff, $buf2, $zip, $docNum);
-
-    return 0 unless $raf->Read($buff, 30) and $buff =~ /^PK\x03\x04/;
+    my ($buff, $buf2, $zip);
+
+    return 0 unless $raf->Read($buff, 30) == 30 and $buff =~ /^PK\x03\x04/;
 
     my $tagTablePtr = GetTagTable('Image::ExifTool::ZIP::Main');
-
-    # use Archive::Zip if avilable
+    my $docNum = 0;
+
+    # use Archive::Zip if available
     for (;;) {
-        unless (eval 'require Archive::Zip' and eval 'require IO::File') {
-            if ($$exifTool{FILE_EXT} and $$exifTool{FILE_EXT} ne 'ZIP') {
-                $exifTool->Warn("Install Archive::Zip to decode compressed ZIP information");
+        unless (eval { require Archive::Zip } and eval { require IO::File }) {
+            if ($$et{FILE_EXT} and $$et{FILE_EXT} ne 'ZIP') {
+                $et->Warn("Install Archive::Zip to decode compressed ZIP information");
             }
             last;
         }
         # Archive::Zip requires a seekable IO::File object
-        my $fh = $raf->{FILE_PT};
-        if ($fh and seek($fh, 0, 0)) {
-            unless (eval 'require IO::File') {
+        my $fh;
+        if ($raf->{TESTED} >= 0) {
+            unless (eval { require IO::File }) {
                 # (this shouldn't happen because IO::File is a prerequisite of Archive::Zip)
-                $exifTool->Warn("Install IO::File to decode compressed ZIP information");
+                $et->Warn("Install IO::File to decode compressed ZIP information");
                 last;
             }
+            $raf->Seek(0,0);
+            $fh = $raf->{FILE_PT};
             bless $fh, 'IO::File';  # Archive::Zip expects an IO::File object
-        } elsif (eval 'require IO::String') {
+        } elsif (eval { require IO::String }) {
             # read the whole file into memory (what else can I do?)
             $raf->Slurp();
             $fh = new IO::String ${$raf->{BUFF_PT}};
         } else {
-            my $type = $fh ? 'pipe or socket' : 'scalar reference';
-            $exifTool->Warn("Install IO::String to decode compressed ZIP information from a $type");
+            my $type = $raf->{FILE_PT} ? 'pipe or socket' : 'scalar reference';
+            $et->Warn("Install IO::String to decode compressed ZIP information from a $type");
             last;
         }
-        $exifTool->VPrint(1, "  --- using Archive::Zip ---\n");
+        $et->VPrint(1, "  --- using Archive::Zip ---\n");
         $zip = new Archive::Zip;
         # catch all warnings! (Archive::Zip is bad for this)
         local $SIG{'__WARN__'} = \&WarnProc;
         my $status = $zip->readFromFileHandle($fh);
+        if ($status eq '4' and $raf->{TESTED} >= 0 and eval { require IO::String } and
+            $raf->Seek(0,2) and $raf->Tell() < 100000000)
+        {
+            # try again, reading it ourself this time in an attempt to avoid
+            # a failed test with Perl 5.6.2 GNU/Linux 2.6.32-5-686 i686-linux-64int-ld
+            $raf->Seek(0,0);
+            $raf->Slurp();
+            $fh = new IO::String ${$raf->{BUFF_PT}};
+            $zip = new Archive::Zip;
+            $status = $zip->readFromFileHandle($fh);
+        }
         if ($status) {
             undef $zip;
             my %err = ( 1=>'Stream end error', 3=>'Format error', 4=>'IO error' );
             my $err = $err{$status} || "Error $status";
-            $exifTool->Warn("$err reading ZIP file");
+            $et->Warn("$err reading ZIP file");
             last;
         }
@@ -415,5 +457,12 @@
         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;
             }
@@ -424,5 +473,5 @@
             $$dirInfo{MIME} = $mime;
             require Image::ExifTool::OOXML;
-            Image::ExifTool::OOXML::ProcessDOCX($exifTool, $dirInfo);
+            Image::ExifTool::OOXML::ProcessDOCX($et, $dirInfo);
             delete $$dirInfo{MIME};
             last;
@@ -433,39 +482,83 @@
         if (@members) {
             require Image::ExifTool::CaptureOne;
-            Image::ExifTool::CaptureOne::ProcessEIP($exifTool, $dirInfo);
+            Image::ExifTool::CaptureOne::ProcessEIP($et, $dirInfo);
             last;
         }
 
         # check for an iWork file
-        @members = $zip->membersMatching('^(index\.(xml|apxl)|QuickLook/Thumbnail\.jpg)$');
+        @members = $zip->membersMatching('(?i)^(index\.(xml|apxl)|QuickLook/Thumbnail\.jpg|[^/]+\.(pages|numbers|key)/Index.(zip|xml|apxl))$');
         if (@members) {
             require Image::ExifTool::iWork;
-            Image::ExifTool::iWork::Process_iWork($exifTool, $dirInfo);
+            Image::ExifTool::iWork::Process_iWork($et, $dirInfo);
             last;
         }
 
-        # check for an Open Document file
+        # check for an Open Document, IDML or EPUB file
         my $mType = $zip->memberNamed('mimetype');
         if ($mType) {
             ($mime, $status) = $zip->contents($mType);
-            unless ($status) {
-                chomp $mime;
-                if ($openDocType{$mime}) {
-                    $exifTool->SetFileType($openDocType{$mime}, $mime);
-                    # extract Open Document metadata from "meta.xml"
-                    my $meta = $zip->memberNamed('meta.xml');
-                    if ($meta) {
-                        ($buff, $status) = $zip->contents($meta);
-                        unless ($status) {
-                            my %dirInfo = (
-                                DataPt => \$buff,
-                                DirLen => length $buff,
-                                DataLen => length $buff,
-                            );
-                            my $xmpTable = GetTagTable('Image::ExifTool::XMP::Main');
-                            $exifTool->ProcessDirectory(\%dirInfo, $xmpTable);
-                        }
+            if (not $status and $mime =~ /([\x21-\xfe]+)/s) {
+                # clean up MIME type just in case (note that MIME is case insensitive)
+                $mime = lc $1;
+                $et->SetFileType($openDocType{$mime} || 'ZIP', $mime);
+                $et->Warn("Unrecognized MIMEType $mime") unless $openDocType{$mime};
+                # extract Open Document metadata from "meta.xml"
+                my $meta = $zip->memberNamed('meta.xml');
+                # IDML files have metadata in a different place (ref 6)
+                $meta or $meta = $zip->memberNamed('META-INF/metadata.xml');
+                if ($meta) {
+                    ($buff, $status) = $zip->contents($meta);
+                    unless ($status) {
+                        my %dirInfo = (
+                            DirName => 'XML',
+                            DataPt  => \$buff,
+                            DirLen  => length $buff,
+                            DataLen => length $buff,
+                        );
+                        # (avoid structure warnings when copying from XML)
+                        my $oldWarn = $$et{NO_STRUCT_WARN};
+                        $$et{NO_STRUCT_WARN} = 1;
+                        $et->ProcessDirectory(\%dirInfo, GetTagTable('Image::ExifTool::XMP::Main'));
+                        $$et{NO_STRUCT_WARN} = $oldWarn;
                     }
-                    # extract preview image(s) from "Thumbnails" directory
+                }
+                # process rootfile of EPUB container if applicable
+                for (;;) {
+                    last if $meta and $mime ne 'application/epub+zip';
+                    my $container = $zip->memberNamed('META-INF/container.xml');
+                    ($buff, $status) = $zip->contents($container);
+                    last if $status;
+                    $buff =~ /<rootfile\s+[^>]*?\bfull-path=(['"])(.*?)\1/s or last;
+                    # load the rootfile data (OPF extension; contains XML metadata)
+                    my $meta2 = $zip->memberNamed($2) or last;
+                    $meta = $meta2;
+                    ($buff, $status) = $zip->contents($meta);
+                    last if $status;
+                    # use opf:event to generate more meaningful tag names for dc:date
+                    while ($buff =~ s{<dc:date opf:event="(\w+)">([^<]+)</dc:date>}{<dc:${1}Date>$2</dc:${1}Date>}s) {
+                        my $dcTable = GetTagTable('Image::ExifTool::XMP::dc');
+                        my $tag = "${1}Date";
+                        AddTagToTable($dcTable, $tag, {
+                            Name => ucfirst $tag,
+                            Groups => { 2 => 'Time' },
+                            List => 'Seq',
+                            %Image::ExifTool::XMP::dateTimeInfo
+                        }) unless $$dcTable{$tag};
+                    }
+                    my %dirInfo = (
+                        DataPt => \$buff,
+                        DirLen => length $buff,
+                        DataLen => length $buff,
+                        IgnoreProp => { 'package' => 1, metadata => 1 },
+                    );
+                    # (avoid structure warnings when copying from XML)
+                    my $oldWarn = $$et{NO_STRUCT_WARN};
+                    $$et{NO_STRUCT_WARN} = 1;
+                    $et->ProcessDirectory(\%dirInfo, GetTagTable('Image::ExifTool::XMP::XML'));
+                    $$et{NO_STRUCT_WARN} = $oldWarn;
+                    last;
+                }
+                if ($openDocType{$mime} or $meta) {
+                    # extract preview image(s) from "Thumbnails" directory if they exist
                     my $type;
                     my %tag = ( jpg => 'PreviewImage', png => 'PreviewPNG' );
@@ -474,20 +567,50 @@
                         next unless $thumb;
                         ($buff, $status) = $zip->contents($thumb);
-                        $exifTool->FoundTag($tag{$type}, $buff) unless $status;
+                        $et->FoundTag($tag{$type}, $buff) unless $status;
                     }
-                    last;
+                    last;   # all done since we recognized the MIME type or found metadata
                 }
+                # continue on to list ZIP contents...
             }
         }
 
         # otherwise just extract general ZIP information
-        $exifTool->SetFileType();
+        $et->SetFileType();
         @members = $zip->members();
-        $docNum = 0;
-        my $member;
+        my ($member, $iWorkType);
+        # special files to extract
+        my %extract = (
+            'meta.json' => 1,
+            'previews/preview.png' => 'PreviewPNG',
+            'preview.jpg' => 'PreviewImage', # (iWork 2013 files)
+            'preview-web.jpg' => 'OtherImage', # (iWork 2013 files)
+            'preview-micro.jpg' => 'ThumbnailImage', # (iWork 2013 files)
+            'QuickLook/Thumbnail.jpg' => 'ThumbnailImage', # (iWork 2009 files)
+            'QuickLook/Preview.pdf' => 'PreviewPDF', # (iWork 2009 files)
+        );
         foreach $member (@members) {
-            $$exifTool{DOC_NUM} = ++$docNum;
-            HandleMember($exifTool, $member, $tagTablePtr);
-        }
+            $$et{DOC_NUM} = ++$docNum;
+            HandleMember($et, $member, $tagTablePtr);
+            my $file = $member->fileName();
+            # extract things from Sketch files
+            if ($extract{$file}) {
+                ($buff, $status) = $zip->contents($member);
+                $status and $et->Warn("Error extracting $file"), next;
+                if ($file eq 'meta.json') {
+                    $et->ExtractInfo(\$buff, { ReEntry => 1 });
+                    if ($$et{VALUE}{App} and $$et{VALUE}{App} =~ /sketch/i) {
+                        $et->OverrideFileType('SKETCH');
+                    }
+                } else {
+                    $et->FoundTag($extract{$file} => $buff);
+                }
+            } elsif ($file eq 'Index/Document.iwa' and not $iWorkType) {
+                my $type = $iWorkType{$$et{FILE_EXT} || ''};
+                $iWorkType = $type || 'PAGES';
+            } elsif ($iWorkFile{$file}) {
+                $iWorkType = $iWorkFile{$file};
+            }
+        }
+        $et->OverrideFileType($iWorkType) if $iWorkType;
         last;
     }
@@ -495,5 +618,8 @@
     if ($zip) {
         delete $$dirInfo{ZIP};
-        delete $$exifTool{DOC_NUM};
+        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;
     }
@@ -501,8 +627,7 @@
 # process the ZIP file by hand (funny, but this seems easier than using Archive::Zip)
 #
-    $docNum = 0;
-    $exifTool->VPrint(1, "  -- processing as binary data --\n");
+    $et->VPrint(1, "  -- processing as binary data --\n");
     $raf->Seek(30, 0);
-    $exifTool->SetFileType();
+    $et->SetFileType();
     SetByteOrder('II');
 
@@ -523,5 +648,5 @@
         $raf->Read($buf2, $len) == $len or last;
 
-        $$exifTool{DOC_NUM} = ++$docNum;
+        $$et{DOC_NUM} = ++$docNum;
         $buff .= $buf2;
         my %dirInfo = (
@@ -532,5 +657,5 @@
             DirLen => 30 + $len,
         );
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         my $flags = Get16u(\$buff, 6);
         if ($flags & 0x08) {
@@ -539,5 +664,5 @@
             #  sizes are set to 0 in the header.  Instead, they are stored
             #  after the compressed data with an optional header of 0x08074b50)
-            $exifTool->Warn('Stream mode data encountered, file list may be incomplete');
+            $et->Warn('Stream mode data encountered, file list may be incomplete');
             last;
         }
@@ -546,5 +671,8 @@
         $raf->Read($buff, 30) == 30 and $buff =~ /^PK\x03\x04/ or last;
     }
-    delete $$exifTool{DOC_NUM};
+    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;
 }
@@ -566,9 +694,12 @@
 This module contains definitions required by Image::ExifTool to extract meta
 information from ZIP, GZIP and RAR archives.  This includes ZIP-based file
-types like DOCX, PPTX, XLSX, ODP, ODS, ODT and EIP.
+types like Office Open XML (DOCX, PPTX and XLSX), Open Document (ODB, ODC,
+ODF, ODG, ODI, ODP, ODS and ODT), iWork (KEY, PAGES, NUMBERS), Capture One
+Enhanced Image Package (EIP), Adobe InDesign Markup Language (IDML),
+Electronic Publication (EPUB), and Sketch design files (SKETCH).
 
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ZISRAW.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ZISRAW.pm	(revision 34921)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/ZISRAW.pm	(revision 34921)
@@ -0,0 +1,123 @@
+#------------------------------------------------------------------------------
+# File:         ZISRAW.pm
+#
+# Description:  Read ZISRAW (CZI) meta information
+#
+# Revisions:    2020-08-07 - P. Harvey Created
+#
+# References:   1) https://www.zeiss.com/microscopy/us/products/microscope-software/zen/czi.html
+#------------------------------------------------------------------------------
+
+package Image::ExifTool::ZISRAW;
+
+use strict;
+use vars qw($VERSION);
+use Image::ExifTool qw(:DataAccess :Utils);
+
+$VERSION = '1.00';
+
+%Image::ExifTool::ZISRAW::Main = (
+    PROCESS_PROC => \&Image::ExifTool::ProcessBinaryData,
+    GROUPS => { 0 => 'File', 1 => 'File', 2 => 'Image' },
+    NOTES => q{
+        As well as the header information listed below, ExifTool also extracts the
+        top-level XML-based metadata from Zeiss Integrated Software RAW (ZISRAW) CZI
+        files.
+    },
+    0x20 => {
+        Name => 'ZISRAWVersion',
+        Format => 'int32u[2]',
+        PrintConv => '$val =~ tr/ /./; $val',
+    },
+    0x30 => {
+        Name => 'PrimaryFileGUID',
+        Format => 'undef[16]',
+        ValueConv => 'unpack("H*",$val)',
+    },
+    0x40 => {
+        Name => 'FileGUID',
+        Format => 'undef[16]',
+        ValueConv => 'unpack("H*",$val)',
+    },
+);
+
+#------------------------------------------------------------------------------
+# Extract metadata from a ZISRAW (CZI) image
+# Inputs: 0) ExifTool object reference, 1) dirInfo reference
+# Returns: 1 on success, 0 if this wasn't a valid CZI file
+sub ProcessCZI($$)
+{
+    my ($et, $dirInfo) = @_;
+    my $raf = $$dirInfo{RAF};
+    my ($buff, $tagTablePtr);
+
+    # verify this is a valid CZI file
+    return 0 unless $raf->Read($buff, 100) == 100;
+    return 0 unless $buff =~ /^ZISRAWFILE\0{6}/;
+    $et->SetFileType();
+    SetByteOrder('II');
+    my %dirInfo = (
+        DataPt => \$buff,
+        DirStart => 0,
+        DirLen => length($buff),
+    );
+    $tagTablePtr = GetTagTable('Image::ExifTool::ZISRAW::Main');
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+
+    # read the metadata section
+    my $pos = Get64u(\$buff, 92) or return 1;
+    $raf->Seek($pos, 0) or $et->Warn('Error seeking to metadata'), return 0;
+    $raf->Read($buff, 288) == 288 or $et->Warn('Error reading metadata header'), return 0;
+    $buff =~ /^ZISRAWMETADATA\0\0/ or $et->Warn('Invalid metadata header'), return 0;
+    my $len = Get32u(\$buff, 32);
+    $len < 200000000 or $et->Warn('Metadata section too large. Ignoring'), return 0;
+    $raf->Read($buff, $len) or $et->Warn('Error reading XML metadata'), return 0;
+    $et->FoundTag('XML', $buff);    # extract as a block
+    $tagTablePtr = GetTagTable('Image::ExifTool::XMP::XML');
+    $dirInfo{DirLen} = length $buff;
+    # shorten tag names somewhat by removing 'ImageDocumentMetadata' prefix from all
+    $$et{XmpIgnoreProps} = [ 'ImageDocument', 'Metadata' ];
+    $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
+
+    return 1;
+}
+
+1;  # end
+
+__END__
+
+=head1 NAME
+
+Image::ExifTool::ZISRAW - Read ZISRAW (CZI) meta information
+
+=head1 SYNOPSIS
+
+This module is used by Image::ExifTool
+
+=head1 DESCRIPTION
+
+This module contains definitions required by Image::ExifTool to read
+metadata from Zeiss Integrated Software RAW (ZISRAW) CZI files.
+
+=head1 AUTHOR
+
+Copyright 2003-2021, 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.zeiss.com/microscopy/us/products/microscope-software/zen/czi.html>
+
+=back
+
+=head1 SEE ALSO
+
+L<Image::ExifTool::TagNames/ZISRAW Tags>,
+L<Image::ExifTool(3pm)|Image::ExifTool>
+
+=cut
+
Index: /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/iWork.pm
===================================================================
--- /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/iWork.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/cpan/Image/ExifTool/iWork.pm	(revision 34921)
@@ -15,20 +15,20 @@
 use Image::ExifTool::ZIP;
 
-$VERSION = '1.02';
-
-# test for recognized iWork document extensions and outter XML elements
+$VERSION = '1.06';
+
+# test for recognized iWork document extensions and outer XML elements
 my %iWorkType = (
     # file extensions
-    NUMBERS => 'Apple Numbers',
-    PAGES   => 'Apple Pages',
-    KEY     => 'Apple Keynote',
-    KTH     => 'Apple Keynote Theme',
-    NMBTEMPLATE => 'Apple Numbers Template',
+    NUMBERS => 'NUMBERS',
+    PAGES   => 'PAGES',
+    KEY     => 'KEY',
+    KTH     => 'KTH',
+    NMBTEMPLATE => 'NMBTEMPLATE',
     # we don't support double extensions --
     # "PAGES.TEMPLATE" => 'Apple Pages Template',
-    # outter XML elements
-    'ls:document' => 'Apple Numbers',
-    'sl:document' => 'Apple Pages',
-    'key:presentation' => 'Apple Keynote',
+    # outer XML elements
+    'ls:document' => 'NUMBERS',
+    'sl:document' => 'PAGES',
+    'key:presentation' => 'KEY',
 );
 
@@ -37,10 +37,10 @@
 # indicates, but I think it refers to the new "flattened" package format)
 my %mimeType = (
-    'Apple Numbers' => 'application/x-iwork-numbers-sffnumbers',
-    'Apple Pages'   => 'application/x-iwork-pages-sffpages',
-    'Apple Keynote' => 'application/x-iWork-keynote-sffkey',
-    'Apple Numbers Template' => 'application/x-iwork-numbers-sfftemplate',
-    'Apple Pages Template'   => 'application/x-iwork-pages-sfftemplate',
-    'Apple Keynote Theme'    => 'application/x-iWork-keynote-sffkth',
+    'NUMBERS'       => 'application/x-iwork-numbers-sffnumbers',
+    'PAGES'         => 'application/x-iwork-pages-sffpages',
+    'KEY'           => 'application/x-iWork-keynote-sffkey',
+    'NMBTEMPLATE'   => 'application/x-iwork-numbers-sfftemplate',
+    'PAGES.TEMPLATE'=> 'application/x-iwork-pages-sfftemplate',
+    'KTH'           => 'application/x-iWork-keynote-sffkth',
 );
 
@@ -71,5 +71,5 @@
     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];
 }
 
@@ -82,23 +82,23 @@
 sub FoundTag($$$$;$)
 {
-    my ($exifTool, $tagTablePtr, $props, $val, $attrs) = @_;
+    my ($et, $tagTablePtr, $props, $val, $attrs) = @_;
     return 0 unless @$props;
-    my $verbose = $exifTool->Options('Verbose');
-
-    $exifTool->VPrint(0, "  | - Tag '", join('/',@$props), "'\n") if $verbose > 1;
+    my $verbose = $et->Options('Verbose');
+
+    $et->VPrint(0, "  | - Tag '", join('/',@$props), "'\n") if $verbose > 1;
 
     # un-escape XML character entities
     $val = Image::ExifTool::XMP::UnescapeXML($val);
     # convert from UTF8 to ExifTool Charset
-    $val = $exifTool->Decode($val, 'UTF8');
+    $val = $et->Decode($val, 'UTF8');
     my $tag = GetTagID($props) or return 0;
 
     # add any unknown tags to table
     unless ($$tagTablePtr{$tag}) {
-        $exifTool->VPrint(0, "  [adding $tag]\n") if $verbose;
-        Image::ExifTool::AddTagToTable($tagTablePtr, $tag, { Name => ucfirst $tag });
+        $et->VPrint(0, "  [adding $tag]\n") if $verbose;
+        AddTagToTable($tagTablePtr, $tag, { Name => ucfirst $tag });
     }
     # save the tag
-    $exifTool->HandleTag($tagTablePtr, $tag, $val);
+    $et->HandleTag($tagTablePtr, $tag, $val);
 
     return 1;
@@ -113,5 +113,5 @@
 sub Process_iWork($$)
 {
-    my ($exifTool, $dirInfo) = @_;
+    my ($et, $dirInfo) = @_;
     my $zip = $$dirInfo{ZIP};
     my ($type, $index, $indexFile, $status);
@@ -120,5 +120,5 @@
     local $SIG{'__WARN__'} = \&Image::ExifTool::ZIP::WarnProc;
     # trust type given by file extension if available
-    $type = $iWorkType{$$exifTool{FILE_EXT}} if $$exifTool{FILE_EXT};
+    $type = $iWorkType{$$et{FILE_EXT}} if $$et{FILE_EXT};
     unless ($type) {
         # read the index file
@@ -132,8 +132,14 @@
                 }
             }
+        } else {
+            @members = $zip->membersMatching('(?i)^.*\.(pages|numbers|key)/Index.*');
+            if (@members) {
+                my $tmp = $members[0]->fileName();
+                $type = $iWorkType{uc $1} if $tmp =~ /\.(pages|numbers|key)/i;
+            }
         }
         $type or $type = 'ZIP';     # assume ZIP by default
     }
-    $exifTool->SetFileType($type, $mimeType{$type});
+    $et->SetFileType($type, $mimeType{$type});
 
     my @members = $zip->members();
@@ -144,11 +150,11 @@
         my $file = $member->fileName();
         next unless defined $file;
-        $exifTool->VPrint(0, "File: $file\n");
+        $et->VPrint(0, "File: $file\n");
         # set the document number and extract ZIP tags
-        $$exifTool{DOC_NUM} = ++$docNum;
-        Image::ExifTool::ZIP::HandleMember($exifTool, $member);
-
-        # process only the index XML and JPEG thumbnail files
-        next unless $file =~ m{^(index\.(xml|apxl)|QuickLook/Thumbnail\.jpg)$}i;
+        $$et{DOC_NUM} = ++$docNum;
+        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(-micro|-web)?.jpg)$}i;
         # get the file contents if necessary
         # (CAREFUL! $buff MUST be local since we hand off a value ref to PreviewImage)
@@ -159,10 +165,11 @@
         } else {
             ($buff, $status) = $zip->contents($member);
-            $status and $exifTool->Warn("Error extracting $file"), next;
+            $status and $et->Warn("Error extracting $file"), next;
             $buffPt = \$buff;
         }
         # extract JPEG as PreviewImage (should only be QuickLook/Thumbnail.jpg)
         if ($file =~ /\.jpg$/) {
-            $exifTool->FoundTag('PreviewImage', $buffPt);
+            my $type = ($file =~ /preview-(\w+)/) ? ($1 eq 'web' ? 'Other' : 'Thumbnail') : 'Preview';
+            $et->FoundTag($type . 'Image', $buffPt);
             next;
         }
@@ -183,8 +190,8 @@
         );
         my $tagTablePtr = GetTagTable('Image::ExifTool::iWork::Main');
-        $exifTool->ProcessDirectory(\%dirInfo, $tagTablePtr);
+        $et->ProcessDirectory(\%dirInfo, $tagTablePtr);
         undef $$buffPt; # (free memory now)
     }
-    delete $$exifTool{DOC_NUM};
+    delete $$et{DOC_NUM};
     return 1;
 }
@@ -209,5 +216,5 @@
 =head1 AUTHOR
 
-Copyright 2003-2011, Phil Harvey (phil at owl.phy.queensu.ca)
+Copyright 2003-2021, Phil Harvey (philharvey66 at gmail.com)
 
 This library is free software; you can redistribute it and/or modify it
Index: /main/trunk/greenstone2/perllib/plugins/EmbeddedMetadataPlugin.pm
===================================================================
--- /main/trunk/greenstone2/perllib/plugins/EmbeddedMetadataPlugin.pm	(revision 34920)
+++ /main/trunk/greenstone2/perllib/plugins/EmbeddedMetadataPlugin.pm	(revision 34921)
@@ -72,4 +72,10 @@
 	'deft' => " "
 	},{
+	'name' => "apply_join_before_split_to_metafields",
+	'desc' => "{EmbeddedMetadataPlugin.apply_join_before_split_to_metafields}",
+	'type' => "string",
+	'reqd' => "no",
+	'deft' => ".*Keywords" # regex. Set to .* to apply join_before_split to All meta fields (that are arrays of values)
+	},{
 	'name' => "trim_whitespace",
 	'desc' => "{EmbeddedMetadataPlugin.trim_whitespace}",
@@ -309,4 +315,10 @@
     }
 
+    # Check if join_before_split is only applied to spefified fields or all fields
+    my $apply_join_before_split_to_metafields = $self->{'apply_join_before_split_to_metafields'};
+    if($apply_join_before_split_to_metafields eq "") {
+	undef $apply_join_before_split_to_metafields;	
+    }
+    
     my @group_list = Image::ExifTool::GetAllGroups(0);
     foreach my $group (@group_list) {
@@ -350,4 +362,12 @@
 				}
 				elsif (ref $value eq 'ARRAY') {
+				    my $join_before_split_for_this_field = $self->{'join_before_split'}; # if join_before_split set, will apply it to all metadata fields 
+				    # If specific metadata fields specified, only apply join_before_split to those fields
+				    # (in which case check if current metadata field matches any of those metadata fields)
+				    # else apply to all metadata fields as before
+				    if($join_before_split_for_this_field && $apply_join_before_split_to_metafields && $field !~ m/$apply_join_before_split_to_metafields/) {					    
+					undef $join_before_split_for_this_field;					
+				    }
+				    
 					$metadata_done = 1;
 					
@@ -356,5 +376,5 @@
 						$v = Encode::decode($encoding,$v);
 						
-						if(!$self->{'join_before_split'}){
+						if(!$join_before_split_for_this_field) { # if(!$self->{'join_before_split'}){
 							if (defined $separator) {
 								my @vs = split($separator, $v);
@@ -377,6 +397,6 @@
 						}
 					}
-					
-					if($self->{'join_before_split'}){
+				    
+					if($join_before_split_for_this_field) { #if($self->{'join_before_split'}){
 						if (defined $separator) {
 							my @vs = split($separator, $allvals);
Index: /main/trunk/greenstone2/perllib/strings.properties
===================================================================
--- /main/trunk/greenstone2/perllib/strings.properties	(revision 34920)
+++ /main/trunk/greenstone2/perllib/strings.properties	(revision 34921)
@@ -931,4 +931,5 @@
 EmbeddedMetadataPlugin.join_before_split:Join fields with multiple entries (e.g. Authors or Keywords) before they are (optionally) split using the specified separator. 
 EmbeddedMetadataPlugin.join_character:The character to use with join_before_split (default is a single space).
+EmbeddedMetadataPlugin.apply_join_before_split_to_metafields:Use in tandem with join_before_split. A Regular Expression specifying which metadata fields join_before_split will be applied to. By default, will apply to any metadata fields whose fieldnames end on Keywords. Set value to .* to apply to all metadata fields. Use vertical bar as separator to list specific metadata field names, e.g. a value of Keywords|Title|Creator, will match metadata fields whose names are exactly any of Keywords, Title and Creator.
 EmbeddedMetadataPlugin.trim_whitespace:Trim whitespace from start and end of any extracted metadata values (Note: this also applies to any values generated through joining with join_before_split or splitting through metadata_field_separator).
 EmbeddedMetadataPlugin.set_filter_list:A comma-separated list of the metadata sets we would like to retrieve.
